Attachment group
Responsive attachment rows with accessible overflow and sent-message alignment.
Usage
import { AttachmentGroup } from '@commenda/pathfinder/attachment-group';
<AttachmentGroup
items={attachments}
maxRows={3}
onRemove={removeAttachment}
onRetry={retryUpload}
onPreview={openPreview}
getPreview={(item) => ({ content: <FileSummary attachment={item} /> })}
/>;The group measures actual pill widths and reserves room for +N within the last permitted row. It recomputes after container resize, font loading, or item changes. IDs must be unique and stable. Input order is preserved; grouping files into folder records is application-owned.
Sent-message alignment
align="end" aligns toward the inline end and suppresses all removal controls, including overflow checkboxes. Preview actions continue to work. Place the group 6px above the message bubble in the conversation composition.
Overflow behavior
+N opens a named Popover listing hidden attachments. Uncheck an item to request removal in an editable group; select its pill to preview or retry. This uses a Popover with Checkbox rather than the action-only Dropdown so selection and preview remain distinct controls. The app updates items after removal; if it rejects the request, the attachment remains selected.
The initial server render provides +N access; measurement takes place before the client paints. Hidden measurement labels are excluded from the accessibility tree and contain no focusable controls.
API reference
| Prop | Type | Behavior |
|---|---|---|
itemsRequired | readonly AttachmentItem[] | Required; empty arrays render nothing |
align | "start"|"end" | Start default; end is a non-removable sent group |
maxRows | 1|2|3 | Default 3; +N stays inside this row budget |
onPreview | (
item: AttachmentItem
) => void | Same lifecycle callbacks as Attachment |
onRetry | (
item: AttachmentItem
) => void | Same lifecycle callbacks as Attachment |
onRemove | (
item: AttachmentItem
) => void | Same lifecycle callbacks as Attachment |
getPreview | (
item: AttachmentItem
) => AttachmentProps['previewConfig'] | Optional per-item hover/focus preview |
label | string | Accessible group name; defaults to Attachments |
className | string | Outer layout |
Design rules
- ATTACH-GROUP-01: Figma 569:26690. Wrap with a 6px gap, cap at three rows, and expose every remaining item through +N. Never clip a fourth row of keyboard-focusable items.
- ATTACH-GROUP-02: Composer alignment enables removal when supplied; sent alignment removes editing controls but retains preview.
- Retain failed items and their retry action. Width calculations use original labels and update when item state changes.
Migration notes
Existing { key, fileName, mimeType, fileRef } arrays map to AttachmentItem without changing persisted data. Keep existing folder aggregation before the group. Overflow, measurement, and keyboard management are handled inside Pathfinder.