Skip to content

Commit

Permalink
fix: do not stop click event propagation on menu-bar button (#8272) (#…
Browse files Browse the repository at this point in the history
…8282)

Co-authored-by: Serhii Kulykov <iamkulykov@gmail.com>
  • Loading branch information
vaadin-bot and web-padawan authored Dec 5, 2024
1 parent 6643db5 commit 2d9f7e4
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 2 deletions.
14 changes: 13 additions & 1 deletion packages/context-menu/src/vaadin-contextmenu-items-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const ItemsMixin = (superClass) =>
// Overlay's outside click listener doesn't work with modeless
// overlays (submenus) so we need additional logic for it
this.__itemsOutsideClickListener = (e) => {
if (!e.composedPath().some((el) => el.localName === `${this._tagNamePrefix}-overlay`)) {
if (this._shouldCloseOnOutsideClick(e)) {
this.dispatchEvent(new CustomEvent('items-outside-click'));
}
};
Expand Down Expand Up @@ -101,6 +101,18 @@ export const ItemsMixin = (superClass) =>
document.documentElement.removeEventListener('click', this.__itemsOutsideClickListener);
}

/**
* Whether to close the overlay on outside click or not.
* Override this method to customize the closing logic.
*
* @param {Event} event
* @return {boolean}
* @protected
*/
_shouldCloseOnOutsideClick(event) {
return !event.composedPath().some((el) => el.localName === `${this._tagNamePrefix}-overlay`);
}

/** @protected */
__forwardFocus() {
const overlay = this._overlayElement;
Expand Down
1 change: 0 additions & 1 deletion packages/menu-bar/src/vaadin-menu-bar-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,6 @@ export const MenuBarMixin = (superClass) =>

/** @private */
__onButtonClick(e) {
e.stopPropagation();
const button = this._getButtonFromEvent(e);
if (button) {
this.__openSubMenu(button, button.__triggeredWithActiveKeys);
Expand Down
17 changes: 17 additions & 0 deletions packages/menu-bar/src/vaadin-menu-bar-submenu-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,21 @@ export const SubMenuMixin = (superClass) =>
this.getRootNode().host._close();
}
}

/**
* Override method from `ContextMenuMixin` to prevent closing
* sub-menu on the same click event that was used to open it.
*
* @param {Event} event
* @return {boolean}
* @protected
* @override
*/
_shouldCloseOnOutsideClick(event) {
if (this.hasAttribute('is-root') && event.composedPath().includes(this.listenOn)) {
return false;
}

return super._shouldCloseOnOutsideClick(event);
}
};
23 changes: 23 additions & 0 deletions packages/menu-bar/test/sub-menu.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,29 @@ describe('sub-menu', () => {
expect(spy.calledOnce).to.be.true;
});

it('should set pointer events to `auto` when opened on click', async () => {
buttons[0].click();
await nextRender(subMenu);
expect(menu.style.pointerEvents).to.equal('auto');
});

it('should reset pointer events after closing on click', async () => {
buttons[0].click();
await nextRender(subMenu);

buttons[0].click();
await nextRender(subMenu);
expect(menu.style.pointerEvents).to.be.empty;
});

it('should not stop click event from propagating when opened ', async () => {
const event = new CustomEvent('click', { bubbles: true });
const spy = sinon.spy(event, 'stopPropagation');
buttons[0].dispatchEvent(event);
await nextRender(subMenu);
expect(spy.called).to.be.false;
});

it('should focus the overlay when sub-menu opened on click', async () => {
const spy = sinon.spy(subMenuOverlay.$.overlay, 'focus');
buttons[0].click();
Expand Down

0 comments on commit 2d9f7e4

Please sign in to comment.