Skip to Content

Themes

Zen supports light and dark themes out of the box. Themes are applied using CSS custom properties that automatically adjust colors, backgrounds, and borders based on the active theme.

Setup

Wrap your application with ZenProvider to enable theme support.

import { ZenProvider } from '@umami/react-zen'; function App() { return ( <ZenProvider> <YourApp /> </ZenProvider> ); }

Theme options

You can configure the initial theme using the theme or colorScheme props.

// Force a specific theme <ZenProvider theme="dark"> // Use system preference <ZenProvider colorScheme="system"> // Default to light, but respect system preference <ZenProvider colorScheme="light">

ThemeButton

Use the ThemeButton component to let users toggle between light and dark themes.

<ThemeButton variant="outline" />

Local themes

You can scope theme changes to a specific container using the target prop. This allows parts of your UI to have a different theme than the rest of the page.

This container has its own theme
function LocalThemeExample() { const containerRef = useRef(null); return ( <Box ref={containerRef} padding="6" backgroundColor="surface-base"> <Row alignItems="center" justifyContent="space-between"> <Text>This container has its own theme</Text> <ThemeButton target={containerRef} /> </Row> </Box> ); }

useTheme hook

Access and control the current theme programmatically with the useTheme hook.

import { useTheme } from '@umami/react-zen'; function MyComponent() { const { theme, setTheme } = useTheme(); return ( <Button onPress={() => setTheme(theme === 'light' ? 'dark' : 'light')}> Current theme: {theme} </Button> ); }

CSS variables

Themes work by redefining CSS custom properties. The following variables change based on the active theme:

VariableDescription
--surface-basePrimary background color
--surface-raisedElevated surface background
--surface-sunkenRecessed surface background
--surface-overlayOverlay/modal background
--text-primaryPrimary text color
--text-mutedMuted/subtle text color
--border-defaultDefault border color
--border-strongEmphasized border color
--interactive-bgInteractive element background
--primaryPrimary/accent color

Theme persistence

Theme preference is automatically saved to localStorage under the key theme. When the page loads, the stored preference is restored.

Dark mode classes

Zen applies both data-theme="dark" attribute and the .dark class to the root element for maximum compatibility with Tailwind CSS and other frameworks.

Color palettes

Zen supports multiple gray-scale palettes inspired by Tailwind CSS. Each palette has a different color temperature and character.

Select palette:
50
100
200
300
400
500
600
700
800
900
950

Available palettes

PaletteDescription
neutralPure gray with no color tint (default)
slateCool blue-gray tones
graySlight blue tint
zincSubtle blue undertones
stoneWarm tan/brown tones

Setting the palette

You can set the palette via ZenProvider or programmatically with useTheme.

// Via provider <ZenProvider palette="slate"> <YourApp /> </ZenProvider> // Programmatically const { palette, setPalette } = useTheme(); setPalette('zinc');

PaletteSwitcher

Use the PaletteSwitcher component to let users switch between palettes.

<PaletteSwitcher />

Palette persistence

Palette preference is automatically saved to localStorage under the key zen.palette. The data-palette attribute is applied to the root element.