Checkbox
Select one or more values from a set.
use herogpui::components::checkbox::Checkbox;Checkbox on docs.rsSource at v0.14.0
Usage
Showing Usage, live: HeroGPUI compiled to WebAssembly. The canvas has no accessibility tree; each example's description and code below carry the same information.
Label content uses 14px medium text with 20px lines, independent of surrounding line height. Toggling animates: the accent fill scales and fades in while the check stroke draws, and unselecting undraws it; reduced motion snaps. Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.
use herogpui::prelude::{ActiveTheme, Checkbox, FieldVariant};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
let (basic, colored) = (self.cb_basic, self.cb_color);
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![
Checkbox::new("checkbox-1")
.is_selected(basic)
.hover_bg(cx.colors().accent.soft_hover())
.label(gpui::div().child("Accept the terms"))
.on_change(cx.listener(|this, v: &bool, _, cx| {
this.cb_basic = *v;
cx.notify();
}))
.into_any_element(),
Checkbox::new("checkbox-2")
.is_selected(colored)
.variant(FieldVariant::Secondary)
.label(gpui::div().child("Subscribe to updates"))
.on_change(cx.listener(|this, v: &bool, _, cx| {
this.cb_color = *v;
cx.notify();
}))
.into_any_element(),
])`text_size` replaces the label's `text-sm`; a 12/14/16px size takes v3's 16/20/24 leading. The control keeps its size step. An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::Checkbox;
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
Checkbox::new("checkbox-label-size")
.text_size(px(16.))
.label(gpui::div().child("Larger label"))
.description("The 16px control is unchanged")`size` is additive, not a prop: `Md` is the 16px control; `Sm` is a 14px control with a 10px indicator and 12px label text. Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.
use herogpui::prelude::{Checkbox, CheckboxSize};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![
Checkbox::new("checkbox-sz-sm")
.size(CheckboxSize::Sm)
.label(gpui::div().child("Small"))
.description("Supporting text aligns with this label")
.into_any_element(),
Checkbox::new("checkbox-sz-md")
.size(CheckboxSize::Md)
.label(gpui::div().child("Medium"))
.description("Supporting text aligns with this label")
.into_any_element(),
])`radius(px)` replaces the control's default `rounded-md`; `is_round` keeps its documented circle either way. An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::{Checkbox, FieldVariant};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![
Checkbox::new("checkbox-primary")
.default_selected(true)
.radius(px(4.))
.label(gpui::div().child("Primary"))
.into_any_element(),
Checkbox::new("checkbox-secondary")
.default_selected(true)
.variant(FieldVariant::Secondary)
.label(gpui::div().child("Secondary"))
.into_any_element(),
])An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::Checkbox;
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![
Checkbox::new("checkbox-round-1")
.is_round(true)
.default_selected(true)
.label(gpui::div().child("Round control"))
.into_any_element(),
Checkbox::new("checkbox-round-2")
.is_round(true)
.label(gpui::div().child("Round, unchecked"))
.into_any_element(),
])A disabled checkbox keeps its value visible but rejects presses and leaves the tab order. An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::Checkbox;
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_wrap()
.items_center()
.justify_center()
.gap(px(12.))
.children(vec![Checkbox::new("checkbox-disabled-feature")
.label("Premium Feature")
.description("This feature is coming soon")
.is_disabled(true)
.into_any_element()])An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::{Checkbox, Label};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_wrap()
.items_center()
.justify_center()
.gap(px(12.))
.children(vec![gpui::div()
.flex()
.items_center()
.gap(px(12.))
.child(Checkbox::new("checkbox-external"))
.child(Label::new("Send me marketing emails"))
.into_any_element()])An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::Checkbox;
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![Checkbox::new("checkbox-desc")
.default_selected(true)
.label(gpui::div().child("Weekly digest"))
.description("One email every Monday morning.")
.into_any_element()])An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::Checkbox;
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![Checkbox::new("checkbox-default")
.default_selected(true)
.label(gpui::div().child("On by default"))
.into_any_element()])An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::Checkbox;
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![Checkbox::new("checkbox-invalid")
.is_required(true)
.is_invalid(true)
.validation_errors(["You must accept the terms"])
.label(gpui::div().child("Accept the terms"))
.into_any_element()])Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.
use herogpui::prelude::{ActiveTheme, Checkbox};
use herogpui::gpui::prelude::*;
use herogpui::gpui::{App, px};
use herogpui::gpui;
let cb_controlled = self.demo_flag("cb-controlled", false);
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![
Checkbox::new("checkbox-controlled")
.is_selected(cb_controlled)
.label(gpui::div().child("Notifications"))
.on_change(cx.listener(|this, v: &bool, _, cx| {
this.set_demo_flag("cb-controlled", *v);
cx.notify();
}))
.into_any_element(),
para(
if cb_controlled {
"Status: selected"
} else {
"Status: not selected"
},
cx,
),
])Also calls para (included when you copy).
A "select all" checkbox: it starts indeterminate, and the first change clears the dash and follows the press. Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.
use herogpui::prelude::Checkbox;
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![
Checkbox::new("checkbox-indeterminate-select-all")
.label("Select all")
.description("Shows indeterminate state (dash icon)")
.is_selected(self.cb_select_all_selected)
.is_indeterminate(self.cb_select_all_indeterminate)
.on_change(cx.listener(
|this, selected: &bool, _, cx| {
this.cb_select_all_selected = *selected;
this.cb_select_all_indeterminate = false;
cx.notify();
},
))
.into_any_element(),
])An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::Checkbox;
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![Checkbox::new("checkbox-form")
.name("terms")
.value("accepted")
.is_required(true)
.label(gpui::div().child("Accept the terms"))
.into_any_element()])Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.
use herogpui::prelude::Checkbox;
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
let cb_controlled = self.demo_flag("cb-controlled", false);
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![Checkbox::new("checkbox-render")
.is_selected(cb_controlled)
.on_change(cx.listener(|this, v: &bool, _, cx| {
this.set_demo_flag("cb-controlled", *v);
cx.notify();
}))
.content(|state| {
gpui::div()
.child(if state.is_selected {
"Terms accepted"
} else {
"Accept terms"
})
.into_any_element()
})
.into_any_element()])An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::{Checkbox, icons};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_wrap()
.items_center()
.justify_center()
.gap(px(12.))
.children(vec![
Checkbox::new("checkbox-ind-heart")
.default_selected(true)
.indicator(move |state| {
if state.is_selected {
gpui::svg()
.size(px(10.))
.path(icons::HEART_FILL)
.text_color(gpui::white())
.into_any_element()
} else {
gpui::div().into_any_element()
}
})
.label(gpui::div().child("Heart"))
.into_any_element(),
Checkbox::new("checkbox-ind-plus")
.default_selected(true)
.indicator(move |state| {
if state.is_selected {
gpui::svg()
.size(px(10.))
.path(icons::PLUS)
.text_color(gpui::white())
.into_any_element()
} else {
gpui::div().into_any_element()
}
})
.label(gpui::div().child("Plus"))
.into_any_element(),
Checkbox::new("checkbox-ind-minus")
.is_indeterminate(true)
.indicator(move |state| {
if state.is_indeterminate {
gpui::div()
.w(px(10.))
.h(px(2.))
.rounded_full()
.bg(gpui::white())
.into_any_element()
} else {
gpui::div().into_any_element()
}
})
.label(gpui::div().child("Indeterminate"))
.into_any_element(),
])Helpers used by these examples
Plain functions over the public API, defined once here and copied with each example that calls them.
fn para(text: &str, cx: &App) -> gpui::AnyElement {
let colors = cx.colors();
gpui::div()
.text_size(px(14.5))
.line_height(px(24.))
.text_color(colors.foreground)
.max_w(px(720.))
.child(text.to_owned())
.into_any_element()
}Anatomy
Rust types
Checkbox is assembled from these builders. The API reference lists each one.
Customization
Shared appearance belongs on ThemeBuilder::components and .recipe("name"). Typed builders change how Checkbox looks at one call site. Every builder also carries sx for placement, width and flex: it takes GPUI's own styling methods and refines them over the component's root after the theme, so an instance override wins. Behaviour builders live in the API reference below.
Styling
| Method | Values | Description |
|---|---|---|
variant(FieldVariant) | FieldVariant::Primary | FieldVariant::Secondary | Primary field chrome or the flat surface treatment. |
// The one slot for caller-owned low-level styling: GPUI's
// styling methods, refined over the root element last.
.sx(|el| {
el.bg(gpui::rgba(0xffa500ff)) // background
.text_color(gpui::rgba(0x000000ff)) // text
.w(gpui::px(13.)) // size
.h(gpui::px(12.))
})API reference
Against HeroUI v3.2.6: 32 entries ported, 3 partial, 2 not ported. Partial rows are marked in the tables; entries not ported are listed under each table with the reason.
Builders
| Builder | Values | Default | Description |
|---|---|---|---|
is_selected( | true | | false | Whether the checkbox is checked (controlled). |
default_selected( | true | | false | Whether the checkbox is checked initially (uncontrolled). |
is_indeterminate( | true | | false | Whether the checkbox displays the indeterminate mark. |
is_disabled( | true | | false | Disables interaction, focus and form submission. |
is_invalid( | true | | false | Marks the checkbox invalid. |
is_read_only( | true | | false | Keeps the checkbox focusable while preventing selection changes. |
is_required( | true | | false | Requires the checkbox to be selected for native validation. |
validate( | Fn( | โ | Custom validation function. |
validation_behavior( | ValidationBehavior:: | ValidationBehavior:: | Whether invalid state blocks form submission or is announced only. |
variant( | FieldVariant:: | FieldVariant:: | Primary field chrome or the flat surface treatment. |
name( | string | โ | Submitted form field name. |
value( | string | โ | Submitted value when selected. |
on_change( | Fn( | โ | Handler called when selection changes. |
label(Partial | AnyElement | | โ | Static children compose or a render function receives the live field state for the clickable content; Description and FieldError remain static sibling builders. |
label(Partial | AnyElement | | โ | Clickable control and label content; static content is composed by the monolithic row. |
content( | true | | โ | Current selected state supplied to root content and the indicator renderer. |
content( | true | | โ | Current indeterminate state supplied to root content and the indicator renderer. |
content( | true | | โ | Current disabled state supplied to root content and the indicator renderer. |
content( | true | | โ | Current read-only state supplied to root content and the indicator renderer. |
content( | true | | โ | Current invalid state supplied to root content and the indicator renderer. |
content( | true | | โ | Current required state supplied to root content and the indicator renderer. |
Not ported2 HeroUI entries not ported
| HeroUI v3 | Why it is not ported |
|---|---|
Checkbox.render | Overrides the root element. |
Checkbox.Content.className | Classes applied to the clickable label. |
Parts
| Part | Description |
|---|---|
Checkbox | Field root that owns value, validation, focus and form state. |
Checkbox | Clickable row containing the control and label. |
Checkbox | Focusable 16px selection box. |
Checkbox | Checkmark, indeterminate mark or caller-drawn indicator. |
Checkbox | Optional field help text rendered as an indented sibling below the content row. |
Checkbox | Validation message rendered as an indented sibling below the content row. |
States
| State | Builder | Description |
|---|---|---|
Selected | checked | Accent fill and checkmark are visible; the fill scales and fades in while the stroke draws, and unselecting reverses both. |
Indeterminate | is_indeterminate | Control background eases to the accent with a dash indicator; a selected fill remains visible. |
Invalid | validation::resolve | Danger treatment reflects controlled, server or custom validation. |
HoveredPartial | util::track_interaction -> fill hover colour | Active control uses the accent hover fill. |
Focus visible | tab_stop_handle | Keyboard focus rings the control. |
Disabled | is_disabled | Control is dimmed, inert and outside the tab order. |
Pressed | on_click keyboard/pointer arbitration | Press activation toggles on Space or pointer release; declares no additional pressed rule body. |
Read only | is_read_only gates activation only | Control remains focusable but selection cannot change. |