@bendyline/docblocks-react 2.2.2 → 2.3.1

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.
@@ -1,3 +1,7 @@
1
+ import {
2
+ browserSaveMode,
3
+ saveActionLabel
4
+ } from "./chunk-UMEDHMT7.js";
1
5
  import {
2
6
  useMenuKeyboard
3
7
  } from "./chunk-MRUK56JS.js";
@@ -7,6 +11,9 @@ import {
7
11
  import {
8
12
  Dialog
9
13
  } from "./chunk-LG6HAWCK.js";
14
+ import {
15
+ buildExportFilename
16
+ } from "./chunk-M5Y5WO7Z.js";
10
17
  import {
11
18
  DEFAULT_OPTIONS,
12
19
  FORMAT_EXTENSIONS,
@@ -29,14 +36,14 @@ import { getThemeSummaries } from "@bendyline/squisq/schemas";
29
36
  import { parseMarkdown } from "@bendyline/squisq/markdown";
30
37
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
31
38
  var ExportDialog = lazy(
32
- () => import("./ExportDialog-HPFPXELL.js").then((module) => ({ default: module.ExportDialog }))
39
+ () => import("./ExportDialog-VBWHFJ2R.js").then((module) => ({ default: module.ExportDialog }))
33
40
  );
34
41
  var ShareDialog = lazy(
35
42
  () => import("./ShareDialog-PAMOQQFB.js").then((module) => ({ default: module.ShareDialog }))
36
43
  );
37
44
  var runExportModulePromise = null;
38
45
  function loadRunExportModule() {
39
- runExportModulePromise ?? (runExportModulePromise = import("./run-export-Z5BVFLIR.js"));
46
+ runExportModulePromise ?? (runExportModulePromise = import("./run-export-UYR5USUJ.js"));
40
47
  return runExportModulePromise;
41
48
  }
42
49
  var ExportCancelledError = class extends Error {
@@ -77,7 +84,7 @@ function exportErrorMessage(caught) {
77
84
  const detail = caught instanceof Error ? caught.message.replace(/^Error invoking remote method '[^']+': Error:\s*/, "").trim() : "";
78
85
  return detail ? `Export failed: ${detail}` : "Export failed. The document could not be exported.";
79
86
  }
80
- function quickLabel(opts, transformSummaries, destinationPath) {
87
+ function quickLabel(opts, transformSummaries, saveMode, destinationPath) {
81
88
  const baseExt = FORMAT_EXTENSIONS[opts.format].toUpperCase().replace(".", "");
82
89
  const isRecursiveHtml = opts.format === "html" && opts.includeLinkedDocs;
83
90
  const ext = opts.format === "html" && (opts.htmlBundle === "zip" || isRecursiveHtml) ? "ZIP" : baseExt;
@@ -96,16 +103,19 @@ function quickLabel(opts, transformSummaries, destinationPath) {
96
103
  const transform = transformSummaries.find((t) => t.id === opts.transformStyle);
97
104
  if (transform) parts.push(transform.name);
98
105
  }
106
+ const prefix = `Save ${ext}`;
107
+ let label = prefix;
99
108
  if (parts.length > 0) {
100
- const label2 = `Export ${ext} with ${parts.join(" + ")}`;
101
- return destinationPath ? `${label2} to ${destinationPath}` : label2;
109
+ label = `${prefix} with ${parts.join(" + ")}`;
102
110
  }
103
- const label = `Export ${ext}`;
111
+ if (saveMode === "save-as") return `${label} as...`;
112
+ if (saveMode === "downloads") return `${label} to Downloads`;
104
113
  return destinationPath ? `${label} to ${destinationPath}` : label;
105
114
  }
106
115
  function ExportToolbarControls({
107
116
  selectedFile,
108
117
  mediaContainer,
118
+ mediaProvider,
109
119
  saveBlob,
110
120
  destinationAdapter,
111
121
  trigger = "menu",
@@ -187,9 +197,7 @@ function ExportToolbarControls({
187
197
  let cancelled = false;
188
198
  setQuickDestination(null);
189
199
  setQuickDestinationPending(true);
190
- void loadRunExportModule().then(
191
- ({ buildExportFilename }) => destinationAdapter.resolveTarget(buildExportFilename(selectedFile, quickOptions))
192
- ).then((target) => {
200
+ void destinationAdapter.resolveTarget(buildExportFilename(selectedFile, quickOptions)).then((target) => {
193
201
  if (!cancelled) setQuickDestination({ key: quickDestinationKey, target });
194
202
  }).catch(() => {
195
203
  if (!cancelled) setQuickDestination(null);
@@ -213,7 +221,6 @@ function ExportToolbarControls({
213
221
  const requestId = destinationRequestRef.current + 1;
214
222
  destinationRequestRef.current = requestId;
215
223
  try {
216
- const { buildExportFilename } = await loadRunExportModule();
217
224
  const filename = buildExportFilename(selectedFile, options);
218
225
  const target = await destinationAdapter.resolveTarget(filename);
219
226
  if (destinationRequestRef.current === requestId) setDestinationTarget(target);
@@ -281,7 +288,6 @@ function ExportToolbarControls({
281
288
  async (options) => {
282
289
  if (!destinationAdapter) return;
283
290
  try {
284
- const { buildExportFilename } = await loadRunExportModule();
285
291
  const filename = buildExportFilename(selectedFile, options);
286
292
  const pickedTarget = await destinationAdapter.pickTarget(filename, destinationTarget);
287
293
  if (pickedTarget === null) return;
@@ -301,24 +307,25 @@ function ExportToolbarControls({
301
307
  },
302
308
  [destinationAdapter]
303
309
  );
304
- const handleDestinationSaveBlob = useCallback(
305
- async (blob, filename) => {
306
- await saveToDestination(blob, filename, destinationTarget);
307
- },
308
- [destinationTarget, saveToDestination]
309
- );
310
310
  const handleExport = useCallback(
311
311
  async (opts) => {
312
312
  setExporting(true);
313
313
  setExportError(null);
314
314
  try {
315
+ let exportTarget = destinationTarget;
316
+ if (destinationAdapter?.pickBeforeSave) {
317
+ const filename = buildExportFilename(selectedFile, opts);
318
+ exportTarget = await destinationAdapter.pickTarget(filename, destinationTarget);
319
+ if (!exportTarget) return;
320
+ setDestinationTarget(exportTarget);
321
+ }
315
322
  const { runExport } = await loadRunExportModule();
316
323
  await runExport(
317
324
  markdownSource,
318
325
  selectedFile,
319
326
  opts,
320
327
  mediaContainer,
321
- destinationAdapter ? handleDestinationSaveBlob : saveBlob
328
+ destinationAdapter ? (blob, filename) => saveToDestination(blob, filename, exportTarget) : saveBlob
322
329
  );
323
330
  setDialogOpen(false);
324
331
  } catch (caught) {
@@ -332,7 +339,8 @@ function ExportToolbarControls({
332
339
  selectedFile,
333
340
  mediaContainer,
334
341
  destinationAdapter,
335
- handleDestinationSaveBlob,
342
+ destinationTarget,
343
+ saveToDestination,
336
344
  saveBlob
337
345
  ]
338
346
  );
@@ -343,12 +351,18 @@ function ExportToolbarControls({
343
351
  setExportError(null);
344
352
  try {
345
353
  saveExportOptions(lastOptions);
346
- const { runExport } = await loadRunExportModule();
347
354
  let quickTarget = null;
348
355
  if (destinationAdapter) {
349
- if (!quickDestinationTarget) return;
350
- quickTarget = quickDestinationTarget;
356
+ if (destinationAdapter.pickBeforeSave) {
357
+ const filename = buildExportFilename(selectedFile, lastOptions);
358
+ quickTarget = await destinationAdapter.pickTarget(filename, quickDestinationTarget);
359
+ if (!quickTarget) return;
360
+ } else {
361
+ if (!quickDestinationTarget) return;
362
+ quickTarget = quickDestinationTarget;
363
+ }
351
364
  }
365
+ const { runExport } = await loadRunExportModule();
352
366
  await runExport(
353
367
  markdownSource,
354
368
  selectedFile,
@@ -374,8 +388,18 @@ function ExportToolbarControls({
374
388
  const handleDismissExportError = useCallback(() => {
375
389
  setExportError(null);
376
390
  }, []);
391
+ const handleVideoSave = useCallback(
392
+ async (blob, filename) => {
393
+ if (!destinationAdapter) return false;
394
+ const target = await destinationAdapter.pickTarget(filename, null);
395
+ if (!target) return false;
396
+ return await destinationAdapter.saveBlob(blob, filename, target) !== null;
397
+ },
398
+ [destinationAdapter]
399
+ );
377
400
  const LoadedVideoExportModal = videoModules?.Modal;
378
401
  const showAnimatedGifExport = showVideoExport && typeof ffmpegWasm?.coreURL === "string" && ffmpegWasm.coreURL.length > 0;
402
+ const quickSaveMode = destinationAdapter ? destinationAdapter.pickBeforeSave ? "save-as" : "destination" : "downloads";
379
403
  return /* @__PURE__ */ jsxs(Fragment, { children: [
380
404
  initialSharedMode && /* @__PURE__ */ jsx(SharedModeInitializer, { mode: initialSharedMode }),
381
405
  trigger === "button" ? /* @__PURE__ */ jsx(
@@ -428,13 +452,15 @@ function ExportToolbarControls({
428
452
  title: quickDestinationTarget ? quickLabel(
429
453
  lastOptions,
430
454
  transformSummaries,
431
- quickDestinationTarget.displayPath
455
+ quickSaveMode,
456
+ destinationAdapter?.pickBeforeSave ? void 0 : quickDestinationTarget.displayPath
432
457
  ) : void 0,
433
458
  children: quickDestinationTarget ? quickLabel(
434
459
  lastOptions,
435
460
  transformSummaries,
436
- quickDestinationTarget.displayPath
437
- ) : quickLabel(lastOptions, transformSummaries) + (destinationAdapter ? quickDestinationPending ? " (finding destination...)" : " (destination unavailable)" : "")
461
+ quickSaveMode,
462
+ destinationAdapter?.pickBeforeSave ? void 0 : quickDestinationTarget.displayPath
463
+ ) : quickLabel(lastOptions, transformSummaries, quickSaveMode) + (destinationAdapter ? quickDestinationPending ? " (finding destination...)" : " (destination unavailable)" : "")
438
464
  }
439
465
  ),
440
466
  /* @__PURE__ */ jsx(
@@ -494,13 +520,23 @@ function ExportToolbarControls({
494
520
  initial: dialogInitial,
495
521
  exporting,
496
522
  error: exportError,
497
- destination: destinationAdapter ? {
523
+ destination: destinationAdapter && destinationAdapter.showDestination !== false ? {
498
524
  value: destinationTarget?.displayPath ?? "",
499
525
  onPick: handlePickDestination,
500
526
  hint: destinationAdapter.hint
501
527
  } : void 0,
502
528
  onExport: handleExport,
503
529
  onOptionsChange: destinationAdapter ? handleOptionsChange : void 0,
530
+ actionLabel: (options) => {
531
+ const extension = options.format === "html" && (options.includeLinkedDocs || options.htmlBundle === "zip") ? "ZIP" : FORMAT_EXTENSIONS[options.format].slice(1);
532
+ if (destinationAdapter && !destinationAdapter.pickBeforeSave) {
533
+ return `Save ${extension.toUpperCase()}`;
534
+ }
535
+ return saveActionLabel(
536
+ extension,
537
+ destinationAdapter?.pickBeforeSave ? "save-as" : browserSaveMode()
538
+ );
539
+ },
504
540
  onClose: handleCloseDialog
505
541
  }
506
542
  ) }),
@@ -543,6 +579,7 @@ function ExportToolbarControls({
543
579
  {
544
580
  doc: videoDoc,
545
581
  playerScript: videoModules.playerScript,
582
+ ...mediaProvider ? { mediaProvider } : {},
546
583
  colorScheme,
547
584
  uiPalette: videoExportPalette,
548
585
  defaultConfig: {
@@ -550,6 +587,10 @@ function ExportToolbarControls({
550
587
  ...ffmpegWasm ? { ffmpegWasm } : {},
551
588
  outputFormat: videoOutputFormat
552
589
  },
590
+ ...destinationAdapter ? {
591
+ saveOutput: handleVideoSave,
592
+ saveActionLabel: (format) => saveActionLabel(format, "save-as")
593
+ } : {},
553
594
  onClose: handleCloseVideoModal
554
595
  }
555
596
  )
@@ -0,0 +1,17 @@
1
+ import {
2
+ FORMAT_EXTENSIONS
3
+ } from "./chunk-EBWYGTN7.js";
4
+
5
+ // src/Export/export-filename.ts
6
+ function buildExportFilename(selectedFile, options) {
7
+ const base = selectedFile ? selectedFile.replace(/^\//, "").replace(/\.[^.]+$/, "") : "document";
8
+ if (options.format === "html") {
9
+ if (options.includeLinkedDocs || options.htmlBundle === "zip") return `${base}.zip`;
10
+ if (options.entryAsIndex) return "index.html";
11
+ }
12
+ return base + FORMAT_EXTENSIONS[options.format];
13
+ }
14
+
15
+ export {
16
+ buildExportFilename
17
+ };
@@ -31,14 +31,6 @@ function buildFilename(selectedFile, format) {
31
31
  const base = selectedFile ? selectedFile.replace(/^\//, "").replace(/\.[^.]+$/, "") : "document";
32
32
  return base + FORMAT_EXTENSIONS[format];
33
33
  }
34
- function buildExportFilename(selectedFile, options) {
35
- const base = selectedFile ? selectedFile.replace(/^\//, "").replace(/\.[^.]+$/, "") : "document";
36
- if (options.format === "html") {
37
- if (options.includeLinkedDocs || options.htmlBundle === "zip") return `${base}.zip`;
38
- if (options.entryAsIndex) return "index.html";
39
- }
40
- return base + FORMAT_EXTENSIONS[options.format];
41
- }
42
34
  async function runExport(markdown, selectedFile, options, mediaContainer, saveBlob, converterOverrides = {}) {
43
35
  const filename = buildFilename(selectedFile, options.format);
44
36
  const themeId = options.themeId !== "standard" ? options.themeId : void 0;
@@ -285,6 +277,5 @@ async function resolveDocImages(doc, container, collectImagePaths) {
285
277
  }
286
278
 
287
279
  export {
288
- buildExportFilename,
289
280
  runExport
290
281
  };
@@ -76,6 +76,7 @@ function ExportDialog({
76
76
  destination,
77
77
  onExport,
78
78
  onOptionsChange,
79
+ actionLabel,
79
80
  onClose
80
81
  }) {
81
82
  const [format, setFormat] = useState(initial.format);
@@ -163,7 +164,7 @@ function ExportDialog({
163
164
  className: "db-export-btn db-export-btn--primary",
164
165
  onClick: handleExport,
165
166
  disabled: exporting || Boolean(destination?.error),
166
- children: exporting ? "Exporting..." : "Export"
167
+ children: exporting ? "Exporting..." : actionLabel?.(currentOptions) ?? "Export"
167
168
  }
168
169
  )
169
170
  ] }),
@@ -0,0 +1,84 @@
1
+ // src/Export/browser-save.ts
2
+ var INSTALLED_DISPLAY_QUERIES = [
3
+ "(display-mode: window-controls-overlay)",
4
+ "(display-mode: standalone)"
5
+ ];
6
+ function isInstalledWebApp() {
7
+ return typeof globalThis.matchMedia === "function" && INSTALLED_DISPLAY_QUERIES.some((query) => globalThis.matchMedia(query).matches);
8
+ }
9
+ function browserSaveMode() {
10
+ return isInstalledWebApp() && typeof window !== "undefined" && typeof window.showSaveFilePicker === "function" ? "save-as" : "downloads";
11
+ }
12
+ function saveActionLabel(format, mode) {
13
+ return mode === "save-as" ? `Save ${format.toUpperCase()} as...` : `Save ${format.toUpperCase()} to Downloads`;
14
+ }
15
+ function isPickerCancellation(caught) {
16
+ return caught instanceof DOMException && caught.name === "AbortError";
17
+ }
18
+ function pickerOptions(blob, filename) {
19
+ const extensionMatch = filename.match(/(\.[^./\\]+)$/);
20
+ const extension = extensionMatch?.[1]?.toLowerCase();
21
+ if (!extension) return { suggestedName: filename };
22
+ const mimeType = blob?.type || "application/octet-stream";
23
+ return {
24
+ suggestedName: filename,
25
+ types: [
26
+ {
27
+ description: `${extension.slice(1).toUpperCase()} file`,
28
+ accept: { [mimeType]: [extension] }
29
+ }
30
+ ]
31
+ };
32
+ }
33
+ function savePickerFilename(filename) {
34
+ return filename.replace(/\\/g, "/").split("/").pop() || "document";
35
+ }
36
+ function createBrowserSaveAsAdapter() {
37
+ if (browserSaveMode() !== "save-as" || !window.showSaveFilePicker) return void 0;
38
+ const handles = /* @__PURE__ */ new Map();
39
+ let nextGrantId = 0;
40
+ return {
41
+ pickBeforeSave: true,
42
+ showDestination: false,
43
+ async resolveTarget(filename) {
44
+ return { grantId: null, displayPath: filename };
45
+ },
46
+ async pickTarget(filename) {
47
+ try {
48
+ const suggestedName = savePickerFilename(filename);
49
+ const handle = await window.showSaveFilePicker?.(pickerOptions(null, suggestedName));
50
+ if (!handle) return null;
51
+ const grantId = `browser-save-${nextGrantId}`;
52
+ nextGrantId += 1;
53
+ handles.set(grantId, handle);
54
+ return { grantId, displayPath: handle.name };
55
+ } catch (caught) {
56
+ if (isPickerCancellation(caught)) return null;
57
+ throw caught;
58
+ }
59
+ },
60
+ async saveBlob(blob, filename, target) {
61
+ if (!target?.grantId) throw new Error("Choose a file before saving the export.");
62
+ const handle = handles.get(target.grantId);
63
+ if (!handle) throw new Error("Choose a file before saving the export.");
64
+ const writable = await handle.createWritable();
65
+ try {
66
+ await writable.write(blob);
67
+ await writable.close();
68
+ } catch (caught) {
69
+ try {
70
+ await writable.abort();
71
+ } catch {
72
+ }
73
+ throw caught;
74
+ }
75
+ return target;
76
+ }
77
+ };
78
+ }
79
+
80
+ export {
81
+ browserSaveMode,
82
+ saveActionLabel,
83
+ createBrowserSaveAsAdapter
84
+ };
@@ -55,12 +55,13 @@ declare const DEFAULT_OPTIONS: ExportOptions;
55
55
  declare function loadLastExportOptions(): ExportOptions | null;
56
56
  declare function saveExportOptions(options: ExportOptions): void;
57
57
 
58
+ declare function buildExportFilename(selectedFile: string | null, options: ExportOptions): string;
59
+
58
60
  type ExportBlobSaver = (blob: Blob, filename: string) => Promise<void> | void;
59
61
  /** Host-provided converters that must be loaded before an export begins. */
60
62
  interface ExportConverterOverrides {
61
63
  docToPptx?: (typeof _bendyline_squisq_formats_pptx)['docToPptx'];
62
64
  }
63
- declare function buildExportFilename(selectedFile: string | null, options: ExportOptions): string;
64
65
  /** Run the export and trigger a download. */
65
66
  declare function runExport(markdown: string, selectedFile: string | null, options: ExportOptions, mediaContainer?: ContentContainer | null, saveBlob?: ExportBlobSaver, converterOverrides?: ExportConverterOverrides): Promise<void>;
66
67
 
@@ -81,6 +82,8 @@ interface ExportDialogProps {
81
82
  onExport: (options: ExportOptions) => void;
82
83
  /** Called whenever the currently selected options change. */
83
84
  onOptionsChange?: (options: ExportOptions) => void;
85
+ /** Host-aware label for the final save action. Defaults to "Export". */
86
+ actionLabel?: (options: ExportOptions) => string;
84
87
  /** Called when the dialog is dismissed. */
85
88
  onClose: () => void;
86
89
  }
@@ -93,7 +96,7 @@ interface ExportDestinationControl {
93
96
  /** A host-supplied validation error for the current destination value. */
94
97
  error?: string | null;
95
98
  }
96
- declare function ExportDialog({ initial, exporting, error, destination, onExport, onOptionsChange, onClose, }: ExportDialogProps): react_jsx_runtime.JSX.Element;
99
+ declare function ExportDialog({ initial, exporting, error, destination, onExport, onOptionsChange, actionLabel, onClose, }: ExportDialogProps): react_jsx_runtime.JSX.Element;
97
100
 
98
101
  /** Keep a user-edited target name while switching the selected export format. */
99
102
  declare function updateExportTargetExtension(targetPath: string, suggestedFilename: string): string;
@@ -3,13 +3,15 @@ import {
3
3
  } from "../chunk-BI7NVU6T.js";
4
4
  import {
5
5
  ExportDialog
6
- } from "../chunk-MHTQORMH.js";
6
+ } from "../chunk-SIIEGOHY.js";
7
7
  import {
8
- buildExportFilename,
9
8
  runExport
10
- } from "../chunk-GHQ4X7KM.js";
9
+ } from "../chunk-OSQUKIUN.js";
11
10
  import "../chunk-YBEYTVU2.js";
12
11
  import "../chunk-LG6HAWCK.js";
12
+ import {
13
+ buildExportFilename
14
+ } from "../chunk-M5Y5WO7Z.js";
13
15
  import {
14
16
  DEFAULT_OPTIONS,
15
17
  FORMAT_EXTENSIONS,
package/dist/index.d.ts CHANGED
@@ -7,6 +7,7 @@ import { PrunePolicy, SaveVersionResult, DocumentVersionManager } from '@bendyli
7
7
  import { ThemePreference, AccentColor, WriteCanvasPreferences } from './settings/index.js';
8
8
  export { AccentColorSettings, AccentColorSettingsProps, DEFAULT_WRITE_CANVAS_FONT_SCHEME, SettingsDialog, SettingsDialogProps, ThemeSettings, ThemeSettingsProps, WRITE_CANVAS_FONT_SCHEMES, WriteCanvasFontScheme, WriteCanvasFontSchemeGroup, WriteCanvasFontSchemeOption, WriteCanvasSettingsControls, WriteCanvasSettingsControlsProps, resolveWriteCanvasFonts } from './settings/index.js';
9
9
  import { SharedDocumentMode } from '@bendyline/docblocks/share';
10
+ import { MediaProvider } from '@bendyline/squisq/schemas';
10
11
  import { ContentContainer } from '@bendyline/squisq/storage';
11
12
  import { VideoExportModalProps } from '@bendyline/squisq-video-react';
12
13
  import { ExportBlobSaver } from './export/index.js';
@@ -26,6 +27,8 @@ interface PinnedDocumentListItem extends PinnedDocument {
26
27
  readonly availability: PinnedDocumentAvailability;
27
28
  }
28
29
 
30
+ type FileExplorerSortMode = 'name' | 'last-modified';
31
+
29
32
  type FileTreeChange = {
30
33
  type: 'create';
31
34
  path: string;
@@ -48,8 +51,14 @@ interface WorkspaceMoveDestination {
48
51
  interface FileExplorerProps {
49
52
  /** The filesystem to display. */
50
53
  provider: FileSystemProvider | null;
54
+ /** Changes after a non-watch provider has durably updated file metadata. */
55
+ metadataRefreshKey?: string | number | null;
51
56
  /** Active document to select and reveal by expanding all ancestor folders. */
52
57
  activeFilePath?: string | null;
58
+ /** Presentation order for files within each directory. */
59
+ sortMode?: FileExplorerSortMode;
60
+ /** Called when a file ordering toolbar button is selected. */
61
+ onSortModeChange?: (mode: FileExplorerSortMode) => void;
53
62
  /** Active workspace identity, used to decorate a selected cross-workspace pin. */
54
63
  activeWorkspaceId?: string | null;
55
64
  /** Documents pinned across every workspace, shown above the active file tree. */
@@ -90,7 +99,7 @@ interface FileExplorerProps {
90
99
  /** Optional className for the root element. */
91
100
  className?: string;
92
101
  }
93
- declare function FileExplorer({ provider, activeFilePath, activeWorkspaceId, pinnedDocuments, pinnedPaths, onPinnedDocumentSelect, onPinnedDocumentUnpin, onPinnedDocumentRename, onPinnedDocumentDelete, onTogglePin, onSelect, onTreeMutation, onTreeChange, onImportFiles, confirmDelete, moveDestinations, onMoveToWorkspace, className, }: FileExplorerProps): react_jsx_runtime.JSX.Element;
102
+ declare function FileExplorer({ provider, metadataRefreshKey, activeFilePath, sortMode, onSortModeChange, activeWorkspaceId, pinnedDocuments, pinnedPaths, onPinnedDocumentSelect, onPinnedDocumentUnpin, onPinnedDocumentRename, onPinnedDocumentDelete, onTogglePin, onSelect, onTreeMutation, onTreeChange, onImportFiles, confirmDelete, moveDestinations, onMoveToWorkspace, className, }: FileExplorerProps): react_jsx_runtime.JSX.Element;
94
103
 
95
104
  /** Git decoration for a row — precomputed by FileExplorer so this node stays context-free. */
96
105
  interface FileTreeNodeBadge {
@@ -208,7 +217,7 @@ interface FileTreeActions {
208
217
  /** Retry one failed directory without treating it as a workspace-root failure. */
209
218
  retryDirectory: (path: string) => Promise<void>;
210
219
  }
211
- declare function useFileTree(provider: FileSystemProvider | null): FileTreeState & FileTreeActions;
220
+ declare function useFileTree(provider: FileSystemProvider | null, metadataRefreshKey?: string | number | null, metadataRefreshPath?: string | null): FileTreeState & FileTreeActions;
212
221
 
213
222
  interface WorkspacePickerProps {
214
223
  /** Currently active workspace id. */
@@ -358,6 +367,8 @@ interface ExportToolbarControlsProps {
358
367
  selectedFile: string | null;
359
368
  /** Media container for resolving images during export. */
360
369
  mediaContainer?: ContentContainer | null;
370
+ /** Active document media provider used to preload audio and video export assets. */
371
+ mediaProvider?: MediaProvider | null;
361
372
  /** Override the default browser download behavior for host-provided save flows. */
362
373
  saveBlob?: ExportBlobSaver;
363
374
  /** Optional host adapter for displaying, picking, and saving to a native target path. */
@@ -386,6 +397,10 @@ interface ExportDestinationAdapter {
386
397
  resolveTarget: (filename: string) => Promise<ExportDestinationTarget>;
387
398
  pickTarget: (filename: string, currentTarget?: ExportDestinationTarget | null) => Promise<ExportDestinationTarget | null>;
388
399
  saveBlob: (blob: Blob, filename: string, target?: ExportDestinationTarget | null) => Promise<ExportDestinationTarget | null>;
400
+ /** Open the picker from the initiating click before expensive conversion work. */
401
+ pickBeforeSave?: boolean;
402
+ /** Whether the export dialog should render the adapter's destination field. */
403
+ showDestination?: boolean;
389
404
  hint?: string;
390
405
  }
391
406
 
@@ -407,4 +422,4 @@ interface UseDocumentSessionResult {
407
422
  */
408
423
  declare function useDocumentSession(autoSaveDelayMs?: number): UseDocumentSessionResult;
409
424
 
410
- export { AccentColor, AppMenu, type AppMenuProps, DocBlocksShell, type DocBlocksShellProps, ExportBlobSaver, type ExportDestinationAdapter, type ExportDestinationTarget, ExportToolbarControls, type ExportToolbarControlsProps, FileExplorer, type FileExplorerProps, type FileTreeActions, type FileTreeChange, type FileTreeMutationHandler, FileTreeNode, type FileTreeNodeProps, type FileTreeReadIssue, type FileTreeState, ThemePreference, type UseDocumentSessionResult, WorkspacePicker, type WorkspacePickerProps, WriteCanvasPreferences, useDocumentSession, useFileTree };
425
+ export { AccentColor, AppMenu, type AppMenuProps, DocBlocksShell, type DocBlocksShellProps, ExportBlobSaver, type ExportDestinationAdapter, type ExportDestinationTarget, ExportToolbarControls, type ExportToolbarControlsProps, FileExplorer, type FileExplorerProps, type FileExplorerSortMode, type FileTreeActions, type FileTreeChange, type FileTreeMutationHandler, FileTreeNode, type FileTreeNodeProps, type FileTreeReadIssue, type FileTreeState, ThemePreference, type UseDocumentSessionResult, WorkspacePicker, type WorkspacePickerProps, WriteCanvasPreferences, useDocumentSession, useFileTree };