sales-dashboard.pdf Uploading · 64%
message-renderer.tsx TypeScript · 12 KB
The Attachment component displays a file or image attachment, its media, name, and metadata, with optional actions and upload state. Use it for files and images in chat composers, message threads, and upload lists.
Copy import {
Attachment,
AttachmentAction,
AttachmentActions,
AttachmentContent,
AttachmentDescription,
AttachmentMedia,
AttachmentTitle,
} from "@/components/ui/attachment"
Copy < Attachment >
< AttachmentMedia >
< FileTextIcon />
</ AttachmentMedia >
< AttachmentContent >
< AttachmentTitle > sales-dashboard.pdf </ AttachmentTitle >
< AttachmentDescription > PDF · 2.4 MB </ AttachmentDescription >
</ AttachmentContent >
< AttachmentActions >
< AttachmentAction aria-label = "Remove sales-dashboard.pdf" >
< XIcon />
</ AttachmentAction >
</ AttachmentActions >
</ Attachment >
Use the following composition to build an attachment:
Copy Attachment
├── AttachmentMedia
├── AttachmentContent
│ ├── AttachmentTitle
│ └── AttachmentDescription
├── AttachmentActions
│ └── AttachmentAction
└── AttachmentTrigger
Use AttachmentGroup to lay out multiple attachments in a scrollable row:
Copy AttachmentGroup
├── Attachment
└── Attachment
Icon and image media through AttachmentMedia
Upload states: idle, uploading, processing, error, and done with built-in styling and a shimmer while in progress
Three sizes and horizontal or vertical orientation
A full-card AttachmentTrigger that opens a link or dialog while the actions stay independently clickable
Scrollable, snapping AttachmentGroup with an edge fade
Customizable styling through the className prop on every part
Set variant="image" on AttachmentMedia and render an <img> inside it. Use orientation="vertical" to stack the media above the content.
Set state to reflect the upload lifecycle. uploading and processing shimmer the title, and error switches to a destructive treatment.
selected-file.pdf Ready to upload
design-system.zip Uploading · 64%
market-research.pdf Processing document
financial-model.xlsx Upload failed. Try again.
uploaded-report.pdf Uploaded · 1.8 MB
Use size to switch between default, sm, and xs.
Default attachment PDF · 2.4 MB
Small attachment PDF · 2.4 MB
Wrap attachments in AttachmentGroup to lay them out in a horizontally scrollable, snapping row with an edge fade.
Add an AttachmentTrigger to make the whole card open a link or dialog. It fills the card behind the actions, so the actions stay clickable.
research-summary.pdf Open preview dialog
Copy < Dialog >
< Attachment >
{ /* media, content, actions */ }
< DialogTrigger
render ={ < AttachmentTrigger aria-label = "Preview research-summary.pdf" /> }
/>
</ Attachment >
< DialogContent > { /* ... */ } </ DialogContent >
</ Dialog >
AttachmentAction renders a Button, and AttachmentTrigger renders a real <button> (or your element via render). Follow the guidance below so both are operable and announced.
AttachmentAction is usually icon-only, so give each one an aria-label describing the action and its target.
Copy < AttachmentAction aria-label = "Remove sales-dashboard.pdf" >
< XIcon />
</ AttachmentAction >
AttachmentTrigger covers the card with no text of its own, so give it an aria-label for what activating it does.
Copy < AttachmentTrigger
render ={
< a
href ={ url }
target = "_blank"
rel = "noreferrer"
aria-label = "Open workspace.png"
/>
}
/>
The trigger sits behind the actions in the stacking order, so an AttachmentAction and the AttachmentTrigger never trap each other, both remain separately focusable and clickable.
An AttachmentGroup scrolls horizontally. When its attachments are interactive: a trigger or actions, keyboard users reach off-screen items by tabbing to them. For a row of presentational attachments, make the group itself focusable and scrollable by adding tabIndex={0}, role="group", and an aria-label.
The error state uses a destructive color. Keep the failure reason in AttachmentDescription so the state is not conveyed by color alone.
The root attachment container.
The media slot for an icon or image preview.
Wraps the title and description.
The attachment name. Shimmers while the attachment is uploading or processing.
Secondary metadata such as the file type, size, or upload status.
A container for one or more actions, aligned to the end of the attachment.
An action button. Renders a Button and accepts all of its props.
A full-card overlay that activates the attachment. Renders a <button> by default.
Lays out attachments in a horizontally scrollable, snapping row.