nuxt-ui-tools 1.7.0 → 1.8.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.
Files changed (162) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +18 -0
  3. package/dist/runtime/file-preview/components/provider/file-preview-host.d.vue.ts +7 -0
  4. package/dist/runtime/file-preview/components/provider/file-preview-host.vue +147 -0
  5. package/dist/runtime/file-preview/components/provider/file-preview-host.vue.d.ts +7 -0
  6. package/dist/runtime/file-preview/components/provider/file-preview-provider.d.vue.ts +21 -0
  7. package/dist/runtime/file-preview/components/provider/file-preview-provider.vue +23 -0
  8. package/dist/runtime/file-preview/components/provider/file-preview-provider.vue.d.ts +21 -0
  9. package/dist/runtime/file-preview/components/renderers/audio-renderer.d.vue.ts +10 -0
  10. package/dist/runtime/file-preview/components/renderers/audio-renderer.vue +83 -0
  11. package/dist/runtime/file-preview/components/renderers/audio-renderer.vue.d.ts +10 -0
  12. package/dist/runtime/file-preview/components/renderers/csv-renderer.d.vue.ts +10 -0
  13. package/dist/runtime/file-preview/components/renderers/csv-renderer.vue +116 -0
  14. package/dist/runtime/file-preview/components/renderers/csv-renderer.vue.d.ts +10 -0
  15. package/dist/runtime/file-preview/components/renderers/fallback-renderer.d.vue.ts +10 -0
  16. package/dist/runtime/file-preview/components/renderers/fallback-renderer.vue +41 -0
  17. package/dist/runtime/file-preview/components/renderers/fallback-renderer.vue.d.ts +10 -0
  18. package/dist/runtime/file-preview/components/renderers/file-preview-code.d.vue.ts +9 -0
  19. package/dist/runtime/file-preview/components/renderers/file-preview-code.vue +83 -0
  20. package/dist/runtime/file-preview/components/renderers/file-preview-code.vue.d.ts +9 -0
  21. package/dist/runtime/file-preview/components/renderers/file-preview-text-loading.d.vue.ts +3 -0
  22. package/dist/runtime/file-preview/components/renderers/file-preview-text-loading.vue +14 -0
  23. package/dist/runtime/file-preview/components/renderers/file-preview-text-loading.vue.d.ts +3 -0
  24. package/dist/runtime/file-preview/components/renderers/image-renderer.d.vue.ts +10 -0
  25. package/dist/runtime/file-preview/components/renderers/image-renderer.vue +182 -0
  26. package/dist/runtime/file-preview/components/renderers/image-renderer.vue.d.ts +10 -0
  27. package/dist/runtime/file-preview/components/renderers/markdown-renderer.d.vue.ts +10 -0
  28. package/dist/runtime/file-preview/components/renderers/markdown-renderer.vue +78 -0
  29. package/dist/runtime/file-preview/components/renderers/markdown-renderer.vue.d.ts +10 -0
  30. package/dist/runtime/file-preview/components/renderers/media-controls.d.vue.ts +10 -0
  31. package/dist/runtime/file-preview/components/renderers/media-controls.vue +145 -0
  32. package/dist/runtime/file-preview/components/renderers/media-controls.vue.d.ts +10 -0
  33. package/dist/runtime/file-preview/components/renderers/pdf-renderer.d.vue.ts +10 -0
  34. package/dist/runtime/file-preview/components/renderers/pdf-renderer.vue +58 -0
  35. package/dist/runtime/file-preview/components/renderers/pdf-renderer.vue.d.ts +10 -0
  36. package/dist/runtime/file-preview/components/renderers/text-renderer.d.vue.ts +10 -0
  37. package/dist/runtime/file-preview/components/renderers/text-renderer.vue +41 -0
  38. package/dist/runtime/file-preview/components/renderers/text-renderer.vue.d.ts +10 -0
  39. package/dist/runtime/file-preview/components/renderers/video-renderer.d.vue.ts +10 -0
  40. package/dist/runtime/file-preview/components/renderers/video-renderer.vue +110 -0
  41. package/dist/runtime/file-preview/components/renderers/video-renderer.vue.d.ts +10 -0
  42. package/dist/runtime/file-preview/components/shell/file-preview-button.d.vue.ts +16 -0
  43. package/dist/runtime/file-preview/components/shell/file-preview-button.vue +40 -0
  44. package/dist/runtime/file-preview/components/shell/file-preview-button.vue.d.ts +16 -0
  45. package/dist/runtime/{form/components/renderer/form-field-error.d.vue.ts → file-preview/components/shell/file-preview-details.d.vue.ts} +4 -2
  46. package/dist/runtime/file-preview/components/shell/file-preview-details.vue +25 -0
  47. package/dist/runtime/{form/components/renderer/form-field-error.vue.d.ts → file-preview/components/shell/file-preview-details.vue.d.ts} +4 -2
  48. package/dist/runtime/file-preview/components/shell/file-preview-header.d.vue.ts +44 -0
  49. package/dist/runtime/file-preview/components/shell/file-preview-header.vue +163 -0
  50. package/dist/runtime/file-preview/components/shell/file-preview-header.vue.d.ts +44 -0
  51. package/dist/runtime/file-preview/components/shell/file-preview-message.d.vue.ts +21 -0
  52. package/dist/runtime/file-preview/components/shell/file-preview-message.vue +49 -0
  53. package/dist/runtime/file-preview/components/shell/file-preview-message.vue.d.ts +21 -0
  54. package/dist/runtime/file-preview/components/shell/file-preview-shell.d.vue.ts +17 -0
  55. package/dist/runtime/file-preview/components/shell/file-preview-shell.vue +280 -0
  56. package/dist/runtime/file-preview/components/shell/file-preview-shell.vue.d.ts +17 -0
  57. package/dist/runtime/file-preview/components/shell/file-preview-stage.d.vue.ts +37 -0
  58. package/dist/runtime/file-preview/components/shell/file-preview-stage.vue +173 -0
  59. package/dist/runtime/file-preview/components/shell/file-preview-stage.vue.d.ts +37 -0
  60. package/dist/runtime/file-preview/components/shell/file-preview-thumb.d.vue.ts +14 -0
  61. package/dist/runtime/file-preview/components/shell/file-preview-thumb.vue +69 -0
  62. package/dist/runtime/file-preview/components/shell/file-preview-thumb.vue.d.ts +14 -0
  63. package/dist/runtime/file-preview/components/shell/file-preview-tools.d.vue.ts +13 -0
  64. package/dist/runtime/file-preview/components/shell/file-preview-tools.vue +10 -0
  65. package/dist/runtime/file-preview/components/shell/file-preview-tools.vue.d.ts +13 -0
  66. package/dist/runtime/file-preview/composables/use-file-preview-api.d.ts +21 -0
  67. package/dist/runtime/file-preview/composables/use-file-preview-api.js +83 -0
  68. package/dist/runtime/file-preview/composables/use-file-preview-shell.d.ts +13 -0
  69. package/dist/runtime/file-preview/composables/use-file-preview-shell.js +30 -0
  70. package/dist/runtime/file-preview/composables/use-file-preview-source.d.ts +17 -0
  71. package/dist/runtime/file-preview/composables/use-file-preview-source.js +51 -0
  72. package/dist/runtime/file-preview/composables/use-file-preview-text.d.ts +14 -0
  73. package/dist/runtime/file-preview/composables/use-file-preview-text.js +79 -0
  74. package/dist/runtime/file-preview/index.d.ts +5 -0
  75. package/dist/runtime/file-preview/index.js +14 -0
  76. package/dist/runtime/file-preview/plugins/file-preview-api.d.ts +11 -0
  77. package/dist/runtime/file-preview/plugins/file-preview-api.js +10 -0
  78. package/dist/runtime/file-preview/types/api.d.ts +74 -0
  79. package/dist/runtime/file-preview/types/api.js +0 -0
  80. package/dist/runtime/file-preview/types/file.d.ts +77 -0
  81. package/dist/runtime/file-preview/types/file.js +0 -0
  82. package/dist/runtime/file-preview/types/index.d.ts +4 -0
  83. package/dist/runtime/file-preview/types/index.js +0 -0
  84. package/dist/runtime/file-preview/types/renderer.d.ts +49 -0
  85. package/dist/runtime/file-preview/types/renderer.js +0 -0
  86. package/dist/runtime/file-preview/types/shell.d.ts +12 -0
  87. package/dist/runtime/file-preview/types/shell.js +0 -0
  88. package/dist/runtime/file-preview/utils/container.d.ts +4 -0
  89. package/dist/runtime/file-preview/utils/container.js +10 -0
  90. package/dist/runtime/file-preview/utils/csv.d.ts +17 -0
  91. package/dist/runtime/file-preview/utils/csv.js +53 -0
  92. package/dist/runtime/file-preview/utils/download.d.ts +8 -0
  93. package/dist/runtime/file-preview/utils/download.js +40 -0
  94. package/dist/runtime/file-preview/utils/files.d.ts +7 -0
  95. package/dist/runtime/file-preview/utils/files.js +53 -0
  96. package/dist/runtime/file-preview/utils/format.d.ts +13 -0
  97. package/dist/runtime/file-preview/utils/format.js +40 -0
  98. package/dist/runtime/file-preview/utils/instance.d.ts +9 -0
  99. package/dist/runtime/file-preview/utils/instance.js +57 -0
  100. package/dist/runtime/file-preview/utils/renderers.d.ts +36 -0
  101. package/dist/runtime/file-preview/utils/renderers.js +247 -0
  102. package/dist/runtime/form/components/page/form-page-header.d.vue.ts +3 -1
  103. package/dist/runtime/form/components/page/form-page-header.vue +4 -4
  104. package/dist/runtime/form/components/page/form-page-header.vue.d.ts +3 -1
  105. package/dist/runtime/form/components/page/form-page-navigation.vue +2 -1
  106. package/dist/runtime/form/components/page/form-page-section.vue +15 -7
  107. package/dist/runtime/form/components/page/form-page.vue +0 -1
  108. package/dist/runtime/form/components/utils/form-file-preview.vue +5 -38
  109. package/dist/runtime/form/composables/use-field-control.d.ts +1 -1
  110. package/dist/runtime/form/composables/use-form-page.js +3 -1
  111. package/dist/runtime/form/composables/use-form-runtime.js +3 -0
  112. package/dist/runtime/form/composables/use-form-upload-registry.d.ts +2 -0
  113. package/dist/runtime/form/composables/use-form-upload-registry.js +11 -6
  114. package/dist/runtime/form/composables/use-form-validation.js +5 -1
  115. package/dist/runtime/form/fields/array-list/use-array-items.d.ts +1 -1
  116. package/dist/runtime/form/fields/array-table/array-table-cell.d.vue.ts +15 -0
  117. package/dist/runtime/form/fields/array-table/array-table-cell.vue +58 -0
  118. package/dist/runtime/form/fields/array-table/array-table-cell.vue.d.ts +15 -0
  119. package/dist/runtime/form/fields/array-table/component.vue +42 -26
  120. package/dist/runtime/form/fields/date/types.d.ts +6 -1
  121. package/dist/runtime/form/fields/date-family/component.vue +7 -1
  122. package/dist/runtime/form/fields/date-family/utils.d.ts +8 -1
  123. package/dist/runtime/form/fields/date-family/utils.js +10 -2
  124. package/dist/runtime/form/fields/hidden/types.d.ts +8 -1
  125. package/dist/runtime/form/fields/upload/component.vue +55 -176
  126. package/dist/runtime/form/fields/upload/types.d.ts +68 -3
  127. package/dist/runtime/form/fields/upload/upload-item.d.vue.ts +24 -0
  128. package/dist/runtime/form/fields/upload/upload-item.vue +158 -0
  129. package/dist/runtime/form/fields/upload/upload-item.vue.d.ts +24 -0
  130. package/dist/runtime/form/fields/upload/use-upload-items.d.ts +44 -0
  131. package/dist/runtime/form/fields/upload/use-upload-items.js +317 -0
  132. package/dist/runtime/form/types/callbacks.d.ts +8 -2
  133. package/dist/runtime/form/types/controller.d.ts +6 -3
  134. package/dist/runtime/form/types/field-base.d.ts +5 -5
  135. package/dist/runtime/form/types/field-output-utils.d.ts +12 -1
  136. package/dist/runtime/form/types/field-output.d.ts +1 -1
  137. package/dist/runtime/form/types/field.d.ts +3 -2
  138. package/dist/runtime/form/types/form-api.d.ts +4 -2
  139. package/dist/runtime/form/types/options-runtime.d.ts +8 -4
  140. package/dist/runtime/form/types/options.d.ts +11 -11
  141. package/dist/runtime/form/types/output.d.ts +33 -10
  142. package/dist/runtime/form/types/page.d.ts +7 -3
  143. package/dist/runtime/form/types/transform.d.ts +5 -2
  144. package/dist/runtime/form/types/ui.d.ts +7 -3
  145. package/dist/runtime/form/types/upload-runtime.d.ts +4 -0
  146. package/dist/runtime/form/utils/page.js +24 -5
  147. package/dist/runtime/form/utils/state.js +14 -11
  148. package/dist/runtime/i18n/locales/en.js +104 -1
  149. package/dist/runtime/i18n/locales/fr.js +104 -1
  150. package/dist/runtime/i18n/types.d.ts +121 -0
  151. package/dist/runtime/query-state/composables.d.ts +2 -2
  152. package/dist/runtime/shared/styles/tokens.css +1 -1
  153. package/dist/runtime/shared/types/utils.d.ts +12 -4
  154. package/dist/runtime/shared/utils/file.d.ts +11 -0
  155. package/dist/runtime/shared/utils/file.js +50 -0
  156. package/dist/runtime/table/components/table/table-renderer.vue +23 -3
  157. package/dist/runtime/table/components/table/table-skeleton-cell.js +2 -2
  158. package/dist/runtime/table/components/utils/search-query-input.d.vue.ts +5 -1
  159. package/dist/runtime/table/components/utils/search-query-input.vue +17 -3
  160. package/dist/runtime/table/components/utils/search-query-input.vue.d.ts +5 -1
  161. package/package.json +56 -29
  162. package/dist/runtime/form/components/renderer/form-field-error.vue +0 -16
