Controls

Switch

Toggle a single setting on or off.

Rust
1use herogpui::components::switch::Switch;

Usage

Content uses 14px text with 20px lines; the built-in label uses 16px text with 24px lines.

Rust
1use herogpui::prelude::Switch;
2use gpui::prelude::*;
3use gpui::px;
4
5gpui::div()
6    .flex()
7    .flex_col()
8    .items_start()
9    .gap(px(12.))
10    .children(vec![
11        Switch::new("switch-a")
12            .is_selected(a)
13            .label(gpui::div().child("Enable notifications"))
14            .on_change(bool_cb(cx.listener(|this, v: &bool, _, cx| {
15                this.switch_a = *v;
16                cx.notify();
17            })))
18            .into_any_element(),
19        Switch::new("switch-b")
20            .is_selected(b)
21            .label(gpui::div().child("Share usage data"))
22            .on_change(bool_cb(cx.listener(|this, v: &bool, _, cx| {
23                this.switch_b = *v;
24                cx.notify();
25            })))
26            .into_any_element(),
27    ])

Live HeroGPUI compiled to WebAssembly. Select any example without loading another WASM instance.

Anatomy

Rust types

SwitchSwitchGroup

Switch is assembled from these builders. The API reference lists each one.

Customization

Appearance builders and theme tokens Switch uses.

Styling

Switch styling
StyleDescription
text_size + line_heightContent uses 14px text with 20px lines; the built-in label uses 16px text with 24px lines.
flex_col + gap(px(4.))Field root around content, description and error.
items_center + gap(px(12.)) + text_size(px(14.))Clickable control and label row.
size match in Switch::renderTrack dimensions and radii for sm, md and lg.
thumb size match + px(2.)Thumb dimensions and resting inset.
ThumbMotionFrame + THUMB_TRANSITION_MSThumb travels from its current position and reverses without jumping.
TrackMotionFrame + TRACK_TRANSITION_MSTrack colors interpolate over 250ms and switch to an immediate fill under reduced motion.
pl(w + px(12.))Help text aligns after the track and 12px content gap.
root opacity(layout.disabled_opacity)Disabled opacity covers content and both message rows.
thumb flex + items_center + justify_centerThumb icon alignment.
flex_col + gap(px(24.))Group root geometry.
flex_row/flex_col + gap(px(16.))Orientation-controlled items layout.

API reference

Builders

Switch builders
BuilderTypeDefaultDescription
size(Size)SizeSize::MdTrack and thumb size.
is_selected(bool)boolfalseCurrent selected state (controlled).
default_selected(bool)boolfalseInitial selected state (uncontrolled).
is_disabled(bool)boolfalseDims the whole field and removes it from interaction and form data.
is_invalid(bool)boolfalseMarks the field invalid and blocks native form submission.
is_read_only(bool)boolfalseKeeps the field focusable while preventing changes.
is_required(bool)boolfalseRequires selection under native form validation.
validate(callback)Fn(value: bool) -> ValidationError | true | null | undefinedComputes field validity from the current selection.
validation_behavior(ValidationBehavior)ValidationBehaviorValidationBehavior::NativeChooses blocking native validation or non-blocking ARIA-style reporting.
name(value) + form_field()value) + form_field(Submitted form field name.
value(value) + form_field()value) + form_field('on'Submitted value when selected.
on_change(callback)Fn(isSelected: bool) -> ()Reports the next selection state.
on_press(callback)Fn(event: ClickEvent) -> ()Reports the next boolean.
label(element), thumb_icons(off, on), content(render)element), thumb_icons(off, on), content(renderLabel, control content and a state-driven content closure are supported.
content(render)boolCurrent selected state supplied to custom content.
orientation(Orientation)OrientationOrientation::VerticalDirection of the items container.
child(element) / ParentElementAnyElementIndependent Switch children.

Parts

Switch parts
PartDescription
SwitchField root carrying selection, validation, form and disabled state.
SwitchClickable row containing the control and label in caller-selected order.
SwitchFocusable track and interaction surface.
SwitchState-positioned thumb with optional content.
SwitchCentered off/on icon inside the thumb.
SwitchOptional label before or after the control.
SwitchSize-aligned help text outside the clickable row.
SwitchSize-aligned validation text outside the clickable row.
SwitchGroupLayout root for independent switches.
SwitchGroupHorizontal or vertical items container.

States

Switch states
BuilderStateDescription
checkedSelectedAccent track and end-positioned foreground thumb.
hover style + SwitchState::is_hoveredHoveredTrack changes to the hover token and custom content sees isHovered.
active style + SwitchState::is_pressedPressedTrack uses the pressed token and custom content sees isPressed.
ring_if_focused + focus_visibleFocus visibleKeyboard focus rings the track.
is_disabledDisabledWhole field is dimmed, inert, untabbable and omitted from form data.
is_read_onlyRead onlyField stays focusable but pointer and keyboard activation do nothing.
validation::resolve + LiveFormFieldState::is_invalidInvalidResolved validation is rendered and blocks native form submission.
is_requiredRequiredRequired marker and native empty-selection validation.
SwitchGroup::orientation(Orientation::Vertical)Vertical groupItems stack in a column.
SwitchGroup::orientation(Orientation::Horizontal)Horizontal groupItems flow in a row.