Skip to content
esr360 edited this page May 9, 2019 · 13 revisions

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)

Creating a Theme

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.

themes/myTheme.json
  • 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",
            ...
        }
        ...
    }
}
modules/Accordion/configuration.js

Learn more about Module Configuration

  • The Accordion module will have a name of accordion (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 the name 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
    }
    ...
})

Overriding Modules

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.

Using a Theme

View a minimal working example of a Synergy theme

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 to window.
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
});

Synergy.theme()

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);

globals Parameter

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.

Learn more about module styles

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
})
Clone this wiki locally