Shadcn Attachment Components

A component for displaying file attachments with media previews, upload states, and actions. The examples integrate cleanly with projects built on Radix UI or Base UI. Browse our collection of 5 Shadcn Attachment variants.

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

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

Default attachmentPDF · 2.4 MB
Small attachmentPDF · 2.4 MB
Extra small attachment

briefing-notes.pdfPDF · 1.4 MB
workspace.png
workspace.pngPNG · 820 KB
customers.csvCSV · 18 KB
renderer.tsxTSX · 12 KB
Unlock premium components
Get full control of shadcn/ui components, blocks and instances, including future additions.

Explore Shadcn Blocks

Ready-made page sections built with the same components.

View all blocks

Shadcn Attachment Component

The Shadcn Attachment is a compact file card that shows a file a user has picked, is uploading or has already sent. It pairs an icon or image preview with the file name, a line of metadata such as type and size, and optional actions like remove, cancel or retry. Chat composers, AI prompt inputs, support tickets and comment threads all need this pattern.

Image galleries with square previews, uploading cards with a cancel action and a single list that walks through all five upload states make up this collection. The shadcn attachment component is plain markup built with shadcn/ui, React and Tailwind CSS, and only AttachmentTrigger uses the Radix Slot for asChild, so it drops into Radix UI or Base UI projects without changes.

What is the Shadcn Attachment Component?

An attachment is a presentational building block: it displays a file, it does not select one. The root accepts a state prop (idle, uploading, processing, error or done), a size prop (default, sm or xs) and an orientation prop for horizontal chips or vertical image tiles. Each state changes the styling for you: idle cards get a dashed border, uploading and processing titles shimmer, and error cards turn the border and media destructive.

Use it whenever a file needs to be shown. When the user has to pick files with a drop zone, start with the File Upload component and render each selected file as an attachment. For a single profile photo an Avatar is a better fit, and for rows of content that are not files, such as settings or contacts, use the Item component.

Anatomy of the Shadcn Attachment

PartDescription
AttachmentThe root card. Takes state, size and orientation and exposes them as data attributes for styling.
AttachmentMediaThe square thumbnail. Use variant="icon" for a file type icon or spinner and variant="image" for an image preview.
AttachmentContentWraps the title and description and handles truncation.
AttachmentTitleThe file name. Long names are truncated, and the text shimmers while the file is uploading or processing.
AttachmentDescriptionMuted metadata under the title, such as type and size, upload progress or an error message.
AttachmentActionsThe slot for action buttons. In vertical tiles it floats in the top right corner of the preview.
AttachmentActionA ghost Button with the icon-xs size by default, used for remove, cancel or retry.
AttachmentTriggerAn optional overlay button that makes the whole card clickable, for example to open a preview. Supports asChild to render a link.
AttachmentGroupA horizontal, scroll snapping row that lays out several attachments side by side.

5 Shadcn Attachment Variants

Each attachment variant listed here is previewed live at the top of this page, together with its source code and install command.

  • Image gallery: Vertical tiles with square image previews, file names and sizes, arranged in a scrollable group for photos and screenshots.
  • Uploading and file card: An uploading file with a spinner, a progress label and a cancel action, next to a finished code file with a remove button.
  • Upload states: All five states stacked in one list: idle, uploading, processing, error with a retry action, and done.
  • Sizes: The default, sm and xs sizes side by side, from a full file card to a small chip for tight composers.
  • Mixed file group: A horizontal group that mixes a PDF, an image, a CSV and a source file, each with its own icon or preview and a remove action.

How to Install the Shadcn Attachment Component

Set up shadcn/ui in your project if you have not already, then add the Shadcn UI Kit registry to your components.json once:

{
  "registries": {
    "@shadcnuikit": "https://shadcnuikit.com/r/{name}.json"
  }
}

Then install a attachment variant by its name:

npx shadcn@latest add @shadcnuikit/attachment1

The same command works with pnpm dlx, yarn dlx and bunx --bun. Each variant has a copy button for every package manager, and the code is added to your project as plain React and Tailwind CSS that you can edit freely.

How to Use the Shadcn Attachment Component

Import the parts you need from components/ui/attachment. Pass the upload status to state and put progress or metadata in the description.

import { FileTextIcon, XIcon } from "lucide-react"

import {
  Attachment,
  AttachmentAction,
  AttachmentActions,
  AttachmentContent,
  AttachmentDescription,
  AttachmentMedia,
  AttachmentTitle,
} from "@/components/ui/attachment"

