@brftech/filex-core 0.4.2 → 0.6.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 (58) hide show
  1. package/dist/{ArchiveViewer-B_0IQExT.js → ArchiveViewer-EGgNqLPE.js} +2 -2
  2. package/dist/{ArchiveViewer-B_0IQExT.js.map → ArchiveViewer-EGgNqLPE.js.map} +1 -1
  3. package/dist/{CsvViewer-maMfUy5i.js → CsvViewer-BvriJ42M.js} +2 -2
  4. package/dist/{CsvViewer-maMfUy5i.js.map → CsvViewer-BvriJ42M.js.map} +1 -1
  5. package/dist/{DrawioViewer-DP_pXI00.js → DrawioViewer-B_bSPsWX.js} +2 -2
  6. package/dist/{DrawioViewer-DP_pXI00.js.map → DrawioViewer-B_bSPsWX.js.map} +1 -1
  7. package/dist/{EpubViewer-DSaqGnVx.js → EpubViewer-hl68h4gG.js} +2 -2
  8. package/dist/{EpubViewer-DSaqGnVx.js.map → EpubViewer-hl68h4gG.js.map} +1 -1
  9. package/dist/{IpynbViewer-BmdBanF1.js → IpynbViewer-lhwOjXK7.js} +2 -2
  10. package/dist/{IpynbViewer-BmdBanF1.js.map → IpynbViewer-lhwOjXK7.js.map} +1 -1
  11. package/dist/{MermaidViewer-Drlkl0Z5.js → MermaidViewer-H2Z6AYXg.js} +2 -2
  12. package/dist/{MermaidViewer-Drlkl0Z5.js.map → MermaidViewer-H2Z6AYXg.js.map} +1 -1
  13. package/dist/{PsdViewer-gftUJrsm.js → PsdViewer-Bsk-11yH.js} +2 -2
  14. package/dist/{PsdViewer-gftUJrsm.js.map → PsdViewer-Bsk-11yH.js.map} +1 -1
  15. package/dist/{TiffViewer-0Uv0-Lxh.js → TiffViewer-D-j9vycG.js} +2 -2
  16. package/dist/{TiffViewer-0Uv0-Lxh.js.map → TiffViewer-D-j9vycG.js.map} +1 -1
  17. package/dist/{Viewer3D-Gu3kUpxV.js → Viewer3D-Bcr70rTe.js} +2 -2
  18. package/dist/{Viewer3D-Gu3kUpxV.js.map → Viewer3D-Bcr70rTe.js.map} +1 -1
  19. package/dist/filex-core.js +50 -25
  20. package/dist/filex-core.umd.cjs +59 -58
  21. package/dist/filex-core.umd.cjs.map +1 -1
  22. package/dist/index-C_ZSnk_I.js +11109 -0
  23. package/dist/index-C_ZSnk_I.js.map +1 -0
  24. package/dist/index.d.ts +597 -4
  25. package/dist/style.css +1 -1
  26. package/package.json +1 -1
  27. package/src/FileExplorer.vue +636 -15
  28. package/src/components/CommandPalette.vue +24 -1
  29. package/src/components/ContextMenu.vue +114 -8
  30. package/src/components/GalleryView.vue +214 -0
  31. package/src/components/GridView.vue +34 -1
  32. package/src/components/InspectorPanel.vue +170 -0
  33. package/src/components/ListView.vue +40 -6
  34. package/src/components/OnboardingTour.vue +332 -0
  35. package/src/components/OperationsCenter.vue +284 -0
  36. package/src/components/PendingOpsTray.vue +50 -66
  37. package/src/components/QuickLook.vue +142 -0
  38. package/src/components/SecondaryPane.vue +411 -0
  39. package/src/components/ShortcutSettings.vue +270 -0
  40. package/src/components/ShortcutsHelp.vue +30 -9
  41. package/src/components/TabBar.vue +174 -0
  42. package/src/components/ThemeGallery.vue +253 -0
  43. package/src/components/Toolbar.vue +75 -11
  44. package/src/components/UploadProgress.vue +49 -57
  45. package/src/composables/useFileApi.ts +53 -0
  46. package/src/composables/useKeyboardShortcuts.ts +340 -137
  47. package/src/composables/useOperations.ts +291 -0
  48. package/src/composables/useTabs.ts +222 -0
  49. package/src/index.ts +51 -0
  50. package/src/lib/dragGhost.ts +41 -0
  51. package/src/lib/themes.ts +505 -0
  52. package/src/locales/en.ts +125 -0
  53. package/src/locales/tr.ts +125 -0
  54. package/src/modals/Modal.vue +41 -5
  55. package/src/styles/base.css +1210 -0
  56. package/src/types/FileNode.ts +1 -1
  57. package/dist/index-BLocdbmc.js +0 -7993
  58. package/dist/index-BLocdbmc.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -12,6 +12,39 @@ declare type __VLS_Props = {
12
12
  config: ExplorerConfig;
13
13
  };
14
14
 
