-
Notifications
You must be signed in to change notification settings - Fork 1
Theming
Theming is a generalised concept in web design/development. When using Cell, we might consider using a theme if we need to:
- Share common properties between different modules
- Change entire project look and feel on the fly by switching themes
Cell doesn't like to make too many assumptions about how your theme may ultimately exist. Cell's goal is to let you use your existing theme(s) to style your Cell modules. You can of course also use plain Sass for your themes.
If you use JavaScript for theming, Cell will ultimately convert your theme to a Sass map and expose it to your Sass under the $theme
variable. This variable is never looked up internally by Cell, but it can be accessed by your custom Cell modules.
Cell provides the theme()
utility function which is used for retreiving values from the theme. You can also use the map-get()
or map-get-deep()
functions to rereive a value from $theme
:
font-size: theme('colors', 'primary');
font-size: map-get-deep($theme, 'colors', 'primary');
Thanks to the Cell Query Draft (CQD), you can write to CSS from configuration. This means we can store CQD configuration within a theme, where it can be automatically merged it into a module's configuration later.
It's important to only include cosmetic CSS properties in themes; manipulating layout properties with themes breaks theme semantics
In order to do this, your theme should have a modules
property which stores your modules' CQD configuration (as well as any normal configuration for your module(s)):
$theme: (
'modules': (
'myModule': (
'someProperty': true,
'font-family': 'Comic Sans MS',
'padding': 20px
...
),
'anotherModule': (
...
)
)
);
export default {
'modules': {
'myModule': {
'someProperty': true,
'font-family': 'Comic Sans MS',
'padding': '20px'
...
},
'anotherModule': {
...
}
}
}
Thanks to the Cell Query Draft (CQD), when the above theme is applied it would write the following to CSS:
.myModule, [class*="myModule--"] {
font-family: 'Comic Sans MS';
padding: 20px
}
It's possible (and encouraged) to use JavaScript for theming instead
As Cell is a Sass library, the easiest (but least practical) way for a theme to exist is as a Sass map.
$theme: (
'colors': (
'primary': red,
'secondary': blue
),
'sizes': (
'small': 12px,
'large': 21px
),
'modules': (
'myModule': (
'font-family': 'Comic Sans MS'
}
}
);
// Calling `create-config` automatically merges module values from `$theme`
$config: create-config((
'name': 'myModule',
// `theme()` utility is used to get theme values
'color': theme('colors', 'primary')
...
));
// Create module styles
@include module {
...
}
See the
theme()
andcreate-config()
utility functions for more information
Sometimes you may wish to access theme values within the theme itself, as in the below example:
$theme: (
'colors': (
'primary': red,
'secondary': blue
),
'modules': (
'myModule': (
'color': theme('colors', 'secondary') // returns 'blue'
)
)
);
See the
theme()
utility function for more information
Make sure to read the JavaScript configuration page for full context and setup instructions
If using JavaScript/JSON for your theme, in order to be exposed to Cell it should exist as one of the following:
- Any valid
.json
/.json5
file - Any
.js
file that exports an object - Any
.js
file that exports a function which returns an object
For Cell to know that an imported file is intended to be a theme, it must either be called
theme.{js|json}
or have a direct parent/grand-parent directory calledthemes
@import 'themes/myTheme.js'; // `$theme` is now defined
You should ensure you import your theme into your Sass before importing your modules (you can also import your theme into each module individually)
Importing a theme into your Sass does a few things:
- It converts the resultant object of your import into a Sass map and exposes it to Sass under the
$theme
variable - It attaches the theme to your environment's global object under
global.Synergy.THEME
- ...where it can be read by subsequent JavaScript imports (namely your modules'
config.js
files)
Given the following theme.js
file imported into your Sass file:
export default {
colors: {
primary: '#ff0000',
secondary: '#0099ff'
},
sizes: {
small: '12px',
large: '21px
}
}
...it would effectively add the following code to your Sass:
$theme: (
'colors'; (
'primary': #ff0000,
'secondary': #0099ff
),
'sizes': (
'small': 12px,
'large': 21px
)
);
Configuration for a given module is merged automatically from the theme into the module's configuration by Cell during compilation (provided you have also imported a JavaScript/JSON config file into the module's Sass) (learn more).
To access your project's theme within a module's configuration, your configuration should:
- Exist as a function that returns an object
- The function should accept a
theme
argument as the first argument
export default (theme) => ({
name: 'myModule',
color: theme.colors.primary,
...
});
When this function is executed by Cell, if you have previously imported a theme file into your Sass, then the evaluated theme will be supplied as the argument. The object returned from executing this function will be converted to a Sass map and made available to your Sass under the $config
variable (learn more).
Sometimes you may wish to access theme values from within the theme itself. This can be achieved by ensuring that values requiring access to theme
exist as a function, passing a theme
parameter:
export default {
'colors': {
'primary': 'red',
'secondary': 'blue'
},
'modules': {
'myModule': {
'color': theme => theme.colors.secondary // 'blue'
}
}
}