Skip to main content

mdc_yew/components/
button.rs

1use mdc_sys::{MDCRipple, get_element_by_id};
2use yew::prelude::*;
3
4pub struct Button {
5    id: String,
6    ripple: Option<MDCRipple>,
7    props: Props,
8}
9
10#[derive(Properties, Debug)]
11pub struct Props {
12    pub children: Children<Button>,
13    #[props(required)]
14    pub id: String,
15    #[props(required)]
16    pub text: String,
17    pub ripple: bool,
18    pub onclick: Option<Callback<()>>,
19}
20
21pub enum Msg {
22    Clicked,
23}
24
25impl Component for Button {
26    type Properties = Props;
27    type Message = Msg;
28
29    fn create(props: Self::Properties, _: ComponentLink<Self>) -> Self {
30        Button {
31            id: props.id.to_owned(),
32            ripple: None,
33            props,
34        }
35    }
36
37    fn mounted(&mut self) -> ShouldRender {
38        if self.props.ripple {
39            self.ripple = get_element_by_id(&self.id).map(MDCRipple::new);
40        }
41        false
42    }
43
44    fn update(&mut self, msg: Self::Message) -> ShouldRender {
45        match msg {
46            Msg::Clicked => {
47                if let Some(callback) = &self.props.onclick {
48                    callback.emit(());
49                }
50            }
51        }
52        false
53    }
54
55    fn view(&self) -> Html<Self> {
56        let ripple = if self.props.ripple {
57            html! {
58                <div class="mdc-button__ripple"></div>
59            }
60        } else {
61            html! {}
62        };
63
64        let inner = html! { <>
65            { self.props.children.render() }
66            <span class="mdc-button__label">{ &self.props.text }</span>
67        </> };
68
69        html! {
70            <button class="mdc-button mdc-button--raised"
71                    id=self.id
72                    onclick=|_| Msg::Clicked>
73                { ripple }
74                { inner }
75            </button>
76        }
77    }
78
79    fn destroy(&mut self) {
80        if let Some(ripple) = &self.ripple {
81            ripple.destroy();
82        }
83    }
84}