@bendyline/docblocks-react 1.1.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -15
- package/dist/AppMenu/AppMenu.d.ts +29 -2
- package/dist/AppMenu/AppMenu.d.ts.map +1 -1
- package/dist/AppMenu/AppMenu.js +41 -2
- package/dist/AppMenu/AppMenu.js.map +1 -1
- package/dist/AppMenu/index.d.ts +1 -1
- package/dist/AppMenu/index.d.ts.map +1 -1
- package/dist/DocBlocksShell/DocBlocksShell.d.ts +17 -4
- package/dist/DocBlocksShell/DocBlocksShell.d.ts.map +1 -1
- package/dist/DocBlocksShell/DocBlocksShell.js +1710 -299
- package/dist/DocBlocksShell/DocBlocksShell.js.map +1 -1
- package/dist/DocBlocksShell/LazyEditorShell.d.ts +3 -0
- package/dist/DocBlocksShell/LazyEditorShell.d.ts.map +1 -0
- package/dist/DocBlocksShell/LazyEditorShell.js +3 -0
- package/dist/DocBlocksShell/LazyEditorShell.js.map +1 -0
- package/dist/DocBlocksShell/UpdateAvailableNotice.d.ts +13 -0
- package/dist/DocBlocksShell/UpdateAvailableNotice.d.ts.map +1 -0
- package/dist/DocBlocksShell/UpdateAvailableNotice.js +16 -0
- package/dist/DocBlocksShell/UpdateAvailableNotice.js.map +1 -0
- package/dist/DocBlocksShell/document-title.d.ts +3 -0
- package/dist/DocBlocksShell/document-title.d.ts.map +1 -0
- package/dist/DocBlocksShell/document-title.js +17 -0
- package/dist/DocBlocksShell/document-title.js.map +1 -0
- package/dist/DocBlocksShell/workspace-authority-barrier.d.ts +14 -0
- package/dist/DocBlocksShell/workspace-authority-barrier.d.ts.map +1 -0
- package/dist/DocBlocksShell/workspace-authority-barrier.js +23 -0
- package/dist/DocBlocksShell/workspace-authority-barrier.js.map +1 -0
- package/dist/Export/DeferredExportToolbarControls.d.ts +5 -0
- package/dist/Export/DeferredExportToolbarControls.d.ts.map +1 -0
- package/dist/Export/DeferredExportToolbarControls.js +10 -0
- package/dist/Export/DeferredExportToolbarControls.js.map +1 -0
- package/dist/Export/ExportDialog.d.ts +10 -1
- package/dist/Export/ExportDialog.d.ts.map +1 -1
- package/dist/Export/ExportDialog.js +39 -20
- package/dist/Export/ExportDialog.js.map +1 -1
- package/dist/Export/ExportToolbarControls.d.ts +21 -1
- package/dist/Export/ExportToolbarControls.d.ts.map +1 -1
- package/dist/Export/ExportToolbarControls.js +161 -26
- package/dist/Export/ExportToolbarControls.js.map +1 -1
- package/dist/Export/export-destination.d.ts +3 -0
- package/dist/Export/export-destination.d.ts.map +1 -0
- package/dist/Export/export-destination.js +32 -0
- package/dist/Export/export-destination.js.map +1 -0
- package/dist/Export/index.d.ts +8 -4
- package/dist/Export/index.d.ts.map +1 -1
- package/dist/Export/index.js +4 -1
- package/dist/Export/index.js.map +1 -1
- package/dist/Export/public-api.d.ts +12 -0
- package/dist/Export/public-api.d.ts.map +1 -0
- package/dist/Export/public-api.js +9 -0
- package/dist/Export/public-api.js.map +1 -0
- package/dist/Export/run-export.d.ts +3 -1
- package/dist/Export/run-export.d.ts.map +1 -1
- package/dist/Export/run-export.js +58 -25
- package/dist/Export/run-export.js.map +1 -1
- package/dist/Export/transform-summaries.d.ts +7 -0
- package/dist/Export/transform-summaries.d.ts.map +1 -0
- package/dist/Export/transform-summaries.js +6 -0
- package/dist/Export/transform-summaries.js.map +1 -0
- package/dist/ExportDialog-MEUISWZX.js +9 -0
- package/dist/ExportDialog-MEUISWZX.js.map +1 -0
- package/dist/ExportToolbarControls-D2YDWOXW.js +373 -0
- package/dist/ExportToolbarControls-D2YDWOXW.js.map +1 -0
- package/dist/FileExplorer/FileExplorer.d.ts +26 -4
- package/dist/FileExplorer/FileExplorer.d.ts.map +1 -1
- package/dist/FileExplorer/FileExplorer.js +204 -29
- package/dist/FileExplorer/FileExplorer.js.map +1 -1
- package/dist/FileExplorer/FileTreeNode.d.ts +24 -3
- package/dist/FileExplorer/FileTreeNode.d.ts.map +1 -1
- package/dist/FileExplorer/FileTreeNode.js +27 -8
- package/dist/FileExplorer/FileTreeNode.js.map +1 -1
- package/dist/FileExplorer/index.d.ts +1 -1
- package/dist/FileExplorer/index.d.ts.map +1 -1
- package/dist/FileExplorer/useFileTree.d.ts +5 -3
- package/dist/FileExplorer/useFileTree.d.ts.map +1 -1
- package/dist/FileExplorer/useFileTree.js +173 -13
- package/dist/FileExplorer/useFileTree.js.map +1 -1
- package/dist/Git/GitAuthGuidanceDialog.d.ts +18 -0
- package/dist/Git/GitAuthGuidanceDialog.d.ts.map +1 -0
- package/dist/Git/GitAuthGuidanceDialog.js +27 -0
- package/dist/Git/GitAuthGuidanceDialog.js.map +1 -0
- package/dist/Git/GitBranchesDialog.d.ts +13 -0
- package/dist/Git/GitBranchesDialog.d.ts.map +1 -0
- package/dist/Git/GitBranchesDialog.js +59 -0
- package/dist/Git/GitBranchesDialog.js.map +1 -0
- package/dist/Git/GitCloneDialog.d.ts +14 -0
- package/dist/Git/GitCloneDialog.d.ts.map +1 -0
- package/dist/Git/GitCloneDialog.js +79 -0
- package/dist/Git/GitCloneDialog.js.map +1 -0
- package/dist/Git/GitCommitDialog.d.ts +12 -0
- package/dist/Git/GitCommitDialog.d.ts.map +1 -0
- package/dist/Git/GitCommitDialog.js +38 -0
- package/dist/Git/GitCommitDialog.js.map +1 -0
- package/dist/Git/GitConflictsDialog.d.ts +12 -0
- package/dist/Git/GitConflictsDialog.d.ts.map +1 -0
- package/dist/Git/GitConflictsDialog.js +17 -0
- package/dist/Git/GitConflictsDialog.js.map +1 -0
- package/dist/Git/GitContext.d.ts +89 -0
- package/dist/Git/GitContext.d.ts.map +1 -0
- package/dist/Git/GitContext.js +15 -0
- package/dist/Git/GitContext.js.map +1 -0
- package/dist/Git/GitDiffDialog.d.ts +20 -0
- package/dist/Git/GitDiffDialog.d.ts.map +1 -0
- package/dist/Git/GitDiffDialog.js +100 -0
- package/dist/Git/GitDiffDialog.js.map +1 -0
- package/dist/Git/GitDiffView.d.ts +23 -0
- package/dist/Git/GitDiffView.d.ts.map +1 -0
- package/dist/Git/GitDiffView.js +77 -0
- package/dist/Git/GitDiffView.js.map +1 -0
- package/dist/Git/GitHistoryDialog.d.ts +15 -0
- package/dist/Git/GitHistoryDialog.d.ts.map +1 -0
- package/dist/Git/GitHistoryDialog.js +107 -0
- package/dist/Git/GitHistoryDialog.js.map +1 -0
- package/dist/Git/GitStatusBar.d.ts +8 -0
- package/dist/Git/GitStatusBar.d.ts.map +1 -0
- package/dist/Git/GitStatusBar.js +49 -0
- package/dist/Git/GitStatusBar.js.map +1 -0
- package/dist/Git/GitToolbarControl.d.ts +15 -0
- package/dist/Git/GitToolbarControl.d.ts.map +1 -0
- package/dist/Git/GitToolbarControl.js +51 -0
- package/dist/Git/GitToolbarControl.js.map +1 -0
- package/dist/Git/GitUI.d.ts +14 -0
- package/dist/Git/GitUI.d.ts.map +1 -0
- package/dist/Git/GitUI.js +21 -0
- package/dist/Git/GitUI.js.map +1 -0
- package/dist/Git/commit-selection.d.ts +22 -0
- package/dist/Git/commit-selection.d.ts.map +1 -0
- package/dist/Git/commit-selection.js +47 -0
- package/dist/Git/commit-selection.js.map +1 -0
- package/dist/Git/git-clone-utils.d.ts +8 -0
- package/dist/Git/git-clone-utils.d.ts.map +1 -0
- package/dist/Git/git-clone-utils.js +26 -0
- package/dist/Git/git-clone-utils.js.map +1 -0
- package/dist/Git/git-status.d.ts +24 -0
- package/dist/Git/git-status.d.ts.map +1 -0
- package/dist/Git/git-status.js +105 -0
- package/dist/Git/git-status.js.map +1 -0
- package/dist/Git/useGit.d.ts +15 -0
- package/dist/Git/useGit.d.ts.map +1 -0
- package/dist/Git/useGit.js +206 -0
- package/dist/Git/useGit.js.map +1 -0
- package/dist/Git/useGitStatus.d.ts +17 -0
- package/dist/Git/useGitStatus.d.ts.map +1 -0
- package/dist/Git/useGitStatus.js +63 -0
- package/dist/Git/useGitStatus.js.map +1 -0
- package/dist/GitToolbarControl-LMIR4R7I.js +117 -0
- package/dist/GitToolbarControl-LMIR4R7I.js.map +1 -0
- package/dist/GitUI-KGF5MSNV.js +1048 -0
- package/dist/GitUI-KGF5MSNV.js.map +1 -0
- package/dist/LazyEditorShell-EF2BWRXU.js +6 -0
- package/dist/LazyEditorShell-EF2BWRXU.js.map +1 -0
- package/dist/Settings/Settings.d.ts +23 -0
- package/dist/Settings/Settings.d.ts.map +1 -0
- package/dist/Settings/Settings.js +22 -0
- package/dist/Settings/Settings.js.map +1 -0
- package/dist/Settings/public-api.d.ts +3 -0
- package/dist/Settings/public-api.d.ts.map +1 -0
- package/dist/Settings/public-api.js +2 -0
- package/dist/Settings/public-api.js.map +1 -0
- package/dist/WorkspacePicker/WorkspacePicker.d.ts +6 -1
- package/dist/WorkspacePicker/WorkspacePicker.d.ts.map +1 -1
- package/dist/WorkspacePicker/WorkspacePicker.js +16 -5
- package/dist/WorkspacePicker/WorkspacePicker.js.map +1 -1
- package/dist/chunk-3SAXDU2U.js +157 -0
- package/dist/chunk-3SAXDU2U.js.map +1 -0
- package/dist/chunk-4XXSWN3T.js +13 -0
- package/dist/chunk-4XXSWN3T.js.map +1 -0
- package/dist/chunk-5A4KEWKT.js +97 -0
- package/dist/chunk-5A4KEWKT.js.map +1 -0
- package/dist/chunk-AOVTHZU7.js +321 -0
- package/dist/chunk-AOVTHZU7.js.map +1 -0
- package/dist/chunk-DD4VFJQI.js +51 -0
- package/dist/chunk-DD4VFJQI.js.map +1 -0
- package/dist/chunk-GSNZSCIK.js +55 -0
- package/dist/chunk-GSNZSCIK.js.map +1 -0
- package/dist/chunk-VHDP4IPL.js +70 -0
- package/dist/chunk-VHDP4IPL.js.map +1 -0
- package/dist/chunk-ZI56BNB7.js +270 -0
- package/dist/chunk-ZI56BNB7.js.map +1 -0
- package/dist/components/Dialog.d.ts +22 -0
- package/dist/components/Dialog.d.ts.map +1 -0
- package/dist/components/Dialog.js +33 -0
- package/dist/components/Dialog.js.map +1 -0
- package/dist/editor.d.ts +10 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +70 -0
- package/dist/editor.js.map +1 -0
- package/dist/export/index.d.ts +87 -0
- package/dist/export/index.js +26 -0
- package/dist/export/index.js.map +1 -0
- package/dist/hooks/index.d.ts +2 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/useDocumentSession.d.ts +16 -0
- package/dist/hooks/useDocumentSession.d.ts.map +1 -0
- package/dist/hooks/useDocumentSession.js +18 -0
- package/dist/hooks/useDocumentSession.js.map +1 -0
- package/dist/icons.d.ts +11 -6
- package/dist/icons.d.ts.map +1 -1
- package/dist/icons.js +21 -20
- package/dist/icons.js.map +1 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/preferences/theme.d.ts +18 -0
- package/dist/preferences/theme.d.ts.map +1 -0
- package/dist/preferences/theme.js +63 -0
- package/dist/preferences/theme.js.map +1 -0
- package/dist/provider-lease.d.ts +10 -0
- package/dist/provider-lease.d.ts.map +1 -0
- package/dist/provider-lease.js +42 -0
- package/dist/provider-lease.js.map +1 -0
- package/dist/run-export-ICTZITXC.js +10 -0
- package/dist/run-export-ICTZITXC.js.map +1 -0
- package/dist/settings/index.d.ts +28 -0
- package/dist/settings/index.js +12 -0
- package/dist/settings/index.js.map +1 -0
- package/package.json +27 -10
- package/src/AppMenu/AppMenu.tsx +169 -99
- package/src/AppMenu/index.ts +1 -1
- package/src/DocBlocksShell/DocBlocksShell.tsx +2183 -516
- package/src/DocBlocksShell/LazyEditorShell.ts +2 -0
- package/src/DocBlocksShell/UpdateAvailableNotice.tsx +60 -0
- package/src/DocBlocksShell/document-title.ts +19 -0
- package/src/DocBlocksShell/workspace-authority-barrier.ts +26 -0
- package/src/Export/DeferredExportToolbarControls.tsx +23 -0
- package/src/Export/ExportDialog.tsx +102 -27
- package/src/Export/ExportToolbarControls.tsx +343 -57
- package/src/Export/export-destination.ts +30 -0
- package/src/Export/index.ts +18 -4
- package/src/Export/public-api.ts +17 -0
- package/src/Export/run-export.ts +66 -29
- package/src/Export/transform-summaries.ts +14 -0
- package/src/FileExplorer/FileExplorer.tsx +284 -38
- package/src/FileExplorer/FileTreeNode.tsx +100 -8
- package/src/FileExplorer/index.ts +1 -1
- package/src/FileExplorer/useFileTree.ts +190 -16
- package/src/Git/GitAuthGuidanceDialog.tsx +84 -0
- package/src/Git/GitBranchesDialog.tsx +144 -0
- package/src/Git/GitCloneDialog.tsx +200 -0
- package/src/Git/GitCommitDialog.tsx +119 -0
- package/src/Git/GitConflictsDialog.tsx +62 -0
- package/src/Git/GitContext.tsx +88 -0
- package/src/Git/GitDiffDialog.tsx +147 -0
- package/src/Git/GitDiffView.tsx +105 -0
- package/src/Git/GitHistoryDialog.tsx +195 -0
- package/src/Git/GitStatusBar.tsx +157 -0
- package/src/Git/GitToolbarControl.tsx +123 -0
- package/src/Git/GitUI.tsx +68 -0
- package/src/Git/commit-selection.ts +63 -0
- package/src/Git/git-clone-utils.ts +23 -0
- package/src/Git/git-status.ts +113 -0
- package/src/Git/useGit.ts +279 -0
- package/src/Git/useGitStatus.ts +78 -0
- package/src/Settings/Settings.tsx +118 -0
- package/src/Settings/public-api.ts +8 -0
- package/src/WorkspacePicker/WorkspacePicker.tsx +62 -8
- package/src/components/Dialog.tsx +81 -0
- package/src/editor.ts +72 -0
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useDocumentSession.ts +37 -0
- package/src/icons.tsx +33 -55
- package/src/index.ts +35 -5
- package/src/preferences/theme.ts +67 -0
- package/src/provider-lease.ts +52 -0
- package/src/styles/docblocks.css +2247 -77
- package/src/types/pwa-dom.d.ts +31 -0
- package/dist/hooks/useAutoSave.d.ts +0 -15
- package/dist/hooks/useAutoSave.d.ts.map +0 -1
- package/dist/hooks/useAutoSave.js +0 -83
- package/dist/hooks/useAutoSave.js.map +0 -1
- package/src/fonts/fonts.css +0 -362
- package/src/fonts/licenses/LICENSE-cormorant-garamond.txt +0 -93
- package/src/fonts/licenses/LICENSE-crimson-text.txt +0 -93
- package/src/fonts/licenses/LICENSE-dm-sans.txt +0 -93
- package/src/fonts/licenses/LICENSE-dm-serif-display.txt +0 -93
- package/src/fonts/licenses/LICENSE-hanken-grotesk.txt +0 -94
- package/src/fonts/licenses/LICENSE-ibm-plex-sans.txt +0 -93
- package/src/fonts/licenses/LICENSE-inter.txt +0 -93
- package/src/fonts/licenses/LICENSE-jetbrains-mono.txt +0 -93
- package/src/fonts/licenses/LICENSE-lora.txt +0 -93
- package/src/fonts/licenses/LICENSE-merriweather.txt +0 -93
- package/src/fonts/licenses/LICENSE-oswald.txt +0 -93
- package/src/fonts/licenses/LICENSE-playfair-display.txt +0 -93
- package/src/fonts/licenses/LICENSE-pt-serif.txt +0 -93
- package/src/fonts/licenses/LICENSE-roboto.txt +0 -93
- package/src/fonts/licenses/LICENSE-source-serif-4.txt +0 -93
- package/src/fonts/woff2/cormorant-garamond-400.woff2 +0 -0
- package/src/fonts/woff2/cormorant-garamond-700.woff2 +0 -0
- package/src/fonts/woff2/crimson-text-400.woff2 +0 -0
- package/src/fonts/woff2/crimson-text-400i.woff2 +0 -0
- package/src/fonts/woff2/crimson-text-700.woff2 +0 -0
- package/src/fonts/woff2/dm-sans-400.woff2 +0 -0
- package/src/fonts/woff2/dm-sans-400i.woff2 +0 -0
- package/src/fonts/woff2/dm-sans-500.woff2 +0 -0
- package/src/fonts/woff2/dm-sans-700.woff2 +0 -0
- package/src/fonts/woff2/dm-serif-display-400.woff2 +0 -0
- package/src/fonts/woff2/hanken-grotesk-400.woff2 +0 -0
- package/src/fonts/woff2/hanken-grotesk-400i.woff2 +0 -0
- package/src/fonts/woff2/hanken-grotesk-500.woff2 +0 -0
- package/src/fonts/woff2/hanken-grotesk-600.woff2 +0 -0
- package/src/fonts/woff2/hanken-grotesk-700.woff2 +0 -0
- package/src/fonts/woff2/ibm-plex-sans-400.woff2 +0 -0
- package/src/fonts/woff2/ibm-plex-sans-400i.woff2 +0 -0
- package/src/fonts/woff2/ibm-plex-sans-500.woff2 +0 -0
- package/src/fonts/woff2/ibm-plex-sans-600.woff2 +0 -0
- package/src/fonts/woff2/ibm-plex-sans-700.woff2 +0 -0
- package/src/fonts/woff2/inter-400.woff2 +0 -0
- package/src/fonts/woff2/inter-400i.woff2 +0 -0
- package/src/fonts/woff2/inter-500.woff2 +0 -0
- package/src/fonts/woff2/inter-600.woff2 +0 -0
- package/src/fonts/woff2/inter-700.woff2 +0 -0
- package/src/fonts/woff2/jetbrains-mono-400.woff2 +0 -0
- package/src/fonts/woff2/jetbrains-mono-400i.woff2 +0 -0
- package/src/fonts/woff2/jetbrains-mono-700.woff2 +0 -0
- package/src/fonts/woff2/lora-400.woff2 +0 -0
- package/src/fonts/woff2/lora-400i.woff2 +0 -0
- package/src/fonts/woff2/lora-700.woff2 +0 -0
- package/src/fonts/woff2/merriweather-400.woff2 +0 -0
- package/src/fonts/woff2/merriweather-700.woff2 +0 -0
- package/src/fonts/woff2/oswald-400.woff2 +0 -0
- package/src/fonts/woff2/oswald-700.woff2 +0 -0
- package/src/fonts/woff2/playfair-display-400.woff2 +0 -0
- package/src/fonts/woff2/playfair-display-700.woff2 +0 -0
- package/src/fonts/woff2/pt-serif-400.woff2 +0 -0
- package/src/fonts/woff2/pt-serif-700.woff2 +0 -0
- package/src/fonts/woff2/roboto-400.woff2 +0 -0
- package/src/fonts/woff2/roboto-400i.woff2 +0 -0
- package/src/fonts/woff2/roboto-700.woff2 +0 -0
- package/src/fonts/woff2/source-serif-4-400.woff2 +0 -0
- package/src/fonts/woff2/source-serif-4-400i.woff2 +0 -0
- package/src/fonts/woff2/source-serif-4-700.woff2 +0 -0
- package/src/hooks/useAutoSave.ts +0 -116
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
import {
|
|
2
|
+
loadTransformStyleSummaries
|
|
3
|
+
} from "./chunk-4XXSWN3T.js";
|
|
4
|
+
import {
|
|
5
|
+
DEFAULT_OPTIONS,
|
|
6
|
+
FORMAT_EXTENSIONS,
|
|
7
|
+
loadLastExportOptions,
|
|
8
|
+
saveExportOptions
|
|
9
|
+
} from "./chunk-DD4VFJQI.js";
|
|
10
|
+
|
|
11
|
+
// src/Export/ExportToolbarControls.tsx
|
|
12
|
+
import {
|
|
13
|
+
lazy,
|
|
14
|
+
Suspense,
|
|
15
|
+
useState,
|
|
16
|
+
useCallback,
|
|
17
|
+
useEffect,
|
|
18
|
+
useRef,
|
|
19
|
+
useMemo
|
|
20
|
+
} from "react";
|
|
21
|
+
import { useEditorContext } from "@bendyline/squisq-editor-react";
|
|
22
|
+
import { getThemeSummaries } from "@bendyline/squisq/schemas";
|
|
23
|
+
import { parseMarkdown } from "@bendyline/squisq/markdown";
|
|
24
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
25
|
+
var ExportDialog = lazy(
|
|
26
|
+
() => import("./ExportDialog-MEUISWZX.js").then((module) => ({ default: module.ExportDialog }))
|
|
27
|
+
);
|
|
28
|
+
var runExportModulePromise = null;
|
|
29
|
+
function loadRunExportModule() {
|
|
30
|
+
runExportModulePromise ?? (runExportModulePromise = import("./run-export-ICTZITXC.js"));
|
|
31
|
+
return runExportModulePromise;
|
|
32
|
+
}
|
|
33
|
+
var videoExportModulesPromise = null;
|
|
34
|
+
function loadVideoExportModules() {
|
|
35
|
+
videoExportModulesPromise ?? (videoExportModulesPromise = Promise.all([
|
|
36
|
+
import("@bendyline/squisq/doc"),
|
|
37
|
+
import("@bendyline/squisq-video-react"),
|
|
38
|
+
import("@bendyline/squisq-react/standalone-source")
|
|
39
|
+
]).then(([docModule, videoModule, playerModule]) => ({
|
|
40
|
+
Modal: videoModule.VideoExportModal,
|
|
41
|
+
markdownToDoc: docModule.markdownToDoc,
|
|
42
|
+
playerScript: playerModule.PLAYER_BUNDLE
|
|
43
|
+
})));
|
|
44
|
+
return videoExportModulesPromise;
|
|
45
|
+
}
|
|
46
|
+
function quickLabel(opts, transformSummaries) {
|
|
47
|
+
const baseExt = FORMAT_EXTENSIONS[opts.format].toUpperCase().replace(".", "");
|
|
48
|
+
const isRecursiveHtml = opts.format === "html" && opts.includeLinkedDocs;
|
|
49
|
+
const ext = opts.format === "html" && (opts.htmlBundle === "zip" || isRecursiveHtml) ? "ZIP" : baseExt;
|
|
50
|
+
const parts = [];
|
|
51
|
+
if (opts.format === "html" && opts.htmlStyle === "rendered") {
|
|
52
|
+
parts.push("rendered");
|
|
53
|
+
}
|
|
54
|
+
if (isRecursiveHtml) {
|
|
55
|
+
parts.push("linked docs");
|
|
56
|
+
}
|
|
57
|
+
if (opts.themeId !== "standard") {
|
|
58
|
+
const theme = getThemeSummaries().find((t) => t.id === opts.themeId);
|
|
59
|
+
if (theme) parts.push(theme.name);
|
|
60
|
+
}
|
|
61
|
+
if (opts.format === "pptx" && opts.transformStyle) {
|
|
62
|
+
const transform = transformSummaries.find((t) => t.id === opts.transformStyle);
|
|
63
|
+
if (transform) parts.push(transform.name);
|
|
64
|
+
}
|
|
65
|
+
if (parts.length > 0) {
|
|
66
|
+
return `Export ${ext} with ${parts.join(" + ")}`;
|
|
67
|
+
}
|
|
68
|
+
return `Export ${ext}`;
|
|
69
|
+
}
|
|
70
|
+
function ExportToolbarControls({
|
|
71
|
+
selectedFile,
|
|
72
|
+
mediaContainer,
|
|
73
|
+
saveBlob,
|
|
74
|
+
destinationAdapter,
|
|
75
|
+
trigger = "menu",
|
|
76
|
+
showVideoExport = true
|
|
77
|
+
}) {
|
|
78
|
+
const { markdownSource, markdownDoc } = useEditorContext();
|
|
79
|
+
const [menuOpen, setMenuOpen] = useState(false);
|
|
80
|
+
const [dialogOpen, setDialogOpen] = useState(false);
|
|
81
|
+
const [videoModalOpen, setVideoModalOpen] = useState(false);
|
|
82
|
+
const [videoLoading, setVideoLoading] = useState(false);
|
|
83
|
+
const [videoLoadError, setVideoLoadError] = useState(null);
|
|
84
|
+
const [videoModules, setVideoModules] = useState(null);
|
|
85
|
+
const [videoDoc, setVideoDoc] = useState(null);
|
|
86
|
+
const [transformSummaries, setTransformSummaries] = useState([]);
|
|
87
|
+
const [exporting, setExporting] = useState(false);
|
|
88
|
+
const [destinationTarget, setDestinationTarget] = useState(null);
|
|
89
|
+
const destinationRequestRef = useRef(0);
|
|
90
|
+
const menuRef = useRef(null);
|
|
91
|
+
const lastOptions = loadLastExportOptions();
|
|
92
|
+
const docThemeId = useMemo(() => {
|
|
93
|
+
const fm = markdownDoc?.frontmatter;
|
|
94
|
+
if (!fm) return null;
|
|
95
|
+
const candidates = [fm["squisq-theme"], fm["theme"], fm["themeId"]];
|
|
96
|
+
for (const v of candidates) {
|
|
97
|
+
if (typeof v === "string" && v.trim()) return v.trim();
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}, [markdownDoc]);
|
|
101
|
+
const dialogInitial = useMemo(() => {
|
|
102
|
+
const base = lastOptions ?? DEFAULT_OPTIONS;
|
|
103
|
+
return docThemeId ? { ...base, themeId: docThemeId } : base;
|
|
104
|
+
}, [lastOptions, docThemeId]);
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
if (!menuOpen) return;
|
|
107
|
+
const onPointerDown = (e) => {
|
|
108
|
+
if (menuRef.current && !menuRef.current.contains(e.target)) {
|
|
109
|
+
setMenuOpen(false);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
document.addEventListener("pointerdown", onPointerDown);
|
|
113
|
+
return () => document.removeEventListener("pointerdown", onPointerDown);
|
|
114
|
+
}, [menuOpen]);
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
if (!menuOpen || lastOptions?.format !== "pptx" || !lastOptions.transformStyle || transformSummaries.length > 0) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
let cancelled = false;
|
|
120
|
+
loadTransformStyleSummaries().then((nextSummaries) => {
|
|
121
|
+
if (!cancelled) setTransformSummaries(nextSummaries);
|
|
122
|
+
}).catch(() => {
|
|
123
|
+
if (!cancelled) setTransformSummaries([]);
|
|
124
|
+
});
|
|
125
|
+
return () => {
|
|
126
|
+
cancelled = true;
|
|
127
|
+
};
|
|
128
|
+
}, [lastOptions?.format, lastOptions?.transformStyle, menuOpen, transformSummaries.length]);
|
|
129
|
+
const handleToggleMenu = useCallback(() => {
|
|
130
|
+
setMenuOpen((prev) => !prev);
|
|
131
|
+
}, []);
|
|
132
|
+
const refreshDestination = useCallback(
|
|
133
|
+
async (options) => {
|
|
134
|
+
if (!destinationAdapter) return;
|
|
135
|
+
const requestId = destinationRequestRef.current + 1;
|
|
136
|
+
destinationRequestRef.current = requestId;
|
|
137
|
+
try {
|
|
138
|
+
const { buildExportFilename } = await loadRunExportModule();
|
|
139
|
+
const filename = buildExportFilename(selectedFile, options);
|
|
140
|
+
const target = await destinationAdapter.resolveTarget(filename);
|
|
141
|
+
if (destinationRequestRef.current === requestId) setDestinationTarget(target);
|
|
142
|
+
} catch {
|
|
143
|
+
if (destinationRequestRef.current === requestId) setDestinationTarget(null);
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
[destinationAdapter, selectedFile]
|
|
147
|
+
);
|
|
148
|
+
const handleOpenDialog = useCallback(() => {
|
|
149
|
+
setMenuOpen(false);
|
|
150
|
+
setDialogOpen(true);
|
|
151
|
+
void refreshDestination(dialogInitial);
|
|
152
|
+
}, [dialogInitial, refreshDestination]);
|
|
153
|
+
const handleCloseDialog = useCallback(() => {
|
|
154
|
+
setDialogOpen(false);
|
|
155
|
+
}, []);
|
|
156
|
+
const handleOpenVideoModal = useCallback(async () => {
|
|
157
|
+
setMenuOpen(false);
|
|
158
|
+
setVideoModalOpen(true);
|
|
159
|
+
setVideoLoading(true);
|
|
160
|
+
setVideoLoadError(null);
|
|
161
|
+
try {
|
|
162
|
+
const modules = videoModules ?? await loadVideoExportModules();
|
|
163
|
+
setVideoModules(modules);
|
|
164
|
+
setVideoDoc(modules.markdownToDoc(parseMarkdown(markdownSource)));
|
|
165
|
+
} catch {
|
|
166
|
+
setVideoLoadError("Video export could not be loaded.");
|
|
167
|
+
} finally {
|
|
168
|
+
setVideoLoading(false);
|
|
169
|
+
}
|
|
170
|
+
}, [markdownSource, videoModules]);
|
|
171
|
+
const handleCloseVideoModal = useCallback(() => {
|
|
172
|
+
setVideoModalOpen(false);
|
|
173
|
+
setVideoDoc(null);
|
|
174
|
+
setVideoLoadError(null);
|
|
175
|
+
}, []);
|
|
176
|
+
const handleOptionsChange = useCallback(
|
|
177
|
+
(options) => {
|
|
178
|
+
void refreshDestination(options);
|
|
179
|
+
},
|
|
180
|
+
[refreshDestination]
|
|
181
|
+
);
|
|
182
|
+
const handlePickDestination = useCallback(
|
|
183
|
+
async (options) => {
|
|
184
|
+
if (!destinationAdapter) return;
|
|
185
|
+
try {
|
|
186
|
+
const { buildExportFilename } = await loadRunExportModule();
|
|
187
|
+
const filename = buildExportFilename(selectedFile, options);
|
|
188
|
+
const pickedTarget = await destinationAdapter.pickTarget(filename, destinationTarget);
|
|
189
|
+
if (pickedTarget === null) return;
|
|
190
|
+
setDestinationTarget(pickedTarget);
|
|
191
|
+
} catch {
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
[destinationAdapter, destinationTarget, selectedFile]
|
|
195
|
+
);
|
|
196
|
+
const saveToDestination = useCallback(
|
|
197
|
+
async (blob, filename, target) => {
|
|
198
|
+
if (!destinationAdapter) return;
|
|
199
|
+
const savedTarget = await destinationAdapter.saveBlob(blob, filename, target);
|
|
200
|
+
if (savedTarget) setDestinationTarget(savedTarget);
|
|
201
|
+
},
|
|
202
|
+
[destinationAdapter]
|
|
203
|
+
);
|
|
204
|
+
const handleDestinationSaveBlob = useCallback(
|
|
205
|
+
async (blob, filename) => {
|
|
206
|
+
await saveToDestination(blob, filename, destinationTarget);
|
|
207
|
+
},
|
|
208
|
+
[destinationTarget, saveToDestination]
|
|
209
|
+
);
|
|
210
|
+
const handleExport = useCallback(
|
|
211
|
+
async (opts) => {
|
|
212
|
+
setExporting(true);
|
|
213
|
+
try {
|
|
214
|
+
const { runExport } = await loadRunExportModule();
|
|
215
|
+
await runExport(
|
|
216
|
+
markdownSource,
|
|
217
|
+
selectedFile,
|
|
218
|
+
opts,
|
|
219
|
+
mediaContainer,
|
|
220
|
+
destinationAdapter ? handleDestinationSaveBlob : saveBlob
|
|
221
|
+
);
|
|
222
|
+
} finally {
|
|
223
|
+
setExporting(false);
|
|
224
|
+
setDialogOpen(false);
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
[
|
|
228
|
+
markdownSource,
|
|
229
|
+
selectedFile,
|
|
230
|
+
mediaContainer,
|
|
231
|
+
destinationAdapter,
|
|
232
|
+
handleDestinationSaveBlob,
|
|
233
|
+
saveBlob
|
|
234
|
+
]
|
|
235
|
+
);
|
|
236
|
+
const handleQuickExport = useCallback(async () => {
|
|
237
|
+
if (!lastOptions) return;
|
|
238
|
+
setMenuOpen(false);
|
|
239
|
+
setExporting(true);
|
|
240
|
+
try {
|
|
241
|
+
saveExportOptions(lastOptions);
|
|
242
|
+
const { runExport } = await loadRunExportModule();
|
|
243
|
+
let quickTarget = null;
|
|
244
|
+
if (destinationAdapter) {
|
|
245
|
+
const { buildExportFilename } = await loadRunExportModule();
|
|
246
|
+
quickTarget = await destinationAdapter.resolveTarget(
|
|
247
|
+
buildExportFilename(selectedFile, lastOptions)
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
await runExport(
|
|
251
|
+
markdownSource,
|
|
252
|
+
selectedFile,
|
|
253
|
+
lastOptions,
|
|
254
|
+
mediaContainer,
|
|
255
|
+
destinationAdapter ? async (blob, filename) => saveToDestination(blob, filename, quickTarget) : saveBlob
|
|
256
|
+
);
|
|
257
|
+
} finally {
|
|
258
|
+
setExporting(false);
|
|
259
|
+
}
|
|
260
|
+
}, [
|
|
261
|
+
destinationAdapter,
|
|
262
|
+
lastOptions,
|
|
263
|
+
markdownSource,
|
|
264
|
+
mediaContainer,
|
|
265
|
+
saveBlob,
|
|
266
|
+
saveToDestination,
|
|
267
|
+
selectedFile
|
|
268
|
+
]);
|
|
269
|
+
const LoadedVideoExportModal = videoModules?.Modal;
|
|
270
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
271
|
+
trigger === "button" ? /* @__PURE__ */ jsx(
|
|
272
|
+
"button",
|
|
273
|
+
{
|
|
274
|
+
type: "button",
|
|
275
|
+
className: "squisq-toolbar-button db-toolbar-export-trigger",
|
|
276
|
+
onClick: handleOpenDialog,
|
|
277
|
+
disabled: exporting,
|
|
278
|
+
"aria-label": "Export document",
|
|
279
|
+
"data-tooltip": exporting ? "Exporting..." : "Export document",
|
|
280
|
+
children: /* @__PURE__ */ jsx(ExportGlyph, {})
|
|
281
|
+
}
|
|
282
|
+
) : /* @__PURE__ */ jsxs("div", { className: "db-toolbar-menu", ref: menuRef, children: [
|
|
283
|
+
/* @__PURE__ */ jsx(
|
|
284
|
+
"button",
|
|
285
|
+
{
|
|
286
|
+
className: "db-toolbar-menu-trigger",
|
|
287
|
+
onClick: handleToggleMenu,
|
|
288
|
+
"aria-label": "More actions",
|
|
289
|
+
title: "More actions",
|
|
290
|
+
children: "\xB7\xB7\xB7"
|
|
291
|
+
}
|
|
292
|
+
),
|
|
293
|
+
menuOpen && /* @__PURE__ */ jsxs("div", { className: "db-toolbar-menu-dropdown", children: [
|
|
294
|
+
lastOptions && /* @__PURE__ */ jsx(
|
|
295
|
+
"button",
|
|
296
|
+
{
|
|
297
|
+
className: "db-toolbar-menu-item",
|
|
298
|
+
onClick: handleQuickExport,
|
|
299
|
+
disabled: exporting,
|
|
300
|
+
children: quickLabel(lastOptions, transformSummaries)
|
|
301
|
+
}
|
|
302
|
+
),
|
|
303
|
+
/* @__PURE__ */ jsx("button", { className: "db-toolbar-menu-item", onClick: handleOpenDialog, children: "Export..." }),
|
|
304
|
+
showVideoExport && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
305
|
+
/* @__PURE__ */ jsx("div", { className: "db-toolbar-menu-divider" }),
|
|
306
|
+
/* @__PURE__ */ jsx("button", { className: "db-toolbar-menu-item", onClick: handleOpenVideoModal, children: "Export Video..." })
|
|
307
|
+
] })
|
|
308
|
+
] })
|
|
309
|
+
] }),
|
|
310
|
+
dialogOpen && /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
|
|
311
|
+
ExportDialog,
|
|
312
|
+
{
|
|
313
|
+
initial: dialogInitial,
|
|
314
|
+
exporting,
|
|
315
|
+
destination: destinationAdapter ? {
|
|
316
|
+
value: destinationTarget?.displayPath ?? "",
|
|
317
|
+
onPick: handlePickDestination,
|
|
318
|
+
hint: destinationAdapter.hint
|
|
319
|
+
} : void 0,
|
|
320
|
+
onExport: handleExport,
|
|
321
|
+
onOptionsChange: destinationAdapter ? handleOptionsChange : void 0,
|
|
322
|
+
onClose: handleCloseDialog
|
|
323
|
+
}
|
|
324
|
+
) }),
|
|
325
|
+
videoModalOpen && (videoLoading || videoLoadError) && /* @__PURE__ */ jsx("div", { className: "db-dialog-overlay", children: /* @__PURE__ */ jsxs("div", { className: "db-dialog", children: [
|
|
326
|
+
/* @__PURE__ */ jsxs("div", { className: "db-dialog-header", children: [
|
|
327
|
+
/* @__PURE__ */ jsx("h2", { className: "db-dialog-title", children: "Export Video" }),
|
|
328
|
+
/* @__PURE__ */ jsx(
|
|
329
|
+
"button",
|
|
330
|
+
{
|
|
331
|
+
className: "db-dialog-close",
|
|
332
|
+
onClick: handleCloseVideoModal,
|
|
333
|
+
"aria-label": "Close",
|
|
334
|
+
children: "\xD7"
|
|
335
|
+
}
|
|
336
|
+
)
|
|
337
|
+
] }),
|
|
338
|
+
/* @__PURE__ */ jsx("div", { className: "db-dialog-body", children: /* @__PURE__ */ jsx("p", { className: "db-export-hint", children: videoLoadError ?? "Loading..." }) })
|
|
339
|
+
] }) }),
|
|
340
|
+
videoModalOpen && videoModules && LoadedVideoExportModal && videoDoc && !videoLoading && !videoLoadError && /* @__PURE__ */ jsx(
|
|
341
|
+
LoadedVideoExportModal,
|
|
342
|
+
{
|
|
343
|
+
doc: videoDoc,
|
|
344
|
+
playerScript: videoModules.playerScript,
|
|
345
|
+
onClose: handleCloseVideoModal
|
|
346
|
+
}
|
|
347
|
+
)
|
|
348
|
+
] });
|
|
349
|
+
}
|
|
350
|
+
function ExportGlyph() {
|
|
351
|
+
return /* @__PURE__ */ jsxs(
|
|
352
|
+
"svg",
|
|
353
|
+
{
|
|
354
|
+
viewBox: "0 0 16 16",
|
|
355
|
+
fill: "none",
|
|
356
|
+
stroke: "currentColor",
|
|
357
|
+
strokeWidth: "1.5",
|
|
358
|
+
strokeLinecap: "round",
|
|
359
|
+
strokeLinejoin: "round",
|
|
360
|
+
"aria-hidden": "true",
|
|
361
|
+
children: [
|
|
362
|
+
/* @__PURE__ */ jsx("path", { d: "M4.5 1.75h4.25L12 5v7.25a1.5 1.5 0 0 1-1.5 1.5h-6A1.5 1.5 0 0 1 3 12.25v-9a1.5 1.5 0 0 1 1.5-1.5z" }),
|
|
363
|
+
/* @__PURE__ */ jsx("path", { d: "M8.75 1.75V5h3.25" }),
|
|
364
|
+
/* @__PURE__ */ jsx("path", { d: "M6 8.75h4.5" }),
|
|
365
|
+
/* @__PURE__ */ jsx("path", { d: "M8.75 7 10.5 8.75 8.75 10.5" })
|
|
366
|
+
]
|
|
367
|
+
}
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
export {
|
|
371
|
+
ExportToolbarControls
|
|
372
|
+
};
|
|
373
|
+
//# sourceMappingURL=ExportToolbarControls-D2YDWOXW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/Export/ExportToolbarControls.tsx"],"sourcesContent":["/**\n * ExportToolbarControls — toolbar-right slot content.\n *\n * Renders a \"...\" overflow menu on the right side of the toolbar\n * containing export actions (document export + video export).\n *\n * Must be rendered inside <EditorProvider> so useEditorContext() works.\n */\n\nimport {\n lazy,\n Suspense,\n useState,\n useCallback,\n useEffect,\n useRef,\n useMemo,\n type ComponentType,\n} from 'react';\nimport { useEditorContext } from '@bendyline/squisq-editor-react';\nimport { getThemeSummaries } from '@bendyline/squisq/schemas';\nimport { parseMarkdown } from '@bendyline/squisq/markdown';\nimport type { ContentContainer } from '@bendyline/squisq/storage';\nimport type { VideoExportModalProps } from '@bendyline/squisq-video-react';\nimport type { ExportOptions } from './export-options.js';\nimport {\n DEFAULT_OPTIONS,\n FORMAT_EXTENSIONS,\n loadLastExportOptions,\n saveExportOptions,\n} from './export-options.js';\nimport type { ExportBlobSaver } from './run-export.js';\nimport { loadTransformStyleSummaries, type ExportSummaryOption } from './transform-summaries.js';\n\nconst ExportDialog = lazy(() =>\n import('./ExportDialog.js').then((module) => ({ default: module.ExportDialog })),\n);\n\nlet runExportModulePromise: Promise<typeof import('./run-export.js')> | null = null;\n\nfunction loadRunExportModule(): Promise<typeof import('./run-export.js')> {\n runExportModulePromise ??= import('./run-export.js');\n return runExportModulePromise;\n}\n\nexport interface ExportToolbarControlsProps {\n /** Currently selected file path — used to derive the download filename. */\n selectedFile: string | null;\n /** Media container for resolving images during export. */\n mediaContainer?: ContentContainer | null;\n /** Override the default browser download behavior for host-provided save flows. */\n saveBlob?: ExportBlobSaver;\n /** Optional host adapter for displaying, picking, and saving to a native target path. */\n destinationAdapter?: ExportDestinationAdapter;\n /** Render the trigger as a direct Export button instead of the overflow menu. */\n trigger?: 'menu' | 'button';\n /** Whether to show video export in the overflow menu. */\n showVideoExport?: boolean;\n}\n\n/** Host-specific operations behind the shared export destination control. */\nexport interface ExportDestinationTarget {\n grantId: string | null;\n displayPath: string;\n}\n\nexport interface ExportDestinationAdapter {\n resolveTarget: (filename: string) => Promise<ExportDestinationTarget>;\n pickTarget: (\n filename: string,\n currentTarget?: ExportDestinationTarget | null,\n ) => Promise<ExportDestinationTarget | null>;\n saveBlob: (\n blob: Blob,\n filename: string,\n target?: ExportDestinationTarget | null,\n ) => Promise<ExportDestinationTarget | null>;\n hint?: string;\n}\n\ntype ParsedMarkdown = ReturnType<typeof parseMarkdown>;\n\ninterface VideoExportModules {\n Modal: ComponentType<VideoExportModalProps>;\n markdownToDoc: (doc: ParsedMarkdown) => VideoExportModalProps['doc'];\n playerScript: string;\n}\n\nlet videoExportModulesPromise: Promise<VideoExportModules> | null = null;\n\nfunction loadVideoExportModules(): Promise<VideoExportModules> {\n videoExportModulesPromise ??= Promise.all([\n import('@bendyline/squisq/doc'),\n import('@bendyline/squisq-video-react'),\n import('@bendyline/squisq-react/standalone-source'),\n ]).then(([docModule, videoModule, playerModule]) => ({\n Modal: videoModule.VideoExportModal,\n markdownToDoc: docModule.markdownToDoc,\n playerScript: playerModule.PLAYER_BUNDLE,\n }));\n return videoExportModulesPromise;\n}\n\n/** Build the quick-export label from saved options. */\nfunction quickLabel(opts: ExportOptions, transformSummaries: ExportSummaryOption[]): string {\n const baseExt = FORMAT_EXTENSIONS[opts.format].toUpperCase().replace('.', '');\n // Recursive HTML always emits a ZIP (multi-doc tree), regardless of\n // the saved `htmlBundle` value. Applies to both plain and rendered\n // styles since both now ship recursive bundle helpers.\n const isRecursiveHtml = opts.format === 'html' && opts.includeLinkedDocs;\n const ext =\n opts.format === 'html' && (opts.htmlBundle === 'zip' || isRecursiveHtml) ? 'ZIP' : baseExt;\n const parts: string[] = [];\n\n if (opts.format === 'html' && opts.htmlStyle === 'rendered') {\n parts.push('rendered');\n }\n if (isRecursiveHtml) {\n parts.push('linked docs');\n }\n // Plain HTML also applies themes now (squisq's `markdownDocToPlainHtml`\n // emits theme-driven CSS), so include the theme name in the quick-\n // export label for every HTML style — not just rendered.\n if (opts.themeId !== 'standard') {\n const theme = getThemeSummaries().find((t) => t.id === opts.themeId);\n if (theme) parts.push(theme.name);\n }\n if (opts.format === 'pptx' && opts.transformStyle) {\n const transform = transformSummaries.find((t) => t.id === opts.transformStyle);\n if (transform) parts.push(transform.name);\n }\n\n if (parts.length > 0) {\n return `Export ${ext} with ${parts.join(' + ')}`;\n }\n return `Export ${ext}`;\n}\n\nexport function ExportToolbarControls({\n selectedFile,\n mediaContainer,\n saveBlob,\n destinationAdapter,\n trigger = 'menu',\n showVideoExport = true,\n}: ExportToolbarControlsProps) {\n const { markdownSource, markdownDoc } = useEditorContext();\n const [menuOpen, setMenuOpen] = useState(false);\n const [dialogOpen, setDialogOpen] = useState(false);\n const [videoModalOpen, setVideoModalOpen] = useState(false);\n const [videoLoading, setVideoLoading] = useState(false);\n const [videoLoadError, setVideoLoadError] = useState<string | null>(null);\n const [videoModules, setVideoModules] = useState<VideoExportModules | null>(null);\n const [videoDoc, setVideoDoc] = useState<VideoExportModalProps['doc'] | null>(null);\n const [transformSummaries, setTransformSummaries] = useState<ExportSummaryOption[]>([]);\n const [exporting, setExporting] = useState(false);\n const [destinationTarget, setDestinationTarget] = useState<ExportDestinationTarget | null>(null);\n const destinationRequestRef = useRef(0);\n const menuRef = useRef<HTMLDivElement>(null);\n\n const lastOptions = loadLastExportOptions();\n\n /** Doc's currently-set squisq theme, pulled from the markdown\n * frontmatter. The Document Settings dialog and Theme Customizer\n * write the theme under `squisq-theme` (canonical) or `theme`\n * (legacy); some older docs persist it as `themeId`. We honor all\n * three so an author who set their theme anywhere upstream sees it\n * pre-selected in the export dialog. */\n const docThemeId = useMemo(() => {\n const fm = markdownDoc?.frontmatter as Record<string, unknown> | undefined;\n if (!fm) return null;\n const candidates = [fm['squisq-theme'], fm['theme'], fm['themeId']];\n for (const v of candidates) {\n if (typeof v === 'string' && v.trim()) return v.trim();\n }\n return null;\n }, [markdownDoc]);\n\n /** Options used to populate the export dialog. Layered: built-in\n * defaults → user's last-chosen export options (if any) → doc's\n * current frontmatter theme (wins). The frontmatter override\n * guarantees that \"set theme in the editor, then export\" pre-selects\n * the right theme instead of resurrecting whatever the user picked\n * for some unrelated previous doc. */\n const dialogInitial = useMemo(() => {\n const base = lastOptions ?? DEFAULT_OPTIONS;\n return docThemeId ? { ...base, themeId: docThemeId } : base;\n }, [lastOptions, docThemeId]);\n\n // Close menu on outside click\n useEffect(() => {\n if (!menuOpen) return;\n const onPointerDown = (e: PointerEvent) => {\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) {\n setMenuOpen(false);\n }\n };\n document.addEventListener('pointerdown', onPointerDown);\n return () => document.removeEventListener('pointerdown', onPointerDown);\n }, [menuOpen]);\n\n useEffect(() => {\n if (\n !menuOpen ||\n lastOptions?.format !== 'pptx' ||\n !lastOptions.transformStyle ||\n transformSummaries.length > 0\n ) {\n return;\n }\n\n let cancelled = false;\n loadTransformStyleSummaries()\n .then((nextSummaries) => {\n if (!cancelled) setTransformSummaries(nextSummaries);\n })\n .catch(() => {\n if (!cancelled) setTransformSummaries([]);\n });\n\n return () => {\n cancelled = true;\n };\n }, [lastOptions?.format, lastOptions?.transformStyle, menuOpen, transformSummaries.length]);\n\n const handleToggleMenu = useCallback(() => {\n setMenuOpen((prev) => !prev);\n }, []);\n\n const refreshDestination = useCallback(\n async (options: ExportOptions) => {\n if (!destinationAdapter) return;\n\n const requestId = destinationRequestRef.current + 1;\n destinationRequestRef.current = requestId;\n\n try {\n const { buildExportFilename } = await loadRunExportModule();\n const filename = buildExportFilename(selectedFile, options);\n const target = await destinationAdapter.resolveTarget(filename);\n if (destinationRequestRef.current === requestId) setDestinationTarget(target);\n } catch {\n if (destinationRequestRef.current === requestId) setDestinationTarget(null);\n }\n },\n [destinationAdapter, selectedFile],\n );\n\n const handleOpenDialog = useCallback(() => {\n setMenuOpen(false);\n setDialogOpen(true);\n void refreshDestination(dialogInitial);\n }, [dialogInitial, refreshDestination]);\n\n const handleCloseDialog = useCallback(() => {\n setDialogOpen(false);\n }, []);\n\n const handleOpenVideoModal = useCallback(async () => {\n setMenuOpen(false);\n setVideoModalOpen(true);\n setVideoLoading(true);\n setVideoLoadError(null);\n\n try {\n const modules = videoModules ?? (await loadVideoExportModules());\n setVideoModules(modules);\n setVideoDoc(modules.markdownToDoc(parseMarkdown(markdownSource)));\n } catch {\n setVideoLoadError('Video export could not be loaded.');\n } finally {\n setVideoLoading(false);\n }\n }, [markdownSource, videoModules]);\n\n const handleCloseVideoModal = useCallback(() => {\n setVideoModalOpen(false);\n setVideoDoc(null);\n setVideoLoadError(null);\n }, []);\n\n const handleOptionsChange = useCallback(\n (options: ExportOptions) => {\n void refreshDestination(options);\n },\n [refreshDestination],\n );\n\n const handlePickDestination = useCallback(\n async (options: ExportOptions) => {\n if (!destinationAdapter) return;\n try {\n const { buildExportFilename } = await loadRunExportModule();\n const filename = buildExportFilename(selectedFile, options);\n const pickedTarget = await destinationAdapter.pickTarget(filename, destinationTarget);\n if (pickedTarget === null) return;\n setDestinationTarget(pickedTarget);\n } catch {\n // Native hosts surface picker failures through their own UI channel.\n }\n },\n [destinationAdapter, destinationTarget, selectedFile],\n );\n\n const saveToDestination = useCallback(\n async (blob: Blob, filename: string, target: ExportDestinationTarget | null) => {\n if (!destinationAdapter) return;\n const savedTarget = await destinationAdapter.saveBlob(blob, filename, target);\n if (savedTarget) setDestinationTarget(savedTarget);\n },\n [destinationAdapter],\n );\n\n const handleDestinationSaveBlob = useCallback(\n async (blob: Blob, filename: string) => {\n await saveToDestination(blob, filename, destinationTarget);\n },\n [destinationTarget, saveToDestination],\n );\n\n const handleExport = useCallback(\n async (opts: ExportOptions) => {\n setExporting(true);\n try {\n const { runExport } = await loadRunExportModule();\n await runExport(\n markdownSource,\n selectedFile,\n opts,\n mediaContainer,\n destinationAdapter ? handleDestinationSaveBlob : saveBlob,\n );\n } finally {\n setExporting(false);\n setDialogOpen(false);\n }\n },\n [\n markdownSource,\n selectedFile,\n mediaContainer,\n destinationAdapter,\n handleDestinationSaveBlob,\n saveBlob,\n ],\n );\n\n const handleQuickExport = useCallback(async () => {\n if (!lastOptions) return;\n setMenuOpen(false);\n setExporting(true);\n try {\n saveExportOptions(lastOptions);\n const { runExport } = await loadRunExportModule();\n let quickTarget: ExportDestinationTarget | null = null;\n if (destinationAdapter) {\n const { buildExportFilename } = await loadRunExportModule();\n quickTarget = await destinationAdapter.resolveTarget(\n buildExportFilename(selectedFile, lastOptions),\n );\n }\n await runExport(\n markdownSource,\n selectedFile,\n lastOptions,\n mediaContainer,\n destinationAdapter\n ? async (blob, filename) => saveToDestination(blob, filename, quickTarget)\n : saveBlob,\n );\n } finally {\n setExporting(false);\n }\n }, [\n destinationAdapter,\n lastOptions,\n markdownSource,\n mediaContainer,\n saveBlob,\n saveToDestination,\n selectedFile,\n ]);\n\n const LoadedVideoExportModal = videoModules?.Modal;\n\n return (\n <>\n {trigger === 'button' ? (\n <button\n type=\"button\"\n className=\"squisq-toolbar-button db-toolbar-export-trigger\"\n onClick={handleOpenDialog}\n disabled={exporting}\n aria-label=\"Export document\"\n data-tooltip={exporting ? 'Exporting...' : 'Export document'}\n >\n <ExportGlyph />\n </button>\n ) : (\n <div className=\"db-toolbar-menu\" ref={menuRef}>\n <button\n className=\"db-toolbar-menu-trigger\"\n onClick={handleToggleMenu}\n aria-label=\"More actions\"\n title=\"More actions\"\n >\n ···\n </button>\n\n {menuOpen && (\n <div className=\"db-toolbar-menu-dropdown\">\n {lastOptions && (\n <button\n className=\"db-toolbar-menu-item\"\n onClick={handleQuickExport}\n disabled={exporting}\n >\n {quickLabel(lastOptions, transformSummaries)}\n </button>\n )}\n <button className=\"db-toolbar-menu-item\" onClick={handleOpenDialog}>\n Export...\n </button>\n {showVideoExport && (\n <>\n <div className=\"db-toolbar-menu-divider\" />\n <button className=\"db-toolbar-menu-item\" onClick={handleOpenVideoModal}>\n Export Video...\n </button>\n </>\n )}\n </div>\n )}\n </div>\n )}\n\n {dialogOpen && (\n <Suspense fallback={null}>\n <ExportDialog\n initial={dialogInitial}\n exporting={exporting}\n destination={\n destinationAdapter\n ? {\n value: destinationTarget?.displayPath ?? '',\n onPick: handlePickDestination,\n hint: destinationAdapter.hint,\n }\n : undefined\n }\n onExport={handleExport}\n onOptionsChange={destinationAdapter ? handleOptionsChange : undefined}\n onClose={handleCloseDialog}\n />\n </Suspense>\n )}\n\n {videoModalOpen && (videoLoading || videoLoadError) && (\n <div className=\"db-dialog-overlay\">\n <div className=\"db-dialog\">\n <div className=\"db-dialog-header\">\n <h2 className=\"db-dialog-title\">Export Video</h2>\n <button\n className=\"db-dialog-close\"\n onClick={handleCloseVideoModal}\n aria-label=\"Close\"\n >\n ×\n </button>\n </div>\n <div className=\"db-dialog-body\">\n <p className=\"db-export-hint\">{videoLoadError ?? 'Loading...'}</p>\n </div>\n </div>\n </div>\n )}\n\n {videoModalOpen &&\n videoModules &&\n LoadedVideoExportModal &&\n videoDoc &&\n !videoLoading &&\n !videoLoadError && (\n <LoadedVideoExportModal\n doc={videoDoc}\n playerScript={videoModules.playerScript}\n onClose={handleCloseVideoModal}\n />\n )}\n </>\n );\n}\n\nfunction ExportGlyph() {\n return (\n <svg\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M4.5 1.75h4.25L12 5v7.25a1.5 1.5 0 0 1-1.5 1.5h-6A1.5 1.5 0 0 1 3 12.25v-9a1.5 1.5 0 0 1 1.5-1.5z\" />\n <path d=\"M8.75 1.75V5h3.25\" />\n <path d=\"M6 8.75h4.5\" />\n <path d=\"M8.75 7 10.5 8.75 8.75 10.5\" />\n </svg>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -4,18 +4,40 @@
|
|
|
4
4
|
* Shows a file/folder tree with expand/collapse, selection, and a toolbar
|
|
5
5
|
* for creating new files/folders.
|
|
6
6
|
*/
|
|
7
|
-
import type
|
|
7
|
+
import { type FileSystemProvider } from '@bendyline/docblocks/filesystem';
|
|
8
|
+
export type FileTreeChange = {
|
|
9
|
+
type: 'create';
|
|
10
|
+
path: string;
|
|
11
|
+
kind?: 'file' | 'directory';
|
|
12
|
+
} | {
|
|
13
|
+
type: 'delete';
|
|
14
|
+
path: string;
|
|
15
|
+
kind: 'file' | 'directory';
|
|
16
|
+
} | {
|
|
17
|
+
type: 'move';
|
|
18
|
+
oldPath: string;
|
|
19
|
+
newPath: string;
|
|
20
|
+
kind: 'file' | 'directory';
|
|
21
|
+
};
|
|
22
|
+
export type FileTreeMutationHandler = (change: FileTreeChange, mutate: () => Promise<void>) => Promise<void>;
|
|
8
23
|
export interface FileExplorerProps {
|
|
9
24
|
/** The filesystem to display. */
|
|
10
25
|
provider: FileSystemProvider | null;
|
|
26
|
+
/** Active document to select and reveal by expanding all ancestor folders. */
|
|
27
|
+
activeFilePath?: string | null;
|
|
11
28
|
/** Called when any entry is selected (file or directory). */
|
|
12
29
|
onSelect?: (path: string, kind: 'file' | 'directory') => void;
|
|
13
|
-
/**
|
|
14
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Wraps destructive tree mutations so the active document session can
|
|
32
|
+
* flush, cancel, or retarget itself before storage changes.
|
|
33
|
+
*/
|
|
34
|
+
onTreeMutation?: FileTreeMutationHandler;
|
|
35
|
+
/** Called after any mutation, with move details when paths change. */
|
|
36
|
+
onTreeChange?: (change?: FileTreeChange) => void;
|
|
15
37
|
/** Called when supported files are dropped onto the explorer. */
|
|
16
38
|
onImportFiles?: (files: File[]) => void;
|
|
17
39
|
/** Optional className for the root element. */
|
|
18
40
|
className?: string;
|
|
19
41
|
}
|
|
20
|
-
export declare function FileExplorer({ provider, onSelect, onTreeChange, onImportFiles, className, }: FileExplorerProps): import("react/jsx-runtime").JSX.Element;
|
|
42
|
+
export declare function FileExplorer({ provider, activeFilePath, onSelect, onTreeMutation, onTreeChange, onImportFiles, className, }: FileExplorerProps): import("react/jsx-runtime").JSX.Element;
|
|
21
43
|
//# sourceMappingURL=FileExplorer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileExplorer.d.ts","sourceRoot":"","sources":["../../src/FileExplorer/FileExplorer.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"FileExplorer.d.ts","sourceRoot":"","sources":["../../src/FileExplorer/FileExplorer.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,iCAAiC,CAAC;AAczC,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;CAAE,GAC5D;IACE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;CAC5B,CAAC;AAEN,MAAM,MAAM,uBAAuB,GAAG,CACpC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KACxB,OAAO,CAAC,IAAI,CAAC,CAAC;AA6DnB,MAAM,WAAW,iBAAiB;IAChC,iCAAiC;IACjC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACpC,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,KAAK,IAAI,CAAC;IAC9D;;;OAGG;IACH,cAAc,CAAC,EAAE,uBAAuB,CAAC;IACzC,sEAAsE;IACtE,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,cAAc,KAAK,IAAI,CAAC;IACjD,iEAAiE;IACjE,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACxC,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,cAAc,EACd,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,aAAa,EACb,SAAS,GACV,EAAE,iBAAiB,2CA8YnB"}
|