Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ui5-navigation-layout): add ui5-navigation-layout component #9517

Merged
merged 32 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
5b0768b
WIP(ui5-tool-page): add ui5-tool-page component
TeodorTaushanov Jul 18, 2024
dc90dc0
chore: fix styles
TeodorTaushanov Jul 18, 2024
fe43552
Merge remote-tracking branch 'origin/main' into tool_page
TeodorTaushanov Jul 19, 2024
9cf2882
chore: reorganize code
TeodorTaushanov Jul 19, 2024
9524b94
chore: rename to ui5-navigation-layout
TeodorTaushanov Jul 19, 2024
57ccd0a
fix: fix mobile aside z-index
TeodorTaushanov Jul 19, 2024
319352f
Merge remote-tracking branch 'origin/main' into tool_page
TeodorTaushanov Jul 19, 2024
b6c1a5d
Merge remote-tracking branch 'origin/main' into tool_page
TeodorTaushanov Jul 24, 2024
ae7849e
Merge remote-tracking branch 'origin/main' into tool_page
TeodorTaushanov Jul 29, 2024
79e3b60
Merge remote-tracking branch 'origin/main' into tool_page
TeodorTaushanov Oct 16, 2024
9f0f72d
chore: adapt styles according to the new design
TeodorTaushanov Oct 16, 2024
ee723b8
chore: fix comments
TeodorTaushanov Oct 16, 2024
5c70243
chore: fix lint error
TeodorTaushanov Oct 16, 2024
e97b8f3
chore: docs and example
TeodorTaushanov Oct 16, 2024
d7b2390
Merge remote-tracking branch 'origin/main' into tool_page
TeodorTaushanov Oct 17, 2024
90b212b
Merge remote-tracking branch 'origin/main' into tool_page
TeodorTaushanov Oct 18, 2024
9cdff67
chore: update example
TeodorTaushanov Oct 18, 2024
4b5d67c
chore: improve layout and sample
TeodorTaushanov Oct 18, 2024
15dc805
chore: improve sample
TeodorTaushanov Oct 18, 2024
a973847
Merge remote-tracking branch 'origin/main' into tool_page
TeodorTaushanov Oct 21, 2024
55e97e5
chore: add tests
TeodorTaushanov Oct 21, 2024
0bd0ece
chore: improve sample
TeodorTaushanov Oct 21, 2024
5993fa0
Merge remote-tracking branch 'origin/main' into tool_page
TeodorTaushanov Oct 21, 2024
3580e35
chore: remove unnecessary code
TeodorTaushanov Oct 21, 2024
5bbb2b4
Merge remote-tracking branch 'origin/main' into tool_page
TeodorTaushanov Oct 23, 2024
ccf9e53
Merge remote-tracking branch 'origin/main' into tool_page
TeodorTaushanov Oct 23, 2024
09401fd
chore: improve styles
TeodorTaushanov Oct 23, 2024
9498988
Merge remote-tracking branch 'origin/main' into tool_page
TeodorTaushanov Oct 29, 2024
f63b3c3
chore: address code review comments
TeodorTaushanov Oct 29, 2024
3699c29
chore: improve the public example
TeodorTaushanov Oct 29, 2024
02b9119
Merge remote-tracking branch 'origin/main' into tool_page
TeodorTaushanov Oct 30, 2024
9228886
chore: fix internal sample
TeodorTaushanov Oct 30, 2024
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
128 changes: 128 additions & 0 deletions packages/fiori/cypress/specs/NavigationLayout.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { html } from "lit";
import "../../src/NavigationLayout.js";
import "../../src/SideNavigation.js";
import "../../src/SideNavigationGroup.js";
import "../../src/SideNavigationItem.js";
import "../../src/ShellBar.js";
import "@ui5/webcomponents/dist/Button.js";
import "@ui5/webcomponents-icons/dist/home.js";
import "@ui5/webcomponents-icons/dist/menu.js";

const sampleCode = html`
<ui5-navigation-layout id="nl1">
<ui5-shellbar
slot="header"
primary-title="UI5 Web Components"
>
<ui5-button icon="menu" slot="startButton" id="startButton"></ui5-button>
</ui5-shellbar>
<ui5-side-navigation id="sn1" slot="sideContent">
<!-- Items -->
<ui5-side-navigation-item text="Home" href="#home" icon="home"></ui5-side-navigation-item>
<ui5-side-navigation-group text="Group 1" expanded>
<ui5-side-navigation-item text="Item 1" href="#item1"
icon="home"></ui5-side-navigation-item>
<ui5-side-navigation-item text="Item 2" href="#item2"
icon="home"></ui5-side-navigation-item>
<ui5-side-navigation-item text="Item 3" href="#item3"
icon="home"></ui5-side-navigation-item>
</ui5-side-navigation-group>
<!-- Fixed Items -->
<ui5-side-navigation-item slot="fixedItems"
text="Legal"
href="https://www.sap.com/about/legal/impressum.html"
target="_blank"
icon="home"></ui5-side-navigation-item>
</ui5-side-navigation>
<div>
Content
</div>
</ui5-navigation-layout>`;

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

