Skip to content

No.152 · AI & Chat

Attachment Tray

File uploads where progress closes a ring around each file's glyph — when the ring meets itself it becomes a seal. Failures stay put with a retry, and removed files fold out of the list.

The prompt

The design brief behind this component — reuse it to regenerate, remix, or explain it.

Build an upload tray for chat attachments. Each file row has a 44px badge: a type glyph (PDF / CSV / IMG / </>, colour-coded) inside a thin track ring, with the progress drawn as a ring around it (pathLength=1, stroke-dashoffset = 1 − progress). When the ring closes the file is 'sealed': the ring thins and turns green and a small check seal springs onto its lower-right edge (overshoot). A failed upload turns its ring rose where it stopped, nudges the glyph, says 'Upload interrupted' and offers Retry, which resumes from that point. Beside the badge: the name (truncated) and a tabular mono readout ('1.2 MB of 4.8 MB' while uploading, just the size when done), a percentage, and a remove ×. Removed rows fold out of the list (grid-template-rows 1fr → 0fr + fade) instead of vanishing. The header shows 'Attachments 2/4'. The tray only lights up (accent ring + soft halo) while files are dragged over it; the drop area below says 'Release to attach' at that moment. Transport is simulated with uneven speed in the demo. Paper and night themes.

Notes

Interaction
Drop files on the tray or use Add files / the drop area; remove with ×; retry a failed upload.
Motion
Ring progress per frame; seal springs in (420ms overshoot) and the ring thins on completion; rows fold out over 420ms; the tray glows while dragging.
Accessibility
Real buttons with labels; each completion or failure is announced through a status line; progress is also shown as text. Reduced motion keeps progress but removes springs and folds.
Responsive
Fluid up to 30rem; file names truncate.
On touch
Add files opens the native picker; every control is a tap-sized button.

Featured

301 components