Material: Export Theming logic

Created on 18 Dec 2014  路  10Comments  路  Source: angular/material

Hello,

I used to be angular, but I'm starting playing with react. I like it and I would like to use angular-material markup to build a react version of angular-material.

I just met the new ThemeProvider... This is much nicer than the previous theme handling.

But I ask myself how to extract the theme building logic from the angular module to be able to do a gulp task and/or a react mixin using the same code... I can do pull request, but I just want to be agree on how to do that.

What do you think about it ?

won't fix build feature

All 10 comments

I would love to see the theming logic in a separate package as well, as a node module that can be run in a grunt/gulp task. I'll take a swing at it and share my progress here.

I've been giving this some thought, and wanted to share my observations and ideas in case anyone else is interested...

Problem

Right now, theme-specific CSS is generated at runtime and added to the <head> section of the application in several <style> tags. This is fine for themes that are created on the fly by the end user, but is not ideal for themes that ship with the application and could be served as static CSS files.

Observations

Looking at the underlying code, here is how the theme generation currently works:

  1. During the Angular Material build process, the themeBuildStream function compiles all *-theme.scss files from components into a single CSS string that is injected into the material.core module as a constant called $MD_THEME_CSS.
  2. The module angular.core appears to only consist of the $MD_THEME_CSS constant definition. (See the end of the unminified angular-material.js file.)
  3. In theming.js there is a function called generateThemes that utilizes $MD_THEME_CSS to generate the <style> tags that get added to the <head> section at runtime.
  4. For each of the four (4) palettes in each registered theme (including the default theme), there are four (4) <style> tags added to the <head> section (e.g. .md-primary, .md-primary.md-hue-1, .md-primary.md-hue-2, .md-primary.md-hue-3). That means each registered theme results in 16 <style> tags being generated and added to the <head> section at runtime.
  5. In theming.js, a closure variable called GENERATED is used to keep track of the themes that have had their CSS added to the <head> section.

Requirements

  1. If one were able to pre-compile theme CSS, they would also need to be able to notify ngMaterial so it does not attempt to generate CSS for the themes that already have it. This would require a new service, or a new method in an existing service ($mdThemingProvider seems like a good candidate) where developers can flag a theme's CSS as generated.
  2. The generateThemes function would need to check for any themes that have been registered as CSS-generated. It already checks a GENERATED closure variable, so that variable should probably be moved into a service (see above).
  3. The $MD_THEME_CSS string should be exported to a file that can be require()'d in a Node.js app like gulp. Same goes for the generateThemes function. If something like Browserify were used in the Angular Material build process, this would be pretty easy to accomplish.

Does anyone else have any thoughts? Hopefully this can spark a discussion that will result in an improved theming system.

@sscovil - Perhaps you would like to blend these notes above into our Configuring a Theme document? Your Pull Request would be welcomed.

@ThomasBurleson I'd be happy to. Will take a look at it tonight.

@ThomasBurleson there you go. Let me know if I can be of any further assistance.

@rschmukler - can you review the https://github.com/angular/material/pull/4448 and merge if ok?

Reviewed #4448 - moving this into a post-1.0 effort / consideration for 2.0

One other issue related to injecting