refactor(toc): reorder according to purpose

This commit is contained in:
Elian Doran 2025-12-18 10:58:25 +02:00
parent 852398426e
commit 41751c205c
No known key found for this signature in database

View File

@ -9,16 +9,13 @@ import { useActiveNoteContext, useIsNoteReadOnly, useNoteProperty, useTextEditor
import Icon from "../react/Icon"; import Icon from "../react/Icon";
import RightPanelWidget from "./RightPanelWidget"; import RightPanelWidget from "./RightPanelWidget";
//#region Generic impl.
interface RawHeading { interface RawHeading {
id: string; id: string;
level: number; level: number;
text: string; text: string;
} }
interface CKHeading extends RawHeading {
element: ModelElement;
}
interface HeadingsWithNesting extends RawHeading { interface HeadingsWithNesting extends RawHeading {
children: HeadingsWithNesting[]; children: HeadingsWithNesting[];
} }
@ -35,38 +32,6 @@ export default function TableOfContents() {
); );
} }
function EditableTextTableOfContents() {
const { note, noteContext } = useActiveNoteContext();
const textEditor = useTextEditor(noteContext);
const [ headings, setHeadings ] = useState<CKHeading[]>([]);
useEffect(() => {
if (!textEditor) return;
const headings = extractTocFromTextEditor(textEditor);
// React to changes.
const changeCallback = () => {
const changes = textEditor.model.document.differ.getChanges();
const affectsHeadings = changes.some( change => {
return (
change.type === 'insert' || change.type === 'remove' || (change.type === 'attribute' && change.attributeKey === 'headingLevel')
);
});
if (affectsHeadings) {
setHeadings(extractTocFromTextEditor(textEditor));
}
};
textEditor.model.document.on("change:data", changeCallback);
setHeadings(headings);
return () => textEditor.model.document.off("change:data", changeCallback);
}, [ textEditor, note ]);
return <AbstractTableOfContents headings={headings} />;
}
function AbstractTableOfContents({ headings }: { function AbstractTableOfContents({ headings }: {
headings: RawHeading[]; headings: RawHeading[];
}) { }) {
@ -124,9 +89,47 @@ function buildHeadingTree(headings: RawHeading[]): HeadingsWithNesting[] {
return root.children; return root.children;
} }
//#endregion
//#region Editable text (CKEditor)
const TOC_ID = 'tocId'; const TOC_ID = 'tocId';
interface CKHeading extends RawHeading {
element: ModelElement;
}
function EditableTextTableOfContents() {
const { note, noteContext } = useActiveNoteContext();
const textEditor = useTextEditor(noteContext);
const [ headings, setHeadings ] = useState<CKHeading[]>([]);
useEffect(() => {
if (!textEditor) return;
const headings = extractTocFromTextEditor(textEditor);
// React to changes.
const changeCallback = () => {
const changes = textEditor.model.document.differ.getChanges();
const affectsHeadings = changes.some( change => {
return (
change.type === 'insert' || change.type === 'remove' || (change.type === 'attribute' && change.attributeKey === 'headingLevel')
);
});
if (affectsHeadings) {
setHeadings(extractTocFromTextEditor(textEditor));
}
};
textEditor.model.document.on("change:data", changeCallback);
setHeadings(headings);
return () => textEditor.model.document.off("change:data", changeCallback);
}, [ textEditor, note ]);
return <AbstractTableOfContents headings={headings} />;
}
function extractTocFromTextEditor(editor: CKTextEditor) { function extractTocFromTextEditor(editor: CKTextEditor) {
const headings: CKHeading[] = []; const headings: CKHeading[] = [];
@ -155,4 +158,4 @@ function extractTocFromTextEditor(editor: CKTextEditor) {
return headings; return headings;
} }
//#endregion