This commit is contained in:
Benjamin Canac
2025-07-21 14:27:28 +02:00
parent 891d66cdb1
commit 0da34cd8e5
2 changed files with 14 additions and 9 deletions

View File

@@ -64,6 +64,10 @@ const state = reactive<Partial<schema>>({
const upload = useUpload('/api/blob', { method: 'PUT' })
function createObjectUrl(file: File): string {
return URL.createObjectURL(file)
}
async function onSubmit(event: FormSubmitEvent<schema>) {
const res = await upload(event.data.avatar)
@@ -79,9 +83,9 @@ async function onSubmit(event: FormSubmitEvent<schema>) {
<UForm :schema="schema" :state="state" class="space-y-4 w-80" @submit="onSubmit">
<UFormField name="avatar" label="Avatar" description="JPG, GIF or PNG. 1MB Max." :size="size">
<UFileUpload v-slot="{ open, reset, urls }" v-model="state.avatar" accept="image/*">
<UFileUpload v-slot="{ open, reset }" v-model="state.avatar" accept="image/*">
<div class="flex flex-wrap items-center gap-3">
<UAvatar size="lg" :src="urls?.[0]" icon="i-lucide-image" />
<UAvatar size="lg" :src="state.avatar ? createObjectUrl(state.avatar) : undefined" icon="i-lucide-image" />
<UButton :label="state.avatar ? 'Change image' : 'Upload image'" color="neutral" @click="open()" />
</div>
@@ -107,11 +111,8 @@ async function onSubmit(event: FormSubmitEvent<schema>) {
<UFileUpload
label="Drop your image here"
description="SVG, PNG, JPG or GIF (max. 2MB)"
multiple
class="w-full"
:size="size"
/>
<UFileUpload multiple />
</div>
</template>

View File

@@ -81,7 +81,9 @@ import { useAppConfig } from '#imports'
import { useFormField } from '../composables/useFormField'
import { useFileUpload } from '../composables/useFileUpload'
import { tv } from '../utils/tv'
import UAvatar from './Avatar.vue'
import UButton from './Button.vue'
import UIcon from './Icon.vue'
defineOptions({ inheritAttrs: false })
@@ -164,7 +166,7 @@ defineExpose({
<div :class="ui.wrapper({ class: props.ui?.wrapper })">
<div :class="ui.leading({ class: props.ui?.leading })">
<slot name="leading">
<UIcon :name="icon || appConfig.ui.icons.upload" :class="ui.leadingIcon({ class: props.ui?.icon })" />
<UIcon :name="icon || appConfig.ui.icons.upload" :class="ui.leadingIcon({ class: props.ui?.leadingIcon })" />
</slot>
</div>
@@ -187,11 +189,13 @@ defineExpose({
</div>
</div>
<div v-if="modelValue && (modelValue as File[]).length > 0" :class="ui.files({ class: props.ui?.files })">
<div v-if="modelValue" :class="ui.files({ class: props.ui?.files })">
<slot name="files">
<div v-for="(file, index) in Array.isArray(modelValue) ? modelValue : [modelValue]" :key="file.name" class="min-w-0 flex items-center gap-2 border border-default rounded-md p-2">
<div v-for="(file, index) in Array.isArray(modelValue) ? modelValue : [modelValue]" :key="(file as File).name" class="min-w-0 flex items-center gap-2 border border-default rounded-md p-2">
<UAvatar :src="createObjectUrl(file)" :icon="appConfig.ui.icons.file" />
<span class="text-sm truncate">{{ file.name }}</span>
<span class="text-sm truncate">{{ (file as File).name }}</span>
<UButton
size="xs"
color="neutral"