Skip to content

Commit 7147e73

Browse files
author
Shipra Gupta
committed
fix(menu): prevent duplicate pointerup listeners causing submenu to close and reopen
- Add _touchListenerActive flag to prevent multiple pointerup listeners from being registered - Reset flag in handleTouchSubmenuToggle after action completes - Prevents rapid close/reopen behavior when tapping on menu items with open submenus
1 parent 44942ca commit 7147e73

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

1st-gen/packages/menu/src/MenuItem.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,8 @@ export class MenuItem extends LikeAnchor(
459459
}
460460
}
461461

462+
private _touchListenerActive = false;
463+
462464
private handlePointerdown(event: PointerEvent): void {
463465
// Track pointer type for touch detection
464466
this._lastPointerType = event.pointerType;
@@ -468,16 +470,23 @@ export class MenuItem extends LikeAnchor(
468470
if (
469471
event.pointerType === 'touch' &&
470472
this.hasSubmenu &&
471-
event.target === this
473+
event.target === this &&
474+
!this._touchListenerActive
472475
) {
473476
event.preventDefault(); // Prevent click suppression
474477
event.stopPropagation(); // Prevent bubbling to parent menu items
478+
this._touchListenerActive = true;
475479
this.addEventListener('pointerup', this.handleTouchSubmenuToggle, {
476480
once: true,
477481
});
478482
}
479483

480-
if (event.target === this && this.hasSubmenu && this.open) {
484+
if (
485+
event.target === this &&
486+
this.hasSubmenu &&
487+
this.open &&
488+
event.pointerType !== 'touch'
489+
) {
481490
this.addEventListener('focus', this.handleSubmenuFocus, {
482491
once: true,
483492
});
@@ -492,6 +501,10 @@ export class MenuItem extends LikeAnchor(
492501
event.preventDefault();
493502
event.stopPropagation();
494503

504+
// Reset the listener flag
505+
this._touchListenerActive = false;
506+
507+
// Toggle the submenu
495508
if (this.open) {
496509
this.open = false;
497510
} else {
@@ -646,24 +659,21 @@ export class MenuItem extends LikeAnchor(
646659
protected handleSubmenuClick(event: Event): void {
647660
const pointerEvent = event as PointerEvent;
648661

649-
// Check if this is a touch event
650662
const isTouchEvent =
651663
pointerEvent.pointerType === 'touch' ||
652664
this._lastPointerType === 'touch';
653665

654-
// For touch events, we handle EVERYTHING via pointerup, so completely ignore click
666+
// For touch events, completely ignore click
655667
if (isTouchEvent) {
656668
event.stopPropagation();
657669
event.preventDefault();
658670
return;
659671
}
660672

661-
// For non-touch (mouse) events, ignore clicks inside the overlay (on child items)
662673
if (event.composedPath().includes(this.overlayElement)) {
663674
return;
664675
}
665676

666-
// For mouse: just open (close is handled by pointerleave)
667677
this.openOverlay(true);
668678
}
669679

0 commit comments

Comments
 (0)