nuxt-media-library 0.0.48 → 0.0.49

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 (87) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/MLMedia/Dropzone.d.vue.ts +60 -0
  3. package/dist/runtime/components/MLMedia/Dropzone.vue +137 -0
  4. package/dist/runtime/components/MLMedia/Dropzone.vue.d.ts +60 -0
  5. package/dist/runtime/components/MLMedia/Editor.d.vue.ts +23 -0
  6. package/dist/runtime/components/MLMedia/Editor.vue +34 -0
  7. package/dist/runtime/components/MLMedia/Editor.vue.d.ts +23 -0
  8. package/dist/runtime/components/MLMedia/EditorPanel.d.vue.ts +38 -0
  9. package/dist/runtime/components/MLMedia/EditorPanel.vue +220 -0
  10. package/dist/runtime/components/MLMedia/EditorPanel.vue.d.ts +38 -0
  11. package/dist/runtime/components/MLMedia/Field.d.vue.ts +65 -0
  12. package/dist/runtime/components/MLMedia/Field.vue +282 -0
  13. package/dist/runtime/components/MLMedia/Field.vue.d.ts +65 -0
  14. package/dist/runtime/components/MLMedia/FileFacts.d.vue.ts +19 -0
  15. package/dist/runtime/components/MLMedia/FileFacts.vue +38 -0
  16. package/dist/runtime/components/MLMedia/FileFacts.vue.d.ts +19 -0
  17. package/dist/runtime/components/MLMedia/FilePicker.d.vue.ts +23 -0
  18. package/dist/runtime/components/MLMedia/FilePicker.vue +33 -0
  19. package/dist/runtime/components/MLMedia/FilePicker.vue.d.ts +23 -0
  20. package/dist/runtime/components/MLMedia/FilePickerPanel.d.vue.ts +33 -0
  21. package/dist/runtime/components/MLMedia/FilePickerPanel.vue +300 -0
  22. package/dist/runtime/components/MLMedia/FilePickerPanel.vue.d.ts +33 -0
  23. package/dist/runtime/components/MLMedia/FilterPill.d.vue.ts +30 -0
  24. package/dist/runtime/components/MLMedia/FilterPill.vue +84 -0
  25. package/dist/runtime/components/MLMedia/FilterPill.vue.d.ts +30 -0
  26. package/dist/runtime/components/MLMedia/Gallery.d.vue.ts +78 -0
  27. package/dist/runtime/components/MLMedia/Gallery.vue +256 -0
  28. package/dist/runtime/components/MLMedia/Gallery.vue.d.ts +78 -0
  29. package/dist/runtime/components/MLMedia/GallerySection.d.vue.ts +102 -0
  30. package/dist/runtime/components/MLMedia/GallerySection.vue +422 -0
  31. package/dist/runtime/components/MLMedia/GallerySection.vue.d.ts +102 -0
  32. package/dist/runtime/components/MLMedia/KindBadge.d.vue.ts +17 -0
  33. package/dist/runtime/components/MLMedia/KindBadge.vue +22 -0
  34. package/dist/runtime/components/MLMedia/KindBadge.vue.d.ts +17 -0
  35. package/dist/runtime/components/MLMedia/MediaTile.d.vue.ts +63 -0
  36. package/dist/runtime/components/MLMedia/MediaTile.vue +117 -0
  37. package/dist/runtime/components/MLMedia/MediaTile.vue.d.ts +63 -0
  38. package/dist/runtime/components/MLMedia/PickerCard.d.vue.ts +42 -0
  39. package/dist/runtime/components/MLMedia/PickerCard.vue +79 -0
  40. package/dist/runtime/components/MLMedia/PickerCard.vue.d.ts +42 -0
  41. package/dist/runtime/components/MLMedia/PickerRow.d.vue.ts +31 -0
  42. package/dist/runtime/components/MLMedia/PickerRow.vue +65 -0
  43. package/dist/runtime/components/MLMedia/PickerRow.vue.d.ts +31 -0
  44. package/dist/runtime/components/MLMedia/PreviewEye.d.vue.ts +16 -0
  45. package/dist/runtime/components/MLMedia/PreviewEye.vue +21 -0
  46. package/dist/runtime/components/MLMedia/PreviewEye.vue.d.ts +16 -0
  47. package/dist/runtime/components/MLMedia/ProgressVeil.d.vue.ts +25 -0
  48. package/dist/runtime/components/MLMedia/ProgressVeil.vue +98 -0
  49. package/dist/runtime/components/MLMedia/ProgressVeil.vue.d.ts +25 -0
  50. package/dist/runtime/components/MLMedia/StatusBadge.d.vue.ts +17 -0
  51. package/dist/runtime/components/MLMedia/StatusBadge.vue +31 -0
  52. package/dist/runtime/components/MLMedia/StatusBadge.vue.d.ts +17 -0
  53. package/dist/runtime/components/MLMedia/Thumbnail.d.vue.ts +36 -0
  54. package/dist/runtime/components/MLMedia/Thumbnail.vue +84 -0
  55. package/dist/runtime/components/MLMedia/Thumbnail.vue.d.ts +36 -0
  56. package/dist/runtime/components/MLMedia/UsageList.d.vue.ts +26 -0
  57. package/dist/runtime/components/MLMedia/UsageList.vue +66 -0
  58. package/dist/runtime/components/MLMedia/UsageList.vue.d.ts +26 -0
  59. package/dist/runtime/components/MLProcessing/StepLayout.d.vue.ts +1 -1
  60. package/dist/runtime/components/MLProcessing/StepLayout.vue.d.ts +1 -1
  61. package/dist/runtime/composables/useMLFilePicker.d.ts +20 -0
  62. package/dist/runtime/composables/useMLFilePicker.js +17 -0
  63. package/dist/runtime/composables/useMLMediaAssets.d.ts +19 -0
  64. package/dist/runtime/composables/useMLMediaAssets.js +56 -0
  65. package/dist/runtime/composables/useMLMediaBrowse.d.ts +147 -0
  66. package/dist/runtime/composables/useMLMediaBrowse.js +72 -0
  67. package/dist/runtime/composables/useMLMediaEditor.d.ts +22 -0
  68. package/dist/runtime/composables/useMLMediaEditor.js +20 -0
  69. package/dist/runtime/composables/useMLMediaField.d.ts +29 -0
  70. package/dist/runtime/composables/useMLMediaField.js +77 -0
  71. package/dist/runtime/composables/useMLMediaGallery.d.ts +55 -0
  72. package/dist/runtime/composables/useMLMediaGallery.js +134 -0
  73. package/dist/runtime/composables/useMLMediaUpload.d.ts +134 -0
  74. package/dist/runtime/composables/useMLMediaUpload.js +153 -0
  75. package/dist/runtime/index.d.ts +11 -0
  76. package/dist/runtime/index.js +11 -0
  77. package/dist/runtime/utils/assetDisplay.d.ts +8 -0
  78. package/dist/runtime/utils/assetDisplay.js +29 -0
  79. package/dist/runtime/utils/assetFormat.d.ts +30 -0
  80. package/dist/runtime/utils/assetFormat.js +69 -0
  81. package/dist/runtime/utils/assetThumbnail.d.ts +11 -0
  82. package/dist/runtime/utils/assetThumbnail.js +14 -0
  83. package/dist/runtime/utils/fileAccept.d.ts +26 -0
  84. package/dist/runtime/utils/fileAccept.js +104 -0
  85. package/dist/runtime/utils/galleryDrag.d.ts +2 -0
  86. package/dist/runtime/utils/galleryDrag.js +1 -0
  87. package/package.json +1 -1
