From 8f7d087b204f9073fb267eee8d35736168a2da06 Mon Sep 17 00:00:00 2001 From: Derek Burgman Date: Tue, 1 Feb 2022 03:08:53 -0600 Subject: [PATCH] feat: added dbxNavbar --- .../angular/angular.router.service.ts | 4 + .../uirouter/uirouter.router.service.ts | 8 ++ .../router/router/service/router.service.ts | 7 ++ .../src/lib/router/router/transition/index.ts | 2 + .../router/transition/transition.directive.ts | 17 ++++ .../router/transition/transition.rxjs.ts | 20 ++++ .../transition.watcher.directive.ts | 17 ++-- packages/dbx-core/src/lib/util/view.ts | 12 +++ .../content/content.container.component.ts | 38 +++----- packages/dbx-web/src/lib/layout/index.ts | 1 + .../dbx-web/src/lib/router/layout/index.ts | 1 + .../src/lib/router/layout/layout.module.ts | 6 +- .../src/lib/router/layout/navbar/index.ts | 2 + .../layout/navbar/navbar.component.html | 19 ++++ .../layout/navbar/navbar.component.spec.ts | 58 +++++++++++ .../router/layout/navbar/navbar.component.ts | 95 +++++++++++++++++++ .../lib/router/layout/navbar/navbar.module.ts | 27 ++++++ .../layout/sidenav/sidenav.component.ts | 10 +- .../dbx-web/src/lib/screen/screen.service.ts | 22 +++-- packages/dbx-web/src/lib/screen/screen.ts | 71 ++++++++------ .../layout/container/home.component.html | 1 + .../layout/container/home.component.ts | 6 ++ .../layout/container/layout.component.html | 7 +- .../layout/container/layout.component.ts | 10 +- .../doc/modules/layout/doc.layout.router.ts | 11 ++- .../app/modules/shared/app.shared.module.ts | 6 +- 26 files changed, 393 insertions(+), 85 deletions(-) create mode 100644 packages/dbx-core/src/lib/router/router/transition/transition.directive.ts create mode 100644 packages/dbx-core/src/lib/router/router/transition/transition.rxjs.ts create mode 100644 packages/dbx-web/src/lib/router/layout/navbar/index.ts create mode 100644 packages/dbx-web/src/lib/router/layout/navbar/navbar.component.html create mode 100644 packages/dbx-web/src/lib/router/layout/navbar/navbar.component.spec.ts create mode 100644 packages/dbx-web/src/lib/router/layout/navbar/navbar.component.ts create mode 100644 packages/dbx-web/src/lib/router/layout/navbar/navbar.module.ts create mode 100644 packages/demo/src/app/modules/doc/modules/layout/container/home.component.html create mode 100644 packages/demo/src/app/modules/doc/modules/layout/container/home.component.ts diff --git a/packages/dbx-core/src/lib/router/router/provider/angular/angular.router.service.ts b/packages/dbx-core/src/lib/router/router/provider/angular/angular.router.service.ts index 0cc72b153..073e7c2e9 100644 --- a/packages/dbx-core/src/lib/router/router/provider/angular/angular.router.service.ts +++ b/packages/dbx-core/src/lib/router/router/provider/angular/angular.router.service.ts @@ -50,4 +50,8 @@ export class DbxAngularRouterService implements DbxRouterService, DbxRouterTrans } } + isActive(segueRef: SegueRef): boolean { + return false; // TODO! + } + } diff --git a/packages/dbx-core/src/lib/router/router/provider/uirouter/uirouter.router.service.ts b/packages/dbx-core/src/lib/router/router/provider/uirouter/uirouter.router.service.ts index c404a43cd..aba6728ca 100644 --- a/packages/dbx-core/src/lib/router/router/provider/uirouter/uirouter.router.service.ts +++ b/packages/dbx-core/src/lib/router/router/provider/uirouter/uirouter.router.service.ts @@ -37,4 +37,12 @@ export class DbxUIRouterService implements DbxRouterService, DbxRouterTransition return this.state.go(segueRef.ref, params, segueRef.refOptions).then(_ => true).catch(_ => false); } + isActive(segueRef: SegueRef): boolean { + const { ref, refParams } = segueRef; + + const targetRef = (ref.startsWith('.') ? `^${ref}` : ref); + const active = this.state.includes(targetRef, refParams); + return active; + } + } diff --git a/packages/dbx-core/src/lib/router/router/service/router.service.ts b/packages/dbx-core/src/lib/router/router/service/router.service.ts index 43803421e..190b03dcd 100644 --- a/packages/dbx-core/src/lib/router/router/service/router.service.ts +++ b/packages/dbx-core/src/lib/router/router/service/router.service.ts @@ -12,4 +12,11 @@ export abstract class DbxRouterService { */ abstract go(segueRef: SegueRef): Promise; + /** + * Returns true if the input segue ref is considered active. + * + * @param segueRef + */ + abstract isActive(segueRef: SegueRef): boolean; + } diff --git a/packages/dbx-core/src/lib/router/router/transition/index.ts b/packages/dbx-core/src/lib/router/router/transition/index.ts index f118b5677..a720093d5 100644 --- a/packages/dbx-core/src/lib/router/router/transition/index.ts +++ b/packages/dbx-core/src/lib/router/router/transition/index.ts @@ -1,2 +1,4 @@ export * from './transition'; +export * from './transition.rxjs'; +export * from './transition.directive'; export * from './transition.watcher.directive'; diff --git a/packages/dbx-core/src/lib/router/router/transition/transition.directive.ts b/packages/dbx-core/src/lib/router/router/transition/transition.directive.ts new file mode 100644 index 000000000..a1ff9963e --- /dev/null +++ b/packages/dbx-core/src/lib/router/router/transition/transition.directive.ts @@ -0,0 +1,17 @@ +import { Observable, startWith } from 'rxjs'; +import { Directive, NgZone } from '@angular/core'; +import { DbxRouterTransitionService } from '../service/router.transition.service'; +import { successTransition } from './transition.rxjs'; + +/** + * Abstract directive that listens to onSuccess transition events and runs a function. + */ +@Directive() +export abstract class AbstractTransitionDirective { + + readonly transitionSuccess$ = successTransition(this.dbNgxRouterTransitionService.transitions$); + readonly initAndUpdateOnTransitionSuccess$: Observable = this.transitionSuccess$.pipe(startWith(undefined)) as Observable; + + constructor(protected readonly dbNgxRouterTransitionService: DbxRouterTransitionService) { } + +} diff --git a/packages/dbx-core/src/lib/router/router/transition/transition.rxjs.ts b/packages/dbx-core/src/lib/router/router/transition/transition.rxjs.ts new file mode 100644 index 000000000..9ccf37210 --- /dev/null +++ b/packages/dbx-core/src/lib/router/router/transition/transition.rxjs.ts @@ -0,0 +1,20 @@ +import { filter, MonoTypeOperatorFunction, Observable } from "rxjs"; +import { DbxRouterTransitionEvent, DbxRouterTransitionEventType } from "./transition"; + +/** + * Convenience function for filtering success from the input observable. + * + * @param obs + * @returns + */ +export function successTransition(obs: Observable): Observable { + return obs.pipe(filterTransitionSuccess()); +} + +export function filterTransitionSuccess(): MonoTypeOperatorFunction { + return filterTransitionEvent(DbxRouterTransitionEventType.SUCCESS); +} + +export function filterTransitionEvent(type: DbxRouterTransitionEventType): MonoTypeOperatorFunction { + return filter(x => x.type === type); +} diff --git a/packages/dbx-core/src/lib/router/router/transition/transition.watcher.directive.ts b/packages/dbx-core/src/lib/router/router/transition/transition.watcher.directive.ts index b9e1379cb..d739fb4ff 100644 --- a/packages/dbx-core/src/lib/router/router/transition/transition.watcher.directive.ts +++ b/packages/dbx-core/src/lib/router/router/transition/transition.watcher.directive.ts @@ -1,23 +1,18 @@ import { Directive, NgZone, OnDestroy, OnInit } from '@angular/core'; -import { filter } from 'rxjs/operators'; -import { DbxRouterTransitionEventType } from './transition'; -import { DbxRouterTransitionService } from '../service/router.transition.service'; import { SubscriptionObject } from '@dereekb/rxjs'; +import { DbxRouterTransitionService } from '../service/router.transition.service'; +import { AbstractTransitionDirective } from './transition.directive'; /** * Abstract directive that listens to onSuccess transition events and runs a function. */ @Directive() -export abstract class AbstractTransitionWatcherDirective implements OnInit, OnDestroy { +export abstract class AbstractTransitionWatcherDirective extends AbstractTransitionDirective implements OnInit, OnDestroy { private _transitionSub = new SubscriptionObject(); - constructor(protected readonly dbNgxRouterTransitionService: DbxRouterTransitionService, protected readonly ngZone: NgZone) { } - ngOnInit(): void { - this._transitionSub.subscription = this.dbNgxRouterTransitionService.transitions$.pipe( - filter(x => x.type === DbxRouterTransitionEventType.SUCCESS) - ).subscribe(() => { + this._transitionSub.subscription = this.transitionSuccess$.subscribe(() => { this.updateForSuccessfulTransition(); }); } @@ -26,6 +21,10 @@ export abstract class AbstractTransitionWatcherDirective implements OnInit, OnDe this._transitionSub.destroy(); } + constructor(dbNgxRouterTransitionService: DbxRouterTransitionService, protected readonly ngZone: NgZone) { + super(dbNgxRouterTransitionService); + } + // MARK: Action protected zoneUpdateForSuccessfulTransition(): void { this.ngZone.run(() => this.updateForSuccessfulTransition()); diff --git a/packages/dbx-core/src/lib/util/view.ts b/packages/dbx-core/src/lib/util/view.ts index a0dfab74c..ac08c15a8 100644 --- a/packages/dbx-core/src/lib/util/view.ts +++ b/packages/dbx-core/src/lib/util/view.ts @@ -1,6 +1,18 @@ +import { MonoTypeOperatorFunction, tap } from 'rxjs'; import { ChangeDetectorRef, ViewRef, ElementRef } from "@angular/core"; import { Maybe } from "@dereekb/util"; +/** + * Convenience function used within observables for views that need to detect changes after a value changes. + * + * @param cdRef + * @param timeout + * @returns + */ +export function tapDetectChanges(cdRef: ChangeDetectorRef, timeout = 0): MonoTypeOperatorFunction { + return tap(() => setTimeout(() => safeDetectChanges(cdRef), timeout)); +} + /** * Triggers a detection change on the input view as long as the view has not been destroyed. * diff --git a/packages/dbx-web/src/lib/layout/content/content.container.component.ts b/packages/dbx-web/src/lib/layout/content/content.container.component.ts index 44cfa4bfd..0352673ca 100644 --- a/packages/dbx-web/src/lib/layout/content/content.container.component.ts +++ b/packages/dbx-web/src/lib/layout/content/content.container.component.ts @@ -1,29 +1,17 @@ import { Component, Input } from '@angular/core'; -export enum DbxContentContainerPadding { - NONE = 'none', - MIN = 'min', - SMALL = 'small', - NORMAL = 'normal' -} +export type DbxContentContainerPadding = 'none' | 'min' | 'small' | 'normal'; -export enum DbxContentContainerWidth { - SMALL = 'small', - MEDIUM = 'medium', - WIDE = 'wide', - FULL = 'full' -} +export type DbxContentContainerWidth = 'small' | 'medium' | 'wide' | 'full'; -export enum DbxContentContainerType { - /** - * Full/unrestricted height content. - */ - NORMAL = 'normal', - /** - * Content that has a header above it and should take up the rest of the height of the page. - */ - CONTENT = 'content' -} +/** + * DbxContentContainer type. + * + * Two values: + * - normal: Full/unrestricted height content. + * - content: Content that has a header above it and should take up the rest of the height of the page. + */ +export type DbxContentContainerType = 'normal' | 'content'; /** * Component that limits the max-width of the content. @@ -40,13 +28,13 @@ export enum DbxContentContainerType { export class DbxContentContainerComponent { @Input() - type = DbxContentContainerType.NORMAL; + type = 'normal'; @Input() - width = DbxContentContainerWidth.WIDE; + width = 'wide'; @Input() - padding = DbxContentContainerPadding.NORMAL; + padding = 'normal'; @Input() scrollingContent = false; diff --git a/packages/dbx-web/src/lib/layout/index.ts b/packages/dbx-web/src/lib/layout/index.ts index 9bb7256c7..b29922a69 100644 --- a/packages/dbx-web/src/lib/layout/index.ts +++ b/packages/dbx-web/src/lib/layout/index.ts @@ -1,3 +1,4 @@ +export * from './bar'; export * from './block'; export * from './card'; export * from './column'; diff --git a/packages/dbx-web/src/lib/router/layout/index.ts b/packages/dbx-web/src/lib/router/layout/index.ts index d499d7f79..81c52c1a3 100644 --- a/packages/dbx-web/src/lib/router/layout/index.ts +++ b/packages/dbx-web/src/lib/router/layout/index.ts @@ -1,2 +1,3 @@ export * from './anchor'; export * from './sidenav'; +export * from './layout.module'; diff --git a/packages/dbx-web/src/lib/router/layout/layout.module.ts b/packages/dbx-web/src/lib/router/layout/layout.module.ts index ec236b8de..fda7e6303 100644 --- a/packages/dbx-web/src/lib/router/layout/layout.module.ts +++ b/packages/dbx-web/src/lib/router/layout/layout.module.ts @@ -1,9 +1,13 @@ import { NgModule } from '@angular/core'; import { DbxAnchorModule } from './anchor/anchor.module'; +import { DbxNavbarModule } from './navbar/navbar.module'; +import { DbxSidenavModule } from './sidenav/sidenav.module'; @NgModule({ exports: [ - DbxAnchorModule + DbxAnchorModule, + DbxNavbarModule, + DbxSidenavModule ] }) export class DbxRouterLayoutModule { } diff --git a/packages/dbx-web/src/lib/router/layout/navbar/index.ts b/packages/dbx-web/src/lib/router/layout/navbar/index.ts new file mode 100644 index 000000000..5d50fad6e --- /dev/null +++ b/packages/dbx-web/src/lib/router/layout/navbar/index.ts @@ -0,0 +1,2 @@ +export * from './navbar.component'; +export * from './navbar.module'; diff --git a/packages/dbx-web/src/lib/router/layout/navbar/navbar.component.html b/packages/dbx-web/src/lib/router/layout/navbar/navbar.component.html new file mode 100644 index 000000000..91837b53c --- /dev/null +++ b/packages/dbx-web/src/lib/router/layout/navbar/navbar.component.html @@ -0,0 +1,19 @@ + + + + + + + + + + + + + diff --git a/packages/dbx-web/src/lib/router/layout/navbar/navbar.component.spec.ts b/packages/dbx-web/src/lib/router/layout/navbar/navbar.component.spec.ts new file mode 100644 index 000000000..dec7b4d36 --- /dev/null +++ b/packages/dbx-web/src/lib/router/layout/navbar/navbar.component.spec.ts @@ -0,0 +1,58 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { Component, Input } from '@angular/core'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { UIRouterModule } from '@uirouter/angular'; +import { DbxNavbarModule } from './navbar.module'; +import { ClickableAnchorLink } from '@dereekb/dbx-core'; + +describe('NavbarComponent', () => { + + beforeEach(async () => { + TestBed.configureTestingModule({ + imports: [ + NoopAnimationsModule, + DbxNavbarModule, + UIRouterModule.forRoot() + ], + declarations: [TestViewComponent] + }).compileComponents(); + }); + + let testComponent: TestViewComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + fixture = TestBed.createComponent(TestViewComponent); + testComponent = fixture.componentInstance; + fixture.detectChanges(); + }); + + describe('with links', () => { + + beforeEach(async () => { + testComponent.links = [{ + title: 'Test' + }]; + + fixture.detectChanges(); + }); + + it('should render', () => { + expect(true).toBe(true); + }); + + }); + +}); + +@Component({ + template: ` + + ` +}) +class TestViewComponent { + + @Input() + public links?: ClickableAnchorLink[]; + +} diff --git a/packages/dbx-web/src/lib/router/layout/navbar/navbar.component.ts b/packages/dbx-web/src/lib/router/layout/navbar/navbar.component.ts new file mode 100644 index 000000000..3eea6f149 --- /dev/null +++ b/packages/dbx-web/src/lib/router/layout/navbar/navbar.component.ts @@ -0,0 +1,95 @@ +import { Observable } from 'rxjs'; +import { ScreenMediaWidthType, screenMediaWidthTypeIsActive } from './../../../screen/screen'; +import { DbxScreenMediaService } from '../../../screen/screen.service'; +import { Maybe } from '@dereekb/util'; +import { Input, Component, NgZone, OnDestroy, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'; +import { ClickableAnchorLink, AbstractTransitionWatcherDirective, DbxRouterService, DbxRouterTransitionService, AbstractTransitionDirective, tapDetectChanges } from '@dereekb/dbx-core'; +import { BehaviorSubject, combineLatest, map, shareReplay, distinctUntilChanged, startWith, tap } from 'rxjs'; + +interface NavAnchorLink { + selected: boolean; + anchor: ClickableAnchorLink; +} + +export type NavBarContentAlign = 'center' | 'left' | 'right'; +export type NavbarMode = 'bar' | 'button'; + +/** + * Component that displays a navbar. + */ +@Component({ + selector: 'dbx-navbar', + templateUrl: './navbar.component.html', + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class DbxNavbarComponent extends AbstractTransitionDirective implements OnDestroy { + + @Input() + navAlign = 'center'; + + private _inputMode = new BehaviorSubject>(undefined); + private _breakpoint = new BehaviorSubject('large'); + private _anchors = new BehaviorSubject([]); + + readonly isBreakpointActive$ = combineLatest([this._dbxScreenMediaService.widthType$, this._breakpoint]).pipe( + map(([current, breakpoint]) => screenMediaWidthTypeIsActive(current, breakpoint)), + distinctUntilChanged(), + shareReplay(1) + ); + + readonly mode$ = combineLatest([this._inputMode, this.isBreakpointActive$]).pipe( + map(([inputMode, breakpointActive]) => { + return (breakpointActive) ? (inputMode ?? 'bar') : 'button'; + }), + distinctUntilChanged(), + tapDetectChanges(this.cdr), + shareReplay(1) + ); + + readonly anchors$: Observable = combineLatest([this._anchors, this.initAndUpdateOnTransitionSuccess$]).pipe( + map(([anchors]) => { + return anchors.map((anchor) => { + let selected = this._dbxRouterService.isActive(anchor); + + return { + selected, + anchor + }; + }); + }), + tapDetectChanges(this.cdr), + shareReplay(1) + ); + + constructor( + dbxRouterTransitionService: DbxRouterTransitionService, + private cdr: ChangeDetectorRef, + private readonly _dbxScreenMediaService: DbxScreenMediaService, + private readonly _dbxRouterService: DbxRouterService + ) { + super(dbxRouterTransitionService); + } + + ngOnDestroy(): void { + this._inputMode.complete(); + this._breakpoint.complete(); + this._anchors.complete(); + } + + // MARK: Accessors + @Input() + public set anchors(anchors: Maybe) { + this._anchors.next(anchors ?? []); + } + + @Input() + public set mode(mode: Maybe) { + this._inputMode.next(mode); + } + + @Input() + public set breakpoint(breakpoint: ScreenMediaWidthType) { + this._breakpoint.next(breakpoint); + } + +} diff --git a/packages/dbx-web/src/lib/router/layout/navbar/navbar.module.ts b/packages/dbx-web/src/lib/router/layout/navbar/navbar.module.ts new file mode 100644 index 000000000..1d528ebbe --- /dev/null +++ b/packages/dbx-web/src/lib/router/layout/navbar/navbar.module.ts @@ -0,0 +1,27 @@ +import { MatIconModule } from '@angular/material/icon'; +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatTabsModule } from '@angular/material/tabs'; +import { DbxAnchorModule } from '../anchor/anchor.module'; +import { MatMenuModule } from '@angular/material/menu'; +import { DbxNavbarComponent } from './navbar.component'; + + +@NgModule({ + imports: [ + CommonModule, + MatTabsModule, + MatButtonModule, + MatIconModule, + MatMenuModule, + DbxAnchorModule, + ], + declarations: [ + DbxNavbarComponent + ], + exports: [ + DbxNavbarComponent + ] +}) +export class DbxNavbarModule { } diff --git a/packages/dbx-web/src/lib/router/layout/sidenav/sidenav.component.ts b/packages/dbx-web/src/lib/router/layout/sidenav/sidenav.component.ts index b6d09b7e4..48787d9ec 100644 --- a/packages/dbx-web/src/lib/router/layout/sidenav/sidenav.component.ts +++ b/packages/dbx-web/src/lib/router/layout/sidenav/sidenav.component.ts @@ -41,15 +41,15 @@ export class DbxSidenavComponent extends AbstractTransitionWatcherDirective impl let mode!: SideNavDisplayMode; switch (width) { - case ScreenMediaWidthType.MICRO: - case ScreenMediaWidthType.SMALL: + case 'micro': + case 'small': mode = SideNavDisplayMode.MOBILE; break; - case ScreenMediaWidthType.TABLET: + case 'tablet': mode = SideNavDisplayMode.ICON; break; - case ScreenMediaWidthType.LARGE: - case ScreenMediaWidthType.FULL: + case 'large': + case 'full': mode = SideNavDisplayMode.FULL; break; } diff --git a/packages/dbx-web/src/lib/screen/screen.service.ts b/packages/dbx-web/src/lib/screen/screen.service.ts index b0ca89edc..019eaf55b 100644 --- a/packages/dbx-web/src/lib/screen/screen.service.ts +++ b/packages/dbx-web/src/lib/screen/screen.service.ts @@ -58,7 +58,7 @@ export class DbxScreenMediaService implements Destroyable { readonly widthType$: Observable = this._updateWidth.pipe( initialize(() => this._updateWidth.next()), throttleTime(100, undefined, { leading: true, trailing: true }), - map(() => this._readWeightType()), + map(() => this._readWidthType()), distinctUntilChanged(), shareReplay(1) ); @@ -100,25 +100,29 @@ export class DbxScreenMediaService implements Destroyable { this._updateWidth.complete(); } - private _readWeightType(): ScreenMediaWidthType { + private _readWidthType(): ScreenMediaWidthType { + let width: ScreenMediaWidthType; + if (this._microQuery.matches) { - return ScreenMediaWidthType.MICRO; + width = 'micro'; } else if (this._smallQuery.matches) { - return ScreenMediaWidthType.SMALL; + width = 'small'; } else if (this._tabletQuery.matches) { - return ScreenMediaWidthType.TABLET; + width = 'tablet'; } else if (this._largeQuery.matches) { - return ScreenMediaWidthType.LARGE; + width = 'large'; } else { - return ScreenMediaWidthType.FULL; + width = 'full'; } + + return width; } private _readHeightType(): ScreenMediaHeightType { if (this._tinyHeightQuery) { - return ScreenMediaHeightType.TINY; + return 'tiny'; } else { - return ScreenMediaHeightType.NORMAL; + return 'normal'; } } diff --git a/packages/dbx-web/src/lib/screen/screen.ts b/packages/dbx-web/src/lib/screen/screen.ts index de9f0619e..a83c2189f 100644 --- a/packages/dbx-web/src/lib/screen/screen.ts +++ b/packages/dbx-web/src/lib/screen/screen.ts @@ -1,34 +1,45 @@ -export enum ScreenMediaWidthType { - /** - * Screen is considered mobile. - */ - MICRO, - /** - * Screen is consider small. - */ - SMALL, - /** - * Screen is considered tablet size. - */ - TABLET, - /** - * Screen is considered large than a tablet, but not full size. - */ - LARGE, - /** - * Screen is greater than 768px. - */ - FULL +/** + * Set of screen media width types. Their pixel sizes correspond with the DbxScreenMediaService's configuration. + * + * Values: + * - micro: Screen is considered mobile. + * - small: Screen is consider small, but larger than mobile. + * - tablet: Screen is considered tablet size. + * - large: Screen is considered large than a tablet, but not full size. + * - full: Screen is greater than large. + */ +export type ScreenMediaWidthType = 'micro' | 'small' | 'tablet' | 'large' | 'full'; + +export const SCREEN_MEDIA_WIDTH_TYPE_SIZE_MAP = { + 'micro': 0, + 'small': 1, + 'tablet': 2, + 'large': 3, + 'full': 4 +} + +/** + * Describes the current screen's vertical space. + * + * Values: + * - tiny: Screen height is tiny, potentially the size of the navigation alone. + * - normal: Screen has a normal height. + */ +export type ScreenMediaHeightType = 'tiny' | 'normal'; + +/** + * Compares the breakpoint with the current width and determines if it is "active" or not. + * + * The current is considered active if it is bigger or equal to the breakpoint. + * + * @param current + * @param breakpoint + */ +export function screenMediaWidthTypeIsActive(current: ScreenMediaWidthType, breakpoint: ScreenMediaWidthType) { + return compareScreenMediaWidthTypes(current, breakpoint, (a, b) => a >= b); } -export enum ScreenMediaHeightType { - /** - * Screen height is tiny, potentially the size of the navigation alone. - */ - TINY, - /** - * Screen has a normal height. - */ - NORMAL +export function compareScreenMediaWidthTypes(a: ScreenMediaWidthType, b: ScreenMediaWidthType, compare: (a: number, b: number) => boolean) { + return compare(SCREEN_MEDIA_WIDTH_TYPE_SIZE_MAP[a], SCREEN_MEDIA_WIDTH_TYPE_SIZE_MAP[b]); } diff --git a/packages/demo/src/app/modules/doc/modules/layout/container/home.component.html b/packages/demo/src/app/modules/doc/modules/layout/container/home.component.html new file mode 100644 index 000000000..e6a0f1cd7 --- /dev/null +++ b/packages/demo/src/app/modules/doc/modules/layout/container/home.component.html @@ -0,0 +1 @@ +

docs home

\ No newline at end of file diff --git a/packages/demo/src/app/modules/doc/modules/layout/container/home.component.ts b/packages/demo/src/app/modules/doc/modules/layout/container/home.component.ts new file mode 100644 index 000000000..846e327b0 --- /dev/null +++ b/packages/demo/src/app/modules/doc/modules/layout/container/home.component.ts @@ -0,0 +1,6 @@ +import { Component } from '@angular/core'; + +@Component({ + templateUrl: './home.component.html' +}) +export class DocLayoutHomeComponent { } diff --git a/packages/demo/src/app/modules/doc/modules/layout/container/layout.component.html b/packages/demo/src/app/modules/doc/modules/layout/container/layout.component.html index c9a42e6e7..8ab3ba7fc 100644 --- a/packages/demo/src/app/modules/doc/modules/layout/container/layout.component.html +++ b/packages/demo/src/app/modules/doc/modules/layout/container/layout.component.html @@ -1 +1,6 @@ -

Todo

+ + + + + + diff --git a/packages/demo/src/app/modules/doc/modules/layout/container/layout.component.ts b/packages/demo/src/app/modules/doc/modules/layout/container/layout.component.ts index eacf5a311..ef2a92f6e 100644 --- a/packages/demo/src/app/modules/doc/modules/layout/container/layout.component.ts +++ b/packages/demo/src/app/modules/doc/modules/layout/container/layout.component.ts @@ -1,6 +1,14 @@ import { Component } from '@angular/core'; +import { ClickableAnchorLink } from '@dereekb/dbx-core'; @Component({ templateUrl: './layout.component.html' }) -export class DocLayoutLayoutComponent { } +export class DocLayoutLayoutComponent { + + readonly navAnchors: ClickableAnchorLink[] = [{ + title: 'Layout', + ref: 'doc.layout' + }]; + +} diff --git a/packages/demo/src/app/modules/doc/modules/layout/doc.layout.router.ts b/packages/demo/src/app/modules/doc/modules/layout/doc.layout.router.ts index 34a85d5d3..d55a8c626 100644 --- a/packages/demo/src/app/modules/doc/modules/layout/doc.layout.router.ts +++ b/packages/demo/src/app/modules/doc/modules/layout/doc.layout.router.ts @@ -1,12 +1,21 @@ import { Ng2StateDeclaration } from '@uirouter/angular'; +import { DocLayoutHomeComponent } from './container/home.component'; import { DocLayoutLayoutComponent } from './container/layout.component'; export const layoutState: Ng2StateDeclaration = { url: '/layout', name: 'doc.layout', component: DocLayoutLayoutComponent, + redirectTo: 'doc.layout.home' +}; + +export const homeState: Ng2StateDeclaration = { + url: '/home', + name: 'doc.layout.home', + component: DocLayoutHomeComponent, }; export const STATES: Ng2StateDeclaration[] = [ - layoutState + layoutState, + homeState ]; diff --git a/packages/demo/src/app/modules/shared/app.shared.module.ts b/packages/demo/src/app/modules/shared/app.shared.module.ts index 7eec176c5..1942f1a68 100644 --- a/packages/demo/src/app/modules/shared/app.shared.module.ts +++ b/packages/demo/src/app/modules/shared/app.shared.module.ts @@ -47,7 +47,7 @@ import { OverlayModule } from '@angular/cdk/overlay'; import { MatProgressButtonsModule } from 'mat-progress-buttons'; import { CommonModule } from '@angular/common'; import { FlexLayoutModule } from '@angular/flex-layout'; -import { DbxButtonModule, DbxAnchorModule, DbxSidenavModule, DbxTextModule } from '@dereekb/dbx-web'; +import { DbxButtonModule, DbxRouterLayoutModule, DbxTextModule, DbxLayoutModule } from '@dereekb/dbx-web'; const ANGULAR_MODULES = [ CommonModule @@ -106,8 +106,8 @@ const ANGULAR_MATERIAL_MODULES = [ const DBX_MODULES = [ DbxButtonModule, - DbxAnchorModule, - DbxSidenavModule, + DbxRouterLayoutModule, + DbxLayoutModule, DbxTextModule ];