patternfly_yew/components/
switch.rs

1//! Switch control
2use crate::ouia;
3use crate::prelude::{Icon, OuiaComponentType};
4use crate::utils::{Ouia, OuiaSafe};
5use web_tools::prelude::*;
6use yew::prelude::*;
7
8const OUIA: Ouia = ouia!("Switch");
9
10/// Properties for [`Switch`]
11#[derive(Clone, PartialEq, Properties)]
12pub struct SwitchProperties {
13    #[prop_or_default]
14    pub id: Option<String>,
15
16    #[prop_or_default]
17    pub checked: bool,
18
19    #[prop_or_default]
20    pub label: Option<String>,
21    #[prop_or_default]
22    pub label_off: Option<String>,
23    #[prop_or_default]
24    pub disabled: bool,
25
26    #[prop_or_default]
27    pub onchange: Callback<bool>,
28
29    #[prop_or_default]
30    pub aria_label: String,
31
32    /// OUIA Component id
33    #[prop_or_default]
34    pub ouia_id: Option<String>,
35    /// OUIA Component Type
36    #[prop_or(OUIA.component_type())]
37    pub ouia_type: OuiaComponentType,
38    /// OUIA Component Safe
39    #[prop_or(OuiaSafe::TRUE)]
40    pub ouia_safe: OuiaSafe,
41}
42
43/// Switch component
44///
45/// > A **switch** toggles the state of a setting (between on and off). Switches and checkboxes can often be used interchangeably, but the switch provides a more explicit, visible representation on a setting.
46///
47/// See: <https://www.patternfly.org/components/switch>
48///
49/// ## Properties
50///
51/// Defined by [`SwitchProperties`].
52#[function_component(Switch)]
53pub fn switch(props: &SwitchProperties) -> Html {
54    let ouia_id = use_memo(props.ouia_id.clone(), |id| {
55        id.clone().unwrap_or(OUIA.generated_id())
56    });
57    let input_ref = use_node_ref();
58
59    let onchange = use_callback(
60        (input_ref.clone(), props.onchange.clone()),
61        |_evt, (input_ref, onchange)| onchange.emit(input_ref.checked()),
62    );
63
64    html! (
65        <label
66            class="pf-v5-c-switch"
67            for={props.id.clone()}
68            data-ouia-component-id={(*ouia_id).clone()}
69            data-ouia-component-type={props.ouia_type}
70            data-ouia-safe={props.ouia_safe}
71        >
72            <input
73                ref={input_ref.clone()}
74                class="pf-v5-c-switch__input"
75                type="checkbox"
76                id={props.id.clone()}
77                aria-label={props.aria_label.clone()}
78                checked={props.checked}
79                disabled={props.disabled}
80                {onchange}
81            />
82            <span class="pf-v5-c-switch__toggle">
83                if props.label.is_none() {
84                    <span class="pf-v5-c-switch__toggle-icon">
85                        { Icon::Check }
86                    </span>
87                }
88            </span>
89            if let Some(ref label) = props.label {
90                <>
91                    <span class="pf-v5-c-switch__label pf-m-on">{ label }</span>
92                    <span class="pf-v5-c-switch__label pf-m-off">{ props.label_off.as_ref().unwrap_or(label) }</span>
93                </>
94            }
95        </label>
96    )
97}