ReScript Shadcn
Get started
  • Installation
Components
  • Accordion
  • Alert
  • AlertDialog
  • AspectRatio
  • Attachment
  • Avatar
  • Badge
  • Breadcrumb
  • Bubble
  • Button
  • ButtonGroup
  • Calendar
  • Card
  • Carousel
  • Chart
  • Checkbox
  • Collapsible
  • Combobox
  • Command
  • ContextMenu
  • DataTable
  • DatePicker
  • Dialog
  • Direction
  • Drawer
  • DropdownMenu
  • Empty
  • Field
  • HoverCard
  • Input
  • InputGroup
  • InputOtp
  • Item
  • Kbd
  • Label
  • Marker
  • Menubar
  • Message
  • MessageScroller
  • NativeSelect
  • NavigationMenu
  • Pagination
  • Popover
  • Progress
  • RadioGroup
  • Resizable
  • ScrollArea
  • Select
  • Separator
  • Sheet
  • Sidebar
  • Skeleton
  • Slider
  • Sonner
  • Spinner
  • Switch
  • Table
  • Tabs
  • Textarea
  • Toast
  • Toggle
  • ToggleGroup
  • Tooltip
  • Typography

Attachment

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

sales-dashboard.pdfPDF - 2.4 MB
message-renderer.resReScript - 12 KB

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.

Analytics dashboard
dashboard.pngPNG - 820 KB
Laptop with notes
research.jpgJPEG - 1.1 MB

States#

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

quarterly-review.pdfUploading...
transcript.jsonProcessing metadata
large-export.zipUpload failed

Group#

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

brief.pdfPDF - 640 KB
schema.sqlSQL - 18 KB
wireframe.pngPNG - 420 KB

Trigger#

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

research-summary.pdfClick the card to preview

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"
@react.component
let make = () =>
  <div className="flex w-full max-w-md flex-col gap-3">
@react.component
let make = () =>
  <div className="flex w-full max-w-md gap-3">
@react.component
let make = () =>
  <div className="flex w-full max-w-md flex-col gap-3">
@react.component
let make = () =>
  <Attachment.Group className="w-full max-w-md">
@react.component
let make = () =>
  <Attachment className="w-full max-w-md">