Last active
July 21, 2016 04:09
-
-
Save jonpitch/655194358902cf3a0c05647dc1aca6a0 to your computer and use it in GitHub Desktop.
Ember Theming
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Ember from 'ember'; | |
export default Ember.Component.extend({ | |
theme: Ember.inject.service() | |
// ... | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Ember from 'ember'; | |
export default Ember.Route.extend({ | |
theme: Ember.inject.service(), | |
// set theme to "second" when hitting route | |
beforeModel: function() { | |
this._super(...arguments); | |
this.get('theme').setTheme('second'); | |
}, | |
actions: { | |
// set theme to "first" when leaving route | |
willTransition: function() { | |
this.get('theme').setTheme('first'); | |
this._super(...arguments); | |
} | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// usage: | |
div.my-awesome-class { | |
@include theme('color', 'primary'); | |
} | |
// results in the output: | |
div.my-awesome-class[data-theme="default-first"] { | |
color: #58b15f; | |
} | |
div.my-awesome-class[data-theme="default-second"] { | |
color: #287f6e; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Ember from 'ember'; | |
export default Ember.Service.extend({ | |
base: 'default', | |
theme: 'first', | |
// the property used as a reference for styles | |
name: Ember.computed('base', function() { | |
const base = this.get('base'); | |
const theme = this.get('theme'); | |
return `${base}-${theme}`; | |
}), | |
// update things that may be using data-theme | |
themeChanged: Ember.observer('base', 'theme', function() { | |
this.notifyPropertyChange('name'); | |
}), | |
// set the base theme for the application | |
setBase: function(base) { | |
this.set('base', Ember.isEmpty(base) ? 'default' : base); | |
}, | |
// set theme to use within base theme | |
setTheme: function(theme) { | |
this.set('theme', Ember.isEmpty(theme) ? 'first' : theme); | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// theme map | |
$themes: ( | |
default: ( | |
first: ( | |
primary: #58b15f, | |
secondary: #e3f0d8 | |
), | |
second: ( | |
primary: #287f6e, | |
secondary: #83e5d2 | |
) | |
) | |
); | |
// if theme service exists as addon - allow 3rd parties to merge into themes. | |
@if variable-exists(theme-additional) { | |
$themes: map-merge($themes, $theme-additional); | |
} | |
@mixin apply-theme() { | |
@each $base, $attributes in $themes { | |
@each $section, $values in $attributes { | |
$name: "#{$base}-#{$section}"; | |
&[data-theme="#{$name}"] { | |
} | |
} | |
} | |
} | |
// helper for SASS files to apply theme values to an element. | |
// usage: @include theme('color', 'primary'); | |
@mixin theme($cssAttribute, $themeValue) { | |
@each $base, $attributes in $themes { | |
@each $section, $values in $attributes { | |
$name: "#{$base}-#{$section}"; | |
&[data-theme="#{$name}"] { | |
@if $cssAttribute == "background" and $themeValue == "bg-image" { | |
$url: map-get($values, $themeValue); | |
#{$cssAttribute}: url($url) repeat-x; | |
} @else if $cssAttribute == "background" and $themeValue == "icon" { | |
$url: map-get($values, $themeValue); | |
#{$cssAttribute}: url($url) no-repeat; | |
} @else { | |
#{$cssAttribute}: map-get($values, $themeValue) !important; | |
} | |
// ... | |
} | |
} | |
} | |
} | |
// helper for more advanced theming. | |
// usage: @include theme-advanced('border', '', 'accent', '1px solid'); | |
@mixin theme-advanced($cssAttribute, $before, $themeValue, $after) { | |
@each $base, $attributes in $themes { | |
@each $section, $values in $attributes { | |
$name: "#{$base}-#{$section}"; | |
&[data-theme="#{$name}"] { | |
#{$cssAttribute}: #{$before} map-get($values, $themeValue) #{$after}; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment