@@ -5,6 +5,7 @@ pub use menu_item::*;
5
5
use crate :: ConfigInjection ;
6
6
use leptos:: {
7
7
context:: Provider ,
8
+ either:: Either ,
8
9
ev:: { self , on} ,
9
10
html:: Div ,
10
11
leptos_dom:: helpers:: TimeoutHandle ,
@@ -13,10 +14,7 @@ use leptos::{
13
14
} ;
14
15
use std:: time:: Duration ;
15
16
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 } ;
20
18
21
19
#[ slot]
22
20
pub struct MenuTrigger < T > {
47
45
let config_provider = ConfigInjection :: expect_context ( ) ;
48
46
49
47
let menu_ref = NodeRef :: < Div > :: new ( ) ;
50
- let target_ref = NodeRef :: < thaw_utils:: Element > :: new ( ) ;
51
48
let is_show_menu = RwSignal :: new ( false ) ;
52
49
let show_menu_handle = StoredValue :: new ( None :: < TimeoutHandle > ) ;
53
50
@@ -80,27 +77,47 @@ where
80
77
} ) ;
81
78
} ;
82
79
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
-
101
80
let MenuTrigger {
102
81
children : trigger_children,
103
82
} = 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
+ } ;
104
121
105
122
let menu_injection = MenuInjection {
106
123
has_icon : RwSignal :: new ( false ) ,
@@ -112,13 +129,7 @@ where
112
129
113
130
view ! {
114
131
<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}
122
133
<Follower slot show=is_show_menu placement=position>
123
134
<Provider value=menu_injection>
124
135
<CSSTransition
0 commit comments