-
Notifications
You must be signed in to change notification settings - Fork 10
Themes
One of the most powerful features of Synergy is the ability to create themes. Themes are used to create distinctly separate UI's using a combination of modules and custom configuration, without modifying any source code.
Using themes requires you to create your modules using the Magic Method (as opposed to the Muggle Method)
Synergy recommends keeping your themes inside a themes
directory that exists alongside the modules
directory.
|-- modules
| |-- Accordion
| | ...
|-- themes
| |-- myTheme.json
| | ...
As a theme should contain no logic and just raw values, it's recommended to use a JSON file for your theme, though you can also use standard JavaScript.
- A theme should contain a single top-level key called
theme
, containing the theme's properties - Your theme should contain a
name
property representing the name of your theme
{
"theme": {
"name": "myTheme",
"colors": {
"primary": "#005DFF",
...
}
...
}
}
- The
Accordion
module will have a name ofaccordion
(lowercase) in the config, which is the name used when rendering the module (the named used to reference the module internally can be different from the name used when rendering the module to the DOM, which is the purpose of thename
property in a module's configuration) - If a theme exists it can be supplied as an argument to the configuration function and utilised in the configuration
export default theme => ({
'name': 'accordion',
'color': 'blue',
panel: {
'color': theme.colors.primary
}
...
})
You can override a module's default configuration by creating a modules
object within the theme
object.
- Pass the name of your module (the name used in the module's interface) as a property of the
modules
object
{
"theme": {
"name": "myTheme",
"colors": {
"primary": "#005DFF",
},
"modules": {
// Theme-level Accordion properties
"Accordion": {
"color": "red"
...
}
},
...
}
}
...the values used above will override the values in the original modules/Accordion/configuration.js
file.
Several things need to occur for a theme to work, which can be handled automatically with the Synergy.theme()
method.
- Create a new Accordion config object, mering the default and custom/theme values
-
Module.config()
is used for merging a module's default configuration with custom configuration
-
- Assign the new config object to
Accordion
and subsequently assign that towindow
.
import Accordion from './modules/Accordion/Accordion.jsx';
import theme from './themes/myTheme.json';
const AccordionConfig = Module.config(Accordion.defaults(theme), theme.modules.Accordion);
window.Accordion = Object.assign(Accordion, {
config: AccordionConfig
});
The above tasks can be acted upon all of your modules at once by using the Synergy.theme()
method.
- It's recommended to export all of your modules in a single file so they can be imported all at once
import modules from './modules';
import theme from './themes/myTheme.json';
Synergy.theme(modules, theme);
Synergy.theme()
accepts a third parameter to act as a globals
object. The globals
value will be merged with the theme
object and assigned to window.ui
, and subsequently made available to your modules (for example within module styles). This is useful is you want to have a base set of values where your theme
only changes certain values, rather than being responsible for for every thematic/cosmetic value (in which case different themes may duplicate many properties).
This object is also useful for storing common tools/utilities and helper functions for your modules.
const globals = {
colors: {
primary: 'red',
secondary: 'blue'
},
sizes: {
small: '10px',
large: '18px'
},
someUtility: element => {
...
}
...
}
const theme = {
colors: {
primary: 'green',
tertiary: 'orange'
}
}
Synergy.theme(modules, theme, globals);
Now within some module's styles.js
file you can access the newly created ui
object by passing a third parameter to the styles
function.
export default (element, config, ui) => ({
'color': ui.someUtility(element) ? ui.colors.primary : ui.colors.tertiary,
'border-color': ui.colors.secondary,
'font-size': ui.sizes.small
})