Skip to main content

Compose command

Installations

To install the CLI you just have to add it to your devDependencies:

yarn add --dev @morfeo/cli
# or npm add -D @morfeo/cli

Or using it directly with npx

npx @morfeo/cli compose --help

The details about all the flags and the configurations of @morfeo/cli can be found in the packages section, here.

Introduction

The theme object can rapidly grow and became hard to review, it's always a good choice to split the theme in multiple files and then re-compose the original theme by importing this files, most of the theme object will look to something like this:

theme.ts
import colors from 'path-to-colors';
import gradients from 'path-to-gradients';
// ...
import buttonConfig from 'path-to-buttonConfig';
import typographyConfig from 'path-to-typographyConfig';

export const theme = {
colors,
gradients,
// ...
components: {
Input: inputConfig,
Button: buttonConfig,
},
};

Instead of doing it manually, the compose command it's a way to compose the theme completely automatically, you just have to write regular typescript files (morfeo style files) wherever you want in your application. These files are easily recognizable by the custom extension: {name}.morfeo.ts

For example in the following structure we can recognize 3 morfeo style files:

src
-- config
-- -- colors.morfeo.ts
-- -- spacings.morfeo.ts
-- components
-- -- Button
-- -- -- index.tsx
-- -- -- Button.morfeo.ts

by running morfeo compose these files will be composed into a single theme object or (in case of multi-theming) in multiple theme objects.

Morfeo style file

A morfeo style file it's a simple typescript file that contains a component configuration or a theme slice. The structure of this file is the following:

{fileName}.morfeo.ts
/**
* Optional
* Useful if the exported style should be applied only in one theme, for example a set of colors
* to be used only in the dark theme.
* If not specified the style will be applied to all the themes.
*/
export const themeName = 'themeName';

/**
* Optional
* Default it's the name of the current file, for example:
* - `colors.morfeo.ts` --> sliceName = 'colors';
*/
export const sliceName = 'sliceName';

/**
* Optional
* Default it's the name of the current file, for example:
* - `Button.morfeo.ts` --> componentName = 'Button';
*/
export const componentName = 'componentName';

export default {
// Can be a component config or a theme slice depending on:
// - the name of the file (if its colors, gradients ... it's a slice, a component instead);
// - the previous values (if sliceName is specified it's a slice, a component instead)
};
Naming convention

If you don't export sliceName or componentName morfeo will understand if the type of the exported value it's a theme slice or a component configuration by only using the file name;

File names like colors, gradients, shadows or any other slice name will be automatically recognized so there is no need to specify sliceName; All the other name will be treated as a component configuration.

If you can't name the file properly just export sliceName or componentName with the right values.

How to use

First of all you should create a .morfeorc file where you will specify the paths to your themes:

.morfeorc
export default {
themes: {
light: `path/where/the theme will be placed`,
// ...
},
};

The most simple usage is just running the command:

morfeo compose

Watch mode

morfeo compose --watch

In this case, the process will run and re-compose the theme any time a morfeo style file is updated.

For advanced usage like custom config file path, check here the full specification of morfeo compose command.

Examples

Component Configuration

Button.morfeo.ts
// Button.morfeo.ts
export default {
tag: 'button',
style: {
bg: 'background',
},
variants: {
success: {
style: {
bg: 'success',
},
},
},
};

This file specify the configuration of the Button component, after running the command we expect to find inside the theme the following configuration for the Button component:

const theme = {
// ...
components: {
// ...
Button: {
tag: 'button',
style: {
bg: 'background',
},
variants: {
success: {
style: {
bg: 'success',
},
},
},
},
},
};

Component Configuration with custom componentName

component.morfeo.ts
export const componentName = 'Typography';

export default {
tag: 'p',
style: {
color: 'background',
},
variants: {
h1: {
tag: 'h1'
style: {
fontSize: '2xl',
},
}
}
}

Theme Slice

spacings.morfeo.ts
export default {
xxs: '8px',
xs: '16px',
s: '24px',
m: '32px',
l: '40px',
xl: '48px',
xxl: '56px',
};

Theme Slice with custom sliceName

slice.morfeo.ts
export const sliceName = 'spacings';

export default {
xxs: '8px',
xs: '16px',
s: '24px',
m: '32px',
l: '40px',
xl: '48px',
xxl: '56px',
};

Style applied to only one theme

lightColors.morfeo.ts
export const themeName = 'light';

export const sliceName = 'colors';

export default {
background: 'white',
invertedBackground: 'black',
};