Displays a file or image attachment with media, metadata, upload state, and actions.
❯buridan add attachmentUse the following to build the Attachment component.
from components.ui.attachment import attachmentFor manual installation, copy each of the source codes below in their respective locations.
attachment.mediaidle, uploading, processing, error, and done with built-in styling and a shimmer while in progressattachment.trigger that opens a link or dialog while the actions stay independently clickableattachment.group with an edge fadeclass_name prop on every partSet variant="image" on attachment.media and render an rx.el.img() inside it. Use orientation="vertical" to stack the media above the content.
Props used: variant on attachment.media; orientation on attachment.root.
Set state to reflect the upload lifecycle. uploading and processing shimmer the title, and error switches to a destructive treatment.
Props used: state on attachment.root.
Use size to switch between default, sm, and xs.
Props used: size on attachment.root.
Wrap attachments in attachment.group to lay them out in a horizontally scrollable, snapping row with an edge fade.
Props used: none required beyond default attachment.group composition.
Add an attachment.trigger to make the whole card open a link or dialog. It fills the card behind the actions, so the actions stay clickable.
Props used: link, href, aria_label on attachment.trigger.
attachment.action renders a Button, and attachment.trigger renders either a real rx.el.button() or a rx.el.a() if the link prop is set to True. Follow the guidance below so both are operable and announced.
attachment.action is usually icon-only, so give each one an aria-label describing the action and its target.
attachment.action(
hi("Cancel01Icon"), aria_label="Remove market-research.pdf"
)
attachment.trigger overlays the entire attachment with a clickable surface.
Use aria_label to describe what activating the attachment does. This is required when the trigger has no visible text.
attachment.trigger(
link=True,
href=url,
target="_blank",
rel="noreferrer",
aria_label="Open workspace.png",
)
attachment.trigger(
on_click=handle_open,
aria_label="Open attachment preview",
)
The trigger sits behind the actions in the stacking order, so an attachment.action and the attachment.trigger never trap each other — both remain separately focusable and clickable.
An attachment.group scrolls horizontally. When its attachments are interactive: a trigger or actions, keyboard users reach off-screen items by tabbing to them. For a row of presentational attachments, make the group itself focusable and scrollable by adding tabIndex={0}, role="group", and an aria-label.
The error state uses a destructive color. Keep the failure reason in attachment.description so the state is not conveyed by color alone.
The root attachment container.
The media slot for an icon or image preview.
Wraps the title and description.
The attachment name. Shimmers while the attachment is uploading or processing.
Secondary metadata such as the file type, size, or upload status.
A container for one or more actions, aligned to the end of the attachment.
An action button. Renders a Button and accepts all of its props.
A full-card overlay that activates the attachment. Renders a rx.el.button by default or a rx.el.a when link=True.
Lays out attachments in a horizontally scrollable, snapping row.