Themes
Dark by default; switch the page or any part of it to light with one attribute.
tokens.css defines every token for the dark theme on :root and redefines the ones that differ
for the light theme under [data-theme="light"]. The styled components only read tokens, so they
follow the theme with no extra setup.
Choose a theme
<!-- The whole page in the light theme -->
<html data-theme="light">
…
</html>
<!-- One region in light, and a dark island inside it -->
<section data-theme="light">
…
<aside data-theme="dark">…</aside>
</section>Each theme also sets color-scheme, so native form controls and scrollbars match.
Set the theme on <html> rather than on an app wrapper: components that render overlays into
document.body, such as menus and tooltips, take the theme from there.
Switch at runtime
ThemeProvider keeps the theme on <html> for you: the system
theme until the user chooses one, then their choice, stored in localStorage and restored on the
next visit. Render it once, around the app:
import { ThemeProvider } from '@contour-ui/react';
<ThemeProvider>
<App />
</ThemeProvider>;Below it, useTheme reads the theme and changes it. theme is the user's choice, system
included; resolvedTheme is the theme in use, light or dark:
import { Button, useTheme } from '@contour-ui/react';
import type { ThemeChoice } from '@contour-ui/react';
const choices: ThemeChoice[] = ['system', 'light', 'dark'];
export function ThemeSwitch() {
const { theme, setTheme } = useTheme();
return (
<fieldset>
<legend>Theme</legend>
{choices.map((choice) => (
<Button
key={choice}
variant={theme === choice ? 'solid' : 'outline'}
aria-pressed={theme === choice}
onClick={() => setTheme(choice)}
>
{choice}
</Button>
))}
</fieldset>
);
}A page rendered on the server also needs the script of themeScript() at the top of its
<head>, so the browser paints it in the right theme before the app runs: see
Set up. For code of your own, @contour-ui/tokens
exports the theme names (themes, defaultTheme) and the attribute (themeAttribute), so it
stays in sync with the stylesheet.
Headless
Headless ships no styles, so it has no themes: theme your own CSS however you like, or use the
token variables and the same data-theme attribute.