@bendyline/squisq-editor-react 1.5.2 → 1.6.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/dist/index.d.ts +757 -20
- package/dist/index.js +16910 -6844
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/BlockCardView.tsx +121 -0
- package/src/BlockPreviewPanel.tsx +69 -0
- package/src/BlockPropertiesPopover.tsx +191 -0
- package/src/EditorContext.tsx +143 -0
- package/src/EditorShell.tsx +200 -120
- package/src/FolderView.tsx +131 -0
- package/src/Icon.tsx +26 -0
- package/src/ImageEditor.tsx +69 -22
- package/src/OutlinePanel.tsx +38 -3
- package/src/PlainHtmlPreview.tsx +30 -3
- package/src/PreviewControls.tsx +180 -8
- package/src/RawEditor.tsx +216 -29
- 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 +528 -174
- package/src/Tooltip.tsx +22 -4
- package/src/TransitionPicker.tsx +351 -0
- package/src/VersionHistoryPanel.tsx +61 -31
- 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__/createShapeLayer.test.ts +46 -0
- package/src/__tests__/drawingShapeRoundTrip.test.ts +49 -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__/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__/useMediaRecorder.test.ts +24 -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/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 +77 -0
- package/src/recorder/RecorderModal.tsx +120 -53
- package/src/recorder/RecorderPanel.tsx +2 -26
- package/src/recorder/hooks/useMediaRecorder.ts +17 -2
- 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/diagram.css +183 -0
- package/src/styles/editor.css +1615 -203
- package/src/styles/folder-view.css +210 -0
- package/src/styles/image-edit-affordance.css +2 -2
- package/src/styles/index.css +4 -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 +105 -0
- package/src/useTimelineClock.ts +76 -0
- package/src/utils/dropUtils.ts +1 -1
|
@@ -1,144 +1,64 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
2
|
+
* Image-editor chrome icons. Thin wrappers around the shared {@link Icon}
|
|
3
|
+
* component, which renders Font Awesome Free glyphs via the webfont CSS
|
|
4
|
+
* imported in `styles/index.css`. Color and size flow from the parent's
|
|
5
|
+
* `color` / `font-size` (e.g. `--squisq-image-editor-text`), matching the
|
|
6
|
+
* toolbar icons so the whole editor shares one icon style.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type
|
|
9
|
+
import { Icon, type IconProps } from '../Icon';
|
|
10
10
|
|
|
11
|
-
type
|
|
11
|
+
type Props = Omit<IconProps, 'icon'>;
|
|
12
12
|
|
|
13
|
-
function
|
|
14
|
-
return
|
|
15
|
-
<svg
|
|
16
|
-
width="1em"
|
|
17
|
-
height="1em"
|
|
18
|
-
viewBox="0 0 24 24"
|
|
19
|
-
fill="none"
|
|
20
|
-
stroke="currentColor"
|
|
21
|
-
strokeWidth={1.75}
|
|
22
|
-
strokeLinecap="round"
|
|
23
|
-
strokeLinejoin="round"
|
|
24
|
-
aria-hidden="true"
|
|
25
|
-
focusable="false"
|
|
26
|
-
{...rest}
|
|
27
|
-
>
|
|
28
|
-
{children}
|
|
29
|
-
</svg>
|
|
30
|
-
);
|
|
13
|
+
export function EyeIcon(props: Props) {
|
|
14
|
+
return <Icon icon="fa-solid fa-eye" {...props} />;
|
|
31
15
|
}
|
|
32
16
|
|
|
33
|
-
export function
|
|
34
|
-
return
|
|
35
|
-
<Svg {...props}>
|
|
36
|
-
<path d="M2.5 12s3.5-6.5 9.5-6.5S21.5 12 21.5 12s-3.5 6.5-9.5 6.5S2.5 12 2.5 12Z" />
|
|
37
|
-
<circle cx="12" cy="12" r="2.75" />
|
|
38
|
-
</Svg>
|
|
39
|
-
);
|
|
17
|
+
export function EyeOffIcon(props: Props) {
|
|
18
|
+
return <Icon icon="fa-solid fa-eye-slash" {...props} />;
|
|
40
19
|
}
|
|
41
20
|
|
|
42
|
-
export function
|
|
43
|
-
return
|
|
44
|
-
<Svg {...props}>
|
|
45
|
-
<path d="M3.5 3.5l17 17" />
|
|
46
|
-
<path d="M9.5 5.7A10.6 10.6 0 0 1 12 5.5c6 0 9.5 6.5 9.5 6.5a17 17 0 0 1-3.2 4" />
|
|
47
|
-
<path d="M6.2 7.6A17 17 0 0 0 2.5 12s3.5 6.5 9.5 6.5a10.6 10.6 0 0 0 4.3-.9" />
|
|
48
|
-
<path d="M9.9 9.9a3 3 0 0 0 4.2 4.2" />
|
|
49
|
-
</Svg>
|
|
50
|
-
);
|
|
21
|
+
export function LockIcon(props: Props) {
|
|
22
|
+
return <Icon icon="fa-solid fa-lock" {...props} />;
|
|
51
23
|
}
|
|
52
24
|
|
|
53
|
-
export function
|
|
54
|
-
return
|
|
55
|
-
<Svg {...props}>
|
|
56
|
-
<rect x="5" y="11" width="14" height="9" rx="1.5" />
|
|
57
|
-
<path d="M8 11V8a4 4 0 0 1 8 0v3" />
|
|
58
|
-
</Svg>
|
|
59
|
-
);
|
|
25
|
+
export function UnlockIcon(props: Props) {
|
|
26
|
+
return <Icon icon="fa-solid fa-lock-open" {...props} />;
|
|
60
27
|
}
|
|
61
28
|
|
|
62
|
-
export function
|
|
63
|
-
return
|
|
64
|
-
<Svg {...props}>
|
|
65
|
-
<rect x="5" y="11" width="14" height="9" rx="1.5" />
|
|
66
|
-
<path d="M8 11V8a4 4 0 0 1 7.6-1.7" />
|
|
67
|
-
</Svg>
|
|
68
|
-
);
|
|
29
|
+
export function ChevronUpIcon(props: Props) {
|
|
30
|
+
return <Icon icon="fa-solid fa-chevron-up" {...props} />;
|
|
69
31
|
}
|
|
70
32
|
|
|
71
|
-
export function
|
|
72
|
-
return
|
|
73
|
-
<Svg {...props}>
|
|
74
|
-
<path d="M6 14l6-6 6 6" />
|
|
75
|
-
</Svg>
|
|
76
|
-
);
|
|
33
|
+
export function ChevronDownIcon(props: Props) {
|
|
34
|
+
return <Icon icon="fa-solid fa-chevron-down" {...props} />;
|
|
77
35
|
}
|
|
78
36
|
|
|
79
|
-
export function
|
|
80
|
-
return
|
|
81
|
-
<Svg {...props}>
|
|
82
|
-
<path d="M6 10l6 6 6-6" />
|
|
83
|
-
</Svg>
|
|
84
|
-
);
|
|
37
|
+
export function CloseIcon(props: Props) {
|
|
38
|
+
return <Icon icon="fa-solid fa-xmark" {...props} />;
|
|
85
39
|
}
|
|
86
40
|
|
|
87
|
-
export function
|
|
88
|
-
return
|
|
89
|
-
<Svg {...props}>
|
|
90
|
-
<path d="M6 6l12 12M18 6L6 18" />
|
|
91
|
-
</Svg>
|
|
92
|
-
);
|
|
41
|
+
export function CursorIcon(props: Props) {
|
|
42
|
+
return <Icon icon="fa-solid fa-arrow-pointer" {...props} />;
|
|
93
43
|
}
|
|
94
44
|
|
|
95
|
-
export function
|
|
96
|
-
return
|
|
97
|
-
<Svg {...props}>
|
|
98
|
-
<path d="M5 4l6.5 14.5 2.2-6 6-2.2L5 4Z" />
|
|
99
|
-
</Svg>
|
|
100
|
-
);
|
|
45
|
+
export function TextIcon(props: Props) {
|
|
46
|
+
return <Icon icon="fa-solid fa-font" {...props} />;
|
|
101
47
|
}
|
|
102
48
|
|
|
103
|
-
export function
|
|
104
|
-
return
|
|
105
|
-
<Svg {...props}>
|
|
106
|
-
<path d="M5 6h14M12 6v13M9 19h6" />
|
|
107
|
-
</Svg>
|
|
108
|
-
);
|
|
49
|
+
export function ShapeIcon(props: Props) {
|
|
50
|
+
return <Icon icon="fa-solid fa-shapes" {...props} />;
|
|
109
51
|
}
|
|
110
52
|
|
|
111
|
-
export function
|
|
112
|
-
return
|
|
113
|
-
<Svg {...props}>
|
|
114
|
-
<rect x="4" y="4" width="16" height="16" rx="2" />
|
|
115
|
-
</Svg>
|
|
116
|
-
);
|
|
53
|
+
export function CropIcon(props: Props) {
|
|
54
|
+
return <Icon icon="fa-solid fa-crop-simple" {...props} />;
|
|
117
55
|
}
|
|
118
56
|
|
|
119
|
-
export function
|
|
120
|
-
return
|
|
121
|
-
<Svg {...props}>
|
|
122
|
-
<path d="M7 2v15a1 1 0 0 0 1 1h15" />
|
|
123
|
-
<path d="M2 7h15a1 1 0 0 1 1 1v15" />
|
|
124
|
-
</Svg>
|
|
125
|
-
);
|
|
57
|
+
export function PlusIcon(props: Props) {
|
|
58
|
+
return <Icon icon="fa-solid fa-plus" {...props} />;
|
|
126
59
|
}
|
|
127
60
|
|
|
128
|
-
export function
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
<path d="M12 5v14M5 12h14" />
|
|
132
|
-
</Svg>
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export function NoneIcon(props: IconProps) {
|
|
137
|
-
// Used for "no fill / transparent" affordance.
|
|
138
|
-
return (
|
|
139
|
-
<Svg {...props}>
|
|
140
|
-
<circle cx="12" cy="12" r="8" />
|
|
141
|
-
<path d="M6.3 6.3l11.4 11.4" />
|
|
142
|
-
</Svg>
|
|
143
|
-
);
|
|
61
|
+
export function NoneIcon(props: Props) {
|
|
62
|
+
// "No fill / transparent" affordance.
|
|
63
|
+
return <Icon icon="fa-solid fa-ban" {...props} />;
|
|
144
64
|
}
|
|
@@ -60,6 +60,19 @@
|
|
|
60
60
|
.squisq-image-editor-tool-group--right {
|
|
61
61
|
margin-left: auto;
|
|
62
62
|
}
|
|
63
|
+
/* Read-only property value (e.g. a path shape's kind). */
|
|
64
|
+
.squisq-image-editor-readonly-value {
|
|
65
|
+
text-transform: capitalize;
|
|
66
|
+
opacity: 0.8;
|
|
67
|
+
}
|
|
68
|
+
/* Anchor for the shape palette popover that drops from the Shape tool. */
|
|
69
|
+
.squisq-image-editor-shape-trigger {
|
|
70
|
+
position: relative;
|
|
71
|
+
display: inline-flex;
|
|
72
|
+
}
|
|
73
|
+
.squisq-image-editor-shape-trigger .squisq-shape-palette {
|
|
74
|
+
z-index: 20;
|
|
75
|
+
}
|
|
63
76
|
.squisq-image-editor-tool-button {
|
|
64
77
|
background: var(--squisq-image-editor-control-bg);
|
|
65
78
|
color: inherit;
|
|
@@ -133,21 +146,28 @@
|
|
|
133
146
|
/* ── Canvas surface ────────────────────────────────────────────────── */
|
|
134
147
|
.squisq-image-editor-surface {
|
|
135
148
|
flex: 1 1 auto;
|
|
149
|
+
min-width: 0;
|
|
150
|
+
min-height: 0;
|
|
151
|
+
overflow: auto;
|
|
152
|
+
background: var(--squisq-image-editor-workspace-bg);
|
|
153
|
+
}
|
|
154
|
+
.squisq-image-editor-canvas-wrap {
|
|
136
155
|
display: flex;
|
|
137
156
|
align-items: center;
|
|
138
157
|
justify-content: center;
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
158
|
+
min-width: 100%;
|
|
159
|
+
min-height: 100%;
|
|
160
|
+
padding: 16px;
|
|
161
|
+
box-sizing: border-box;
|
|
142
162
|
}
|
|
143
163
|
.squisq-image-editor-canvas {
|
|
144
164
|
display: block;
|
|
145
|
-
|
|
146
|
-
max-height: 100%;
|
|
165
|
+
flex: 0 0 auto;
|
|
147
166
|
background: transparent;
|
|
148
167
|
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4);
|
|
149
168
|
user-select: none;
|
|
150
169
|
touch-action: none;
|
|
170
|
+
image-rendering: pixelated;
|
|
151
171
|
}
|
|
152
172
|
.squisq-image-editor-canvas--tool-text,
|
|
153
173
|
.squisq-image-editor-canvas--tool-shape {
|
|
@@ -156,6 +176,9 @@
|
|
|
156
176
|
.squisq-image-editor-canvas--tool-crop {
|
|
157
177
|
cursor: crosshair;
|
|
158
178
|
}
|
|
179
|
+
.squisq-image-editor-canvas--tool-zoom-rect {
|
|
180
|
+
cursor: zoom-in;
|
|
181
|
+
}
|
|
159
182
|
|
|
160
183
|
/* ── Layers panel ──────────────────────────────────────────────────── */
|
|
161
184
|
.squisq-image-editor-panel-header {
|
|
@@ -328,6 +351,32 @@
|
|
|
328
351
|
justify-content: center;
|
|
329
352
|
}
|
|
330
353
|
|
|
354
|
+
/* ── Zoom controls ──────────────────────────────────────────────────── */
|
|
355
|
+
.squisq-image-editor-tool-group--zoom {
|
|
356
|
+
gap: 0.15rem;
|
|
357
|
+
}
|
|
358
|
+
.squisq-image-editor-zoom-input {
|
|
359
|
+
width: 44px;
|
|
360
|
+
text-align: center;
|
|
361
|
+
background: var(--squisq-image-editor-control-bg);
|
|
362
|
+
border: 1px solid var(--squisq-image-editor-control-border);
|
|
363
|
+
color: inherit;
|
|
364
|
+
border-radius: 3px;
|
|
365
|
+
padding: 3px 2px;
|
|
366
|
+
font: inherit;
|
|
367
|
+
font-size: 12px;
|
|
368
|
+
-moz-appearance: textfield;
|
|
369
|
+
}
|
|
370
|
+
.squisq-image-editor-zoom-input::-webkit-inner-spin-button,
|
|
371
|
+
.squisq-image-editor-zoom-input::-webkit-outer-spin-button {
|
|
372
|
+
-webkit-appearance: none;
|
|
373
|
+
}
|
|
374
|
+
.squisq-image-editor-zoom-label {
|
|
375
|
+
font-size: 12px;
|
|
376
|
+
color: var(--squisq-image-editor-text-muted);
|
|
377
|
+
padding: 0 1px;
|
|
378
|
+
}
|
|
379
|
+
|
|
331
380
|
/* -- Version history dropdown --------------------------------------- */
|
|
332
381
|
.squisq-image-editor-version-dropdown {
|
|
333
382
|
position: relative;
|
package/src/imageEditor/state.ts
CHANGED
|
@@ -16,15 +16,18 @@ import {
|
|
|
16
16
|
touch,
|
|
17
17
|
} from '@bendyline/squisq/imageEdit';
|
|
18
18
|
|
|
19
|
+
// Distributive Omit: applied per union member so the discriminant (`type`) is preserved.
|
|
20
|
+
type DOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
|
|
21
|
+
|
|
19
22
|
/**
|
|
20
23
|
* Layer payload accepted by the `add-layer` action — the `id` field is
|
|
21
24
|
* optional and will be assigned by the underlying `addLayer` helper if
|
|
22
25
|
* the caller doesn't supply one.
|
|
23
26
|
*/
|
|
24
|
-
export type ImageEditLayerInput = ImageEditLayer | (
|
|
27
|
+
export type ImageEditLayerInput = ImageEditLayer | (DOmit<ImageEditLayer, 'id'> & { id?: string });
|
|
25
28
|
|
|
26
29
|
/** The currently active interaction tool. */
|
|
27
|
-
export type ImageEditorTool = 'select' | 'text' | 'shape' | 'image' | 'crop';
|
|
30
|
+
export type ImageEditorTool = 'select' | 'text' | 'shape' | 'image' | 'crop' | 'zoom-rect';
|
|
28
31
|
|
|
29
32
|
/** A pixel-space rectangle in canvas coordinates. */
|
|
30
33
|
export interface CanvasRect {
|
|
@@ -41,6 +44,12 @@ export interface ImageEditorState {
|
|
|
41
44
|
selectedLayerId: string | null;
|
|
42
45
|
/** Active tool. */
|
|
43
46
|
tool: ImageEditorTool;
|
|
47
|
+
/**
|
|
48
|
+
* The shape kind the shape tool will drop next (a drawing palette kind,
|
|
49
|
+
* e.g. `'rectangle'`, `'diamond'`, `'arrow-right'`). Set when the user
|
|
50
|
+
* picks from the shape palette; defaults to `'rectangle'`.
|
|
51
|
+
*/
|
|
52
|
+
shapeKind: string;
|
|
44
53
|
/**
|
|
45
54
|
* Dirty flag — true when the in-memory doc has unsaved changes
|
|
46
55
|
* relative to the last `markClean()` call. The hook uses this to
|
|
@@ -53,6 +62,7 @@ export type ImageEditorAction =
|
|
|
53
62
|
| { type: 'load'; doc: ImageEditDoc }
|
|
54
63
|
| { type: 'mark-clean' }
|
|
55
64
|
| { type: 'set-tool'; tool: ImageEditorTool }
|
|
65
|
+
| { type: 'set-shape-kind'; kind: string }
|
|
56
66
|
| { type: 'select'; layerId: string | null }
|
|
57
67
|
| { type: 'set-canvas'; canvas: ImageEditDoc['canvas'] }
|
|
58
68
|
| { type: 'add-layer'; layer: ImageEditLayerInput; select?: boolean }
|
|
@@ -67,6 +77,7 @@ export function initialImageEditorState(doc: ImageEditDoc): ImageEditorState {
|
|
|
67
77
|
doc,
|
|
68
78
|
selectedLayerId: null,
|
|
69
79
|
tool: 'select',
|
|
80
|
+
shapeKind: 'rectangle',
|
|
70
81
|
dirty: false,
|
|
71
82
|
};
|
|
72
83
|
}
|
|
@@ -77,7 +88,13 @@ export function imageEditorReducer(
|
|
|
77
88
|
): ImageEditorState {
|
|
78
89
|
switch (action.type) {
|
|
79
90
|
case 'load':
|
|
80
|
-
return {
|
|
91
|
+
return {
|
|
92
|
+
doc: action.doc,
|
|
93
|
+
selectedLayerId: null,
|
|
94
|
+
tool: 'select',
|
|
95
|
+
shapeKind: state.shapeKind,
|
|
96
|
+
dirty: false,
|
|
97
|
+
};
|
|
81
98
|
|
|
82
99
|
case 'mark-clean':
|
|
83
100
|
return state.dirty ? { ...state, dirty: false } : state;
|
|
@@ -85,6 +102,9 @@ export function imageEditorReducer(
|
|
|
85
102
|
case 'set-tool':
|
|
86
103
|
return state.tool === action.tool ? state : { ...state, tool: action.tool };
|
|
87
104
|
|
|
105
|
+
case 'set-shape-kind':
|
|
106
|
+
return state.shapeKind === action.kind ? state : { ...state, shapeKind: action.kind };
|
|
107
|
+
|
|
88
108
|
case 'select':
|
|
89
109
|
return state.selectedLayerId === action.layerId
|
|
90
110
|
? state
|
package/src/index.ts
CHANGED
|
@@ -21,6 +21,10 @@
|
|
|
21
21
|
export { EditorShell } from './EditorShell.js';
|
|
22
22
|
export type { EditorShellProps, EditorTheme } from './EditorShell.js';
|
|
23
23
|
|
|
24
|
+
// FolderView — standalone folder browser surface (companion to the shell)
|
|
25
|
+
export { FolderView } from './FolderView.js';
|
|
26
|
+
export type { FolderViewProps, FolderEntry } from './FolderView.js';
|
|
27
|
+
|
|
24
28
|
// Context
|
|
25
29
|
export { EditorProvider, useEditorContext } from './EditorContext.js';
|
|
26
30
|
export type {
|
|
@@ -37,8 +41,33 @@ export type {
|
|
|
37
41
|
DocumentLinkProvider,
|
|
38
42
|
ViewPreferences,
|
|
39
43
|
ThemeInheritance,
|
|
44
|
+
LayoutMode,
|
|
40
45
|
} from './EditorContext.js';
|
|
41
46
|
|
|
47
|
+
// Block-at-a-time primitives — reusable outside EditorShell. `useBlockNavigator`
|
|
48
|
+
// drives a one-block-at-a-time editing channel from any `(source, setSource)`
|
|
49
|
+
// pair; `BlockCardView` is the matching card chrome; the `blockRange` utilities
|
|
50
|
+
// are pure source-slicing helpers.
|
|
51
|
+
export { useBlockNavigator } from './useBlockNavigator.js';
|
|
52
|
+
export type { BlockNavigator, UseBlockNavigatorOptions } from './useBlockNavigator.js';
|
|
53
|
+
export { BlockCardView } from './BlockCardView.js';
|
|
54
|
+
export type { BlockCardViewProps } from './BlockCardView.js';
|
|
55
|
+
export {
|
|
56
|
+
getBlockSlices,
|
|
57
|
+
spliceBlock,
|
|
58
|
+
lineToOffset,
|
|
59
|
+
offsetToLine,
|
|
60
|
+
sliceIndexAtOffset,
|
|
61
|
+
} from './blockRange.js';
|
|
62
|
+
export type { BlockRange, BlockSlice } from './blockRange.js';
|
|
63
|
+
|
|
64
|
+
// Timeline view — the horizontal block + media track and the line-level
|
|
65
|
+
// markdown write-back helpers it commits edits through.
|
|
66
|
+
export { TimelineTrack } from './TimelineTrack.js';
|
|
67
|
+
export type { TimelineTrackProps } from './TimelineTrack.js';
|
|
68
|
+
export { formatSeconds, setBlockDurationInSource, setMediaClipInSource } from './timelineSource.js';
|
|
69
|
+
export type { MediaClipPatch } from './timelineSource.js';
|
|
70
|
+
|
|
42
71
|
// File-kind detection — useful for hosts that want to pre-decide chrome
|
|
43
72
|
// around the editor based on whether a file is markdown or code.
|
|
44
73
|
export { resolveFileKind, detectLanguageFromFileName } from './fileKind.js';
|
|
@@ -89,6 +118,35 @@ export type { OutlinePanelProps } from './OutlinePanel.js';
|
|
|
89
118
|
export { ThemeCustomizerPanel } from './ThemeCustomizerPanel.js';
|
|
90
119
|
export type { ThemeCustomizerPanelProps } from './ThemeCustomizerPanel.js';
|
|
91
120
|
export { TemplatePicker, templateLabel } from './TemplatePicker.js';
|
|
121
|
+
export { TransitionPicker } from './TransitionPicker.js';
|
|
122
|
+
export type { TransitionPickerProps } from './TransitionPicker.js';
|
|
123
|
+
export {
|
|
124
|
+
TRANSITION_GROUPS,
|
|
125
|
+
TRANSITION_ENTRIES,
|
|
126
|
+
transitionLabel,
|
|
127
|
+
findTransitionEntry,
|
|
128
|
+
} from './transitionCatalog.js';
|
|
129
|
+
export type {
|
|
130
|
+
TransitionGroup,
|
|
131
|
+
TransitionCatalogEntry,
|
|
132
|
+
DirectionModel,
|
|
133
|
+
} from './transitionCatalog.js';
|
|
134
|
+
export {
|
|
135
|
+
readHeadingLineTransition,
|
|
136
|
+
setHeadingLineTransition,
|
|
137
|
+
readBlockAttrsTransition,
|
|
138
|
+
setBlockAttrsTransition,
|
|
139
|
+
EMPTY_TRANSITION,
|
|
140
|
+
} from './headingTransition.js';
|
|
141
|
+
export type { TransitionFields } from './headingTransition.js';
|
|
142
|
+
export {
|
|
143
|
+
readBlockAttrsParams,
|
|
144
|
+
readBlockAttrsValue,
|
|
145
|
+
setBlockAttrsValue,
|
|
146
|
+
summarizeBlockProps,
|
|
147
|
+
} from './blockProperties.js';
|
|
148
|
+
export { BlockPropertiesPopover } from './BlockPropertiesPopover.js';
|
|
149
|
+
export type { BlockPropertiesPopoverProps } from './BlockPropertiesPopover.js';
|
|
92
150
|
export { InlinePreviewGutter } from './InlinePreviewGutter.js';
|
|
93
151
|
export type { InlinePreviewGutterProps } from './InlinePreviewGutter.js';
|
|
94
152
|
|
|
@@ -129,6 +187,25 @@ export { buildPreviewDoc } from './buildPreviewDoc.js';
|
|
|
129
187
|
// Tiptap extension: Heading with template annotation support
|
|
130
188
|
export { HeadingWithTemplate } from './TemplateAnnotation.js';
|
|
131
189
|
|
|
190
|
+
// Diagram editor — Tiptap extension that mounts a React-Flow canvas
|
|
191
|
+
// below any `### Title {[diagram]}` heading and hides the section's
|
|
192
|
+
// child headings (they're rendered as nodes in the canvas).
|
|
193
|
+
export { DiagramExtension } from './diagram/DiagramExtension.js';
|
|
194
|
+
export { DiagramCanvas } from './diagram/DiagramCanvas.js';
|
|
195
|
+
export type { DiagramCommand } from './diagram/DiagramCanvas.js';
|
|
196
|
+
export { DiagramWidget } from './diagram/DiagramWidget.js';
|
|
197
|
+
export { useDiagramData } from './diagram/useDiagramData.js';
|
|
198
|
+
export type { DiagramData, DiagramRFNode, DiagramRFEdge } from './diagram/useDiagramData.js';
|
|
199
|
+
export {
|
|
200
|
+
moveNode,
|
|
201
|
+
addConnection,
|
|
202
|
+
removeConnection,
|
|
203
|
+
renameNode,
|
|
204
|
+
addNode,
|
|
205
|
+
removeNode,
|
|
206
|
+
listDiagramChildren,
|
|
207
|
+
} from './diagram/diagramCommands.js';
|
|
208
|
+
|
|
132
209
|
// JSON Form — editable component
|
|
133
210
|
export { JsonEditor } from './jsonEditor/index.js';
|
|
134
211
|
export type { JsonEditorProps } from './jsonEditor/index.js';
|