Theming
Theming is driven entirely by CSS custom properties. styles.css defines the design
tokens on :root, plus a light theme (:root, [data-theme="light"]) and a dark theme
([data-theme="dark"]). Switching theme = setting data-theme on <html> (or any subtree —
the variables cascade).
:root /* brand colors, typography, spacing, radius, motion, z-index */
:root, [data-theme="light"] /* light surfaces, text, borders, fills, shadows */
[data-theme="dark"] /* dark surfaces, text, borders, fills, shadows */ThemeProvider
React context that manages the active theme: reads the stored choice (or the OS preference),
applies it to <html data-theme>, and persists changes to localStorage.
import { ThemeProvider } from '@gg-software/ui';
<ThemeProvider defaultTheme="light" followSystem>
<App />
</ThemeProvider>;| Prop | Type | Default | Description |
|---|---|---|---|
children* | ReactNode | — | content rendered inside the component |
defaultTheme | string | light | theme used when nothing is stored (default "light") |
storageKey | string | null | gg-theme | localStorage key to persist the choice; set to null to disable |
followSystem | boolean | false | fall back to the OS color scheme when nothing is stored |
* required · generated from packages/ui/src/theme/ThemeProvider.tsx
useTheme
Reads and controls the active theme. Works inside a <ThemeProvider>; outside one it falls
back to managing data-theme directly (no persistence).
import { useTheme } from '@gg-software/ui';
function ThemeButtons() {
const { theme, setTheme, toggle } = useTheme();
return (
<>
<span>Current: {theme}</span>
<button onClick={toggle}>Toggle</button>
<button onClick={() => setTheme('dark')}>Dark</button>
</>
);
}Returned value (ThemeContextValue):
| Field | Type | Description |
|---|---|---|
theme | string | the active theme name |
setTheme | (theme: string) => void | switch to a named theme |
toggle | () => void | flip between light and dark |
ColorModeToggle
A ready-made light/dark switch button (uses useTheme internally).
import { ColorModeToggle } from '@gg-software/ui';
<ColorModeToggle />;| Prop | Type | Default | Description |
|---|---|---|---|
variant | "default" | "primary" | "text" | "dashed" | "link" | text | |
size | "sm" | "md" | "lg" | md | |
className | string | — |
* required · generated from packages/ui/src/theme/ColorModeToggle.tsx
setTheme
Imperatively switch the active theme via the data-theme attribute on <html>. This is
what ThemeProvider calls under the hood; use it directly in non-React code.
import { setTheme } from '@gg-software/ui';
setTheme('dark');initializeTheme
Register (or update) a custom named theme’s CSS variables at runtime. It injects a
<style> tag with a [data-theme="<name>"] block, so the theme becomes activatable with
setTheme(name).
import { initializeTheme, setTheme } from '@gg-software/ui';
initializeTheme('ocean', {
'gg-color-brand': '#0e7490',
'gg-color-bg': '#f0fdff',
});
setTheme('ocean');The variable map is typed as ThemeProperty = Record<`gg-${string}`, string> — keys are
written without the leading --.
tokens
Design tokens as CSS var() references, for use in inline styles / JS. They resolve against
the active theme, so they stay theme-correct.
import { tokens } from '@gg-software/ui';
<div
style={{
color: tokens.color.primary,
padding: tokens.space.md,
borderRadius: tokens.radius.lg,
boxShadow: tokens.shadow.card,
}}
/>;Available groups:
| Group | Keys |
|---|---|
tokens.color | brand, brandLight, primary, primaryHover, primaryActive, primaryBg, primaryFg, success, warning, danger, info, bg, surface, surfaceElevated, border, borderSecondary, text, textSecondary, textMuted, textDisabled, fill, fillSecondary, fillTertiary, fillQuaternary |
tokens.font | sans, mono |
tokens.fontSize | sm, base, lg, xl, h3, h2, h1 |
tokens.fontWeight | regular, medium, semibold |
tokens.space | xxs (4), xs (8), sm (12), md (16), lg (24), xl (32), xxl (48) |
tokens.radius | sm, md, lg, full |
tokens.shadow | card, popup, control |
tokens.controlHeight | sm, md, lg |
tokens.zIndex | affix, modal, drawer, popover, dropdown, tooltip |
tokens.duration | fast, mid, slow |
The Tokens type (typeof tokens) is exported too.
SpaceValue
Layout components (Box, Stack, Flex, Grid, Spacer) accept spacing as SpaceValue:
type SpaceValue = 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | number | string;Named values map to the spacing scale (--space-*); a number is treated as pixels; any
other string is passed through as a raw CSS length.