From 912e97dc3cf134526285374dbc2218f442658c68 Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Sat, 25 Feb 2023 11:56:48 +0500 Subject: [PATCH] editor: add button to sort task list --- .../src/extensions/task-list/component.tsx | 24 ++++++++++- .../editor/src/extensions/task-list/utils.ts | 41 +++++++++++++++++++ packages/editor/src/toolbar/icons.ts | 4 +- 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/packages/editor/src/extensions/task-list/component.tsx b/packages/editor/src/extensions/task-list/component.tsx index 609a0fbcc..e2cb1f762 100644 --- a/packages/editor/src/extensions/task-list/component.tsx +++ b/packages/editor/src/extensions/task-list/component.tsx @@ -19,7 +19,6 @@ along with this program. If not, see . import { Box, Flex, Input, Text } from "@theme-ui/components"; import { findChildren, getNodeType } from "@tiptap/core"; -import TaskItem from "@tiptap/extension-task-item"; import { Node } from "prosemirror-model"; import { useCallback, useEffect, useMemo, useState } from "react"; import { ToolButton } from "../../toolbar/components/tool-button"; @@ -27,7 +26,7 @@ import { findParentNodeOfTypeClosestToPos } from "../../utils/prosemirror"; import { ReactNodeViewProps } from "../react"; import { TaskItemNode } from "../task-item"; import { TaskListAttributes } from "./task-list"; -import { countCheckedItems, deleteCheckedItems } from "./utils"; +import { countCheckedItems, deleteCheckedItems, sortList } from "./utils"; export function TaskListComponent( props: ReactNodeViewProps @@ -120,6 +119,26 @@ export function TaskListComponent( }} /> {editor.isEditable && ( + <> + { + const pos = getPos(); + editor.current + ?.chain() + .focus() + .command(({ tr }) => { + return !!sortList(tr, pos); + }) + .run(); + }} + /> + )} { + if (node.type.name === TaskList.name) + sublists.push({ node, pos: pos + nodePos + 1 }); + }); + if (sublists.length > 1) sublists.reverse(); + sublists.push(parent); + + for (const list of sublists) { + const children: { + checked: number; + index: number; + }[] = []; + + list.node.forEach((node, _, index) => { + children.push({ + index, + checked: node.attrs.checked ? 1 : 0 + }); + }); + + tr.replaceWith( + tr.mapping.map(list.pos), + tr.mapping.map(list.pos + list.node.nodeSize), + Fragment.from( + children + .sort((a, b) => a.checked - b.checked) + .map((c) => list.node.child(c.index)) + ) + ); + } + + if (!tr.steps.length) return null; + return tr; +} diff --git a/packages/editor/src/toolbar/icons.ts b/packages/editor/src/toolbar/icons.ts index 71b35dfc7..035072961 100644 --- a/packages/editor/src/toolbar/icons.ts +++ b/packages/editor/src/toolbar/icons.ts @@ -112,7 +112,8 @@ import { mdiNewspaper, mdiFullscreen, mdiWeb, - mdiPageNextOutline + mdiPageNextOutline, + mdiSortBoolAscendingVariant } from "@mdi/js"; export const Icons = { @@ -190,6 +191,7 @@ export const Icons = { borderColor: "M4 24q-.825 0-1.412-.587Q2 22.825 2 22q0-.825.588-1.413Q3.175 20 4 20h16q.825 0 1.413.587Q22 21.175 22 22q0 .825-.587 1.413Q20.825 24 20 24Zm1-6q-.425 0-.713-.288Q4 17.425 4 17v-2.325q0-.2.075-.388q.075-.187.225-.337l8.75-8.75l3.75 3.75l-8.75 8.75q-.15.15-.337.225q-.188.075-.388.075Zm1-2h.9L14 8.95L13.05 8L6 15.1Zm11.925-8.15l-3.75-3.75l1.8-1.8q.275-.3.7-.288q.425.013.7.288l2.35 2.35q.275.275.275.688q0 .412-.275.712ZM6 16Z", sortDesc: mdiSortDescending, + sortTaskList: mdiSortBoolAscendingVariant, deleteTable: mdiTableOff, mergeCells: mdiTableMergeCells, splitCells: mdiTableSplitCell,