nuxt-ui-tools 1.6.5 → 1.8.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 (185) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +20 -0
  3. package/dist/runtime/dashboard/components/block/dashboard-skeleton.vue +12 -0
  4. package/dist/runtime/dashboard/components/dashboard-details.d.vue.ts +38 -0
  5. package/dist/runtime/dashboard/components/dashboard-details.vue +194 -0
  6. package/dist/runtime/dashboard/components/dashboard-details.vue.d.ts +38 -0
  7. package/dist/runtime/dashboard/components/dashboard-page.d.vue.ts +8 -0
  8. package/dist/runtime/dashboard/components/dashboard-page.vue +20 -3
  9. package/dist/runtime/dashboard/components/dashboard-page.vue.d.ts +8 -0
  10. package/dist/runtime/dashboard/components/dashboard-view-tabs.d.vue.ts +2 -5
  11. package/dist/runtime/dashboard/components/dashboard-view-tabs.vue +5 -1
  12. package/dist/runtime/dashboard/components/dashboard-view-tabs.vue.d.ts +2 -5
  13. package/dist/runtime/dashboard/composables/use-dashboard-api.js +4 -1
  14. package/dist/runtime/dashboard/composables/use-dashboard-views.d.ts +4 -1
  15. package/dist/runtime/dashboard/composables/use-dashboard-views.js +15 -1
  16. package/dist/runtime/dashboard/schema/index.d.ts +15 -1
  17. package/dist/runtime/dashboard/types/blocks.d.ts +27 -1
  18. package/dist/runtime/dashboard/types/runtime.d.ts +3 -0
  19. package/dist/runtime/dashboard/types/schema.d.ts +23 -4
  20. package/dist/runtime/dashboard/types/ui.d.ts +27 -0
  21. package/dist/runtime/dashboard/utils/schema.js +1 -0
  22. package/dist/runtime/file-preview/components/provider/file-preview-host.d.vue.ts +7 -0
  23. package/dist/runtime/file-preview/components/provider/file-preview-host.vue +147 -0
  24. package/dist/runtime/file-preview/components/provider/file-preview-host.vue.d.ts +7 -0
  25. package/dist/runtime/file-preview/components/provider/file-preview-provider.d.vue.ts +21 -0
  26. package/dist/runtime/file-preview/components/provider/file-preview-provider.vue +23 -0
  27. package/dist/runtime/file-preview/components/provider/file-preview-provider.vue.d.ts +21 -0
  28. package/dist/runtime/file-preview/components/renderers/audio-renderer.d.vue.ts +10 -0
  29. package/dist/runtime/file-preview/components/renderers/audio-renderer.vue +83 -0
  30. package/dist/runtime/file-preview/components/renderers/audio-renderer.vue.d.ts +10 -0
  31. package/dist/runtime/file-preview/components/renderers/csv-renderer.d.vue.ts +10 -0
  32. package/dist/runtime/file-preview/components/renderers/csv-renderer.vue +116 -0
  33. package/dist/runtime/file-preview/components/renderers/csv-renderer.vue.d.ts +10 -0
  34. package/dist/runtime/file-preview/components/renderers/fallback-renderer.d.vue.ts +10 -0
  35. package/dist/runtime/file-preview/components/renderers/fallback-renderer.vue +41 -0
  36. package/dist/runtime/file-preview/components/renderers/fallback-renderer.vue.d.ts +10 -0
  37. package/dist/runtime/file-preview/components/renderers/file-preview-code.d.vue.ts +9 -0
  38. package/dist/runtime/file-preview/components/renderers/file-preview-code.vue +83 -0
  39. package/dist/runtime/file-preview/components/renderers/file-preview-code.vue.d.ts +9 -0
  40. package/dist/runtime/file-preview/components/renderers/file-preview-text-loading.d.vue.ts +3 -0
  41. package/dist/runtime/file-preview/components/renderers/file-preview-text-loading.vue +14 -0
  42. package/dist/runtime/file-preview/components/renderers/file-preview-text-loading.vue.d.ts +3 -0
  43. package/dist/runtime/file-preview/components/renderers/image-renderer.d.vue.ts +10 -0
  44. package/dist/runtime/file-preview/components/renderers/image-renderer.vue +182 -0
  45. package/dist/runtime/file-preview/components/renderers/image-renderer.vue.d.ts +10 -0
  46. package/dist/runtime/file-preview/components/renderers/markdown-renderer.d.vue.ts +10 -0
  47. package/dist/runtime/file-preview/components/renderers/markdown-renderer.vue +78 -0
  48. package/dist/runtime/file-preview/components/renderers/markdown-renderer.vue.d.ts +10 -0
  49. package/dist/runtime/file-preview/components/renderers/media-controls.d.vue.ts +10 -0
  50. package/dist/runtime/file-preview/components/renderers/media-controls.vue +145 -0
  51. package/dist/runtime/file-preview/components/renderers/media-controls.vue.d.ts +10 -0
  52. package/dist/runtime/file-preview/components/renderers/pdf-renderer.d.vue.ts +10 -0
  53. package/dist/runtime/file-preview/components/renderers/pdf-renderer.vue +58 -0
  54. package/dist/runtime/file-preview/components/renderers/pdf-renderer.vue.d.ts +10 -0
  55. package/dist/runtime/file-preview/components/renderers/text-renderer.d.vue.ts +10 -0
  56. package/dist/runtime/file-preview/components/renderers/text-renderer.vue +41 -0
  57. package/dist/runtime/file-preview/components/renderers/text-renderer.vue.d.ts +10 -0
  58. package/dist/runtime/file-preview/components/renderers/video-renderer.d.vue.ts +10 -0
  59. package/dist/runtime/file-preview/components/renderers/video-renderer.vue +110 -0
  60. package/dist/runtime/file-preview/components/renderers/video-renderer.vue.d.ts +10 -0
  61. package/dist/runtime/file-preview/components/shell/file-preview-button.d.vue.ts +16 -0
  62. package/dist/runtime/file-preview/components/shell/file-preview-button.vue +40 -0
  63. package/dist/runtime/file-preview/components/shell/file-preview-button.vue.d.ts +16 -0
  64. package/dist/runtime/{form/components/renderer/form-field-error.d.vue.ts → file-preview/components/shell/file-preview-details.d.vue.ts} +4 -2
  65. package/dist/runtime/file-preview/components/shell/file-preview-details.vue +25 -0
  66. package/dist/runtime/{form/components/renderer/form-field-error.vue.d.ts → file-preview/components/shell/file-preview-details.vue.d.ts} +4 -2
  67. package/dist/runtime/file-preview/components/shell/file-preview-header.d.vue.ts +44 -0
  68. package/dist/runtime/file-preview/components/shell/file-preview-header.vue +163 -0
  69. package/dist/runtime/file-preview/components/shell/file-preview-header.vue.d.ts +44 -0
  70. package/dist/runtime/file-preview/components/shell/file-preview-message.d.vue.ts +21 -0
  71. package/dist/runtime/file-preview/components/shell/file-preview-message.vue +49 -0
  72. package/dist/runtime/file-preview/components/shell/file-preview-message.vue.d.ts +21 -0
  73. package/dist/runtime/file-preview/components/shell/file-preview-shell.d.vue.ts +17 -0
  74. package/dist/runtime/file-preview/components/shell/file-preview-shell.vue +280 -0
  75. package/dist/runtime/file-preview/components/shell/file-preview-shell.vue.d.ts +17 -0
  76. package/dist/runtime/file-preview/components/shell/file-preview-stage.d.vue.ts +37 -0
  77. package/dist/runtime/file-preview/components/shell/file-preview-stage.vue +173 -0
  78. package/dist/runtime/file-preview/components/shell/file-preview-stage.vue.d.ts +37 -0
  79. package/dist/runtime/file-preview/components/shell/file-preview-thumb.d.vue.ts +14 -0
  80. package/dist/runtime/file-preview/components/shell/file-preview-thumb.vue +69 -0
  81. package/dist/runtime/file-preview/components/shell/file-preview-thumb.vue.d.ts +14 -0
  82. package/dist/runtime/file-preview/components/shell/file-preview-tools.d.vue.ts +13 -0
  83. package/dist/runtime/file-preview/components/shell/file-preview-tools.vue +10 -0
  84. package/dist/runtime/file-preview/components/shell/file-preview-tools.vue.d.ts +13 -0
  85. package/dist/runtime/file-preview/composables/use-file-preview-api.d.ts +21 -0
  86. package/dist/runtime/file-preview/composables/use-file-preview-api.js +83 -0
  87. package/dist/runtime/file-preview/composables/use-file-preview-shell.d.ts +13 -0
  88. package/dist/runtime/file-preview/composables/use-file-preview-shell.js +30 -0
  89. package/dist/runtime/file-preview/composables/use-file-preview-source.d.ts +17 -0
  90. package/dist/runtime/file-preview/composables/use-file-preview-source.js +51 -0
  91. package/dist/runtime/file-preview/composables/use-file-preview-text.d.ts +14 -0
  92. package/dist/runtime/file-preview/composables/use-file-preview-text.js +79 -0
  93. package/dist/runtime/file-preview/index.d.ts +5 -0
  94. package/dist/runtime/file-preview/index.js +14 -0
  95. package/dist/runtime/file-preview/plugins/file-preview-api.d.ts +11 -0
  96. package/dist/runtime/file-preview/plugins/file-preview-api.js +10 -0
  97. package/dist/runtime/file-preview/types/api.d.ts +74 -0
  98. package/dist/runtime/file-preview/types/api.js +0 -0
  99. package/dist/runtime/file-preview/types/file.d.ts +77 -0
  100. package/dist/runtime/file-preview/types/file.js +0 -0
  101. package/dist/runtime/file-preview/types/index.d.ts +4 -0
  102. package/dist/runtime/file-preview/types/index.js +0 -0
  103. package/dist/runtime/file-preview/types/renderer.d.ts +49 -0
  104. package/dist/runtime/file-preview/types/renderer.js +0 -0
  105. package/dist/runtime/file-preview/types/shell.d.ts +12 -0
  106. package/dist/runtime/file-preview/types/shell.js +0 -0
  107. package/dist/runtime/file-preview/utils/container.d.ts +4 -0
  108. package/dist/runtime/file-preview/utils/container.js +10 -0
  109. package/dist/runtime/file-preview/utils/csv.d.ts +17 -0
  110. package/dist/runtime/file-preview/utils/csv.js +53 -0
  111. package/dist/runtime/file-preview/utils/download.d.ts +8 -0
  112. package/dist/runtime/file-preview/utils/download.js +40 -0
  113. package/dist/runtime/file-preview/utils/files.d.ts +7 -0
  114. package/dist/runtime/file-preview/utils/files.js +53 -0
  115. package/dist/runtime/file-preview/utils/format.d.ts +13 -0
  116. package/dist/runtime/file-preview/utils/format.js +40 -0
  117. package/dist/runtime/file-preview/utils/instance.d.ts +9 -0
  118. package/dist/runtime/file-preview/utils/instance.js +57 -0
  119. package/dist/runtime/file-preview/utils/renderers.d.ts +36 -0
  120. package/dist/runtime/file-preview/utils/renderers.js +247 -0
  121. package/dist/runtime/form/components/page/form-page-header.d.vue.ts +3 -1
  122. package/dist/runtime/form/components/page/form-page-header.vue +4 -4
  123. package/dist/runtime/form/components/page/form-page-header.vue.d.ts +3 -1
  124. package/dist/runtime/form/components/page/form-page-navigation.vue +2 -1
  125. package/dist/runtime/form/components/page/form-page-section.vue +15 -7
  126. package/dist/runtime/form/components/page/form-page.vue +0 -1
  127. package/dist/runtime/form/components/utils/form-file-preview.vue +5 -38
  128. package/dist/runtime/form/composables/use-field-control.d.ts +1 -1
  129. package/dist/runtime/form/composables/use-form-api.d.ts +8 -0
  130. package/dist/runtime/form/composables/use-form-api.js +4 -4
  131. package/dist/runtime/form/composables/use-form-page.js +3 -1
  132. package/dist/runtime/form/composables/use-form-runtime.js +3 -0
  133. package/dist/runtime/form/composables/use-form-upload-registry.d.ts +2 -0
  134. package/dist/runtime/form/composables/use-form-upload-registry.js +11 -6
  135. package/dist/runtime/form/composables/use-form-validation.js +5 -1
  136. package/dist/runtime/form/fields/array-list/use-array-items.d.ts +1 -1
  137. package/dist/runtime/form/fields/array-table/array-table-cell.d.vue.ts +15 -0
  138. package/dist/runtime/form/fields/array-table/array-table-cell.vue +58 -0
  139. package/dist/runtime/form/fields/array-table/array-table-cell.vue.d.ts +15 -0
  140. package/dist/runtime/form/fields/array-table/component.vue +42 -26
  141. package/dist/runtime/form/fields/choice-card/use-choice-card.js +4 -1
  142. package/dist/runtime/form/fields/date/types.d.ts +6 -1
  143. package/dist/runtime/form/fields/date-family/component.vue +7 -1
  144. package/dist/runtime/form/fields/date-family/utils.d.ts +8 -1
  145. package/dist/runtime/form/fields/date-family/utils.js +10 -2
  146. package/dist/runtime/form/fields/hidden/types.d.ts +8 -1
  147. package/dist/runtime/form/fields/upload/component.vue +55 -176
  148. package/dist/runtime/form/fields/upload/types.d.ts +68 -3
  149. package/dist/runtime/form/fields/upload/upload-item.d.vue.ts +24 -0
  150. package/dist/runtime/form/fields/upload/upload-item.vue +158 -0
  151. package/dist/runtime/form/fields/upload/upload-item.vue.d.ts +24 -0
  152. package/dist/runtime/form/fields/upload/use-upload-items.d.ts +44 -0
  153. package/dist/runtime/form/fields/upload/use-upload-items.js +317 -0
  154. package/dist/runtime/form/plugins/form-api.d.ts +10 -0
  155. package/dist/runtime/form/plugins/form-api.js +10 -0
  156. package/dist/runtime/form/types/callbacks.d.ts +8 -2
  157. package/dist/runtime/form/types/controller.d.ts +6 -3
  158. package/dist/runtime/form/types/field-base.d.ts +5 -5
  159. package/dist/runtime/form/types/field-output-utils.d.ts +12 -1
  160. package/dist/runtime/form/types/field-output.d.ts +1 -1
  161. package/dist/runtime/form/types/field.d.ts +3 -2
  162. package/dist/runtime/form/types/form-api.d.ts +4 -2
  163. package/dist/runtime/form/types/options-runtime.d.ts +8 -4
  164. package/dist/runtime/form/types/options.d.ts +11 -11
  165. package/dist/runtime/form/types/output.d.ts +33 -10
  166. package/dist/runtime/form/types/page.d.ts +7 -3
  167. package/dist/runtime/form/types/transform.d.ts +5 -2
  168. package/dist/runtime/form/types/ui.d.ts +7 -3
  169. package/dist/runtime/form/types/upload-runtime.d.ts +4 -0
  170. package/dist/runtime/form/utils/page.js +24 -5
  171. package/dist/runtime/form/utils/state.js +14 -11
  172. package/dist/runtime/i18n/locales/en.js +108 -1
  173. package/dist/runtime/i18n/locales/fr.js +108 -1
  174. package/dist/runtime/i18n/types.d.ts +127 -0
  175. package/dist/runtime/query-state/composables.d.ts +2 -2
  176. package/dist/runtime/shared/styles/tokens.css +1 -1
  177. package/dist/runtime/shared/types/utils.d.ts +12 -4
  178. package/dist/runtime/shared/utils/file.d.ts +11 -0
  179. package/dist/runtime/shared/utils/file.js +50 -0
  180. package/dist/runtime/table/components/table/table-renderer.vue +23 -3
  181. package/dist/runtime/table/components/utils/search-query-input.d.vue.ts +5 -1
  182. package/dist/runtime/table/components/utils/search-query-input.vue +17 -3
  183. package/dist/runtime/table/components/utils/search-query-input.vue.d.ts +5 -1
  184. package/package.json +56 -29
  185. package/dist/runtime/form/components/renderer/form-field-error.vue +0 -16
