Skip to content

Commit d2603c4

Browse files
committed
fix: Clicking the outer part of the Menu component does not close
1 parent 292a6a4 commit d2603c4

File tree

1 file changed

+41
-30
lines changed

1 file changed

+41
-30
lines changed

thaw/src/menu/mod.rs

+41-30
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pub use menu_item::*;
55
use crate::ConfigInjection;
66
use leptos::{
77
context::Provider,
8+
either::Either,
89
ev::{self, on},
910
html::Div,
1011
leptos_dom::helpers::TimeoutHandle,
@@ -13,10 +14,7 @@ use leptos::{
1314
};
1415
use std::time::Duration;
1516
use thaw_components::{Binder, CSSTransition, Follower, FollowerPlacement};
16-
use thaw_utils::{
17-
add_event_listener, call_on_click_outside, class_list, mount_style, ArcOneCallback,
18-
BoxCallback, BoxOneCallback,
19-
};
17+
use thaw_utils::{class_list, mount_style, on_click_outside, ArcOneCallback, BoxOneCallback};
2018

2119
#[slot]
2220
pub struct MenuTrigger<T> {
@@ -47,7 +45,6 @@ where
4745
let config_provider = ConfigInjection::expect_context();
4846

4947
let menu_ref = NodeRef::<Div>::new();
50-
let target_ref = NodeRef::<thaw_utils::Element>::new();
5148
let is_show_menu = RwSignal::new(false);
5249
let show_menu_handle = StoredValue::new(None::<TimeoutHandle>);
5350

@@ -80,27 +77,47 @@ where
8077
});
8178
};
8279

83-
if trigger_type != MenuTriggerType::Hover {
84-
call_on_click_outside(menu_ref, BoxCallback::new(move || is_show_menu.set(false)));
85-
}
86-
87-
Effect::new(move |_| {
88-
let Some(target_el) = target_ref.get() else {
89-
return;
90-
};
91-
let handler = add_event_listener(target_el, ev::click, move |event| {
92-
if trigger_type != MenuTriggerType::Click {
93-
return;
94-
}
95-
event.stop_propagation();
96-
is_show_menu.update(|show| *show = !*show);
97-
});
98-
on_cleanup(move || handler.remove());
99-
});
100-
10180
let MenuTrigger {
10281
children: trigger_children,
10382
} = menu_trigger;
83+
let trigger_children = trigger_children.into_inner()()
84+
.into_inner()
85+
.add_any_attr(tachys_class(("thaw-menu-trigger", true)));
86+
87+
let trigger_children = match trigger_type {
88+
MenuTriggerType::Click => {
89+
let trigger_ref = NodeRef::<thaw_utils::Element>::new();
90+
on_click_outside(
91+
move || {
92+
if !is_show_menu.get_untracked() {
93+
return None;
94+
}
95+
let Some(trigger_el) = trigger_ref.get_untracked() else {
96+
return None;
97+
};
98+
let Some(menu_el) = menu_ref.get_untracked() else {
99+
return None;
100+
};
101+
Some(vec![menu_el.into(), trigger_el])
102+
},
103+
move || is_show_menu.set(false),
104+
);
105+
Either::Left(
106+
trigger_children
107+
.add_any_attr(node_ref(trigger_ref))
108+
.add_any_attr(on(ev::click, move |_| {
109+
is_show_menu.update(|show| {
110+
*show = !*show;
111+
});
112+
})),
113+
)
114+
}
115+
MenuTriggerType::Hover => Either::Right(
116+
trigger_children
117+
.add_any_attr(on(ev::mouseenter, on_mouse_enter))
118+
.add_any_attr(on(ev::mouseleave, on_mouse_leave)),
119+
),
120+
};
104121

105122
let menu_injection = MenuInjection {
106123
has_icon: RwSignal::new(false),
@@ -112,13 +129,7 @@ where
112129

113130
view! {
114131
<Binder>
115-
{trigger_children
116-
.into_inner()()
117-
.into_inner()
118-
.add_any_attr(tachys_class(("thaw-menu-trigger", true)))
119-
.add_any_attr(node_ref(target_ref))
120-
.add_any_attr(on(ev::mouseenter, on_mouse_enter))
121-
.add_any_attr(on(ev::mouseleave, on_mouse_leave))}
132+
{trigger_children}
122133
<Follower slot show=is_show_menu placement=position>
123134
<Provider value=menu_injection>
124135
<CSSTransition

0 commit comments

Comments
 (0)