Attachment Preview
A file chip with an icon chosen from the MIME type. Never from the extension: a `.dat` that is really a PDF should show a PDF, and a `.pdf` that is really an executable should not.
src/components/ui/attachment-preview.tsxAbout
From the component's own source, where it was written.
An attached file: thumbnail, size, progress.
The icon is chosen from the MIME type, not the file extension. Extensions are user-supplied and routinely wrong or absent, and invoice.pdf.exe is the oldest trick there is — deriving the icon from what the file claims to be by name would draw a document icon on an executable.
An upload in progress is the same component as a finished one, so the layout does not jump when it completes. Files change height on completion in most implementations and the list reflows under the pointer.
Install
npx astralyx-ui add attachment-preview
Usage
import { AttachmentPreview } from '@/components/ui/attachment-preview'
<AttachmentPreview attachment={file} onRemove={remove} onDownload={download} />Composer
Change the props and the source below follows.
contract-renewal-2026.pdf
dashboard-mock.png
export.csv
<AttachmentPreview attachment={file} onRemove={remove} onDownload={download} />API
Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.
AttachmentPreview
An attached file: thumbnail, size, progress.
Extends Omit<ComponentProps<'div'>, 'children'>.
| Prop | Type | Default | Description |
|---|---|---|---|
| attachment | Attachment | required | { id, name, type?, size?, url?, thumbnail?, progress?, error? }. |
| onRemove | (id: string) => void | — | — |
| onDownload | (attachment: Attachment) => void | — | — |
| compact | boolean | false | A single-line chip for an inline message, rather than a card in a list. |
Functions
| Function | Signature | Description |
|---|---|---|
| attachmentIconFor | (type: string | undefined) => ForwardRefExoticComponent<Omit<LucideProps, 'ref'> & RefAttributes<SVGSVGElement>> | — |
Types
Attachment
| Field | Type | Description |
|---|---|---|
| id | string | — |
| name | string | The extension is preserved when the name is trimmed, since it is the most informative part of a long filename. |
| type? | string | MIME type. Drives the icon — not the extension. |
| size? | number | Bytes. |
| url? | string | — |
| thumbnail? | string | — |
| progress? | number | 0–1 while uploading. Omit once complete; a bar stuck at 100% is indistinguishable from one that stalled. |
| error? | ReactNode | — |
Behaviour
| Topic | Detail | Description |
|---|---|---|
| icon | from MIME type | Chosen from type, falling back to the extension only when no type is given. |