@@ -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,58 @@
1
+ <script setup>
2
+ import UButton from "@nuxt/ui/components/Button.vue";
3
+ import { useObjectUrl } from "@vueuse/core";
4
+ import { computed, onMounted } from "vue";
5
+ import { useUiToolsLocale } from "../../../i18n/use-locale";
6
+ import { useFilePreviewShell } from "../../composables/use-file-preview-shell";
7
+ import FilePreviewMessage from "../shell/file-preview-message.vue";
8
+ const props = defineProps({
9
+ file: { type: Object, required: true },
10
+ url: { type: String, required: true },
11
+ blob: { type: null, required: true },
12
+ container: { type: String, required: true }
13
+ });
14
+ const emit = defineEmits(["ready", "error"]);
15
+ const { t } = useUiToolsLocale();
16
+ const shell = useFilePreviewShell();
17
+ const inline = globalThis.navigator?.pdfViewerEnabled !== false;
18
+ const typed = computed(
19
+ () => props.blob ? new Blob([props.blob], { type: "application/pdf" }) : null
20
+ );
21
+ const objectUrl = useObjectUrl(typed);
22
+ const source = computed(() => {
23
+ const base = objectUrl.value ?? props.url;
24
+ if (base.includes("#")) return base;
25
+ const page = shell.options.pdf?.page;
26
+ return `${base}#${page ? `page=${page}&` : ""}view=FitH`;
27
+ });
28
+ function openInTab() {
29
+ window.open(props.url, "_blank", "noopener");
30
+ }
31
+ onMounted(() => {
32
+ if (!inline) emit("ready");
33
+ });
34
+ </script>
35
+
36
+ <template>
37
+ <iframe
38
+ v-if="inline"
39
+ :src="source"
40
+ :title="file.name"
41
+ class="absolute inset-0 size-full border-0 bg-(--nut-fp-document)"
42
+ data-file-preview-pdf=""
43
+ @load="emit('ready')"
44
+ />
45
+ <FilePreviewMessage
46
+ v-else
47
+ icon="i-lucide-file-text"
48
+ badge="PDF"
49
+ :title="t('filePreview.errors.pdfTitle')"
50
+ :description="t('filePreview.errors.pdfDescription')"
51
+ >
52
+ <UButton
53
+ icon="i-lucide-external-link"
54
+ :label="t('filePreview.errors.open')"
55
+ @click="openInTab"
56
+ />
57
+ </FilePreviewMessage>
58
+ </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 { computed, watch } from "vue";
3
+ import { useUiToolsLocale } from "../../../i18n/use-locale";
4
+ import { useFilePreviewText } from "../../composables/use-file-preview-text";
5
+ import FilePreviewCode from "./file-preview-code.vue";
6
+ import FilePreviewTextLoading from "./file-preview-text-loading.vue";
7
+ const props = defineProps({
8
+ file: { type: Object, required: true },
9
+ url: { type: String, required: true },
10
+ blob: { type: null, required: true },
11
+ container: { type: String, required: true }
12
+ });
13
+ const emit = defineEmits(["ready", "error"]);
14
+ const { t } = useUiToolsLocale();
15
+ const content = useFilePreviewText(props);
16
+ const json = computed(
17
+ () => ["json", "jsonc"].includes(props.file.extension ?? "") || Boolean(props.file.mime?.includes("json"))
18
+ );
19
+ const facts = computed(() => content.notice.value ? [content.notice.value] : []);
20
+ watch(
21
+ content.status,
22
+ (status) => {
23
+ if (status === "error")
24
+ emit("error", { message: content.error.value?.message, reason: "source" });
25
+ if (status !== "ready") return;
26
+ const lines = content.text.value.split(/\r?\n/u).length;
27
+ emit("ready", [{ label: t("filePreview.fields.lines"), value: lines.toLocaleString() }]);
28
+ },
29
+ { immediate: true }
30
+ );
31
+ </script>
32
+
33
+ <template>
34
+ <FilePreviewCode
35
+ v-if="content.status.value === 'ready'"
36
+ :text="content.text.value"
37
+ :json="json"
38
+ :facts="facts"
39
+ />
40
+ <FilePreviewTextLoading v-else />
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,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,110 @@
1
+ <script setup>
2
+ import UIcon from "@nuxt/ui/components/Icon.vue";
3
+ import { useFullscreen, useMediaControls, useTimeoutFn } from "@vueuse/core";
4
+ import { computed, ref, useTemplateRef } from "vue";
5
+ import { useUiToolsLocale } from "../../../i18n/use-locale";
6
+ import { onFilePreviewKey, useFilePreviewShell } from "../../composables/use-file-preview-shell";
7
+ import { formatFilePreviewDuration } from "../../utils/format";
8
+ import MediaControls from "./media-controls.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 shell = useFilePreviewShell();
18
+ const frame = useTemplateRef("frame");
19
+ const video = useTemplateRef("video");
20
+ const controls = useMediaControls(video, {
21
+ tracks: () => (props.file.file.tracks ?? []).map((track) => ({
22
+ default: track.default,
23
+ kind: track.kind ?? "subtitles",
24
+ label: track.label,
25
+ src: track.src,
26
+ srcLang: track.srcLang
27
+ }))
28
+ });
29
+ const fullscreen = useFullscreen(frame);
30
+ const active = ref(true);
31
+ const rest = useTimeoutFn(() => active.value = false, 2500);
32
+ const started = computed(() => controls.playing.value || controls.currentTime.value > 0.05);
33
+ const showControls = computed(() => !controls.playing.value || active.value);
34
+ function wake() {
35
+ active.value = true;
36
+ rest.start();
37
+ }
38
+ function toggle() {
39
+ controls.playing.value = !controls.playing.value;
40
+ wake();
41
+ }
42
+ function handleMetadata() {
43
+ const element = video.value;
44
+ if (!element) return;
45
+ emit("ready", [
46
+ { label: t("filePreview.fields.duration"), value: formatFilePreviewDuration(element.duration) },
47
+ {
48
+ label: t("filePreview.fields.dimensions"),
49
+ value: `${element.videoWidth} \xD7 ${element.videoHeight} px`
50
+ }
51
+ ]);
52
+ }
53
+ function handleError() {
54
+ emit("error", { message: video.value?.error?.message || void 0, reason: "decode" });
55
+ }
56
+ onFilePreviewKey([" ", "k", "m", "f"], (event) => {
57
+ if (event.key === "m") controls.muted.value = !controls.muted.value;
58
+ else if (event.key === "f") void fullscreen.toggle();
59
+ else toggle();
60
+ });
61
+ </script>
62
+
63
+ <template>
64
+ <div
65
+ ref="frame"
66
+ :class="['absolute inset-0 overflow-hidden bg-black', showControls ? '' : 'cursor-none']"
67
+ data-file-preview-video=""
68
+ @pointermove="wake"
69
+ >
70
+ <video
71
+ ref="video"
72
+ :src="url"
73
+ :poster="file.file.poster"
74
+ preload="metadata"
75
+ playsinline
76
+ class="size-full object-contain"
77
+ @click="toggle"
78
+ @dblclick="fullscreen.toggle()"
79
+ @loadedmetadata="handleMetadata"
80
+ @error="handleError"
81
+ />
82
+
83
+ <button
84
+ v-if="!started"
85
+ type="button"
86
+ class="absolute top-1/2 left-1/2 grid size-17 -translate-1/2 place-items-center rounded-full bg-black/55 ps-1 text-white transition hover:bg-black/70"
87
+ :aria-label="t('filePreview.media.play')"
88
+ data-file-preview-big-play=""
89
+ @click="toggle"
90
+ >
91
+ <UIcon name="i-lucide-play" class="size-7" />
92
+ </button>
93
+ <span
94
+ v-else-if="controls.waiting.value"
95
+ class="pointer-events-none absolute top-1/2 left-1/2 size-10 -translate-1/2 animate-spin rounded-full border-2 border-white/30 border-t-white"
96
+ aria-hidden="true"
97
+ />
98
+
99
+ <MediaControls
100
+ :class="[
101
+ 'absolute inset-x-0 bottom-0 transition-opacity duration-200 motion-reduce:transition-none',
102
+ showControls ? 'opacity-100' : 'pointer-events-none opacity-0'
103
+ ]"
104
+ :controls="controls"
105
+ :fullscreen="fullscreen"
106
+ :compact="shell.narrow.value"
107
+ variant="video"
108
+ />
109
+ </div>
110
+ </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,16 @@
1
+ type __VLS_Props = {
2
+ icon: string;
3
+ label: string;
4
+ kbds?: string[];
5
+ pressed?: boolean;
6
+ disabled?: boolean;
7
+ /** `inverted` sits on dark media, such as video controls. */
8
+ tone?: 'default' | 'inverted';
9
+ };
10
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
11
+ click: (event: MouseEvent) => any;
12
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
13
+ onClick?: ((event: MouseEvent) => any) | undefined;
14
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
+ declare const _default: typeof __VLS_export;
16
+ export default _default;
@@ -0,0 +1,40 @@
1
+ <script setup>
2
+ import UButton from "@nuxt/ui/components/Button.vue";
3
+ import UTooltip from "@nuxt/ui/components/Tooltip.vue";
4
+ const {
5
+ disabled = false,
6
+ kbds = void 0,
7
+ pressed = void 0,
8
+ tone = "default"
9
+ } = defineProps({
10
+ icon: { type: String, required: true },
11
+ label: { type: String, required: true },
12
+ kbds: { type: Array, required: false },
13
+ pressed: { type: Boolean, required: false },
14
+ disabled: { type: Boolean, required: false },
15
+ tone: { type: String, required: false }
16
+ });
17
+ defineEmits(["click"]);
18
+ defineOptions({ inheritAttrs: false });
19
+ </script>
20
+
21
+ <template>
22
+ <UTooltip :text="label" :kbds="kbds" :disabled="disabled" :content="{ side: 'bottom' }">
23
+ <UButton
24
+ v-bind="$attrs"
25
+ :icon="icon"
26
+ :aria-label="label"
27
+ :aria-pressed="pressed"
28
+ :disabled="disabled"
29
+ color="neutral"
30
+ variant="ghost"
31
+ size="sm"
32
+ square
33
+ :class="[
34
+ 'shrink-0',
35
+ tone === 'inverted' ? 'text-white hover:bg-white/15 hover:text-white active:bg-white/20 disabled:bg-transparent' : pressed ? 'bg-elevated text-highlighted' : 'text-muted hover:text-highlighted'
36
+ ]"
37
+ @click="$emit('click', $event)"
38
+ />
39
+ </UTooltip>
40
+ </template>
@@ -0,0 +1,16 @@
1
+ type __VLS_Props = {
2
+ icon: string;
3
+ label: string;
4
+ kbds?: string[];
5
+ pressed?: boolean;
6
+ disabled?: boolean;
7
+ /** `inverted` sits on dark media, such as video controls. */
8
+ tone?: 'default' | 'inverted';
9
+ };
10
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
11
+ click: (event: MouseEvent) => any;
12
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
13
+ onClick?: ((event: MouseEvent) => any) | undefined;
14
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
+ declare const _default: typeof __VLS_export;
16
+ export default _default;
@@ -1,6 +1,8 @@
1
1
  type __VLS_Props = {
2
- path: readonly string[];
3
- class?: string;
2
+ rows: readonly {
3
+ label: string;
4
+ value: string;
5
+ }[];
4
6
  };
