0

Attachment

Displays a file or image attachment with media, metadata, upload state, and actions.

Workspace
workspace.pngPNG · 820 KB
Desk
desk-reference.jpgJPG · 1.1 MB
Office
office-reference.jpgJPG · 940 KB
sales-dashboard.pdfUploading · 64%
message-renderer.tsxTypeScript · 12 KB
import { IconFileCode, IconX } from "@tabler/icons-react"

import {

Installation

bunx --bun shadcn@latest add @ondo-ui/attachment

Usage

import {
  Attachment,
  AttachmentAction,
  AttachmentActions,
  AttachmentContent,
  AttachmentDescription,
  AttachmentMedia,
  AttachmentTitle,
} from "@/components/ui/attachment"
<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>

Composition

Use the following composition to build an attachment:

Attachment
├── AttachmentMedia
├── AttachmentContent
│   ├── AttachmentTitle
│   └── AttachmentDescription
├── AttachmentActions
│   └── AttachmentAction
└── AttachmentTrigger

Use AttachmentGroup to lay out multiple attachments in a scrollable row:

AttachmentGroup
├── Attachment
└── Attachment

Examples

Image

Set variant="image" on AttachmentMedia and render an <img> inside it. Use orientation="vertical" to stack the media above the content.

Workspace
workspace.pngPNG · 820 KB
Desk
desk-reference.jpgJPG · 1.1 MB
Office
office-reference.jpgJPG · 940 KB
import { IconX } from "@tabler/icons-react"

import {

States

Set state to reflect the upload lifecycle. uploading and processing shimmer the title, and error switches to a destructive treatment.

selected-file.pdfReady to upload
design-system.zipUploading · 64%
market-research.pdfProcessing document
financial-model.xlsxUpload failed. Try again.
uploaded-report.pdfUploaded · 1.8 MB
import {
  IconCheck,
  IconClock,

Sizes

Use size to switch between default, sm, and xs.

Default attachmentPDF · 2.4 MB
Small attachmentPDF · 2.4 MB
Extra small attachment
import { IconFileText } from "@tabler/icons-react"

import {

Group

Wrap attachments in AttachmentGroup to lay them out in a horizontally scrollable, snapping row with an edge fade.

briefing-notes.pdfPDF · 1.4 MB
workspace.png
workspace.pngPNG · 820 KB
customers.csvCSV · 18 KB
renderer.tsxTSX · 12 KB
import { IconFileCode, IconFileText, IconTable, IconX } from "@tabler/icons-react"
import { type FC, type SVGProps } from "react"

Trigger

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.pdfOpen preview dialog
import { IconCopy, IconFileSearch, IconX } from "@tabler/icons-react"

import {

API reference

Attachment

The root attachment container.

PropTypeDefaultDescription
state"idle" | "uploading" | "processing" | "error" | "done""done"The upload state. Drives styling and the shimmer.
size"default" | "sm" | "xs""default"The attachment size.
orientation"horizontal" | "vertical""horizontal"Lay the media beside or above the content.
classNamestring-Additional classes to apply to the root element.

AttachmentMedia

The media slot for an icon or image preview.

PropTypeDefaultDescription
variant"icon" | "image""icon"Whether the media holds an icon or an <img>.
classNamestring-Additional classes to apply to the media slot.

AttachmentContent

Wraps the title and description.

PropTypeDefaultDescription
classNamestring-Additional classes to apply to the content slot.

AttachmentTitle

The attachment name. Shimmers while the attachment is uploading or processing.

PropTypeDefaultDescription
classNamestring-Additional classes to apply to the title.

AttachmentDescription

Secondary metadata such as the file type, size, or upload status.

PropTypeDefaultDescription
classNamestring-Additional classes to apply to the description.

AttachmentActions

A container for one or more actions, aligned to the end of the attachment.

PropTypeDefaultDescription
classNamestring-Additional classes to apply to the actions.

AttachmentAction

An action button. Renders a Button and accepts all of its props.

PropTypeDefaultDescription
sizeButton["size"]"icon-xs"The button size.
...propsReact.ComponentProps<typeof Button>-Props spread to the underlying Button.

AttachmentTrigger

A full-card overlay that activates the attachment. Renders a <button> by default.

PropTypeDefaultDescription
renderReactElement | function-Render as a different element, such as a link.
...propsReact.ComponentProps<"button">-Props spread to the trigger element.

AttachmentGroup

Lays out attachments in a horizontally scrollable, snapping row.

PropTypeDefaultDescription
classNamestring-Additional classes to apply to the group.