Collapsible
An interactive component which expands/collapses a panel.
Overview
卡片 trigger + 尾部 chevron,点击展开面板;MotionReveal 高度揭幕动画。
Installation
Collapsible 是单个 Rust 文件(src/collapsible.rs)—— 展开动画复用 gpui-base 的 MotionReveal,chevron/文件夹图标用 PathBuilder 手绘。
[dependencies]gpui-kit = "0.6.6"# collapsible.rs reuses gpui-base MotionReveal for the# height animation — no extra deps.# Download the runnable example crate, then:cargo run --locked -- --collapsible# Other demos:cargo run --locked -- --collapsible opencargo run --locked -- --collapsible settingscargo run --locked -- --collapsible file-treeUsage
Collapsible 是实体:.trigger(..) 渲染标题行,.content(..) 接收一个工厂闭包(元素每帧重建,所以传构造器而不是元素本体)。点击或 Enter/Space 切换,发出 CollapsibleChangeEvent。
use justdo_command::collapsible::{Collapsible, CollapsibleChangeEvent};// One entity owns the open state and the reveal animation.let details = cx.new(|_| { Collapsible::new() .trigger("Product details") .content(|| { div() .child("This panel can be expanded or collapsed.") .into_any_element() })});cx.subscribe(&details, |view, _, ev: &CollapsibleChangeEvent, cx| { view.details_open = ev.open; cx.notify();});div().child(details)网页预览与桌面端运行同一份 Rust / GPUI 组件。
Composition
结构对应 Collapsible → Trigger + Content:trigger 是单行实体按钮,content 面板经 MotionReveal 做高度揭幕动画。
Collapsible entity — trigger row + reveal panel├── trigger .trigger(..) — click row / Enter / Space toggles├── hint .hint(..) — quiet text right of the label├── chevron ChevronStyle::Down (trailing, flips 180°)│ ChevronStyle::Right (leading, rotates 90°)├── icon RowIcon::Folder | File — tree-row glyph├── content .content(|| element) — CollapsibleContent panel│ revealed with a MotionReveal height wipe├── disabled .disabled(true) — dimmed + inert└── emits CollapsibleChangeEvent { open }// Controlled state — mirror of isExpanded + onExpandedChange.// The entity stores open state; drive it with set_open and// read the change through CollapsibleChangeEvent.collapsible.update(cx, |c, cx| c.set_open(true, cx));cx.subscribe(&collapsible, |view, _, ev, cx| { view.open = ev.open; cx.notify();});Notes
内容工厂。 GPUI 元素是 render-once —— .content(..) 收 Fn() -> AnyElement,每次渲染重建面板子树。嵌套 Collapsible(文件树)直接把孩子 entity 放进闭包里 clone。
展开动画。 transition keyed-state 驱动 0↔1 进度,MotionReveal 负责高度擦除;收起时保持挂载直到动画播完。cx.reduce_motion() 下直接跳终态。
// Nested collapsibles build the file tree: each folder is an// entity whose content factory returns child rows — nested// folder entities clone cheaply (Entity<T> is a handle).let ui = folder(cx, "ui", /* open */ true, move || { files.iter().map(|f| file_row(f)).collect()});let components = folder(cx, "components", true, move || { vec![div().child(ui.clone()).into_any_element(), /* … */]});Accessibility
Keyboard
Trigger 行进入 Tab 顺序,Enter / Space 切换;chevron 方向即状态提示(右指=收起、下指=展开),不只靠颜色。
Focus
点击聚焦后可用键盘操作;disabled 行半透明且完全不响应输入或聚焦。
API Reference
实体暴露的 builder 方法、受控方法与事件。
| API | Signature | Notes |
|---|---|---|
Collapsible::new() | -> Collapsible | Collapsed, chevron-down trigger. |
.trigger(..) | &str | Trigger label; row click / Enter / Space toggles. |
.hint(..) | &str | Quiet secondary text next to the label. |
.content(..) | Fn() -> AnyElement | Panel factory — rebuilt each render (CollapsibleContent). |
.open(..) | bool | Initial state (defaultExpanded). |
.chevron(..) | ChevronStyle | Down (trailing, flips) | Right (leading, rotates 90°). |
.icon(..) | RowIcon | Folder | File glyph before the label (tree rows). |
.disabled(..) | bool | Dimmed and inert. |
.set_open(..) | bool, &mut Context | Controlled update (isExpanded / onExpandedChange). |
CollapsibleChangeEvent | { open: bool } | Emitted on every expand/collapse. |
Source & inspiration
结构与视觉参考 shadcn/ui Collapsible 。本页交互由 Rust / GPUI 绘制,基础样式来自 gpui-kit 。