Attachment

A file attached to a message or composer — preview, metadata, actions, and upload states.

quarterly-report.pdf1.2 MB · PDF
<Attachment>
  <AttachmentMedia>
    <FileTextIcon />
  </AttachmentMedia>
  <AttachmentContent>
    <AttachmentTitle>quarterly-report.pdf</AttachmentTitle>
    <AttachmentDescription>1.2 MB · PDF</AttachmentDescription>
  </AttachmentContent>
  <AttachmentActions>
    <AttachmentAction aria-label="Remove attachment">
      <XIcon />
    </AttachmentAction>
  </AttachmentActions>
</Attachment>

Installation

npx shadcn@latest add @dotui/attachment

Usage

import {
  Attachment,
  AttachmentContent,
  AttachmentDescription,
  AttachmentMedia,
  AttachmentTitle,
} from "@/ui/attachment"
<Attachment>
  <AttachmentMedia>
    <FileTextIcon />
  </AttachmentMedia>
  <AttachmentContent>
    <AttachmentTitle>quarterly-report.pdf</AttachmentTitle>
    <AttachmentDescription>1.2 MB · PDF</AttachmentDescription>
  </AttachmentContent>
</Attachment>

Anatomy

Attachment is the card; its state walks the upload lifecycle — idle renders a dashed outline, uploading and processing pulse the title, and error switches to the danger treatment. AttachmentMedia holds a file-type icon or an image thumbnail, AttachmentActions holds icon buttons that stay pressable even when an AttachmentTrigger stretches a click target over the whole card. A scrolling row of attachments goes in an AttachmentGroup.

import {
  Attachment,
  AttachmentAction,
  AttachmentActions,
  AttachmentGroup,
  AttachmentTrigger,
} from "@/ui/attachment"
<AttachmentGroup>
  <Attachment state="uploading">
    {/* media, content… */}
    <AttachmentActions>
      <AttachmentAction aria-label="Cancel upload">
        <XIcon />
      </AttachmentAction>
    </AttachmentActions>
    <AttachmentTrigger aria-label="Open file" onClick={openFile} />
  </Attachment>
</AttachmentGroup>

Examples

States

screen-recording.mp4Uploading… 34%
design-specs.figUpload failed

Sizes

quarterly-report.pdf1.2 MB · PDF
quarterly-report.pdf1.2 MB · PDF
quarterly-report.pdf1.2 MB · PDF

Vertical

hero-banner.png640 KB

Group

notes.md4 KB
styles.ts12 KB
tokens.json8 KB

API Reference

Attachment

A file attached to a message or a composer — an icon or image preview, a name, metadata, and actions, with upload states.

Supports all div attributes.

PropType
union
"md" | "sm" | "xs"
"horizontal" | "vertical"

AttachmentMedia

The attachment's visual — a file-type icon or an image thumbnail.

Supports all div attributes.

PropType
"icon" | "image"

AttachmentContent

The attachment's text column — title and description.

Supports all div attributes.

PropType

AttachmentTitle

The file name. Truncates, and pulses while the file uploads or processes.

Supports all span attributes.

PropType

AttachmentDescription

Metadata under the title — file size, type, or an error message.

Supports all span attributes.

PropType

AttachmentActions

The attachment's action row — remove, retry, download.

Supports all div attributes.

PropType

AttachmentAction

A single icon action. Renders a quiet, icon-only button.

PropType
boolean
ReactNode | function
boolean

AttachmentTrigger

An invisible button stretched over the attachment, making the whole card clickable while the actions stay independently pressable.

Supports all button attributes.

PropType

AttachmentGroup

A horizontally scrolling row of attachments with snap points.

Supports all div attributes.

PropType

Last updated on 8/31/2026