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:
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:
/**
* 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:
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
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
export const componentName = 'Typography';
export default {
tag: 'p',
style: {
color: 'background',
},
variants: {
h1: {
tag: 'h1'
style: {
fontSize: '2xl',
},
}
}
}
Theme Slice
export default {
xxs: '8px',
xs: '16px',
s: '24px',
m: '32px',
l: '40px',
xl: '48px',
xxl: '56px',
};
Theme Slice with custom sliceName
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
export const themeName = 'light';
export const sliceName = 'colors';
export default {
background: 'white',
invertedBackground: 'black',
};