Skip to content
This repository was archived by the owner on Dec 18, 2024. It is now read-only.

Commit 46e1553

Browse files
mmalerbariavalon
authored andcommitted
feat(navbar): Add themepicker component with lazy loaded themes
1 parent 48d4ea8 commit 46e1553

18 files changed

+287
-9
lines changed

angular-cli.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@
1919
"mobile": false,
2020
"styles": [
2121
"main.scss",
22-
"highlightjs/solarized-light.css"
22+
"highlightjs/solarized-light.css",
23+
{"input": "assets/pink-bluegrey.css", "lazy": true},
24+
{"input": "assets/deeppurple-amber.css", "lazy": true},
25+
{"input": "assets/indigo-pink.css", "lazy": true},
26+
{"input": "assets/purple-green.css", "lazy": true}
2327
],
2428
"scripts": [],
2529
"environmentSource": "environments/environment.ts",

karma.conf.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,20 @@ const path = require('path');
66
module.exports = function (config) {
77
config.set({
88
basePath: '',
9-
frameworks: ['jasmine', 'angular-cli'],
9+
frameworks: ['jasmine', '@angular/cli'],
1010
plugins: [
1111
require('karma-jasmine'),
1212
require('karma-chrome-launcher'),
1313
require('karma-remap-istanbul'),
14-
require('angular-cli/plugins/karma'),
14+
require('@angular/cli/plugins/karma'),
1515
require('karma-browserstack-launcher'),
1616
require('karma-sauce-launcher'),
1717
],
1818
files: [
1919
{ pattern: './src/test.ts', watched: false }
2020
],
2121
preprocessors: {
22-
'./src/test.ts': ['angular-cli']
22+
'./src/test.ts': ['@angular/cli']
2323
},
2424
mime: {
2525
'text/x-typescript': ['ts','tsx']
@@ -66,7 +66,7 @@ module.exports = function (config) {
6666
pollingTimeout: 20000
6767
},
6868
});
69-
69+
7070
if (process.env['TRAVIS']) {
7171

7272
let buildId = `TRAVIS #${process.env.TRAVIS_BUILD_NUMBER} (${process.env.TRAVIS_BUILD_ID})`;
@@ -87,5 +87,5 @@ module.exports = function (config) {
8787
}
8888

8989
config.browsers = platformMap[platformType];
90-
}
90+
}
9191
};

src/app/app-module.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
12
import {BrowserModule} from '@angular/platform-browser';
23
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
34
import {NgModule} from '@angular/core';
@@ -19,6 +20,7 @@ import {ComponentSidenav} from './pages/component-sidenav/component-sidenav';
1920
import {Footer} from './shared/footer/footer';
2021
import {ComponentPageTitle} from './pages/page-title/page-title';
2122
import {ComponentPageHeader} from './pages/component-page-header/component-page-header';
23+
import {StyleManager} from './shared/style-manager/style-manager';
2224

2325