it("tests initial rendering", () => {
cy.get("[ui5-navigation-layout]")
.shadow()
.find(".ui5-nl-root")
.should("exist");

cy.get("[ui5-navigation-layout]")
.shadow()
.find(".ui5-nl-header")
.should("exist");

cy.get("[ui5-navigation-layout]")
.shadow()
.find(".ui5-nl-section")
.should("exist");

cy.get("[ui5-navigation-layout]")
.shadow()
.find(".ui5-nl-aside")
.should("exist");

cy.get("[ui5-navigation-layout]")
.shadow()
.find(".ui5-nl-content")
.should("exist");
});

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

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

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

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

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

describe("Navigation Layout on Phone", () => {
beforeEach(() => {
cy.ui5SimulateDevice("phone");
cy.mount(sampleCode);
});

it("tests initial rendering", () => {
cy.get("[ui5-navigation-layout]")
.should("have.prop", "sideCollapsed", true);

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

cy.get("[ui5-navigation-layout]")
.shadow()
.find(".ui5-nl-aside")
.should("not.be.visible");
});

it("tests collapsing", () => {
cy.get("[ui5-navigation-layout]")
.invoke("prop", "sideCollapsed", false);

cy.get("[ui5-navigation-layout]")
.shadow()
.find(".ui5-nl-aside")
.should("be.visible");

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

cy.get("[ui5-navigation-layout]")
.shadow()
.find(".ui5-nl-aside")
.should("not.be.visible");
});
});
13 changes: 13 additions & 0 deletions packages/fiori/src/NavigationLayout.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div class="ui5-nl-root">
<header class="ui5-nl-header">
<slot name="header"></slot>
</header>
<section class="ui5-nl-section">
<aside class="ui5-nl-aside">
<slot name="sideContent"></slot>
</aside>
<div class="ui5-nl-content">
<slot></slot>
</div>
</section>
</div>
131 changes: 131 additions & 0 deletions packages/fiori/src/NavigationLayout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
import property from "@ui5/webcomponents-base/dist/decorators/property.js";
import slot from "@ui5/webcomponents-base/dist/decorators/slot.js";
import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
import browserScrollbarCSS from "@ui5/webcomponents/dist/generated/themes/BrowserScrollbar.css.js";
import {
isPhone,
isTablet,
isCombi,
} from "@ui5/webcomponents-base/dist/Device.js";
import type SideNavigation from "./SideNavigation.js";

// Template
import NavigationLayoutTemplate from "./generated/templates/NavigationLayoutTemplate.lit.js";

// Styles
import NavigationLayoutCss from "./generated/themes/NavigationLayout.css.js";

/**
* @class
*
* ### Overview
*
* The `ui5-navigation-layout` is a container component that can be used to
* create a layout with a header, a side navigation and a content area.
*
* ### Usage
*
* Use the `ui5-navigation-layout` to create whole screen of an application with vertical navigation.
*
* ### Responsive Behavior
*
* On desktop and tablet devices, the side navigation remains visible and can
* be expanded or collapsed using the `sideCollapsed` property. On phone devices, the side navigation
* is hidden by default but can be displayed using the same `sideCollapsed` property.
*
* ### ES6 Module Import
TeodorTaushanov marked this conversation as resolved.
Show resolved Hide resolved
*
TeodorTaushanov marked this conversation as resolved.
Show resolved Hide resolved
* `import "@ui5/webcomponents-fiori/dist/NavigationLayout.js";`
* @constructor
* @extends UI5Element
* @since 2.4.0
* @public
*/
@customElement({
tag: "ui5-navigation-layout",
languageAware: true,
renderer: litRender,
styles: [
browserScrollbarCSS,
NavigationLayoutCss,
],
template: NavigationLayoutTemplate,
})
class NavigationLayout extends UI5Element {
_sideCollapsed = isPhone() || (isTablet() && !isCombi());

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

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

/**
* Indicates whether the side navigation is collapsed.
* @default false
* @public
*/
@property({ type: Boolean })
set sideCollapsed(value: boolean) {
TeodorTaushanov marked this conversation as resolved.
Show resolved Hide resolved
this._sideCollapsed = value;

if (isPhone()) {
return;
}

const sideNavigation = this.sideContent[0];

if (sideNavigation) {
TeodorTaushanov marked this conversation as resolved.
Show resolved Hide resolved
sideNavigation.collapsed = value;
}
}

get sideCollapsed() : boolean {
return this._sideCollapsed;
}

/**
* Defines the header.
* @public
*/
@slot()
header!: Array<HTMLElement>;

/**
* Defines the side content.
* @public
*/
@slot()
sideContent!: Array<SideNavigation>;

/**
* Defines the content.
* @public
*/
@slot({ type: HTMLElement, "default": true })
content!: Array<HTMLElement>;

onBeforeRendering() {
if (isPhone()) {
return;
}

const sideNavigation = this.sideContent[0];

if (sideNavigation) {
sideNavigation.collapsed = this.sideCollapsed;
}
}
}

