@@ -543,28 +543,48 @@ impl RenderOnce for Switch {
}
}
-/// A [`Switch`] that has a [`Label`].
-#[derive(IntoElement)]
-pub struct SwitchWithLabel {
+/// # SwitchField
+///
+/// A field component that combines a label, description, and switch into one reusable component.
+///
+/// # Examples
+///
+/// ```
+/// use ui::prelude::*;
+///
+/// SwitchField::new(
+/// "feature-toggle",
+/// "Enable feature",
+/// "This feature adds new functionality to the app.",
+/// ToggleState::Unselected,
+/// |state, window, cx| {
+/// // Logic here
+/// }
+/// );
+/// ```
+#[derive(IntoElement, RegisterComponent)]
+pub struct SwitchField {
id: ElementId,
- label: Label,
+ label: SharedString,
+ description: SharedString,
toggle_state: ToggleState,
on_click: Arc<dyn Fn(&ToggleState, &mut Window, &mut App) + 'static>,
disabled: bool,
color: SwitchColor,
}
-impl SwitchWithLabel {
- /// Creates a switch with an attached label.
+impl SwitchField {
pub fn new(
id: impl Into<ElementId>,
- label: Label,
+ label: impl Into<SharedString>,
+ description: impl Into<SharedString>,
toggle_state: impl Into<ToggleState>,
on_click: impl Fn(&ToggleState, &mut Window, &mut App) + 'static,
) -> Self {
Self {
id: id.into(),
- label,
+ label: label.into(),
+ description: description.into(),
toggle_state: toggle_state.into(),
on_click: Arc::new(on_click),
disabled: false,
@@ -572,43 +592,141 @@ impl SwitchWithLabel {
}
}
- /// Sets the disabled state of the [`SwitchWithLabel`].
pub fn disabled(mut self, disabled: bool) -> Self {
self.disabled = disabled;
self
}
/// Sets the color of the switch using the specified [`SwitchColor`].
+ /// This changes the color scheme of the switch when it's in the "on" state.
pub fn color(mut self, color: SwitchColor) -> Self {
self.color = color;
self
}
}
-impl RenderOnce for SwitchWithLabel {
- fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
+impl RenderOnce for SwitchField {
+ fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
h_flex()
.id(SharedString::from(format!("{}-container", self.id)))
- .gap(DynamicSpacing::Base08.rems(cx))
+ .w_full()
+ .gap_4()
+ .justify_between()
+ .flex_wrap()
.child(
- Switch::new(self.id.clone(), self.toggle_state)
- .disabled(self.disabled)
- .color(self.color)
- .on_click({
- let on_click = self.on_click.clone();
- move |checked, window, cx| {
- (on_click)(checked, window, cx);
- }
- }),
+ v_flex()
+ .gap_0p5()
+ .max_w_5_6()
+ .child(Label::new(self.label))
+ .child(Label::new(self.description).color(Color::Muted)),
)
.child(
- div()
- .id(SharedString::from(format!("{}-label", self.id)))
- .child(self.label),
+ Switch::new(
+ SharedString::from(format!("{}-switch", self.id)),
+ self.toggle_state,
+ )
+ .color(self.color)
+ .disabled(self.disabled)
+ .on_click({
+ let on_click = self.on_click.clone();
+ move |state, window, cx| {
+ (on_click)(state, window, cx);
+ }
+ }),
)
}
}
+impl Component for SwitchField {
+ fn scope() -> ComponentScope {
+ ComponentScope::Input
+ }
+
+ fn description() -> Option<&'static str> {
+ Some("A field component that combines a label, description, and switch")
+ }
+
+ fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
+ Some(
+ v_flex()
+ .gap_6()
+ .children(vec![
+ example_group_with_title(
+ "States",
+ vec![
+ single_example(
+ "Unselected",
+ SwitchField::new(
+ "switch_field_unselected",
+ "Enable notifications",
+ "Receive notifications when new messages arrive.",
+ ToggleState::Unselected,
+ |_, _, _| {},
+ )
+ .into_any_element(),
+ ),
+ single_example(
+ "Selected",
+ SwitchField::new(
+ "switch_field_selected",
+ "Enable notifications",
+ "Receive notifications when new messages arrive.",
+ ToggleState::Selected,
+ |_, _, _| {},
+ )
+ .into_any_element(),
+ ),
+ ],
+ ),
+ example_group_with_title(
+ "Colors",
+ vec![
+ single_example(
+ "Default",
+ SwitchField::new(
+ "switch_field_default",
+ "Default color",
+ "This uses the default switch color.",
+ ToggleState::Selected,
+ |_, _, _| {},
+ )
+ .into_any_element(),
+ ),
+ single_example(
+ "Accent",
+ SwitchField::new(
+ "switch_field_accent",
+ "Accent color",
+ "This uses the accent color scheme.",
+ ToggleState::Selected,
+ |_, _, _| {},
+ )
+ .color(SwitchColor::Accent)
+ .into_any_element(),
+ ),
+ ],
+ ),
+ example_group_with_title(
+ "Disabled",
+ vec![single_example(
+ "Disabled",
+ SwitchField::new(
+ "switch_field_disabled",
+ "Disabled field",
+ "This field is disabled and cannot be toggled.",
+ ToggleState::Selected,
+ |_, _, _| {},
+ )
+ .disabled(true)
+ .into_any_element(),
+ )],
+ ),
+ ])
+ .into_any_element(),
+ )
+ }
+}
+
impl Component for Checkbox {
fn scope() -> ComponentScope {
ComponentScope::Input