euv_ui/hook/use_hover/
impl.rs1use super::*;
2
3impl UseHover {
5 pub(crate) fn new() -> Self {
11 Self {
12 target: NodeRef::new(),
13 hovered: Signal::create(false),
14 teardown: Rc::new(RefCell::new(None)),
15 }
16 }
17
18 pub fn is_hovered(&self) -> bool {
24 self.get_hovered().get()
25 }
26
27 pub(crate) fn attach(&self) {
35 #[cfg(target_arch = "wasm32")]
36 {
37 let Some(document) = browser_document() else {
38 return;
39 };
40 let hovered: Signal<bool> = self.get_hovered();
41 let over_target: NodeRef<Element> = self.get_target().clone();
42 let on_over: Closure<dyn FnMut(Event)> =
43 Closure::wrap(Box::new(move |event: Event| {
44 if pointer_is_inside(&over_target, &event) {
45 hovered.set(true);
46 }
47 }));
48 if document
49 .add_event_listener_with_callback("mouseover", on_over.as_ref().unchecked_ref())
50 .is_err()
51 {
52 return;
53 }
54 let out_target: NodeRef<Element> = self.get_target().clone();
55 let on_out: Closure<dyn FnMut(Event)> = Closure::wrap(Box::new(move |event: Event| {
56 let Some(element) = out_target.get_cloned() else {
57 return;
58 };
59 let related: Option<Node> = event
60 .dyn_into::<MouseEvent>()
61 .ok()
62 .and_then(|mouse: MouseEvent| mouse.related_target())
63 .and_then(|related: EventTarget| related.dyn_into::<Node>().ok());
64 if let Some(related) = related
65 && node_contains(&element, &related)
66 {
67 return;
68 }
69 hovered.set(false);
70 }));
71 if document
72 .add_event_listener_with_callback("mouseout", on_out.as_ref().unchecked_ref())
73 .is_err()
74 {
75 return;
76 }
77 *self.get_teardown().borrow_mut() = Some(Box::new(move || {
78 let _: Result<(), JsValue> = document.remove_event_listener_with_callback(
79 "mouseover",
80 on_over.as_ref().unchecked_ref(),
81 );
82 let _: Result<(), JsValue> = document.remove_event_listener_with_callback(
83 "mouseout",
84 on_out.as_ref().unchecked_ref(),
85 );
86 }));
87 }
88 }
89
90 pub(crate) fn detach(&self) {
92 let taken: Option<Box<dyn Fn()>> = self.get_teardown().borrow_mut().take();
93 if let Some(teardown) = taken {
94 teardown();
95 }
96 }
97}