suiss/ui · Component
Attachment
A compact file card that shows a document or image with its name, details, upload state and actions.
Attachment is an open-source component from suiss/ui for React, React Native, SwiftUI and Jetpack Compose. The @esuiss/ui CLI copies its source into your project, so you own the code.
An Attachment typically contains an AttachmentMedia thumbnail, an AttachmentContent block with AttachmentTitle and AttachmentDescription, and an AttachmentActions slot holding one or more AttachmentAction buttons. AttachmentMedia can hold an icon, an img, or an AttachmentLabel file-type tag. During an upload, put an AttachmentProgress bar inside the content. Add an AttachmentTrigger to make the whole card clickable.
Wrap several attachments in an AttachmentGroup to render them as a single list with inset dividers. Use attachments for files in composers, chat messages and upload forms.
Installation
CLI
Works in any project with a components.json. See Installation for the one-line registry setup. Or use the suiss/ui CLI:
Manual
- Install the dependencies and add the
cnhelper:
-
Add the pieces it builds on: Button.
-
Copy the source into
components/ui/attachment.tsx:
- Update the import paths to match your project.
Usage
Set state to reflect the file's lifecycle. idle adds a dashed border (outside a group), and error colors the description with text-destructive. The state, size and orientation values are also exposed as data-* attributes for your own styling.
AttachmentAction renders a Button with the secondary variant and an icon size by default. Pass variant="link" for a text action such as "Try Again". Icon-only actions need an aria-label.
AttachmentTrigger is an invisible button stretched over the card. Give it an aria-label, or use render to turn it into a link. Actions sit above it, so they remain separately clickable.
Examples
Sizes
Compares the default, sm and xs sizes.
States
Shows the idle, uploading, processing, error and done states.
Drop zone
Image
Uses an image thumbnail with the image media variant.
Vertical
Stacks the media above the content with orientation="vertical".
Clickable
Makes the whole card a button with AttachmentTrigger, alongside a separate download action.
Group
Combines several attachments in one AttachmentGroup list.
File types
Uses colored AttachmentLabel tags to indicate file extensions.
File list
A full-width list of separate attachment cards.
Uploaded
Marks completed uploads with a check icon in the actions slot.
API Reference
Attachment
The card container that sets size, orientation and state.
| Prop | Type | Default | Description |
|---|---|---|---|
size | "default" | "sm" | "xs" | "default" | Overall density: default, sm or xs. |
orientation | "horizontal" | "vertical" | "horizontal" | horizontal places media beside the content; vertical stacks it above and overlays actions on the media. |
state | "idle" | "uploading" | "processing" | "error" | "done" | "done" | Upload lifecycle state. idle adds a dashed border and error colors the description red. |
Also accepts the props of React.ComponentProps<"div">.
AttachmentLabel
A small uppercase tag, usually the file extension, shown inside the media.
Also accepts the props of React.ComponentProps<"span">.
AttachmentMedia
The thumbnail area for an icon, document tag or image.
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "icon" | "document" | "image" | "icon" | Thumbnail style: icon for a bordered icon tile, document for a page shape with a bottom tag, image for a cropped image. |
Also accepts the props of React.ComponentProps<"div">.
AttachmentContent
Wraps the title, description and progress bar.
Also accepts the props of React.ComponentProps<"div">.
AttachmentTitle
The file name, truncated to one line.
Also accepts the props of React.ComponentProps<"span">.
AttachmentDescription
Secondary details such as file size or an error message.
Also accepts the props of React.ComponentProps<"span">.
AttachmentProgress
A progress bar with a value readout for uploads.
Also accepts the props of the primitive part it wraps.
AttachmentActions
The slot for action buttons or status indicators.
Also accepts the props of React.ComponentProps<"div">.
AttachmentAction
A compact button for actions such as remove, cancel or download.
Also accepts the props of React.ComponentProps<typeof Button>.
AttachmentTrigger
An invisible button covering the card to make it clickable.
Also accepts the props of useRender.ComponentProps<"button">.
AttachmentGroup
Stacks attachments into one rounded list with dividers.
Also accepts the props of React.ComponentProps<"div">.
Accessibility
AttachmentProgresswraps the progress primitive and exposes theprogressbarrole witharia-valuenow; give it anaria-label.AttachmentTriggerrenders abuttonwithtype="button"by default; give it anaria-labelthat names the file.- The trigger and each
AttachmentActionare separate tab stops, in that order. - The card shows a focus ring when its trigger has keyboard focus.
Notes
- Styling hooks:
data-slotvalues such asattachment,attachment-media,attachment-contentandattachment-action, plusdata-state,data-sizeanddata-orientationon the root anddata-varianton the media. - Inside
AttachmentGroup, attachments fill the width, lose their own rounding and get inset top dividers. AttachmentLabelusesbg-primaryby default; override it with a color class per file type.
Attachment is a rounded View that lays out an AttachmentMedia thumbnail, an AttachmentContent column and AttachmentActions. It comes in default, sm and xs sizes and in horizontal or vertical orientation; the vertical layout makes a tile with the actions floating over the media.
The state prop reflects the upload lifecycle: idle draws a dashed border for an empty drop slot, error turns the description red, and uploading, processing and done are passed to the parts through context. Put several attachments in an AttachmentGroup to show them as one list with hairlines between rows.