From 8ed86ae4fa476e8cce39cb65e47b56082bc27363 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Thu, 8 Feb 2024 10:13:25 +0200 Subject: [PATCH 01/44] feat(ui5-side-navigation): add navigation groups --- packages/fiori/src/SideNavigation.ts | 24 +-- packages/fiori/src/SideNavigationItem.ts | 6 +- packages/fiori/src/SideNavigationItemBase.ts | 112 ------------- .../src/SideNavigationSelectableItemBase.ts | 147 ++++++++++++++++++ packages/fiori/src/SideNavigationSubItem.ts | 6 +- .../test/pages/SideNavigationWithGroups.html | 87 +++++++++++ 6 files changed, 252 insertions(+), 130 deletions(-) create mode 100644 packages/fiori/src/SideNavigationSelectableItemBase.ts create mode 100644 packages/fiori/test/pages/SideNavigationWithGroups.html diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index fcbb9540ee99..78399e63eabf 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -26,7 +26,7 @@ import Icon from "@ui5/webcomponents/dist/Icon.js"; import "@ui5/webcomponents-icons/dist/circle-task-2.js"; import "@ui5/webcomponents-icons/dist/navigation-right-arrow.js"; import "@ui5/webcomponents-icons/dist/navigation-down-arrow.js"; -import type SideNavigationItemBase from "./SideNavigationItemBase.js"; +import type SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase.js"; import SideNavigationItem from "./SideNavigationItem.js"; import SideNavigationSubItem from "./SideNavigationSubItem.js"; import SideNavigationTemplate from "./generated/templates/SideNavigationTemplate.lit.js"; @@ -51,20 +51,20 @@ type SideNavigationPopoverContents = { }; type SideNavigationSelectionChangeEventDetail = { - item: SideNavigationItemBase; + item: SideNavigationSelectableItemBase; }; // used for the inner side navigation used in the SideNavigationPopoverTemplate type PopupClickEventDetail = { target: { - associatedItem: SideNavigationItemBase + associatedItem: SideNavigationSelectableItemBase } }; // used for the inner side navigation used in the SideNavigationPopoverTemplate type NavigationMenuClickEventDetail = { item: { - associatedItem: SideNavigationItemBase + associatedItem: SideNavigationSelectableItemBase } }; @@ -128,7 +128,7 @@ type NavigationMenuClickEventDetail = { /** * Fired when the selection has changed via user interaction * - * @param {SideNavigationItemBase} item the clicked item. + * @param {SideNavigationSelectableItemBase} item the clicked item. * @allowPreventDefault * @public */ @@ -416,7 +416,7 @@ class SideNavigation extends UI5Element { return result; } - focusItem(item: SideNavigationItemBase) { + focusItem(item: SideNavigationSelectableItemBase) { if (item.isFixedItem) { this._fixedItemNavigation.setCurrentItem(item); } else { @@ -527,7 +527,7 @@ class SideNavigation extends UI5Element { }); } - _findFocusedItem(items: Array) : SideNavigationItemBase | undefined { + _findFocusedItem(items: Array) : SideNavigationSelectableItemBase | undefined { let focusedItem; if (this.collapsed) { @@ -539,8 +539,8 @@ class SideNavigation extends UI5Element { return focusedItem; } - _getWithNestedItems(items: Array, expandedOnly = false): Array { - let result = new Array(); + _getWithNestedItems(items: Array, expandedOnly = false): Array { + let result = new Array(); items.forEach(item => { result.push(item); @@ -553,7 +553,7 @@ class SideNavigation extends UI5Element { return result; } - _findSelectedItem(items: Array) : SideNavigationItemBase | undefined { + _findSelectedItem(items: Array) : SideNavigationSelectableItemBase | undefined { let selectedItem; if (this.collapsed) { @@ -565,7 +565,7 @@ class SideNavigation extends UI5Element { return selectedItem; } - _handleItemClick(e: KeyboardEvent | PointerEvent, item: SideNavigationItemBase) { + _handleItemClick(e: KeyboardEvent | PointerEvent, item: SideNavigationSelectableItemBase) { if (item.selected && !this.collapsed) { item.fireEvent("click"); return; @@ -609,7 +609,7 @@ class SideNavigation extends UI5Element { return result; } - _selectItem(item: SideNavigationItemBase) { + _selectItem(item: SideNavigationSelectableItemBase) { if (item.disabled) { return; } diff --git a/packages/fiori/src/SideNavigationItem.ts b/packages/fiori/src/SideNavigationItem.ts index 13d88e42b3f1..779c2d6a22f2 100644 --- a/packages/fiori/src/SideNavigationItem.ts +++ b/packages/fiori/src/SideNavigationItem.ts @@ -2,7 +2,7 @@ import customElement from "@ui5/webcomponents-base/dist/decorators/customElement import property from "@ui5/webcomponents-base/dist/decorators/property.js"; import slot from "@ui5/webcomponents-base/dist/decorators/slot.js"; import { isLeft, isRight } from "@ui5/webcomponents-base/dist/Keys.js"; -import SideNavigationItemBase from "./SideNavigationItemBase.js"; +import SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase.js"; import type SideNavigation from "./SideNavigation.js"; import type SideNavigationSubItem from "./SideNavigationSubItem.js"; @@ -19,13 +19,13 @@ import type SideNavigationSubItem from "./SideNavigationSubItem.js"; * import "@ui5/webcomponents-fiori/dist/SideNavigationItem.js"; * * @constructor - * @extends SideNavigationItemBase + * @extends SideNavigationSelectableItemBase * @abstract * @public * @since 1.0.0-rc.8 */ @customElement("ui5-side-navigation-item") -class SideNavigationItem extends SideNavigationItemBase { +class SideNavigationItem extends SideNavigationSelectableItemBase { /** * Defines if the item is expanded * diff --git a/packages/fiori/src/SideNavigationItemBase.ts b/packages/fiori/src/SideNavigationItemBase.ts index bb35d2de3412..0d281de03044 100644 --- a/packages/fiori/src/SideNavigationItemBase.ts +++ b/packages/fiori/src/SideNavigationItemBase.ts @@ -1,7 +1,6 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; import event from "@ui5/webcomponents-base/dist/decorators/event.js"; import property from "@ui5/webcomponents-base/dist/decorators/property.js"; -import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; import type { ITabbable } from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js"; import type SideNavigation from "./SideNavigation.js"; @@ -34,63 +33,6 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { @property() text!: string; - /** - * Defines the icon of the item. - *

- * - * The SAP-icons font provides numerous options. - *
- * See all the available icons in the Icon Explorer. - * @public - * @default "" - */ - @property() - icon!: string; - - /** - * Defines whether the item is selected - * - * @public - * @default false - */ - @property({ type: Boolean }) - selected!: boolean; - - /** - * Defines the link target URI. Supports standard hyperlink behavior. - * If a JavaScript action should be triggered, - * this should not be set, but instead an event handler - * for the click event should be registered. - * - * @public - * @default "" - * @since 1.19.0 - */ - @property() - href!: string; - - /** - * Defines the component target. - *

- * Notes: - * - *
    - *
  • _self
  • - *
  • _top
  • - *
  • _blank
  • - *
  • _parent
  • - *
  • _search
  • - *
- * - * This property must only be used when the href property is set. - * - * @public - * @default "" - * @since 1.19.0 - */ - @property() - target!: string; - /** * Defines whether the component is disabled. * A disabled component can't be pressed or @@ -119,18 +61,6 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { return this.title || this.text; } - get _href() { - return (!this.disabled && this.href) ? this.href : undefined; - } - - get _target() { - return (!this.disabled && this.target) ? this.target : undefined; - } - - get _selected() { - return this.selected; - } - get classesArray() { const classes = []; @@ -138,10 +68,6 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { classes.push("ui5-sn-item-disabled"); } - if (this._selected) { - classes.push("ui5-sn-item-selected"); - } - return classes; } @@ -149,14 +75,6 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { return this.classesArray.join(" "); } - get _ariaCurrent() { - if (!this.selected) { - return undefined; - } - - return "page"; - } - get _effectiveTabIndex() { if (this.disabled) { return undefined; @@ -181,39 +99,9 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { return this.sideNavigation?.shadowRoot!.querySelector(`#${this._id}`) as HTMLElement; } - _onkeydown(e: KeyboardEvent) { - if (isSpace(e)) { - e.preventDefault(); - } - - if (isEnter(e)) { - this._activate(e); - } - } - - _onkeyup(e: KeyboardEvent) { - if (isSpace(e)) { - this._activate(e); - } - } - - _onclick(e: PointerEvent) { - this._activate(e); - } - get isFixedItem() { return true; } - - _onfocusin(e: FocusEvent) { - e.stopPropagation(); - - this.sideNavigation?.focusItem(this); - } - - _activate(e: KeyboardEvent | PointerEvent) { - this.sideNavigation?._handleItemClick(e, this); - } } export default SideNavigationItemBase; diff --git a/packages/fiori/src/SideNavigationSelectableItemBase.ts b/packages/fiori/src/SideNavigationSelectableItemBase.ts new file mode 100644 index 000000000000..78629ad5f6b7 --- /dev/null +++ b/packages/fiori/src/SideNavigationSelectableItemBase.ts @@ -0,0 +1,147 @@ +import property from "@ui5/webcomponents-base/dist/decorators/property.js"; +import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; +import SideNavigationItemBase from "./SideNavigationItemBase.js"; + +/** + * @class + * A class to serve as a foundation + * for the SideNavigationItem and SideNavigationSubItem classes. + * + * @constructor + * @extends UI5Element + * @abstract + * @public + * @since 1.19.0 + */ +class SideNavigationSelectableItemBase extends SideNavigationItemBase { + /** + * Defines the icon of the item. + *

+ * + * The SAP-icons font provides numerous options. + *
+ * See all the available icons in the Icon Explorer. + * @public + * @default "" + */ + @property() + icon!: string; + + /** + * Defines whether the item is selected + * + * @public + * @default false + */ + @property({ type: Boolean }) + selected!: boolean; + + /** + * Defines the link target URI. Supports standard hyperlink behavior. + * If a JavaScript action should be triggered, + * this should not be set, but instead an event handler + * for the click event should be registered. + * + * @public + * @default "" + * @since 1.19.0 + */ + @property() + href!: string; + + /** + * Defines the component target. + *

+ * Notes: + * + *
    + *
  • _self
  • + *
  • _top
  • + *
  • _blank
  • + *
  • _parent
  • + *
  • _search
  • + *
+ * + * This property must only be used when the href property is set. + * + * @public + * @default "" + * @since 1.19.0 + */ + @property() + target!: string; + + get _tooltip() { + return this.title || this.text; + } + + get _href() { + return (!this.disabled && this.href) ? this.href : undefined; + } + + get _target() { + return (!this.disabled && this.target) ? this.target : undefined; + } + + get _selected() { + return this.selected; + } + + get classesArray() { + const classes = []; + + if (this.disabled) { + classes.push("ui5-sn-item-disabled"); + } + + if (this._selected) { + classes.push("ui5-sn-item-selected"); + } + + return classes; + } + + get _classes() { + return this.classesArray.join(" "); + } + + get _ariaCurrent() { + if (!this.selected) { + return undefined; + } + + return "page"; + } + + _onkeydown(e: KeyboardEvent) { + if (isSpace(e)) { + e.preventDefault(); + } + + if (isEnter(e)) { + this._activate(e); + } + } + + _onkeyup(e: KeyboardEvent) { + if (isSpace(e)) { + this._activate(e); + } + } + + _onclick(e: PointerEvent) { + this._activate(e); + } + + _onfocusin(e: FocusEvent) { + e.stopPropagation(); + + this.sideNavigation?.focusItem(this); + } + + _activate(e: KeyboardEvent | PointerEvent) { + this.sideNavigation?._handleItemClick(e, this); + } +} + +export default SideNavigationSelectableItemBase; diff --git a/packages/fiori/src/SideNavigationSubItem.ts b/packages/fiori/src/SideNavigationSubItem.ts index a1bb93debf1b..088a4890cdfb 100644 --- a/packages/fiori/src/SideNavigationSubItem.ts +++ b/packages/fiori/src/SideNavigationSubItem.ts @@ -1,5 +1,5 @@ import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; -import SideNavigationItemBase from "./SideNavigationItemBase.js"; +import SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase.js"; /** * @class @@ -13,13 +13,13 @@ import SideNavigationItemBase from "./SideNavigationItemBase.js"; * import "@ui5/webcomponents-fiori/dist/SideNavigationSubItem.js"; * * @constructor - * @extends SideNavigationItemBase + * @extends SideNavigationSelectableItemBase * @public * @abstract * @since 1.0.0-rc.8 */ @customElement("ui5-side-navigation-sub-item") -class SideNavigationSubItem extends SideNavigationItemBase { +class SideNavigationSubItem extends SideNavigationSelectableItemBase { get isFixedItem() { return this.parentElement?.slot === "fixedItems"; } diff --git a/packages/fiori/test/pages/SideNavigationWithGroups.html b/packages/fiori/test/pages/SideNavigationWithGroups.html new file mode 100644 index 000000000000..5916b400d074 --- /dev/null +++ b/packages/fiori/test/pages/SideNavigationWithGroups.html @@ -0,0 +1,87 @@ + + + + + Side Navigation With Groups + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + + From caa974a706540f75e24311db242eb53337d0b6d0 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Fri, 9 Feb 2024 13:12:21 +0200 Subject: [PATCH 02/44] feat(ui5-side-navigation): add navigation groups --- packages/fiori/src/SideNavigationGroup.ts | 81 +++++++++++++++++++ packages/fiori/src/SideNavigationItemBase.ts | 9 +-- .../src/SideNavigationSelectableItemBase.ts | 15 +++- 3 files changed, 93 insertions(+), 12 deletions(-) create mode 100644 packages/fiori/src/SideNavigationGroup.ts diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts new file mode 100644 index 000000000000..6d749abe2751 --- /dev/null +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -0,0 +1,81 @@ +import property from "@ui5/webcomponents-base/dist/decorators/property.js"; +import slot from "@ui5/webcomponents-base/dist/decorators/slot.js"; +import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; +import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; +import SideNavigationItemBase from "./SideNavigationItemBase.js"; +import SideNavigationItem from "./SideNavigationItem.js"; + +/** + * @class + * + *

Overview

+ * + * The ui5-side-navigation-group is intended to be used inside a ui5-side-navigation-group only. + * + *

ES6 Module Import

+ * + * import "@ui5/webcomponents-fiori/dist/SideNavigationGroup.js"; + * + * @constructor + * @extends SideNavigationItemBase + * @public + * @abstract + * @since 1.0.0-rc.8 + */ +@customElement("ui5-side-navigation-group") +class SideNavigationGroup extends SideNavigationItemBase { + /** + * Defines if the item is expanded + * + * @public + * @default false + */ + @property({ type: Boolean }) + expanded!: boolean; + + /** + * Defines nested items by passing ui5-side-navigation-item to the default slot. + * + * @public + */ + @slot({ type: HTMLElement, invalidateOnChildChange: true, "default": true }) + items!: Array; + + get isFixedItem() { + return this.slot === "fixedItems"; + } + + _onkeydown(e: KeyboardEvent) { + if (isSpace(e)) { + e.preventDefault(); + } + + if (isEnter(e)) { + this._toggle(); + } + } + + _onkeyup(e: KeyboardEvent) { + if (isSpace(e)) { + this._toggle(); + } + } + + _onclick() { + this._toggle(); + } + + _onfocusin(e: FocusEvent) { + e.stopPropagation(); + + // this.sideNavigation?.focusItem(this); + } + + _toggle() { + this.expanded = !this.expanded; + } +} + +SideNavigationGroup.define(); + +export default SideNavigationGroup; diff --git a/packages/fiori/src/SideNavigationItemBase.ts b/packages/fiori/src/SideNavigationItemBase.ts index 0d281de03044..e213061b03f3 100644 --- a/packages/fiori/src/SideNavigationItemBase.ts +++ b/packages/fiori/src/SideNavigationItemBase.ts @@ -1,16 +1,9 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; -import event from "@ui5/webcomponents-base/dist/decorators/event.js"; import property from "@ui5/webcomponents-base/dist/decorators/property.js"; import type { ITabbable } from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js"; import type SideNavigation from "./SideNavigation.js"; -/** - * Fired when the component is activated either with a - * click/tap or by using the Enter or Space key. - * - * @public - */ -@event("click") + /** * @class diff --git a/packages/fiori/src/SideNavigationSelectableItemBase.ts b/packages/fiori/src/SideNavigationSelectableItemBase.ts index 78629ad5f6b7..41d651458391 100644 --- a/packages/fiori/src/SideNavigationSelectableItemBase.ts +++ b/packages/fiori/src/SideNavigationSelectableItemBase.ts @@ -1,7 +1,17 @@ +import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; import property from "@ui5/webcomponents-base/dist/decorators/property.js"; +import event from "@ui5/webcomponents-base/dist/decorators/event.js"; import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; import SideNavigationItemBase from "./SideNavigationItemBase.js"; +/** + * Fired when the component is activated either with a + * click/tap or by using the Enter or Space key. + * + * @public + */ +@event("click") + /** * @class * A class to serve as a foundation @@ -13,6 +23,7 @@ import SideNavigationItemBase from "./SideNavigationItemBase.js"; * @public * @since 1.19.0 */ +@customElement() class SideNavigationSelectableItemBase extends SideNavigationItemBase { /** * Defines the icon of the item. @@ -71,10 +82,6 @@ class SideNavigationSelectableItemBase extends SideNavigationItemBase { @property() target!: string; - get _tooltip() { - return this.title || this.text; - } - get _href() { return (!this.disabled && this.href) ? this.href : undefined; } From e17a74b6e51a207bb791f3caac9fa2fa112dde07 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Fri, 9 Feb 2024 13:14:52 +0200 Subject: [PATCH 03/44] feat(ui5-side-navigation): fix lint error --- packages/fiori/src/SideNavigationItemBase.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/fiori/src/SideNavigationItemBase.ts b/packages/fiori/src/SideNavigationItemBase.ts index e213061b03f3..da86a1075871 100644 --- a/packages/fiori/src/SideNavigationItemBase.ts +++ b/packages/fiori/src/SideNavigationItemBase.ts @@ -3,8 +3,6 @@ import property from "@ui5/webcomponents-base/dist/decorators/property.js"; import type { ITabbable } from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js"; import type SideNavigation from "./SideNavigation.js"; - - /** * @class * A class to serve as a foundation From 11519682ba0c6951c767aef4bca2093181af9b63 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Mon, 12 Feb 2024 11:23:01 +0200 Subject: [PATCH 04/44] feat(ui5-side-navigation): add group support --- packages/fiori/src/SideNavigation.ts | 83 ++++++++++++++++------- packages/fiori/src/SideNavigationGroup.ts | 9 +++ packages/fiori/src/SideNavigationItem.ts | 8 +++ 3 files changed, 76 insertions(+), 24 deletions(-) diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index 78399e63eabf..44e71940e879 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -27,8 +27,10 @@ import "@ui5/webcomponents-icons/dist/circle-task-2.js"; import "@ui5/webcomponents-icons/dist/navigation-right-arrow.js"; import "@ui5/webcomponents-icons/dist/navigation-down-arrow.js"; import type SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase.js"; +import SideNavigationItemBase from "./SideNavigationItemBase.js"; import SideNavigationItem from "./SideNavigationItem.js"; import SideNavigationSubItem from "./SideNavigationSubItem.js"; +import SideNavigationGroup from "./SideNavigationGroup.js"; import SideNavigationTemplate from "./generated/templates/SideNavigationTemplate.lit.js"; import SideNavigationPopoverTemplate from "./generated/templates/SideNavigationPopoverTemplate.lit.js"; @@ -158,7 +160,18 @@ class SideNavigation extends UI5Element { * @public */ @slot({ type: HTMLElement, invalidateOnChildChange: true, "default": true }) - items!: Array; + items!: Array; + + /** + * Defines the fixed items at the bottom of the ui5-side-navigation. Use the ui5-side-navigation-item component + * for the fixed items, and optionally the ui5-side-navigation-sub-item component to provide second-level items inside them. + * + * Note: In order to achieve the best user experience, it is recommended that you keep the fixed items "flat" (do not pass sub-items) + * + * @public + */ + @slot({ type: HTMLElement, invalidateOnChildChange: true }) + fixedItems!: Array; /** * Defines the header of the ui5-side-navigation. @@ -172,16 +185,6 @@ class SideNavigation extends UI5Element { @slot() header!: Array; - /** - * Defines the fixed items at the bottom of the ui5-side-navigation. Use the ui5-side-navigation-item component - * for the fixed items, and optionally the ui5-side-navigation-sub-item component to provide second-level items inside them. - * - * Note: In order to achieve the best user experience, it is recommended that you keep the fixed items "flat" (do not pass sub-items) - * - * @public - */ - @slot({ type: HTMLElement, invalidateOnChildChange: true }) - fixedItems!: Array; /** * @private */ @@ -397,10 +400,10 @@ class SideNavigation extends UI5Element { return [...this.getEnabledItems(this.items), this._overflowDom]; } - getEnabledItems(items: Array) : Array { + getEnabledItems(items: Array) : Array { let result = new Array(); - items.forEach(item => { + this._getFocusableItems(items).forEach(item => { if (item.getDomRef()?.classList.contains("ui5-sn-item-hidden")) { return; } @@ -413,10 +416,11 @@ class SideNavigation extends UI5Element { result = result.concat(item.items.filter(el => !el.disabled)); } }); + return result; } - focusItem(item: SideNavigationSelectableItemBase) { + focusItem(item: SideNavigationItemBase) { if (item.isFixedItem) { this._fixedItemNavigation.setCurrentItem(item); } else { @@ -527,25 +531,56 @@ class SideNavigation extends UI5Element { }); } - _findFocusedItem(items: Array) : SideNavigationSelectableItemBase | undefined { + _findFocusedItem(items: Array) : SideNavigationItemBase | undefined { let focusedItem; if (this.collapsed) { focusedItem = items.find(item => item.forcedTabIndex === "0"); } else { - focusedItem = this._getWithNestedItems(items, true).find(item => item.forcedTabIndex === "0"); + focusedItem = this._getAllFocusableItems(items).find(item => item.forcedTabIndex === "0"); } return focusedItem; } - _getWithNestedItems(items: Array, expandedOnly = false): Array { + _getSelectableItems(items: Array) : Array { + let result = new Array(); + + items.forEach(item => { + result = result.concat(item.selectableItems); + }); + + return result; + } + + _getAllSelectableItems(items: Array): Array { let result = new Array(); + this._getSelectableItems(items).forEach(item => { + result.push(item); + result = result.concat(item.items); + }); + + return result; + } + + _getFocusableItems(items: Array) : Array { + let result = new Array(); + + items.forEach(item => { + result = result.concat(item.focusableItems); + }); + + return result; + } + + _getAllFocusableItems(items: Array): Array { + let result = new Array(); + items.forEach(item => { result.push(item); - if (!expandedOnly || item.expanded) { + if (item.expanded) { result = result.concat(item.items); } }); @@ -553,13 +588,13 @@ class SideNavigation extends UI5Element { return result; } - _findSelectedItem(items: Array) : SideNavigationSelectableItemBase | undefined { + _findSelectedItem(items: Array) : SideNavigationSelectableItemBase | undefined { let selectedItem; if (this.collapsed) { - selectedItem = items.find(item => item._selected); + selectedItem = this._getSelectableItems(items).find(item => item._selected); } else { - selectedItem = this._getWithNestedItems(items).find(current => current.selected); + selectedItem = this._getAllSelectableItems(items).find(current => current.selected); } return selectedItem; @@ -601,7 +636,7 @@ class SideNavigation extends UI5Element { const overflowClass = "ui5-sn-item-hidden"; const result: Array = []; - this.items.forEach(item => { + this._getSelectableItems(this.items).forEach(item => { if (item.getDomRef().classList.contains(overflowClass)) { result.push(item); } @@ -618,8 +653,8 @@ class SideNavigation extends UI5Element { return; } - let items = this._getWithNestedItems(this.items); - items = items.concat(this._getWithNestedItems(this.fixedItems)); + let items = this._getAllSelectableItems(this.items); + items = items.concat(this._getAllSelectableItems(this.fixedItems)); items.forEach(current => { current.selected = false; diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts index 6d749abe2751..df323c57c211 100644 --- a/packages/fiori/src/SideNavigationGroup.ts +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -4,6 +4,7 @@ import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; import SideNavigationItemBase from "./SideNavigationItemBase.js"; import SideNavigationItem from "./SideNavigationItem.js"; +import arraysAreEqual from "@ui5/webcomponents-base/dist/util/arraysAreEqual"; /** * @class @@ -41,6 +42,14 @@ class SideNavigationGroup extends SideNavigationItemBase { @slot({ type: HTMLElement, invalidateOnChildChange: true, "default": true }) items!: Array; + get selectableItems() : Array { + return this.items; + } + + get focusableItems() : Array { + return [this, ...this.items]; + } + get isFixedItem() { return this.slot === "fixedItems"; } diff --git a/packages/fiori/src/SideNavigationItem.ts b/packages/fiori/src/SideNavigationItem.ts index 779c2d6a22f2..348617626ada 100644 --- a/packages/fiori/src/SideNavigationItem.ts +++ b/packages/fiori/src/SideNavigationItem.ts @@ -65,6 +65,14 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { @property({ type: Boolean }) wholeItemToggleable!: boolean; + get selectableItems() : Array { + return [this]; + } + + get focusableItems() : Array { + return [this]; + } + get _ariaHasPopup() { if (!this.disabled && (this.parentNode as SideNavigation).collapsed && this.items.length) { return "tree"; From 777520cae9ceba4c0833fb40bff1d7a1da7dd36d Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Mon, 12 Feb 2024 11:37:51 +0200 Subject: [PATCH 05/44] feat(ui5-side-navigation): fix lint error --- packages/fiori/src/SideNavigationGroup.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts index df323c57c211..b71282b56d28 100644 --- a/packages/fiori/src/SideNavigationGroup.ts +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -4,7 +4,6 @@ import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; import SideNavigationItemBase from "./SideNavigationItemBase.js"; import SideNavigationItem from "./SideNavigationItem.js"; -import arraysAreEqual from "@ui5/webcomponents-base/dist/util/arraysAreEqual"; /** * @class From 5a22a46216489e344f22b75097bba1bed2f7d6c0 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Mon, 12 Feb 2024 12:46:54 +0200 Subject: [PATCH 06/44] feat(ui5-side-navigation): fix "this" context --- packages/fiori/src/SideNavigationGroup.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts index b71282b56d28..8846edd1da02 100644 --- a/packages/fiori/src/SideNavigationGroup.ts +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -53,7 +53,7 @@ class SideNavigationGroup extends SideNavigationItemBase { return this.slot === "fixedItems"; } - _onkeydown(e: KeyboardEvent) { + _onkeydown = (e: KeyboardEvent) => { if (isSpace(e)) { e.preventDefault(); } @@ -63,20 +63,20 @@ class SideNavigationGroup extends SideNavigationItemBase { } } - _onkeyup(e: KeyboardEvent) { + _onkeyup = (e: KeyboardEvent) => { if (isSpace(e)) { this._toggle(); } } - _onclick() { + _onclick = () => { this._toggle(); } - _onfocusin(e: FocusEvent) { + _onfocusin = (e: FocusEvent) => { e.stopPropagation(); - // this.sideNavigation?.focusItem(this); + this.sideNavigation?.focusItem(this); } _toggle() { From 493d687eaf120b45946cf56fa054cef9aff6c27c Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Mon, 12 Feb 2024 14:58:48 +0200 Subject: [PATCH 07/44] feat(ui5-side-navigation): refactor rendering --- packages/fiori/src/SideNavigation.hbs | 191 +----------- packages/fiori/src/SideNavigation.ts | 8 +- packages/fiori/src/SideNavigationGroup.hbs | 38 +++ packages/fiori/src/SideNavigationGroup.ts | 36 ++- packages/fiori/src/SideNavigationItem.hbs | 134 +++++++++ packages/fiori/src/SideNavigationItem.ts | 22 +- packages/fiori/src/SideNavigationItemBase.ts | 12 +- packages/fiori/src/SideNavigationSubItem.hbs | 47 +++ packages/fiori/src/SideNavigationSubItem.ts | 16 +- packages/fiori/src/themes/SideNavigation.css | 270 ----------------- .../fiori/src/themes/SideNavigationItem.css | 279 ++++++++++++++++++ 11 files changed, 582 insertions(+), 471 deletions(-) create mode 100644 packages/fiori/src/SideNavigationGroup.hbs create mode 100644 packages/fiori/src/SideNavigationItem.hbs create mode 100644 packages/fiori/src/SideNavigationSubItem.hbs create mode 100644 packages/fiori/src/themes/SideNavigationItem.css diff --git a/packages/fiori/src/SideNavigation.hbs b/packages/fiori/src/SideNavigation.hbs index f5f97bc3e51c..cbb52874ea6e 100644 --- a/packages/fiori/src/SideNavigation.hbs +++ b/packages/fiori/src/SideNavigation.hbs @@ -7,9 +7,7 @@ aria-orientation="vertical" aria-roledescription="{{ariaRoleDescNavigationList}}" > - {{#each items}} - {{> menuitem }} - {{/each}} + {{> overflowItem}} {{else}} @@ -17,9 +15,7 @@ class="ui5-sn-list ui5-sn-flexible" aria-roledescription="{{ariaRoleDescNavigationList}}" > - {{#each items}} - {{> treeitem }} - {{/each}} + {{/if}} @@ -31,18 +27,14 @@ aria-orientation="vertical" aria-roledescription="{{ariaRoleDescNavigationList}}" > - {{#each fixedItems}} - {{> menuitem }} - {{/each}} + {{else}}
    - {{#each fixedItems}} - {{> treeitem }} - {{/each}} +
{{/if}} {{/if}} @@ -54,181 +46,6 @@ {{/if}} {{/inline}} -{{#*inline menuitem}} - {{#if _href}} - - -
{{text}}
- {{#if items.length}} - - {{/if}} -
- {{else}} -
- -
{{text}}
- {{#if items.length}} - - {{/if}} -
- {{/if}} -{{/inline}} - -{{#*inline treeitem}} -
  • - {{#if _href}} - - {{#if icon}} - - {{/if}} -
    {{text}}
    - - {{#if items.length}} - - {{/if}} -
    - {{else}} -
    - {{#if icon}} - - {{/if}} -
    {{text}}
    - - {{#if items.length}} - - {{/if}} -
    - {{/if}} - {{#if items.length}} - - {{/if}} -
  • -{{/inline}} - {{#*inline overflowItem}}
    ) { @@ -637,7 +637,7 @@ class SideNavigation extends UI5Element { const result: Array = []; this._getSelectableItems(this.items).forEach(item => { - if (item.getDomRef().classList.contains(overflowClass)) { + if (item.getDomRef()!.classList.contains(overflowClass)) { result.push(item); } }); @@ -663,7 +663,7 @@ class SideNavigation extends UI5Element { item.selected = true; if (this.collapsed && item.getDomRef()?.classList.contains("ui5-sn-item-hidden")) { - item.getDomRef().classList.remove("ui5-sn-item-hidden"); + item.getDomRef()?.classList.remove("ui5-sn-item-hidden"); } } diff --git a/packages/fiori/src/SideNavigationGroup.hbs b/packages/fiori/src/SideNavigationGroup.hbs new file mode 100644 index 000000000000..403feaf01750 --- /dev/null +++ b/packages/fiori/src/SideNavigationGroup.hbs @@ -0,0 +1,38 @@ +{{#if sideNavExpanded}} + {{> treeitem }} +{{else}} +
    +{{/if}} + +{{#*inline treeitem}} +
  • +
    +
    {{text}}
    + {{#if items.length}} + + {{/if}} +
    + {{#if items.length}} +
      + +
    + {{/if}} +
  • +{{/inline}} \ No newline at end of file diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts index 8846edd1da02..3a6b0b5d9ec9 100644 --- a/packages/fiori/src/SideNavigationGroup.ts +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -1,9 +1,15 @@ import property from "@ui5/webcomponents-base/dist/decorators/property.js"; +import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; import slot from "@ui5/webcomponents-base/dist/decorators/slot.js"; import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; +import Icon from "@ui5/webcomponents/dist/Icon.js"; import SideNavigationItemBase from "./SideNavigationItemBase.js"; import SideNavigationItem from "./SideNavigationItem.js"; +import SideNavigationGroupTemplate from "./generated/templates/SideNavigationGroupTemplate.lit.js"; + +// Styles +import SideNavigationCss from "./generated/themes/SideNavigation.css.js"; /** * @class @@ -22,7 +28,15 @@ import SideNavigationItem from "./SideNavigationItem.js"; * @abstract * @since 1.0.0-rc.8 */ -@customElement("ui5-side-navigation-group") +@customElement({ + tag: "ui5-side-navigation-group", + renderer: litRender, + template: SideNavigationGroupTemplate, + styles: SideNavigationCss, + dependencies: [ + Icon, + ], +}) class SideNavigationGroup extends SideNavigationItemBase { /** * Defines if the item is expanded @@ -53,6 +67,26 @@ class SideNavigationGroup extends SideNavigationItemBase { return this.slot === "fixedItems"; } + get _groupId() { + if (!this.items.length) { + return undefined; + } + + return `${this._id}-group`; + } + + get _expanded() { + if (!this.items.length) { + return undefined; + } + + return this.expanded; + } + + get _toggleIconName() { + return this.expanded ? "navigation-down-arrow" : "navigation-right-arrow"; + } + _onkeydown = (e: KeyboardEvent) => { if (isSpace(e)) { e.preventDefault(); diff --git a/packages/fiori/src/SideNavigationItem.hbs b/packages/fiori/src/SideNavigationItem.hbs new file mode 100644 index 000000000000..983fe742306e --- /dev/null +++ b/packages/fiori/src/SideNavigationItem.hbs @@ -0,0 +1,134 @@ +{{#if sideNavExpanded}} + {{> treeitem }} +{{else}} + {{> menuitem }} +{{/if}} + +{{#*inline menuitem}} + {{#if _href}} + + +
    {{text}}
    + {{#if items.length}} + + {{/if}} +
    + {{else}} +
    + +
    {{text}}
    + {{#if items.length}} + + {{/if}} +
    + {{/if}} +{{/inline}} + +{{#*inline treeitem}} +
  • + {{#if _href}} + + {{#if icon}} + + {{/if}} +
    {{text}}
    + + {{#if items.length}} + + {{/if}} +
    + {{else}} +
    + {{#if icon}} + + {{/if}} +
    {{text}}
    + + {{#if items.length}} + + {{/if}} +
    + {{/if}} + {{#if items.length}} +
      + +
    + {{/if}} +
  • +{{/inline}} \ No newline at end of file diff --git a/packages/fiori/src/SideNavigationItem.ts b/packages/fiori/src/SideNavigationItem.ts index 348617626ada..dee8bc0c2856 100644 --- a/packages/fiori/src/SideNavigationItem.ts +++ b/packages/fiori/src/SideNavigationItem.ts @@ -1,10 +1,16 @@ import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; +import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; import property from "@ui5/webcomponents-base/dist/decorators/property.js"; import slot from "@ui5/webcomponents-base/dist/decorators/slot.js"; import { isLeft, isRight } from "@ui5/webcomponents-base/dist/Keys.js"; +import Icon from "@ui5/webcomponents/dist/Icon.js"; import SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase.js"; import type SideNavigation from "./SideNavigation.js"; import type SideNavigationSubItem from "./SideNavigationSubItem.js"; +import SideNavigationItemTemplate from "./generated/templates/SideNavigationItemTemplate.lit.js"; + +// Styles +import SideNavigationItemCss from "./generated/themes/SideNavigationItem.css.js"; /** * @class @@ -24,7 +30,15 @@ import type SideNavigationSubItem from "./SideNavigationSubItem.js"; * @public * @since 1.0.0-rc.8 */ -@customElement("ui5-side-navigation-item") +@customElement({ + tag: "ui5-side-navigation-item", + renderer: litRender, + template: SideNavigationItemTemplate, + styles: SideNavigationItemCss, + dependencies: [ + Icon, + ], +}) class SideNavigationItem extends SideNavigationSelectableItemBase { /** * Defines if the item is expanded @@ -173,7 +187,7 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { return; } - this.getDomRef().classList.remove("ui5-sn-item-no-hover-effect"); + this.getDomRef()!.classList.remove("ui5-sn-item-no-hover-effect"); } _onmouseenter = () => { @@ -181,7 +195,7 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { return; } - this.getDomRef().classList.remove("ui5-sn-item-no-hover-effect"); + this.getDomRef()!.classList.remove("ui5-sn-item-no-hover-effect"); } _onmouseleave = () => { @@ -189,7 +203,7 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { return; } - this.getDomRef().classList.add("ui5-sn-item-no-hover-effect"); + this.getDomRef()!.classList.add("ui5-sn-item-no-hover-effect"); } } diff --git a/packages/fiori/src/SideNavigationItemBase.ts b/packages/fiori/src/SideNavigationItemBase.ts index da86a1075871..f0c53c8e7f84 100644 --- a/packages/fiori/src/SideNavigationItemBase.ts +++ b/packages/fiori/src/SideNavigationItemBase.ts @@ -15,6 +15,11 @@ import type SideNavigation from "./SideNavigation.js"; * @since 1.19.0 */ class SideNavigationItemBase extends UI5Element implements ITabbable { + constructor() { + super(); + + this.sideNavExpanded = true; + } /** * Defines the text of the item. * @@ -48,6 +53,9 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { @property({ defaultValue: "-1", noAttribute: true }) forcedTabIndex!: string; + @property({ type: Boolean, noAttribute: true }) + sideNavExpanded!: boolean; + get _tooltip() { return this.title || this.text; } @@ -86,10 +94,6 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { } } - getDomRef() { - return this.sideNavigation?.shadowRoot!.querySelector(`#${this._id}`) as HTMLElement; - } - get isFixedItem() { return true; } diff --git a/packages/fiori/src/SideNavigationSubItem.hbs b/packages/fiori/src/SideNavigationSubItem.hbs new file mode 100644 index 000000000000..41b9827700c9 --- /dev/null +++ b/packages/fiori/src/SideNavigationSubItem.hbs @@ -0,0 +1,47 @@ +{{#if sideNavExpanded}} +
  • + {{#if _href}} + + {{#if icon}} + + {{/if}} +
    {{text}}
    + +
    + {{else}} +
    + {{#if icon}} + + {{/if}} +
    {{text}}
    + +
    + {{/if}} +
  • +{{/if}} \ No newline at end of file diff --git a/packages/fiori/src/SideNavigationSubItem.ts b/packages/fiori/src/SideNavigationSubItem.ts index 088a4890cdfb..0da5c8efcc41 100644 --- a/packages/fiori/src/SideNavigationSubItem.ts +++ b/packages/fiori/src/SideNavigationSubItem.ts @@ -1,5 +1,11 @@ import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; +import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; +import Icon from "@ui5/webcomponents/dist/Icon.js"; import SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase.js"; +import SideNavigationSubItemTemplate from "./generated/templates/SideNavigationSubItemTemplate.lit.js"; + +// Styles +import SideNavigationItemCss from "./generated/themes/SideNavigationItem.css.js"; /** * @class @@ -18,7 +24,15 @@ import SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase * @abstract * @since 1.0.0-rc.8 */ -@customElement("ui5-side-navigation-sub-item") +@customElement({ + tag: "ui5-side-navigation-sub-item", + renderer: litRender, + template: SideNavigationSubItemTemplate, + styles: SideNavigationItemCss, + dependencies: [ + Icon, + ], +}) class SideNavigationSubItem extends SideNavigationSelectableItemBase { get isFixedItem() { return this.parentElement?.slot === "fixedItems"; diff --git a/packages/fiori/src/themes/SideNavigation.css b/packages/fiori/src/themes/SideNavigation.css index 2f830a3b2583..54118e96102c 100644 --- a/packages/fiori/src/themes/SideNavigation.css +++ b/packages/fiori/src/themes/SideNavigation.css @@ -75,276 +75,6 @@ flex-direction: column; } -.ui5-sn-item { - display: flex; - align-items: center; - width: 100%; - box-sizing: border-box; - text-decoration: none; - position: relative; - - height: var(--_ui5_side_navigation_item_height); - min-height: var(--_ui5_side_navigation_item_height); - cursor: pointer; - background-color: var(--sapList_Background); - border-radius: var(--_ui5_side_navigation_item_border_radius); - transition: var(--_ui5_side_navigation_item_transition); - - margin-block-end: var(--_ui5_side_navigation_item_bottom_margin); -} -.ui5-sn-item-hidden { - display: none; -} -.ui5-sn-item:focus { - outline: none; -} - -.ui5-sn-item:focus::after { - border: var(--sapContent_FocusWidth) var(--sapContent_FocusStyle) var(--sapContent_FocusColor); - position: absolute; - content: ""; - inset: var(--_ui5_side_navigation_item_focus_border_offset); - z-index: 2; - pointer-events: none; - border-radius: var(--_ui5_side_navigation_item_focus_border_radius); -} - -.ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected:focus::before { - border: var(--_ui5_side_navigation_selected_and_focused_border_style_color); -} - -.ui5-sn-item.ui5-sn-item-level1::before { - border: var(--_ui5_side_navigation_group_border_style_color); - border-width: var(--_ui5_side_navigation_group_border_width); -} - -.ui5-sn-item-level1[aria-expanded="true"]::before { - border-width: var(--_ui5_side_navigation_group_expanded_border_width); -} - -.ui5-sn-item-group .ui5-sn-list-li:last-child .ui5-sn-item.ui5-sn-item-level2:not(.ui5-sn-item-selected)::before { - border: var(--_ui5_side_navigation_group_border_style_color); - border-width: var(--_ui5_side_navigation_group_border_width); -} - - /* borders are drawn using a pseudo element. - in some themes, the border is drawn only on the bottom. - in high contrast themes the border is on all sides and there is extra border on hover */ -.ui5-sn-item::before { - content: ""; - position: absolute; - inset: 0; - pointer-events: none; -} - -.ui5-sn-item.ui5-sn-item-disabled { - opacity: var(--sapContent_DisabledOpacity); - cursor: default; -} - -.ui5-sn-item:not(.ui5-sn-item-disabled):hover { - background: var(--sapList_Hover_Background); -} - -.ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected { - background: var(--sapList_SelectionBackgroundColor); -} - -.ui5-sn-item:not(.ui5-sn-item-disabled):active .ui5-sn-item-text, -.ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-active .ui5-sn-item-text { - color: var(--sapList_Active_TextColor); -} - -.ui5-sn-item:not(.ui5-sn-item-disabled):active [ui5-icon], -.ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-active [ui5-icon] { - color: var(--sapList_Active_TextColor); -} - -.ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected:hover { - background: var(--sapList_Hover_SelectionBackground); -} - -.ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected:active, -.ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected.ui5-sn-item-active, -.ui5-sn-item:not(.ui5-sn-item-disabled):active, -.ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-active, -.ui5-sn-collapsed .ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected:active, -.ui5-sn-collapsed .ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected.ui5-sn-item-active { - background: var(--sapList_Active_Background); -} - -.ui5-sn-collapsed .ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected { - background: var(--_ui5_side_navigation_collapsed_selected_item_background); -} - -.ui5-sn-item::before { - border: var(--_ui5_side_navigation_item_border_style_color); - border-width: var(--_ui5_side_navigation_item_border_width); -} - -.ui5-sn-collapsed .ui5-sn-item::before { - border-width: var(--_ui5_side_navigation_item_border_width); -} - -.ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected::before { - border: var(--_ui5_side_navigation_selected_border_style_color); - border-width: var(--_ui5_side_navigation_selected_border_width); -} - -.ui5-sn-item:not(.ui5-sn-item-disabled):not(.ui5-sn-item-selected):hover::before { - border: var(--_ui5_side_navigation_hover_border_style_color); - border-width: var(--_ui5_side_navigation_hover_border_width); -} - -.ui5-sn-item.ui5-sn-item-level2::before { - border: var(--_ui5_side_navigation_item_border_style_color); - border-width: var(--_ui5_side_navigation_item_border_width); -} - -.ui5-sn-collapsed .ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected::before { - border-radius: var(--_ui5_side_navigation_item_border_radius); -} - -.ui5-sn-in-popover .ui5-sn-item-group .ui5-sn-list-li:last-child .ui5-sn-item:not(:hover):not(:active)::before { - border: var(--_ui5_side_navigation_last_item_border_style); -} - -.ui5-sn-item-icon { - color: var(--_ui5_side_navigation_icon_color); - height: var(--_ui5_side_navigation_icon_font_size); - min-width: var(--_ui5_side_navigation_group_icon_width); -} - -.ui5-sn-item-toggle-icon { - color: var(--_ui5_side_navigation_expand_icon_color); - min-width: 2rem; - height: 0.875rem; -} - -.ui5-sn-item-fixed .ui5-sn-item-toggle-icon { - display: none; -} - -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item { - justify-content: center; -} - -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item-icon { - padding: var(--_ui5_side_navigation_item_collapsed_icon_padding); -} - -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item-text { - display: none; -} - -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item-toggle-icon { - display: none; -} - -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover, -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus { - width: var(--_ui5_side_navigation_item_collapsed_hover_focus_width); - box-shadow: var(--_ui5_side_navigation_box_shadow); - z-index: 1; -} - -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item.ui5-sn-item-selected:hover, -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item.ui5-sn-item-selected:focus { - background: var(--sapList_SelectionBackgroundColor); -} - -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover:not(.ui5-sn-item-with-expander), -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus:not(.ui5-sn-item-with-expander) { - padding-right: var(--_ui5_side_navigation_item_collapsed_hover_focus_padding_right); -} - -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover .ui5-sn-item-text, -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus .ui5-sn-item-text { - display: var(--_ui5_side_navigation_item_collapsed_hover_focus_display); -} - -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover .ui5-sn-item-toggle-icon, -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus .ui5-sn-item-toggle-icon { - display: var(--_ui5_side_navigation_item_collapsed_hover_focus_display); -} - -.ui5-sn-item[aria-expanded=false] + .ui5-sn-item-group { - display: none; -} - -.ui5-sn-item-level2 { - padding-inline-start: var(--_ui5_side_navigation_group_icon_width); -} - -.ui5-sn-item-text { - flex: 1; - min-width: 0; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - color: var(--sapList_TextColor); -} - -.ui5-sn-item-level1 .ui5-sn-item-text { - font-weight: var(--_ui5_side_navigation_group_text_weight); -} - -.ui5-sn-item-level1:not(:has(> .ui5-sn-item-icon)), -.ui5-sn-item-level1.ui5-sn-item-selected:not(:has(> .ui5-sn-item-icon)) { - padding-inline-start: var(--_ui5_side_navigation_item_padding_left); -} - -.ui5-sn-item-with-expander .ui5-sn-item-icon::after { - display: var(--_ui5_side_navigation_triangle_display); - content: ""; - width: 0; - height: 0; - border-left: 0.375rem solid transparent; - border-bottom: 0.375rem solid var(--_ui5_side_navigation_triangle_color); - position: absolute; - right: 0.1875rem; - bottom: 0.125rem; -} - -.ui5-sn-item-selection-icon { - display: none; - height: 0.5rem; - width: 0.5rem; - margin-inline: 0.5rem; - color: var(--sapList_SelectionBorderColor); -} - -.ui5-sn-item[aria-expanded] .ui5-sn-item-selection-icon { - margin-inline: 0.5rem 0; -} - -.ui5-sn-root:not(.ui5-sn-collapsed) .ui5-sn-item:not([aria-expanded]) { - padding-inline-end: var(--_ui5_side_navigation_item_padding_right); -} - -.ui5-sn-item-selected .ui5-sn-item-selection-icon { - display: var(--_ui5_side_navigation_selection_indicator_display); -} - -.ui5-sn-in-popover .ui5-sn-list { - padding: var(--_ui5_side_navigation_parent_popup_padding); -} - -.ui5-sn-in-popover .ui5-sn-item { - padding: var(--_ui5_side_navigation_popup_item_padding); - width: auto; -} - -.ui5-sn-in-popover .ui5-sn-item-level1 { - margin-bottom: var(--_ui5_side_navigation_group_bottom_margin_in_popup); -} - -.ui5-sn-in-popover .ui5-sn-item-level1 .ui5-sn-item-text { - margin: 0 1rem 0 0; - font-size: var(--_ui5_side_navigation_popup_title_text_size); - line-height: var(--_ui5_side_navigation_popup_title_line_height); -} - .ui5-sn-item.ui5-sn-item-level1.ui5-sn-item-overflow { margin-top: auto; } \ No newline at end of file diff --git a/packages/fiori/src/themes/SideNavigationItem.css b/packages/fiori/src/themes/SideNavigationItem.css new file mode 100644 index 000000000000..c8a84127cbd6 --- /dev/null +++ b/packages/fiori/src/themes/SideNavigationItem.css @@ -0,0 +1,279 @@ +.ui5-sn-item-group { + margin: 0; + padding: 0; + list-style: none; +} + +.ui5-sn-item { + display: flex; + align-items: center; + width: 100%; + box-sizing: border-box; + text-decoration: none; + position: relative; + + height: var(--_ui5_side_navigation_item_height); + min-height: var(--_ui5_side_navigation_item_height); + cursor: pointer; + background-color: var(--sapList_Background); + border-radius: var(--_ui5_side_navigation_item_border_radius); + transition: var(--_ui5_side_navigation_item_transition); + + margin-block-end: var(--_ui5_side_navigation_item_bottom_margin); +} +.ui5-sn-item-hidden { + display: none; +} +.ui5-sn-item:focus { + outline: none; +} + +.ui5-sn-item:focus::after { + border: var(--sapContent_FocusWidth) var(--sapContent_FocusStyle) var(--sapContent_FocusColor); + position: absolute; + content: ""; + inset: var(--_ui5_side_navigation_item_focus_border_offset); + z-index: 2; + pointer-events: none; + border-radius: var(--_ui5_side_navigation_item_focus_border_radius); +} + +.ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected:focus::before { + border: var(--_ui5_side_navigation_selected_and_focused_border_style_color); +} + +.ui5-sn-item.ui5-sn-item-level1::before { + border: var(--_ui5_side_navigation_group_border_style_color); + border-width: var(--_ui5_side_navigation_group_border_width); +} + +.ui5-sn-item-level1[aria-expanded="true"]::before { + border-width: var(--_ui5_side_navigation_group_expanded_border_width); +} + +.ui5-sn-item-group .ui5-sn-list-li:last-child .ui5-sn-item.ui5-sn-item-level2:not(.ui5-sn-item-selected)::before { + border: var(--_ui5_side_navigation_group_border_style_color); + border-width: var(--_ui5_side_navigation_group_border_width); +} + + /* borders are drawn using a pseudo element. + in some themes, the border is drawn only on the bottom. + in high contrast themes the border is on all sides and there is extra border on hover */ +.ui5-sn-item::before { + content: ""; + position: absolute; + inset: 0; + pointer-events: none; +} + +.ui5-sn-item.ui5-sn-item-disabled { + opacity: var(--sapContent_DisabledOpacity); + cursor: default; +} + +.ui5-sn-item:not(.ui5-sn-item-disabled):hover { + background: var(--sapList_Hover_Background); +} + +.ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected { + background: var(--sapList_SelectionBackgroundColor); +} + +.ui5-sn-item:not(.ui5-sn-item-disabled):active .ui5-sn-item-text, +.ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-active .ui5-sn-item-text { + color: var(--sapList_Active_TextColor); +} + +.ui5-sn-item:not(.ui5-sn-item-disabled):active [ui5-icon], +.ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-active [ui5-icon] { + color: var(--sapList_Active_TextColor); +} + +.ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected:hover { + background: var(--sapList_Hover_SelectionBackground); +} + +.ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected:active, +.ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected.ui5-sn-item-active, +.ui5-sn-item:not(.ui5-sn-item-disabled):active, +.ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-active, +.ui5-sn-collapsed .ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected:active, +.ui5-sn-collapsed .ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected.ui5-sn-item-active { + background: var(--sapList_Active_Background); +} + +.ui5-sn-collapsed .ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected { + background: var(--_ui5_side_navigation_collapsed_selected_item_background); +} + +.ui5-sn-item::before { + border: var(--_ui5_side_navigation_item_border_style_color); + border-width: var(--_ui5_side_navigation_item_border_width); +} + +.ui5-sn-collapsed .ui5-sn-item::before { + border-width: var(--_ui5_side_navigation_item_border_width); +} + +.ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected::before { + border: var(--_ui5_side_navigation_selected_border_style_color); + border-width: var(--_ui5_side_navigation_selected_border_width); +} + +.ui5-sn-item:not(.ui5-sn-item-disabled):not(.ui5-sn-item-selected):hover::before { + border: var(--_ui5_side_navigation_hover_border_style_color); + border-width: var(--_ui5_side_navigation_hover_border_width); +} + +.ui5-sn-item.ui5-sn-item-level2::before { + border: var(--_ui5_side_navigation_item_border_style_color); + border-width: var(--_ui5_side_navigation_item_border_width); +} + +.ui5-sn-collapsed .ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected::before { + border-radius: var(--_ui5_side_navigation_item_border_radius); +} + +.ui5-sn-in-popover .ui5-sn-item-group .ui5-sn-list-li:last-child .ui5-sn-item:not(:hover):not(:active)::before { + border: var(--_ui5_side_navigation_last_item_border_style); +} + +.ui5-sn-item-icon { + color: var(--_ui5_side_navigation_icon_color); + height: var(--_ui5_side_navigation_icon_font_size); + min-width: var(--_ui5_side_navigation_group_icon_width); +} + +.ui5-sn-item-toggle-icon { + color: var(--_ui5_side_navigation_expand_icon_color); + min-width: 2rem; + height: 0.875rem; +} + +.ui5-sn-item-fixed .ui5-sn-item-toggle-icon { + display: none; +} + +.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item { + justify-content: center; +} + +.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item-icon { + padding: var(--_ui5_side_navigation_item_collapsed_icon_padding); +} + +.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item-text { + display: none; +} + +.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item-toggle-icon { + display: none; +} + +.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover, +.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus { + width: var(--_ui5_side_navigation_item_collapsed_hover_focus_width); + box-shadow: var(--_ui5_side_navigation_box_shadow); + z-index: 1; +} + +.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item.ui5-sn-item-selected:hover, +.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item.ui5-sn-item-selected:focus { + background: var(--sapList_SelectionBackgroundColor); +} + +.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover:not(.ui5-sn-item-with-expander), +.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus:not(.ui5-sn-item-with-expander) { + padding-right: var(--_ui5_side_navigation_item_collapsed_hover_focus_padding_right); +} + +.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover .ui5-sn-item-text, +.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus .ui5-sn-item-text { + display: var(--_ui5_side_navigation_item_collapsed_hover_focus_display); +} + +.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover .ui5-sn-item-toggle-icon, +.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus .ui5-sn-item-toggle-icon { + display: var(--_ui5_side_navigation_item_collapsed_hover_focus_display); +} + +.ui5-sn-item[aria-expanded=false] + .ui5-sn-item-group { + display: none; +} + +.ui5-sn-item-level2 { + padding-inline-start: var(--_ui5_side_navigation_group_icon_width); +} + +.ui5-sn-item-text { + flex: 1; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + color: var(--sapList_TextColor); +} + +.ui5-sn-item-level1 .ui5-sn-item-text { + font-weight: var(--_ui5_side_navigation_group_text_weight); +} + +.ui5-sn-item-level1:not(:has(> .ui5-sn-item-icon)), +.ui5-sn-item-level1.ui5-sn-item-selected:not(:has(> .ui5-sn-item-icon)) { + padding-inline-start: var(--_ui5_side_navigation_item_padding_left); +} + +.ui5-sn-item-with-expander .ui5-sn-item-icon::after { + display: var(--_ui5_side_navigation_triangle_display); + content: ""; + width: 0; + height: 0; + border-left: 0.375rem solid transparent; + border-bottom: 0.375rem solid var(--_ui5_side_navigation_triangle_color); + position: absolute; + right: 0.1875rem; + bottom: 0.125rem; +} + +.ui5-sn-item-selection-icon { + display: none; + height: 0.5rem; + width: 0.5rem; + margin-inline: 0.5rem; + color: var(--sapList_SelectionBorderColor); +} + +.ui5-sn-item[aria-expanded] .ui5-sn-item-selection-icon { + margin-inline: 0.5rem 0; +} + +.ui5-sn-root:not(.ui5-sn-collapsed) .ui5-sn-item:not([aria-expanded]) { + padding-inline-end: var(--_ui5_side_navigation_item_padding_right); +} + +.ui5-sn-item-selected .ui5-sn-item-selection-icon { + display: var(--_ui5_side_navigation_selection_indicator_display); +} + +.ui5-sn-in-popover .ui5-sn-list { + padding: var(--_ui5_side_navigation_parent_popup_padding); +} + +.ui5-sn-in-popover .ui5-sn-item { + padding: var(--_ui5_side_navigation_popup_item_padding); + width: auto; +} + +.ui5-sn-in-popover .ui5-sn-item-level1 { + margin-bottom: var(--_ui5_side_navigation_group_bottom_margin_in_popup); +} + +.ui5-sn-in-popover .ui5-sn-item-level1 .ui5-sn-item-text { + margin: 0 1rem 0 0; + font-size: var(--_ui5_side_navigation_popup_title_text_size); + line-height: var(--_ui5_side_navigation_popup_title_line_height); +} + +.ui5-sn-item.ui5-sn-item-level1.ui5-sn-item-overflow { + margin-top: auto; +} \ No newline at end of file From d7de1611cddd783908d760c358df84ab8363a1d2 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Mon, 12 Feb 2024 16:23:26 +0200 Subject: [PATCH 08/44] feat(ui5-side-navigation): refactor rendering --- packages/fiori/src/SideNavigationGroup.ts | 4 ++-- packages/fiori/src/SideNavigationItemBase.ts | 10 +++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts index 3a6b0b5d9ec9..8c1abc352ac4 100644 --- a/packages/fiori/src/SideNavigationGroup.ts +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -9,7 +9,7 @@ import SideNavigationItem from "./SideNavigationItem.js"; import SideNavigationGroupTemplate from "./generated/templates/SideNavigationGroupTemplate.lit.js"; // Styles -import SideNavigationCss from "./generated/themes/SideNavigation.css.js"; +import SideNavigationItemCss from "./generated/themes/SideNavigationItem.css.js"; /** * @class @@ -32,7 +32,7 @@ import SideNavigationCss from "./generated/themes/SideNavigation.css.js"; tag: "ui5-side-navigation-group", renderer: litRender, template: SideNavigationGroupTemplate, - styles: SideNavigationCss, + styles: SideNavigationItemCss, dependencies: [ Icon, ], diff --git a/packages/fiori/src/SideNavigationItemBase.ts b/packages/fiori/src/SideNavigationItemBase.ts index f0c53c8e7f84..aec5f27ce371 100644 --- a/packages/fiori/src/SideNavigationItemBase.ts +++ b/packages/fiori/src/SideNavigationItemBase.ts @@ -18,7 +18,7 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { constructor() { super(); - this.sideNavExpanded = true; + // this.sideNavExpanded = true; } /** * Defines the text of the item. @@ -53,8 +53,8 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { @property({ defaultValue: "-1", noAttribute: true }) forcedTabIndex!: string; - @property({ type: Boolean, noAttribute: true }) - sideNavExpanded!: boolean; + // @property({ type: Boolean, noAttribute: true }) + // sideNavExpanded!: boolean; get _tooltip() { return this.title || this.text; @@ -82,6 +82,10 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { return this.forcedTabIndex; } + get sideNavExpanded() { + return !this.sideNavigation?.collapsed; + } + get sideNavigation() : SideNavigation | undefined { let parentElement = this.parentElement; From ca76b07b5ad01ba8cd4ec7c2f2c9573ed96ef112 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Tue, 13 Feb 2024 14:16:13 +0200 Subject: [PATCH 09/44] feat(ui5-side-navigation): refactor rendering --- packages/fiori/src/SideNavigation.ts | 26 +++++++++++- packages/fiori/src/SideNavigationGroup.hbs | 6 +-- packages/fiori/src/SideNavigationGroup.ts | 12 +++++- packages/fiori/src/SideNavigationItem.hbs | 6 +-- packages/fiori/src/SideNavigationItem.ts | 17 +++++--- packages/fiori/src/SideNavigationItemBase.ts | 13 +----- packages/fiori/src/SideNavigationSubItem.hbs | 4 +- .../fiori/src/themes/SideNavigationItem.css | 40 +++++++++---------- 8 files changed, 76 insertions(+), 48 deletions(-) diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index 9607a3b903c2..811fff93332a 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -159,7 +159,7 @@ class SideNavigation extends UI5Element { * * @public */ - @slot({ type: HTMLElement, invalidateOnChildChange: true, "default": true }) + @slot({ type: HTMLElement, "default": true }) items!: Array; /** @@ -170,7 +170,7 @@ class SideNavigation extends UI5Element { * * @public */ - @slot({ type: HTMLElement, invalidateOnChildChange: true }) + @slot({ type: HTMLElement }) fixedItems!: Array; /** @@ -229,6 +229,18 @@ class SideNavigation extends UI5Element { _handleResizeBound: () => void; + onBeforeRendering() { + super.onBeforeRendering(); + + this._getAllItems(this.items).forEach(item => { + item.sideNavCollapsed = this.collapsed; + }); + + this._getAllItems(this.fixedItems).forEach(item => { + item.sideNavCollapsed = this.collapsed; + }); + } + async _onAfterPopoverOpen() { // as the tree/list inside the popover is never destroyed, // item navigation index should be managed, because items are @@ -588,6 +600,16 @@ class SideNavigation extends UI5Element { return result; } + _getAllItems(items: Array) : Array { + let result = new Array(); + + items.forEach(item => { + result = result.concat(item.allItems); + }); + + return result; + } + _findSelectedItem(items: Array) : SideNavigationSelectableItemBase | undefined { let selectedItem; diff --git a/packages/fiori/src/SideNavigationGroup.hbs b/packages/fiori/src/SideNavigationGroup.hbs index 403feaf01750..74d367803da0 100644 --- a/packages/fiori/src/SideNavigationGroup.hbs +++ b/packages/fiori/src/SideNavigationGroup.hbs @@ -1,7 +1,7 @@ -{{#if sideNavExpanded}} - {{> treeitem }} -{{else}} +{{#if sideNavCollapsed}}
    +{{else}} + {{> treeitem }} {{/if}} {{#*inline treeitem}} diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts index 8c1abc352ac4..519db2fab6bb 100644 --- a/packages/fiori/src/SideNavigationGroup.ts +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -52,7 +52,7 @@ class SideNavigationGroup extends SideNavigationItemBase { * * @public */ - @slot({ type: HTMLElement, invalidateOnChildChange: true, "default": true }) + @slot({ type: HTMLElement, "default": true }) items!: Array; get selectableItems() : Array { @@ -63,6 +63,16 @@ class SideNavigationGroup extends SideNavigationItemBase { return [this, ...this.items]; } + get allItems() : Array { + let result = new Array(this); + + this.items.forEach(item => { + result = result.concat(item.allItems); + }); + + return result; + } + get isFixedItem() { return this.slot === "fixedItems"; } diff --git a/packages/fiori/src/SideNavigationItem.hbs b/packages/fiori/src/SideNavigationItem.hbs index 983fe742306e..99ad1d052bbc 100644 --- a/packages/fiori/src/SideNavigationItem.hbs +++ b/packages/fiori/src/SideNavigationItem.hbs @@ -1,7 +1,7 @@ -{{#if sideNavExpanded}} - {{> treeitem }} -{{else}} +{{#if sideNavCollapsed}} {{> menuitem }} +{{else}} + {{> treeitem }} {{/if}} {{#*inline menuitem}} diff --git a/packages/fiori/src/SideNavigationItem.ts b/packages/fiori/src/SideNavigationItem.ts index dee8bc0c2856..ab2cc4e15779 100644 --- a/packages/fiori/src/SideNavigationItem.ts +++ b/packages/fiori/src/SideNavigationItem.ts @@ -4,6 +4,7 @@ import property from "@ui5/webcomponents-base/dist/decorators/property.js"; import slot from "@ui5/webcomponents-base/dist/decorators/slot.js"; import { isLeft, isRight } from "@ui5/webcomponents-base/dist/Keys.js"; import Icon from "@ui5/webcomponents/dist/Icon.js"; +import SideNavigationItemBase from "./SideNavigationItemBase.js"; import SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase.js"; import type SideNavigation from "./SideNavigation.js"; import type SideNavigationSubItem from "./SideNavigationSubItem.js"; @@ -64,7 +65,7 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { * * @public */ - @slot({ type: HTMLElement, invalidateOnChildChange: true, "default": true }) + @slot({ type: HTMLElement, "default": true }) items!: Array; /** @@ -87,6 +88,10 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { return [this]; } + get allItems() : Array { + return [this, ...this.items]; + } + get _ariaHasPopup() { if (!this.disabled && (this.parentNode as SideNavigation).collapsed && this.items.length) { return "tree"; @@ -130,7 +135,7 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { } get _selected() { - if (this.sideNavigation?.collapsed) { + if (this.sideNavCollapsed) { return this.selected || this.items.some(item => item.selected); } @@ -170,7 +175,7 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { } _onclick = (e: PointerEvent) => { - if (!this.sideNavigation?.collapsed + if (!this.sideNavCollapsed && this.wholeItemToggleable && e.pointerType === "mouse") { e.preventDefault(); @@ -183,7 +188,7 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { } _onfocusout = () => { - if (!this.sideNavigation?.collapsed) { + if (!this.sideNavCollapsed) { return; } @@ -191,7 +196,7 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { } _onmouseenter = () => { - if (!this.sideNavigation?.collapsed) { + if (!this.sideNavCollapsed) { return; } @@ -199,7 +204,7 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { } _onmouseleave = () => { - if (!this.sideNavigation?.collapsed || !this._selected) { + if (!this.sideNavCollapsed || !this._selected) { return; } diff --git a/packages/fiori/src/SideNavigationItemBase.ts b/packages/fiori/src/SideNavigationItemBase.ts index aec5f27ce371..4f21e4b3a6b5 100644 --- a/packages/fiori/src/SideNavigationItemBase.ts +++ b/packages/fiori/src/SideNavigationItemBase.ts @@ -15,11 +15,6 @@ import type SideNavigation from "./SideNavigation.js"; * @since 1.19.0 */ class SideNavigationItemBase extends UI5Element implements ITabbable { - constructor() { - super(); - - // this.sideNavExpanded = true; - } /** * Defines the text of the item. * @@ -53,8 +48,8 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { @property({ defaultValue: "-1", noAttribute: true }) forcedTabIndex!: string; - // @property({ type: Boolean, noAttribute: true }) - // sideNavExpanded!: boolean; + @property({ type: Boolean }) + sideNavCollapsed!: boolean; get _tooltip() { return this.title || this.text; @@ -82,10 +77,6 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { return this.forcedTabIndex; } - get sideNavExpanded() { - return !this.sideNavigation?.collapsed; - } - get sideNavigation() : SideNavigation | undefined { let parentElement = this.parentElement; diff --git a/packages/fiori/src/SideNavigationSubItem.hbs b/packages/fiori/src/SideNavigationSubItem.hbs index 41b9827700c9..5de111856578 100644 --- a/packages/fiori/src/SideNavigationSubItem.hbs +++ b/packages/fiori/src/SideNavigationSubItem.hbs @@ -1,4 +1,4 @@ -{{#if sideNavExpanded}} +{{#unless sideNavCollapsed}}
  • {{#if _href}} {{/if}}
  • -{{/if}} \ No newline at end of file +{{/unless}} \ No newline at end of file diff --git a/packages/fiori/src/themes/SideNavigationItem.css b/packages/fiori/src/themes/SideNavigationItem.css index c8a84127cbd6..a0308ac0100a 100644 --- a/packages/fiori/src/themes/SideNavigationItem.css +++ b/packages/fiori/src/themes/SideNavigationItem.css @@ -97,12 +97,12 @@ .ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected.ui5-sn-item-active, .ui5-sn-item:not(.ui5-sn-item-disabled):active, .ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-active, -.ui5-sn-collapsed .ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected:active, -.ui5-sn-collapsed .ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected.ui5-sn-item-active { +:host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected:active, +:host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected.ui5-sn-item-active { background: var(--sapList_Active_Background); } -.ui5-sn-collapsed .ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected { +:host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected { background: var(--_ui5_side_navigation_collapsed_selected_item_background); } @@ -111,7 +111,7 @@ border-width: var(--_ui5_side_navigation_item_border_width); } -.ui5-sn-collapsed .ui5-sn-item::before { +:host([side-nav-collapsed]) .ui5-sn-item::before { border-width: var(--_ui5_side_navigation_item_border_width); } @@ -130,7 +130,7 @@ border-width: var(--_ui5_side_navigation_item_border_width); } -.ui5-sn-collapsed .ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected::before { +:host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-disabled).ui5-sn-item-selected::before { border-radius: var(--_ui5_side_navigation_item_border_radius); } @@ -154,46 +154,46 @@ display: none; } -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item { +:host([side-nav-collapsed]) .ui5-sn-item { justify-content: center; } -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item-icon { +:host([side-nav-collapsed]) .ui5-sn-item-icon { padding: var(--_ui5_side_navigation_item_collapsed_icon_padding); } -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item-text { +:host([side-nav-collapsed]) .ui5-sn-item-text { display: none; } -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item-toggle-icon { +:host([side-nav-collapsed]) .ui5-sn-item-toggle-icon { display: none; } -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover, -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus { +:host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover, +:host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus { width: var(--_ui5_side_navigation_item_collapsed_hover_focus_width); box-shadow: var(--_ui5_side_navigation_box_shadow); z-index: 1; } -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item.ui5-sn-item-selected:hover, -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item.ui5-sn-item-selected:focus { +:host([side-nav-collapsed]) .ui5-sn-item.ui5-sn-item-selected:hover, +:host([side-nav-collapsed]) .ui5-sn-item.ui5-sn-item-selected:focus { background: var(--sapList_SelectionBackgroundColor); } -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover:not(.ui5-sn-item-with-expander), -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus:not(.ui5-sn-item-with-expander) { +:host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover:not(.ui5-sn-item-with-expander), +:host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus:not(.ui5-sn-item-with-expander) { padding-right: var(--_ui5_side_navigation_item_collapsed_hover_focus_padding_right); } -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover .ui5-sn-item-text, -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus .ui5-sn-item-text { +:host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover .ui5-sn-item-text, +:host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus .ui5-sn-item-text { display: var(--_ui5_side_navigation_item_collapsed_hover_focus_display); } -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover .ui5-sn-item-toggle-icon, -.ui5-sn-collapsed .ui5-sn-list .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus .ui5-sn-item-toggle-icon { +:host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover .ui5-sn-item-toggle-icon, +:host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus .ui5-sn-item-toggle-icon { display: var(--_ui5_side_navigation_item_collapsed_hover_focus_display); } @@ -247,7 +247,7 @@ margin-inline: 0.5rem 0; } -.ui5-sn-root:not(.ui5-sn-collapsed) .ui5-sn-item:not([aria-expanded]) { +:host([side-nav-collapsed]) .ui5-sn-item:not([aria-expanded]) { padding-inline-end: var(--_ui5_side_navigation_item_padding_right); } From 93b9cb9c805929bf74ef7095eb6e49248746de38 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Tue, 13 Feb 2024 15:04:32 +0200 Subject: [PATCH 10/44] feat(ui5-side-navigation): refactor rendering --- packages/fiori/src/SideNavigation.ts | 2 +- packages/fiori/src/SideNavigationGroup.ts | 4 ---- packages/fiori/src/SideNavigationItem.ts | 4 ---- packages/fiori/src/SideNavigationItemBase.ts | 14 +++++++++++++- packages/fiori/src/SideNavigationSubItem.ts | 4 ---- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index 811fff93332a..10fd1d47b139 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -593,7 +593,7 @@ class SideNavigation extends UI5Element { result.push(item); if (item.expanded) { - result = result.concat(item.items); + result = result.concat(item.focusableItems); } }); diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts index 519db2fab6bb..44fe21134018 100644 --- a/packages/fiori/src/SideNavigationGroup.ts +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -73,10 +73,6 @@ class SideNavigationGroup extends SideNavigationItemBase { return result; } - get isFixedItem() { - return this.slot === "fixedItems"; - } - get _groupId() { if (!this.items.length) { return undefined; diff --git a/packages/fiori/src/SideNavigationItem.ts b/packages/fiori/src/SideNavigationItem.ts index ab2cc4e15779..dbce0bc6a09c 100644 --- a/packages/fiori/src/SideNavigationItem.ts +++ b/packages/fiori/src/SideNavigationItem.ts @@ -142,10 +142,6 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { return this.selected; } - get isFixedItem() { - return this.slot === "fixedItems"; - } - _onToggleClick = (e: PointerEvent) => { e.stopPropagation(); diff --git a/packages/fiori/src/SideNavigationItemBase.ts b/packages/fiori/src/SideNavigationItemBase.ts index 4f21e4b3a6b5..21a435e7bd6e 100644 --- a/packages/fiori/src/SideNavigationItemBase.ts +++ b/packages/fiori/src/SideNavigationItemBase.ts @@ -90,7 +90,19 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { } get isFixedItem() { - return true; + let element : HTMLElement = this; // eslint-disable-line + let parentElement = element.parentElement; + + while (parentElement) { + if (parentElement.hasAttribute("ui5-side-navigation")) { + break; + } + + element = parentElement; + parentElement = element.parentElement; + } + + return element?.slot === "fixedItems"; } } diff --git a/packages/fiori/src/SideNavigationSubItem.ts b/packages/fiori/src/SideNavigationSubItem.ts index 0da5c8efcc41..7142de31dc28 100644 --- a/packages/fiori/src/SideNavigationSubItem.ts +++ b/packages/fiori/src/SideNavigationSubItem.ts @@ -34,10 +34,6 @@ import SideNavigationItemCss from "./generated/themes/SideNavigationItem.css.js" ], }) class SideNavigationSubItem extends SideNavigationSelectableItemBase { - get isFixedItem() { - return this.parentElement?.slot === "fixedItems"; - } - _onkeydown = (e: KeyboardEvent) => { super._onkeydown(e); } From 68d5107403bc6c34cbe93332fbfa1ebf13a7e277 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Tue, 13 Feb 2024 15:29:27 +0200 Subject: [PATCH 11/44] feat(ui5-side-navigation): refactor rendering --- packages/fiori/src/SideNavigationItem.hbs | 20 +++++++++++++++++++ packages/fiori/src/SideNavigationItemBase.ts | 4 ---- .../src/SideNavigationSelectableItemBase.ts | 4 ++++ .../fiori/src/themes/SideNavigationItem.css | 19 ++++++++++++++---- 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/packages/fiori/src/SideNavigationItem.hbs b/packages/fiori/src/SideNavigationItem.hbs index 99ad1d052bbc..50947d61e471 100644 --- a/packages/fiori/src/SideNavigationItem.hbs +++ b/packages/fiori/src/SideNavigationItem.hbs @@ -31,6 +31,11 @@ name="navigation-right-arrow" > {{/if}} + {{#if _isExternalLink}} + + {{/if}} {{else}}
    {{/if}} + {{#if _isExternalLink}} + + {{/if}}
    {{/if}} {{/inline}} @@ -91,6 +101,11 @@ @click="{{_onToggleClick}}" > {{/if}} + {{#if _isExternalLink}} + + {{/if}} {{else}}
    {{/if}} + {{#if _isExternalLink}} + + {{/if}}
    {{/if}} {{#if items.length}} diff --git a/packages/fiori/src/SideNavigationItemBase.ts b/packages/fiori/src/SideNavigationItemBase.ts index bbd725acc824..21a435e7bd6e 100644 --- a/packages/fiori/src/SideNavigationItemBase.ts +++ b/packages/fiori/src/SideNavigationItemBase.ts @@ -77,10 +77,6 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { return this.forcedTabIndex; } - get _isExternalLink() { - return this.href && this.target === "_blank"; - } - get sideNavigation() : SideNavigation | undefined { let parentElement = this.parentElement; diff --git a/packages/fiori/src/SideNavigationSelectableItemBase.ts b/packages/fiori/src/SideNavigationSelectableItemBase.ts index 41d651458391..4a4589fd757c 100644 --- a/packages/fiori/src/SideNavigationSelectableItemBase.ts +++ b/packages/fiori/src/SideNavigationSelectableItemBase.ts @@ -90,6 +90,10 @@ class SideNavigationSelectableItemBase extends SideNavigationItemBase { return (!this.disabled && this.target) ? this.target : undefined; } + get _isExternalLink() { + return this.href && this.target === "_blank"; + } + get _selected() { return this.selected; } diff --git a/packages/fiori/src/themes/SideNavigationItem.css b/packages/fiori/src/themes/SideNavigationItem.css index a0308ac0100a..56a4e5d253d7 100644 --- a/packages/fiori/src/themes/SideNavigationItem.css +++ b/packages/fiori/src/themes/SideNavigationItem.css @@ -144,13 +144,19 @@ min-width: var(--_ui5_side_navigation_group_icon_width); } -.ui5-sn-item-toggle-icon { +.ui5-sn-item-toggle-icon, +.ui5-sn-item-external-link-icon { color: var(--_ui5_side_navigation_expand_icon_color); min-width: 2rem; height: 0.875rem; } -.ui5-sn-item-fixed .ui5-sn-item-toggle-icon { +.ui5-sn-item-external-link-icon { + color: var(--_ui5_side_navigation_external_link_icon_color); +} + +.ui5-sn-item-fixed .ui5-sn-item-toggle-icon, +.ui5-sn-item-fixed .ui5-sn-item-external-link-icon { display: none; } @@ -166,7 +172,8 @@ display: none; } -:host([side-nav-collapsed]) .ui5-sn-item-toggle-icon { +:host([side-nav-collapsed]) .ui5-sn-item-toggle-icon, +:host([side-nav-collapsed]) .ui5-sn-item-external-link-icon { display: none; } @@ -188,7 +195,11 @@ } :host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover .ui5-sn-item-text, -:host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus .ui5-sn-item-text { +:host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus .ui5-sn-item-text, +:host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover .ui5-sn-item-toggle-icon, +:host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover .ui5-sn-item-external-link-icon, +:host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus .ui5-sn-item-toggle-icon, +:host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus .ui5-sn-item-external-link-icon { display: var(--_ui5_side_navigation_item_collapsed_hover_focus_display); } From 076f399e0ee56183b37bc245bacbd4490a32c42e Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Wed, 14 Feb 2024 13:51:17 +0200 Subject: [PATCH 12/44] feat(ui5-side-navigation): overflow items --- packages/fiori/src/SideNavigation.ts | 23 ++++++++++++++----- .../fiori/src/themes/SideNavigationItem.css | 4 +++- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index 10fd1d47b139..0ae49a335af5 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -416,7 +416,7 @@ class SideNavigation extends UI5Element { let result = new Array(); this._getFocusableItems(items).forEach(item => { - if (item.getDomRef()?.classList.contains("ui5-sn-item-hidden")) { + if (item.classList.contains("ui5-sn-item-hidden")) { return; } @@ -509,7 +509,7 @@ class SideNavigation extends UI5Element { overflowItemRef.classList.add("ui5-sn-item-hidden"); - const itemsRefs = [...domRef.querySelectorAll(".ui5-sn-flexible .ui5-sn-item-level1:not(.ui5-sn-item-overflow)")]; + const itemsRefs = this.flexibleItems; let itemsHeight = itemsRefs.reduce((sum, itemRef) => { itemRef.classList.remove("ui5-sn-item-hidden"); @@ -622,6 +622,16 @@ class SideNavigation extends UI5Element { return selectedItem; } + get flexibleItems() : Array { + let result = new Array(); + + this.items.forEach(item => { + result = result.concat(item.selectableItems); + }); + + return result; + } + _handleItemClick(e: KeyboardEvent | PointerEvent, item: SideNavigationSelectableItemBase) { if (item.selected && !this.collapsed) { item.fireEvent("click"); @@ -658,11 +668,12 @@ class SideNavigation extends UI5Element { const overflowClass = "ui5-sn-item-hidden"; const result: Array = []; - this._getSelectableItems(this.items).forEach(item => { - if (item.getDomRef()!.classList.contains(overflowClass)) { + this.flexibleItems.forEach(item => { + if (item.classList.contains(overflowClass)) { result.push(item); } }); + return result; } @@ -684,8 +695,8 @@ class SideNavigation extends UI5Element { item.selected = true; - if (this.collapsed && item.getDomRef()?.classList.contains("ui5-sn-item-hidden")) { - item.getDomRef()?.classList.remove("ui5-sn-item-hidden"); + if (this.collapsed && item.classList.contains("ui5-sn-item-hidden")) { + item.classList.remove("ui5-sn-item-hidden"); } } diff --git a/packages/fiori/src/themes/SideNavigationItem.css b/packages/fiori/src/themes/SideNavigationItem.css index 56a4e5d253d7..94b458211f85 100644 --- a/packages/fiori/src/themes/SideNavigationItem.css +++ b/packages/fiori/src/themes/SideNavigationItem.css @@ -21,9 +21,11 @@ margin-block-end: var(--_ui5_side_navigation_item_bottom_margin); } -.ui5-sn-item-hidden { + +:host(.ui5-sn-item-hidden[side-nav-collapsed]) { display: none; } + .ui5-sn-item:focus { outline: none; } From faced76660a5d196ff87d8a5c38f5bcdda4b19b3 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Thu, 15 Feb 2024 10:41:46 +0200 Subject: [PATCH 13/44] feat(ui5-side-navigation): overflow item --- packages/fiori/src/SideNavigation.hbs | 31 +++++++-------------------- packages/fiori/src/SideNavigation.ts | 14 ++++++------ 2 files changed, 16 insertions(+), 29 deletions(-) diff --git a/packages/fiori/src/SideNavigation.hbs b/packages/fiori/src/SideNavigation.hbs index cbb52874ea6e..d557829e687c 100644 --- a/packages/fiori/src/SideNavigation.hbs +++ b/packages/fiori/src/SideNavigation.hbs @@ -8,7 +8,14 @@ aria-roledescription="{{ariaRoleDescNavigationList}}" > - {{> overflowItem}} + +
    {{else}}
      {{/if}} {{/inline}} - -{{#*inline overflowItem}} - -{{/inline}} diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index 0ae49a335af5..a2f1f889e1ab 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -121,6 +121,7 @@ type NavigationMenuClickEventDetail = { staticAreaStyles: SideNavigationPopoverCss, dependencies: [ ResponsivePopover, + SideNavigationGroup, SideNavigationItem, SideNavigationSubItem, Icon, @@ -405,11 +406,11 @@ class SideNavigation extends UI5Element { } getEnabledFlexibleItems() : Array { - if (!this._overflowDom) { + if (!this._overflowItem) { return this.getEnabledItems(this.items); } - return [...this.getEnabledItems(this.items), this._overflowDom]; + return [...this.getEnabledItems(this.items), this._overflowItem]; } getEnabledItems(items: Array) : Array { @@ -467,6 +468,7 @@ class SideNavigation extends UI5Element { } } } + if (this.collapsed) { this.handleResize(); } @@ -501,8 +503,8 @@ class SideNavigation extends UI5Element { return null; } - const overflowItemRef:HTMLElement = domRef.querySelector(".ui5-sn-item-overflow")!; - const flexibleContentDomRef:HTMLElement = domRef.querySelector(".ui5-sn-flexible")!; + const overflowItemRef = this._overflowItem!; + const flexibleContentDomRef : HTMLElement = domRef.querySelector(".ui5-sn-flexible")!; if (!overflowItemRef) { return null; } @@ -661,7 +663,7 @@ class SideNavigation extends UI5Element { this._isOverflow = true; this._menuPopoverItems = this._getOverflowItems(); - this.openOverflowMenu(this._overflowDom as HTMLElement); + this.openOverflowMenu(this._overflowItem as HTMLElement); } _getOverflowItems(): Array { @@ -700,7 +702,7 @@ class SideNavigation extends UI5Element { } } - get _overflowDom() { + get _overflowItem() { return this.shadowRoot!.querySelector(".ui5-sn-item-overflow"); } From eaf8d349eb34f4e5acffe9f89213221190df7c98 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Thu, 15 Feb 2024 15:28:54 +0200 Subject: [PATCH 14/44] feat(ui5-side-navigation): selection --- packages/fiori/src/SideNavigation.ts | 103 ++++--------------- packages/fiori/src/SideNavigationGroup.ts | 47 +++++++-- packages/fiori/src/SideNavigationItem.hbs | 20 ++-- packages/fiori/src/SideNavigationItem.ts | 18 +++- packages/fiori/src/SideNavigationSubItem.hbs | 10 ++ 5 files changed, 92 insertions(+), 106 deletions(-) diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index a2f1f889e1ab..0f958d5ee55f 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -424,10 +424,6 @@ class SideNavigation extends UI5Element { if (!item.disabled) { result.push(item); } - - if (!this.collapsed && item.expanded) { - result = result.concat(item.items.filter(el => !el.disabled)); - } }); return result; @@ -546,92 +542,35 @@ class SideNavigation extends UI5Element { } _findFocusedItem(items: Array) : SideNavigationItemBase | undefined { - let focusedItem; - - if (this.collapsed) { - focusedItem = items.find(item => item.forcedTabIndex === "0"); - } else { - focusedItem = this._getAllFocusableItems(items).find(item => item.forcedTabIndex === "0"); - } - - return focusedItem; + return this._getFocusableItems(items).find(item => item.forcedTabIndex === "0"); } - _getSelectableItems(items: Array) : Array { - let result = new Array(); - - items.forEach(item => { - result = result.concat(item.selectableItems); - }); - - return result; - } - - _getAllSelectableItems(items: Array): Array { - let result = new Array(); - - this._getSelectableItems(items).forEach(item => { - result.push(item); - result = result.concat(item.items); - }); - - return result; - } - - _getFocusableItems(items: Array) : Array { - let result = new Array(); - - items.forEach(item => { - result = result.concat(item.focusableItems); - }); - - return result; + _getSelectableItems(items: Array) : Array { + return items.reduce((result, item) => { + return result.concat(item.selectableItems); + }, new Array()); } - _getAllFocusableItems(items: Array): Array { - let result = new Array(); - - items.forEach(item => { - result.push(item); - - if (item.expanded) { - result = result.concat(item.focusableItems); - } - }); - - return result; + _getFocusableItems(items: Array) : Array { + return items.reduce((result, item) => { + return result.concat(item.focusableItems); + }, new Array()); } _getAllItems(items: Array) : Array { - let result = new Array(); - - items.forEach(item => { - result = result.concat(item.allItems); - }); - - return result; + return items.reduce((result, item) => { + return result.concat(item.allItems); + }, new Array()); } _findSelectedItem(items: Array) : SideNavigationSelectableItemBase | undefined { - let selectedItem; - - if (this.collapsed) { - selectedItem = this._getSelectableItems(items).find(item => item._selected); - } else { - selectedItem = this._getAllSelectableItems(items).find(current => current.selected); - } - - return selectedItem; + return this._getSelectableItems(items).find(item => item._selected); } - get flexibleItems() : Array { - let result = new Array(); - - this.items.forEach(item => { - result = result.concat(item.selectableItems); - }); - - return result; + get flexibleItems() : Array { + return this.items.reduce((result, item) => { + return result.concat(item.overflowItems); + }, new Array()); } _handleItemClick(e: KeyboardEvent | PointerEvent, item: SideNavigationSelectableItemBase) { @@ -666,9 +605,9 @@ class SideNavigation extends UI5Element { this.openOverflowMenu(this._overflowItem as HTMLElement); } - _getOverflowItems(): Array { + _getOverflowItems(): Array { const overflowClass = "ui5-sn-item-hidden"; - const result: Array = []; + const result: Array = []; this.flexibleItems.forEach(item => { if (item.classList.contains(overflowClass)) { @@ -688,8 +627,8 @@ class SideNavigation extends UI5Element { return; } - let items = this._getAllSelectableItems(this.items); - items = items.concat(this._getAllSelectableItems(this.fixedItems)); + let items = this._getSelectableItems(this.items); + items = items.concat(this._getSelectableItems(this.fixedItems)); items.forEach(current => { current.selected = false; diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts index 44fe21134018..c94d546fc76d 100644 --- a/packages/fiori/src/SideNavigationGroup.ts +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -1,7 +1,7 @@ import property from "@ui5/webcomponents-base/dist/decorators/property.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; import slot from "@ui5/webcomponents-base/dist/decorators/slot.js"; -import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; +import { isSpace, isEnter, isLeft, isRight } from "@ui5/webcomponents-base/dist/Keys.js"; import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; import Icon from "@ui5/webcomponents/dist/Icon.js"; import SideNavigationItemBase from "./SideNavigationItemBase.js"; @@ -10,6 +10,7 @@ import SideNavigationGroupTemplate from "./generated/templates/SideNavigationGro // Styles import SideNavigationItemCss from "./generated/themes/SideNavigationItem.css.js"; +import SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase"; /** * @class @@ -55,22 +56,36 @@ class SideNavigationGroup extends SideNavigationItemBase { @slot({ type: HTMLElement, "default": true }) items!: Array; - get selectableItems() : Array { - return this.items; + get overflowItems() : Array { + return this.items.reduce((result, item) => { + return result.concat(item.overflowItems); + }, new Array()); } - get focusableItems() : Array { - return [this, ...this.items]; + get selectableItems() : Array { + return this.items.reduce((result, item) => { + return result.concat(item.selectableItems); + }, new Array()); } - get allItems() : Array { - let result = new Array(this); + get focusableItems() : Array { + if (this.sideNavCollapsed) { + return this.items; + } - this.items.forEach(item => { - result = result.concat(item.allItems); - }); + if (this.expanded) { + return this.items.reduce((result, item) => { + return result.concat(item.focusableItems); + }, new Array(this)); + } + + return [this]; + } - return result; + get allItems() : Array { + return this.items.reduce((result, item) => { + return result.concat(item.allItems); + }, new Array(this)); } get _groupId() { @@ -94,6 +109,16 @@ class SideNavigationGroup extends SideNavigationItemBase { } _onkeydown = (e: KeyboardEvent) => { + if (isLeft(e)) { + this.expanded = false; + return; + } + + if (isRight(e)) { + this.expanded = true; + return; + } + if (isSpace(e)) { e.preventDefault(); } diff --git a/packages/fiori/src/SideNavigationItem.hbs b/packages/fiori/src/SideNavigationItem.hbs index 50947d61e471..e0ab0473254c 100644 --- a/packages/fiori/src/SideNavigationItem.hbs +++ b/packages/fiori/src/SideNavigationItem.hbs @@ -95,17 +95,17 @@ + {{#if _isExternalLink}} + + {{/if}} {{#if items.length}} {{/if}} - {{#if _isExternalLink}} - - {{/if}} {{else}}
      + {{#if _isExternalLink}} + + {{/if}} {{#if items.length}} {{/if}} - {{#if _isExternalLink}} - - {{/if}}
      {{/if}} {{#if items.length}} diff --git a/packages/fiori/src/SideNavigationItem.ts b/packages/fiori/src/SideNavigationItem.ts index dbce0bc6a09c..edac97f3991c 100644 --- a/packages/fiori/src/SideNavigationItem.ts +++ b/packages/fiori/src/SideNavigationItem.ts @@ -80,11 +80,23 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { @property({ type: Boolean }) wholeItemToggleable!: boolean; - get selectableItems() : Array { + get overflowItems() : Array { return [this]; } - get focusableItems() : Array { + get selectableItems() : Array { + return [this, ...this.items]; + } + + get focusableItems() : Array { + if (this.sideNavCollapsed) { + return [this]; + } + + if (this.expanded) { + return [this, ...this.items]; + } + return [this]; } @@ -93,7 +105,7 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { } get _ariaHasPopup() { - if (!this.disabled && (this.parentNode as SideNavigation).collapsed && this.items.length) { + if (!this.disabled && this.sideNavCollapsed && this.items.length) { return "tree"; } diff --git a/packages/fiori/src/SideNavigationSubItem.hbs b/packages/fiori/src/SideNavigationSubItem.hbs index 5de111856578..d8f0b8964e94 100644 --- a/packages/fiori/src/SideNavigationSubItem.hbs +++ b/packages/fiori/src/SideNavigationSubItem.hbs @@ -21,6 +21,11 @@ + {{#if _isExternalLink}} + + {{/if}} {{else}}
      + {{#if _isExternalLink}} + + {{/if}}
      {{/if}} From 179e5b156cc8d86b462fc1240930a7165b2cfada Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Thu, 15 Feb 2024 15:31:47 +0200 Subject: [PATCH 15/44] feat(ui5-side-navigation): invalidation flow --- packages/fiori/src/SideNavigation.ts | 4 ++-- packages/fiori/src/SideNavigationGroup.ts | 2 +- packages/fiori/src/SideNavigationItem.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index 0f958d5ee55f..98e6aa71a265 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -160,7 +160,7 @@ class SideNavigation extends UI5Element { * * @public */ - @slot({ type: HTMLElement, "default": true }) + @slot({ type: HTMLElement, invalidateOnChildChange: true, "default": true }) items!: Array; /** @@ -171,7 +171,7 @@ class SideNavigation extends UI5Element { * * @public */ - @slot({ type: HTMLElement }) + @slot({ type: HTMLElement, invalidateOnChildChange: true }) fixedItems!: Array; /** diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts index c94d546fc76d..649bcb54d69c 100644 --- a/packages/fiori/src/SideNavigationGroup.ts +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -53,7 +53,7 @@ class SideNavigationGroup extends SideNavigationItemBase { * * @public */ - @slot({ type: HTMLElement, "default": true }) + @slot({ type: HTMLElement, invalidateOnChildChange: true, "default": true }) items!: Array; get overflowItems() : Array { diff --git a/packages/fiori/src/SideNavigationItem.ts b/packages/fiori/src/SideNavigationItem.ts index edac97f3991c..4957f702c03e 100644 --- a/packages/fiori/src/SideNavigationItem.ts +++ b/packages/fiori/src/SideNavigationItem.ts @@ -65,7 +65,7 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { * * @public */ - @slot({ type: HTMLElement, "default": true }) + @slot({ type: HTMLElement, invalidateOnChildChange: true, "default": true }) items!: Array; /** From 8cc1cad8fb043a1e2f6686cbfc6acf215cf06202 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Thu, 15 Feb 2024 16:06:46 +0200 Subject: [PATCH 16/44] feat(ui5-side-navigation): fix lint errors --- packages/fiori/src/SideNavigation.ts | 2 +- packages/fiori/src/SideNavigationGroup.ts | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index 98e6aa71a265..0e99e0839946 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -414,7 +414,7 @@ class SideNavigation extends UI5Element { } getEnabledItems(items: Array) : Array { - let result = new Array(); + const result = new Array(); this._getFocusableItems(items).forEach(item => { if (item.classList.contains("ui5-sn-item-hidden")) { diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts index 649bcb54d69c..1d685cfbe020 100644 --- a/packages/fiori/src/SideNavigationGroup.ts +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -1,16 +1,21 @@ import property from "@ui5/webcomponents-base/dist/decorators/property.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; import slot from "@ui5/webcomponents-base/dist/decorators/slot.js"; -import { isSpace, isEnter, isLeft, isRight } from "@ui5/webcomponents-base/dist/Keys.js"; +import { + isSpace, + isEnter, + isLeft, + isRight, +} from "@ui5/webcomponents-base/dist/Keys.js"; import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; import Icon from "@ui5/webcomponents/dist/Icon.js"; import SideNavigationItemBase from "./SideNavigationItemBase.js"; +import SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase.js"; import SideNavigationItem from "./SideNavigationItem.js"; import SideNavigationGroupTemplate from "./generated/templates/SideNavigationGroupTemplate.lit.js"; // Styles import SideNavigationItemCss from "./generated/themes/SideNavigationItem.css.js"; -import SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase"; /** * @class From 782b160e64eeffbe489bfe3136c2a9409219bb0b Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Thu, 15 Feb 2024 17:36:25 +0200 Subject: [PATCH 17/44] feat(ui5-side-navigation): fixed selection --- packages/fiori/src/SideNavigation.ts | 13 ++++++------- packages/fiori/src/SideNavigationGroup.hbs | 1 + packages/fiori/src/themes/SideNavigation.css | 10 +++++----- .../fiori/test/pages/SideNavigationWithGroups.html | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index 0e99e0839946..cced068ff052 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -438,9 +438,8 @@ class SideNavigation extends UI5Element { } onAfterRendering() { - const activeElement = this.shadowRoot!.activeElement; - const flexibleDom = this.shadowRoot!.querySelector(".ui5-sn-flexible")!; - if (!flexibleDom.contains(activeElement)) { + const activeElement = document.activeElement as SideNavigationItemBase; + if (this._getAllItems(this.items).indexOf(activeElement) === -1) { const selectedItem = this._findSelectedItem(this.items); if (selectedItem) { this._flexibleItemNavigation.setCurrentItem(selectedItem); @@ -453,7 +452,7 @@ class SideNavigation extends UI5Element { } const fixedDom = this.shadowRoot!.querySelector(".ui5-sn-fixed"); - if (!fixedDom?.contains(activeElement)) { + if (this._getAllItems(this.fixedItems).indexOf(activeElement) === -1) { const selectedItem = this._findSelectedItem(this.fixedItems); if (selectedItem) { this._fixedItemNavigation.setCurrentItem(selectedItem); @@ -507,7 +506,7 @@ class SideNavigation extends UI5Element { overflowItemRef.classList.add("ui5-sn-item-hidden"); - const itemsRefs = this.flexibleItems; + const itemsRefs = this.overflowItems; let itemsHeight = itemsRefs.reduce((sum, itemRef) => { itemRef.classList.remove("ui5-sn-item-hidden"); @@ -567,7 +566,7 @@ class SideNavigation extends UI5Element { return this._getSelectableItems(items).find(item => item._selected); } - get flexibleItems() : Array { + get overflowItems() : Array { return this.items.reduce((result, item) => { return result.concat(item.overflowItems); }, new Array()); @@ -609,7 +608,7 @@ class SideNavigation extends UI5Element { const overflowClass = "ui5-sn-item-hidden"; const result: Array = []; - this.flexibleItems.forEach(item => { + this.overflowItems.forEach(item => { if (item.classList.contains(overflowClass)) { result.push(item); } diff --git a/packages/fiori/src/SideNavigationGroup.hbs b/packages/fiori/src/SideNavigationGroup.hbs index 74d367803da0..8c699f208e2a 100644 --- a/packages/fiori/src/SideNavigationGroup.hbs +++ b/packages/fiori/src/SideNavigationGroup.hbs @@ -1,5 +1,6 @@ {{#if sideNavCollapsed}}
      + {{else}} {{> treeitem }} {{/if}} diff --git a/packages/fiori/src/themes/SideNavigation.css b/packages/fiori/src/themes/SideNavigation.css index 54118e96102c..83e278ab8be8 100644 --- a/packages/fiori/src/themes/SideNavigation.css +++ b/packages/fiori/src/themes/SideNavigation.css @@ -6,6 +6,10 @@ max-width: 100%; transition: width 0.3s, min-width 0.3s; border-radius: var(--_ui5_side_navigation_border_radius); + box-shadow: var(--_ui5_side_navigation_box_shadow); + font-family: "72override", var(--sapFontFamily); + font-size: var(--sapFontSize); + background: var(--sapList_Background); } :host([collapsed]) { @@ -22,12 +26,8 @@ display: flex; flex-direction: column; box-sizing: border-box; - font-family: "72override", var(--sapFontFamily); - font-size: var(--sapFontSize); - background: var(--sapList_Background); - border-inline-end: var(--_ui5_side_navigation_border_right); - box-shadow: var(--_ui5_side_navigation_box_shadow); border-radius: inherit; + border-inline-end: var(--_ui5_side_navigation_border_right); } .ui5-sn-spacer { diff --git a/packages/fiori/test/pages/SideNavigationWithGroups.html b/packages/fiori/test/pages/SideNavigationWithGroups.html index 5916b400d074..45a03662881a 100644 --- a/packages/fiori/test/pages/SideNavigationWithGroups.html +++ b/packages/fiori/test/pages/SideNavigationWithGroups.html @@ -20,10 +20,10 @@ - + - + From 8238b6a63e045e33bf5f688f861ee7b8421136eb Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Thu, 15 Feb 2024 17:40:02 +0200 Subject: [PATCH 18/44] feat(ui5-side-navigation): fixe lint error --- packages/fiori/src/SideNavigation.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index cced068ff052..ea143546ec1b 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -451,7 +451,6 @@ class SideNavigation extends UI5Element { } } - const fixedDom = this.shadowRoot!.querySelector(".ui5-sn-fixed"); if (this._getAllItems(this.fixedItems).indexOf(activeElement) === -1) { const selectedItem = this._findSelectedItem(this.fixedItems); if (selectedItem) { From 641497bf6ec0e5152e5d3ef546e63329aff3ef28 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Fri, 16 Feb 2024 11:34:00 +0200 Subject: [PATCH 19/44] feat(ui5-side-navigation): fix overflow item selection --- packages/fiori/src/SideNavigation.hbs | 1 + packages/fiori/src/SideNavigation.ts | 19 ++++++++--------- packages/fiori/src/SideNavigationItem.hbs | 8 +++---- .../src/SideNavigationSelectableItemBase.ts | 21 ++++++++++++++++++- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/packages/fiori/src/SideNavigation.hbs b/packages/fiori/src/SideNavigation.hbs index d557829e687c..64b99f5ba9fa 100644 --- a/packages/fiori/src/SideNavigation.hbs +++ b/packages/fiori/src/SideNavigation.hbs @@ -9,6 +9,7 @@ > ) { + async handleOverflowItemClick(e: CustomEvent) { const associatedItem = e.detail?.item.associatedItem; associatedItem.fireEvent("click"); @@ -335,6 +335,9 @@ class SideNavigation extends UI5Element { } this.closeMenu(); + await renderFinished(); + + associatedItem.focus(); } async getOverflowPopover() { @@ -505,9 +508,9 @@ class SideNavigation extends UI5Element { overflowItemRef.classList.add("ui5-sn-item-hidden"); - const itemsRefs = this.overflowItems; + const overflowItems = this.overflowItems; - let itemsHeight = itemsRefs.reduce((sum, itemRef) => { + let itemsHeight = overflowItems.reduce((sum, itemRef) => { itemRef.classList.remove("ui5-sn-item-hidden"); return sum + itemRef.offsetHeight; }, 0); @@ -518,14 +521,14 @@ class SideNavigation extends UI5Element { overflowItemRef.classList.remove("ui5-sn-item-hidden"); itemsHeight = overflowItemRef.offsetHeight; - const oSelectedItemRef = domRef.querySelector(".ui5-sn-item-selected") as HTMLElement; + const oSelectedItemRef = overflowItems.find(item => item._selected); if (oSelectedItemRef) { const { marginTop, marginBottom } = window.getComputedStyle(oSelectedItemRef); itemsHeight += oSelectedItemRef.offsetHeight + parseFloat(marginTop) + parseFloat(marginBottom); } - itemsRefs.forEach(itemRef => { + overflowItems.forEach(itemRef => { if (itemRef === oSelectedItemRef) { return; } @@ -600,7 +603,7 @@ class SideNavigation extends UI5Element { this._isOverflow = true; this._menuPopoverItems = this._getOverflowItems(); - this.openOverflowMenu(this._overflowItem as HTMLElement); + this.openOverflowMenu(this._overflowItem!.getFocusDomRef() as HTMLElement); } _getOverflowItems(): Array { @@ -633,10 +636,6 @@ class SideNavigation extends UI5Element { }); item.selected = true; - - if (this.collapsed && item.classList.contains("ui5-sn-item-hidden")) { - item.classList.remove("ui5-sn-item-hidden"); - } } get _overflowItem() { diff --git a/packages/fiori/src/SideNavigationItem.hbs b/packages/fiori/src/SideNavigationItem.hbs index e0ab0473254c..0f35c6c6cc45 100644 --- a/packages/fiori/src/SideNavigationItem.hbs +++ b/packages/fiori/src/SideNavigationItem.hbs @@ -8,7 +8,7 @@ {{#if _href}} {{#if _href}} {{else}}
      Date: Fri, 16 Feb 2024 14:07:35 +0200 Subject: [PATCH 20/44] feat(ui5-side-navigation): group styles --- packages/fiori/src/SideNavigation.ts | 21 +-- packages/fiori/src/SideNavigationGroup.hbs | 7 +- packages/fiori/src/SideNavigationItem.hbs | 130 +++++++++--------- packages/fiori/src/SideNavigationPopover.hbs | 1 - packages/fiori/src/themes/SideNavigation.css | 8 +- .../fiori/src/themes/SideNavigationItem.css | 36 ++++- .../test/pages/SideNavigationWithGroups.html | 8 +- 7 files changed, 116 insertions(+), 95 deletions(-) diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index 6265eb284441..c95f4c70de69 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -255,13 +255,6 @@ class SideNavigation extends UI5Element { } } - async _onAfterMenuClose() { - const selectedItem = this._findSelectedItem(this.items)!; - - await renderFinished(); - selectedItem.getDomRef()!.focus(); - } - async _onBeforePopoverOpen() { const popover = await this.getPicker(); (popover?.opener as HTMLElement)?.classList.add("ui5-sn-item-active"); @@ -326,18 +319,18 @@ class SideNavigation extends UI5Element { this._selectItem(associatedItem); + this.closeMenu(); + await renderFinished(); + // When subitem is selected in collapsed mode parent element should be focused if (associatedItem.nodeName.toLowerCase() === "ui5-side-navigation-sub-item") { const parent = associatedItem.parentElement as SideNavigationItem; - this._flexibleItemNavigation.setCurrentItem(parent); + this.focusItem(parent); + parent?.focus(); } else { - this._flexibleItemNavigation.setCurrentItem(associatedItem); + this.focusItem(associatedItem); + associatedItem?.focus(); } - - this.closeMenu(); - await renderFinished(); - - associatedItem.focus(); } async getOverflowPopover() { diff --git a/packages/fiori/src/SideNavigationGroup.hbs b/packages/fiori/src/SideNavigationGroup.hbs index 8c699f208e2a..cc51fb5238ac 100644 --- a/packages/fiori/src/SideNavigationGroup.hbs +++ b/packages/fiori/src/SideNavigationGroup.hbs @@ -1,13 +1,14 @@ +
    • {{#if sideNavCollapsed}} -
      {{else}} {{> treeitem }} {{/if}} +
    • {{#*inline treeitem}}
    • -
      {{#if items.length}}
        diff --git a/packages/fiori/src/SideNavigationItem.hbs b/packages/fiori/src/SideNavigationItem.hbs index 0f35c6c6cc45..102e578e1181 100644 --- a/packages/fiori/src/SideNavigationItem.hbs +++ b/packages/fiori/src/SideNavigationItem.hbs @@ -5,69 +5,71 @@ {{/if}} {{#*inline menuitem}} - {{#if _href}} - - -
        {{text}}
        - {{#if items.length}} - - {{/if}} - {{#if _isExternalLink}} - - {{/if}} -
        - {{else}} -
        - -
        {{text}}
        - {{#if items.length}} - - {{/if}} - {{#if _isExternalLink}} - - {{/if}} -
        - {{/if}} +
      • + {{#if _href}} + + +
        {{text}}
        + {{#if items.length}} + + {{/if}} + {{#if _isExternalLink}} + + {{/if}} +
        + {{else}} +
        + +
        {{text}}
        + {{#if items.length}} + + {{/if}} + {{#if _isExternalLink}} + + {{/if}} +
        + {{/if}} +
      • {{/inline}} {{#*inline treeitem}} @@ -143,7 +145,7 @@ {{/if}} {{#if items.length}}
          diff --git a/packages/fiori/src/SideNavigationPopover.hbs b/packages/fiori/src/SideNavigationPopover.hbs index 42a01adfcb76..2d2d74256e9f 100644 --- a/packages/fiori/src/SideNavigationPopover.hbs +++ b/packages/fiori/src/SideNavigationPopover.hbs @@ -1,7 +1,6 @@ {{#if isOverflow}}
        {{/if}} +
        {{/inline}} \ No newline at end of file diff --git a/packages/fiori/src/SideNavigationItem.hbs b/packages/fiori/src/SideNavigationItem.hbs index 102e578e1181..dad52783fec1 100644 --- a/packages/fiori/src/SideNavigationItem.hbs +++ b/packages/fiori/src/SideNavigationItem.hbs @@ -5,71 +5,69 @@ {{/if}} {{#*inline menuitem}} -
      • - {{#if _href}} - - -
        {{text}}
        - {{#if items.length}} - - {{/if}} - {{#if _isExternalLink}} - - {{/if}} -
        - {{else}} -
        - -
        {{text}}
        - {{#if items.length}} - - {{/if}} - {{#if _isExternalLink}} - - {{/if}} -
        - {{/if}} -
      • + {{#if _href}} + + +
        {{text}}
        + {{#if items.length}} + + {{/if}} + {{#if _isExternalLink}} + + {{/if}} +
        + {{else}} +
        + +
        {{text}}
        + {{#if items.length}} + + {{/if}} + {{#if _isExternalLink}} + + {{/if}} +
        + {{/if}} {{/inline}} {{#*inline treeitem}} diff --git a/packages/fiori/src/SideNavigationItem.ts b/packages/fiori/src/SideNavigationItem.ts index 4957f702c03e..e3c6e149f468 100644 --- a/packages/fiori/src/SideNavigationItem.ts +++ b/packages/fiori/src/SideNavigationItem.ts @@ -112,6 +112,14 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { return undefined; } + get _ariaChecked() { + if (this.disabled && this.sideNavCollapsed && this.items.length) { + return "tree"; + } + + return undefined; + } + get _groupId() { if (!this.items.length) { return undefined; From 39229ab5fcb28e3c6e062f2e539cf8f22aaf92c7 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Fri, 16 Feb 2024 16:04:13 +0200 Subject: [PATCH 22/44] feat(ui5-side-navigation): remove overflow item aria-checked --- packages/fiori/src/SideNavigationItem.hbs | 4 ++-- packages/fiori/src/SideNavigationItem.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/fiori/src/SideNavigationItem.hbs b/packages/fiori/src/SideNavigationItem.hbs index dad52783fec1..ff277728b1fb 100644 --- a/packages/fiori/src/SideNavigationItem.hbs +++ b/packages/fiori/src/SideNavigationItem.hbs @@ -19,7 +19,7 @@ @mouseleave="{{_onmouseleave}}" tabindex="{{_effectiveTabIndex}}" aria-haspopup="{{_ariaHasPopup}}" - aria-checked="{{selected}}" + aria-checked="{{_ariaChecked}}" title="{{_tooltip}}" href="{{_href}}" target="{{_target}}" @@ -51,7 +51,7 @@ @mouseleave="{{_onmouseleave}}" tabindex="{{_effectiveTabIndex}}" aria-haspopup="{{_ariaHasPopup}}" - aria-checked="{{selected}}" + aria-checked="{{_ariaChecked}}" title="{{_tooltip}}" > diff --git a/packages/fiori/src/SideNavigationItem.ts b/packages/fiori/src/SideNavigationItem.ts index e3c6e149f468..4c713c2dd5f7 100644 --- a/packages/fiori/src/SideNavigationItem.ts +++ b/packages/fiori/src/SideNavigationItem.ts @@ -113,11 +113,11 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { } get _ariaChecked() { - if (this.disabled && this.sideNavCollapsed && this.items.length) { - return "tree"; + if (this.isOverflow) { + return undefined; } - return undefined; + return this.selected; } get _groupId() { From 86b4b1224614f0e54f19a663916041edb1185349 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Mon, 19 Feb 2024 10:52:40 +0200 Subject: [PATCH 23/44] feat(ui5-side-navigation): style popover items --- packages/fiori/src/SideNavigation.ts | 7 ++++--- packages/fiori/src/SideNavigationItemBase.ts | 3 +++ packages/fiori/src/SideNavigationPopover.hbs | 2 +- packages/fiori/src/themes/SideNavigation.css | 4 ++++ packages/fiori/src/themes/SideNavigationItem.css | 15 +++++++-------- 5 files changed, 19 insertions(+), 12 deletions(-) diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index c95f4c70de69..8d9d1fe17189 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -193,7 +193,7 @@ class SideNavigation extends UI5Element { _popoverContents!: SideNavigationPopoverContents; @property({ type: Boolean }) - _inPopover!: boolean; + inPopover!: boolean; _isOverflow!: boolean; _flexibleItemNavigation: ItemNavigation; _fixedItemNavigation: ItemNavigation; @@ -235,10 +235,12 @@ class SideNavigation extends UI5Element { this._getAllItems(this.items).forEach(item => { item.sideNavCollapsed = this.collapsed; + item.inPopover = this.inPopover; }); this._getAllItems(this.fixedItems).forEach(item => { item.sideNavCollapsed = this.collapsed; + item.inPopover = this.inPopover; }); } @@ -385,14 +387,13 @@ class SideNavigation extends UI5Element { } get _rootRole() { - return this._inPopover ? "none" : undefined; + return this.inPopover ? "none" : undefined; } get classes() { return { root: { "ui5-sn-collapsed": this.collapsed, - "ui5-sn-in-popover": this._inPopover, }, }; } diff --git a/packages/fiori/src/SideNavigationItemBase.ts b/packages/fiori/src/SideNavigationItemBase.ts index 21a435e7bd6e..8459dbc29f45 100644 --- a/packages/fiori/src/SideNavigationItemBase.ts +++ b/packages/fiori/src/SideNavigationItemBase.ts @@ -51,6 +51,9 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { @property({ type: Boolean }) sideNavCollapsed!: boolean; + @property({ type: Boolean }) + inPopover!: boolean; + get _tooltip() { return this.title || this.text; } diff --git a/packages/fiori/src/SideNavigationPopover.hbs b/packages/fiori/src/SideNavigationPopover.hbs index 2d2d74256e9f..ab3e1842dc53 100644 --- a/packages/fiori/src/SideNavigationPopover.hbs +++ b/packages/fiori/src/SideNavigationPopover.hbs @@ -41,7 +41,7 @@ > {{accSideNavigationPopoverHiddenText}} Date: Mon, 19 Feb 2024 13:24:20 +0200 Subject: [PATCH 24/44] feat(ui5-side-navigation): improve styles --- packages/fiori/src/SideNavigationItem.hbs | 8 ++++---- .../fiori/src/SideNavigationSelectableItemBase.ts | 2 +- packages/fiori/src/SideNavigationSubItem.hbs | 4 ++-- packages/fiori/src/themes/SideNavigationItem.css | 13 +++---------- .../src/themes/base/SideNavigation-parameters.css | 1 - .../sap_horizon/SideNavigation-parameters.css | 1 - .../sap_horizon_dark/SideNavigation-parameters.css | 1 - .../sap_horizon_hcb/SideNavigation-parameters.css | 1 - .../sap_horizon_hcw/SideNavigation-parameters.css | 1 - packages/main/src/NavigationMenu.hbs | 2 +- packages/main/src/NavigationMenuItem.ts | 4 ++++ 11 files changed, 15 insertions(+), 23 deletions(-) diff --git a/packages/fiori/src/SideNavigationItem.hbs b/packages/fiori/src/SideNavigationItem.hbs index ff277728b1fb..c25e9fa73444 100644 --- a/packages/fiori/src/SideNavigationItem.hbs +++ b/packages/fiori/src/SideNavigationItem.hbs @@ -31,7 +31,7 @@ name="navigation-right-arrow" > {{/if}} - {{#if _isExternalLink}} + {{#if isExternalLink}} @@ -61,7 +61,7 @@ name="navigation-right-arrow" > {{/if}} - {{#if _isExternalLink}} + {{#if isExternalLink}} @@ -95,7 +95,7 @@ - {{#if _isExternalLink}} + {{#if isExternalLink}} @@ -128,7 +128,7 @@ - {{#if _isExternalLink}} + {{#if isExternalLink}} diff --git a/packages/fiori/src/SideNavigationSelectableItemBase.ts b/packages/fiori/src/SideNavigationSelectableItemBase.ts index 022248af83ec..d4735293cb0a 100644 --- a/packages/fiori/src/SideNavigationSelectableItemBase.ts +++ b/packages/fiori/src/SideNavigationSelectableItemBase.ts @@ -105,7 +105,7 @@ class SideNavigationSelectableItemBase extends SideNavigationItemBase { return (!this.disabled && this.target) ? this.target : undefined; } - get _isExternalLink() { + get isExternalLink() { return this.href && this.target === "_blank"; } diff --git a/packages/fiori/src/SideNavigationSubItem.hbs b/packages/fiori/src/SideNavigationSubItem.hbs index d8f0b8964e94..cf75f7bc3746 100644 --- a/packages/fiori/src/SideNavigationSubItem.hbs +++ b/packages/fiori/src/SideNavigationSubItem.hbs @@ -21,7 +21,7 @@ - {{#if _isExternalLink}} + {{#if isExternalLink}} @@ -46,7 +46,7 @@ - {{#if _isExternalLink}} + {{#if isExternalLink}} diff --git a/packages/fiori/src/themes/SideNavigationItem.css b/packages/fiori/src/themes/SideNavigationItem.css index 32a628896c69..6bfa53e08c06 100644 --- a/packages/fiori/src/themes/SideNavigationItem.css +++ b/packages/fiori/src/themes/SideNavigationItem.css @@ -71,7 +71,7 @@ border-width: var(--_ui5_side_navigation_group_expanded_border_width); } -.ui5-sn-item-ul .ui5-sn-list-li:last-child .ui5-sn-item.ui5-sn-item-level2:not(.ui5-sn-item-selected)::before { +:host(:last-child) .ui5-sn-item.ui5-sn-item-level2:not(.ui5-sn-item-selected)::before { border: var(--_ui5_side_navigation_group_border_style_color); border-width: var(--_ui5_side_navigation_group_border_width); } @@ -154,10 +154,7 @@ border-radius: var(--_ui5_side_navigation_item_border_radius); } -/*todo -:host([in-popover]) .ui5-sn-item-ul .ui5-sn-list-li:last-child .ui5-sn-item:not(:hover):not(:active)::before { - */ -:host([in-popover]) .ui5-sn-item:not(:hover):not(:active)::before { +:host([in-popover]:last-of-type) .ui5-sn-item:not(:hover):not(:active)::before { border: var(--_ui5_side_navigation_last_item_border_style); } @@ -214,7 +211,7 @@ :host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover:not(.ui5-sn-item-with-expander), :host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):focus:not(.ui5-sn-item-with-expander) { - padding-right: var(--_ui5_side_navigation_item_collapsed_hover_focus_padding_right); + padding-inline-end: var(--_ui5_side_navigation_item_collapsed_hover_focus_padding_right); } :host([side-nav-collapsed]) .ui5-sn-item:not(.ui5-sn-item-active):not(.ui5-sn-item-no-hover-effect):hover .ui5-sn-item-text, @@ -287,10 +284,6 @@ margin-inline: 0.5rem 0; } -:host([side-nav-collapsed]) .ui5-sn-item:not([aria-expanded]) { - padding-inline-end: var(--_ui5_side_navigation_item_padding_right); -} - .ui5-sn-item-selected .ui5-sn-item-selection-icon { display: var(--_ui5_side_navigation_selection_indicator_display); } diff --git a/packages/fiori/src/themes/base/SideNavigation-parameters.css b/packages/fiori/src/themes/base/SideNavigation-parameters.css index bbdf62eacf86..4f3aed2914f0 100644 --- a/packages/fiori/src/themes/base/SideNavigation-parameters.css +++ b/packages/fiori/src/themes/base/SideNavigation-parameters.css @@ -34,7 +34,6 @@ --_ui5_side_navigation_item_bottom_margin: 0; --_ui5_side_navigation_item_bottom_margin_compact: 0; --_ui5_side_navigation_item_transition: none; - --_ui5_side_navigation_item_padding_right: 0.5rem; --_ui5_side_navigation_item_padding_left: 0.5rem; --_ui5_side_navigation_no_icons_group_padding: 1rem; --_ui5_side_navigation_no_icons_nested_item_padding: 1rem; diff --git a/packages/fiori/src/themes/sap_horizon/SideNavigation-parameters.css b/packages/fiori/src/themes/sap_horizon/SideNavigation-parameters.css index dee320e7d77f..87bf769b782b 100644 --- a/packages/fiori/src/themes/sap_horizon/SideNavigation-parameters.css +++ b/packages/fiori/src/themes/sap_horizon/SideNavigation-parameters.css @@ -29,7 +29,6 @@ --_ui5_side_navigation_item_bottom_margin: 0.25rem; --_ui5_side_navigation_item_bottom_margin_compact: 0.5rem; --_ui5_side_navigation_item_transition: background-color 0.3s ease-in-out; - --_ui5_side_navigation_item_padding_right: 0; --_ui5_side_navigation_no_icons_nested_item_padding: 2rem; --_ui5_side_navigation_item_focus_border_offset: calc(-1 * var(--sapContent_FocusWidth)); --_ui5_side_navigation_item_focus_border_radius: calc(var(--_ui5_side_navigation_item_border_radius) + var(--sapContent_FocusWidth)); diff --git a/packages/fiori/src/themes/sap_horizon_dark/SideNavigation-parameters.css b/packages/fiori/src/themes/sap_horizon_dark/SideNavigation-parameters.css index e83a2439f1e4..836fc71c4828 100644 --- a/packages/fiori/src/themes/sap_horizon_dark/SideNavigation-parameters.css +++ b/packages/fiori/src/themes/sap_horizon_dark/SideNavigation-parameters.css @@ -29,7 +29,6 @@ --_ui5_side_navigation_item_bottom_margin: 0.25rem; --_ui5_side_navigation_item_bottom_margin_compact: 0.5rem; --_ui5_side_navigation_item_transition: background-color 0.3s ease-in-out; - --_ui5_side_navigation_item_padding_right: 0; --_ui5_side_navigation_no_icons_nested_item_padding: 2rem; --_ui5_side_navigation_item_focus_border_offset: calc(-1 * var(--sapContent_FocusWidth)); --_ui5_side_navigation_item_focus_border_radius: calc(var(--_ui5_side_navigation_item_border_radius) + var(--sapContent_FocusWidth)); diff --git a/packages/fiori/src/themes/sap_horizon_hcb/SideNavigation-parameters.css b/packages/fiori/src/themes/sap_horizon_hcb/SideNavigation-parameters.css index 31c22e370c18..4f3647784a20 100644 --- a/packages/fiori/src/themes/sap_horizon_hcb/SideNavigation-parameters.css +++ b/packages/fiori/src/themes/sap_horizon_hcb/SideNavigation-parameters.css @@ -24,7 +24,6 @@ --_ui5_side_navigation_item_focus_border_offset: 0; --_ui5_side_navigation_item_border_style_color: solid var(--sapList_BorderColor); --_ui5_side_navigation_item_border_width: 0 0 0.0625rem 0; - --_ui5_side_navigation_item_padding_right: 0; --_ui5_side_navigation_group_expanded_border_width: var(--_ui5_side_navigation_item_border_width); --_ui5_side_navigation_last_item_border_style: solid transparent; --_ui5_side_navigation_hover_border_style_color: solid var(--sapList_SelectionBorderColor); diff --git a/packages/fiori/src/themes/sap_horizon_hcw/SideNavigation-parameters.css b/packages/fiori/src/themes/sap_horizon_hcw/SideNavigation-parameters.css index 31c22e370c18..4f3647784a20 100644 --- a/packages/fiori/src/themes/sap_horizon_hcw/SideNavigation-parameters.css +++ b/packages/fiori/src/themes/sap_horizon_hcw/SideNavigation-parameters.css @@ -24,7 +24,6 @@ --_ui5_side_navigation_item_focus_border_offset: 0; --_ui5_side_navigation_item_border_style_color: solid var(--sapList_BorderColor); --_ui5_side_navigation_item_border_width: 0 0 0.0625rem 0; - --_ui5_side_navigation_item_padding_right: 0; --_ui5_side_navigation_group_expanded_border_width: var(--_ui5_side_navigation_item_border_width); --_ui5_side_navigation_last_item_border_style: solid transparent; --_ui5_side_navigation_hover_border_style_color: solid var(--sapList_SelectionBorderColor); diff --git a/packages/main/src/NavigationMenu.hbs b/packages/main/src/NavigationMenu.hbs index 188007e57b0e..5b433e93c8bf 100644 --- a/packages/main/src/NavigationMenu.hbs +++ b/packages/main/src/NavigationMenu.hbs @@ -90,7 +90,7 @@ {{else if this.item._siblingsWithChildren}}
        {{/if}} - {{#if this.item.target}} + {{#if this.item.isExternalLink}} diff --git a/packages/main/src/NavigationMenuItem.ts b/packages/main/src/NavigationMenuItem.ts index 63138f6dd86f..90972933e7b9 100644 --- a/packages/main/src/NavigationMenuItem.ts +++ b/packages/main/src/NavigationMenuItem.ts @@ -62,6 +62,10 @@ class NavigationMenuItem extends MenuItem { */ @property() target!: string; + + get isExternalLink() { + return this.href && this.target === "_blank"; + } } NavigationMenuItem.define(); From 606dde8345ae07bee589124587e9b1aade77719c Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Mon, 19 Feb 2024 16:17:49 +0200 Subject: [PATCH 25/44] feat(ui5-side-navigation): improve styles --- packages/fiori/src/SideNavigation.ts | 13 +++-- packages/fiori/src/SideNavigationGroup.hbs | 4 +- packages/fiori/src/SideNavigationGroup.ts | 16 ++++-- packages/fiori/src/SideNavigationItem.hbs | 8 +-- packages/fiori/src/SideNavigationItem.ts | 2 +- packages/fiori/src/SideNavigationItemBase.ts | 2 +- packages/fiori/src/SideNavigationSubItem.hbs | 4 +- .../fiori/src/themes/SideNavigationItem.css | 11 +++- .../test/pages/SideNavigationWithGroups.html | 53 ++++++++++++++----- 9 files changed, 81 insertions(+), 32 deletions(-) diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index 8d9d1fe17189..8cc0c7447532 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -26,8 +26,8 @@ import Icon from "@ui5/webcomponents/dist/Icon.js"; import "@ui5/webcomponents-icons/dist/circle-task-2.js"; import "@ui5/webcomponents-icons/dist/navigation-right-arrow.js"; import "@ui5/webcomponents-icons/dist/navigation-down-arrow.js"; -import type SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase.js"; import SideNavigationItemBase from "./SideNavigationItemBase.js"; +import SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase.js"; import SideNavigationItem from "./SideNavigationItem.js"; import SideNavigationSubItem from "./SideNavigationSubItem.js"; import SideNavigationGroup from "./SideNavigationGroup.js"; @@ -515,7 +515,9 @@ class SideNavigation extends UI5Element { overflowItemRef.classList.remove("ui5-sn-item-hidden"); itemsHeight = overflowItemRef.offsetHeight; - const oSelectedItemRef = overflowItems.find(item => item._selected); + const oSelectedItemRef = overflowItems.find(item => { + return item instanceof SideNavigationSelectableItemBase && item._selected; + }); if (oSelectedItemRef) { const { marginTop, marginBottom } = window.getComputedStyle(oSelectedItemRef); @@ -562,10 +564,10 @@ class SideNavigation extends UI5Element { return this._getSelectableItems(items).find(item => item._selected); } - get overflowItems() : Array { + get overflowItems() : Array { return this.items.reduce((result, item) => { return result.concat(item.overflowItems); - }, new Array()); + }, new Array()); } _handleItemClick(e: KeyboardEvent | PointerEvent, item: SideNavigationSelectableItemBase) { @@ -605,7 +607,8 @@ class SideNavigation extends UI5Element { const result: Array = []; this.overflowItems.forEach(item => { - if (item.classList.contains(overflowClass)) { + if (item instanceof SideNavigationSelectableItemBase + && item.classList.contains(overflowClass)) { result.push(item); } }); diff --git a/packages/fiori/src/SideNavigationGroup.hbs b/packages/fiori/src/SideNavigationGroup.hbs index fe2c00757930..25fcd6354592 100644 --- a/packages/fiori/src/SideNavigationGroup.hbs +++ b/packages/fiori/src/SideNavigationGroup.hbs @@ -7,7 +7,7 @@ {{/if}} {{#*inline treeitem}} -
      • +
      • ; - get overflowItems() : Array { + get overflowItems() : Array { return this.items.reduce((result, item) => { - return result.concat(item.overflowItems); - }, new Array()); + const first = this.shadowRoot!.querySelector(".ui5-sn-item-separator:first-child") as HTMLElement; + const last = this.shadowRoot!.querySelector(".ui5-sn-item-separator:last-child") as HTMLElement; + return result.concat([first, ...item.overflowItems, last]); + }, new Array()); } get selectableItems() : Array { @@ -113,6 +115,14 @@ class SideNavigationGroup extends SideNavigationItemBase { return this.expanded ? "navigation-down-arrow" : "navigation-right-arrow"; } + get belowGroupClassName() { + if (this.previousElementSibling instanceof SideNavigationGroup) { + return "ui5-sn-item-group-below-group"; + } + + return ""; + } + _onkeydown = (e: KeyboardEvent) => { if (isLeft(e)) { this.expanded = false; diff --git a/packages/fiori/src/SideNavigationItem.hbs b/packages/fiori/src/SideNavigationItem.hbs index c25e9fa73444..b58b6678ba6e 100644 --- a/packages/fiori/src/SideNavigationItem.hbs +++ b/packages/fiori/src/SideNavigationItem.hbs @@ -17,7 +17,7 @@ @focusout="{{_onfocusout}}" @mouseenter="{{_onmouseenter}}" @mouseleave="{{_onmouseleave}}" - tabindex="{{_effectiveTabIndex}}" + tabindex="{{effectiveTabIndex}}" aria-haspopup="{{_ariaHasPopup}}" aria-checked="{{_ariaChecked}}" title="{{_tooltip}}" @@ -49,7 +49,7 @@ @focusout="{{_onfocusout}}" @mouseenter="{{_onmouseenter}}" @mouseleave="{{_onmouseleave}}" - tabindex="{{_effectiveTabIndex}}" + tabindex="{{effectiveTabIndex}}" aria-haspopup="{{_ariaHasPopup}}" aria-checked="{{_ariaChecked}}" title="{{_tooltip}}" @@ -80,7 +80,7 @@ @keyup="{{_onkeyup}}" @click="{{_onclick}}" @focusin="{{_onfocusin}}" - tabindex="{{_effectiveTabIndex}}" + tabindex="{{effectiveTabIndex}}" aria-expanded="{{_expanded}}" aria-current="{{_ariaCurrent}}" title="{{_tooltip}}" @@ -115,7 +115,7 @@ @keyup="{{_onkeyup}}" @click="{{_onclick}}" @focusin="{{_onfocusin}}" - tabindex="{{_effectiveTabIndex}}" + tabindex="{{effectiveTabIndex}}" aria-expanded="{{_expanded}}" aria-current="{{_ariaCurrent}}" title="{{_tooltip}}" diff --git a/packages/fiori/src/SideNavigationItem.ts b/packages/fiori/src/SideNavigationItem.ts index 4c713c2dd5f7..190b29509ca1 100644 --- a/packages/fiori/src/SideNavigationItem.ts +++ b/packages/fiori/src/SideNavigationItem.ts @@ -80,7 +80,7 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { @property({ type: Boolean }) wholeItemToggleable!: boolean; - get overflowItems() : Array { + get overflowItems() : Array { return [this]; } diff --git a/packages/fiori/src/SideNavigationItemBase.ts b/packages/fiori/src/SideNavigationItemBase.ts index 8459dbc29f45..63347a28c8d9 100644 --- a/packages/fiori/src/SideNavigationItemBase.ts +++ b/packages/fiori/src/SideNavigationItemBase.ts @@ -72,7 +72,7 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { return this.classesArray.join(" "); } - get _effectiveTabIndex() { + get effectiveTabIndex() { if (this.disabled) { return undefined; } diff --git a/packages/fiori/src/SideNavigationSubItem.hbs b/packages/fiori/src/SideNavigationSubItem.hbs index cf75f7bc3746..cd0327bc8b79 100644 --- a/packages/fiori/src/SideNavigationSubItem.hbs +++ b/packages/fiori/src/SideNavigationSubItem.hbs @@ -8,7 +8,7 @@ @keyup="{{_onkeyup}}" @click="{{_onclick}}" @focusin="{{_onfocusin}}" - tabindex="{{_effectiveTabIndex}}" + tabindex="{{effectiveTabIndex}}" aria-current="{{_ariaCurrent}}" title="{{_tooltip}}" href="{{_href}}" @@ -35,7 +35,7 @@ @keyup="{{_onkeyup}}" @click="{{_onclick}}" @focusin="{{_onfocusin}}" - tabindex="{{_effectiveTabIndex}}" + tabindex="{{effectiveTabIndex}}" aria-current="{{_ariaCurrent}}" title="{{_tooltip}}" > diff --git a/packages/fiori/src/themes/SideNavigationItem.css b/packages/fiori/src/themes/SideNavigationItem.css index 6bfa53e08c06..8d21748bb79b 100644 --- a/packages/fiori/src/themes/SideNavigationItem.css +++ b/packages/fiori/src/themes/SideNavigationItem.css @@ -38,7 +38,8 @@ display: block; } -:host(.ui5-sn-item-hidden[side-nav-collapsed]) { +:host(.ui5-sn-item-hidden[side-nav-collapsed]), +:host([side-nav-collapsed]) .ui5-sn-item-hidden { display: none; } @@ -309,4 +310,10 @@ .ui5-sn-item-separator { min-height: 0.75rem; -} \ No newline at end of file +} + +:host(:first-child) .ui5-sn-list-li .ui5-sn-item-separator:first-child, +:host(:last-child) .ui5-sn-list-li .ui5-sn-item-separator:last-child, +.ui5-sn-item-group-below-group .ui5-sn-item-separator:first-child{ + display: none; +} diff --git a/packages/fiori/test/pages/SideNavigationWithGroups.html b/packages/fiori/test/pages/SideNavigationWithGroups.html index a284e9d6b382..c323f5cae60b 100644 --- a/packages/fiori/test/pages/SideNavigationWithGroups.html +++ b/packages/fiori/test/pages/SideNavigationWithGroups.html @@ -9,10 +9,10 @@ - + + + + - - - - + + + + + + + + + + + + + + + + @@ -51,11 +69,11 @@ - + - - - + + + @@ -66,6 +84,17 @@ + + + + + + + +
        From 5fb784e3a54cd8c8ecf61b775f7bc928c7dd0fc8 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Mon, 19 Feb 2024 16:47:12 +0200 Subject: [PATCH 26/44] feat(ui5-side-navigation): improve styles --- packages/fiori/src/SideNavigationGroup.hbs | 2 +- packages/fiori/src/themes/SideNavigationItem.css | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/fiori/src/SideNavigationGroup.hbs b/packages/fiori/src/SideNavigationGroup.hbs index 25fcd6354592..9bb54f12852b 100644 --- a/packages/fiori/src/SideNavigationGroup.hbs +++ b/packages/fiori/src/SideNavigationGroup.hbs @@ -1,5 +1,5 @@ {{#if sideNavCollapsed}} -
        +
        {{else}} diff --git a/packages/fiori/src/themes/SideNavigationItem.css b/packages/fiori/src/themes/SideNavigationItem.css index 8d21748bb79b..d41cce07d50a 100644 --- a/packages/fiori/src/themes/SideNavigationItem.css +++ b/packages/fiori/src/themes/SideNavigationItem.css @@ -312,8 +312,9 @@ min-height: 0.75rem; } -:host(:first-child) .ui5-sn-list-li .ui5-sn-item-separator:first-child, -:host(:last-child) .ui5-sn-list-li .ui5-sn-item-separator:last-child, -.ui5-sn-item-group-below-group .ui5-sn-item-separator:first-child{ +:host(:first-child) .ui5-sn-item-separator:first-child, +:host(:last-child) .ui5-sn-item-separator:last-child, +.ui5-sn-item-group-below-group.ui5-sn-item-separator, +.ui5-sn-item-group-below-group .ui5-sn-item-separator:first-child { display: none; } From b3dfb7b85ba43c81c6566efa7316c25a94373307 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Tue, 20 Feb 2024 14:14:32 +0200 Subject: [PATCH 27/44] feat(ui5-side-navigation): fix overflow when groups are used --- packages/fiori/src/SideNavigation.ts | 54 +++++++++++++---------- packages/fiori/src/SideNavigationGroup.ts | 11 +++-- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index 8cc0c7447532..999df5a4a847 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -476,16 +476,7 @@ class SideNavigation extends UI5Element { } handleResize() { - const domRef = this.getDomRef(), - overflowItemRef = domRef?.querySelector(".ui5-sn-item-overflow"); - this._updateOverflowItems(); - - if (this._getOverflowItems().length > 0 && this.collapsed) { - overflowItemRef?.classList.remove("ui5-sn-item-hidden"); - } else { - overflowItemRef?.classList.add("ui5-sn-item-hidden"); - } } _updateOverflowItems() { @@ -494,13 +485,13 @@ class SideNavigation extends UI5Element { return null; } - const overflowItemRef = this._overflowItem!; + const overflowItem = this._overflowItem!; const flexibleContentDomRef : HTMLElement = domRef.querySelector(".ui5-sn-flexible")!; - if (!overflowItemRef) { + if (!overflowItem) { return null; } - overflowItemRef.classList.add("ui5-sn-item-hidden"); + overflowItem.classList.add("ui5-sn-item-hidden"); const overflowItems = this.overflowItems; @@ -512,28 +503,43 @@ class SideNavigation extends UI5Element { const { paddingTop, paddingBottom } = window.getComputedStyle(flexibleContentDomRef); const listHeight = flexibleContentDomRef?.offsetHeight - parseInt(paddingTop) - parseInt(paddingBottom); - overflowItemRef.classList.remove("ui5-sn-item-hidden"); + if (itemsHeight <= listHeight) { + return; + } + + overflowItem.classList.remove("ui5-sn-item-hidden"); - itemsHeight = overflowItemRef.offsetHeight; - const oSelectedItemRef = overflowItems.find(item => { + itemsHeight = overflowItem.offsetHeight; + + const selectedItem = overflowItems.find(item => { return item instanceof SideNavigationSelectableItemBase && item._selected; }); - if (oSelectedItemRef) { - const { marginTop, marginBottom } = window.getComputedStyle(oSelectedItemRef); - itemsHeight += oSelectedItemRef.offsetHeight + parseFloat(marginTop) + parseFloat(marginBottom); + if (selectedItem && selectedItem instanceof SideNavigationItemBase) { + const selectedItemDomRef = selectedItem.getDomRef(); + const { marginTop, marginBottom } = window.getComputedStyle(selectedItemDomRef!); + + itemsHeight += selectedItemDomRef!.offsetHeight + parseFloat(marginTop) + parseFloat(marginBottom); } - overflowItems.forEach(itemRef => { - if (itemRef === oSelectedItemRef) { + overflowItems.forEach(item => { + if (item === selectedItem) { return; } - const { marginTop, marginBottom } = window.getComputedStyle(itemRef); - itemsHeight += itemRef.offsetHeight + parseFloat(marginTop) + parseFloat(marginBottom); + let itemDomRef; + + if (item instanceof SideNavigationItemBase) { + itemDomRef = item.getDomRef()!; + } else { + itemDomRef = item; + } + + const { marginTop, marginBottom } = window.getComputedStyle(itemDomRef); + itemsHeight += itemDomRef.offsetHeight + parseFloat(marginTop) + parseFloat(marginBottom); - if (itemsHeight >= listHeight) { - itemRef.classList.add("ui5-sn-item-hidden"); + if (itemsHeight > listHeight) { + item.classList.add("ui5-sn-item-hidden"); } }); } diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts index b43cacf7f816..36bc97813034 100644 --- a/packages/fiori/src/SideNavigationGroup.ts +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -62,11 +62,14 @@ class SideNavigationGroup extends SideNavigationItemBase { items!: Array; get overflowItems() : Array { - return this.items.reduce((result, item) => { - const first = this.shadowRoot!.querySelector(".ui5-sn-item-separator:first-child") as HTMLElement; - const last = this.shadowRoot!.querySelector(".ui5-sn-item-separator:last-child") as HTMLElement; - return result.concat([first, ...item.overflowItems, last]); + const separator1 = this.shadowRoot!.querySelector(".ui5-sn-item-separator:first-child") as HTMLElement; + const separator2 = this.shadowRoot!.querySelector(".ui5-sn-item-separator:last-child") as HTMLElement; + + const overflowItems = this.items.reduce((result, item) => { + return result.concat(item.overflowItems); }, new Array()); + + return [separator1, ...overflowItems, separator2]; } get selectableItems() : Array { From 45f8b27fc0c64f1b1d625f82613a82198eb32c47 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Wed, 21 Feb 2024 14:04:52 +0200 Subject: [PATCH 28/44] feat(ui5-side-navigation): focus handling --- packages/fiori/src/SideNavigation.ts | 15 ++++++++------- packages/fiori/src/SideNavigationItemBase.ts | 16 +++++++--------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index 999df5a4a847..77e78ad98de6 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -233,14 +233,10 @@ class SideNavigation extends UI5Element { onBeforeRendering() { super.onBeforeRendering(); - this._getAllItems(this.items).forEach(item => { - item.sideNavCollapsed = this.collapsed; - item.inPopover = this.inPopover; - }); - - this._getAllItems(this.fixedItems).forEach(item => { + this._getAllItems(this.items).concat(this._getAllItems(this.fixedItems)).forEach(item => { item.sideNavCollapsed = this.collapsed; item.inPopover = this.inPopover; + item.sideNavigation = this; }); } @@ -642,7 +638,12 @@ class SideNavigation extends UI5Element { } get _overflowItem() { - return this.shadowRoot!.querySelector(".ui5-sn-item-overflow"); + const overflowItem = this.shadowRoot!.querySelector(".ui5-sn-item-overflow"); + if (overflowItem) { + overflowItem.sideNavigation = this; + } + + return overflowItem; } get isOverflow() { diff --git a/packages/fiori/src/SideNavigationItemBase.ts b/packages/fiori/src/SideNavigationItemBase.ts index 63347a28c8d9..8cfba8919cae 100644 --- a/packages/fiori/src/SideNavigationItemBase.ts +++ b/packages/fiori/src/SideNavigationItemBase.ts @@ -54,6 +54,8 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { @property({ type: Boolean }) inPopover!: boolean; + _sideNavigation!: SideNavigation; + get _tooltip() { return this.title || this.text; } @@ -80,16 +82,12 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { return this.forcedTabIndex; } - get sideNavigation() : SideNavigation | undefined { - let parentElement = this.parentElement; - - while (parentElement) { - if (parentElement.hasAttribute("ui5-side-navigation")) { - return parentElement as SideNavigation; - } + get sideNavigation() { + return this._sideNavigation; + } - parentElement = parentElement.parentElement; - } + set sideNavigation(sideNavigation) { + this._sideNavigation = sideNavigation; } get isFixedItem() { From 1a6867892f6073e65b409372199d4614135b2824 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Wed, 21 Feb 2024 17:23:07 +0200 Subject: [PATCH 29/44] feat(ui5-side-navigation): improve item navigation --- packages/fiori/src/SideNavigation.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index 77e78ad98de6..a11541f17a8d 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -399,11 +399,13 @@ class SideNavigation extends UI5Element { } getEnabledFlexibleItems() : Array { - if (!this._overflowItem) { - return this.getEnabledItems(this.items); + const items = this.getEnabledItems(this.items); + + if (this._overflowItem) { + items.push(this._overflowItem); } - return [...this.getEnabledItems(this.items), this._overflowItem]; + return items; } getEnabledItems(items: Array) : Array { @@ -538,6 +540,8 @@ class SideNavigation extends UI5Element { item.classList.add("ui5-sn-item-hidden"); } }); + + this._flexibleItemNavigation._init(); } _findFocusedItem(items: Array) : SideNavigationItemBase | undefined { From f9149f4e5dea78178a8d60ca65d53320a78b8181 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Thu, 22 Feb 2024 11:12:54 +0200 Subject: [PATCH 30/44] feat(ui5-side-navigation): fix item navigation --- packages/fiori/src/SideNavigation.ts | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index a11541f17a8d..3104ff2acaa8 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -433,28 +433,30 @@ class SideNavigation extends UI5Element { } onAfterRendering() { - const activeElement = document.activeElement as SideNavigationItemBase; - if (this._getAllItems(this.items).indexOf(activeElement) === -1) { + const shadowRootActiveElement = this.shadowRoot!.activeElement; + if (shadowRootActiveElement instanceof SideNavigationItem && shadowRootActiveElement.isOverflow) { + return; + } + + let activeElement = document.activeElement; + + if (activeElement + && !(activeElement instanceof SideNavigationItemBase) + && activeElement.shadowRoot) { + activeElement = activeElement.shadowRoot.activeElement; + } + + if (!(activeElement instanceof SideNavigationItemBase) || this._getAllItems(this.items).indexOf(activeElement) === -1) { const selectedItem = this._findSelectedItem(this.items); if (selectedItem) { this._flexibleItemNavigation.setCurrentItem(selectedItem); - } else { - const focusedItem = this._findFocusedItem(this.items); - if (!focusedItem) { - this._flexibleItemNavigation.setCurrentItem(this.items[0]); - } } } - if (this._getAllItems(this.fixedItems).indexOf(activeElement) === -1) { + if (!(activeElement instanceof SideNavigationItemBase) || this._getAllItems(this.fixedItems).indexOf(activeElement) === -1) { const selectedItem = this._findSelectedItem(this.fixedItems); if (selectedItem) { this._fixedItemNavigation.setCurrentItem(selectedItem); - } else { - const focusedItem = this._findFocusedItem(this.fixedItems); - if (!focusedItem) { - this._fixedItemNavigation.setCurrentItem(this.fixedItems[0]); - } } } From bf8be5060733992ef566e9ecb84a694f18b6b736 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Fri, 23 Feb 2024 09:13:23 +0200 Subject: [PATCH 31/44] feat(ui5-side-navigation): tests --- .../fiori/test/specs/SideNavigation.spec.js | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/fiori/test/specs/SideNavigation.spec.js b/packages/fiori/test/specs/SideNavigation.spec.js index e53726533a32..2050a24f1330 100644 --- a/packages/fiori/test/specs/SideNavigation.spec.js +++ b/packages/fiori/test/specs/SideNavigation.spec.js @@ -2,7 +2,7 @@ import { assert } from "chai"; async function getTreeItemsInPopover() { const staticAreaItemClassName = await browser.getStaticAreaItemClassName("#sn1"); - const items = await browser.$$(`>>>.${staticAreaItemClassName} ui5-responsive-popover .ui5-sn-item`); + const items = await browser.$$(`.${staticAreaItemClassName} [ui5-side-navigation-item], .${staticAreaItemClassName} [ui5-side-navigation-sub-item]`); return items; } @@ -23,8 +23,10 @@ describe("Component Behavior", () => { it("Tests selection-change event", async () => { const input = await browser.$("#counter"); const sideNavigation = await browser.$("#sn1"); - let items = await sideNavigation.shadow$$(".ui5-sn-flexible .ui5-sn-item"); - const fixedItems = await sideNavigation.shadow$$(".ui5-sn-fixed .ui5-sn-item"); + let items = await browser.$$("#sn1 [ui5-side-navigation-item]:not([slot='fixedItems']), #sn1 [ui5-side-navigation-item]:not([slot='fixedItems']) [ui5-side-navigation-sub-item]"); + const fixedItems = await browser.$$("#sn1 [slot='fixedItems'], #sn1 [slot='fixedItems'] [ui5-side-navigation-sub-item]"); + + await browser.debug(); await items[0].click(); await items[3].click(); @@ -36,7 +38,6 @@ describe("Component Behavior", () => { assert.strictEqual(await input.getProperty("value"), "3", "Event is fired"); await sideNavigation.setAttribute("collapsed", "true"); - items = await sideNavigation.shadow$$(".ui5-sn-flexible .ui5-sn-item"); await items[0].click(); @@ -58,7 +59,7 @@ describe("Component Behavior", () => { it("Tests click event & whole-item-toggleable property", async () => { const input = await browser.$("#click-counter"); const sideNavigation = await browser.$("ui5-side-navigation"); - let items = await sideNavigation.shadow$$(".ui5-sn-flexible .ui5-sn-item-level1"); + let items = await browser.$$("#sn1 [ui5-side-navigation-item]:not([slot='fixedItems'])"); await items[0].click(); @@ -92,7 +93,7 @@ describe("Component Behavior", () => { it("Tests tooltips when expanded", async () => { const sideNavigation = await browser.$("#sn1"); - const renderedItems = await sideNavigation.shadow$$(".ui5-sn-item"); + const renderedItems = await browser.$$("#sn1 [ui5-side-navigation-item], #sn1 [ui5-side-navigation-item] [ui5-side-navigation-sub-item]"); // items assert.strictEqual(await renderedItems[0].getAttribute("title"), await browser.$("#item1").getAttribute("title"), "Title is set as tooltip to root item"); @@ -107,7 +108,7 @@ describe("Component Behavior", () => { await browser.$("#sn1").setProperty("collapsed", true); const sideNavigation = await browser.$("#sn1"); - const renderedItems = await sideNavigation.shadow$$(".ui5-sn-item"); + const renderedItems = await browser.$$("#sn1 [ui5-side-navigation-item], #sn1 [ui5-side-navigation-item] [ui5-side-navigation-sub-item]"); assert.strictEqual(await renderedItems[0].getAttribute("title"), await browser.$("#item1").getAttribute("title"), "Title is set as tooltip to root item"); assert.strictEqual(await renderedItems[1].getAttribute("title"), await browser.$("#item2").getAttribute("text"), "Text is set as tooltip to root item when title is not specified"); @@ -125,7 +126,7 @@ describe("Component Behavior", () => { it("tests the prevention of the ui5-selection-change event", async () => { const sideNavigation = await browser.$("#sn1"); - const items = await sideNavigation.shadow$$(".ui5-sn-item"); + const items = await browser.$$("#sn1 [ui5-side-navigation-item], #sn1 [ui5-side-navigation-item] [ui5-side-navigation-sub-item]"); await items[3].click(); @@ -151,7 +152,7 @@ describe("Component Behavior", () => { await sideNavigation.setAttribute("collapsed", "true"); const input = await browser.$("#counter"); - const items = await sideNavigation.shadow$$(".ui5-sn-item"); + const items = await browser.$$("#sn1 [ui5-side-navigation-item], #sn1 [ui5-side-navigation-item] [ui5-side-navigation-sub-item]"); await items[0].click(); @@ -173,8 +174,8 @@ describe("Component Behavior", () => { const sideNavigationTree = await sideNavigation.shadow$(".ui5-sn-flexible"); const sideNavigationFixedTree = await sideNavigation.shadow$(".ui5-sn-fixed"); - const items = await sideNavigation.shadow$$(".ui5-sn-flexible .ui5-sn-item"); - const fixedItems = await sideNavigation.shadow$$(".ui5-sn-fixed .ui5-sn-item"); + let items = await browser.$$("#sn1 [ui5-side-navigation-item]:not([slot='fixedItems']), #sn1 [ui5-side-navigation-item]:not([slot='fixedItems']) [ui5-side-navigation-sub-item]"); + const fixedItems = await browser.$$("#sn1 [slot='fixedItems'], #sn1 [slot='fixedItems'] [ui5-side-navigation-sub-item]"); assert.strictEqual(await sideNavigationRoot.getTagName(), "nav", "tag name of the SideNavigation root element is correctly set"); @@ -208,8 +209,8 @@ describe("Component Behavior", () => { const sideNavigationTree = await sideNavigation.shadow$(".ui5-sn-flexible"); const sideNavigationFixedTree = await sideNavigation.shadow$(".ui5-sn-fixed"); - const items = await sideNavigation.shadow$$(".ui5-sn-flexible .ui5-sn-item"); - const fixedItems = await sideNavigation.shadow$$(".ui5-sn-fixed .ui5-sn-item"); + let items = await browser.$$("#sn1 [ui5-side-navigation-item]:not([slot='fixedItems']), #sn1 [ui5-side-navigation-item]:not([slot='fixedItems']) [ui5-side-navigation-sub-item]"); + const fixedItems = await browser.$$("#sn1 [slot='fixedItems'], #sn1 [slot='fixedItems'] [ui5-side-navigation-sub-item]"); assert.strictEqual(await sideNavigationRoot.getTagName(), "nav", "tag name of the SideNavigation root element is correctly set"); From 0fb12d2ad287465a8558dea60f77455f496e9493 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Fri, 23 Feb 2024 12:07:04 +0200 Subject: [PATCH 32/44] feat(ui5-side-navigation): tests --- .../fiori/test/specs/SideNavigation.spec.js | 81 ++++++++++--------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/packages/fiori/test/specs/SideNavigation.spec.js b/packages/fiori/test/specs/SideNavigation.spec.js index 2050a24f1330..f523f68b742f 100644 --- a/packages/fiori/test/specs/SideNavigation.spec.js +++ b/packages/fiori/test/specs/SideNavigation.spec.js @@ -2,7 +2,14 @@ import { assert } from "chai"; async function getTreeItemsInPopover() { const staticAreaItemClassName = await browser.getStaticAreaItemClassName("#sn1"); - const items = await browser.$$(`.${staticAreaItemClassName} [ui5-side-navigation-item], .${staticAreaItemClassName} [ui5-side-navigation-sub-item]`); + const items = await browser.$$(`>>>.${staticAreaItemClassName} [ui5-side-navigation-item], .${staticAreaItemClassName} [ui5-side-navigation-sub-item]`); + + return items; +} + +async function getRenderedTreeItemsInPopover() { + const staticAreaItemClassName = await browser.getStaticAreaItemClassName("#sn1"); + const items = await browser.$$(`>>>.${staticAreaItemClassName} .ui5-sn-item`); return items; } @@ -26,8 +33,6 @@ describe("Component Behavior", () => { let items = await browser.$$("#sn1 [ui5-side-navigation-item]:not([slot='fixedItems']), #sn1 [ui5-side-navigation-item]:not([slot='fixedItems']) [ui5-side-navigation-sub-item]"); const fixedItems = await browser.$$("#sn1 [slot='fixedItems'], #sn1 [slot='fixedItems'] [ui5-side-navigation-sub-item]"); - await browser.debug(); - await items[0].click(); await items[3].click(); @@ -58,19 +63,20 @@ describe("Component Behavior", () => { it("Tests click event & whole-item-toggleable property", async () => { const input = await browser.$("#click-counter"); - const sideNavigation = await browser.$("ui5-side-navigation"); - let items = await browser.$$("#sn1 [ui5-side-navigation-item]:not([slot='fixedItems'])"); - await items[0].click(); + await browser.$("#item1").click(); assert.strictEqual(await input.getProperty("value"), "6", "Event is fired"); - await items[3].click(); + const item = await browser.$("#item21"); + await item.click(); + + const itemRef = await item.shadow$(".ui5-sn-item"); assert.strictEqual(await input.getProperty("value"), "6", "Event is not fired"); - assert.strictEqual(await items[3].getAttribute("aria-expanded"), "true" ,"Expanded is toggled"); + assert.strictEqual(await itemRef.getAttribute("aria-expanded"), "true" ,"Expanded is toggled"); - await items[1].click(); + await browser.$("#item2").click(); assert.strictEqual(await input.getProperty("value"), "7", "Event is fired"); }); @@ -93,7 +99,7 @@ describe("Component Behavior", () => { it("Tests tooltips when expanded", async () => { const sideNavigation = await browser.$("#sn1"); - const renderedItems = await browser.$$("#sn1 [ui5-side-navigation-item], #sn1 [ui5-side-navigation-item] [ui5-side-navigation-sub-item]"); + const renderedItems = await browser.$$(">>>#sn1 .ui5-sn-item"); // items assert.strictEqual(await renderedItems[0].getAttribute("title"), await browser.$("#item1").getAttribute("title"), "Title is set as tooltip to root item"); @@ -107,15 +113,14 @@ describe("Component Behavior", () => { it("Tests tooltips when collapsed", async () => { await browser.$("#sn1").setProperty("collapsed", true); - const sideNavigation = await browser.$("#sn1"); - const renderedItems = await browser.$$("#sn1 [ui5-side-navigation-item], #sn1 [ui5-side-navigation-item] [ui5-side-navigation-sub-item]"); + const renderedItems = await browser.$$(">>>#sn1 .ui5-sn-item"); - assert.strictEqual(await renderedItems[0].getAttribute("title"), await browser.$("#item1").getAttribute("title"), "Title is set as tooltip to root item"); - assert.strictEqual(await renderedItems[1].getAttribute("title"), await browser.$("#item2").getAttribute("text"), "Text is set as tooltip to root item when title is not specified"); + assert.strictEqual(await renderedItems[1].getAttribute("title"), await browser.$("#item1").getAttribute("title"), "Title is set as tooltip to root item"); + assert.strictEqual(await renderedItems[2].getAttribute("title"), await browser.$("#item2").getAttribute("text"), "Text is set as tooltip to root item when title is not specified"); - await renderedItems[1].click(); + await browser.$("#item2").click(); - const popoverItems = await getTreeItemsInPopover(); + const popoverItems = await getRenderedTreeItemsInPopover(); assert.strictEqual(await popoverItems[0].getAttribute("title"), await browser.$("#item2").getAttribute("text"), "Text is set as tooltip to sub item when title is not specified"); assert.strictEqual(await popoverItems[1].getAttribute("title"), await browser.$("#item21").getAttribute("title"), "Title is set as tooltip to sub item"); @@ -125,24 +130,23 @@ describe("Component Behavior", () => { }); it("tests the prevention of the ui5-selection-change event", async () => { - const sideNavigation = await browser.$("#sn1"); - const items = await browser.$$("#sn1 [ui5-side-navigation-item], #sn1 [ui5-side-navigation-item] [ui5-side-navigation-sub-item]"); + const renderedItems = await browser.$$(">>>#sn1 .ui5-sn-item"); - await items[3].click(); + await browser.$("#item21").click(); assert.ok(await browser.$("#item22").getProperty("selected"), "new item is selected"); - assert.strictEqual(await items[3].getAttribute("aria-current"), "page", "aria-current is set"); + assert.strictEqual(await renderedItems[3].getAttribute("aria-current"), "page", "aria-current is set"); const selectionChangeCheckbox = await browser.$("#prevent-selection"); await selectionChangeCheckbox.click(); - await items[0].click(); + await browser.$("#item1").click(); assert.notOk(await browser.$("#item1").getProperty("selected"), "new item is not selected"); - assert.notExists(await items[0].getAttribute("aria-current"), "aria-current is not changed"); + assert.notExists(await renderedItems[0].getAttribute("aria-current"), "aria-current is not changed"); assert.ok(await browser.$("#item22").getProperty("selected"), "initially selected item has not changed"); - assert.strictEqual(await items[3].getAttribute("aria-current"), "page", "aria-current is not changed"); + assert.strictEqual(await renderedItems[3].getAttribute("aria-current"), "page", "aria-current is not changed"); await selectionChangeCheckbox.click(); }); @@ -152,7 +156,7 @@ describe("Component Behavior", () => { await sideNavigation.setAttribute("collapsed", "true"); const input = await browser.$("#counter"); - const items = await browser.$$("#sn1 [ui5-side-navigation-item], #sn1 [ui5-side-navigation-item] [ui5-side-navigation-sub-item]"); + const items = await browser.$$("#sn1 [ui5-side-navigation-item]"); await items[0].click(); @@ -174,8 +178,7 @@ describe("Component Behavior", () => { const sideNavigationTree = await sideNavigation.shadow$(".ui5-sn-flexible"); const sideNavigationFixedTree = await sideNavigation.shadow$(".ui5-sn-fixed"); - let items = await browser.$$("#sn1 [ui5-side-navigation-item]:not([slot='fixedItems']), #sn1 [ui5-side-navigation-item]:not([slot='fixedItems']) [ui5-side-navigation-sub-item]"); - const fixedItems = await browser.$$("#sn1 [slot='fixedItems'], #sn1 [slot='fixedItems'] [ui5-side-navigation-sub-item]"); + let items = await browser.$$(">>>#sn1 .ui5-sn-item"); assert.strictEqual(await sideNavigationRoot.getTagName(), "nav", "tag name of the SideNavigation root element is correctly set"); @@ -192,8 +195,8 @@ describe("Component Behavior", () => { // fixed items assert.strictEqual(await sideNavigationFixedTree.getAttribute("aria-roledescription"), roleDescription, "Role description of the SideNavigation fixed tree element is correctly set"); - assert.notExists(await fixedItems[0].getAttribute("aria-roledescription"), "Role description of the SideNavigation fixed tree item is not set"); - assert.notExists(await fixedItems[0].getAttribute("aria-haspopup"), "There is no 'aria-haspopup'"); + assert.notExists(await items[13].getAttribute("aria-roledescription"), "Role description of the SideNavigation fixed tree item is not set"); + assert.notExists(await items[13].getAttribute("aria-haspopup"), "There is no 'aria-haspopup'"); }); it("Tests ACC roles and more when collapsed", async () => { @@ -209,8 +212,7 @@ describe("Component Behavior", () => { const sideNavigationTree = await sideNavigation.shadow$(".ui5-sn-flexible"); const sideNavigationFixedTree = await sideNavigation.shadow$(".ui5-sn-fixed"); - let items = await browser.$$("#sn1 [ui5-side-navigation-item]:not([slot='fixedItems']), #sn1 [ui5-side-navigation-item]:not([slot='fixedItems']) [ui5-side-navigation-sub-item]"); - const fixedItems = await browser.$$("#sn1 [slot='fixedItems'], #sn1 [slot='fixedItems'] [ui5-side-navigation-sub-item]"); + let items = await browser.$$(">>>#sn1 .ui5-sn-item"); assert.strictEqual(await sideNavigationRoot.getTagName(), "nav", "tag name of the SideNavigation root element is correctly set"); @@ -220,18 +222,18 @@ describe("Component Behavior", () => { }); assert.strictEqual(await sideNavigationTree.getAttribute("aria-roledescription"), roleDescription, "Role description of the SideNavigation tree element is correctly set"); - assert.notExists(await items[0].getAttribute("aria-roledescription"), "Role description of the SideNavigation tree item is not set"); - assert.notExists(await items[0].getAttribute("aria-haspopup"), "There is no 'aria-haspopup'"); - assert.strictEqual(await items[1].getAttribute("aria-haspopup"), "tree", "There is 'aria-haspopup' with correct value"); + assert.notExists(await items[1].getAttribute("aria-roledescription"), "Role description of the SideNavigation tree item is not set"); + assert.notExists(await items[1].getAttribute("aria-haspopup"), "There is no 'aria-haspopup'"); + assert.strictEqual(await items[2].getAttribute("aria-haspopup"), "tree", "There is 'aria-haspopup' with correct value"); // fixed items assert.strictEqual(await sideNavigationFixedTree.getAttribute("aria-roledescription"), roleDescription, "Role description of the SideNavigation fixed tree element is correctly set"); - assert.notExists(await fixedItems[0].getAttribute("aria-roledescription"), "Role description of the SideNavigation fixed tree item is not set"); - assert.strictEqual(await fixedItems[0].getAttribute("aria-haspopup"), "tree", "There is 'aria-haspopup' with correct value"); - assert.notExists(await fixedItems[1].getAttribute("aria-haspopup"), "There is no 'aria-haspopup'"); + assert.notExists(await items[8].getAttribute("aria-roledescription"), "Role description of the SideNavigation fixed tree item is not set"); + assert.strictEqual(await items[8].getAttribute("aria-haspopup"), "tree", "There is 'aria-haspopup' with correct value"); + assert.notExists(await items[9].getAttribute("aria-haspopup"), "There is no 'aria-haspopup'"); // popup - await items[1].click(); + await browser.$("#item2").click(); const popoverRootItem = await getRootItemInPopover(); @@ -268,10 +270,9 @@ describe("Component Behavior", () => { }); it("Tests external link items", async () => { - const sideNavigation = await browser.$("#sn1"); - const items = await sideNavigation.shadow$$(".ui5-sn-flexible .ui5-sn-item"); + const item = await browser.$("#externalLinkItem"); - assert.ok(await items[4].$(".ui5-sn-item-external-link-icon").isExisting(), "External link icon is rendered"); + assert.ok(await item.shadow$(".ui5-sn-item-external-link-icon").isExisting(), "External link icon is rendered"); }); }); }); From 8dc8023f85aa9a96fbc0c3aa97882091f3e40e7a Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Fri, 23 Feb 2024 12:55:50 +0200 Subject: [PATCH 33/44] feat(ui5-side-navigation): tests --- packages/fiori/test/pages/SideNavigation.html | 4 ++-- packages/fiori/test/specs/SideNavigation.spec.js | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/fiori/test/pages/SideNavigation.html b/packages/fiori/test/pages/SideNavigation.html index 3249a7651619..4670d89372ad 100644 --- a/packages/fiori/test/pages/SideNavigation.html +++ b/packages/fiori/test/pages/SideNavigation.html @@ -43,13 +43,13 @@ - + - + diff --git a/packages/fiori/test/specs/SideNavigation.spec.js b/packages/fiori/test/specs/SideNavigation.spec.js index f523f68b742f..20826b2d3d7d 100644 --- a/packages/fiori/test/specs/SideNavigation.spec.js +++ b/packages/fiori/test/specs/SideNavigation.spec.js @@ -68,7 +68,7 @@ describe("Component Behavior", () => { assert.strictEqual(await input.getProperty("value"), "6", "Event is fired"); - const item = await browser.$("#item21"); + const item = await browser.$("#item3"); await item.click(); const itemRef = await item.shadow$(".ui5-sn-item"); @@ -134,8 +134,8 @@ describe("Component Behavior", () => { await browser.$("#item21").click(); - assert.ok(await browser.$("#item22").getProperty("selected"), "new item is selected"); - assert.strictEqual(await renderedItems[3].getAttribute("aria-current"), "page", "aria-current is set"); + assert.ok(await browser.$("#item21").getProperty("selected"), "new item is selected"); + assert.strictEqual(await renderedItems[2].getAttribute("aria-current"), "page", "aria-current is set"); const selectionChangeCheckbox = await browser.$("#prevent-selection"); await selectionChangeCheckbox.click(); @@ -145,8 +145,8 @@ describe("Component Behavior", () => { assert.notOk(await browser.$("#item1").getProperty("selected"), "new item is not selected"); assert.notExists(await renderedItems[0].getAttribute("aria-current"), "aria-current is not changed"); - assert.ok(await browser.$("#item22").getProperty("selected"), "initially selected item has not changed"); - assert.strictEqual(await renderedItems[3].getAttribute("aria-current"), "page", "aria-current is not changed"); + assert.ok(await browser.$("#item21").getProperty("selected"), "initially selected item has not changed"); + assert.strictEqual(await renderedItems[2].getAttribute("aria-current"), "page", "aria-current is not changed"); await selectionChangeCheckbox.click(); }); From 2db34ff54a7c3163b5e1e79a57303a1f7163720f Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Fri, 23 Feb 2024 13:43:25 +0200 Subject: [PATCH 34/44] feat(ui5-side-navigation): tests --- .../fiori/test/specs/SideNavigation.spec.js | 46 +++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/packages/fiori/test/specs/SideNavigation.spec.js b/packages/fiori/test/specs/SideNavigation.spec.js index 20826b2d3d7d..8e3a2c8b283d 100644 --- a/packages/fiori/test/specs/SideNavigation.spec.js +++ b/packages/fiori/test/specs/SideNavigation.spec.js @@ -30,29 +30,27 @@ describe("Component Behavior", () => { it("Tests selection-change event", async () => { const input = await browser.$("#counter"); const sideNavigation = await browser.$("#sn1"); - let items = await browser.$$("#sn1 [ui5-side-navigation-item]:not([slot='fixedItems']), #sn1 [ui5-side-navigation-item]:not([slot='fixedItems']) [ui5-side-navigation-sub-item]"); - const fixedItems = await browser.$$("#sn1 [slot='fixedItems'], #sn1 [slot='fixedItems'] [ui5-side-navigation-sub-item]"); - await items[0].click(); - await items[3].click(); + await browser.$("#item1").click(); + await browser.$("#item21").click(); assert.strictEqual(await input.getProperty("value"), "2", "Event is fired"); - await fixedItems[0].click(); + await browser.$("#fixedItem1").click(); assert.strictEqual(await input.getProperty("value"), "3", "Event is fired"); await sideNavigation.setAttribute("collapsed", "true"); - await items[0].click(); + await browser.$("#item1").click(); assert.strictEqual(await input.getProperty("value"), "4", "Event is fired"); - await items[1].click(); + await browser.$("#item2").click(); assert.strictEqual(await input.getProperty("value"), "4", "Event is not fired"); - items = await getTreeItemsInPopover(); + let items = await getTreeItemsInPopover(); await items[1].click(); @@ -69,6 +67,7 @@ describe("Component Behavior", () => { assert.strictEqual(await input.getProperty("value"), "6", "Event is fired"); const item = await browser.$("#item3"); + await item.scrollIntoView(); await item.click(); const itemRef = await item.shadow$(".ui5-sn-item"); @@ -76,6 +75,7 @@ describe("Component Behavior", () => { assert.strictEqual(await input.getProperty("value"), "6", "Event is not fired"); assert.strictEqual(await itemRef.getAttribute("aria-expanded"), "true" ,"Expanded is toggled"); + await browser.$("#item2").scrollIntoView(); await browser.$("#item2").click(); assert.strictEqual(await input.getProperty("value"), "7", "Event is fired"); }); @@ -98,25 +98,24 @@ describe("Component Behavior", () => { }); it("Tests tooltips when expanded", async () => { - const sideNavigation = await browser.$("#sn1"); - const renderedItems = await browser.$$(">>>#sn1 .ui5-sn-item"); + const items = await browser.$$(">>>#sn1 .ui5-sn-item"); // items - assert.strictEqual(await renderedItems[0].getAttribute("title"), await browser.$("#item1").getAttribute("title"), "Title is set as tooltip to root item"); - assert.strictEqual(await renderedItems[1].getAttribute("title"), await browser.$("#item2").getAttribute("text"), "Text is set as tooltip to root item when title is not specified"); + assert.strictEqual(await items[0].getAttribute("title"), await browser.$("#item1").getAttribute("title"), "Title is set as tooltip to root item"); + assert.strictEqual(await items[1].getAttribute("title"), await browser.$("#item2").getAttribute("text"), "Text is set as tooltip to root item when title is not specified"); // sub items - assert.strictEqual(await renderedItems[2].getAttribute("title"), await browser.$("#item21").getAttribute("title"), "Title is set as tooltip to sub item"); - assert.strictEqual(await renderedItems[3].getAttribute("title"), await browser.$("#item22").getAttribute("text"), "Text is set as tooltip to sub item when title is not specified"); + assert.strictEqual(await items[2].getAttribute("title"), await browser.$("#item21").getAttribute("title"), "Title is set as tooltip to sub item"); + assert.strictEqual(await items[3].getAttribute("title"), await browser.$("#item22").getAttribute("text"), "Text is set as tooltip to sub item when title is not specified"); }); it("Tests tooltips when collapsed", async () => { await browser.$("#sn1").setProperty("collapsed", true); - const renderedItems = await browser.$$(">>>#sn1 .ui5-sn-item"); + const items = await browser.$$(">>>#sn1 .ui5-sn-item"); - assert.strictEqual(await renderedItems[1].getAttribute("title"), await browser.$("#item1").getAttribute("title"), "Title is set as tooltip to root item"); - assert.strictEqual(await renderedItems[2].getAttribute("title"), await browser.$("#item2").getAttribute("text"), "Text is set as tooltip to root item when title is not specified"); + assert.strictEqual(await items[1].getAttribute("title"), await browser.$("#item1").getAttribute("title"), "Title is set as tooltip to root item"); + assert.strictEqual(await items[2].getAttribute("title"), await browser.$("#item2").getAttribute("text"), "Text is set as tooltip to root item when title is not specified"); await browser.$("#item2").click(); @@ -130,12 +129,12 @@ describe("Component Behavior", () => { }); it("tests the prevention of the ui5-selection-change event", async () => { - const renderedItems = await browser.$$(">>>#sn1 .ui5-sn-item"); + const items = await browser.$$(">>>#sn1 .ui5-sn-item"); await browser.$("#item21").click(); assert.ok(await browser.$("#item21").getProperty("selected"), "new item is selected"); - assert.strictEqual(await renderedItems[2].getAttribute("aria-current"), "page", "aria-current is set"); + assert.strictEqual(await items[2].getAttribute("aria-current"), "page", "aria-current is set"); const selectionChangeCheckbox = await browser.$("#prevent-selection"); await selectionChangeCheckbox.click(); @@ -143,10 +142,10 @@ describe("Component Behavior", () => { await browser.$("#item1").click(); assert.notOk(await browser.$("#item1").getProperty("selected"), "new item is not selected"); - assert.notExists(await renderedItems[0].getAttribute("aria-current"), "aria-current is not changed"); + assert.notExists(await items[0].getAttribute("aria-current"), "aria-current is not changed"); assert.ok(await browser.$("#item21").getProperty("selected"), "initially selected item has not changed"); - assert.strictEqual(await renderedItems[2].getAttribute("aria-current"), "page", "aria-current is not changed"); + assert.strictEqual(await items[2].getAttribute("aria-current"), "page", "aria-current is not changed"); await selectionChangeCheckbox.click(); }); @@ -156,13 +155,12 @@ describe("Component Behavior", () => { await sideNavigation.setAttribute("collapsed", "true"); const input = await browser.$("#counter"); - const items = await browser.$$("#sn1 [ui5-side-navigation-item]"); - await items[0].click(); + await browser.$("#item1").click(); const beforeClickingSelectedItem = await input.getProperty("value"); - await items[0].click(); + await browser.$("#item1").click(); const afterClickingSelectedItem = await input.getProperty("value"); From ee096a29fdb47a19b26562321f3d6dca4ce2bad7 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Fri, 23 Feb 2024 14:50:21 +0200 Subject: [PATCH 35/44] feat(ui5-side-navigation): tests --- .../test/pages/SideNavigationWithGroups.html | 10 +++---- .../specs/SideNavigationWithGroups.spec.js | 27 +++++++++++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 packages/fiori/test/specs/SideNavigationWithGroups.spec.js diff --git a/packages/fiori/test/pages/SideNavigationWithGroups.html b/packages/fiori/test/pages/SideNavigationWithGroups.html index c323f5cae60b..981dfdab2b8c 100644 --- a/packages/fiori/test/pages/SideNavigationWithGroups.html +++ b/packages/fiori/test/pages/SideNavigationWithGroups.html @@ -9,11 +9,11 @@ - - - - - + + { + before(async () => { + await browser.url(`test/pages/SideNavigationWithGroups.html`); + }); + + describe("Main functionality", async () => { + it("collapse/expand", async () => { + const sideNavigation = await browser.$("#sn1"); + + assert.ok(await browser.$("#group1").getProperty("expanded"), "Group is expanded"); + + await browser.$("#group1").shadow$(".ui5-sn-item").click(); + assert.notOk(await browser.$("#group1").getProperty("expanded"), "Group is collapsed"); + + await browser.$("#group1").shadow$(".ui5-sn-item").click(); + assert.ok(await browser.$("#group1").getProperty("expanded"), "Group is expanded"); + + await sideNavigation.setAttribute("collapsed", "true"); + assert.notOk(await browser.$("#group1").shadow$(".ui5-sn-item").isExisting(), 'group item is not rendered'); + + await sideNavigation.removeAttribute("collapsed"); + }); + }); +}); From c2384c18c192ed0ba185a2689238199705176f5b Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Mon, 26 Feb 2024 11:00:08 +0200 Subject: [PATCH 36/44] feat(ui5-side-navigation): texts, documentations, examples --- packages/fiori/src/SideNavigation.ts | 10 ++- packages/fiori/src/SideNavigationGroup.ts | 7 +- packages/fiori/src/SideNavigationItem.ts | 5 +- packages/fiori/src/SideNavigationSubItem.ts | 1 + .../specs/SideNavigationWithGroups.spec.js | 16 +++-- .../SideNavigation/SideNavigation.stories.ts | 64 ++++++++++--------- .../SideNavigationGroup.stories.ts | 35 ++++++++++ 7 files changed, 93 insertions(+), 45 deletions(-) create mode 100644 packages/playground/_stories/fiori/SideNavigation/SideNavigationGroup/SideNavigationGroup.stories.ts diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index 3104ff2acaa8..b387261cab5f 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -22,10 +22,6 @@ import { isEnter, } from "@ui5/webcomponents-base/dist/Keys.js"; import NavigationMode from "@ui5/webcomponents-base/dist/types/NavigationMode.js"; -import Icon from "@ui5/webcomponents/dist/Icon.js"; -import "@ui5/webcomponents-icons/dist/circle-task-2.js"; -import "@ui5/webcomponents-icons/dist/navigation-right-arrow.js"; -import "@ui5/webcomponents-icons/dist/navigation-down-arrow.js"; import SideNavigationItemBase from "./SideNavigationItemBase.js"; import SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase.js"; import SideNavigationItem from "./SideNavigationItem.js"; @@ -85,7 +81,8 @@ type NavigationMenuClickEventDetail = { * *

        Usage

        * - * Use the available ui5-side-navigation-item and ui5-side-navigation-sub-item components to build your menu. + * Use the available ui5-side-navigation-group, ui5-side-navigation-item + * and ui5-side-navigation-sub-item components to build your menu. * The items can consist of text only or an icon with text. The use or non-use of icons must be consistent for all items on one level. * You must not combine entries with and without icons on the same level. We strongly recommend that you do not use icons on the second level. * @@ -101,6 +98,8 @@ type NavigationMenuClickEventDetail = { * * import "@ui5/webcomponents-fiori/dist/SideNavigation.js"; *
        + * import "@ui5/webcomponents-fiori/dist/SideNavigationGroup.js"; (for ui5-side-navigation-group) + *
        * import "@ui5/webcomponents-fiori/dist/SideNavigationItem.js"; (for ui5-side-navigation-item) *
        * import "@ui5/webcomponents-fiori/dist/SideNavigationSubItem.js"; (for ui5-side-navigation-sub-item) @@ -124,7 +123,6 @@ type NavigationMenuClickEventDetail = { SideNavigationGroup, SideNavigationItem, SideNavigationSubItem, - Icon, NavigationMenu, ], }) diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts index 36bc97813034..a943c363afd3 100644 --- a/packages/fiori/src/SideNavigationGroup.ts +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -8,6 +8,8 @@ import { isRight, } from "@ui5/webcomponents-base/dist/Keys.js"; import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; +import "@ui5/webcomponents-icons/dist/navigation-right-arrow.js"; +import "@ui5/webcomponents-icons/dist/navigation-down-arrow.js"; import Icon from "@ui5/webcomponents/dist/Icon.js"; import SideNavigationItemBase from "./SideNavigationItemBase.js"; import SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase.js"; @@ -22,7 +24,8 @@ import SideNavigationItemCss from "./generated/themes/SideNavigationItem.css.js" * *

        Overview

        * - * The ui5-side-navigation-group is intended to be used inside a ui5-side-navigation-group only. + * The ui5-side-navigation-group represents a group of navigation actions, which can be selected by the user. + * The ui5-side-navigation-group is intended to be used inside a ui5-side-navigation only. * *

        ES6 Module Import

        * @@ -32,7 +35,7 @@ import SideNavigationItemCss from "./generated/themes/SideNavigationItem.css.js" * @extends SideNavigationItemBase * @public * @abstract - * @since 1.0.0-rc.8 + * @since 1.24.0 */ @customElement({ tag: "ui5-side-navigation-group", diff --git a/packages/fiori/src/SideNavigationItem.ts b/packages/fiori/src/SideNavigationItem.ts index 190b29509ca1..b324e38000a8 100644 --- a/packages/fiori/src/SideNavigationItem.ts +++ b/packages/fiori/src/SideNavigationItem.ts @@ -3,6 +3,9 @@ import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; import property from "@ui5/webcomponents-base/dist/decorators/property.js"; import slot from "@ui5/webcomponents-base/dist/decorators/slot.js"; import { isLeft, isRight } from "@ui5/webcomponents-base/dist/Keys.js"; +import "@ui5/webcomponents-icons/dist/navigation-right-arrow.js"; +import "@ui5/webcomponents-icons/dist/navigation-down-arrow.js"; +import "@ui5/webcomponents-icons/dist/circle-task-2.js"; import Icon from "@ui5/webcomponents/dist/Icon.js"; import SideNavigationItemBase from "./SideNavigationItemBase.js"; import SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase.js"; @@ -18,7 +21,7 @@ import SideNavigationItemCss from "./generated/themes/SideNavigationItem.css.js" * *

        Overview

        * - * The ui5-side-navigation-item is used within ui5-side-navigation only. + * The ui5-side-navigation-item is used within ui5-side-navigation or ui5-side-navigation-group only. * Via the ui5-side-navigation-item you control the content of the SideNavigation. * *

        ES6 Module Import

        diff --git a/packages/fiori/src/SideNavigationSubItem.ts b/packages/fiori/src/SideNavigationSubItem.ts index 7142de31dc28..ed85a9d41a83 100644 --- a/packages/fiori/src/SideNavigationSubItem.ts +++ b/packages/fiori/src/SideNavigationSubItem.ts @@ -1,6 +1,7 @@ import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; import Icon from "@ui5/webcomponents/dist/Icon.js"; +import "@ui5/webcomponents-icons/dist/circle-task-2.js"; import SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase.js"; import SideNavigationSubItemTemplate from "./generated/templates/SideNavigationSubItemTemplate.lit.js"; diff --git a/packages/fiori/test/specs/SideNavigationWithGroups.spec.js b/packages/fiori/test/specs/SideNavigationWithGroups.spec.js index d718c6f90382..3ef238cda7af 100644 --- a/packages/fiori/test/specs/SideNavigationWithGroups.spec.js +++ b/packages/fiori/test/specs/SideNavigationWithGroups.spec.js @@ -7,9 +7,18 @@ describe("Component Behavior", () => { }); describe("Main functionality", async () => { - it("collapse/expand", async () => { + it("rendering", async () => { const sideNavigation = await browser.$("#sn1"); + assert.ok(await browser.$("#group1").shadow$(".ui5-sn-item").isExisting(), 'group item is rendered'); + + await sideNavigation.setAttribute("collapsed", "true"); + assert.notOk(await browser.$("#group1").shadow$(".ui5-sn-item").isExisting(), 'group item is not rendered'); + + await sideNavigation.removeAttribute("collapsed"); + }); + + it("collapse/expand", async () => { assert.ok(await browser.$("#group1").getProperty("expanded"), "Group is expanded"); await browser.$("#group1").shadow$(".ui5-sn-item").click(); @@ -17,11 +26,6 @@ describe("Component Behavior", () => { await browser.$("#group1").shadow$(".ui5-sn-item").click(); assert.ok(await browser.$("#group1").getProperty("expanded"), "Group is expanded"); - - await sideNavigation.setAttribute("collapsed", "true"); - assert.notOk(await browser.$("#group1").shadow$(".ui5-sn-item").isExisting(), 'group item is not rendered'); - - await sideNavigation.removeAttribute("collapsed"); }); }); }); diff --git a/packages/playground/_stories/fiori/SideNavigation/SideNavigation.stories.ts b/packages/playground/_stories/fiori/SideNavigation/SideNavigation.stories.ts index fa395b015939..c0df03703ee6 100644 --- a/packages/playground/_stories/fiori/SideNavigation/SideNavigation.stories.ts +++ b/packages/playground/_stories/fiori/SideNavigation/SideNavigation.stories.ts @@ -35,21 +35,26 @@ ${story()}`; export const Basic = Template.bind({}); Basic.args = { default: ` - - - - - - - - - + + + + + + + + + + + + + + + + `, + fixedItems: ` - - `, - fixedItems: ` - - `, + + `, }; Basic.decorators = [setHeight]; Basic.parameters = { @@ -65,20 +70,23 @@ Basic.parameters = { export const ToolLayout = Template.bind({}); ToolLayout.args = { default: ` - - - - - - - - + + + + + + + + + + + + + `, + fixedItems: ` - `, - fixedItems: ` - - `, + `, }; ToolLayout.decorators = [ setHeight, @@ -102,10 +110,6 @@ ToolLayout.decorators = [ grid-template-columns: auto 1fr; } - .tool-layout > * { - z-index: 1; - } - ui5-shellbar { grid-column: 1 / span 2; grid-row: 1 / 2; diff --git a/packages/playground/_stories/fiori/SideNavigation/SideNavigationGroup/SideNavigationGroup.stories.ts b/packages/playground/_stories/fiori/SideNavigation/SideNavigationGroup/SideNavigationGroup.stories.ts new file mode 100644 index 000000000000..58e593822b61 --- /dev/null +++ b/packages/playground/_stories/fiori/SideNavigation/SideNavigationGroup/SideNavigationGroup.stories.ts @@ -0,0 +1,35 @@ +import { html } from "lit"; +import { unsafeHTML } from "lit/directives/unsafe-html.js"; +import { ifDefined } from "lit/directives/if-defined.js"; +import type { Meta } from "@storybook/web-components"; +import argTypes from "./argTypes.js"; +import type { StoryArgsSlots } from "./argTypes.js"; +import type { UI5StoryArgs } from "../../../../types.js"; + +import type SideNavigationGroup from "@ui5/webcomponents-fiori/dist/SideNavigationGroup.js"; + +export default { + title: "Fiori/Side Navigation/Side Navigation Group", + component: "SideNavigationGroup", + argTypes, +} as Meta; + +const Template: UI5StoryArgs = (args) => { + return html` + + + ${unsafeHTML(args.default)} + +`; +}; + +export const Basic = Template.bind({}); +Basic.tags = ["_hidden_"]; +Basic.args = { + text: "Group", + expanded: true, + default: `` +}; \ No newline at end of file From b2c46830c7e70011b394670cf634465c60e4ee6e Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Mon, 26 Feb 2024 15:29:39 +0200 Subject: [PATCH 37/44] feat(ui5-side-navigation): code clean, documentation --- packages/fiori/src/SideNavigationGroup.ts | 8 ++++---- packages/fiori/src/SideNavigationItem.ts | 4 ++-- packages/fiori/src/SideNavigationItemBase.ts | 3 +-- packages/fiori/src/SideNavigationSelectableItemBase.ts | 5 ++--- packages/fiori/src/SideNavigationSubItem.ts | 2 +- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts index a943c363afd3..faeb65f341cf 100644 --- a/packages/fiori/src/SideNavigationGroup.ts +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -12,8 +12,8 @@ import "@ui5/webcomponents-icons/dist/navigation-right-arrow.js"; import "@ui5/webcomponents-icons/dist/navigation-down-arrow.js"; import Icon from "@ui5/webcomponents/dist/Icon.js"; import SideNavigationItemBase from "./SideNavigationItemBase.js"; -import SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase.js"; -import SideNavigationItem from "./SideNavigationItem.js"; +import type SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase.js"; +import type SideNavigationItem from "./SideNavigationItem.js"; import SideNavigationGroupTemplate from "./generated/templates/SideNavigationGroupTemplate.lit.js"; // Styles @@ -24,8 +24,8 @@ import SideNavigationItemCss from "./generated/themes/SideNavigationItem.css.js" * *

        Overview

        * - * The ui5-side-navigation-group represents a group of navigation actions, which can be selected by the user. - * The ui5-side-navigation-group is intended to be used inside a ui5-side-navigation only. + * Represents a group of navigation actions. + * The ui5-side-navigation-group can to be used inside a ui5-side-navigation only. * *

        ES6 Module Import

        * diff --git a/packages/fiori/src/SideNavigationItem.ts b/packages/fiori/src/SideNavigationItem.ts index b324e38000a8..eaef912bc6f7 100644 --- a/packages/fiori/src/SideNavigationItem.ts +++ b/packages/fiori/src/SideNavigationItem.ts @@ -7,7 +7,7 @@ import "@ui5/webcomponents-icons/dist/navigation-right-arrow.js"; import "@ui5/webcomponents-icons/dist/navigation-down-arrow.js"; import "@ui5/webcomponents-icons/dist/circle-task-2.js"; import Icon from "@ui5/webcomponents/dist/Icon.js"; -import SideNavigationItemBase from "./SideNavigationItemBase.js"; +import type SideNavigationItemBase from "./SideNavigationItemBase.js"; import SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase.js"; import type SideNavigation from "./SideNavigation.js"; import type SideNavigationSubItem from "./SideNavigationSubItem.js"; @@ -21,8 +21,8 @@ import SideNavigationItemCss from "./generated/themes/SideNavigationItem.css.js" * *

        Overview

        * + * Represents a navigation action. It can provide sub items. * The ui5-side-navigation-item is used within ui5-side-navigation or ui5-side-navigation-group only. - * Via the ui5-side-navigation-item you control the content of the SideNavigation. * *

        ES6 Module Import

        * diff --git a/packages/fiori/src/SideNavigationItemBase.ts b/packages/fiori/src/SideNavigationItemBase.ts index 8cfba8919cae..cf69ba37ab4d 100644 --- a/packages/fiori/src/SideNavigationItemBase.ts +++ b/packages/fiori/src/SideNavigationItemBase.ts @@ -5,8 +5,7 @@ import type SideNavigation from "./SideNavigation.js"; /** * @class - * A class to serve as a foundation - * for the SideNavigationItem and SideNavigationSubItem classes. + * Base class for the items that are accepted by the ui5-side-navigation component. * * @constructor * @extends UI5Element diff --git a/packages/fiori/src/SideNavigationSelectableItemBase.ts b/packages/fiori/src/SideNavigationSelectableItemBase.ts index d4735293cb0a..b1bc8d762db3 100644 --- a/packages/fiori/src/SideNavigationSelectableItemBase.ts +++ b/packages/fiori/src/SideNavigationSelectableItemBase.ts @@ -14,14 +14,13 @@ import SideNavigationItemBase from "./SideNavigationItemBase.js"; /** * @class - * A class to serve as a foundation - * for the SideNavigationItem and SideNavigationSubItem classes. + * Base class for the navigation items that support actions. * * @constructor * @extends UI5Element * @abstract * @public - * @since 1.19.0 + * @since 1.24.0 */ @customElement() class SideNavigationSelectableItemBase extends SideNavigationItemBase { diff --git a/packages/fiori/src/SideNavigationSubItem.ts b/packages/fiori/src/SideNavigationSubItem.ts index ed85a9d41a83..cda62a84289f 100644 --- a/packages/fiori/src/SideNavigationSubItem.ts +++ b/packages/fiori/src/SideNavigationSubItem.ts @@ -12,7 +12,7 @@ import SideNavigationItemCss from "./generated/themes/SideNavigationItem.css.js" * @class * *

        Overview

        - * + * Represents a single navigation action. * The ui5-side-navigation-sub-item is intended to be used inside a ui5-side-navigation-item only. * *

        ES6 Module Import

        From e3ef35d027d56d85fa872cda0b1cd06105c41d5a Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Mon, 26 Feb 2024 16:00:13 +0200 Subject: [PATCH 38/44] feat(ui5-side-navigation): fix item navigation --- packages/fiori/src/SideNavigation.ts | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index b387261cab5f..d7272766df36 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -431,28 +431,13 @@ class SideNavigation extends UI5Element { } onAfterRendering() { - const shadowRootActiveElement = this.shadowRoot!.activeElement; - if (shadowRootActiveElement instanceof SideNavigationItem && shadowRootActiveElement.isOverflow) { - return; - } - - let activeElement = document.activeElement; - - if (activeElement - && !(activeElement instanceof SideNavigationItemBase) - && activeElement.shadowRoot) { - activeElement = activeElement.shadowRoot.activeElement; - } - - if (!(activeElement instanceof SideNavigationItemBase) || this._getAllItems(this.items).indexOf(activeElement) === -1) { - const selectedItem = this._findSelectedItem(this.items); + if (!this.getDomRef()?.matches(":focus-within")) { + let selectedItem = this._findSelectedItem(this.items); if (selectedItem) { this._flexibleItemNavigation.setCurrentItem(selectedItem); } - } - if (!(activeElement instanceof SideNavigationItemBase) || this._getAllItems(this.fixedItems).indexOf(activeElement) === -1) { - const selectedItem = this._findSelectedItem(this.fixedItems); + selectedItem = this._findSelectedItem(this.fixedItems); if (selectedItem) { this._fixedItemNavigation.setCurrentItem(selectedItem); } From 611b489986e859cd9e3b492419d77b51e50c4e00 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Fri, 1 Mar 2024 13:03:35 +0200 Subject: [PATCH 39/44] feat(ui5-side-navigation): fix code review comments --- packages/fiori/src/SideNavigationGroup.hbs | 1 - packages/fiori/src/SideNavigationGroup.ts | 17 ----------------- .../SideNavigationGroup.stories.ts | 2 ++ .../SideNavigationItem.stories.ts | 1 + .../SideNavigationSubItem.stories.ts | 1 + 5 files changed, 4 insertions(+), 18 deletions(-) diff --git a/packages/fiori/src/SideNavigationGroup.hbs b/packages/fiori/src/SideNavigationGroup.hbs index 9bb54f12852b..00fcae89764b 100644 --- a/packages/fiori/src/SideNavigationGroup.hbs +++ b/packages/fiori/src/SideNavigationGroup.hbs @@ -13,7 +13,6 @@ role="treeitem" data-sap-focus-ref @keydown="{{_onkeydown}}" - @keyup="{{_onkeyup}}" @click="{{_onclick}}" @focusin="{{_onfocusin}}" tabindex="{{effectiveTabIndex}}" diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts index faeb65f341cf..801d38ecc5d8 100644 --- a/packages/fiori/src/SideNavigationGroup.ts +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -2,8 +2,6 @@ import property from "@ui5/webcomponents-base/dist/decorators/property.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; import slot from "@ui5/webcomponents-base/dist/decorators/slot.js"; import { - isSpace, - isEnter, isLeft, isRight, } from "@ui5/webcomponents-base/dist/Keys.js"; @@ -137,21 +135,6 @@ class SideNavigationGroup extends SideNavigationItemBase { if (isRight(e)) { this.expanded = true; - return; - } - - if (isSpace(e)) { - e.preventDefault(); - } - - if (isEnter(e)) { - this._toggle(); - } - } - - _onkeyup = (e: KeyboardEvent) => { - if (isSpace(e)) { - this._toggle(); } } diff --git a/packages/playground/_stories/fiori/SideNavigation/SideNavigationGroup/SideNavigationGroup.stories.ts b/packages/playground/_stories/fiori/SideNavigation/SideNavigationGroup/SideNavigationGroup.stories.ts index 58e593822b61..b2a8286cc587 100644 --- a/packages/playground/_stories/fiori/SideNavigation/SideNavigationGroup/SideNavigationGroup.stories.ts +++ b/packages/playground/_stories/fiori/SideNavigation/SideNavigationGroup/SideNavigationGroup.stories.ts @@ -20,6 +20,7 @@ const Template: UI5StoryArgs = (args) => { ${unsafeHTML(args.default)} @@ -31,5 +32,6 @@ Basic.tags = ["_hidden_"]; Basic.args = { text: "Group", expanded: true, + disabled: false, default: `` }; \ No newline at end of file diff --git a/packages/playground/_stories/fiori/SideNavigation/SideNavigationItem/SideNavigationItem.stories.ts b/packages/playground/_stories/fiori/SideNavigation/SideNavigationItem/SideNavigationItem.stories.ts index 24feb168a25c..88dab865d31d 100644 --- a/packages/playground/_stories/fiori/SideNavigation/SideNavigationItem/SideNavigationItem.stories.ts +++ b/packages/playground/_stories/fiori/SideNavigation/SideNavigationItem/SideNavigationItem.stories.ts @@ -21,6 +21,7 @@ const Template: UI5StoryArgs = (args) => { text="${ifDefined(args.text)}" icon="${ifDefined(args.icon)}" ?expanded="${ifDefined(args.expanded)}" + ?disabled="${ifDefined(args.disabled)}" ?whole-item-toggleable="${ifDefined(args.wholeItemToggleable)}" href="${ifDefined(args.href)}" ?selected="${ifDefined(args.selected)}" diff --git a/packages/playground/_stories/fiori/SideNavigation/SideNavigationSubItem/SideNavigationSubItem.stories.ts b/packages/playground/_stories/fiori/SideNavigation/SideNavigationSubItem/SideNavigationSubItem.stories.ts index 4a45c0faa26a..34faf44fc79a 100644 --- a/packages/playground/_stories/fiori/SideNavigation/SideNavigationSubItem/SideNavigationSubItem.stories.ts +++ b/packages/playground/_stories/fiori/SideNavigation/SideNavigationSubItem/SideNavigationSubItem.stories.ts @@ -21,6 +21,7 @@ const Template: UI5StoryArgs = (args) => text="${ifDefined(args.text)}" href="${ifDefined(args.href)}" ?selected="${ifDefined(args.selected)}" + ?disabled="${ifDefined(args.disabled)}" target="${ifDefined(args.target)}" >
        From 2666f08fa51a26d2eacbc6dd767e14289be99ca3 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Fri, 1 Mar 2024 13:35:33 +0200 Subject: [PATCH 40/44] feat(ui5-side-navigation): resoleve merge conflicts --- packages/fiori/src/SideNavigation.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index c054ca40b6aa..00af72b43af5 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -53,12 +53,12 @@ type SideNavigationSelectionChangeEventDetail = { item: SideNavigationItemBase, }; -type PopupSideNavigationItem = SideNavigationItem & { associatedItem: SideNavigationItemBase }; +type PopupSideNavigationItem = SideNavigationItem & { associatedItem: SideNavigationSelectableItemBase }; // used for the inner side navigation used in the SideNavigationPopoverTemplate type NavigationMenuClickEventDetail = MenuItemClickEventDetail & { item: Pick & { - associatedItem: SideNavigationItemBase, + associatedItem: SideNavigationSelectableItemBase, } }; From 43af0c9fefc25da1a84cc3bc347ab027299536fc Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Fri, 1 Mar 2024 14:03:43 +0200 Subject: [PATCH 41/44] feat(ui5-side-navigation): fix code review issues --- packages/fiori/src/SideNavigationGroup.hbs | 1 + packages/fiori/src/SideNavigationGroup.ts | 19 +++++++++++++++++++ packages/fiori/src/SideNavigationItemBase.ts | 2 +- .../fiori/src/i18n/messagebundle.properties | 3 +++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/fiori/src/SideNavigationGroup.hbs b/packages/fiori/src/SideNavigationGroup.hbs index 00fcae89764b..6b353e47d987 100644 --- a/packages/fiori/src/SideNavigationGroup.hbs +++ b/packages/fiori/src/SideNavigationGroup.hbs @@ -17,6 +17,7 @@ @focusin="{{_onfocusin}}" tabindex="{{effectiveTabIndex}}" aria-expanded="{{_expanded}}" + aria-description="{{accDescription}}" title="{{_tooltip}}" aria-owns="{{_groupId}}" > diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts index 801d38ecc5d8..19f44893fcf7 100644 --- a/packages/fiori/src/SideNavigationGroup.ts +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -6,6 +6,8 @@ import { isRight, } from "@ui5/webcomponents-base/dist/Keys.js"; import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; +import { getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; +import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js"; import "@ui5/webcomponents-icons/dist/navigation-right-arrow.js"; import "@ui5/webcomponents-icons/dist/navigation-down-arrow.js"; import Icon from "@ui5/webcomponents/dist/Icon.js"; @@ -14,6 +16,10 @@ import type SideNavigationSelectableItemBase from "./SideNavigationSelectableIte import type SideNavigationItem from "./SideNavigationItem.js"; import SideNavigationGroupTemplate from "./generated/templates/SideNavigationGroupTemplate.lit.js"; +import { + SIDE_NAVIGATION_GROUP_HEADER_DESC, +} from "./generated/i18n/i18n-defaults.js"; + // Styles import SideNavigationItemCss from "./generated/themes/SideNavigationItem.css.js"; @@ -62,6 +68,8 @@ class SideNavigationGroup extends SideNavigationItemBase { @slot({ type: HTMLElement, invalidateOnChildChange: true, "default": true }) items!: Array; + static i18nBundle: I18nBundle; + get overflowItems() : Array { const separator1 = this.shadowRoot!.querySelector(".ui5-sn-item-separator:first-child") as HTMLElement; const separator2 = this.shadowRoot!.querySelector(".ui5-sn-item-separator:last-child") as HTMLElement; @@ -127,6 +135,10 @@ class SideNavigationGroup extends SideNavigationItemBase { return ""; } + get accDescription() { + return SideNavigationGroup.i18nBundle.getText(SIDE_NAVIGATION_GROUP_HEADER_DESC); + } + _onkeydown = (e: KeyboardEvent) => { if (isLeft(e)) { this.expanded = false; @@ -151,6 +163,13 @@ class SideNavigationGroup extends SideNavigationItemBase { _toggle() { this.expanded = !this.expanded; } + + static async onDefine() { + [SideNavigationGroup.i18nBundle] = await Promise.all([ + getI18nBundle("@ui5/webcomponents-fiori"), + super.onDefine(), + ]); + } } SideNavigationGroup.define(); diff --git a/packages/fiori/src/SideNavigationItemBase.ts b/packages/fiori/src/SideNavigationItemBase.ts index cf69ba37ab4d..b6780d6073d5 100644 --- a/packages/fiori/src/SideNavigationItemBase.ts +++ b/packages/fiori/src/SideNavigationItemBase.ts @@ -56,7 +56,7 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { _sideNavigation!: SideNavigation; get _tooltip() { - return this.title || this.text; + return this.title || undefined; } get classesArray() { diff --git a/packages/fiori/src/i18n/messagebundle.properties b/packages/fiori/src/i18n/messagebundle.properties index 34db9c285ce1..2c6c260081e7 100644 --- a/packages/fiori/src/i18n/messagebundle.properties +++ b/packages/fiori/src/i18n/messagebundle.properties @@ -405,3 +405,6 @@ SIDE_NAVIGATION_LIST_ITEMS_ARIA_ROLE_DESC=Navigation List Tree Item #XTXT: Accessible name for the Side Navigation overflow item SIDE_NAVIGATION_OVERFLOW_ACCESSIBLE_NAME=More Items + +#XTXT: Accessible name for the Group Header +SIDE_NAVIGATION_GROUP_HEADER_DESC=Group Header From 4205e1e69127606a8bb8f3676cb39635fe1086c3 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Fri, 1 Mar 2024 14:20:30 +0200 Subject: [PATCH 42/44] feat(ui5-side-navigation): fix failing tests --- packages/fiori/test/specs/SideNavigation.spec.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/fiori/test/specs/SideNavigation.spec.js b/packages/fiori/test/specs/SideNavigation.spec.js index 8e3a2c8b283d..60f6733cfcb7 100644 --- a/packages/fiori/test/specs/SideNavigation.spec.js +++ b/packages/fiori/test/specs/SideNavigation.spec.js @@ -102,11 +102,11 @@ describe("Component Behavior", () => { // items assert.strictEqual(await items[0].getAttribute("title"), await browser.$("#item1").getAttribute("title"), "Title is set as tooltip to root item"); - assert.strictEqual(await items[1].getAttribute("title"), await browser.$("#item2").getAttribute("text"), "Text is set as tooltip to root item when title is not specified"); + assert.notOk(await items[1].getAttribute("title"), "No tooltip"); // sub items assert.strictEqual(await items[2].getAttribute("title"), await browser.$("#item21").getAttribute("title"), "Title is set as tooltip to sub item"); - assert.strictEqual(await items[3].getAttribute("title"), await browser.$("#item22").getAttribute("text"), "Text is set as tooltip to sub item when title is not specified"); + assert.notOk(await items[3].getAttribute("title"), "No tooltip"); }); it("Tests tooltips when collapsed", async () => { @@ -115,13 +115,13 @@ describe("Component Behavior", () => { const items = await browser.$$(">>>#sn1 .ui5-sn-item"); assert.strictEqual(await items[1].getAttribute("title"), await browser.$("#item1").getAttribute("title"), "Title is set as tooltip to root item"); - assert.strictEqual(await items[2].getAttribute("title"), await browser.$("#item2").getAttribute("text"), "Text is set as tooltip to root item when title is not specified"); + assert.notOk(await items[2].getAttribute("title"), "No tooltip"); await browser.$("#item2").click(); const popoverItems = await getRenderedTreeItemsInPopover(); - assert.strictEqual(await popoverItems[0].getAttribute("title"), await browser.$("#item2").getAttribute("text"), "Text is set as tooltip to sub item when title is not specified"); + assert.notOk(await popoverItems[0].getAttribute("title"), "No tooltip"); assert.strictEqual(await popoverItems[1].getAttribute("title"), await browser.$("#item21").getAttribute("title"), "Title is set as tooltip to sub item"); // clean up From b0f408992b727de878f08ae6f5b9229dff5a6e68 Mon Sep 17 00:00:00 2001 From: Teodor Taushanov Date: Fri, 1 Mar 2024 16:10:24 +0200 Subject: [PATCH 43/44] feat(ui5-side-navigation): move to Markdown syntax --- packages/fiori/src/SideNavigation.ts | 61 +++++++++---------- packages/fiori/src/SideNavigationGroup.ts | 10 +-- packages/fiori/src/SideNavigationItem.ts | 12 ++-- packages/fiori/src/SideNavigationItemBase.ts | 2 +- .../src/SideNavigationSelectableItemBase.ts | 25 ++++---- packages/fiori/src/SideNavigationSubItem.ts | 8 +-- 6 files changed, 56 insertions(+), 62 deletions(-) diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index 00af72b43af5..21dace0ee990 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -65,41 +65,39 @@ type NavigationMenuClickEventDetail = MenuItemClickEventDetail & { /** * @class * - *

        Overview

        + * ### Overview * - * The SideNavigation is used as a standard menu in applications. + * The `SideNavigation` is used as a standard menu in applications. * It consists of three containers: header (top-aligned), main navigation section (top-aligned) and the secondary section (bottom-aligned). - *
          - *
        • The header is meant for displaying user related information - profile data, avatar, etc.
        • - *
        • The main navigation section is related to the user’s current work context
        • - *
        • The secondary section is mostly used to link additional information that may be of interest (legal information, developer communities, external help, contact information and so on).
        • - *
        * - *

        Usage

        + * - The header is meant for displaying user related information - profile data, avatar, etc. + * - The main navigation section is related to the user’s current work context + * - The secondary section is mostly used to link additional information that may be of interest (legal information, developer communities, external help, contact information and so on). * - * Use the available ui5-side-navigation-group, ui5-side-navigation-item - * and ui5-side-navigation-sub-item components to build your menu. + * ### Usage + * + * Use the available `ui5-side-navigation-group`, `ui5-side-navigation-item` + * and `ui5-side-navigation-sub-item` components to build your menu. * The items can consist of text only or an icon with text. The use or non-use of icons must be consistent for all items on one level. * You must not combine entries with and without icons on the same level. We strongly recommend that you do not use icons on the second level. * - *

        Keyboard Handling

        + * ### Keyboard Handling * - *

        Fast Navigation

        - * This component provides a build in fast navigation group which can be used via F6 / Shift + F6 or Ctrl + Alt(Option) + Down / Ctrl + Alt(Option) + Up. + * ### Fast Navigation + * This component provides a build in fast navigation group which can be used via `F6 / Shift + F6` or ` Ctrl + Alt(Option) + Down / Ctrl + Alt(Option) + Up`. * In order to use this functionality, you need to import the following module: - * import "@ui5/webcomponents-base/dist/features/F6Navigation.js" - *

        + * `import "@ui5/webcomponents-base/dist/features/F6Navigation.js"` + * + * + * ### ES6 Module Import + * + * `import "@ui5/webcomponents-fiori/dist/SideNavigation.js"` * - *

        ES6 Module Import

        + * `import "@ui5/webcomponents-fiori/dist/SideNavigationGroup.js";` (for `ui5-side-navigation-group`) * - * import "@ui5/webcomponents-fiori/dist/SideNavigation.js"; - *
        - * import "@ui5/webcomponents-fiori/dist/SideNavigationGroup.js"; (for ui5-side-navigation-group) - *
        - * import "@ui5/webcomponents-fiori/dist/SideNavigationItem.js"; (for ui5-side-navigation-item) - *
        - * import "@ui5/webcomponents-fiori/dist/SideNavigationSubItem.js"; (for ui5-side-navigation-sub-item) + * `import "@ui5/webcomponents-fiori/dist/SideNavigationItem.js";` (for `ui5-side-navigation-item`) * + * `import "@ui5/webcomponents-fiori/dist/SideNavigationSubItem.js";` (for `ui5-side-navigation-sub-item`) * @constructor * @extends UI5Element * @since 1.0.0-rc.8 @@ -139,7 +137,7 @@ type NavigationMenuClickEventDetail = MenuItemClickEventDetail & { }) class SideNavigation extends UI5Element { /** - * Defines whether the ui5-side-navigation is expanded or collapsed. + * Defines whether the `ui5-side-navigation` is expanded or collapsed. * * @public * @default false @@ -148,8 +146,8 @@ class SideNavigation extends UI5Element { collapsed!: boolean; /** - * Defines the main items of the ui5-side-navigation. Use the ui5-side-navigation-item component - * for the top-level items, and the ui5-side-navigation-sub-item component for second-level items, nested + * Defines the main items of the `ui5-side-navigation`. Use the `ui5-side-navigation-item` component + * for the top-level items, and the `ui5-side-navigation-sub-item` component for second-level items, nested * inside the items. * * @public @@ -158,10 +156,10 @@ class SideNavigation extends UI5Element { items!: Array; /** - * Defines the fixed items at the bottom of the ui5-side-navigation. Use the ui5-side-navigation-item component - * for the fixed items, and optionally the ui5-side-navigation-sub-item component to provide second-level items inside them. + * Defines the fixed items at the bottom of the `ui5-side-navigation`. Use the `ui5-side-navigation-item` component + * for the fixed items, and optionally the `ui5-side-navigation-sub-item` component to provide second-level items inside them. * - * Note: In order to achieve the best user experience, it is recommended that you keep the fixed items "flat" (do not pass sub-items) + * **Note:** In order to achieve the best user experience, it is recommended that you keep the fixed items "flat" (do not pass sub-items) * * @public */ @@ -169,10 +167,9 @@ class SideNavigation extends UI5Element { fixedItems!: Array; /** - * Defines the header of the ui5-side-navigation. + * Defines the header of the `ui5-side-navigation`. * - *

        - * Note: The header is displayed when the component is expanded - the property collapsed is false; + * **Note:** The header is displayed when the component is expanded - the property `collapsed` is false; * * @public * @since 1.0.0-rc.11 diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts index 19f44893fcf7..237e20c6f981 100644 --- a/packages/fiori/src/SideNavigationGroup.ts +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -26,14 +26,14 @@ import SideNavigationItemCss from "./generated/themes/SideNavigationItem.css.js" /** * @class * - *

        Overview

        + * ### Overview * * Represents a group of navigation actions. - * The ui5-side-navigation-group can to be used inside a ui5-side-navigation only. + * The `ui5-side-navigation-group` can to be used inside a `ui5-side-navigation` only. * - *

        ES6 Module Import

        + * ### ES6 Module Import * - * import "@ui5/webcomponents-fiori/dist/SideNavigationGroup.js"; + * `import "@ui5/webcomponents-fiori/dist/SideNavigationGroup.js";` * * @constructor * @extends SideNavigationItemBase @@ -61,7 +61,7 @@ class SideNavigationGroup extends SideNavigationItemBase { expanded!: boolean; /** - * Defines nested items by passing ui5-side-navigation-item to the default slot. + * Defines nested items by passing `ui5-side-navigation-item` to the default slot. * * @public */ diff --git a/packages/fiori/src/SideNavigationItem.ts b/packages/fiori/src/SideNavigationItem.ts index eaef912bc6f7..a745a0e6b1ee 100644 --- a/packages/fiori/src/SideNavigationItem.ts +++ b/packages/fiori/src/SideNavigationItem.ts @@ -19,14 +19,14 @@ import SideNavigationItemCss from "./generated/themes/SideNavigationItem.css.js" /** * @class * - *

        Overview

        + * ### Overview * * Represents a navigation action. It can provide sub items. - * The ui5-side-navigation-item is used within ui5-side-navigation or ui5-side-navigation-group only. + * The `ui5-side-navigation-item` is used within `ui5-side-navigation` or `ui5-side-navigation-group` only. * - *

        ES6 Module Import

        + * ### ES6 Module Import * - * import "@ui5/webcomponents-fiori/dist/SideNavigationItem.js"; + * `import "@ui5/webcomponents-fiori/dist/SideNavigationItem.js";` * * @constructor * @extends SideNavigationSelectableItemBase @@ -64,7 +64,7 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { _fixed!: boolean; /** - * Defines nested items by passing ui5-side-navigation-sub-item to the default slot. + * Defines nested items by passing `ui5-side-navigation-sub-item` to the default slot. * * @public */ @@ -73,7 +73,7 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { /** * Defines whether clicking the whole item or only pressing the icon will show/hide the sub items (if present). - * If set to true, clicking the whole item will toggle the sub items, and it won't fire the click event. + * If set to true, clicking the whole item will toggle the sub items, and it won't fire the `click` event. * By default, only clicking the arrow icon will toggle the sub items. * * @public diff --git a/packages/fiori/src/SideNavigationItemBase.ts b/packages/fiori/src/SideNavigationItemBase.ts index b6780d6073d5..df868622b26b 100644 --- a/packages/fiori/src/SideNavigationItemBase.ts +++ b/packages/fiori/src/SideNavigationItemBase.ts @@ -5,7 +5,7 @@ import type SideNavigation from "./SideNavigation.js"; /** * @class - * Base class for the items that are accepted by the ui5-side-navigation component. + * Base class for the items that are accepted by the `ui5-side-navigation` component. * * @constructor * @extends UI5Element diff --git a/packages/fiori/src/SideNavigationSelectableItemBase.ts b/packages/fiori/src/SideNavigationSelectableItemBase.ts index b1bc8d762db3..62d4f6f7a9d3 100644 --- a/packages/fiori/src/SideNavigationSelectableItemBase.ts +++ b/packages/fiori/src/SideNavigationSelectableItemBase.ts @@ -26,11 +26,10 @@ import SideNavigationItemBase from "./SideNavigationItemBase.js"; class SideNavigationSelectableItemBase extends SideNavigationItemBase { /** * Defines the icon of the item. - *

        * * The SAP-icons font provides numerous options. - *
        - * See all the available icons in the Icon Explorer. + * + * See all the available icons in the [Icon Explorer](https://sdk.openui5.org/test-resources/sap/m/demokit/iconExplorer/webapp/index.html). * @public * @default "" */ @@ -50,7 +49,7 @@ class SideNavigationSelectableItemBase extends SideNavigationItemBase { * Defines the link target URI. Supports standard hyperlink behavior. * If a JavaScript action should be triggered, * this should not be set, but instead an event handler - * for the click event should be registered. + * for the `click` event should be registered. * * @public * @default "" @@ -61,18 +60,16 @@ class SideNavigationSelectableItemBase extends SideNavigationItemBase { /** * Defines the component target. - *

        - * Notes: * - *
          - *
        • _self
        • - *
        • _top
        • - *
        • _blank
        • - *
        • _parent
        • - *
        • _search
        • - *
        + * **Notes:** + * + * - `_self` + * - `_top` + * - `_blank` + * - `_parent` + * - `_search` * - * This property must only be used when the href property is set. + * **This property must only be used when the `href` property is set.** * * @public * @default "" diff --git a/packages/fiori/src/SideNavigationSubItem.ts b/packages/fiori/src/SideNavigationSubItem.ts index cda62a84289f..39452998f75f 100644 --- a/packages/fiori/src/SideNavigationSubItem.ts +++ b/packages/fiori/src/SideNavigationSubItem.ts @@ -11,13 +11,13 @@ import SideNavigationItemCss from "./generated/themes/SideNavigationItem.css.js" /** * @class * - *

        Overview

        + * ### Overview * Represents a single navigation action. - * The ui5-side-navigation-sub-item is intended to be used inside a ui5-side-navigation-item only. + * The `ui5-side-navigation-sub-item` is intended to be used inside a `ui5-side-navigation-item` only. * - *

        ES6 Module Import

        + * ### ES6 Module Import * - * import "@ui5/webcomponents-fiori/dist/SideNavigationSubItem.js"; + * `import "@ui5/webcomponents-fiori/dist/SideNavigationSubItem.js";` * * @constructor * @extends SideNavigationSelectableItemBase From 5a5675fc8eeb96c69b6cb8af33962e1421518eb6 Mon Sep 17 00:00:00 2001 From: Petar Dimov Date: Thu, 14 Mar 2024 13:45:51 +0200 Subject: [PATCH 44/44] docs: better wording --- packages/fiori/src/SideNavigationGroup.ts | 4 ++-- packages/fiori/src/SideNavigationSelectableItemBase.ts | 2 +- packages/fiori/src/SideNavigationSubItem.ts | 2 +- packages/fiori/test/pages/SideNavigationWithGroups.html | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts index 237e20c6f981..46b19038e955 100644 --- a/packages/fiori/src/SideNavigationGroup.ts +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -28,8 +28,8 @@ import SideNavigationItemCss from "./generated/themes/SideNavigationItem.css.js" * * ### Overview * - * Represents a group of navigation actions. - * The `ui5-side-navigation-group` can to be used inside a `ui5-side-navigation` only. + * Represents a group of navigation actions within `ui5-side-navigation`. + * The `ui5-side-navigation-group` can only be used inside a `ui5-side-navigation`. * * ### ES6 Module Import * diff --git a/packages/fiori/src/SideNavigationSelectableItemBase.ts b/packages/fiori/src/SideNavigationSelectableItemBase.ts index 62d4f6f7a9d3..cc35579f706f 100644 --- a/packages/fiori/src/SideNavigationSelectableItemBase.ts +++ b/packages/fiori/src/SideNavigationSelectableItemBase.ts @@ -6,7 +6,7 @@ import SideNavigationItemBase from "./SideNavigationItemBase.js"; /** * Fired when the component is activated either with a - * click/tap or by using the Enter or Space key. + * click/tap or by using the [Enter] or [Space] keys. * * @public */ diff --git a/packages/fiori/src/SideNavigationSubItem.ts b/packages/fiori/src/SideNavigationSubItem.ts index 39452998f75f..3eb8078c679f 100644 --- a/packages/fiori/src/SideNavigationSubItem.ts +++ b/packages/fiori/src/SideNavigationSubItem.ts @@ -12,7 +12,7 @@ import SideNavigationItemCss from "./generated/themes/SideNavigationItem.css.js" * @class * * ### Overview - * Represents a single navigation action. + * Represents a single navigation action within `ui5-side-navigation-item`. * The `ui5-side-navigation-sub-item` is intended to be used inside a `ui5-side-navigation-item` only. * * ### ES6 Module Import diff --git a/packages/fiori/test/pages/SideNavigationWithGroups.html b/packages/fiori/test/pages/SideNavigationWithGroups.html index 981dfdab2b8c..ee78b955fa30 100644 --- a/packages/fiori/test/pages/SideNavigationWithGroups.html +++ b/packages/fiori/test/pages/SideNavigationWithGroups.html @@ -2,7 +2,7 @@ - Side Navigation With Groups + Side Navigation with Groups