15
+ declare type __VLS_Props_10 = {
16
+ tabs: TabItem[];
17
+ activeId: string;
18
+ locale: LocaleCode;
19
+ /** false → the split toggle is hidden (narrow embeds). */
20
+ splitEnabled?: boolean;
21
+ /** true → the split toggle renders pressed (active tab has a pane). */
22
+ splitActive?: boolean;
23
+ };
24
+
25
+ declare type __VLS_Props_11 = {
26
+ api: FileApi;
27
+ /** Opening location, in the host's `currentPath` form. */
28
+ initialPath: string;
29
+ locale: LocaleCode;
30
+ /** Host's own qualify(): user path → wire `<adapter>://<rel>`. */
31
+ qualify: (p: string) => string;
32
+ /** Host's wire → user-path converter (multi-storage aware). */
33
+ toUser: (wire: string) => string;
34
+ /** Host's rootFloor clamp — keeps the pane inside the confine. */
35
+ clamp: (p: string) => string;
36
+ /** Label for the root crumb (adapter name / storage list). */
37
+ rootLabel: string;
38
+ /** rootFloor (user-path form, '' when unconfined) — trims crumbs. */
39
+ floor?: string;
40
+ /** Multi-storage mode: '' is the virtual drives root (no fetch). */
41
+ multiRoot?: boolean;
42
+ /** Synthesized storage rows for the virtual drives root. */
43
+ virtualRows?: () => FileNode[];
44
+ /** Active-panel highlight (keyboard target). */
45
+ active?: boolean;
46
+ };
47
+
15
48
  declare type __VLS_Props_2 = {
16
49
  open: boolean;
17
50
  locale: LocaleCode;
@@ -71,6 +104,53 @@ declare type __VLS_Props_5 = {
71
104
  refreshKey?: number | string;
72
105
  };
73
106
 
107
+ declare type __VLS_Props_6 = {
108
+ open: boolean;
109
+ locale: LocaleCode;
110
+ /** Host mode (forwarded to Modal so the backdrop themes correctly). */
111
+ theme?: ThemeMode;
112
+ /** Resolved mode — decides which variant the preview cards paint. */
113
+ dark: boolean;
114
+ /** Currently selected theme id. */
115
+ current: string;
116
+ };
117
+
118
+ declare type __VLS_Props_7 = {
119
+ open: boolean;
120
+ locale: LocaleCode;
121
+ theme?: 'light' | 'dark' | 'auto';
122
+ };
123
+
124
+ declare type __VLS_Props_8 = {
125
+ open: boolean;
126
+ locale: LocaleCode;
127
+ file: FileNode | null;
128
+ previewUrl: (path: string) => string;
129
+ downloadUrl: (path: string) => string;
130
+ onlyOfficeBase?: string | null;
131
+ onlyOfficeConfigEndpoint?: string | null;
132
+ authHeaders?: () => Record<string, string>;
133
+ authCredentials?: RequestCredentials;
134
+ drawioUrl?: string | null;
135
+ pdfWorkerUrl?: string | null;
136
+ viewerBaseUrl?: string | null;
137
+ theme?: 'light' | 'dark' | 'auto';
138
+ };
139
+
140
+ declare type __VLS_Props_9 = {
141
+ center: OperationsStore;
142
+ locale: LocaleCode;
143
+ narrow?: boolean;
144
+ };
145
+
146
+ /**
147
+ * Set (or clear, for the default theme) the selected theme's tokens as
148
+ * inline CSS variables on the explorer root element, resolved to the
149
+ * active variant. Inline style wins over every stylesheet rule, so the
150
+ * root subtree is always correct regardless of host CSS.
151
+ */
152
+ export declare function applyThemeToEl(el: HTMLElement, id: string, dark: boolean): void;
153
+
74
154
  export declare interface ArchiveEntry {
75
155
  name: string;
76
156
  size: number;
@@ -152,6 +232,13 @@ export declare interface ClipboardState {
152
232
  sourcePath: string | null;
153
233
  }
154
234
 
235
+ /**
236
+ * Canonical combo for a keyboard event, or null for a bare modifier
237
+ * press. Meta folds into Ctrl; Shift is dropped for printable symbols
238
+ * because the produced character already encodes it (`?` not `Shift+?`).
239
+ */
240
+ export declare function comboFromEvent(e: KeyboardEvent): string | null;
241
+
155
242
  declare interface ContextAction {
156
243
  key: string;
157
244
  label: string;
@@ -162,8 +249,13 @@ declare interface ContextAction {
162
249
  divider?: boolean;
163
250
  }
164
251
 
252
+ export declare const DEFAULT_THEME_ID = "default";
253
+
165
254
  declare type Density = 'comfortable' | 'compact';
166
255
 
256
+ /** Current combo for an action ('' = unbound). */
257
+ export declare function effectiveCombo(id: string): string;
258
+
167
259
  /** English UI strings. */
168
260
  export declare const en: Record<string, string>;
169
261
 
@@ -484,27 +576,31 @@ inspectorOpen?: boolean;
484
576
  }> & Readonly<{
485
577
  onAction?: ((key: string) => any) | undefined;
486
578
  onUpload?: (() => any) | undefined;
579
+ "onGo-up"?: (() => any) | undefined;
487
580
  "onUpdate:viewMode"?: ((v: ViewMode) => any) | undefined;
488
581
  "onUpdate:searchQuery"?: ((v: string) => any) | undefined;
489
582
  "onNew-folder"?: (() => any) | undefined;
490
583
  onRefresh?: (() => any) | undefined;
491
- "onGo-up"?: (() => any) | undefined;
492
584
  "onOpen-recents"?: (() => any) | undefined;
493
585
  "onUpdate:density"?: ((v: Density) => any) | undefined;
494
586
  "onToggle-inspector"?: (() => any) | undefined;
587
+ "onOpen-theme"?: (() => any) | undefined;
588
+ "onOpen-shortcut-settings"?: (() => any) | undefined;
495
589
  }>, {
496
590
  focusSearch: () => Promise<void>;
497
591
  }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
498
592
  action: (key: string) => any;
499
593
  upload: () => any;
594
+ "go-up": () => any;
500
595
  "update:viewMode": (v: ViewMode) => any;
501
596
  "update:searchQuery": (v: string) => any;
502
597
  "new-folder": () => any;
503
598
  refresh: () => any;
504
- "go-up": () => any;
505
599
  "open-recents": () => any;
506
600
  "update:density": (v: Density) => any;
507
601
  "toggle-inspector": () => any;
602
+ "open-theme": () => any;
603
+ "open-shortcut-settings": () => any;
508
604
  }, PublicProps, {}, false, {}, {}, GlobalComponents, GlobalDirectives, string, {
509
605
  searchEl: HTMLInputElement;
510
606
  moreBtnEl: HTMLButtonElement;
@@ -572,17 +668,95 @@ inspectorOpen?: boolean;
572
668
  }> & Readonly<{
573
669
  onAction?: ((key: string) => any) | undefined;
574
670
  onUpload?: (() => any) | undefined;
671
+ "onGo-up"?: (() => any) | undefined;
575
672
  "onUpdate:viewMode"?: ((v: ViewMode) => any) | undefined;
576
673
  "onUpdate:searchQuery"?: ((v: string) => any) | undefined;
577
674
  "onNew-folder"?: (() => any) | undefined;
578
675
  onRefresh?: (() => any) | undefined;
579
- "onGo-up"?: (() => any) | undefined;
580
676
  "onOpen-recents"?: (() => any) | undefined;
581
677
  "onUpdate:density"?: ((v: Density) => any) | undefined;
582
678
  "onToggle-inspector"?: (() => any) | undefined;
679
+ "onOpen-theme"?: (() => any) | undefined;
680
+ "onOpen-shortcut-settings"?: (() => any) | undefined;
583
681
  }>, {
584
682
  focusSearch: () => Promise<void>;
585
683
  }, {}, {}, {}, {}> | null;
684
+ splitPaneRef: CreateComponentPublicInstanceWithMixins<Readonly<{
685
+ api: FileApi;
686
+ initialPath: string;
687
+ locale: LocaleCode;
688
+ qualify: (p: string) => string;
689
+ toUser: (wire: string) => string;
690
+ clamp: (p: string) => string;
691
+ rootLabel: string;
692
+ floor?: string;
693
+ multiRoot?: boolean;
694
+ virtualRows?: () => FileNode[];
695
+ active?: boolean;
696
+ }> & Readonly<{
697
+ onClose?: (() => any) | undefined;
698
+ onNavigate?: ((path: string) => any) | undefined;
699
+ onActivate?: (() => any) | undefined;
700
+ "onOpen-tab"?: ((path: string) => any) | undefined;
701
+ onTransfer?: ((p: {
702
+ sources: string[];
703
+ targetWire: string;
704
+ originWire?: string;
705
+ }) => any) | undefined;
706
+ }>, {
707
+ reload: () => Promise<void>;
708
+ goUp: () => void;
709
+ selectAll: () => void;
710
+ openSelected: () => void;
711
+ selectedNodes: () => FileNode[];
712
+ getPath: () => string;
713
+ }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
714
+ close: () => any;
715
+ navigate: (path: string) => any;
716
+ activate: () => any;
717
+ "open-tab": (path: string) => any;
718
+ transfer: (p: {
719
+ sources: string[];
720
+ targetWire: string;
721
+ originWire?: string;
722
+ }) => any;
723
+ }, PublicProps, {}, false, {}, {}, GlobalComponents, GlobalDirectives, string, {}, HTMLElement, ComponentProvideOptions, {
724
+ P: {};
725
+ B: {};
726
+ D: {};
727
+ C: {};
728
+ M: {};
729
+ Defaults: {};
730
+ }, Readonly<{
731
+ api: FileApi;
732
+ initialPath: string;
733
+ locale: LocaleCode;
734
+ qualify: (p: string) => string;
735
+ toUser: (wire: string) => string;
736
+ clamp: (p: string) => string;
737
+ rootLabel: string;
738
+ floor?: string;
739
+ multiRoot?: boolean;
740
+ virtualRows?: () => FileNode[];
741
+ active?: boolean;
742
+ }> & Readonly<{
743
+ onClose?: (() => any) | undefined;
744
+ onNavigate?: ((path: string) => any) | undefined;
745
+ onActivate?: (() => any) | undefined;
746
+ "onOpen-tab"?: ((path: string) => any) | undefined;
747
+ onTransfer?: ((p: {
748
+ sources: string[];
749
+ targetWire: string;
750
+ originWire?: string;
751
+ }) => any) | undefined;
752
+ }>, {
753
+ reload: () => Promise<void>;
754
+ goUp: () => void;
755
+ selectAll: () => void;
756
+ openSelected: () => void;
757
+ selectedNodes: () => FileNode[];
758
+ getPath: () => string;
759
+ }, {}, {}, {}, {}> | null;
586
760
  ctxRef: CreateComponentPublicInstanceWithMixins<Readonly<{
587
761
  locale: LocaleCode;
588
762
  actions: ContextAction[];
@@ -673,11 +847,29 @@ export declare interface FileNode {
673
847
  [k: string]: unknown;
674
848
  }
675
849
 
850
+ /**
851
+ * Does `combo` already trigger another action? Checks both effective
852
+ * combos and the reserved fixed combos (Backspace, Esc). Returns null
853
+ * when free.
854
+ */
855
+ export declare function findShortcutConflict(combo: string, excludeId: string): ShortcutConflict | null;
856
+
857
+ /**
858
+ * Generate a stylesheet that mirrors styles/variables.css' selector
859
+ * cascade 1:1 (light base → explicit-dark selectors → prefers-dark media
860
+ * block) with the theme's palette. Appended after the bundled CSS it
861
+ * overrides every surface — teleported context menus, modal backdrops —
862
+ * in whichever mode they resolve to, without JS having to track them.
863
+ */
864
+ export declare function generateThemeCss(theme: ThemeDef): string;
865
+
676
866
  export declare function getHighlight(): unknown | null;
677
867
 
678
868
  /** Synchronous cached lookup — null if Monaco not yet ready or absent. */
679
869
  export declare function getMonaco(): unknown | null;
680
870
 
871
+ declare function getPath(): string;
872
+
681
873
  /**
682
874
  * One hit from the dedicated files-search endpoint. The backend returns raw
683
875
  * node rows (`{results: [...]}`), so `path` is the IN-STORAGE relative path
@@ -704,6 +896,8 @@ export declare interface GlobalSearchHit {
704
896
 
705
897
  export declare type GlobalSearchScope = 'name' | 'content' | 'all';
706
898
 
899
+ declare function goUp(): void;
900
+
707
901
  /** A single ACL grant row (RBAC permissions panel). */
708
902
  declare interface Grant {
709
903
  id: number;
@@ -749,6 +943,20 @@ export declare function matchedInContent(matched: unknown): boolean;
749
943
 
750
944
  export declare const messages: Record<LocaleCode, Record<string, string>>;
751
945
 
946
+ /** Mirrors backend `model.NodeComment` (GET /api/files/comments?node_id=…). */
947
+ declare interface NodeComment {
948
+ id: number;
949
+ node_id: number;
950
+ user_id: number;
951
+ body: string;
952
+ created_at: string;
953
+ updated_at?: string;
954
+ /** Joined author display name (email fallback), filled by the backend. */
955
+ author_name?: string;
956
+ /** Whether the CURRENT caller may delete this row (author or admin). */
957
+ can_delete?: boolean;
958
+ }
959
+
752
960
  /** Mirrors backend `model.NodeVersion` (GET /api/files/versions?node_id=…). */
753
961
  declare interface NodeVersion {
754
962
  id: number;
@@ -760,6 +968,91 @@ declare interface NodeVersion {
760
968
  created_at: string;
761
969
  }
762
970
 
971
+ declare function openSelected(): void;
972
+
973
+ export declare interface Operation {
974
+ /** `${group}:${id}` — unique across publishers. */
975
+ key: string;
976
+ kind: OperationKind;
977
+ name: string;
978
+ percent: number | null;
979
+ status: OperationStatus;
980
+ error: string | null;
981
+ queued: boolean;
982
+ doneCount: number | null;
983
+ totalCount: number | null;
984
+ uploadedBytes: number | null;
985
+ totalBytes: number | null;
986
+ cancellable: boolean;
987
+ retryable: boolean;
988
+ startedAt: number;
989
+ settledAt: number | null;
990
+ }
991
+
992
+ export declare interface OperationActions {
993
+ cancel?: () => void;
994
+ /** Clean the row out of the OWNING source list (called on retire/dismiss). */
995
+ dismiss?: () => void;
996
+ retry?: () => void;
997
+ }
998
+
999
+ /** What a publisher hands to `sync()` for one row. */
1000
+ export declare interface OperationInput {
1001
+ /** Stable id within the group (upload uuid / ops row id). */
1002
+ id: string | number;
1003
+ kind: OperationKind;
1004
+ /** Primary label — file name or target path. '' → renderer falls back to the kind verb. */
1005
+ name: string;
1006
+ /** 0..100, or null for indeterminate (renderer shows a spinner). */
1007
+ percent: number | null;
1008
+ status: OperationStatus;
1009
+ error?: string | null;
1010
+ /** Queue op accepted but not started yet ("Sırada"). */
1011
+ queued?: boolean;
1012
+ /** Progress counters for queue ops (3/5 items). */
1013
+ doneCount?: number;
1014
+ totalCount?: number;
1015
+ /** Byte progress for uploads. */
1016
+ uploadedBytes?: number;
1017
+ totalBytes?: number;
1018
+ cancellable?: boolean;
1019
+ retryable?: boolean;
1020
+ }
1021
+
1022
+ /**
1023
+ * useOperations — unified long-running-operation store (wiring:c3).
1024
+ *
1025
+ * One presentation-level aggregation point for everything that used to be
1026
+ * scattered across corner UIs:
1027
+ * - uploads (useUploadChunked jobs / legacy multipart rows)
1028
+ * - ops-queue jobs (usePendingOps copy/move/delete worker ops)
1029
+ * - future kinds (convert / archive — same `sync()` contract, own group)
1030
+ *
1031
+ * The store does NOT talk to the network. Publishers (renderless
1032
+ * UploadProgress / PendingOpsTray adapters) reconcile their reactive source
1033
+ * lists into the store via `sync(group, items)`; OperationsCenter renders the
1034
+ * merged picture (badge + panel). Action callbacks (cancel/retry/dismiss)
1035
+ * are registered per row so the panel can route user intent back to the
1036
+ * owning surface without the store knowing any transport details.
1037
+ *
1038
+ * Lifecycle rules (per the İşlem Merkezi contract):
1039
+ * - running rows live in `active`;
1040
+ * - done/aborted rows linger in `active` for DONE_LINGER_MS ("bitti"
1041
+ * flash) then move to `history` (session-only, capped);
1042
+ * - error rows are STICKY: they stay in `active` until the user
1043
+ * dismisses or retries them — even after the source list swept them
1044
+ * (usePendingOps drops terminal ops after its RETAIN window).
1045
+ */
1046
+ export declare type OperationKind = 'upload' | 'copy' | 'move' | 'delete' | 'convert' | 'archive';
1047
+
1048
+ export declare const OperationsCenter: DefineComponent<__VLS_Props_9, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<__VLS_Props_9> & Readonly<{}>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {
1049
+ rootEl: HTMLDivElement;
1050
+ }, any>;
1051
+
1052
+ export declare type OperationsStore = ReturnType<typeof useOperations>;
1053
+
1054
+ export declare type OperationStatus = 'running' | 'done' | 'error' | 'aborted';
1055
+
763
1056
  export declare interface PendingOp {
764
1057
  id: number;
765
1058
  op_type: 'copy' | 'move' | 'delete';
@@ -839,6 +1132,16 @@ monacoEl: HTMLDivElement;
839
1132
  officeEl: HTMLDivElement;
840
1133
  }, any>;
841
1134
 
1135
+ export declare const QuickLook: DefineComponent<__VLS_Props_8, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
1136
+ close: () => any;
1137
+ nav: (delta: number) => any;
1138
+ "open-full": () => any;
1139
+ }, string, PublicProps, Readonly<__VLS_Props_8> & Readonly<{
1140
+ onClose?: (() => any) | undefined;
1141
+ onNav?: ((delta: number) => any) | undefined;
1142
+ "onOpen-full"?: (() => any) | undefined;
1143
+ }>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, any>;
1144
+
842
1145
  export declare const RecentlyOpened: DefineComponent<__VLS_Props_5, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
843
1146
  error: (message: string) => any;
844
1147
  open: (node: RecentNode) => any;
@@ -856,6 +1159,12 @@ declare interface RecentNode {
856
1159
  last_opened?: string;
857
1160
  }
858
1161
 
1162
+ declare function reload(): Promise<void>;
1163
+
1164
+ export declare function resetAllShortcuts(): void;
1165
+
1166
+ export declare function resetShortcut(id: string): void;
1167
+
859
1168
  declare interface ResolveEmailResponse {
860
1169
  found: boolean;
861
1170
  user?: {
@@ -877,8 +1186,46 @@ export declare function resolveEndpoints(config: ExplorerConfig): EndpointMap;
877
1186
  /** Matched-in values the search contract allows on a hit. */
878
1187
  export declare type SearchMatched = 'name' | 'content' | 'both';
879
1188
 
1189
+ export declare const SecondaryPane: DefineComponent<__VLS_Props_11, {
1190
+ reload: typeof reload;
1191
+ goUp: typeof goUp;
1192
+ selectAll: typeof selectAll;
1193
+ openSelected: typeof openSelected;
1194
+ selectedNodes: typeof selectedNodes;
1195
+ getPath: typeof getPath;
1196
+ }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
1197
+ close: () => any;
1198
+ navigate: (path: string) => any;
1199
+ activate: () => any;
1200
+ "open-tab": (path: string) => any;
1201
+ transfer: (p: {
1202
+ sources: string[];
1203
+ targetWire: string;
1204
+ originWire?: string;
1205
+ }) => any;
1206
+ }, string, PublicProps, Readonly<__VLS_Props_11> & Readonly<{
1207
+ onClose?: (() => any) | undefined;
1208
+ onNavigate?: ((path: string) => any) | undefined;
1209
+ onActivate?: (() => any) | undefined;
1210
+ "onOpen-tab"?: ((path: string) => any) | undefined;
1211
+ onTransfer?: ((p: {
1212
+ sources: string[];
1213
+ targetWire: string;
1214
+ originWire?: string;
1215
+ }) => any) | undefined;
1216
+ }>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, HTMLElement>;
1217
+
1218
+ declare function selectAll(): void;
1219
+
1220
+ declare function selectedNodes(): FileNode[];
1221
+
880
1222
  declare type SelectionMode_2 = 'none' | 'single-file' | 'single-dir' | 'multi';
881
1223
 
1224
+ /** Set (or clear back to default) a user override. '' unbinds. */
1225
+ export declare function setShortcutOverride(id: string, combo: string): void;
1226
+
1227
+ export declare function setTheme(id: string): void;
1228
+
882
1229
  export declare interface ShareInfo {
883
1230
  uuid: string;
884
1231
  url: string;
@@ -889,6 +1236,38 @@ export declare interface ShareInfo {
889
1236
  created_at?: string;
890
1237
  }
891
1238
 
1239
+ /** Registry order = help/settings display order. */
1240
+ export declare const SHORTCUT_ACTIONS: ShortcutActionDef[];
1241
+
1242
+ /** One remappable action in the shortcut registry. */
1243
+ export declare interface ShortcutActionDef {
1244
+ /** Stable id — also the localStorage override key. */
1245
+ id: string;
1246
+ /** Default combo in canonical form. */
1247
+ defaultCombo: string;
1248
+ /**
1249
+ * Extra built-in combos that also trigger the action but are NOT
1250
+ * remappable (e.g. Backspace on go-up, which carries the
1251
+ * selection-dependent dual behaviour). Shown in the help sheet and
1252
+ * reserved in conflict detection.
1253
+ */
1254
+ fixedCombos?: string[];
1255
+ labelKey: string;
1256
+ groupKey: string;
1257
+ /** false → the combo can't be remapped (Esc). Default true. */
1258
+ customizable?: boolean;
1259
+ /** false → don't preventDefault on match (Enter / Esc). Default true. */
1260
+ prevent?: boolean;
1261
+ /** true → fires even when focus sits in a form control (Esc). */
1262
+ inForms?: boolean;
1263
+ }
1264
+
1265
+ export declare interface ShortcutConflict {
1266
+ id: string;
1267
+ /** true → the clash is with a fixed (non-remappable) combo. */
1268
+ fixed: boolean;
1269
+ }
1270
+
892
1271
  export declare interface ShortcutHandlers {
893
1272
  onDelete?: () => void;
894
1273
  onRename?: () => void;
@@ -904,9 +1283,34 @@ export declare interface ShortcutHandlers {
904
1283
  onGoUp?: () => void;
905
1284
  onShowHelp?: () => void;
906
1285
  onToggleInspector?: () => void;
1286
+ onQuickLook?: () => void;
1287
+ onTabNew?: () => void;
1288
+ onTabClose?: () => void;
1289
+ onTabNext?: () => void;
1290
+ onTabPrev?: () => void;
907
1291
  hasSelection?: () => boolean;
908
1292
  }
909
1293
 
1294
+ export declare const ShortcutSettings: DefineComponent<__VLS_Props_7, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
1295
+ close: () => any;
1296
+ }, string, PublicProps, Readonly<__VLS_Props_7> & Readonly<{
1297
+ onClose?: (() => any) | undefined;
1298
+ }>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, any>;
1299
+
1300
+ export declare interface ShortcutView {
1301
+ id: string;
1302
+ /** Current (possibly remapped) combo, '' = unbound. */
1303
+ combo: string;
1304
+ /** Non-remappable extra combos (display + reservation only). */
1305
+ fixedCombos: string[];
1306
+ /** Display combos: [combo, ...fixedCombos] minus empties. */
1307
+ keys: string[];
1308
+ labelKey: string;
1309
+ groupKey: string;
1310
+ customizable: boolean;
1311
+ overridden: boolean;
1312
+ }
1313
+
910
1314
  /**
911
1315
  * Snippet segment parser — the search backend returns content snippets as
912
1316
  * PLAIN TEXT with matched words wrapped in «guillemets» (contract: no HTML
@@ -936,6 +1340,48 @@ onError?: ((message: string) => any) | undefined;
936
1340
  onChange?: ((value: boolean) => any) | undefined;
937
1341
  }>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, HTMLButtonElement>;
938
1342
 
1343
+ /**
1344
+ * Create/update/empty the singleton `<style data-filex-theme>` element in
1345
+ * <head>. Idempotent — safe to call from every explorer instance.
1346
+ */
1347
+ export declare function syncThemeStyle(id: string): void;
1348
+
1349
+ export declare const TabBar: DefineComponent<__VLS_Props_10, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
1350
+ close: (id: string) => any;
1351
+ select: (id: string) => any;
1352
+ new: () => any;
1353
+ reorder: (from: number, to: number) => any;
1354
+ "toggle-split": () => any;
1355
+ }, string, PublicProps, Readonly<__VLS_Props_10> & Readonly<{
1356
+ onClose?: ((id: string) => any) | undefined;
1357
+ onSelect?: ((id: string) => any) | undefined;
1358
+ onNew?: (() => any) | undefined;
1359
+ onReorder?: ((from: number, to: number) => any) | undefined;
1360
+ "onToggle-split"?: (() => any) | undefined;
1361
+ }>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, HTMLDivElement>;
1362
+
1363
+ declare interface TabItem {
1364
+ id: string;
1365
+ label: string;
1366
+ /** true → the tab carries a split pane (small accent dot). */
1367
+ split: boolean;
1368
+ }
1369
+
1370
+ export declare type TabsApi = ReturnType<typeof useTabs>;
1371
+
1372
+ /** Per-tab split state — the secondary pane's own location. */
1373
+ export declare interface TabSplit {
1374
+ path: string;
1375
+ }
1376
+
1377
+ export declare interface TabState {
1378
+ id: string;
1379
+ /** Location snapshot in `currentPath` form (see module docs). */
1380
+ path: string;
1381
+ viewMode: ViewMode;
1382
+ split: TabSplit | null;
1383
+ }
1384
+
939
1385
  export declare const TagPicker: DefineComponent<__VLS_Props_4, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
940
1386
  error: (message: string) => any;
941
1387
  change: (tags: string[]) => any;
@@ -944,8 +1390,36 @@ onError?: ((message: string) => any) | undefined;
944
1390
  onChange?: ((tags: string[]) => any) | undefined;
945
1391
  }>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, HTMLDivElement>;
946
1392
 
1393
+ export declare const THEME_LS_KEY = "filex.theme";
1394
+
1395
+ export declare function themeById(id: string | null | undefined): ThemeDef | undefined;
1396
+
1397
+ export declare interface ThemeDef {
1398
+ /** Stable id — persisted in localStorage, never shown to users. */
1399
+ id: string;
1400
+ /** i18n catalogue key for the display name (tr + en). */
1401
+ nameKey: string;
1402
+ /** Palette applied when the resolved mode is light. */
1403
+ light: ThemeTokenMap;
1404
+ /** Palette applied when the resolved mode is dark. */
1405
+ dark: ThemeTokenMap;
1406
+ }
1407
+
1408
+ export declare const ThemeGallery: DefineComponent<__VLS_Props_6, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
1409
+ close: () => any;
1410
+ select: (id: string) => any;
1411
+ }, string, PublicProps, Readonly<__VLS_Props_6> & Readonly<{
1412
+ onClose?: (() => any) | undefined;
1413
+ onSelect?: ((id: string) => any) | undefined;
1414
+ }>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, any>;
1415
+
947
1416
  export declare type ThemeMode = 'light' | 'dark' | 'auto';
948
1417
 
1418
+ export declare const THEMES: ThemeDef[];
1419
+
1420
+ /** Map of `--fe-*` custom property → value. */
1421
+ export declare type ThemeTokenMap = Record<string, string>;
1422
+
949
1423
  /** Turkish UI strings. */
950
1424
  export declare const tr: Record<string, string>;
951
1425
 
@@ -1091,6 +1565,9 @@ export declare function useFileApi(config: ExplorerConfig): {
1091
1565
  listVersions: (nodeId: number) => Promise<NodeVersion[]>;
1092
1566
  restoreVersion: (nodeId: number, versionId: number, snapshotCurrent?: boolean) => Promise<void>;
1093
1567
  snapshotVersion: (nodeId: number) => Promise<void>;
1568
+ listComments: (nodeId: number) => Promise<NodeComment[]>;
1569
+ addComment: (nodeId: number, body: string) => Promise<NodeComment>;
1570
+ deleteComment: (id: number) => Promise<void>;
1094
1571
  listPermissions: (path: string) => Promise<PermissionsResponse>;
1095
1572
  resolveEmail: (email: string) => Promise<ResolveEmailResponse>;
1096
1573
  searchUsers: (q: string) => Promise<UserSearchResponse>;
@@ -1157,6 +1634,87 @@ export declare function useMonacoLoader(): {
1157
1634
  getHighlight: typeof getHighlight;
1158
1635
  };
1159
1636
 
1637
+ export declare function useOperations(): {
1638
+ active: Ref< {
1639
+ key: string;
1640
+ kind: OperationKind;
1641
+ name: string;
1642
+ percent: number | null;
1643
+ status: OperationStatus;
1644
+ error: string | null;
1645
+ queued: boolean;
1646
+ doneCount: number | null;
1647
+ totalCount: number | null;
1648
+ uploadedBytes: number | null;
1649
+ totalBytes: number | null;
1650
+ cancellable: boolean;
1651
+ retryable: boolean;
1652
+ startedAt: number;
1653
+ settledAt: number | null;
1654
+ }[], Operation[] | {
1655
+ key: string;
1656
+ kind: OperationKind;
1657
+ name: string;
1658
+ percent: number | null;
1659
+ status: OperationStatus;
1660
+ error: string | null;
1661
+ queued: boolean;
1662
+ doneCount: number | null;
1663
+ totalCount: number | null;
1664
+ uploadedBytes: number | null;
1665
+ totalBytes: number | null;
1666
+ cancellable: boolean;
1667
+ retryable: boolean;
1668
+ startedAt: number;
1669
+ settledAt: number | null;
1670
+ }[]>;
1671
+ history: Ref< {
1672
+ key: string;
1673
+ kind: OperationKind;
1674
+ name: string;
1675
+ percent: number | null;
1676
+ status: OperationStatus;
1677
+ error: string | null;
1678
+ queued: boolean;
1679
+ doneCount: number | null;
1680
+ totalCount: number | null;
1681
+ uploadedBytes: number | null;
1682
+ totalBytes: number | null;
1683
+ cancellable: boolean;
1684
+ retryable: boolean;
1685
+ startedAt: number;
1686
+ settledAt: number | null;
1687
+ }[], Operation[] | {
1688
+ key: string;
1689
+ kind: OperationKind;
1690
+ name: string;
1691
+ percent: number | null;
1692
+ status: OperationStatus;
1693
+ error: string | null;
1694
+ queued: boolean;
1695
+ doneCount: number | null;
1696
+ totalCount: number | null;
1697
+ uploadedBytes: number | null;
1698
+ totalBytes: number | null;
1699
+ cancellable: boolean;
1700
+ retryable: boolean;
1701
+ startedAt: number;
1702
+ settledAt: number | null;
1703
+ }[]>;
1704
+ runningCount: ComputedRef<number>;
1705
+ errorCount: ComputedRef<number>;
1706
+ hasError: ComputedRef<boolean>;
1707
+ overallPercent: ComputedRef<number | null>;
1708
+ sync: (group: string, items: Array<{
1709
+ input: OperationInput;
1710
+ actions?: OperationActions;
1711
+ }>) => void;
1712
+ cancel: (key: string) => void;
1713
+ retry: (key: string) => void;
1714
+ dismiss: (key: string) => void;
1715
+ clearHistory: () => void;
1716
+ };
1717
+
1160
1718
  export declare function usePendingOps(config: ExplorerConfig, api: FileApi, opts?: UsePendingOpsOptions): {
1161
1719
  ops: Ref< {
1162
1720
  id: number;
@@ -1226,10 +1784,45 @@ export declare function useSelection(items: () => FileNode[]): {
1226
1784
  nodes: ComputedRef<FileNode[]>;
1227
1785
  };
1228
1786
 
1787
+ /** Reactive, override-aware view of the registry (registry order). */
1788
+ export declare function useShortcutList(): ComputedRef<ShortcutView[]>;
1789
+
1790
+ export declare function useTabs(opts: UseTabsOptions): {
1791
+ tabs: Ref<TabState[], TabState[]>;
1792
+ activeId: Ref<string, string>;
1793
+ activeTab: ComputedRef<TabState | null>;
1794
+ activeIndex: ComputedRef<number>;
1795
+ hasMultiple: ComputedRef<boolean>;
1796
+ restore: () => boolean;
1797
+ seed: (path: string, viewMode: ViewMode) => void;
1798
+ syncActive: (patch: Partial<Pick<TabState, "path" | "viewMode">>) => void;
1799
+ openTab: (path: string, o: {
1800
+ viewMode: ViewMode;
1801
+ background?: boolean;
1802
+ split?: TabSplit | null;
1803
+ }) => TabState;
1804
+ closeTab: (id: string) => TabState | null;
1805
+ activate: (id: string) => TabState | null;
1806
+ step: (delta: number) => TabState | null;
1807
+ move: (from: number, to: number) => void;
1808
+ setSplit: (split: TabSplit | null) => void;
1809
+ };
1810
+
1811
+ declare interface UseTabsOptions {
1812
+ /** localStorage key; null disables persistence entirely. */
1813
+ storageKey: string | null;
1814
+ }
1815
+
1816
+ /** Reactive handle for components: `{ themeId, setTheme }`. */
1817
+ export declare function useThemeState(): {
1818
+ themeId: Ref<string>;
1819
+ setTheme: (id: string) => void;
1820
+ };
1821
+
1229
1822
  export declare function useUploadChunked(config: ExplorerConfig, api: FileApi): {
1230
1823
  uploadFile: (opts: UploadOptions) => Promise<UploadFinalizeResponse>;
1231
1824
  };
1232
1825
 
1233
- export declare type ViewMode = 'list' | 'grid';
1826
+ export declare type ViewMode = 'list' | 'grid' | 'gallery';
1234
1827
 
1235
1828
  export { }