Theme
XAUI keeps the colours you choose apart from the colours components need. createTheme resolves both modes once; the provider only picks one.
Create a theme
import { createTheme } from '@xaui/native/theme'export const appTheme = createTheme({colors: {light: {accent: '#2563EB',accentForeground: '#FFFFFF',background: '#FFFFFF',foreground: '#0F172A',},dark: {accent: '#60A5FA',accentForeground: '#0F172A',},},radius: 16,spacingUnit: 4,fontFamilies: { body: 'Inter', heading: 'Inter', mono: 'JetBrains Mono' },})
Declare the theme at module level. A fresh config on every render changes its identity and throws away the cached styles.
Two colour layers
Source
background, foreground, surfaces, overlay, accent, semantic states, fields, borders and links — the product's own choices.
Derived
pressed, soft, softForeground, secondary grounds, focus and separators. XAUI computes them from the source, in OKLab.
You can override a derived value, but start from the source: that is what keeps the palette coherent and the contrast right.
Provider and colour mode
import { XAUIProvider } from '@xaui/native/theme'import { appTheme } from './theme'<XAUIProvider theme={appTheme} colorMode="system"><App /></XAUIProvider>
system follows the device. For an in-app switch, control colorMode with light or dark state — XAUI does not persist that choice for you.
Read the tokens
import { useColorMode, useThemeColor, useXAUITheme } from '@xaui/native/theme'function Example() {const theme = useXAUITheme()const mode = useColorMode()const accent = useThemeColor('accent')return (<Viewpadding={theme.spacing(4)}borderRadius={theme.radius.lg}backgroundColor={accent}accessibilityLabel={`${mode} mode`}/>)}
Scales
- spacing(steps) — configurable base, 4 by default
- radius — xs to 4xl, plus field and full
- fontSizes and lineHeights — xs to 4xl
- fontWeights — regular, medium, semibold, bold
- controlHeights — xs, sm, md and lg
- shadows — surface, overlay and field
- borderWidth — default and field
- opacity.disabled — the shared disabled state