Button Group
Group related buttons with a shared variant and merged edges.
1use herogpui::components::button_group::ButtonGroup;Usage
1use herogpui::prelude::{ActiveTheme, Button, ButtonGroup, icons};
2use gpui::prelude::*;
3use gpui::px;
4
5ButtonGroup::new()
6 .separators(true)
7 .button(Button::new("button-group-1").label("Merge pull request"))
8 .button(
9 Button::new("button-group-2")
10 .is_icon_only(true)
11 .child(gpui::svg()
12 .size(px(16.))
13 .path(icons::CHEVRON_DOWN)
14 .text_color(cx.colors().foreground)),
15 )Live HeroGPUI compiled to WebAssembly. Select any example without loading another WASM instance.
Anatomy
Rust types
ButtonGroup
Button Group is assembled from these builders. The API reference lists each one.
Customization
Appearance builders and theme tokens Button Group uses.
Styling
| Style | Description |
|---|---|
div flex items_center justify_center | Flex alignment and zero gap match; GPUI has no inline-flex display mode and relies on the parent layout for intrinsic width. |
Orientation + flex_row/flex_col | Both orientations match. |
GroupEdge + group_radius | Only the first/last external corners retain the 24px Button radius, and a lone member keeps the full radius. |
group_edge.is_none() gate | Grouped members skip Button's pressed-scale wrapper. |
ring_if_focused | The outward focus ring renders, but GPUI provides no matching local z-index elevation. |
separators + separator_variant + absolute hairline | Horizontal and vertical separator geometry and opacity match; bg-current resolves per member, so each hairline takes the resolved variant foreground of the member drawn in its slot and a type-erased child's slot falls back to the group variant. The inert opacity transition has no runtime-changing endpoint in this composition. |
Button outline + collapsed_border_sides(GroupEdge, vertical) | Each outline member drops exactly the border sides its group position shares with a neighbour, resolved per GroupEdge and orientation; a lone member is:first-child:last-child so its whole stacking-axis border collapses, and a member outside a group keeps the full border. |
full_width + Button::group_defaults + per-member flex_1 | The group root and each resolved-full member stretch; an explicit child fullWidth=false overrides the context and hugs content, matching pinned button.tsx precedence. |
API reference
Builders
| Builder | Type | Default | Description |
|---|---|---|---|
variant( | 'primary' | | — | Supplies a default variant to direct Button members while preserving explicit child variants; unset members keep Button's own default. The pinned context type is ButtonProps['variant'], so all seven values inherit. |
size( | 'sm' | | — | Supplies a default size to direct Button members while preserving explicit child sizes; unset members keep Button's own default. |
orientation( | Orientation | Orientation:: | Chooses row or column layout and the corresponding joined-edge geometry. |
full_width( | bool | false | The group root fills its parent, and each typed member resolves pinned button.tsx's finalFullWidth = fullWidth ?? Context.fullWidth: unset members inherit, an explicit child false/true overrides, and only resolved-full members take an equal stretch slot. |
is_disabled( | bool | false | Disables direct typed members unless a child explicitly sets isDisabled=false, matching pinned context precedence. |
button( | Button / AnyElement | — | Button(Button) preserves typed direct-child inheritance and joined edges; arbitrary ParentElement children are rendered but cannot receive that context after type erasure, so they take no fullWidth stretch slot either. |
separators( | bool | — | Synthesizes pinned separators through a composition flag rather than accepting browser classes. |
Parts
| Part | Description |
|---|---|
ButtonGroup | Orientation, width, direct-child defaults, and joined-edge owner. |
ButtonGroup | Optional hairline drawn by ButtonGroup::separators(bool) before each member after the first; composes one child per member, so per-member placement is not expressible. |
States
| Builder | State | Description |
|---|---|---|
Orientation::Horizontal + GroupEdge | Horizontal | Members form a row with start/end outer corners. |
Orientation::Vertical + GroupEdge | Vertical | Members form a column with top/bottom outer corners. |
full_width + w_full + resolved member flex_1 slots | Full width | The group fills its parent; each member that resolves fullWidth ?? Context.fullWidth shares the width equally, and an explicit child false frees its share. |
Button::group_defaults precedence | Disabled | Unset children inherit disabled; an explicit child false overrides it. |
Button group_edge skips anim::pressed | Pressed | Grouped buttons suppress the standalone press scale. |
Button ring_if_focused without z-10 | Focus visible | The focus ring is present, but GPUI has no z-index elevation equivalent for overlapping adjacent controls. |