Dark Mode
There are 2 ways to customize styles for dark mode in Morfeo, one at Style level, similar to how Morfeo's handles Responsive Styles, and one at Theme level.
Style Level
Just like with the Responsive Value
, we can pass to properties an object that specifies the value that the property should have for dark (or light) mode:
import { morfeo } from '../morfeo';
const classes = morfeo.css({
container: {
px: 'm',
bg: {
light: 'black',
dark: 'white',
},
color: {
light: 'white',
dark: 'black',
},
},
});
export function Card() {
return (
<div className={classes('container')}>
This card will have a different background and text color based on the
user's preferred scheme.
</div>
);
}
Theme Level
In most of the applications, the difference between dark and light modes is just colors
and something color-related like gradients
and shadows
.
Morfeo makes you customize exactly these slices so then it will apply the right styles at the right color schemes
automatically, so you don't have to worry about it while styling your components:
The values of the colors background
and text
, when used inside a style, will automatically be adapted based on the current user's preferred color scheme.
const theme = {
// ...
colors: {
primary: '#0066ff', // Always the same no matter the color scheme.
// Dynamic color
background: {
light: '#ffffff', // Used only in light mode
dark: '#000000', // Used only in dark mode
},
// Dynamic color
text: {
light: '#2f2f2f', // Used only in light mode
dark: '#ececec', // Used only in dark mode
},
},
};
Customization
Sometimes you want to switch between a light and dark mode in other ways than the @media (prefers-colors-scheme)
rule, Morfeo lets you customize this completely by overriding the slice colorSchemes
, for example:
const theme = {
// ...
colorSchemes: {
- dark: '@media (prefers-color-scheme: 'dark')',
+ dark: '[data-theme="dark"]',
- light: '@media (prefers-color-scheme: 'light')',
+ light: '[data-theme="light"]',
/**
* No one is blocking you from creating custom color schemes too, but be aware that the only
* possible values for "@media (prefers-colors-scheme)" are light and dark.
*/
custom: '[data-theme="custom"]',
},
};
With this customization, you're telling Morfeo to use dark-specific values under any HTML element that has the data-theme
attribute equal to dark
:
import { morfeo } from '../morfeo';
const classes = morfeo.css({
button: {
bg: {
light: 'primary',
dark: 'secondary',
},
},
});
export function Card() {
const [darkMode, setDarkMode] = useState(false);
function toggleDarkMode() {
setSchema(prev => !prev);
}
return (
<div data-theme={darkMode ? 'dark' : 'light'}>
The following button will have the background color equal to "primary" if
in light mode, "secondary" otherwise.
<button className={classes('button')} onClick={toggleDarkMode}>
Toggle
</button>
<div data-theme="light">
Here instead, the button will always have a "primary" background because
light mode is forced.
<button className={classes('button')} onClick={toggleDarkMode}>
Toggle
</button>
</div>
</div>
);
}