package/dist/module.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "configKey": "nuxtUiTools",
6
6
  "docs": "https://ui.nuxt.com/docs/getting-started/installation/nuxt",
7
7
  "name": "nuxt-ui-tools",
8
- "version": "1.7.0",
8
+ "version": "1.8.1",
9
9
  "builder": {
10
10
  "@nuxt/module-builder": "1.0.3",
11
11
  "unbuild": "unknown"
package/dist/module.mjs CHANGED
@@ -81,6 +81,17 @@ function getPublicComponents(runtimeDir, options) {
81
81
  global: options.global,
82
82
  name: `${prefix}Dashboard${part}`
83
83
  })),
84
+ // File preview
85
+ {
86
+ filePath: `${runtimeDir}/file-preview/components/provider/file-preview-provider.vue`,
87
+ global: options.global,
88
+ name: `${prefix}FilePreviewProvider`
89
+ },
90
+ {
91
+ filePath: `${runtimeDir}/file-preview/components/shell/file-preview-tools.vue`,
92
+ global: options.global,
93
+ name: `${prefix}FilePreviewTools`
94
+ },
84
95
  // Form
85
96
  {
86
97
  filePath: `${runtimeDir}/form/components/root/form.vue`,
@@ -173,6 +184,11 @@ function setupImports(runtimeDir) {
173
184
  { from: "dashboard", name: "useDashboardView" },
174
185
  { from: "dashboard", name: "resolveDashboardComparisonRange" }
175
186
  ]),