@@ -0,0 +1,65 @@
1
+ import type { MediaUploadOptions } from '../../composables/useMLMediaUpload.js';
2
+ type __VLS_Props = {
3
+ /** Asset kinds the field takes: ['image'], "image,video". Empty means any file. */
4
+ accept?: readonly string[] | string;
5
+ label?: string;
6
+ /** Under the field. Defaults to what the field accepts and its size limit. */
7
+ hint?: string;
8
+ required?: boolean;
9
+ disabled?: boolean;
10
+ /** Bytes. */
11
+ maxSize?: number | null;
12
+ /** Shows "No alt text" on a filled image field. Alt text lives on the host record. */
13
+ missingAlt?: boolean;
14
+ /** Upload session settings for new files. */
15
+ visibility?: MediaUploadOptions['visibility'];
16
+ processingConfig?: MediaUploadOptions['processingConfig'];
17
+ collectionName?: string | null;
18
+ /** Show "Select existing", which opens the library picker. */
19
+ picker?: boolean;
20
+ /** Replaces the built-in picker, e.g. with the host's own dialog. */
21
+ onPick?: () => void;
22
+ /** Show the eye button on the thumbnail, which opens the media editor. */
23
+ editor?: boolean;
24
+ /** Label for the editor's remove button. Empty hides it. */
25
+ removeLabel?: string;
26
+ /** Replaces the built-in editor. Receives the asset ID. */
27
+ onOpen?: (assetId: string) => void;
28
+ };
29
+ type __VLS_ModelProps = {
30
+ modelValue?: string | null;
31
+ /** Alt text for the file, stored on the host record. Edited in the media editor. */
32
+ 'alt'?: string | undefined;
33
+ };
34
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
35
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
36
+ uploaded: (assetId: string) => any;
37
+ "update:modelValue": (value: string | null) => any;
38
+ "update:alt": (value: string | undefined) => any;
39
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
40
+ onUploaded?: ((assetId: string) => any) | undefined;
41
+ "onUpdate:modelValue"?: ((value: string | null) => any) | undefined;
42
+ "onUpdate:alt"?: ((value: string | undefined) => any) | undefined;
43
+ }>, {
44
+ visibility: "private" | "restricted" | "public";
45
+ label: string;
46
+ accept: readonly string[] | string;
47
+ maxSize: number | null;
48
+ processingConfig: {
49
+ stepOptions?: Record<string, Record<string, unknown>> | null;
50
+ useFilenameAsAssetId?: boolean;
51
+ enableTranscription?: boolean;
52
+ };
53
+ collectionName: string | null;
54
+ disabled: boolean;
55
+ required: boolean;
56
+ removeLabel: string;
57
+ hint: string;
58
+ missingAlt: boolean;
59
+ picker: boolean;
60
+ onPick: () => void;
61
+ editor: boolean;
62
+ onOpen: (assetId: string) => void;
63
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
64
+ declare const _default: typeof __VLS_export;
65
+ export default _default;
@@ -0,0 +1,282 @@
1
+ <script setup>
2
+ import { computed } from "vue";
3
+ import { useMLMediaField } from "../../composables/useMLMediaField";
4
+ import { useMLFilePicker } from "../../composables/useMLFilePicker";
5
+ import { useMLMediaEditor } from "../../composables/useMLMediaEditor";
6
+ import { assetDimensions, assetDurationSeconds, assetName, assetSizeBytes, formatBytes, formatDuration } from "../../utils/assetFormat";
7
+ const props = defineProps({
8
+ accept: { type: [Array, String], required: false, default: "" },
9
+ label: { type: String, required: false, default: void 0 },
10
+ hint: { type: String, required: false, default: void 0 },
11
+ required: { type: Boolean, required: false, default: false },
12
+ disabled: { type: Boolean, required: false, default: false },
13
+ maxSize: { type: [Number, null], required: false, default: null },
14
+ missingAlt: { type: Boolean, required: false, default: false },
15
+ visibility: { type: String, required: false, default: void 0 },
16
+ processingConfig: { type: Object, required: false, default: void 0 },
17
+ collectionName: { type: [String, null], required: false, default: null },
18
+ picker: { type: Boolean, required: false, default: true },
19
+ onPick: { type: Function, required: false, default: void 0 },
20
+ editor: { type: Boolean, required: false, default: true },
21
+ removeLabel: { type: String, required: false, default: "Remove from this field" },
22
+ onOpen: { type: Function, required: false, default: void 0 }
23
+ });
24
+ const model = defineModel({ type: [String, null], ...{ default: null } });
25
+ const alt = defineModel("alt", { type: null, ...{ default: void 0 } });
26
+ const emit = defineEmits(["uploaded"]);
27
+ const field = useMLMediaField(model, {
28
+ accept: () => props.accept,
29
+ maxSize: () => props.maxSize,
30
+ visibility: props.visibility,
31
+ processingConfig: props.processingConfig,
32
+ collectionName: props.collectionName,
33
+ onUploaded: (id) => emit("uploaded", id)
34
+ });
35
+ const { state, asset, upload, message } = field;
36
+ const helpText = computed(() => {
37
+ if (props.hint) return props.hint;
38
+ const parts = [field.acceptLabel.value === "any file" ? "" : `Takes ${field.acceptLabel.value}`];
39
+ if (props.maxSize) parts.push(`up to ${formatBytes(props.maxSize)}`);
40
+ return parts.filter(Boolean).join(" ").replace(/^./, (c) => c.toUpperCase());
41
+ });
42
+ const name = computed(() => upload.value?.file.name ?? assetName(asset.value));
43
+ const kind = computed(() => upload.value?.kind ?? asset.value?.kind ?? null);
44
+ const isImage = computed(() => (kind.value ?? "").toLowerCase() === "image");
45
+ const details = computed(() => {
46
+ const u = upload.value;
47
+ if (u && state.value === "uploading") {
48
+ if (u.phase === "failed") return u.error ?? "Upload failed";
49
+ if (u.phase === "processing") return u.progress != null ? `Processing ${Math.round(u.progress)}%` : "Processing\u2026";
50
+ return `Uploading ${Math.round(u.progress ?? 0)}% \xB7 ${formatBytes(u.file.size)}`;
51
+ }
52
+ const a = asset.value;
53
+ if (!a) return "";
54
+ const dims = assetDimensions(a);
55
+ const duration = assetDurationSeconds(a);
56
+ return [
57
+ formatBytes(assetSizeBytes(a)),
58
+ dims ? `${dims.width} \xD7 ${dims.height}` : "",
59
+ duration ? formatDuration(duration) : ""
60
+ ].filter(Boolean).join(" \xB7 ");
61
+ });
62
+ const veilPhase = computed(() => {
63
+ const p = upload.value?.phase;
64
+ return state.value === "uploading" && (p === "uploading" || p === "processing" || p === "failed") ? p : null;
65
+ });
66
+ const filePicker = useMLFilePicker();
67
+ const canPick = computed(() => !!props.onPick || props.picker);
68
+ async function pickExisting() {
69
+ if (props.onPick) return props.onPick();
70
+ const ids = await filePicker.open({
71
+ accept: props.accept,
72
+ max: 1,
73
+ selected: [model.value],
74
+ title: props.label ? `Select ${props.label.toLowerCase()}` : "Select file",
75
+ maxSize: props.maxSize,
76
+ upload: { visibility: props.visibility, processingConfig: props.processingConfig, collectionName: props.collectionName }
77
+ });
78
+ if (ids) {
79
+ field.clearMessage();
80
+ model.value = ids[0] ?? null;
81
+ }
82
+ }
83
+ const mediaEditor = useMLMediaEditor();
84
+ const canOpen = computed(() => state.value === "filled" && !!model.value && (!!props.onOpen || props.editor));
85
+ const showNoAlt = computed(() => isImage.value && (props.missingAlt || alt.value !== void 0 && !alt.value.trim()));
86
+ async function openEditor() {
87
+ const id = model.value;
88
+ if (!canOpen.value || !id) return;
89
+ if (props.onOpen) return props.onOpen(id);
90
+ const result = await mediaEditor.open(id, {
91
+ alt: alt.value ?? "",
92
+ readonly: props.disabled,
93
+ removeLabel: props.removeLabel
94
+ });
95
+ if (result?.action === "save") alt.value = result.alt[id] ?? "";
96
+ else if (result?.action === "remove") field.clear();
97
+ }
98
+ function changeItems(open) {
99
+ return [
100
+ { label: "Upload new", icon: "i-lucide-upload", onSelect: open },
101
+ { label: "Select existing", icon: "i-lucide-layout-grid", onSelect: () => void pickExisting() }
102
+ ];
103
+ }
104
+ </script>
105
+
106
+ <template>
107
+ <UFormField
108
+ :label="label"
109
+ :required="required"
110
+ :help="message ? void 0 : helpText || void 0"
111
+ :error="message ?? void 0"
112
+ >
113
+ <!-- Empty -->
114
+ <MLMediaDropzone
115
+ v-if="state === 'empty'"
116
+ :accept="field.acceptAttr.value"
117
+ :multiple="false"
118
+ :max-size="maxSize"
119
+ :disabled="disabled"
120
+ @files="field.onFiles"
121
+ @rejected="field.onRejected"
122
+ >
123
+ <template
124
+ v-if="canPick"
125
+ #actions
126
+ >
127
+ <UButton
128
+ size="sm"
129
+ color="neutral"
130
+ variant="outline"
131
+ icon="i-lucide-layout-grid"
132
+ label="Select existing"
133
+ :disabled="disabled"
134
+ @click="pickExisting"
135
+ />
136
+ </template>
137
+ </MLMediaDropzone>
138
+
139
+ <!-- Loading the current file -->
140
+ <div
141
+ v-else-if="state === 'loading'"
142
+ class="flex items-center gap-3 rounded-lg border border-default p-2"
143
+ >
144
+ <USkeleton class="aspect-[4/3] w-20 rounded-md" />
145
+ <div class="flex flex-1 flex-col gap-1.5">
146
+ <USkeleton class="h-3.5 w-2/3" />
147
+ <USkeleton class="h-3 w-1/3" />
148
+ </div>
149
+ </div>
150
+
151
+ <!-- Filled, uploading, or pointing at a file that is gone -->
152
+ <MLMediaDropzone
153
+ v-else
154
+ variant="overlay"
155
+ :accept="field.acceptAttr.value"
156
+ :multiple="false"
157
+ :max-size="maxSize"
158
+ :disabled="disabled || state === 'uploading'"
159
+ title="Drop to replace"
160
+ class="rounded-lg"
161
+ @files="field.onFiles"
162
+ @rejected="field.onRejected"
163
+ >
164
+ <template #default="{ open }">
165
+ <div
166
+ class="flex items-center gap-3 rounded-lg border p-2"
167
+ :class="state === 'missing' ? 'border-warning/50 bg-warning/5' : 'border-default bg-default'"
168
+ >
169
+ <div class="group relative shrink-0">
170
+ <MLMediaThumbnail
171
+ :asset="upload?.localPreview ? null : asset"
172
+ :src="upload?.localPreview ?? void 0"
173
+ :kind="kind"
174
+ size="md"
175
+ aspect="landscape"
176
+ >
177
+ <MLMediaProgressVeil
178
+ v-if="veilPhase"
179
+ :phase="veilPhase"
180
+ :progress="upload?.progress ?? null"
181
+ compact
182
+ />
183
+ </MLMediaThumbnail>
184
+ <MLMediaPreviewEye
185
+ v-if="canOpen"
186
+ :name="name"
187
+ class="absolute bottom-1 right-1 z-20"
188
+ @click="openEditor"
189
+ />
190
+ </div>
191
+
192
+ <div class="flex min-w-0 flex-1 flex-col gap-0.5">
193
+ <span
194
+ v-if="state === 'missing'"
195
+ class="text-sm font-semibold"
196
+ >File unavailable</span>
197
+ <span
198
+ v-else
199
+ class="truncate text-sm font-semibold"
200
+ >{{ name }}</span>
201
+ <span
202
+ v-if="state === 'missing'"
203
+ class="text-xs text-muted"
204
+ >It was deleted, or you don't have access to it.</span>
205
+ <span
206
+ v-else
207
+ class="truncate text-xs tabular-nums"
208
+ :class="upload?.phase === 'failed' ? 'text-error' : 'text-muted'"
209
+ >{{ details }}</span>
210
+ <span
211
+ v-if="state === 'filled' && showNoAlt"
212
+ class="text-xs text-warning"
213
+ >No alt text</span>
214
+ </div>
215
+
216
+ <div
217
+ v-if="!disabled"
218
+ class="flex shrink-0 items-center gap-0.5"
219
+ >
220
+ <template v-if="state === 'uploading'">
221
+ <UButton
222
+ v-if="upload?.phase === 'failed'"
223
+ size="sm"
224
+ color="neutral"
225
+ variant="ghost"
226
+ icon="i-lucide-rotate-ccw"
227
+ label="Retry"
228
+ @click="upload?.retry()"
229
+ />
230
+ <UButton
231
+ v-if="upload?.phase === 'failed'"
232
+ size="sm"
233
+ color="neutral"
234
+ variant="ghost"
235
+ icon="i-lucide-x"
236
+ aria-label="Remove"
237
+ @click="field.clear()"
238
+ />
239
+ <UButton
240
+ v-else
241
+ size="sm"
242
+ color="neutral"
243
+ variant="ghost"
244
+ label="Cancel"
245
+ @click="upload?.cancel()"
246
+ />
247
+ </template>
248
+ <template v-else>
249
+ <UDropdownMenu
250
+ v-if="canPick"
251
+ :items="changeItems(open)"
252
+ :content="{ align: 'end' }"
253
+ >
254
+ <UButton
255
+ size="sm"
256
+ variant="ghost"
257
+ label="Change"
258
+ trailing-icon="i-lucide-chevron-down"
259
+ />
260
+ </UDropdownMenu>
261
+ <UButton
262
+ v-else
263
+ size="sm"
264
+ variant="ghost"
265
+ label="Change"
266
+ @click="open"
267
+ />
268
+ <UButton
269
+ size="sm"
270
+ color="neutral"
271
+ variant="ghost"
272
+ icon="i-lucide-x"
273
+ :aria-label="`Remove ${name || 'file'}`"
274
+ @click="field.clear()"
275
+ />
276
+ </template>
277
+ </div>
278
+ </div>
279
+ </template>
280
+ </MLMediaDropzone>
281
+ </UFormField>
282
+ </template>
@@ -0,0 +1,65 @@
1
+ import type { MediaUploadOptions } from '../../composables/useMLMediaUpload.js';
2
+ type __VLS_Props = {
3
+ /** Asset kinds the field takes: ['image'], "image,video". Empty means any file. */
4
+ accept?: readonly string[] | string;
5
+ label?: string;
6
+ /** Under the field. Defaults to what the field accepts and its size limit. */
7
+ hint?: string;
8
+ required?: boolean;
9
+ disabled?: boolean;
10
+ /** Bytes. */
11
+ maxSize?: number | null;
12
+ /** Shows "No alt text" on a filled image field. Alt text lives on the host record. */
13
+ missingAlt?: boolean;
14
+ /** Upload session settings for new files. */
15
+ visibility?: MediaUploadOptions['visibility'];
16
+ processingConfig?: MediaUploadOptions['processingConfig'];
17
+ collectionName?: string | null;
18
+ /** Show "Select existing", which opens the library picker. */
19
+ picker?: boolean;
20
+ /** Replaces the built-in picker, e.g. with the host's own dialog. */
21
+ onPick?: () => void;
22
+ /** Show the eye button on the thumbnail, which opens the media editor. */
23
+ editor?: boolean;
24
+ /** Label for the editor's remove button. Empty hides it. */
25
+ removeLabel?: string;
26
+ /** Replaces the built-in editor. Receives the asset ID. */
27
+ onOpen?: (assetId: string) => void;
28
+ };
29
+ type __VLS_ModelProps = {
30
+ modelValue?: string | null;
31
+ /** Alt text for the file, stored on the host record. Edited in the media editor. */
32
+ 'alt'?: string | undefined;
33
+ };
34
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
35
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
36
+ uploaded: (assetId: string) => any;
37
+ "update:modelValue": (value: string | null) => any;
38
+ "update:alt": (value: string | undefined) => any;
39
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
40
+ onUploaded?: ((assetId: string) => any) | undefined;
41
+ "onUpdate:modelValue"?: ((value: string | null) => any) | undefined;
42
+ "onUpdate:alt"?: ((value: string | undefined) => any) | undefined;
43
+ }>, {
44
+ visibility: "private" | "restricted" | "public";
45
+ label: string;
46
+ accept: readonly string[] | string;
47
+ maxSize: number | null;
48
+ processingConfig: {
49
+ stepOptions?: Record<string, Record<string, unknown>> | null;
50
+ useFilenameAsAssetId?: boolean;
51
+ enableTranscription?: boolean;
52
+ };
53
+ collectionName: string | null;
54
+ disabled: boolean;
55
+ required: boolean;
56
+ removeLabel: string;
57
+ hint: string;
58
+ missingAlt: boolean;
59
+ picker: boolean;
60
+ onPick: () => void;
61
+ editor: boolean;
62
+ onOpen: (assetId: string) => void;
63
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
64
+ declare const _default: typeof __VLS_export;
65
+ export default _default;
@@ -0,0 +1,19 @@
1
+ import type { AssetDetail, DeliveryAsset } from '../../types/asset.js';
2
+ import { type AssetFact } from '../../utils/assetFormat.js';
3
+ type __VLS_Props = {
4
+ /** Derives size, dimensions, duration, pages, type and date. */
5
+ asset?: AssetDetail | DeliveryAsset | null;
6
+ /** Explicit facts; shown instead of the derived ones. */
7
+ items?: AssetFact[];
8
+ /** Appended to whichever list is used, e.g. a dedup hint. */
9
+ extra?: AssetFact[];
10
+ title?: string;
11
+ };
12
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
13
+ asset: AssetDetail | DeliveryAsset | null;
14
+ title: string;
15
+ items: AssetFact[];
16
+ extra: AssetFact[];
17
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
18
+ declare const _default: typeof __VLS_export;
19
+ export default _default;
@@ -0,0 +1,38 @@
1
+ <script setup>
2
+ import { computed } from "vue";
3
+ import { assetFacts } from "../../utils/assetFormat";
4
+ const props = defineProps({
5
+ asset: { type: [Object, null], required: false, default: null },
6
+ items: { type: Array, required: false, default: void 0 },
7
+ extra: { type: Array, required: false, default: () => [] },
8
+ title: { type: String, required: false, default: "File" }
9
+ });
10
+ const facts = computed(() => [...props.items ?? assetFacts(props.asset), ...props.extra]);
11
+ </script>
12
+
13
+ <template>
14
+ <section
15
+ v-if="facts.length"
16
+ class="flex flex-col gap-1.5"
17
+ >
18
+ <h4
19
+ v-if="title"
20
+ class="text-[11px] font-semibold uppercase tracking-wider text-dimmed"
21
+ >
22
+ {{ title }}
23
+ </h4>
24
+ <dl class="grid grid-cols-[auto_minmax(0,1fr)] gap-x-3 gap-y-1 text-xs">
25
+ <template
26
+ v-for="fact in facts"
27
+ :key="fact.label"
28
+ >
29
+ <dt class="text-muted">
30
+ {{ fact.label }}
31
+ </dt>
32
+ <dd class="text-right tabular-nums [overflow-wrap:anywhere]">
33
+ {{ fact.value }}
34
+ </dd>
35
+ </template>
36
+ </dl>
37
+ </section>
38
+ </template>
@@ -0,0 +1,19 @@
1
+ import type { AssetDetail, DeliveryAsset } from '../../types/asset.js';
2
+ import { type AssetFact } from '../../utils/assetFormat.js';
3
+ type __VLS_Props = {
4
+ /** Derives size, dimensions, duration, pages, type and date. */
5
+ asset?: AssetDetail | DeliveryAsset | null;
6
+ /** Explicit facts; shown instead of the derived ones. */
7
+ items?: AssetFact[];
8
+ /** Appended to whichever list is used, e.g. a dedup hint. */
9
+ extra?: AssetFact[];
10
+ title?: string;
11
+ };
12
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
13
+ asset: AssetDetail | DeliveryAsset | null;
14
+ title: string;
15
+ items: AssetFact[];
16
+ extra: AssetFact[];
17
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
18
+ declare const _default: typeof __VLS_export;
19
+ export default _default;
@@ -0,0 +1,23 @@
1
+ import type { MediaUploadOptions } from '../../composables/useMLMediaUpload.js';
2
+ type __VLS_Props = {
3
+ accept?: readonly string[] | string;
4
+ max?: number;
5
+ selected?: readonly string[];
6
+ title?: string;
7
+ maxSize?: number | null;
8
+ upload?: MediaUploadOptions;
9
+ };
10
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
11
+ close: (ids: string[] | null) => any;
12
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
13
+ onClose?: ((ids: string[] | null) => any) | undefined;
14
+ }>, {
15
+ title: string;
16
+ accept: readonly string[] | string;
17
+ maxSize: number | null;
18
+ max: number;
19
+ selected: readonly string[];
20
+ upload: MediaUploadOptions;
21
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
22
+ declare const _default: typeof __VLS_export;
23
+ export default _default;
@@ -0,0 +1,33 @@
1
+ <script setup>
2
+ defineProps({
3
+ accept: { type: [Array, String], required: false, default: "" },
4
+ max: { type: Number, required: false, default: Number.POSITIVE_INFINITY },
5
+ selected: { type: Array, required: false, default: () => [] },
6
+ title: { type: String, required: false, default: "Select file" },
7
+ maxSize: { type: [Number, null], required: false, default: null },
8
+ upload: { type: Object, required: false, default: () => ({}) }
9
+ });
10
+ const emit = defineEmits(["close"]);
11
+ </script>
12
+
13
+ <template>
14
+ <UModal
15
+ :title="title"
16
+ :description="Number.isFinite(max) && max > 1 ? `Choose up to ${max} files` : void 0"
17
+ :close="{ onClick: () => emit('close', null) }"
18
+ :ui="{ content: 'sm:max-w-4xl', body: 'p-0 sm:p-0' }"
19
+ @update:open="(open) => !open && emit('close', null)"
20
+ >
21
+ <template #body>
22
+ <MLMediaFilePickerPanel
23
+ :accept="accept"
24
+ :max="max"
25
+ :selected="selected"
26
+ :max-size="maxSize"
27
+ :upload="upload"
28
+ @done="(ids) => emit('close', ids)"
29
+ @cancel="emit('close', null)"
30
+ />
31
+ </template>
32
+ </UModal>
33
+ </template>
@@ -0,0 +1,23 @@
1
+ import type { MediaUploadOptions } from '../../composables/useMLMediaUpload.js';
2
+ type __VLS_Props = {
3
+ accept?: readonly string[] | string;
4
+ max?: number;
5
+ selected?: readonly string[];
6
+ title?: string;
7
+ maxSize?: number | null;
8
+ upload?: MediaUploadOptions;
9
+ };
10
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
11
+ close: (ids: string[] | null) => any;
12
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
13
+ onClose?: ((ids: string[] | null) => any) | undefined;
14
+ }>, {
15
+ title: string;
16
+ accept: readonly string[] | string;
17
+ maxSize: number | null;
18
+ max: number;
19
+ selected: readonly string[];
20
+ upload: MediaUploadOptions;
21
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
22
+ declare const _default: typeof __VLS_export;
23
+ export default _default;
@@ -0,0 +1,33 @@
1
+ import { type MediaUploadOptions } from '../../composables/useMLMediaUpload.js';
2
+ type __VLS_Props = {
3
+ /** Kinds the caller takes. Others are listed but dimmed. Empty means any. */
4
+ accept?: readonly string[] | string;
5
+ /** Most files that can be chosen. 1 makes clicks replace the choice. */
6
+ max?: number;
7
+ /** IDs already attached. Listed first and checked. */
8
+ selected?: readonly string[];
9
+ title?: string;
10
+ /** Bytes, for uploads from the picker. */
11
+ maxSize?: number | null;
12
+ /** Upload session settings for files dropped into the picker. */
13
+ upload?: MediaUploadOptions;
14
+ /** Grid rows for a fixed-height body; the list scrolls inside it. */
15
+ bodyClass?: string;
16
+ };
17
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
18
+ cancel: () => any;
19
+ done: (ids: string[]) => any;
20
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
21
+ onCancel?: (() => any) | undefined;
22
+ onDone?: ((ids: string[]) => any) | undefined;
23
+ }>, {
24
+ title: string;
25
+ accept: readonly string[] | string;
26
+ maxSize: number | null;
27
+ max: number;
28
+ selected: readonly string[];
29
+ upload: MediaUploadOptions;
30
+ bodyClass: string;
31
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
32
+ declare const _default: typeof __VLS_export;
33
+ export default _default;