fix(aio): reimplement side-nav

This commit is contained in:
Peter Bacon Darwin 2017-03-05 21:25:41 +00:00 committed by Igor Minar
parent 61ef756ef2
commit 46d6e8d191
5 changed files with 63 additions and 41 deletions

View File

@ -1,7 +1,7 @@
import { Component, ViewChild, OnInit } from '@angular/core'; import { Component, ViewChild, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { DocumentService, DocumentContents } from 'app/documents/document.service'; import { DocumentService, DocumentContents } from 'app/documents/document.service';
import { NavigationService, NavigationViews } from 'app/navigation/navigation.service'; import { NavigationService, NavigationViews, NavigationNode } from 'app/navigation/navigation.service';
import { SearchService, QueryResults } from 'app/search/search.service'; import { SearchService, QueryResults } from 'app/search/search.service';
@Component({ @Component({
@ -19,7 +19,7 @@ import { SearchService, QueryResults } from 'app/search/search.service';
<md-sidenav-container class="sidenav-container" (window:resize)="onResize($event.target.innerWidth)"> <md-sidenav-container class="sidenav-container" (window:resize)="onResize($event.target.innerWidth)">
<md-sidenav #sidenav class="sidenav" [opened]="isSideBySide" [mode] = "this.isSideBySide ? 'side' : 'over'"> <md-sidenav #sidenav class="sidenav" [opened]="isSideBySide" [mode] = "this.isSideBySide ? 'side' : 'over'">
<aio-nav-menu [nodes]="(navigationViews | async)?.SideNav"></aio-nav-menu> <aio-nav-menu [nodes]="(navigationViews | async)?.SideNav" [selectedNodes]="selectedNodes | async"></aio-nav-menu>
</md-sidenav> </md-sidenav>
<section class="sidenav-content"> <section class="sidenav-content">
@ -93,11 +93,13 @@ export class AppComponent implements OnInit {
currentDocument: Observable<DocumentContents>; currentDocument: Observable<DocumentContents>;
navigationViews: Observable<NavigationViews>; navigationViews: Observable<NavigationViews>;
selectedNodes: Observable<NavigationNode[]>;
searchResults: Observable<QueryResults>; searchResults: Observable<QueryResults>;
constructor(documentService: DocumentService, navigationService: NavigationService, private searchService: SearchService) { constructor(documentService: DocumentService, navigationService: NavigationService, private searchService: SearchService) {
this.currentDocument = documentService.currentDocument; this.currentDocument = documentService.currentDocument;
this.navigationViews = navigationService.navigationViews; this.navigationViews = navigationService.navigationViews;
this.selectedNodes = navigationService.activeNodes;
this.searchResults = searchService.searchResults; this.searchResults = searchService.searchResults;
} }

View File

@ -0,0 +1,27 @@
<div *ngIf="!node.children">
<a href="{{node.url}}" [ngClass]="classes" title="{{node.tooltip}}"
(click)="itemClicked()" class="vertical-menu">
{{node.title}}
</a>
</div>
<div *ngIf="node.children">
<a *ngIf="node.url != null" href="{{node.url}}" [ngClass]="classes" title="{{node.tooltip}}"
(click)="headerClicked()" class="vertical-menu heading">
{{node.title}}
<md-icon [class.expanded]="!isExpanded">keyboard_arrow_right</md-icon>
<md-icon [class.expanded]="isExpanded">keyboard_arrow_down</md-icon>
</a>
<a *ngIf="node.url == null" [ngClass]="classes" title="{{node.tooltip}}"
(click)="headerClicked()" class="vertical-menu heading">
{{node.title}}
<md-icon [class.expanded]="!isExpanded">keyboard_arrow_right</md-icon>
<md-icon [class.expanded]="isExpanded">keyboard_arrow_down</md-icon>
</a>
<div class="heading-children" [ngClass]="classes">
<aio-nav-item *ngFor="let node of node.children" [level]="level + 1"
[node]="node" [selectedNodes]="selectedNodes"></aio-nav-item>
</div>
</div>

View File

@ -80,7 +80,7 @@ a.vertical-menu {
display: none; display: none;
} }
.material-icons.active { .material-icons.expanded {
display: inline-block; display: inline-block;
position: absolute; position: absolute;
top: 6px; top: 6px;
@ -91,7 +91,7 @@ a.vertical-menu {
display: none; display: none;
} }
.heading-children.active { .heading-children.expanded {
display: block; display: block;
} }

View File

@ -1,50 +1,42 @@
import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { NavigationService, NavigationNode } from 'app/navigation/navigation.service'; import { NavigationNode } from 'app/navigation/navigation.service';
@Component({ @Component({
selector: 'aio-nav-item', selector: 'aio-nav-item',
template: ` templateUrl: 'nav-item.component.html',
<div> styleUrls: ['nav-item.component.scss']
<a *ngIf="node.url"
[href]="node.url"
[ngClass]="classes"
target={{node.target}}
title={{node.title}}
class="vertical-menu">
{{node.title}}
<ng-template [ngIf]="node.children">
<md-icon [class.active]="!isActive">keyboard_arrow_right</md-icon>
<md-icon [class.active]="isActive">keyboard_arrow_down</md-icon>
</ng-template>
</a>
<div *ngIf="!node.url" [ngClass]="classes">{{node.title}}</div>
<div class="TODO:heading-children" [ngClass]="classes" *ngIf="node.children">
<aio-nav-item *ngFor="let node of node.children" [level]="level + 1" [node]="node"></aio-nav-item>
</div>
</div>`,
styles: ['nav-item.component.scss'],
// we don't expect the inputs to change
changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class NavItemComponent implements OnInit { export class NavItemComponent implements OnChanges {
@Input() selectedNodes: NavigationNode[];
@Input() node: NavigationNode; @Input() node: NavigationNode;
@Input() level = 1; @Input() level = 1;
isActive: boolean; isExpanded = false;
isSelected = false;
classes: {[index: string]: boolean }; classes: {[index: string]: boolean };
constructor(navigation: NavigationService) { ngOnChanges(changes: SimpleChanges) {
navigation.activeNodes.subscribe(nodes => { if (changes['selectedNodes'] || changes['node']) {
this.classes['active'] = nodes.indexOf(this.node) !== -1; this.isSelected = this.selectedNodes.indexOf(this.node) !== -1;
}); }
this.setClasses();
} }
ngOnInit() { setClasses() {
this.classes = { this.classes = {
['level-' + this.level]: true, ['level-' + this.level]: true,
active: false, expanded: this.isExpanded,
heading: !!this.node.children selected: this.isSelected
}; };
} }
itemClicked() {
this.isExpanded = true;
this.isSelected = !!this.node;
}
headerClicked() {
this.isExpanded = !this.isExpanded;
this.setClasses();
}
} }

View File

@ -3,12 +3,13 @@ import { NavigationNode } from 'app/navigation/navigation.service';
@Component({ @Component({
selector: 'aio-nav-menu', selector: 'aio-nav-menu',
template: `<aio-nav-item *ngFor="let node of nodes" [node]="node"></aio-nav-item>`, template: `<aio-nav-item *ngFor="let node of nodes" [selectedNodes]="selectedNodes" [node]="node"></aio-nav-item>`
// we don't expect the inputs to change
changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class NavMenuComponent { export class NavMenuComponent {
@Input()
selectedNodes: NavigationNode[];
@Input() @Input()
nodes: NavigationNode[]; nodes: NavigationNode[];
} }