diff --git a/packages/angular/src/components.ts b/packages/angular/src/components.ts index 2972994e7fd..0b196acfde9 100644 --- a/packages/angular/src/components.ts +++ b/packages/angular/src/components.ts @@ -837,10 +837,6 @@ export declare interface IxMenu extends Components.IxMenu { * Map Sidebar expanded */ mapExpandChange: EventEmitter>; - /** - * Event to emit to parent that the item was selected - */ - overlayClose: EventEmitter>; } @@ -860,7 +856,7 @@ export class IxMenu { constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { c.detach(); this.el = r.nativeElement; - proxyOutputs(this, this.el, ['expandChange', 'mapExpandChange', 'overlayClose']); + proxyOutputs(this, this.el, ['expandChange', 'mapExpandChange']); } } @@ -1002,13 +998,7 @@ export class IxMenuAvatarItem { } -export declare interface IxMenuItem extends Components.IxMenuItem { - /** - * Event to emit to parent that the item was selected - */ - onClick: EventEmitter>; - -} +export declare interface IxMenuItem extends Components.IxMenuItem {} @ProxyCmp({ defineCustomElementFn: undefined, @@ -1025,7 +1015,6 @@ export class IxMenuItem { constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { c.detach(); this.el = r.nativeElement; - proxyOutputs(this, this.el, ['onClick']); } } diff --git a/packages/core/component-doc.json b/packages/core/component-doc.json index dc901aa13d9..812f57c82b5 100644 --- a/packages/core/component-doc.json +++ b/packages/core/component-doc.json @@ -228,13 +228,18 @@ "docs": "", "docsTags": [], "encapsulation": "scoped", - "dependents": [], + "dependents": [ + "my-component" + ], "dependencies": [ "ix-application-header" ], "dependencyGraph": { "ix-basic-navigation": [ "ix-application-header" + ], + "my-component": [ + "ix-basic-navigation" ] }, "props": [ @@ -4095,7 +4100,9 @@ "docs": "", "docsTags": [], "encapsulation": "none", - "dependents": [], + "dependents": [ + "my-component" + ], "dependencies": [ "ix-menu-item", "ix-dropdown" @@ -4104,6 +4111,9 @@ "ix-menu": [ "ix-menu-item", "ix-dropdown" + ], + "my-component": [ + "ix-menu" ] }, "props": [ @@ -4446,27 +4456,12 @@ "composed": true, "docs": "Map Sidebar expanded", "docsTags": [] - }, - { - "event": "overlayClose", - "detail": "boolean", - "bubbles": true, - "cancelable": true, - "composed": true, - "docs": "Event to emit to parent that the item was selected", - "docsTags": [] } ], "styles": [], "slots": [], "parts": [], "listeners": [ - { - "event": "onClick", - "target": "body", - "capture": false, - "passive": false - }, { "event": "resize", "target": "window", @@ -4488,7 +4483,8 @@ "docsTags": [], "encapsulation": "scoped", "dependents": [ - "ix-map-navigation" + "ix-map-navigation", + "my-component" ], "dependencies": [ "ix-tab-item", @@ -4506,6 +4502,9 @@ ], "ix-map-navigation": [ "ix-menu-about" + ], + "my-component": [ + "ix-menu-about" ] }, "props": [ @@ -4596,9 +4595,15 @@ "docs": "", "docsTags": [], "encapsulation": "scoped", - "dependents": [], + "dependents": [ + "my-component" + ], "dependencies": [], - "dependencyGraph": {}, + "dependencyGraph": { + "my-component": [ + "ix-menu-about-item" + ] + }, "props": [ { "name": "label", @@ -4974,12 +4979,16 @@ "docsTags": [], "encapsulation": "none", "dependents": [ - "ix-menu" + "ix-menu", + "my-component" ], "dependencies": [], "dependencyGraph": { "ix-menu": [ "ix-menu-item" + ], + "my-component": [ + "ix-menu-item" ] }, "props": [ @@ -5084,17 +5093,7 @@ } ], "methods": [], - "events": [ - { - "event": "onClick", - "detail": "boolean", - "bubbles": true, - "cancelable": true, - "composed": true, - "docs": "Event to emit to parent that the item was selected", - "docsTags": [] - } - ], + "events": [], "styles": [], "slots": [], "parts": [], @@ -5112,7 +5111,9 @@ "docs": "", "docsTags": [], "encapsulation": "scoped", - "dependents": [], + "dependents": [ + "my-component" + ], "dependencies": [ "ix-tab-item", "ix-icon-button", @@ -5126,6 +5127,9 @@ ], "ix-icon-button": [ "ix-icon" + ], + "my-component": [ + "ix-menu-settings" ] }, "props": [ @@ -5216,9 +5220,15 @@ "docs": "", "docsTags": [], "encapsulation": "scoped", - "dependents": [], + "dependents": [ + "my-component" + ], "dependencies": [], - "dependencyGraph": {}, + "dependencyGraph": { + "my-component": [ + "ix-menu-settings-item" + ] + }, "props": [ { "name": "label", @@ -8615,8 +8625,46 @@ "docsTags": [], "encapsulation": "scoped", "dependents": [], - "dependencies": [], - "dependencyGraph": {}, + "dependencies": [ + "ix-basic-navigation", + "ix-menu", + "ix-menu-item", + "ix-menu-settings", + "ix-menu-settings-item", + "ix-menu-about", + "ix-menu-about-item" + ], + "dependencyGraph": { + "my-component": [ + "ix-basic-navigation", + "ix-menu", + "ix-menu-item", + "ix-menu-settings", + "ix-menu-settings-item", + "ix-menu-about", + "ix-menu-about-item" + ], + "ix-basic-navigation": [ + "ix-application-header" + ], + "ix-menu": [ + "ix-menu-item", + "ix-dropdown" + ], + "ix-menu-settings": [ + "ix-tab-item", + "ix-icon-button", + "ix-tabs" + ], + "ix-icon-button": [ + "ix-icon" + ], + "ix-menu-about": [ + "ix-tab-item", + "ix-icon-button", + "ix-tabs" + ] + }, "props": [], "methods": [], "events": [], diff --git a/packages/core/src/components/menu-item/readme.md b/packages/core/src/components/menu-item/readme.md index 85e6a59de5d..9c991aac897 100644 --- a/packages/core/src/components/menu-item/readme.md +++ b/packages/core/src/components/menu-item/readme.md @@ -21,13 +21,6 @@ SPDX-License-Identifier: MIT | `tabIcon` | `tab-icon` | Icon name from @siemens/ix-icons | `string` | `'document'` | -## Events - -| Event | Description | Type | -| --------- | -------------------------------------------------- | ---------------------- | -| `onClick` | Event to emit to parent that the item was selected | `CustomEvent` | - - ---------------------------------------------- diff --git a/packages/core/src/components/menu/menu.tsx b/packages/core/src/components/menu/menu.tsx index b1d103a4303..db1d56f4052 100644 --- a/packages/core/src/components/menu/menu.tsx +++ b/packages/core/src/components/menu/menu.tsx @@ -257,6 +257,10 @@ export class Menu { return this.hostElement.querySelector('ix-menu-avatar'); } + get tabsContainer(): HTMLDivElement { + return this.hostElement.querySelector('#menu-tabs'); + } + private popoverListener: Popover; private showTab(index: number) { @@ -658,18 +662,17 @@ export class Menu { return this.mapExpand ? 'double-chevron-left' : 'double-chevron-right'; } - private closeOverlay(event: MouseEvent) { + private isMenuItemClicked(event: MouseEvent) { const path = event.composedPath(); - const shouldCloseOverlay = path.some((element: HTMLElement) => { - if (element.tagName !== 'IX-MENU-ITEM') { - return false; - } - if (!element.id) { - return true; - } - }); - return shouldCloseOverlay; + const menuItems = (path as HTMLElement[]) + + .filter((element) => element.id !== 'more-tab') + .filter((element) => { + return element.tagName === 'IX-MENU-ITEM'; + }); + + return menuItems.some((menu) => this.tabsContainer.contains(menu)); } render() { @@ -684,11 +687,8 @@ export class Menu { menu: true, expanded: this.expand, }} - onClick={(event) => { + onClick={() => { this.resetActiveTab(); - if (this.closeOverlay(event)) { - this.resetOverlay(); - } }} >
-
- -
- {this.activeTab ? ( - - {this.activeTab.innerText} - - ) : null} -
- { + if (this.isMenuItemClicked(event)) { + this.resetOverlay(); + } }} - title="Show more" - notifications={this.countMoreNotifications} - onClick={() => this.toggleShowMoreDropdown()} > - {this.i18nMore} - - {this.menuItems - .filter( - (elm: HTMLIxMenuItemElement, index) => - !this.showTab(index) && - !this.isMenuItemActive(elm) && - this.isVisible(elm) - ) - .map((e: HTMLIxMenuItemElement) => { - return ( - e.dispatchEvent(new CustomEvent('click'))} - > - {e.innerText} - - ); - })} - - +
+ +
+ {this.activeTab ? ( + + {this.activeTab.innerText} + + ) : null} +
+ this.toggleShowMoreDropdown()} + > + {this.i18nMore} + + {this.menuItems + .filter( + (elm: HTMLIxMenuItemElement, index) => + !this.showTab(index) && + !this.isMenuItemActive(elm) && + this.isVisible(elm) + ) + .map((e: HTMLIxMenuItemElement) => { + return ( + + e.dispatchEvent(new CustomEvent('click')) + } + > + {e.innerText} + + ); + })} + + +
{this.enableSettings && !this.isSettingsEmpty ? ( ` | -| `mapExpandChange` | Map Sidebar expanded | `CustomEvent` | -| `overlayClose` | Event to emit to parent that the item was selected | `CustomEvent` | +| Event | Description | Type | +| ----------------- | -------------------- | ---------------------- | +| `expandChange` | Menu expanded | `CustomEvent` | +| `mapExpandChange` | Map Sidebar expanded | `CustomEvent` | ## Methods diff --git a/packages/core/src/components/menu/test/menu.spec.tsx b/packages/core/src/components/menu/test/menu.spec.tsx new file mode 100644 index 00000000000..c3ea9b53be5 --- /dev/null +++ b/packages/core/src/components/menu/test/menu.spec.tsx @@ -0,0 +1,60 @@ +/* + * SPDX-FileCopyrightText: 2022 Siemens AG + * + * SPDX-License-Identifier: MIT + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { newSpecPage } from '@stencil/core/testing'; +import { fireEvent } from '@testing-library/dom'; +import { MenuAbout } from '../../menu-about/menu-about'; +import { MenuItem } from '../../menu-item/menu-item'; +import { Menu } from '../menu'; + +const mutationObserverMock = jest.fn(function MutationObserver(callback) { + this.observe = jest.fn(); + this.disconnect = jest.fn(); + // Optionally add a trigger() method to manually trigger a change + this.trigger = (mockedMutationsList) => { + callback(mockedMutationsList, this); + }; +}); +(global as any).MutationObserver = mutationObserverMock; + +describe('ix-menu', () => { + it('should close overlay', async () => { + const page = await newSpecPage({ + components: [Menu, MenuItem, MenuAbout], + html: ` + Test + + `, + }); + await page.waitForChanges(); + + const element = page.doc.querySelector('.menu-overlay'); + expect(element.className).toContain('d-none'); + + fireEvent( + page.root.querySelector('#aboutAndLegal'), + new MouseEvent('click') + ); + await page.waitForChanges(); + + expect(element.className).not.toContain('d-none'); + + const item = page.root.querySelector('#test-item'); + fireEvent( + item, + new MouseEvent('click', { + bubbles: true, + cancelable: true, + }) + ); + await page.waitForChanges(); + + expect(element.className).not.toContain('d-block'); + }); +}); diff --git a/packages/core/src/components/my-component/my-component.tsx b/packages/core/src/components/my-component/my-component.tsx index f75c4d6c966..a93c41698d4 100644 --- a/packages/core/src/components/my-component/my-component.tsx +++ b/packages/core/src/components/my-component/my-component.tsx @@ -16,6 +16,31 @@ import { Component, h, Host } from '@stencil/core'; }) export class MyComponent { render() { - return ; + return ( + + + + 123 + 456 + 123 + 456 + 123 + 456 + 123 + 456 + 123 + 456 + 123 + 456 + + Test + + + Test + + + + + ); } }