@brftech/filex-core 0.41.4 → 0.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/dist/{ArchiveViewer-oqaEyqcB.js → ArchiveViewer-CGl_J_qE.js} +2 -2
  2. package/dist/{ArchiveViewer-oqaEyqcB.js.map → ArchiveViewer-CGl_J_qE.js.map} +1 -1
  3. package/dist/{CsvViewer-BfT-4WpB.js → CsvViewer-D-na6SEG.js} +2 -2
  4. package/dist/{CsvViewer-BfT-4WpB.js.map → CsvViewer-D-na6SEG.js.map} +1 -1
  5. package/dist/{DrawioViewer-Cu2ZquNO.js → DrawioViewer-BFkTSrNc.js} +2 -2
  6. package/dist/{DrawioViewer-Cu2ZquNO.js.map → DrawioViewer-BFkTSrNc.js.map} +1 -1
  7. package/dist/{EpubViewer-yfAfnrYF.js → EpubViewer-BfRE0DTL.js} +2 -2
  8. package/dist/{EpubViewer-yfAfnrYF.js.map → EpubViewer-BfRE0DTL.js.map} +1 -1
  9. package/dist/{IpynbViewer-DLSOs3yU.js → IpynbViewer-BpBlICH-.js} +2 -2
  10. package/dist/{IpynbViewer-DLSOs3yU.js.map → IpynbViewer-BpBlICH-.js.map} +1 -1
  11. package/dist/{MermaidViewer-D2AsT14x.js → MermaidViewer-Ry5Ma463.js} +2 -2
  12. package/dist/{MermaidViewer-D2AsT14x.js.map → MermaidViewer-Ry5Ma463.js.map} +1 -1
  13. package/dist/{PsdViewer-DOza4QJt.js → PsdViewer-BmTlq1Gh.js} +2 -2
  14. package/dist/{PsdViewer-DOza4QJt.js.map → PsdViewer-BmTlq1Gh.js.map} +1 -1
  15. package/dist/{TiffViewer-24MCOn1t.js → TiffViewer-DE5bKDDx.js} +2 -2
  16. package/dist/{TiffViewer-24MCOn1t.js.map → TiffViewer-DE5bKDDx.js.map} +1 -1
  17. package/dist/{Viewer3D-BVjtbhhc.js → Viewer3D-DefcNYOm.js} +2 -2
  18. package/dist/{Viewer3D-BVjtbhhc.js.map → Viewer3D-DefcNYOm.js.map} +1 -1
  19. package/dist/filex-core.js +1 -1
  20. package/dist/filex-core.umd.cjs +8 -8
  21. package/dist/filex-core.umd.cjs.map +1 -1
  22. package/dist/{index-B8PLGR-X.js → index-B0N5qiyj.js} +401 -386
  23. package/dist/{index-B8PLGR-X.js.map → index-B0N5qiyj.js.map} +1 -1
  24. package/dist/index.d.ts +59 -4
  25. package/package.json +1 -1
  26. package/src/FileExplorer.vue +19 -0
  27. package/src/components/FilePane.vue +22 -7
  28. package/src/types/ExplorerConfig.ts +32 -0
package/dist/index.d.ts CHANGED
@@ -484,6 +484,7 @@ readonly authHeaders?: (() => Record<string, string> | Promise<Record<string, st
484
484
  readonly authCredentials?: RequestCredentials | undefined;
485
485
  readonly e2eActive?: boolean | undefined;
486
486
  readonly bodyOverride?: boolean | undefined;
487
+ readonly openTrigger?: "single" | "double" | undefined;
487
488
  } & VNodeProps & AllowedComponentProps & ComponentCustomProps;
488
489
  $attrs: Attrs;
