@owdproject/nuxt-kit-nuxt-ui 0.0.0-stage → 4.0.0-alpha.3

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 (65) hide show
  1. package/dist/module.d.mts +14 -0
  2. package/dist/module.json +9 -0
  3. package/dist/module.mjs +90 -0
  4. package/dist/runtime/components/dialogs/NuxtUIAlertModal.d.vue.ts +8 -0
  5. package/dist/runtime/components/dialogs/NuxtUIAlertModal.vue +40 -0
  6. package/dist/runtime/components/dialogs/NuxtUIAlertModal.vue.d.ts +8 -0
  7. package/dist/runtime/components/dialogs/NuxtUIConfirmModal.d.vue.ts +12 -0
  8. package/dist/runtime/components/dialogs/NuxtUIConfirmModal.vue +47 -0
  9. package/dist/runtime/components/dialogs/NuxtUIConfirmModal.vue.d.ts +12 -0
  10. package/dist/runtime/components/explorer/AddressBar.d.vue.ts +17 -0
  11. package/dist/runtime/components/explorer/AddressBar.vue +39 -0
  12. package/dist/runtime/components/explorer/AddressBar.vue.d.ts +17 -0
  13. package/dist/runtime/components/explorer/Chrome.d.vue.ts +13 -0
  14. package/dist/runtime/components/explorer/Chrome.vue +5 -0
  15. package/dist/runtime/components/explorer/Chrome.vue.d.ts +13 -0
  16. package/dist/runtime/components/explorer/DefaultToolbar.d.vue.ts +31 -0
  17. package/dist/runtime/components/explorer/DefaultToolbar.vue +92 -0
  18. package/dist/runtime/components/explorer/DefaultToolbar.vue.d.ts +31 -0
  19. package/dist/runtime/components/explorer/FileContextMenu.d.vue.ts +18 -0
  20. package/dist/runtime/components/explorer/FileContextMenu.vue +90 -0
  21. package/dist/runtime/components/explorer/FileContextMenu.vue.d.ts +18 -0
  22. package/dist/runtime/components/explorer/FileEntry.d.vue.ts +109 -0
  23. package/dist/runtime/components/explorer/FileEntry.vue +263 -0
  24. package/dist/runtime/components/explorer/FileEntry.vue.d.ts +109 -0
  25. package/dist/runtime/components/explorer/FileIcon.d.vue.ts +29 -0
  26. package/dist/runtime/components/explorer/FileIcon.vue +41 -0
  27. package/dist/runtime/components/explorer/FileIcon.vue.d.ts +29 -0
  28. package/dist/runtime/components/explorer/FilePane.d.vue.ts +13 -0
  29. package/dist/runtime/components/explorer/FilePane.vue +5 -0
  30. package/dist/runtime/components/explorer/FilePane.vue.d.ts +13 -0
  31. package/dist/runtime/components/explorer/Frame.d.vue.ts +75 -0
  32. package/dist/runtime/components/explorer/Frame.vue +73 -0
  33. package/dist/runtime/components/explorer/Frame.vue.d.ts +75 -0
  34. package/dist/runtime/components/explorer/Nav.d.vue.ts +17 -0
  35. package/dist/runtime/components/explorer/Nav.vue +83 -0
  36. package/dist/runtime/components/explorer/Nav.vue.d.ts +17 -0
  37. package/dist/runtime/components/explorer/SelectableArea.d.vue.ts +33 -0
  38. package/dist/runtime/components/explorer/SelectableArea.vue +83 -0
  39. package/dist/runtime/components/explorer/SelectableArea.vue.d.ts +33 -0
  40. package/dist/runtime/components/explorer/Workspace.d.vue.ts +24 -0
  41. package/dist/runtime/components/explorer/Workspace.vue +116 -0
  42. package/dist/runtime/components/explorer/Workspace.vue.d.ts +24 -0
  43. package/dist/runtime/dialogs/createDesktopDialogs.d.ts +2 -0
  44. package/dist/runtime/dialogs/createDesktopDialogs.js +47 -0
  45. package/dist/runtime/plugins/01.desktop-nuxt-ui-dialogs.client.d.ts +2 -0
  46. package/dist/runtime/plugins/01.desktop-nuxt-ui-dialogs.client.js +13 -0
  47. package/dist/types.d.mts +9 -0
  48. package/package.json +78 -4
  49. package/src/kit/registerTailwindPath.ts +44 -0
  50. package/src/runtime/components/dialogs/NuxtUIAlertModal.vue +42 -0
  51. package/src/runtime/components/dialogs/NuxtUIConfirmModal.vue +49 -0
  52. package/src/runtime/components/explorer/AddressBar.vue +44 -0
  53. package/src/runtime/components/explorer/Chrome.vue +5 -0
  54. package/src/runtime/components/explorer/DefaultToolbar.vue +92 -0
  55. package/src/runtime/components/explorer/FileContextMenu.vue +99 -0
  56. package/src/runtime/components/explorer/FileEntry.vue +286 -0
  57. package/src/runtime/components/explorer/FileIcon.vue +43 -0
  58. package/src/runtime/components/explorer/FilePane.vue +5 -0
  59. package/src/runtime/components/explorer/Frame.vue +106 -0
  60. package/src/runtime/components/explorer/Nav.vue +87 -0
  61. package/src/runtime/components/explorer/SelectableArea.vue +93 -0
  62. package/src/runtime/components/explorer/Workspace.vue +119 -0
  63. package/src/runtime/dialogs/createDesktopDialogs.ts +56 -0
  64. package/src/runtime/plugins/01.desktop-nuxt-ui-dialogs.client.ts +14 -0
  65. package/README.md +0 -3
