Appearance
BnFileInput
BnFileInput is a wrapper for <input type="file">
elements, designed to work with v-model
to simplify management. It returns a file list if it allows multiple files or a single file if it's not.
Basic Usage
The only required prop for BnFileInput
is name
. The name
prop is used to identify the input in the context of a Form
or an useForm
, or when submitting a form in the traditional way.
html
<bn-file-input v-model="file" name="name" />
Input Attributes
The BnFileInput
component inherits all attributes that a native <input type="file">
element would accept but, since its appearance is customized, some attributes may not work as expected. Common attributes are disabled
and multiple
:
html
<bn-file-input name="disabled" placeholder="Disabled" disabled />
<bn-file-input name="multiple" placeholder="Multiple" multiple />
Variants
The variant
prop can be used to change the appearance of the input. There are two variants included by default: default
and avatar
.
html
<bn-file-input name="default" placeholder="Default" />
<bn-file-input name="avatar" variant="avatar" />
Default Appearance
The default appearance is a button with a text label. The buttonText
prop can be used to change the text of the button. The placeholder
prop can be used to change the text of the placeholder.
html
<bn-file-input name="default" placeholder="Default" buttonText="Click me!" />
Avatar
The avatarShape
prop can be used to change the shape of the avatar. It can be default
or circle
.
html
<bn-file-input name="default" variant="avatar" />
<bn-file-input name="circle" variant="avatar" avatar-shape="circle" />
Vee-Validate
BnFileInput works with vee-validate out of the box.
vue
<script setup lang="ts">
import { Form } from 'vee-validate';
import isRequired from '../rules';
const validationSchema = {
file: isRequired,
};
</script>
<template>
<Form :validation-schema="validationSchema">
<bn-file-input name="file"/>
</Form>
</template>
Rules
If you want to validate a field without being in the context of a Form
or an useForm
, you can use the rules
prop.
WARNING
The rules
prop will be ignored if the component is inside a Form
or an useForm
context with a validationSchema
.
vue
<script setup lang="ts">
import isRequired from '../rules';
</script>
<template>
<bn-file-input
v-model="validate"
name="validation"
:rules="isRequired"
/>
</template>
[TODO] Colors
You can change the color accent of the default variants of the file input using the color
prop.
html
<bn-file-input name="input" color="lime" />
<bn-file-input name="avatar" color="lime" variant="avatar" />
TIP
The color
prop only supports the colors set when configuring the library. See Colors for more information.
Slots
default
The default
slot allows you to customize the appearance of the entire BnFileInput
component. It includes the following slot props:
imagePreviewPath
: A function that takes a file as input and generates a URL to preview itdisabled
: A boolean indicating whether the input is disabledopenFileDialog
: A function that allows you to open the file upload windowremoveFile
: A function that removes the provided file from the value. If the input allows a single file, it sets the value toundefined
. If it allows multiple files, it removes the selected file from the listaddFile
: A function that adds a file. If the input allows a single file, it replaces the older file with the new one. If it allows multiple files, it adds the file to the listvalue
: The input value. If it's a single file input, it returns a file object. If it's a multiple file input, it returns a file list
html
<bn-file-input
v-model="file"
name="file"
>
<template #default="{ imagePreviewPath, openFileDialog, value, addFile, removeFile, disabled }">
<div class="w-full">
<button
v-if="value"
class="mb-2 rounded border border-gray-300 py-1 px-2 text-sm shadow"
@click="addFile()"
>
Add File
</button>
<button
v-else
class="mb-2 rounded border border-gray-300 py-1 px-2 text-sm shadow"
@click="openFileDialog()"
>
Browse
</button>
<ul
v-if="value"
class="w-full"
>
<li
class="flex w-full items-center border border-t-0 p-1 text-sm first:border-t"
>
<img
:src="imagePreviewPath(value)"
class="mr-2 h-6 w-6 rounded-full"
>
<span class="truncate">{{ value.name }}</span> ({{ value.size / 1000 }} KB)
<button
class="ml-auto"
@click="removeFile(value)"
>
🗑
</button>
</li>
</ul>
</div>
</template>
</bn-file-input>
bottom
The bottom
slot is used to add content below the input. Useful for hints or errors. Includes the following slot props:
errorMessage
:vee-validate
property, if the input is invalidvalid
:vee-validate
meta propertytouched
:vee-validate
meta property
html
<bn-file-input
v-model="file"
name="required"
:rules="isRequired"
>
<template #bottom="{ errorMessage, valid, touched }">
<div
v-if="!valid && touched"
class="mt-1 flex items-center text-rose-700"
>
<svg
viewBox="0 0 24 24"
class="fill-none mr-1 h-4 w-4 stroke-current stroke-2"
>
<path
:d="warningIcon"
/>
</svg>
<span class="mr-1">
{{ errorMessage }}
</span>
<svg
viewBox="0 0 24 24"
class="fill-none mr-1 h-4 w-4 stroke-current stroke-2"
>
<path
:d="warningIcon"
/>
</svg>
</div>
</template>
</bn-file-input>
Customization
There are two ways to customize the appearance of the BnFileInput
component:
classes
prop
Every component has a classes
prop that will accept an object where each key corresponds to an internal element of the component. The value of each key will be the classes that will be applied to that element. For the values, you can use strings, objects or arrays, the same way it works with Vue's class binding.
html
<bn-file-input name="input" :classes="{ button: 'rounded-full' }" />
Default styles will still be applied, but the classes you provide will take precedence, so you can use this to override any existing style.
The available keys for this component are:
wrapper
: The element surrounding everything but thebottom
slotbutton
: The button that opens the file dialogavatar
: The<button>
element when using theavatar
variant. It contains the preview when file is selectedlabel
: The element that contains either the placeholder or the file name and clear buttonplaceholder
: The element that contains the placeholder text when no file is selectedclear-button
: The button that clears the selected file(s)
Theming
You can change the default appearance or even add variants by editing the configuration of the TailwindCSS plugin.
javascript
plugins: [
require('@tailwindcss/forms'),
require('@headlessui/tailwindcss'),
banano.tailwindPlugin({
theme: {
BnInput: {
'.bn-file-input': {
'@apply bg-green-600': {},
}
}
}
}),
],
You can find more information about customizing the library in Theme Customization.
API Reference
Props
Prop | Default | Description |
---|---|---|
modelValue | undefined | FileType (File[] | File | undefined ) Initial value for the file input. Can be a single file, an array of files, or undefined. |
name | -- | string The name attribute of the file input. |
color | 'banano-base' | string Determines the color of the file input. |
rules | undefined | RuleExpression<FileType> Validation rules for the checkbox. Usually a function that receives the value of the component and returns a boolean or a string if invalid. |
multiple | false | boolean If true, the file input will accept multiple files. |
disabled | false | boolean If true, the file input will be disabled. |
buttonText | 'Browse' | string The text displayed on the file input button. |
placeholder | 'No file selected' | string The placeholder text for the file input when no file is selected. |
variant | 'default' | 'default' | 'avatar' The variant of the file input. |
avatarShape | 'default' | string The shape of the avatar in the file input. |
classes | {} | object Allows to customize the classes of the file input's elements. |
Events
Event | Payload | Description |
---|---|---|
focus | Event | Emitted when the file input is focused. |
blur | Event | Emitted when the file input is blurred |
Slots
Slot | Slot Props | Description |
---|---|---|
default |
| Use to input the content inside the file input wrapper. openFileDialog function can be used to open the file dialog. disabled is a boolean indicating whether the file input is disabled. imagePreviewPath function can be used to get the preview path of a file. removeFile function can be used to remove a file from the file input. addFile function can be used to add a file to the file input. value is the current value of the file input. |
bottom |
| Use to input the content at the bottom of the file input. errorMessage is the validation error message. valid is a boolean indicating whether the file input value is valid. touched is a boolean indicating whether the file input has been touched. |