@bendyline/squisq-editor-react 2.0.1 → 2.2.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.
Files changed (357) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +40 -0
  3. package/README.md +10 -2
  4. package/dist/index.d.ts +683 -60
  5. package/dist/index.js +9648 -3750
  6. package/dist/monaco.js +0 -1
  7. package/dist/styles/index.css +1160 -241
  8. package/package.json +10 -6
  9. package/dist/index.js.map +0 -1
  10. package/dist/monaco.js.map +0 -1
  11. package/src/BlockCardView.tsx +0 -121
  12. package/src/BlockPreviewPanel.tsx +0 -69
  13. package/src/BlockPropertiesPopover.tsx +0 -222
  14. package/src/DocumentSettingsDialog.tsx +0 -272
  15. package/src/DropZoneOverlay.tsx +0 -137
  16. package/src/EditorContext.tsx +0 -1247
  17. package/src/EditorShell.tsx +0 -1334
  18. package/src/EmojiPicker.tsx +0 -332
  19. package/src/FolderView.tsx +0 -131
  20. package/src/Icon.tsx +0 -26
  21. package/src/ImageEditor.tsx +0 -395
  22. package/src/ImageNodeView.tsx +0 -284
  23. package/src/ImageViewer.tsx +0 -221
  24. package/src/InlineIcon.ts +0 -84
  25. package/src/InlinePreviewGutter.tsx +0 -590
  26. package/src/LinkDialog.tsx +0 -276
  27. package/src/MediaBin.tsx +0 -500
  28. package/src/MentionExtension.tsx +0 -261
  29. package/src/OutlinePanel.tsx +0 -547
  30. package/src/PlainHtmlPreview.tsx +0 -277
  31. package/src/PreviewControls.tsx +0 -1250
  32. package/src/PreviewPanel.tsx +0 -422
  33. package/src/RawEditor.tsx +0 -731
  34. package/src/RecorderEntry.tsx +0 -159
  35. package/src/StatusBar.tsx +0 -51
  36. package/src/TemplateAnnotation.ts +0 -167
  37. package/src/TemplateContentPreview.tsx +0 -56
  38. package/src/TemplatePicker.tsx +0 -1314
  39. package/src/ThemeCustomizerPanel.tsx +0 -304
  40. package/src/ThemePicker.tsx +0 -433
  41. package/src/TimelineBlockPreview.tsx +0 -37
  42. package/src/TimelineTrack.tsx +0 -671
  43. package/src/Toolbar.tsx +0 -2587
  44. package/src/Tooltip.tsx +0 -142
  45. package/src/TransitionPicker.tsx +0 -390
  46. package/src/VersionHistoryPanel.tsx +0 -359
  47. package/src/ViewMenuPanel.tsx +0 -189
  48. package/src/ViewSwitcher.tsx +0 -56
  49. package/src/WysiwygEditor.tsx +0 -792
  50. package/src/__tests__/blockProperties.test.ts +0 -92
  51. package/src/__tests__/blockPropertiesPopoverTheme.test.tsx +0 -33
  52. package/src/__tests__/blockRange.test.ts +0 -105
  53. package/src/__tests__/blockTagActivity.test.ts +0 -183
  54. package/src/__tests__/buildDocumentPreviewMarkdown.test.ts +0 -75
  55. package/src/__tests__/buildPreviewDocContent.test.ts +0 -48
  56. package/src/__tests__/buildPreviewDocTransition.test.ts +0 -92
  57. package/src/__tests__/canvasSurfaceTextEditing.test.tsx +0 -60
  58. package/src/__tests__/codeContextSectionView.test.tsx +0 -97
  59. package/src/__tests__/codeContextZoneManager.test.ts +0 -127
  60. package/src/__tests__/createShapeLayer.test.ts +0 -46
  61. package/src/__tests__/customLayoutManagerTheme.test.tsx +0 -34
  62. package/src/__tests__/detectMarkdown.test.ts +0 -73
  63. package/src/__tests__/diffContextSections.test.ts +0 -39
  64. package/src/__tests__/documentSettingsDialog.test.tsx +0 -197
  65. package/src/__tests__/drawingShapeRoundTrip.test.ts +0 -49
  66. package/src/__tests__/editorScrollHandoff.test.tsx +0 -102
  67. package/src/__tests__/editorScrollSync.test.ts +0 -65
  68. package/src/__tests__/editorShellCodeContext.test.tsx +0 -86
  69. package/src/__tests__/editorShellProps.test.tsx +0 -485
  70. package/src/__tests__/embeddedMedia.test.ts +0 -48
  71. package/src/__tests__/emojiPicker.test.tsx +0 -93
  72. package/src/__tests__/fileKind.test.ts +0 -112
  73. package/src/__tests__/headingTransition.test.ts +0 -176
  74. package/src/__tests__/imageEditAffordance.test.tsx +0 -272
  75. package/src/__tests__/imageEditModalContract.test.tsx +0 -119
  76. package/src/__tests__/imageEditorShell.test.tsx +0 -94
  77. package/src/__tests__/imageEditorState.test.ts +0 -171
  78. package/src/__tests__/inlinePreviewGutter.test.tsx +0 -62
  79. package/src/__tests__/inlinePreviewGutterAllBlocks.test.tsx +0 -103
  80. package/src/__tests__/jsonEditor.test.tsx +0 -223
  81. package/src/__tests__/layersPanel.test.tsx +0 -167
  82. package/src/__tests__/layoutChildRoundTrip.test.ts +0 -71
  83. package/src/__tests__/linkDialogDocPicker.test.tsx +0 -137
  84. package/src/__tests__/majorApiTypes.test.ts +0 -26
  85. package/src/__tests__/mediaAttachmentFlow.test.ts +0 -110
  86. package/src/__tests__/mediaBinDrop.test.tsx +0 -90
  87. package/src/__tests__/mediaReferences.test.ts +0 -82
  88. package/src/__tests__/narrationSave.test.ts +0 -148
  89. package/src/__tests__/outlinePanel.test.tsx +0 -169
  90. package/src/__tests__/outlineSource.test.ts +0 -217
  91. package/src/__tests__/plainHtmlPreview.test.tsx +0 -125
  92. package/src/__tests__/presentationMode.test.tsx +0 -290
  93. package/src/__tests__/previewControls.test.tsx +0 -540
  94. package/src/__tests__/previewPanelAudioFailure.test.tsx +0 -46
  95. package/src/__tests__/previewPanelPresentation.test.tsx +0 -126
  96. package/src/__tests__/previewPanelTransforms.test.tsx +0 -117
  97. package/src/__tests__/propertiesPanel.test.tsx +0 -69
  98. package/src/__tests__/rawEditorModelIsolation.test.ts +0 -19
  99. package/src/__tests__/recorderFormats.test.ts +0 -146
  100. package/src/__tests__/recorderMediaInsert.test.ts +0 -86
  101. package/src/__tests__/recorderTheme.test.tsx +0 -42
  102. package/src/__tests__/recorderTimingJson.test.ts +0 -41
  103. package/src/__tests__/resolveBlockVisual.test.ts +0 -43
  104. package/src/__tests__/selectionConversions.test.ts +0 -80
  105. package/src/__tests__/statusBar.test.tsx +0 -27
  106. package/src/__tests__/teleprompter.test.tsx +0 -190
  107. package/src/__tests__/templateAnnotationRoundTrip.test.ts +0 -99
  108. package/src/__tests__/templateContentPreview.test.ts +0 -101
  109. package/src/__tests__/templatePickerMetadata.test.ts +0 -32
  110. package/src/__tests__/templatePickerPortal.test.tsx +0 -62
  111. package/src/__tests__/timelineSource.test.ts +0 -134
  112. package/src/__tests__/tiptapBridge.test.ts +0 -566
  113. package/src/__tests__/tiptapBridgeConformance.test.ts +0 -47
  114. package/src/__tests__/tiptapCodeBlockRoundTrip.test.ts +0 -109
  115. package/src/__tests__/tiptapImageRoundTrip.test.ts +0 -73
  116. package/src/__tests__/toolbarSelectionConversion.test.tsx +0 -164
  117. package/src/__tests__/tooltip.test.tsx +0 -72
  118. package/src/__tests__/transformStyleId.test.ts +0 -13
  119. package/src/__tests__/transitionCatalog.test.ts +0 -64
  120. package/src/__tests__/useBlockNavigator.test.tsx +0 -67
  121. package/src/__tests__/useImageEditor.test.tsx +0 -226
  122. package/src/__tests__/useJsonEditorTokens.test.ts +0 -59
  123. package/src/__tests__/useMediaRecorder.test.ts +0 -302
  124. package/src/__tests__/useTimelineClock.test.ts +0 -21
  125. package/src/__tests__/versionHistory.test.tsx +0 -197
  126. package/src/__tests__/viewMenuPanel.test.tsx +0 -130
  127. package/src/__tests__/wysiwygImageUpload.test.ts +0 -69
  128. package/src/__tests__/wysiwygTemplateBadgeFocus.test.tsx +0 -56
  129. package/src/asciiDiagram/AsciiDiagramExtension.ts +0 -343
  130. package/src/asciiDiagram/AsciiDiagramWidget.tsx +0 -254
  131. package/src/asciiDiagram/RepairableDiagramExtension.ts +0 -200
  132. package/src/asciiDiagram/__tests__/AsciiDiagramExtension.test.ts +0 -145
  133. package/src/asciiDiagram/__tests__/RepairableDiagramExtension.test.ts +0 -159
  134. package/src/asciiDiagram/__tests__/asciiDiagramCommands.test.ts +0 -284
  135. package/src/asciiDiagram/__tests__/asciiDiagramOps.test.ts +0 -114
  136. package/src/asciiDiagram/__tests__/asciiPaste.test.ts +0 -43
  137. package/src/asciiDiagram/asciiDiagramCommands.ts +0 -174
  138. package/src/asciiDiagram/asciiDiagramData.ts +0 -149
  139. package/src/asciiDiagram/asciiDiagramOps.ts +0 -238
  140. package/src/asciiDiagram/asciiPaste.ts +0 -19
  141. package/src/blockProperties.ts +0 -88
  142. package/src/blockRange.ts +0 -132
  143. package/src/blockSlice.ts +0 -75
  144. package/src/blockTagActivity.ts +0 -233
  145. package/src/buildDocumentPreviewMarkdown.ts +0 -168
  146. package/src/buildPreviewDoc.ts +0 -405
  147. package/src/codeContext/CodeContextSectionView.tsx +0 -124
  148. package/src/codeContext/CodeContextZoneManager.ts +0 -149
  149. package/src/codeContext/CodeContextZones.tsx +0 -121
  150. package/src/codeContext/diffContextSections.ts +0 -38
  151. package/src/codeContext/types.ts +0 -75
  152. package/src/customTemplates/AddBin.tsx +0 -126
  153. package/src/customTemplates/CustomLayoutManager.tsx +0 -234
  154. package/src/customTemplates/CustomTemplateContext.tsx +0 -188
  155. package/src/customTemplates/LayerToolbar.tsx +0 -580
  156. package/src/customTemplates/ShapeGlyph.tsx +0 -47
  157. package/src/customTemplates/TemplateDesigner.tsx +0 -433
  158. package/src/customTemplates/__tests__/library.test.ts +0 -96
  159. package/src/customTemplates/__tests__/normalizePositions.test.ts +0 -109
  160. package/src/customTemplates/__tests__/shapeDefs.test.ts +0 -49
  161. package/src/customTemplates/__tests__/useMemoryLayerAdapter.test.ts +0 -108
  162. package/src/customTemplates/designer.css +0 -732
  163. package/src/customTemplates/index.ts +0 -31
  164. package/src/customTemplates/library.ts +0 -110
  165. package/src/customTemplates/normalizePositions.ts +0 -75
  166. package/src/customTemplates/shapeDefs.ts +0 -131
  167. package/src/customTemplates/thumbnail.tsx +0 -63
  168. package/src/customTemplates/tokenDefs.ts +0 -60
  169. package/src/customTemplates/useDocCustomTemplates.ts +0 -52
  170. package/src/customTemplates/useMemoryLayerAdapter.ts +0 -129
  171. package/src/customThemes/CustomThemeContext.tsx +0 -185
  172. package/src/customThemes/CustomThemeDialog.tsx +0 -316
  173. package/src/customThemes/ImportThemeSection.tsx +0 -178
  174. package/src/customThemes/__tests__/CustomThemeContext.test.tsx +0 -64
  175. package/src/customThemes/__tests__/CustomThemeDialog.test.tsx +0 -47
  176. package/src/customThemes/__tests__/customThemeLibrary.test.ts +0 -60
  177. package/src/customThemes/__tests__/importThemeSection.test.tsx +0 -192
  178. package/src/customThemes/customThemeLibrary.ts +0 -100
  179. package/src/customThemes/index.ts +0 -37
  180. package/src/customThemes/themeControls.tsx +0 -229
  181. package/src/customThemes/themeDraft.ts +0 -288
  182. package/src/customThemes/useDocCustomThemes.ts +0 -49
  183. package/src/detectMarkdown.ts +0 -62
  184. package/src/diagram/DiagramCanvas.tsx +0 -259
  185. package/src/diagram/DiagramMaximizedOverlay.tsx +0 -46
  186. package/src/diagram/diagramCommands.ts +0 -604
  187. package/src/diagram/diagramConstants.ts +0 -17
  188. package/src/diagram/types.ts +0 -35
  189. package/src/editorScrollSync.ts +0 -73
  190. package/src/embeddedMedia.ts +0 -78
  191. package/src/emojiData.ts +0 -1317
  192. package/src/fileKind.ts +0 -158
  193. package/src/frontmatter.ts +0 -29
  194. package/src/frontmatterSettings.ts +0 -23
  195. package/src/headingTransition.ts +0 -291
  196. package/src/hooks/useFileDrop.ts +0 -266
  197. package/src/imageEditor/CanvasSurface.tsx +0 -703
  198. package/src/imageEditor/ImageVersionHistoryDropdown.tsx +0 -396
  199. package/src/imageEditor/LayersPanel.tsx +0 -218
  200. package/src/imageEditor/PropertiesPanel.tsx +0 -474
  201. package/src/imageEditor/Toolbar.tsx +0 -459
  202. package/src/imageEditor/createShapeLayer.ts +0 -280
  203. package/src/imageEditor/icons.tsx +0 -68
  204. package/src/imageEditor/image-editor.css +0 -574
  205. package/src/imageEditor/layers/EditorImageLayer.tsx +0 -45
  206. package/src/imageEditor/layers/EditorShapeLayer.tsx +0 -62
  207. package/src/imageEditor/layers/EditorTextLayer.tsx +0 -45
  208. package/src/imageEditor/layers/SelectionHandles.tsx +0 -86
  209. package/src/imageEditor/state.ts +0 -173
  210. package/src/imageEditor/useImageEditor.ts +0 -385
  211. package/src/imageEditor/useImageEditorTokens.ts +0 -70
  212. package/src/index.ts +0 -470
  213. package/src/jsonEditor/EmbeddedRichTextField.tsx +0 -81
  214. package/src/jsonEditor/JsonEditor.tsx +0 -81
  215. package/src/jsonEditor/JsonEditorContext.tsx +0 -81
  216. package/src/jsonEditor/RenderNode.tsx +0 -87
  217. package/src/jsonEditor/editors.tsx +0 -745
  218. package/src/jsonEditor/index.ts +0 -2
  219. package/src/jsonEditor/json-editor.css +0 -463
  220. package/src/jsonEditor/useJsonEditorTokens.ts +0 -33
  221. package/src/mediaDragMime.ts +0 -32
  222. package/src/mediaEntries.ts +0 -12
  223. package/src/mediaReferences.ts +0 -299
  224. package/src/monaco.ts +0 -35
  225. package/src/monacoWorkers.ts +0 -89
  226. package/src/outlineSource.ts +0 -171
  227. package/src/presentation/PresentationMode.tsx +0 -596
  228. package/src/rawEditorIsolation.ts +0 -18
  229. package/src/recorder/RecorderButton.tsx +0 -80
  230. package/src/recorder/RecorderModal.tsx +0 -706
  231. package/src/recorder/RecorderPanel.tsx +0 -77
  232. package/src/recorder/formats.ts +0 -159
  233. package/src/recorder/hooks/useMediaRecorder.ts +0 -436
  234. package/src/recorder/hooks/useStreamPreview.ts +0 -47
  235. package/src/recorder/insertMediaBlock.ts +0 -30
  236. package/src/recorder/sources/cameraStream.ts +0 -32
  237. package/src/recorder/sources/micStream.ts +0 -25
  238. package/src/recorder/sources/screenStream.ts +0 -162
  239. package/src/recorder/timingJson.ts +0 -66
  240. package/src/resolveBlockVisual.ts +0 -39
  241. package/src/scene/Scene.tsx +0 -616
  242. package/src/scene/SceneBlockExtension.ts +0 -205
  243. package/src/scene/SceneBlockToolbar.tsx +0 -201
  244. package/src/scene/SceneBlockWidget.tsx +0 -441
  245. package/src/scene/ScenePropsBar.tsx +0 -85
  246. package/src/scene/SceneSelection.tsx +0 -111
  247. package/src/scene/SceneSideToolbar.tsx +0 -89
  248. package/src/scene/SceneViewport.tsx +0 -106
  249. package/src/scene/ShapePalette.tsx +0 -196
  250. package/src/scene/__tests__/DiagramAdapter.test.ts +0 -142
  251. package/src/scene/__tests__/SceneBlockExtension.test.ts +0 -33
  252. package/src/scene/__tests__/bezierEdit.test.ts +0 -85
  253. package/src/scene/__tests__/blockLayers.test.ts +0 -57
  254. package/src/scene/__tests__/sceneIsolation.test.tsx +0 -119
  255. package/src/scene/__tests__/shapeLayers.test.ts +0 -106
  256. package/src/scene/__tests__/useSceneHitTest.test.ts +0 -90
  257. package/src/scene/__tests__/useScenePanZoom.test.ts +0 -103
  258. package/src/scene/adapters/DiagramAdapter.ts +0 -79
  259. package/src/scene/adapters/DrawingAdapter.ts +0 -420
  260. package/src/scene/adapters/LayoutAdapter.ts +0 -313
  261. package/src/scene/adapters/blockLayers.ts +0 -159
  262. package/src/scene/commands/SceneCommand.ts +0 -84
  263. package/src/scene/commands/drawingCommands.ts +0 -318
  264. package/src/scene/commands/layoutCommands.ts +0 -301
  265. package/src/scene/hooks/useSceneHitTest.ts +0 -105
  266. package/src/scene/hooks/useScenePanZoom.ts +0 -147
  267. package/src/scene/hooks/useSceneSelection.ts +0 -62
  268. package/src/scene/index.ts +0 -90
  269. package/src/scene/layers/DiagramEdges.tsx +0 -142
  270. package/src/scene/layers/edgeGeometry.ts +0 -104
  271. package/src/scene/layers/nodeCard.tsx +0 -164
  272. package/src/scene/layers/renderLayer.tsx +0 -70
  273. package/src/scene/layers/shapeLayers.ts +0 -201
  274. package/src/scene/paths/bezierEdit.ts +0 -208
  275. package/src/scene/scene.css +0 -792
  276. package/src/scene/text/SceneTextOverlay.tsx +0 -161
  277. package/src/scene/text/sceneTextChannel.ts +0 -46
  278. package/src/scene/text/sceneTextConfig.ts +0 -31
  279. package/src/scene/text/sceneTiptap.ts +0 -36
  280. package/src/scene/text/useSceneTextEditing.ts +0 -39
  281. package/src/scene/tools/ConnectTool.ts +0 -209
  282. package/src/scene/tools/DrawingConnectTool.ts +0 -231
  283. package/src/scene/tools/PathTool.ts +0 -158
  284. package/src/scene/tools/PlaceTool.ts +0 -47
  285. package/src/scene/tools/SceneTool.ts +0 -85
  286. package/src/scene/tools/SelectTool.ts +0 -300
  287. package/src/scene/tools/ShapeTool.ts +0 -143
  288. package/src/scene/tools/TextTool.ts +0 -72
  289. package/src/scene/tools/TokenTool.ts +0 -95
  290. package/src/scene/tools/createDrawShapeTool.ts +0 -82
  291. package/src/selectionConversions.ts +0 -155
  292. package/src/styles/ascii-diagram.css +0 -79
  293. package/src/styles/ascii-timeline.css +0 -596
  294. package/src/styles/code-context.css +0 -155
  295. package/src/styles/diagram.css +0 -183
  296. package/src/styles/editor.css +0 -6811
  297. package/src/styles/folder-view.css +0 -210
  298. package/src/styles/image-edit-affordance.css +0 -201
  299. package/src/styles/index.css +0 -18
  300. package/src/styles/tree-view.css +0 -189
  301. package/src/teleprompter/TeleprompterControls.tsx +0 -218
  302. package/src/teleprompter/TeleprompterSelfView.tsx +0 -22
  303. package/src/teleprompter/TeleprompterSurface.tsx +0 -267
  304. package/src/teleprompter/TeleprompterView.tsx +0 -338
  305. package/src/teleprompter/canvasRenderer.ts +0 -161
  306. package/src/teleprompter/floatingWindow.ts +0 -352
  307. package/src/teleprompter/index.ts +0 -61
  308. package/src/teleprompter/pcmWorklet.ts +0 -62
  309. package/src/teleprompter/recording/insertPreamble.ts +0 -80
  310. package/src/teleprompter/recording/narrationSave.ts +0 -134
  311. package/src/teleprompter/recording/useNarrationRecorder.ts +0 -367
  312. package/src/teleprompter/scrollModel.ts +0 -85
  313. package/src/teleprompter/teleprompterTheme.ts +0 -303
  314. package/src/teleprompter/types.ts +0 -38
  315. package/src/teleprompter/useFloatingWindow.ts +0 -74
  316. package/src/teleprompter/useMicAnalysis.ts +0 -211
  317. package/src/teleprompter/useTeleprompter.ts +0 -421
  318. package/src/templateContentPreviewResolver.ts +0 -360
  319. package/src/timeline/TimelineEditorWidget.tsx +0 -861
  320. package/src/timeline/TimelineViewExtension.ts +0 -252
  321. package/src/timeline/__tests__/TimelineEditorWidget.test.tsx +0 -414
  322. package/src/timeline/__tests__/TimelineViewExtension.test.ts +0 -163
  323. package/src/timeline/__tests__/timelineCommands.test.ts +0 -359
  324. package/src/timeline/__tests__/timelineOps.test.ts +0 -277
  325. package/src/timeline/__tests__/timelinePaste.test.ts +0 -34
  326. package/src/timeline/timelineCommands.ts +0 -421
  327. package/src/timeline/timelineData.ts +0 -54
  328. package/src/timeline/timelineOps.ts +0 -381
  329. package/src/timeline/timelinePaste.ts +0 -8
  330. package/src/timelineSource.ts +0 -244
  331. package/src/tiptap/TiptapAudio.tsx +0 -86
  332. package/src/tiptap/TiptapVideo.tsx +0 -119
  333. package/src/tiptap/useResolvedMediaSrc.ts +0 -47
  334. package/src/tiptapBridge.ts +0 -986
  335. package/src/tooltipPlacement.ts +0 -13
  336. package/src/transformStyleId.ts +0 -17
  337. package/src/transitionCatalog.ts +0 -159
  338. package/src/treeview/TreeOutlineWidget.tsx +0 -390
  339. package/src/treeview/TreeViewExtension.ts +0 -250
  340. package/src/treeview/__tests__/TreeOutlineWidget.test.tsx +0 -156
  341. package/src/treeview/__tests__/TreeViewExtension.test.ts +0 -122
  342. package/src/treeview/__tests__/treeOps.test.ts +0 -177
  343. package/src/treeview/__tests__/treePaste.test.ts +0 -40
  344. package/src/treeview/__tests__/treeViewCommands.test.ts +0 -179
  345. package/src/treeview/treeOps.ts +0 -231
  346. package/src/treeview/treePaste.ts +0 -13
  347. package/src/treeview/treeViewCommands.ts +0 -99
  348. package/src/treeview/treeViewData.ts +0 -41
  349. package/src/types/monaco-shims.d.ts +0 -10
  350. package/src/useBlockNavigator.ts +0 -153
  351. package/src/useHeadingLayout.ts +0 -294
  352. package/src/useMonacoLoader.ts +0 -82
  353. package/src/useTimelineClock.ts +0 -76
  354. package/src/utils/collectInlineFontAwesomeCss.ts +0 -69
  355. package/src/utils/dropUtils.ts +0 -136
  356. package/src/utils/normalizeMalformedAssetUrl.ts +0 -22
  357. package/src/wysiwygImageUpload.ts +0 -113
