-
Notifications
You must be signed in to change notification settings - Fork 9
Themes
Themes are used to create distinctly separate UI's using a combination of modules and custom configuration.
By default themes exist in the src/themes
directory. As each theme can be comprised of multiple files, it is neccessery to create a separate directory for each theme.
|-- src
| |-- themes
| | |-- One-Nexus
| | | |-- config.json
| | | |-- One-Nexus.js
| | | |-- One-Nexus.scss
Pass the js
and scss
files to their respective compilers and they will generate your project's UI using the configuration from the json
file. If using the provided Grunt
tasks, you can run grunt theme
to do this.
The theme's JavaScript file must first import the app
('src/app.js'):
import * as app from '../../app';
Next, the theme's configuration is imported:
import * as app from '../../app';
import config from './config.json';
Finally, the configuration is exposed to the entire app:
import * as app from '../../app';
import config from './config.json';
app.theme = config.app;
Modules from the app
can now be included:
import * as app from '../../app';
import config from './config.json';
app.theme = config.app;
app.accordion();
app.carousel();
app.modal();
...
Like with the corresponding JavaScript file, the theme's Sass file must first import the app
('src/_app.scss'):
@import '../../app';
And again, the theme's configuration is imported:
@import '../../app';
@import './config.json';
Modules from the app
can now be included:
@import '../../app';
@import './config.json';
@include accordions;
@include carousels;
@include modals;
This file is used to store custom configuration for any modules that are included, overwriting the default value. To use a module's default configuration entirely, you do not need to add it to this object.
The below values should be considered pseudo values and may not reflect real module options
{
"app": {
"accordions": {
"title": {
"color": "red",
"active": {
"color": "#454545"
}
},
"keepOpenModifier": "keepOpen"
},
"carousels": {
"nav-buttons": {
"enabled": "true"
}
},
"billboard": {
"fullscreen": {
"enabled": true,
"min-height": "500px"
},
"overlay": {
"enabled": false
}
}
}
}
Each module can have any number of configuration options. All values for a module are accessible in the module's corresponding scss
and js
files, even options which may seemingly only suit one of these technologies. It makes things eaiser keeping all of the module's configuration in one place, and it helps with keeping things modular.
However, it is entirely possible to use modules in a way which don't have shared configuration in the form of JSON, where the corresponding scss
and js
files have their own config options. Rather than having a common app JSON file (and separate JSON files for each module), config would be passed to modules when including them, like so:
import * as app from '../../app';
app.accordion({
keepOpenModifier: 'keepOpen'
});
app.carousel();
...
@import '../../app';
@include accordions((
'title': (
'color': red,
'active': (
'color': #454545
)
)
));
@include carousels;
...
Understanding that configuration can be passed to modules in this way opens up the explanation as to how modules will use any custom configuration that exists in config.json
.
When a module is called without any options passed to it, it will search for the global app
object. In Sass, this object is created by Sass-JSON-Vars when config.json
is imported (@import './config.json'
), and accessible by the $app
variable (the variable name is determined by the first key in the JSON object, which in the case for One-Nexus is app
). Having access to this variable allows it to be searched for configuration. Specifically, this is handled by the custom
function:
@function custom($module) {
@return if(variable-exists('app') and map-get($app, $module), map-get($app, $module), ())
}
So this means when calling a module, custom configuration (if it exists in config.json
) can be passed to it like so:
@import '../../app';
@import './config.json'; // config now accessible globally by `$app` variable
@include accordions(custom('accordions'));
And to avoid the need for doing this with every module, custom(MODULE_NAME)
is passed as a default parameter when defining modules, as seen in the Accordions example:
@mixin accordions($custom: custom('accordions')) {
...
}
And it works exactly the same way for the corresponding JavaScript. The configuration object is created after importing config.json
:
import * as app from '../../app';
import config from './config.json';
app.theme = config.app; // `app.theme` now exposes the same information as `$app` in the Sass
Again, One-Nexus provides a custom
JS function (accessed by app.custom
) which can be used to search app.theme
for any existing custom configuration. This means when calling a module, custom configuration (if it exists in config.json
) can be passed to it like so:
import * as app from '../../app';
import config from './config.json';
app.theme = config.app;
app.accordion(app.custom('accordions'));
And again just like with the corresponding Sass, to avoid the need for doing this with every module, app.custom(MODULE_NAME)
is built into the module definition.