Attachment
Displays a file or image attachment with media, metadata, upload state, and actions.
Overview
横向布局:图标 media + 标题/描述 + 移除按钮,对应 shadcn 的默认 Attachment 组合。点 × 发出 AttachmentRemoveEvent。
GPUI · Live previewGPUI WASM
Installation
Attachment 是单个 Rust 文件(src/attachment.rs),用 gpui 的 div / canvas / PathBuilder 自绘,不依赖额外原语。复制到你的 crate,或下载完整示例直接运行。
[dependencies]gpui-kit = "0.6.6"# attachment.rs is a single styled component —# it uses gpui's div / canvas / PathBuilder# directly, no extra primitives needed.# Download the runnable example crate, then:cargo run --locked -- --attachment# Other demos:cargo run --locked -- --attachment imagecargo run --locked -- --attachment statescargo run --locked -- --attachment sizescargo run --locked -- --attachment groupcargo run --locked -- --attachment triggerUsage
builder 链式配置 media、标题、描述、上传状态与交互;把实体保留在宿主视图上,渲染时放进任意容器,事件用 cx.subscribe 订阅。
use justdo_command::attachment::{Attachment, AttachmentMedia, AttachmentState};// Keep the entity on your host view.let attachment = cx.new(|_| { Attachment::new() .media(AttachmentMedia::FileText) .title("sales-dashboard.pdf") .description("PDF · 2.4 MB") .state(AttachmentState::Uploading { progress: 0.64 })});// In render: div().child(self.attachment.clone())网页预览与桌面端运行同一份 Rust / GPUI 组件。
Composition
组合结构对齐 shadcn/ui 的 Attachment:Media / Content / Actions / Trigger,外加横向滚动的 Group。
Attachment card container├── AttachmentMedia icon box or image thumbnail├── AttachmentContent title + metadata column│ ├── AttachmentTitle .title(..)│ └── AttachmentDescription .description(..)├── AttachmentActions remove button -> AttachmentRemoveEvent└── AttachmentTrigger .openable(true) -> AttachmentOpenEventAttachmentGroup horizontal scroll row .overflow_x_scroll() + .track_scroll(&handle)Accessibility
Keyboard
- Tab 沿页面 tab 序聚焦移除按钮,focus-visible 描边
- Enter Space 触发 AttachmentRemoveEvent
- Group 行用滚轮 / 触控板横向滚动,每张卡仍可通过 Tab 到达
Semantics
Error 状态除红色描边外始终带文字失败原因,不单靠颜色;trigger 遮罩避开操作列,移除按钮保持独立可点;processing 状态同步降标题对比度。
API Reference
组件实体暴露的方法与事件。
| API | Signature | Notes |
|---|---|---|
Attachment::new() | -> Attachment | Creates the entity content; state Done, horizontal layout. |
.media(..) | AttachmentMedia | FileText | FileCode | Image line icons, or Photo thumbnail. |
.title(..) | impl Into<SharedString> | File name heading. |
.description(..) | impl Into<SharedString> | Metadata line: type · size, or a failure reason on error. |
.state(..) | AttachmentState | Idle | Uploading { progress } | Processing | Error | Done. |
.size(..) | AttachmentSize | Default | Sm | Xs — Xs renders media + title only. |
.vertical() | -> Self | Stacks media above content; action pinned top-right. |
.removable(bool) | bool | Shows the focusable × action (default true). |
.openable(bool) | bool | Adds a card-wide trigger emitting AttachmentOpenEvent. |
.dark(bool) | bool | Dark color scheme for surface, text and borders. |
AttachmentRemoveEvent | { name } | Emitted on × press; subscribe with cx.subscribe. |
AttachmentOpenEvent | { name } | Emitted on card press when openable. |
// Both events carry the attachment title.cx.subscribe(&self.attachment, |view, _a, event: &AttachmentRemoveEvent, cx| { view.files.retain(|f| *f != event.name); cx.notify();});cx.subscribe(&self.attachment, |view, _a, event: &AttachmentOpenEvent, cx| { view.preview = Some(event.name.clone()); cx.notify();});Source & inspiration
结构与视觉参考 shadcn/ui Attachment 。本页交互由 Rust / GPUI 绘制,基础样式来自 gpui-kit 。