489
490
  $refs: {
@@ -548,6 +549,7 @@ authHeaders?: () => Record<string, string> | Promise<Record<string, string>>;
548
549
  authCredentials?: RequestCredentials;
549
550
  e2eActive?: boolean;
550
551
  bodyOverride?: boolean;
552
+ openTrigger?: "single" | "double";
551
553
  }> & Readonly<{
552
554
  [x: `on${Capitalize<any>}`]: ((...args: any) => any) | undefined;
553
555
  }>, {
@@ -566,6 +568,7 @@ trashVisible: boolean;
566
568
  showCrumbs: boolean;
567
569
  showFilterBar: boolean;
568
570
  showViewSwitcher: boolean;
571
+ openTrigger: "single" | "double";
569
572
  }, {}, string, {}, GlobalComponents, GlobalDirectives, string, ComponentProvideOptions> & {
570
573
  beforeCreate?: (() => void) | (() => void)[];
571
574
  created?: (() => void) | (() => void)[];
@@ -655,6 +658,7 @@ trashVisible: boolean;
655
658
  showCrumbs: boolean;
656
659
  showFilterBar: boolean;
657
660
  showViewSwitcher: boolean;
661
+ openTrigger: "single" | "double";
658
662
  }> & Omit<Readonly<{
659
663
  paneId: PaneId;
660
664
  api: FileApi;
@@ -706,9 +710,10 @@ authHeaders?: () => Record<string, string> | Promise<Record<string, string>>;
706
710
  authCredentials?: RequestCredentials;
707
711
  e2eActive?: boolean;
708
712
  bodyOverride?: boolean;
713
+ openTrigger?: "single" | "double";
709
714
  }> & Readonly<{
710
715
  [x: `on${Capitalize<any>}`]: ((...args: any) => any) | undefined;
711
- }>, "reload" | "dirPerm" | "goUp" | "getPath" | "visibleNodes" | "loadFolder" | "rowCount" | "rowPaths" | ("trashVisible" | "showCrumbs" | "showFilterBar" | "showViewSwitcher")> & {
716
+ }>, "reload" | "dirPerm" | "goUp" | "getPath" | "visibleNodes" | "loadFolder" | "rowCount" | "rowPaths" | ("trashVisible" | "showCrumbs" | "showFilterBar" | "showViewSwitcher" | "openTrigger")> & {
712
717
  reload: () => Promise<void>;
713
718
  goUp: () => void;
714
719
  getPath: () => string;
@@ -780,6 +785,7 @@ readonly authHeaders?: (() => Record<string, string> | Promise<Record<string, st
780
785
  readonly authCredentials?: RequestCredentials | undefined;
781
786
  readonly e2eActive?: boolean | undefined;
782
787
  readonly bodyOverride?: boolean | undefined;
788
+ readonly openTrigger?: "single" | "double" | undefined;
783
789
  } & VNodeProps & AllowedComponentProps & ComponentCustomProps;
784
790
  $attrs: Attrs;
785
791
  $refs: {
@@ -844,6 +850,7 @@ authHeaders?: () => Record<string, string> | Promise<Record<string, string>>;
844
850
  authCredentials?: RequestCredentials;
845
851
  e2eActive?: boolean;
846
852
  bodyOverride?: boolean;
853
+ openTrigger?: "single" | "double";
847
854
  }> & Readonly<{
848
855
  [x: `on${Capitalize<any>}`]: ((...args: any) => any) | undefined;
849
856
  }>, {
@@ -862,6 +869,7 @@ trashVisible: boolean;
862
869
  showCrumbs: boolean;
863
870
  showFilterBar: boolean;
864
871
  showViewSwitcher: boolean;
872
+ openTrigger: "single" | "double";
865
873
  }, {}, string, {}, GlobalComponents, GlobalDirectives, string, ComponentProvideOptions> & {
866
874
  beforeCreate?: (() => void) | (() => void)[];
867
875
  created?: (() => void) | (() => void)[];
@@ -951,6 +959,7 @@ trashVisible: boolean;
951
959
  showCrumbs: boolean;
952
960
  showFilterBar: boolean;
953
961
  showViewSwitcher: boolean;
962
+ openTrigger: "single" | "double";
954
963
  }> & Omit<Readonly<{
955
964
  paneId: PaneId;
956
965
  api: FileApi;
@@ -1002,9 +1011,10 @@ authHeaders?: () => Record<string, string> | Promise<Record<string, string>>;
1002
1011
  authCredentials?: RequestCredentials;
1003
1012
  e2eActive?: boolean;
1004
1013
  bodyOverride?: boolean;
1014
+ openTrigger?: "single" | "double";
1005
1015
  }> & Readonly<{
1006
1016
  [x: `on${Capitalize<any>}`]: ((...args: any) => any) | undefined;
1007
- }>, "reload" | "dirPerm" | "goUp" | "getPath" | "visibleNodes" | "loadFolder" | "rowCount" | "rowPaths" | ("trashVisible" | "showCrumbs" | "showFilterBar" | "showViewSwitcher")> & {
1017
+ }>, "reload" | "dirPerm" | "goUp" | "getPath" | "visibleNodes" | "loadFolder" | "rowCount" | "rowPaths" | ("trashVisible" | "showCrumbs" | "showFilterBar" | "showViewSwitcher" | "openTrigger")> & {
1008
1018
  reload: () => Promise<void>;
1009
1019
  goUp: () => void;
1010
1020
  getPath: () => string;
@@ -1081,6 +1091,7 @@ trashVisible: boolean;
1081
1091
  showCrumbs: boolean;
1082
1092
  showFilterBar: boolean;
1083
1093
  showViewSwitcher: boolean;
1094
+ openTrigger: "single" | "double";
1084
1095
  }, {}, {}, {}, string, ComponentProvideOptions, false, {}, HTMLElement>;
1085
1096
 
1086
1097
  declare type __VLS_Props = {
@@ -1284,6 +1295,10 @@ declare type __VLS_Props_15 = {
1284
1295
  * encrypted lock screen) — those are WINDOW states with no listing
1285
1296
  * behind them, so the pane's own state chain must not also run. */
1286
1297
  bodyOverride?: boolean;
1298
+ /** Mouse open gesture — 'double' (single selects, double opens) or
1299
+ * 'single' (first click opens). Touch always opens on tap; the checkbox
1300
+ * always selects. See onViewClick. */
1301
+ openTrigger?: 'single' | 'double';
1287
1302
  };
1288
1303
 
1289
1304
  declare type __VLS_Props_16 = {
@@ -1979,6 +1994,7 @@ declare function __VLS_template(): {
1979
1994
  readonly authCredentials?: RequestCredentials | undefined;
1980
1995
  readonly e2eActive?: boolean | undefined;
1981
1996
  readonly bodyOverride?: boolean | undefined;
1997
+ readonly openTrigger?: "single" | "double" | undefined;
1982
1998
  } & VNodeProps & AllowedComponentProps & ComponentCustomProps;
1983
1999
  $attrs: Attrs;
1984
2000
  $refs: {
@@ -2043,6 +2059,7 @@ declare function __VLS_template(): {
2043
2059
  authCredentials?: RequestCredentials;
2044
2060
  e2eActive?: boolean;
2045
2061
  bodyOverride?: boolean;
2062
+ openTrigger?: "single" | "double";
2046
2063
  }> & Readonly<{
2047
2064
  [x: `on${Capitalize<any>}`]: ((...args: any) => any) | undefined;
2048
2065
  }>, {
@@ -2061,6 +2078,7 @@ declare function __VLS_template(): {
2061
2078
  showCrumbs: boolean;
2062
2079
  showFilterBar: boolean;
2063
2080
  showViewSwitcher: boolean;
2081
+ openTrigger: "single" | "double";
2064
2082
  }, {}, string, {}, GlobalComponents, GlobalDirectives, string, ComponentProvideOptions> & {
2065
2083
  beforeCreate?: (() => void) | (() => void)[];
2066
2084
  created?: (() => void) | (() => void)[];
@@ -2150,6 +2168,7 @@ declare function __VLS_template(): {
2150
2168
  showCrumbs: boolean;
2151
2169
  showFilterBar: boolean;
2152
2170
  showViewSwitcher: boolean;
2171
+ openTrigger: "single" | "double";
2153
2172
  }> & Omit<Readonly<{
2154
2173
  paneId: PaneId;
2155
2174
  api: FileApi;
@@ -2201,9 +2220,10 @@ declare function __VLS_template(): {
2201
2220
  authCredentials?: RequestCredentials;
2202
2221
  e2eActive?: boolean;
2203
2222
  bodyOverride?: boolean;
2223
+ openTrigger?: "single" | "double";
2204
2224
  }> & Readonly<{
2205
2225
  [x: `on${Capitalize<any>}`]: ((...args: any) => any) | undefined;
2206
- }>, "reload" | "dirPerm" | "goUp" | "getPath" | "visibleNodes" | "loadFolder" | "rowCount" | "rowPaths" | ("trashVisible" | "showCrumbs" | "showFilterBar" | "showViewSwitcher")> & {
2226
+ }>, "reload" | "dirPerm" | "goUp" | "getPath" | "visibleNodes" | "loadFolder" | "rowCount" | "rowPaths" | ("trashVisible" | "showCrumbs" | "showFilterBar" | "showViewSwitcher" | "openTrigger")> & {
2207
2227
  reload: () => Promise<void>;
2208
2228
  goUp: () => void;
2209
2229
  getPath: () => string;
@@ -2275,6 +2295,7 @@ declare function __VLS_template(): {
2275
2295
  readonly authCredentials?: RequestCredentials | undefined;
2276
2296
  readonly e2eActive?: boolean | undefined;
2277
2297
  readonly bodyOverride?: boolean | undefined;
2298
+ readonly openTrigger?: "single" | "double" | undefined;
2278
2299
  } & VNodeProps & AllowedComponentProps & ComponentCustomProps;
2279
2300
  $attrs: Attrs;
2280
2301
  $refs: {
@@ -2339,6 +2360,7 @@ declare function __VLS_template(): {
2339
2360
  authCredentials?: RequestCredentials;
2340
2361
  e2eActive?: boolean;
2341
2362
  bodyOverride?: boolean;
2363
+ openTrigger?: "single" | "double";
2342
2364
  }> & Readonly<{
2343
2365
  [x: `on${Capitalize<any>}`]: ((...args: any) => any) | undefined;
2344
2366
  }>, {
@@ -2357,6 +2379,7 @@ declare function __VLS_template(): {
2357
2379
  showCrumbs: boolean;
2358
2380
  showFilterBar: boolean;
2359
2381
  showViewSwitcher: boolean;
2382
+ openTrigger: "single" | "double";
2360
2383
  }, {}, string, {}, GlobalComponents, GlobalDirectives, string, ComponentProvideOptions> & {
2361
2384
  beforeCreate?: (() => void) | (() => void)[];
2362
2385
  created?: (() => void) | (() => void)[];
@@ -2446,6 +2469,7 @@ declare function __VLS_template(): {
2446
2469
  showCrumbs: boolean;
2447
2470
  showFilterBar: boolean;
2448
2471
  showViewSwitcher: boolean;
2472
+ openTrigger: "single" | "double";
2449
2473
  }> & Omit<Readonly<{
2450
2474
  paneId: PaneId;
2451
2475
  api: FileApi;
@@ -2497,9 +2521,10 @@ declare function __VLS_template(): {
2497
2521
  authCredentials?: RequestCredentials;
2498
2522
  e2eActive?: boolean;
2499
2523
  bodyOverride?: boolean;
2524
+ openTrigger?: "single" | "double";
2500
2525
  }> & Readonly<{
2501
2526
  [x: `on${Capitalize<any>}`]: ((...args: any) => any) | undefined;
2502
- }>, "reload" | "dirPerm" | "goUp" | "getPath" | "visibleNodes" | "loadFolder" | "rowCount" | "rowPaths" | ("trashVisible" | "showCrumbs" | "showFilterBar" | "showViewSwitcher")> & {
2527
+ }>, "reload" | "dirPerm" | "goUp" | "getPath" | "visibleNodes" | "loadFolder" | "rowCount" | "rowPaths" | ("trashVisible" | "showCrumbs" | "showFilterBar" | "showViewSwitcher" | "openTrigger")> & {
2503
2528
  reload: () => Promise<void>;
2504
2529
  goUp: () => void;
2505
2530
  getPath: () => string;
@@ -4188,6 +4213,36 @@ export declare interface ExplorerConfig {
4188
4213
  * Starred row that then disappears. A value here wins over the server's.
4189
4214
  */
4190
4215
  callerKind?: 'user' | 'app';
4216
+ /**
4217
+ * How a mouse opens an item.
4218
+ *
4219
+ * 'double' (default) — a single click SELECTS, a double click OPENS
4220
+ * (classic desktop file-manager). This is a
4221
+ * per-viewer preference the host may expose as a
4222
+ * setting.
4223
+ * 'single' — a single click OPENS (the item is opened on the
4224
+ * first click; the checkbox is still the one click
4225
+ * that selects).
4226
+ *
4227
+ * ⚠ TOUCH is not governed by this: a finger tap always opens (the mobile
4228
+ * convention, and there is no hover-to-select on a touchscreen). The
4229
+ * checkbox always selects, on every device and in either mode. See
4230
+ * FilePane.onViewClick + composables/useRowTouch.
4231
+ */
4232
+ openTrigger?: 'single' | 'double';
4233
+ /**
4234
+ * Hand the OPEN of a file to the host instead of opening the in-page
4235
+ * preview/editor overlay. When true, opening a file emits `file-opened`
4236
+ * (path + basename) and the explorer does NOT mount its own PreviewModal —
4237
+ * the host decides what to do (the desktop app opens the file in its own
4238
+ * window per document). Directories still navigate inline, and Space
4239
+ * quick-look still peeks in-page. Default false (web/embeds preview inline).
4240
+ *
4241
+ * ⚠ Ignored inside an unlocked E2E-encrypted folder: the host window would
4242
+ * fetch raw server bytes (ciphertext), so those keep the in-page decrypted
4243
+ * preview.
4244
+ */
4245
+ openInHost?: boolean;
4191
4246
  /** Default view. */
4192
4247
  viewMode?: 'list' | 'grid';
4193
4248
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brftech/filex-core",
3
- "version": "0.41.4",
3
+ "version": "0.42.0",
4
4
  "description": "filex core — Vue 3 source of truth for the filex file manager (FileExplorer + ConnectionsPanel SFCs, composables, types)",
5
5
  "type": "module",
6
6
  "main": "./dist/filex-core.umd.cjs",
@@ -3090,6 +3090,16 @@ function openNode(n: FileNode) {
3090
3090
  }
3091
3091
  if (e2eLocked.value && n.type === 'file') return;
3092
3092
  /* /wiring:e2 */
3093
+ // Host-owned open (desktop app): a file opens in the host's OWN window per
3094
+ // document, not in the in-page overlay. Emit and stop — the host listens on
3095
+ // `file-opened` and spawns the window. Directories still navigate inline
3096
+ // (handled above); Space quick-look still peeks in-page. E2E files fell into
3097
+ // the decrypted in-page branch above, so a host window never gets ciphertext.
3098
+ if (props.config.openInHost && n.type === 'file') {
3099
+ emit('file-opened', { path: n.path, basename: n.basename });
3100
+ void markRecent(n);
3101
+ return;
3102
+ }
3093
3103
  // "Aç" / double-click contract: open in a new tab against the
3094
3104
  // standalone editor route, regardless of file type. The editor page
3095
3105
  // picks the right viewer (OnlyOffice for office, Monaco for code/
@@ -3204,6 +3214,13 @@ function openNodeInNewTab(n: FileNode) {
3204
3214
  return;
3205
3215
  }
3206
3216
  /* /wiring:e2 */
3217
+ // Host-owned open (desktop): the context-menu "Aç" opens the host window
3218
+ // too, so Enter/double-click/"Aç" are ONE open path — not a window here and
3219
+ // a system-browser tab there. openNode carries the `file-opened` emit.
3220
+ if (props.config.openInHost) {
3221
+ openNode(n);
3222
+ return;
3223
+ }
3207
3224
  // RBAC: a viewer (no edit on this item) can't use the editable "Aç"
3208
3225
  // surface — drop to the read-only in-page preview instead.
3209
3226
  if (!permCanEdit((n.perm as string) ?? dirPerm.value)) {
@@ -6365,6 +6382,7 @@ function closeRecoveryKey() {
6365
6382
  :order="listingOrder"
6366
6383
  :view-mode="viewMode"
6367
6384
  :view-modes="allowedViewModes"
6385
+ :open-trigger="props.config.openTrigger"
6368
6386
  :show-crumbs="navView !== 'home' /* Home has no address: its cards come
6369
6387
  from every folder in every storage, so a trail would have to name
6370
6388
  one */"
@@ -6843,6 +6861,7 @@ function closeRecoveryKey() {
6843
6861
  :nav-offers-trash="navOffersTrash"
6844
6862
  :view-mode="paneViewMode"
6845
6863
  :view-modes="allowedViewModes"
6864
+ :open-trigger="props.config.openTrigger"
6846
6865
  :clipped="clippedPaths"
6847
6866
  :can-write="canWriteHere"
6848
6867
  :can-paste="!!clipboard.mode"
@@ -217,12 +217,18 @@ const props = withDefaults(
217
217
  * encrypted lock screen) — those are WINDOW states with no listing
218
218
  * behind them, so the pane's own state chain must not also run. */
219
219
  bodyOverride?: boolean;
220
+
221
+ /** Mouse open gesture — 'double' (single selects, double opens) or
222
+ * 'single' (first click opens). Touch always opens on tap; the checkbox
223
+ * always selects. See onViewClick. */
224
+ openTrigger?: 'single' | 'double';
220
225
  }>(),
221
226
  {
222
227
  showCrumbs: true,
223
228
  showFilterBar: true,
224
229
  showViewSwitcher: true,
225
230
  trashVisible: true,
231
+ openTrigger: 'double',
226
232
  },
227
233
  );
228
234
 
@@ -458,22 +464,31 @@ function withinOpenGuard(): boolean {
458
464
 
459
465
  function onViewClick(n: FileNode, mod: ClickMod) {
460
466
  if (withinOpenGuard()) return;
461
- /* issue #26, fourth round the reporter's rule, on every device: "only
462
- * clicking on checkbox selects it, any other click will open". The checkbox
463
- * is the one click that reaches the selection; a click or tap anywhere else
464
- * on the item opens it, Ctrl/Shift held or not, selection or not. See
465
- * composables/useRowTouch. */
467
+ /* The checkbox is the one click that always reaches the selection — issue
468
+ * #26's rule, kept on every device and in either open mode. A shift-tick
469
+ * still extends the range; a plain tick toggles (ctrl: true). */
466
470
  if (mod.check) {
467
471
  emit('activate');
468
472
  emit('click-row', n, { ctrl: true, shift: mod.shift });
469
473
  return;
470
474
  }
471
- openedAt = Date.now();
472
- onRowOpen(n);
475
+ /* A finger tap always OPENS (the mobile convention — there is no
476
+ * hover-to-select on a touchscreen). For a mouse the host's `openTrigger`
477
+ * decides: 'single' opens on this click; 'double' (default) makes a single
478
+ * click SELECT and leaves opening to onViewDbl. issue #26's "any click
479
+ * opens" is `openTrigger: 'single'`. */
480
+ if (mod.touch || props.openTrigger === 'single') {
481
+ openedAt = Date.now();
482
+ onRowOpen(n);
483
+ return;
484
+ }
485
+ emit('activate');
486
+ emit('click-row', n, { ctrl: mod.ctrl, shift: mod.shift });
473
487
  }
474
488
 
475
489
  function onViewDbl(n: FileNode) {
476
490
  if (withinOpenGuard()) return;
491
+ openedAt = Date.now();
477
492
  onRowOpen(n);
478
493
  }
479
494
 
@@ -454,6 +454,38 @@ export interface ExplorerConfig {
454
454
  callerKind?: 'user' | 'app';
455
455
 
456
456
 
457
+ /**
458
+ * How a mouse opens an item.
459
+ *
460
+ * 'double' (default) — a single click SELECTS, a double click OPENS
461
+ * (classic desktop file-manager). This is a
462
+ * per-viewer preference the host may expose as a
463
+ * setting.
464
+ * 'single' — a single click OPENS (the item is opened on the
465
+ * first click; the checkbox is still the one click
466
+ * that selects).
467
+ *
468
+ * ⚠ TOUCH is not governed by this: a finger tap always opens (the mobile
469
+ * convention, and there is no hover-to-select on a touchscreen). The
470
+ * checkbox always selects, on every device and in either mode. See
471
+ * FilePane.onViewClick + composables/useRowTouch.
472
+ */
473
+ openTrigger?: 'single' | 'double';
474
+
475
+ /**
476
+ * Hand the OPEN of a file to the host instead of opening the in-page
477
+ * preview/editor overlay. When true, opening a file emits `file-opened`
478
+ * (path + basename) and the explorer does NOT mount its own PreviewModal —
479
+ * the host decides what to do (the desktop app opens the file in its own
480
+ * window per document). Directories still navigate inline, and Space
481
+ * quick-look still peeks in-page. Default false (web/embeds preview inline).
482
+ *
483
+ * ⚠ Ignored inside an unlocked E2E-encrypted folder: the host window would
484
+ * fetch raw server bytes (ciphertext), so those keep the in-page decrypted
485
+ * preview.
486
+ */
487
+ openInHost?: boolean;
488
+
457
489
  /** Default view. */
458
490
  viewMode?: 'list' | 'grid';
459
491