From 4ecf6d05ab74fffef6f63691021f5becde623181 Mon Sep 17 00:00:00 2001 From: Arturo Date: Mon, 23 Jan 2023 14:37:26 +0100 Subject: [PATCH 1/3] fix(telekom-nav-flyout): hover/click handling --- .../telekom-nav-flyout/telekom-nav-flyout.tsx | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/packages/components/src/components/telekom/telekom-nav-flyout/telekom-nav-flyout.tsx b/packages/components/src/components/telekom/telekom-nav-flyout/telekom-nav-flyout.tsx index beea437fe4..0a1cfdeb17 100644 --- a/packages/components/src/components/telekom/telekom-nav-flyout/telekom-nav-flyout.tsx +++ b/packages/components/src/components/telekom/telekom-nav-flyout/telekom-nav-flyout.tsx @@ -73,16 +73,6 @@ export class TelekomNavItem { } } - // @Listen('focusin', { target: 'document' }) - // handleDocumentFocusin(event) { - // if (!this.isExpanded) { - // return; - // } - // if (!this.hostElement.contains(event.target)) { - // this.expanded = false; - // } - // } - @Listen('scale-close-nav-flyout') handleScaleCloseNavFlyout() { this.expanded = false; @@ -114,16 +104,36 @@ export class TelekomNavItem { } this.triggerElement.setAttribute('aria-haspopup', 'true'); this.triggerElement.setAttribute('aria-expanded', String(this.expanded)); - this.triggerElement.addEventListener('click', this.handleTriggerClick); if (this.hover) { this.triggerElement.addEventListener('mouseenter', this.handlePointerIn); + this.triggerElement.addEventListener( + 'keypress', + this.handleSpaceOrEnterForHover + ); + } else { + this.triggerElement.addEventListener('click', this.handleTriggerClick); } } disconnectedCallback() { this.triggerElement.removeEventListener('click', this.handleTriggerClick); + this.triggerElement.removeEventListener('mouseenter', this.handlePointerIn); + this.triggerElement.removeEventListener( + 'keypress', + this.handleSpaceOrEnterForHover + ); } + handleSpaceOrEnterForHover = (event: KeyboardEvent) => { + if (this.isExpanded) { + return; + } + if (event.key === 'Enter' || event.key === ' ') { + this.expanded = true; + this.show(); + } + }; + handleTriggerClick = (event: MouseEvent) => { if (event.ctrlKey) { return; From 3f074e8e9082fb413c4cee3623f12ee22695ad9d Mon Sep 17 00:00:00 2001 From: Arturo Date: Mon, 23 Jan 2023 14:58:19 +0100 Subject: [PATCH 2/3] fix(telekom-nav-item): styles hover and expanded state for main-nav and functions --- .../telekom-nav-item/telekom-nav-item.css | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/components/src/components/telekom/telekom-nav-item/telekom-nav-item.css b/packages/components/src/components/telekom/telekom-nav-item/telekom-nav-item.css index f35e55495c..ecd4129d9e 100644 --- a/packages/components/src/components/telekom/telekom-nav-item/telekom-nav-item.css +++ b/packages/components/src/components/telekom/telekom-nav-item/telekom-nav-item.css @@ -70,7 +70,8 @@ cursor: pointer; } -.scale-telekom-nav-item > :where(a, button):hover { +.scale-telekom-nav-item > :where(a, button):hover, +.scale-telekom-nav-item > :where(button[aria-expanded='true']) { color: var(--telekom-color-text-and-icon-primary-hovered); } .scale-telekom-nav-item > :where(a, button):active { @@ -116,6 +117,28 @@ left: 0; } +.scale-telekom-nav-list[variant='main-nav'] + > .scale-telekom-nav-item + > :where(a, button):hover:after, +.scale-telekom-nav-list[variant='main-nav'] + > .scale-telekom-nav-item + > :where(button[aria-expanded='true']):after, +.scale-telekom-nav-list[variant='functions'] + > .scale-telekom-nav-item + > :where(a, button):hover:after, +.scale-telekom-nav-list[variant='functions'] + > .scale-telekom-nav-item + > :where(button[aria-expanded='true']):after { + content: ''; + width: 100%; + height: var(--telekom-spacing-unit-x05); + background: var(--telekom-color-primary-standard); + display: block; + position: absolute; + bottom: 0; + left: 0; +} + /* variants: meta-nav-external, meta-nav, lang-switcher (top bar) */ .scale-telekom-nav-list[variant='meta-nav-external'] From e36df3bf282e5a1c2715121643b33796d3e0addf Mon Sep 17 00:00:00 2001 From: Arturo Date: Mon, 23 Jan 2023 16:39:50 +0100 Subject: [PATCH 3/3] fix(telekom-nav-list): close expanded sibling flyout children --- .../telekom/telekom-nav-flyout/readme.md | 7 ++++++ .../telekom-nav-flyout/telekom-nav-flyout.tsx | 7 +++++- .../telekom-nav-list/telekom-nav-list.tsx | 24 ++++++++++++++++++- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/packages/components/src/components/telekom/telekom-nav-flyout/readme.md b/packages/components/src/components/telekom/telekom-nav-flyout/readme.md index 595fa44b55..794cd52f66 100644 --- a/packages/components/src/components/telekom/telekom-nav-flyout/readme.md +++ b/packages/components/src/components/telekom/telekom-nav-flyout/readme.md @@ -14,6 +14,13 @@ | `triggerSelector` | `trigger-selector` | Selector to query the trigger element in case it's not the previous sibling | `string` | `undefined` | +## Events + +| Event | Description | Type | +| ---------------- | ----------- | ------------------ | +| `scale-expanded` | | `CustomEvent` | + + ## Methods ### `hide() => Promise` diff --git a/packages/components/src/components/telekom/telekom-nav-flyout/telekom-nav-flyout.tsx b/packages/components/src/components/telekom/telekom-nav-flyout/telekom-nav-flyout.tsx index 0a1cfdeb17..82845bc0d6 100644 --- a/packages/components/src/components/telekom/telekom-nav-flyout/telekom-nav-flyout.tsx +++ b/packages/components/src/components/telekom/telekom-nav-flyout/telekom-nav-flyout.tsx @@ -14,6 +14,7 @@ import { h, Host, Element, + Event, Listen, Method, Prop, @@ -22,6 +23,7 @@ import { } from '@stencil/core'; import { HTMLStencilElement } from '@stencil/core/internal'; import cx from 'classnames'; +import { emitEvent } from '../../../utils/utils'; // TODO make util const animFinished = (el: HTMLElement | ShadowRoot) => { @@ -58,6 +60,8 @@ export class TelekomNavItem { @State() isExpanded: boolean = this.expanded; @State() animationState: 'in' | 'out' | undefined; + @Event({ eventName: 'scale-expanded', bubbles: true }) scaleExpanded; + private parentElement: HTMLElement; @Listen('keydown', { target: 'window' }) @@ -141,7 +145,6 @@ export class TelekomNavItem { event.preventDefault(); event.stopImmediatePropagation(); this.expanded = !this.expanded; - this.expanded ? this.show() : this.hide(); this.parentElement.removeEventListener('mouseleave', this.handlePointerOut); }; @@ -166,6 +169,7 @@ export class TelekomNavItem { await animFinished(this.hostElement.shadowRoot); this.animationState = undefined; this.triggerElement.setAttribute('aria-expanded', 'true'); + emitEvent(this, 'scaleExpanded', { expanded: true }); }); } @@ -177,6 +181,7 @@ export class TelekomNavItem { this.animationState = undefined; this.isExpanded = false; this.triggerElement.setAttribute('aria-expanded', 'false'); + emitEvent(this, 'scaleExpanded', { expanded: false }); }); } diff --git a/packages/components/src/components/telekom/telekom-nav-list/telekom-nav-list.tsx b/packages/components/src/components/telekom/telekom-nav-list/telekom-nav-list.tsx index 1fc4d031e2..22469621d7 100644 --- a/packages/components/src/components/telekom/telekom-nav-list/telekom-nav-list.tsx +++ b/packages/components/src/components/telekom/telekom-nav-list/telekom-nav-list.tsx @@ -9,9 +9,12 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import { Component, h, Host, Element, Prop } from '@stencil/core'; +import { Component, h, Host, Element, Listen, Prop } from '@stencil/core'; import { HTMLStencilElement } from '@stencil/core/internal'; +const isDirectChild = (parent: HTMLElement, child: HTMLElement) => + [...parent.children].includes(child); + @Component({ tag: 'scale-telekom-nav-list', styleUrl: 'telekom-nav-list.css', @@ -28,6 +31,25 @@ export class TelekomNavList { | 'main-nav' | 'functions' = 'main-nav'; + @Listen('scale-expanded') + handleScaleExpanded(event) { + if (event.detail.expanded) { + this.closeExpandedFlyoutSiblings(event.target); + } + } + + closeExpandedFlyoutSiblings(target: HTMLElement) { + const siblingItems = [...this.hostElement.children].filter( + (x) => !x.contains(target) + ) as HTMLElement[]; + siblingItems.forEach((item) => { + const flyout = item.querySelector('scale-telekom-nav-flyout'); + if (isDirectChild(item, flyout) && flyout.expanded) { + flyout.expanded = false; + } + }); + } + render() { return (