@@ -56,6 +56,8 @@ export class RdxNavigationMenuDirective implements OnDestroy {
5656 private openTimerRef = 0 ;
5757 private closeTimerRef = 0 ;
5858 private skipDelayTimerRef = 0 ;
59+ private recentlyActivatedTimerRef = 0 ;
60+ private readonly recentlyActivatedItem = signal < string | null > ( null ) ;
5961 readonly #isOpenDelayed = signal ( true ) ;
6062
6163 // pointer tracking
@@ -67,6 +69,7 @@ export class RdxNavigationMenuDirective implements OnDestroy {
6769
6870 @Input ( ) orientation : 'horizontal' | 'vertical' = 'horizontal' ;
6971 @Input ( ) dir : 'ltr' | 'rtl' = 'ltr' ;
72+ @Input ( { transform : numberAttribute } ) clickIgnoreDuration = 250 ;
7073 @Input ( { transform : numberAttribute } ) delayDuration = 200 ;
7174 @Input ( { transform : numberAttribute } ) skipDelayDuration = 300 ;
7275 @Input ( { transform : booleanAttribute } ) loop = false ;
@@ -148,6 +151,7 @@ export class RdxNavigationMenuDirective implements OnDestroy {
148151 this . window . clearTimeout ( this . openTimerRef ) ;
149152 this . window . clearTimeout ( this . closeTimerRef ) ;
150153 this . window . clearTimeout ( this . skipDelayTimerRef ) ;
154+ this . window . clearTimeout ( this . recentlyActivatedTimerRef ) ;
151155
152156 // clean up document event listener
153157 if ( this . documentMouseLeaveHandler ) {
@@ -198,6 +202,13 @@ export class RdxNavigationMenuDirective implements OnDestroy {
198202
199203 onItemSelect ( itemValue : string ) {
200204 const wasOpen = this . #value( ) === itemValue ;
205+
206+ // if this item just opened and the click would close it,
207+ // ignore the click during the brief protection window
208+ if ( this . recentlyActivatedItem ( ) === itemValue && wasOpen ) {
209+ return ;
210+ }
211+
201212 const newValue = wasOpen ? '' : itemValue ;
202213
203214 // if user is closing an open menu, mark as user-dismissed
@@ -229,8 +240,20 @@ export class RdxNavigationMenuDirective implements OnDestroy {
229240 }
230241
231242 private setValue ( value : string ) {
232- // Store previous value before changing
233- this . #previousValue. set ( this . #value( ) ) ;
243+ const previousValue = this . #value( ) ;
244+
245+ if ( value && value !== previousValue ) {
246+ this . window . clearTimeout ( this . recentlyActivatedTimerRef ) ;
247+
248+ this . recentlyActivatedItem . set ( value ) ;
249+
250+ this . recentlyActivatedTimerRef = this . window . setTimeout ( ( ) => {
251+ this . recentlyActivatedItem . set ( null ) ;
252+ } , this . clickIgnoreDuration ) ;
253+ }
254+
255+ // store previous value before changing
256+ this . #previousValue. set ( previousValue ) ;
234257 this . #value. set ( value ) ;
235258 }
236259
0 commit comments