From 59892297442c7dd6a558e794d909abaa56c1a41a Mon Sep 17 00:00:00 2001 From: Benjamin Canac Date: Mon, 21 Jul 2025 15:33:58 +0200 Subject: [PATCH] up --- .../app/pages/components/file-upload.vue | 10 ++- src/runtime/components/FileUpload.vue | 72 ++++++++++++------- src/theme/file-upload.ts | 6 +- 3 files changed, 56 insertions(+), 32 deletions(-) diff --git a/playground/app/pages/components/file-upload.vue b/playground/app/pages/components/file-upload.vue index b747e4cc..b9a7cfdc 100644 --- a/playground/app/pages/components/file-upload.vue +++ b/playground/app/pages/components/file-upload.vue @@ -85,7 +85,7 @@ async function onSubmit(event: FormSubmitEvent) { - +
@@ -101,7 +101,7 @@ async function onSubmit(event: FormSubmitEvent) { variant="link" size="xs" class="p-0" - @click="reset()" + @click="remove()" />

@@ -117,6 +117,10 @@ async function onSubmit(event: FormSubmitEvent) { class="w-full" multiple :size="size" - /> + > + +
diff --git a/src/runtime/components/FileUpload.vue b/src/runtime/components/FileUpload.vue index 7300e835..12ca8a76 100644 --- a/src/runtime/components/FileUpload.vue +++ b/src/runtime/components/FileUpload.vue @@ -2,7 +2,7 @@ import type { AppConfig } from '@nuxt/schema' import type { UseFileDialogReturn } from '@vueuse/core' import theme from '#build/ui/file-upload' -import type { AvatarProps, ButtonProps } from '../types' +import type { ButtonProps } from '../types' import type { ComponentConfig } from '../types/utils' type FileUpload = ComponentConfig @@ -53,6 +53,12 @@ export interface FileUploadProps { * @defaultValue true */ dropzone?: boolean + /** + * The icon to display for the file. + * @defaultValue appConfig.ui.icons.file + * @IconifyIcon + */ + fileIcon?: string class?: any ui?: FileUpload['slots'] } @@ -65,12 +71,15 @@ export interface FileUploadEmits { export interface FileUploadSlots { 'default'(props: { open: UseFileDialogReturn['open'] + remove: (index?: number) => void }): any 'leading'(props?: {}): any 'label'(props?: {}): any 'description'(props?: {}): any 'actions'(props?: {}): any 'files'(props: { files: M extends true ? File[] : File | null }): any + 'files-top'(props: { remove: (index?: number) => void }): any + 'files-bottom'(props: { remove: (index?: number) => void }): any 'file'(props: { file: File, index: number }): any 'file-leading'(props: { file: File, index: number }): any 'file-name'(props: { file: File, index: number }): any @@ -130,21 +139,6 @@ function createObjectUrl(file: File): string { return URL.createObjectURL(file) } -function onUpdate(files: File[]) { - if (props.multiple) { - const existingFiles = (modelValue.value as File[]) || [] - modelValue.value = [...existingFiles, ...(files || [])] as (M extends true ? File[] : File) | null - } else { - modelValue.value = files?.[0] as (M extends true ? File[] : File) | null - } - - // @ts-expect-error - 'target' does not exist in type 'EventInit' - const event = new Event('change', { target: { value: modelValue.value } }) - emits('change', event) - emitFormChange() - emitFormInput() -} - function formatFileSize(bytes: number): string { if (bytes === 0) { return '0B' @@ -160,18 +154,40 @@ function formatFileSize(bytes: number): string { return `${formattedSize}${sizes[i]}` } -function removeFile(index: number) { +function onUpdate(files: File[], reset = false) { + console.log('onUpdate', files) + if (props.multiple) { + if (reset) { + modelValue.value = files as (M extends true ? File[] : File) | null + } else { + const existingFiles = (modelValue.value as File[]) || [] + modelValue.value = [...existingFiles, ...(files || [])] as (M extends true ? File[] : File) | null + } + } else { + modelValue.value = files?.[0] as (M extends true ? File[] : File) | null + } + + // @ts-expect-error - 'target' does not exist in type 'EventInit' + const event = new Event('change', { target: { value: modelValue.value } }) + emits('change', event) + emitFormChange() + emitFormInput() +} + +function remove(index?: number) { if (!modelValue.value) { return } - const fileList = Array.from(modelValue.value as File[]) + if (!props.multiple || !index) { + onUpdate([], true) + return + } - fileList.splice(index, 1) + const files = Array.from(modelValue.value as File[]) + files.splice(index, 1) - modelValue.value = fileList as (M extends true ? File[] : File) | null - - emitFormInput() + onUpdate(files, true) } defineExpose({ @@ -181,7 +197,7 @@ defineExpose({