File picker
The drop zone sibling of VFileInput: a surface rather than a field, with the same screening rules and the same list of files as its value.
Usage
Examples
Title and subtitle
title is required and subtitle is where the rules go in plain words. Both have a slot, taking text and inline elements only.
The list of files
preview says where the list of chosen files goes, under the zone or beside it, or removes it. Beside, it folds back underneath as soon as the component is narrow.
Custom icons
icon is the large glyph at the top of the zone. typeIcons replaces the glyph a row shows for a kind of file, naming only the kinds you want to change, and removeIcon the button that takes a row out.
Thumbnails
An image is listed as itself, through a temporary address made in the page. hideThumbnails shows the icon for its kind instead.
Multiple files
multiple lets the zone take several files, the extra ones being turned away otherwise. The value is a list either way, and reject fires once per refused file.
Accepted kinds
accept takes the browser syntax and filters the system dialog as well as a dropped file. A file that fails it comes back through reject with the reason type.
Maximum size
maxSize is the largest one file may be, in bytes. Each file is weighed on its own.
Total size and count
maxTotalSize and maxFiles bound the selection as a whole, counting what is already in the list. Screening runs in a fixed order: kind, then size, then count, then total size.
States
readonly shows what was taken and lets nothing change it, the remove buttons included. disabled greys the zone out and stops it accepting anything, mid-drag included.
API
Props
| Prop | Type | Default |
|---|---|---|
title | string | none |
| What the reader is being asked to drop, in one line. It is required: a drop zone with no instruction is just a rectangle. It shadows the HTML attribute of the same name, an accepted trade-off. | ||
subtitle | string | none |
| A second line under it, for the constraints in plain words: kinds, sizes, how many. | ||
icon | IconSource | cloud_upload |
| The large icon at the top of the zone. | ||
hideBrowse | boolean | false |
| Hides the separator and the browse button under the instruction. That changes the nature of the zone: it then becomes the control itself, a real button, so Enter, Space and the focus come from the platform rather than from a container that merely reacts to clicks. | ||
browseText | string | none |
| The wording drawn on the browse button, which is also its accessible name. It falls back to the design system dictionary. | ||
preview | FilePickerPreviewfalse | 'bottom' | 'end' | false |
| Where the files taken are listed: under the zone, or beside it, which folds back underneath when the component is narrow, following the width it was given rather than the width of the window. By default nothing is listed at all. | ||
hideThumbnails | boolean | false |
| Shows the kind icon for every file in that list, images included, the way out when a list holds many images or very large ones. Left out, an image is shown as a thumbnail: it is given a temporary address, created in the browser only and released as soon as the file leaves the list or the component goes away. | ||
typeIcons | Partial<Record<FilePickerKind, IconSource>> | none |
| Replaces the icon of one or more kinds of file. | ||
removeIcon | IconSource | close |
| The icon of the button removing a file from the list. | ||
multiple | boolean | false |
| Allows several files to be taken. With one only, every extra file is turned away. | ||
accept | string | none |
| Which kinds of file are accepted, in the browser's own syntax. It is applied twice: as an attribute, which filters the system's file dialog, and again in code, which is the only thing that can filter a dropped file. | ||
maxSize | number | none |
| The largest one file may be, in bytes. | ||
maxTotalSize | number | none |
| The largest the whole selection may be, in bytes. | ||
maxFiles | number | none |
| How many files may be taken at most. | ||
disabled | boolean | false |
| Makes the zone unusable, greyed out through the colour tokens. | ||
readonly | boolean | false |
| Shows what was taken without allowing it to change: no dialog, no drop, no removal. Its buttons stay reachable from the keyboard, announced as unavailable. | ||
invalid | boolean | false |
| Marks the zone as invalid, which colours its outline and is announced on the control the reader reaches. It is for a rule of your own: nothing here is checked by the browser, the real input being hidden. | ||
loading | boolean | false |
| Shows a spinner in place of the zone icon, while an upload is under way typically. It says that something is happening and changes nothing else: files can still be dropped and the dialog still opens. | ||
loadingText | string | none |
| What screen readers announce while the spinner turns. It falls back to the design system dictionary. | ||
v-model | File[] | [] |
| Always a list of files, whether or not several are allowed, never a file on its own. The shape does not depend on a prop, so you never have to narrow a union TypeScript cannot discriminate. | ||
Events
| Event | Type |
|---|---|
change | [files: File[]] |
| The selection changed, with the whole list as it now stands. | |
reject | [rejection: FileRejection] |
| A file was turned away, with which one and why. | |
remove | [file: File, index: number] |
| A file was removed from the list, with which one and where it was. | |
Slots
| Slot | Type |
|---|---|
icon | {} |
| The large icon, for an illustration the icon prop cannot express. It must stay non-interactive, and so must the two below: with the browse button hidden the zone is a button, and nothing interactive may sit inside one. | |
title | {} |
| The instruction. Text and inline elements only, for the same reason. | |
subtitle | {} |
| The second line. Same contract as the instruction. | |
browse | FilePickerBrowseSlotProps |
The browse button. Call the open it receives: without it a button of your own could no longer open the file dialog at all. | |
item | FilePickerRow |
| A whole row of the list, the way out for a row showing its own upload progress. It receives everything the standard row was given. | |
thumbnail | FilePickerRow |
| The square at the start of a row alone: for a thumbnail produced by your server, a video's poster frame, or a format the browser cannot decode. | |
remove | FilePickerRemoveSlotProps |
The control that removes a row. remove is the only thing that can take the file out, and removeLabel is the ready-made accessible name, including the file's own, without which the button would be announced as nothing at all. | |
Types
The types the tables above name, written as the library declares them. The ones carrying export can be imported from vectis-ui to type your own code; the others are the shape of what a slot hands out.
export interface BuiltinIcon {
name: string
paths: readonly [string] | readonly [string, string]
}export interface FilePickerBrowseSlotProps {
open: () => void
disabled: boolean
}export type FilePickerKind = 'image' | 'pdf' | 'audio' | 'video' | 'archive' | 'spreadsheet' | 'code' | 'file'
export interface FilePickerRemoveSlotProps {
file: File
index: number
remove: () => void
removeLabel: string
}export interface FilePickerRow {
file: File
index: number
kind: FilePickerKind
thumbnail: string | undefined
icon: IconSource
sizeText: string
remove: () => void
}export type FileRejectReason = 'type' | 'size' | 'count' | 'total-size'
export interface FileRejection {
file: File
reason: FileRejectReason
}export type IconRender =
| { path: string; viewBox?: string }
| { component: Component; props?: Record<string, unknown> }
| { src: string }
| { text: string; class?: string }
| { class: string }export type IconSource = string | BuiltinIcon | IconRender
CSS variables
| Token | Value |
|---|---|
--vectis-control-size-file-picker-min-block | 10rem |
--vectis-control-size-file-picker-icon | 2.5rem |
--vectis-control-size-file-picker-thumb | 2.5rem |