@morfeo/hooks expose a set of hooks to easily use morfeo inside a react
context.
To properly use Morfeo in a React environment, you need to have a version of react >= 18
Installation
npm i @morfeo/hooks
yarn add @morfeo/hooks
Advanced
useTheme
Use this hook to get the current theme and use it inside a components:
function MyComponent() {
const theme = useTheme();
return (
<>
<p>
My primary color is:{' '}
<code style={{ color: theme.colors.primary }}>
{theme.colors.primary}
</code>
</p>
<p>
My xl space is: <code>{theme.spacings.xl}</code>
</p>
</>
);
}
If you already know the core API useTheme is the equivalent of morfeo.getTheme()
, the main difference is that useTheme subscribes your component to theme changes and force a re-render when they'll happen, for example when dark mode is triggered.
Most of the time you don't need the whole theme, but just a slice or single value, in this cases useThemeSlice and useThemeValue will give you only the part of the theme you want:
useThemeSlice
function MyComponent() {
const colors = useThemeSlice('colors');
return (
<>
<p>
My primary color is:{' '}
<code style={{ color: colors.primary }}>{colors.primary}</code>
</p>
<p>
My secondary color is:{' '}
<code style={{ color: colors.secondary }}>{colors.secondary}</code>
</p>
</>
);
}
useThemeValue
function MyComponent() {
const primaryColor = useThemeValue('colors', 'primary');
return (
<p>
My primary color is:{' '}
<code style={{ color: primaryColor }}>{primaryColor}</code>
</p>
);
}
useCurrentTheme
A hook to retrieve the current theme name and a callback to change it,
they correspond to morfeo.getCurrentTheme
and morfeo.setCurrentTheme
of the core-api.
function Button() {
const [currentTheme, setCurrentTheme] = useCurrentTheme();
const style = useStyle({
componentName: 'Button',
color: 'text',
bg: 'background',
});
const onClick = () => {
setCurrentTheme(currentTheme === 'light' ? 'dark' : 'light');
};
return (
<button onClick={onClick} style={style}>
Toggle theme
</button>
);
}
useStyles
If you don't need the theme, but to generate a style based on the theme; The hooks useStyles
and useStyle
are made for this reason:
function MyComponent() {
const { agreeStyle, disagreeStyle, textStyle } = useStyles({
agreeStyle: { componentName: 'Button', variant: 'success', mb: 'm' },
disagreeStyle: { componentName: 'Button' },
textStyle: { fontSize: 'xl', color: 'text' },
});
return (
<div>
<p style={textStyle}>Nothing is better than a fresh beer in summer 🍺</p>
<button style={agreeStyle}>Oh yes! 🍻</button>
<button style={disagreeStyle}>What about a Coke? 🥤</button>
</div>
);
}
useStyle
Use it if you need to generate just one style:
function AgreeButton() {
const buttonStyle = useStyle({
componentName: 'Button',
variant: 'success',
});
return <button style={buttonStyle}>Agree</button>;
}
Just like useTheme, useStyles and useStyle are the equivalent of the core API's morfeo.resolve(style)
but they force a re-render when the theme changes.
Advanced
useSyncMorfeo
This hook is used under the hood in all of the others hooks, you'll probably never need to use it directly.
By using useSyncMorfeo
the component is subscribed to theme changes, which means that if the theme changes the component
will re-render:
function App() {
useSyncMorfeo();
const onClick = () => {
morfeo.setCurrentTheme(
morfeo.getCurrentTheme() === 'light' ? 'dark' : 'light',
);
};
return (
<p>
The current theme is: <code>{morfeo.getCurrentTheme()}</code>
<br />
<button onClick={onClick}>Toggle theme</button>
<br />
<i>
Try to click on the "Toggle theme" button and see the current theme
changing
</i>
</p>
);
}
If instead we use directly the morfeo
instance from the core-api without using useSyncMorfeo
, the component will not re-render when the theme changes:
function App() {
const onClick = () => {
morfeo.setCurrentTheme(
morfeo.getCurrentTheme() === 'light' ? 'dark' : 'light',
);
};
return (
<p>
The current theme is: <code>{morfeo.getCurrentTheme()}</code>
<br />
<button onClick={onClick}>Toggle theme</button>
<br />
<i>
Try to click on the "Toggle theme" button and see that nothing changes
</i>
</p>
);
}
useProps
Use it to get the default props of a components, a common use is to merge the defaut props with the current props:
function MyButton(props) {
const defaultProps = useProps('Button', 'primary');
const className = useClassName({
componentName: 'Button',
variant: 'primary',
});
return (
<button {...defaultProps} {...props} className={className}>
Button with default props
</button>
);
}