Component 09 of 60
Checkbox
A control that toggles between checked and unchecked.
Starting the preview. GPUI compiles to WebAssembly, so the first load takes a few seconds. This browser has neither WebGPU nor WebGL 2, so the live preview cannot run. The code on this page still works. The preview did not start.
fn checkbox_preview(&self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let checkbox_view = cx.entity().downgrade();
let label_view = cx.entity().downgrade();
div()
.flex()
.flex_col()
.gap(px(16.0))
.child(
div()
.flex()
.items_center()
.gap(px(8.0))
.child(
Checkbox::new("preview.checkbox.interactive")
.checked(self.checked)
.aria_label("Accept terms")
.on_change(move |checked, _, _, cx| {
checkbox_view
.update(cx, |this, cx| {
this.checked = checked;
cx.notify();
})
.ok();
}),
)
.child(
div()
.id("preview.checkbox.interactive-label")
.cursor_pointer()
.on_click(move |_, _, cx| {
label_view
.update(cx, |this, cx| {
this.checked = !this.checked;
cx.notify();
})
.ok();
})
.child(if self.checked {
"Accepted"
} else {
"Accept terms"
}),
),
)
.child(checkbox_row(
Checkbox::new("preview.checkbox.indeterminate")
.indeterminate(true)
.aria_label("Partly selected"),
"Partly selected",
))
.child(checkbox_row(
Checkbox::new("preview.checkbox.disabled")
.checked(true)
.disabled(true)
.aria_label("Disabled"),
"Disabled",
))
.child(checkbox_row(
Checkbox::new("preview.checkbox.readonly")
.checked(true)
.read_only(true)
.aria_label("Read only"),
"Read only",
))
}
Installation
After the one-time setup, run the command from your app root. The CLI
writes the modules and keeps src/ui/mod.rs in step.
gpuicn add checkbox
If you prefer to copy the files by hand, declare them yourself:
// src/ui/mod.rs
pub mod theme;
pub mod checkbox;
// src/main.rs
mod ui;
Usage
Put this in a view module and return example(checked) from its render method.
use crate::ui::checkbox::*;
use gpui_kit::IntoElement;
fn example(checked: bool) -> impl IntoElement {
Checkbox::new("terms")
.checked(checked)
.aria_label("Accept terms")
.on_change(|checked, _, _, _| println!("Accepted: {checked}"))
}
API reference
pub fn new(id: impl Into<ElementId>) -> Self
Creates a `Checkbox` with a stable caller-owned ID.
pub fn checked(mut self, value: bool) -> Self
Sets the caller-owned checked state.
pub fn indeterminate(mut self, value: bool) -> Self
Shows mixed or unknown state.
pub fn disabled(mut self, value: bool) -> Self
Disables interaction and applies the disabled appearance.
pub fn read_only(mut self, value: bool) -> Self
Prevents user changes while preserving focus and reading.
pub fn aria_label(mut self, value: impl Into<SharedString>) -> Self
Sets the accessible name of the control.
pub fn on_change(
mut self,
handler: impl Fn(bool, &ClickEvent, &mut Window, &mut App) + 'static,
) -> Self
Reports a requested value change; retain the next value in the owning view.
Installed source, 109 lines
//! Nova-styled controlled checkbox using GPUI Kit's interaction and accessibility.
use super::theme::{
UiTheme,
primitives::{control, disabled, focus},
};
use gpui_kit::base::{Checkbox as BaseCheckbox, CheckboxState};
use gpui_kit::{
App, ClickEvent, ElementId, InteractiveElement as _, IntoElement, RenderOnce, SharedString,
StatefulInteractiveElement as _, Styled, Window, prelude::FluentBuilder as _,
};
use std::rc::Rc;
type ChangeHandler = Rc<dyn Fn(bool, &ClickEvent, &mut Window, &mut App)>;
#[derive(IntoElement)]
/// A controlled Nova checkbox with optional mixed state.
pub struct Checkbox {
style: gpui_kit::StyleRefinement,
id: ElementId,
checked: bool,
indeterminate: bool,
disabled: bool,
read_only: bool,
label: Option<SharedString>,
on_change: Option<ChangeHandler>,
}
impl Checkbox {
/// Creates a `Checkbox` with a stable caller-owned ID.
pub fn new(id: impl Into<ElementId>) -> Self {
Self {
style: Default::default(),
id: id.into(),
checked: false,
indeterminate: false,
disabled: false,
read_only: false,
label: None,
on_change: None,
}
}
/// Sets the caller-owned checked state.
pub fn checked(mut self, value: bool) -> Self {
self.checked = value;
self
}
/// Shows mixed or unknown state.
pub fn indeterminate(mut self, value: bool) -> Self {
self.indeterminate = value;
self
}
/// Disables interaction and applies the disabled appearance.
pub fn disabled(mut self, value: bool) -> Self {
self.disabled = value;
self
}
/// Prevents user changes while preserving focus and reading.
pub fn read_only(mut self, value: bool) -> Self {
self.read_only = value;
self
}
/// Sets the accessible name of the control.
pub fn aria_label(mut self, value: impl Into<SharedString>) -> Self {
self.label = Some(value.into());
self
}
/// Reports a requested value change; retain the next value in the owning view.
pub fn on_change(
mut self,
handler: impl Fn(bool, &ClickEvent, &mut Window, &mut App) + 'static,
) -> Self {
self.on_change = Some(Rc::new(handler));
self
}
}
impl RenderOnce for Checkbox {
fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
let theme = UiTheme::read(cx).clone();
let focus_theme = theme.clone();
let root = BaseCheckbox::new(self.id)
.checked(self.checked)
.indeterminate(self.indeterminate)
.disabled(self.disabled)
.when(self.read_only, |root| root.aria_description("Read only"));
let root = control::checkbox_box(root, &theme, self.checked, self.indeterminate)
.focus_visible(move |style| focus::ring(style, &focus_theme))
.when(!self.disabled && !self.read_only, |root| {
root.cursor_pointer()
})
.when(self.disabled, disabled::style)
.when_some(self.label, |root, label| root.accessibility_label(label))
.when(!self.read_only, |root| {
root.when_some(self.on_change, |root, handler| {
root.on_change(move |state, event, window, cx| {
handler(state == CheckboxState::Checked, event, window, cx)
})
})
});
super::theme::apply_style(root, &self.style)
}
}
impl Styled for Checkbox {
fn style(&mut self) -> &mut gpui_kit::StyleRefinement {
&mut self.style
}
}
Platform notes
Visual reference: shadcn/ui 4.19.0, Neutral Nova. Implementation:
crates/ui/registry/checkbox/checkbox.rs, using GPUI Kit 0.6.4.
The application passes checked state and handles on_change. Kit supplies the checkbox primitive; gpuicn adds the Nova indicator, focus border and disabled styling.
The Rust source and Usage example define the supported API. Browser DOM/CSS behavior, exact exit animations and cross-platform screen-reader parity are not implied by the native component. See migration qualification for the checks completed on this revision.