# AttachmentPreview

A file attached to a message or to one being written: a thumbnail or a type icon, the file name, then its size, its upload progress or why it failed, and a remove button. Put tiles in the Composer's attachments, or in a sent message with href.

**Dependencies:** npm: 1 direct, 4 total; registry: 4 direct, 4 total.

## Usage

### When to use

- Show files picked for a message while they upload, with a way to remove them.
- Show the files in a sent message, as links that open them.

### When not to use

- Show a picture that should be seen. Use Image.
- Pick files from a drop zone. Use a file input in a Field.
- A list of documents in a project. Use Table.

## Examples

### Files

```tsx
<div className="flex flex-wrap gap-sm">
  <AttachmentPreview name="brief.pdf" type="application/pdf" fileSize={482000} onRemove={removeFile} />
  <AttachmentPreview name="assets.zip" type="application/zip" fileSize={12400000} onRemove={removeFile} />
</div>
```

### Uploading

A progress bar takes the place of the size until the file is uploaded.

```tsx
<AttachmentPreview name="photo.jpg" type="image/jpeg" progress={40} onRemove={removeFile} />
```

### Upload failed

The reason shows under the name and the edge turns to danger.

```tsx
<AttachmentPreview name="recording.mov" type="video/quicktime" error="File is larger than 25 MB" onRemove={removeFile} />
```

### In a sent message

With href the name opens the file, and the whole tile is its target.

```tsx
<AttachmentPreview name="invoice-0042.pdf" type="application/pdf" fileSize={96000} href="#invoice" />
```

## Do and don't

### Do

- Show a tile as soon as a file is picked, with its progress, so the reader sees it is on its way.
- Say why an upload failed, such as the size limit, and keep the tile so it can be removed.
- Pass href on files in sent messages, so they open.

### Don't

- Do not show images larger here; use Image in the message for a picture that should be seen.
- Do not hide the file name behind the thumbnail.
- Do not remove a failed file on its own; let the reader remove it.

## Props

| Name | Type | Values | Default | Description |
| --- | --- | --- | --- | --- |
| `name` (required) | `string` |  |  | The file name, shown and used in the remove button and progress names. |
| `type` | `string` |  |  | The MIME type, which picks the icon, such as application/pdf. Without it the extension of name decides. |
| `fileSize` | `number` |  |  | The size in bytes, shown under the name. |
| `src` | `string` |  |  | A thumbnail URL for an image, such as an object URL of the picked file. Without it the type icon shows. |
| `progress` | `number \| null` |  |  | Upload progress from 0 to 100; null for an upload of unknown length. Leave it out once the file is uploaded. |
| `error` | `string` |  |  | Why the upload failed, such as File is larger than 25 MB. Turns the edge to danger and shows under the name. |
| `href` | `string` |  |  | Opens or downloads the file, such as an attachment in a sent message. |
| `onRemove` | `() => void` |  |  | Shows a remove button and is called when it is pressed. |
| `formatSize` | `(bytes: number) => string` |  |  | Formats fileSize. Default decimal units, such as 482 KB or 1.3 MB. |
| `labels` | `{ remove?: string; uploading?: string }` |  |  | Button and progress names, with {name} for the file. Defaults: Remove {name}, Uploading {name}. Vietnamese: Gỡ {name}, Đang tải lên {name}. |

## Anatomy

| Part | Description |
| --- | --- |
| `root` | The tile: thumbnail, body and remove button in one row, 256px wide at most. |
| `thumbnail` | A 40px box in the sunken fill with the image, or the icon for the file type. |
| `image` | The thumbnail image. It fades in once loaded and dims to opacity-pending while the file uploads. |
| `icon` | The file type icon, 20px: photo, video, music, PDF, archive, text or a plain file. |
| `body` | The name over the size, the progress bar or the error. |
| `name` | The file name on one line, cut with an ellipsis. A link when href is set. |
| `meta` | The file size, such as 482 KB. |
| `error` | Why the upload failed, in the danger color. |
| `remove` | The ghost icon Button in size sm that removes the file. |

## Accessibility

Role: `generic`

| Keys | Action |
| --- | --- |
| `Tab` | Moves to the file link, if href is set, then to the remove button. |
| `Enter / Space` | On the remove button, removes the file. On the link, opens it. |

- The file name is written out; the thumbnail and the type icon are decorative.
- The remove button is named with the file, EN `Remove brief.pdf`, from labels.remove with {name}.
- While the file uploads, a progress bar named EN `Uploading brief.pdf` reports the percentage.
- A failed upload shows its reason under the name in the danger color, as text, not by the red edge alone. The remove button and the link are described by it.
- The link stretches over the whole tile for the pointer; only the name is in the tab order.

## Install

```bash
npx werewolf-ui add attachment-preview
```

Run `npx werewolf-ui init` once in your app before adding components. Init sets up tokens, their CSS import and agent rules. Add installs this component and its dependencies while preserving your theme. See [Installation](https://www.werewolf-ui.dev/docs/installation.md) for requirements and the alternative registry setup.
