Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
e639022
docs(ui5-tabcontainer): edit texts in sample
LidiyaGeorgieva Dec 17, 2025
d975ffa
Merge branch 'main' of github.com:UI5/webcomponents into NavigationLa…
LidiyaGeorgieva Dec 18, 2025
6c50e97
chore: edit texts
LidiyaGeorgieva Dec 18, 2025
52fc728
chore: change implementation to reflect resizing
LidiyaGeorgieva Dec 19, 2025
4bff4fd
chore: fix bug
LidiyaGeorgieva Jan 5, 2026
a681afd
chore: 2 more test added
LidiyaGeorgieva Jan 5, 2026
c8c6c54
chore: fix description of property
LidiyaGeorgieva Jan 5, 2026
b566a2f
Merge branch 'main' of github.com:UI5/webcomponents into NavigationLa…
LidiyaGeorgieva Jan 5, 2026
af6deb8
chore: fix error
LidiyaGeorgieva Jan 6, 2026
539faa9
Merge branch 'main' of github.com:UI5/webcomponents into NavigationLa…
LidiyaGeorgieva Jan 6, 2026
b77c1e7
Merge branch 'main' into NavigationLayoutNewResponsivness
LidiyaGeorgieva Jan 6, 2026
45f1ce3
chore: fix texts
LidiyaGeorgieva Jan 6, 2026
0c2cda4
chore: fix case when itemRef is null
LidiyaGeorgieva Jan 6, 2026
8ea2f0d
Merge branch 'main' of github.com:UI5/webcomponents into NavigationLa…
LidiyaGeorgieva Jan 6, 2026
7719dd2
chore: fix
LidiyaGeorgieva Jan 6, 2026
30f3b5f
Merge branch 'NavigationLayoutNewResponsivness' of github.com:UI5/web…
LidiyaGeorgieva Jan 6, 2026
83e6b8d
chore: fix css
LidiyaGeorgieva Jan 6, 2026
ddf76d1
Merge branch 'main' of github.com:UI5/webcomponents into NavigationLa…
LidiyaGeorgieva Jan 6, 2026
f8a24b9
Merge branch 'main' into NavigationLayoutNewResponsivness
LidiyaGeorgieva Jan 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 83 additions & 19 deletions packages/fiori/cypress/specs/NavigationLayout.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function Sample() {

<SideNavigationGroup text="Group 1" expanded={true}>
<SideNavigationItem text="Item 1" href="#item1" icon={home}></SideNavigationItem>
<SideNavigationItem text="Item 2" href="#item2"icon={home}></SideNavigationItem>
<SideNavigationItem text="Item 2" href="#item2" icon={home}></SideNavigationItem>
<SideNavigationItem text="Item 3" href="#item3" icon={home}></SideNavigationItem>
</SideNavigationGroup>

Expand All @@ -37,12 +37,55 @@ function Sample() {
</NavigationLayout>;
}

function SampleWithCollapsedMode() {
return <NavigationLayout id="nl1" mode="Collapsed">
<ShellBar slot="header" primaryTitle="UI5 Web Components">
<Button icon={menu} slot="startButton" id="startButton"></Button>
</ShellBar>

<SideNavigation id="sn1" slot="sideContent">
<SideNavigationItem text="Home" href="#home" icon={home}></SideNavigationItem>

<SideNavigationGroup text="Group 1" expanded={true}>
<SideNavigationItem text="Item 1" href="#item1" icon={home}></SideNavigationItem>
<SideNavigationItem text="Item 2" href="#item2" icon={home}></SideNavigationItem>
<SideNavigationItem text="Item 3" href="#item3" icon={home}></SideNavigationItem>
</SideNavigationGroup>
</SideNavigation>

<div>
Content
</div>
</NavigationLayout>;
}

function SampleWithExpandedMode() {
return <NavigationLayout id="nl1" mode="Expanded">
<ShellBar slot="header" primaryTitle="UI5 Web Components">
<Button icon={menu} slot="startButton" id="startButton"></Button>
</ShellBar>

<SideNavigation id="sn1" slot="sideContent">
<SideNavigationItem text="Home" href="#home" icon={home}></SideNavigationItem>

<SideNavigationGroup text="Group 1" expanded={true}>
<SideNavigationItem text="Item 1" href="#item1" icon={home}></SideNavigationItem>
<SideNavigationItem text="Item 2" href="#item2" icon={home}></SideNavigationItem>
<SideNavigationItem text="Item 3" href="#item3" icon={home}></SideNavigationItem>
</SideNavigationGroup>
</SideNavigation>

<div>
Content
</div>
</NavigationLayout>;
}

describe("Rendering and interaction", () => {
beforeEach(() => {
cy.mount(<Sample />);
});

it("tests initial rendering", () => {
cy.mount(<Sample />);

cy.get("[ui5-navigation-layout]")
.shadow()
.find(".ui5-nl-root")
Expand All @@ -69,31 +112,41 @@ describe("Rendering and interaction", () => {
.should("exist");
});

// it("tests collapsing", () => {
// cy.get("[ui5-side-navigation]")
// .should("have.prop", "collapsed", false);
it("tests collapsing", () => {
cy.mount(<Sample />);

cy.get("[ui5-side-navigation]")
.should("have.prop", "collapsed", false);

// cy.get("[ui5-navigation-layout]")
// .invoke("prop", "mode", "Collapsed");
cy.get("[ui5-navigation-layout]")
.invoke("prop", "mode", "Collapsed");

cy.get("[ui5-side-navigation]")
.should("have.prop", "collapsed", true);

cy.get("[ui5-navigation-layout]")
.invoke("prop", "mode", "Expanded");

// cy.get("[ui5-side-navigation]")
// .should("have.prop", "collapsed", true);
cy.get("[ui5-side-navigation]")
.should("have.prop", "collapsed", false);
});

// cy.get("[ui5-navigation-layout]")
// .invoke("prop", "mode", "Expanded");
it("tests that initial mode=Collapsed overrides default expand/collapse behaviour", () => {
cy.mount(<SampleWithCollapsedMode />);

// cy.get("[ui5-side-navigation]")
// .should("have.prop", "collapsed", false);
// });
cy.get("[ui5-side-navigation]")
.should("have.prop", "collapsed", true);
});
});

describe("Navigation Layout on Phone", () => {
describe("Navigation Layout on Size S", () => {
beforeEach(() => {
cy.ui5SimulateDevice("phone");
cy.mount(<Sample />);
cy.viewport(500, 1080);
});

it("tests initial rendering", () => {
cy.mount(<Sample />);

cy.get("[ui5-navigation-layout]")
.should("have.prop", "sideCollapsed", true);

Expand All @@ -107,6 +160,8 @@ describe("Navigation Layout on Phone", () => {
});

it("tests collapsing", () => {
cy.mount(<Sample />);

cy.get("[ui5-navigation-layout]")
.invoke("prop", "mode", "Expanded");

Expand All @@ -123,4 +178,13 @@ describe("Navigation Layout on Phone", () => {
.find(".ui5-nl-aside")
.should("not.be.visible");
});

it("tests that initial mode=Expanded overrides default expand/collapse behaviour", () => {
cy.mount(<SampleWithExpandedMode />);

cy.get("[ui5-navigation-layout]")
.shadow()
.find(".ui5-nl-aside")
.should("be.visible");
});
});
27 changes: 5 additions & 22 deletions packages/fiori/src/NavigationLayout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ 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 jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js";
import {
isPhone,
isTablet,
isCombi,
} from "@ui5/webcomponents-base/dist/Device.js";
import NavigationLayoutMode from "./types/NavigationLayoutMode.js";
import type SideNavigation from "./SideNavigation.js";

Expand All @@ -31,10 +26,10 @@ import NavigationLayoutCss from "./generated/themes/NavigationLayout.css.js";
*
* ### Responsive Behavior
*
* On desktop and tablet devices, the side navigation is visible
* On larger screens (over 600px width), the side navigation is visible
* by default and can be expanded or collapsed using the `mode` property.
* On phone devices, the side navigation is hidden by default and can
* be displayed using the `mode` property.
* On small screens (under 600px width), the side navigation is hidden by
* default and can be displayed using the `mode` property.
*
* ### ES6 Module Import
*
Expand All @@ -54,7 +49,7 @@ import NavigationLayoutCss from "./generated/themes/NavigationLayout.css.js";
template: NavigationLayoutTemplate,
})
class NavigationLayout extends UI5Element {
_defaultSideCollapsed = isPhone() || (isTablet() && !isCombi());
_defaultSideCollapsed = window.innerWidth < 600; // Size S

/**
* Specifies the navigation layout mode.
Expand All @@ -76,18 +71,6 @@ class NavigationLayout extends UI5Element {
@property({ type: Boolean })
hasSideNavigation = false;

/**
* @private
*/
@property({ type: Boolean })
isPhone = isPhone();

/**
* @private
*/
@property({ type: Boolean })
isTablet = isTablet() && !isCombi();

/**
* Gets whether the side navigation is collapsed.
* @public
Expand Down Expand Up @@ -121,7 +104,7 @@ class NavigationLayout extends UI5Element {
onBeforeRendering() {
this.calcSideCollapsed();

if (isPhone()) {
if (window.innerWidth < 600 && this.isSideCollapsed()) {
return;
}

Expand Down
27 changes: 4 additions & 23 deletions packages/fiori/src/SideNavigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ import slot from "@ui5/webcomponents-base/dist/decorators/slot.js";
import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js";
import ItemNavigation from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js";
import type { ITabbable } from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js";
import {
isPhone,
isTablet,
isCombi,
} from "@ui5/webcomponents-base/dist/Device.js";

import NavigationMode from "@ui5/webcomponents-base/dist/types/NavigationMode.js";
import type SideNavigationItemBase from "./SideNavigationItemBase.js";
Expand Down Expand Up @@ -77,7 +72,7 @@ type PopupSideNavigationItem = SideNavigationItem & { associatedItem: SideNaviga
* The `ui5-side-navigation` component is designed to be used within a `ui5-navigation-layout` component to ensure an optimal user experience.
*
* Using it standalone may not match the intended design and functionality.
* For example, the side navigation may not exhibit the correct behavior on phones and tablets.
* For example, the side navigation may not exhibit the correct behavior on smaller screens.
* Padding of the `ui5-shellbar` will not match the padding of the side navigation.
*
* ### Keyboard Handling
Expand Down Expand Up @@ -128,11 +123,12 @@ class SideNavigation extends UI5Element {
/**
* Defines whether the `ui5-side-navigation` is expanded or collapsed.
*
* **Note:** The collapsed mode is not supported on phones.
* **Note:** On small screens (under 600 px wide) the collapsed mode is not supported and in
* expanded mode the Side Navigation will take the whole width of the screen.
* The `ui5-side-navigation` component is intended to be used within a `ui5-navigation-layout`
* component to ensure proper responsive behavior. If you choose not to use the
* `ui5-navigation-layout`, you will need to implement the appropriate responsive patterns yourself,
* particularly for phones where the collapsed mode should not be used.
* particularly for smaller screens where the collapsed mode should not be used.
*
* @public
* @default false
Expand Down Expand Up @@ -190,23 +186,10 @@ class SideNavigation extends UI5Element {
@property({ type: Object })
_menuPopoverItems: Array<SideNavigationItem> = [];

/**
* Defines if the component is rendered on a mobile device.
* @private
*/
@property({ type: Boolean })
isPhone = isPhone();

_isOverflow = false;
_flexibleItemNavigation: ItemNavigation;
_fixedItemNavigation: ItemNavigation;

/**
* @private
*/
@property({ type: Boolean })
isTouchDevice = false;

@i18n("@ui5/webcomponents-fiori")
static i18nBundle: I18nBundle;

Expand Down Expand Up @@ -492,8 +475,6 @@ class SideNavigation extends UI5Element {

onEnterDOM() {
ResizeHandler.register(this, this._handleResizeBound);

this.isTouchDevice = isPhone() || (isTablet() && !isCombi());
}

onExitDOM() {
Expand Down
36 changes: 22 additions & 14 deletions packages/fiori/src/themes/NavigationLayout.css
Original file line number Diff line number Diff line change
Expand Up @@ -32,31 +32,39 @@
z-index: 2;
}

:host([is-phone]) .ui5-nl-aside {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 100%;
@media (width < 600px) {
:host .ui5-nl-aside {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 100%;
}
}

:host([is-phone]) ::slotted([ui5-side-navigation][slot="sideContent"]) {
width: 100%;
box-shadow: none;
@media (width < 600px) {
:host ::slotted([ui5-side-navigation][slot="sideContent"]) {
width: 100%;
box-shadow: none;
}
}

.ui5-nl-content {
flex: 1;
min-width: 0;
overflow: auto;
}

:host([side-collapsed][is-phone]) .ui5-nl-aside {
transform: translateX(-100%);
@media (width < 600px) {
:host([side-collapsed]) .ui5-nl-aside {
transform: translateX(-100%);
}
}

:host([side-collapsed][is-phone]) :dir(rtl) .ui5-nl-aside {
transform: translateX(100%);
@media (width < 600px) {
:host([side-collapsed]) :dir(rtl) .ui5-nl-aside {
transform: translateX(100%);
}

}

:host([has-side-navigation]) ::slotted([ui5-shellbar][slot="header"]) {
Expand Down
7 changes: 5 additions & 2 deletions packages/fiori/src/themes/SideNavigation.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@
width: var(--_ui5_side_navigation_collapsed_width);
}

:host([is-phone]) {
width: 100%;
@media (width < 600px) {
:host(:not([hidden])) {
width: 100%;
}
}


.ui5-sn-root {
height: 100%;
display: flex;
Expand Down
2 changes: 1 addition & 1 deletion packages/fiori/src/types/NavigationLayoutMode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
enum NavigationLayoutMode {
/**
* Automatically calculates the navigation layout mode based on the screen device type.
* `Expanded` on desktop and `Collapsed` on tablet and phone.
* `Collapsed` on small screens (under 600 px wide) and `Expanded` on larger screens.
* @public
*/
Auto = "Auto",
Expand Down
Loading