5
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>;
6
8
  declare const _default: typeof __VLS_export;
@@ -0,0 +1,25 @@
1
+ <script setup>
2
+ import { useUiToolsLocale } from "../../../i18n/use-locale";
3
+ defineProps({
4
+ rows: { type: Array, required: true }
5
+ });
6
+ const { t } = useUiToolsLocale();
7
+ </script>
8
+
9
+ <template>
10
+ <section
11
+ class="absolute top-3 right-3 z-20 w-[min(320px,calc(100%-24px))] rounded-xl border border-default bg-default px-4 py-3.5 shadow-lg"
12
+ :aria-label="t('filePreview.details')"
13
+ data-file-preview-details=""
14
+ >
15
+ <p class="m-0 mb-2 text-[11px] font-semibold tracking-wider text-muted uppercase">
16
+ {{ t("filePreview.details") }}
17
+ </p>
18
+ <dl class="m-0 grid grid-cols-[auto_minmax(0,1fr)] gap-x-4 gap-y-1.5 text-[13px]">
19
+ <template v-for="row in rows" :key="row.label">
20
+ <dt class="text-muted">{{ row.label }}</dt>
21
+ <dd class="m-0 text-toned tabular-nums [overflow-wrap:anywhere]">{{ row.value }}</dd>
22
+ </template>
23
+ </dl>
24
+ </section>
25
+ </template>
@@ -1,6 +1,8 @@
1
1
  type __VLS_Props = {
2
- path: readonly string[];
3
- class?: string;
2
+ rows: readonly {
3
+ label: string;
4
+ value: string;
5
+ }[];
4
6
  };
