waterui_controls/toggle.rs
1//! A boolean toggle switch backed by a reactive binding.
2//!
3//! 
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", ¬ifications),
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}