@bendyline/squisq-editor-react 1.5.3 → 1.6.1
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 +57 -10
- package/dist/index.d.ts +1114 -52
- package/dist/index.js +18446 -8050
- package/dist/index.js.map +1 -1
- package/dist/styles/fa-brands-400-AHOAZHCU.woff2 +0 -0
- package/dist/styles/fa-regular-400-VRZYIBIZ.woff2 +0 -0
- package/dist/styles/fa-solid-900-MDEYK55F.woff2 +0 -0
- package/dist/styles/fa-v4compatibility-ETEVP6IB.woff2 +0 -0
- package/dist/styles/index.css +13867 -0
- package/package.json +15 -7
- package/src/BlockCardView.tsx +121 -0
- package/src/BlockPreviewPanel.tsx +69 -0
- package/src/BlockPropertiesPopover.tsx +191 -0
- package/src/EditorContext.tsx +165 -16
- package/src/EditorShell.tsx +265 -144
- package/src/FolderView.tsx +131 -0
- package/src/Icon.tsx +26 -0
- package/src/ImageEditor.tsx +69 -22
- package/src/OutlinePanel.tsx +64 -7
- package/src/PlainHtmlPreview.tsx +30 -3
- package/src/PreviewControls.tsx +491 -122
- package/src/PreviewPanel.tsx +15 -9
- package/src/RawEditor.tsx +179 -17
- package/src/RecorderEntry.tsx +9 -16
- package/src/TemplateAnnotation.ts +44 -0
- package/src/TemplatePicker.tsx +329 -54
- package/src/ThemeCustomizerPanel.tsx +30 -336
- package/src/ThemePicker.tsx +112 -3
- package/src/TimelineBlockPreview.tsx +37 -0
- package/src/TimelineTrack.tsx +671 -0
- package/src/Toolbar.tsx +544 -180
- package/src/Tooltip.tsx +22 -4
- package/src/TransitionPicker.tsx +351 -0
- package/src/VersionHistoryPanel.tsx +4 -16
- package/src/ViewMenuPanel.tsx +17 -14
- package/src/WysiwygEditor.tsx +161 -65
- package/src/__tests__/blockProperties.test.ts +92 -0
- package/src/__tests__/blockRange.test.ts +105 -0
- package/src/__tests__/buildPreviewDocTransition.test.ts +73 -0
- package/src/__tests__/codeContextSectionView.test.tsx +95 -0
- package/src/__tests__/codeContextZoneManager.test.ts +127 -0
- package/src/__tests__/createShapeLayer.test.ts +46 -0
- package/src/__tests__/diffContextSections.test.ts +39 -0
- package/src/__tests__/drawingShapeRoundTrip.test.ts +49 -0
- package/src/__tests__/editorShellCodeContext.test.tsx +86 -0
- package/src/__tests__/editorShellProps.test.tsx +96 -0
- package/src/__tests__/embeddedMedia.test.ts +48 -0
- package/src/__tests__/headingTransition.test.ts +138 -0
- package/src/__tests__/layoutChildRoundTrip.test.ts +71 -0
- package/src/__tests__/plainHtmlPreview.test.tsx +10 -8
- package/src/__tests__/previewControls.test.tsx +70 -0
- package/src/__tests__/recorderMediaInsert.test.ts +86 -0
- package/src/__tests__/templateAnnotationRoundTrip.test.ts +18 -0
- package/src/__tests__/templatePickerMetadata.test.ts +32 -0
- package/src/__tests__/timelineSource.test.ts +134 -0
- package/src/__tests__/tiptapBridge.test.ts +92 -0
- package/src/__tests__/tiptapBridgeConformance.test.ts +47 -0
- package/src/__tests__/tooltip.test.tsx +72 -0
- package/src/__tests__/transitionCatalog.test.ts +64 -0
- package/src/__tests__/useBlockNavigator.test.tsx +67 -0
- package/src/__tests__/useJsonEditorTokens.test.ts +59 -0
- package/src/__tests__/useMediaRecorder.test.ts +41 -0
- package/src/__tests__/useTimelineClock.test.ts +21 -0
- package/src/blockProperties.ts +88 -0
- package/src/blockRange.ts +132 -0
- package/src/buildPreviewDoc.ts +98 -9
- package/src/codeContext/CodeContextSectionView.tsx +124 -0
- package/src/codeContext/CodeContextZoneManager.ts +149 -0
- package/src/codeContext/CodeContextZones.tsx +121 -0
- package/src/codeContext/diffContextSections.ts +38 -0
- package/src/codeContext/types.ts +75 -0
- package/src/customTemplates/AddBin.tsx +126 -0
- package/src/customTemplates/CustomLayoutManager.tsx +233 -0
- package/src/customTemplates/CustomTemplateContext.tsx +182 -0
- package/src/customTemplates/LayerToolbar.tsx +580 -0
- package/src/customTemplates/ShapeGlyph.tsx +47 -0
- package/src/customTemplates/TemplateDesigner.tsx +430 -0
- package/src/customTemplates/__tests__/library.test.ts +88 -0
- package/src/customTemplates/__tests__/normalizePositions.test.ts +109 -0
- package/src/customTemplates/__tests__/shapeDefs.test.ts +49 -0
- package/src/customTemplates/__tests__/useMemoryLayerAdapter.test.ts +95 -0
- package/src/customTemplates/designer.css +673 -0
- package/src/customTemplates/index.ts +31 -0
- package/src/customTemplates/library.ts +97 -0
- package/src/customTemplates/normalizePositions.ts +75 -0
- package/src/customTemplates/shapeDefs.ts +131 -0
- package/src/customTemplates/thumbnail.tsx +63 -0
- package/src/customTemplates/tokenDefs.ts +60 -0
- package/src/customTemplates/useDocCustomTemplates.ts +52 -0
- package/src/customTemplates/useMemoryLayerAdapter.ts +123 -0
- package/src/customThemes/CustomThemeContext.tsx +179 -0
- package/src/customThemes/CustomThemeDialog.tsx +286 -0
- package/src/customThemes/__tests__/CustomThemeContext.test.tsx +64 -0
- package/src/customThemes/__tests__/CustomThemeDialog.test.tsx +47 -0
- package/src/customThemes/__tests__/customThemeLibrary.test.ts +51 -0
- package/src/customThemes/customThemeLibrary.ts +97 -0
- package/src/customThemes/index.ts +31 -0
- package/src/customThemes/themeControls.tsx +229 -0
- package/src/customThemes/themeDraft.ts +272 -0
- package/src/customThemes/useDocCustomThemes.ts +49 -0
- package/src/diagram/DiagramCanvas.tsx +240 -0
- package/src/diagram/DiagramExtension.ts +209 -0
- package/src/diagram/DiagramMaximizedOverlay.tsx +46 -0
- package/src/diagram/DiagramWidget.tsx +270 -0
- package/src/diagram/diagramCommands.ts +604 -0
- package/src/diagram/diagramConstants.ts +17 -0
- package/src/diagram/useDiagramData.ts +126 -0
- package/src/embeddedMedia.ts +78 -0
- package/src/frontmatter.ts +29 -0
- package/src/headingTransition.ts +231 -0
- package/src/imageEditor/CanvasSurface.tsx +383 -88
- package/src/imageEditor/PropertiesPanel.tsx +47 -1
- package/src/imageEditor/Toolbar.tsx +229 -16
- package/src/imageEditor/createShapeLayer.ts +280 -0
- package/src/imageEditor/icons.tsx +34 -114
- package/src/imageEditor/image-editor.css +54 -5
- package/src/imageEditor/state.ts +23 -3
- package/src/index.ts +109 -1
- package/src/jsonEditor/useJsonEditorTokens.ts +13 -43
- package/src/recorder/RecorderModal.tsx +120 -53
- package/src/recorder/RecorderPanel.tsx +2 -26
- package/src/recorder/hooks/useMediaRecorder.ts +17 -11
- package/src/recorder/insertMediaBlock.ts +30 -0
- package/src/resolveBlockVisual.ts +33 -0
- package/src/scene/Scene.tsx +540 -0
- package/src/scene/SceneBlockExtension.ts +198 -0
- package/src/scene/SceneBlockToolbar.tsx +201 -0
- package/src/scene/SceneBlockWidget.tsx +434 -0
- package/src/scene/ScenePropsBar.tsx +85 -0
- package/src/scene/SceneSelection.tsx +107 -0
- package/src/scene/SceneViewport.tsx +102 -0
- package/src/scene/ShapePalette.tsx +181 -0
- package/src/scene/__tests__/DiagramAdapter.test.ts +56 -0
- package/src/scene/__tests__/bezierEdit.test.ts +85 -0
- package/src/scene/__tests__/blockLayers.test.ts +57 -0
- package/src/scene/__tests__/shapeLayers.test.ts +106 -0
- package/src/scene/__tests__/useSceneHitTest.test.ts +90 -0
- package/src/scene/__tests__/useScenePanZoom.test.ts +103 -0
- package/src/scene/adapters/DiagramAdapter.ts +168 -0
- package/src/scene/adapters/DrawingAdapter.ts +415 -0
- package/src/scene/adapters/LayoutAdapter.ts +310 -0
- package/src/scene/adapters/blockLayers.ts +159 -0
- package/src/scene/commands/SceneCommand.ts +70 -0
- package/src/scene/commands/drawingCommands.ts +318 -0
- package/src/scene/commands/layoutCommands.ts +301 -0
- package/src/scene/hooks/useSceneHitTest.ts +105 -0
- package/src/scene/hooks/useScenePanZoom.ts +147 -0
- package/src/scene/hooks/useSceneSelection.ts +62 -0
- package/src/scene/index.ts +95 -0
- package/src/scene/layers/DiagramEdges.tsx +127 -0
- package/src/scene/layers/edgeGeometry.ts +77 -0
- package/src/scene/layers/nodeCard.tsx +145 -0
- package/src/scene/layers/renderLayer.tsx +70 -0
- package/src/scene/layers/shapeLayers.ts +201 -0
- package/src/scene/paths/bezierEdit.ts +208 -0
- package/src/scene/scene.css +649 -0
- package/src/scene/text/SceneTextOverlay.tsx +161 -0
- package/src/scene/text/sceneTextChannel.ts +40 -0
- package/src/scene/text/sceneTextConfig.ts +27 -0
- package/src/scene/text/sceneTiptap.ts +36 -0
- package/src/scene/text/useSceneTextEditing.ts +39 -0
- package/src/scene/tools/ConnectTool.ts +111 -0
- package/src/scene/tools/DrawingConnectTool.ts +161 -0
- package/src/scene/tools/PathTool.ts +158 -0
- package/src/scene/tools/PlaceTool.ts +47 -0
- package/src/scene/tools/SceneTool.ts +75 -0
- package/src/scene/tools/SelectTool.ts +284 -0
- package/src/scene/tools/ShapeTool.ts +144 -0
- package/src/scene/tools/TextTool.ts +72 -0
- package/src/scene/tools/TokenTool.ts +95 -0
- package/src/scene/tools/createDrawShapeTool.ts +82 -0
- package/src/styles/code-context.css +155 -0
- package/src/styles/diagram.css +183 -0
- package/src/styles/editor.css +1708 -150
- package/src/styles/folder-view.css +210 -0
- package/src/styles/image-edit-affordance.css +2 -2
- package/src/styles/index.css +5 -0
- package/src/timelineSource.ts +244 -0
- package/src/tiptapBridge.ts +115 -34
- package/src/tooltipPlacement.ts +13 -0
- package/src/transitionCatalog.ts +159 -0
- package/src/types/monaco-shims.d.ts +10 -0
- package/src/useBlockNavigator.ts +153 -0
- package/src/useMonacoLoader.ts +23 -1
- package/src/useTimelineClock.ts +76 -0
- package/src/utils/dropUtils.ts +1 -1
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DiagramWidget — the Squisq-Scene-backed canvas that sits below a
|
|
3
|
+
* `### Title {[diagram]}` heading in the WYSIWYG view.
|
|
4
|
+
*
|
|
5
|
+
* Owns the maximize toggle. Resolves the parent heading's position
|
|
6
|
+
* dynamically each render via `headingKey`, so the widget can survive
|
|
7
|
+
* attribute-only doc changes (drag commits) without going stale when
|
|
8
|
+
* content above the diagram shifts.
|
|
9
|
+
*
|
|
10
|
+
* Pushes user actions back through the `diagramCommands` helpers.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
14
|
+
import type { Editor } from '@tiptap/react';
|
|
15
|
+
import { DiagramCanvas, type DiagramCommand } from './DiagramCanvas';
|
|
16
|
+
import { DIAGRAM_TOOLS, DIAGRAM_VIEWPORT } from './diagramConstants';
|
|
17
|
+
import { DiagramMaximizedOverlay } from './DiagramMaximizedOverlay';
|
|
18
|
+
import { useDiagramData } from './useDiagramData';
|
|
19
|
+
import { findDiagramHeadingPos } from './DiagramExtension';
|
|
20
|
+
import { SceneBlockToolbar, type SceneBlockAction } from '../scene/SceneBlockToolbar';
|
|
21
|
+
import { nodeIdFromCardLayerId, NODE_WIDTH, NODE_HEIGHT } from '../scene';
|
|
22
|
+
import { Icon } from '../Icon';
|
|
23
|
+
import {
|
|
24
|
+
moveNode,
|
|
25
|
+
resizeNode,
|
|
26
|
+
addConnection,
|
|
27
|
+
removeConnection,
|
|
28
|
+
renameNode,
|
|
29
|
+
addNode,
|
|
30
|
+
removeNode,
|
|
31
|
+
getDiagramHeight,
|
|
32
|
+
setDiagramHeight,
|
|
33
|
+
} from './diagramCommands';
|
|
34
|
+
|
|
35
|
+
/** Smallest height the canvas can be dragged to (px). */
|
|
36
|
+
const MIN_DIAGRAM_HEIGHT = 160;
|
|
37
|
+
/** Default canvas height when none is pinned — must match `.squisq-diagram-inline` in diagram.css. */
|
|
38
|
+
const DEFAULT_DIAGRAM_HEIGHT = 420;
|
|
39
|
+
|
|
40
|
+
interface DiagramWidgetProps {
|
|
41
|
+
editor: Editor;
|
|
42
|
+
/** Stable id derived from the parent heading (slug / `#id`). */
|
|
43
|
+
headingKey: string;
|
|
44
|
+
/** Position of the parent heading at widget-creation time. Used as a
|
|
45
|
+
* fallback when the dynamic lookup fails (e.g. before the first
|
|
46
|
+
* transaction). */
|
|
47
|
+
fallbackParentPos: number;
|
|
48
|
+
/** Host element used for portal targeting by the maximize overlay. */
|
|
49
|
+
host?: HTMLElement | null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function DiagramWidget({ editor, headingKey, fallbackParentPos, host }: DiagramWidgetProps) {
|
|
53
|
+
// Re-resolve parentPos on every editor transaction so writes target
|
|
54
|
+
// the current heading position even after content above shifts. The same
|
|
55
|
+
// pass refreshes the pinned canvas height from the heading annotation so
|
|
56
|
+
// an external edit (or markdown reload) is reflected.
|
|
57
|
+
const [parentPos, setParentPos] = useState<number>(
|
|
58
|
+
() => findDiagramHeadingPos(editor, headingKey) ?? fallbackParentPos,
|
|
59
|
+
);
|
|
60
|
+
const [pinnedHeight, setPinnedHeight] = useState<number | null>(() =>
|
|
61
|
+
getDiagramHeight(editor, findDiagramHeadingPos(editor, headingKey) ?? fallbackParentPos),
|
|
62
|
+
);
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
const onUpdate = () => {
|
|
65
|
+
const next = findDiagramHeadingPos(editor, headingKey);
|
|
66
|
+
if (next != null && next !== parentPos) setParentPos(next);
|
|
67
|
+
setPinnedHeight(getDiagramHeight(editor, next ?? parentPos));
|
|
68
|
+
};
|
|
69
|
+
editor.on('transaction', onUpdate);
|
|
70
|
+
return () => {
|
|
71
|
+
editor.off('transaction', onUpdate);
|
|
72
|
+
};
|
|
73
|
+
}, [editor, headingKey, parentPos]);
|
|
74
|
+
|
|
75
|
+
const { nodes, edges } = useDiagramData(editor, parentPos);
|
|
76
|
+
const [maximized, setMaximized] = useState(false);
|
|
77
|
+
|
|
78
|
+
// Live height while the bottom handle is being dragged (null = not
|
|
79
|
+
// dragging). Takes precedence over the persisted height so the canvas
|
|
80
|
+
// tracks the pointer before the markdown write lands on release.
|
|
81
|
+
const [dragHeight, setDragHeight] = useState<number | null>(null);
|
|
82
|
+
const inlineRef = useRef<HTMLDivElement>(null);
|
|
83
|
+
const effectiveHeight = dragHeight ?? pinnedHeight;
|
|
84
|
+
|
|
85
|
+
const onResizeStart = useCallback(
|
|
86
|
+
(e: React.PointerEvent) => {
|
|
87
|
+
// The handle owns this gesture — keep ProseMirror and the Scene from
|
|
88
|
+
// treating it as a selection / canvas drag.
|
|
89
|
+
e.preventDefault();
|
|
90
|
+
e.stopPropagation();
|
|
91
|
+
const startY = e.clientY;
|
|
92
|
+
// Measure the live rendered height so a drag starting from the CSS
|
|
93
|
+
// default (no pinned height yet) grows from the right baseline.
|
|
94
|
+
const startHeight =
|
|
95
|
+
inlineRef.current?.getBoundingClientRect().height ??
|
|
96
|
+
effectiveHeight ??
|
|
97
|
+
DEFAULT_DIAGRAM_HEIGHT;
|
|
98
|
+
const heightAt = (clientY: number) =>
|
|
99
|
+
Math.max(MIN_DIAGRAM_HEIGHT, Math.round(startHeight + (clientY - startY)));
|
|
100
|
+
const prevCursor = document.body.style.cursor;
|
|
101
|
+
const prevSelect = document.body.style.userSelect;
|
|
102
|
+
document.body.style.cursor = 'ns-resize';
|
|
103
|
+
document.body.style.userSelect = 'none';
|
|
104
|
+
const onMove = (ev: PointerEvent) => setDragHeight(heightAt(ev.clientY));
|
|
105
|
+
const onUp = (ev: PointerEvent) => {
|
|
106
|
+
window.removeEventListener('pointermove', onMove);
|
|
107
|
+
window.removeEventListener('pointerup', onUp);
|
|
108
|
+
document.body.style.cursor = prevCursor;
|
|
109
|
+
document.body.style.userSelect = prevSelect;
|
|
110
|
+
const finalH = heightAt(ev.clientY);
|
|
111
|
+
setDragHeight(null);
|
|
112
|
+
const livePos = findDiagramHeadingPos(editor, headingKey) ?? parentPos;
|
|
113
|
+
setDiagramHeight(editor, livePos, finalH);
|
|
114
|
+
};
|
|
115
|
+
window.addEventListener('pointermove', onMove);
|
|
116
|
+
window.addEventListener('pointerup', onUp);
|
|
117
|
+
},
|
|
118
|
+
[editor, headingKey, parentPos, effectiveHeight],
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
// Double-click the handle to clear the pinned height (revert to default).
|
|
122
|
+
const onResizeReset = useCallback(() => {
|
|
123
|
+
const livePos = findDiagramHeadingPos(editor, headingKey) ?? parentPos;
|
|
124
|
+
setDragHeight(null);
|
|
125
|
+
setDiagramHeight(editor, livePos, null);
|
|
126
|
+
}, [editor, headingKey, parentPos]);
|
|
127
|
+
|
|
128
|
+
const dispatch = useCallback(
|
|
129
|
+
(cmd: DiagramCommand) => {
|
|
130
|
+
// Re-resolve at dispatch time too — the React state may not have
|
|
131
|
+
// caught up yet when the user issues rapid-fire commands.
|
|
132
|
+
const livePos = findDiagramHeadingPos(editor, headingKey) ?? parentPos;
|
|
133
|
+
switch (cmd.kind) {
|
|
134
|
+
case 'moveNode':
|
|
135
|
+
moveNode(editor, livePos, cmd.nodeId, cmd.x, cmd.y);
|
|
136
|
+
break;
|
|
137
|
+
case 'resizeNode':
|
|
138
|
+
resizeNode(editor, livePos, cmd.nodeId, cmd.width, cmd.height);
|
|
139
|
+
break;
|
|
140
|
+
case 'addConnection':
|
|
141
|
+
addConnection(editor, livePos, cmd.source, cmd.target, cmd.type);
|
|
142
|
+
break;
|
|
143
|
+
case 'removeConnection':
|
|
144
|
+
removeConnection(editor, livePos, cmd.source, cmd.target, cmd.type);
|
|
145
|
+
break;
|
|
146
|
+
case 'renameNode':
|
|
147
|
+
renameNode(editor, livePos, cmd.nodeId, cmd.newLabel);
|
|
148
|
+
break;
|
|
149
|
+
case 'addNode': {
|
|
150
|
+
const used = new Set(nodes.map((n) => n.id));
|
|
151
|
+
let i = nodes.length + 1;
|
|
152
|
+
let id = `node-${i}`;
|
|
153
|
+
while (used.has(id)) {
|
|
154
|
+
i++;
|
|
155
|
+
id = `node-${i}`;
|
|
156
|
+
}
|
|
157
|
+
addNode(editor, livePos, id, `Node ${i}`, cmd.x, cmd.y);
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
case 'removeNode':
|
|
161
|
+
removeNode(editor, livePos, cmd.nodeId);
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
[editor, headingKey, parentPos, nodes],
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
// ── Shared toolbar (above the canvas) ────────────────────
|
|
169
|
+
// Tool selection + node CRUD live here rather than inside the canvas,
|
|
170
|
+
// so diagram/drawing/layout share one consistent bar above each canvas.
|
|
171
|
+
const [activeToolId, setActiveToolId] = useState<string>('select');
|
|
172
|
+
const [selectedIds, setSelectedIds] = useState<ReadonlySet<string>>(() => new Set());
|
|
173
|
+
// Map the Scene's selected layer ids (node cards) back to node ids.
|
|
174
|
+
const selectedNodeIds = useMemo(
|
|
175
|
+
() =>
|
|
176
|
+
[...selectedIds]
|
|
177
|
+
.map((id) => nodeIdFromCardLayerId(id))
|
|
178
|
+
.filter((id): id is string => id != null),
|
|
179
|
+
[selectedIds],
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
const actions: SceneBlockAction[] = [
|
|
183
|
+
{
|
|
184
|
+
id: 'add-node',
|
|
185
|
+
label: 'Node',
|
|
186
|
+
icon: <Icon icon="fa-solid fa-plus" />,
|
|
187
|
+
title: 'Add node',
|
|
188
|
+
onClick: () =>
|
|
189
|
+
dispatch({
|
|
190
|
+
kind: 'addNode',
|
|
191
|
+
x: DIAGRAM_VIEWPORT.width / 2 - NODE_WIDTH / 2,
|
|
192
|
+
y: DIAGRAM_VIEWPORT.height / 2 - NODE_HEIGHT / 2,
|
|
193
|
+
}),
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
id: 'delete',
|
|
197
|
+
label: 'Delete',
|
|
198
|
+
icon: <Icon icon="fa-solid fa-trash" />,
|
|
199
|
+
title: 'Delete selected node',
|
|
200
|
+
danger: true,
|
|
201
|
+
disabled: selectedNodeIds.length === 0,
|
|
202
|
+
onClick: () => selectedNodeIds.forEach((id) => dispatch({ kind: 'removeNode', nodeId: id })),
|
|
203
|
+
},
|
|
204
|
+
];
|
|
205
|
+
|
|
206
|
+
const toolbar = (
|
|
207
|
+
<SceneBlockToolbar
|
|
208
|
+
tools={DIAGRAM_TOOLS}
|
|
209
|
+
activeToolId={activeToolId}
|
|
210
|
+
onSelectTool={setActiveToolId}
|
|
211
|
+
actions={actions}
|
|
212
|
+
/>
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
const canvas = (
|
|
216
|
+
<DiagramCanvas
|
|
217
|
+
nodes={nodes}
|
|
218
|
+
edges={edges}
|
|
219
|
+
onCommand={dispatch}
|
|
220
|
+
showMaximize
|
|
221
|
+
maximized={maximized}
|
|
222
|
+
onToggleMaximize={() => setMaximized((m) => !m)}
|
|
223
|
+
activeToolId={activeToolId}
|
|
224
|
+
onActiveToolIdChange={setActiveToolId}
|
|
225
|
+
onSelectionChange={setSelectedIds}
|
|
226
|
+
/>
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
const sideToolbar = <div className="squisq-scene-side-toolbar">{toolbar}</div>;
|
|
230
|
+
|
|
231
|
+
if (maximized) {
|
|
232
|
+
return (
|
|
233
|
+
<div
|
|
234
|
+
className="squisq-diagram-inline-placeholder"
|
|
235
|
+
style={effectiveHeight != null ? { height: effectiveHeight } : undefined}
|
|
236
|
+
>
|
|
237
|
+
<DiagramMaximizedOverlay host={host ?? null} onClose={() => setMaximized(false)}>
|
|
238
|
+
<div className="squisq-scene-block-max">
|
|
239
|
+
{canvas}
|
|
240
|
+
{sideToolbar}
|
|
241
|
+
</div>
|
|
242
|
+
</DiagramMaximizedOverlay>
|
|
243
|
+
</div>
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return (
|
|
248
|
+
<div className="squisq-scene-shell">
|
|
249
|
+
<div
|
|
250
|
+
className="squisq-diagram-inline"
|
|
251
|
+
ref={inlineRef}
|
|
252
|
+
style={effectiveHeight != null ? { height: effectiveHeight } : undefined}
|
|
253
|
+
>
|
|
254
|
+
{canvas}
|
|
255
|
+
<div
|
|
256
|
+
className="squisq-diagram-resize-handle"
|
|
257
|
+
onPointerDown={onResizeStart}
|
|
258
|
+
onDoubleClick={onResizeReset}
|
|
259
|
+
role="separator"
|
|
260
|
+
aria-orientation="horizontal"
|
|
261
|
+
aria-label="Resize diagram height"
|
|
262
|
+
title="Drag to resize · double-click to reset"
|
|
263
|
+
/>
|
|
264
|
+
</div>
|
|
265
|
+
{sideToolbar}
|
|
266
|
+
</div>
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export default DiagramWidget;
|