5
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>;
6
8
  declare const _default: typeof __VLS_export;
@@ -0,0 +1,44 @@
1
+ import type { FilePreviewAction, FilePreviewItem } from '../../types/index.js';
2
+ type __VLS_Props = {
3
+ item: FilePreviewItem;
4
+ icon: string;
5
+ meta: string;
6
+ index: number;
7
+ total: number;
8
+ loop: boolean;
9
+ narrow: boolean;
10
+ canExpand: boolean;
11
+ expanded: boolean;
12
+ details: boolean;
13
+ };
14
+ declare var __VLS_20: {};
15
+ type __VLS_Slots = {} & {
16
+ tools?: (props: typeof __VLS_20) => any;
17
+ };
18
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
19
+ previous: () => any;
20
+ details: () => any;
21
+ expand: () => any;
22
+ download: () => any;
23
+ open: () => any;
24
+ action: (action: FilePreviewAction) => any;
25
+ close: () => any;
26
+ next: () => any;
27
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
28
+ onPrevious?: (() => any) | undefined;
29
+ onDetails?: (() => any) | undefined;
30
+ onExpand?: (() => any) | undefined;
31
+ onDownload?: (() => any) | undefined;
32
+ onOpen?: (() => any) | undefined;
33
+ onAction?: ((action: FilePreviewAction) => any) | undefined;
34
+ onClose?: (() => any) | undefined;
35
+ onNext?: (() => any) | undefined;
36
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
37
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
38
+ declare const _default: typeof __VLS_export;
39
+ export default _default;
40
+ type __VLS_WithSlots<T, S> = T & {
41
+ new (): {
42
+ $slots: S;
43
+ };
44
+ };
@@ -0,0 +1,163 @@
1
+ <script setup>
2
+ import UButton from "@nuxt/ui/components/Button.vue";
3
+ import UDropdownMenu from "@nuxt/ui/components/DropdownMenu.vue";
4
+ import UIcon from "@nuxt/ui/components/Icon.vue";
5
+ import { computed } from "vue";
6
+ import { useUiToolsLocale } from "../../../i18n/use-locale";
7
+ import { resolveFilePreviewText, splitFilePreviewName } from "../../utils/format";
8
+ import FilePreviewButton from "./file-preview-button.vue";
9
+ const props = defineProps({
10
+ item: { type: Object, required: true },
11
+ icon: { type: String, required: true },
12
+ meta: { type: String, required: true },
13
+ index: { type: Number, required: true },
14
+ total: { type: Number, required: true },
15
+ loop: { type: Boolean, required: true },
16
+ narrow: { type: Boolean, required: true },
17
+ canExpand: { type: Boolean, required: true },
18
+ expanded: { type: Boolean, required: true },
19
+ details: { type: Boolean, required: true }
20
+ });
21
+ const emit = defineEmits(["previous", "next", "close", "expand", "details", "download", "open", "action"]);
22
+ const { t } = useUiToolsLocale();
23
+ const name = computed(() => splitFilePreviewName(props.item.name || t("filePreview.untitled")));
24
+ const downloadable = computed(() => props.item.file.download !== false);
25
+ const actions = computed(() => props.item.file.actions ?? []);
26
+ const menu = computed(() => [
27
+ [
28
+ { icon: "i-lucide-info", label: t("filePreview.details"), onSelect: () => emit("details") },
29
+ ...downloadable.value ? [
30
+ {
31
+ icon: "i-lucide-download",
32
+ label: t("filePreview.download"),
33
+ onSelect: () => emit("download")
34
+ }
35
+ ] : [],
36
+ {
37
+ icon: "i-lucide-external-link",
38
+ label: t("filePreview.openInNewTab"),
39
+ onSelect: () => emit("open")
40
+ }
41
+ ],
42
+ actions.value.map((action) => ({
43
+ icon: action.icon,
44
+ label: resolveFilePreviewText(action.label),
45
+ onSelect: () => emit("action", action)
46
+ }))
47
+ ]);
48
+ </script>
49
+
50
+ <template>
51
+ <header
52
+ class="flex min-h-14 shrink-0 items-center gap-1.5 border-b border-default bg-default py-2 ps-3.5 pe-2 sm:gap-2"
53
+ data-file-preview-header=""
54
+ >
55
+ <span
56
+ class="grid size-8 shrink-0 place-items-center rounded-lg border border-default bg-elevated text-toned"
57
+ aria-hidden="true"
58
+ >
59
+ <UIcon :name="icon" class="size-4" />
60
+ </span>
61
+ <div class="ms-0.5 min-w-0 flex-1">
62
+ <p
63
+ class="m-0 flex min-w-0 text-sm leading-5 font-semibold text-highlighted"
64
+ :title="item.name"
65
+ data-file-preview-name=""
66
+ >
67
+ <span class="overflow-hidden text-ellipsis whitespace-pre">{{ name.head }}</span>
68
+ <span class="shrink-0 whitespace-pre">{{ name.tail }}</span>
69
+ </p>
70
+ <p class="m-0 truncate text-xs text-muted tabular-nums" data-file-preview-meta="">
71
+ {{ meta }}
72
+ </p>
73
+ </div>
74
+
75
+ <template v-if="!narrow">
76
+ <div v-if="total > 1" class="flex shrink-0 items-center" data-file-preview-nav="">
77
+ <FilePreviewButton
78
+ icon="i-lucide-chevron-left"
79
+ :label="t('filePreview.previous')"
80
+ :kbds="['arrowleft']"
81
+ :disabled="!loop && index === 0"
82
+ @click="emit('previous')"
83
+ />
84
+ <span
85
+ class="min-w-11 text-center text-xs text-muted tabular-nums"
86
+ data-file-preview-counter=""
87
+ >
88
+ {{ t("filePreview.counter", { current: index + 1, total }) }}
89
+ </span>
90
+ <FilePreviewButton
91
+ icon="i-lucide-chevron-right"
92
+ :label="t('filePreview.next')"
93
+ :kbds="['arrowright']"
94
+ :disabled="!loop && index === total - 1"
95
+ @click="emit('next')"
96
+ />
97
+ </div>
98
+ <span v-if="total > 1" class="mx-1 h-5 w-px shrink-0 bg-(--ui-border)" aria-hidden="true" />
99
+ <slot name="tools" />
100
+ <FilePreviewButton
101
+ icon="i-lucide-info"
102
+ :label="t('filePreview.details')"
103
+ :pressed="details"
104
+ @click="emit('details')"
105
+ />
106
+ <template v-for="(action, position) in actions" :key="position">
107
+ <FilePreviewButton
108
+ v-if="action.icon"
109
+ :icon="action.icon"
110
+ :label="resolveFilePreviewText(action.label)"
111
+ @click="emit('action', action)"
112
+ />
113
+ <UButton
114
+ v-else
115
+ :label="resolveFilePreviewText(action.label)"
116
+ color="neutral"
117
+ variant="ghost"
118
+ size="sm"
119
+ class="shrink-0 text-toned"
120
+ @click="emit('action', action)"
121
+ />
122
+ </template>
123
+ <FilePreviewButton
124
+ v-if="downloadable"
125
+ icon="i-lucide-download"
126
+ :label="t('filePreview.download')"
127
+ @click="emit('download')"
128
+ />
129
+ <FilePreviewButton
130
+ icon="i-lucide-external-link"
131
+ :label="t('filePreview.openInNewTab')"
132
+ @click="emit('open')"
133
+ />
134
+ <span class="mx-1 h-5 w-px shrink-0 bg-(--ui-border)" aria-hidden="true" />
135
+ <FilePreviewButton
136
+ v-if="canExpand"
137
+ :icon="expanded ? 'i-lucide-minimize-2' : 'i-lucide-maximize-2'"
138
+ :label="expanded ? t('filePreview.restore') : t('filePreview.expand')"
139
+ @click="emit('expand')"
140
+ />
141
+ </template>
142
+ <UDropdownMenu v-else :items="menu" :content="{ align: 'end' }">
143
+ <UButton
144
+ icon="i-lucide-ellipsis"
145
+ :aria-label="t('filePreview.moreActions')"
146
+ color="neutral"
147
+ variant="ghost"
148
+ size="sm"
149
+ square
150
+ class="shrink-0 text-muted"
151
+ data-file-preview-menu=""
152
+ />
153
+ </UDropdownMenu>
154
+
155
+ <FilePreviewButton
156
+ icon="i-lucide-x"
157
+ :label="t('filePreview.close')"
158
+ :kbds="['escape']"
159
+ data-file-preview-close=""
160
+ @click="emit('close')"
161
+ />
162
+ </header>
163
+ </template>
@@ -0,0 +1,44 @@
1
+ import type { FilePreviewAction, FilePreviewItem } from '../../types/index.js';
2
+ type __VLS_Props = {
3
+ item: FilePreviewItem;
4
+ icon: string;
5
+ meta: string;
6
+ index: number;
7
+ total: number;
8
+ loop: boolean;
9
+ narrow: boolean;
10
+ canExpand: boolean;
11
+ expanded: boolean;
12
+ details: boolean;
13
+ };
14
+ declare var __VLS_20: {};
15
+ type __VLS_Slots = {} & {
16
+ tools?: (props: typeof __VLS_20) => any;
17
+ };
18
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
19
+ previous: () => any;
20
+ details: () => any;
21
+ expand: () => any;
22
+ download: () => any;
23
+ open: () => any;
24
+ action: (action: FilePreviewAction) => any;
25
+ close: () => any;
26
+ next: () => any;
27
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
28
+ onPrevious?: (() => any) | undefined;
29
+ onDetails?: (() => any) | undefined;
30
+ onExpand?: (() => any) | undefined;
31
+ onDownload?: (() => any) | undefined;
32
+ onOpen?: (() => any) | undefined;
33
+ onAction?: ((action: FilePreviewAction) => any) | undefined;
34
+ onClose?: (() => any) | undefined;
35
+ onNext?: (() => any) | undefined;
36
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
37
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
38
+ declare const _default: typeof __VLS_export;
39
+ export default _default;
40
+ type __VLS_WithSlots<T, S> = T & {
41
+ new (): {
42
+ $slots: S;
43
+ };
44
+ };