187
+ // File preview
188
+ ...withRuntime(runtimeDir, [
189
+ { from: "file-preview", name: "defineFilePreviewRenderer" },
190
+ { from: "file-preview", name: "useFilePreview" }
191
+ ]),
176
192
  // Form
177
193
  ...withRuntime(runtimeDir, [
178
194
  { from: "form", name: "defineFormField" },
@@ -355,6 +371,7 @@ const viewportDefaults = {
355
371
  };
356
372
  const publicRuntimeDomains = [
357
373
  "dashboard",
374
+ "file-preview",
358
375
  "form",
359
376
  "i18n",
360
377
  "query-prefetch",
@@ -425,6 +442,7 @@ const module$1 = defineNuxtModule({
425
442
  setupComponents(resolve("./runtime"), options);
426
443
  addPlugin(resolve("./runtime/query-prefetch/plugins/link-prefetch.client"));
427
444
  addPlugin(resolve("./runtime/form/plugins/form-api"));
445
+ addPlugin(resolve("./runtime/file-preview/plugins/file-preview-api"));
428
446
  addVitePlugin({
429
447
  enforce: "pre",
430
448
  name: "nuxt-ui-tools:query-prefetch-macro",
@@ -0,0 +1,7 @@
1
+ import type { FilePreviewInstance } from '../../types/index.js';
2
+ type __VLS_Props = {
3
+ instance: FilePreviewInstance;
4
+ };
5
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
+ declare const _default: typeof __VLS_export;
7
+ export default _default;
@@ -0,0 +1,147 @@
1
+ <script setup>
2
+ import UDrawer from "@nuxt/ui/components/Drawer.vue";
3
+ import UModal from "@nuxt/ui/components/Modal.vue";
4
+ import { useLocalStorage } from "@vueuse/core";
5
+ import { computed, ref } from "vue";
6
+ import { useUiToolsLocale } from "../../../i18n/use-locale";
7
+ import {
8
+ getResponsiveValue,
9
+ useResponsiveValue
10
+ } from "../../../shared/composables/use-responsive-value";
11
+ import { useFilePreview } from "../../composables/use-file-preview-api";
12
+ import { largestFilePreviewContainer, normalizeFilePreviewContainer } from "../../utils/container";
13
+ import { findFilePreviewRenderer } from "../../utils/renderers";
14
+ import FilePreviewShell from "../shell/file-preview-shell.vue";
15
+ const DRAWER_MIN_WIDTH = 420;
16
+ const DRAWER_GUTTER = 56;
17
+ const props = defineProps({
18
+ instance: { type: Object, required: true }
19
+ });
20
+ const { t } = useUiToolsLocale();
21
+ const api = useFilePreview();
22
+ const expanded = ref(false);
23
+ const drawerWidth = useLocalStorage("nut-file-preview-drawer-width", 940);
24
+ const width = useResponsiveValue("narrow md:wide");
25
+ const narrow = computed(() => width.value === "narrow");
26
+ const renderers = computed(
27
+ () => props.instance.files.value.map(
28
+ (item) => findFilePreviewRenderer((item.rendition ?? item).kind, api.renderers.value)
29
+ )
30
+ );
31
+ const base = computed(() => {
32
+ const explicit = props.instance.options.mode;
33
+ const modes = explicit ? [explicit] : renderers.value.map((renderer) => renderer.mode ?? "modal");
34
+ return largestFilePreviewContainer(
35
+ modes.map((mode) => normalizeFilePreviewContainer(getResponsiveValue(mode, "string")))
36
+ );
37
+ });
38
+ const container = computed(() => expanded.value ? "fullscreen" : base.value);
39
+ const compact = computed(
40
+ () => base.value === "modal" && renderers.value.every((renderer) => renderer.compact === true)
41
+ );
42
+ const canExpand = computed(() => !narrow.value && (base.value !== "fullscreen" || expanded.value));
43
+ const title = computed(() => {
44
+ const item = props.instance.files.value[props.instance.index.value];
45
+ return item?.name || t("filePreview.untitled");
46
+ });
47
+ const drawerContent = computed(() => ({
48
+ disableOutsidePointerEvents: void 0,
49
+ style: {
50
+ width: expanded.value ? "100vw" : `min(${Math.max(DRAWER_MIN_WIDTH, drawerWidth.value)}px, calc(100vw - ${DRAWER_GUTTER}px))`
51
+ }
52
+ }));
53
+ function close() {
54
+ props.instance.handle.close();
55
+ }
56
+ function handleOpen(open) {
57
+ if (!open) close();
58
+ }
59
+ function handleDrawerAnimation(open) {
60
+ if (!open) props.instance.dispose();
61
+ }
62
+ function resize(event) {
63
+ if (expanded.value || !(event.currentTarget instanceof HTMLElement)) return;
64
+ const handle = event.currentTarget;
65
+ handle.setPointerCapture(event.pointerId);
66
+ const move = (moved) => {
67
+ drawerWidth.value = Math.round(
68
+ Math.min(
69
+ window.innerWidth - DRAWER_GUTTER,
70
+ Math.max(DRAWER_MIN_WIDTH, window.innerWidth - moved.clientX)
71
+ )
72
+ );
73
+ };
74
+ const stop = () => {
75
+ handle.removeEventListener("pointermove", move);
76
+ handle.removeEventListener("pointerup", stop);
77
+ handle.removeEventListener("pointercancel", stop);
78
+ };
79
+ handle.addEventListener("pointermove", move);
80
+ handle.addEventListener("pointerup", stop);
81
+ handle.addEventListener("pointercancel", stop);
82
+ }
83
+ </script>
84
+
85
+ <template>
86
+ <UDrawer
87
+ v-if="base === 'drawer'"
88
+ :open="instance.open.value"
89
+ :title="title"
90
+ :description="title"
91
+ direction="right"
92
+ :handle="false"
93
+ :content="drawerContent"
94
+ :ui="{
95
+ overlay: 'bg-(--nut-fp-veil)',
96
+ content: 'h-dvh max-w-none overflow-hidden rounded-none border-s border-default p-0',
97
+ container: 'size-full p-0'
98
+ }"
99
+ @update:open="handleOpen"
100
+ @animation-end="handleDrawerAnimation"
101
+ >
102
+ <template #content>
103
+ <div
104
+ v-if="!expanded"
105
+ class="absolute inset-y-0 start-0 z-30 w-1.5 cursor-col-resize touch-none transition-colors hover:bg-primary/40"
106
+ aria-hidden="true"
107
+ data-file-preview-resize=""
108
+ @pointerdown="resize"
109
+ />
110
+ <FilePreviewShell
111
+ :instance="instance"
112
+ :container="container"
113
+ :narrow="narrow"
114
+ :can-expand="canExpand"
115
+ :expanded="expanded"
116
+ @close="close"
117
+ @expand="expanded = !expanded"
118
+ />
119
+ </template>
120
+ </UDrawer>
121
+
122
+ <UModal
123
+ v-else
124
+ :open="instance.open.value"
125
+ :title="title"
126
+ :description="title"
127
+ :fullscreen="container === 'fullscreen'"
128
+ :ui="{
129
+ overlay: 'bg-(--nut-fp-veil)',
130
+ content: container === 'fullscreen' ? 'h-dvh max-w-none overflow-hidden rounded-none p-0' : compact ? 'h-auto max-h-[calc(100dvh-32px)] w-[min(468px,calc(100%-32px))] max-w-none overflow-hidden rounded-xl p-0' : 'h-[min(780px,calc(100dvh-48px))] w-[min(1080px,calc(100%-48px))] max-w-none overflow-hidden rounded-xl p-0'
131
+ }"
132
+ @update:open="handleOpen"
133
+ @after:leave="instance.dispose()"
134
+ >
135
+ <template #content>
136
+ <FilePreviewShell
137
+ :instance="instance"
138
+ :container="container"
139
+ :narrow="narrow"
140
+ :can-expand="canExpand"
141
+ :expanded="expanded"
142
+ @close="close"
143
+ @expand="expanded = !expanded"
144
+ />
145
+ </template>
146
+ </UModal>
147
+ </template>
@@ -0,0 +1,7 @@
1
+ import type { FilePreviewInstance } from '../../types/index.js';
2
+ type __VLS_Props = {
3
+ instance: FilePreviewInstance;
4
+ };
5
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
+ declare const _default: typeof __VLS_export;
7
+ export default _default;
@@ -0,0 +1,21 @@
1
+ import type { FilePreviewMarkdownRenderer } from '../../types/index.js';
2
+ type __VLS_Props = {
3
+ /**
4
+ * Renders markdown files as HTML in the markdown preview. It must return sanitized HTML. Without
5
+ * it, markdown files show their source.
6
+ */
7
+ markdown?: FilePreviewMarkdownRenderer | null;
8
+ };
9
+ declare var __VLS_1: {};
10
+ type __VLS_Slots = {} & {
11
+ default?: (props: typeof __VLS_1) => any;
12
+ };
13
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
14
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
15
+ declare const _default: typeof __VLS_export;
16
+ export default _default;
17
+ type __VLS_WithSlots<T, S> = T & {
18
+ new (): {
19
+ $slots: S;
20
+ };
21
+ };
@@ -0,0 +1,23 @@
1
+ <script setup>
2
+ import { onBeforeUnmount, onMounted, provide } from "vue";
3
+ import { provideFilePreview } from "../../composables/use-file-preview-api";
4
+ import { filePreviewMarkdownKey } from "../../composables/use-file-preview-shell";
5
+ import FilePreviewHost from "./file-preview-host.vue";
6
+ const { markdown = null } = defineProps({
7
+ markdown: { type: [Function, null], required: false }
8
+ });
9
+ const filePreview = provideFilePreview();
10
+ const { instances } = filePreview;
11
+ let detach = null;
12
+ provide(filePreviewMarkdownKey, markdown);
13
+ onMounted(() => {
14
+ detach = filePreview.attach();
15
+ });
16
+ onBeforeUnmount(() => detach?.());
17
+ </script>
18
+
19
+ <template>
20
+ <slot />
21
+
22
+ <FilePreviewHost v-for="instance in instances" :key="instance.id" :instance="instance" />
23
+ </template>
@@ -0,0 +1,21 @@
1
+ import type { FilePreviewMarkdownRenderer } from '../../types/index.js';
2
+ type __VLS_Props = {
3
+ /**
4
+ * Renders markdown files as HTML in the markdown preview. It must return sanitized HTML. Without
5
+ * it, markdown files show their source.
6
+ */
7
+ markdown?: FilePreviewMarkdownRenderer | null;
8
+ };
9
+ declare var __VLS_1: {};
10
+ type __VLS_Slots = {} & {
11
+ default?: (props: typeof __VLS_1) => any;
12
+ };
13
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
14
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
15
+ declare const _default: typeof __VLS_export;
16
+ export default _default;
17
+ type __VLS_WithSlots<T, S> = T & {
18
+ new (): {
19
+ $slots: S;
20
+ };
21
+ };
@@ -0,0 +1,10 @@
1
+ import type { FilePreviewRendererProps } from '../../types/index.js';
2
+ declare const __VLS_export: import("vue").DefineComponent<FilePreviewRendererProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
3
+ ready: (details?: readonly import("../../types/index.js").FilePreviewDetail[] | undefined) => any;
4
+ error: (error: import("../../types/index.js").FilePreviewRendererError) => any;
5
+ }, string, import("vue").PublicProps, Readonly<FilePreviewRendererProps> & Readonly<{
6
+ onReady?: ((details?: readonly import("../../types/index.js").FilePreviewDetail[] | undefined) => any) | undefined;
7
+ onError?: ((error: import("../../types/index.js").FilePreviewRendererError) => any) | undefined;
8
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
+ declare const _default: typeof __VLS_export;
10
+ export default _default;
@@ -0,0 +1,83 @@
1
+ <script setup>
2
+ import UIcon from "@nuxt/ui/components/Icon.vue";
3
+ import { useMediaControls } from "@vueuse/core";
4
+ import { computed, useTemplateRef } from "vue";
5
+ import { useUiToolsLocale } from "../../../i18n/use-locale";
6
+ import { onFilePreviewKey } from "../../composables/use-file-preview-shell";
7
+ import { formatFilePreviewDuration } from "../../utils/format";
8
+ import MediaControls from "./media-controls.vue";
9
+ const BARS = Array.from(
10
+ { length: 28 },
11
+ (_, index) => 18 + Math.abs(Math.sin(index * 1.3) * Math.cos(index * 0.4)) * 62
12
+ );
13
+ defineProps({
14
+ file: { type: Object, required: true },
15
+ url: { type: String, required: true },
16
+ blob: { type: null, required: true },
17
+ container: { type: String, required: true }
18
+ });
19
+ const emit = defineEmits(["ready", "error"]);
20
+ const { t } = useUiToolsLocale();
21
+ const audio = useTemplateRef("audio");
22
+ const controls = useMediaControls(audio);
23
+ const duration = computed(
24
+ () => controls.duration.value > 0 ? formatFilePreviewDuration(controls.duration.value) : null
25
+ );
26
+ function handleMetadata() {
27
+ const element = audio.value;
28
+ if (!element) return;
29
+ emit("ready", [
30
+ { label: t("filePreview.fields.duration"), value: formatFilePreviewDuration(element.duration) }
31
+ ]);
32
+ }
33
+ onFilePreviewKey([" ", "k", "m"], (event) => {
34
+ if (event.key === "m") controls.muted.value = !controls.muted.value;
35
+ else controls.playing.value = !controls.playing.value;
36
+ });
37
+ </script>
38
+
39
+ <template>
40
+ <div class="flex size-full items-center justify-center p-5" data-file-preview-audio="">
41
+ <div class="flex w-full max-w-md flex-col gap-4">
42
+ <div
43
+ class="relative flex h-36 items-center justify-center gap-[3px] overflow-hidden rounded-xl bg-linear-135 from-[#3b2f4a] via-[#b8466e] to-primary px-6"
44
+ aria-hidden="true"
45
+ >
46
+ <img
47
+ v-if="file.file.poster"
48
+ :src="file.file.poster"
49
+ alt=""
50
+ class="absolute inset-0 size-full object-cover"
51
+ />
52
+ <template v-else>
53
+ <i
54
+ v-for="(height, position) in BARS"
55
+ :key="position"
56
+ :class="[
57
+ 'block w-1 rounded-full bg-white/80',
58
+ controls.playing.value ? 'nut-fp-equalizer' : ''
59
+ ]"
60
+ :style="{ height: `${height}px`, animationDelay: `${position % 7 * -0.13}s` }"
61
+ />
62
+ <UIcon
63
+ name="i-lucide-audio-lines"
64
+ class="absolute right-3 bottom-3 size-4 text-white/70"
65
+ />
66
+ </template>
67
+ </div>
68
+ <div class="min-w-0">
69
+ <p class="m-0 truncate text-sm font-semibold text-highlighted">{{ file.name }}</p>
70
+ <p v-if="duration" class="m-0 text-xs text-muted tabular-nums">{{ duration }}</p>
71
+ </div>
72
+ <audio
73
+ ref="audio"
74
+ :src="url"
75
+ preload="metadata"
76
+ class="hidden"
77
+ @loadedmetadata="handleMetadata"
78
+ @error="emit('error', { reason: 'decode' })"
79
+ />
80
+ <MediaControls :controls="controls" variant="audio" compact />
81
+ </div>
82
+ </div>
83
+ </template>
@@ -0,0 +1,10 @@
1
+ import type { FilePreviewRendererProps } from '../../types/index.js';
2
+ declare const __VLS_export: import("vue").DefineComponent<FilePreviewRendererProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
3
+ ready: (details?: readonly import("../../types/index.js").FilePreviewDetail[] | undefined) => any;
4
+ error: (error: import("../../types/index.js").FilePreviewRendererError) => any;
5
+ }, string, import("vue").PublicProps, Readonly<FilePreviewRendererProps> & Readonly<{
6
+ onReady?: ((details?: readonly import("../../types/index.js").FilePreviewDetail[] | undefined) => any) | undefined;
7
+ onError?: ((error: import("../../types/index.js").FilePreviewRendererError) => any) | undefined;
8
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
+ declare const _default: typeof __VLS_export;
10
+ export default _default;
@@ -0,0 +1,10 @@
1
+ import type { FilePreviewRendererProps } from '../../types/index.js';
2
+ declare const __VLS_export: import("vue").DefineComponent<FilePreviewRendererProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
3
+ ready: (details?: readonly import("../../types/index.js").FilePreviewDetail[] | undefined) => any;
4
+ error: (error: import("../../types/index.js").FilePreviewRendererError) => any;
5
+ }, string, import("vue").PublicProps, Readonly<FilePreviewRendererProps> & Readonly<{
6
+ onReady?: ((details?: readonly import("../../types/index.js").FilePreviewDetail[] | undefined) => any) | undefined;
7
+ onError?: ((error: import("../../types/index.js").FilePreviewRendererError) => any) | undefined;
8
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
+ declare const _default: typeof __VLS_export;
10
+ export default _default;
@@ -0,0 +1,116 @@
1
+ <script setup>
2
+ import { computed, watch } from "vue";
3
+ import { useUiToolsLocale } from "../../../i18n/use-locale";
4
+ import { useFilePreviewText } from "../../composables/use-file-preview-text";
5
+ import { parseCsv } from "../../utils/csv";
6
+ import FilePreviewTextLoading from "./file-preview-text-loading.vue";
7
+ const MAX_ROWS = 1e3;
8
+ const NUMBER = /^-?[\d\s  .,]+%?$/u;
9
+ const props = defineProps({
10
+ file: { type: Object, required: true },
11
+ url: { type: String, required: true },
12
+ blob: { type: null, required: true },
13
+ container: { type: String, required: true }
14
+ });
15
+ const emit = defineEmits(["ready", "error"]);
16
+ const { t } = useUiToolsLocale();
17
+ const content = useFilePreviewText(props);
18
+ const table = computed(() => {
19
+ const parsed = parseCsv(content.text.value, {
20
+ delimiter: props.file.extension === "tsv" ? " " : void 0,
21
+ maxRows: MAX_ROWS + 1
22
+ });
23
+ const [head = [], ...rows] = parsed.rows;
24
+ const width = Math.max(head.length, ...rows.map((row) => row.length));
25
+ const columns = Array.from({ length: width }, (_, index) => head[index] ?? "");
26
+ const numeric = columns.map((_, index) => {
27
+ const values = rows.map((row) => (row[index] ?? "").trim()).filter(Boolean);
28
+ return values.length > 0 && values.every((value) => NUMBER.test(value));
29
+ });
30
+ return { columns, complete: parsed.complete, delimiter: parsed.delimiter, numeric, rows };
31
+ });
32
+ const facts = computed(
33
+ () => [
34
+ t("filePreview.csv.rows", { count: table.value.rows.length.toLocaleString() }),
35
+ t("filePreview.csv.columns", { count: table.value.columns.length }),
36
+ t("filePreview.csv.delimiter", {
37
+ value: table.value.delimiter === " " ? t("filePreview.csv.tab") : table.value.delimiter
38
+ }),
39
+ content.notice.value
40
+ ].filter((fact) => fact !== null)
41
+ );
42
+ watch(
43
+ content.status,
44
+ (status) => {
45
+ if (status === "error")
46
+ emit("error", { message: content.error.value?.message, reason: "source" });
47
+ if (status !== "ready") return;
48
+ emit("ready", [
49
+ { label: t("filePreview.fields.rows"), value: table.value.rows.length.toLocaleString() },
50
+ { label: t("filePreview.fields.columns"), value: String(table.value.columns.length) }
51
+ ]);
52
+ },
53
+ { immediate: true }
54
+ );
55
+ </script>
56
+
57
+ <template>
58
+ <div
59
+ v-if="content.status.value === 'ready'"
60
+ class="absolute inset-0 flex flex-col bg-default"
61
+ data-file-preview-csv=""
62
+ >
63
+ <div class="min-h-0 flex-1 overflow-auto">
64
+ <table class="min-w-full border-separate border-spacing-0 text-[12.5px] tabular-nums">
65
+ <thead>
66
+ <tr>
67
+ <th
68
+ class="sticky top-0 left-0 z-20 min-w-10 border-e border-b border-default bg-elevated px-3 py-1.5 text-end font-normal text-dimmed"
69
+ scope="col"
70
+ >
71
+ #
72
+ </th>
73
+ <th
74
+ v-for="(column, index) in table.columns"
75
+ :key="index"
76
+ scope="col"
77
+ :class="[
78
+ 'sticky top-0 z-10 max-w-72 truncate border-e border-b border-default bg-elevated px-3 py-1.5 font-semibold whitespace-nowrap text-toned',
79
+ table.numeric[index] ? 'text-end' : 'text-start'
80
+ ]"
81
+ >
82
+ {{ column }}
83
+ </th>
84
+ </tr>
85
+ </thead>
86
+ <tbody>
87
+ <tr v-for="(row, rowIndex) in table.rows" :key="rowIndex" class="hover:bg-elevated/60">
88
+ <td
89
+ class="sticky left-0 z-10 border-e border-b border-(--ui-border-muted) bg-elevated px-3 py-1.5 text-end text-dimmed"
90
+ >
91
+ {{ rowIndex + 1 }}
92
+ </td>
93
+ <td
94
+ v-for="(_, index) in table.columns"
95
+ :key="index"
96
+ :title="row[index]"
97
+ :class="[
98
+ 'max-w-72 truncate border-e border-b border-(--ui-border-muted) px-3 py-1.5 whitespace-nowrap text-default',
99
+ table.numeric[index] ? 'text-end' : 'text-start'
100
+ ]"
101
+ >
102
+ {{ row[index] ?? "" }}
103
+ </td>
104
+ </tr>
105
+ </tbody>
106
+ </table>
107
+ </div>
108
+ <div
109
+ class="flex shrink-0 flex-wrap gap-x-3.5 gap-y-1 border-t border-default bg-elevated px-3.5 py-1.5 text-[11.5px] text-muted tabular-nums"
110
+ data-file-preview-facts=""
111
+ >
112
+ <span v-for="fact in facts" :key="fact">{{ fact }}</span>
113
+ </div>
114
+ </div>
115
+ <FilePreviewTextLoading v-else />
116
+ </template>
@@ -0,0 +1,10 @@
1
+ import type { FilePreviewRendererProps } from '../../types/index.js';
2
+ declare const __VLS_export: import("vue").DefineComponent<FilePreviewRendererProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
3
+ ready: (details?: readonly import("../../types/index.js").FilePreviewDetail[] | undefined) => any;
4
+ error: (error: import("../../types/index.js").FilePreviewRendererError) => any;
5
+ }, string, import("vue").PublicProps, Readonly<FilePreviewRendererProps> & Readonly<{
6
+ onReady?: ((details?: readonly import("../../types/index.js").FilePreviewDetail[] | undefined) => any) | undefined;
7
+ onError?: ((error: import("../../types/index.js").FilePreviewRendererError) => any) | undefined;
8
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
+ declare const _default: typeof __VLS_export;
10
+ export default _default;
@@ -0,0 +1,10 @@
1
+ import type { FilePreviewRendererProps } from '../../types/index.js';
2
+ declare const __VLS_export: import("vue").DefineComponent<FilePreviewRendererProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
3
+ ready: (details?: readonly import("../../types/index.js").FilePreviewDetail[] | undefined) => any;
4
+ error: (error: import("../../types/index.js").FilePreviewRendererError) => any;
5
+ }, string, import("vue").PublicProps, Readonly<FilePreviewRendererProps> & Readonly<{
6
+ onReady?: ((details?: readonly import("../../types/index.js").FilePreviewDetail[] | undefined) => any) | undefined;
7
+ onError?: ((error: import("../../types/index.js").FilePreviewRendererError) => any) | undefined;
8
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
+ declare const _default: typeof __VLS_export;
10
+ export default _default;
@@ -0,0 +1,41 @@
1
+ <script setup>
2
+ import UButton from "@nuxt/ui/components/Button.vue";
3
+ import { computed, onMounted } from "vue";
4
+ import { useUiToolsLocale } from "../../../i18n/use-locale";
5
+ import { useFilePreview } from "../../composables/use-file-preview-api";
6
+ import { downloadFilePreviewItem } from "../../utils/download";
7
+ import { findFilePreviewRenderer } from "../../utils/renderers";
8
+ import FilePreviewMessage from "../shell/file-preview-message.vue";
9
+ const props = defineProps({
10
+ file: { type: Object, required: true },
11
+ url: { type: String, required: true },
12
+ blob: { type: null, required: true },
13
+ container: { type: String, required: true }
14
+ });
15
+ const emit = defineEmits(["ready", "error"]);
16
+ const { t } = useUiToolsLocale();
17
+ const api = useFilePreview();
18
+ const icon = computed(() => findFilePreviewRenderer(props.file.kind, api.renderers.value).icon);
19
+ const extension = computed(() => props.file.extension?.toUpperCase() ?? null);
20
+ onMounted(() => emit("ready"));
21
+ </script>
22
+
23
+ <template>
24
+ <FilePreviewMessage
25
+ :icon="icon"
26
+ :badge="extension"
27
+ :title="t('filePreview.fallback.title')"
28
+ :description="
29
+ extension ? t('filePreview.fallback.description', { extension }) : t('filePreview.fallback.descriptionUnnamed')
30
+ "
31
+ data-file-preview-fallback=""
32
+ >
33
+ <UButton
34
+ v-if="file.file.download !== false"
35
+ icon="i-lucide-download"
36
+ :label="t('filePreview.download')"
37
+ data-file-preview-download=""
38
+ @click="downloadFilePreviewItem(file)"
39
+ />
40
+ </FilePreviewMessage>
41
+ </template>
@@ -0,0 +1,10 @@
1
+ import type { FilePreviewRendererProps } from '../../types/index.js';
2
+ declare const __VLS_export: import("vue").DefineComponent<FilePreviewRendererProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
3
+ ready: (details?: readonly import("../../types/index.js").FilePreviewDetail[] | undefined) => any;
4
+ error: (error: import("../../types/index.js").FilePreviewRendererError) => any;
5
+ }, string, import("vue").PublicProps, Readonly<FilePreviewRendererProps> & Readonly<{
6
+ onReady?: ((details?: readonly import("../../types/index.js").FilePreviewDetail[] | undefined) => any) | undefined;
7
+ onError?: ((error: import("../../types/index.js").FilePreviewRendererError) => any) | undefined;
8
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
+ declare const _default: typeof __VLS_export;
10
+ export default _default;
@@ -0,0 +1,9 @@
1
+ type __VLS_Props = {
2
+ text: string;
3
+ json: boolean;
4
+ facts: readonly string[];
5
+ tools?: boolean;
6
+ };
7
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
8
+ declare const _default: typeof __VLS_export;
9
+ export default _default;