waterui_controls/
toggle.rs

1//! A boolean toggle switch backed by a reactive binding.
2//!
3//! ![Toggle](https://raw.githubusercontent.com/water-rs/waterui/dev/docs/illustrations/toggle.svg)
4
5use nami::Binding;
6use waterui_core::configurable;
7
8use waterui_core::{AnyView, View};
9
10#[derive(Debug)]
11#[non_exhaustive]
12/// Configuration for the `Toggle` component.
13pub struct ToggleConfig {
14    /// The label to display for the toggle.
15    pub label: AnyView,
16    /// The binding to the toggle state.
17    pub toggle: Binding<bool>,
18}
19
20configurable!(
21    /// A control that toggles between on and off states.
22    ///
23    /// Toggle displays a switch with an optional label. It's commonly used
24    /// for settings that can be turned on or off.
25    ///
26    /// # Layout Behavior
27    ///
28    /// With a label: Toggle expands horizontally to fill available space,
29    /// placing the label on the left and switch on the right.
30    /// Without a label: Toggle is content-sized (just the switch).
31    ///
32    /// # Examples
33    ///
34    /// ```ignore
35    /// // Simple toggle with label
36    /// toggle("Wi-Fi", &is_enabled)
37    ///
38    /// // Toggle without label
39    /// Toggle::new(&dark_mode)
40    ///
41    /// // In a settings list
42    /// vstack((
43    ///     toggle("Notifications", &notifications),
44    ///     toggle("Sound", &sound),
45    /// ))
46    /// ```
47    //
48    // ═══════════════════════════════════════════════════════════════════════════
49    // INTERNAL: Layout Contract for Backend Implementers
50    // ═══════════════════════════════════════════════════════════════════════════
51    //
52    // - stretchAxis: .horizontal (toggle expands to fill available width)
53    // - sizeThatFits: Returns proposed width (or minimum), intrinsic height
54    // - Layout: label on left, switch on right, flexible space between
55    //
56    // ═══════════════════════════════════════════════════════════════════════════
57    //
58    Toggle,
59    ToggleConfig,
60    waterui_core::layout::StretchAxis::Horizontal
61);
62
63impl Toggle {
64    #[must_use]
65    /// Creates a new `Toggle` with the specified binding for the toggle state.
66    pub fn new(toggle: &Binding<bool>) -> Self {
67        Self(ToggleConfig {
68            label: AnyView::default(),
69            toggle: toggle.clone(),
70        })
71    }
72    #[must_use]
73    /// Sets the label for the toggle.
74    pub fn label(mut self, view: impl View) -> Self {
75        self.0.label = AnyView::new(view);
76        self
77    }
78}
79
80/// Creates a new `Toggle` with the specified label and binding for the toggle state.
81#[must_use]
82pub fn toggle(label: impl View, toggle: &Binding<bool>) -> Toggle {
83    Toggle::new(toggle).label(label)
84}