export function ReportAttachment({ onRemove }: { onRemove: () => void }) {
  return (
    <Attachment state="done">
      <AttachmentMedia>
        <FileTextIcon />
      </AttachmentMedia>
      <AttachmentContent>
        <AttachmentTitle>quarterly-report.pdf</AttachmentTitle>
        <AttachmentDescription>PDF · 2.4 MB</AttachmentDescription>
      </AttachmentContent>
      <AttachmentActions>
        <AttachmentAction
          aria-label="Remove quarterly-report.pdf"
          onClick={onRemove}
        >
          <XIcon />
        </AttachmentAction>
      </AttachmentActions>
    </Attachment>
  )
}

Why Use the Shadcn Attachment Component

  • Built-in upload states: One prop switches between idle, uploading, processing, error and done, with matching borders, colors and shimmer.
  • Icon or image previews: The same card shows a file type icon for documents or a cropped thumbnail for images.
  • Three sizes and two orientations: Use full cards in upload lists, small chips in chat inputs and vertical tiles in galleries.
  • Theme aware: Colors come from tokens like bg-card, bg-muted and destructive, so light and dark mode work without extra classes.
  • You own the code: The component is copied into your project, so you can add a size, a new state or a progress bar whenever you need.

Common Attachment Use Cases

  • Chat and AI prompt inputs: Show files queued above the message field and let users remove them before sending.
  • Upload queues: Track each file from selection to upload, processing and completion, with a retry on failure.
  • Message threads: Render files that were already sent inside chat bubbles or comment threads.
  • Support tickets and email: List screenshots, logs and documents attached to a ticket or message.
  • Image galleries: Display reference photos or screenshots as a row of vertical tiles.
  • Project files: Show briefs, spreadsheets and source files attached to a task or document.

Customizing the Shadcn Attachment

Size and orientation are defined with class variance authority, so a new size is a single entry in the variant map. Every part accepts a className that is merged through cn(), and the root exposes data-state, data-size and data-orientation for targeted styling. Generate a matching palette with the free Theme Generator.

For example, this makes a whole attachment open a preview link:

<Attachment>
  <AttachmentTrigger asChild>
    <a href="/files/brief.pdf" aria-label="Open brief.pdf" />
  </AttachmentTrigger>
  <AttachmentMedia>
    <FileTextIcon />
  </AttachmentMedia>
  <AttachmentContent>
    <AttachmentTitle>brief.pdf</AttachmentTitle>
  </AttachmentContent>
</Attachment>

Attachment Accessibility and Keyboard Support

The attachment renders semantic markup, and its actions are real buttons, so they are reachable with the keyboard. The root shows a focus ring whenever a child has focus, which keeps keyboard users oriented in a row of files. Give icon-only actions an aria-label that names the file, such as "Remove report.pdf".

Write meaningful alt text for image previews and keep upload progress or error messages as text in the description, so screen readers announce them together with the file name instead of relying on color alone.

KeyAction
TabMoves focus to the next action or trigger.
ShiftTabMoves focus to the previous action or trigger.
EnterActivates the focused action or trigger.
SpaceActivates the focused action or trigger.

Attachment Best Practices

  • Always show the file name and a short piece of metadata so users can tell files apart at a glance.
  • Drive state from your real upload logic instead of faking progress, and write the percentage into the description.
  • Offer a retry action next to remove when an upload fails.
  • Use the sm or xs size inside composers and the default size in upload lists.
  • Wrap long vertical lists in a Scroll Area and reveal truncated names with a Tooltip.
  • Revoke object URLs created for image previews when the file is removed.

Components Related to Attachment

Shadcn Attachment FAQ

Keep the selected files in React state, render an AttachmentGroup above the message field and map each file to an Attachment with the sm or xs size. Add an AttachmentAction that removes the file from state, and reuse the same markup inside the message after it is sent.

Set state to uploading while the file is transferred, put a Spinner in AttachmentMedia and write the percentage into AttachmentDescription. Switch to processing while the server works and to done when it finishes.

Set state="error" on the Attachment. The border and media turn destructive, and you can place a retry AttachmentAction next to the remove action inside AttachmentActions.

Use AttachmentMedia with variant="image" and put an img element inside it. For a larger tile, set orientation="vertical" on the Attachment root.

Add an AttachmentTrigger inside the Attachment. It renders a button that covers the whole card, so its onClick can open a preview dialog, and with asChild it can render a link that downloads the file instead. AttachmentActions sits above the trigger, so remove and retry buttons keep working.

Looking for something else? Browse all shadcn/ui components or ready-made UI blocks built with them.