mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-07-02 08:58:36 +00:00
* feat(@shadcn/react): add message-scroller package Add the @shadcn/react headless primitives package with MessageScroller scroll anchoring, streaming follow, history prepend, and jump-to-message behavior. Includes geometry helpers, use-render utility, and unit, browser, and perf tests. * feat(registry): add chat components Add MessageScroller, Message, Bubble, Attachment, and Marker registry sources for base and radix, style variants, preview-03 chat blocks, and registry index wiring. * feat(v4): integrate chat components into docs site Wire chat components into the v4 app with docs routes, example preview pages, message part renderers, markdown support, registry build updates, and supporting lib utilities. * feat(examples): add chat component demos Add base and radix example demos for MessageScroller, Message, Bubble, Attachment, Marker, scroll-fade, and shimmer. * docs: add chat component documentation Add component and utility docs for the chat component set, update docs navigation, and add the June 2026 chat components changelog entry. * chore: regenerate registry JSON output Rebuild public registry artifacts for all style variants with the new chat components. * chore(release): add @shadcn/react publish and CI pipeline Add Changesets prerelease workflow, browser test job, RELEASING docs, and monorepo wiring for publishing @shadcn/react independently from the shadcn CLI. * docs: fix display of component preview on mobile * fix * fix * docs: add message scroller docs * style: format * fix
305 lines
9.9 KiB
Plaintext
305 lines
9.9 KiB
Plaintext
---
|
|
title: Attachment
|
|
description: Displays a file or image attachment with media, metadata, upload state, and actions.
|
|
base: base
|
|
component: true
|
|
---
|
|
|
|
<ComponentPreview
|
|
styleName="base-rhea"
|
|
name="attachment-demo"
|
|
previewClassName="h-auto theme-blue bg-surface dark:bg-background"
|
|
/>
|
|
|
|
The `Attachment` component displays a file or image attachment, its media, name, and metadata, with optional actions and upload state. Use it for files and images in chat composers, message threads, and upload lists.
|
|
|
|
## Installation
|
|
|
|
<CodeTabs>
|
|
|
|
<TabsList>
|
|
<TabsTrigger value="cli">Command</TabsTrigger>
|
|
<TabsTrigger value="manual">Manual</TabsTrigger>
|
|
</TabsList>
|
|
<TabsContent value="cli">
|
|
|
|
```bash
|
|
npx shadcn@latest add attachment
|
|
```
|
|
|
|
</TabsContent>
|
|
|
|
<TabsContent value="manual">
|
|
|
|
<Steps className="mb-0 pt-2">
|
|
|
|
<Step>Install the required shadcn/ui dependencies:</Step>
|
|
|
|
```bash
|
|
npx shadcn@latest add button
|
|
```
|
|
|
|
<Step>Copy and paste the following code into your project.</Step>
|
|
|
|
<ComponentSource
|
|
name="attachment"
|
|
title="components/ui/attachment.tsx"
|
|
styleName="base-rhea"
|
|
/>
|
|
|
|
<Step>Update the import paths to match your project setup.</Step>
|
|
|
|
</Steps>
|
|
|
|
</TabsContent>
|
|
|
|
</CodeTabs>
|
|
|
|
## Usage
|
|
|
|
```tsx
|
|
import {
|
|
Attachment,
|
|
AttachmentAction,
|
|
AttachmentActions,
|
|
AttachmentContent,
|
|
AttachmentDescription,
|
|
AttachmentMedia,
|
|
AttachmentTitle,
|
|
} from "@/components/ui/attachment"
|
|
```
|
|
|
|
```tsx
|
|
<Attachment>
|
|
<AttachmentMedia>
|
|
<FileTextIcon />
|
|
</AttachmentMedia>
|
|
<AttachmentContent>
|
|
<AttachmentTitle>sales-dashboard.pdf</AttachmentTitle>
|
|
<AttachmentDescription>PDF · 2.4 MB</AttachmentDescription>
|
|
</AttachmentContent>
|
|
<AttachmentActions>
|
|
<AttachmentAction aria-label="Remove sales-dashboard.pdf">
|
|
<XIcon />
|
|
</AttachmentAction>
|
|
</AttachmentActions>
|
|
</Attachment>
|
|
```
|
|
|
|
## Composition
|
|
|
|
Use the following composition to build an attachment:
|
|
|
|
```text
|
|
Attachment
|
|
├── AttachmentMedia
|
|
├── AttachmentContent
|
|
│ ├── AttachmentTitle
|
|
│ └── AttachmentDescription
|
|
├── AttachmentActions
|
|
│ └── AttachmentAction
|
|
└── AttachmentTrigger
|
|
```
|
|
|
|
Use `AttachmentGroup` to lay out multiple attachments in a scrollable row:
|
|
|
|
```text
|
|
AttachmentGroup
|
|
├── Attachment
|
|
└── Attachment
|
|
```
|
|
|
|
## Features
|
|
|
|
- Icon and image media through `AttachmentMedia`
|
|
- Upload states: `idle`, `uploading`, `processing`, `error`, and `done` with built-in styling and a shimmer while in progress
|
|
- Three sizes and horizontal or vertical orientation
|
|
- A full-card `AttachmentTrigger` that opens a link or dialog while the actions stay independently clickable
|
|
- Scrollable, snapping `AttachmentGroup` with an edge fade
|
|
- Customizable styling through the `className` prop on every part
|
|
|
|
## Examples
|
|
|
|
### Image
|
|
|
|
Set `variant="image"` on `AttachmentMedia` and render an `<img>` inside it. Use `orientation="vertical"` to stack the media above the content.
|
|
|
|
<ComponentPreview
|
|
styleName="base-rhea"
|
|
name="attachment-image"
|
|
previewClassName="h-auto theme-blue bg-surface dark:bg-background"
|
|
/>
|
|
|
|
### States
|
|
|
|
Set `state` to reflect the upload lifecycle. `uploading` and `processing` shimmer the title, and `error` switches to a destructive treatment.
|
|
|
|
<ComponentPreview
|
|
styleName="base-rhea"
|
|
name="attachment-states"
|
|
previewClassName="h-auto theme-blue bg-surface dark:bg-background"
|
|
/>
|
|
|
|
### Sizes
|
|
|
|
Use `size` to switch between `default`, `sm`, and `xs`.
|
|
|
|
<ComponentPreview
|
|
styleName="base-rhea"
|
|
name="attachment-sizes"
|
|
previewClassName="h-auto theme-blue bg-surface dark:bg-background"
|
|
/>
|
|
|
|
### Group
|
|
|
|
Wrap attachments in `AttachmentGroup` to lay them out in a horizontally scrollable, snapping row with an edge fade.
|
|
|
|
<ComponentPreview
|
|
styleName="base-rhea"
|
|
name="attachment-group"
|
|
previewClassName="h-auto theme-blue bg-surface dark:bg-background"
|
|
/>
|
|
|
|
### Trigger
|
|
|
|
Add an `AttachmentTrigger` to make the whole card open a link or dialog. It fills the card behind the actions, so the actions stay clickable.
|
|
|
|
<ComponentPreview
|
|
styleName="base-rhea"
|
|
name="attachment-trigger"
|
|
previewClassName="h-auto theme-blue bg-surface dark:bg-background"
|
|
/>
|
|
|
|
```tsx showLineNumbers
|
|
<Dialog>
|
|
<Attachment>
|
|
{/* media, content, actions */}
|
|
<DialogTrigger
|
|
render={<AttachmentTrigger aria-label="Preview research-summary.pdf" />}
|
|
/>
|
|
</Attachment>
|
|
<DialogContent>{/* ... */}</DialogContent>
|
|
</Dialog>
|
|
```
|
|
|
|
## Accessibility
|
|
|
|
`AttachmentAction` renders a `Button`, and `AttachmentTrigger` renders a real `<button>` (or your element via `render`). Follow the guidance below so both are operable and announced.
|
|
|
|
### Label icon-only actions
|
|
|
|
`AttachmentAction` is usually icon-only, so give each one an `aria-label` describing the action and its target.
|
|
|
|
```tsx showLineNumbers
|
|
<AttachmentAction aria-label="Remove sales-dashboard.pdf">
|
|
<XIcon />
|
|
</AttachmentAction>
|
|
```
|
|
|
|
### Label the trigger
|
|
|
|
`AttachmentTrigger` covers the card with no text of its own, so give it an `aria-label` for what activating it does.
|
|
|
|
```tsx showLineNumbers
|
|
<AttachmentTrigger
|
|
render={
|
|
<a
|
|
href={url}
|
|
target="_blank"
|
|
rel="noreferrer"
|
|
aria-label="Open workspace.png"
|
|
/>
|
|
}
|
|
/>
|
|
```
|
|
|
|
The trigger sits behind the actions in the stacking order, so an `AttachmentAction` and the `AttachmentTrigger` never trap each other — both remain separately focusable and clickable.
|
|
|
|
### Keyboard scrolling
|
|
|
|
An `AttachmentGroup` scrolls horizontally. When its attachments are interactive: a trigger or actions, keyboard users reach off-screen items by tabbing to them. For a row of presentational attachments, make the group itself focusable and scrollable by adding `tabIndex={0}`, `role="group"`, and an `aria-label`.
|
|
|
|
### Meaning beyond color
|
|
|
|
The `error` state uses a destructive color. Keep the failure reason in `AttachmentDescription` so the state is not conveyed by color alone.
|
|
|
|
## API Reference
|
|
|
|
### Attachment
|
|
|
|
The root attachment container.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ------------- | ------------------------------------------------------------ | -------------- | ------------------------------------------------- |
|
|
| `state` | `"idle" \| "uploading" \| "processing" \| "error" \| "done"` | `"done"` | The upload state. Drives styling and the shimmer. |
|
|
| `size` | `"default" \| "sm" \| "xs"` | `"default"` | The attachment size. |
|
|
| `orientation` | `"horizontal" \| "vertical"` | `"horizontal"` | Lay the media beside or above the content. |
|
|
| `className` | `string` | - | Additional classes to apply to the root element. |
|
|
|
|
### AttachmentMedia
|
|
|
|
The media slot for an icon or image preview.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ----------- | ------------------- | -------- | ---------------------------------------------- |
|
|
| `variant` | `"icon" \| "image"` | `"icon"` | Whether the media holds an icon or an `<img>`. |
|
|
| `className` | `string` | - | Additional classes to apply to the media slot. |
|
|
|
|
### AttachmentContent
|
|
|
|
Wraps the title and description.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ----------- | -------- | ------- | ------------------------------------------------ |
|
|
| `className` | `string` | - | Additional classes to apply to the content slot. |
|
|
|
|
### AttachmentTitle
|
|
|
|
The attachment name. Shimmers while the attachment is `uploading` or `processing`.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ----------- | -------- | ------- | ----------------------------------------- |
|
|
| `className` | `string` | - | Additional classes to apply to the title. |
|
|
|
|
### AttachmentDescription
|
|
|
|
Secondary metadata such as the file type, size, or upload status.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ----------- | -------- | ------- | ----------------------------------------------- |
|
|
| `className` | `string` | - | Additional classes to apply to the description. |
|
|
|
|
### AttachmentActions
|
|
|
|
A container for one or more actions, aligned to the end of the attachment.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ----------- | -------- | ------- | ------------------------------------------- |
|
|
| `className` | `string` | - | Additional classes to apply to the actions. |
|
|
|
|
### AttachmentAction
|
|
|
|
An action button. Renders a [`Button`](/docs/components/button) and accepts all of its props.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ---------- | ------------------------------------- | ----------- | ---------------------------------------- |
|
|
| `size` | `Button["size"]` | `"icon-xs"` | The button size. |
|
|
| `...props` | `React.ComponentProps<typeof Button>` | - | Props spread to the underlying `Button`. |
|
|
|
|
### AttachmentTrigger
|
|
|
|
A full-card overlay that activates the attachment. Renders a `<button>` by default.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ---------- | -------------------------------- | ------- | ---------------------------------------------- |
|
|
| `render` | `ReactElement \| function` | - | Render as a different element, such as a link. |
|
|
| `...props` | `React.ComponentProps<"button">` | - | Props spread to the trigger element. |
|
|
|
|
### AttachmentGroup
|
|
|
|
Lays out attachments in a horizontally scrollable, snapping row.
|
|
|
|
| Prop | Type | Default | Description |
|
|
| ----------- | -------- | ------- | ----------------------------------------- |
|
|
| `className` | `string` | - | Additional classes to apply to the group. |
|