euv_ui/hook/use_click_outside/
impl.rs1use super::*;
2
3impl UseClickOutside {
5 pub(crate) fn new() -> Self {
11 Self {
12 target: NodeRef::new(),
13 triggered: Signal::create(false),
14 teardown: Rc::new(RefCell::new(None)),
15 }
16 }
17
18 pub fn is_triggered(&self) -> bool {
24 self.get_triggered().get()
25 }
26
27 pub fn reset(&self) {
29 self.get_triggered().set(false);
30 }
31
32 pub(crate) fn attach(&self) {
38 #[cfg(target_arch = "wasm32")]
39 {
40 let Some(document) = browser_document() else {
41 return;
42 };
43 let triggered: Signal<bool> = self.get_triggered();
44 let press_target: NodeRef<Element> = self.get_target().clone();
45 let on_press: Closure<dyn FnMut(Event)> =
46 Closure::wrap(Box::new(move |event: Event| {
47 if press_is_outside(&press_target, &event) {
48 triggered.set(true);
49 }
50 }));
51 if document
52 .add_event_listener_with_callback(
53 EVENT_MOUSEDOWN,
54 on_press.as_ref().unchecked_ref(),
55 )
56 .is_err()
57 {
58 return;
59 }
60 let touch_target: NodeRef<Element> = self.get_target().clone();
61 let on_touch: Closure<dyn FnMut(Event)> =
62 Closure::wrap(Box::new(move |event: Event| {
63 if press_is_outside(&touch_target, &event) {
64 triggered.set(true);
65 }
66 }));
67 if document
68 .add_event_listener_with_callback(
69 EVENT_TOUCHSTART,
70 on_touch.as_ref().unchecked_ref(),
71 )
72 .is_err()
73 {
74 return;
75 }
76 *self.get_teardown().borrow_mut() = Some(Box::new(move || {
77 let _: Result<(), JsValue> = document.remove_event_listener_with_callback(
78 EVENT_MOUSEDOWN,
79 on_press.as_ref().unchecked_ref(),
80 );
81 let _: Result<(), JsValue> = document.remove_event_listener_with_callback(
82 EVENT_TOUCHSTART,
83 on_touch.as_ref().unchecked_ref(),
84 );
85 }));
86 }
87 }
88
89 pub(crate) fn detach(&self) {
91 let taken: Option<Box<dyn Fn()>> = self.get_teardown().borrow_mut().take();
92 if let Some(teardown) = taken {
93 teardown();
94 }
95 }
96}