Commit b4fea8c6 authored by Steven's avatar Steven

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
parent cf0a285e
...@@ -3,7 +3,7 @@ import { Checkbox } from "@/components/ui/checkbox"; ...@@ -3,7 +3,7 @@ import { Checkbox } from "@/components/ui/checkbox";
import { useUpdateMemo } from "@/hooks/useMemoQueries"; import { useUpdateMemo } from "@/hooks/useMemoQueries";
import { toggleTaskAtIndex } from "@/utils/markdown-manipulation"; import { toggleTaskAtIndex } from "@/utils/markdown-manipulation";
import { useMemoViewContext, useMemoViewDerived } from "../MemoView/MemoViewContext"; 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"; import type { ReactMarkdownProps } from "./markdown/types";
interface TaskListItemProps extends React.InputHTMLAttributes<HTMLInputElement>, ReactMarkdownProps { interface TaskListItemProps extends React.InputHTMLAttributes<HTMLInputElement>, ReactMarkdownProps {
...@@ -35,14 +35,12 @@ export const TaskListItem: React.FC<TaskListItemProps> = ({ checked, node: _node ...@@ -35,14 +35,12 @@ export const TaskListItem: React.FC<TaskListItemProps> = ({ checked, node: _node
if (taskIndexStr !== null) { if (taskIndexStr !== null) {
taskIndex = parseInt(taskIndexStr); taskIndex = parseInt(taskIndexStr);
} else { } else {
// Fallback: Calculate index by counting task list items // Fallback: Calculate index by counting all task list items in the entire memo
// Walk up to find the parent element with all task items // We need to search from the root memo content container, not just the nearest list
let searchRoot = listItem.parentElement; // to ensure nested tasks are counted in document order
while (searchRoot && !searchRoot.classList.contains(TASK_LIST_CLASS)) { let searchRoot = listItem.closest('[class*="memo-content"], [class*="MemoContent"]');
searchRoot = searchRoot.parentElement;
}
// If not found, search from the document root // If memo content container not found, search from document body
if (!searchRoot) { if (!searchRoot) {
searchRoot = document.body; searchRoot = document.body;
} }
......
...@@ -19,7 +19,11 @@ export const List = ({ ordered, children, className, node: _node, ...domProps }: ...@@ -19,7 +19,11 @@ export const List = ({ ordered, children, className, node: _node, ...domProps }:
<Component <Component
className={cn( className={cn(
"my-0 mb-2 list-outside", "my-0 mb-2 list-outside",
isTaskList ? "pl-0 list-none" : cn("pl-6", ordered ? "list-decimal" : "list-disc"), isTaskList
? // Task list: no bullets, nested lists get left margin for indentation
"list-none [&_ul.contains-task-list]:ml-6"
: // Regular list: standard padding and list style
cn("pl-6", ordered ? "list-decimal" : "list-disc"),
className, className,
)} )}
{...domProps} {...domProps}
...@@ -46,10 +50,10 @@ export const ListItem = ({ children, className, node: _node, ...domProps }: List ...@@ -46,10 +50,10 @@ export const ListItem = ({ children, className, node: _node, ...domProps }: List
<li <li
className={cn( className={cn(
"mt-0.5 leading-6 list-none", "mt-0.5 leading-6 list-none",
// Task item styles: checkbox margins, inline paragraph, nested list indent // Checkbox styling: margin and alignment
"[&>button]:mr-2 [&>button]:align-middle", "[&>button]:mr-2 [&>button]:align-middle",
// Inline paragraph for task text
"[&>p]:inline [&>p]:m-0", "[&>p]:inline [&>p]:m-0",
`[&>.${TASK_LIST_CLASS}]:pl-6`,
className, className,
)} )}
{...domProps} {...domProps}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment