patternfly_yew/utils/
global_close.rs1use std::ops::Deref;
2use wasm_bindgen::prelude::*;
3use wasm_bindgen::JsCast;
4use web_sys::window;
5use yew::prelude::*;
6
7const CLICK_TYPE: &str = "mousedown";
8
9pub struct GlobalClose {
23 node_ref: NodeRef,
24 listener: Closure<dyn Fn(MouseEvent)>,
25}
26
27impl GlobalClose {
28 pub fn new(node_ref: NodeRef, callback: Callback<()>) -> Self {
29 let cloned_ref = node_ref.clone();
30 let listener = Closure::wrap(Box::new(move |e: MouseEvent| {
31 if let Some(control_ref) = cloned_ref.get() {
32 if !control_ref.contains(e.target().as_ref().and_then(|t| t.dyn_ref())) {
33 callback.emit(());
34 }
35 }
36 }) as Box<dyn Fn(MouseEvent)>);
37
38 if let Some(cb) = listener.as_ref().dyn_ref() {
39 window()
40 .unwrap()
41 .add_event_listener_with_callback(CLICK_TYPE, cb)
42 .ok();
43 }
44
45 Self { node_ref, listener }
46 }
47
48 pub fn node_ref(&self) -> NodeRef {
49 self.node_ref.clone()
50 }
51}
52
53impl Drop for GlobalClose {
54 fn drop(&mut self) {
55 if let Some(cb) = self.listener.as_ref().dyn_ref() {
56 window()
57 .unwrap()
58 .remove_event_listener_with_callback(CLICK_TYPE, cb)
59 .ok();
60 }
61 }
62}
63
64impl Deref for GlobalClose {
65 type Target = NodeRef;
66
67 fn deref(&self) -> &Self::Target {
68 &self.node_ref
69 }
70}