FilePicker
A dropzone you drag files onto, or press to open the file dialog. It checks size, type and count, and reports back what it turned away.
import { FilePicker } from 'neba';
<FilePicker
multiple
label="Attachments"
accept="image/*,.pdf"
maxSize={5_000_000}
maxFiles={4}
onFilesChange={setFiles}
onReject={setRejected}
/>;Props
| Prop | Type | Default | Description |
|---|---|---|---|
| variantshared | 'solid' | 'outline' | 'text' | 'outline' | Weight of the surface. All three share the dashed edge: the one place the library draws a line that is not solid, because a dashed rectangle is the established sign for a drop target |
| sizeshared | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | The box's padding and type scale. A dropzone is sized by the gesture it has to catch, not by what is written in it |
| colorshared | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info' | 'primary' | Semantic colour role. Arbitrary colour values are not accepted |
| densityshared | 'default' | 'compact' | 'default' | Padding only: never the height, never the type scale |
| elevationshared | 0 | 1 | 2 | 3 | 0 | Drop shadow depth. 0 means no shadow at all |
| accept | string | — | Which files the browser's own picker offers: 'image/*,.pdf'. Dropped files are checked against it too, which the attribute alone does not do |
| multiple | boolean | false | Whether more than one file may be chosen |
| maxSize | number | — | The largest a single file may be, in bytes |
| maxFiles | number | — | How many files may be held at once: counted against what is already chosen, not against one drop |
| value | readonly File[] | — | The chosen files, for a controlled picker |
| defaultValue | readonly File[] | — | The initially chosen files |
| onFilesChange | (files: File[]) => void | — | Called when the list of files changes |
| onReject | (rejections: FileRejection[]) => void | — | Called with everything turned away, and why. Without it a rejected file disappears silently, which is the worst thing a dropzone does |
| title | ReactNode | — | The line inside the box |
| hint | ReactNode | — | The line under it: what is accepted, how big, how many |
| icon | ReactNode | — | The glyph above the title. Pass null for a box with no picture in it |
| showList | boolean | true | Lists the chosen files under the box, each with a way to remove it |
| removeLabel | (name: string) => string | — | Accessible name of a file's remove button |
| label | ReactNode | — | The label, wired to the control by Base UI's Field |
| description | ReactNode | — | Helper text |
| error | ReactNode | — | Error message. Its presence turns the control invalid and re-points the colour family at danger |
| invalid | boolean | !!error | Forces the invalid state without a message, for when a form library owns validity |
| readOnly | boolean | false | Shown but not changeable. Keeps its colour and edge, drains the saturation |
| disabled | boolean | false | Unavailable. Drops the colour family for neutral grey |
| fullWidth | boolean | true | Stretches to the width of the container |
| required | boolean | false | Whether a file must be chosen before the form is submitted |
| name | string | — | Identifies the field when a form is submitted |
Native <div> attributes pass through to the root. Only color, defaultValue and title are excluded, since the table above spells them differently.
Examples
variant
All three weights share the dashed edge, which is the established sign that an area accepts a drop.
accept · maxSize · maxFiles
The browser's accept attribute only governs its own file dialog and never a file that arrived by drag, so this component runs the same string itself. All three forms are supported: .ext, type/subtype and type/*.
maxFiles is not how many may be dropped at once but how many may be held in total. Dropping three files on a maxFiles={3} picker that already holds two accepts exactly one.
onReject
Reports the files that were turned away and why. Without this handler a rejected file disappears with no feedback, so always pass it.
disabled · readOnly · error
title · hint · icon · showList
title and hint are the copy inside the dropzone and icon the glyph above it. showList renders the chosen files under the zone, and removeLabel names each remove button.
Accessibility
- The shell is a
<div>and the pressable area inside it is a real<button>. The file list sits outside that button, so the remove buttons are never nested inside the browse button. - The
<input type="file">is moved off-screen rather than set todisplay: none, which makes an input unfocusable in some browsers and would blockrequiredvalidation messages. - The drag state is tracked by counting events, so it does not flicker as the pointer crosses children of the dropzone.