Skip to content

Commit

Permalink
feat(VFileUpload): support slot to override filename display
Browse files Browse the repository at this point in the history
feat(VFileUpload): added logic to show filename when input is set as multiple
feat(VFileUploadImageTheme): added support for previewClass prop

docs(VFileUpload): add story to showcase customizing filename slot
  • Loading branch information
gretchelin authored and gravitano committed Jan 6, 2023
1 parent 0394561 commit 835f9cc
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 11 deletions.
12 changes: 12 additions & 0 deletions docs/components/file-input.md
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,18 @@ Use the `hint` slot to add a hint or a description to the file input.
</template>
```

### `filename`

Use the `filename` slot to customize displayed filename text

```vue
<template>
<VFileUpload>
<template #filename> A file has been chosen. </template>
</VFileUpload>
</template>
```

### `error`

Use the `error` slot to customize the error message displayed when the file input has an error. The slot receives an object with the following properties:
Expand Down
103 changes: 103 additions & 0 deletions packages/forms/src/file-input/VFileUpload.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,3 +270,106 @@ export const InitialValues: Story<{}> = () => ({
</form>
`,
});

export const SlotFilename: Story<{}> = () => ({
components: {VInput, VBtn, VFileUpload},
setup() {
const schema = object({
avatar: mixed().required().label('Avatar'),
banner: mixed().required().label('Banner'),
document: mixed().required().label('Document'),
});

const {handleSubmit, resetForm, values} = useForm({
validationSchema: schema,
initialValues: {
avatar: 'https://picsum.photos/200/300',
banner: 'https://picsum.photos/200/300',
document: 'https://picsum.photos/200/300',
},
});

const onSubmit = handleSubmit((values) => {
alert(JSON.stringify(values));
});

return {onSubmit, resetForm, values};
},
template: `
<form @submit="onSubmit" class="border-none">
<v-file-upload
wrapper-class="mb-4 WRAPPER"
theme="image"
name="avatar"
label="Avatar w/ image preview"
placeholder="Pick your best photo"
class='TEST_CLASSs'
preview-class='relative'
rounded
image
preview
multiple
>
<template #filename="{value}">
<div class='bg-[#0000008a] text-white text-xs p-2 absolute bottom-0 left-0 w-full'>
The filename is overriden here. {{ value }}
</div>
</template>
</v-file-upload>
<v-file-upload
wrapper-class="mb-4"
theme="image"
name="avatar"
label="Avatar w/o image preview"
placeholder="Pick your best photo"
rounded
preview
multiple
>
<template #filename="{value}">
<div class="text-xs">
The filename is overriden here. {{ value }}
</div>
</template>
</v-file-upload>
<v-file-upload
wrapper-class="mb-4"
theme="dropzone"
name="banner"
label="Banner"
placeholder="Choose banner image"
image
preview
multiple
>
<template #filename="{value}">
<div class="text-sm">
The filename is overriden here. {{ value }}
</div>
</template>
</v-file-upload>
<v-file-upload
wrapper-class="mb-4"
name="document"
label="Document"
placeholder="Pick PDF File"
accept="application/pdf"
multiple
>
<template #filename="{value}">
<div class="text-sm text-gray-400 italic">
The filename is overriden here. {{ value }}
</div>
</template>
</v-file-upload>
<div class="mt-4">
<v-btn type="submit">Submit</v-btn>
<v-btn type="button" text @click="resetForm">Reset</v-btn>
</div>
<pre>{{ {values} }}</pre>
</form>
`,
});
40 changes: 36 additions & 4 deletions packages/forms/src/file-input/VFileUpload.vue
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,21 @@ const fileName = computed(() => {
return innerValue.value.split('/').pop();
}
if((innerValue.value as any)?.length) {
let str = '';
for(let i = 0; i < (innerValue.value as any)?.length; i+=1) {
const f = innerValue?.value ? (innerValue.value as Record<any, any>)[i] as any : {};
if(i > 0){
str += ', ';
}
str += f?.name || '';
}
return str;
}
return getFileValue('name', '');
});
Expand Down Expand Up @@ -343,7 +358,11 @@ const borderClass = computed(() => {
}"
@choose="pickFile"
@remove="removeFile"
/>
>
<template v-slot:filename>
<slot name="filename" />
</template>
</VFileUploadButtonTheme>

<VFileUploadImageTheme
v-else-if="theme === 'image'"
Expand All @@ -358,9 +377,14 @@ const borderClass = computed(() => {
hasFile,
loadingText,
browseText,
previewClass,
}"
@choose="pickFile"
/>
>
<template v-slot:filename="slotData">
<slot name="filename" v-bind="slotData"/>
</template>
</VFileUploadImageTheme>

<VFileUploadDropzoneTheme
v-else-if="theme === 'dropzone'"
Expand All @@ -386,7 +410,11 @@ const borderClass = computed(() => {
@dropped="handleFiles"
@choose="pickFile"
@remove="removeFile"
/>
>
<template v-slot:filename="slotData">
<slot name="filename" v-bind="slotData"/>
</template>
</VFileUploadDropzoneTheme>

<VFileUploadDefaultTheme
v-else
Expand All @@ -404,7 +432,11 @@ const borderClass = computed(() => {
}"
@choose="pickFile"
@remove="removeFile"
/>
>
<template v-slot:filename="slotData">
<slot name="filename" v-bind="slotData"/>
</template>
</VFileUploadDefaultTheme>

<input
:id="id"
Expand Down
6 changes: 4 additions & 2 deletions packages/forms/src/file-input/VFileUploadButtonTheme.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,12 @@ const emit =
rounded
hover:border-gray-400
"
:class="[disabledClass, borderClass]"
:class='[disabledClass, borderClass]'
@click="emit('choose')"
>
{{ fileName }}
<slot name="filename" :value="filename">
{{ fileName }}
</slot>
</div>
<v-btn
v-if="readonly"
Expand Down
1 change: 1 addition & 0 deletions packages/forms/src/file-input/VFileUploadDefaultTheme.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,5 @@ const emit =
</div>
</template>
</VInput>
<slot name="filename" :value="fileName" />
</template>
9 changes: 6 additions & 3 deletions packages/forms/src/file-input/VFileUploadDropzoneTheme.vue
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,12 @@ onUnmounted(() => {
backgroundImage: !loading ? `url(${previewURL})` : 'none',
}"
></div>
<div v-if="fileName" class="text-gray-500 text-sm">
{{ fileName }}
</div>

<slot name='filename' :value='fileName'>
<div v-if="fileName" class="text-gray-500 text-sm">
{{ fileName }}
</div>
</slot>
</div>
</slot>

Expand Down
8 changes: 6 additions & 2 deletions packages/forms/src/file-input/VFileUploadImageTheme.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type Props = {
hasFile?: boolean;
loadingText?: string;
browseText?: string;
previewClass?: string;
};
const props = withDefaults(defineProps<Props>(), {
Expand Down Expand Up @@ -43,19 +44,22 @@ const backgroundImage = computed(() =>
cursor-pointer
flex flex-col
items-center
items-center
justify-center
py-10
bg-no-repeat bg-contain bg-center
max-w-full
"
:class="[sizeClass, {'rounded-lg': rounded}, borderClass]"
:class="[sizeClass, {'rounded-lg': rounded}, borderClass, previewClass]"
:style="{backgroundImage}"
type="button"
@click="emit('choose')"
>
<v-spinner v-if="loading" color="primary" large />
<div v-else-if="hasFile" class="px-2 text-center">
{{ image ? '' : fileName }}
<slot name="filename" :value="fileName">
{{ image ? '' : fileName }}
</slot>
</div>
<template v-else>
<Icon
Expand Down

0 comments on commit 835f9cc

Please sign in to comment.