Attachment & Dropzone
File chips with image thumbnails or type icons, size, a springing upload bar, error state and remove; the list springs chips in and closes the gap. FileDropzone wraps a real file input: click, keyboard and the native picker work, drop and paste are checked against accept and maxSize, and dropped files land in the input so forms and Server Actions receive them.
- summer-montage.mp448.3 MB
- sponsor-brief.pdfUpload failed. Try again.
import { FileDropzone } from "@/components/ui/attachment";import { Button } from "@/components/ui/button";import { uploadClips } from "./actions"; // "use server": (formData) => formData.getAll("clips")// Picked and dropped files both land in the input, so the Server Action gets them.export function ClipUpload() { return ( <form action={uploadClips} className="grid gap-3"> <FileDropzone name="clips" multiple accept="video/*" maxSize={500 * 1024 * 1024} required /> <Button type="submit">Upload</Button> </form> );}"use client";import { Attachment, AttachmentList } from "@/components/ui/attachment";type File = { id: string; name: string; size: number; type: string; progress?: number;};export function Attachments({ files, onRemove,}: { files: File[]; onRemove: (id: string) => void;}) { return ( <AttachmentList aria-label="Attachments"> {files.map((f) => ( <Attachment key={f.id} name={f.name} size={f.size} type={f.type} progress={f.progress} onRemove={() => onRemove(f.id)} /> ))} </AttachmentList> );}<Attachment>
File chip: thumbnail or type icon, name, size, upload progress or error, and remove.
name*stringFile name.
errorstringReplaces the size line and turns the chip red.
hrefstringMakes the name a download link.
localestringBCP 47 locale for the size.
onRemove() => voidShows a remove button; called when it is pressed.
progressnumber0 to 100 while uploading; the bar springs along the bottom edge.
sizenumberBytes.
srcstringThumbnail source: a URL, or
URL.createObjectURL(file)for a fresh upload.typestringMIME type; picks the icon, and image types show
srcas a thumbnail.
| Prop | Type | Default |
|---|---|---|
name*File name. | string | — |
errorReplaces the size line and turns the chip red. | string | — |
hrefMakes the name a download link. | string | — |
localeBCP 47 locale for the size. | string | — |
onRemoveShows a remove button; called when it is pressed. | () => void | — |
progress0 to 100 while uploading; the bar springs along the bottom edge. | number | — |
sizeBytes. | number | — |
srcThumbnail source: a URL, or | string | — |
typeMIME type; picks the icon, and image types show | string | — |
<AttachmentList>
Attachments that spring in, out and into place when one is removed. Key each child.
Also accepts every <ul> prop (none of its own).
<FileDropzone>
Drop area around a real file input: click, Enter/Space and the native picker work as-is, and dropped files are written back into the input so plain forms and Server Actions get them.
acceptstringSame syntax as the input attribute: ".pdf,image/*". Enforced on drop and paste too.
aria-describedbystringIds of hint or error text; Field fills it in.
aria-invalidbooleanError styling; Field sets it from
error.childrenReactNodeReplaces the default "Drop files or browse" content.
disabledbooleanBlocks drops and the picker.
idstringId of the file input; Field fills it in.
maxSizenumberBytes.
multiplebooleanAccept more than one file.
namestringForm field name: picked and dropped files both submit with the form.
onFiles(files: File[]) => voidFiles that passed
acceptandmaxSize, from a drop or the picker.onReject(rejected: Rejection[]) => voidFiles that failed
acceptormaxSize, each with a reason.requiredbooleanForm submit needs at least one file.
| Prop | Type | Default |
|---|---|---|
acceptSame syntax as the input attribute: ".pdf,image/*". Enforced on drop and paste too. | string | — |
aria-describedbyIds of hint or error text; Field fills it in. | string | — |
aria-invalidError styling; Field sets it from | boolean | — |
childrenReplaces the default "Drop files or browse" content. | ReactNode | — |
disabledBlocks drops and the picker. | boolean | — |
idId of the file input; Field fills it in. | string | — |
maxSizeBytes. | number | — |
multipleAccept more than one file. | boolean | — |
nameForm field name: picked and dropped files both submit with the form. | string | — |
onFilesFiles that passed | (files: File[]) => void | — |
onRejectFiles that failed | (rejected: Rejection[]) => void | — |
requiredForm submit needs at least one file. | boolean | — |
formatBytes()
Bytes as text in the given locale: 1536 is "1.5 kB".
formatBytes(bytes: number, locale?: string) => string
- type Rejection
- { file: File; reason: "type" | "size" }
* required. Every component also takes className.