NavigationLayout.define();

export default NavigationLayout;
1 change: 1 addition & 0 deletions packages/fiori/src/bundle.esm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import SideNavigationItem from "./SideNavigationItem.js";
import SideNavigationSubItem from "./SideNavigationSubItem.js";
import SortItem from "./SortItem.js";
import Timeline from "./Timeline.js";
import NavigationLayout from "./NavigationLayout.js";
import UploadCollection from "./UploadCollection.js";
import UploadCollectionItem from "./UploadCollectionItem.js";
import ViewSettingsDialog from "./ViewSettingsDialog.js";
Expand Down
65 changes: 65 additions & 0 deletions packages/fiori/src/themes/NavigationLayout.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@

:host(:not([hidden])) {
position: absolute;
inset: 0;
display: block;
background: var(--sapBackgroundColor);
box-sizing: border-box;
overflow: hidden;
}

.ui5-nl-root {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
box-sizing: border-box;
}

.ui5-nl-header {
box-shadow: var(--sapShell_Shadow);
z-index: 2;
}

.ui5-nl-section {
display: flex;
flex: 1;
min-height: 0;
position: relative;
}

.ui5-nl-aside {
transition: transform 0.3s;
z-index: 1;
}

:host([is-phone]) .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;
}

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

:host([side-collapsed][is-phone]) .ui5-nl-aside {
transform: translateX(-100%);
TeodorTaushanov marked this conversation as resolved.
Show resolved Hide resolved
}

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

::slotted([ui5-shellbar][slot="header"]) {
padding-inline: .5rem;
}
5 changes: 0 additions & 5 deletions packages/fiori/src/themes/SideNavigation.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
width: var(--_ui5_side_navigation_width);
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);
TeodorTaushanov marked this conversation as resolved.
Show resolved Hide resolved
font-family: "72override", var(--sapFontFamily);
font-size: var(--sapFontSize);
Expand All @@ -17,10 +16,6 @@
width: var(--_ui5_side_navigation_collapsed_width);
}

:host([is-touch-device]) {
border-radius: var(--_ui5_side_navigation_phone_border_radius);
}

.ui5-sn-root {
height: 100%;
display: flex;
Expand Down
2 changes: 0 additions & 2 deletions packages/fiori/src/themes/base/SideNavigation-parameters.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
--_ui5_side_navigation_navigation_separator_height: calc(2 * var(--sapList_BorderWidth));
--_ui5_side_navigation_triangle_color: var(--sapContent_IconColor);
--_ui5_side_navigation_border_right: 1px solid var(--sapGroup_ContentBorderColor);
--_ui5_side_navigation_border_radius: 0;
--_ui5_side_navigation_phone_border_radius: 0;
--_ui5_side_navigation_box_shadow: none;
--_ui5_side_navigation_triangle_display: block;
--_ui5_side_navigation_phone_width: var(--_ui5_side_navigation_width);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@
--_ui5_side_navigation_navigation_separator_height: 0.0625rem;
--_ui5_side_navigation_triangle_color: var(--sapContent_NonInteractiveIconColor);
--_ui5_side_navigation_border_right: 0;
--_ui5_side_navigation_border_radius: 0.5rem 0.5rem 0 0;
--_ui5_side_navigation_phone_border_radius: 0.5rem;
--_ui5_side_navigation_shadow_color1: color-mix(in srgb, var(--sapContent_ShadowColor) 16%, transparent);
--_ui5_side_navigation_shadow_color2: color-mix(in srgb, var(--sapContent_ShadowColor) 16%, transparent);
--_ui5_side_navigation_box_shadow: 0 0 0.125rem 0 var(--_ui5_side_navigation_shadow_color1), 0 0.5rem 1rem 0 var(--_ui5_side_navigation_shadow_color2);
--_ui5_side_navigation_box_shadow: var(--sapContent_Shadow0);
--_ui5_side_navigation_triangle_display: none;
--_ui5_side_navigation_phone_width: 100%;

Expand Down
Loading