@bendyline/squisq-editor-react 1.6.2 → 2.0.0
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/README.md +12 -3
- package/dist/index.d.ts +1229 -179
- package/dist/index.js +18017 -11231
- package/dist/index.js.map +1 -1
- package/dist/monaco.d.ts +1 -0
- package/dist/monaco.js +4 -0
- package/dist/monaco.js.map +1 -0
- package/dist/styles/index.css +1471 -245
- package/package.json +9 -5
- package/src/BlockPropertiesPopover.tsx +30 -15
- package/src/DocumentSettingsDialog.tsx +13 -21
- package/src/EditorContext.tsx +199 -42
- package/src/EditorShell.tsx +348 -260
- package/src/ImageEditor.tsx +22 -1
- package/src/InlinePreviewGutter.tsx +16 -8
- package/src/MediaBin.tsx +107 -14
- package/src/OutlinePanel.tsx +202 -7
- package/src/PlainHtmlPreview.tsx +40 -1
- package/src/PreviewControls.tsx +309 -69
- package/src/PreviewPanel.tsx +312 -78
- package/src/RawEditor.tsx +13 -2
- package/src/StatusBar.tsx +5 -2
- package/src/TemplateAnnotation.ts +12 -3
- package/src/TemplatePicker.tsx +75 -21
- package/src/ThemeCustomizerPanel.tsx +8 -0
- package/src/ThemePicker.tsx +10 -5
- package/src/TimelineBlockPreview.tsx +1 -1
- package/src/Toolbar.tsx +202 -41
- package/src/TransitionPicker.tsx +36 -4
- package/src/ViewMenuPanel.tsx +12 -14
- package/src/WysiwygEditor.tsx +124 -91
- package/src/__tests__/blockPropertiesPopoverTheme.test.tsx +33 -0
- package/src/__tests__/blockTagActivity.test.ts +183 -0
- package/src/__tests__/buildDocumentPreviewMarkdown.test.ts +75 -0
- package/src/__tests__/buildPreviewDocContent.test.ts +48 -0
- package/src/__tests__/buildPreviewDocTransition.test.ts +21 -1
- package/src/__tests__/canvasSurfaceTextEditing.test.tsx +60 -0
- package/src/__tests__/customLayoutManagerTheme.test.tsx +34 -0
- package/src/__tests__/documentSettingsDialog.test.tsx +29 -1
- package/src/__tests__/editorScrollHandoff.test.tsx +102 -0
- package/src/__tests__/editorScrollSync.test.ts +65 -0
- package/src/__tests__/editorShellProps.test.tsx +123 -1
- package/src/__tests__/emojiPicker.test.tsx +2 -42
- package/src/__tests__/headingTransition.test.ts +0 -12
- package/src/__tests__/imageEditAffordance.test.tsx +5 -1
- package/src/__tests__/imageEditModalContract.test.tsx +119 -0
- package/src/__tests__/imageEditorShell.test.tsx +15 -1
- package/src/__tests__/jsonEditor.test.tsx +56 -1
- package/src/__tests__/layersPanel.test.tsx +75 -5
- package/src/__tests__/majorApiTypes.test.ts +26 -0
- package/src/__tests__/mediaBinDrop.test.tsx +90 -0
- package/src/__tests__/narrationSave.test.ts +148 -0
- package/src/__tests__/outlinePanel.test.tsx +93 -3
- package/src/__tests__/outlineSource.test.ts +217 -0
- package/src/__tests__/plainHtmlPreview.test.tsx +17 -1
- package/src/__tests__/presentationMode.test.tsx +290 -0
- package/src/__tests__/previewControls.test.tsx +218 -5
- package/src/__tests__/previewPanelAudioFailure.test.tsx +46 -0
- package/src/__tests__/previewPanelPresentation.test.tsx +126 -0
- package/src/__tests__/previewPanelTransforms.test.tsx +117 -0
- package/src/__tests__/rawEditorModelIsolation.test.ts +19 -0
- package/src/__tests__/resolveBlockVisual.test.ts +43 -0
- package/src/__tests__/statusBar.test.tsx +27 -0
- package/src/__tests__/teleprompter.test.tsx +190 -0
- package/src/__tests__/templateAnnotationRoundTrip.test.ts +26 -0
- package/src/__tests__/templatePickerPortal.test.tsx +62 -0
- package/src/__tests__/tiptapBridge.test.ts +23 -0
- package/src/__tests__/tiptapCodeBlockRoundTrip.test.ts +109 -0
- package/src/__tests__/transformStyleId.test.ts +13 -0
- package/src/__tests__/useImageEditor.test.tsx +67 -0
- package/src/__tests__/useMediaRecorder.test.ts +75 -0
- package/src/__tests__/viewMenuPanel.test.tsx +130 -0
- package/src/__tests__/wysiwygImageUpload.test.ts +69 -0
- package/src/__tests__/wysiwygTemplateBadgeFocus.test.tsx +56 -0
- package/src/asciiDiagram/AsciiDiagramExtension.ts +343 -0
- package/src/asciiDiagram/AsciiDiagramWidget.tsx +224 -0
- package/src/asciiDiagram/RepairableDiagramExtension.ts +200 -0
- package/src/asciiDiagram/__tests__/AsciiDiagramExtension.test.ts +145 -0
- package/src/asciiDiagram/__tests__/RepairableDiagramExtension.test.ts +159 -0
- package/src/asciiDiagram/__tests__/asciiDiagramCommands.test.ts +227 -0
- package/src/asciiDiagram/__tests__/asciiDiagramOps.test.ts +114 -0
- package/src/asciiDiagram/__tests__/asciiPaste.test.ts +43 -0
- package/src/asciiDiagram/asciiDiagramCommands.ts +148 -0
- package/src/asciiDiagram/asciiDiagramData.ts +116 -0
- package/src/asciiDiagram/asciiDiagramOps.ts +219 -0
- package/src/asciiDiagram/asciiPaste.ts +19 -0
- package/src/blockTagActivity.ts +233 -0
- package/src/buildDocumentPreviewMarkdown.ts +168 -0
- package/src/buildPreviewDoc.ts +19 -12
- package/src/customTemplates/CustomLayoutManager.tsx +3 -2
- package/src/customTemplates/CustomTemplateContext.tsx +6 -0
- package/src/customTemplates/TemplateDesigner.tsx +7 -4
- package/src/customTemplates/__tests__/library.test.ts +8 -0
- package/src/customTemplates/designer.css +158 -99
- package/src/customTemplates/library.ts +16 -3
- package/src/customThemes/CustomThemeContext.tsx +6 -0
- package/src/customThemes/CustomThemeDialog.tsx +35 -5
- package/src/customThemes/ImportThemeSection.tsx +178 -0
- package/src/customThemes/__tests__/customThemeLibrary.test.ts +9 -0
- package/src/customThemes/__tests__/importThemeSection.test.tsx +192 -0
- package/src/customThemes/customThemeLibrary.ts +7 -4
- package/src/customThemes/index.ts +7 -1
- package/src/customThemes/themeDraft.ts +23 -7
- package/src/diagram/DiagramCanvas.tsx +9 -4
- package/src/diagram/types.ts +35 -0
- package/src/editorScrollSync.ts +73 -0
- package/src/emojiData.ts +3 -23
- package/src/headingTransition.ts +0 -15
- package/src/imageEditor/CanvasSurface.tsx +29 -23
- package/src/imageEditor/LayersPanel.tsx +78 -3
- package/src/imageEditor/Toolbar.tsx +5 -1
- package/src/imageEditor/icons.tsx +4 -0
- package/src/imageEditor/image-editor.css +75 -0
- package/src/imageEditor/layers/SelectionHandles.tsx +1 -1
- package/src/imageEditor/useImageEditor.ts +71 -14
- package/src/index.ts +191 -19
- package/src/jsonEditor/JsonEditorContext.tsx +12 -6
- package/src/jsonEditor/RenderNode.tsx +24 -3
- package/src/jsonEditor/editors.tsx +86 -19
- package/src/mediaEntries.ts +12 -0
- package/src/monaco.ts +35 -0
- package/src/monacoWorkers.ts +89 -0
- package/src/outlineSource.ts +171 -0
- package/src/presentation/PresentationMode.tsx +596 -0
- package/src/rawEditorIsolation.ts +18 -0
- package/src/recorder/hooks/useMediaRecorder.ts +97 -53
- package/src/resolveBlockVisual.ts +10 -4
- package/src/scene/Scene.tsx +48 -18
- package/src/scene/SceneBlockExtension.ts +17 -10
- package/src/scene/SceneBlockWidget.tsx +5 -1
- package/src/scene/SceneViewport.tsx +7 -3
- package/src/scene/ShapePalette.tsx +17 -2
- package/src/scene/__tests__/DiagramAdapter.test.ts +86 -0
- package/src/scene/__tests__/SceneBlockExtension.test.ts +33 -0
- package/src/scene/__tests__/sceneIsolation.test.tsx +93 -0
- package/src/scene/adapters/DiagramAdapter.ts +12 -101
- package/src/scene/commands/SceneCommand.ts +4 -1
- package/src/scene/index.ts +1 -6
- package/src/scene/layers/DiagramEdges.tsx +21 -7
- package/src/scene/layers/edgeGeometry.ts +9 -1
- package/src/scene/layers/nodeCard.tsx +27 -8
- package/src/scene/scene.css +5 -2
- package/src/scene/text/SceneTextOverlay.tsx +5 -5
- package/src/scene/text/sceneTextChannel.ts +26 -20
- package/src/scene/text/sceneTextConfig.ts +4 -0
- package/src/scene/tools/ConnectTool.ts +13 -4
- package/src/scene/tools/SceneTool.ts +8 -0
- package/src/scene/tools/SelectTool.ts +34 -18
- package/src/scene/tools/ShapeTool.ts +2 -3
- package/src/styles/ascii-diagram.css +79 -0
- package/src/styles/ascii-timeline.css +499 -0
- package/src/styles/editor.css +706 -120
- package/src/styles/index.css +3 -0
- package/src/styles/tree-view.css +139 -0
- package/src/teleprompter/TeleprompterControls.tsx +218 -0
- package/src/teleprompter/TeleprompterSelfView.tsx +22 -0
- package/src/teleprompter/TeleprompterSurface.tsx +267 -0
- package/src/teleprompter/TeleprompterView.tsx +338 -0
- package/src/teleprompter/canvasRenderer.ts +161 -0
- package/src/teleprompter/floatingWindow.ts +352 -0
- package/src/teleprompter/index.ts +61 -0
- package/src/teleprompter/pcmWorklet.ts +62 -0
- package/src/teleprompter/recording/insertPreamble.ts +80 -0
- package/src/teleprompter/recording/narrationSave.ts +134 -0
- package/src/teleprompter/recording/useNarrationRecorder.ts +367 -0
- package/src/teleprompter/scrollModel.ts +85 -0
- package/src/teleprompter/teleprompterTheme.ts +303 -0
- package/src/teleprompter/types.ts +38 -0
- package/src/teleprompter/useFloatingWindow.ts +74 -0
- package/src/teleprompter/useMicAnalysis.ts +211 -0
- package/src/teleprompter/useTeleprompter.ts +421 -0
- package/src/templateContentPreviewResolver.ts +12 -5
- package/src/timeline/TimelineEditorWidget.tsx +702 -0
- package/src/timeline/TimelineViewExtension.ts +252 -0
- package/src/timeline/__tests__/TimelineEditorWidget.test.tsx +355 -0
- package/src/timeline/__tests__/TimelineViewExtension.test.ts +163 -0
- package/src/timeline/__tests__/timelineCommands.test.ts +327 -0
- package/src/timeline/__tests__/timelineOps.test.ts +222 -0
- package/src/timeline/__tests__/timelinePaste.test.ts +34 -0
- package/src/timeline/timelineCommands.ts +367 -0
- package/src/timeline/timelineData.ts +54 -0
- package/src/timeline/timelineOps.ts +277 -0
- package/src/timeline/timelinePaste.ts +8 -0
- package/src/tiptapBridge.ts +24 -16
- package/src/transformStyleId.ts +17 -0
- package/src/treeview/TreeOutlineWidget.tsx +240 -0
- package/src/treeview/TreeViewExtension.ts +250 -0
- package/src/treeview/__tests__/TreeViewExtension.test.ts +122 -0
- package/src/treeview/__tests__/treeOps.test.ts +125 -0
- package/src/treeview/__tests__/treePaste.test.ts +40 -0
- package/src/treeview/__tests__/treeViewCommands.test.ts +163 -0
- package/src/treeview/treeOps.ts +172 -0
- package/src/treeview/treePaste.ts +13 -0
- package/src/treeview/treeViewCommands.ts +94 -0
- package/src/treeview/treeViewData.ts +41 -0
- package/src/useMonacoLoader.ts +11 -34
- package/src/wysiwygImageUpload.ts +113 -0
- package/src/diagram/DiagramExtension.ts +0 -209
- package/src/diagram/DiagramWidget.tsx +0 -272
- package/src/diagram/useDiagramData.ts +0 -126
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bendyline/squisq-editor-react",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "React editor shell with raw/WYSIWYG/preview modes for Squisq documents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Bendyline",
|
|
@@ -34,6 +34,10 @@
|
|
|
34
34
|
"types": "./dist/index.d.ts",
|
|
35
35
|
"import": "./dist/index.js"
|
|
36
36
|
},
|
|
37
|
+
"./monaco": {
|
|
38
|
+
"types": "./dist/monaco.d.ts",
|
|
39
|
+
"import": "./dist/monaco.js"
|
|
40
|
+
},
|
|
37
41
|
"./styles": "./dist/styles/index.css"
|
|
38
42
|
},
|
|
39
43
|
"scripts": {
|
|
@@ -42,7 +46,7 @@
|
|
|
42
46
|
"typecheck": "tsc --noEmit"
|
|
43
47
|
},
|
|
44
48
|
"peerDependencies": {
|
|
45
|
-
"monaco-editor": "
|
|
49
|
+
"monaco-editor": ">=0.50.0",
|
|
46
50
|
"react": "^18.0.0 || ^19.0.0",
|
|
47
51
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
48
52
|
},
|
|
@@ -52,9 +56,9 @@
|
|
|
52
56
|
}
|
|
53
57
|
},
|
|
54
58
|
"dependencies": {
|
|
55
|
-
"@bendyline/squisq": "
|
|
56
|
-
"@bendyline/squisq-formats": "
|
|
57
|
-
"@bendyline/squisq-react": "
|
|
59
|
+
"@bendyline/squisq": "2.0.0",
|
|
60
|
+
"@bendyline/squisq-formats": "2.0.0",
|
|
61
|
+
"@bendyline/squisq-react": "2.0.0",
|
|
58
62
|
"@fortawesome/fontawesome-free": "7.2.0",
|
|
59
63
|
"@monaco-editor/react": "4.7.0",
|
|
60
64
|
"@tiptap/extension-image": "2.27.2",
|
|
@@ -16,12 +16,11 @@
|
|
|
16
16
|
* `TemplateBadgePopover`.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import { useEffect, useState } from 'react';
|
|
19
|
+
import { useEffect, useId, useRef, useState } from 'react';
|
|
20
20
|
import { createPortal } from 'react-dom';
|
|
21
21
|
import { TransitionPicker } from './TransitionPicker';
|
|
22
22
|
import {
|
|
23
23
|
readBlockAttrsTransition,
|
|
24
|
-
setBlockAttrsTransition,
|
|
25
24
|
setHeadingAttrsTransition,
|
|
26
25
|
type TransitionFields,
|
|
27
26
|
} from './headingTransition';
|
|
@@ -37,14 +36,17 @@ export interface BlockPropertiesPopoverProps {
|
|
|
37
36
|
/** Apply a new `dataBlockAttrs` inner to the heading (null clears it). */
|
|
38
37
|
onChange: (nextInner: string | null) => void;
|
|
39
38
|
/** Apply a paired `dataBlockAttrs` / `dataTemplateParams` transition rewrite. */
|
|
40
|
-
onAnnotationChange
|
|
39
|
+
onAnnotationChange: (next: {
|
|
41
40
|
blockAttrsInner: string | null;
|
|
42
41
|
templateParams: string | null;
|
|
43
42
|
}) => void;
|
|
43
|
+
/** Editor surface scheme. Required explicitly because this popover is portaled to `<body>`. */
|
|
44
|
+
colorScheme?: 'light' | 'dark';
|
|
45
|
+
/** Active document-theme accent used for focus and selected-state highlights. */
|
|
46
|
+
accentColor?: string;
|
|
44
47
|
onClose: () => void;
|
|
45
48
|
}
|
|
46
49
|
|
|
47
|
-
const PANEL_ID = 'squisq-block-props-portal';
|
|
48
50
|
/** The nested transition flyout is portaled out here; don't treat it as "outside". */
|
|
49
51
|
const TRANSITION_FLYOUT = '.squisq-transition-flyout';
|
|
50
52
|
|
|
@@ -54,15 +56,19 @@ export function BlockPropertiesPopover({
|
|
|
54
56
|
templateParams,
|
|
55
57
|
onChange,
|
|
56
58
|
onAnnotationChange,
|
|
59
|
+
colorScheme = 'light',
|
|
60
|
+
accentColor,
|
|
57
61
|
onClose,
|
|
58
62
|
}: BlockPropertiesPopoverProps) {
|
|
63
|
+
const panelRef = useRef<HTMLDivElement>(null);
|
|
64
|
+
const panelId = `squisq-block-props-portal-${useId().replace(/:/g, '')}`;
|
|
59
65
|
// Working copy of the Pandoc inner; successive edits compose off it.
|
|
60
66
|
const [inner, setInner] = useState<string | null>(blockAttrs);
|
|
61
67
|
const [templateInner, setTemplateInner] = useState<string | null>(templateParams);
|
|
62
68
|
const [style, setStyle] = useState<React.CSSProperties>(() => computeStyle(anchorRect));
|
|
63
69
|
|
|
64
70
|
useEffect(() => {
|
|
65
|
-
requestAnimationFrame(() => setStyle(computeStyle(anchorRect)));
|
|
71
|
+
requestAnimationFrame(() => setStyle(computeStyle(anchorRect, panelRef.current)));
|
|
66
72
|
}, [anchorRect]);
|
|
67
73
|
|
|
68
74
|
// Outside click + Escape close. A click inside the popover OR inside the
|
|
@@ -73,7 +79,7 @@ export function BlockPropertiesPopover({
|
|
|
73
79
|
};
|
|
74
80
|
const onMouse = (e: MouseEvent) => {
|
|
75
81
|
const target = e.target as HTMLElement;
|
|
76
|
-
const inPanel =
|
|
82
|
+
const inPanel = panelRef.current?.contains(target);
|
|
77
83
|
const inFlyout = target.closest?.(TRANSITION_FLYOUT);
|
|
78
84
|
if (!inPanel && !inFlyout) onClose();
|
|
79
85
|
};
|
|
@@ -96,10 +102,6 @@ export function BlockPropertiesPopover({
|
|
|
96
102
|
const startTime = readBlockAttrsValue(inner, 'startTime');
|
|
97
103
|
|
|
98
104
|
const onTransition = (next: TransitionFields) => {
|
|
99
|
-
if (!onAnnotationChange) {
|
|
100
|
-
apply(setBlockAttrsTransition(inner, next));
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
105
|
const updated = setHeadingAttrsTransition(inner, templateInner, next);
|
|
104
106
|
setInner(updated.blockAttrsInner);
|
|
105
107
|
setTemplateInner(updated.templateParams);
|
|
@@ -110,15 +112,22 @@ export function BlockPropertiesPopover({
|
|
|
110
112
|
|
|
111
113
|
return createPortal(
|
|
112
114
|
<div
|
|
113
|
-
|
|
115
|
+
ref={panelRef}
|
|
116
|
+
id={panelId}
|
|
114
117
|
className="squisq-block-props-popover"
|
|
118
|
+
data-theme={colorScheme}
|
|
115
119
|
role="dialog"
|
|
116
120
|
aria-label="Block properties"
|
|
117
|
-
style={style}
|
|
121
|
+
style={{ ...style, ...blockAccentStyle(accentColor) }}
|
|
118
122
|
>
|
|
119
123
|
<div className="squisq-block-props-row">
|
|
120
124
|
<span className="squisq-block-props-label">Transition</span>
|
|
121
|
-
<TransitionPicker
|
|
125
|
+
<TransitionPicker
|
|
126
|
+
value={transition}
|
|
127
|
+
onChange={onTransition}
|
|
128
|
+
colorScheme={colorScheme}
|
|
129
|
+
accentColor={accentColor}
|
|
130
|
+
/>
|
|
122
131
|
</div>
|
|
123
132
|
|
|
124
133
|
<div className="squisq-block-props-row">
|
|
@@ -147,6 +156,12 @@ export function BlockPropertiesPopover({
|
|
|
147
156
|
);
|
|
148
157
|
}
|
|
149
158
|
|
|
159
|
+
function blockAccentStyle(accentColor: string | undefined): React.CSSProperties {
|
|
160
|
+
return accentColor
|
|
161
|
+
? ({ ['--squisq-block-props-accent' as string]: accentColor } as React.CSSProperties)
|
|
162
|
+
: {};
|
|
163
|
+
}
|
|
164
|
+
|
|
150
165
|
function NumberField({
|
|
151
166
|
value,
|
|
152
167
|
placeholder,
|
|
@@ -178,8 +193,8 @@ function NumberField({
|
|
|
178
193
|
}
|
|
179
194
|
|
|
180
195
|
/** Place the panel below the badge, flipping above / clamping to the viewport. */
|
|
181
|
-
function computeStyle(rect: DOMRect): React.CSSProperties {
|
|
182
|
-
const panel =
|
|
196
|
+
function computeStyle(rect: DOMRect, element?: HTMLElement | null): React.CSSProperties {
|
|
197
|
+
const panel = element?.getBoundingClientRect();
|
|
183
198
|
const width = panel?.width ?? 280;
|
|
184
199
|
const height = panel?.height ?? 160;
|
|
185
200
|
const margin = 8;
|
|
@@ -19,17 +19,19 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
|
19
19
|
import {
|
|
20
20
|
inferDocumentTitle,
|
|
21
21
|
parseMarkdown,
|
|
22
|
+
readFrontmatterThemeId,
|
|
22
23
|
setFrontmatterValues,
|
|
23
24
|
} from '@bendyline/squisq/markdown';
|
|
24
25
|
import { getTransformStyleSummaries } from '@bendyline/squisq/transform';
|
|
25
26
|
import { ThemePicker } from './ThemePicker';
|
|
27
|
+
import { resolvePersistedTransformStyleId } from './transformStyleId';
|
|
26
28
|
|
|
27
29
|
// ── Frontmatter key constants ─────────────────────────────────────
|
|
28
30
|
|
|
29
31
|
/** Mirror of `FM_KEYS` in PreviewControls.tsx. Canonical names are the
|
|
30
32
|
* ones we write; legacy aliases are still read so older docs work. */
|
|
31
33
|
const FM = {
|
|
32
|
-
theme: { canonical: 'squisq-theme', legacy: 'theme' },
|
|
34
|
+
theme: { canonical: 'squisq-theme', legacy: ['themeId', 'theme'] },
|
|
33
35
|
transform: { canonical: 'squisq-transform', legacy: 'transform-style' },
|
|
34
36
|
captions: { canonical: 'squisq-captions', legacy: 'caption-style' },
|
|
35
37
|
} as const;
|
|
@@ -75,8 +77,11 @@ export function DocumentSettingsDialog({
|
|
|
75
77
|
const inferredTitle = useMemo(() => inferDocumentTitle(parsed), [parsed]);
|
|
76
78
|
|
|
77
79
|
const currentTitle = typeof frontmatter?.title === 'string' ? (frontmatter.title as string) : '';
|
|
78
|
-
const currentTheme =
|
|
79
|
-
const currentTransform =
|
|
80
|
+
const currentTheme = readFrontmatterThemeId(frontmatter) ?? '';
|
|
81
|
+
const currentTransform =
|
|
82
|
+
resolvePersistedTransformStyleId(
|
|
83
|
+
readFm(frontmatter, FM.transform.canonical, FM.transform.legacy),
|
|
84
|
+
) ?? '';
|
|
80
85
|
const currentCaptions = readFm(frontmatter, FM.captions.canonical, FM.captions.legacy);
|
|
81
86
|
|
|
82
87
|
const [title, setTitle] = useState(currentTitle);
|
|
@@ -128,13 +133,11 @@ export function DocumentSettingsDialog({
|
|
|
128
133
|
const updates: Record<string, string | null> = {
|
|
129
134
|
title: nextTitle,
|
|
130
135
|
[FM.theme.canonical]: theme || null,
|
|
131
|
-
//
|
|
132
|
-
|
|
133
|
-
|
|
136
|
+
// Saving settings canonicalizes all older theme spellings.
|
|
137
|
+
[FM.theme.legacy[0]]: null,
|
|
138
|
+
[FM.theme.legacy[1]]: null,
|
|
134
139
|
[FM.transform.canonical]: transform || null,
|
|
135
|
-
|
|
136
|
-
? { [FM.transform.legacy]: null }
|
|
137
|
-
: {}),
|
|
140
|
+
[FM.transform.legacy]: null,
|
|
138
141
|
[FM.captions.canonical]: captions || null,
|
|
139
142
|
...(currentCaptions && captions !== currentCaptions ? { [FM.captions.legacy]: null } : {}),
|
|
140
143
|
};
|
|
@@ -142,18 +145,7 @@ export function DocumentSettingsDialog({
|
|
|
142
145
|
const nextSource = setFrontmatterValues(markdownSource, updates);
|
|
143
146
|
onSave(nextSource);
|
|
144
147
|
},
|
|
145
|
-
[
|
|
146
|
-
title,
|
|
147
|
-
theme,
|
|
148
|
-
transform,
|
|
149
|
-
captions,
|
|
150
|
-
inferredTitle,
|
|
151
|
-
markdownSource,
|
|
152
|
-
currentTheme,
|
|
153
|
-
currentTransform,
|
|
154
|
-
currentCaptions,
|
|
155
|
-
onSave,
|
|
156
|
-
],
|
|
148
|
+
[title, theme, transform, captions, inferredTitle, markdownSource, currentCaptions, onSave],
|
|
157
149
|
);
|
|
158
150
|
|
|
159
151
|
return (
|