nuxt-ui-tools 1.7.0 → 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.
- package/dist/module.json +1 -1
- package/dist/module.mjs +18 -0
- package/dist/runtime/file-preview/components/provider/file-preview-host.d.vue.ts +7 -0
- package/dist/runtime/file-preview/components/provider/file-preview-host.vue +147 -0
- package/dist/runtime/file-preview/components/provider/file-preview-host.vue.d.ts +7 -0
- package/dist/runtime/file-preview/components/provider/file-preview-provider.d.vue.ts +21 -0
- package/dist/runtime/file-preview/components/provider/file-preview-provider.vue +23 -0
- package/dist/runtime/file-preview/components/provider/file-preview-provider.vue.d.ts +21 -0
- package/dist/runtime/file-preview/components/renderers/audio-renderer.d.vue.ts +10 -0
- package/dist/runtime/file-preview/components/renderers/audio-renderer.vue +83 -0
- package/dist/runtime/file-preview/components/renderers/audio-renderer.vue.d.ts +10 -0
- package/dist/runtime/file-preview/components/renderers/csv-renderer.d.vue.ts +10 -0
- package/dist/runtime/file-preview/components/renderers/csv-renderer.vue +116 -0
- package/dist/runtime/file-preview/components/renderers/csv-renderer.vue.d.ts +10 -0
- package/dist/runtime/file-preview/components/renderers/fallback-renderer.d.vue.ts +10 -0
- package/dist/runtime/file-preview/components/renderers/fallback-renderer.vue +41 -0
- package/dist/runtime/file-preview/components/renderers/fallback-renderer.vue.d.ts +10 -0
- package/dist/runtime/file-preview/components/renderers/file-preview-code.d.vue.ts +9 -0
- package/dist/runtime/file-preview/components/renderers/file-preview-code.vue +83 -0
- package/dist/runtime/file-preview/components/renderers/file-preview-code.vue.d.ts +9 -0
- package/dist/runtime/file-preview/components/renderers/file-preview-text-loading.d.vue.ts +3 -0
- package/dist/runtime/file-preview/components/renderers/file-preview-text-loading.vue +14 -0
- package/dist/runtime/file-preview/components/renderers/file-preview-text-loading.vue.d.ts +3 -0
- package/dist/runtime/file-preview/components/renderers/image-renderer.d.vue.ts +10 -0
- package/dist/runtime/file-preview/components/renderers/image-renderer.vue +182 -0
- package/dist/runtime/file-preview/components/renderers/image-renderer.vue.d.ts +10 -0
- package/dist/runtime/file-preview/components/renderers/markdown-renderer.d.vue.ts +10 -0
- package/dist/runtime/file-preview/components/renderers/markdown-renderer.vue +78 -0
- package/dist/runtime/file-preview/components/renderers/markdown-renderer.vue.d.ts +10 -0
- package/dist/runtime/file-preview/components/renderers/media-controls.d.vue.ts +10 -0
- package/dist/runtime/file-preview/components/renderers/media-controls.vue +145 -0
- package/dist/runtime/file-preview/components/renderers/media-controls.vue.d.ts +10 -0
- package/dist/runtime/file-preview/components/renderers/pdf-renderer.d.vue.ts +10 -0
- package/dist/runtime/file-preview/components/renderers/pdf-renderer.vue +58 -0
- package/dist/runtime/file-preview/components/renderers/pdf-renderer.vue.d.ts +10 -0
- package/dist/runtime/file-preview/components/renderers/text-renderer.d.vue.ts +10 -0
- package/dist/runtime/file-preview/components/renderers/text-renderer.vue +41 -0
- package/dist/runtime/file-preview/components/renderers/text-renderer.vue.d.ts +10 -0
- package/dist/runtime/file-preview/components/renderers/video-renderer.d.vue.ts +10 -0
- package/dist/runtime/file-preview/components/renderers/video-renderer.vue +110 -0
- package/dist/runtime/file-preview/components/renderers/video-renderer.vue.d.ts +10 -0
- package/dist/runtime/file-preview/components/shell/file-preview-button.d.vue.ts +16 -0
- package/dist/runtime/file-preview/components/shell/file-preview-button.vue +40 -0
- package/dist/runtime/file-preview/components/shell/file-preview-button.vue.d.ts +16 -0
- package/dist/runtime/{form/components/renderer/form-field-error.d.vue.ts → file-preview/components/shell/file-preview-details.d.vue.ts} +4 -2
- package/dist/runtime/file-preview/components/shell/file-preview-details.vue +25 -0
- package/dist/runtime/{form/components/renderer/form-field-error.vue.d.ts → file-preview/components/shell/file-preview-details.vue.d.ts} +4 -2
- package/dist/runtime/file-preview/components/shell/file-preview-header.d.vue.ts +44 -0
- package/dist/runtime/file-preview/components/shell/file-preview-header.vue +163 -0
- package/dist/runtime/file-preview/components/shell/file-preview-header.vue.d.ts +44 -0
- package/dist/runtime/file-preview/components/shell/file-preview-message.d.vue.ts +21 -0
- package/dist/runtime/file-preview/components/shell/file-preview-message.vue +49 -0
- package/dist/runtime/file-preview/components/shell/file-preview-message.vue.d.ts +21 -0
- package/dist/runtime/file-preview/components/shell/file-preview-shell.d.vue.ts +17 -0
- package/dist/runtime/file-preview/components/shell/file-preview-shell.vue +280 -0
- package/dist/runtime/file-preview/components/shell/file-preview-shell.vue.d.ts +17 -0
- package/dist/runtime/file-preview/components/shell/file-preview-stage.d.vue.ts +37 -0
- package/dist/runtime/file-preview/components/shell/file-preview-stage.vue +173 -0
- package/dist/runtime/file-preview/components/shell/file-preview-stage.vue.d.ts +37 -0
- package/dist/runtime/file-preview/components/shell/file-preview-thumb.d.vue.ts +14 -0
- package/dist/runtime/file-preview/components/shell/file-preview-thumb.vue +69 -0
- package/dist/runtime/file-preview/components/shell/file-preview-thumb.vue.d.ts +14 -0
- package/dist/runtime/file-preview/components/shell/file-preview-tools.d.vue.ts +13 -0
- package/dist/runtime/file-preview/components/shell/file-preview-tools.vue +10 -0
- package/dist/runtime/file-preview/components/shell/file-preview-tools.vue.d.ts +13 -0
- package/dist/runtime/file-preview/composables/use-file-preview-api.d.ts +21 -0
- package/dist/runtime/file-preview/composables/use-file-preview-api.js +83 -0
- package/dist/runtime/file-preview/composables/use-file-preview-shell.d.ts +13 -0
- package/dist/runtime/file-preview/composables/use-file-preview-shell.js +30 -0
- package/dist/runtime/file-preview/composables/use-file-preview-source.d.ts +17 -0
- package/dist/runtime/file-preview/composables/use-file-preview-source.js +51 -0
- package/dist/runtime/file-preview/composables/use-file-preview-text.d.ts +14 -0
- package/dist/runtime/file-preview/composables/use-file-preview-text.js +79 -0
- package/dist/runtime/file-preview/index.d.ts +5 -0
- package/dist/runtime/file-preview/index.js +14 -0
- package/dist/runtime/file-preview/plugins/file-preview-api.d.ts +11 -0
- package/dist/runtime/file-preview/plugins/file-preview-api.js +10 -0
- package/dist/runtime/file-preview/types/api.d.ts +74 -0
- package/dist/runtime/file-preview/types/api.js +0 -0
- package/dist/runtime/file-preview/types/file.d.ts +77 -0
- package/dist/runtime/file-preview/types/file.js +0 -0
- package/dist/runtime/file-preview/types/index.d.ts +4 -0
- package/dist/runtime/file-preview/types/index.js +0 -0
- package/dist/runtime/file-preview/types/renderer.d.ts +49 -0
- package/dist/runtime/file-preview/types/renderer.js +0 -0
- package/dist/runtime/file-preview/types/shell.d.ts +12 -0
- package/dist/runtime/file-preview/types/shell.js +0 -0
- package/dist/runtime/file-preview/utils/container.d.ts +4 -0
- package/dist/runtime/file-preview/utils/container.js +10 -0
- package/dist/runtime/file-preview/utils/csv.d.ts +17 -0
- package/dist/runtime/file-preview/utils/csv.js +53 -0
- package/dist/runtime/file-preview/utils/download.d.ts +8 -0
- package/dist/runtime/file-preview/utils/download.js +40 -0
- package/dist/runtime/file-preview/utils/files.d.ts +7 -0
- package/dist/runtime/file-preview/utils/files.js +53 -0
- package/dist/runtime/file-preview/utils/format.d.ts +13 -0
- package/dist/runtime/file-preview/utils/format.js +40 -0
- package/dist/runtime/file-preview/utils/instance.d.ts +9 -0
- package/dist/runtime/file-preview/utils/instance.js +57 -0
- package/dist/runtime/file-preview/utils/renderers.d.ts +36 -0
- package/dist/runtime/file-preview/utils/renderers.js +247 -0
- package/dist/runtime/form/components/page/form-page-header.d.vue.ts +3 -1
- package/dist/runtime/form/components/page/form-page-header.vue +4 -4
- package/dist/runtime/form/components/page/form-page-header.vue.d.ts +3 -1
- package/dist/runtime/form/components/page/form-page-navigation.vue +2 -1
- package/dist/runtime/form/components/page/form-page-section.vue +15 -7
- package/dist/runtime/form/components/page/form-page.vue +0 -1
- package/dist/runtime/form/components/utils/form-file-preview.vue +5 -38
- package/dist/runtime/form/composables/use-field-control.d.ts +1 -1
- package/dist/runtime/form/composables/use-form-page.js +3 -1
- package/dist/runtime/form/composables/use-form-runtime.js +3 -0
- package/dist/runtime/form/composables/use-form-upload-registry.d.ts +2 -0
- package/dist/runtime/form/composables/use-form-upload-registry.js +11 -6
- package/dist/runtime/form/composables/use-form-validation.js +5 -1
- package/dist/runtime/form/fields/array-list/use-array-items.d.ts +1 -1
- package/dist/runtime/form/fields/array-table/array-table-cell.d.vue.ts +15 -0
- package/dist/runtime/form/fields/array-table/array-table-cell.vue +58 -0
- package/dist/runtime/form/fields/array-table/array-table-cell.vue.d.ts +15 -0
- package/dist/runtime/form/fields/array-table/component.vue +42 -26
- package/dist/runtime/form/fields/date/types.d.ts +6 -1
- package/dist/runtime/form/fields/date-family/component.vue +7 -1
- package/dist/runtime/form/fields/date-family/utils.d.ts +8 -1
- package/dist/runtime/form/fields/date-family/utils.js +10 -2
- package/dist/runtime/form/fields/hidden/types.d.ts +8 -1
- package/dist/runtime/form/fields/upload/component.vue +55 -176
- package/dist/runtime/form/fields/upload/types.d.ts +68 -3
- package/dist/runtime/form/fields/upload/upload-item.d.vue.ts +24 -0
- package/dist/runtime/form/fields/upload/upload-item.vue +158 -0
- package/dist/runtime/form/fields/upload/upload-item.vue.d.ts +24 -0
- package/dist/runtime/form/fields/upload/use-upload-items.d.ts +44 -0
- package/dist/runtime/form/fields/upload/use-upload-items.js +317 -0
- package/dist/runtime/form/types/callbacks.d.ts +8 -2
- package/dist/runtime/form/types/controller.d.ts +6 -3
- package/dist/runtime/form/types/field-base.d.ts +5 -5
- package/dist/runtime/form/types/field-output-utils.d.ts +12 -1
- package/dist/runtime/form/types/field-output.d.ts +1 -1
- package/dist/runtime/form/types/field.d.ts +3 -2
- package/dist/runtime/form/types/form-api.d.ts +4 -2
- package/dist/runtime/form/types/options-runtime.d.ts +8 -4
- package/dist/runtime/form/types/options.d.ts +11 -11
- package/dist/runtime/form/types/output.d.ts +33 -10
- package/dist/runtime/form/types/page.d.ts +7 -3
- package/dist/runtime/form/types/transform.d.ts +5 -2
- package/dist/runtime/form/types/ui.d.ts +7 -3
- package/dist/runtime/form/types/upload-runtime.d.ts +4 -0
- package/dist/runtime/form/utils/page.js +24 -5
- package/dist/runtime/form/utils/state.js +14 -11
- package/dist/runtime/i18n/locales/en.js +104 -1
- package/dist/runtime/i18n/locales/fr.js +104 -1
- package/dist/runtime/i18n/types.d.ts +121 -0
- package/dist/runtime/query-state/composables.d.ts +2 -2
- package/dist/runtime/shared/styles/tokens.css +1 -1
- package/dist/runtime/shared/types/utils.d.ts +12 -4
- package/dist/runtime/shared/utils/file.d.ts +11 -0
- package/dist/runtime/shared/utils/file.js +50 -0
- package/dist/runtime/table/components/table/table-renderer.vue +23 -3
- package/dist/runtime/table/components/utils/search-query-input.d.vue.ts +5 -1
- package/dist/runtime/table/components/utils/search-query-input.vue +17 -3
- package/dist/runtime/table/components/utils/search-query-input.vue.d.ts +5 -1
- package/package.json +56 -29
- package/dist/runtime/form/components/renderer/form-field-error.vue +0 -16
|
@@ -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
|
-
|
|
3
|
-
|
|
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
|
-
|
|
3
|
-
|
|
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
|
+
};
|