From feba62c4dd24833cb2609ad8cd347f3557fe7f91 Mon Sep 17 00:00:00 2001 From: Hirotaka Mizutani <52546+hirotaka@users.noreply.github.com> Date: Sun, 28 Jun 2026 13:21:13 +0900 Subject: [PATCH] feat(registry): Add file attachment block --- app/components/demo/FileAttachmentDemo.vue | 40 +++++ .../blocks/file-attachment/FileAttachment.vue | 162 ++++++++++++++++++ app/registry/blocks/file-attachment/index.ts | 1 + .../docs/2.components/17.file-attachment.md | 83 +++++++++ scripts/registry-verify.ts | 4 + 5 files changed, 290 insertions(+) create mode 100644 app/components/demo/FileAttachmentDemo.vue create mode 100644 app/registry/blocks/file-attachment/FileAttachment.vue create mode 100644 app/registry/blocks/file-attachment/index.ts create mode 100644 content/docs/2.components/17.file-attachment.md diff --git a/app/components/demo/FileAttachmentDemo.vue b/app/components/demo/FileAttachmentDemo.vue new file mode 100644 index 0000000..a4a272f --- /dev/null +++ b/app/components/demo/FileAttachmentDemo.vue @@ -0,0 +1,40 @@ + + + diff --git a/app/registry/blocks/file-attachment/FileAttachment.vue b/app/registry/blocks/file-attachment/FileAttachment.vue new file mode 100644 index 0000000..b485004 --- /dev/null +++ b/app/registry/blocks/file-attachment/FileAttachment.vue @@ -0,0 +1,162 @@ + + + diff --git a/app/registry/blocks/file-attachment/index.ts b/app/registry/blocks/file-attachment/index.ts new file mode 100644 index 0000000..50578ab --- /dev/null +++ b/app/registry/blocks/file-attachment/index.ts @@ -0,0 +1 @@ +export { default as FileAttachment, type FileAttachmentProps, type FileAttachmentStatus } from "./FileAttachment.vue"; diff --git a/content/docs/2.components/17.file-attachment.md b/content/docs/2.components/17.file-attachment.md new file mode 100644 index 0000000..84da6a4 --- /dev/null +++ b/content/docs/2.components/17.file-attachment.md @@ -0,0 +1,83 @@ +--- +title: FileAttachment +description: Render display-only file attachment UI while your app owns upload behavior. +category: chat +--- + +::component-preview +--- +name: FileAttachmentDemo +--- +:: + +## Installation + +```bash +npx shadcn-vue@latest add "https://ui.stackhacker.io/r/file-attachment.json" +``` + +## Usage + +```vue + + + +``` + +## App-Owned Upload State + +`FileAttachment` renders display-only attachment UI. Your app owns upload handlers, preview URL creation and cleanup, file limits, server state, toast messages, and removal confirmation. + +Pass display-ready state through props. Use the `icon`, `preview`, or `actions` slots when your app needs custom file-type icons, preview rendering, or actions. + +## Examples + +### Status states + +::component-preview +--- +name: FileAttachmentDemo +--- +:: + +## API Reference + +### Props + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `name` | `string` | — | Original file name supplied by your app. | +| `type` | `string` | `""` | Optional MIME type used for default fallback icons. | +| `displayName` | `string` | — | Optional display name. Falls back to `name`. | +| `previewUrl` | `string` | — | Optional preview image URL supplied by your app. | +| `status` | `'idle' \| 'uploading' \| 'uploaded' \| 'error'` | `'idle'` | Display status supplied by your app. | +| `error` | `string` | — | Error text shown when status is `error`. | +| `removable` | `boolean` | `false` | Show a remove button when not uploading. | +| `removeLabel` | `string` | `'Remove attachment'` | Accessible label for the remove button. | +| `ariaLabel` | `string` | — | Accessible label for the attachment. | +| `class` | `string` | — | Additional CSS classes for the root element. | + +### Events + +| Event | Payload | Description | +|------|---------|-------------| +| `remove` | `[]` | Emitted when the remove button is clicked. | + +### Slots + +| Slot | Props | Description | +|------|-------|-------------| +| `preview` | `{ name, displayName, type, previewUrl, status }` | Replace the preview area. | +| `icon` | `{ name, displayName, type, status }` | Replace the fallback file icon. | +| `actions` | `{ name, displayName, type, previewUrl, status, remove }` | Replace the remove/action area. | diff --git a/scripts/registry-verify.ts b/scripts/registry-verify.ts index 09a0359..22521ca 100644 --- a/scripts/registry-verify.ts +++ b/scripts/registry-verify.ts @@ -155,6 +155,10 @@ const expectedItems: Record = { dependencies: ["@lucide/vue"], registryDependencies: [], }, + "file-attachment": { + dependencies: ["@lucide/vue"], + registryDependencies: [], + }, }; if (registryIndex) {