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,