From 1d692fb5246d0ebf9921290e21a71decdd7413ce Mon Sep 17 00:00:00 2001 From: Benjamin Canac Date: Fri, 18 Jul 2025 18:38:27 +0200 Subject: [PATCH] up --- .../app/pages/components/file-upload.vue | 5 ++- src/runtime/components/FileUpload.vue | 38 +++++++++++++++++-- src/theme/file-upload.ts | 14 ++++--- src/theme/icons.ts | 1 + 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/playground/app/pages/components/file-upload.vue b/playground/app/pages/components/file-upload.vue index 80a035df..52f8712b 100644 --- a/playground/app/pages/components/file-upload.vue +++ b/playground/app/pages/components/file-upload.vue @@ -73,9 +73,9 @@ async function onSubmit(event: FormSubmitEvent) {
- +
- +
@@ -105,6 +105,7 @@ async function onSubmit(event: FormSubmitEvent) { :size="size" label="Drop your image here" description="SVG, PNG, JPG or GIF (max. 2MB)" + multiple />
diff --git a/src/runtime/components/FileUpload.vue b/src/runtime/components/FileUpload.vue index 33903937..13d056a2 100644 --- a/src/runtime/components/FileUpload.vue +++ b/src/runtime/components/FileUpload.vue @@ -24,10 +24,16 @@ export interface FileUploadProps { label?: string description?: string actions?: ButtonProps[] + /** + * @defaultValue 'primary' + */ + color?: FileUpload['variants']['color'] /** * @defaultValue 'md' */ size?: FileUpload['variants']['size'] + /** Highlight the ring color like a focus state. */ + highlight?: boolean required?: boolean disabled?: boolean multiple?: M & boolean @@ -57,7 +63,11 @@ export interface FileUploadEmits { } export interface FileUploadSlots { - default(props: { open: UseFileDialogReturn['open'], reset: UseFileDialogReturn['reset'] }): any + default(props: { + open: UseFileDialogReturn['open'] + reset: UseFileDialogReturn['reset'] + urls: string[] + }): any leading(props?: {}): any label(props?: {}): any description(props?: {}): any @@ -105,10 +115,14 @@ const { isOverDropZone } = useDropZone(dropZoneRef, { }) const { emitFormInput, id, name, disabled, ariaAttrs } = useFormField(props, { deferInputValidation: true }) +const urls = computed(() => Array.from(files.value || []).map(file => URL.createObjectURL(file))) + const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.fileUpload || {}) })({ dropzone: props.dropzone, multiple: props.multiple, - size: props.size + color: props.color, + size: props.size, + highlight: props.highlight })) onChange((files) => { @@ -121,6 +135,17 @@ function onDrop(files: File[] | null) { modelValue.value = (props.multiple ? files : files?.[0]) as (M extends true ? File[] : File) | null } +function removeFile(index: number) { + const file = files.value?.[index] + + if (file) { + URL.revokeObjectURL(URL.createObjectURL(file)) + } + + const fileListArr = Array.from(files.value!) + fileListArr.splice(index, 1) +} + defineExpose({ inputRef }) @@ -128,12 +153,13 @@ defineExpose({