File dropzone
import { FileDropzone } from '@yarcl/react';
<FileDropzone label="Attachments" description="Images or PDF files" accept="image/*,.pdf" multiple onFilesChange={(files) => upload(files)}/>The button opens the native file picker. Files can also be dropped on the bordered area. accept filters dropped files as well as picker selections. multiple shows a file list with remove buttons. Use the render prop to provide your own list:
<FileDropzone label="Attachments" multiple> {(files, removeFile) => ( <ul> {files.map((file, index) => ( <li key={`${file.name}-${index}`}> {file.name} <button type="button" onClick={() => removeFile(index)}>Remove</button> </li> ))} </ul> )}</FileDropzone>Use onFilesChange to upload or validate the selected files. Upload progress belongs to the upload request, so render it beside this component.
Single file and image preview
Section titled “Single file and image preview”Without multiple, the dropzone shows one current file with Replace and Remove controls. Pass preview to show a thumbnail for a selected image. Use value with onChange for a controlled picker, or defaultValue for an uncontrolled initial file.
const [cover, setCover] = useState<File | null>(null);
<FileDropzone label="Course cover" accept="image/*" value={cover} onChange={setCover} preview/>For an existing image hosted by your app, pass previewUrl and previewName. Clear the URL in your onChange handler when the user replaces or removes it:
<FileDropzone label="Course cover" accept="image/*" value={cover} onChange={(file) => { setCover(file); setCoverUrl(undefined); }} preview previewUrl={coverUrl} previewName="Current cover"/>onFilesChange still receives an array in either mode for existing upload handlers. In single-file mode, onChange receives the file or null after removal.
Controlled multi-file uploads
Section titled “Controlled multi-file uploads”With multiple, use files and onFilesChange to own the selected list, or defaultFiles for an uncontrolled initial list. Picker selections and drops replace the list after applying accept; removing a file proposes a new list. A controlled picker displays the parent’s files until the parent updates them. Pass [] to clear it after an upload. Arrays can be readonly and are never mutated.
import { useState } from 'react';import { FileDropzone } from '@yarcl/react';
function Attachments() { const [files, setFiles] = useState<readonly File[]>([]); return ( <FileDropzone label="Attachments" multiple files={files} onFilesChange={setFiles} /> );}For upload-on-select, leave files={[]} and start the request in onFilesChange. Display progress and uploaded attachments in your own list. The native input resets after every selection, allowing the same file to be picked again. Cancelling the picker or selecting only rejected files leaves the list unchanged.
files and defaultFiles apply only to multi-file mode. value, defaultValue, onChange, and preview props apply only to single-file mode. Choose the API that matches multiple.
Open the picker from another control
Section titled “Open the picker from another control”inputRef exposes the existing native file input. Call its click() from a user action, such as a Replace button. This opens the same picker with the same accept, multiple, disabled state and callbacks. The regular ref still targets the outer div. Object refs and React 19 callback refs with cleanup are supported.
import { useRef } from 'react';import { Button, FileDropzone } from '@yarcl/react';
function AttachmentPicker() { const inputRef = useRef<HTMLInputElement>(null); return ( <> <Button onClick={() => inputRef.current?.click()}>Replace attachment</Button> <FileDropzone label="Attachments" inputRef={inputRef} onFilesChange={(files) => upload(files)} /> </> );}Browsers require a user action to open a file picker. Disable an external Replace control when the dropzone is disabled. Set the attachment being replaced in your own state before opening the picker; the component handles file selection, while your app decides which upload to replace.
Custom copy and accessibility
Section titled “Custom copy and accessibility”Use labels to override picker and drop instructions locally, or translate config.labels for the whole app:
<FileDropzone label="Attachments" multiple labels={{ chooseFiles: 'Browse attachments', dropFiles: 'Drop attachments here', removeItem: (name) => `Delete ${name}`, }}/>The visible label names the group. The picker button works with Enter and Space; the hidden input stays out of the tab sequence. Selected files are announced through a polite live region, and Remove buttons include each file’s name. Disabled controls ignore picking and dropping. Keep uploaded-file actions outside the dropzone’s internal list when they belong to a separate server-side attachment state.
| Prop | Type | Default | Description |
|---|---|---|---|
label required | string | Visible label for the picker and drop area. | |
accept | string | Accepted extensions or MIME types, as on a native file input. | |
children | (files: readonly File[], removeFile: (index: number) => void) => ReactNode | Custom file list renderer. Receives the files and a remove function. | |
defaultFiles | readonly File[] | Initial files in uncontrolled multi-file mode. | |
defaultValue | File | null | Initial file in uncontrolled single-file mode. | |
description | string | Optional helper text below the label. | |
disabled | boolean | Disables picking and dropping files. | |
files | readonly File[] | Selected files in multi-file mode. Pass an empty array to reset after uploading. | |
inputRef | Ref<HTMLInputElement> | Native picker input. Call inputRef.current?.click() from an external button. | |
labels | Partial<FileDropzoneLabels> | Overrides the active catalog for this picker. Unspecified entries keep config labels. | |
multiple | boolean | Allows more than one file. | |
onChange | (file: File | null) => void | Called with the selected file or null when it is removed in single-file mode. | |
onFilesChange | (files: File[]) => void | Called whenever the selected file list changes. | |
preview | boolean | Shows a thumbnail when the selected file is an image. | |
previewName | string | Name shown for a remote file supplied through previewUrl. | |
previewUrl | string | Image URL for an existing remote file in single-file mode. | |
value | File | null | Selected file in single-file mode. Use null for no file. |