@bendyline/squisq-editor-react 1.5.0 → 1.5.2
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 +1991 -90
- package/dist/index.js +17088 -82
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/dist/DocumentSettingsDialog.d.ts +0 -26
- package/dist/DocumentSettingsDialog.d.ts.map +0 -1
- package/dist/DocumentSettingsDialog.js +0 -115
- package/dist/DocumentSettingsDialog.js.map +0 -1
- package/dist/DropZoneOverlay.d.ts +0 -24
- package/dist/DropZoneOverlay.d.ts.map +0 -1
- package/dist/DropZoneOverlay.js +0 -53
- package/dist/DropZoneOverlay.js.map +0 -1
- package/dist/EditorContext.d.ts +0 -391
- package/dist/EditorContext.d.ts.map +0 -1
- package/dist/EditorContext.js +0 -471
- package/dist/EditorContext.js.map +0 -1
- package/dist/EditorShell.d.ts +0 -328
- package/dist/EditorShell.d.ts.map +0 -1
- package/dist/EditorShell.js +0 -290
- package/dist/EditorShell.js.map +0 -1
- package/dist/EmojiPicker.d.ts +0 -50
- package/dist/EmojiPicker.d.ts.map +0 -1
- package/dist/EmojiPicker.js +0 -182
- package/dist/EmojiPicker.js.map +0 -1
- package/dist/ImageEditor.d.ts +0 -68
- package/dist/ImageEditor.d.ts.map +0 -1
- package/dist/ImageEditor.js +0 -166
- package/dist/ImageEditor.js.map +0 -1
- package/dist/ImageNodeView.d.ts +0 -27
- package/dist/ImageNodeView.d.ts.map +0 -1
- package/dist/ImageNodeView.js +0 -215
- package/dist/ImageNodeView.js.map +0 -1
- package/dist/ImageViewer.d.ts +0 -26
- package/dist/ImageViewer.d.ts.map +0 -1
- package/dist/ImageViewer.js +0 -119
- package/dist/ImageViewer.js.map +0 -1
- package/dist/InlineIcon.d.ts +0 -17
- package/dist/InlineIcon.d.ts.map +0 -1
- package/dist/InlineIcon.js +0 -72
- package/dist/InlineIcon.js.map +0 -1
- package/dist/InlinePreviewGutter.d.ts +0 -52
- package/dist/InlinePreviewGutter.d.ts.map +0 -1
- package/dist/InlinePreviewGutter.js +0 -397
- package/dist/InlinePreviewGutter.js.map +0 -1
- package/dist/LinkDialog.d.ts +0 -43
- package/dist/LinkDialog.d.ts.map +0 -1
- package/dist/LinkDialog.js +0 -102
- package/dist/LinkDialog.js.map +0 -1
- package/dist/MediaBin.d.ts +0 -29
- package/dist/MediaBin.d.ts.map +0 -1
- package/dist/MediaBin.js +0 -166
- package/dist/MediaBin.js.map +0 -1
- package/dist/MentionExtension.d.ts +0 -22
- package/dist/MentionExtension.d.ts.map +0 -1
- package/dist/MentionExtension.js +0 -245
- package/dist/MentionExtension.js.map +0 -1
- package/dist/OutlinePanel.d.ts +0 -17
- package/dist/OutlinePanel.d.ts.map +0 -1
- package/dist/OutlinePanel.js +0 -167
- package/dist/OutlinePanel.js.map +0 -1
- package/dist/PlainHtmlPreview.d.ts +0 -50
- package/dist/PlainHtmlPreview.d.ts.map +0 -1
- package/dist/PlainHtmlPreview.js +0 -155
- package/dist/PlainHtmlPreview.js.map +0 -1
- package/dist/PreviewControls.d.ts +0 -55
- package/dist/PreviewControls.d.ts.map +0 -1
- package/dist/PreviewControls.js +0 -277
- package/dist/PreviewControls.js.map +0 -1
- package/dist/PreviewPanel.d.ts +0 -29
- package/dist/PreviewPanel.d.ts.map +0 -1
- package/dist/PreviewPanel.js +0 -94
- package/dist/PreviewPanel.js.map +0 -1
- package/dist/RawEditor.d.ts +0 -32
- package/dist/RawEditor.d.ts.map +0 -1
- package/dist/RawEditor.js +0 -440
- package/dist/RawEditor.js.map +0 -1
- package/dist/RecorderEntry.d.ts +0 -24
- package/dist/RecorderEntry.d.ts.map +0 -1
- package/dist/RecorderEntry.js +0 -139
- package/dist/RecorderEntry.js.map +0 -1
- package/dist/StatusBar.d.ts +0 -15
- package/dist/StatusBar.d.ts.map +0 -1
- package/dist/StatusBar.js +0 -24
- package/dist/StatusBar.js.map +0 -1
- package/dist/TemplateAnnotation.d.ts +0 -20
- package/dist/TemplateAnnotation.d.ts.map +0 -1
- package/dist/TemplateAnnotation.js +0 -97
- package/dist/TemplateAnnotation.js.map +0 -1
- package/dist/TemplatePicker.d.ts +0 -53
- package/dist/TemplatePicker.d.ts.map +0 -1
- package/dist/TemplatePicker.js +0 -388
- package/dist/TemplatePicker.js.map +0 -1
- package/dist/ThemeCustomizerPanel.d.ts +0 -32
- package/dist/ThemeCustomizerPanel.d.ts.map +0 -1
- package/dist/ThemeCustomizerPanel.js +0 -256
- package/dist/ThemeCustomizerPanel.js.map +0 -1
- package/dist/ThemePicker.d.ts +0 -33
- package/dist/ThemePicker.d.ts.map +0 -1
- package/dist/ThemePicker.js +0 -148
- package/dist/ThemePicker.js.map +0 -1
- package/dist/Toolbar.d.ts +0 -36
- package/dist/Toolbar.d.ts.map +0 -1
- package/dist/Toolbar.js +0 -1001
- package/dist/Toolbar.js.map +0 -1
- package/dist/Tooltip.d.ts +0 -10
- package/dist/Tooltip.d.ts.map +0 -1
- package/dist/Tooltip.js +0 -104
- package/dist/Tooltip.js.map +0 -1
- package/dist/VersionHistoryPanel.d.ts +0 -14
- package/dist/VersionHistoryPanel.d.ts.map +0 -1
- package/dist/VersionHistoryPanel.js +0 -147
- package/dist/VersionHistoryPanel.js.map +0 -1
- package/dist/ViewMenuPanel.d.ts +0 -13
- package/dist/ViewMenuPanel.d.ts.map +0 -1
- package/dist/ViewMenuPanel.js +0 -58
- package/dist/ViewMenuPanel.js.map +0 -1
- package/dist/ViewSwitcher.d.ts +0 -14
- package/dist/ViewSwitcher.d.ts.map +0 -1
- package/dist/ViewSwitcher.js +0 -26
- package/dist/ViewSwitcher.js.map +0 -1
- package/dist/WysiwygEditor.d.ts +0 -39
- package/dist/WysiwygEditor.d.ts.map +0 -1
- package/dist/WysiwygEditor.js +0 -537
- package/dist/WysiwygEditor.js.map +0 -1
- package/dist/__tests__/detectMarkdown.test.d.ts +0 -2
- package/dist/__tests__/detectMarkdown.test.d.ts.map +0 -1
- package/dist/__tests__/detectMarkdown.test.js +0 -55
- package/dist/__tests__/detectMarkdown.test.js.map +0 -1
- package/dist/__tests__/documentSettingsDialog.test.d.ts +0 -2
- package/dist/__tests__/documentSettingsDialog.test.d.ts.map +0 -1
- package/dist/__tests__/documentSettingsDialog.test.js +0 -132
- package/dist/__tests__/documentSettingsDialog.test.js.map +0 -1
- package/dist/__tests__/emojiPicker.test.d.ts +0 -2
- package/dist/__tests__/emojiPicker.test.d.ts.map +0 -1
- package/dist/__tests__/emojiPicker.test.js +0 -111
- package/dist/__tests__/emojiPicker.test.js.map +0 -1
- package/dist/__tests__/fileKind.test.d.ts +0 -2
- package/dist/__tests__/fileKind.test.d.ts.map +0 -1
- package/dist/__tests__/fileKind.test.js +0 -94
- package/dist/__tests__/fileKind.test.js.map +0 -1
- package/dist/__tests__/imageEditAffordance.test.d.ts +0 -2
- package/dist/__tests__/imageEditAffordance.test.d.ts.map +0 -1
- package/dist/__tests__/imageEditAffordance.test.js +0 -188
- package/dist/__tests__/imageEditAffordance.test.js.map +0 -1
- package/dist/__tests__/imageEditorShell.test.d.ts +0 -2
- package/dist/__tests__/imageEditorShell.test.d.ts.map +0 -1
- package/dist/__tests__/imageEditorShell.test.js +0 -52
- package/dist/__tests__/imageEditorShell.test.js.map +0 -1
- package/dist/__tests__/imageEditorState.test.d.ts +0 -3
- package/dist/__tests__/imageEditorState.test.d.ts.map +0 -1
- package/dist/__tests__/imageEditorState.test.js +0 -148
- package/dist/__tests__/imageEditorState.test.js.map +0 -1
- package/dist/__tests__/inlinePreviewGutter.test.d.ts +0 -2
- package/dist/__tests__/inlinePreviewGutter.test.d.ts.map +0 -1
- package/dist/__tests__/inlinePreviewGutter.test.js +0 -51
- package/dist/__tests__/inlinePreviewGutter.test.js.map +0 -1
- package/dist/__tests__/inlinePreviewGutterAllBlocks.test.d.ts +0 -2
- package/dist/__tests__/inlinePreviewGutterAllBlocks.test.d.ts.map +0 -1
- package/dist/__tests__/inlinePreviewGutterAllBlocks.test.js +0 -63
- package/dist/__tests__/inlinePreviewGutterAllBlocks.test.js.map +0 -1
- package/dist/__tests__/jsonEditor.test.d.ts +0 -2
- package/dist/__tests__/jsonEditor.test.d.ts.map +0 -1
- package/dist/__tests__/jsonEditor.test.js +0 -134
- package/dist/__tests__/jsonEditor.test.js.map +0 -1
- package/dist/__tests__/layersPanel.test.d.ts +0 -2
- package/dist/__tests__/layersPanel.test.d.ts.map +0 -1
- package/dist/__tests__/layersPanel.test.js +0 -84
- package/dist/__tests__/layersPanel.test.js.map +0 -1
- package/dist/__tests__/linkDialogDocPicker.test.d.ts +0 -7
- package/dist/__tests__/linkDialogDocPicker.test.d.ts.map +0 -1
- package/dist/__tests__/linkDialogDocPicker.test.js +0 -75
- package/dist/__tests__/linkDialogDocPicker.test.js.map +0 -1
- package/dist/__tests__/mediaAttachmentFlow.test.d.ts +0 -2
- package/dist/__tests__/mediaAttachmentFlow.test.d.ts.map +0 -1
- package/dist/__tests__/mediaAttachmentFlow.test.js +0 -99
- package/dist/__tests__/mediaAttachmentFlow.test.js.map +0 -1
- package/dist/__tests__/outlinePanel.test.d.ts +0 -2
- package/dist/__tests__/outlinePanel.test.d.ts.map +0 -1
- package/dist/__tests__/outlinePanel.test.js +0 -68
- package/dist/__tests__/outlinePanel.test.js.map +0 -1
- package/dist/__tests__/plainHtmlPreview.test.d.ts +0 -2
- package/dist/__tests__/plainHtmlPreview.test.d.ts.map +0 -1
- package/dist/__tests__/plainHtmlPreview.test.js +0 -87
- package/dist/__tests__/plainHtmlPreview.test.js.map +0 -1
- package/dist/__tests__/propertiesPanel.test.d.ts +0 -2
- package/dist/__tests__/propertiesPanel.test.d.ts.map +0 -1
- package/dist/__tests__/propertiesPanel.test.js +0 -64
- package/dist/__tests__/propertiesPanel.test.js.map +0 -1
- package/dist/__tests__/recorderFormats.test.d.ts +0 -2
- package/dist/__tests__/recorderFormats.test.d.ts.map +0 -1
- package/dist/__tests__/recorderFormats.test.js +0 -121
- package/dist/__tests__/recorderFormats.test.js.map +0 -1
- package/dist/__tests__/recorderTimingJson.test.d.ts +0 -2
- package/dist/__tests__/recorderTimingJson.test.d.ts.map +0 -1
- package/dist/__tests__/recorderTimingJson.test.js +0 -37
- package/dist/__tests__/recorderTimingJson.test.js.map +0 -1
- package/dist/__tests__/templateAnnotationRoundTrip.test.d.ts +0 -2
- package/dist/__tests__/templateAnnotationRoundTrip.test.d.ts.map +0 -1
- package/dist/__tests__/templateAnnotationRoundTrip.test.js +0 -31
- package/dist/__tests__/templateAnnotationRoundTrip.test.js.map +0 -1
- package/dist/__tests__/tiptapBridge.test.d.ts +0 -2
- package/dist/__tests__/tiptapBridge.test.d.ts.map +0 -1
- package/dist/__tests__/tiptapBridge.test.js +0 -303
- package/dist/__tests__/tiptapBridge.test.js.map +0 -1
- package/dist/__tests__/tiptapImageRoundTrip.test.d.ts +0 -2
- package/dist/__tests__/tiptapImageRoundTrip.test.d.ts.map +0 -1
- package/dist/__tests__/tiptapImageRoundTrip.test.js +0 -68
- package/dist/__tests__/tiptapImageRoundTrip.test.js.map +0 -1
- package/dist/__tests__/useImageEditor.test.d.ts +0 -2
- package/dist/__tests__/useImageEditor.test.d.ts.map +0 -1
- package/dist/__tests__/useImageEditor.test.js +0 -131
- package/dist/__tests__/useImageEditor.test.js.map +0 -1
- package/dist/__tests__/useMediaRecorder.test.d.ts +0 -2
- package/dist/__tests__/useMediaRecorder.test.d.ts.map +0 -1
- package/dist/__tests__/useMediaRecorder.test.js +0 -153
- package/dist/__tests__/useMediaRecorder.test.js.map +0 -1
- package/dist/__tests__/versionHistory.test.d.ts +0 -2
- package/dist/__tests__/versionHistory.test.d.ts.map +0 -1
- package/dist/__tests__/versionHistory.test.js +0 -124
- package/dist/__tests__/versionHistory.test.js.map +0 -1
- package/dist/blockSlice.d.ts +0 -24
- package/dist/blockSlice.d.ts.map +0 -1
- package/dist/blockSlice.js +0 -63
- package/dist/blockSlice.js.map +0 -1
- package/dist/buildPreviewDoc.d.ts +0 -22
- package/dist/buildPreviewDoc.d.ts.map +0 -1
- package/dist/buildPreviewDoc.js +0 -262
- package/dist/buildPreviewDoc.js.map +0 -1
- package/dist/detectMarkdown.d.ts +0 -20
- package/dist/detectMarkdown.d.ts.map +0 -1
- package/dist/detectMarkdown.js +0 -61
- package/dist/detectMarkdown.js.map +0 -1
- package/dist/emojiData.d.ts +0 -81
- package/dist/emojiData.d.ts.map +0 -1
- package/dist/emojiData.js +0 -1283
- package/dist/emojiData.js.map +0 -1
- package/dist/fileKind.d.ts +0 -34
- package/dist/fileKind.d.ts.map +0 -1
- package/dist/fileKind.js +0 -144
- package/dist/fileKind.js.map +0 -1
- package/dist/hooks/useFileDrop.d.ts +0 -41
- package/dist/hooks/useFileDrop.d.ts.map +0 -1
- package/dist/hooks/useFileDrop.js +0 -205
- package/dist/hooks/useFileDrop.js.map +0 -1
- package/dist/imageEditor/CanvasSurface.d.ts +0 -31
- package/dist/imageEditor/CanvasSurface.d.ts.map +0 -1
- package/dist/imageEditor/CanvasSurface.js +0 -264
- package/dist/imageEditor/CanvasSurface.js.map +0 -1
- package/dist/imageEditor/ImageVersionHistoryDropdown.d.ts +0 -39
- package/dist/imageEditor/ImageVersionHistoryDropdown.d.ts.map +0 -1
- package/dist/imageEditor/ImageVersionHistoryDropdown.js +0 -283
- package/dist/imageEditor/ImageVersionHistoryDropdown.js.map +0 -1
- package/dist/imageEditor/LayersPanel.d.ts +0 -14
- package/dist/imageEditor/LayersPanel.d.ts.map +0 -1
- package/dist/imageEditor/LayersPanel.js +0 -43
- package/dist/imageEditor/LayersPanel.js.map +0 -1
- package/dist/imageEditor/PropertiesPanel.d.ts +0 -14
- package/dist/imageEditor/PropertiesPanel.d.ts.map +0 -1
- package/dist/imageEditor/PropertiesPanel.js +0 -97
- package/dist/imageEditor/PropertiesPanel.js.map +0 -1
- package/dist/imageEditor/Toolbar.d.ts +0 -30
- package/dist/imageEditor/Toolbar.d.ts.map +0 -1
- package/dist/imageEditor/Toolbar.js +0 -108
- package/dist/imageEditor/Toolbar.js.map +0 -1
- package/dist/imageEditor/icons.d.ts +0 -24
- package/dist/imageEditor/icons.d.ts.map +0 -1
- package/dist/imageEditor/icons.js +0 -45
- package/dist/imageEditor/icons.js.map +0 -1
- package/dist/imageEditor/layers/EditorImageLayer.d.ts +0 -16
- package/dist/imageEditor/layers/EditorImageLayer.d.ts.map +0 -1
- package/dist/imageEditor/layers/EditorImageLayer.js +0 -37
- package/dist/imageEditor/layers/EditorImageLayer.js.map +0 -1
- package/dist/imageEditor/layers/EditorShapeLayer.d.ts +0 -15
- package/dist/imageEditor/layers/EditorShapeLayer.d.ts.map +0 -1
- package/dist/imageEditor/layers/EditorShapeLayer.js +0 -20
- package/dist/imageEditor/layers/EditorShapeLayer.js.map +0 -1
- package/dist/imageEditor/layers/EditorTextLayer.d.ts +0 -18
- package/dist/imageEditor/layers/EditorTextLayer.d.ts.map +0 -1
- package/dist/imageEditor/layers/EditorTextLayer.js +0 -13
- package/dist/imageEditor/layers/EditorTextLayer.js.map +0 -1
- package/dist/imageEditor/layers/SelectionHandles.d.ts +0 -17
- package/dist/imageEditor/layers/SelectionHandles.d.ts.map +0 -1
- package/dist/imageEditor/layers/SelectionHandles.js +0 -19
- package/dist/imageEditor/layers/SelectionHandles.js.map +0 -1
- package/dist/imageEditor/state.d.ts +0 -76
- package/dist/imageEditor/state.d.ts.map +0 -1
- package/dist/imageEditor/state.js +0 -87
- package/dist/imageEditor/state.js.map +0 -1
- package/dist/imageEditor/useImageEditor.d.ts +0 -53
- package/dist/imageEditor/useImageEditor.d.ts.map +0 -1
- package/dist/imageEditor/useImageEditor.js +0 -244
- package/dist/imageEditor/useImageEditor.js.map +0 -1
- package/dist/imageEditor/useImageEditorTokens.d.ts +0 -16
- package/dist/imageEditor/useImageEditorTokens.d.ts.map +0 -1
- package/dist/imageEditor/useImageEditorTokens.js +0 -45
- package/dist/imageEditor/useImageEditorTokens.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/jsonEditor/EmbeddedRichTextField.d.ts +0 -15
- package/dist/jsonEditor/EmbeddedRichTextField.d.ts.map +0 -1
- package/dist/jsonEditor/EmbeddedRichTextField.js +0 -74
- package/dist/jsonEditor/EmbeddedRichTextField.js.map +0 -1
- package/dist/jsonEditor/JsonEditor.d.ts +0 -36
- package/dist/jsonEditor/JsonEditor.d.ts.map +0 -1
- package/dist/jsonEditor/JsonEditor.js +0 -15
- package/dist/jsonEditor/JsonEditor.js.map +0 -1
- package/dist/jsonEditor/JsonEditorContext.d.ts +0 -28
- package/dist/jsonEditor/JsonEditorContext.d.ts.map +0 -1
- package/dist/jsonEditor/JsonEditorContext.js +0 -41
- package/dist/jsonEditor/JsonEditorContext.js.map +0 -1
- package/dist/jsonEditor/RenderNode.d.ts +0 -16
- package/dist/jsonEditor/RenderNode.d.ts.map +0 -1
- package/dist/jsonEditor/RenderNode.js +0 -32
- package/dist/jsonEditor/RenderNode.js.map +0 -1
- package/dist/jsonEditor/editors.d.ts +0 -36
- package/dist/jsonEditor/editors.d.ts.map +0 -1
- package/dist/jsonEditor/editors.js +0 -347
- package/dist/jsonEditor/editors.js.map +0 -1
- package/dist/jsonEditor/index.d.ts +0 -3
- package/dist/jsonEditor/index.d.ts.map +0 -1
- package/dist/jsonEditor/index.js +0 -2
- package/dist/jsonEditor/index.js.map +0 -1
- package/dist/jsonEditor/useJsonEditorTokens.d.ts +0 -13
- package/dist/jsonEditor/useJsonEditorTokens.d.ts.map +0 -1
- package/dist/jsonEditor/useJsonEditorTokens.js +0 -38
- package/dist/jsonEditor/useJsonEditorTokens.js.map +0 -1
- package/dist/mediaDragMime.d.ts +0 -17
- package/dist/mediaDragMime.d.ts.map +0 -1
- package/dist/mediaDragMime.js +0 -22
- package/dist/mediaDragMime.js.map +0 -1
- package/dist/recorder/RecorderButton.d.ts +0 -31
- package/dist/recorder/RecorderButton.d.ts.map +0 -1
- package/dist/recorder/RecorderButton.js +0 -24
- package/dist/recorder/RecorderButton.js.map +0 -1
- package/dist/recorder/RecorderModal.d.ts +0 -59
- package/dist/recorder/RecorderModal.d.ts.map +0 -1
- package/dist/recorder/RecorderModal.js +0 -333
- package/dist/recorder/RecorderModal.js.map +0 -1
- package/dist/recorder/RecorderPanel.d.ts +0 -25
- package/dist/recorder/RecorderPanel.d.ts.map +0 -1
- package/dist/recorder/RecorderPanel.js +0 -30
- package/dist/recorder/RecorderPanel.js.map +0 -1
- package/dist/recorder/formats.d.ts +0 -51
- package/dist/recorder/formats.d.ts.map +0 -1
- package/dist/recorder/formats.js +0 -144
- package/dist/recorder/formats.js.map +0 -1
- package/dist/recorder/hooks/useMediaRecorder.d.ts +0 -90
- package/dist/recorder/hooks/useMediaRecorder.d.ts.map +0 -1
- package/dist/recorder/hooks/useMediaRecorder.js +0 -277
- package/dist/recorder/hooks/useMediaRecorder.js.map +0 -1
- package/dist/recorder/hooks/useStreamPreview.d.ts +0 -22
- package/dist/recorder/hooks/useStreamPreview.d.ts.map +0 -1
- package/dist/recorder/hooks/useStreamPreview.js +0 -44
- package/dist/recorder/hooks/useStreamPreview.js.map +0 -1
- package/dist/recorder/sources/cameraStream.d.ts +0 -22
- package/dist/recorder/sources/cameraStream.d.ts.map +0 -1
- package/dist/recorder/sources/cameraStream.js +0 -24
- package/dist/recorder/sources/cameraStream.js.map +0 -1
- package/dist/recorder/sources/micStream.d.ts +0 -15
- package/dist/recorder/sources/micStream.d.ts.map +0 -1
- package/dist/recorder/sources/micStream.js +0 -24
- package/dist/recorder/sources/micStream.js.map +0 -1
- package/dist/recorder/sources/screenStream.d.ts +0 -53
- package/dist/recorder/sources/screenStream.d.ts.map +0 -1
- package/dist/recorder/sources/screenStream.js +0 -114
- package/dist/recorder/sources/screenStream.js.map +0 -1
- package/dist/recorder/timingJson.d.ts +0 -51
- package/dist/recorder/timingJson.d.ts.map +0 -1
- package/dist/recorder/timingJson.js +0 -42
- package/dist/recorder/timingJson.js.map +0 -1
- package/dist/tiptap/TiptapAudio.d.ts +0 -26
- package/dist/tiptap/TiptapAudio.d.ts.map +0 -1
- package/dist/tiptap/TiptapAudio.js +0 -58
- package/dist/tiptap/TiptapAudio.js.map +0 -1
- package/dist/tiptap/TiptapVideo.d.ts +0 -30
- package/dist/tiptap/TiptapVideo.d.ts.map +0 -1
- package/dist/tiptap/TiptapVideo.js +0 -66
- package/dist/tiptap/TiptapVideo.js.map +0 -1
- package/dist/tiptap/useResolvedMediaSrc.d.ts +0 -2
- package/dist/tiptap/useResolvedMediaSrc.d.ts.map +0 -1
- package/dist/tiptap/useResolvedMediaSrc.js +0 -42
- package/dist/tiptap/useResolvedMediaSrc.js.map +0 -1
- package/dist/tiptapBridge.d.ts +0 -24
- package/dist/tiptapBridge.d.ts.map +0 -1
- package/dist/tiptapBridge.js +0 -749
- package/dist/tiptapBridge.js.map +0 -1
- package/dist/useHeadingLayout.d.ts +0 -54
- package/dist/useHeadingLayout.d.ts.map +0 -1
- package/dist/useHeadingLayout.js +0 -260
- package/dist/useHeadingLayout.js.map +0 -1
- package/dist/utils/collectInlineFontAwesomeCss.d.ts +0 -21
- package/dist/utils/collectInlineFontAwesomeCss.d.ts.map +0 -1
- package/dist/utils/collectInlineFontAwesomeCss.js +0 -68
- package/dist/utils/collectInlineFontAwesomeCss.js.map +0 -1
- package/dist/utils/dropUtils.d.ts +0 -55
- package/dist/utils/dropUtils.d.ts.map +0 -1
- package/dist/utils/dropUtils.js +0 -110
- package/dist/utils/dropUtils.js.map +0 -1
- package/dist/utils/normalizeMalformedAssetUrl.d.ts +0 -15
- package/dist/utils/normalizeMalformedAssetUrl.d.ts.map +0 -1
- package/dist/utils/normalizeMalformedAssetUrl.js +0 -27
- package/dist/utils/normalizeMalformedAssetUrl.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,97 +1,1998 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as react from 'react';
|
|
3
|
+
import { ReactNode, CSSProperties, RefObject } from 'react';
|
|
4
|
+
import { Doc, MediaProvider, Theme, ViewportPreset, ViewportConfig, SurfaceScheme, ImageEditDoc, ImageEditLayer } from '@bendyline/squisq/schemas';
|
|
5
|
+
import { MarkdownDocument } from '@bendyline/squisq/markdown';
|
|
6
|
+
import { ContentContainer } from '@bendyline/squisq/storage';
|
|
7
|
+
import { DocumentVersionManager, SaveVersionOptions, SaveVersionResult, PrunePolicy } from '@bendyline/squisq/versions';
|
|
8
|
+
import * as _tiptap_core from '@tiptap/core';
|
|
9
|
+
import { Editor } from '@tiptap/core';
|
|
10
|
+
import { editor } from 'monaco-editor';
|
|
11
|
+
import { IconFamily } from '@bendyline/squisq/icons';
|
|
12
|
+
import { DisplayMode, CaptionStyle } from '@bendyline/squisq-react';
|
|
13
|
+
import * as _tiptap_extension_heading from '@tiptap/extension-heading';
|
|
14
|
+
import { SquisqAnnotatedSchema, JsonFormValidator, JsonFormValidationError } from '@bendyline/squisq/jsonForm';
|
|
15
|
+
import { ImageEditExportFormat, ImageEditVersionManager } from '@bendyline/squisq/imageEdit';
|
|
16
|
+
|
|
17
|
+
/** Monaco standalone code editor instance type */
|
|
18
|
+
type MonacoEditor = editor.IStandaloneCodeEditor;
|
|
1
19
|
/**
|
|
2
|
-
* @
|
|
20
|
+
* One candidate returned by a {@link MentionProvider}. Shown in the editor's
|
|
21
|
+
* `@` popover. `id` is the stable identifier (serialized into the mention
|
|
22
|
+
* wire format); `label` is what the reader sees; `scheme` is the namespace
|
|
23
|
+
* (e.g. `'user'`, `'issue'`) written into the markdown as `@[label](scheme:id)`;
|
|
24
|
+
* `description` and `group` are optional hints for richer suggestion UIs.
|
|
3
25
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
|
|
26
|
+
* Different candidates in the same result set may carry different schemes —
|
|
27
|
+
* a provider that returns both users and issues, for example, tags each
|
|
28
|
+
* candidate with its own namespace and the editor emits mentions accordingly.
|
|
29
|
+
*/
|
|
30
|
+
interface MentionCandidate {
|
|
31
|
+
id: string;
|
|
32
|
+
label: string;
|
|
33
|
+
scheme: string;
|
|
34
|
+
description?: string;
|
|
35
|
+
group?: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Looks up mention candidates matching a query. Called as the user types
|
|
39
|
+
* after `@`. The provider is free to do server-side or client-side filtering;
|
|
40
|
+
* the editor only cares that candidates come back in relevance order.
|
|
41
|
+
*/
|
|
42
|
+
type MentionProvider = (query: string) => Promise<MentionCandidate[]>;
|
|
43
|
+
/**
|
|
44
|
+
* A document that the link dialog's "Browse documents" picker can offer.
|
|
45
|
+
* `path` is what lands in the markdown URL (typically relative to the
|
|
46
|
+
* current document so `home.md → resume.md` round-trips through file-
|
|
47
|
+
* system serializers). `label` is the human name shown in the list.
|
|
48
|
+
* `description` is an optional secondary line (e.g. workspace folder,
|
|
49
|
+
* last-modified date).
|
|
50
|
+
*/
|
|
51
|
+
interface DocumentLinkCandidate {
|
|
52
|
+
path: string;
|
|
53
|
+
label: string;
|
|
54
|
+
description?: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Resolves sibling / workspace document candidates for the link dialog.
|
|
58
|
+
* The editor itself has no notion of "neighbors" — hosts that organize
|
|
59
|
+
* docs in a workspace (e.g. docblocks) implement this to power the
|
|
60
|
+
* dialog's document picker. Pass `''` as the query for an initial list
|
|
61
|
+
* (the dialog calls it once on open); subsequent calls narrow by user
|
|
62
|
+
* input.
|
|
63
|
+
*/
|
|
64
|
+
type DocumentLinkProvider = (query: string) => Promise<DocumentLinkCandidate[]>;
|
|
65
|
+
type EditorView = 'raw' | 'wysiwyg' | 'preview';
|
|
66
|
+
type EditorTheme = 'light' | 'dark';
|
|
67
|
+
/**
|
|
68
|
+
* How much of the active Squisq theme the WYSIWYG editing surface
|
|
69
|
+
* mirrors. `'fonts'` is the historical default — body and heading
|
|
70
|
+
* fonts only. `'fonts-colors'` also borrows the theme canvas / text
|
|
71
|
+
* colors. `'none'` opts out completely.
|
|
72
|
+
*/
|
|
73
|
+
type ThemeInheritance = 'none' | 'fonts' | 'fonts-colors';
|
|
74
|
+
/**
|
|
75
|
+
* Editor operating mode. `markdown` is the full experience (WYSIWYG +
|
|
76
|
+
* Preview tabs, formatting toolbar). `code` is a Monaco-only view used
|
|
77
|
+
* when the content represents a non-markdown file like `foo.ts`.
|
|
78
|
+
*/
|
|
79
|
+
type EditorMode = 'markdown' | 'code' | 'image';
|
|
80
|
+
interface EditorState {
|
|
81
|
+
/** Raw markdown source string */
|
|
82
|
+
markdownSource: string;
|
|
83
|
+
/** Parsed markdown document (JSON DOM) */
|
|
84
|
+
markdownDoc: MarkdownDocument | null;
|
|
85
|
+
/** Generated Doc (block hierarchy) */
|
|
86
|
+
doc: Doc | null;
|
|
87
|
+
/** Currently active editor view */
|
|
88
|
+
activeView: EditorView;
|
|
89
|
+
/** Parse error, if any */
|
|
90
|
+
parseError: string | null;
|
|
91
|
+
/** Whether a parse is pending */
|
|
92
|
+
isParsing: boolean;
|
|
93
|
+
/** Current color theme */
|
|
94
|
+
theme: EditorTheme;
|
|
95
|
+
/** Operating mode — 'markdown' for the full shell, 'code' for Monaco-only. */
|
|
96
|
+
editorMode: EditorMode;
|
|
97
|
+
/** Monaco language ID for the Raw editor. */
|
|
98
|
+
language: string;
|
|
99
|
+
/**
|
|
100
|
+
* Whether the inline preview gutter (per-block card previews next to the
|
|
101
|
+
* WYSIWYG surface) is currently visible. Initialized from the EditorShell
|
|
102
|
+
* `inlinePreview` prop; the View menu in the toolbar can toggle it at
|
|
103
|
+
* runtime.
|
|
104
|
+
*/
|
|
105
|
+
inlinePreviewVisible: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Whether the bottom status bar is currently visible. Initialized from
|
|
108
|
+
* the EditorShell `showStatusBar` prop (default true); the View menu in
|
|
109
|
+
* the toolbar can toggle it at runtime.
|
|
110
|
+
*/
|
|
111
|
+
statusBarVisible: boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Whether the left-side outline pane is currently visible. Initialized
|
|
114
|
+
* from the EditorShell `outline` prop (default false); the View menu in
|
|
115
|
+
* the toolbar can toggle it at runtime.
|
|
116
|
+
*/
|
|
117
|
+
outlineVisible: boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Whether inline block-template tags (the chip next to each templated
|
|
120
|
+
* heading in the WYSIWYG view, plus the subtle affordance chip on plain
|
|
121
|
+
* headings) are currently visible. Initialized from the EditorShell
|
|
122
|
+
* `blockTags` prop (default true); the View menu in the toolbar can
|
|
123
|
+
* toggle it at runtime.
|
|
124
|
+
*/
|
|
125
|
+
blockTagsVisible: boolean;
|
|
126
|
+
/**
|
|
127
|
+
* How much of the active Squisq theme the WYSIWYG editing surface should
|
|
128
|
+
* inherit. `'none'` shows the default editor styling, `'fonts'` (the
|
|
129
|
+
* default) matches body and heading fonts only, and `'fonts-colors'`
|
|
130
|
+
* also borrows the theme's canvas / text colors so authors get a
|
|
131
|
+
* closer preview while editing.
|
|
132
|
+
*/
|
|
133
|
+
themeInheritance: ThemeInheritance;
|
|
134
|
+
/**
|
|
135
|
+
* Relative path of an image the user requested to edit, or `null` when
|
|
136
|
+
* no editor is open. Surfaced by `<ImageNodeView>`'s hover affordance
|
|
137
|
+
* and consumed by `<EditorShell>` to render the modal `<ImageEditor>`.
|
|
138
|
+
*/
|
|
139
|
+
imageEditTarget: string | null;
|
|
140
|
+
/**
|
|
141
|
+
* Monotonic counter bumped whenever a managed media asset is rewritten
|
|
142
|
+
* (e.g. after the image-editor modal saves back). Image render paths
|
|
143
|
+
* that cache resolved blob URLs should include this in their effect
|
|
144
|
+
* deps so the new bytes get picked up.
|
|
145
|
+
*/
|
|
146
|
+
mediaRevision: number;
|
|
147
|
+
/**
|
|
148
|
+
* Whether the in-editor media recorder should be available. Defaults
|
|
149
|
+
* to true when a `mediaProvider` is wired; hosts that explicitly
|
|
150
|
+
* don't want the affordance (e.g. read-only embeds, surfaces where
|
|
151
|
+
* camera/screen prompts would be jarring) can pass `false` on the
|
|
152
|
+
* shell.
|
|
153
|
+
*/
|
|
154
|
+
allowRecording: boolean;
|
|
155
|
+
}
|
|
156
|
+
interface EditorActions {
|
|
157
|
+
/** Set markdown source and trigger re-parse */
|
|
158
|
+
setMarkdownSource: (source: string) => void;
|
|
159
|
+
/** Set markdown from a MarkdownDocument (e.g. from WYSIWYG) */
|
|
160
|
+
setMarkdownDoc: (doc: MarkdownDocument) => void;
|
|
161
|
+
/** Switch the active view */
|
|
162
|
+
setActiveView: (view: EditorView) => void;
|
|
163
|
+
/** Register / unregister the Tiptap editor instance (called by WysiwygEditor) */
|
|
164
|
+
setTiptapEditor: (editor: Editor | null) => void;
|
|
165
|
+
/** Register / unregister the Monaco editor instance (called by RawEditor) */
|
|
166
|
+
setMonacoEditor: (editor: MonacoEditor | null) => void;
|
|
167
|
+
/** Set the color theme */
|
|
168
|
+
setTheme: (theme: EditorTheme) => void;
|
|
169
|
+
/** Show or hide the inline preview gutter at runtime (driven by the View menu). */
|
|
170
|
+
setInlinePreviewVisible: (visible: boolean) => void;
|
|
171
|
+
/** Show or hide the bottom status bar at runtime (driven by the View menu). */
|
|
172
|
+
setStatusBarVisible: (visible: boolean) => void;
|
|
173
|
+
/** Show or hide the left-side outline pane at runtime (driven by the View menu). */
|
|
174
|
+
setOutlineVisible: (visible: boolean) => void;
|
|
175
|
+
/** Show or hide inline block-template tags at runtime (driven by the View menu). */
|
|
176
|
+
setBlockTagsVisible: (visible: boolean) => void;
|
|
177
|
+
/** Change how much of the active Squisq theme the WYSIWYG surface mirrors. */
|
|
178
|
+
setThemeInheritance: (mode: ThemeInheritance) => void;
|
|
179
|
+
/** Insert text at the current cursor position in the active editor */
|
|
180
|
+
insertAtCursor: (text: string) => void;
|
|
181
|
+
/** Replace all editor content with the given text */
|
|
182
|
+
replaceAll: (text: string) => void;
|
|
183
|
+
/**
|
|
184
|
+
* Request the modal image editor open on the given relative media path.
|
|
185
|
+
* The path must resolve through the active `mediaProvider`. No-op when
|
|
186
|
+
* no provider is wired — callers should hide the affordance in that
|
|
187
|
+
* case.
|
|
188
|
+
*/
|
|
189
|
+
openImageEdit: (relativePath: string) => void;
|
|
190
|
+
/** Close the image editor modal without saving. */
|
|
191
|
+
closeImageEdit: () => void;
|
|
192
|
+
/**
|
|
193
|
+
* Bump `mediaRevision`. Called after the image editor writes back to
|
|
194
|
+
* the original media path so dependent `<img>` nodes re-resolve their
|
|
195
|
+
* blob URL.
|
|
196
|
+
*/
|
|
197
|
+
bumpMediaRevision: () => void;
|
|
198
|
+
}
|
|
199
|
+
interface EditorContextValue extends EditorState, EditorActions {
|
|
200
|
+
/** The live Tiptap editor instance (null when WYSIWYG is not mounted) */
|
|
201
|
+
tiptapEditor: Editor | null;
|
|
202
|
+
/** The live Monaco editor instance (null when Raw is not mounted) */
|
|
203
|
+
monacoEditor: MonacoEditor | null;
|
|
204
|
+
/**
|
|
205
|
+
* Workspace-scoped `ContentContainer` for this document — the folder
|
|
206
|
+
* holding the doc, its `_files/` sidecar, sibling documents, and any
|
|
207
|
+
* version snapshots. Drives audio mapping, version history, and
|
|
208
|
+
* sibling-doc reads for the recursive HTML export.
|
|
209
|
+
*/
|
|
210
|
+
workspaceContainer: ContentContainer | null;
|
|
211
|
+
/**
|
|
212
|
+
* Version manager — non-null only when the host opted into versioning
|
|
213
|
+
* (`allowVersioning` + a `workspaceContainer`). Components can call
|
|
214
|
+
* `saveVersion` directly, or render the version-history panel which
|
|
215
|
+
* reads it from here.
|
|
216
|
+
*/
|
|
217
|
+
versioning: DocumentVersionManager | null;
|
|
218
|
+
/**
|
|
219
|
+
* Stamp a new snapshot of the current document. No-op (returns
|
|
220
|
+
* `unchanged`) when content matches the latest version. Always safe
|
|
221
|
+
* to call — when versioning is disabled, returns `no-document`
|
|
222
|
+
* without writing.
|
|
223
|
+
*/
|
|
224
|
+
saveVersion: (options?: SaveVersionOptions) => Promise<SaveVersionResult>;
|
|
225
|
+
/** MediaProvider for resolving image URLs in the WYSIWYG editor */
|
|
226
|
+
mediaProvider: MediaProvider | null;
|
|
227
|
+
/**
|
|
228
|
+
* How pasted/inserted images should be displayed in the WYSIWYG view.
|
|
229
|
+
* `'inline'` (default) lets them flow at natural size up to the editor
|
|
230
|
+
* width; `'thumbnail'` constrains them to a 100×100 box so chat
|
|
231
|
+
* composers and other dense surfaces don't get dominated by a single
|
|
232
|
+
* pasted screenshot. The stored image bytes are unchanged — this is a
|
|
233
|
+
* pure render-time decision.
|
|
234
|
+
*/
|
|
235
|
+
imageDisplayMode: ImageDisplayMode;
|
|
236
|
+
/**
|
|
237
|
+
* Optional provider for `@`-mention suggestions. When set, both the
|
|
238
|
+
* WYSIWYG (Tiptap) and Raw (Monaco) editors show a mention popover as
|
|
239
|
+
* the user types `@<query>`. When unset, `@` is just a literal character.
|
|
240
|
+
*/
|
|
241
|
+
mentionProvider: MentionProvider | null;
|
|
242
|
+
/**
|
|
243
|
+
* Optional provider for sibling-document suggestions in the link
|
|
244
|
+
* dialog. When set, the dialog shows a "Browse documents" picker that
|
|
245
|
+
* lets authors search neighbor docs by name and insert a relative-
|
|
246
|
+
* path link. When unset, the dialog falls back to URL-only.
|
|
247
|
+
*/
|
|
248
|
+
documentLinkProvider: DocumentLinkProvider | null;
|
|
249
|
+
}
|
|
250
|
+
type ImageDisplayMode = 'inline' | 'thumbnail';
|
|
251
|
+
/**
|
|
252
|
+
* Hook to access the editor context. Must be used within an EditorProvider.
|
|
253
|
+
*/
|
|
254
|
+
declare function useEditorContext(): EditorContextValue;
|
|
255
|
+
interface EditorProviderProps {
|
|
256
|
+
/** Initial markdown content */
|
|
257
|
+
initialMarkdown?: string;
|
|
258
|
+
/** Initial active view */
|
|
259
|
+
initialView?: EditorView;
|
|
260
|
+
/** Article ID used when generating the Doc */
|
|
261
|
+
articleId?: string;
|
|
262
|
+
/** Color theme */
|
|
263
|
+
theme?: EditorTheme;
|
|
264
|
+
/**
|
|
265
|
+
* Workspace-scoped `ContentContainer` for this document — the folder
|
|
266
|
+
* holding the doc, its `_files/` sidecar, sibling documents, and any
|
|
267
|
+
* version snapshots. Required for `allowVersioning` to take effect.
|
|
268
|
+
*/
|
|
269
|
+
workspaceContainer?: ContentContainer | null;
|
|
270
|
+
/**
|
|
271
|
+
* Enable version history. Snapshots are stored at
|
|
272
|
+
* `.versions/<basename>.<timestamp>.md` inside `workspaceContainer`.
|
|
273
|
+
* Auto-save fires after `versioningAutoSaveIdleMs` of idle; hosts can
|
|
274
|
+
* also call `saveVersion()` from the context. Without a
|
|
275
|
+
* `workspaceContainer`, this prop is ignored (and a `console.warn` is
|
|
276
|
+
* emitted).
|
|
277
|
+
*/
|
|
278
|
+
allowVersioning?: boolean;
|
|
279
|
+
/** Override the basename used in version filenames. Defaults to the
|
|
280
|
+
* basename of the container's primary document path. */
|
|
281
|
+
versionBasename?: string;
|
|
282
|
+
/**
|
|
283
|
+
* Prune policy applied after each successful auto-save. Defaults to
|
|
284
|
+
* keeping the last 50 snapshots so the count doesn't grow unbounded.
|
|
285
|
+
*/
|
|
286
|
+
versioningPrunePolicy?: PrunePolicy;
|
|
287
|
+
/**
|
|
288
|
+
* Idle delay (ms) before auto-saving a version. `0` disables auto-save
|
|
289
|
+
* entirely (versions are saved only via host-driven `saveVersion`
|
|
290
|
+
* calls). Default: 5000.
|
|
291
|
+
*/
|
|
292
|
+
versioningAutoSaveIdleMs?: number;
|
|
293
|
+
/**
|
|
294
|
+
* Notified after each `saveVersion` attempt — both successful saves
|
|
295
|
+
* (`reason: 'saved'`) and skips (`'unchanged'`, `'no-document'`,
|
|
296
|
+
* `'empty'`). Useful for hosts that want a "Last saved" indicator.
|
|
297
|
+
*/
|
|
298
|
+
onSaveVersion?: (result: SaveVersionResult) => void;
|
|
299
|
+
/** MediaProvider for resolving image URLs */
|
|
300
|
+
mediaProvider?: MediaProvider | null;
|
|
301
|
+
/** Display mode for images in the WYSIWYG view. Defaults to `'inline'`. */
|
|
302
|
+
imageDisplayMode?: ImageDisplayMode;
|
|
303
|
+
/**
|
|
304
|
+
* Async provider for `@`-mention suggestions. Omit to disable mentions
|
|
305
|
+
* entirely — typing `@` becomes just a literal character again.
|
|
306
|
+
*/
|
|
307
|
+
mentionProvider?: MentionProvider | null;
|
|
308
|
+
/**
|
|
309
|
+
* Async provider for sibling-document suggestions in the link dialog.
|
|
310
|
+
* Omit to fall back to URL-only link insertion.
|
|
311
|
+
*/
|
|
312
|
+
documentLinkProvider?: DocumentLinkProvider | null;
|
|
313
|
+
/**
|
|
314
|
+
* Whether the in-editor media recorder is available in the toolbar.
|
|
315
|
+
* Defaults to true. Set to false to suppress the recorder affordance
|
|
316
|
+
* even when a `mediaProvider` is wired (e.g. read-only embeds,
|
|
317
|
+
* surfaces where camera/screen prompts would be jarring).
|
|
318
|
+
*/
|
|
319
|
+
allowRecording?: boolean;
|
|
320
|
+
/**
|
|
321
|
+
* File name (e.g. `foo.ts`) or bare extension — used to pick a Monaco
|
|
322
|
+
* language and decide between markdown vs. code mode.
|
|
323
|
+
*/
|
|
324
|
+
fileName?: string;
|
|
325
|
+
/** Explicit Monaco language ID — wins over the fileName-derived one. */
|
|
326
|
+
language?: string;
|
|
327
|
+
/**
|
|
328
|
+
* Initial visibility of the inline preview gutter. Defaults to false.
|
|
329
|
+
* The toolbar's View menu can toggle it at runtime.
|
|
330
|
+
*/
|
|
331
|
+
inlinePreview?: boolean;
|
|
332
|
+
/**
|
|
333
|
+
* Initial visibility of the bottom status bar. Defaults to true.
|
|
334
|
+
* The toolbar's View menu can toggle it at runtime.
|
|
335
|
+
*/
|
|
336
|
+
showStatusBar?: boolean;
|
|
337
|
+
/**
|
|
338
|
+
* Initial visibility of the left-side outline pane. Defaults to false.
|
|
339
|
+
* The toolbar's View menu can toggle it at runtime.
|
|
340
|
+
*/
|
|
341
|
+
outline?: boolean;
|
|
342
|
+
/**
|
|
343
|
+
* Initial visibility of inline block-template tags on headings.
|
|
344
|
+
* Defaults to true. The toolbar's View menu can toggle it at runtime.
|
|
345
|
+
*/
|
|
346
|
+
blockTags?: boolean;
|
|
347
|
+
/**
|
|
348
|
+
* Initial value for how much of the active Squisq theme the WYSIWYG
|
|
349
|
+
* editing surface should mirror. Defaults to `'fonts'` — the
|
|
350
|
+
* historical behavior of inheriting body / heading fonts only. The
|
|
351
|
+
* toolbar's View menu can change it at runtime.
|
|
352
|
+
*/
|
|
353
|
+
themeInheritance?: ThemeInheritance;
|
|
354
|
+
/**
|
|
355
|
+
* Bundled view preferences — a serializable JSON blob covering all
|
|
356
|
+
* runtime-toggleable view options. When provided, individual values
|
|
357
|
+
* here override the matching individual props (`inlinePreview`,
|
|
358
|
+
* `showStatusBar`, `outline`). Hosts wiring this up typically load
|
|
359
|
+
* the blob from their own preferences storage and pair it with
|
|
360
|
+
* {@link onViewPreferencesChange}.
|
|
361
|
+
*/
|
|
362
|
+
viewPreferences?: ViewPreferences;
|
|
363
|
+
/**
|
|
364
|
+
* Notified after each user-driven toggle in the View menu (or any
|
|
365
|
+
* programmatic call to the corresponding context setters). The
|
|
366
|
+
* argument is a full snapshot — hosts can persist it as-is.
|
|
367
|
+
* Not called when {@link viewPreferences} is changed externally.
|
|
368
|
+
*/
|
|
369
|
+
onViewPreferencesChange?: (prefs: ViewPreferences) => void;
|
|
370
|
+
children: ReactNode;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Serializable bundle of all runtime-toggleable view preferences for
|
|
374
|
+
* the editor shell. Hosts can persist this verbatim (e.g. to
|
|
375
|
+
* localStorage) and pass it back via {@link EditorProviderProps.viewPreferences}
|
|
376
|
+
* to restore the user's last view configuration.
|
|
377
|
+
*/
|
|
378
|
+
interface ViewPreferences {
|
|
379
|
+
/** Whether the left-side outline pane is visible. */
|
|
380
|
+
outline?: boolean;
|
|
381
|
+
/** Whether the inline preview gutter (per-block cards) is visible. */
|
|
382
|
+
inlinePreview?: boolean;
|
|
383
|
+
/** Whether the bottom status bar is visible. */
|
|
384
|
+
showStatusBar?: boolean;
|
|
385
|
+
/** Whether inline block-template tags on headings are visible. */
|
|
386
|
+
blockTags?: boolean;
|
|
387
|
+
/** How much of the active Squisq theme the WYSIWYG surface mirrors. */
|
|
388
|
+
themeInheritance?: ThemeInheritance;
|
|
389
|
+
}
|
|
390
|
+
declare function EditorProvider({ initialMarkdown, initialView, articleId, theme: initialTheme, workspaceContainer, allowVersioning, versionBasename, versioningPrunePolicy, versioningAutoSaveIdleMs, onSaveVersion, mediaProvider, imageDisplayMode, mentionProvider, documentLinkProvider, allowRecording, fileName, language, inlinePreview, showStatusBar, outline, blockTags, themeInheritance, viewPreferences, onViewPreferencesChange, children, }: EditorProviderProps): react_jsx_runtime.JSX.Element;
|
|
391
|
+
|
|
392
|
+
interface EditorShellProps {
|
|
393
|
+
/** Initial markdown content */
|
|
394
|
+
initialMarkdown?: string;
|
|
395
|
+
/** Initial active view */
|
|
396
|
+
/** Initial active view (default: 'wysiwyg') */
|
|
397
|
+
initialView?: EditorView;
|
|
398
|
+
/** Article ID for Doc generation */
|
|
399
|
+
articleId?: string;
|
|
400
|
+
/** Base path for media URLs in preview */
|
|
401
|
+
basePath?: string;
|
|
402
|
+
/** Called when markdown source changes */
|
|
403
|
+
onChange?: (source: string) => void;
|
|
404
|
+
/** Color theme: 'light' or 'dark' (default: 'light') */
|
|
405
|
+
theme?: 'light' | 'dark';
|
|
406
|
+
/** Additional class name */
|
|
407
|
+
className?: string;
|
|
408
|
+
/** CSS height for the shell container (default: '100vh') */
|
|
409
|
+
height?: string;
|
|
410
|
+
/**
|
|
411
|
+
* Minimum CSS height for the shell. When either `minHeight` or
|
|
412
|
+
* `maxHeight` is set, the shell switches to **auto-grow mode**:
|
|
413
|
+
* `height` is ignored, the root becomes `height: auto` between the
|
|
414
|
+
* bounds, and the content area scrolls internally when content
|
|
415
|
+
* exceeds `maxHeight`. Useful for chat composers that should grow
|
|
416
|
+
* with content up to some cap.
|
|
417
|
+
*/
|
|
418
|
+
minHeight?: string;
|
|
419
|
+
/** See `minHeight`. Upper bound of the auto-grow range. */
|
|
420
|
+
maxHeight?: string;
|
|
421
|
+
/** Optional MediaProvider for the Files panel. When set (even to null), a Files toggle appears in the toolbar. */
|
|
422
|
+
mediaProvider?: MediaProvider | null;
|
|
423
|
+
/**
|
|
424
|
+
* The workspace-scoped `ContentContainer` for this document — the
|
|
425
|
+
* folder that contains the doc, its `_files/` sidecar, sibling
|
|
426
|
+
* documents, and any version snapshots. Used for:
|
|
427
|
+
* - audio mapping (MP3 discovery + timing.json reading);
|
|
428
|
+
* - version history snapshots (when `allowVersioning` is true);
|
|
429
|
+
* - reading sibling `.md` files for the recursive HTML export;
|
|
430
|
+
* - resolving per-document scoped views (e.g. the image-edit
|
|
431
|
+
* sidecar derived via `scopeContainer`).
|
|
432
|
+
* Doc-scoped concerns (per-doc media URLs, per-doc asset writes)
|
|
433
|
+
* flow through `mediaProvider` instead — typically derived from
|
|
434
|
+
* this container via `createMediaProviderFromContainer`.
|
|
435
|
+
*/
|
|
436
|
+
workspaceContainer?: ContentContainer | null;
|
|
437
|
+
/**
|
|
438
|
+
* @deprecated Renamed to `workspaceContainer` to make the workspace-
|
|
439
|
+
* vs. doc-scoped distinction explicit. Still accepted as a fallback
|
|
440
|
+
* for now; remove in the next breaking release.
|
|
441
|
+
*/
|
|
442
|
+
container?: ContentContainer | null;
|
|
443
|
+
/**
|
|
444
|
+
* Enable version history. Snapshots are stored at
|
|
445
|
+
* `.versions/<basename>.<timestamp>.md` inside the same
|
|
446
|
+
* `workspaceContainer`, so they ride along with the document when
|
|
447
|
+
* the host serializes.
|
|
448
|
+
*
|
|
449
|
+
* Snapshots fire on idle (controlled by `versioningAutoSaveIdleMs`)
|
|
450
|
+
* and can also be triggered host-side via the manager exposed in the
|
|
451
|
+
* context (`useEditorContext().versioning`). Has no effect without a
|
|
452
|
+
* `workspaceContainer` — a `console.warn` flags the misconfiguration
|
|
453
|
+
* in dev.
|
|
454
|
+
*/
|
|
455
|
+
allowVersioning?: boolean;
|
|
456
|
+
/**
|
|
457
|
+
* Override the document basename used in version filenames. Defaults
|
|
458
|
+
* to the basename of the container's primary document path.
|
|
459
|
+
*/
|
|
460
|
+
versionBasename?: string;
|
|
461
|
+
/**
|
|
462
|
+
* Prune policy applied after each successful save. Defaults to
|
|
463
|
+
* `{ type: 'keep-last-n', n: 50 }` so the snapshot count stays bounded.
|
|
464
|
+
*/
|
|
465
|
+
versioningPrunePolicy?: PrunePolicy;
|
|
466
|
+
/**
|
|
467
|
+
* Idle delay (ms) before the editor auto-saves a version. `0` disables
|
|
468
|
+
* auto-save entirely (snapshots are then only saved when the host
|
|
469
|
+
* calls `versioning.saveVersion()` from the context). Default: 5000.
|
|
470
|
+
*/
|
|
471
|
+
versioningAutoSaveIdleMs?: number;
|
|
472
|
+
/**
|
|
473
|
+
* Notified after each `saveVersion` attempt. Fires for both successful
|
|
474
|
+
* saves (`reason: 'saved'`) and skips (`'unchanged'`, `'no-document'`,
|
|
475
|
+
* `'empty'`). Useful for hosts that want a "Last saved" indicator.
|
|
476
|
+
*/
|
|
477
|
+
onSaveVersion?: (result: SaveVersionResult) => void;
|
|
478
|
+
/** Show the Files toggle in the toolbar. Defaults to true when mediaProvider is passed. */
|
|
479
|
+
showFilesToggle?: boolean;
|
|
480
|
+
/** Content rendered at the left edge of the toolbar, before the view tabs. */
|
|
481
|
+
toolbarSlotLeft?: ReactNode;
|
|
482
|
+
/** Content rendered after the formatting controls (in the middle area of the toolbar). */
|
|
483
|
+
toolbarSlotAfterActions?: ReactNode;
|
|
484
|
+
/** Content rendered at the rightmost end of the toolbar, after all other elements. */
|
|
485
|
+
toolbarSlotRight?: ReactNode;
|
|
486
|
+
/**
|
|
487
|
+
* Whether to show the "Play" (preview) tab in the toolbar. When false, the
|
|
488
|
+
* tab and its preview panel are hidden, and ⌘3 becomes a no-op. Use this
|
|
489
|
+
* when embedding the editor somewhere the slideshow preview doesn't make
|
|
490
|
+
* sense (e.g. editing free-form prompt documents). Defaults to true.
|
|
491
|
+
*/
|
|
492
|
+
showPlayTab?: boolean;
|
|
493
|
+
/**
|
|
494
|
+
* Optional "submit on Enter" callback. When provided, a plain Enter
|
|
495
|
+
* keypress fires this callback instead of inserting a newline, and
|
|
496
|
+
* Cmd/Ctrl+Enter inserts a newline instead. Matches chat-composer UX
|
|
497
|
+
* (Slack, Discord). When omitted, the editor behaves normally.
|
|
498
|
+
*/
|
|
499
|
+
submitOnEnter?: () => void;
|
|
500
|
+
/**
|
|
501
|
+
* Let the WYSIWYG editing surface fill its container instead of rendering
|
|
502
|
+
* as a centered 800px "page" column. Useful when embedding in chat
|
|
503
|
+
* composers, side panels, or any layout where the page metaphor doesn't
|
|
504
|
+
* fit. Defaults to false (page mode).
|
|
505
|
+
*/
|
|
506
|
+
fullWidth?: boolean;
|
|
507
|
+
/**
|
|
508
|
+
* Font-family stack applied to the editor **chrome** — toolbar buttons,
|
|
509
|
+
* tabs, status bar, and control surfaces. The actual editing areas
|
|
510
|
+
* (Tiptap / Monaco) keep their own fonts so document editing isn't
|
|
511
|
+
* affected. Use this when the editor is embedded in a larger product
|
|
512
|
+
* that has its own UX type system and you want the controls to blend in.
|
|
513
|
+
*
|
|
514
|
+
* @example
|
|
515
|
+
* ```tsx
|
|
516
|
+
* <EditorShell uxFont="'Hanken Grotesk', system-ui, sans-serif" ... />
|
|
517
|
+
* ```
|
|
518
|
+
*/
|
|
519
|
+
uxFont?: string;
|
|
520
|
+
/**
|
|
521
|
+
* Drop the editor's generous page-style padding in favor of a tight
|
|
522
|
+
* layout that hugs its container. The default WYSIWYG surface uses
|
|
523
|
+
* 16×24px padding suitable for editing long-form documents; chat
|
|
524
|
+
* composers want much less. Applies to the editing area only — the
|
|
525
|
+
* toolbar, tabs, and status bar keep their normal sizing.
|
|
526
|
+
*/
|
|
527
|
+
thinMargins?: boolean;
|
|
528
|
+
/**
|
|
529
|
+
* Render the bottom status bar (word / character / line / block counts
|
|
530
|
+
* and parse-state indicator). Defaults to `true`. Set to `false` in
|
|
531
|
+
* embedded surfaces — chat composers and other short-form inputs —
|
|
532
|
+
* where the stats are noise.
|
|
533
|
+
*/
|
|
534
|
+
showStatusBar?: boolean;
|
|
535
|
+
/**
|
|
536
|
+
* How images should be displayed in the WYSIWYG view. `'inline'`
|
|
537
|
+
* (default) flows them at natural size up to the container width;
|
|
538
|
+
* `'thumbnail'` constrains each image to a 100×100 box with
|
|
539
|
+
* aspect-preserving containment — useful for chat composers and other
|
|
540
|
+
* dense surfaces where a full-resolution paste would dominate the
|
|
541
|
+
* layout. Storage bytes are unchanged either way.
|
|
542
|
+
*/
|
|
543
|
+
imageDisplayMode?: ImageDisplayMode;
|
|
544
|
+
/**
|
|
545
|
+
* File name (e.g. `foo.ts`) or bare extension that the content
|
|
546
|
+
* represents. When set to a non-markdown/text extension, the shell
|
|
547
|
+
* enters **code mode**: Monaco picks the right language based on the
|
|
548
|
+
* extension, the WYSIWYG and Preview tabs disappear, and the toolbar
|
|
549
|
+
* drops its markdown-specific formatting buttons. Markdown-ish
|
|
550
|
+
* extensions (`.md`, `.markdown`, `.mdown`, `.txt`) keep the full
|
|
551
|
+
* experience. Omit to get today's markdown behavior unchanged.
|
|
552
|
+
*/
|
|
553
|
+
fileName?: string;
|
|
554
|
+
/**
|
|
555
|
+
* Explicit Monaco language ID override (e.g. `'typescript'`,
|
|
556
|
+
* `'python'`, `'json'`). Wins over the language derived from
|
|
557
|
+
* `fileName`. Anything other than `'markdown'` or `'plaintext'`
|
|
558
|
+
* switches the shell into code mode.
|
|
559
|
+
*/
|
|
560
|
+
language?: string;
|
|
561
|
+
/**
|
|
562
|
+
* Optional async provider for `@`-mention suggestions. When supplied,
|
|
563
|
+
* typing `@` inside the editor opens a popover of candidates; selecting
|
|
564
|
+
* one inserts a `@[Label](scheme:id)` mention token. Used by chat
|
|
565
|
+
* composers and any other surface that wants to address named entities
|
|
566
|
+
* inline. Omit to disable mentions entirely.
|
|
567
|
+
*/
|
|
568
|
+
mentionProvider?: MentionProvider | null;
|
|
569
|
+
/**
|
|
570
|
+
* Optional async provider for sibling-document suggestions in the
|
|
571
|
+
* link insert dialog. When supplied, the dialog gains a "Browse
|
|
572
|
+
* documents" picker so authors can pick a neighbor `.md` by name and
|
|
573
|
+
* insert a relative-path link without typing the URL by hand. Hosts
|
|
574
|
+
* that organize docs in a workspace (file-system, IndexedDB slot,
|
|
575
|
+
* remote API, …) implement this; the editor stays agnostic.
|
|
576
|
+
*/
|
|
577
|
+
documentLinkProvider?: DocumentLinkProvider | null;
|
|
578
|
+
/**
|
|
579
|
+
* Whether the in-editor media recorder is surfaced in the toolbar.
|
|
580
|
+
* Defaults to true — when a `mediaProvider` is wired, a record
|
|
581
|
+
* button appears next to the version history. Pass `false` to
|
|
582
|
+
* suppress it (read-only embeds, surfaces where camera/screen
|
|
583
|
+
* permission prompts would be jarring). Without a `mediaProvider`,
|
|
584
|
+
* the button is hidden regardless of this prop.
|
|
585
|
+
*/
|
|
586
|
+
allowRecording?: boolean;
|
|
587
|
+
/**
|
|
588
|
+
* Placeholder text shown in the WYSIWYG editor while the document is
|
|
589
|
+
* empty. When omitted, the editor rotates through its own generic
|
|
590
|
+
* "start typing…" prompts; pass a value here to override with copy
|
|
591
|
+
* that fits the embedding surface (e.g. a chat composer knows who
|
|
592
|
+
* the message is going to and can say so).
|
|
593
|
+
*/
|
|
594
|
+
placeholder?: string;
|
|
595
|
+
/**
|
|
596
|
+
* When true, both editing surfaces become non-editable: Monaco runs in
|
|
597
|
+
* `readOnly` mode and Tiptap is set to `editable: false`. The toolbar
|
|
598
|
+
* still renders — hide it from the host side if you want a pure preview.
|
|
599
|
+
* Useful for reference panels that show file content without inviting
|
|
600
|
+
* accidental edits.
|
|
601
|
+
*/
|
|
602
|
+
readOnly?: boolean;
|
|
603
|
+
/**
|
|
604
|
+
* Image source URL used when the resolved file mode is `image` (PNG,
|
|
605
|
+
* JPEG, GIF, WebP, BMP, ICO, AVIF). When this prop is set, the shell
|
|
606
|
+
* replaces its text-editing surfaces with a dedicated `ImageViewer`.
|
|
607
|
+
*
|
|
608
|
+
* Lifecycle of the URL is the caller's responsibility — when fed a
|
|
609
|
+
* `blob:` URL, the host should `URL.revokeObjectURL` on unmount or
|
|
610
|
+
* src change.
|
|
611
|
+
*/
|
|
612
|
+
imageSrc?: string;
|
|
613
|
+
/** Alt text passed through to the underlying ImageViewer. */
|
|
614
|
+
imageAlt?: string;
|
|
615
|
+
/**
|
|
616
|
+
* Whether the image surface should render as a read-only viewer
|
|
617
|
+
* (`'view'`, default) or as the editable {@link ImageEditor}
|
|
618
|
+
* (`'edit'`). Editing requires {@link EditorShellProps.imageEditorContainer}
|
|
619
|
+
* — without it the shell falls back to view mode and logs a warning.
|
|
620
|
+
*/
|
|
621
|
+
imageMode?: 'view' | 'edit';
|
|
622
|
+
/**
|
|
623
|
+
* Sidecar `ContentContainer` for the image being edited. Conventionally
|
|
624
|
+
* scoped to `<basename>_files/` via
|
|
625
|
+
* `scopeContainer(parentContainer, basename + '_files')`. The image
|
|
626
|
+
* editor persists `state.json`, layer assets in `assets/`, and (when
|
|
627
|
+
* `allowVersioning` is true) snapshots in `.versions/` inside it.
|
|
628
|
+
*/
|
|
629
|
+
imageEditorContainer?: ContentContainer;
|
|
630
|
+
/**
|
|
631
|
+
* Called after the user clicks Export in the image editor and the
|
|
632
|
+
* raster blob is produced. When omitted, the editor triggers a
|
|
633
|
+
* default browser download.
|
|
634
|
+
*/
|
|
635
|
+
onImageExport?: (blob: Blob, format: 'png' | 'jpeg' | 'webp') => void;
|
|
636
|
+
/**
|
|
637
|
+
* Show an inline preview gutter to the right of the WYSIWYG editor.
|
|
638
|
+
* The gutter renders one small SVG card per template-annotated block in
|
|
639
|
+
* the document, letting authors see their rendered output without
|
|
640
|
+
* leaving Edit mode. Auto-hidden via container query when the editor
|
|
641
|
+
* body is narrower than ~720px. Defaults to `false`.
|
|
642
|
+
*/
|
|
643
|
+
inlinePreview?: boolean;
|
|
644
|
+
/**
|
|
645
|
+
* Width in pixels for the inline preview gutter. Defaults to 320.
|
|
646
|
+
* Only takes effect when {@link EditorShellProps.inlinePreview} is true.
|
|
647
|
+
*/
|
|
648
|
+
inlinePreviewWidth?: number;
|
|
649
|
+
/**
|
|
650
|
+
* Show an outline pane on the left of the WYSIWYG editor — a
|
|
651
|
+
* hierarchical tree of the document's headings (h1 → h2 → h3) with
|
|
652
|
+
* click-to-scroll. Auto-hidden via container query on narrow editors.
|
|
653
|
+
* Defaults to `false`. The toolbar's View menu can toggle this at
|
|
654
|
+
* runtime regardless of the initial value.
|
|
655
|
+
*/
|
|
656
|
+
outline?: boolean;
|
|
657
|
+
/**
|
|
658
|
+
* Width in pixels for the outline pane. Defaults to 240. Only takes
|
|
659
|
+
* effect when {@link EditorShellProps.outline} is true (or the View
|
|
660
|
+
* menu has toggled it on).
|
|
661
|
+
*/
|
|
662
|
+
outlineWidth?: number;
|
|
663
|
+
/**
|
|
664
|
+
* Initial visibility of inline block-template tags on headings — the
|
|
665
|
+
* chip rendered next to each heading in the WYSIWYG view that opens
|
|
666
|
+
* the block-template picker. Defaults to true; the View menu can
|
|
667
|
+
* toggle it at runtime regardless of the initial value.
|
|
668
|
+
*/
|
|
669
|
+
blockTags?: boolean;
|
|
670
|
+
/**
|
|
671
|
+
* How much of the active Squisq theme the WYSIWYG editing surface
|
|
672
|
+
* mirrors. Defaults to `'fonts'` — the historical behavior of
|
|
673
|
+
* inheriting body / heading fonts only. The View menu can change it
|
|
674
|
+
* at runtime.
|
|
675
|
+
*/
|
|
676
|
+
themeInheritance?: ThemeInheritance;
|
|
677
|
+
/**
|
|
678
|
+
* Bundled view preferences — a serializable JSON blob covering the
|
|
679
|
+
* runtime-toggleable view options surfaced in the View menu. When
|
|
680
|
+
* provided, fields here override the corresponding individual props
|
|
681
|
+
* (`outline`, `inlinePreview`, `showStatusBar`). Pair with
|
|
682
|
+
* {@link onViewPreferencesChange} to externalize storage of these
|
|
683
|
+
* preferences in the host.
|
|
684
|
+
*/
|
|
685
|
+
viewPreferences?: ViewPreferences;
|
|
686
|
+
/**
|
|
687
|
+
* Notified after each user-driven toggle in the View menu. The
|
|
688
|
+
* argument is a full snapshot of all view preferences — hosts can
|
|
689
|
+
* persist it as-is. Not called when {@link viewPreferences} is
|
|
690
|
+
* changed externally.
|
|
691
|
+
*/
|
|
692
|
+
onViewPreferencesChange?: (prefs: ViewPreferences) => void;
|
|
693
|
+
/**
|
|
694
|
+
* Override the preview theme with an explicit `Theme` object. When set,
|
|
695
|
+
* `Doc.themeId` and the user's theme dropdown selection are ignored for
|
|
696
|
+
* the preview surface. Used by the theme customizer to live-preview an
|
|
697
|
+
* in-progress theme without mutating the document.
|
|
698
|
+
*/
|
|
699
|
+
themeOverride?: Theme | null;
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Complete markdown editor shell with toolbar, view switcher, and three
|
|
703
|
+
* editing modes: Raw (Monaco), WYSIWYG (Tiptap), and Preview.
|
|
704
|
+
*/
|
|
705
|
+
declare function EditorShell({ initialMarkdown, initialView, articleId, basePath, onChange, theme, className, height, minHeight, maxHeight, mediaProvider, workspaceContainer, container, allowVersioning, versionBasename, versioningPrunePolicy, versioningAutoSaveIdleMs, onSaveVersion, showFilesToggle, toolbarSlotLeft, toolbarSlotAfterActions, toolbarSlotRight, showPlayTab, submitOnEnter, fullWidth, uxFont, thinMargins, showStatusBar, imageDisplayMode, fileName, language, mentionProvider, documentLinkProvider, allowRecording, placeholder, readOnly, imageSrc, imageAlt, imageMode, imageEditorContainer, onImageExport, inlinePreview, inlinePreviewWidth, outline, outlineWidth, blockTags, themeInheritance, viewPreferences, onViewPreferencesChange, themeOverride, }: EditorShellProps): react_jsx_runtime.JSX.Element;
|
|
706
|
+
|
|
707
|
+
/**
|
|
708
|
+
* fileKind
|
|
709
|
+
*
|
|
710
|
+
* Maps a file name (or bare extension) to a Monaco language ID and decides
|
|
711
|
+
* whether the editor shell should operate in markdown mode (full WYSIWYG +
|
|
712
|
+
* Preview experience) or code mode (Monaco-only view with formatting
|
|
713
|
+
* buttons hidden).
|
|
714
|
+
*
|
|
715
|
+
* The mapping favors common web / systems languages that Monaco ships with
|
|
716
|
+
* out of the box. Unknown extensions fall back to markdown mode so the
|
|
717
|
+
* existing UX remains the default for anything we don't recognize.
|
|
718
|
+
*/
|
|
719
|
+
interface FileKind {
|
|
720
|
+
/**
|
|
721
|
+
* 'markdown' keeps the full editor (WYSIWYG + Preview tabs); 'code' is
|
|
722
|
+
* Monaco-only; 'image' renders a dedicated image viewer with no text
|
|
723
|
+
* editing surface.
|
|
724
|
+
*/
|
|
725
|
+
mode: 'markdown' | 'code' | 'image';
|
|
726
|
+
/** Monaco language ID — passed to `<Editor defaultLanguage={...} />`. */
|
|
727
|
+
language: string;
|
|
728
|
+
}
|
|
729
|
+
/**
|
|
730
|
+
* Detect a Monaco language ID from a file name. Returns null when the
|
|
731
|
+
* extension (or bare name) is not in the mapping.
|
|
732
|
+
*/
|
|
733
|
+
declare function detectLanguageFromFileName(fileName: string): string | null;
|
|
734
|
+
/**
|
|
735
|
+
* Resolve the editor mode + Monaco language for a given file. The explicit
|
|
736
|
+
* `language` argument, if provided, wins over any detection from
|
|
737
|
+
* `fileName`. When nothing matches, falls back to markdown mode.
|
|
738
|
+
*/
|
|
739
|
+
declare function resolveFileKind(fileName?: string, language?: string): FileKind;
|
|
740
|
+
|
|
741
|
+
/**
|
|
742
|
+
* ImageViewer
|
|
743
|
+
*
|
|
744
|
+
* Read-only image viewer used when EditorShell runs in `image` file mode
|
|
745
|
+
* (PNG/JPEG/etc.). Renders a centered image that fits its container with
|
|
746
|
+
* a small overlay toolbar for fit / 100% / zoom in / zoom out, and a
|
|
747
|
+
* status row showing intrinsic dimensions and current zoom.
|
|
748
|
+
*
|
|
749
|
+
* Lifecycle of the `src` URL is the caller's responsibility — when fed a
|
|
750
|
+
* blob URL, the host should `URL.revokeObjectURL` on unmount or src change.
|
|
751
|
+
*
|
|
752
|
+
* Future image-editing actions (rotate, flip, crop) will slot in alongside
|
|
753
|
+
* the existing zoom controls.
|
|
754
|
+
*/
|
|
755
|
+
interface ImageViewerProps {
|
|
756
|
+
/** Image source — typically a blob: URL the host owns and revokes. */
|
|
757
|
+
src: string;
|
|
758
|
+
/** Alt text for accessibility. Defaults to empty string (decorative). */
|
|
759
|
+
alt?: string;
|
|
760
|
+
/** Additional class name on the outer container. */
|
|
761
|
+
className?: string;
|
|
762
|
+
/** Color theme for the chrome around the image. */
|
|
763
|
+
theme?: 'light' | 'dark';
|
|
764
|
+
}
|
|
765
|
+
declare function ImageViewer({ src, alt, className, theme }: ImageViewerProps): react_jsx_runtime.JSX.Element;
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* RawEditor
|
|
769
|
+
*
|
|
770
|
+
* Monaco-based raw markdown editor. Provides full VS Code-like editing
|
|
771
|
+
* experience with syntax highlighting, minimap, and bracket matching.
|
|
772
|
+
* Syncs changes back to EditorContext on every keystroke (debounced).
|
|
773
|
+
*/
|
|
774
|
+
interface RawEditorProps {
|
|
775
|
+
/** Monaco editor theme (default: 'vs-dark') */
|
|
776
|
+
theme?: string;
|
|
777
|
+
/** Show minimap (default: false) */
|
|
778
|
+
minimap?: boolean;
|
|
779
|
+
/** Font size in pixels (default: 14) */
|
|
780
|
+
fontSize?: number;
|
|
781
|
+
/** Word wrap setting (default: 'on') */
|
|
782
|
+
wordWrap?: 'on' | 'off' | 'wordWrapColumn' | 'bounded';
|
|
783
|
+
/** Additional class name for the container */
|
|
784
|
+
className?: string;
|
|
785
|
+
/**
|
|
786
|
+
* Chat-composer mode: Enter fires this callback (submit) and Cmd/Ctrl+Enter
|
|
787
|
+
* inserts a newline. When undefined, behaves normally.
|
|
788
|
+
*/
|
|
789
|
+
submitOnEnter?: () => void;
|
|
790
|
+
/** Make Monaco read-only (no edits, no cursor blink). */
|
|
791
|
+
readOnly?: boolean;
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Raw markdown editor using Monaco Editor.
|
|
795
|
+
* Binds to the shared EditorContext for source synchronization.
|
|
796
|
+
*/
|
|
797
|
+
declare function RawEditor({ theme, minimap, fontSize, wordWrap, className, submitOnEnter, readOnly, }: RawEditorProps): react_jsx_runtime.JSX.Element;
|
|
798
|
+
|
|
799
|
+
/**
|
|
800
|
+
* WysiwygEditor
|
|
801
|
+
*
|
|
802
|
+
* Tiptap-based rich text editor that provides a WYSIWYG editing experience
|
|
803
|
+
* for markdown content. Uses squisq's parseMarkdown/stringifyMarkdown for
|
|
804
|
+
* conversion rather than Tiptap's built-in HTML serialization, ensuring
|
|
805
|
+
* perfect fidelity with the markdown format.
|
|
806
|
+
*
|
|
807
|
+
* Includes extensions for GFM features: tables, task lists, strikethrough,
|
|
808
|
+
* and code blocks.
|
|
809
|
+
*/
|
|
810
|
+
interface WysiwygEditorProps {
|
|
811
|
+
/**
|
|
812
|
+
* Placeholder text when the editor is empty. If omitted, one of several
|
|
813
|
+
* rotating prompts is picked at random on mount. Pass a fixed string to
|
|
814
|
+
* override with a host-specific call to action.
|
|
815
|
+
*/
|
|
816
|
+
placeholder?: string;
|
|
817
|
+
/** Additional class name for the container */
|
|
818
|
+
className?: string;
|
|
819
|
+
/**
|
|
820
|
+
* If set, a plain Enter keypress fires this callback instead of inserting
|
|
821
|
+
* a newline, and Cmd/Ctrl+Enter inserts a soft break. Chat-composer UX.
|
|
822
|
+
*/
|
|
823
|
+
submitOnEnter?: () => void;
|
|
824
|
+
/** Disable Tiptap editing — renders content but blocks input. */
|
|
825
|
+
readOnly?: boolean;
|
|
826
|
+
}
|
|
827
|
+
/**
|
|
828
|
+
* Rich WYSIWYG markdown editor built on Tiptap (ProseMirror).
|
|
829
|
+
* Binds to the shared EditorContext for source synchronization.
|
|
830
|
+
*/
|
|
831
|
+
declare function WysiwygEditor({ placeholder, className, submitOnEnter, readOnly, }: WysiwygEditorProps): react_jsx_runtime.JSX.Element;
|
|
832
|
+
|
|
833
|
+
interface PreviewPanelProps {
|
|
834
|
+
/** Base path for resolving media URLs in DocPlayer */
|
|
835
|
+
basePath?: string;
|
|
836
|
+
/** Additional class name for the container */
|
|
837
|
+
className?: string;
|
|
838
|
+
/**
|
|
839
|
+
* Workspace-scoped `ContentContainer` (the folder holding the doc and
|
|
840
|
+
* its siblings). Used here for audio mapping — MP3 discovery and
|
|
841
|
+
* `timing.json` reading.
|
|
842
|
+
*/
|
|
843
|
+
workspaceContainer?: ContentContainer | null;
|
|
844
|
+
}
|
|
845
|
+
/**
|
|
846
|
+
* Live preview panel that renders the current document as a slideshow
|
|
847
|
+
* or document view. Controls (viewport, mode, theme, transform, captions)
|
|
848
|
+
* are rendered in the main toolbar via PreviewToolbarControls.
|
|
849
|
+
*/
|
|
850
|
+
declare function PreviewPanel({ basePath, className, workspaceContainer }: PreviewPanelProps): react_jsx_runtime.JSX.Element;
|
|
851
|
+
|
|
852
|
+
interface PlainHtmlPreviewProps {
|
|
853
|
+
/** Raw markdown source. */
|
|
854
|
+
markdown: string;
|
|
855
|
+
/** Document title — populates the iframe's `<title>`. */
|
|
856
|
+
title?: string;
|
|
857
|
+
/**
|
|
858
|
+
* Pre-resolved image substitutions (export-time use). Takes precedence
|
|
859
|
+
* over live `mediaProvider` resolution for any URL it contains.
|
|
860
|
+
*/
|
|
861
|
+
images?: Map<string, string>;
|
|
862
|
+
/**
|
|
863
|
+
* When passed, relative image URLs in the markdown are resolved live
|
|
864
|
+
* via this provider. Skip for static previews where `images` already
|
|
865
|
+
* contains everything.
|
|
866
|
+
*/
|
|
867
|
+
mediaProvider?: MediaProvider | null;
|
|
868
|
+
/** Token that, when changed, forces re-resolution of media URLs.
|
|
869
|
+
* Mirrors the `mediaRevision` bump the editor uses after an image
|
|
870
|
+
* edit so saves show up in the preview without remount. */
|
|
871
|
+
mediaRevision?: number;
|
|
872
|
+
/**
|
|
873
|
+
* Squisq theme to apply. When set, the iframe loads any Google-
|
|
874
|
+
* hosted fonts the theme uses and the rendered HTML adopts the
|
|
875
|
+
* theme's colors and typography.
|
|
876
|
+
*/
|
|
877
|
+
theme?: Theme;
|
|
878
|
+
className?: string;
|
|
879
|
+
style?: CSSProperties;
|
|
880
|
+
}
|
|
881
|
+
declare function PlainHtmlPreview({ markdown, title, images, mediaProvider, mediaRevision, theme, className, style, }: PlainHtmlPreviewProps): react_jsx_runtime.JSX.Element;
|
|
882
|
+
|
|
883
|
+
/**
|
|
884
|
+
* Emoji Dataset
|
|
885
|
+
*
|
|
886
|
+
* Curated set of common emoji grouped by Unicode CLDR category. Used by
|
|
887
|
+
* `EmojiPicker` for both the category tabs and the search index.
|
|
888
|
+
*
|
|
889
|
+
* Each entry is a flat tuple `[char, name, ...keywords]` so the data
|
|
890
|
+
* stays compact in source and is cheap to scan for the typeahead
|
|
891
|
+
* search. Categories follow the official Unicode buckets in display
|
|
892
|
+
* order (CLDR v44 grouping), trimmed to common picks per category —
|
|
893
|
+
* we deliberately don't ship the whole Unicode emoji set (thousands)
|
|
894
|
+
* because the picker is meant for quick insertion, not exhaustive
|
|
895
|
+
* lookup; the user can paste anything we don't have.
|
|
896
|
+
*/
|
|
897
|
+
interface EmojiEntry {
|
|
898
|
+
/** The actual emoji glyph (may be multi-codepoint, e.g. ZWJ sequences). */
|
|
899
|
+
char: string;
|
|
900
|
+
/** Display name shown in the tooltip. */
|
|
901
|
+
name: string;
|
|
902
|
+
/** Lowercase keywords for the search index — name words plus aliases. */
|
|
903
|
+
keywords: string;
|
|
904
|
+
}
|
|
905
|
+
interface EmojiCategory {
|
|
906
|
+
id: string;
|
|
907
|
+
label: string;
|
|
908
|
+
/** Single-glyph icon shown on the tab. */
|
|
909
|
+
icon: string;
|
|
910
|
+
emojis: EmojiEntry[];
|
|
911
|
+
}
|
|
912
|
+
declare const EMOJI_CATEGORIES: EmojiCategory[];
|
|
913
|
+
/**
|
|
914
|
+
* Flat list of every emoji across all categories — used as the search
|
|
915
|
+
* corpus and to expose a `getEmojiByChar` lookup.
|
|
916
|
+
*/
|
|
917
|
+
declare const ALL_EMOJIS: EmojiEntry[];
|
|
918
|
+
/** Search for emoji whose name or keywords contain the query (case-insensitive). */
|
|
919
|
+
declare function searchEmojis(query: string, limit?: number): EmojiEntry[];
|
|
920
|
+
|
|
921
|
+
/**
|
|
922
|
+
* Discriminated picker entry. The picker UI dispatches on `kind` to
|
|
923
|
+
* render either an emoji glyph or a FontAwesome `<i>` element. The
|
|
924
|
+
* Toolbar consumes the selected entry to insert into the editor.
|
|
925
|
+
*/
|
|
926
|
+
type PickerEntry = {
|
|
927
|
+
kind: 'emoji';
|
|
928
|
+
char: string;
|
|
929
|
+
name: string;
|
|
930
|
+
keywords: string;
|
|
931
|
+
} | {
|
|
932
|
+
kind: 'icon';
|
|
933
|
+
family: IconFamily;
|
|
934
|
+
name: string;
|
|
935
|
+
label: string;
|
|
936
|
+
keywords: string;
|
|
937
|
+
/** Canonical token used in the markdown source (bare or qualified). */
|
|
938
|
+
token: string;
|
|
939
|
+
};
|
|
940
|
+
|
|
941
|
+
interface EmojiPickerProps {
|
|
942
|
+
/** Whether the picker is visible. */
|
|
943
|
+
open: boolean;
|
|
944
|
+
/**
|
|
945
|
+
* Fired when the user picks an entry. Carries either an emoji glyph
|
|
946
|
+
* or a FontAwesome icon descriptor — the caller dispatches on
|
|
947
|
+
* `kind` to insert it into the active editor. The caller is also
|
|
948
|
+
* responsible for closing the popover.
|
|
949
|
+
*/
|
|
950
|
+
onSelect: (entry: PickerEntry) => void;
|
|
951
|
+
/** Fired on Escape, click-outside, or selection so the caller can close. */
|
|
952
|
+
onClose: () => void;
|
|
953
|
+
/** Optional anchor element — used for click-outside detection. When the
|
|
954
|
+
* popover is rendered inside the same container as the trigger, pointer
|
|
955
|
+
* events on the trigger don't fire the outside handler. */
|
|
956
|
+
anchorRef?: React.RefObject<HTMLElement>;
|
|
957
|
+
/** Optional CSS class for the popover root. */
|
|
958
|
+
className?: string;
|
|
959
|
+
/** Optional inline style for the popover root (e.g. positioning). */
|
|
960
|
+
style?: CSSProperties;
|
|
961
|
+
/**
|
|
962
|
+
* Editor theme — `'light'` or `'dark'`. Drives the picker's color
|
|
963
|
+
* palette. Required for the picker to render correctly when portaled
|
|
964
|
+
* outside the editor shell, since CSS custom properties defined on
|
|
965
|
+
* the shell don't cascade to portal targets. Defaults to `'light'`.
|
|
966
|
+
*/
|
|
967
|
+
theme?: 'light' | 'dark';
|
|
968
|
+
}
|
|
969
|
+
declare function EmojiPicker({ open, onSelect, onClose, anchorRef, className, style, theme, }: EmojiPickerProps): react_jsx_runtime.JSX.Element | null;
|
|
970
|
+
|
|
971
|
+
/**
|
|
972
|
+
* DocumentSettingsDialog
|
|
973
|
+
*
|
|
974
|
+
* Modal editor for the frontmatter values that Squisq currently
|
|
975
|
+
* understands: document title plus the persisted preview keys
|
|
976
|
+
* (`squisq-theme`, `squisq-transform`, `squisq-captions`). Writes back
|
|
977
|
+
* to the same `setFrontmatterValues` channel that `PreviewControls`
|
|
978
|
+
* uses, so any change made here is reflected in the play-mode controls
|
|
979
|
+
* (and vice versa).
|
|
980
|
+
*
|
|
981
|
+
* Title behavior: the placeholder shows the title that
|
|
982
|
+
* `inferDocumentTitle()` would derive from frontmatter or headings.
|
|
983
|
+
* When the user-entered title is empty or equal to the inferred title,
|
|
984
|
+
* the `title:` key is removed from frontmatter — there's no point
|
|
985
|
+
* storing a redundant value.
|
|
986
|
+
*/
|
|
987
|
+
interface DocumentSettingsDialogProps {
|
|
988
|
+
/** Current markdown source string (frontmatter + body). */
|
|
989
|
+
markdownSource: string;
|
|
990
|
+
/** Called with the rewritten source after the user clicks Save. */
|
|
991
|
+
onSave: (nextSource: string) => void;
|
|
992
|
+
/** Called when the dialog is dismissed (Cancel, Escape, backdrop click). */
|
|
993
|
+
onClose: () => void;
|
|
994
|
+
}
|
|
995
|
+
declare function DocumentSettingsDialog({ markdownSource, onSave, onClose, }: DocumentSettingsDialogProps): react_jsx_runtime.JSX.Element;
|
|
996
|
+
|
|
997
|
+
/**
|
|
998
|
+
* ThemePicker
|
|
999
|
+
*
|
|
1000
|
+
* Custom theme dropdown that replaces a plain `<select>` with a popover
|
|
1001
|
+
* showing each theme as a card: the theme name rendered in the theme's
|
|
1002
|
+
* own background / foreground / title font, plus three color swatches
|
|
1003
|
+
* (primary, secondary, highlight). Used by both the play-mode preview
|
|
1004
|
+
* toolbar and the Document Settings dialog so authors see a
|
|
1005
|
+
* preview-on-hover style listing rather than a wall of names.
|
|
1006
|
+
*/
|
|
1007
|
+
interface ThemePickerProps {
|
|
1008
|
+
/** Currently selected theme id. Empty string represents "default". */
|
|
1009
|
+
value: string;
|
|
1010
|
+
/** Called with the new theme id. The empty string is emitted when the
|
|
1011
|
+
* user picks the "Default" option (only available with
|
|
1012
|
+
* `includeDefault`). */
|
|
1013
|
+
onChange: (id: string) => void;
|
|
1014
|
+
/**
|
|
1015
|
+
* Show a "Default" entry at the top of the popover that emits an empty
|
|
1016
|
+
* string. Used by the Document Settings dialog so the user can choose
|
|
1017
|
+
* "no explicit theme" (frontmatter omits the key entirely).
|
|
1018
|
+
*/
|
|
1019
|
+
includeDefault?: boolean;
|
|
1020
|
+
/**
|
|
1021
|
+
* `'compact'` (default) renders a small toolbar trigger; `'full'`
|
|
1022
|
+
* stretches to fill the parent and is sized for dialog layouts.
|
|
1023
|
+
*/
|
|
1024
|
+
variant?: 'compact' | 'full';
|
|
1025
|
+
/** Accessible label, e.g. "Theme". */
|
|
1026
|
+
ariaLabel?: string;
|
|
1027
|
+
}
|
|
1028
|
+
declare function ThemePicker({ value, onChange, includeDefault, variant, ariaLabel, }: ThemePickerProps): react_jsx_runtime.JSX.Element;
|
|
1029
|
+
|
|
1030
|
+
interface PreviewSettings {
|
|
1031
|
+
activePreset: ViewportPreset;
|
|
1032
|
+
setSelectedPreset: (preset: ViewportPreset | null) => void;
|
|
1033
|
+
activeViewport: ViewportConfig;
|
|
1034
|
+
activeDisplayMode: DisplayMode;
|
|
1035
|
+
setSelectedDisplayMode: (mode: DisplayMode | null) => void;
|
|
1036
|
+
activeThemeId: string;
|
|
1037
|
+
setSelectedThemeId: (id: string | null) => void;
|
|
1038
|
+
activeTheme: Theme;
|
|
1039
|
+
activeTransformStyle: string;
|
|
1040
|
+
setSelectedTransformStyle: (id: string | null) => void;
|
|
1041
|
+
activeCaptionStyle: CaptionStyle;
|
|
1042
|
+
setSelectedCaptionStyle: (style: CaptionStyle | null) => void;
|
|
1043
|
+
}
|
|
1044
|
+
declare function usePreviewSettings(): PreviewSettings;
|
|
1045
|
+
interface PreviewSettingsProviderProps {
|
|
1046
|
+
doc: Doc | null;
|
|
1047
|
+
children: ReactNode;
|
|
1048
|
+
/**
|
|
1049
|
+
* Optional Theme to use for the preview, regardless of `Doc.themeId` or
|
|
1050
|
+
* the user's theme dropdown selection. Used by the theme customizer to
|
|
1051
|
+
* preview an in-progress theme without mutating the document. When
|
|
1052
|
+
* present, `activeTheme` is this value and `activeThemeId` is its `id`.
|
|
1053
|
+
*/
|
|
1054
|
+
themeOverride?: Theme | null;
|
|
1055
|
+
}
|
|
1056
|
+
declare function PreviewSettingsProvider({ doc, children, themeOverride, }: PreviewSettingsProviderProps): react_jsx_runtime.JSX.Element;
|
|
1057
|
+
/**
|
|
1058
|
+
* Inline preview controls rendered in the main toolbar row.
|
|
1059
|
+
* On narrow viewports, collapses into a single settings button with a dropdown.
|
|
1060
|
+
*/
|
|
1061
|
+
declare function PreviewToolbarControls(): react_jsx_runtime.JSX.Element;
|
|
1062
|
+
|
|
1063
|
+
/**
|
|
1064
|
+
* ViewSwitcher
|
|
1065
|
+
*
|
|
1066
|
+
* Tab bar for switching between Raw, WYSIWYG, and Preview editor views.
|
|
1067
|
+
*/
|
|
1068
|
+
interface ViewSwitcherProps {
|
|
1069
|
+
/** Additional class name */
|
|
1070
|
+
className?: string;
|
|
1071
|
+
}
|
|
1072
|
+
/**
|
|
1073
|
+
* Tab-style view switcher for the three editor modes.
|
|
1074
|
+
*/
|
|
1075
|
+
declare function ViewSwitcher({ className }: ViewSwitcherProps): react_jsx_runtime.JSX.Element | null;
|
|
1076
|
+
|
|
1077
|
+
interface ToolbarProps {
|
|
1078
|
+
/** Additional class name */
|
|
1079
|
+
className?: string;
|
|
1080
|
+
/** Whether the Files panel is currently shown */
|
|
1081
|
+
showFiles?: boolean;
|
|
1082
|
+
/** Toggle the Files panel. When provided, a "Files" button appears in the toolbar. */
|
|
1083
|
+
onToggleFiles?: () => void;
|
|
1084
|
+
/** Content rendered at the left edge of the toolbar, before the view tabs. */
|
|
1085
|
+
slotLeft?: ReactNode;
|
|
1086
|
+
/** Content rendered after the formatting controls (in the middle area). */
|
|
1087
|
+
slotAfterActions?: ReactNode;
|
|
1088
|
+
/** Content rendered at the rightmost end of the toolbar, after all other elements. */
|
|
1089
|
+
slotRight?: ReactNode;
|
|
1090
|
+
/**
|
|
1091
|
+
* Whether to include the "Play" (preview) tab in the view switcher.
|
|
1092
|
+
* Defaults to true. Hosts that don't want the slideshow preview — e.g.
|
|
1093
|
+
* editing free-form prompts — can pass false to suppress it.
|
|
1094
|
+
*/
|
|
1095
|
+
showPlayTab?: boolean;
|
|
1096
|
+
}
|
|
1097
|
+
/**
|
|
1098
|
+
* Formatting toolbar.
|
|
1099
|
+
* - WYSIWYG: calls Tiptap chain commands (toggleBold, etc.)
|
|
1100
|
+
* - Raw: appends markdown syntax to the source
|
|
1101
|
+
*/
|
|
1102
|
+
declare function Toolbar({ className, showFiles, onToggleFiles, slotLeft, slotAfterActions, slotRight, showPlayTab, }: ToolbarProps): react_jsx_runtime.JSX.Element;
|
|
1103
|
+
|
|
1104
|
+
/**
|
|
1105
|
+
* VersionHistoryPanel
|
|
1106
|
+
*
|
|
1107
|
+
* Toolbar-anchored popover that lists prior version snapshots and lets
|
|
1108
|
+
* the user revert to one. When a snapshot is selected, a Monaco diff
|
|
1109
|
+
* view appears to the left of the list comparing the snapshot (original,
|
|
1110
|
+
* left) with the current editor content (modified, right).
|
|
1111
|
+
*
|
|
1112
|
+
* Wraps the toolbar trigger button + popover surface. Versioning state
|
|
1113
|
+
* is read from the EditorContext — render this component anywhere inside
|
|
1114
|
+
* a provider that has `allowVersioning` and a `container`.
|
|
1115
|
+
*/
|
|
1116
|
+
declare function VersionHistoryPanel(): react_jsx_runtime.JSX.Element | null;
|
|
1117
|
+
|
|
1118
|
+
/**
|
|
1119
|
+
* ViewMenuPanel
|
|
1120
|
+
*
|
|
1121
|
+
* Toolbar overflow menu (`…` button) for view-related toggles. Currently
|
|
1122
|
+
* houses the inline preview gutter toggle; new view options can be added
|
|
1123
|
+
* as additional `<MenuToggle>` rows without restructuring.
|
|
1124
|
+
*
|
|
1125
|
+
* State lives in EditorContext so the toggle survives view switches and
|
|
1126
|
+
* the host doesn't need to manage it. The initial value comes from the
|
|
1127
|
+
* EditorShell `inlinePreview` prop.
|
|
1128
|
+
*/
|
|
1129
|
+
declare function ViewMenuPanel(): react_jsx_runtime.JSX.Element;
|
|
1130
|
+
|
|
1131
|
+
/**
|
|
1132
|
+
* OutlinePanel
|
|
1133
|
+
*
|
|
1134
|
+
* Left-side companion to the InlinePreviewGutter. Renders a hierarchical
|
|
1135
|
+
* tree of the document's headings (h1 → h2 → h3 …) so the structure is
|
|
1136
|
+
* graspable at a glance and the user can jump to any section. Works in
|
|
1137
|
+
* BOTH the WYSIWYG and Markdown editor views — view-specific positioning
|
|
1138
|
+
* lives in `useHeadingLayout`.
|
|
1139
|
+
*/
|
|
1140
|
+
interface OutlinePanelProps {
|
|
1141
|
+
/** Width of the pane in pixels (default: 240). */
|
|
1142
|
+
width?: number;
|
|
1143
|
+
/** Optional CSS class for the outer container. */
|
|
1144
|
+
className?: string;
|
|
1145
|
+
}
|
|
1146
|
+
declare function OutlinePanel({ width, className }: OutlinePanelProps): react_jsx_runtime.JSX.Element;
|
|
1147
|
+
|
|
1148
|
+
interface ThemeCustomizerPanelProps {
|
|
1149
|
+
/** Current custom theme (or null to start from defaults). */
|
|
1150
|
+
value: Theme | null;
|
|
1151
|
+
/** Fired on every edit. Host typically registers the theme + previews it. */
|
|
1152
|
+
onChange: (theme: Theme) => void;
|
|
1153
|
+
/** Fired when the user clicks Save. Host typically persists the theme JSON. */
|
|
1154
|
+
onSave?: (theme: Theme, json: string) => void;
|
|
1155
|
+
/** Fired when the user clicks Reset. Host typically clears its persistent storage. */
|
|
1156
|
+
onReset?: () => void;
|
|
1157
|
+
}
|
|
1158
|
+
declare function ThemeCustomizerPanel({ value, onChange, onSave, onReset, }: ThemeCustomizerPanelProps): react_jsx_runtime.JSX.Element;
|
|
1159
|
+
|
|
1160
|
+
/**
|
|
1161
|
+
* Convert a camelCase template id to a human-readable label. Accepts both
|
|
1162
|
+
* the canonical short ids (`title`, `quote`, `map`, `list`) and the
|
|
1163
|
+
* legacy long ones (`titleBlock`, `quoteBlock`, `mapBlock`, `listBlock`)
|
|
1164
|
+
* so existing documents keep showing a friendly label without first
|
|
1165
|
+
* normalizing their annotations.
|
|
1166
|
+
*/
|
|
1167
|
+
declare function templateLabel(name: string): string;
|
|
1168
|
+
interface TemplatePickerProps {
|
|
1169
|
+
value: string;
|
|
1170
|
+
onChange: (name: string) => void;
|
|
1171
|
+
/** When true, shows only the trigger button (no popover) — used in the overflow menu. */
|
|
1172
|
+
compact?: boolean;
|
|
1173
|
+
/**
|
|
1174
|
+
* Template names to surface in a "Recommended for this block" section
|
|
1175
|
+
* above the full list. When omitted or empty, the gallery renders as a
|
|
1176
|
+
* single ungrouped grid (legacy behavior).
|
|
1177
|
+
*/
|
|
1178
|
+
recommended?: readonly string[];
|
|
1179
|
+
}
|
|
1180
|
+
declare function TemplatePicker({ value, onChange, compact, recommended }: TemplatePickerProps): react_jsx_runtime.JSX.Element;
|
|
1181
|
+
|
|
1182
|
+
interface InlinePreviewGutterProps {
|
|
1183
|
+
/** Width of the gutter in pixels (default: 320). */
|
|
1184
|
+
width?: number;
|
|
1185
|
+
/** Base path for resolving media URLs in card thumbnails. */
|
|
1186
|
+
basePath?: string;
|
|
1187
|
+
/** Viewport used to render each card (default: landscape preset). */
|
|
1188
|
+
viewport?: ViewportConfig;
|
|
1189
|
+
/** Optional CSS class for the outer container. */
|
|
1190
|
+
className?: string;
|
|
1191
|
+
/**
|
|
1192
|
+
* Width in pixels of the connector strip that bridges the editor and
|
|
1193
|
+
* the gutter. Defaults to 24.
|
|
1194
|
+
*/
|
|
1195
|
+
connectorWidth?: number;
|
|
1196
|
+
/**
|
|
1197
|
+
* Optional MediaProvider used to resolve relative image src values inside
|
|
1198
|
+
* preview cards. When omitted, images with relative paths fall back to
|
|
1199
|
+
* `basePath`-prefixed URLs (which usually 404 in container-backed editors).
|
|
1200
|
+
*/
|
|
1201
|
+
mediaProvider?: MediaProvider | null;
|
|
1202
|
+
}
|
|
1203
|
+
declare function InlinePreviewGutter({ width, basePath, viewport, className, connectorWidth, mediaProvider, }: InlinePreviewGutterProps): react_jsx_runtime.JSX.Element;
|
|
1204
|
+
|
|
1205
|
+
interface MediaBinProps {
|
|
1206
|
+
/** The active MediaProvider (null when no media context is available) */
|
|
1207
|
+
mediaProvider: MediaProvider | null;
|
|
1208
|
+
/** Whether the editor is in dark mode */
|
|
1209
|
+
isDark: boolean;
|
|
1210
|
+
/** Incremented externally to signal a re-scan of the media list */
|
|
1211
|
+
refreshKey?: number;
|
|
1212
|
+
/**
|
|
1213
|
+
* Fired after a successful upload via the MediaBin's own "+ Upload"
|
|
1214
|
+
* button. `relativePath` is what the provider returned (the same
|
|
1215
|
+
* value embedded in markdown refs, e.g. `attachments/xyz.png`);
|
|
1216
|
+
* `name` is the uploader-chosen filename before storage renamed
|
|
1217
|
+
* it. Consumers typically use this to insert a markdown image ref
|
|
1218
|
+
* at the editor's cursor so the file actually participates in the
|
|
1219
|
+
* outgoing message — previously files went to the bin and nowhere
|
|
1220
|
+
* else, leaving the message body empty when the user hit Send.
|
|
1221
|
+
*/
|
|
1222
|
+
onMediaUploaded?: (relativePath: string, name: string, mimeType: string) => void | Promise<void>;
|
|
1223
|
+
}
|
|
1224
|
+
declare function MediaBin({ mediaProvider, isDark, refreshKey, onMediaUploaded }: MediaBinProps): react_jsx_runtime.JSX.Element;
|
|
1225
|
+
|
|
1226
|
+
/**
|
|
1227
|
+
* StatusBar
|
|
1228
|
+
*
|
|
1229
|
+
* Bottom status bar showing document statistics and parse status.
|
|
1230
|
+
*/
|
|
1231
|
+
interface StatusBarProps {
|
|
1232
|
+
/** Additional class name */
|
|
1233
|
+
className?: string;
|
|
1234
|
+
}
|
|
1235
|
+
/**
|
|
1236
|
+
* Status bar displaying document statistics: character count, word count,
|
|
1237
|
+
* block count, and parse/error status.
|
|
1238
|
+
*/
|
|
1239
|
+
declare function StatusBar({ className }: StatusBarProps): react_jsx_runtime.JSX.Element;
|
|
1240
|
+
|
|
1241
|
+
/**
|
|
1242
|
+
* TooltipLayer
|
|
1243
|
+
*
|
|
1244
|
+
* A single portal-mounted tooltip that activates on hover over any element
|
|
1245
|
+
* with a `data-tooltip` attribute. Shorter delay than native browser
|
|
1246
|
+
* tooltips and fires regardless of window focus, making toolbar hints feel
|
|
1247
|
+
* immediate. Mount once near the root of the editor shell.
|
|
1248
|
+
*/
|
|
1249
|
+
declare function TooltipLayer(): react.ReactPortal | null;
|
|
1250
|
+
|
|
1251
|
+
/**
|
|
1252
|
+
* useFileDrop
|
|
1253
|
+
*
|
|
1254
|
+
* React hook that manages HTML5 drag-and-drop state for file uploads.
|
|
1255
|
+
* Tracks whether files are being dragged over the target element,
|
|
1256
|
+
* classifies dragged file types (media vs text), and dispatches
|
|
1257
|
+
* drop events to callers.
|
|
1258
|
+
*/
|
|
1259
|
+
type FileCategory = 'media' | 'text' | 'unknown';
|
|
1260
|
+
type DragContentType = 'media' | 'text' | 'mixed' | null;
|
|
1261
|
+
type DropTarget = 'media' | 'insert' | 'replace';
|
|
1262
|
+
declare function classifyFile(file: {
|
|
1263
|
+
name: string;
|
|
1264
|
+
type: string;
|
|
1265
|
+
}): FileCategory;
|
|
1266
|
+
interface UseFileDropOptions {
|
|
1267
|
+
/** Called when files are dropped on a specific target zone. */
|
|
1268
|
+
onDrop: (files: File[], target: DropTarget) => void;
|
|
1269
|
+
/** Whether drop is enabled (default: true) */
|
|
1270
|
+
enabled?: boolean;
|
|
1271
|
+
}
|
|
1272
|
+
interface UseFileDropResult {
|
|
1273
|
+
/** Whether a drag-with-files is currently hovering over the container */
|
|
1274
|
+
isDragging: boolean;
|
|
1275
|
+
/** Classification of the dragged content */
|
|
1276
|
+
dragContentType: DragContentType;
|
|
1277
|
+
/** Attach these to the container element */
|
|
1278
|
+
containerProps: {
|
|
1279
|
+
onDragEnter: (e: React.DragEvent) => void;
|
|
1280
|
+
onDragOver: (e: React.DragEvent) => void;
|
|
1281
|
+
onDragLeave: (e: React.DragEvent) => void;
|
|
1282
|
+
onDrop: (e: React.DragEvent) => void;
|
|
1283
|
+
};
|
|
1284
|
+
/** Create props for an individual drop zone target */
|
|
1285
|
+
zoneProps: (target: DropTarget) => {
|
|
1286
|
+
onDragOver: (e: React.DragEvent) => void;
|
|
1287
|
+
onDrop: (e: React.DragEvent) => void;
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1290
|
+
declare function useFileDrop({ onDrop, enabled }: UseFileDropOptions): UseFileDropResult;
|
|
1291
|
+
|
|
1292
|
+
interface DropZoneOverlayProps {
|
|
1293
|
+
/** What kind of content is being dragged */
|
|
1294
|
+
dragContentType: DragContentType;
|
|
1295
|
+
/** Factory that creates event props for a specific drop target */
|
|
1296
|
+
zoneProps: UseFileDropResult['zoneProps'];
|
|
1297
|
+
/** Whether a MediaProvider is available (disables media zone when false) */
|
|
1298
|
+
hasMediaProvider: boolean;
|
|
1299
|
+
}
|
|
1300
|
+
/**
|
|
1301
|
+
* Full-size overlay with contextual drop targets for file uploads.
|
|
1302
|
+
* Rendered conditionally by EditorShell when files are dragged over the editor.
|
|
1303
|
+
*/
|
|
1304
|
+
declare function DropZoneOverlay({ dragContentType, zoneProps, hasMediaProvider, }: DropZoneOverlayProps): react_jsx_runtime.JSX.Element;
|
|
1305
|
+
|
|
1306
|
+
/**
|
|
1307
|
+
* Drop Utilities
|
|
1308
|
+
*
|
|
1309
|
+
* File processing pipeline for dropped files. Classifies files by type,
|
|
1310
|
+
* processes media files into a MediaProvider, and converts text files
|
|
1311
|
+
* (.md, .txt, .docx) to markdown strings.
|
|
1312
|
+
*/
|
|
1313
|
+
|
|
1314
|
+
/**
|
|
1315
|
+
* Partition an array of files into media and text categories.
|
|
1316
|
+
* Files with unknown type are skipped.
|
|
1317
|
+
*/
|
|
1318
|
+
declare function partitionFiles(files: File[]): {
|
|
1319
|
+
media: File[];
|
|
1320
|
+
text: File[];
|
|
1321
|
+
};
|
|
1322
|
+
/**
|
|
1323
|
+
* Add media files to a MediaProvider. Returns the relative paths
|
|
1324
|
+
* assigned by the provider, with `null` slots where a file could not
|
|
1325
|
+
* be processed — keeping the result aligned with the input array so
|
|
1326
|
+
* callers can correlate indices.
|
|
1327
|
+
*
|
|
1328
|
+
* Two failure modes are handled defensively:
|
|
1329
|
+
*
|
|
1330
|
+
* 1. `file.arrayBuffer()` throws (`InvalidStateError` — "An operation
|
|
1331
|
+
* that depends on state cached in an interface object was made but
|
|
1332
|
+
* the state had changed since it was read from disk"). This happens
|
|
1333
|
+
* with virtual drag sources whose File reference goes stale before
|
|
1334
|
+
* the async read completes — Phone Link / iOS continuity / certain
|
|
1335
|
+
* screenshot tools / etc.
|
|
1336
|
+
*
|
|
1337
|
+
* 2. `file.arrayBuffer()` returns a 0-byte buffer. Some virtual
|
|
1338
|
+
* sources resolve the read successfully but with no payload,
|
|
1339
|
+
* leaving an empty file in the media bin. We skip those so the
|
|
1340
|
+
* bin doesn't accumulate placeholders.
|
|
1341
|
+
*
|
|
1342
|
+
* In both cases we warn via console rather than throwing, so a single
|
|
1343
|
+
* problematic file doesn't abort a multi-file drop.
|
|
1344
|
+
*/
|
|
1345
|
+
declare function processMediaFiles(files: File[], mediaProvider: MediaProvider): Promise<(string | null)[]>;
|
|
1346
|
+
/**
|
|
1347
|
+
* Read a text-content file and return its content as a markdown string.
|
|
1348
|
+
*
|
|
1349
|
+
* - `.md` and `.txt` files are read as UTF-8 text directly
|
|
1350
|
+
* - `.docx` files are converted to markdown via `@bendyline/squisq-formats/docx`
|
|
1351
|
+
*/
|
|
1352
|
+
declare function processTextFile(file: File): Promise<string>;
|
|
1353
|
+
/**
|
|
1354
|
+
* Process multiple text files and concatenate their content.
|
|
1355
|
+
*/
|
|
1356
|
+
declare function processTextFiles(files: File[]): Promise<string>;
|
|
1357
|
+
|
|
1358
|
+
/**
|
|
1359
|
+
* Tiptap Bridge
|
|
1360
|
+
*
|
|
1361
|
+
* Conversion utilities between raw markdown source and Tiptap's JSON/HTML
|
|
1362
|
+
* content format. Uses a lightweight HTML-based approach: we convert markdown
|
|
1363
|
+
* to a simple HTML representation that Tiptap can consume, and parse
|
|
1364
|
+
* Tiptap's HTML output back to markdown.
|
|
1365
|
+
*
|
|
1366
|
+
* This bridge preserves markdown semantics much better than going through
|
|
1367
|
+
* Tiptap's native markdown extension, since we control the conversion
|
|
1368
|
+
* using squisq's own parser.
|
|
1369
|
+
*/
|
|
1370
|
+
/**
|
|
1371
|
+
* Convert raw markdown source to Tiptap-consumable HTML content.
|
|
1372
|
+
* Uses a simple markdown-to-HTML conversion that maps cleanly to
|
|
1373
|
+
* Tiptap's ProseMirror schema.
|
|
1374
|
+
*/
|
|
1375
|
+
declare function markdownToTiptap(markdown: string): string;
|
|
1376
|
+
/**
|
|
1377
|
+
* Convert Tiptap HTML output back to markdown source.
|
|
1378
|
+
* Extracts semantic structure from HTML and produces clean markdown.
|
|
1379
|
+
*/
|
|
1380
|
+
declare function tiptapToMarkdown(html: string): string;
|
|
1381
|
+
|
|
1382
|
+
/**
|
|
1383
|
+
* buildPreviewDoc — Converts a markdown-derived Doc into a player-ready Doc
|
|
1384
|
+
* with TemplateBlock slides and interleaved images.
|
|
1385
|
+
*
|
|
1386
|
+
* Shared between PreviewPanel (live preview) and export flows (HTML/video).
|
|
1387
|
+
*
|
|
1388
|
+
* Pipeline:
|
|
1389
|
+
* 1. Flatten hierarchical blocks into a linear slide sequence
|
|
1390
|
+
* 2. Convert each block into a TemplateBlock-compatible object
|
|
1391
|
+
* 3. Interleave images as standalone imageWithCaption slides
|
|
1392
|
+
* 4. Synthesize a dummy audio segment for timer-based playback
|
|
1393
|
+
*/
|
|
1394
|
+
|
|
1395
|
+
/**
|
|
1396
|
+
* Build a player-ready Doc from a markdown-derived Doc.
|
|
1397
|
+
*
|
|
1398
|
+
* Flattens hierarchical blocks, converts each to a TemplateBlock-compatible
|
|
1399
|
+
* slide, interleaves images, recalculates timing, and adds a synthetic
|
|
1400
|
+
* audio segment.
|
|
1401
|
+
*/
|
|
1402
|
+
declare function buildPreviewDoc(doc: Doc): Doc;
|
|
1403
|
+
|
|
1404
|
+
/**
|
|
1405
|
+
* TemplateAnnotation — Tiptap Heading Extension
|
|
1406
|
+
*
|
|
1407
|
+
* Extends Tiptap's built-in Heading node to support `data-template` and
|
|
1408
|
+
* `data-template-params` HTML attributes. These attributes store which block
|
|
1409
|
+
* template should be used for a heading section.
|
|
1410
|
+
*
|
|
1411
|
+
* When present, the heading renders a visible badge (styled CSS chip)
|
|
1412
|
+
* showing the template name, e.g. `[chart]`.
|
|
1413
|
+
*
|
|
1414
|
+
* The tiptapBridge converts `### Title {[chart]}` markdown into
|
|
1415
|
+
* `<h3 data-template="chart">Title</h3>` and back, so this extension
|
|
1416
|
+
* ensures Tiptap's schema preserves those attributes through edits.
|
|
1417
|
+
*/
|
|
1418
|
+
/**
|
|
1419
|
+
* HeadingWithTemplate — drop-in replacement for Tiptap's Heading that
|
|
1420
|
+
* persists template annotation attributes.
|
|
1421
|
+
*/
|
|
1422
|
+
declare const HeadingWithTemplate: _tiptap_core.Node<_tiptap_extension_heading.HeadingOptions, any>;
|
|
1423
|
+
|
|
1424
|
+
interface JsonEditorProps {
|
|
1425
|
+
/** Schema describing the value's shape (with optional `squisq` hints). */
|
|
1426
|
+
schema: SquisqAnnotatedSchema;
|
|
1427
|
+
/** Controlled value. */
|
|
1428
|
+
value: unknown;
|
|
1429
|
+
/** Called with the new root after each edit. Omit for read-only behavior. */
|
|
1430
|
+
onChange?: (next: unknown) => void;
|
|
1431
|
+
/** Optional theme. Defaults to `DEFAULT_THEME`. */
|
|
1432
|
+
theme?: Theme;
|
|
1433
|
+
/** Light/dark surface override; `'auto'` uses `prefers-color-scheme`. */
|
|
1434
|
+
surface?: SurfaceScheme | 'auto';
|
|
1435
|
+
/** Padding/gap density. Default: 'comfortable'. */
|
|
1436
|
+
density?: 'comfortable' | 'compact';
|
|
1437
|
+
/** Optional consumer-supplied validator (e.g. ajv-backed). */
|
|
1438
|
+
validate?: JsonFormValidator;
|
|
1439
|
+
/** Notified after validation runs. */
|
|
1440
|
+
onValidate?: (errors: readonly JsonFormValidationError[]) => void;
|
|
1441
|
+
/** Optional CSS class for the outer container. */
|
|
1442
|
+
className?: string;
|
|
1443
|
+
}
|
|
1444
|
+
declare function JsonEditor(props: JsonEditorProps): react_jsx_runtime.JSX.Element;
|
|
1445
|
+
|
|
1446
|
+
/**
|
|
1447
|
+
* Format probing for MediaRecorder.
|
|
1448
|
+
*
|
|
1449
|
+
* Different browsers expose different container/codec combinations. Chrome
|
|
1450
|
+
* and Firefox produce WebM (VP8/VP9 + Opus); Safari produces MP4 (H.264 +
|
|
1451
|
+
* AAC). We probe at runtime via `MediaRecorder.isTypeSupported()` and pick
|
|
1452
|
+
* the best supported option, falling back to whatever the browser hands
|
|
1453
|
+
* back when no probe succeeds.
|
|
1454
|
+
*/
|
|
1455
|
+
/** What the recorded stream is intended to capture. */
|
|
1456
|
+
type CaptureKind = 'audio' | 'video';
|
|
1457
|
+
/** A probed format choice — what to pass to `MediaRecorder` and where to write it. */
|
|
1458
|
+
interface ResolvedFormat {
|
|
1459
|
+
/** MIME type to pass to `new MediaRecorder(stream, { mimeType })`. Empty string means "let the browser pick". */
|
|
1460
|
+
mimeType: string;
|
|
1461
|
+
/** File extension to use when writing to the container, including the leading dot. */
|
|
1462
|
+
extension: string;
|
|
1463
|
+
/** Container directory inside the `ContentContainer` (no trailing slash). */
|
|
1464
|
+
directory: 'audio' | 'video';
|
|
1465
|
+
}
|
|
1466
|
+
/**
|
|
1467
|
+
* Resolve the format the recorder will use for a given capture kind. If a
|
|
1468
|
+
* `preferred` MIME type is supported, it wins; otherwise we fall through
|
|
1469
|
+
* the priority list. When nothing matches (extremely old browser), we
|
|
1470
|
+
* return an empty `mimeType` — `MediaRecorder` will pick a default and we
|
|
1471
|
+
* tag the file with `.webm` as a best guess.
|
|
1472
|
+
*/
|
|
1473
|
+
declare function resolveFormat(kind: CaptureKind, preferred?: string): ResolvedFormat;
|
|
1474
|
+
/**
|
|
1475
|
+
* `MediaRecorder` support probe. Returns false when running in a
|
|
1476
|
+
* non-browser environment (e.g. SSR) or on a browser that doesn't
|
|
1477
|
+
* implement the API at all.
|
|
1478
|
+
*/
|
|
1479
|
+
declare function supportsMediaRecorder(): boolean;
|
|
1480
|
+
/**
|
|
1481
|
+
* `getUserMedia` support probe (for mic / camera capture).
|
|
1482
|
+
*/
|
|
1483
|
+
declare function supportsUserMedia(): boolean;
|
|
1484
|
+
/**
|
|
1485
|
+
* `getDisplayMedia` support probe (for screen capture). Browsers may
|
|
1486
|
+
* implement `mediaDevices` without `getDisplayMedia` (Firefox on Android
|
|
1487
|
+
* being the long-standing example), so this is its own probe.
|
|
1488
|
+
*/
|
|
1489
|
+
declare function supportsDisplayMedia(): boolean;
|
|
1490
|
+
/**
|
|
1491
|
+
* Build a default filename for a recording. `basename` is a hint
|
|
1492
|
+
* (e.g. user-typed name); when omitted, a sortable timestamp is used so
|
|
1493
|
+
* concurrent recordings don't collide.
|
|
1494
|
+
*/
|
|
1495
|
+
declare function buildFilename(kind: CaptureKind, extension: string, basename?: string): string;
|
|
1496
|
+
|
|
1497
|
+
/**
|
|
1498
|
+
* useMediaRecorder
|
|
1499
|
+
*
|
|
1500
|
+
* React wrapper around `MediaRecorder` that handles stream acquisition,
|
|
1501
|
+
* the recorder lifecycle, and produces a single `Blob` on stop. Selects
|
|
1502
|
+
* a browser-supported MIME type via {@link resolveFormat}.
|
|
1503
|
+
*
|
|
1504
|
+
* Mirrors the shape of `useVideoExport` in `@bendyline/squisq-video-react`
|
|
1505
|
+
* (request → start → stop → blob), inverted for capture rather than
|
|
1506
|
+
* export.
|
|
1507
|
+
*/
|
|
1508
|
+
|
|
1509
|
+
/** Which capture source to use. `screen+mic` mixes the microphone into the screen stream. */
|
|
1510
|
+
type RecorderSource = 'mic' | 'camera' | 'screen' | 'screen+mic';
|
|
1511
|
+
/** Discriminated state describing what the recorder is currently doing. */
|
|
1512
|
+
type RecorderState = 'idle' | 'requesting' | 'ready' | 'recording' | 'stopping' | 'stopped' | 'error';
|
|
1513
|
+
interface UseMediaRecorderOptions {
|
|
1514
|
+
/** Which capture pipeline to use. */
|
|
1515
|
+
source: RecorderSource;
|
|
1516
|
+
/**
|
|
1517
|
+
* Preferred MIME type override. When the browser supports it, this
|
|
1518
|
+
* wins over the default candidate list. When unset (or unsupported),
|
|
1519
|
+
* the hook probes a built-in priority list.
|
|
1520
|
+
*/
|
|
1521
|
+
mimeType?: string;
|
|
1522
|
+
/** Video track constraints for camera / screen sources. */
|
|
1523
|
+
videoConstraints?: MediaTrackConstraints | boolean;
|
|
1524
|
+
/** Audio track constraints for mic / camera / screen+mic sources. */
|
|
1525
|
+
audioConstraints?: MediaTrackConstraints | boolean;
|
|
1526
|
+
/**
|
|
1527
|
+
* Bits-per-second hint passed to `MediaRecorder`. Most browsers cap to
|
|
1528
|
+
* reasonable defaults internally; leaving this undefined is usually
|
|
1529
|
+
* fine.
|
|
1530
|
+
*/
|
|
1531
|
+
bitsPerSecond?: number;
|
|
1532
|
+
/**
|
|
1533
|
+
* Whether to attempt to capture system audio when `source === 'screen'`
|
|
1534
|
+
* or `'screen+mic'`. Browser support is limited (desktop Chromium
|
|
1535
|
+
* only); when unsupported the resulting stream simply omits it.
|
|
1536
|
+
*/
|
|
1537
|
+
systemAudio?: boolean;
|
|
1538
|
+
}
|
|
1539
|
+
interface UseMediaRecorderResult {
|
|
1540
|
+
/** Current recorder state. */
|
|
1541
|
+
state: RecorderState;
|
|
1542
|
+
/** Live `MediaStream` after `request()` succeeds; useful for preview. */
|
|
1543
|
+
stream: MediaStream | null;
|
|
1544
|
+
/** Final `Blob` after `stop()` resolves, or `null` while recording. */
|
|
1545
|
+
blob: Blob | null;
|
|
1546
|
+
/** MIME type the recorder actually used (after `request()`). */
|
|
1547
|
+
mimeType: string | null;
|
|
1548
|
+
/** File extension matching `mimeType` (e.g. `.webm`). */
|
|
1549
|
+
extension: string | null;
|
|
1550
|
+
/** Suggested container directory (`'audio'` for mic, `'video'` for camera/screen). */
|
|
1551
|
+
directory: 'audio' | 'video' | null;
|
|
1552
|
+
/** Milliseconds elapsed since `start()` was called. Updates ~10× per second while recording. */
|
|
1553
|
+
durationMs: number;
|
|
1554
|
+
/** Most recent error, if any. */
|
|
1555
|
+
error: Error | null;
|
|
1556
|
+
/**
|
|
1557
|
+
* Acquire the stream and prepare a `MediaRecorder`. After this resolves
|
|
1558
|
+
* the hook is in `'ready'` state and a `<video>`/`<audio>` element can
|
|
1559
|
+
* preview `stream`. Call `start()` to begin recording.
|
|
1560
|
+
*/
|
|
1561
|
+
request: () => Promise<void>;
|
|
1562
|
+
/** Start recording. Must be called from `'ready'`. */
|
|
1563
|
+
start: () => void;
|
|
1564
|
+
/**
|
|
1565
|
+
* Stop recording and resolve with the resulting `Blob`. Safe to call
|
|
1566
|
+
* from `'recording'`; a no-op from any other state (resolves with the
|
|
1567
|
+
* existing `blob`, or `null`).
|
|
1568
|
+
*/
|
|
1569
|
+
stop: () => Promise<Blob | null>;
|
|
1570
|
+
/**
|
|
1571
|
+
* Tear everything down — stops the recorder if running, releases all
|
|
1572
|
+
* tracks, disposes the AudioContext mixer (if any), and returns to
|
|
1573
|
+
* `'idle'`. Always safe to call.
|
|
1574
|
+
*/
|
|
1575
|
+
cancel: () => void;
|
|
1576
|
+
/** Reset state without releasing the stream. Useful for re-recording. */
|
|
1577
|
+
reset: () => void;
|
|
1578
|
+
}
|
|
1579
|
+
/**
|
|
1580
|
+
* Returns the kind of capture that the given source produces. Exposed
|
|
1581
|
+
* separately from {@link useMediaRecorder} so non-React callers
|
|
1582
|
+
* (e.g. headless tests) can resolve a format up front.
|
|
1583
|
+
*/
|
|
1584
|
+
declare function getCaptureKind(source: RecorderSource): CaptureKind;
|
|
1585
|
+
declare function useMediaRecorder(options: UseMediaRecorderOptions): UseMediaRecorderResult;
|
|
1586
|
+
|
|
1587
|
+
interface RecorderModalProps {
|
|
1588
|
+
/** Required — recordings are written here. */
|
|
1589
|
+
mediaProvider: MediaProvider;
|
|
1590
|
+
/**
|
|
1591
|
+
* Optional — when provided, narration-mode recordings drop a
|
|
1592
|
+
* `.timing.json` sidecar at the matching container path so
|
|
1593
|
+
* `resolveAudioMapping()` can auto-link them. Without it, only the
|
|
1594
|
+
* raw recording is saved.
|
|
1595
|
+
*/
|
|
1596
|
+
container?: ContentContainer | null;
|
|
1597
|
+
/** Initial capture source. Defaults to `'mic'` (narration). */
|
|
1598
|
+
initialMode?: RecorderSource;
|
|
1599
|
+
/** Called after the modal is dismissed (save or cancel). */
|
|
1600
|
+
onClose: () => void;
|
|
1601
|
+
/**
|
|
1602
|
+
* Fired after a successful save. Hosts typically use this to insert a
|
|
1603
|
+
* markdown reference at the cursor — see {@link RecorderSaveResult}
|
|
1604
|
+
* for the fields a host needs to build that reference.
|
|
1605
|
+
*/
|
|
1606
|
+
onSave?: (result: RecorderSaveResult) => void;
|
|
1607
|
+
}
|
|
1608
|
+
/** Payload handed to {@link RecorderModalProps.onSave} on a successful save. */
|
|
1609
|
+
interface RecorderSaveResult {
|
|
1610
|
+
/** Path returned by `mediaProvider.addMedia()` — what the doc should reference. */
|
|
1611
|
+
relativePath: string;
|
|
1612
|
+
/** Filename the modal chose (e.g. `narration-20260516-091200.webm`). */
|
|
1613
|
+
filename: string;
|
|
1614
|
+
/** Capture source the user picked. */
|
|
1615
|
+
source: RecorderSource;
|
|
1616
|
+
/** MIME type of the saved blob. */
|
|
1617
|
+
mimeType: string;
|
|
1618
|
+
/** Recording length in seconds. */
|
|
1619
|
+
duration: number;
|
|
1620
|
+
/** Whether a narration sidecar was written. Always `false` for video sources. */
|
|
1621
|
+
hasTimingSidecar: boolean;
|
|
1622
|
+
/** Script text the user typed (narration only). */
|
|
1623
|
+
sourceText?: string;
|
|
1624
|
+
}
|
|
1625
|
+
declare function RecorderModal({ mediaProvider, container, initialMode, onClose, onSave, }: RecorderModalProps): react_jsx_runtime.JSX.Element;
|
|
1626
|
+
|
|
1627
|
+
interface RecorderButtonProps {
|
|
1628
|
+
/** Where to write the resulting recording. Required. */
|
|
1629
|
+
mediaProvider: MediaProvider;
|
|
1630
|
+
/** Optional container for narration `.timing.json` sidecar writes. */
|
|
1631
|
+
container?: ContentContainer | null;
|
|
1632
|
+
/** Initial capture source. Defaults to `'mic'`. */
|
|
1633
|
+
initialMode?: RecorderSource;
|
|
1634
|
+
/** Fired after a successful save. */
|
|
1635
|
+
onSave?: (result: RecorderSaveResult) => void;
|
|
1636
|
+
/** Button label. Defaults to `'Record'`. */
|
|
1637
|
+
label?: string;
|
|
1638
|
+
/** Optional inline button styles. */
|
|
1639
|
+
style?: CSSProperties;
|
|
1640
|
+
/** Whether the button is disabled. */
|
|
1641
|
+
disabled?: boolean;
|
|
1642
|
+
}
|
|
1643
|
+
declare function RecorderButton({ mediaProvider, container, initialMode, onSave, label, style, disabled, }: RecorderButtonProps): react_jsx_runtime.JSX.Element;
|
|
1644
|
+
|
|
1645
|
+
interface RecorderPanelProps {
|
|
1646
|
+
mediaProvider: MediaProvider;
|
|
1647
|
+
container?: ContentContainer | null;
|
|
1648
|
+
initialMode?: RecorderSource;
|
|
1649
|
+
onSave?: (result: RecorderSaveResult) => void;
|
|
1650
|
+
/** ARIA / tooltip label. Defaults to `'Record media'`. */
|
|
1651
|
+
tooltip?: string;
|
|
1652
|
+
/** Optional className for the trigger button. */
|
|
1653
|
+
className?: string;
|
|
1654
|
+
}
|
|
1655
|
+
declare function RecorderPanel({ mediaProvider, container, initialMode, onSave, tooltip, className, }: RecorderPanelProps): react_jsx_runtime.JSX.Element;
|
|
1656
|
+
|
|
1657
|
+
/**
|
|
1658
|
+
* useStreamPreview — binds a `MediaStream` to a `<video>` element's
|
|
1659
|
+
* `srcObject`. Decouples the preview surface from `useMediaRecorder`,
|
|
1660
|
+
* letting hosts compose the preview element however they like.
|
|
1661
|
+
*/
|
|
1662
|
+
|
|
1663
|
+
/**
|
|
1664
|
+
* Assign `stream` to `<video>.srcObject` whenever either changes; clears
|
|
1665
|
+
* it on unmount or when `stream` is `null`. The element is set to
|
|
1666
|
+
* `playsInline` + `muted` automatically because previewing your own
|
|
1667
|
+
* microphone with audio playthrough creates a feedback loop.
|
|
8
1668
|
*
|
|
9
1669
|
* @example
|
|
10
1670
|
* ```tsx
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* return <EditorShell initialMarkdown="# Hello World" />;
|
|
16
|
-
* }
|
|
1671
|
+
* const videoRef = useRef<HTMLVideoElement>(null);
|
|
1672
|
+
* const { stream } = useMediaRecorder({ source: 'camera' });
|
|
1673
|
+
* useStreamPreview(videoRef, stream);
|
|
1674
|
+
* return <video ref={videoRef} autoPlay />;
|
|
17
1675
|
* ```
|
|
18
1676
|
*/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
1677
|
+
declare function useStreamPreview(ref: RefObject<HTMLVideoElement | null>, stream: MediaStream | null): void;
|
|
1678
|
+
|
|
1679
|
+
/**
|
|
1680
|
+
* Microphone-only capture via `getUserMedia({ audio: true })`.
|
|
1681
|
+
*/
|
|
1682
|
+
/**
|
|
1683
|
+
* Request a microphone-only `MediaStream`. Caller owns the stream and
|
|
1684
|
+
* must stop its tracks when done.
|
|
1685
|
+
*
|
|
1686
|
+
* @param constraints - Optional audio constraints (sample rate, device
|
|
1687
|
+
* id, echo cancellation, etc.). Defaults to `true` — let the browser
|
|
1688
|
+
* pick.
|
|
1689
|
+
* @throws When `mediaDevices` is unavailable, or when the user denies
|
|
1690
|
+
* permission (the underlying `getUserMedia` rejection propagates).
|
|
1691
|
+
*/
|
|
1692
|
+
declare function requestMicStream(constraints?: MediaTrackConstraints): Promise<MediaStream>;
|
|
1693
|
+
|
|
1694
|
+
/**
|
|
1695
|
+
* Camera + microphone capture via `getUserMedia({ video, audio })`.
|
|
1696
|
+
*/
|
|
1697
|
+
interface CameraStreamOptions {
|
|
1698
|
+
/** Video track constraints (resolution, facing mode, frame rate). Pass `true` for browser default, or `false` to omit video. */
|
|
1699
|
+
video?: boolean | MediaTrackConstraints;
|
|
1700
|
+
/** Audio track constraints. Pass `true` for browser default, or `false` to omit audio. */
|
|
1701
|
+
audio?: boolean | MediaTrackConstraints;
|
|
1702
|
+
}
|
|
1703
|
+
/**
|
|
1704
|
+
* Request a camera + mic `MediaStream`. Caller owns the stream and must
|
|
1705
|
+
* stop its tracks when done.
|
|
1706
|
+
*
|
|
1707
|
+
* Both tracks are requested by default. To capture video only, pass
|
|
1708
|
+
* `audio: false`; to capture audio only use {@link requestMicStream}
|
|
1709
|
+
* instead.
|
|
1710
|
+
*
|
|
1711
|
+
* @throws When `mediaDevices` is unavailable, or when the user denies
|
|
1712
|
+
* permission.
|
|
1713
|
+
*/
|
|
1714
|
+
declare function requestCameraStream(options?: CameraStreamOptions): Promise<MediaStream>;
|
|
1715
|
+
|
|
1716
|
+
/**
|
|
1717
|
+
* Screen capture via `getDisplayMedia`, with optional microphone mixing.
|
|
1718
|
+
*
|
|
1719
|
+
* The browser-native `getDisplayMedia({ audio: true })` flag only
|
|
1720
|
+
* captures *system* audio (and only on Chromium on desktop). For
|
|
1721
|
+
* narrated screencasts, hosts usually want the speaker's voice too —
|
|
1722
|
+
* we provide an opt-in "include mic" path that pulls a parallel
|
|
1723
|
+
* `getUserMedia` audio track and mixes it into the screen stream via
|
|
1724
|
+
* `AudioContext`, so the resulting `MediaStream` carries a single audio
|
|
1725
|
+
* track and a single video track.
|
|
1726
|
+
*/
|
|
1727
|
+
interface ScreenStreamOptions {
|
|
1728
|
+
/** Video constraints for the screen surface. Pass `true` for browser default. */
|
|
1729
|
+
video?: boolean | MediaTrackConstraints;
|
|
1730
|
+
/**
|
|
1731
|
+
* Whether to attempt to capture the system audio (tab / window / monitor
|
|
1732
|
+
* audio). Browser support is limited (desktop Chromium only); when the
|
|
1733
|
+
* platform doesn't honor this flag, the resulting stream simply omits
|
|
1734
|
+
* the system audio track.
|
|
1735
|
+
*/
|
|
1736
|
+
systemAudio?: boolean;
|
|
1737
|
+
/**
|
|
1738
|
+
* Whether to also pull the microphone via `getUserMedia` and mix it
|
|
1739
|
+
* into the resulting stream's audio track. When both `systemAudio` and
|
|
1740
|
+
* `includeMicrophone` produce tracks, they're combined via
|
|
1741
|
+
* `AudioContext` into a single output track.
|
|
1742
|
+
*/
|
|
1743
|
+
includeMicrophone?: boolean;
|
|
1744
|
+
/** Microphone track constraints, when `includeMicrophone` is true. */
|
|
1745
|
+
microphoneConstraints?: MediaTrackConstraints;
|
|
1746
|
+
}
|
|
1747
|
+
/**
|
|
1748
|
+
* Handle returned by {@link requestScreenStream}. The `stream` is what
|
|
1749
|
+
* gets handed to `MediaRecorder`; the `dispose()` callback shuts down
|
|
1750
|
+
* any auxiliary resources (e.g. the mic-mix `AudioContext`). Callers
|
|
1751
|
+
* must also stop the stream's tracks via `stream.getTracks().forEach(t
|
|
1752
|
+
* => t.stop())` when done — `dispose()` cleans up everything that isn't
|
|
1753
|
+
* the stream itself.
|
|
1754
|
+
*/
|
|
1755
|
+
interface ScreenStreamHandle {
|
|
1756
|
+
stream: MediaStream;
|
|
1757
|
+
/** Auxiliary cleanup beyond the stream tracks. Safe to call multiple times. */
|
|
1758
|
+
dispose: () => void;
|
|
1759
|
+
}
|
|
1760
|
+
/**
|
|
1761
|
+
* Request a screen-capture `MediaStream`, optionally with a mixed-in
|
|
1762
|
+
* microphone track. Caller owns the resulting stream.
|
|
1763
|
+
*
|
|
1764
|
+
* @throws When `getDisplayMedia` isn't available, or when the user
|
|
1765
|
+
* cancels the picker / denies permission.
|
|
1766
|
+
*/
|
|
1767
|
+
declare function requestScreenStream(options?: ScreenStreamOptions): Promise<ScreenStreamHandle>;
|
|
1768
|
+
|
|
1769
|
+
/**
|
|
1770
|
+
* Build the `.timing.json` sidecar that pairs with a narration recording.
|
|
1771
|
+
*
|
|
1772
|
+
* The shape matches what `resolveAudioMapping()` in
|
|
1773
|
+
* `@bendyline/squisq` reads at runtime: `sourceText`, `duration`, and
|
|
1774
|
+
* `bookmarks[]`. Sidecars are stored at `<audio-path>.timing.json`
|
|
1775
|
+
* inside the same `ContentContainer`, so the recorder can drop them
|
|
1776
|
+
* alongside its audio file and have the existing audio-mapping pipeline
|
|
1777
|
+
* pick them up with no schema changes.
|
|
1778
|
+
*/
|
|
1779
|
+
/**
|
|
1780
|
+
* Word-level timing bookmark — same shape as `AudioBookmark` in
|
|
1781
|
+
* `@bendyline/squisq`. Recorder output produces an empty `bookmarks`
|
|
1782
|
+
* array; word-level timing is the domain of TTS pipelines, not
|
|
1783
|
+
* browser-side dictation.
|
|
1784
|
+
*/
|
|
1785
|
+
interface RecordedBookmark {
|
|
1786
|
+
id: string;
|
|
1787
|
+
time: number;
|
|
1788
|
+
charOffset: number;
|
|
1789
|
+
textFragment?: string;
|
|
1790
|
+
}
|
|
1791
|
+
interface TimingJson {
|
|
1792
|
+
/** Plain text the user said (or intended to say) during the recording. */
|
|
1793
|
+
sourceText: string;
|
|
1794
|
+
/** Recording length in seconds. */
|
|
1795
|
+
duration: number;
|
|
1796
|
+
/** Word-level timing data. Empty by default — populated only when a downstream tool aligns the audio. */
|
|
1797
|
+
bookmarks: RecordedBookmark[];
|
|
1798
|
+
}
|
|
1799
|
+
/**
|
|
1800
|
+
* Build a `TimingJson` payload from a user-typed script and the
|
|
1801
|
+
* recording's measured duration. Both fields are required by the
|
|
1802
|
+
* downstream `parseTimingJson()` validator; missing them produces a
|
|
1803
|
+
* sidecar that gets silently dropped by the audio-mapping pipeline.
|
|
1804
|
+
*/
|
|
1805
|
+
declare function buildTimingJson(sourceText: string, durationSec: number): TimingJson;
|
|
1806
|
+
/**
|
|
1807
|
+
* Serialize a `TimingJson` payload to a `Uint8Array` ready to hand to
|
|
1808
|
+
* `ContentContainer.writeFile()`. Pretty-printed so authors can hand-
|
|
1809
|
+
* edit the sidecar if they ever want to.
|
|
1810
|
+
*/
|
|
1811
|
+
declare function encodeTimingJson(timing: TimingJson): Uint8Array;
|
|
1812
|
+
/**
|
|
1813
|
+
* The container path convention `resolveAudioMapping()` expects:
|
|
1814
|
+
* `<audio-path>.timing.json`. Pass the audio file's relative path
|
|
1815
|
+
* (e.g. `'audio/narration-001.webm'`) and the matching sidecar path is
|
|
1816
|
+
* returned (`'audio/narration-001.webm.timing.json'`).
|
|
1817
|
+
*/
|
|
1818
|
+
declare function timingPathFor(audioRelativePath: string): string;
|
|
1819
|
+
|
|
1820
|
+
interface ImageEditorProps {
|
|
1821
|
+
/**
|
|
1822
|
+
* Scoped sidecar container for this image — typically
|
|
1823
|
+
* `scopeContainer(parent, basename + '_files')`.
|
|
1824
|
+
*/
|
|
1825
|
+
filesContainer: ContentContainer;
|
|
1826
|
+
/**
|
|
1827
|
+
* Source URL used to seed `assets/source.<ext>` and layer 0 the
|
|
1828
|
+
* first time the sidecar is opened. Ignored once `state.json` exists.
|
|
1829
|
+
*/
|
|
1830
|
+
initialSrc?: string;
|
|
1831
|
+
/** Override the state filename. Default: `state.json`. */
|
|
1832
|
+
stateFilename?: string;
|
|
1833
|
+
/** Enable version-history snapshots in `.versions/`. Default: `false`. */
|
|
1834
|
+
allowVersioning?: boolean;
|
|
1835
|
+
/** Auto-save idle delay (ms) for version snapshots. Default: `5000`. */
|
|
1836
|
+
versioningAutoSaveIdleMs?: number;
|
|
1837
|
+
/** Called after the user clicks Export and the blob is produced. */
|
|
1838
|
+
onExport?: (blob: Blob, format: ImageEditExportFormat) => void;
|
|
1839
|
+
/**
|
|
1840
|
+
* What the toolbar's Save button does:
|
|
1841
|
+
* - `'flush'` (default): write `state.json` to the sidecar.
|
|
1842
|
+
* - `'export'`: rasterize the canvas in `saveFormat` and fire
|
|
1843
|
+
* {@link onExport} — the same code path the Export menu uses.
|
|
1844
|
+
* Hosts that want one-click "save and close" semantics use this.
|
|
1845
|
+
*/
|
|
1846
|
+
saveBehavior?: 'flush' | 'export';
|
|
1847
|
+
/** Format used when `saveBehavior === 'export'`. Default: `'png'`. */
|
|
1848
|
+
saveFormat?: ImageEditExportFormat;
|
|
1849
|
+
/** Override the Save button label. Default: `'Save'`. */
|
|
1850
|
+
saveLabel?: string;
|
|
1851
|
+
/** Override the Save button tooltip. */
|
|
1852
|
+
saveTitle?: string;
|
|
1853
|
+
/**
|
|
1854
|
+
* Squisq Theme to color the editor chrome (toolbar, panels, controls).
|
|
1855
|
+
* Defaults to `DEFAULT_THEME`. Combined with {@link surface} the same
|
|
1856
|
+
* way `<JsonView>` and `<LinearDocView>` do.
|
|
1857
|
+
*/
|
|
1858
|
+
theme?: Theme;
|
|
1859
|
+
/**
|
|
1860
|
+
* Surface scheme — `LIGHT_SURFACE`, `DARK_SURFACE`, an explicit
|
|
1861
|
+
* `SurfaceScheme` object, or `'auto'` to track the user's OS
|
|
1862
|
+
* `prefers-color-scheme`. When omitted, the theme's own background is
|
|
1863
|
+
* used as-is.
|
|
1864
|
+
*/
|
|
1865
|
+
surface?: SurfaceScheme | 'auto';
|
|
1866
|
+
/** Optional className for the root element. */
|
|
1867
|
+
className?: string;
|
|
1868
|
+
}
|
|
1869
|
+
declare function ImageEditor(props: ImageEditorProps): react_jsx_runtime.JSX.Element;
|
|
1870
|
+
|
|
1871
|
+
/**
|
|
1872
|
+
* Pure state + reducer for the `<ImageEditor>` component.
|
|
1873
|
+
*
|
|
1874
|
+
* Kept React-free so it's easy to unit-test in isolation. The actual
|
|
1875
|
+
* React hook that wires this to a {@link ContentContainer} (and the
|
|
1876
|
+
* version manager) lives in `useImageEditor.ts`.
|
|
1877
|
+
*/
|
|
1878
|
+
|
|
1879
|
+
/**
|
|
1880
|
+
* Layer payload accepted by the `add-layer` action — the `id` field is
|
|
1881
|
+
* optional and will be assigned by the underlying `addLayer` helper if
|
|
1882
|
+
* the caller doesn't supply one.
|
|
1883
|
+
*/
|
|
1884
|
+
type ImageEditLayerInput = ImageEditLayer | (Omit<ImageEditLayer, 'id'> & {
|
|
1885
|
+
id?: string;
|
|
1886
|
+
});
|
|
1887
|
+
/** The currently active interaction tool. */
|
|
1888
|
+
type ImageEditorTool = 'select' | 'text' | 'shape' | 'image' | 'crop';
|
|
1889
|
+
/** A pixel-space rectangle in canvas coordinates. */
|
|
1890
|
+
interface CanvasRect {
|
|
1891
|
+
x: number;
|
|
1892
|
+
y: number;
|
|
1893
|
+
width: number;
|
|
1894
|
+
height: number;
|
|
1895
|
+
}
|
|
1896
|
+
interface ImageEditorState {
|
|
1897
|
+
/** The persisted document. */
|
|
1898
|
+
doc: ImageEditDoc;
|
|
1899
|
+
/** Selected layer id, or `null` when nothing is selected. */
|
|
1900
|
+
selectedLayerId: string | null;
|
|
1901
|
+
/** Active tool. */
|
|
1902
|
+
tool: ImageEditorTool;
|
|
1903
|
+
/**
|
|
1904
|
+
* Dirty flag — true when the in-memory doc has unsaved changes
|
|
1905
|
+
* relative to the last `markClean()` call. The hook uses this to
|
|
1906
|
+
* debounce writes back to `state.json`.
|
|
1907
|
+
*/
|
|
1908
|
+
dirty: boolean;
|
|
1909
|
+
}
|
|
1910
|
+
type ImageEditorAction = {
|
|
1911
|
+
type: 'load';
|
|
1912
|
+
doc: ImageEditDoc;
|
|
1913
|
+
} | {
|
|
1914
|
+
type: 'mark-clean';
|
|
1915
|
+
} | {
|
|
1916
|
+
type: 'set-tool';
|
|
1917
|
+
tool: ImageEditorTool;
|
|
1918
|
+
} | {
|
|
1919
|
+
type: 'select';
|
|
1920
|
+
layerId: string | null;
|
|
1921
|
+
} | {
|
|
1922
|
+
type: 'set-canvas';
|
|
1923
|
+
canvas: ImageEditDoc['canvas'];
|
|
1924
|
+
} | {
|
|
1925
|
+
type: 'add-layer';
|
|
1926
|
+
layer: ImageEditLayerInput;
|
|
1927
|
+
select?: boolean;
|
|
1928
|
+
} | {
|
|
1929
|
+
type: 'remove-layer';
|
|
1930
|
+
layerId: string;
|
|
1931
|
+
} | {
|
|
1932
|
+
type: 'update-layer';
|
|
1933
|
+
layerId: string;
|
|
1934
|
+
patch: Partial<ImageEditLayer>;
|
|
1935
|
+
} | {
|
|
1936
|
+
type: 'reorder-layer';
|
|
1937
|
+
layerId: string;
|
|
1938
|
+
toIndex: number;
|
|
1939
|
+
} | {
|
|
1940
|
+
type: 'crop';
|
|
1941
|
+
rect: CanvasRect;
|
|
1942
|
+
};
|
|
1943
|
+
/** Build the initial state from a freshly-loaded doc. */
|
|
1944
|
+
declare function initialImageEditorState(doc: ImageEditDoc): ImageEditorState;
|
|
1945
|
+
declare function imageEditorReducer(state: ImageEditorState, action: ImageEditorAction): ImageEditorState;
|
|
1946
|
+
|
|
1947
|
+
/**
|
|
1948
|
+
* React hook that bundles the image-editor reducer with sidecar
|
|
1949
|
+
* persistence, versioning, and an object-URL cache for asset bytes.
|
|
1950
|
+
*
|
|
1951
|
+
* Hosts pass an already-scoped {@link ContentContainer} (typically built
|
|
1952
|
+
* with `scopeContainer(parent, basename + '_files')`); the hook never
|
|
1953
|
+
* looks above that root.
|
|
1954
|
+
*/
|
|
1955
|
+
|
|
1956
|
+
interface UseImageEditorOptions {
|
|
1957
|
+
/** Sidecar container for the image being edited. */
|
|
1958
|
+
container: ContentContainer;
|
|
1959
|
+
/**
|
|
1960
|
+
* Initial source image URL — used to seed layer 0 when the sidecar has
|
|
1961
|
+
* no `state.json` yet. Bytes are fetched and copied into
|
|
1962
|
+
* `assets/source.<ext>` so the doc is portable.
|
|
1963
|
+
*/
|
|
1964
|
+
initialSrc?: string;
|
|
1965
|
+
/** Override the state filename. Defaults to `state.json`. */
|
|
1966
|
+
stateFilename?: string;
|
|
1967
|
+
/** Enable version history. Default: `false`. */
|
|
1968
|
+
allowVersioning?: boolean;
|
|
1969
|
+
/** Auto-save idle delay (ms). `0` disables. Default: `5000`. */
|
|
1970
|
+
versioningAutoSaveIdleMs?: number;
|
|
1971
|
+
/** Debounced write delay for state.json (ms). Default: `500`. */
|
|
1972
|
+
persistDebounceMs?: number;
|
|
1973
|
+
}
|
|
1974
|
+
interface UseImageEditorReturn {
|
|
1975
|
+
/** Current reducer state (or `null` while still loading the initial doc). */
|
|
1976
|
+
state: ImageEditorState | null;
|
|
1977
|
+
/** Dispatch a reducer action. No-op while loading. */
|
|
1978
|
+
dispatch: (action: ImageEditorAction) => void;
|
|
1979
|
+
/** Manually trigger a synchronous write of `state.json`. */
|
|
1980
|
+
flush: () => Promise<void>;
|
|
1981
|
+
/** Resolve an asset path inside the sidecar to a blob URL (cached). */
|
|
1982
|
+
resolveAssetUrl: (path: string) => Promise<string>;
|
|
1983
|
+
/**
|
|
1984
|
+
* Write a new asset (raster image) into `assets/` and return the
|
|
1985
|
+
* sidecar-relative path. The caller is then expected to push a layer
|
|
1986
|
+
* referencing that path.
|
|
1987
|
+
*/
|
|
1988
|
+
uploadAsset: (file: Blob, suggestedName?: string) => Promise<string>;
|
|
1989
|
+
/** Versioning handle. `null` when `allowVersioning` is false or no container. */
|
|
1990
|
+
versioning: ImageEditVersionManager | null;
|
|
1991
|
+
/** True after the initial load completes (either an existing doc or seeded). */
|
|
1992
|
+
ready: boolean;
|
|
1993
|
+
/** Last load / persistence error, if any. */
|
|
1994
|
+
error: Error | null;
|
|
1995
|
+
}
|
|
1996
|
+
declare function useImageEditor(options: UseImageEditorOptions): UseImageEditorReturn;
|
|
1997
|
+
|
|
1998
|
+
export { ALL_EMOJIS, type CameraStreamOptions, type CanvasRect, type CaptureKind, type DocumentLinkCandidate, type DocumentLinkProvider, DocumentSettingsDialog, type DocumentSettingsDialogProps, type DragContentType, type DropTarget, DropZoneOverlay, type DropZoneOverlayProps, EMOJI_CATEGORIES, type EditorActions, type EditorContextValue, type EditorMode, EditorProvider, type EditorProviderProps, EditorShell, type EditorShellProps, type EditorState, type EditorTheme, type EditorView, type EmojiCategory, type EmojiEntry, EmojiPicker, type EmojiPickerProps, type FileCategory, type FileKind, HeadingWithTemplate, type ImageDisplayMode, ImageEditor, type ImageEditorAction, type ImageEditorProps, type ImageEditorState, type ImageEditorTool, ImageViewer, type ImageViewerProps, InlinePreviewGutter, type InlinePreviewGutterProps, JsonEditor, type JsonEditorProps, MediaBin, type MediaBinProps, type MentionCandidate, type MentionProvider, OutlinePanel, type OutlinePanelProps, PlainHtmlPreview, type PlainHtmlPreviewProps, PreviewPanel, type PreviewPanelProps, type PreviewSettings, PreviewSettingsProvider, PreviewToolbarControls, RawEditor, type RawEditorProps, type RecordedBookmark, RecorderButton, type RecorderButtonProps, RecorderModal, type RecorderModalProps, RecorderPanel, type RecorderPanelProps, type RecorderSaveResult, type RecorderSource, type RecorderState, type ResolvedFormat, type ScreenStreamHandle, type ScreenStreamOptions, StatusBar, type StatusBarProps, TemplatePicker, ThemeCustomizerPanel, type ThemeCustomizerPanelProps, type ThemeInheritance, ThemePicker, type ThemePickerProps, type TimingJson, Toolbar, type ToolbarProps, TooltipLayer, type UseFileDropOptions, type UseFileDropResult, type UseImageEditorOptions, type UseImageEditorReturn, type UseMediaRecorderOptions, type UseMediaRecorderResult, VersionHistoryPanel, ViewMenuPanel, type ViewPreferences, ViewSwitcher, type ViewSwitcherProps, WysiwygEditor, type WysiwygEditorProps, buildFilename, buildPreviewDoc, buildTimingJson, classifyFile, detectLanguageFromFileName, encodeTimingJson, getCaptureKind, imageEditorReducer, initialImageEditorState, markdownToTiptap, partitionFiles, processMediaFiles, processTextFile, processTextFiles, requestCameraStream, requestMicStream, requestScreenStream, resolveFileKind, resolveFormat, searchEmojis, supportsDisplayMedia, supportsMediaRecorder, supportsUserMedia, templateLabel, timingPathFor, tiptapToMarkdown, useEditorContext, useFileDrop, useImageEditor, useMediaRecorder, usePreviewSettings, useStreamPreview };
|