Appearance
Toggle
A button-style toggle component that represents on/off or selected states. Unlike a traditional switch, toggles appear as buttons that can be pressed in or out. They're perfect for toolbar buttons, filter options, or any binary choice that benefits from a button-like appearance.
Import
rust
use gpui_component::button::{Toggle, ToggleGroup};Usage
Basic Toggle
rust
Toggle::new("toggle1").
.label("Toggle me")
.checked(false)
.on_click(|checked, _, _| {
println!("Toggle is now: {}", checked);
})Here, we can use on_click to handle toggle state changes. The callback receives the new checked state as a bool.
Icon Toggle
rust
use gpui_component::IconName;
Toggle::new("toggle2")
.icon(IconName::Eye)
.checked(true)
.on_click(|checked, _, _| {
println!("Visibility: {}", if *checked { "shown" } else { "hidden" });
})Controlled Toggle
rust
struct MyView {
is_active: bool,
}
impl Render for MyView {
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
Toggle::new("active")
.label("Active")
.checked(self.is_active)
.on_click(cx.listener(|view, checked, _, cx| {
view.is_active = *checked;
cx.notify();
}))
}
}Toggle Variants
rust
// Ghost toggle (default)
Toggle::new("ghost-toggle")
.ghost()
.label("Ghost")
// Outline toggle
Toggle::new("outline-toggle")
.outline()
.label("Outline")Different Sizes
rust
// Extra small
Toggle::new("xs-toggle")
.icon(IconName::Star)
.xsmall()
// Small
Toggle::new("small-toggle")
.label("Small")
.small()
// Medium (default)
Toggle::new("medium-toggle")
.label("Medium")
// Large
Toggle::new("large-toggle")
.label("Large")
.large()Disabled State
rust
// Disabled unchecked
Toggle::new("disabled-toggle")
.label("Disabled")
.disabled(true)
.checked(false)
// Disabled checked
Toggle::new("disabled-checked-toggle")
.label("Selected (Disabled)")
.disabled(true)
.checked(true)Toggle vs Switch
| Feature | Toggle | Switch |
|---|---|---|
| Appearance | Button-like, can be pressed in/out | Traditional switch with sliding indicator |
| Use Cases | Toolbar buttons, filters, binary options | Settings, preferences, on/off states |
| Visual Style | Rectangular button shape | Rounded switch track with thumb |
| State Indication | Background color change, pressed appearance | Position of sliding thumb |
| Multiple Selection | Supports groups with multiple selection | Individual switches only |
Use Toggle when you want:
- Button-like appearance for binary states
- Grouping multiple related options
- Toolbar or filter interfaces
- Options that feel like "selections" rather than "settings"
Use Switch when you want:
- Traditional on/off control appearance
- Settings or preferences interface
- Clear visual indication of state with sliding animation
- Individual boolean controls
Integration with ToggleGroup
Toggle buttons can be grouped together using ToggleGroup for related options:
Basic Toggle Group
rust
ToggleGroup::new("filter-group")
.child(Toggle::new(0).icon(IconName::Bell))
.child(Toggle::new(1).icon(IconName::Bot))
.child(Toggle::new(2).icon(IconName::Inbox))
.child(Toggle::new(3).label("Other"))
.on_click(|checkeds, _, _| {
println!("Selected toggles: {:?}", checkeds);
})The on_click callback receives a Vec<bool> representing the new checked state of each toggle in the group.
Toggle Group with Controlled State
rust
struct FilterView {
notifications: bool,
bots: bool,
inbox: bool,
other: bool,
}
impl Render for FilterView {
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
ToggleGroup::new("filters")
.child(Toggle::new(0).icon(IconName::Bell).checked(self.notifications))
.child(Toggle::new(1).icon(IconName::Bot).checked(self.bots))
.child(Toggle::new(2).icon(IconName::Inbox).checked(self.inbox))
.child(Toggle::new(3).label("Other").checked(self.other))
.on_click(cx.listener(|view, checkeds, _, cx| {
view.notifications = checkeds[0];
view.bots = checkeds[1];
view.inbox = checkeds[2];
view.other = checkeds[3];
cx.notify();
}))
}
}Toggle Group Variants and Sizes
rust
// Outline variant, small size
ToggleGroup::new("compact-filters")
.outline()
.small()
.child(Toggle::new(0).icon(IconName::Filter))
.child(Toggle::new(1).icon(IconName::Sort))
.child(Toggle::new(2).icon(IconName::Search))
// Ghost variant (default), extra small
ToggleGroup::new("mini-toolbar")
.xsmall()
.child(Toggle::new(0).icon(IconName::Bold))
.child(Toggle::new(1).icon(IconName::Italic))
.child(Toggle::new(2).icon(IconName::Underline))Event Handling
Individual Toggle Events
rust
Toggle::new("subscribe-toggle")
.label("Subscribe")
.on_click(|checked, window, cx| {
if *checked {
// Handle subscription logic
println!("Subscribed!");
} else {
// Handle unsubscription logic
println!("Unsubscribed!");
}
})Examples
Toolbar with Toggle Buttons
rust
struct EditorToolbar {
bold: bool,
italic: bool,
underline: bool,
strikethrough: bool,
}
h_flex()
.gap_1()
.p_2()
.bg(cx.theme().background)
.border_1()
.border_color(cx.theme().border)
.child(
ToggleGroup::new("formatting")
.small()
.child(Toggle::new(0).icon(IconName::Bold).checked(self.bold))
.child(Toggle::new(1).icon(IconName::Italic).checked(self.italic))
.child(Toggle::new(2).icon(IconName::Underline).checked(self.underline))
.child(Toggle::new(3).icon(IconName::Strikethrough).checked(self.strikethrough))
.on_click(cx.listener(|view, states, _, cx| {
view.bold = states[0];
view.italic = states[1];
view.underline = states[2];
view.strikethrough = states[3];
cx.notify();
}))
)Filter Interface
rust
struct FilterPanel {
show_completed: bool,
show_pending: bool,
show_cancelled: bool,
show_urgent: bool,
}
v_flex()
.gap_3()
.p_4()
.child(Label::new("Filter by status"))
.child(
ToggleGroup::new("status-filters")
.outline()
.child(Toggle::new(0).label("Completed").checked(self.show_completed))
.child(Toggle::new(1).label("Pending").checked(self.show_pending))
.child(Toggle::new(2).label("Cancelled").checked(self.show_cancelled))
.on_click(cx.listener(|view, states, _, cx| {
view.show_completed = states[0];
view.show_pending = states[1];
view.show_cancelled = states[2];
cx.notify();
}))
)
.child(
Toggle::new("urgent-filter")
.label("Show urgent only")
.checked(self.show_urgent)
.on_click(cx.listener(|view, checked, _, cx| {
view.show_urgent = *checked;
cx.notify();
}))
)Settings with Individual Toggles
rust
struct NotificationSettings {
email_notifications: bool,
push_notifications: bool,
marketing_emails: bool,
}
v_flex()
.gap_4()
.child(
h_flex()
.items_center()
.justify_between()
.child(
v_flex()
.child(Label::new("Email notifications"))
.child(
Label::new("Receive notifications via email")
.text_color(cx.theme().muted_foreground)
.text_sm()
)
)
.child(
Toggle::new("email-notifications")
.icon(IconName::Mail)
.checked(self.email_notifications)
.on_click(cx.listener(|view, checked, _, cx| {
view.email_notifications = *checked;
cx.notify();
}))
)
)
.child(
h_flex()
.items_center()
.justify_between()
.child(Label::new("Push notifications"))
.child(
Toggle::new("push-notifications")
.icon(IconName::Bell)
.checked(self.push_notifications)
.on_click(cx.listener(|view, checked, _, cx| {
view.push_notifications = *checked;
cx.notify();
}))
)
)Multi-select Options
rust
struct SelectionView {
selected_categories: Vec<bool>,
}
impl SelectionView {
fn categories() -> Vec<&'static str> {
vec!["Technology", "Design", "Business", "Science", "Art"]
}
}
v_flex()
.gap_3()
.child(Label::new("Select categories of interest"))
.child(
ToggleGroup::new("categories")
.children(
Self::categories()
.into_iter()
.enumerate()
.map(|(i, category)| {
Toggle::new(i)
.label(category)
.checked(self.selected_categories.get(i).copied().unwrap_or(false))
})
)
.on_click(cx.listener(|view, states, _, cx| {
view.selected_categories = states.clone();
cx.notify();
}))
)Best Practices
- Use meaningful labels: Choose clear, descriptive text for toggle labels
- Group related options: Use ToggleGroup for logically related binary choices
- Provide visual feedback: The checked state should be clearly distinguishable
- Consider context: Use toggles for options that feel like "selections" rather than "settings"
- Maintain state consistency: Ensure toggle state reflects the actual application state
- Accessible labels: Provide tooltips or ARIA labels for icon-only toggles