use super::*;
impl UseClickOutside {
pub(crate) fn new() -> Self {
Self {
target: NodeRef::new(),
triggered: Signal::create(false),
teardown: Rc::new(RefCell::new(None)),
}
}
pub fn is_triggered(&self) -> bool {
self.get_triggered().get()
}
pub fn reset(&self) {
self.get_triggered().set(false);
}
pub(crate) fn attach(&self) {
#[cfg(target_arch = "wasm32")]
{
let Some(document) = browser_document() else {
return;
};
let triggered: Signal<bool> = self.get_triggered();
let press_target: NodeRef<Element> = self.get_target().clone();
let on_press: Closure<dyn FnMut(Event)> =
Closure::wrap(Box::new(move |event: Event| {
if press_is_outside(&press_target, &event) {
triggered.set(true);
}
}));
if document
.add_event_listener_with_callback(
EVENT_MOUSEDOWN,
on_press.as_ref().unchecked_ref(),
)
.is_err()
{
return;
}
let touch_target: NodeRef<Element> = self.get_target().clone();
let on_touch: Closure<dyn FnMut(Event)> =
Closure::wrap(Box::new(move |event: Event| {
if press_is_outside(&touch_target, &event) {
triggered.set(true);
}
}));
if document
.add_event_listener_with_callback(
EVENT_TOUCHSTART,
on_touch.as_ref().unchecked_ref(),
)
.is_err()
{
return;
}
*self.get_teardown().borrow_mut() = Some(Box::new(move || {
let _: Result<(), JsValue> = document.remove_event_listener_with_callback(
EVENT_MOUSEDOWN,
on_press.as_ref().unchecked_ref(),
);
let _: Result<(), JsValue> = document.remove_event_listener_with_callback(
EVENT_TOUCHSTART,
on_touch.as_ref().unchecked_ref(),
);
}));
}
}
pub(crate) fn detach(&self) {
let taken: Option<Box<dyn Fn()>> = self.get_teardown().borrow_mut().take();
if let Some(teardown) = taken {
teardown();
}
}
}