theme
Customize the appearance of SDK UI dialogs (onboarding, signing, transactions, permissions).
Type: JawTheme
Required: No
Default: { mode: 'auto', borderRadius: 'md', fontStack: 'system' }
Quick Start
import { JAW, Mode } from '@jaw.id/core';
import { ReactUIHandler } from '@jaw.id/ui';
const jaw = JAW.create({
apiKey: 'your-api-key',
theme: {
mode: 'dark',
accentColor: '#6366f1',
borderRadius: 'lg',
},
preference: {
mode: Mode.AppSpecific,
uiHandler: new ReactUIHandler(),
},
});Theme Properties
| Property | Type | Default | Description |
|---|---|---|---|
mode | 'light' | 'dark' | 'auto' | 'auto' | Color scheme. 'auto' follows the user's system preference. |
accentColor | string | — | Primary color as hex (e.g. '#6366f1'). Applied to buttons, focus rings, links. |
accentColorForeground | string | auto-detected | Text color on accent backgrounds. Auto-detected from luminance if omitted. |
borderRadius | 'sm' | 'md' | 'lg' | 'md' | Corner rounding for cards, buttons, and inputs. |
fontStack | 'system' | 'rounded' | 'mono' | 'system' | Font family preset. |
cssVariables | Record<string, string> | — | Granular CSS variable overrides (see below). |
Three Layers of Customization
Layer 1: Simple Props (recommended)
Covers 90% of use cases. Pass mode, accentColor, and borderRadius.
const jaw = JAW.create({
apiKey: 'your-api-key',
theme: {
mode: 'dark',
accentColor: '#e11d48', // Rose
borderRadius: 'lg',
},
preference: {
mode: Mode.AppSpecific,
uiHandler: new ReactUIHandler(),
},
});Layer 2: CSS Variable Overrides
For precise control, override individual CSS variables. These take highest priority.
const jaw = JAW.create({
apiKey: 'your-api-key',
theme: {
mode: 'dark',
accentColor: '#7b3fe4',
cssVariables: {
'--jaw-color-background': 'oklch(0.15 0.02 280)',
'--jaw-color-card': 'oklch(0.20 0.02 280)',
'--jaw-font-family': '"Berkeley Mono", monospace',
},
},
preference: {
mode: Mode.AppSpecific,
uiHandler: new ReactUIHandler(),
},
});Layer 3: Raw CSS (escape hatch)
Target [data-jaw-modal-container] in your own CSS. No SDK changes needed.
[data-jaw-modal-container] {
--jaw-color-primary: oklch(0.65 0.25 270);
--jaw-color-background: oklch(0.12 0.01 260);
font-family: 'Inter', sans-serif;
}Passing Theme to ReactUIHandler
You can pass the theme in two places. Both work, and the constructor theme takes precedence:
// Theme flows through SDK -> UIHandler.init()
const jaw = JAW.create({
apiKey: 'your-api-key',
theme: { mode: 'dark', accentColor: '#6366f1' },
preference: {
mode: Mode.AppSpecific,
uiHandler: new ReactUIHandler(),
},
});Auto Mode (System Preference)
When mode is 'auto' (the default), the SDK detects the user's system color scheme and switches dynamically. If the user changes their OS dark/light preference while a dialog is open, it updates live.
theme: {
mode: 'auto';
} // follows system preferenceAvailable CSS Variables
Use these with cssVariables for granular overrides. All values use the OKLCH color space.
Colors
| Variable | Description |
|---|---|
--jaw-color-background | Dialog backdrop |
--jaw-color-foreground | Primary text |
--jaw-color-card | Card/section backgrounds |
--jaw-color-card-foreground | Card text |
--jaw-color-primary | Buttons, links, focus rings |
--jaw-color-primary-foreground | Text on primary backgrounds |
--jaw-color-secondary | Secondary backgrounds |
--jaw-color-secondary-foreground | Secondary text |
--jaw-color-muted | Muted/disabled backgrounds |
--jaw-color-muted-foreground | Muted text |
--jaw-color-accent | Hover/active state backgrounds |
--jaw-color-accent-foreground | Accent text |
--jaw-color-border | Borders and dividers |
--jaw-color-input | Input field borders |
--jaw-color-ring | Focus ring color |
--jaw-color-destructive | Error/danger backgrounds |
--jaw-color-destructive-foreground | Error/danger text |
--jaw-color-success | Success state |
--jaw-color-success-foreground | Success text |
--jaw-color-warning | Warning state |
--jaw-color-warning-foreground | Warning text |
--jaw-color-info | Info state |
--jaw-color-info-foreground | Info text |
Layout
| Variable | Description |
|---|---|
--jaw-radius | Base border radius (e.g. 0.625rem) |
--jaw-font-family | Font family string |
How Accent Color Works
When you set accentColor, the SDK:
- Converts your hex color to OKLCH color space
- Sets it as
--jaw-color-primary(buttons, links) - Auto-detects a contrasting foreground color (light text for dark accents, dark text for light accents)
- Derives a subtle tint for hover states (
--jaw-color-accent) - Creates a desaturated variant for focus rings (
--jaw-color-ring)
In dark mode, dark accent colors are automatically lightened for better visibility.
To override the auto-detected foreground, pass accentColorForeground:
theme: {
accentColor: '#1e1e2e',
accentColorForeground: '#ffffff', // force white text
}Related Configuration
- mode - Authentication mode (AppSpecific required for theming)
- AppSpecific - AppSpecific mode setup
- appName - App name shown in dialogs
- appLogoUrl - App logo shown in dialogs