2426
@NgModule({
@@ -32,7 +34,14 @@ import {ComponentPageHeader} from './pages/component-page-header/component-page-
3234
GuideList,
3335
GuideViewer,
3436
Homepage,
35-
Footer
37+
Footer,
38+
],
39+
schemas: [
40+
CUSTOM_ELEMENTS_SCHEMA,
41+
],
42+
exports: [
43+
MaterialDocsApp,
44+
Homepage,
3645
],
3746
imports: [
3847
BrowserModule,
@@ -47,6 +56,7 @@ import {ComponentPageHeader} from './pages/component-page-header/component-page-
4756
providers: [
4857
Location,
4958
ComponentPageTitle,
59+
StyleManager,
5060
{provide: LocationStrategy, useClass: PathLocationStrategy},
5161
],
5262
bootstrap: [MaterialDocsApp],

src/app/shared/navbar/navbar.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
</a>
99
<a md-button class="docs-button" routerLink="components">Components</a>
1010
<a md-button class="docs-button" routerLink="guides">Guides</a>
11+
<div class="flex-spacer"></div>
12+
<theme-chooser></theme-chooser>
1113
<a md-button class="docs-button" href="https://github.com/angular/material2" aria-label="GitHub Repository">
1214
<img class="docs-github-logo"
1315
src="../../../assets/img/homepage/github-circle-white-transparent.svg"

src/app/shared/navbar/navbar.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.docs-navbar {
22
display: flex;
33
flex-wrap: wrap;
4+
align-items: center;
45
padding: 8px 16px;
56

67
> .mat-button {
@@ -21,3 +22,7 @@
2122
margin: 0 7px 2px 0;
2223
vertical-align: middle;
2324
}
25+
26+
.flex-spacer {
27+
flex-grow: 1;
28+
}

src/app/shared/shared-module.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {BrowserModule} from '@angular/platform-browser';
99
import {RouterModule} from '@angular/router';
1010
import {PlunkerButton} from './plunker';
1111
import {GuideItems} from './guide-items/guide-items';
12+
import {ThemeChooser} from './theme-chooser/theme-chooser';
1213

1314

1415
@NgModule({
@@ -18,8 +19,8 @@ import {GuideItems} from './guide-items/guide-items';
1819
BrowserModule,
1920
MaterialModule,
2021
],
21-
declarations: [DocViewer, ExampleViewer, NavBar, PlunkerButton],
22-
exports: [DocViewer, ExampleViewer, NavBar, PlunkerButton],
22+
declarations: [DocViewer, ExampleViewer, NavBar, PlunkerButton, ThemeChooser],
23+
exports: [DocViewer, ExampleViewer, NavBar, PlunkerButton, ThemeChooser],
2324
providers: [DocumentationItems, GuideItems],
2425
entryComponents: [
2526
ExampleViewer,

src/app/shared/style-manager/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './style-manager';
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import {TestBed, inject} from '@angular/core/testing';
2+
import {StyleManager} from './style-manager';
3+
4+
5+
describe('StyleManager', () => {
6+
let styleManager: StyleManager;
7+
8+
beforeEach(() => TestBed.configureTestingModule({
9+
providers: [StyleManager]
10+
}));
11+
12+
beforeEach(inject([StyleManager], (sm: StyleManager) => {
13+
styleManager = sm;
14+
}));
15+
16+
afterEach(() => {
17+
let links = document.head.querySelectorAll('link');
18+
for (let link of Array.prototype.slice.call(links)) {
19+
if (link.className.includes('style-manager-')) {
20+
document.head.removeChild(link);
21+
}
22+
}
23+
});
24+
25+
it('should add stylesheet to head', () => {
26+
styleManager.setStyle('test', 'test.css');
27+
let styleEl = document.head.querySelector('.style-manager-test') as HTMLLinkElement;
28+
expect(styleEl).not.toBeNull();
29+
expect(styleEl.href.endsWith('test.css')).toBe(true);
30+
});
31+
32+
it('should change existing stylesheet', () => {
33+
styleManager.setStyle('test', 'test.css');
34+
let styleEl = document.head.querySelector('.style-manager-test') as HTMLLinkElement;
35+
expect(styleEl).not.toBeNull();
36+
expect(styleEl.href.endsWith('test.css')).toBe(true);
37+
38+
styleManager.setStyle('test', 'new.css');
39+
expect(styleEl.href.endsWith('new.css')).toBe(true);
40+
});
41+
42+
it('should remove existing stylesheet', () => {
43+
styleManager.setStyle('test', 'test.css');
44+
let styleEl = document.head.querySelector('.style-manager-test') as HTMLLinkElement;
45+
expect(styleEl).not.toBeNull();
46+
expect(styleEl.href.endsWith('test.css')).toBe(true);
47+
48+
styleManager.removeStyle('test');
49+
styleEl = document.head.querySelector('.style-manager-test') as HTMLLinkElement;
50+
expect(styleEl).toBeNull();
51+
});
52+
});
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import {Injectable} from '@angular/core';
2+
3+
4+
/**
5+
* Class for managing stylesheets. Stylesheets are loaded into named slots so that they can be
6+
* removed or changed later.
7+
*/
8+
@Injectable()
9+
export class StyleManager {
10+
/**
11+
* Set the stylesheet with the specified key.
12+
*/
13+
setStyle(key: string, href: string) {
14+
getLinkElementForKey(key).setAttribute('href', href);
15+
}
16+
17+
/**
18+
* Remove the stylesheet with the specified key.
19+
*/
20+
removeStyle(key: string) {
21+
const existingLinkElement = getExistingLinkElementByKey(key);
22+
if (existingLinkElement) {
23+
document.head.removeChild(existingLinkElement);
24+
}
25+
}
26+
}
27+
28+
function getLinkElementForKey(key: string) {
29+
return getExistingLinkElementByKey(key) || createLinkElementWithKey(key);
30+
}
31+
32+
function getExistingLinkElementByKey(key: string) {
33+
return document.head.querySelector(`link[rel="stylesheet"].${getClassNameForKey(key)}`);
34+
}
35+
36+
function createLinkElementWithKey(key: string) {
37+
const linkEl = document.createElement('link');
38+
linkEl.setAttribute('rel', 'stylesheet');
39+
linkEl.classList.add(getClassNameForKey(key));
40+
document.head.appendChild(linkEl);
41+
return linkEl;
42+
}
43+
44+
function getClassNameForKey(key: string) {
45+
return `style-manager-${key}`;
46+
}

src/app/shared/theme-chooser/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './theme-chooser';

0 commit comments

Comments
 (0)