Token API
Tokens, the t accessor, createUi, and theme-reactive component props.
Token<T>
Every design value is a frozen Token<T> object with three fields:
type Token<T> = {
readonly __token: true // discriminant — lets the compiler detect token props
readonly id: string // stable unique identifier, e.g. "celurenBlue-500"
readonly value: T // resolved design value, e.g. "#024CCE"
}Create your own tokens with the token() factory:
import { token } from '@stareezy-ui/tokens'
const brandPrimary = token('#FF6B35', 'brand-primary')
brandPrimary.value // "#FF6B35"
brandPrimary.id // "brand-primary"__token: true discriminant is what lets the Babel/Vite compiler detect token props at build time and replace them with atomic CSS class names — zero runtime cost.Static token props
Pass token objects directly as props on Box and other primitives. TypeScript autocompletes and validates every value:
import { colors, spacing, radius } from '@stareezy-ui/tokens'
import { Box, Text } from '@stareezy-ui/components'
function Card() {
return (
<Box
bg={colors.celurenBlue[500]} // Token<string> — always #024CCE
p={spacing[4]} // Token<number> — always 16px
rounded={radius.md} // Token<number> — always 10px
>
<Text type="M-heading-bold" text="Hello" />
</Box>
)
}Static tokens always resolve to their fixed .value — they don't change when the theme switches. Use them for values that should be the same across all themes.
Theme-reactive props with t
The t accessor returns ThemeToken references — lightweight objects that resolve to the current theme's value at render time. When the theme switches, every component using a ThemeToken re-renders with the correct color automatically.
import { t } from '@stareezy-ui/tokens'
import { Box, Text } from '@stareezy-ui/components'
function Card() {
return (
// These resolve to the CURRENT theme's value at render time:
// aurora → backgrounds.primary = #00ff88
// dark → backgrounds.primary = #024cce
// steins-gate → backgrounds.primary = #4a9eff
<Box
bg={t.backgrounds.primary}
borderColor={t.border.primaryBrand}
p={16}
rounded={8}
>
<Text
style={{ color: t.text.primary }} // also works in style objects
type="M-heading-bold"
text="Auto-switches with theme"
/>
</Box>
)
}t is a typed proxy tree — TypeScript knows every valid path. t.text.primary, t.backgrounds.secondary, t.border.danger — all autocomplete and type-check.Available t slots
t.text.primary.secondary.tertiary.placeholder.disable.inverse.importantBrand.danger.success.dangerPrimary.successPrimary.warningPrimaryt.backgrounds.primary.secondary.disabled.primaryBlackt.border.default.secondary.tertiary.primaryBrand.danger.success.dangerPrimary.successPrimary.primaryBlackResolving ThemeTokens manually
When you need the raw string value inside a component (e.g. for a non-Box element), use useResolveThemeToken:
import { t, useResolveThemeToken } from '@stareezy-ui/tokens'
function MyComponent() {
const brandColor = useResolveThemeToken(t.text.importantBrand)
// aurora → "#00ff88"
// steins-gate → "#4a9eff"
// dark/light → "#024cce"
return <canvas style={{ borderColor: brandColor }} />
}createUi
Call createUi() once at app startup to register themes, custom tokens, breakpoints, fonts, and shorthands. The returned ui object exposes ui.t (same as the standalone t), ui.tokens, and helper methods.
import { createUi, token, themes } from '@stareezy-ui/tokens'
export const ui = createUi({
// Register all four themes
themes: {
aurora: themes.aurora,
dark: themes.dark,
light: themes.light,
'steins-gate': themes['steins-gate'],
},
// Custom token groups — fully typed on ui.tokens
tokens: {
brand: {
primary: token('#FF6B35', 'brand-primary'),
secondary: token('#004E89', 'brand-secondary'),
},
},
// Responsive breakpoints
media: { sm: 480, md: 768, lg: 1024, xl: 1280, '2xl': 1536 },
// Prop shorthands for Box
shorthands: { bg: 'backgroundColor', p: 'padding' },
})
// Access custom tokens with full type safety
ui.tokens.brand.primary.value // "#FF6B35"
ui.tokens.colors.celurenBlue[500].value // "#024CCE"
// ui.t is the same as the standalone t accessor
<Box bg={ui.t.backgrounds.primary} />ui from a single ui.config.ts file and import it wherever you need typed token access. This is the recommended pattern — one config, full type inference everywhere.Accessing raw values
Every token exposes its raw value via .value. Use this when you need a plain string or number (e.g. inline styles, RN StyleSheet, canvas):
import { colors, spacing, radius } from '@stareezy-ui/tokens'
colors.celurenBlue[500].value // "#024CCE"
spacing[4].value // 16
radius.md.value // 10
// In a non-Box context
const style = {
backgroundColor: colors.celurenBlue[500].value,
padding: spacing[4].value,
borderRadius: radius.md.value,
}Token categories
colorsFull palette — celurenBlue, raisinBlack, beauBlue, lawnGreen, crimsonRed, neutral…
semanticColorsRole-based — text.primary, backgrounds.primary, border.default…
spacingScale from 0 to 480px, named aliases (tiny, small, medium…)
radiusBorder radius — sm (6), md (10), lg (16), xl (24), full (9999)
typographyFont families, sizes, weights — Inter + Plus Jakarta Sans
shadowBox shadow presets — sm, md, lg, xl
motionDuration, easing, spring — for animations
glowGlow effects — aurora green, nebula purple, teal