Attachment

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

@react.component
let make = () =>
  <div className="flex w-full max-w-md flex-col gap-3">

The Attachment component displays a file or image attachment, its media, name, metadata, optional actions, and upload state. Use it for chat composers, message threads, and upload lists.

Installation

npx shadcn@latest add @rescript-shadcn/Attachment

Usage

<Attachment>
  <Attachment.Media>
    <Icons.FileText />
  </Attachment.Media>
  <Attachment.Content>
    <Attachment.Title> {"sales-dashboard.pdf"->React.string} </Attachment.Title>
    <Attachment.Description> {"PDF - 2.4 MB"->React.string} </Attachment.Description>
  </Attachment.Content>
  <Attachment.Actions>
    <Attachment.Action ariaLabel="Remove sales-dashboard.pdf">
      <Icons.X />
    </Attachment.Action>
  </Attachment.Actions>
</Attachment>

Composition

Attachment
├── Attachment.Media
├── Attachment.Content
│   ├── Attachment.Title
│   └── Attachment.Description
├── Attachment.Actions
│   └── Attachment.Action
└── Attachment.Trigger

Use Attachment.Group to lay out multiple attachments in a horizontally scrollable row.

Features

  • Icon and image media through Attachment.Media
  • Upload states: Idle, Uploading, Processing, Error, and Done
  • Three sizes and horizontal or vertical orientation
  • A full-card Attachment.Trigger for preview/open interactions
  • Scrollable, snapping Attachment.Group
  • Custom styling through className on every part

Examples

Image

Set variant=Image on Attachment.Media and render an <img /> inside it. Use orientation=Vertical to stack the media above the content.

@react.component
let make = () =>
  <div className="flex w-full max-w-md gap-3">

States

Set state to reflect the upload lifecycle. Uploading and Processing shimmer the title, and Error switches to a destructive treatment.

@react.component
let make = () =>
  <div className="flex w-full max-w-md flex-col gap-3">

Group

Wrap attachments in Attachment.Group to lay them out in a horizontally scrollable, snapping row.

@react.component
let make = () =>
  <Attachment.Group className="w-full max-w-md">

Trigger

Add Attachment.Trigger to make the whole card clickable while actions stay independently clickable.

@react.component
let make = () =>
  <Attachment className="w-full max-w-md">

Accessibility

Attachment.Action is usually icon-only, so pass an ariaLabel that names the action and target. Attachment.Trigger covers the card with no visible text, so it should also receive an ariaLabel.

API Reference

Attachment

PropTypeDefault
stateIdle | Uploading | Processing | Error | DoneDone
sizeDefault | Sm | XsDefault
orientationHorizontal | VerticalHorizontal
classNamestring-

Attachment.Media

PropTypeDefault
variantIcon | ImageIcon
classNamestring-

Attachment.Trigger

PropTypeDefault
ariaLabelstring-
type_string"button"