@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.
- package/LICENSE +21 -0
- package/NOTICE.md +40 -0
- package/README.md +10 -2
- package/dist/index.d.ts +683 -60
- package/dist/index.js +9648 -3750
- package/dist/monaco.js +0 -1
- package/dist/styles/index.css +1160 -241
- package/package.json +10 -6
- package/dist/index.js.map +0 -1
- package/dist/monaco.js.map +0 -1
- package/src/BlockCardView.tsx +0 -121
- package/src/BlockPreviewPanel.tsx +0 -69
- package/src/BlockPropertiesPopover.tsx +0 -222
- package/src/DocumentSettingsDialog.tsx +0 -272
- package/src/DropZoneOverlay.tsx +0 -137
- package/src/EditorContext.tsx +0 -1247
- package/src/EditorShell.tsx +0 -1334
- package/src/EmojiPicker.tsx +0 -332
- package/src/FolderView.tsx +0 -131
- package/src/Icon.tsx +0 -26
- package/src/ImageEditor.tsx +0 -395
- package/src/ImageNodeView.tsx +0 -284
- package/src/ImageViewer.tsx +0 -221
- package/src/InlineIcon.ts +0 -84
- package/src/InlinePreviewGutter.tsx +0 -590
- package/src/LinkDialog.tsx +0 -276
- package/src/MediaBin.tsx +0 -500
- package/src/MentionExtension.tsx +0 -261
- package/src/OutlinePanel.tsx +0 -547
- package/src/PlainHtmlPreview.tsx +0 -277
- package/src/PreviewControls.tsx +0 -1250
- package/src/PreviewPanel.tsx +0 -422
- package/src/RawEditor.tsx +0 -731
- package/src/RecorderEntry.tsx +0 -159
- package/src/StatusBar.tsx +0 -51
- package/src/TemplateAnnotation.ts +0 -167
- package/src/TemplateContentPreview.tsx +0 -56
- package/src/TemplatePicker.tsx +0 -1314
- package/src/ThemeCustomizerPanel.tsx +0 -304
- package/src/ThemePicker.tsx +0 -433
- package/src/TimelineBlockPreview.tsx +0 -37
- package/src/TimelineTrack.tsx +0 -671
- package/src/Toolbar.tsx +0 -2587
- package/src/Tooltip.tsx +0 -142
- package/src/TransitionPicker.tsx +0 -390
- package/src/VersionHistoryPanel.tsx +0 -359
- package/src/ViewMenuPanel.tsx +0 -189
- package/src/ViewSwitcher.tsx +0 -56
- package/src/WysiwygEditor.tsx +0 -792
- package/src/__tests__/blockProperties.test.ts +0 -92
- package/src/__tests__/blockPropertiesPopoverTheme.test.tsx +0 -33
- package/src/__tests__/blockRange.test.ts +0 -105
- package/src/__tests__/blockTagActivity.test.ts +0 -183
- package/src/__tests__/buildDocumentPreviewMarkdown.test.ts +0 -75
- package/src/__tests__/buildPreviewDocContent.test.ts +0 -48
- package/src/__tests__/buildPreviewDocTransition.test.ts +0 -92
- package/src/__tests__/canvasSurfaceTextEditing.test.tsx +0 -60
- package/src/__tests__/codeContextSectionView.test.tsx +0 -97
- package/src/__tests__/codeContextZoneManager.test.ts +0 -127
- package/src/__tests__/createShapeLayer.test.ts +0 -46
- package/src/__tests__/customLayoutManagerTheme.test.tsx +0 -34
- package/src/__tests__/detectMarkdown.test.ts +0 -73
- package/src/__tests__/diffContextSections.test.ts +0 -39
- package/src/__tests__/documentSettingsDialog.test.tsx +0 -197
- package/src/__tests__/drawingShapeRoundTrip.test.ts +0 -49
- package/src/__tests__/editorScrollHandoff.test.tsx +0 -102
- package/src/__tests__/editorScrollSync.test.ts +0 -65
- package/src/__tests__/editorShellCodeContext.test.tsx +0 -86
- package/src/__tests__/editorShellProps.test.tsx +0 -485
- package/src/__tests__/embeddedMedia.test.ts +0 -48
- package/src/__tests__/emojiPicker.test.tsx +0 -93
- package/src/__tests__/fileKind.test.ts +0 -112
- package/src/__tests__/headingTransition.test.ts +0 -176
- package/src/__tests__/imageEditAffordance.test.tsx +0 -272
- package/src/__tests__/imageEditModalContract.test.tsx +0 -119
- package/src/__tests__/imageEditorShell.test.tsx +0 -94
- package/src/__tests__/imageEditorState.test.ts +0 -171
- package/src/__tests__/inlinePreviewGutter.test.tsx +0 -62
- package/src/__tests__/inlinePreviewGutterAllBlocks.test.tsx +0 -103
- package/src/__tests__/jsonEditor.test.tsx +0 -223
- package/src/__tests__/layersPanel.test.tsx +0 -167
- package/src/__tests__/layoutChildRoundTrip.test.ts +0 -71
- package/src/__tests__/linkDialogDocPicker.test.tsx +0 -137
- package/src/__tests__/majorApiTypes.test.ts +0 -26
- package/src/__tests__/mediaAttachmentFlow.test.ts +0 -110
- package/src/__tests__/mediaBinDrop.test.tsx +0 -90
- package/src/__tests__/mediaReferences.test.ts +0 -82
- package/src/__tests__/narrationSave.test.ts +0 -148
- package/src/__tests__/outlinePanel.test.tsx +0 -169
- package/src/__tests__/outlineSource.test.ts +0 -217
- package/src/__tests__/plainHtmlPreview.test.tsx +0 -125
- package/src/__tests__/presentationMode.test.tsx +0 -290
- package/src/__tests__/previewControls.test.tsx +0 -540
- package/src/__tests__/previewPanelAudioFailure.test.tsx +0 -46
- package/src/__tests__/previewPanelPresentation.test.tsx +0 -126
- package/src/__tests__/previewPanelTransforms.test.tsx +0 -117
- package/src/__tests__/propertiesPanel.test.tsx +0 -69
- package/src/__tests__/rawEditorModelIsolation.test.ts +0 -19
- package/src/__tests__/recorderFormats.test.ts +0 -146
- package/src/__tests__/recorderMediaInsert.test.ts +0 -86
- package/src/__tests__/recorderTheme.test.tsx +0 -42
- package/src/__tests__/recorderTimingJson.test.ts +0 -41
- package/src/__tests__/resolveBlockVisual.test.ts +0 -43
- package/src/__tests__/selectionConversions.test.ts +0 -80
- package/src/__tests__/statusBar.test.tsx +0 -27
- package/src/__tests__/teleprompter.test.tsx +0 -190
- package/src/__tests__/templateAnnotationRoundTrip.test.ts +0 -99
- package/src/__tests__/templateContentPreview.test.ts +0 -101
- package/src/__tests__/templatePickerMetadata.test.ts +0 -32
- package/src/__tests__/templatePickerPortal.test.tsx +0 -62
- package/src/__tests__/timelineSource.test.ts +0 -134
- package/src/__tests__/tiptapBridge.test.ts +0 -566
- package/src/__tests__/tiptapBridgeConformance.test.ts +0 -47
- package/src/__tests__/tiptapCodeBlockRoundTrip.test.ts +0 -109
- package/src/__tests__/tiptapImageRoundTrip.test.ts +0 -73
- package/src/__tests__/toolbarSelectionConversion.test.tsx +0 -164
- package/src/__tests__/tooltip.test.tsx +0 -72
- package/src/__tests__/transformStyleId.test.ts +0 -13
- package/src/__tests__/transitionCatalog.test.ts +0 -64
- package/src/__tests__/useBlockNavigator.test.tsx +0 -67
- package/src/__tests__/useImageEditor.test.tsx +0 -226
- package/src/__tests__/useJsonEditorTokens.test.ts +0 -59
- package/src/__tests__/useMediaRecorder.test.ts +0 -302
- package/src/__tests__/useTimelineClock.test.ts +0 -21
- package/src/__tests__/versionHistory.test.tsx +0 -197
- package/src/__tests__/viewMenuPanel.test.tsx +0 -130
- package/src/__tests__/wysiwygImageUpload.test.ts +0 -69
- package/src/__tests__/wysiwygTemplateBadgeFocus.test.tsx +0 -56
- package/src/asciiDiagram/AsciiDiagramExtension.ts +0 -343
- package/src/asciiDiagram/AsciiDiagramWidget.tsx +0 -254
- package/src/asciiDiagram/RepairableDiagramExtension.ts +0 -200
- package/src/asciiDiagram/__tests__/AsciiDiagramExtension.test.ts +0 -145
- package/src/asciiDiagram/__tests__/RepairableDiagramExtension.test.ts +0 -159
- package/src/asciiDiagram/__tests__/asciiDiagramCommands.test.ts +0 -284
- package/src/asciiDiagram/__tests__/asciiDiagramOps.test.ts +0 -114
- package/src/asciiDiagram/__tests__/asciiPaste.test.ts +0 -43
- package/src/asciiDiagram/asciiDiagramCommands.ts +0 -174
- package/src/asciiDiagram/asciiDiagramData.ts +0 -149
- package/src/asciiDiagram/asciiDiagramOps.ts +0 -238
- package/src/asciiDiagram/asciiPaste.ts +0 -19
- package/src/blockProperties.ts +0 -88
- package/src/blockRange.ts +0 -132
- package/src/blockSlice.ts +0 -75
- package/src/blockTagActivity.ts +0 -233
- package/src/buildDocumentPreviewMarkdown.ts +0 -168
- package/src/buildPreviewDoc.ts +0 -405
- package/src/codeContext/CodeContextSectionView.tsx +0 -124
- package/src/codeContext/CodeContextZoneManager.ts +0 -149
- package/src/codeContext/CodeContextZones.tsx +0 -121
- package/src/codeContext/diffContextSections.ts +0 -38
- package/src/codeContext/types.ts +0 -75
- package/src/customTemplates/AddBin.tsx +0 -126
- package/src/customTemplates/CustomLayoutManager.tsx +0 -234
- package/src/customTemplates/CustomTemplateContext.tsx +0 -188
- package/src/customTemplates/LayerToolbar.tsx +0 -580
- package/src/customTemplates/ShapeGlyph.tsx +0 -47
- package/src/customTemplates/TemplateDesigner.tsx +0 -433
- package/src/customTemplates/__tests__/library.test.ts +0 -96
- package/src/customTemplates/__tests__/normalizePositions.test.ts +0 -109
- package/src/customTemplates/__tests__/shapeDefs.test.ts +0 -49
- package/src/customTemplates/__tests__/useMemoryLayerAdapter.test.ts +0 -108
- package/src/customTemplates/designer.css +0 -732
- package/src/customTemplates/index.ts +0 -31
- package/src/customTemplates/library.ts +0 -110
- package/src/customTemplates/normalizePositions.ts +0 -75
- package/src/customTemplates/shapeDefs.ts +0 -131
- package/src/customTemplates/thumbnail.tsx +0 -63
- package/src/customTemplates/tokenDefs.ts +0 -60
- package/src/customTemplates/useDocCustomTemplates.ts +0 -52
- package/src/customTemplates/useMemoryLayerAdapter.ts +0 -129
- package/src/customThemes/CustomThemeContext.tsx +0 -185
- package/src/customThemes/CustomThemeDialog.tsx +0 -316
- package/src/customThemes/ImportThemeSection.tsx +0 -178
- package/src/customThemes/__tests__/CustomThemeContext.test.tsx +0 -64
- package/src/customThemes/__tests__/CustomThemeDialog.test.tsx +0 -47
- package/src/customThemes/__tests__/customThemeLibrary.test.ts +0 -60
- package/src/customThemes/__tests__/importThemeSection.test.tsx +0 -192
- package/src/customThemes/customThemeLibrary.ts +0 -100
- package/src/customThemes/index.ts +0 -37
- package/src/customThemes/themeControls.tsx +0 -229
- package/src/customThemes/themeDraft.ts +0 -288
- package/src/customThemes/useDocCustomThemes.ts +0 -49
- package/src/detectMarkdown.ts +0 -62
- package/src/diagram/DiagramCanvas.tsx +0 -259
- package/src/diagram/DiagramMaximizedOverlay.tsx +0 -46
- package/src/diagram/diagramCommands.ts +0 -604
- package/src/diagram/diagramConstants.ts +0 -17
- package/src/diagram/types.ts +0 -35
- package/src/editorScrollSync.ts +0 -73
- package/src/embeddedMedia.ts +0 -78
- package/src/emojiData.ts +0 -1317
- package/src/fileKind.ts +0 -158
- package/src/frontmatter.ts +0 -29
- package/src/frontmatterSettings.ts +0 -23
- package/src/headingTransition.ts +0 -291
- package/src/hooks/useFileDrop.ts +0 -266
- package/src/imageEditor/CanvasSurface.tsx +0 -703
- package/src/imageEditor/ImageVersionHistoryDropdown.tsx +0 -396
- package/src/imageEditor/LayersPanel.tsx +0 -218
- package/src/imageEditor/PropertiesPanel.tsx +0 -474
- package/src/imageEditor/Toolbar.tsx +0 -459
- package/src/imageEditor/createShapeLayer.ts +0 -280
- package/src/imageEditor/icons.tsx +0 -68
- package/src/imageEditor/image-editor.css +0 -574
- package/src/imageEditor/layers/EditorImageLayer.tsx +0 -45
- package/src/imageEditor/layers/EditorShapeLayer.tsx +0 -62
- package/src/imageEditor/layers/EditorTextLayer.tsx +0 -45
- package/src/imageEditor/layers/SelectionHandles.tsx +0 -86
- package/src/imageEditor/state.ts +0 -173
- package/src/imageEditor/useImageEditor.ts +0 -385
- package/src/imageEditor/useImageEditorTokens.ts +0 -70
- package/src/index.ts +0 -470
- package/src/jsonEditor/EmbeddedRichTextField.tsx +0 -81
- package/src/jsonEditor/JsonEditor.tsx +0 -81
- package/src/jsonEditor/JsonEditorContext.tsx +0 -81
- package/src/jsonEditor/RenderNode.tsx +0 -87
- package/src/jsonEditor/editors.tsx +0 -745
- package/src/jsonEditor/index.ts +0 -2
- package/src/jsonEditor/json-editor.css +0 -463
- package/src/jsonEditor/useJsonEditorTokens.ts +0 -33
- package/src/mediaDragMime.ts +0 -32
- package/src/mediaEntries.ts +0 -12
- package/src/mediaReferences.ts +0 -299
- package/src/monaco.ts +0 -35
- package/src/monacoWorkers.ts +0 -89
- package/src/outlineSource.ts +0 -171
- package/src/presentation/PresentationMode.tsx +0 -596
- package/src/rawEditorIsolation.ts +0 -18
- package/src/recorder/RecorderButton.tsx +0 -80
- package/src/recorder/RecorderModal.tsx +0 -706
- package/src/recorder/RecorderPanel.tsx +0 -77
- package/src/recorder/formats.ts +0 -159
- package/src/recorder/hooks/useMediaRecorder.ts +0 -436
- package/src/recorder/hooks/useStreamPreview.ts +0 -47
- package/src/recorder/insertMediaBlock.ts +0 -30
- package/src/recorder/sources/cameraStream.ts +0 -32
- package/src/recorder/sources/micStream.ts +0 -25
- package/src/recorder/sources/screenStream.ts +0 -162
- package/src/recorder/timingJson.ts +0 -66
- package/src/resolveBlockVisual.ts +0 -39
- package/src/scene/Scene.tsx +0 -616
- package/src/scene/SceneBlockExtension.ts +0 -205
- package/src/scene/SceneBlockToolbar.tsx +0 -201
- package/src/scene/SceneBlockWidget.tsx +0 -441
- package/src/scene/ScenePropsBar.tsx +0 -85
- package/src/scene/SceneSelection.tsx +0 -111
- package/src/scene/SceneSideToolbar.tsx +0 -89
- package/src/scene/SceneViewport.tsx +0 -106
- package/src/scene/ShapePalette.tsx +0 -196
- package/src/scene/__tests__/DiagramAdapter.test.ts +0 -142
- package/src/scene/__tests__/SceneBlockExtension.test.ts +0 -33
- package/src/scene/__tests__/bezierEdit.test.ts +0 -85
- package/src/scene/__tests__/blockLayers.test.ts +0 -57
- package/src/scene/__tests__/sceneIsolation.test.tsx +0 -119
- package/src/scene/__tests__/shapeLayers.test.ts +0 -106
- package/src/scene/__tests__/useSceneHitTest.test.ts +0 -90
- package/src/scene/__tests__/useScenePanZoom.test.ts +0 -103
- package/src/scene/adapters/DiagramAdapter.ts +0 -79
- package/src/scene/adapters/DrawingAdapter.ts +0 -420
- package/src/scene/adapters/LayoutAdapter.ts +0 -313
- package/src/scene/adapters/blockLayers.ts +0 -159
- package/src/scene/commands/SceneCommand.ts +0 -84
- package/src/scene/commands/drawingCommands.ts +0 -318
- package/src/scene/commands/layoutCommands.ts +0 -301
- package/src/scene/hooks/useSceneHitTest.ts +0 -105
- package/src/scene/hooks/useScenePanZoom.ts +0 -147
- package/src/scene/hooks/useSceneSelection.ts +0 -62
- package/src/scene/index.ts +0 -90
- package/src/scene/layers/DiagramEdges.tsx +0 -142
- package/src/scene/layers/edgeGeometry.ts +0 -104
- package/src/scene/layers/nodeCard.tsx +0 -164
- package/src/scene/layers/renderLayer.tsx +0 -70
- package/src/scene/layers/shapeLayers.ts +0 -201
- package/src/scene/paths/bezierEdit.ts +0 -208
- package/src/scene/scene.css +0 -792
- package/src/scene/text/SceneTextOverlay.tsx +0 -161
- package/src/scene/text/sceneTextChannel.ts +0 -46
- package/src/scene/text/sceneTextConfig.ts +0 -31
- package/src/scene/text/sceneTiptap.ts +0 -36
- package/src/scene/text/useSceneTextEditing.ts +0 -39
- package/src/scene/tools/ConnectTool.ts +0 -209
- package/src/scene/tools/DrawingConnectTool.ts +0 -231
- package/src/scene/tools/PathTool.ts +0 -158
- package/src/scene/tools/PlaceTool.ts +0 -47
- package/src/scene/tools/SceneTool.ts +0 -85
- package/src/scene/tools/SelectTool.ts +0 -300
- package/src/scene/tools/ShapeTool.ts +0 -143
- package/src/scene/tools/TextTool.ts +0 -72
- package/src/scene/tools/TokenTool.ts +0 -95
- package/src/scene/tools/createDrawShapeTool.ts +0 -82
- package/src/selectionConversions.ts +0 -155
- package/src/styles/ascii-diagram.css +0 -79
- package/src/styles/ascii-timeline.css +0 -596
- package/src/styles/code-context.css +0 -155
- package/src/styles/diagram.css +0 -183
- package/src/styles/editor.css +0 -6811
- package/src/styles/folder-view.css +0 -210
- package/src/styles/image-edit-affordance.css +0 -201
- package/src/styles/index.css +0 -18
- package/src/styles/tree-view.css +0 -189
- package/src/teleprompter/TeleprompterControls.tsx +0 -218
- package/src/teleprompter/TeleprompterSelfView.tsx +0 -22
- package/src/teleprompter/TeleprompterSurface.tsx +0 -267
- package/src/teleprompter/TeleprompterView.tsx +0 -338
- package/src/teleprompter/canvasRenderer.ts +0 -161
- package/src/teleprompter/floatingWindow.ts +0 -352
- package/src/teleprompter/index.ts +0 -61
- package/src/teleprompter/pcmWorklet.ts +0 -62
- package/src/teleprompter/recording/insertPreamble.ts +0 -80
- package/src/teleprompter/recording/narrationSave.ts +0 -134
- package/src/teleprompter/recording/useNarrationRecorder.ts +0 -367
- package/src/teleprompter/scrollModel.ts +0 -85
- package/src/teleprompter/teleprompterTheme.ts +0 -303
- package/src/teleprompter/types.ts +0 -38
- package/src/teleprompter/useFloatingWindow.ts +0 -74
- package/src/teleprompter/useMicAnalysis.ts +0 -211
- package/src/teleprompter/useTeleprompter.ts +0 -421
- package/src/templateContentPreviewResolver.ts +0 -360
- package/src/timeline/TimelineEditorWidget.tsx +0 -861
- package/src/timeline/TimelineViewExtension.ts +0 -252
- package/src/timeline/__tests__/TimelineEditorWidget.test.tsx +0 -414
- package/src/timeline/__tests__/TimelineViewExtension.test.ts +0 -163
- package/src/timeline/__tests__/timelineCommands.test.ts +0 -359
- package/src/timeline/__tests__/timelineOps.test.ts +0 -277
- package/src/timeline/__tests__/timelinePaste.test.ts +0 -34
- package/src/timeline/timelineCommands.ts +0 -421
- package/src/timeline/timelineData.ts +0 -54
- package/src/timeline/timelineOps.ts +0 -381
- package/src/timeline/timelinePaste.ts +0 -8
- package/src/timelineSource.ts +0 -244
- package/src/tiptap/TiptapAudio.tsx +0 -86
- package/src/tiptap/TiptapVideo.tsx +0 -119
- package/src/tiptap/useResolvedMediaSrc.ts +0 -47
- package/src/tiptapBridge.ts +0 -986
- package/src/tooltipPlacement.ts +0 -13
- package/src/transformStyleId.ts +0 -17
- package/src/transitionCatalog.ts +0 -159
- package/src/treeview/TreeOutlineWidget.tsx +0 -390
- package/src/treeview/TreeViewExtension.ts +0 -250
- package/src/treeview/__tests__/TreeOutlineWidget.test.tsx +0 -156
- package/src/treeview/__tests__/TreeViewExtension.test.ts +0 -122
- package/src/treeview/__tests__/treeOps.test.ts +0 -177
- package/src/treeview/__tests__/treePaste.test.ts +0 -40
- package/src/treeview/__tests__/treeViewCommands.test.ts +0 -179
- package/src/treeview/treeOps.ts +0 -231
- package/src/treeview/treePaste.ts +0 -13
- package/src/treeview/treeViewCommands.ts +0 -99
- package/src/treeview/treeViewData.ts +0 -41
- package/src/types/monaco-shims.d.ts +0 -10
- package/src/useBlockNavigator.ts +0 -153
- package/src/useHeadingLayout.ts +0 -294
- package/src/useMonacoLoader.ts +0 -82
- package/src/useTimelineClock.ts +0 -76
- package/src/utils/collectInlineFontAwesomeCss.ts +0 -69
- package/src/utils/dropUtils.ts +0 -136
- package/src/utils/normalizeMalformedAssetUrl.ts +0 -22
- package/src/wysiwygImageUpload.ts +0 -113
package/src/RecorderEntry.tsx
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RecorderEntry — toolbar slot that wires `RecorderPanel` from
|
|
3
|
-
* `@bendyline/squisq-recorder-react` into the editor.
|
|
4
|
-
*
|
|
5
|
-
* Reads `mediaProvider`, `workspaceContainer`, `activeView`,
|
|
6
|
-
* `tiptapEditor`, and the markdown editing helpers from
|
|
7
|
-
* `useEditorContext()`. On a successful save it:
|
|
8
|
-
* - inserts an HTML5 media element at the cursor — `<video>` for
|
|
9
|
-
* camera / screen recordings, `<audio>` for narration / mic
|
|
10
|
-
* recordings — which the markdown renderer turns into an inline
|
|
11
|
-
* `<InlineVideoPlayer>` / `<InlineAudioPlayer>` with native
|
|
12
|
-
* controls;
|
|
13
|
-
* - for narration, also annotates the nearest heading with
|
|
14
|
-
* `{[audio=filename]}` so `resolveAudioMapping()` continues to tie
|
|
15
|
-
* the recording to that block during slideshow playback;
|
|
16
|
-
* - bumps `mediaRevision` so any blob URLs the media bin cached for
|
|
17
|
-
* the previous file list are invalidated.
|
|
18
|
-
*
|
|
19
|
-
* The component returns `null` when no `mediaProvider` is wired —
|
|
20
|
-
* recording without a place to write the captured bytes is a
|
|
21
|
-
* misconfiguration, not a feature.
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
import { useCallback } from 'react';
|
|
25
|
-
import { RecorderPanel } from './recorder/RecorderPanel.js';
|
|
26
|
-
import type { RecorderSaveResult } from './recorder/RecorderModal.js';
|
|
27
|
-
import { insertMediaBlock } from './recorder/insertMediaBlock.js';
|
|
28
|
-
import { useEditorContext } from './EditorContext';
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Insert a narration annotation `{[audio=filename]}` onto the heading
|
|
32
|
-
* line currently above the cursor in the Monaco editor. Pure-text
|
|
33
|
-
* insertion at the line's end keeps the markdown valid and matches the
|
|
34
|
-
* shape `resolveAudioMapping()` reads. Returns true if a heading line
|
|
35
|
-
* was found and updated.
|
|
36
|
-
*/
|
|
37
|
-
function annotateMonacoHeading(
|
|
38
|
-
editor: NonNullable<ReturnType<typeof useEditorContext>['monacoEditor']>,
|
|
39
|
-
filename: string,
|
|
40
|
-
): boolean {
|
|
41
|
-
const model = editor.getModel();
|
|
42
|
-
if (!model) return false;
|
|
43
|
-
const position = editor.getPosition();
|
|
44
|
-
if (!position) return false;
|
|
45
|
-
// Walk upward from the cursor to find the nearest heading line.
|
|
46
|
-
for (let line = position.lineNumber; line >= 1; line--) {
|
|
47
|
-
const text = model.getLineContent(line);
|
|
48
|
-
if (!/^#{1,6}\s/.test(text)) continue;
|
|
49
|
-
// Skip if the heading already has an audio annotation — don't
|
|
50
|
-
// stomp the user's existing wiring. Add a separate annotation in
|
|
51
|
-
// that case wouldn't help either (resolveAudioMapping reads only
|
|
52
|
-
// the first audio= entry).
|
|
53
|
-
if (/\{\[audio=/.test(text)) return true;
|
|
54
|
-
const trimmed = text.replace(/\s+$/, '');
|
|
55
|
-
const insertText = ` {[audio=${filename}]}`;
|
|
56
|
-
const column = trimmed.length + 1;
|
|
57
|
-
editor.executeEdits('recorder-annotation', [
|
|
58
|
-
{
|
|
59
|
-
range: {
|
|
60
|
-
startLineNumber: line,
|
|
61
|
-
startColumn: column,
|
|
62
|
-
endLineNumber: line,
|
|
63
|
-
endColumn: column,
|
|
64
|
-
},
|
|
65
|
-
text: insertText,
|
|
66
|
-
},
|
|
67
|
-
]);
|
|
68
|
-
return true;
|
|
69
|
-
}
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export function RecorderEntry() {
|
|
74
|
-
const {
|
|
75
|
-
mediaProvider,
|
|
76
|
-
workspaceContainer,
|
|
77
|
-
activeView,
|
|
78
|
-
monacoEditor,
|
|
79
|
-
tiptapEditor,
|
|
80
|
-
insertAtCursor,
|
|
81
|
-
bumpMediaRevision,
|
|
82
|
-
markdownSource,
|
|
83
|
-
setMarkdownSource,
|
|
84
|
-
colorScheme,
|
|
85
|
-
} = useEditorContext();
|
|
86
|
-
|
|
87
|
-
const handleSave = useCallback(
|
|
88
|
-
(result: RecorderSaveResult) => {
|
|
89
|
-
bumpMediaRevision();
|
|
90
|
-
|
|
91
|
-
if (result.source === 'mic') {
|
|
92
|
-
// Narration — annotate the nearest heading (drives the
|
|
93
|
-
// slideshow narration pipeline at `core/src/doc/audioMapping.ts`)
|
|
94
|
-
// *and* insert an inline `<audio controls>` so the user can
|
|
95
|
-
// audition the recording inside the editor. The two roles are
|
|
96
|
-
// orthogonal: the annotation is metadata for playback timing,
|
|
97
|
-
// the HTML tag is an in-editor preview control.
|
|
98
|
-
if (activeView === 'raw' && monacoEditor) {
|
|
99
|
-
annotateMonacoHeading(monacoEditor, result.filename);
|
|
100
|
-
}
|
|
101
|
-
const audioTag = `<audio src="${result.relativePath}" controls></audio>`;
|
|
102
|
-
if (activeView === 'wysiwyg' && tiptapEditor) {
|
|
103
|
-
insertMediaBlock(tiptapEditor, {
|
|
104
|
-
type: 'audio',
|
|
105
|
-
attrs: { src: result.relativePath, controls: true },
|
|
106
|
-
});
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
if (activeView === 'raw' && monacoEditor) {
|
|
110
|
-
// The annotation went onto the heading line; drop the player
|
|
111
|
-
// on a fresh line at the cursor.
|
|
112
|
-
insertAtCursor(`\n\n${audioTag}\n`);
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
setMarkdownSource(markdownSource ? `${markdownSource}\n\n${audioTag}` : audioTag);
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Camera / screen / screen+mic — inline video player. We pin
|
|
120
|
-
// width=480 so the editor preview doesn't blow up to natural
|
|
121
|
-
// resolution on big monitors; the height is intrinsic, so the
|
|
122
|
-
// aspect ratio is preserved regardless of source dimensions.
|
|
123
|
-
const videoTag = `<video src="${result.relativePath}" controls width="480"></video>`;
|
|
124
|
-
if (activeView === 'wysiwyg' && tiptapEditor) {
|
|
125
|
-
insertMediaBlock(tiptapEditor, {
|
|
126
|
-
type: 'video',
|
|
127
|
-
attrs: { src: result.relativePath, controls: true, width: 480 },
|
|
128
|
-
});
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
if (activeView === 'raw' && monacoEditor) {
|
|
132
|
-
insertAtCursor(videoTag);
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
setMarkdownSource(markdownSource ? `${markdownSource}\n\n${videoTag}` : videoTag);
|
|
136
|
-
},
|
|
137
|
-
[
|
|
138
|
-
activeView,
|
|
139
|
-
monacoEditor,
|
|
140
|
-
tiptapEditor,
|
|
141
|
-
insertAtCursor,
|
|
142
|
-
bumpMediaRevision,
|
|
143
|
-
markdownSource,
|
|
144
|
-
setMarkdownSource,
|
|
145
|
-
],
|
|
146
|
-
);
|
|
147
|
-
|
|
148
|
-
if (!mediaProvider) return null;
|
|
149
|
-
|
|
150
|
-
return (
|
|
151
|
-
<RecorderPanel
|
|
152
|
-
mediaProvider={mediaProvider}
|
|
153
|
-
container={workspaceContainer}
|
|
154
|
-
colorScheme={colorScheme}
|
|
155
|
-
onSave={handleSave}
|
|
156
|
-
className="squisq-toolbar-button"
|
|
157
|
-
/>
|
|
158
|
-
);
|
|
159
|
-
}
|
package/src/StatusBar.tsx
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* StatusBar
|
|
3
|
-
*
|
|
4
|
-
* Bottom status bar showing document statistics and parse status.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { useMemo } from 'react';
|
|
8
|
-
import { countBlocks } from '@bendyline/squisq/doc';
|
|
9
|
-
import { useEditorContext } from './EditorContext';
|
|
10
|
-
|
|
11
|
-
export interface StatusBarProps {
|
|
12
|
-
/** Additional class name */
|
|
13
|
-
className?: string;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Status bar displaying document statistics: character count, word count,
|
|
18
|
-
* block count, and parse/error status.
|
|
19
|
-
*/
|
|
20
|
-
export function StatusBar({ className }: StatusBarProps) {
|
|
21
|
-
const { markdownSource, doc, parseError, isParsing } = useEditorContext();
|
|
22
|
-
|
|
23
|
-
const stats = useMemo(() => {
|
|
24
|
-
const chars = markdownSource.length;
|
|
25
|
-
const words = markdownSource.trim() ? markdownSource.trim().split(/\s+/).length : 0;
|
|
26
|
-
const lines = markdownSource.split('\n').length;
|
|
27
|
-
const blocks = doc ? countBlocks(doc.blocks) : 0;
|
|
28
|
-
return { chars, words, lines, blocks };
|
|
29
|
-
}, [markdownSource, doc]);
|
|
30
|
-
|
|
31
|
-
return (
|
|
32
|
-
<div className={`squisq-status-bar ${className || ''}`}>
|
|
33
|
-
<span className="squisq-status-item">{stats.words} words</span>
|
|
34
|
-
<span className="squisq-status-item">{stats.chars} chars</span>
|
|
35
|
-
<span className="squisq-status-item">{stats.lines} lines</span>
|
|
36
|
-
<span className="squisq-status-item">
|
|
37
|
-
{stats.blocks} {stats.blocks === 1 ? 'block' : 'blocks'}
|
|
38
|
-
</span>
|
|
39
|
-
<span className="squisq-status-spacer" />
|
|
40
|
-
{isParsing && <span className="squisq-status-item squisq-status-parsing">Parsing…</span>}
|
|
41
|
-
{parseError && (
|
|
42
|
-
<span className="squisq-status-item squisq-status-error" title={parseError}>
|
|
43
|
-
⚠ Error
|
|
44
|
-
</span>
|
|
45
|
-
)}
|
|
46
|
-
{!isParsing && !parseError && (
|
|
47
|
-
<span className="squisq-status-item squisq-status-ok">✓ OK</span>
|
|
48
|
-
)}
|
|
49
|
-
</div>
|
|
50
|
-
);
|
|
51
|
-
}
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TemplateAnnotation — Tiptap Heading Extension
|
|
3
|
-
*
|
|
4
|
-
* Extends Tiptap's built-in Heading node to support `data-template`,
|
|
5
|
-
* `data-template-params`, and `data-template-empty` HTML attributes. These
|
|
6
|
-
* attributes store the authored template annotation without exposing its raw
|
|
7
|
-
* `{[…]}` syntax in the Write view.
|
|
8
|
-
*
|
|
9
|
-
* When present, the heading renders a visible badge (styled CSS chip)
|
|
10
|
-
* showing the template name, e.g. `[chart]`.
|
|
11
|
-
*
|
|
12
|
-
* The tiptapBridge converts `### Title {[chart]}` markdown into
|
|
13
|
-
* `<h3 data-template="chart">Title</h3>` and back, so this extension
|
|
14
|
-
* ensures Tiptap's schema preserves those attributes through edits.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import Heading from '@tiptap/extension-heading';
|
|
18
|
-
import { templateLabel } from './TemplatePicker';
|
|
19
|
-
import { summarizeBlockProps } from './blockProperties';
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* HeadingWithTemplate — drop-in replacement for Tiptap's Heading that
|
|
23
|
-
* persists template annotation attributes.
|
|
24
|
-
*/
|
|
25
|
-
export const HeadingWithTemplate = Heading.extend({
|
|
26
|
-
addAttributes() {
|
|
27
|
-
return {
|
|
28
|
-
...this.parent?.(),
|
|
29
|
-
dataTemplate: {
|
|
30
|
-
default: null,
|
|
31
|
-
parseHTML: (element: HTMLElement) => element.getAttribute('data-template') || null,
|
|
32
|
-
renderHTML: (attributes: Record<string, unknown>) => {
|
|
33
|
-
if (!attributes.dataTemplate) return {};
|
|
34
|
-
return { 'data-template': attributes.dataTemplate };
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
dataTemplateParams: {
|
|
38
|
-
default: null,
|
|
39
|
-
parseHTML: (element: HTMLElement) => element.getAttribute('data-template-params') || null,
|
|
40
|
-
renderHTML: (attributes: Record<string, unknown>) => {
|
|
41
|
-
if (!attributes.dataTemplateParams) return {};
|
|
42
|
-
return { 'data-template-params': attributes.dataTemplateParams };
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
dataTemplateEmpty: {
|
|
46
|
-
default: false,
|
|
47
|
-
parseHTML: (element: HTMLElement) => element.hasAttribute('data-template-empty'),
|
|
48
|
-
renderHTML: (attributes: Record<string, unknown>) => {
|
|
49
|
-
if (!attributes.dataTemplateEmpty) return {};
|
|
50
|
-
return { 'data-template-empty': 'true' };
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
dataBlockAttrs: {
|
|
54
|
-
default: null,
|
|
55
|
-
parseHTML: (element: HTMLElement) => element.getAttribute('data-block-attrs') || null,
|
|
56
|
-
renderHTML: (attributes: Record<string, unknown>) => {
|
|
57
|
-
if (!attributes.dataBlockAttrs) return {};
|
|
58
|
-
return { 'data-block-attrs': attributes.dataBlockAttrs };
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
},
|
|
63
|
-
|
|
64
|
-
renderHTML({ node, HTMLAttributes }) {
|
|
65
|
-
const level = node.attrs.level;
|
|
66
|
-
const tag = `h${level}`;
|
|
67
|
-
const templateName = HTMLAttributes['data-template'];
|
|
68
|
-
// Concise summary of authored block properties (transition / timing),
|
|
69
|
-
// painted on the props badge so the canvas shows what's set at a glance.
|
|
70
|
-
const propsSummary = summarizeBlockProps(
|
|
71
|
-
(HTMLAttributes['data-block-attrs'] as string | undefined) ?? null,
|
|
72
|
-
(HTMLAttributes['data-template-params'] as string | undefined) ?? null,
|
|
73
|
-
);
|
|
74
|
-
|
|
75
|
-
// Render heading with a trailing badge span. The badge and its inner core
|
|
76
|
-
// have no real text content — labels/braces are painted via CSS so the
|
|
77
|
-
// template name never becomes part of serialized heading text (which
|
|
78
|
-
// would leak into markdown on round-trip).
|
|
79
|
-
//
|
|
80
|
-
// When no template is set we still render a subtle "empty" badge so
|
|
81
|
-
// authors have a visible affordance for opening the template picker
|
|
82
|
-
// straight from the heading (matches the clicky chip shown for
|
|
83
|
-
// templated headings). The empty variant has no `data-template`
|
|
84
|
-
// attribute, so the bridge treats the heading as plain on save.
|
|
85
|
-
if (templateName) {
|
|
86
|
-
return [
|
|
87
|
-
tag,
|
|
88
|
-
HTMLAttributes,
|
|
89
|
-
['span', { class: 'squisq-heading-content' }, 0],
|
|
90
|
-
[
|
|
91
|
-
'span',
|
|
92
|
-
{
|
|
93
|
-
class: 'squisq-template-badge',
|
|
94
|
-
contenteditable: 'false',
|
|
95
|
-
role: 'button',
|
|
96
|
-
tabindex: '0',
|
|
97
|
-
'aria-haspopup': 'listbox',
|
|
98
|
-
title: 'Change block type',
|
|
99
|
-
'data-template': templateName,
|
|
100
|
-
},
|
|
101
|
-
[
|
|
102
|
-
'span',
|
|
103
|
-
{
|
|
104
|
-
class: 'squisq-template-badge-core',
|
|
105
|
-
'data-template-label': templateLabel(templateName),
|
|
106
|
-
'aria-hidden': 'true',
|
|
107
|
-
},
|
|
108
|
-
],
|
|
109
|
-
],
|
|
110
|
-
propsBadgeSpec(propsSummary),
|
|
111
|
-
];
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return [
|
|
115
|
-
tag,
|
|
116
|
-
HTMLAttributes,
|
|
117
|
-
['span', { class: 'squisq-heading-content' }, 0],
|
|
118
|
-
[
|
|
119
|
-
'span',
|
|
120
|
-
{
|
|
121
|
-
class: 'squisq-template-badge squisq-template-badge--empty',
|
|
122
|
-
contenteditable: 'false',
|
|
123
|
-
role: 'button',
|
|
124
|
-
tabindex: '0',
|
|
125
|
-
'aria-haspopup': 'listbox',
|
|
126
|
-
title: 'Choose block type',
|
|
127
|
-
},
|
|
128
|
-
[
|
|
129
|
-
'span',
|
|
130
|
-
{
|
|
131
|
-
class: 'squisq-template-badge-core',
|
|
132
|
-
'data-template-label': 'Block',
|
|
133
|
-
'aria-hidden': 'true',
|
|
134
|
-
},
|
|
135
|
-
],
|
|
136
|
-
],
|
|
137
|
-
propsBadgeSpec(propsSummary),
|
|
138
|
-
];
|
|
139
|
-
},
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* The block-properties chip rendered beside the template badge — the on-canvas
|
|
144
|
-
* entry point to the {@link BlockPropertiesPopover} (transition, timing, …).
|
|
145
|
-
*
|
|
146
|
-
* Like the template badge, this is an EMPTY inert span: the sliders glyph and
|
|
147
|
-
* the optional `summary` text are painted via CSS (`::before` / `::after` with
|
|
148
|
-
* `content: attr(data-props-summary)`, using the Font Awesome font the editor
|
|
149
|
-
* already loads). Keeping it childless is deliberate — `tiptapToMarkdown`
|
|
150
|
-
* serializes the rendered heading HTML, so any real child node here would risk
|
|
151
|
-
* leaking into the markdown; a `data-*` attribute is stripped with the span.
|
|
152
|
-
* Clicks are delegated in `WysiwygEditor`.
|
|
153
|
-
*/
|
|
154
|
-
function propsBadgeSpec(summary: string): [string, Record<string, string>] {
|
|
155
|
-
const attrs: Record<string, string> = {
|
|
156
|
-
class: 'squisq-props-badge',
|
|
157
|
-
contenteditable: 'false',
|
|
158
|
-
role: 'button',
|
|
159
|
-
tabindex: '0',
|
|
160
|
-
'aria-haspopup': 'dialog',
|
|
161
|
-
title: summary ? `Block properties — ${summary}` : 'Block properties',
|
|
162
|
-
};
|
|
163
|
-
// Only set the attribute when there's something to show, so the CSS
|
|
164
|
-
// `[data-props-summary]` selector cleanly distinguishes "has properties".
|
|
165
|
-
if (summary) attrs['data-props-summary'] = summary;
|
|
166
|
-
return ['span', attrs];
|
|
167
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
2
|
-
import { BlockRenderer, MediaContext } from '@bendyline/squisq-react';
|
|
3
|
-
import {
|
|
4
|
-
resolveTemplateContentPreviewResult,
|
|
5
|
-
type TemplatePreviewSource,
|
|
6
|
-
} from './templateContentPreviewResolver';
|
|
7
|
-
|
|
8
|
-
export interface TemplateContentPreviewProps {
|
|
9
|
-
templateName: string;
|
|
10
|
-
source?: TemplatePreviewSource;
|
|
11
|
-
fallback: JSX.Element;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function TemplateContentPreview({
|
|
15
|
-
templateName,
|
|
16
|
-
source,
|
|
17
|
-
fallback,
|
|
18
|
-
}: TemplateContentPreviewProps) {
|
|
19
|
-
const preview = useMemo(
|
|
20
|
-
() => (source ? resolveTemplateContentPreviewResult(templateName, source) : null),
|
|
21
|
-
[templateName, source],
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
if (!source) return fallback;
|
|
25
|
-
|
|
26
|
-
if (!preview?.visual) {
|
|
27
|
-
if (!preview?.warning) return fallback;
|
|
28
|
-
return (
|
|
29
|
-
<div
|
|
30
|
-
className="squisq-template-gallery-content-preview squisq-template-gallery-content-preview--fallback"
|
|
31
|
-
style={{ aspectRatio: `${source.viewport.width} / ${source.viewport.height}` }}
|
|
32
|
-
aria-hidden="true"
|
|
33
|
-
>
|
|
34
|
-
<div className="squisq-template-gallery-content-preview-fallback">{fallback}</div>
|
|
35
|
-
<span className="squisq-template-gallery-content-preview-warning">{preview.warning}</span>
|
|
36
|
-
</div>
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return (
|
|
41
|
-
<div
|
|
42
|
-
className="squisq-template-gallery-content-preview"
|
|
43
|
-
style={{ aspectRatio: `${source.viewport.width} / ${source.viewport.height}` }}
|
|
44
|
-
aria-hidden="true"
|
|
45
|
-
>
|
|
46
|
-
<MediaContext.Provider value={source.mediaProvider ?? null}>
|
|
47
|
-
<BlockRenderer
|
|
48
|
-
block={preview.visual}
|
|
49
|
-
blockTime={0}
|
|
50
|
-
basePath={source.basePath ?? '/'}
|
|
51
|
-
viewport={source.viewport}
|
|
52
|
-
/>
|
|
53
|
-
</MediaContext.Provider>
|
|
54
|
-
</div>
|
|
55
|
-
);
|
|
56
|
-
}
|