diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index 046031c798a7..8309aefb35c5 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -1,5 +1,6 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; import type { Slot, DefaultSlot } from "@ui5/webcomponents-base/dist/UI5Element.js"; +import type { ChangeInfo } from "@ui5/webcomponents-base/dist/UI5Element.js"; import { createMultiInstanceChecker } from "@ui5/webcomponents-base/dist/util/createMultiInstanceChecker.js"; import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; import i18n from "@ui5/webcomponents-base/dist/decorators/i18n.js"; @@ -237,6 +238,16 @@ class SideNavigation extends UI5Element { } _handleResizeBound: () => void; + _fnTransitionEnd?: (event: TransitionEvent) => void; + _bAnimating = false; + + onInvalidation(changeInfo: ChangeInfo) { + if (changeInfo.type === "property" && changeInfo.name === "collapsed") { + if (this.getDomRef()) { + this._bAnimating = true; + } + } + } onBeforeRendering() { super.onBeforeRendering(); @@ -247,6 +258,7 @@ class SideNavigation extends UI5Element { item.sideNavCollapsed = this.collapsed; item.inPopover = this.inPopover; item.sideNavigation = this; + item.sideNavAnimating = this._bAnimating; }); this.initGroupsSettings(this.items); @@ -497,6 +509,8 @@ class SideNavigation extends UI5Element { if (this.collapsed) { this.handleResize(); } + + this._handleExpandCollapseAnimation(); } onEnterDOM() { @@ -505,6 +519,10 @@ class SideNavigation extends UI5Element { onExitDOM() { ResizeHandler.deregister(this, this._handleResizeBound); + if (this._fnTransitionEnd) { + this.removeEventListener("transitionend", this._fnTransitionEnd); + this._fnTransitionEnd = undefined; + } } handleResize() { @@ -622,6 +640,42 @@ class SideNavigation extends UI5Element { return isPhone() || window.innerWidth < SCREEN_WIDTH_BREAKPOINT; } + _handleExpandCollapseAnimation() { + if (!this._bAnimating) { + return; + } + + const oDomRef = this.getDomRef(); + if (!oDomRef) { + return; + } + + oDomRef.classList.add("ui5-sn-animating"); + + if (this._fnTransitionEnd) { + this.removeEventListener("transitionend", this._fnTransitionEnd); + } + + this._fnTransitionEnd = (oEvent: TransitionEvent) => { + if (oEvent.propertyName !== "width" && oEvent.propertyName !== "min-width") { + return; + } + + oDomRef.classList.remove("ui5-sn-animating"); + this.removeEventListener("transitionend", this._fnTransitionEnd!); + this._fnTransitionEnd = undefined; + this._bAnimating = false; + + this._getAllItems(this.items) + .concat(this._getAllItems(this.fixedItems)) + .forEach(item => { + item.sideNavAnimating = false; + }); + }; + + this.addEventListener("transitionend", this._fnTransitionEnd); + } + _handleItemClick(e: KeyboardEvent | MouseEvent, item: SideNavigationSelectableItemBase) { this.fireDecoratorEvent("item-click", { item }); diff --git a/packages/fiori/src/SideNavigationItemBase.ts b/packages/fiori/src/SideNavigationItemBase.ts index a1781507a77a..466bd786cd8a 100644 --- a/packages/fiori/src/SideNavigationItemBase.ts +++ b/packages/fiori/src/SideNavigationItemBase.ts @@ -79,6 +79,9 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { @property({ type: Boolean }) sideNavCollapsed = false; + @property({ type: Boolean }) + sideNavAnimating = false; + @property({ type: Boolean }) inPopover = false; diff --git a/packages/fiori/src/themes/SideNavigation.css b/packages/fiori/src/themes/SideNavigation.css index 47fdadb8fa4b..c2379289e2a1 100644 --- a/packages/fiori/src/themes/SideNavigation.css +++ b/packages/fiori/src/themes/SideNavigation.css @@ -35,6 +35,10 @@ border-radius: inherit; } +.ui5-sn-root.ui5-sn-animating { + overflow: hidden; +} + .ui5-sn-flexible { display: flex; flex-direction: column; @@ -48,6 +52,12 @@ position: relative; } +.ui5-sn-root.ui5-sn-animating .ui5-sn-list.ui5-sn-flexible, +.ui5-sn-root.ui5-sn-animating .ui5-sn-list.ui5-sn-fixed { + width: var(--_ui5_side_navigation_width); + overflow: hidden; +} + .ui5-sn-list { margin: 0; list-style: none; diff --git a/packages/fiori/src/themes/SideNavigationItemBase.css b/packages/fiori/src/themes/SideNavigationItemBase.css index a2f94abb16ba..0645081b1bc7 100644 --- a/packages/fiori/src/themes/SideNavigationItemBase.css +++ b/packages/fiori/src/themes/SideNavigationItemBase.css @@ -261,6 +261,10 @@ and there is an additional border that appears on hover. */ justify-content: center; } +:host([side-nav-collapsed][side-nav-animating]) .ui5-sn-item { + justify-content: flex-start; +} + :host([slot="fixedItems"]:not(side-nav-collapsed)) .ui5-sn-item.ui5-sn-item-level1 { margin-top: var(--_ui5_side_navigation_first_fixed_item_margin_top); /* space for the focus*/ }