Attachments
freeAttachments presents removable file chips or image tiles with reusable preview and file-info parts.
Preview
Dark
launch-brief.png
image/png
notes.pdf
application/pdf
import { useState } from 'react';
import Attachments, { Attachment } from '@/components/composites/Attachments';
const initialFiles = [
{
id: 'brief',
name: 'launch-brief.png',
mediaType: 'image/png',
url: '/img/thumbs/misc/img-1.png',
},
{
id: 'notes',
name: 'notes.pdf',
mediaType: 'application/pdf',
url: '/notes.pdf',
},
];
export default function UsageDemo() {
const [files, setFiles] = useState(initialFiles);
return (
<Attachments>
{files.map((file) => (
<Attachment
key={file.id}
data={file}
onRemove={() =>
setFiles((current) => current.filter((item) => item.id !== file.id))
}
>
<Attachment.Preview />
<Attachment.Info />
</Attachment>
))}
</Attachments>
);
}Installation
Add this component with the NateUI CLI.
npx nateui@latest add AttachmentsExamples
Grid
Preview
Dark
import { useState } from 'react';
import Attachments, { Attachment } from '@/components/composites/Attachments';
const images = [
{ id: 'one', name: 'reference-1.png', mediaType: 'image/png', url: '/img/thumbs/misc/img-1.png' },
{ id: 'two', name: 'reference-2.png', mediaType: 'image/png', url: '/img/thumbs/misc/img-2.png' },
{ id: 'three', name: 'reference-3.png', mediaType: 'image/png', url: '/img/thumbs/misc/img-3.png' },
];
export default function GridDemo() {
const [items, setItems] = useState(images);
return (
<div className="max-w-xs">
<Attachments variant="grid">
{items.map((image) => (
<Attachment
key={image.id}
data={image}
variant="grid"
onRemove={() =>
setItems((current) => current.filter((item) => item.id !== image.id))
}
>
<Attachment.Preview />
</Attachment>
))}
</Attachments>
</div>
);
}Non-image Files
Preview
Dark
scope.pdf
application/pdf
estimates.xlsx
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
import Attachments, { Attachment } from '@/components/composites/Attachments';
const files = [
{ id: 'pdf', name: 'scope.pdf', mediaType: 'application/pdf', url: '/scope.pdf' },
{ id: 'sheet', name: 'estimates.xlsx', mediaType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', url: '/estimates.xlsx' },
];
export default function NonImageFilesDemo() {
return (
<Attachments>
{files.map((file) => (
<Attachment key={file.id} data={file}>
<Attachment.Preview />
<Attachment.Info />
</Attachment>
))}
</Attachments>
);
}API
Attachments
| Prop | Description | Type | Default |
|---|---|---|---|
variant | Arranges chips in a wrapping row, square tiles in a grid, or images at their own size. | 'inline' | 'grid' | 'media' | 'inline' |
...divProps | Standard <div> attributes forwarded to the container. | ComponentProps<'div'> | — |
Attachment
| Prop | Description | Type | Default |
|---|---|---|---|
data | File metadata and preview URL. | AttachmentData | — |
onRemove | Makes the remove action available. | (attachment: AttachmentData) => void | — |
variant | Matches the parent layout. Inherited from Attachments when omitted. | 'inline' | 'grid' | 'media' | 'inline' |
children | Use Preview and Info to arrange the item explicitly. | ReactNode | — |
Types
type AttachmentData = {
id: string;
name: string;
mediaType: string;
url: string;
};