1mod drawer_app_content;
2mod drawer_header;
3mod drawer_subtitle;
4mod drawer_title;
5
6pub use drawer_app_content::*;
7pub use drawer_header::*;
8pub use drawer_subtitle::*;
9pub use drawer_title::*;
10
11use crate::{bool_to_option, WeakComponentLink};
12use gloo::events::EventListener;
13use wasm_bindgen::prelude::*;
14use web_sys::Node;
15use yew::prelude::*;
16use yew::virtual_dom::AttrValue;
17
18#[wasm_bindgen(module = "/build/mwc-drawer.js")]
19extern "C" {
20 #[derive(Debug)]
21 #[wasm_bindgen(extends = Node)]
22 type Drawer;
23
24 #[wasm_bindgen(getter, static_method_of = Drawer)]
25 fn _dummy_loader() -> JsValue;
26
27 #[wasm_bindgen(method, getter)]
28 fn open(this: &Drawer) -> bool;
29
30 #[wasm_bindgen(method, setter)]
31 fn set_open(this: &Drawer, value: bool);
32
33 #[wasm_bindgen(method, setter)]
34 fn set_type(this: &Drawer, value: &JsValue);
35}
36
37loader_hack!(Drawer);
38
39pub struct MatDrawer {
43 node_ref: NodeRef,
44 opened_listener: Option<EventListener>,
45 closed_listener: Option<EventListener>,
46}
47
48#[derive(Properties, PartialEq, Clone)]
55pub struct DrawerProps {
56 #[prop_or_default]
57 pub open: bool,
58 #[prop_or_default]
59 pub has_header: bool,
60 #[prop_or_default]
61 pub drawer_type: Option<AttrValue>,
62 #[prop_or_default]
66 pub onopened: Callback<()>,
67 #[prop_or_default]
71 pub onclosed: Callback<()>,
72 #[prop_or_default]
73 pub drawer_link: WeakComponentLink<MatDrawer>,
74 pub children: Children,
75}
76
77impl Component for MatDrawer {
78 type Message = ();
79 type Properties = DrawerProps;
80
81 fn create(ctx: &Context<Self>) -> Self {
82 ctx.props()
83 .drawer_link
84 .borrow_mut()
85 .replace(ctx.link().clone());
86 Drawer::ensure_loaded();
87 Self {
88 node_ref: NodeRef::default(),
89 opened_listener: None,
90 closed_listener: None,
91 }
92 }
93
94 fn view(&self, ctx: &Context<Self>) -> Html {
95 let props = ctx.props();
96 html! {
97 <mwc-drawer hasHeader={bool_to_option(props.has_header)} ref={self.node_ref.clone()}>
98 {props.children.clone()}
99 </mwc-drawer>
100 }
101 }
102
103 fn rendered(&mut self, ctx: &Context<Self>, _first_render: bool) {
104 let props = ctx.props();
105 let element = self.node_ref.cast::<Drawer>().unwrap();
106 element.set_type(&JsValue::from(
107 props
108 .drawer_type
109 .as_ref()
110 .map(|s| s.as_ref())
111 .unwrap_or_default(),
112 ));
113 element.set_open(props.open);
114
115 if self.opened_listener.is_none() {
116 let onopen_callback = props.onopened.clone();
117 self.opened_listener = Some(EventListener::new(
118 &element,
119 "MDCDrawer:opened",
120 move |_| {
121 onopen_callback.emit(());
122 },
123 ));
124 }
125
126 if self.closed_listener.is_none() {
127 let onclose_callback = props.onclosed.clone();
128 self.closed_listener = Some(EventListener::new(
129 &element,
130 "MDCDrawer:closed",
131 move |_| {
132 onclose_callback.emit(());
133 },
134 ));
135 }
136 }
137}
138
139impl WeakComponentLink<MatDrawer> {
140 pub fn flip_open_state(&self) {
142 let node_ref = self
143 .borrow()
144 .as_ref()
145 .unwrap()
146 .get_component()
147 .unwrap()
148 .node_ref
149 .clone();
150 let element = node_ref.cast::<Drawer>().unwrap();
151 let open = element.open();
152 element.set_open(!open);
153 }
154}