Theming
Projection UI 0.1.5 archive
You are reading version 0.1.5. This archive retains its original API and installation requirements. Open the current alpha documentation.
Quick start
1. Import the fallback tokens (optional but recommended)
In your entry file (main.tsx or index.tsx):
import '@hannasage/projection-ui/tokens'This loads a set of CSS custom property defaults. If you wrap your app with ThemeProvider, these are overridden by your theme — but they act as a safe fallback.
2. Define your theme
import type { UITheme } from '@hannasage/projection-ui'
const myTheme: UITheme = {
bg: '#07090C', // page background
surface: '#0D1117', // card / panel
border: '#1B2535', // borders
text: '#DDE3EE', // primary text
muted: '#8396AB', // secondary text / labels
primary: '#C9F53A', // accent — buttons, focus rings
primaryFg: '#07090C', // text on top of primary (e.g. button label)
danger: '#FF5252', // destructive actions
font: "'IBM Plex Mono', monospace",
radius: 'soft', // 'sharp' | 'soft' | 'rounded'
}Radius presets:
| preset | buttons/inputs | cards | pills/toggles |
|---|---|---|---|
sharp | 2px | 4px | 4px (no pill) |
soft | 6px | 10px | 9999px |
rounded | 16px | 24px | 9999px |
3. Wrap your app
import { ThemeProvider, ToastContainer } from '@hannasage/projection-ui'
export default function App() {
return (
<ThemeProvider theme={myTheme}>
<YourApp />
<ToastContainer />
</ThemeProvider>
)
}Switching themes is instant — pass a new theme object and all --ui-* CSS variables update automatically.
Dynamic theming
ThemeProvider is just a div that writes CSS vars — swapping themes is a single state update:
const [theme, setTheme] = useState<UITheme>(darkTheme)
<ThemeProvider theme={theme}>
<button onClick={() => setTheme(lightTheme)}>Toggle theme</button>
</ThemeProvider>