Attachments

GitHub

Standalone file attachment picker and preview list with file-type icons, upload states, and readonly mode.

Installation

bash
pnpm dlx shadcn@latest add @cs/attachments

Usage

tsx
import { Attachments } from "@/components/cs/attachments";
tsx
<Attachments
  defaultValue={existingFiles}
  value={files}
  onAdd={addFile}
  onRemove={removeFile}
/>

Read-only attachments

Displays existing attachments without allowing users to add or remove files.

tsx
"use client"

import { Attachments } from "@/registry/cs/ui/attachments"
import { NextIntlClientProvider } from "next-intl"

export default function AttachmentsReadonlyPreview() {
	return (
		<NextIntlClientProvider
			locale="en"
			messages={{
				form: {
					attachments: {
						add: "Add file",
						idle: "Ready",
						remove: "Remove {name}",
						noFiles: "No files selected",
						error: "Error",
						done: "Done",
						uploading: "Uploading",
						processing: "Processing",
					},
				},
			}}
		>
			<Attachments
				readOnly
				defaultValue={[
					{
						uuid: "contract",
						name: "signed-contract.pdf",
						type: "application/pdf",
						src: "",
					},
					{
						uuid: "brief",
						name: "project-brief.docx",
						type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
						src: "",
					},
				]}
			/>
		</NextIntlClientProvider>
	)
}

API Reference

Attachments

Displays existing and newly selected file attachments with previews, file-type icons, and upload states. Use onAdd, onRemove, and onDefaultRemove to connect it to application state.

Props

NameTypeDefaultDescription
acceptstringCS_ACCEPTAccepted file extensions or MIME types passed to the native file picker.
containerClassNamestring-Additional class names applied to the grid wrapper that contains all attachment cards.
defaultValueDefaultFile[]-Files already stored by the application and shown before new uploads.
disabledboolean-Disables the file picker button.
itemClassNamestring-Additional class names applied to each individual attachment item.
onAdd(file: File) => void-Called for every file selected in the native file picker.
onDefaultRemove(file: DefaultFile) => void-Called when an existing default file is removed.
onRemove(file: File) => void-Called when a selected file is removed.
readOnlybooleanfalsePrevents selecting or removing files while keeping existing attachments visible.
translationsRootKeystring"form.attachments"Translation namespace containing the attachment labels and messages. The namespace must provide add, noFiles, idle, uploading, processing, error, done, and ready strings, plus remove with a {name} interpolation. json { "add": "Add file", "noFiles": "No files selected", "idle": "Ready to upload", "uploading": "Uploading", "processing": "Processing", "error": "Upload failed", "done": "Uploaded", "ready": "Ready", "remove": "Remove {name}" } The default namespace is form.attachments.
valueCsFile[]-Files selected by the user and tracked through their upload lifecycle.