Guide

Theming

Five built-in themes, theme-reactive components, ThemeProvider, and full control over theme switching.

Every component is Theme_Reactive

Every component in @stareezy-ui/components resolves its colors through useThemedColors() at render time. There are no hardcoded color literals in any component — all colors come from the Active_Theme via the Theme_Accessor.

This means switching themes causes every component to re-render with the correct colors for the new theme — automatically, with no extra code.

// Same component code — correct colors in all five themes
<Button variant="primary">Save</Button>
<Card p={16}>Content</Card>
<Badge variant="success">Done</Badge>

// Switch theme — all components update simultaneously
const { setTheme } = useThemeSwitch()
setTheme('aurora')       // → aurora green brand
setTheme('quasar')       // → quasar purple brand
setTheme('steins-gate')  // → electric blue brand

Five built-in themes

Stareezy UI ships five themes. Each maps the same semantic color slots to different primitive values.

"aurora"

Deep space dark — aurora green primary, nebula purple accent.

"dark"

GitHub-style dark — celuren blue primary.

"light"

Clean light — celuren blue primary, warm white surfaces.

"steins-gate"

Midnight navy — electric blue primary, divergence red danger.

"quasar"

Deep violet — quasar purple primary, pulsar orange accent.

ThemeProvider

Wrap your app with ThemeProvider and pass a theme prop. On web it injects CSS variables under [data-theme]. On React Native it provides resolved token values via context.

import { ThemeProvider } from '@stareezy-ui/tokens'

<ThemeProvider theme="aurora">...</ThemeProvider>
<ThemeProvider theme="dark">...</ThemeProvider>
<ThemeProvider theme="light">...</ThemeProvider>
<ThemeProvider theme="steins-gate">...</ThemeProvider>
<ThemeProvider theme="quasar">...</ThemeProvider>

// Partial override — inherits unspecified slots from parent
<ThemeProvider theme={{ text: { primary: colors.celurenBlue[700] } }}>
  ...
</ThemeProvider>
On web, switching themes is a single data-theme attribute change — CSS variables do the rest. No full re-render of the tree.

Theme-reactive props with t

The t accessor returns ThemeToken references. Pass them as bg, color, borderColor props — they resolve to the current theme's value at render time.

import { t } from '@stareezy-ui/tokens'

// Same component, correct colors in every theme:
<Box bg={t.backgrounds.primary} borderColor={t.border.primaryBrand}>
  <Text style={{ color: t.text.primary }} />
</Box>

// aurora       → bg: #00ff88, border: #00ff88, text: #f0f0f8
// dark         → bg: #024cce, border: #024cce, text: #f0f6fc
// light        → bg: #024cce, border: #024cce, text: #0f1010
// steins-gate  → bg: #4a9eff, border: #4a9eff, text: #e8dcc8
// quasar       → bg: #a855f7, border: #a855f7, text: #f3e8ff

Semantic slot reference

Slotlightdarkaurorasteins-gatequasar
t.text.primary#0f1010#f0f6fc#f0f0f8#e8dcc8#f3e8ff
t.text.importantBrand#024cce#024cce#00ff88#4a9eff#a855f7
t.text.danger#f2021f#ff4444#ff4444#e63030#ff4444
t.text.success#4d8d01#00ff88#00ff88#2a9d8f#22c55e
t.backgrounds.primary#024cce#024cce#00ff88#4a9eff#a855f7
t.backgrounds.primaryBlack#070707#0d1117#050505#080c18#06030f
t.border.primaryBrand#024cce#024cce#00ff88#4a9eff#a855f7
t.border.danger#f2021f#ff4444#ff4444#e63030#ff4444

useThemeSwitch

Switch themes from anywhere in the tree without prop drilling:

import { useThemeSwitch } from '@stareezy-ui/tokens'

function ThemeSwitcher() {
  const { theme, setTheme, toggleTheme, isDark } = useThemeSwitch()

  return (
    <>
      <button onClick={() => setTheme('aurora')}>Aurora</button>
      <button onClick={() => setTheme('steins-gate')}>Steins;Gate</button>
      <button onClick={() => setTheme('quasar')}>Quasar</button>
      <button onClick={toggleTheme}>{isDark ? '☀ Light' : '☾ Dark'}</button>
      <span>Current: {theme}</span>
    </>
  )
}

useTheme

Access the full resolved theme object — every leaf is a Token<string>:

import { useTheme } from '@stareezy-ui/tokens'

function MyComponent() {
  const theme = useTheme()

  return (
    <div style={{ color: theme.text.primary.value }}>
      {/* theme.text.primary.value → current theme's primary text color */}
    </div>
  )
}

Nested themes

Child ThemeProvider instances override only the tokens they specify and inherit the rest from the nearest ancestor:

<ThemeProvider theme="light">
  <Box>Normal light content</Box>

  <ThemeProvider theme="quasar">
    <Box>This section uses Quasar colors</Box>
  </ThemeProvider>
</ThemeProvider>
On React Native, resolved token values are provided via React context. Use useTheme() to access them — no CSS variables involved.

Custom themes via createUi

import { createUi, themes, token } from '@stareezy-ui/tokens'

const ui = createUi({
  themes: {
    aurora:        themes.aurora,
    dark:          themes.dark,
    light:         themes.light,
    'steins-gate': themes['steins-gate'],
    quasar:        themes.quasar,

    // Your own theme — partial override of semanticColors
    brand: {
      text: {
        primary:        token('#1a1a1a', 'brand-text-primary'),
        importantBrand: token('#FF6B35', 'brand-text-brand'),
      },
      backgrounds: {
        primary: token('#FF6B35', 'brand-bg-primary'),
      },
    },
  },
})

<ThemeProvider theme="brand">...</ThemeProvider>
The quasar theme is new in v0.4. If you are upgrading from an earlier version, add quasar: themes.quasar to your createUi config to enable it.