diff --git a/src/app/pages/component-viewer/component-api.html b/src/app/pages/component-viewer/component-api.html
index 841d16d96..3de0bac87 100644
--- a/src/app/pages/component-viewer/component-api.html
+++ b/src/app/pages/component-viewer/component-api.html
@@ -2,9 +2,9 @@
API for {{componentViewer.componentDocItem.id}}
-
diff --git a/src/app/pages/component-viewer/component-overview.html b/src/app/pages/component-viewer/component-overview.html
index b40b81a66..e56dcb1b5 100644
--- a/src/app/pages/component-viewer/component-overview.html
+++ b/src/app/pages/component-viewer/component-overview.html
@@ -2,7 +2,7 @@
Overview for {{componentViewer.componentDocItem.id}}
diff --git a/src/app/pages/component-viewer/component-viewer.spec.ts b/src/app/pages/component-viewer/component-viewer.spec.ts
index aee52d75e..ccf280bc2 100644
--- a/src/app/pages/component-viewer/component-viewer.spec.ts
+++ b/src/app/pages/component-viewer/component-viewer.spec.ts
@@ -42,7 +42,7 @@ describe('ComponentViewer', () => {
it('should set page title correctly', () => {
const component = fixture.componentInstance;
fixture.detectChanges();
- const expected = `${component.docItems.getItemById(docItemsId).name}`;
+ const expected = `${component.docItems.getItemById(docItemsId, 'material').name}`;
expect(component._componentPageTitle.title).toEqual(expected);
});
});
diff --git a/src/app/pages/component-viewer/component-viewer.ts b/src/app/pages/component-viewer/component-viewer.ts
index 24be9285c..54f37b2f4 100644
--- a/src/app/pages/component-viewer/component-viewer.ts
+++ b/src/app/pages/component-viewer/component-viewer.ts
@@ -1,11 +1,13 @@
import {Component, OnInit, NgModule, ElementRef, ViewEncapsulation, ViewChild} from '@angular/core';
-import {ActivatedRoute, Router, RouterModule} from '@angular/router';
+import {ActivatedRoute, Params, Router, RouterModule} from '@angular/router';
import {DocumentationItems, DocItem} from '../../shared/documentation-items/documentation-items';
import {ComponentPageTitle} from '../page-title/page-title';
import {MatTabsModule} from '@angular/material';
import {DocViewerModule} from '../../shared/doc-viewer/doc-viewer-module';
import {CommonModule} from '@angular/common';
import {TableOfContentsModule} from '../../shared/table-of-contents/table-of-contents.module';
+import {Observable} from 'rxjs/Observable';
+
@Component({
selector: 'app-component-viewer',
@@ -22,19 +24,23 @@ export class ComponentViewer {
private router: Router,
public _componentPageTitle: ComponentPageTitle,
public docItems: DocumentationItems) {
- this._route.params.subscribe(params => {
- this.componentDocItem = docItems.getItemById(params['id']);
-
- if (this.componentDocItem) {
- this._componentPageTitle.title = `${this.componentDocItem.name}`;
- this.componentDocItem.examples.length ?
- this.sections.add('examples') :
- this.sections.delete('examples');
+ // Listen to changes on the current route for the doc id (e.g. button/checkbox) and the
+ // parent route for the section (material/cdk).
+ Observable.combineLatest(_route.params, _route.parent.params)
+ .map((p: [Params, Params]) => ({id: p[0]['id'], section: p[1]['section']}))
+ .map(p => docItems.getItemById(p.id, p.section))
+ .subscribe(d => {
+ this.componentDocItem = d;
+ if (this.componentDocItem) {
+ this._componentPageTitle.title = `${this.componentDocItem.name}`;
+ this.componentDocItem.examples.length ?
+ this.sections.add('examples') :
+ this.sections.delete('examples');
- } else {
- this.router.navigate(['/components']);
- }
- });
+ } else {
+ this.router.navigate(['/components']);
+ }
+ });
}
}
diff --git a/src/app/shared/documentation-items/documentation-items.spec.ts b/src/app/shared/documentation-items/documentation-items.spec.ts
index 9522ac7e1..ee3338fac 100644
--- a/src/app/shared/documentation-items/documentation-items.spec.ts
+++ b/src/app/shared/documentation-items/documentation-items.spec.ts
@@ -37,6 +37,6 @@ describe('DocViewer', () => {
});
it('should get a doc item by id', () => {
- expect(docsItems.getItemById('button')).toBeDefined();
+ expect(docsItems.getItemById('button', 'material')).toBeDefined();
});
});
diff --git a/src/app/shared/documentation-items/documentation-items.ts b/src/app/shared/documentation-items/documentation-items.ts
index 78b2a2c18..97d8fd331 100644
--- a/src/app/shared/documentation-items/documentation-items.ts
+++ b/src/app/shared/documentation-items/documentation-items.ts
@@ -3,6 +3,7 @@ import {Injectable} from '@angular/core';
export interface DocItem {
id: string;
name: string;
+ packageName?: string;
examples?: string[];
}
@@ -107,51 +108,47 @@ const DOCS: {[key: string]: DocCategory[]} = {
}
],
[CDK] : [
- {
- id: 'components',
- name: 'Components',
- items: [
- {id: 'table', name: 'Table', examples: []},
- {id: 'stepper', name: 'Stepper', examples: []},
-
- ]
- },
{
id: 'component-composition',
- name: 'Component Composition',
+ name: 'Common Behaviors',
items: [
+ {id: 'a11y', name: 'Accessibility', examples: []},
{id: 'observers', name: 'Observers', examples: []},
{id: 'layout', name: 'Layout', examples: []},
{id: 'overlay', name: 'Overlay', examples: []},
{id: 'portal', name: 'Portal', examples: []},
{id: 'bidi', name: 'Bidirectionality', examples: []},
{id: 'scrolling', name: 'Scrolling', examples: []},
- {id: 'viewport', name: 'Viewport', examples: []},
- ]
- },
- {
- id: 'utilities',
- name: 'Utilities',
- items: [
- {id: 'coercion', name: 'Coercion', examples: []},
- {id: 'collections', name: 'Collections', examples: []},
- {id: 'keycodes', name: 'Keycodes', examples: []},
- {id: 'platform', name: 'Platform', examples: []},
]
},
{
- id: 'accessibility',
- name: 'Accessibility',
+ id: 'components',
+ name: 'Components',
items: [
- {id: 'focus-key-manager', name: 'Focus Key Manager', examples: []},
- {id: 'focus-trap', name: 'Focus Trap', examples: []},
- {id: 'interactivity-checker', name: 'Interactivity Checker', examples: []},
- {id: 'list-key-manager', name: 'List Key Manager', examples: []},
- {id: 'live-announcer', name: 'Live Announcer', examples: []},
+ {id: 'table', name: 'Table', examples: []},
+ {id: 'stepper', name: 'Stepper', examples: []},
+
]
},
+ // TODO(jelbourn): re-add utilities and a11y as top-level categories once we can generate
+ // their API docs with dgeni. Currently our setup doesn't generate API docs for constants
+ // and standalone functions (much of the utilities) and we have no way of generating API
+ // docs more granularly than directory-level (within a11y) (same for viewport).
]
};
+
+for (let category of DOCS[COMPONENTS]) {
+ for (let doc of category.items) {
+ doc.packageName = 'material';
+ }
+}
+
+for (let category of DOCS[CDK]) {
+ for (let doc of category.items) {
+ doc.packageName = 'cdk';
+ }
+}
+
const ALL_COMPONENTS = DOCS[COMPONENTS].reduce(
(result, category) => result.concat(category.items), []);
const ALL_CDK = DOCS[CDK].reduce((result, cdk) => result.concat(cdk.items), []);
@@ -174,8 +171,9 @@ export class DocumentationItems {
return [];
}
- getItemById(id: string): DocItem {
- return ALL_DOCS.find(i => i.id === id);
+ getItemById(id: string, section: string): DocItem {
+ const sectionLookup = section == 'cdk' ? 'cdk' : 'material';
+ return ALL_DOCS.find(doc => doc.id === id && doc.packageName == sectionLookup);
}
getCategoryById(id: string): DocCategory {
diff --git a/src/app/shared/table-of-contents/table-of-contents.ts b/src/app/shared/table-of-contents/table-of-contents.ts
index b358154b9..9735aeed2 100644
--- a/src/app/shared/table-of-contents/table-of-contents.ts
+++ b/src/app/shared/table-of-contents/table-of-contents.ts
@@ -1,10 +1,11 @@
-import {Component, Input, Inject, ElementRef, OnInit} from '@angular/core';
+import {Component, ElementRef, Inject, Input, OnInit} from '@angular/core';
import {DOCUMENT} from '@angular/platform-browser';
-import {Router, ActivatedRoute, NavigationEnd} from '@angular/router';
-import {Observable} from 'rxjs/Observable';
-import {Subscription} from 'rxjs/Subscription';
+import {ActivatedRoute, NavigationEnd, Router} from '@angular/router';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/operator/debounceTime';
+import 'rxjs/add/operator/takeUntil';
+import {Observable} from 'rxjs/Observable';
+import {Subject} from 'rxjs/Subject';
interface Link {
/* id of the section*/
@@ -36,9 +37,7 @@ export class TableOfContents implements OnInit {
_rootUrl: string;
private _scrollContainer: any;
- private _scrollSubscription: Subscription;
- private _routeSubscription: Subscription;
- private _fragmentSubscription: Subscription;
+ private _destroyed = new Subject();
private _urlFragment = '';
constructor(private _router: Router,
@@ -46,7 +45,7 @@ export class TableOfContents implements OnInit {
private _element: ElementRef,
@Inject(DOCUMENT) private _document: Document) {
- this._routeSubscription = this._router.events.subscribe((event) => {
+ this._router.events.takeUntil(this._destroyed).subscribe((event) => {
if (event instanceof NavigationEnd) {
const rootUrl = _router.url.split('#')[0];
if (rootUrl !== this._rootUrl) {
@@ -56,7 +55,7 @@ export class TableOfContents implements OnInit {
}
});
- this._fragmentSubscription = this._route.fragment.subscribe(fragment => {
+ this._route.fragment.takeUntil(this._destroyed).subscribe(fragment => {
this._urlFragment = fragment;
const target = document.getElementById(this._urlFragment);
@@ -73,17 +72,15 @@ export class TableOfContents implements OnInit {
this._scrollContainer = this.container ?
this._document.querySelectorAll(this.container)[0] : window;
- this._scrollSubscription = Observable
- .fromEvent(this._scrollContainer, 'scroll')
+ Observable.fromEvent(this._scrollContainer, 'scroll')
+ .takeUntil(this._destroyed)
.debounceTime(10)
.subscribe(() => this.onScroll());
});
}
ngOnDestroy(): void {
- this._routeSubscription.unsubscribe();
- this._scrollSubscription.unsubscribe();
- this._fragmentSubscription.unsubscribe();
+ this._destroyed.next();
}
updateScrollPosition(): void {