patternfly_yew/components/
switch.rs1use 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#[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 #[prop_or_default]
34 pub ouia_id: Option<String>,
35 #[prop_or(OUIA.component_type())]
37 pub ouia_type: OuiaComponentType,
38 #[prop_or(OuiaSafe::TRUE)]
40 pub ouia_safe: OuiaSafe,
41}
42
43#[function_component(Switch)]
53pub fn switch(props: &SwitchProperties) -> Html {
54 let checked = use_state(|| props.checked);
55
56 use_effect_with(
57 (props.checked, checked.setter()),
58 |(checked, checked_setter)| {
59 checked_setter.set(*checked);
60 },
61 );
62
63 let ouia_id = use_memo(props.ouia_id.clone(), |id| {
64 id.clone().unwrap_or(OUIA.generated_id())
65 });
66 let input_ref = use_node_ref();
67
68 let onchange = use_callback(
69 (input_ref.clone(), props.onchange.clone(), checked.setter()),
70 |_evt, (input_ref, onchange, checked_setter)| {
71 checked_setter.set(input_ref.checked());
72 onchange.emit(input_ref.checked())
73 },
74 );
75
76 let label = match (props.label.as_ref(), *checked) {
77 (Some(label), true) => html!(<span class="pf-v6-c-switch__label">{ label }</span>),
78 (Some(label), false) => {
79 let label = props.label_off.as_ref().unwrap_or(label);
80 html!(<span class="pf-v6-c-switch__label">{ label }</span>)
81 }
82 (None, _) => html!(),
83 };
84
85 html! (
86 <label
87 class="pf-v6-c-switch"
88 for={props.id.clone()}
89 data-ouia-component-id={(*ouia_id).clone()}
90 data-ouia-component-type={props.ouia_type}
91 data-ouia-safe={props.ouia_safe}
92 >
93 <input
94 ref={input_ref.clone()}
95 class="pf-v6-c-switch__input"
96 type="checkbox"
97 id={props.id.clone()}
98 aria-label={props.aria_label.clone()}
99 checked={*checked}
100 disabled={props.disabled}
101 {onchange}
102 />
103 <span class="pf-v6-c-switch__toggle">
104 if props.label.is_none() {
105 <span class="pf-v6-c-switch__toggle-icon">{ Icon::Check }</span>
106 }
107 </span>
108 { label }
109 </label>
110 )
111}