From b4fea8c6476b8ce95fd1b1bb42f4d274dd5c30c3 Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 3 Feb 2026 23:45:45 +0800 Subject: [PATCH] fix: nested task list display and checkbox interaction (#5575) - Fix nested task lists not showing proper indentation - Use simple CSS cascade with [&_ul.contains-task-list]:ml-6 - Fix checkbox clicks toggling wrong tasks in nested lists - Search from memo root container for global task indexing - Remove complex selectors in favor of standard approach - Match behavior of GitHub, Notion, and other platforms Closes #5575 --- web/src/components/MemoContent/TaskListItem.tsx | 14 ++++++-------- web/src/components/MemoContent/markdown/List.tsx | 10 +++++++--- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/web/src/components/MemoContent/TaskListItem.tsx b/web/src/components/MemoContent/TaskListItem.tsx index 379824e01..a76e7afe5 100644 --- a/web/src/components/MemoContent/TaskListItem.tsx +++ b/web/src/components/MemoContent/TaskListItem.tsx @@ -3,7 +3,7 @@ import { Checkbox } from "@/components/ui/checkbox"; import { useUpdateMemo } from "@/hooks/useMemoQueries"; import { toggleTaskAtIndex } from "@/utils/markdown-manipulation"; import { useMemoViewContext, useMemoViewDerived } from "../MemoView/MemoViewContext"; -import { TASK_LIST_CLASS, TASK_LIST_ITEM_CLASS } from "./constants"; +import { TASK_LIST_ITEM_CLASS } from "./constants"; import type { ReactMarkdownProps } from "./markdown/types"; interface TaskListItemProps extends React.InputHTMLAttributes, ReactMarkdownProps { @@ -35,14 +35,12 @@ export const TaskListItem: React.FC = ({ checked, node: _node if (taskIndexStr !== null) { taskIndex = parseInt(taskIndexStr); } else { - // Fallback: Calculate index by counting task list items - // Walk up to find the parent element with all task items - let searchRoot = listItem.parentElement; - while (searchRoot && !searchRoot.classList.contains(TASK_LIST_CLASS)) { - searchRoot = searchRoot.parentElement; - } + // Fallback: Calculate index by counting all task list items in the entire memo + // We need to search from the root memo content container, not just the nearest list + // to ensure nested tasks are counted in document order + let searchRoot = listItem.closest('[class*="memo-content"], [class*="MemoContent"]'); - // If not found, search from the document root + // If memo content container not found, search from document body if (!searchRoot) { searchRoot = document.body; } diff --git a/web/src/components/MemoContent/markdown/List.tsx b/web/src/components/MemoContent/markdown/List.tsx index b9969bfcf..79942cd51 100644 --- a/web/src/components/MemoContent/markdown/List.tsx +++ b/web/src/components/MemoContent/markdown/List.tsx @@ -19,7 +19,11 @@ export const List = ({ ordered, children, className, node: _node, ...domProps }: button]:mr-2 [&>button]:align-middle", + // Inline paragraph for task text "[&>p]:inline [&>p]:m-0", - `[&>.${TASK_LIST_CLASS}]:pl-6`, className, )} {...domProps}