Skip to content

Module Configuration

esr360 edited this page Feb 13, 2020 · 12 revisions

Overview

One of the most useful aspects of Synergy is the ability to configure your Modules. By abstracting design decisions to configuration, you can leave the Module's source code cleaner and more concise, whilst also allowing them to be more flexible and customizable.

Configuration should be used to store any configurable aspect of your Module

Creating Configuration

Object

Configuration can exist as a plain object:

export default {
  someProperty: true
}

Function (Exposes Theme)

Or if you require your project's theme to be exposed to your Module's config, your config can exist as a function that accepts a theme argument:

export default (theme) => ({
  someProperty: theme.someThemeProperty
})

Passing Configuration

Configuration should be passed to the config prop of the <Module> instance

import React from 'react';
import { Module } from '@onenexus/synergy';
import styles from './styles';
import config from './config';

const MyModule = (props) => (
  <Module name='MyModule' styles={styles} config={config} {...props}>
    {props.children}
  </Module>
);

export default MyModule;

Accessing Evaluated Configuration

When using themes, you can provide additional (or custom) configuration to your Modules at run-time. Your Module's configuration can also exist as a function instead of an object. This means that the final evaluated config for a given Module (the config exposed to your styles) is likely to be different from the config reference you import and pass to the config prop (but doesn't have to be) - so in this case the evaluated configuration is what would be required.

From Within Your Module's Styles

Learn more

export default ({ config }) => ({
  margin: config.gutter,
  ...
});

From Within Your Module's JSX

In some cases, you may wish to access your Module's final evaluated configuration within the Module's JSX in addition to accessing it within the Module's styles.

Using Render Function
import React from 'react';
import { Module } from '@onenexus/synergy';
import styles from './styles';
import config from './config';

const myModule = (props) => (
  <Module styles={styles} config={config} {...props}>
    {({ config }) => {

      // some logic using `config`...

      return props.childre;
    }}
  </Module>
);

export default MyModule;

Note that using a render function with <Module> also exposes some other useful objects

Using Hooks
import React from 'react';
import { Module, useConfig, useTheme } from '@onenexus/synergy';
import styles from './styles';
import config from './config';

const myModule = (props) => {
  const theme = useTheme();
  const evaluatedConfig = useConfig(config, theme);

  // some logic using `evaluatedConfig`...

  return (
    <Module styles={styles} config={config} {...props}>
      {props.childre}
    </Module>
  );
}

export default MyModule;

Retreiving Cosmetic Styles From Config

As configuration can often map directly to CSS properties (e.g color, fontSize, fontFamily etc...), it's possible for you to pass your Module's configuration object (if it has one) to a styles array, where configuration properties that correspond to CSS properties will be parsed:

Learn more about this convention

const config = {
  fontSize: '12px',
  someNoneCSSProp: true,
  color: 'purple',
  myComponent: {
    color: 'green',
    anotherGeneralProp: false
  }
}

const styles = ({ config }) => {
  // some non-cosmetic/configurable style properties
  const layout = {
    position: 'relative',

    myComponent: {
      display: 'flex'
    }
  }
  
  // return an array passing the config as one of the values,
  // so that styles can be retreived and parsed from it
  return [config, layout];
}

const MyModule = () => (
  <Module styles={styles} config={config}>
    <Component name='myComponent'>
      ...
    </Component>
    <Component name='myComponent'>
      ...
    </Component>
  </Module>
);

All Objects returned by styles (i.e [config, layout]) will be parsed as Cell Query, allowing you to style the Module and its Components as plain Objects (including JSON)