- Accordion
- Avatar
- Badge
- Breadcrumb
- Button
- Calendar
- ChatContainer
- ChatInput
- ChatMessage
- ChatMultiChoiceQuestion
- ChatMultiOptionQuestion
- ChatThinking
- Checkbox
- Combobox
- Container
- CurrencyInput
- DistributionSlider
- Drawer
- Dropdown
- FilePicker
- Grid
- Heading
- Image
- Input
- InputGroup
- Label
- Logo
- MapPin
- Markdown
- Modal
- NativeSelect
- NumberInput
- OptionSlider
- OtpInput
- PhoneInput
- Popover
- Progress
- PropertyCalendar
- RadioGroup
- RadioGroupCards
- ResponsiveModal
- ScrollArea
- SearchBar
- SearchBarFallback
- SearchInput
- Select
- Separator
- Spinner
- Switch
- Table
- Tabs
- Text
- Textarea
- TimePicker
- Toast
- Toggle
- ToggleCard
- ToggleGroup
- Toolbar
- Tooltip
FilePicker
Lets users select files via a native trigger, drag-and-drop zone, or compact chat-style affordance, with optional file list and constraints
pnpm add @wandercom/design-system-web
import {
FilePicker,
FilePickerItem,
} from '@wandercom/design-system-web/ui/file-picker';
export function Example() {
const [files, setFiles] = useState<File[]>([]);
return (
<FilePicker onFilesAccepted={setFiles} value={files} />
);
}A compact native-style trigger that opens the file picker on click. Shows the selected filenames or a placeholder.
<FilePicker
onFilesAccepted={setFiles}
value={files}
/>A bordered drop region with a cloud-upload icon, title, helper text, and a primary "Select files" button. Helper text is generated automatically from accept and maxSize, or can be overridden via the description prop.
<FilePicker
variant="dropzone"
accept={{
'image/jpeg': ['.jpg', '.jpeg'],
'image/png': ['.png'],
'application/pdf': ['.pdf'],
'video/mp4': ['.mp4'],
}}
maxSize={50 * 1024 * 1024}
onFilesAccepted={(files) => attach(files)}
/>For chat composers, pair FilePickerChatTrigger (a secondary icon button that opens the picker) with FilePickerChatThumbnail (a 28x42 image preview chip). Both render independently so the trigger and uploaded previews can sit anywhere in the composer.
import {
FilePickerChatThumbnail,
FilePickerChatTrigger,
} from '@wandercom/design-system-web/ui/file-picker';
<FilePickerChatTrigger
accept={{ 'image/*': ['.jpg', '.jpeg', '.png'] }}
onFilesAccepted={(files) => attach(files)}
/>
<FilePickerChatThumbnail
src={previewUrl}
alt="Uploaded screenshot"
onRemove={() => removeAttachment(id)}
/>Wrap selected files in FilePickerList (resets browser default <ul> margin / padding / list-style and stretches each <li> to full width) and render rows with FilePickerItem. For images, pass an object URL (or any image URL) via previewUrl to show the actual asset as a thumbnail; for non-image files the extension is rendered as a fallback. Pass loading for in-flight uploads (replaces the trash button with a spinner) and error (boolean or message string) to surface a failed state. Provide onRemove to display a ghost trash button on idle rows.
<FilePickerItem
name="wander-villa-sunset.jpg"
size={2_400_000}
previewUrl={URL.createObjectURL(imageFile)}
onRemove={() => removeFile(id)}
/>accept and maxSize are forwarded to react-dropzone for validation and also drive the dropzone helper text. Pass onFilesRejected to surface validation errors.
<FilePicker
variant="dropzone"
accept={{ 'application/pdf': ['.pdf'] }}
maxSize={10 * 1024 * 1024}
onFilesAccepted={(files) => handleUpload(files)}
onFilesRejected={(rejections) => toast.error(rejections[0]?.errors[0]?.message)}
/>variant?
accept?
maxSize?
maxFiles?
multiple?
disabled?
title?
description?
chooseFileLabel?
value?
onFilesAccepted?
onFilesRejected?
className?
name
size
previewUrl?
previewAlt?
extension?
onRemove?
loading?
error?
uploadingLabel?
className?
className?
children
accept?
maxSize?
maxFiles?
multiple?
onFilesAccepted?
onFilesRejected?
aria-label?
src
alt?
onRemove?
loading?
uploadingLabel?
removeLabel?
className?
The underlying react-dropzone hook gives the dropzone region role="button" and tabIndex={0} so it is reachable by keyboard. The visually hidden <input type="file"> remains in the DOM for screen reader users, and Enter / Space open the picker.
For icon-only triggers (FilePickerChatTrigger, the remove button on FilePickerItem, and the optional remove overlay on FilePickerChatThumbnail), an aria-label is provided by default. Override it via the aria-label prop when the surrounding context calls for a more specific name.
When disabled is true the trigger is removed from the tab order and click / drop interactions are blocked.