diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index cc636aa9bc187..52f8ac46629e0 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -537,74 +537,135 @@ class SideNavigation extends UI5Element { } } - _updateOverflowItems() { - const domRef = this.getDomRef(); - if (!this.collapsed || !domRef) { - return null; - } - - const overflowItem = this._overflowItem!; - const flexibleContentDomRef: HTMLElement = domRef.querySelector(".ui5-sn-flexible")!; - if (!overflowItem) { - return null; - } - - overflowItem.classList.add("ui5-sn-item-hidden"); - - const overflowItems = this.overflowItems; - - let itemsHeight = overflowItems.reduce((sum, itemRef) => { + _resetAndCalculateItemsHeight() { + return this.overflowItems.reduce((sum, itemRef) => { if (!itemRef) { return sum; } itemRef.classList.remove("ui5-sn-item-hidden"); - return sum + itemRef.offsetHeight; - }, 0); - const { paddingTop, paddingBottom } = window.getComputedStyle(flexibleContentDomRef); - const listHeight = flexibleContentDomRef?.offsetHeight - parseInt(paddingTop) - parseInt(paddingBottom); + let itemDomRef = itemRef; - if (itemsHeight <= listHeight) { - return; - } + if (isInstanceOfSideNavigationItemBase(itemRef) && itemRef.getDomRef()) { + itemDomRef = itemRef.getDomRef()!; + } - overflowItem.classList.remove("ui5-sn-item-hidden"); + const { marginTop, marginBottom } = window.getComputedStyle(itemDomRef); - itemsHeight = overflowItem.offsetHeight; + return sum + itemDomRef.offsetHeight + parseFloat(marginTop) + parseFloat(marginBottom); + }, 0); + } + _getSelectedItemHeight() { + const overflowItems = this.overflowItems; const selectedItem = overflowItems.filter(isInstanceOfSideNavigationSelectableItemBase).find(item => item._selected); + if (!selectedItem) { + return 0; + } + + let height = 0; + if (selectedItem) { const selectedItemDomRef = selectedItem.getDomRef(); if (selectedItemDomRef) { const { marginTop, marginBottom } = window.getComputedStyle(selectedItemDomRef); - itemsHeight += selectedItemDomRef.offsetHeight + parseFloat(marginTop) + parseFloat(marginBottom); + height += selectedItemDomRef.offsetHeight + parseFloat(marginTop) + parseFloat(marginBottom); + } + + const indexOf = overflowItems.indexOf(selectedItem); + const itemAfterSelected = overflowItems[indexOf + 1]; + if (itemAfterSelected && !isInstanceOfSideNavigationItemBase(itemAfterSelected)) { + height += itemAfterSelected.offsetHeight; } } - overflowItems.forEach(item => { + return height; + } + + _updateVisibility(selectedItem: SideNavigationSelectableItemBase | undefined, itemsHeight: number, listHeight: number) { + const overflowItems = this.overflowItems; + + for (let i = 0; i < overflowItems.length; i++) { + const item = overflowItems[i]; + const nextItem = overflowItems[i + 1]; + let nextItemDomRef; + if (!item || item === selectedItem) { - return; + continue; } let itemDomRef; - if (isInstanceOfSideNavigationItemBase(item) && item.getDomRef()) { + if (isInstanceOfSideNavigationItemBase(item)) { itemDomRef = item.getDomRef(); - } else { - itemDomRef = item; } - if (itemDomRef) { - const { marginTop, marginBottom } = window.getComputedStyle(itemDomRef); - itemsHeight += itemDomRef.offsetHeight + parseFloat(marginTop) + parseFloat(marginBottom); + if (!itemDomRef) { + continue; + } + + const { marginTop, marginBottom } = window.getComputedStyle(itemDomRef); + itemsHeight += itemDomRef.offsetHeight + parseFloat(marginTop) + parseFloat(marginBottom); + + if (nextItem && !isInstanceOfSideNavigationItemBase(nextItem)) { + nextItemDomRef = nextItem; + i++; - if (itemsHeight > listHeight) { - item.classList.add("ui5-sn-item-hidden"); - } + itemsHeight += nextItemDomRef.offsetHeight; } - }); + + if (itemsHeight > listHeight) { + item.classList.add("ui5-sn-item-hidden"); + nextItemDomRef?.classList.add("ui5-sn-item-hidden"); + } + + nextItemDomRef = null; + } + } + + _updateOverflowItems() { + const domRef = this.getDomRef(); + if (!this.collapsed || !domRef) { + return null; + } + + const overflowItem = this._overflowItem; + if (!overflowItem) { + return null; + } + + overflowItem.classList.add("ui5-sn-item-hidden"); + + const overflowItems = this.overflowItems; + + let itemsHeight = this._resetAndCalculateItemsHeight(); + + const flexibleContentDomRef: HTMLElement = domRef.querySelector(".ui5-sn-flexible")!; + const { paddingTop, paddingBottom } = window.getComputedStyle(flexibleContentDomRef); + let listHeight = flexibleContentDomRef?.offsetHeight - parseInt(paddingTop) - parseInt(paddingBottom); + + if (itemsHeight < listHeight) { + return; + } + + overflowItem.classList.remove("ui5-sn-item-hidden"); + + itemsHeight = overflowItem.offsetHeight; + + const selectedItem = overflowItems.filter(isInstanceOfSideNavigationSelectableItemBase).find(item => item._selected); + + itemsHeight += this._getSelectedItemHeight(); + + listHeight--; // account for sub-pixel rounding + + const lastItem = overflowItems[overflowItems.length - 1]; + if (!isInstanceOfSideNavigationItemBase(lastItem)) { + listHeight -= lastItem.offsetHeight; + } + + this._updateVisibility(selectedItem, itemsHeight, listHeight); this._flexibleItemNavigation._init(); } diff --git a/packages/fiori/src/themes/SideNavigation.css b/packages/fiori/src/themes/SideNavigation.css index c2379289e2a10..3f5c159c31288 100644 --- a/packages/fiori/src/themes/SideNavigation.css +++ b/packages/fiori/src/themes/SideNavigation.css @@ -85,4 +85,12 @@ .ui5-sn-item-overflow { margin-top: auto; +} + +.ui5-sn-spacer { + margin: var(--_ui5_side_navigation_navigation_separator_margin); + height: var(--_ui5_side_navigation_navigation_separator_height); + min-height: var(--_ui5_side_navigation_navigation_separator_height); + background-color: var(--_ui5_side_navigation_navigation_separator_background_color); + border-radius: var(--_ui5_side_navigation_navigation_separator_radius); } \ No newline at end of file diff --git a/packages/fiori/src/themes/SideNavigationGroup.css b/packages/fiori/src/themes/SideNavigationGroup.css index 00833c2f23d2b..c28a6eb844165 100644 --- a/packages/fiori/src/themes/SideNavigationGroup.css +++ b/packages/fiori/src/themes/SideNavigationGroup.css @@ -22,12 +22,4 @@ .ui5-sn-item-group-below-group.ui5-sn-item-separator, .ui5-sn-item-group-below-group .ui5-sn-item-separator:first-child { display: none; -} - -.ui5-sn-spacer { - margin: var(--_ui5_side_navigation_navigation_separator_margin); - height: var(--_ui5_side_navigation_navigation_separator_height); - min-height: var(--_ui5_side_navigation_navigation_separator_height); - background-color: var(--_ui5_side_navigation_navigation_separator_background_color); - border-radius: var(--_ui5_side_navigation_navigation_separator_radius); -} +} \ No newline at end of file diff --git a/packages/fiori/src/themes/SideNavigationItemBase.css b/packages/fiori/src/themes/SideNavigationItemBase.css index 0645081b1bc7b..e55a1ac8d33ae 100644 --- a/packages/fiori/src/themes/SideNavigationItemBase.css +++ b/packages/fiori/src/themes/SideNavigationItemBase.css @@ -407,4 +407,5 @@ and there is an additional border that appears on hover. */ .ui5-sn-item-separator { min-height: 0.625rem; + background: red; } diff --git a/packages/fiori/test/pages/SideNavigationTest.html b/packages/fiori/test/pages/SideNavigationTest.html new file mode 100644 index 0000000000000..cbb63a9404f11 --- /dev/null +++ b/packages/fiori/test/pages/SideNavigationTest.html @@ -0,0 +1,73 @@ + + + + + Side Navigation Only + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +