Skip to main content

yew_tincture/components/
checkbox_label.rs

1use yew::{html, Callback, Component, Context, Html, Properties};
2
3pub struct CheckboxLabel {
4    css_id: String,
5    /// copy of state in DOM
6    checked: bool,
7}
8
9pub enum Msg {
10    Toggle,
11}
12
13#[derive(PartialEq, Properties)]
14pub struct Props {
15    #[prop_or_default]
16    pub label: String,
17    #[prop_or_default]
18    pub oncheck: Option<Callback<bool>>,
19    /// Sets the `checked` property once, upon the creation of the checkbox.
20    #[prop_or_default]
21    pub initially_checked: bool,
22    /// When not None, sets the `checked` property of the checkbox.
23    #[prop_or_default]
24    pub updating_checked: Option<bool>,
25}
26
27impl Component for CheckboxLabel {
28    type Message = Msg;
29    type Properties = Props;
30
31    fn create(ctx: &Context<Self>) -> Self {
32        Self {
33            css_id: uuid::Uuid::new_v4().to_string(),
34            checked: ctx.props().initially_checked,
35        }
36    }
37
38    fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
39        match msg {
40            Msg::Toggle => {
41                let checked = !self.checked;
42                self.checked = checked;
43                if let Some(ref callback) = &ctx.props().oncheck {
44                    callback.emit(checked);
45                }
46            }
47        }
48        true
49    }
50
51    fn view(&self, ctx: &Context<Self>) -> Html {
52        // Hmm, putting this in one html!{} macro fails, so make a list
53        // manually.
54
55        // Ideally, the structure would be <label><input /></label> but
56        // I could not get this to work, so we are using `css_id` here.
57        let el1 = html! {
58            <input
59                id={self.css_id.clone()}
60                type="checkbox"
61                checked={self.checked}
62                onclick={ctx.link().callback(|_| Msg::Toggle)}
63                />
64        };
65        let el2 = html! {
66            <label for={self.css_id.clone()}>
67                {ctx.props().label.as_str()}
68            </label>
69        };
70        let mut vlist = yew::virtual_dom::vlist::VList::new();
71        vlist.add_child(el1);
72        vlist.add_child(el2);
73        vlist.into()
74    }
75}