@@ -0,0 +1,109 @@
1
+ declare var __VLS_1: {
2
+ fileName: string;
3
+ isDirectory: boolean;
4
+ layout: string;
5
+ }, __VLS_8: {
6
+ fileName: string;
7
+ isDirectory: boolean;
8
+ layout: string;
9
+ };
10
+ type __VLS_Slots = {} & {
11
+ icon?: (props: typeof __VLS_1) => any;
12
+ } & {
13
+ icon?: (props: typeof __VLS_8) => any;
14
+ };
15
+ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
16
+ basePath: {
17
+ type: StringConstructor;
18
+ required: true;
19
+ };
20
+ fileName: {
21
+ type: StringConstructor;
22
+ required: true;
23
+ };
24
+ layout: {
25
+ type: StringConstructor;
26
+ required: true;
27
+ };
28
+ selected: {
29
+ type: BooleanConstructor;
30
+ required: false;
31
+ };
32
+ cutted: {
33
+ type: BooleanConstructor;
34
+ required: false;
35
+ };
36
+ window: {
37
+ type: ObjectConstructor;
38
+ required: true;
39
+ };
40
+ contextMenuComponent: {
41
+ type: null;
42
+ required: false;
43
+ };
44
+ openPathInNewTab: {
45
+ type: FunctionConstructor;
46
+ required: false;
47
+ };
48
+ dragEnabled: {
49
+ type: BooleanConstructor;
50
+ required: false;
51
+ };
52
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
53
+ rename: (...args: any[]) => void;
54
+ openDirectory: (...args: any[]) => void;
55
+ openFile: (...args: any[]) => void;
56
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
57
+ basePath: {
58
+ type: StringConstructor;
59
+ required: true;
60
+ };
61
+ fileName: {
62
+ type: StringConstructor;
63
+ required: true;
64
+ };
65
+ layout: {
66
+ type: StringConstructor;
67
+ required: true;
68
+ };
69
+ selected: {
70
+ type: BooleanConstructor;
71
+ required: false;
72
+ };
73
+ cutted: {
74
+ type: BooleanConstructor;
75
+ required: false;
76
+ };
77
+ window: {
78
+ type: ObjectConstructor;
79
+ required: true;
80
+ };
81
+ contextMenuComponent: {
82
+ type: null;
83
+ required: false;
84
+ };
85
+ openPathInNewTab: {
86
+ type: FunctionConstructor;
87
+ required: false;
88
+ };
89
+ dragEnabled: {
90
+ type: BooleanConstructor;
91
+ required: false;
92
+ };
93
+ }>> & Readonly<{
94
+ onRename?: ((...args: any[]) => any) | undefined;
95
+ onOpenDirectory?: ((...args: any[]) => any) | undefined;
96
+ onOpenFile?: ((...args: any[]) => any) | undefined;
97
+ }>, {
98
+ selected: boolean;
99
+ cutted: boolean;
100
+ dragEnabled: boolean;
101
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
102
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
103
+ declare const _default: typeof __VLS_export;
104
+ export default _default;
105
+ type __VLS_WithSlots<T, S> = T & {
106
+ new (): {
107
+ $slots: S;
108
+ };
109
+ };
@@ -0,0 +1,263 @@
1
+ <script setup>
2
+ import { explorerEntryAbsolutePath } from "@owdproject/nuxt-module-fs/runtime/utils/utilExplorerEntryPath";
3
+ import { fetchExplorerEntryMetadata } from "@owdproject/nuxt-module-fs/runtime/utils/utilExplorerEntryMetadata";
4
+ import { ref, computed, watch } from "vue";
5
+ import FileContextMenu from "./FileContextMenu.vue";
6
+ import FileIcon from "./FileIcon.vue";
7
+ import { useExplorerInternalDrag } from "@owdproject/nuxt-module-fs/runtime/composables/useExplorerInternalDrag";
8
+ import { useExplorerFolderDropTarget } from "@owdproject/nuxt-module-fs/runtime/composables/useExplorerFolderDropTarget";
9
+ const props = defineProps({
10
+ basePath: { type: String, required: true },
11
+ fileName: { type: String, required: true },
12
+ layout: { type: String, required: true },
13
+ selected: { type: Boolean, required: false },
14
+ cutted: { type: Boolean, required: false },
15
+ window: { type: Object, required: true },
16
+ contextMenuComponent: { type: null, required: false },
17
+ openPathInNewTab: { type: Function, required: false },
18
+ dragEnabled: { type: Boolean, required: false }
19
+ });
20
+ const menuImpl = computed(
21
+ () => props.contextMenuComponent ?? FileContextMenu
22
+ );
23
+ const emit = defineEmits([
24
+ "openDirectory",
25
+ "openFile",
26
+ "rename"
27
+ ]);
28
+ const path = computed(
29
+ () => explorerEntryAbsolutePath(props.basePath, props.fileName)
30
+ );
31
+ const pathStats = ref(null);
32
+ const isDirectory = ref(false);
33
+ const isFile = ref();
34
+ const fileContent = ref(null);
35
+ const contextMenuRef = ref();
36
+ function fetchStatsAndContent(currentPath) {
37
+ fetchExplorerEntryMetadata(currentPath, (meta) => {
38
+ pathStats.value = meta.stats;
39
+ isFile.value = meta.isFile;
40
+ isDirectory.value = meta.isDirectory;
41
+ fileContent.value = meta.fileContent;
42
+ });
43
+ }
44
+ function onFileOpen() {
45
+ if (isDirectory.value) {
46
+ props.window.fsExplorer.openDirectory(props.fileName);
47
+ } else {
48
+ props.window.fsExplorer.openFile(props.fileName);
49
+ }
50
+ }
51
+ function onRightClick(event) {
52
+ contextMenuRef.value?.show(event);
53
+ }
54
+ function onAuxClick(event) {
55
+ if (event.button !== 1) return;
56
+ if (!isDirectory.value || !props.openPathInNewTab) return;
57
+ event.preventDefault();
58
+ event.stopPropagation();
59
+ props.openPathInNewTab(path.value);
60
+ }
61
+ watch(
62
+ path,
63
+ (p) => {
64
+ fetchStatsAndContent(p);
65
+ },
66
+ { immediate: true }
67
+ );
68
+ const isRenaming = ref(false);
69
+ const editableName = ref(props.fileName);
70
+ function renameCommit() {
71
+ const newName = editableName.value.trim();
72
+ if (newName && newName !== props.fileName) {
73
+ emit("rename", { oldName: props.fileName, newName });
74
+ }
75
+ isRenaming.value = false;
76
+ }
77
+ function renameStart() {
78
+ editableName.value = props.fileName;
79
+ isRenaming.value = true;
80
+ }
81
+ function renameCancel() {
82
+ editableName.value = props.fileName;
83
+ isRenaming.value = false;
84
+ }
85
+ const isRowLayout = computed(
86
+ () => props.layout === "list" || props.layout === "details"
87
+ );
88
+ function formatBytes(n) {
89
+ if (!Number.isFinite(n) || n < 0) return "\u2014";
90
+ if (n < 1024) return `${n} B`;
91
+ const units = ["KB", "MB", "GB", "TB"];
92
+ let v = n / 1024;
93
+ let i = 0;
94
+ while (v >= 1024 && i < units.length - 1) {
95
+ v /= 1024;
96
+ i++;
97
+ }
98
+ const rounded = v < 10 && i > 0 ? v.toFixed(1) : String(Math.round(v));
99
+ return `${rounded} ${units[i]}`;
100
+ }
101
+ function statToDate(stats) {
102
+ if (!stats) return null;
103
+ const m = stats.mtime;
104
+ if (m instanceof Date) return m;
105
+ if (typeof m === "number") return new Date(m);
106
+ return null;
107
+ }
108
+ const modifiedLabel = computed(() => {
109
+ const d = statToDate(pathStats.value);
110
+ if (!d || Number.isNaN(d.getTime())) return "\u2014";
111
+ return d.toLocaleString(void 0, {
112
+ dateStyle: "short",
113
+ timeStyle: "short"
114
+ });
115
+ });
116
+ const typeLabel = computed(() => {
117
+ if (isDirectory.value) return "File folder";
118
+ const parts = props.fileName.split(".");
119
+ if (parts.length < 2) return "File";
120
+ return `${parts.pop()?.toUpperCase()} file`;
121
+ });
122
+ const sizeLabel = computed(() => {
123
+ if (!pathStats.value || isDirectory.value) return "\u2014";
124
+ if (typeof pathStats.value.isFile === "function" && !pathStats.value.isFile()) return "\u2014";
125
+ return formatBytes(pathStats.value.size);
126
+ });
127
+ const dragEnabledValue = computed(() => props.dragEnabled ?? true);
128
+ const { onDragStart } = useExplorerInternalDrag({
129
+ entryPath: () => path.value,
130
+ selectedFiles: () => props.window.fsExplorer?.selectedFiles.value ?? [],
131
+ dragEnabled: () => dragEnabledValue.value
132
+ });
133
+ const folderDrop = useExplorerFolderDropTarget({
134
+ fsExplorer: props.window.fsExplorer,
135
+ folderPath: () => path.value,
136
+ enabled: () => dragEnabledValue.value && isDirectory.value
137
+ });
138
+ const classes = computed(() => {
139
+ const list = [
140
+ "owd-file select-none rounded-lg transition-all cursor-pointer p-1.5 flex flex-col items-center",
141
+ isRowLayout.value ? "w-full text-left" : "w-[90px] text-center"
142
+ ];
143
+ if (props.selected) {
144
+ list.push("bg-primary-50 dark:bg-primary-950/30 ring-1 ring-primary-500/50");
145
+ } else {
146
+ list.push("hover:bg-gray-100 dark:hover:bg-gray-800/50");
147
+ }
148
+ if (props.cutted) {
149
+ list.push("opacity-50");
150
+ }
151
+ if (folderDrop.isDragOver.value) {
152
+ list.push("bg-blue-100/50 dark:bg-blue-900/30 ring-2 ring-dashed ring-blue-500");
153
+ }
154
+ return list;
155
+ });
156
+ </script>
157
+
158
+ <template>
159
+ <div
160
+ :class="classes"
161
+ :title="fileName"
162
+ :draggable="dragEnabledValue"
163
+ @dragstart.stop="onDragStart"
164
+ @dragenter="folderDrop.onDragEnter"
165
+ @dragover="folderDrop.onDragOver"
166
+ @dragleave="folderDrop.onDragLeave"
167
+ @drop="folderDrop.onDrop"
168
+ @dblclick="onFileOpen"
169
+ @contextmenu.prevent="onRightClick"
170
+ @auxclick.prevent="onAuxClick"
171
+ >
172
+ <template v-if="isRowLayout">
173
+ <div class="flex items-center w-full space-x-3">
174
+ <div class="w-8 flex-shrink-0 flex items-center justify-center">
175
+ <slot
176
+ name="icon"
177
+ :file-name="fileName"
178
+ :is-directory="isDirectory"
179
+ :layout="layout"
180
+ >
181
+ <FileIcon
182
+ :file-name="fileName"
183
+ :is-directory="isDirectory"
184
+ :layout="layout"
185
+ />
186
+ </slot>
187
+ </div>
188
+
189
+ <div class="flex-1 min-w-0">
190
+ <span
191
+ v-if="!isRenaming"
192
+ @dblclick.stop="renameStart"
193
+ class="text-sm truncate block font-medium text-gray-700 dark:text-gray-200"
194
+ v-text="fileName"
195
+ />
196
+
197
+ <input
198
+ v-else
199
+ v-model="editableName"
200
+ class="text-sm truncate border border-primary-500 rounded px-1 w-full bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 outline-none"
201
+ @blur="renameCommit"
202
+ @keyup.enter="renameCommit"
203
+ @keyup.esc="renameCancel"
204
+ autofocus
205
+ />
206
+ </div>
207
+
208
+ <template v-if="layout === 'details'">
209
+ <div class="text-xs text-gray-400 w-32 text-right truncate tabular-nums">{{ modifiedLabel }}</div>
210
+ <div class="text-xs text-gray-400 w-24 truncate" :title="typeLabel">{{ typeLabel }}</div>
211
+ <div class="text-xs text-gray-400 w-20 text-right truncate tabular-nums">{{ sizeLabel }}</div>
212
+ </template>
213
+ </div>
214
+ </template>
215
+
216
+ <template v-else>
217
+ <div class="p-1 rounded flex items-center justify-center mb-1">
218
+ <slot
219
+ name="icon"
220
+ :file-name="fileName"
221
+ :is-directory="isDirectory"
222
+ :layout="layout"
223
+ >
224
+ <FileIcon
225
+ :file-name="fileName"
226
+ :is-directory="isDirectory"
227
+ :layout="layout"
228
+ />
229
+ </slot>
230
+ </div>
231
+
232
+ <div class="w-full text-center">
233
+ <span
234
+ v-if="!isRenaming"
235
+ @dblclick.stop="renameStart"
236
+ class="text-xs block truncate font-medium text-gray-700 dark:text-gray-200 px-1"
237
+ v-text="fileName"
238
+ />
239
+
240
+ <input
241
+ v-else
242
+ v-model="editableName"
243
+ class="text-xs truncate border border-primary-500 rounded px-1 w-full bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 outline-none text-center"
244
+ @blur="renameCommit"
245
+ @keyup.enter="renameCommit"
246
+ @keyup.esc="renameCancel"
247
+ autofocus
248
+ />
249
+ </div>
250
+ </template>
251
+
252
+ <component
253
+ :is="menuImpl"
254
+ ref="contextMenuRef"
255
+ :file-name="fileName"
256
+ :window="window"
257
+ :is-directory="!!isDirectory"
258
+ :open-path-in-new-tab="openPathInNewTab"
259
+ @open="onFileOpen"
260
+ @rename="renameStart"
261
+ />
262
+ </div>
263
+ </template>
@@ -0,0 +1,109 @@
1
+ declare var __VLS_1: {
2
+ fileName: string;
3
+ isDirectory: boolean;
4
+ layout: string;
5
+ }, __VLS_8: {
6
+ fileName: string;
7
+ isDirectory: boolean;
8
+ layout: string;
9
+ };
10
+ type __VLS_Slots = {} & {
11
+ icon?: (props: typeof __VLS_1) => any;
12
+ } & {
13
+ icon?: (props: typeof __VLS_8) => any;
14
+ };
15
+ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
16
+ basePath: {
17
+ type: StringConstructor;
18
+ required: true;
19
+ };
20
+ fileName: {
21
+ type: StringConstructor;
22
+ required: true;
23
+ };
24
+ layout: {
25
+ type: StringConstructor;
26
+ required: true;
27
+ };
28
+ selected: {
29
+ type: BooleanConstructor;
30
+ required: false;
31
+ };
32
+ cutted: {
33
+ type: BooleanConstructor;
34
+ required: false;
35
+ };
36
+ window: {
37
+ type: ObjectConstructor;
38
+ required: true;
39
+ };
40
+ contextMenuComponent: {
41
+ type: null;
42
+ required: false;
43
+ };
44
+ openPathInNewTab: {
45
+ type: FunctionConstructor;
46
+ required: false;
47
+ };
48
+ dragEnabled: {
49
+ type: BooleanConstructor;
50
+ required: false;
51
+ };
52
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
53
+ rename: (...args: any[]) => void;
54
+ openDirectory: (...args: any[]) => void;
55
+ openFile: (...args: any[]) => void;
56
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
57
+ basePath: {
58
+ type: StringConstructor;
59
+ required: true;
60
+ };
61
+ fileName: {
62
+ type: StringConstructor;
63
+ required: true;
64
+ };
65
+ layout: {
66
+ type: StringConstructor;
67
+ required: true;
68
+ };
69
+ selected: {
70
+ type: BooleanConstructor;
71
+ required: false;
72
+ };
73
+ cutted: {
74
+ type: BooleanConstructor;
75
+ required: false;
76
+ };
77
+ window: {
78
+ type: ObjectConstructor;
79
+ required: true;
80
+ };
81
+ contextMenuComponent: {
82
+ type: null;
83
+ required: false;
84
+ };
85
+ openPathInNewTab: {
86
+ type: FunctionConstructor;
87
+ required: false;
88
+ };
89
+ dragEnabled: {
90
+ type: BooleanConstructor;
91
+ required: false;
92
+ };
93
+ }>> & Readonly<{
94
+ onRename?: ((...args: any[]) => any) | undefined;
95
+ onOpenDirectory?: ((...args: any[]) => any) | undefined;
96
+ onOpenFile?: ((...args: any[]) => any) | undefined;
97
+ }>, {
98
+ selected: boolean;
99
+ cutted: boolean;
100
+ dragEnabled: boolean;
101
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
102
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
103
+ declare const _default: typeof __VLS_export;
104
+ export default _default;
105
+ type __VLS_WithSlots<T, S> = T & {
106
+ new (): {
107
+ $slots: S;
108
+ };
109
+ };
@@ -0,0 +1,29 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
2
+ fileName: {
3
+ type: StringConstructor;
4
+ required: true;
5
+ };
6
+ isDirectory: {
7
+ type: BooleanConstructor;
8
+ required: true;
9
+ };
10
+ layout: {
11
+ type: StringConstructor;
12
+ required: true;
13
+ };
14
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
15
+ fileName: {
16
+ type: StringConstructor;
17
+ required: true;
18
+ };
19
+ isDirectory: {
20
+ type: BooleanConstructor;
21
+ required: true;
22
+ };
23
+ layout: {
24
+ type: StringConstructor;
25
+ required: true;
26
+ };
27
+ }>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
28
+ declare const _default: typeof __VLS_export;
29
+ export default _default;
@@ -0,0 +1,41 @@
1
+ <script setup>
2
+ import { computed } from "vue";
3
+ const props = defineProps({
4
+ fileName: { type: String, required: true },
5
+ isDirectory: { type: Boolean, required: true },
6
+ layout: { type: String, required: true }
7
+ });
8
+ const imageIcon = "data:image/x-icon;base64,AAABAAIAICAQAAEABADoAgAAJgAAABAQEAABAAQAKAEAAA4DAAAoAAAAIAAAAEAAAAABAAQAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAACHd3d3d3d3d3d3d3AAAAAAj/////////////9wAAAAAI//////////////cAAAAACP/////////////3AAAAAAj/////////////9wAAAAAI//////////////cAAAAACP/wAP/wAP/wAA/3AAAAAAj/83MAC3sAA3MP9wAAAAAI//O3t7e3t7ezD/cAAAAACP//O3MzMzM7MP/3AAAAAAj///Ow////Nw//9wAAAAAI///zcP///zsP//cAAAAACP//M7D/AAAAMP/3AAAAAAj//ztw8CKnAAD/9wAAAAAI//8zsKqvL3AA//cAAAAACP//83Cqr/KIAP/3AAAAAAj///OwqqqvOPsP9wAAAAAI//87cKqq/zuPsAcAAAAACP/zN7AAAAA3OPkQAAAAAAj/83t7e3t7e3MdmQAAAAAI//OzMzOzMzOzAdmQAAAACP/zM//zM//zMw8dmQAAAAj/////////////8dmQAAAI//////////////cdmQAACP//////////gAAAAdmQAAj//////////4/3gAAdmQAI//////////+PeAAAAdmQCP//////////h4AAAAAdmQj//////////4gAAAAAAdkI//////////+AAAAAAAARCIiIiIiIiIiIgAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAfwAAAD8AAAAfAAAADwAAAAcAAAGDAAADwQAAB+AAAA/wAAAf+AAAP/8oAAAAEAAAACAAAAABAAQAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAh3d3d3d3AACP//////cAAI/wAAAA9wAAj/c3NzD3AACP8w//MPcAAI/3DyIA9wAAj/MCd4cHAACP9wqqOAEAAI/zCqowmRAAj/cAADD5kQCP83NzMPeZEI/////wAAmRj/////f4AJGP////94AAAIiIiIiIAAAAAAeIiAAH//8AB///AAf//wAHAKAAB70AAAe9AAAHIgAABwAAAAcACAAD/CIAAYgAAAAAAAAMAAAAH2b2AD8AAA==";
9
+ const audioIcon = "data:image/x-icon;base64,AAABAAIAICAQAAEABADoAgAAJgAAABAQEAABAAQAKAEAAA4DAAAoAAAAIAAAAEAAAAABAAQAAAAAAIACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvwAAvwAAAL+/AL8AAAC/AL8Av78AAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACHd3d3d3d3d3dwAAAAAAAAj///////////cAAAAAAAAI///////////3AAAAAAAACP//d///////9wAAAAAAAAj/93d///////cAAAAAAAAI/wB3d//////3AAAAAAAACPAwh3f//4//9wAAAAAAAAgDB3h3/4j///cAAAAAAABwOI/4d4j////3AAAAAAAHA7B/+Hj/////9wAAAAAAADvwf/h3//////cAAAAAADi/sA/4d//////3AAAAAAO3+/CA+HiIiP//9wAAAAADt7+wcPh3//////cAAAAAA/f78A/4d//////3AAAAAAAzv7B/+Hj/////9wAAAAAAADvwf/h/iP////cAAAAAAAADuIf4f/+I///3AAAAAAAACDsHd////4//9wAAAAAAAAjzgI////////cAAAAAAAAI/wD////////3AAAAAAAACP////////gAAAAAAAAAAAj////////4/4AAAAAAAAAI////////+PgAAAAAAAAACP////////iAAAAAAAAAAAj////////4AAAAAAAAAAAIiIiIiIiIiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AAAP/wAAD/8AAA//AAAP/wAAD/8AAA//AAAP/wAAD/8AAA/+AAAP/AAAD/gAAA/wAAAP8AAAD/AAAA/wAAAP+AAAD/4AAA//AAAP/wAAD/8AAA//AAAP/wAAD/8AAB//AAA//wAAf/8AAP//AAH///////////8oAAAAEAAAACAAAAABAAQAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvwAAvwAAAL+/AL8AAAC/AL8Av78AAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAACHd3d3d3AAAI//////cAAAgAD///9wAAADMI/4/3AAgDsPj4//cAADsH+P//9wC4vwD4+Ij3A/e/CPj///cAM/sH+Pj/9wADP4D4/4/3AAAD8Hj///cAAAg4D//wAAAACP////f4AAAI////94AAAAiIiIiIAA8AAAAPAAAADwAAAA8AAAAPAAAADAAAAAgAAAAAAAAAAAAAAAgAAAAMAAAADwAAAA8AAAAPABAADwAwAA8AcAAA==";
10
+ const videoIcon = "data:image/x-icon;base64,AAABAAIAICAQAAEABADoAgAAJgAAABAQEAABAAQAKAEAAA4DAAAoAAAAIAAAAEAAAAABAAQAAAAAAIACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvwAAvwAAAL+/AL8AAAC/AL8Av78AAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACHd3d3d3d3d3dwAAAAAAAAj///////////cAAAAAAAB4d3d3d3d3d//3AAAAAAAHeHd3d3d3d3f/9wAAAAAAAAAAAAAAAAB3//cAAAAACIiIiIiIiIiAd//3AAAAAAj/////////gHf/9wAAAAAI//n/zM/y/4B3//cAAAAACP+fn8//8v+Ad//3AAAAAAj/+f/8//L/gHf/9wAAAAAI/5+fz88i/4B3//cAAAAACP/5//z/8v+Ad//3AAAAAAj/////////gHf/9wAAAAAAAP8A/wD/AIB///cAAAAAAz8A/wD/AP8A///3AAAAAI/4CACIAIgAiP//9wAAAACLuAB3d/////////cAAAAACID/AHd3///////3AAAAAAAIAP8Ad3f/////9wAAAAAAAAgA/wB3d/////cAAAAAAAAI+AD/AHd3///3AAAAAAAACP/4AP8Af/gAAAAAAAAAAAj///gA/w/4/4AAAAAAAAAI////+ACP+PgAAAAAAAAACP/////4//iAAAAAAAAAAAj////////4AAAAAAAAAAAIiIiIiIiIiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AAAP/wAAD/8AAA/+AAAP/AAAD/gAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP4AAAD+AAAA/wAAAP/AAAD/8AAA//AAAP/wAAD/8AAB//AAA//wAAf/8AAP//AAH///////////8oAAAAEAAAACAAAAABAAQAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvwAAvwAAAL+/AL8AAAC/AL8Av78AAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAACHd3d3d3AAAI//////cAAAAAAAD/9wiIiIiIgP/3CP////+A//cI+Z/PL4D/9wj/////gP/3CPDw8PCA//cACAgICA//9wiwAP/////3CIj/AA////cAAIiP8P/wAAAACPiP//f4AAAI////94AAAAiIiIiIAA8AAAAPAAAADwAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAPABAADwAwAA8AcAAA==";
11
+ const iconMap = {
12
+ mp4: videoIcon,
13
+ webm: videoIcon,
14
+ mp3: audioIcon,
15
+ wav: audioIcon,
16
+ iso: "data:image/x-icon;base64,AAABAAEAICAQAAEABADoAgAAFgAAACgAAAAgAAAAQAAAAAEABAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAwMDAAICAgAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAId3d3d3d3d3d3AAAAAAAACP//////////9wAAAAAAAAj///////////cAAAAAAAAI///////////3AAAAAAAACP/3d3f/////9wAAAAAAAAj3d3d3f/////cAAAAAAAAIiAAHd3f////3AAAAAAAAiHd6oAd3f///9wAAAAAACHd3equwd3f///cAAAAAAI93d3q77gd3///3AAAAAACH93d6vucHd///9wAAAAAId393+r53cHf///cAAAAACHd3+Ajnd3B3///3AAAAAAh3d6Dwd3dwd///9wAAAAAId3roCHd3cHf///cAAAAACHeq63f3d3B////3AAAAAACKrrt3f3cHf///9wAAAAAAiu67d3f3D/////cAAAAAAAjru3d3cP/////3AAAAAAAAiLt3cA//////9wAAAAAAAAiIiI////////cAAAAAAAAI////////+AAAAAAAAAAACP////////j/gAAAAAAAAAj////////4+AAAAAAAAAAI////////+IAAAAAAAAAACP////////gAAAAAAAAAAAiIiIiIiIiIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8AAA//AAAP/wAAD/8AAA//AAAP/wAAD/8AAA//AAAP/gAAD/wAAA/4AAAP+AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP+AAAD/gAAA/8AAAP/gAAD/8AAA//AAAP/wAAH/8AAD//AAB//wAA//8AAf///////////w==",
17
+ webp: imageIcon,
18
+ gif: imageIcon,
19
+ jpg: imageIcon,
20
+ png: imageIcon,
21
+ txt: "data:image/x-icon;base64,AAABAAIAICAQAAEABADoAgAAJgAAABAQEAABAAQAKAEAAA4DAAAoAAAAIAAAAEAAAAABAAQAAAAAAIACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvwAAvwAAAL+/AL8AAAC/AL8Av78AAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAACHd3d3d3d3d3d3dwcAAAAI//////////////9wcAAACP//////////////cHAAAAj/AAAA/////////3BwAAAI//////////////9wcAAACP8AAAD/////////cHAAAAj//////////////3BwAAAI//////////////9wcAAACP8AAAAAAAAAAAD/cHAAAAj//////////////3BwAAAI/wAAAAAAAAAAAP9wcAAACP//////////////cHAAAAj/AAAAAAAAAAAA/3BwAAAI//////////////9wcAAACP8AAAAAAAAAAAD/cHAAAAj//////////////3BwAAAI//////////////9wcAAACP8AAAD/////////cHAAAAj//////////////3BwAAAI//////////////9wcAAACP//////////////cHAAAAj/AAAA/////////3BwAAAI//////////////9wcAAACP8AAAD////w8AD/cHAAAAj//////////////3BwAAAI//////////////9wcAAACP//////////////cHAAAAjw/w/w/w/w/w/w/4BwAAAI8P8P8P8P8P8P8P+AcAAAAI+I+I+I+I+I+I+I+AAAAAAAAAAAAAAAAAAAAAAAAA8AAAH+AAAA/AAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAH4AAAD/JJJL8oAAAAEAAAACAAAAABAAQAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvwAAvwAAAL+/AL8AAAC/AL8Av78AAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAh3d3d3d3AACP//////cAAI//////9wAAj/AAAA/3AACP//////cAAI/wAAAP9wAAj//////3AACP8AAAD/cAAI//////9wAAj/AA8A/3AACP//////cAAI//////9wAAjw8PDw8PAAAA+Pj4+PAAAAAAAAAAAAAAgA8AAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAACADwAA1V8AAA==",
22
+ pdf: "/icons/pdf.ico",
23
+ default: "data:image/x-icon;base64,AAABAAEAICAQAAEABADoAgAAFgAAACgAAAAgAAAAQAAAAAEABAAAAAAAgAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8AAAAHd3d3d3d3d3d3d3dwAAAAAAAAAAAAAAAAAAAAcAAAAA//////////////8HAAAAAP//////////////BwAAAAD//////////////wcAAAAA//////////////8HAAAAAP//////////////BwAAAAD//////////////wcAAAAA//////////////8HAAAAAP//////////////BwAAAAD//////////////wcAAAAA//////////////8HAAAAAP//////////////BwAAAAD//////////////wcAAAAA//////////////8HAAAAAP//////////////BwAAAAD//////////////wcAAAAA//////////////8HAAAAAP//////////////BwAAAAD//////////////wcAAAAA//////////////8HAAAAAP//////////////BwAAAAD//////////////wcAAAAA//////////////8HAAAAAP//////////////BwAAAAD//////////wAAAAAAAAAA//////////8P+HAAAAAAAP//////////D4cAAAAAAAD//////////whwAAAAAAAA//////////8HAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAD4AAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAD/AAAB/wAAA/8AAAf/AAAP/wAAH/8AAD/w=="
24
+ };
25
+ const directoryIcon = "data:image/x-icon;base64,AAABAAIAICAQAAEABADoAgAAJgAAABAQEAABAAQAKAEAAA4DAAAoAAAAIAAAAEAAAAABAAQAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDMzMzMzMzMzMzMzMzMzMwj7e3t7e3t7e3t7e3t7e3wCHd3d3d3d3d4iIiIiIiIgACPt7e3t7e3gAAAAAAAAAAACPt7e3t7eAAAAAAAAAAAAACP/////4AAAAAAAAAAAAAACIiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////////gAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAP//wAH//+AD///wB/////////////8oAAAAEAAAACAAAAABAAQAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIiIiIiIiIgAj7e3t7e3uACPe3t7e3t4AI+3t7e3t7gAj3t7e3t7eACPt7e3t7e4AI97e3t7e3gAj7e3t7e3uACP///////4AIe3t7eIiIgACHt7eAAAAAAAiIiAAAAAAAAAAAAAAAAA//8AAP//AACAAQCgAAHOAAABzgAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAMAAID/AADB/wAA//8AAA==";
26
+ const getFileExtension = (name) => name.split(".").pop()?.toLowerCase() ?? "";
27
+ const iconSrc = computed(() => {
28
+ if (props.isDirectory) return directoryIcon;
29
+ const ext = getFileExtension(props.fileName);
30
+ return iconMap[ext] || iconMap.default;
31
+ });
32
+ </script>
33
+
34
+ <template>
35
+ <img
36
+ :src="iconSrc"
37
+ draggable="false"
38
+ alt=""
39
+ class="mx-auto"
40
+ />
41
+ </template>
@@ -0,0 +1,29 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
2
+ fileName: {
3
+ type: StringConstructor;
4
+ required: true;
5
+ };
6
+ isDirectory: {
7
+ type: BooleanConstructor;
8
+ required: true;
9
+ };
10
+ layout: {
11
+ type: StringConstructor;
12
+ required: true;
13
+ };
14
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
15
+ fileName: {
16
+ type: StringConstructor;
17
+ required: true;
18
+ };
19
+ isDirectory: {
20
+ type: BooleanConstructor;
21
+ required: true;
22
+ };
23
+ layout: {
24
+ type: StringConstructor;
25
+ required: true;
26
+ };
27
+ }>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
28
+ declare const _default: typeof __VLS_export;
29
+ export default _default;
@@ -0,0 +1,13 @@
1
+ declare var __VLS_1: {};
2
+ type __VLS_Slots = {} & {
3
+ default?: (props: typeof __VLS_1) => any;
4
+ };
5
+ declare const __VLS_base: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
6
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
7
+ declare const _default: typeof __VLS_export;
8
+ export default _default;
9
+ type __VLS_WithSlots<T, S> = T & {
10
+ new (): {
11
+ $slots: S;
12
+ };
13
+ };
@@ -0,0 +1,5 @@
1
+ <template>
2
+ <div class="flex-1 min-h-0 relative flex overflow-auto">
3
+ <slot />
4
+ </div>
5
+ </template>
@@ -0,0 +1,13 @@
1
+ declare var __VLS_1: {};
2
+ type __VLS_Slots = {} & {
3
+ default?: (props: typeof __VLS_1) => any;
4
+ };
5
+ declare const __VLS_base: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
6
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
7
+ declare const _default: typeof __VLS_export;
8
+ export default _default;
9
+ type __VLS_WithSlots<T, S> = T & {
10
+ new (): {
11
+ $slots: S;
12
+ };
13
+ };