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

Commit a0ca139

Browse files
devversionThomasBurleson
authored andcommitted
feat(theming): register custom theme styles
* Add a public method, which allows developers to register their own theme styles for the app theming * Adds descriptions and examples to the service documentation. Credits to @Emeegeemee for implementing the `registerStyles` functionality. Closes #7708. Closes #7864. Closes #8641
1 parent ae9ab47 commit a0ca139

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

src/core/services/theming/theming.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,74 @@ angular.module('material.core.theming', ['material.core.theming.palette'])
1616
* @module material.core.theming
1717
*
1818
* @description Provider to configure the `$mdTheming` service.
19+
*
20+
* ### Default Theme
21+
* The `$mdThemingProvider` uses by default the following theme configuration:
22+
*
23+
* - Primary Palette: `Primary`
24+
* - Accent Palette: `Pink`
25+
* - Warn Palette: `Deep-Orange`
26+
* - Background Palette: `Grey`
27+
*
28+
* If you don't want to use the `md-theme` directive on the elements itself, you may want to overwrite
29+
* the default theme.<br/>
30+
* This can be done by using the following markup.
31+
*
32+
* <hljs lang="js">
33+
* myAppModule.config(function($mdThemingProvider) {
34+
* $mdThemingProvider
35+
* .theme('default')
36+
* .primaryPalette('blue')
37+
* .accentPalette('teal')
38+
* .warnPalette('red')
39+
* .backgroundPalette('grey');
40+
* });
41+
* </hljs>
42+
*
43+
44+
* ### Dynamic Themes
45+
*
46+
* By default, if you change a theme at runtime, the `$mdTheming` service will not detect those changes.<br/>
47+
* If you have an application, which changes its theme on runtime, you have to enable theme watching.
48+
*
49+
* <hljs lang="js">
50+
* myAppModule.config(function($mdThemingProvider) {
51+
* // Enable theme watching.
52+
* $mdThemingProvider.alwaysWatchTheme(true);
53+
* });
54+
* </hljs>
55+
*
56+
* ### Custom Theme Styles
57+
*
58+
* Sometimes you may want to use your own theme styles for some custom components.<br/>
59+
* You are able to register your own styles by using the following markup.
60+
*
61+
* <hljs lang="js">
62+
* myAppModule.config(function($mdThemingProvider) {
63+
* // Register our custom stylesheet into the theming provider.
64+
* $mdThemingProvider.registerStyles(STYLESHEET);
65+
* });
66+
* </hljs>
67+
*
68+
* The `registerStyles` method only accepts strings as value, so you're actually not able to load an external
69+
* stylesheet file into the `$mdThemingProvider`.
70+
*
71+
* If it's necessary to load an external stylesheet, we suggest using a bundler, which supports including raw content,
72+
* like [raw-loader](https://github.com/webpack/raw-loader) for `webpack`.
73+
*
74+
* <hljs lang="js">
75+
* myAppModule.config(function($mdThemingProvider) {
76+
* // Register your custom stylesheet into the theming provider.
77+
* $mdThemingProvider.registerStyles(require('../styles/my-component.theme.css'));
78+
* });
79+
* </hljs>
1980
*/
2081

82+
/**
83+
* @ngdoc method
84+
* @name $mdThemingProvider#registerStyles
85+
* @param {string} styles The styles to be appended to Angular Material's built in theme css.
86+
*/
2187
/**
2288
* @ngdoc method
2389
* @name $mdThemingProvider#setNonce
@@ -143,6 +209,9 @@ var generateOnDemand = false;
143209
var nonce = null;
144210
var disableTheming = false;
145211

212+
// Custom styles registered to be used in the theming of custom components.
213+
var registeredStyles = [];
214+
146215
function ThemingProvider($mdColorPalette) {
147216
PALETTES = { };
148217
var THEMES = { };
@@ -170,18 +239,26 @@ function ThemingProvider($mdColorPalette) {
170239
disableTheming = true;
171240
},
172241

242+
registerStyles: function(styles) {
243+
registeredStyles.push(styles);
244+
},
245+
173246
setNonce: function(nonceValue) {
174247
nonce = nonceValue;
175248
},
249+
176250
setDefaultTheme: function(theme) {
177251
defaultTheme = theme;
178252
},
253+
179254
alwaysWatchTheme: function(alwaysWatch) {
180255
alwaysWatchTheme = alwaysWatch;
181256
},
257+
182258
generateThemesOnDemand: function(onDemand) {
183259
generateOnDemand = onDemand;
184260
},
261+
185262
$get: ThemingService,
186263
_LIGHT_DEFAULT_HUES: LIGHT_DEFAULT_HUES,
187264
_DARK_DEFAULT_HUES: DARK_DEFAULT_HUES,
@@ -530,6 +607,8 @@ function generateAllThemes($injector, $mdTheming) {
530607
var head = document.head;
531608
var firstChild = head ? head.firstElementChild : null;
532609
var themeCss = !disableTheming && $injector.has('$MD_THEME_CSS') ? $injector.get('$MD_THEME_CSS') : '';
610+
// Append our custom registered styles to the theme stylesheet.
611+
themeCss += registeredStyles.join('');
533612

534613
if ( !firstChild ) return;
535614
if (themeCss.length === 0) return; // no rules, so no point in running this expensive task

src/core/services/theming/theming.spec.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,22 @@ describe('$mdThemingProvider', function() {
345345

346346
});
347347

348+
describe('$mdThemeProvider with custom styles', function() {
349+
it('appends the custom styles to the end of the $MD_THEME_CSS string', function() {
350+
module('material.core', function($mdThemingProvider) {
351+
$mdThemingProvider.registerStyles('/*test*/');
352+
$mdThemingProvider.theme('register-custom-styles');
353+
});
354+
355+
// Verify that $MD_THEME_CSS is still set to '/**/' in the test environment.
356+
// Check angular-material-mocks.js for $MD_THEME_CSS latest value if this test starts to fail.
357+
inject(function($MD_THEME_CSS) { expect($MD_THEME_CSS).toBe('/**/'); });
358+
359+
// Find the string '/**//*test*/' in the head tag.
360+
expect(document.head.innerHTML).toContain('/*test*/');
361+
});
362+
});
363+
348364
describe('$mdThemeProvider with on-demand generation', function() {
349365
var $mdTheming;
350366

0 commit comments

Comments
 (0)