forked from NationalBankBelgium/stark
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(stark-ui): implementation of the app sidebar
ISSUES CLOSED: NationalBankBelgium#592
- Loading branch information
Showing
32 changed files
with
647 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from "./app-sidebar/app-sidebar.module"; | ||
export * from "./app-sidebar/components"; | ||
export * from "./app-sidebar/services"; |
13 changes: 13 additions & 0 deletions
13
packages/stark-ui/src/modules/app-sidebar/app-sidebar.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { NgModule } from "@angular/core"; | ||
import { CommonModule } from "@angular/common"; | ||
import { MatSidenavModule } from "@angular/material/sidenav"; | ||
import { StarkAppSidebarComponent } from "./components"; | ||
import { StarkAppSidebarService } from "./services"; | ||
|
||
@NgModule({ | ||
declarations: [StarkAppSidebarComponent], | ||
imports: [CommonModule, MatSidenavModule], | ||
exports: [StarkAppSidebarComponent], | ||
providers: [StarkAppSidebarService] | ||
}) | ||
export class StarkAppSidebarModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./components/app-sidebar.component"; |
6 changes: 6 additions & 0 deletions
6
packages/stark-ui/src/modules/app-sidebar/components/_app-sidebar-theme.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/* ============================================================================== */ | ||
/* S t a r k A p p S i d e b a r - T h e m e */ | ||
/* ============================================================================== */ | ||
/* stark-ui: src/modules/app-sidebar/components/_app-sidebar-theme.scss */ | ||
|
||
/* END stark-ui: src/modules/app-sidebar/components/_app-sidebar-theme.scss */ |
42 changes: 42 additions & 0 deletions
42
packages/stark-ui/src/modules/app-sidebar/components/_app-sidebar.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/* ============================================================================== */ | ||
/* S t a r k A p p S i d e b a r */ | ||
/* ============================================================================== */ | ||
/* stark-ui: src/modules/app-sidebar/components/_app-sidebar.component.scss */ | ||
|
||
.stark-app-sidebar { | ||
.mat-sidenav-content { | ||
margin-top: $stark-header-size; | ||
} | ||
|
||
.mat-sidenav-container { | ||
min-height: 100%; | ||
} | ||
|
||
.mat-sidenav { | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: space-between; | ||
} | ||
|
||
.stark-app-sidenav-left { | ||
width: 150px; | ||
} | ||
.stark-app-sidenav-right { | ||
width: 300px; | ||
} | ||
.stark-app-sidenav-menu { | ||
margin-top: $stark-header-size; | ||
width: 200px; | ||
} | ||
} | ||
|
||
@media #{$tablet-query} { | ||
.stark-app-sidebar { | ||
.stark-app-sidenav-menu, | ||
.mat-sidenav-content { | ||
margin-top: $stark-header-size-desktop; | ||
} | ||
} | ||
} | ||
|
||
/* END stark-ui: src/modules/app-sidebar/components/_app-sidebar.component.scss */ |
20 changes: 20 additions & 0 deletions
20
packages/stark-ui/src/modules/app-sidebar/components/app-sidebar.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<mat-sidenav-container #appSidenavContainer> | ||
<mat-sidenav #appSidenavLeft class="stark-app-sidenav-left" [ngClass]="{'stark-app-sidenav-menu': sidenavLeftMode==='menu'}" closed mode="over" [fixedInViewport]="true" | ||
[fixedBottomGap]="0"> | ||
<ng-container *ngIf="sidenavLeftMode==='regular'"> | ||
<ng-content class="regular" select="[stark-app-sidenav-left]"></ng-content> | ||
</ng-container> | ||
<ng-container class="menu" *ngIf="sidenavLeftMode==='menu'"> | ||
<ng-content select="[stark-app-sidenav-menu]"></ng-content> | ||
</ng-container> | ||
</mat-sidenav> | ||
<mat-sidenav #appSidenavRight class="stark-app-sidenav-right" closed mode="over" position="end" [fixedInViewport]="true" | ||
[fixedBottomGap]="0"> | ||
<ng-content select="[stark-app-sidenav-right]"></ng-content> | ||
</mat-sidenav> | ||
<mat-sidenav-content> | ||
<div class="stark-container"> | ||
<ng-content select="[stark-app-sidenav-content]"></ng-content> | ||
</div> | ||
</mat-sidenav-content> | ||
</mat-sidenav-container> |
81 changes: 81 additions & 0 deletions
81
packages/stark-ui/src/modules/app-sidebar/components/app-sidebar.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { CommonModule } from "@angular/common"; | ||
import { NoopAnimationsModule } from "@angular/platform-browser/animations"; | ||
import { async, ComponentFixture, TestBed } from "@angular/core/testing"; | ||
import { MatSidenavModule } from "@angular/material/sidenav"; | ||
import { STARK_LOGGING_SERVICE } from "@nationalbankbelgium/stark-core"; | ||
import { MockStarkLoggingService } from "@nationalbankbelgium/stark-core/testing"; | ||
import { StarkAppSidebarComponent } from "./app-sidebar.component"; | ||
import { StarkAppSidebarService } from "./../services/app-sidebar.service"; | ||
|
||
describe("AppSidebarComponent", () => { | ||
let fixture: ComponentFixture<StarkAppSidebarComponent>; | ||
let component: StarkAppSidebarComponent; | ||
|
||
beforeEach(async(() => { | ||
return TestBed.configureTestingModule({ | ||
declarations: [StarkAppSidebarComponent], | ||
imports: [CommonModule, MatSidenavModule, NoopAnimationsModule], | ||
providers: [{ provide: STARK_LOGGING_SERVICE, useValue: new MockStarkLoggingService() }, StarkAppSidebarService] | ||
}).compileComponents(); | ||
})); | ||
|
||
beforeEach(() => { | ||
fixture = TestBed.createComponent(StarkAppSidebarComponent); | ||
component = fixture.componentInstance; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
describe("sidenavs opening features ", () => { | ||
it("left sidebar should be opened", () => { | ||
component.onOpenSideNav({ | ||
sidebar: "left" | ||
}); | ||
expect(component.appSidenavLeft.opened).toBe(true); | ||
}); | ||
|
||
it("right sidebar should be opened", () => { | ||
component.onOpenSideNav({ | ||
sidebar: "right" | ||
}); | ||
expect(component.appSidenavRight.opened).toBe(true); | ||
}); | ||
|
||
it("left sidebar should show the menu in menu mode", () => { | ||
component.onOpenSideNav({ | ||
mode: "menu", | ||
sidebar: "left" | ||
}); | ||
fixture.detectChanges(); | ||
const sidenav: HTMLElement = fixture.nativeElement.querySelector(".stark-app-sidenav-menu"); | ||
expect(sidenav).toBeTruthy(); | ||
}); | ||
|
||
it("left sidebar should hide the menu in regular mode", () => { | ||
component.onOpenSideNav({ | ||
mode: "regular", | ||
sidebar: "left" | ||
}); | ||
fixture.detectChanges(); | ||
const sidenav: HTMLElement = fixture.nativeElement.querySelector(".stark-app-sidenav-menu"); | ||
expect(sidenav).toBeFalsy(); | ||
}); | ||
}); | ||
|
||
describe("sidenavs closing features ", () => { | ||
it("left sidebar should close", () => { | ||
component.onOpenSideNav({ | ||
sidebar: "left" | ||
}); | ||
component.onCloseSideNavs(); | ||
expect(component.appSidenavLeft.opened).toBe(false); | ||
}); | ||
|
||
it("right sidebar should close", () => { | ||
component.onOpenSideNav({ | ||
sidebar: "right" | ||
}); | ||
component.onCloseSideNavs(); | ||
expect(component.appSidenavRight.opened).toBe(false); | ||
}); | ||
}); | ||
}); |
123 changes: 123 additions & 0 deletions
123
packages/stark-ui/src/modules/app-sidebar/components/app-sidebar.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import { Component, HostBinding, Inject, Input, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from "@angular/core"; | ||
import { from, Subscription } from "rxjs"; | ||
import { MatSidenav, MatSidenavContainer, MatDrawerToggleResult } from "@angular/material/sidenav"; | ||
import { STARK_LOGGING_SERVICE, StarkLoggingService } from "@nationalbankbelgium/stark-core"; | ||
import { StarkAppSidebarOpenEvent } from "../services/app-sidebar-open-event.intf"; | ||
import { StarkAppSidebarService } from "../services/app-sidebar.service"; | ||
|
||
/** | ||
* Name of the component | ||
*/ | ||
const componentName: string = "stark-app-sidebar"; | ||
|
||
/** | ||
* Component to display the application's sidebar | ||
* Only 2 sidebars are allowed: https://github.com/angular/material2/issues/1514 | ||
*/ | ||
@Component({ | ||
selector: "stark-app-sidebar", | ||
templateUrl: "./app-sidebar.component.html", | ||
encapsulation: ViewEncapsulation.None | ||
}) | ||
export class StarkAppSidebarComponent implements OnDestroy, OnInit { | ||
/** | ||
* Adds class="stark-app-sidebar" attribute on the host component | ||
*/ | ||
@HostBinding("class") | ||
public class: string = componentName; | ||
|
||
/** | ||
* Mode for the left sidebar: either the menu is shown or the regular sidebar | ||
*/ | ||
@Input() | ||
public sidenavLeftMode: "regular" | "menu"; | ||
|
||
/** | ||
* Reference to the MatSidenavContainer embedded in this component | ||
*/ | ||
@ViewChild("appSidenavContainer") | ||
public appSidenavContainer: MatSidenavContainer; | ||
|
||
/** | ||
* Reference to the left MatSidenav embedded in this component | ||
*/ | ||
@ViewChild("appSidenavLeft") | ||
public appSidenavLeft: MatSidenav; | ||
|
||
/** | ||
* Reference to the right MatSidenav embedded in this component | ||
*/ | ||
@ViewChild("appSidenavRight") | ||
public appSidenavRight: MatSidenav; | ||
|
||
/** | ||
* Subscription to the open sidebar Observable | ||
*/ | ||
public openSidebarSubscription: Subscription; | ||
|
||
/** | ||
* Subscription to the close sidebar Observable | ||
*/ | ||
public closeSidebarSubscription: Subscription; | ||
|
||
/** | ||
* Class constructor | ||
* @param sidebarService - The sidebar service of the application | ||
*/ | ||
public constructor(@Inject(STARK_LOGGING_SERVICE) public logger: StarkLoggingService, public sidebarService: StarkAppSidebarService) {} | ||
|
||
/** | ||
* open sidenav handler | ||
*/ | ||
public onOpenSideNav(event: StarkAppSidebarOpenEvent): void { | ||
if (event.mode) { | ||
this.sidenavLeftMode = event.mode; | ||
} | ||
switch (event.sidebar) { | ||
case "left": | ||
from(this.appSidenavLeft.open()).subscribe( | ||
(result: MatDrawerToggleResult) => this.logger.debug(componentName + ": left sidenav " + result), | ||
(error: Error) => this.logger.warn(componentName + ": ", error) | ||
); | ||
break; | ||
case "right": | ||
from(this.appSidenavRight.open()).subscribe( | ||
(result: MatDrawerToggleResult) => this.logger.debug(componentName + ": right sidebar " + result), | ||
(error: Error) => this.logger.warn(componentName + ": ", error) | ||
); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
/** | ||
* close sidenav handler | ||
*/ | ||
public onCloseSideNavs(): void { | ||
this.appSidenavContainer.close(); | ||
} | ||
|
||
/** | ||
* Component lifecycle OnDestroy hook | ||
* Prevent memory leak when component destroyed | ||
*/ | ||
public ngOnDestroy(): void { | ||
this.openSidebarSubscription.unsubscribe(); | ||
this.closeSidebarSubscription.unsubscribe(); | ||
} | ||
|
||
/** | ||
* Component lifecycle OnInit hook | ||
*/ | ||
public ngOnInit(): void { | ||
this.logger.debug(componentName + ": component initialized"); | ||
this.openSidebarSubscription = this.sidebarService.openSidebar$.subscribe((event: StarkAppSidebarOpenEvent) => { | ||
this.onOpenSideNav(event); | ||
}); | ||
|
||
this.closeSidebarSubscription = this.sidebarService.closeSidebar$.subscribe(() => { | ||
this.onCloseSideNavs(); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from "./services/app-sidebar.service"; | ||
export * from "./services/app-sidebar-open-event.intf"; | ||
export * from "./services/app-sidebar.service"; |
7 changes: 7 additions & 0 deletions
7
packages/stark-ui/src/modules/app-sidebar/services/app-sidebar-open-event.intf.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
/** | ||
* StarkAppSidebarOpenEvent interface | ||
*/ | ||
export interface StarkAppSidebarOpenEvent { | ||
mode?: "regular" | "menu"; | ||
sidebar: "left" | "right"; | ||
} |
39 changes: 39 additions & 0 deletions
39
packages/stark-ui/src/modules/app-sidebar/services/app-sidebar.service.intf.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { Observable } from "rxjs"; | ||
import { StarkAppSidebarOpenEvent } from "./app-sidebar-open-event.intf"; | ||
|
||
/** | ||
* Stark User Service. | ||
* Service to fetch the user profile from the REST API. | ||
* In Development, it can also be used to set the user profile manually. | ||
*/ | ||
export interface StarkAppSidebarServiceIntf { | ||
/** | ||
* Observable subscribed by components to catch open events | ||
*/ | ||
openSidebar$: Observable<StarkAppSidebarOpenEvent>; | ||
|
||
/** | ||
* Observable subscribed by components to catch close events | ||
*/ | ||
closeSidebar$: Observable<void>; | ||
|
||
/** | ||
* open sidebar's menu | ||
*/ | ||
openMenu(): void; | ||
|
||
/** | ||
* open the left sidebar | ||
*/ | ||
openLeft(): void; | ||
|
||
/** | ||
* open the right sidebar | ||
*/ | ||
openRight(): void; | ||
|
||
/** | ||
* close all sidebars | ||
*/ | ||
close(): void; | ||
} |
Oops, something went wrong.