smartrte-react 0.3.5 → 1.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +106 -14
- package/dist/adapters/domChecklistCommandBridge.js +1 -1
- package/dist/adapters/domCommandBridge.d.ts +2 -2
- package/dist/adapters/domCommandBridge.js +2 -2
- package/dist/adapters/domInlineAtomCommandBridge.d.ts +10 -9
- package/dist/adapters/domInlineAtomCommandBridge.js +154 -50
- package/dist/adapters/domInlineImageCommandBridge.d.ts +7 -7
- package/dist/adapters/domInlineImageCommandBridge.js +6 -72
- package/dist/adapters/domMoveCommandBridge.js +1 -1
- package/dist/adapters/domSelectionBridge.d.ts +3 -3
- package/dist/adapters/domSmartDocument.d.ts +4 -4
- package/dist/adapters/domSmartDocument.js +2 -2
- package/dist/adapters/domTableCommandBridge.d.ts +42 -16
- package/dist/adapters/domTableCommandBridge.js +203 -173
- package/dist/adapters/internalFlags.d.ts +0 -8
- package/dist/adapters/internalFlags.js +0 -24
- package/dist/adapters/legacyListShadowComparator.d.ts +1 -1
- package/dist/adapters/legacyListShadowComparator.js +1 -1
- package/dist/adapters/pdfPrint.d.ts +8 -0
- package/dist/adapters/pdfPrint.js +22 -0
- package/dist/adapters/shadowMode.d.ts +3 -3
- package/dist/adapters/shadowMode.js +1 -1
- package/dist/canonicalEditorRuntime.d.ts +53 -1
- package/dist/canonicalEditorRuntime.js +61 -4
- package/dist/capabilityPresets.d.ts +27 -0
- package/dist/capabilityPresets.js +21 -0
- package/dist/collabTransport.d.ts +66 -0
- package/dist/collabTransport.js +1 -0
- package/dist/commentProvider.d.ts +24 -0
- package/dist/commentProvider.js +1 -0
- package/dist/components/CanonicalAuthorityEditor.d.ts +35 -1
- package/dist/components/CanonicalAuthorityEditor.js +1086 -112
- package/dist/components/ClassicEditorAuthority.d.ts +93 -22
- package/dist/components/ClassicEditorAuthority.js +11 -43
- package/dist/components/ColorPickerPopover.d.ts +39 -0
- package/dist/components/ColorPickerPopover.js +285 -0
- package/dist/components/CommentMarkers.d.ts +25 -0
- package/dist/components/CommentMarkers.js +105 -0
- package/dist/components/CommentThreadPanel.d.ts +26 -0
- package/dist/components/CommentThreadPanel.js +47 -0
- package/dist/components/ContextMenu.d.ts +23 -0
- package/dist/components/ContextMenu.js +141 -0
- package/dist/components/FormulaLibraryPopover.d.ts +16 -0
- package/dist/components/FormulaLibraryPopover.js +107 -0
- package/dist/components/LinkEditorPopover.d.ts +3 -1
- package/dist/components/LinkEditorPopover.js +22 -6
- package/dist/components/MediaManager.d.ts +4 -20
- package/dist/components/MediaManager.js +35 -6
- package/dist/components/MediaOverlay.d.ts +36 -0
- package/dist/components/MediaOverlay.js +163 -0
- package/dist/components/SpecialCharacterPopover.d.ts +18 -0
- package/dist/components/SpecialCharacterPopover.js +99 -0
- package/dist/components/StructuralSuggestionMarkers.d.ts +20 -0
- package/dist/components/StructuralSuggestionMarkers.js +56 -0
- package/dist/components/SuggestionPanel.d.ts +26 -0
- package/dist/components/SuggestionPanel.js +33 -0
- package/dist/components/TableBorderPopover.d.ts +59 -0
- package/dist/components/TableBorderPopover.js +147 -0
- package/dist/components/TableResizeHandles.d.ts +25 -0
- package/dist/components/TableResizeHandles.js +301 -0
- package/dist/components/TableSizePickerPopover.d.ts +16 -0
- package/dist/components/TableSizePickerPopover.js +126 -0
- package/dist/components/ToolbarPrimitives.d.ts +129 -0
- package/dist/components/ToolbarPrimitives.js +146 -0
- package/dist/components/VersionHistoryPanel.d.ts +9 -0
- package/dist/components/VersionHistoryPanel.js +157 -0
- package/dist/formulaLibrary.d.ts +31 -0
- package/dist/formulaLibrary.js +90 -0
- package/dist/index.d.ts +22 -24
- package/dist/index.js +14 -11
- package/dist/mediaManagerAdapter.d.ts +12 -0
- package/dist/mediaManagerAdapter.js +34 -0
- package/dist/mediaProvider.d.ts +21 -1
- package/dist/specialCharacters.d.ts +22 -0
- package/dist/specialCharacters.js +86 -0
- package/dist/standalone/classic-editor-embed.js +19 -12
- package/dist/suggestionProvider.d.ts +17 -0
- package/dist/suggestionProvider.js +1 -0
- package/dist/theme.d.ts +1 -1
- package/dist/theme.js +150 -20
- package/dist/versionProvider.d.ts +29 -0
- package/dist/versionProvider.js +1 -0
- package/package.json +28 -14
- package/dist/adapters/canonicalInlineCommandBridge.d.ts +0 -15
- package/dist/adapters/canonicalInlineCommandBridge.js +0 -269
- package/dist/adapters/canonicalListCommandBridge.d.ts +0 -26
- package/dist/adapters/canonicalListCommandBridge.js +0 -430
- package/dist/adapters/coreBold.d.ts +0 -5
- package/dist/adapters/coreBold.js +0 -3
- package/dist/adapters/documentFormats.d.ts +0 -26
- package/dist/adapters/documentFormats.js +0 -49
- package/dist/adapters/docxFormat.d.ts +0 -5
- package/dist/adapters/docxFormat.js +0 -272
- package/dist/adapters/domBlockCommandBridge.d.ts +0 -19
- package/dist/adapters/domBlockCommandBridge.js +0 -79
- package/dist/adapters/inlineMarkCoreExecution.d.ts +0 -9
- package/dist/adapters/inlineMarkCoreExecution.js +0 -25
- package/dist/adapters/pdfFormat.d.ts +0 -23
- package/dist/adapters/pdfFormat.js +0 -204
- package/dist/adapters/portableDocxAtoms.d.ts +0 -4
- package/dist/adapters/portableDocxAtoms.js +0 -58
- package/dist/adapters/styledDocxFormat.d.ts +0 -8
- package/dist/adapters/styledDocxFormat.js +0 -190
- package/dist/builtInFormatDefinitions.d.ts +0 -5
- package/dist/builtInFormatDefinitions.js +0 -82
- package/dist/canonicalAuthorityFlag.d.ts +0 -32
- package/dist/canonicalAuthorityFlag.js +0 -49
- package/dist/canonicalClipboardRuntime.d.ts +0 -15
- package/dist/canonicalClipboardRuntime.js +0 -76
- package/dist/components/ClassicEditor.d.ts +0 -76
- package/dist/components/ClassicEditor.js +0 -6729
- package/dist/editorController.d.ts +0 -78
- package/dist/editorController.js +0 -298
- package/dist/formatFidelity.d.ts +0 -14
- package/dist/formatFidelity.js +0 -107
- package/dist/formatRuntime.d.ts +0 -50
- package/dist/formatRuntime.js +0 -20
- package/dist/pluginRuntime.d.ts +0 -68
- package/dist/pluginRuntime.js +0 -78
- package/dist/standalone/editor.js +0 -1068
- package/dist/test-harness/atomShadowComparator.d.ts +0 -14
- package/dist/test-harness/atomShadowComparator.js +0 -63
- package/dist/test-harness/blockShadowComparator.d.ts +0 -30
- package/dist/test-harness/blockShadowComparator.js +0 -140
- package/dist/test-harness/clipboardShadowComparator.d.ts +0 -12
- package/dist/test-harness/clipboardShadowComparator.js +0 -46
- package/dist/test-harness/inlineShadowComparator.d.ts +0 -32
- package/dist/test-harness/inlineShadowComparator.js +0 -152
- package/dist/test-harness/legacyAtomEngine.d.ts +0 -10
- package/dist/test-harness/legacyAtomEngine.js +0 -15
- package/dist/test-harness/legacyBlockEngine.d.ts +0 -31
- package/dist/test-harness/legacyBlockEngine.js +0 -31
- package/dist/test-harness/legacyClipboardEngine.d.ts +0 -14
- package/dist/test-harness/legacyClipboardEngine.js +0 -67
- package/dist/test-harness/legacyInlineEngine.d.ts +0 -19
- package/dist/test-harness/legacyInlineEngine.js +0 -49
- package/dist/test-harness/legacyTableEngine.d.ts +0 -12
- package/dist/test-harness/legacyTableEngine.js +0 -25
- package/dist/test-harness/tableShadowComparator.d.ts +0 -29
- package/dist/test-harness/tableShadowComparator.js +0 -101
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export declare const toolbarIcons: {
|
|
3
|
+
readonly bold: import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
readonly italic: import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
readonly underline: import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
readonly strikethrough: import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
readonly code: import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
readonly superscript: import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
readonly subscript: import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
readonly textColor: import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
readonly backgroundColor: import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
readonly fontSize: import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
readonly fontFamily: import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
readonly paragraphStyle: import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
readonly alignLeft: import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
readonly alignCenter: import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
readonly alignRight: import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
readonly alignJustify: import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
readonly quote: import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
readonly moveUp: import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
readonly moveDown: import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
readonly moveLeft: import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
readonly moveRight: import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
readonly indent: import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
readonly outdent: import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
readonly link: import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
readonly unlink: import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
readonly bulletedList: import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
readonly numberedList: import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
readonly checklist: import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
readonly checkSquare: import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
readonly restart: import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
readonly continueNumbering: import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
readonly table: import("react/jsx-runtime").JSX.Element;
|
|
35
|
+
readonly mergeCells: import("react/jsx-runtime").JSX.Element;
|
|
36
|
+
readonly splitCell: import("react/jsx-runtime").JSX.Element;
|
|
37
|
+
readonly addRow: import("react/jsx-runtime").JSX.Element;
|
|
38
|
+
readonly addColumn: import("react/jsx-runtime").JSX.Element;
|
|
39
|
+
readonly headerRow: import("react/jsx-runtime").JSX.Element;
|
|
40
|
+
readonly deleteTable: import("react/jsx-runtime").JSX.Element;
|
|
41
|
+
readonly image: import("react/jsx-runtime").JSX.Element;
|
|
42
|
+
readonly video: import("react/jsx-runtime").JSX.Element;
|
|
43
|
+
readonly audio: import("react/jsx-runtime").JSX.Element;
|
|
44
|
+
readonly formula: import("react/jsx-runtime").JSX.Element;
|
|
45
|
+
readonly specialChar: import("react/jsx-runtime").JSX.Element;
|
|
46
|
+
readonly cellBorder: import("react/jsx-runtime").JSX.Element;
|
|
47
|
+
readonly edit: import("react/jsx-runtime").JSX.Element;
|
|
48
|
+
readonly zoomIn: import("react/jsx-runtime").JSX.Element;
|
|
49
|
+
readonly zoomOut: import("react/jsx-runtime").JSX.Element;
|
|
50
|
+
readonly delete: import("react/jsx-runtime").JSX.Element;
|
|
51
|
+
readonly import: import("react/jsx-runtime").JSX.Element;
|
|
52
|
+
readonly saveCopy: import("react/jsx-runtime").JSX.Element;
|
|
53
|
+
readonly json: import("react/jsx-runtime").JSX.Element;
|
|
54
|
+
readonly history: import("react/jsx-runtime").JSX.Element;
|
|
55
|
+
readonly addComment: import("react/jsx-runtime").JSX.Element;
|
|
56
|
+
readonly comments: import("react/jsx-runtime").JSX.Element;
|
|
57
|
+
readonly suggest: import("react/jsx-runtime").JSX.Element;
|
|
58
|
+
readonly suggestions: import("react/jsx-runtime").JSX.Element;
|
|
59
|
+
readonly showEdits: import("react/jsx-runtime").JSX.Element;
|
|
60
|
+
readonly undo: import("react/jsx-runtime").JSX.Element;
|
|
61
|
+
readonly redo: import("react/jsx-runtime").JSX.Element;
|
|
62
|
+
readonly more: import("react/jsx-runtime").JSX.Element;
|
|
63
|
+
};
|
|
64
|
+
export type ToolbarIconKey = keyof typeof toolbarIcons;
|
|
65
|
+
/** A single always-visible toolbar control: icon + plain-language label together, per the redesign's core principle. */
|
|
66
|
+
export declare function ToolbarButton({ icon, label, ariaLabel, pressed, disabled, title, onClick, iconOnly, widePromote }: {
|
|
67
|
+
icon: ToolbarIconKey;
|
|
68
|
+
label: string;
|
|
69
|
+
ariaLabel?: string;
|
|
70
|
+
/** "mixed" renders aria-pressed="mixed" - the selection is partially covered by this mark (see markCoverage in CanonicalAuthorityEditor.tsx). */
|
|
71
|
+
pressed?: boolean | "mixed";
|
|
72
|
+
disabled?: boolean;
|
|
73
|
+
title?: string;
|
|
74
|
+
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
|
75
|
+
/** Only for genuinely space-constrained spots (e.g. a 4-way align cluster) - the accessible name is preserved via ariaLabel/label regardless. */
|
|
76
|
+
iconOnly?: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* This is the wide-viewport standalone copy of a tool that also lives in a
|
|
79
|
+
* dropdown (via the matching `widePromote` ToolbarMenuItem below) - hidden
|
|
80
|
+
* by default, shown only past theme.ts's wide-promotion breakpoint. See
|
|
81
|
+
* docs/bugs/toolbar-priority-collapse-fixed-threshold-no-wide-promotion.md.
|
|
82
|
+
*/
|
|
83
|
+
widePromote?: boolean;
|
|
84
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
85
|
+
/** One row inside an open dropdown menu - closes the dropdown after acting, matching ContextMenu.tsx's own dismiss-on-action convention. */
|
|
86
|
+
export declare function ToolbarMenuItem({ icon, label, ariaLabel, pressed, disabled, title, onClick, widePromote }: {
|
|
87
|
+
icon?: ToolbarIconKey;
|
|
88
|
+
label: string;
|
|
89
|
+
ariaLabel?: string;
|
|
90
|
+
pressed?: boolean | "mixed";
|
|
91
|
+
disabled?: boolean;
|
|
92
|
+
title?: string;
|
|
93
|
+
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
|
94
|
+
/** This tool also has a standalone wide-viewport ToolbarButton copy - hide this dropdown/mobile-menu row once that copy is showing (see ToolbarButton's own doc comment). */
|
|
95
|
+
widePromote?: boolean;
|
|
96
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
97
|
+
/**
|
|
98
|
+
* A labeled dropdown for a group's long-tail tools - wires up the
|
|
99
|
+
* `.srte-toolbar-menu`/`.srte-menu` CSS `theme.ts` already defines but the
|
|
100
|
+
* pre-redesign toolbar never used. `<details>/<summary>` gives free
|
|
101
|
+
* keyboard support (Enter/Space to open, native focus handling) without a
|
|
102
|
+
* new open/close state to manage; outside-click dismiss is handled by
|
|
103
|
+
* useDismissDetailsOnOutsideClick above.
|
|
104
|
+
*/
|
|
105
|
+
export declare function ToolbarDropdown({ icon, label, priority, children }: {
|
|
106
|
+
icon?: ToolbarIconKey;
|
|
107
|
+
label: string;
|
|
108
|
+
/** Mirrors theme.ts's `[data-srte-priority]` responsive rules - 2 collapses into the mobile "More" menu before 1 (never collapses), leaving priority 3 whole *groups* to collapse first. */
|
|
109
|
+
priority?: 2;
|
|
110
|
+
children: React.ReactNode;
|
|
111
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
112
|
+
/** A visually-separated cluster of controls, optionally collapsing as a whole unit on narrow viewports (theme.ts's `.srte-toolbar-group[data-srte-priority="3"]`). */
|
|
113
|
+
export declare function ToolbarGroup({ priority, children }: {
|
|
114
|
+
priority?: 3;
|
|
115
|
+
children: React.ReactNode;
|
|
116
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
117
|
+
/**
|
|
118
|
+
* The narrow-viewport overflow trigger - `.srte-mobile-more` is CSS-hidden
|
|
119
|
+
* except under theme.ts's `max-width: 639px` rules, which also hide every
|
|
120
|
+
* `[data-srte-priority="2"]`/`[data-srte-priority="3"]` element. Its own
|
|
121
|
+
* menu statically lists every tool that lives inside one of those
|
|
122
|
+
* collapsing dropdowns/groups, so nothing becomes unreachable once the
|
|
123
|
+
* primary row starts shedding groups - this is plain CSS visibility
|
|
124
|
+
* toggling of pre-rendered content, not JS media-query logic, matching how
|
|
125
|
+
* the rest of this responsive system already works.
|
|
126
|
+
*/
|
|
127
|
+
export declare function MobileMoreMenu({ children }: {
|
|
128
|
+
children: React.ReactNode;
|
|
129
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef } from "react";
|
|
3
|
+
import { AlignCenter, AlignJustify, AlignLeft, AlignRight, ALargeSmall, Baseline, Bold, CheckSquare, ChevronDown, Code, Columns3, Download, Eye, FileJson, History, Image as ImageIcon, IndentDecrease, IndentIncrease, Italic, Link2, ListChecks, ListOrdered, ListRestart, List as ListIcon, MessageSquare, MessageSquarePlus, MoreHorizontal, MoveDown, MoveLeft, MoveRight, MoveUp, Music, Omega, PanelTop, PenLine, Pilcrow, Quote, Redo2, Rows3, Square, Sigma, Strikethrough, Subscript, Superscript, Table2, Trash2, Type, Underline, Undo2, Unlink2, Upload, Video, Pencil, ZoomIn, ZoomOut, } from "lucide-react";
|
|
4
|
+
/**
|
|
5
|
+
* The toolbar's icon set (Phase: Direction B toolbar redesign, 2026-08-29).
|
|
6
|
+
* Lucide, per the design proposal's §11 recommendation - MIT-licensed,
|
|
7
|
+
* tree-shakeable (only these ~40 icons ship), a consistent stroke style
|
|
8
|
+
* that reads at the toolbar's small render size. Two icons here
|
|
9
|
+
* (mergeCells/splitCell) have no Lucide equivalent and are hand-drawn to
|
|
10
|
+
* match Lucide's own stroke weight/corner radius - the "grid + directional
|
|
11
|
+
* arrow" concept the owner confirmed from the proposal's two alternatives.
|
|
12
|
+
*/
|
|
13
|
+
const stroke = { width: 17, height: 17, strokeWidth: 1.9 };
|
|
14
|
+
const MergeCellsIcon = () => (_jsxs("svg", { width: "17", height: "17", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.9", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("rect", { x: "3", y: "4", width: "18", height: "16", rx: "2" }), _jsx("line", { x1: "15", y1: "4", x2: "15", y2: "20" }), _jsx("path", { d: "M6 12h5" }), _jsx("polyline", { points: "9 9 12 12 9 15" })] }));
|
|
15
|
+
const SplitCellIcon = () => (_jsxs("svg", { width: "17", height: "17", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.9", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("rect", { x: "3", y: "4", width: "18", height: "16", rx: "2" }), _jsx("line", { x1: "9", y1: "4", x2: "9", y2: "20" }), _jsx("path", { d: "M18 9v6" }), _jsx("polyline", { points: "20 10.5 18 12 20 13.5" }), _jsx("polyline", { points: "16 10.5 18 12 16 13.5" })] }));
|
|
16
|
+
export const toolbarIcons = {
|
|
17
|
+
bold: _jsx(Bold, { ...stroke }),
|
|
18
|
+
italic: _jsx(Italic, { ...stroke }),
|
|
19
|
+
underline: _jsx(Underline, { ...stroke }),
|
|
20
|
+
strikethrough: _jsx(Strikethrough, { ...stroke }),
|
|
21
|
+
code: _jsx(Code, { ...stroke }),
|
|
22
|
+
superscript: _jsx(Superscript, { ...stroke }),
|
|
23
|
+
subscript: _jsx(Subscript, { ...stroke }),
|
|
24
|
+
textColor: _jsx(Baseline, { ...stroke }),
|
|
25
|
+
backgroundColor: _jsx(PenLine, { ...stroke }),
|
|
26
|
+
fontSize: _jsx(ALargeSmall, { ...stroke }),
|
|
27
|
+
fontFamily: _jsx(Type, { ...stroke }),
|
|
28
|
+
paragraphStyle: _jsx(Pilcrow, { ...stroke }),
|
|
29
|
+
alignLeft: _jsx(AlignLeft, { ...stroke }),
|
|
30
|
+
alignCenter: _jsx(AlignCenter, { ...stroke }),
|
|
31
|
+
alignRight: _jsx(AlignRight, { ...stroke }),
|
|
32
|
+
alignJustify: _jsx(AlignJustify, { ...stroke }),
|
|
33
|
+
quote: _jsx(Quote, { ...stroke }),
|
|
34
|
+
moveUp: _jsx(MoveUp, { ...stroke }),
|
|
35
|
+
moveDown: _jsx(MoveDown, { ...stroke }),
|
|
36
|
+
moveLeft: _jsx(MoveLeft, { ...stroke }),
|
|
37
|
+
moveRight: _jsx(MoveRight, { ...stroke }),
|
|
38
|
+
indent: _jsx(IndentIncrease, { ...stroke }),
|
|
39
|
+
outdent: _jsx(IndentDecrease, { ...stroke }),
|
|
40
|
+
link: _jsx(Link2, { ...stroke }),
|
|
41
|
+
unlink: _jsx(Unlink2, { ...stroke }),
|
|
42
|
+
bulletedList: _jsx(ListIcon, { ...stroke }),
|
|
43
|
+
numberedList: _jsx(ListOrdered, { ...stroke }),
|
|
44
|
+
checklist: _jsx(ListChecks, { ...stroke }),
|
|
45
|
+
checkSquare: _jsx(CheckSquare, { ...stroke }),
|
|
46
|
+
restart: _jsx(ListRestart, { ...stroke }),
|
|
47
|
+
continueNumbering: _jsx(Rows3, { ...stroke }),
|
|
48
|
+
table: _jsx(Table2, { ...stroke }),
|
|
49
|
+
mergeCells: _jsx(MergeCellsIcon, {}),
|
|
50
|
+
splitCell: _jsx(SplitCellIcon, {}),
|
|
51
|
+
addRow: _jsx(Rows3, { ...stroke }),
|
|
52
|
+
addColumn: _jsx(Columns3, { ...stroke }),
|
|
53
|
+
headerRow: _jsx(PanelTop, { ...stroke }),
|
|
54
|
+
deleteTable: _jsx(Trash2, { ...stroke }),
|
|
55
|
+
image: _jsx(ImageIcon, { ...stroke }),
|
|
56
|
+
video: _jsx(Video, { ...stroke }),
|
|
57
|
+
audio: _jsx(Music, { ...stroke }),
|
|
58
|
+
formula: _jsx(Sigma, { ...stroke }),
|
|
59
|
+
specialChar: _jsx(Omega, { ...stroke }),
|
|
60
|
+
cellBorder: _jsx(Square, { ...stroke }),
|
|
61
|
+
edit: _jsx(Pencil, { ...stroke }),
|
|
62
|
+
zoomIn: _jsx(ZoomIn, { ...stroke }),
|
|
63
|
+
zoomOut: _jsx(ZoomOut, { ...stroke }),
|
|
64
|
+
delete: _jsx(Trash2, { ...stroke }),
|
|
65
|
+
import: _jsx(Upload, { ...stroke }),
|
|
66
|
+
saveCopy: _jsx(Download, { ...stroke }),
|
|
67
|
+
json: _jsx(FileJson, { ...stroke }),
|
|
68
|
+
history: _jsx(History, { ...stroke }),
|
|
69
|
+
addComment: _jsx(MessageSquarePlus, { ...stroke }),
|
|
70
|
+
comments: _jsx(MessageSquare, { ...stroke }),
|
|
71
|
+
suggest: _jsx(PenLine, { ...stroke }),
|
|
72
|
+
suggestions: _jsx(MessageSquare, { ...stroke }),
|
|
73
|
+
showEdits: _jsx(Eye, { ...stroke }),
|
|
74
|
+
undo: _jsx(Undo2, { ...stroke }),
|
|
75
|
+
redo: _jsx(Redo2, { ...stroke }),
|
|
76
|
+
more: _jsx(MoreHorizontal, { ...stroke }),
|
|
77
|
+
};
|
|
78
|
+
/** A single always-visible toolbar control: icon + plain-language label together, per the redesign's core principle. */
|
|
79
|
+
export function ToolbarButton({ icon, label, ariaLabel, pressed, disabled, title, onClick, iconOnly, widePromote }) {
|
|
80
|
+
return _jsxs("button", { type: "button", className: "srte-tool-button", "aria-label": ariaLabel ?? label, "aria-pressed": pressed, title: title ?? ariaLabel ?? label, disabled: disabled, onMouseDown: (event) => event.preventDefault(), onClick: onClick, ...(widePromote ? { "data-srte-wide-promote": "true" } : {}), children: [toolbarIcons[icon], !iconOnly && _jsx("span", { children: label })] });
|
|
81
|
+
}
|
|
82
|
+
/** One row inside an open dropdown menu - closes the dropdown after acting, matching ContextMenu.tsx's own dismiss-on-action convention. */
|
|
83
|
+
export function ToolbarMenuItem({ icon, label, ariaLabel, pressed, disabled, title, onClick, widePromote }) {
|
|
84
|
+
return _jsxs("button", { type: "button", className: "srte-menu-item", role: "menuitem", "aria-label": ariaLabel ?? label, "aria-pressed": pressed, title: title, disabled: disabled, onMouseDown: (event) => event.preventDefault(), onClick: (event) => {
|
|
85
|
+
onClick(event);
|
|
86
|
+
event.currentTarget.closest("details")?.removeAttribute("open");
|
|
87
|
+
}, ...(widePromote ? { "data-srte-wide-promote": "true" } : {}), children: [icon ? toolbarIcons[icon] : null, _jsx("span", { children: label }), pressed === true && _jsx("span", { className: "srte-menu-check", "aria-hidden": "true", children: "\u2713" }), pressed === "mixed" && _jsx("span", { className: "srte-menu-check", "aria-hidden": "true", children: "~" })] });
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Closes an open `<details>` when the user clicks anywhere outside it -
|
|
91
|
+
* native `<details>` does *not* do this on its own (confirmed directly:
|
|
92
|
+
* unlike a real modal, it only ever closes via its own `<summary>` or a
|
|
93
|
+
* script setting `open = false`), so a dropdown left open and then clicked
|
|
94
|
+
* past straight into the editor previously just stayed open. Same
|
|
95
|
+
* pointerdown+mousedown, capture-phase, ref-read pattern as
|
|
96
|
+
* ContextMenu.tsx/ColorPickerPopover.tsx's own outside-click dismiss -
|
|
97
|
+
* mounted once for the element's lifetime regardless of open/closed state,
|
|
98
|
+
* since `<details>` (unlike those components) isn't unmounted when closed.
|
|
99
|
+
*/
|
|
100
|
+
const useDismissDetailsOnOutsideClick = (ref) => {
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
const dismissIfOutside = (event) => {
|
|
103
|
+
const el = ref.current;
|
|
104
|
+
if (el?.open && !el.contains(event.target))
|
|
105
|
+
el.removeAttribute("open");
|
|
106
|
+
};
|
|
107
|
+
window.addEventListener("pointerdown", dismissIfOutside, true);
|
|
108
|
+
window.addEventListener("mousedown", dismissIfOutside, true);
|
|
109
|
+
return () => {
|
|
110
|
+
window.removeEventListener("pointerdown", dismissIfOutside, true);
|
|
111
|
+
window.removeEventListener("mousedown", dismissIfOutside, true);
|
|
112
|
+
};
|
|
113
|
+
}, [ref]);
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* A labeled dropdown for a group's long-tail tools - wires up the
|
|
117
|
+
* `.srte-toolbar-menu`/`.srte-menu` CSS `theme.ts` already defines but the
|
|
118
|
+
* pre-redesign toolbar never used. `<details>/<summary>` gives free
|
|
119
|
+
* keyboard support (Enter/Space to open, native focus handling) without a
|
|
120
|
+
* new open/close state to manage; outside-click dismiss is handled by
|
|
121
|
+
* useDismissDetailsOnOutsideClick above.
|
|
122
|
+
*/
|
|
123
|
+
export function ToolbarDropdown({ icon, label, priority, children }) {
|
|
124
|
+
const detailsRef = useRef(null);
|
|
125
|
+
useDismissDetailsOnOutsideClick(detailsRef);
|
|
126
|
+
return _jsxs("details", { ref: detailsRef, className: "srte-toolbar-menu", ...(priority ? { "data-srte-priority": priority } : {}), children: [_jsxs("summary", { className: "srte-tool-button srte-menu-trigger", onMouseDown: (event) => event.preventDefault(), children: [icon ? toolbarIcons[icon] : null, _jsx("span", { children: label }), _jsx(ChevronDown, { width: 13, height: 13, strokeWidth: 2, "aria-hidden": "true" })] }), _jsx("div", { className: "srte-menu", role: "menu", children: children })] });
|
|
127
|
+
}
|
|
128
|
+
/** A visually-separated cluster of controls, optionally collapsing as a whole unit on narrow viewports (theme.ts's `.srte-toolbar-group[data-srte-priority="3"]`). */
|
|
129
|
+
export function ToolbarGroup({ priority, children }) {
|
|
130
|
+
return _jsx("span", { className: "srte-toolbar-group", ...(priority ? { "data-srte-priority": priority } : {}), children: children });
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* The narrow-viewport overflow trigger - `.srte-mobile-more` is CSS-hidden
|
|
134
|
+
* except under theme.ts's `max-width: 639px` rules, which also hide every
|
|
135
|
+
* `[data-srte-priority="2"]`/`[data-srte-priority="3"]` element. Its own
|
|
136
|
+
* menu statically lists every tool that lives inside one of those
|
|
137
|
+
* collapsing dropdowns/groups, so nothing becomes unreachable once the
|
|
138
|
+
* primary row starts shedding groups - this is plain CSS visibility
|
|
139
|
+
* toggling of pre-rendered content, not JS media-query logic, matching how
|
|
140
|
+
* the rest of this responsive system already works.
|
|
141
|
+
*/
|
|
142
|
+
export function MobileMoreMenu({ children }) {
|
|
143
|
+
const detailsRef = useRef(null);
|
|
144
|
+
useDismissDetailsOnOutsideClick(detailsRef);
|
|
145
|
+
return _jsxs("details", { ref: detailsRef, className: "srte-toolbar-menu srte-mobile-more", children: [_jsx("summary", { className: "srte-tool-button srte-menu-trigger", "aria-label": "More tools", onMouseDown: (event) => event.preventDefault(), children: toolbarIcons.more }), _jsx("div", { className: "srte-menu", role: "menu", children: children })] });
|
|
146
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { VersionProvider } from "../versionProvider.js";
|
|
2
|
+
import type { CanonicalEditorRuntime } from "../canonicalEditorRuntime.js";
|
|
3
|
+
export declare function VersionHistoryPanel(props: {
|
|
4
|
+
open: boolean;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
runtime: CanonicalEditorRuntime;
|
|
7
|
+
versionProvider: VersionProvider;
|
|
8
|
+
authorId?: string;
|
|
9
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { diffVersions, foundationSchema } from "smartrte-core/foundation";
|
|
4
|
+
const formatTimestamp = (createdAt) => new Date(createdAt).toLocaleString();
|
|
5
|
+
const summarize = (diff) => {
|
|
6
|
+
const parts = [
|
|
7
|
+
diff.added.length ? `${diff.added.length} added` : null,
|
|
8
|
+
diff.removed.length ? `${diff.removed.length} removed` : null,
|
|
9
|
+
diff.changed.length ? `${diff.changed.length} edited` : null,
|
|
10
|
+
].filter((part) => Boolean(part));
|
|
11
|
+
return parts.length ? parts.join(", ") : "No differences";
|
|
12
|
+
};
|
|
13
|
+
export function VersionHistoryPanel(props) {
|
|
14
|
+
const { open, onClose, runtime, versionProvider, authorId } = props;
|
|
15
|
+
const [versions, setVersions] = useState([]);
|
|
16
|
+
const [loading, setLoading] = useState(false);
|
|
17
|
+
const [error, setError] = useState(null);
|
|
18
|
+
const [label, setLabel] = useState("");
|
|
19
|
+
const [saving, setSaving] = useState(false);
|
|
20
|
+
const [busyId, setBusyId] = useState(null);
|
|
21
|
+
// Selecting two entries computes a diff summary between them - order is
|
|
22
|
+
// the order they were selected in, not list order, so "swap" reads
|
|
23
|
+
// naturally when a user picks the later one first.
|
|
24
|
+
const [compareIds, setCompareIds] = useState([]);
|
|
25
|
+
const [diffSummary, setDiffSummary] = useState(null);
|
|
26
|
+
const [diffLoading, setDiffLoading] = useState(false);
|
|
27
|
+
const refresh = async () => {
|
|
28
|
+
setLoading(true);
|
|
29
|
+
setError(null);
|
|
30
|
+
try {
|
|
31
|
+
setVersions([...(await versionProvider.list())].sort((a, b) => b.createdAt - a.createdAt));
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
setError("Failed to load version history.");
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
setLoading(false);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
if (!open)
|
|
42
|
+
return;
|
|
43
|
+
setError(null);
|
|
44
|
+
setCompareIds([]);
|
|
45
|
+
setDiffSummary(null);
|
|
46
|
+
void refresh();
|
|
47
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
48
|
+
}, [open]);
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (compareIds.length !== 2) {
|
|
51
|
+
setDiffSummary(null);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
let cancelled = false;
|
|
55
|
+
setDiffLoading(true);
|
|
56
|
+
(async () => {
|
|
57
|
+
try {
|
|
58
|
+
const [a, b] = await Promise.all(compareIds.map((id) => versionProvider.load(id)));
|
|
59
|
+
if (cancelled)
|
|
60
|
+
return;
|
|
61
|
+
setDiffSummary(summarize(diffVersions(a, b, foundationSchema)));
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
if (!cancelled)
|
|
65
|
+
setError("Failed to compare the selected versions.");
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
if (!cancelled)
|
|
69
|
+
setDiffLoading(false);
|
|
70
|
+
}
|
|
71
|
+
})();
|
|
72
|
+
return () => { cancelled = true; };
|
|
73
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
74
|
+
}, [compareIds]);
|
|
75
|
+
const handleSave = async () => {
|
|
76
|
+
setSaving(true);
|
|
77
|
+
setError(null);
|
|
78
|
+
try {
|
|
79
|
+
const version = runtime.saveVersion({ ...(label.trim() ? { label: label.trim() } : {}), ...(authorId ? { authorId } : {}) });
|
|
80
|
+
await versionProvider.save(version);
|
|
81
|
+
setLabel("");
|
|
82
|
+
await refresh();
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
setError("Failed to save this version.");
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
setSaving(false);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const handleRestore = async (entry) => {
|
|
92
|
+
setBusyId(entry.id);
|
|
93
|
+
setError(null);
|
|
94
|
+
try {
|
|
95
|
+
const target = await versionProvider.load(entry.id);
|
|
96
|
+
runtime.restoreVersion(target);
|
|
97
|
+
// Non-destructive restore (Phase 12a spec's explicit recommendation):
|
|
98
|
+
// record the restoration as a new, forward-moving version rather
|
|
99
|
+
// than silently rewriting/discarding anything - the version list
|
|
100
|
+
// only ever grows. Nothing between the current state and the
|
|
101
|
+
// restore target is ever deleted; every prior version, including
|
|
102
|
+
// whatever was live immediately before this restore, is still
|
|
103
|
+
// reachable by restoring to it directly.
|
|
104
|
+
const recorded = runtime.saveVersion({
|
|
105
|
+
label: `Restored: ${entry.label || formatTimestamp(entry.createdAt)}`,
|
|
106
|
+
...(authorId ? { authorId } : {}),
|
|
107
|
+
});
|
|
108
|
+
await versionProvider.save(recorded);
|
|
109
|
+
await refresh();
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
setError("Failed to restore this version.");
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
setBusyId(null);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const handleDelete = async (entry) => {
|
|
119
|
+
setBusyId(entry.id);
|
|
120
|
+
setError(null);
|
|
121
|
+
try {
|
|
122
|
+
await versionProvider.remove(entry.id);
|
|
123
|
+
setCompareIds((current) => current.filter((id) => id !== entry.id));
|
|
124
|
+
await refresh();
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
setError("Failed to delete this version.");
|
|
128
|
+
}
|
|
129
|
+
finally {
|
|
130
|
+
setBusyId(null);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
const toggleCompare = (id) => {
|
|
134
|
+
setCompareIds((current) => {
|
|
135
|
+
if (current.includes(id))
|
|
136
|
+
return current.filter((existing) => existing !== id);
|
|
137
|
+
if (current.length < 2)
|
|
138
|
+
return [...current, id];
|
|
139
|
+
return [current[1], id];
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
if (!open)
|
|
143
|
+
return null;
|
|
144
|
+
return (_jsx("div", { style: {
|
|
145
|
+
position: "fixed", inset: 0, background: "var(--srte-modal-backdrop)",
|
|
146
|
+
backdropFilter: "var(--srte-modal-backdrop-filter)", WebkitBackdropFilter: "var(--srte-modal-backdrop-filter)",
|
|
147
|
+
display: "flex", alignItems: "center", justifyContent: "center", zIndex: 80,
|
|
148
|
+
}, onClick: onClose, children: _jsxs("div", { role: "dialog", "aria-label": "Version history", "data-srte-version-history": "true", style: {
|
|
149
|
+
background: "var(--srte-modal-bg)", color: "var(--srte-modal-text)",
|
|
150
|
+
width: 560, maxWidth: "90vw", maxHeight: "86vh",
|
|
151
|
+
borderRadius: 10, boxShadow: "var(--srte-menu-shadow)",
|
|
152
|
+
display: "flex", flexDirection: "column",
|
|
153
|
+
}, onClick: (event) => event.stopPropagation(), children: [_jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", padding: "10px 14px", borderBottom: "1px solid var(--srte-border-light)" }, children: [_jsx("div", { style: { fontWeight: 600 }, children: "Version history" }), _jsx("button", { type: "button", "aria-label": "Close version history", onClick: onClose, children: "\u2715" })] }), error && _jsx("div", { style: { color: "var(--srte-danger)", padding: "8px 14px" }, children: error }), _jsxs("div", { style: { display: "flex", gap: 8, padding: "12px 14px", borderBottom: "1px solid var(--srte-border-light)" }, children: [_jsx("input", { value: label, onChange: (event) => setLabel(event.target.value), placeholder: "Label this version (optional)", style: { flex: 1, padding: "6px 8px", border: "1px solid var(--srte-border)", borderRadius: 6, background: "var(--srte-input-bg)", color: "var(--srte-input-text)" } }), _jsx("button", { type: "button", "data-srte-version-save": "true", disabled: saving, onClick: () => void handleSave(), children: saving ? "Saving…" : "Save version" })] }), compareIds.length === 2 && (_jsx("div", { style: { padding: "8px 14px", fontSize: 13, color: "var(--srte-text-muted)", borderBottom: "1px solid var(--srte-border-light)" }, "data-srte-version-diff-summary": "true", children: diffLoading ? "Comparing…" : diffSummary })), _jsxs("div", { style: { overflowY: "auto", padding: "8px 14px 14px" }, children: [loading && _jsx("div", { style: { color: "var(--srte-text-muted)", padding: "8px 0" }, children: "Loading\u2026" }), !loading && versions.length === 0 && _jsx("div", { style: { color: "var(--srte-text-muted)", padding: "8px 0" }, children: "No saved versions yet." }), versions.map((entry) => (_jsxs("div", { "data-srte-version-entry": entry.id, style: {
|
|
154
|
+
display: "flex", alignItems: "center", gap: 8, padding: "8px 0",
|
|
155
|
+
borderBottom: "1px solid var(--srte-border-light)",
|
|
156
|
+
}, children: [_jsx("input", { type: "checkbox", "aria-label": `Select ${entry.label || formatTimestamp(entry.createdAt)} for comparison`, checked: compareIds.includes(entry.id), onChange: () => toggleCompare(entry.id) }), _jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [_jsx("div", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: entry.label || "Untitled version" }), _jsx("div", { style: { fontSize: 11, color: "var(--srte-text-muted)" }, children: formatTimestamp(entry.createdAt) })] }), _jsx("button", { type: "button", "data-srte-version-restore": entry.id, disabled: busyId === entry.id, onClick: () => void handleRestore(entry), children: "Restore" }), _jsx("button", { type: "button", "data-srte-version-delete": entry.id, disabled: busyId === entry.id, onClick: () => void handleDelete(entry), style: { color: "var(--srte-danger)" }, children: "Delete" })] }, entry.id)))] })] }) }));
|
|
157
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formula library (Direction B "Small" scope, per the owner-approved
|
|
3
|
+
* proposal - see the "Formula Library & Special Character Picker" scoping
|
|
4
|
+
* artifact): a curated set of common science/math formulas, browsable by
|
|
5
|
+
* domain and searchable by name, replacing the raw `window.prompt`
|
|
6
|
+
* formula-insert flow.
|
|
7
|
+
*
|
|
8
|
+
* Every entry's `latex` is plain LaTeX, verified against KaTeX 0.18's
|
|
9
|
+
* supported command set (the actual rendering ceiling - see
|
|
10
|
+
* `surface/renderer.ts`'s `KATEX_OPTIONS`, `{ trust: false, strict: "error"
|
|
11
|
+
* }`). Chemistry entries use the `mhchem` extension's `\ce{...}` macro,
|
|
12
|
+
* registered in `surface/renderer.ts` (core) for real document rendering
|
|
13
|
+
* and in `FormulaLibraryPopover.tsx` for this library's own previews.
|
|
14
|
+
*
|
|
15
|
+
* `notation` is always `"latex"` - the schema also accepts `"mathml"`, but
|
|
16
|
+
* the renderer never implements a MathML render path
|
|
17
|
+
* (docs/bugs/formula-mathml-notation-not-rendered.md, open) - so no library
|
|
18
|
+
* entry may use it.
|
|
19
|
+
*/
|
|
20
|
+
export type FormulaDomain = "algebra" | "geometry" | "calculus" | "physics" | "chemistry" | "statistics";
|
|
21
|
+
export interface FormulaLibraryEntry {
|
|
22
|
+
readonly id: string;
|
|
23
|
+
readonly domain: FormulaDomain;
|
|
24
|
+
readonly name: string;
|
|
25
|
+
readonly latex: string;
|
|
26
|
+
}
|
|
27
|
+
export declare const FORMULA_DOMAINS: readonly {
|
|
28
|
+
readonly id: FormulaDomain;
|
|
29
|
+
readonly label: string;
|
|
30
|
+
}[];
|
|
31
|
+
export declare const FORMULA_LIBRARY: readonly FormulaLibraryEntry[];
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formula library (Direction B "Small" scope, per the owner-approved
|
|
3
|
+
* proposal - see the "Formula Library & Special Character Picker" scoping
|
|
4
|
+
* artifact): a curated set of common science/math formulas, browsable by
|
|
5
|
+
* domain and searchable by name, replacing the raw `window.prompt`
|
|
6
|
+
* formula-insert flow.
|
|
7
|
+
*
|
|
8
|
+
* Every entry's `latex` is plain LaTeX, verified against KaTeX 0.18's
|
|
9
|
+
* supported command set (the actual rendering ceiling - see
|
|
10
|
+
* `surface/renderer.ts`'s `KATEX_OPTIONS`, `{ trust: false, strict: "error"
|
|
11
|
+
* }`). Chemistry entries use the `mhchem` extension's `\ce{...}` macro,
|
|
12
|
+
* registered in `surface/renderer.ts` (core) for real document rendering
|
|
13
|
+
* and in `FormulaLibraryPopover.tsx` for this library's own previews.
|
|
14
|
+
*
|
|
15
|
+
* `notation` is always `"latex"` - the schema also accepts `"mathml"`, but
|
|
16
|
+
* the renderer never implements a MathML render path
|
|
17
|
+
* (docs/bugs/formula-mathml-notation-not-rendered.md, open) - so no library
|
|
18
|
+
* entry may use it.
|
|
19
|
+
*/
|
|
20
|
+
export const FORMULA_DOMAINS = [
|
|
21
|
+
{ id: "algebra", label: "Algebra" },
|
|
22
|
+
{ id: "geometry", label: "Geometry" },
|
|
23
|
+
{ id: "calculus", label: "Calculus" },
|
|
24
|
+
{ id: "physics", label: "Physics" },
|
|
25
|
+
{ id: "chemistry", label: "Chemistry" },
|
|
26
|
+
{ id: "statistics", label: "Statistics" },
|
|
27
|
+
];
|
|
28
|
+
export const FORMULA_LIBRARY = [
|
|
29
|
+
// Algebra
|
|
30
|
+
{ id: "algebra-quadratic", domain: "algebra", name: "Quadratic formula", latex: "x = \\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}" },
|
|
31
|
+
{ id: "algebra-binomial-sum-sq", domain: "algebra", name: "Square of a sum", latex: "(a+b)^2 = a^2 + 2ab + b^2" },
|
|
32
|
+
{ id: "algebra-binomial-diff-sq", domain: "algebra", name: "Square of a difference", latex: "(a-b)^2 = a^2 - 2ab + b^2" },
|
|
33
|
+
{ id: "algebra-diff-of-squares", domain: "algebra", name: "Difference of squares", latex: "a^2 - b^2 = (a+b)(a-b)" },
|
|
34
|
+
{ id: "algebra-exponent-product", domain: "algebra", name: "Exponent product rule", latex: "a^m \\cdot a^n = a^{m+n}" },
|
|
35
|
+
{ id: "algebra-exponent-power", domain: "algebra", name: "Exponent power rule", latex: "(a^m)^n = a^{mn}" },
|
|
36
|
+
{ id: "algebra-log-product", domain: "algebra", name: "Logarithm product rule", latex: "\\log_a(xy) = \\log_a x + \\log_a y" },
|
|
37
|
+
{ id: "algebra-log-quotient", domain: "algebra", name: "Logarithm quotient rule", latex: "\\log_a\\left(\\frac{x}{y}\\right) = \\log_a x - \\log_a y" },
|
|
38
|
+
{ id: "algebra-binomial-theorem", domain: "algebra", name: "Binomial theorem", latex: "(x+y)^n = \\sum_{k=0}^{n} \\binom{n}{k} x^{n-k} y^k" },
|
|
39
|
+
{ id: "algebra-vertex", domain: "algebra", name: "Vertex of a parabola", latex: "x = -\\frac{b}{2a}" },
|
|
40
|
+
// Geometry
|
|
41
|
+
{ id: "geometry-circle-area", domain: "geometry", name: "Circle area", latex: "A = \\pi r^2" },
|
|
42
|
+
{ id: "geometry-circle-circumference", domain: "geometry", name: "Circle circumference", latex: "C = 2\\pi r" },
|
|
43
|
+
{ id: "geometry-triangle-area", domain: "geometry", name: "Triangle area", latex: "A = \\frac{1}{2}bh" },
|
|
44
|
+
{ id: "geometry-sphere-volume", domain: "geometry", name: "Sphere volume", latex: "V = \\frac{4}{3}\\pi r^3" },
|
|
45
|
+
{ id: "geometry-sphere-surface", domain: "geometry", name: "Sphere surface area", latex: "A = 4\\pi r^2" },
|
|
46
|
+
{ id: "geometry-cylinder-volume", domain: "geometry", name: "Cylinder volume", latex: "V = \\pi r^2 h" },
|
|
47
|
+
{ id: "geometry-cone-volume", domain: "geometry", name: "Cone volume", latex: "V = \\frac{1}{3}\\pi r^2 h" },
|
|
48
|
+
{ id: "geometry-pythagorean", domain: "geometry", name: "Pythagorean theorem", latex: "a^2 + b^2 = c^2" },
|
|
49
|
+
{ id: "geometry-box-volume", domain: "geometry", name: "Rectangular box volume", latex: "V = lwh" },
|
|
50
|
+
{ id: "geometry-trapezoid-area", domain: "geometry", name: "Trapezoid area", latex: "A = \\frac{1}{2}(b_1+b_2)h" },
|
|
51
|
+
// Calculus
|
|
52
|
+
{ id: "calculus-power-rule", domain: "calculus", name: "Power rule (derivative)", latex: "\\frac{d}{dx}x^n = nx^{n-1}" },
|
|
53
|
+
{ id: "calculus-product-rule", domain: "calculus", name: "Product rule", latex: "\\frac{d}{dx}[f(x)g(x)] = f'(x)g(x) + f(x)g'(x)" },
|
|
54
|
+
{ id: "calculus-quotient-rule", domain: "calculus", name: "Quotient rule", latex: "\\frac{d}{dx}\\left[\\frac{f(x)}{g(x)}\\right] = \\frac{f'(x)g(x) - f(x)g'(x)}{g(x)^2}" },
|
|
55
|
+
{ id: "calculus-chain-rule", domain: "calculus", name: "Chain rule", latex: "\\frac{d}{dx}f(g(x)) = f'(g(x))\\,g'(x)" },
|
|
56
|
+
{ id: "calculus-ftc", domain: "calculus", name: "Fundamental theorem of calculus", latex: "\\int_a^b f'(x)\\,dx = f(b) - f(a)" },
|
|
57
|
+
{ id: "calculus-power-rule-integral", domain: "calculus", name: "Power rule (integral)", latex: "\\int x^n\\,dx = \\frac{x^{n+1}}{n+1} + C" },
|
|
58
|
+
{ id: "calculus-derivative-exp", domain: "calculus", name: "Derivative of eˣ", latex: "\\frac{d}{dx}e^x = e^x" },
|
|
59
|
+
{ id: "calculus-derivative-ln", domain: "calculus", name: "Derivative of ln(x)", latex: "\\frac{d}{dx}\\ln x = \\frac{1}{x}" },
|
|
60
|
+
{ id: "calculus-derivative-def", domain: "calculus", name: "Definition of the derivative", latex: "f'(x) = \\lim_{h \\to 0} \\frac{f(x+h) - f(x)}{h}" },
|
|
61
|
+
{ id: "calculus-taylor-series", domain: "calculus", name: "Taylor series", latex: "f(x) = \\sum_{n=0}^{\\infty} \\frac{f^{(n)}(a)}{n!}(x-a)^n" },
|
|
62
|
+
// Physics
|
|
63
|
+
{ id: "physics-kinematics-v", domain: "physics", name: "Kinematics: velocity", latex: "v = u + at" },
|
|
64
|
+
{ id: "physics-kinematics-s", domain: "physics", name: "Kinematics: displacement", latex: "s = ut + \\frac{1}{2}at^2" },
|
|
65
|
+
{ id: "physics-kinematics-v2", domain: "physics", name: "Kinematics: velocity²", latex: "v^2 = u^2 + 2as" },
|
|
66
|
+
{ id: "physics-newton-second", domain: "physics", name: "Newton's second law", latex: "F = ma" },
|
|
67
|
+
{ id: "physics-kinetic-energy", domain: "physics", name: "Kinetic energy", latex: "E_k = \\frac{1}{2}mv^2" },
|
|
68
|
+
{ id: "physics-potential-energy", domain: "physics", name: "Gravitational potential energy", latex: "E_p = mgh" },
|
|
69
|
+
{ id: "physics-ohms-law", domain: "physics", name: "Ohm's law", latex: "V = IR" },
|
|
70
|
+
{ id: "physics-power", domain: "physics", name: "Power", latex: "P = \\frac{W}{t}" },
|
|
71
|
+
{ id: "physics-gravitation", domain: "physics", name: "Newton's law of gravitation", latex: "F = G\\frac{m_1 m_2}{r^2}" },
|
|
72
|
+
{ id: "physics-momentum", domain: "physics", name: "Momentum", latex: "p = mv" },
|
|
73
|
+
{ id: "physics-wave-equation", domain: "physics", name: "Wave equation", latex: "v = f\\lambda" },
|
|
74
|
+
{ id: "physics-mass-energy", domain: "physics", name: "Mass-energy equivalence", latex: "E = mc^2" },
|
|
75
|
+
// Chemistry (needs the mhchem KaTeX extension - see this file's own doc comment)
|
|
76
|
+
{ id: "chemistry-ideal-gas", domain: "chemistry", name: "Ideal gas law", latex: "PV = nRT" },
|
|
77
|
+
{ id: "chemistry-molarity", domain: "chemistry", name: "Molarity", latex: "M = \\frac{n}{V}" },
|
|
78
|
+
{ id: "chemistry-ph", domain: "chemistry", name: "pH", latex: "\\text{pH} = -\\log_{10}[\\text{H}^+]" },
|
|
79
|
+
{ id: "chemistry-density", domain: "chemistry", name: "Density", latex: "\\rho = \\frac{m}{V}" },
|
|
80
|
+
{ id: "chemistry-combined-gas-law", domain: "chemistry", name: "Combined gas law", latex: "\\frac{P_1 V_1}{T_1} = \\frac{P_2 V_2}{T_2}" },
|
|
81
|
+
{ id: "chemistry-percent-yield", domain: "chemistry", name: "Percent yield", latex: "\\%\\,\\text{yield} = \\frac{\\text{actual}}{\\text{theoretical}} \\times 100\\%" },
|
|
82
|
+
{ id: "chemistry-water-formation", domain: "chemistry", name: "Combustion: hydrogen + oxygen", latex: "\\ce{2 H2 + O2 -> 2 H2O}" },
|
|
83
|
+
// Statistics
|
|
84
|
+
{ id: "statistics-mean", domain: "statistics", name: "Mean", latex: "\\bar{x} = \\frac{1}{n}\\sum_{i=1}^{n} x_i" },
|
|
85
|
+
{ id: "statistics-variance", domain: "statistics", name: "Variance", latex: "\\sigma^2 = \\frac{1}{n}\\sum_{i=1}^{n}(x_i - \\bar{x})^2" },
|
|
86
|
+
{ id: "statistics-std-dev", domain: "statistics", name: "Standard deviation", latex: "\\sigma = \\sqrt{\\frac{1}{n}\\sum_{i=1}^{n}(x_i - \\bar{x})^2}" },
|
|
87
|
+
{ id: "statistics-normal-pdf", domain: "statistics", name: "Normal distribution", latex: "f(x) = \\frac{1}{\\sigma\\sqrt{2\\pi}}\\, e^{-\\frac{(x-\\mu)^2}{2\\sigma^2}}" },
|
|
88
|
+
{ id: "statistics-z-score", domain: "statistics", name: "Z-score", latex: "z = \\frac{x - \\mu}{\\sigma}" },
|
|
89
|
+
{ id: "statistics-binomial-probability", domain: "statistics", name: "Binomial probability", latex: "P(X=k) = \\binom{n}{k} p^k (1-p)^{n-k}" },
|
|
90
|
+
];
|
package/dist/index.d.ts
CHANGED
|
@@ -1,28 +1,26 @@
|
|
|
1
|
-
export { ClassicEditor } from './components/
|
|
2
|
-
export type { ClassicEditorProps } from './components/
|
|
1
|
+
export { ClassicEditor } from './components/ClassicEditorAuthority.js';
|
|
2
|
+
export type { ClassicEditorProps } from './components/ClassicEditorAuthority.js';
|
|
3
|
+
export { CanonicalAuthorityEditor } from './components/CanonicalAuthorityEditor.js';
|
|
4
|
+
export type { CanonicalAuthorityEditorProps } from './components/CanonicalAuthorityEditor.js';
|
|
5
|
+
export { CanonicalEditorRuntime, createCanonicalEditorRuntime } from './canonicalEditorRuntime.js';
|
|
6
|
+
export type { SmartEditorChange, SmartEditorCheckpoint, SmartEditorHandle } from './canonicalEditorRuntime.js';
|
|
3
7
|
export type { MediaManagerAdapter, MediaItem, MediaSearchQuery } from './components/MediaManager.js';
|
|
8
|
+
export type { MediaFilters, MediaKind, MediaProvider, UploadOptions } from './mediaProvider.js';
|
|
9
|
+
export type { VersionListEntry, VersionProvider } from './versionProvider.js';
|
|
10
|
+
export type { CollabTransport, PresenceUpdate } from './collabTransport.js';
|
|
11
|
+
export type { DocumentVersion, CommentThread, CommentReply } from 'smartrte-core/foundation';
|
|
12
|
+
export type { CommentProvider } from './commentProvider.js';
|
|
13
|
+
export type { InlineSuggestionSummary, StructuralSuggestion, SuggestionKind } from 'smartrte-core/foundation';
|
|
14
|
+
export type { SuggestionProvider } from './suggestionProvider.js';
|
|
15
|
+
export { DefaultMediaPicker } from './components/MediaPicker.js';
|
|
16
|
+
export type { MediaPickerComponent, MediaPickerProps } from './components/MediaPicker.js';
|
|
4
17
|
export type { SrteTheme } from './theme.js';
|
|
5
18
|
export { SRTE_DEFAULT_CSS, ensureStyleSheet } from './theme.js';
|
|
6
|
-
export {
|
|
7
|
-
export type {
|
|
8
|
-
export
|
|
9
|
-
export
|
|
10
|
-
export type {
|
|
11
|
-
export { matchesPluginShortcut } from './pluginRuntime.js';
|
|
12
|
-
export { createDocumentFormatRegistry, defaultDocumentFormatRegistry, DocumentFormatRegistry, exportTextDocument, getDocumentFormatAdapter, importTextDocument, roundTripTextDocument } from './adapters/documentFormats.js';
|
|
13
|
-
export type { DocumentFormatAdapter, DocumentImportContext, TextDocumentFormat } from './adapters/documentFormats.js';
|
|
14
|
-
export { DOCX_MEDIA_TYPE, exportDocxDocument, importDocxDocumentWithMammoth, smartDocumentToDocxXml } from './adapters/docxFormat.js';
|
|
15
|
-
export { enhanceDocxTables, importStyledDocxDocument } from './adapters/styledDocxFormat.js';
|
|
16
|
-
export type { StyledDocxImportResult } from './adapters/styledDocxFormat.js';
|
|
17
|
-
export { buildPdfPrintDocument, importPdfDocument, PDF_MEDIA_TYPE, printSmartDocumentAsPdf, reconstructPdfPages } from './adapters/pdfFormat.js';
|
|
18
|
-
export type { PdfImportResult, PdfPageSnapshot, PdfTextItemSnapshot } from './adapters/pdfFormat.js';
|
|
19
|
-
export { createEditorFormatRuntime } from './formatRuntime.js';
|
|
20
|
-
export type { BuiltInDocumentFormat, EditorDocumentFormat, EditorFormatConfig, EditorFormatDefinition, EditorFormatExportContext, EditorFormatExportResult, EditorFormatImportContext, EditorFormatImportResult, EditorFormatRuntime } from './formatRuntime.js';
|
|
21
|
-
export { builtInFormatFidelity, getFormatFidelity } from './formatFidelity.js';
|
|
22
|
-
export type { FeatureFidelityContract, FidelityFeature, FidelityFormat, FidelityLevel, FormatFidelityCapability } from './formatFidelity.js';
|
|
23
|
-
export { createBuiltInFormatDefinitions } from './builtInFormatDefinitions.js';
|
|
24
|
-
export type { BuiltInFormatDefinitionOptions } from './builtInFormatDefinitions.js';
|
|
25
|
-
export { createDomEditorController, DomEditorController } from './editorController.js';
|
|
26
|
-
export type { DomEditorControllerChange, DomEditorControllerListener, DomEditorControllerSnapshot } from './editorController.js';
|
|
27
|
-
export type { DomBlockCommand } from './adapters/domBlockCommandBridge.js';
|
|
19
|
+
export { DOCX_MEDIA_TYPE, exportDocxDocument, importDocxDocumentWithMammoth, smartDocumentToDocxXml, enhanceDocxTables, importStyledDocxDocument, buildPdfPrintDocument, importPdfDocument, PDF_MEDIA_TYPE, reconstructPdfPages } from 'smartrte-core/foundation';
|
|
20
|
+
export type { StyledDocxImportResult, PdfImportResult, PdfPageSnapshot, PdfTextItemSnapshot } from 'smartrte-core/foundation';
|
|
21
|
+
export { printSmartDocumentAsPdf } from './adapters/pdfPrint.js';
|
|
22
|
+
export { builtInFormatFidelity, getFormatFidelity } from 'smartrte-core/foundation';
|
|
23
|
+
export type { FeatureFidelityContract, FidelityFeature, FidelityFormat, FidelityLevel, FormatFidelityCapability, FeatureFormatCodec, DocumentFormatCodec, FormatId, FormatFidelityLevel, ParseContext, SerializeContext } from 'smartrte-core/foundation';
|
|
28
24
|
export type { DomTableCommand } from './adapters/domTableCommandBridge.js';
|
|
25
|
+
export { createPluginRegistry, resolveShortcut, builtInPlugins } from 'smartrte-core/foundation';
|
|
26
|
+
export type { FoundationPlugin, PluginCommand, PluginCommandContext, PluginRegistry, KeyboardShortcutContribution, ToolbarContribution, ContextMenuContribution, ClipboardContribution, RendererContribution } from 'smartrte-core/foundation';
|