diff --git a/packages/editor/src/extensions/task-list/component.tsx b/packages/editor/src/extensions/task-list/component.tsx index 7a8360baa..ef58a015e 100644 --- a/packages/editor/src/extensions/task-list/component.tsx +++ b/packages/editor/src/extensions/task-list/component.tsx @@ -18,14 +18,18 @@ along with this program. If not, see . */ import { Box, Flex, Input, Text } from "@theme-ui/components"; -import { findChildren, getNodeType } from "@tiptap/core"; +import { + findChildren, + findParentNodeClosestToPos, + getNodeType +} from "@tiptap/core"; import { Node } from "prosemirror-model"; import { useCallback, useEffect, useMemo, useState } from "react"; import { ToolButton } from "../../toolbar/components/tool-button"; import { findParentNodeOfTypeClosestToPos } from "../../utils/prosemirror"; import { ReactNodeViewProps } from "../react"; import { TaskItemNode } from "../task-item"; -import { TaskListAttributes } from "./task-list"; +import { TaskListAttributes, TaskListNode } from "./task-list"; import { countCheckedItems, deleteCheckedItems, sortList } from "./utils"; export function TaskListComponent( @@ -34,7 +38,7 @@ export function TaskListComponent( // const isMobile = useIsMobile(); const { editor, getPos, node, updateAttributes, forwardRef, pos } = props; const taskItemType = getNodeType(TaskItemNode.name, editor.schema); - const { title, textDirection } = node.attrs; + const { title, textDirection, readonly } = node.attrs; const [stats, setStats] = useState({ checked: 0, total: 0, percentage: 0 }); const getParent = useCallback(() => { @@ -49,6 +53,18 @@ export function TaskListComponent( return !!getParent(); }, [getParent]); + const isReadonly = useMemo(() => { + console.log("HEERE!"); + const isParentReadonly = + !!isNested && + !!pos && + !!findParentNodeClosestToPos( + editor.state.doc.resolve(pos), + (node) => node.type.name === TaskListNode.name && node.attrs.readonly + ); + return readonly || isParentReadonly; + }, [isNested, readonly, editor.state.doc, pos]); + useEffect(() => { const parent = getParent(); if (!parent) return; @@ -103,7 +119,7 @@ export function TaskListComponent( }} /> {editor.isEditable && ( <> + { + const pos = getPos(); + const node = editor.current?.state.doc.nodeAt(pos); + if (!node) return; + updateAttributes( + { readonly: !node.attrs.readonly }, + { addToHistory: true, preventUpdate: false } + ); + }} + /> element.dataset.readonly, + renderHTML: (attributes) => { + if (!attributes.readonly) { + return {}; + } + return { + "data-readonly": attributes.readonly + }; + } } }; }, diff --git a/packages/editor/src/toolbar/icons.ts b/packages/editor/src/toolbar/icons.ts index 6a5e1c3a9..6e7ed9654 100644 --- a/packages/editor/src/toolbar/icons.ts +++ b/packages/editor/src/toolbar/icons.ts @@ -115,7 +115,9 @@ import { mdiTableRowRemove, mdiTableSplitCell, mdiUploadOutline, - mdiWeb + mdiWeb, + mdiPencilOff, + mdiPencil } from "@mdi/js"; export const Icons = { @@ -239,6 +241,8 @@ export const Icons = { circle: mdiCircle, arrowLeft: mdiArrowLeft, resize: mdiResizeBottomRight, + readonlyOn: mdiPencilOff, + readonlyOff: mdiPencil, none: "" };