1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use crate::{random_id, Icon};
use web_sys::HtmlInputElement;
use yew::prelude::*;
#[derive(Clone, PartialEq, Properties)]
pub struct Props {
#[prop_or_default]
pub id: Option<String>,
#[prop_or_default]
pub checked: bool,
#[prop_or_default]
pub label: Option<String>,
#[prop_or_default]
pub label_off: Option<String>,
#[prop_or_default]
pub disabled: bool,
#[prop_or_default]
pub on_change: Callback<bool>,
#[prop_or_default]
pub aria_label: String,
}
pub struct Switch {
id: String,
input_ref: NodeRef,
}
pub enum Msg {
Changed,
}
impl Component for Switch {
type Message = Msg;
type Properties = Props;
fn create(ctx: &Context<Self>) -> Self {
let id = ctx
.props()
.id
.as_ref()
.cloned()
.unwrap_or_else(|| random_id());
Self {
id,
input_ref: Default::default(),
}
}
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
Msg::Changed => {
ctx.props().on_change.emit(self.current_state());
return false;
}
}
}
fn changed(&mut self, ctx: &Context<Self>) -> bool {
self.id = ctx
.props()
.id
.as_ref()
.cloned()
.unwrap_or_else(|| self.id.clone());
true
}
fn view(&self, ctx: &Context<Self>) -> Html {
html! {
<label class="pf-c-switch" for={self.id.clone()}>
<input
ref={self.input_ref.clone()}
class="pf-c-switch__input"
type="checkbox"
id={self.id.clone()}
aria-label={ctx.props().aria_label.clone()}
checked={ctx.props().checked}
disabled={ctx.props().disabled}
onchange={ctx.link().callback(|_|Msg::Changed)}
/>
<span class="pf-c-switch__toggle">
if ctx.props().label.is_none() {
<span class="pf-c-switch__toggle-icon">
{ Icon::Check }
</span>
}
</span>
if let Some(ref label) = ctx.props().label {
<>
<span class="pf-c-switch__label pf-m-on">{ label }</span>
<span class="pf-c-switch__label pf-m-off">{ ctx.props().label_off.as_ref().unwrap_or_else(||label) }</span>
</>
}
</label>
}
}
}
impl Switch {
fn current_state(&self) -> bool {
self.input_ref
.cast::<HtmlInputElement>()
.map(|input| input.checked())
.unwrap_or_default()
}
}