@@ -282,6 +282,52 @@ impl RenderOnce for Switch {
}
}
+/// A [`Switch`] that has a [`Label`].
+#[derive(IntoElement)]
+pub struct SwitchWithLabel {
+ id: ElementId,
+ label: Label,
+ checked: ToggleState,
+ on_click: Arc<dyn Fn(&ToggleState, &mut WindowContext) + 'static>,
+}
+
+impl SwitchWithLabel {
+ pub fn new(
+ id: impl Into<ElementId>,
+ label: Label,
+ checked: ToggleState,
+ on_click: impl Fn(&ToggleState, &mut WindowContext) + 'static,
+ ) -> Self {
+ Self {
+ id: id.into(),
+ label,
+ checked,
+ on_click: Arc::new(on_click),
+ }
+ }
+}
+
+impl RenderOnce for SwitchWithLabel {
+ fn render(self, cx: &mut WindowContext) -> impl IntoElement {
+ h_flex()
+ .gap(DynamicSpacing::Base08.rems(cx))
+ .child(Switch::new(self.id.clone(), self.checked).on_click({
+ let on_click = self.on_click.clone();
+ move |checked, cx| {
+ (on_click)(checked, cx);
+ }
+ }))
+ .child(
+ div()
+ .id(SharedString::from(format!("{}-label", self.id)))
+ .on_click(move |_event, cx| {
+ (self.on_click)(&self.checked.inverse(), cx);
+ })
+ .child(self.label),
+ )
+ }
+}
+
impl ComponentPreview for Checkbox {
fn description() -> impl Into<Option<&'static str>> {
"A checkbox lets people choose between a pair of opposing states, like enabled and disabled, using a different appearance to indicate each state."
@@ -407,3 +453,32 @@ impl ComponentPreview for CheckboxWithLabel {
])]
}
}
+
+impl ComponentPreview for SwitchWithLabel {
+ fn description() -> impl Into<Option<&'static str>> {
+ "A switch with an associated label, allowing users to select an option while providing a descriptive text."
+ }
+
+ fn examples(_: &mut WindowContext) -> Vec<ComponentExampleGroup<Self>> {
+ vec![example_group(vec![
+ single_example(
+ "Off",
+ SwitchWithLabel::new(
+ "switch_with_label_unselected",
+ Label::new("Always save on quit"),
+ ToggleState::Unselected,
+ |_, _| {},
+ ),
+ ),
+ single_example(
+ "On",
+ SwitchWithLabel::new(
+ "switch_with_label_selected",
+ Label::new("Always save on quit"),
+ ToggleState::Selected,
+ |_, _| {},
+ ),
+ ),
+ ])]
+ }
+}
@@ -6,7 +6,7 @@ use ui::{
element_cell, prelude::*, string_cell, utils::calculate_contrast_ratio, AudioStatus,
Availability, Avatar, AvatarAudioStatusIndicator, AvatarAvailabilityIndicator, ButtonLike,
Checkbox, CheckboxWithLabel, ContentGroup, DecoratedIcon, ElevationIndex, Facepile,
- IconDecoration, Indicator, Switch, Table, TintColor, Tooltip,
+ IconDecoration, Indicator, Switch, SwitchWithLabel, Table, TintColor, Tooltip,
};
use crate::{Item, Workspace};
@@ -369,16 +369,17 @@ impl ThemePreview {
.overflow_scroll()
.size_full()
.gap_2()
- .child(Switch::render_component_previews(cx))
- .child(ContentGroup::render_component_previews(cx))
- .child(IconDecoration::render_component_previews(cx))
- .child(DecoratedIcon::render_component_previews(cx))
+ .child(Button::render_component_previews(cx))
.child(Checkbox::render_component_previews(cx))
.child(CheckboxWithLabel::render_component_previews(cx))
+ .child(ContentGroup::render_component_previews(cx))
+ .child(DecoratedIcon::render_component_previews(cx))
.child(Facepile::render_component_previews(cx))
- .child(Button::render_component_previews(cx))
- .child(Indicator::render_component_previews(cx))
.child(Icon::render_component_previews(cx))
+ .child(IconDecoration::render_component_previews(cx))
+ .child(Indicator::render_component_previews(cx))
+ .child(Switch::render_component_previews(cx))
+ .child(SwitchWithLabel::render_component_previews(cx))
.child(Table::render_component_previews(cx))
}