Button Group
A container that groups related buttons together with consistent styling.
Overview
相关动作并排:Archive / Report 合并成一组,Snooze 用间距分开。
Installation
Button Group 是单个 Rust 文件(src/button_group.rs),容器、分隔线与文本格自绘,按钮复用 button.rs —— 合并圆角与描边通过 .join() / .vjoin() 声明。
[dependencies]gpui-kit = "0.6.6"# button_group.rs composes button.rs — joined corners and merged# borders live on Button via .join() / .vjoin().# Download the runnable example crate, then:cargo run --locked -- --button-group# Other demos:cargo run --locked -- --button-group orientationcargo run --locked -- --button-group sizescargo run --locked -- --button-group nestedcargo run --locked -- --button-group separatorcargo run --locked -- --button-group splitcargo run --locked -- --button-group inputUsage
ButtonGroup 是 render-once 容器,直接 .child(..) 装按钮。参与合并的子项用 .join(Start|Middle|End)(横向)或 .vjoin(..)(纵向)标记自己在组内的位置。
use justdo_command::button_group::{ButtonGroup, group_separator, group_text};use justdo_command::button::{Button, ButtonJoin, ButtonVariant};// ButtonGroup is a render-once container — children opt into the merged// look with .join(Start|Middle|End) for horizontal and .vjoin(..) for// vertical orientation.ButtonGroup::new() .gap(px(0.)) .child( Button::new("archive").label("Archive") .variant(ButtonVariant::Outline) .join(ButtonJoin::Start), ) .child( Button::new("report").label("Report") .variant(ButtonVariant::Outline) .join(ButtonJoin::End), )网页预览与桌面端运行同一份 Rust / GPUI 组件。
Composition
组合结构对齐 shadcn/ui 的 ButtonGroup / ButtonGroupSeparator / ButtonGroupText。
ButtonGroup container — flex row/col, role="group" semantics├── Button children .join(Start|Middle|End) merges borders + corners│ .vjoin(..) same treatment stacked top-to-bottom├── group_separator() 1px divider — needed between same-surface buttons├── group_text() non-interactive label cell dressed like a button└── nested ButtonGroup groups inside groups keep the parent's gap// join() controls which corners keep their radius; Middle/End// drop the leading border (border-l-0) so the previous button's// trailing border is the shared seam — same trick as shadcn's CSS.Button::new("first").join(ButtonJoin::Start) // left corners onlyButton::new("mid").join(ButtonJoin::Middle) // square, no left borderButton::new("last").join(ButtonJoin::End) // right corners onlyNotes
Join mechanics. 与 shadcn 的 CSS 方案一致:.join(Middle) / .join(End) 的按钮去掉左边框(border-l-0)并抹平左圆角,前一枚按钮的右边框即共享接缝 —— 不用负边距,也不会遮住分隔线。.vjoin(..) 在纵向组里对应去上边框 + 上下圆角取舍。
When to use a separator. Outline 按钮自带描边,合并后自然可见分界;Default/Secondary 等同色按钮之间要显式插 group_separator(false, dark)(1px、self-stretch 全高),split button 同理。
Group vs Toggle Group. Button Group 放的是相关动作;如果需要"选中态保持"(多选/单选切换),应该用 Toggle Group —— 语义不同。
Accessibility
Role & focus
组容器对应 role="group" 语义;组内每个按钮仍是独立的 gpui_base::Button —— Tab 逐个聚焦、Enter/Space 激活、focus-visible 描边都保留。
Labeling
icon-only 成员(翻页、split 触发器)必须给 .a11y_label(..);组本身在宿主侧应有一个可读的语境标签。
API Reference
容器与辅助元素的 API。
| API | Signature | Notes |
|---|---|---|
ButtonGroup::new() | -> ButtonGroup | Render-once flex container. |
.vertical(..) | bool | Stack children top-to-bottom. |
.gap(..) | impl Into<Pixels> | Spacing between non-joined children / nested groups. |
.dark(..) | bool | Theme for separator/text cells. |
group_separator(..) | (vertical, dark) | 1px divider between same-surface buttons. |
group_text(..) | (text, dark) | Non-interactive label cell styled like a button. |
Button::join(..) | ButtonJoin | Solo | Start | Middle | End — horizontal merge. |
Button::vjoin(..) | ButtonJoin | Same, for vertical groups. |
Source & inspiration
结构与视觉参考 shadcn/ui Button Group (React Aria) 。本页交互由 Rust / GPUI 绘制,基础样式来自 gpui-kit 。