Skip to content
Kura UI

Attachment

beta

File and image attachment chips with thumbnails, upload progress rings, error/retry, remove, a “+N” overflow stack and a dropzone.

@kura-ui/react/attachmentCopy page for agents.mdregistry.json

A single file

minimal
q3-board-report.pdf

Mixed states with overflow

Thumbnails, a live upload, a failed upload with retry, remove buttons and a +N stack.

full
  • brief.md
  • harbour.png
  • transactions.csv
  • schema.tsUpload failed: Network connection lost

Hover a file to remove it · Retry the failed upload · Open the +N stack

Dropzone feeding a list

Browse or drop files; accepted ones upload, rejected ones are reported.

composition

Installation

npx shadcn@latest add https://kuro.abstergo.fyi/r/attachment.json

Copies the source into components/kura/attachment with its dependencies (kura-theme, kura-motion, use-reduced-motion, utils). Tokens come from the kura-theme item.

When to use it

Use it for

  • Show files the user attached to a prompt before sending (inside or above a composer).
  • Display upload progress, failures and a retry action for files sent to a model.
  • Render the files that belong to a sent message or an agent artifact list.
  • A standalone drop area for documents to index, e.g. “Add files to this project”.

Reach for something else when

  • A complete prompt input with paste and drag-drop built in — use composer (it renders attachment for you).
  • Rich previews of generated documents or code — use artifact-card or code-block.
  • Audio recordings with playback — use audio-waveform with `peaks`.

Props

PropTypeDefaultDescription
name*string—File name shown on the chip; long names truncate with an ellipsis.
sizenumber—Size in bytes, rendered as “2.4 MB”.
typestring—MIME type. Chooses the file-type icon (image, pdf, code, text, sheet, audio, video, archive) and whether a preview renders as a thumbnail.
previewUrlstring—Image URL (object URL or remote). With an image type the attachment renders as a 44px square thumbnail.
status"ready" | "uploading" | "error""ready"Upload state. Uploading shows a progress ring; error shows a danger tint.
progressnumber—Upload progress 0..1 while uploading. Omit for an indeterminate spinning arc.
errorstring—Error message for status=error; shown as the title and announced via role=alert.
variant"auto" | "chip" | "tile""auto"auto = thumbnail tile for images that have a previewUrl, a chip (icon + name + size) otherwise.
onRemove() => void—Render a × button (revealed on hover/focus, always visible on touch).
onRetry() => void—Render a Retry action while status is error.

All native attributes of the root element, className and ref pass through.

Anatomy

  1. AttachmentOne file. Exposes data-variant (chip|tile), data-kind and data-status (ready|uploading|error).data-slot="attachment"
  2. AttachmentRemoveThe × button, labelled “Remove <name>”. Rendered when onRemove is set.data-slot="attachment-remove"
  3. AttachmentListWrapping <ul> of attachments with pop-in/out and gap-closing layout motion, plus the “+N” stack.data-slot="attachment-list"
  4. AttachmentOverflowThe “+N” stack button (a counter with two offset cards behind it).data-slot="attachment-overflow"
  5. AttachmentDropzoneClick-to-browse + drop target with a dashed hairline. data-dragging is set only while a drag carries files.data-slot="attachment-dropzone"
  6. AttachmentProgressRingStandalone circular progress (currentColor) used by uploading attachments.data-slot="attachment-progress"

Accessibility

  • Image tiles render <img alt={name}>; chips render the name as text, so every file has a readable name.
  • The remove button is a real <button> labelled “Remove <file name>” with a 28px hit area; it is revealed on hover and on keyboard focus within the item.
  • Upload failures are announced once with role=alert; progress is not announced on every tick.
  • The list is a <ul aria-label="Attachments">; the overflow button is labelled “Show N more attachments”.
  • The dropzone is a native <button> that opens the file picker; the drop target never steals focus.
  • Reduced motion: Items fade in and out without scale, blur or layout travel; the indeterminate ring pulses instead of spinning; hover lifts are removed.
KeysAction
TabMoves through each attachment's Retry and Remove buttons
Enter / SpaceActivates Remove, Retry, the +N stack or the dropzone

Notes for agents

  • Keep attachments in state as AttachmentItem[] and render <AttachmentList items={…} />; use createAttachment(file) to build items (it creates an object URL for images — revoke it with URL.revokeObjectURL when removing).
  • Helpers exported alongside: formatBytes, attachmentKind, acceptsFile, filesFromDataTransfer, dragHasFiles.
  • Progress is 0..1, not a percentage. Omit progress for an indeterminate ring.
  • Inside a composer, prefer composer's built-in ComposerAttachments, which wires paste, drop and removal.