Extendible
The main function of morfeo described here it's none other than 2 other functions combined called theme
and parsers
.
The theme
function is responsible for the providing of the design language across the application;
The parsers
function instead, is responsible of how a morfeo style object
is resolved into a valid css-in-js
object based on this theme.
Both these functions can be extended, adding typings or new functionalities.
Extend the theme
@morfeo/spec is completely written in typescript, all the interfaces used to describe each theme slice can be found in the theme-specification section.
The Theme interface and each slice are extendible, in this way you can define new theme slices or add other aliases to each slice. To do that we suggest using Declaration Merging and Module Augmentation to customize the definition of the Theme interface.
Create a declaration file (for example morfeo.d.ts
or types.d.ts
):
import { ComponentConfig } from '@morfeo/spec';
declare module '@morfeo/spec' {
// add a new Components
export interface Components extends MyComponents {
Title: ComponentConfig<'h1', 'h2', 'h3'>;
Text: ComponentConfig<'p1', 'p2', 'p3'>;
}
// add a new color
export interface Colors {
myColor: string;
}
// new theme slice
export interface Theme {
myCustomSlice: {
customValue: string;
};
}
}
Here is the result:
Extend the parsers
The parsers
singleton is composed by a set of smaller parsers, one for each property you can pass to the resolve
method;
For example there is a parser that recognize the bg
property and returns a valid style by referring the value to the colors
slice of the theme:
{ bg: "primary" } ---> { backgroundColor: morfeo.getTheme().colors.primary }
parsers
exposes other methods other than resolve, with the add
method you can define a new parser.
Let's say you want to add a parser for the property "fullSize"
, if this property it's true
the parsers will return width: '100%'
and height: '100%'
, nothing instead:
import { parsers, morfeo, ParserParams } from '@morfeo/core';
parsers.add(
'fullSize',
({ property, value, style }: ParserParams<'fullSize'>) => {
if (value) {
return {
width: '100%',
height: '100%',
};
}
return {};
},
);
const style = morfeo.resolve({ fullSize: true }); // { width: '100%', height: '100%' }
the add
method needs 2 parameters, the first is the property that should be handled, the second is a callback that will be called each time the property should be resolved; The callback receives an object with 3 attributes:
property
: the name of the property
value
: the value passed
style
: all the style passed inside the resolve function
In our example, this object will be equals to:
{
"property": "fullSize",
"value": true,
"style": { "fullSize": true }
}
What about responsive behavior in this case?
Don't worry, morfeo will think about responsive under the hood, feel free to you use your custom parser like this:
const style = morfeo.resolve({
fullSize: {
sm: false,
md: false,
lg: true,
},
});
Morfeo will automatically create all the media queries:
{
"@media (min-width: 300px)": {},
"@media (min-width: 600px)": {},
"@media (min-width: 900px)": {
"width": "100%",
"height": "100%"
}
}
Typescript
Other then this, if you're using typescript, you'll need to augment the interface CustomStyle
:
declare module '@morfeo/core' {
export interface CustomStyle {
fullSize: boolean;
}
}