Themes
A theme is a named TypeStyles surface: light/dark token values (via tokens +
colorMode), optional fixed data-surface subtrees, optional custom token
namespaces (extend), and optional typed component overrides (components).
Theme class names use the configured scope: theme-var-ui-<name> (e.g.
theme-var-ui-default).
Authoring
Built-in default tokens ship from @var-ui/core (tokenValues,
defaultThemeClassName). The default theme surface is registered when you import
from the package. Use createDesignTheme({ name: '…' }) for custom themes.
Additional palette and style themes (forest, rose, AI Glow, Windows 95, …) live
as copyable examples in the docs repo under docs/src/themes/.
import { createDesignTheme, type DesignThemePreset } from '@var-ui/core';
// Reusable preset — spread into createDesignTheme
export const forestPreset: DesignThemePreset = {
tokens: {
color: {
/* light-face DesignColorValues */
},
shadow: {
/* mode-invariant overrides */
},
},
colorMode: {
dark: {
color: {
/* dark-face DesignColorValues */
},
},
},
};
export const forestTheme = createDesignTheme({
name: 'forest',
...forestPreset,
extend: {
/* optional custom tokens — see Customize */
},
components: {
/* optional — each key is `(t) => override` or a plain object; see Customize */
},
});
For a full working forest theme, see docs/src/themes/forest.ts in the var-ui repo.
Fixed-tone surfaces
Mark subtrees with data-surface="light" or data-surface="dark" to pin chrome
regardless of ambient mode. Import SURFACE_ATTRIBUTE from @var-ui/core if you
need the attribute name in code. Global color-scheme rules for these markers are
registered on package load — no theme option required.
Note:
surfacesonDesignThemeConfigis deprecated and has no effect.
Applying a theme
Wrap the app in DesignSystemProvider and pass the theme object:
import { DesignSystemProvider } from '@var-ui/react';
import { forestTheme } from './themes/forest';
export function App() {
return (
<DesignSystemProvider applyToDocument defaultColorMode="system" customTheme={forestTheme}>
{/* … */}
</DesignSystemProvider>
);
}
customTheme— preferred; pass thecreateDesignThemereturn directly.customThemeClassName— string escape hatch if you only have the class name.- When
customTheme/customThemeClassNameis set, it replaces the built-in default surface class on the provider wrapper (it does not stack both). defaultThemeClassName/ controlledtheme— light / dark / system color mode viadata-mode(independent of which palette theme class is applied).
For SPA / full-page apps, pass applyToDocument so the theme class and data-mode
live on <html> and body picks up tokenized background/text from core document globals.
For SSR without a flash of wrong mode, also use getColorModeInitScript.
Next
- Customize —
extend,components,styles.override - Design tokens — what
tokens/colorModeoverride