Skip to Content
Theming

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>;
PropTypeDefaultDescription
children*ReactNodecontent rendered inside the component
defaultThemestringlighttheme used when nothing is stored (default "light")
storageKeystring | nullgg-themelocalStorage key to persist the choice; set to null to disable
followSystembooleanfalsefall 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):

FieldTypeDescription
themestringthe active theme name
setTheme(theme: string) => voidswitch to a named theme
toggle() => voidflip between light and dark

ColorModeToggle

A ready-made light/dark switch button (uses useTheme internally).

import { ColorModeToggle } from '@gg-software/ui'; <ColorModeToggle />;
PropTypeDefaultDescription
variant"default" | "primary" | "text" | "dashed" | "link"text
size"sm" | "md" | "lg"md
classNamestring

* 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:

GroupKeys
tokens.colorbrand, brandLight, primary, primaryHover, primaryActive, primaryBg, primaryFg, success, warning, danger, info, bg, surface, surfaceElevated, border, borderSecondary, text, textSecondary, textMuted, textDisabled, fill, fillSecondary, fillTertiary, fillQuaternary
tokens.fontsans, mono
tokens.fontSizesm, base, lg, xl, h3, h2, h1
tokens.fontWeightregular, medium, semibold
tokens.spacexxs (4), xs (8), sm (12), md (16), lg (24), xl (32), xxl (48)
tokens.radiussm, md, lg, full
tokens.shadowcard, popup, control
tokens.controlHeightsm, md, lg
tokens.zIndexaffix, modal, drawer, popover, dropdown, tooltip
tokens.durationfast, 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.