Skip to content

Commit 2d9f7e4

Browse files
fix: do not stop click event propagation on menu-bar button (#8272) (#8282)
Co-authored-by: Serhii Kulykov <iamkulykov@gmail.com>
1 parent 6643db5 commit 2d9f7e4

File tree

4 files changed

+53
-2
lines changed

4 files changed

+53
-2
lines changed

packages/context-menu/src/vaadin-contextmenu-items-mixin.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export const ItemsMixin = (superClass) =>
6969
// Overlay's outside click listener doesn't work with modeless
7070
// overlays (submenus) so we need additional logic for it
7171
this.__itemsOutsideClickListener = (e) => {
72-
if (!e.composedPath().some((el) => el.localName === `${this._tagNamePrefix}-overlay`)) {
72+
if (this._shouldCloseOnOutsideClick(e)) {
7373
this.dispatchEvent(new CustomEvent('items-outside-click'));
7474
}
7575
};
@@ -101,6 +101,18 @@ export const ItemsMixin = (superClass) =>
101101
document.documentElement.removeEventListener('click', this.__itemsOutsideClickListener);
102102
}
103103

104+
/**
105+
* Whether to close the overlay on outside click or not.
106+
* Override this method to customize the closing logic.
107+
*
108+
* @param {Event} event
109+
* @return {boolean}
110+
* @protected
111+
*/
112+
_shouldCloseOnOutsideClick(event) {
113+
return !event.composedPath().some((el) => el.localName === `${this._tagNamePrefix}-overlay`);
114+
}
115+
104116
/** @protected */
105117
__forwardFocus() {
106118
const overlay = this._overlayElement;

packages/menu-bar/src/vaadin-menu-bar-mixin.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,6 @@ export const MenuBarMixin = (superClass) =>
904904

905905
/** @private */
906906
__onButtonClick(e) {
907-
e.stopPropagation();
908907
const button = this._getButtonFromEvent(e);
909908
if (button) {
910909
this.__openSubMenu(button, button.__triggeredWithActiveKeys);

packages/menu-bar/src/vaadin-menu-bar-submenu-mixin.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,21 @@ export const SubMenuMixin = (superClass) =>
4646
this.getRootNode().host._close();
4747
}
4848
}
49+
50+
/**
51+
* Override method from `ContextMenuMixin` to prevent closing
52+
* sub-menu on the same click event that was used to open it.
53+
*
54+
* @param {Event} event
55+
* @return {boolean}
56+
* @protected
57+
* @override
58+
*/
59+
_shouldCloseOnOutsideClick(event) {
60+
if (this.hasAttribute('is-root') && event.composedPath().includes(this.listenOn)) {
61+
return false;
62+
}
63+
64+
return super._shouldCloseOnOutsideClick(event);
65+
}
4966
};

packages/menu-bar/test/sub-menu.common.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,29 @@ describe('sub-menu', () => {
9494
expect(spy.calledOnce).to.be.true;
9595
});
9696

97+
it('should set pointer events to `auto` when opened on click', async () => {
98+
buttons[0].click();
99+
await nextRender(subMenu);
100+
expect(menu.style.pointerEvents).to.equal('auto');
101+
});
102+
103+
it('should reset pointer events after closing on click', async () => {
104+
buttons[0].click();
105+
await nextRender(subMenu);
106+
107+
buttons[0].click();
108+
await nextRender(subMenu);
109+
expect(menu.style.pointerEvents).to.be.empty;
110+
});
111+
112+
it('should not stop click event from propagating when opened ', async () => {
113+
const event = new CustomEvent('click', { bubbles: true });
114+
const spy = sinon.spy(event, 'stopPropagation');
115+
buttons[0].dispatchEvent(event);
116+
await nextRender(subMenu);
117+
expect(spy.called).to.be.false;
118+
});
119+
97120
it('should focus the overlay when sub-menu opened on click', async () => {
98121
const spy = sinon.spy(subMenuOverlay.$.overlay, 'focus');
99122
buttons[0].click();

0 commit comments

Comments
 (0)