1use yew::prelude::*;
2
3pub struct Modal {
4    props: Props,
5    link: ComponentLink<Self>,
6}
7
8#[derive(Clone, Properties)]
9pub struct Props {
10    pub visible: bool,
11
12    #[prop_or_default]
13    pub close_requested: Callback<()>,
14    #[prop_or_default]
15    pub close_button: bool,
16    #[prop_or_default]
17    pub children: Children,
18}
19
20pub enum Message {
21    CloseRequested,
22}
23
24impl Component for Modal {
25    type Message = Message;
26    type Properties = Props;
27
28    fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
29        Self { props, link }
30    }
31
32    fn update(&mut self, msg: Self::Message) -> ShouldRender {
33        match msg {
34            Message::CloseRequested => {
35                self.props.close_requested.emit(());
36            }
37        }
38        false
39    }
40    fn change(&mut self, props: Self::Properties) -> ShouldRender {
41        self.props = props;
42        true
43    }
44
45    fn view(&self) -> Html {
46        html! {
47            <div class=self.css_class()>
48                <div class="modal-background" onclick=self.link.callback(|e: MouseEvent| {e.prevent_default(); Message::CloseRequested}) />
49                <div class="modal-content">
50                    { self.props.children.clone() }
51                </div>
52                { self.close_button() }
53            </div>
54        }
55    }
56}
57
58impl Modal {
59    fn css_class(&self) -> &'static str {
60        if self.props.visible {
61            "modal is-active"
62        } else {
63            "modal"
64        }
65    }
66
67    fn close_button(&self) -> Html {
68        if self.props.close_button {
69            html! {
70                <button class="modal-close is-large" aria-label="close" onclick=self.link.callback(|e: MouseEvent| {e.prevent_default(); Message::CloseRequested}) />
71            }
72        } else {
73            Html::default()
74        }
75    }
76}