@@ -1,205 +0,0 @@
1
- /**
2
- * SceneBlockExtension — Tiptap plugin that mounts a Scene-based editor
3
- * below any heading whose `dataTemplate` is `layout` or `drawing`.
4
- *
5
- * Same shape as `DiagramExtension`: each matching heading gets a
6
- * ProseMirror widget decoration that renders a `<SceneBlockWidget>`
7
- * (React) into a contenteditable=false host. Sub-headings of the
8
- * matched block are hidden via a `data-squisq-scene-child` attribute
9
- * so the canvas is the sole visual representation of the section in
10
- * the WYSIWYG view (mirrors the diagram hide rule).
11
- */
12
-
13
- import { Extension } from '@tiptap/core';
14
- import { Plugin, PluginKey } from '@tiptap/pm/state';
15
- import { Decoration, DecorationSet } from '@tiptap/pm/view';
16
- import type { EditorState } from '@tiptap/pm/state';
17
- import type { Editor } from '@tiptap/react';
18
- import { createRoot, type Root } from 'react-dom/client';
19
- import { createElement } from 'react';
20
- import type { Node as PMNode } from '@tiptap/pm/model';
21
- import { parsePandocAttrTokens } from '@bendyline/squisq/markdown';
22
- import { SceneBlockWidget, type SceneBlockMode } from './SceneBlockWidget';
23
- import type { SceneTextChannel } from './text/sceneTextChannel';
24
-
25
- /**
26
- * Stable identifier for a layout/drawing heading — used as part of the
27
- * widget decoration's `key` so the canvas survives attribute-only doc
28
- * changes (drag/resize commits write into the heading's
29
- * `data-block-attrs`).
30
- */
31
- export function getHeadingKey(node: PMNode, position?: number): string {
32
- const raw = (node.attrs as Record<string, unknown>).dataBlockAttrs;
33
- if (typeof raw === 'string' && raw.length > 0) {
34
- const attrs = parsePandocAttrTokens(raw);
35
- if (attrs.id) return position == null ? attrs.id : `${attrs.id}@${position}`;
36
- }
37
- let text = '';
38
- node.content.forEach((child) => {
39
- if (child.isText) text += child.text ?? '';
40
- });
41
- const slug =
42
- text
43
- .toLowerCase()
44
- .replace(/[^\w\s-]/g, '')
45
- .replace(/[\s_]+/g, '-')
46
- .replace(/-+/g, '-')
47
- .replace(/^-|-$/g, '') || 'block';
48
- return position == null ? slug : `${slug}@${position}`;
49
- }
50
-
51
- /**
52
- * Find the current document position of a layout/drawing heading by
53
- * its stable key. Returns `null` if the heading no longer exists.
54
- */
55
- export function findSceneHeadingPos(
56
- editor: Editor,
57
- headingKey: string,
58
- mode: SceneBlockMode,
59
- ): number | null {
60
- const expectedTemplate = mode;
61
- let found: number | null = null;
62
- editor.state.doc.descendants((node, pos) => {
63
- if (found != null) return false;
64
- if (node.type.name !== 'heading') return;
65
- const attrs = node.attrs as { dataTemplate?: string };
66
- if (attrs.dataTemplate !== expectedTemplate) return;
67
- if (getHeadingKey(node, pos) === headingKey) {
68
- found = pos;
69
- return false;
70
- }
71
- });
72
- return found;
73
- }
74
-
75
- const KEY = new PluginKey('squisq-scene-block');
76
- const TEMPLATE_MODE: Record<string, SceneBlockMode> = {
77
- layout: 'layout',
78
- drawing: 'drawing',
79
- };
80
-
81
- interface SceneRoot {
82
- el: HTMLElement;
83
- root: Root;
84
- }
85
-
86
- function buildDecorations(
87
- state: EditorState,
88
- editor: Editor,
89
- textChannel?: SceneTextChannel,
90
- ): DecorationSet {
91
- const decos: Decoration[] = [];
92
-
93
- state.doc.descendants((node, pos) => {
94
- if (node.type.name !== 'heading') return;
95
- const attrs = node.attrs as { level: number; dataTemplate?: string };
96
- const mode = attrs.dataTemplate ? TEMPLATE_MODE[attrs.dataTemplate] : undefined;
97
- if (!mode) return;
98
- const parentDepth = attrs.level;
99
- const widgetPos = pos + node.nodeSize;
100
- const parentPos = pos;
101
- const headingKey = getHeadingKey(node, pos);
102
- decos.push(
103
- Decoration.widget(
104
- widgetPos,
105
- (view) => {
106
- const container = document.createElement('div');
107
- container.className = 'squisq-scene-widget-host';
108
- container.contentEditable = 'false';
109
- container.addEventListener('mousedown', (e) => e.stopPropagation());
110
- container.addEventListener('keydown', (e) => e.stopPropagation());
111
-
112
- const root = createRoot(container);
113
- root.render(
114
- createElement(SceneBlockWidget, {
115
- editor,
116
- headingKey,
117
- fallbackParentPos: parentPos,
118
- mode,
119
- host: view.dom.parentElement ?? view.dom,
120
- textChannel,
121
- }),
122
- );
123
-
124
- (container as HTMLElement & { __squisqSceneRoot?: SceneRoot }).__squisqSceneRoot = {
125
- el: container,
126
- root,
127
- };
128
- return container;
129
- },
130
- {
131
- destroy: (dom) => {
132
- const ref = (dom as HTMLElement & { __squisqSceneRoot?: SceneRoot }).__squisqSceneRoot;
133
- if (ref) setTimeout(() => ref.root.unmount(), 0);
134
- },
135
- side: 1,
136
- ignoreSelection: true,
137
- // Stable key so the canvas survives attribute-only doc changes
138
- // (drag/resize commits) — see DiagramExtension for the same
139
- // pattern and rationale.
140
- key: `squisq-scene-${mode}-${headingKey}`,
141
- },
142
- ),
143
- );
144
-
145
- // Hide direct sub-headings of this block — the Scene canvas is the
146
- // visible representation of any nested structure.
147
- let cursor = pos + node.nodeSize;
148
- while (cursor < state.doc.content.size) {
149
- const child = state.doc.nodeAt(cursor);
150
- if (!child) break;
151
- if (child.type.name === 'heading') {
152
- const childLevel = (child.attrs as { level: number }).level;
153
- if (childLevel <= parentDepth) break;
154
- decos.push(
155
- Decoration.node(cursor, cursor + child.nodeSize, {
156
- 'data-squisq-scene-child': 'true',
157
- }),
158
- );
159
- }
160
- cursor += child.nodeSize;
161
- }
162
- });
163
-
164
- return DecorationSet.create(state.doc, decos);
165
- }
166
-
167
- export interface SceneBlockExtensionOptions {
168
- /** When false, the extension is inert. */
169
- enabled?: boolean;
170
- textChannel?: SceneTextChannel;
171
- }
172
-
173
- export const SceneBlockExtension = Extension.create<SceneBlockExtensionOptions>({
174
- name: 'squisqSceneBlock',
175
-
176
- addOptions() {
177
- return { enabled: true };
178
- },
179
-
180
- addProseMirrorPlugins() {
181
- const editor = this.editor as Editor;
182
- const enabled = this.options.enabled !== false;
183
- if (!enabled) return [];
184
-
185
- return [
186
- new Plugin({
187
- key: KEY,
188
- state: {
189
- init: (_config, state) => buildDecorations(state, editor, this.options.textChannel),
190
- apply: (tr, oldDecos, _oldState, newState) => {
191
- if (!tr.docChanged) return oldDecos;
192
- return buildDecorations(newState, editor, this.options.textChannel);
193
- },
194
- },
195
- props: {
196
- decorations(state) {
197
- return this.getState(state);
198
- },
199
- },
200
- }),
201
- ];
202
- },
203
- });
204
-
205
- export default SceneBlockExtension;
@@ -1,201 +0,0 @@
1
- /**
2
- * SceneBlockToolbar — the shared chrome that sits *above* a diagram /
3
- * drawing / layout canvas (right-aligned, outside the canvas box) and
4
- * hosts the tools for CRUDing the block's shapes.
5
- *
6
- * It renders two groups:
7
- * - **Tools** — mode buttons that drive the Scene's `activeToolId`
8
- * (Select / Shape / Pen / Text / Connect …). Hidden when a block has
9
- * only one tool (e.g. layout's Select-only set), since a lone mode
10
- * button is noise.
11
- * - **Actions** — one-shot buttons (Create a shape, Delete the
12
- * selection, …). These are domain commands, not modes.
13
- *
14
- * Each host (DiagramWidget / SceneBlockWidget) owns the active-tool and
15
- * selection state and supplies the tools + actions appropriate to its
16
- * block type, so the bar looks and behaves consistently everywhere while
17
- * the vocabulary differs per block.
18
- */
19
-
20
- import type { ReactNode } from 'react';
21
- import type { SceneTool } from './tools/SceneTool';
22
- import { Icon } from '../Icon';
23
-
24
- export type HAlign = 'left' | 'center' | 'right';
25
- export type VAlign = 'top' | 'middle' | 'bottom';
26
-
27
- /** Text alignment controls shown when a textbox is the current selection. */
28
- export interface SceneAlignment {
29
- textAlign: HAlign;
30
- verticalAlign: VAlign;
31
- onTextAlign: (v: HAlign) => void;
32
- onVerticalAlign: (v: VAlign) => void;
33
- }
34
-
35
- export interface SceneBlockAction {
36
- id: string;
37
- label: string;
38
- /** Optional glyph/icon; falls back to the label text. */
39
- icon?: ReactNode;
40
- title?: string;
41
- onClick: () => void;
42
- disabled?: boolean;
43
- /** Render with the destructive (red) treatment — used for Delete. */
44
- danger?: boolean;
45
- }
46
-
47
- export interface SceneBlockToolbarProps {
48
- /** Mode tools that drive the Scene's active tool. */
49
- tools?: readonly SceneTool[];
50
- activeToolId?: string;
51
- onSelectTool?: (id: string) => void;
52
- /** One-shot command buttons (create / delete / …). */
53
- actions?: readonly SceneBlockAction[];
54
- /** Text-alignment controls — shown when a textbox is the selection. */
55
- alignment?: SceneAlignment;
56
- /**
57
- * Per-selection style controls (Fill / Stroke / Color swatches, connector
58
- * dropdowns) shown inline next to the tools when something is selected.
59
- */
60
- properties?: ReactNode;
61
- /**
62
- * A popover anchored *below* a specific tool button (e.g. the shape
63
- * palette under the Shape tool). Rendered as a dropdown so it pops down
64
- * from the button in the toolbar.
65
- */
66
- toolPopover?: { toolId: string; content: ReactNode };
67
- /** Extra controls rendered at the start of the bar (e.g. a shape palette). */
68
- leading?: ReactNode;
69
- }
70
-
71
- const H_ALIGNS: { value: HAlign; icon: string; label: string }[] = [
72
- { value: 'left', icon: 'fa-solid fa-align-left', label: 'Align left' },
73
- { value: 'center', icon: 'fa-solid fa-align-center', label: 'Align center' },
74
- { value: 'right', icon: 'fa-solid fa-align-right', label: 'Align right' },
75
- ];
76
-
77
- /** Vertical-align glyph: a box with a bar pinned to top / middle / bottom. */
78
- function VAlignIcon({ pos }: { pos: VAlign }) {
79
- const y = pos === 'top' ? 3.5 : pos === 'middle' ? 7.5 : 11.5;
80
- return (
81
- <svg width="14" height="14" viewBox="0 0 16 16" fill="none" aria-hidden="true">
82
- <rect x="2.5" y="1.5" width="11" height="13" rx="1" stroke="currentColor" strokeWidth="1.3" />
83
- <line
84
- x1="5"
85
- y1={y}
86
- x2="11"
87
- y2={y}
88
- stroke="currentColor"
89
- strokeWidth="2"
90
- strokeLinecap="round"
91
- />
92
- </svg>
93
- );
94
- }
95
-
96
- const V_ALIGNS: { value: VAlign; label: string }[] = [
97
- { value: 'top', label: 'Align top' },
98
- { value: 'middle', label: 'Align middle' },
99
- { value: 'bottom', label: 'Align bottom' },
100
- ];
101
-
102
- export function SceneBlockToolbar({
103
- tools = [],
104
- activeToolId,
105
- onSelectTool,
106
- actions = [],
107
- alignment,
108
- properties,
109
- toolPopover,
110
- leading,
111
- }: SceneBlockToolbarProps) {
112
- // A single mode (e.g. layout's Select) isn't worth a button — there's
113
- // nothing to switch to. Still render the bar for its actions/leading.
114
- const showTools = tools.length > 1;
115
- if (!showTools && actions.length === 0 && !leading && !alignment && !properties) return null;
116
-
117
- return (
118
- <div className="squisq-scene-block-toolbar" role="toolbar" aria-label="Canvas tools">
119
- {leading}
120
- {alignment && (
121
- <div className="squisq-scene-block-tools" aria-label="Text alignment">
122
- {H_ALIGNS.map((a) => (
123
- <button
124
- key={a.value}
125
- type="button"
126
- className={`squisq-scene-tool${alignment.textAlign === a.value ? ' squisq-scene-tool--active' : ''}`}
127
- onClick={() => alignment.onTextAlign(a.value)}
128
- title={a.label}
129
- aria-label={a.label}
130
- aria-pressed={alignment.textAlign === a.value}
131
- >
132
- <Icon icon={a.icon} />
133
- </button>
134
- ))}
135
- {V_ALIGNS.map((a) => (
136
- <button
137
- key={a.value}
138
- type="button"
139
- className={`squisq-scene-tool${alignment.verticalAlign === a.value ? ' squisq-scene-tool--active' : ''}`}
140
- onClick={() => alignment.onVerticalAlign(a.value)}
141
- title={a.label}
142
- aria-label={a.label}
143
- aria-pressed={alignment.verticalAlign === a.value}
144
- >
145
- <VAlignIcon pos={a.value} />
146
- </button>
147
- ))}
148
- </div>
149
- )}
150
- {showTools && (
151
- <div className="squisq-scene-block-tools">
152
- {tools.map((t) => {
153
- const button = (
154
- <button
155
- key={t.id}
156
- type="button"
157
- className={`squisq-scene-tool${activeToolId === t.id ? ' squisq-scene-tool--active' : ''}`}
158
- onClick={() => onSelectTool?.(t.id)}
159
- title={t.shortcut ? `${t.label} (${t.shortcut.toUpperCase()})` : t.label}
160
- aria-pressed={activeToolId === t.id}
161
- >
162
- {t.icon ?? <span className="squisq-scene-tool-label">{t.label}</span>}
163
- </button>
164
- );
165
- // Anchor a dropdown (e.g. the shape palette) below this button.
166
- if (toolPopover && toolPopover.toolId === t.id) {
167
- return (
168
- <span key={t.id} className="squisq-scene-tool-popover-anchor">
169
- {button}
170
- {toolPopover.content}
171
- </span>
172
- );
173
- }
174
- return button;
175
- })}
176
- </div>
177
- )}
178
- {properties}
179
- {actions.length > 0 && (
180
- <div className="squisq-scene-block-actions">
181
- {actions.map((a) => (
182
- <button
183
- key={a.id}
184
- type="button"
185
- className={`squisq-scene-action${a.danger ? ' squisq-scene-action--danger' : ''}`}
186
- onClick={a.onClick}
187
- disabled={a.disabled}
188
- title={a.title ?? a.label}
189
- aria-label={a.title ?? a.label}
190
- >
191
- {a.icon && <span className="squisq-scene-action-icon">{a.icon}</span>}
192
- <span className="squisq-scene-action-label">{a.label}</span>
193
- </button>
194
- ))}
195
- </div>
196
- )}
197
- </div>
198
- );
199
- }
200
-
201
- export default SceneBlockToolbar;