KQ-753 · ATTACH/TRAY

Attach Tray

Files that dock beside the prompt. The whole tray takes a drop from the OS and an Add files button opens a real file input, so the keyboard reaches the same door. Each file becomes a chip that slides in from eight pixels on snap with a progress ring whose dash offset follows progress on glide — an upload settles, it does not jump — and at 1 the ring gives way to a check drawn on flick. Removing a chip runs its exit on the exit ease while the row beneath is measured, so the tray's height glides to the new row count and to zero when the last chip goes, with nothing reserved. Rings are progress bars with a value text, remove buttons are named by file, and a status line announces each file as it attaches.

KQ-753 · ATTACH/TRAY
Attach to the briefNothing attached
    Drop files here

    Empty · drop a file

    Install

    One command — the source lands in your repo. Or copy it from the Code tab.

    $ pnpm dlx shadcn@latest add @kinetiq/attach-tray

    Props

    files
    AttachFile[]
    default
    { id, name, size, progress, kind? } — size in bytes, progress 0..1, kind image, doc, sheet, code or file (inferred from the extension when omitted).
    onAdd
    (files: { name: string; size: number }[]) => void
    default
    Fires from a drop or the file picker with the names and sizes chosen; the parent starts the upload and owns the progress.
    onRemove
    (id: string) => void
    default
    Fires from a chip's remove button.
    format
    (bytes: number) => string
    default formatBytes
    Formats every size; the default prints B, KB or MB with one decimal.
    label
    string
    default
    Names the tray as a group.