@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
|
@@ -4,6 +4,61 @@
|
|
|
4
4
|
* at the top, and save/cancel actions at the bottom.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
/* Both entry points are portaled to <body>, so they establish their own
|
|
8
|
+
editor-shell theme scope. These tokens keep the light palette unchanged
|
|
9
|
+
while giving every piece of designer chrome a dark-mode counterpart. */
|
|
10
|
+
.squisq-template-designer-overlay,
|
|
11
|
+
.squisq-layout-manager-overlay {
|
|
12
|
+
color-scheme: light;
|
|
13
|
+
--squisq-layout-panel: #ffffff;
|
|
14
|
+
--squisq-layout-chrome: #f9fafb;
|
|
15
|
+
--squisq-layout-subtle: #fafafa;
|
|
16
|
+
--squisq-layout-workspace: #f3f4f6;
|
|
17
|
+
--squisq-layout-input: #ffffff;
|
|
18
|
+
--squisq-layout-border: #e5e7eb;
|
|
19
|
+
--squisq-layout-border-strong: #d1d5db;
|
|
20
|
+
--squisq-layout-text: #111827;
|
|
21
|
+
--squisq-layout-text-soft: #1f2937;
|
|
22
|
+
--squisq-layout-muted: #6b7280;
|
|
23
|
+
--squisq-layout-faint: #9ca3af;
|
|
24
|
+
--squisq-layout-hover: #f1f5f9;
|
|
25
|
+
--squisq-layout-accent-text: #4338ca;
|
|
26
|
+
--squisq-layout-accent-bg: #4f46e5;
|
|
27
|
+
--squisq-layout-accent-bg-hover: #4338ca;
|
|
28
|
+
--squisq-layout-accent-border: #6366f1;
|
|
29
|
+
--squisq-layout-accent-soft: #eef2ff;
|
|
30
|
+
--squisq-layout-accent-soft-hover: #e0e7ff;
|
|
31
|
+
--squisq-layout-accent-soft-border: #c7d2fe;
|
|
32
|
+
--squisq-layout-accent-hover-border: #a5b4fc;
|
|
33
|
+
--squisq-layout-thumb: #f8fafc;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.squisq-template-designer-overlay[data-theme='dark'],
|
|
37
|
+
.squisq-layout-manager-overlay[data-theme='dark'] {
|
|
38
|
+
color-scheme: dark;
|
|
39
|
+
--squisq-layout-panel: #111827;
|
|
40
|
+
--squisq-layout-chrome: #1f2937;
|
|
41
|
+
--squisq-layout-subtle: #18212f;
|
|
42
|
+
--squisq-layout-workspace: #0f172a;
|
|
43
|
+
--squisq-layout-input: #111827;
|
|
44
|
+
--squisq-layout-border: #374151;
|
|
45
|
+
--squisq-layout-border-strong: #4b5563;
|
|
46
|
+
--squisq-layout-text: #f3f4f6;
|
|
47
|
+
--squisq-layout-text-soft: #e5e7eb;
|
|
48
|
+
--squisq-layout-muted: #9ca3af;
|
|
49
|
+
--squisq-layout-faint: #6b7280;
|
|
50
|
+
--squisq-layout-hover: #334155;
|
|
51
|
+
--squisq-layout-accent-text: #c7d2fe;
|
|
52
|
+
--squisq-layout-accent-bg: #4f46e5;
|
|
53
|
+
--squisq-layout-accent-bg-hover: #6366f1;
|
|
54
|
+
--squisq-layout-accent-border: #818cf8;
|
|
55
|
+
--squisq-layout-accent-soft: #312e81;
|
|
56
|
+
--squisq-layout-accent-soft-hover: #3730a3;
|
|
57
|
+
--squisq-layout-accent-soft-border: #4f46e5;
|
|
58
|
+
--squisq-layout-accent-hover-border: #6366f1;
|
|
59
|
+
--squisq-layout-thumb: #0f172a;
|
|
60
|
+
}
|
|
61
|
+
|
|
7
62
|
.squisq-template-designer-overlay {
|
|
8
63
|
position: fixed;
|
|
9
64
|
inset: 0;
|
|
@@ -20,7 +75,8 @@
|
|
|
20
75
|
flex-direction: column;
|
|
21
76
|
width: min(1200px, 100%);
|
|
22
77
|
height: min(800px, 100%);
|
|
23
|
-
|
|
78
|
+
color: var(--squisq-layout-text-soft);
|
|
79
|
+
background: var(--squisq-layout-panel);
|
|
24
80
|
border-radius: 12px;
|
|
25
81
|
box-shadow: 0 24px 60px rgba(0, 0, 0, 0.3);
|
|
26
82
|
overflow: hidden;
|
|
@@ -54,15 +110,15 @@
|
|
|
54
110
|
align-items: center;
|
|
55
111
|
justify-content: space-between;
|
|
56
112
|
padding: 14px 20px;
|
|
57
|
-
border-bottom: 1px solid
|
|
58
|
-
background:
|
|
113
|
+
border-bottom: 1px solid var(--squisq-layout-border);
|
|
114
|
+
background: var(--squisq-layout-chrome);
|
|
59
115
|
}
|
|
60
116
|
|
|
61
117
|
.squisq-template-designer-title {
|
|
62
118
|
margin: 0;
|
|
63
119
|
font-size: 16px;
|
|
64
120
|
font-weight: 600;
|
|
65
|
-
color:
|
|
121
|
+
color: var(--squisq-layout-text);
|
|
66
122
|
}
|
|
67
123
|
|
|
68
124
|
.squisq-template-designer-close {
|
|
@@ -73,7 +129,7 @@
|
|
|
73
129
|
justify-content: center;
|
|
74
130
|
font-size: 24px;
|
|
75
131
|
line-height: 1;
|
|
76
|
-
color:
|
|
132
|
+
color: var(--squisq-layout-muted);
|
|
77
133
|
background: transparent;
|
|
78
134
|
border: 1px solid transparent;
|
|
79
135
|
border-radius: 6px;
|
|
@@ -81,9 +137,9 @@
|
|
|
81
137
|
}
|
|
82
138
|
|
|
83
139
|
.squisq-template-designer-close:hover {
|
|
84
|
-
color:
|
|
85
|
-
background:
|
|
86
|
-
border-color:
|
|
140
|
+
color: var(--squisq-layout-text);
|
|
141
|
+
background: var(--squisq-layout-hover);
|
|
142
|
+
border-color: var(--squisq-layout-border-strong);
|
|
87
143
|
}
|
|
88
144
|
|
|
89
145
|
.squisq-template-designer-meta {
|
|
@@ -91,8 +147,8 @@
|
|
|
91
147
|
grid-template-columns: minmax(160px, 1fr) minmax(160px, 1fr) minmax(240px, 2fr);
|
|
92
148
|
gap: 12px;
|
|
93
149
|
padding: 12px 20px;
|
|
94
|
-
border-bottom: 1px solid
|
|
95
|
-
background:
|
|
150
|
+
border-bottom: 1px solid var(--squisq-layout-border);
|
|
151
|
+
background: var(--squisq-layout-panel);
|
|
96
152
|
}
|
|
97
153
|
|
|
98
154
|
.squisq-template-designer-field {
|
|
@@ -106,21 +162,21 @@
|
|
|
106
162
|
font-weight: 600;
|
|
107
163
|
text-transform: uppercase;
|
|
108
164
|
letter-spacing: 0.04em;
|
|
109
|
-
color:
|
|
165
|
+
color: var(--squisq-layout-muted);
|
|
110
166
|
}
|
|
111
167
|
|
|
112
168
|
.squisq-template-designer-field input {
|
|
113
169
|
padding: 6px 10px;
|
|
114
170
|
font-size: 13px;
|
|
115
|
-
color:
|
|
116
|
-
background:
|
|
117
|
-
border: 1px solid
|
|
171
|
+
color: var(--squisq-layout-text);
|
|
172
|
+
background: var(--squisq-layout-input);
|
|
173
|
+
border: 1px solid var(--squisq-layout-border-strong);
|
|
118
174
|
border-radius: 6px;
|
|
119
175
|
outline: none;
|
|
120
176
|
}
|
|
121
177
|
|
|
122
178
|
.squisq-template-designer-field input:focus {
|
|
123
|
-
border-color:
|
|
179
|
+
border-color: var(--squisq-layout-accent-border);
|
|
124
180
|
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);
|
|
125
181
|
}
|
|
126
182
|
|
|
@@ -129,7 +185,7 @@
|
|
|
129
185
|
font-weight: 400;
|
|
130
186
|
text-transform: none;
|
|
131
187
|
letter-spacing: normal;
|
|
132
|
-
color:
|
|
188
|
+
color: var(--squisq-layout-faint);
|
|
133
189
|
}
|
|
134
190
|
|
|
135
191
|
.squisq-template-designer-body {
|
|
@@ -142,8 +198,8 @@
|
|
|
142
198
|
width: 220px;
|
|
143
199
|
flex-shrink: 0;
|
|
144
200
|
padding: 16px;
|
|
145
|
-
border-right: 1px solid
|
|
146
|
-
background:
|
|
201
|
+
border-right: 1px solid var(--squisq-layout-border);
|
|
202
|
+
background: var(--squisq-layout-subtle);
|
|
147
203
|
overflow-y: auto;
|
|
148
204
|
}
|
|
149
205
|
|
|
@@ -153,13 +209,13 @@
|
|
|
153
209
|
font-weight: 700;
|
|
154
210
|
text-transform: uppercase;
|
|
155
211
|
letter-spacing: 0.06em;
|
|
156
|
-
color:
|
|
212
|
+
color: var(--squisq-layout-accent-text);
|
|
157
213
|
}
|
|
158
214
|
|
|
159
215
|
.squisq-template-designer-palette-hint {
|
|
160
216
|
margin: 0 0 12px;
|
|
161
217
|
font-size: 11px;
|
|
162
|
-
color:
|
|
218
|
+
color: var(--squisq-layout-muted);
|
|
163
219
|
line-height: 1.4;
|
|
164
220
|
}
|
|
165
221
|
|
|
@@ -185,7 +241,7 @@
|
|
|
185
241
|
font-weight: 700;
|
|
186
242
|
text-transform: uppercase;
|
|
187
243
|
letter-spacing: 0.06em;
|
|
188
|
-
color:
|
|
244
|
+
color: var(--squisq-layout-muted);
|
|
189
245
|
}
|
|
190
246
|
|
|
191
247
|
/* Shapes are compact icon tiles in a grid. */
|
|
@@ -201,11 +257,11 @@
|
|
|
201
257
|
justify-content: center;
|
|
202
258
|
aspect-ratio: 1 / 1;
|
|
203
259
|
padding: 4px;
|
|
204
|
-
background:
|
|
205
|
-
border: 1px solid
|
|
260
|
+
background: var(--squisq-layout-input);
|
|
261
|
+
border: 1px solid var(--squisq-layout-border);
|
|
206
262
|
border-radius: 6px;
|
|
207
263
|
cursor: grab;
|
|
208
|
-
color:
|
|
264
|
+
color: var(--squisq-layout-muted);
|
|
209
265
|
transition:
|
|
210
266
|
background 0.1s,
|
|
211
267
|
border-color 0.1s;
|
|
@@ -216,13 +272,13 @@
|
|
|
216
272
|
}
|
|
217
273
|
|
|
218
274
|
.squisq-template-designer-shape-item:hover {
|
|
219
|
-
background:
|
|
220
|
-
border-color:
|
|
275
|
+
background: var(--squisq-layout-accent-soft);
|
|
276
|
+
border-color: var(--squisq-layout-accent-soft-border);
|
|
221
277
|
}
|
|
222
278
|
|
|
223
279
|
.squisq-template-designer-shape-item--active {
|
|
224
|
-
background:
|
|
225
|
-
border-color:
|
|
280
|
+
background: var(--squisq-layout-accent-soft);
|
|
281
|
+
border-color: var(--squisq-layout-accent-border);
|
|
226
282
|
}
|
|
227
283
|
|
|
228
284
|
.squisq-template-designer-palette-media-add {
|
|
@@ -231,22 +287,22 @@
|
|
|
231
287
|
padding: 8px 10px;
|
|
232
288
|
font-size: 12px;
|
|
233
289
|
font-weight: 600;
|
|
234
|
-
color:
|
|
235
|
-
background:
|
|
236
|
-
border: 1px dashed
|
|
290
|
+
color: var(--squisq-layout-accent-text);
|
|
291
|
+
background: var(--squisq-layout-accent-soft);
|
|
292
|
+
border: 1px dashed var(--squisq-layout-accent-soft-border);
|
|
237
293
|
border-radius: 6px;
|
|
238
294
|
cursor: pointer;
|
|
239
295
|
}
|
|
240
296
|
|
|
241
297
|
.squisq-template-designer-palette-media-add:hover:not(:disabled) {
|
|
242
|
-
background:
|
|
243
|
-
border-color:
|
|
298
|
+
background: var(--squisq-layout-accent-soft-hover);
|
|
299
|
+
border-color: var(--squisq-layout-accent-hover-border);
|
|
244
300
|
}
|
|
245
301
|
|
|
246
302
|
.squisq-template-designer-palette-media-add:disabled {
|
|
247
|
-
color:
|
|
248
|
-
background:
|
|
249
|
-
border-color:
|
|
303
|
+
color: var(--squisq-layout-faint);
|
|
304
|
+
background: var(--squisq-layout-workspace);
|
|
305
|
+
border-color: var(--squisq-layout-border);
|
|
250
306
|
cursor: not-allowed;
|
|
251
307
|
}
|
|
252
308
|
|
|
@@ -256,8 +312,9 @@
|
|
|
256
312
|
align-items: flex-start;
|
|
257
313
|
gap: 2px;
|
|
258
314
|
padding: 8px 10px;
|
|
259
|
-
|
|
260
|
-
|
|
315
|
+
color: var(--squisq-layout-text-soft);
|
|
316
|
+
background: var(--squisq-layout-input);
|
|
317
|
+
border: 1px solid var(--squisq-layout-border);
|
|
261
318
|
border-radius: 6px;
|
|
262
319
|
/* Draggable onto the canvas — `grab` hints the drag affordance. */
|
|
263
320
|
cursor: grab;
|
|
@@ -272,24 +329,24 @@
|
|
|
272
329
|
}
|
|
273
330
|
|
|
274
331
|
.squisq-template-designer-palette-item:hover {
|
|
275
|
-
background:
|
|
276
|
-
border-color:
|
|
332
|
+
background: var(--squisq-layout-accent-soft);
|
|
333
|
+
border-color: var(--squisq-layout-accent-soft-border);
|
|
277
334
|
}
|
|
278
335
|
|
|
279
336
|
.squisq-template-designer-palette-item--active {
|
|
280
|
-
background:
|
|
281
|
-
border-color:
|
|
337
|
+
background: var(--squisq-layout-accent-soft);
|
|
338
|
+
border-color: var(--squisq-layout-accent-border);
|
|
282
339
|
}
|
|
283
340
|
|
|
284
341
|
.squisq-template-designer-palette-item-preview {
|
|
285
342
|
font-family: 'JetBrains Mono', 'SF Mono', 'Menlo', monospace;
|
|
286
343
|
font-size: 12px;
|
|
287
|
-
color:
|
|
344
|
+
color: var(--squisq-layout-accent-text);
|
|
288
345
|
}
|
|
289
346
|
|
|
290
347
|
.squisq-template-designer-palette-item-label {
|
|
291
348
|
font-size: 11px;
|
|
292
|
-
color:
|
|
349
|
+
color: var(--squisq-layout-muted);
|
|
293
350
|
}
|
|
294
351
|
|
|
295
352
|
.squisq-template-designer-stage {
|
|
@@ -299,7 +356,7 @@
|
|
|
299
356
|
min-width: 0;
|
|
300
357
|
padding: 12px;
|
|
301
358
|
gap: 8px;
|
|
302
|
-
background:
|
|
359
|
+
background: var(--squisq-layout-workspace);
|
|
303
360
|
}
|
|
304
361
|
|
|
305
362
|
/* Unified controls bar above the canvas: the compact aspect-ratio
|
|
@@ -314,8 +371,8 @@
|
|
|
314
371
|
align-items: center;
|
|
315
372
|
gap: 5px;
|
|
316
373
|
padding: 6px 8px;
|
|
317
|
-
background:
|
|
318
|
-
border: 1px solid
|
|
374
|
+
background: var(--squisq-layout-panel);
|
|
375
|
+
border: 1px solid var(--squisq-layout-border);
|
|
319
376
|
border-radius: 6px;
|
|
320
377
|
align-self: stretch;
|
|
321
378
|
overflow-x: auto;
|
|
@@ -327,7 +384,7 @@
|
|
|
327
384
|
font-weight: 600;
|
|
328
385
|
text-transform: uppercase;
|
|
329
386
|
letter-spacing: 0.04em;
|
|
330
|
-
color:
|
|
387
|
+
color: var(--squisq-layout-muted);
|
|
331
388
|
}
|
|
332
389
|
|
|
333
390
|
/* ─── Contextual layer styling controls ─────────────────── */
|
|
@@ -365,7 +422,7 @@
|
|
|
365
422
|
width: 28px;
|
|
366
423
|
height: 28px;
|
|
367
424
|
font-size: 13px;
|
|
368
|
-
color:
|
|
425
|
+
color: var(--squisq-layout-text-soft);
|
|
369
426
|
background: transparent;
|
|
370
427
|
border: 1px solid transparent;
|
|
371
428
|
border-radius: 4px;
|
|
@@ -373,22 +430,22 @@
|
|
|
373
430
|
}
|
|
374
431
|
|
|
375
432
|
.squisq-layer-toolbar-btn:hover {
|
|
376
|
-
background:
|
|
433
|
+
background: var(--squisq-layout-hover);
|
|
377
434
|
}
|
|
378
435
|
|
|
379
436
|
.squisq-layer-toolbar-btn--active {
|
|
380
|
-
background:
|
|
381
|
-
border-color:
|
|
382
|
-
color:
|
|
437
|
+
background: var(--squisq-layout-accent-soft);
|
|
438
|
+
border-color: var(--squisq-layout-accent-border);
|
|
439
|
+
color: var(--squisq-layout-accent-text);
|
|
383
440
|
}
|
|
384
441
|
|
|
385
442
|
.squisq-layer-toolbar-select {
|
|
386
443
|
height: 28px;
|
|
387
444
|
padding: 0 6px;
|
|
388
445
|
font-size: 12px;
|
|
389
|
-
color:
|
|
390
|
-
background:
|
|
391
|
-
border: 1px solid
|
|
446
|
+
color: var(--squisq-layout-text-soft);
|
|
447
|
+
background: var(--squisq-layout-input);
|
|
448
|
+
border: 1px solid var(--squisq-layout-border-strong);
|
|
392
449
|
border-radius: 4px;
|
|
393
450
|
cursor: pointer;
|
|
394
451
|
}
|
|
@@ -398,9 +455,9 @@
|
|
|
398
455
|
height: 28px;
|
|
399
456
|
padding: 0 4px 0 6px;
|
|
400
457
|
font-size: 12px;
|
|
401
|
-
color:
|
|
402
|
-
background:
|
|
403
|
-
border: 1px solid
|
|
458
|
+
color: var(--squisq-layout-text-soft);
|
|
459
|
+
background: var(--squisq-layout-input);
|
|
460
|
+
border: 1px solid var(--squisq-layout-border-strong);
|
|
404
461
|
border-radius: 4px;
|
|
405
462
|
}
|
|
406
463
|
|
|
@@ -417,7 +474,7 @@
|
|
|
417
474
|
.squisq-layer-toolbar-label {
|
|
418
475
|
display: inline-flex;
|
|
419
476
|
align-items: center;
|
|
420
|
-
color:
|
|
477
|
+
color: var(--squisq-layout-muted);
|
|
421
478
|
font-size: 13px;
|
|
422
479
|
}
|
|
423
480
|
|
|
@@ -431,9 +488,9 @@
|
|
|
431
488
|
width: 28px;
|
|
432
489
|
height: 28px;
|
|
433
490
|
padding: 0;
|
|
434
|
-
border: 1px solid
|
|
491
|
+
border: 1px solid var(--squisq-layout-border-strong);
|
|
435
492
|
border-radius: 4px;
|
|
436
|
-
background:
|
|
493
|
+
background: var(--squisq-layout-input);
|
|
437
494
|
cursor: pointer;
|
|
438
495
|
}
|
|
439
496
|
|
|
@@ -441,14 +498,14 @@
|
|
|
441
498
|
width: 1px;
|
|
442
499
|
align-self: stretch;
|
|
443
500
|
margin: 2px 2px;
|
|
444
|
-
background:
|
|
501
|
+
background: var(--squisq-layout-border);
|
|
445
502
|
}
|
|
446
503
|
|
|
447
504
|
.squisq-template-designer-scene {
|
|
448
505
|
flex: 1;
|
|
449
506
|
min-height: 0;
|
|
450
|
-
background:
|
|
451
|
-
border: 1px solid
|
|
507
|
+
background: var(--squisq-layout-panel);
|
|
508
|
+
border: 1px solid var(--squisq-layout-border);
|
|
452
509
|
border-radius: 8px;
|
|
453
510
|
overflow: hidden;
|
|
454
511
|
}
|
|
@@ -458,14 +515,14 @@
|
|
|
458
515
|
align-items: center;
|
|
459
516
|
justify-content: space-between;
|
|
460
517
|
padding: 12px 20px;
|
|
461
|
-
border-top: 1px solid
|
|
462
|
-
background:
|
|
518
|
+
border-top: 1px solid var(--squisq-layout-border);
|
|
519
|
+
background: var(--squisq-layout-chrome);
|
|
463
520
|
gap: 12px;
|
|
464
521
|
}
|
|
465
522
|
|
|
466
523
|
.squisq-template-designer-footer-hint {
|
|
467
524
|
font-size: 11px;
|
|
468
|
-
color:
|
|
525
|
+
color: var(--squisq-layout-muted);
|
|
469
526
|
flex: 1;
|
|
470
527
|
min-width: 0;
|
|
471
528
|
}
|
|
@@ -479,26 +536,26 @@
|
|
|
479
536
|
padding: 6px 14px;
|
|
480
537
|
font-size: 13px;
|
|
481
538
|
font-weight: 500;
|
|
482
|
-
color:
|
|
483
|
-
background:
|
|
484
|
-
border: 1px solid
|
|
539
|
+
color: var(--squisq-layout-text-soft);
|
|
540
|
+
background: var(--squisq-layout-input);
|
|
541
|
+
border: 1px solid var(--squisq-layout-border-strong);
|
|
485
542
|
border-radius: 6px;
|
|
486
543
|
cursor: pointer;
|
|
487
544
|
transition: background 0.1s;
|
|
488
545
|
}
|
|
489
546
|
|
|
490
547
|
.squisq-template-designer-btn:hover {
|
|
491
|
-
background:
|
|
548
|
+
background: var(--squisq-layout-hover);
|
|
492
549
|
}
|
|
493
550
|
|
|
494
551
|
.squisq-template-designer-btn--primary {
|
|
495
552
|
color: #ffffff;
|
|
496
|
-
background:
|
|
497
|
-
border-color:
|
|
553
|
+
background: var(--squisq-layout-accent-bg);
|
|
554
|
+
border-color: var(--squisq-layout-accent-bg-hover);
|
|
498
555
|
}
|
|
499
556
|
|
|
500
557
|
.squisq-template-designer-btn--primary:hover {
|
|
501
|
-
background:
|
|
558
|
+
background: var(--squisq-layout-accent-bg-hover);
|
|
502
559
|
}
|
|
503
560
|
|
|
504
561
|
/* ─── Custom Layout Manager ────────────────────────────────
|
|
@@ -521,7 +578,8 @@
|
|
|
521
578
|
flex-direction: column;
|
|
522
579
|
width: min(1600px, 96vw);
|
|
523
580
|
height: 92vh;
|
|
524
|
-
|
|
581
|
+
color: var(--squisq-layout-text-soft);
|
|
582
|
+
background: var(--squisq-layout-panel);
|
|
525
583
|
border-radius: 12px;
|
|
526
584
|
box-shadow: 0 24px 60px rgba(0, 0, 0, 0.3);
|
|
527
585
|
overflow: hidden;
|
|
@@ -532,15 +590,15 @@
|
|
|
532
590
|
align-items: center;
|
|
533
591
|
justify-content: space-between;
|
|
534
592
|
padding: 14px 20px;
|
|
535
|
-
border-bottom: 1px solid
|
|
536
|
-
background:
|
|
593
|
+
border-bottom: 1px solid var(--squisq-layout-border);
|
|
594
|
+
background: var(--squisq-layout-chrome);
|
|
537
595
|
}
|
|
538
596
|
|
|
539
597
|
.squisq-layout-manager-title {
|
|
540
598
|
margin: 0;
|
|
541
599
|
font-size: 16px;
|
|
542
600
|
font-weight: 600;
|
|
543
|
-
color:
|
|
601
|
+
color: var(--squisq-layout-text);
|
|
544
602
|
}
|
|
545
603
|
|
|
546
604
|
.squisq-layout-manager-body {
|
|
@@ -556,8 +614,8 @@
|
|
|
556
614
|
flex-direction: column;
|
|
557
615
|
gap: 8px;
|
|
558
616
|
padding: 16px;
|
|
559
|
-
border-right: 1px solid
|
|
560
|
-
background:
|
|
617
|
+
border-right: 1px solid var(--squisq-layout-border);
|
|
618
|
+
background: var(--squisq-layout-subtle);
|
|
561
619
|
overflow-y: auto;
|
|
562
620
|
}
|
|
563
621
|
|
|
@@ -565,22 +623,22 @@
|
|
|
565
623
|
padding: 10px 12px;
|
|
566
624
|
font-size: 13px;
|
|
567
625
|
font-weight: 600;
|
|
568
|
-
color:
|
|
569
|
-
background:
|
|
570
|
-
border: 1px dashed
|
|
626
|
+
color: var(--squisq-layout-accent-text);
|
|
627
|
+
background: var(--squisq-layout-accent-soft);
|
|
628
|
+
border: 1px dashed var(--squisq-layout-accent-soft-border);
|
|
571
629
|
border-radius: 8px;
|
|
572
630
|
cursor: pointer;
|
|
573
631
|
text-align: center;
|
|
574
632
|
}
|
|
575
633
|
|
|
576
634
|
.squisq-layout-manager-new:hover {
|
|
577
|
-
background:
|
|
578
|
-
border-color:
|
|
635
|
+
background: var(--squisq-layout-accent-soft-hover);
|
|
636
|
+
border-color: var(--squisq-layout-accent-hover-border);
|
|
579
637
|
}
|
|
580
638
|
|
|
581
639
|
.squisq-layout-manager-new--active {
|
|
582
640
|
border-style: solid;
|
|
583
|
-
border-color:
|
|
641
|
+
border-color: var(--squisq-layout-accent-border);
|
|
584
642
|
}
|
|
585
643
|
|
|
586
644
|
.squisq-layout-manager-section-title {
|
|
@@ -589,7 +647,7 @@
|
|
|
589
647
|
font-weight: 700;
|
|
590
648
|
text-transform: uppercase;
|
|
591
649
|
letter-spacing: 0.06em;
|
|
592
|
-
color:
|
|
650
|
+
color: var(--squisq-layout-muted);
|
|
593
651
|
}
|
|
594
652
|
|
|
595
653
|
.squisq-layout-manager-list {
|
|
@@ -603,8 +661,9 @@
|
|
|
603
661
|
align-items: center;
|
|
604
662
|
gap: 10px;
|
|
605
663
|
padding: 8px;
|
|
606
|
-
|
|
607
|
-
|
|
664
|
+
color: var(--squisq-layout-text-soft);
|
|
665
|
+
background: var(--squisq-layout-input);
|
|
666
|
+
border: 1px solid var(--squisq-layout-border);
|
|
608
667
|
border-radius: 8px;
|
|
609
668
|
cursor: pointer;
|
|
610
669
|
text-align: left;
|
|
@@ -614,13 +673,13 @@
|
|
|
614
673
|
}
|
|
615
674
|
|
|
616
675
|
.squisq-layout-manager-item:hover {
|
|
617
|
-
background:
|
|
618
|
-
border-color:
|
|
676
|
+
background: var(--squisq-layout-accent-soft);
|
|
677
|
+
border-color: var(--squisq-layout-accent-soft-border);
|
|
619
678
|
}
|
|
620
679
|
|
|
621
680
|
.squisq-layout-manager-item--active {
|
|
622
|
-
background:
|
|
623
|
-
border-color:
|
|
681
|
+
background: var(--squisq-layout-accent-soft);
|
|
682
|
+
border-color: var(--squisq-layout-accent-border);
|
|
624
683
|
}
|
|
625
684
|
|
|
626
685
|
.squisq-layout-manager-item-thumb {
|
|
@@ -628,10 +687,10 @@
|
|
|
628
687
|
display: inline-flex;
|
|
629
688
|
width: 56px;
|
|
630
689
|
height: 40px;
|
|
631
|
-
border: 1px solid
|
|
690
|
+
border: 1px solid var(--squisq-layout-border);
|
|
632
691
|
border-radius: 4px;
|
|
633
692
|
overflow: hidden;
|
|
634
|
-
background:
|
|
693
|
+
background: var(--squisq-layout-thumb);
|
|
635
694
|
}
|
|
636
695
|
|
|
637
696
|
.squisq-layout-manager-item-text {
|
|
@@ -644,7 +703,7 @@
|
|
|
644
703
|
.squisq-layout-manager-item-label {
|
|
645
704
|
font-size: 13px;
|
|
646
705
|
font-weight: 600;
|
|
647
|
-
color:
|
|
706
|
+
color: var(--squisq-layout-text);
|
|
648
707
|
white-space: nowrap;
|
|
649
708
|
overflow: hidden;
|
|
650
709
|
text-overflow: ellipsis;
|
|
@@ -653,7 +712,7 @@
|
|
|
653
712
|
.squisq-layout-manager-item-name {
|
|
654
713
|
font-family: 'JetBrains Mono', 'SF Mono', 'Menlo', monospace;
|
|
655
714
|
font-size: 11px;
|
|
656
|
-
color:
|
|
715
|
+
color: var(--squisq-layout-muted);
|
|
657
716
|
white-space: nowrap;
|
|
658
717
|
overflow: hidden;
|
|
659
718
|
text-overflow: ellipsis;
|
|
@@ -663,7 +722,7 @@
|
|
|
663
722
|
margin: 8px 2px;
|
|
664
723
|
font-size: 12px;
|
|
665
724
|
line-height: 1.5;
|
|
666
|
-
color:
|
|
725
|
+
color: var(--squisq-layout-muted);
|
|
667
726
|
}
|
|
668
727
|
|
|
669
728
|
.squisq-layout-manager-main {
|
|
@@ -37,12 +37,12 @@ function safeStorage(): Storage | null {
|
|
|
37
37
|
function readPayload(): LibraryPayload {
|
|
38
38
|
const storage = safeStorage();
|
|
39
39
|
if (!storage) return { version: 1, templates: [] };
|
|
40
|
-
const raw = storage.getItem(LIBRARY_STORAGE_KEY);
|
|
41
|
-
if (!raw) return { version: 1, templates: [] };
|
|
42
40
|
try {
|
|
41
|
+
const raw = storage.getItem(LIBRARY_STORAGE_KEY);
|
|
42
|
+
if (!raw) return { version: 1, templates: [] };
|
|
43
43
|
const parsed = JSON.parse(raw) as Partial<LibraryPayload>;
|
|
44
44
|
if (parsed && Array.isArray(parsed.templates)) {
|
|
45
|
-
return { version: 1, templates: parsed.templates };
|
|
45
|
+
return { version: 1, templates: parsed.templates.filter(isTemplateDefinition) };
|
|
46
46
|
}
|
|
47
47
|
} catch {
|
|
48
48
|
// Corrupt payload — drop it.
|
|
@@ -50,6 +50,19 @@ function readPayload(): LibraryPayload {
|
|
|
50
50
|
return { version: 1, templates: [] };
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
function isTemplateDefinition(value: unknown): value is CustomTemplateDefinition {
|
|
54
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return false;
|
|
55
|
+
const candidate = value as Partial<CustomTemplateDefinition>;
|
|
56
|
+
return (
|
|
57
|
+
typeof candidate.name === 'string' &&
|
|
58
|
+
typeof candidate.label === 'string' &&
|
|
59
|
+
!!candidate.viewport &&
|
|
60
|
+
Number.isFinite(candidate.viewport.width) &&
|
|
61
|
+
Number.isFinite(candidate.viewport.height) &&
|
|
62
|
+
Array.isArray(candidate.layers)
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
53
66
|
function writePayload(payload: LibraryPayload): void {
|
|
54
67
|
const storage = safeStorage();
|
|
55
68
|
if (!storage) return;
|
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
listLibraryThemes,
|
|
35
35
|
saveLibraryTheme as saveLibraryThemeRaw,
|
|
36
36
|
deleteLibraryTheme as deleteLibraryThemeRaw,
|
|
37
|
+
THEME_LIBRARY_STORAGE_KEY,
|
|
37
38
|
} from './customThemeLibrary';
|
|
38
39
|
|
|
39
40
|
export interface CustomThemeContextValue {
|
|
@@ -96,6 +97,11 @@ export function CustomThemeProvider({
|
|
|
96
97
|
// which is enough for the single-tab common case.
|
|
97
98
|
useEffect(() => {
|
|
98
99
|
setLibraryThemes(listLibraryThemes());
|
|
100
|
+
const onStorage = (event: StorageEvent) => {
|
|
101
|
+
if (event.key === THEME_LIBRARY_STORAGE_KEY) setLibraryThemes(listLibraryThemes());
|
|
102
|
+
};
|
|
103
|
+
window.addEventListener('storage', onStorage);
|
|
104
|
+
return () => window.removeEventListener('storage', onStorage);
|
|
99
105
|
}, []);
|
|
100
106
|
|
|
101
107
|
const upsertDocTheme = useCallback(
|