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
Pass theme in the constructor. It works the same way in both authentication modes.
With Wagmi (Recommended)
import { jaw } from '@jaw.id/wagmi';
const connector = jaw({
apiKey: 'your-api-key',
appName: 'My App',
theme: {
mode: 'dark',
accentColor: '#6366f1',
borderRadius: 'lg',
},
});With Provider Directly
import { JAW } from '@jaw.id/core';
const jaw = JAW.create({
apiKey: 'your-api-key',
theme: {
mode: 'dark',
accentColor: '#6366f1',
borderRadius: 'lg',
},
});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. |
colors | JawThemeColors | — | Semantic palette overrides as plain hex colors (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',
},
});Layer 2: Semantic Colors (full re-skins)
For a complete custom look, pass a colors palette — every value is an ordinary hex color. Any key you omit keeps its default, and explicit colors win over accentColor.
const jaw = JAW.create({
apiKey: 'your-api-key',
theme: {
mode: 'dark',
borderRadius: 'lg',
colors: {
background: '#0E2F28',
card: '#123A31',
foreground: '#ECFDF5',
primary: '#34E3A0',
primaryForeground: '#052E22',
muted: '#17453B',
mutedForeground: '#93C0B1',
border: '#1F5449',
// Status colors are themeable too
warning: '#F5C24B',
positive: '#34E3A0',
negative: '#F0836E',
},
},
});The full list of keys is in the Color Reference below.
Layer 3: Raw CSS (escape hatch)
Target [data-jaw-modal-container] in your own CSS. No SDK changes needed. This only applies to AppSpecific mode — the cross-platform dialog is served from keys.jaw.id in a separate origin, so use the simple props or colors to theme it.
[data-jaw-modal-container] {
/* Color variables take bare OKLCH channels ("L C H"), not oklch(...) or hex */
--jaw-color-primary: 0.65 0.25 270;
--jaw-color-background: 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(),
},
});// Constructor theme takes precedence over JAW.create() theme
const jaw = JAW.create({
apiKey: 'your-api-key',
preference: {
mode: Mode.AppSpecific,
uiHandler: new ReactUIHandler({
theme: { mode: 'dark', accentColor: '#6366f1' },
}),
},
});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 preferenceUpdating the Theme at Runtime
If your app toggles light/dark after the provider is created, call setTheme() to push the new theme to the live dialog without rebuilding the provider or reconnecting. In CrossPlatform mode this re-themes the embedded keys.jaw.id dialog in place.
// jaw is the object returned by JAW.create()
jaw.provider.setTheme({ mode: 'dark', accentColor: '#6366f1' });import { useConnect } from 'wagmi';
import type { JawTheme } from '@jaw.id/core';
const { connectors } = useConnect();
const jaw = connectors.find((c) => c.id === 'jaw') as { setTheme?: (theme: JawTheme | undefined) => void } | undefined;
jaw?.setTheme?.({ mode: 'dark', accentColor: '#6366f1' });Color Reference
Every key you can set in colors, with the CSS variable it maps to (only needed for the raw-CSS escape hatch).
| Key | CSS variable | Description |
|---|---|---|
background | --jaw-color-background | Dialog backdrop |
foreground | --jaw-color-foreground | Primary text |
card | --jaw-color-card | Card/section backgrounds |
cardForeground | --jaw-color-card-foreground | Card text |
popover | --jaw-color-popover | Popover backgrounds |
popoverForeground | --jaw-color-popover-foreground | Popover text |
primary | --jaw-color-primary | Buttons, links, key actions |
primaryForeground | --jaw-color-primary-foreground | Text on primary backgrounds |
secondary | --jaw-color-secondary | Secondary backgrounds |
secondaryForeground | --jaw-color-secondary-foreground | Secondary text |
muted | --jaw-color-muted | Muted/disabled backgrounds |
mutedForeground | --jaw-color-muted-foreground | Muted text |
accent | --jaw-color-accent | Hover/active state backgrounds |
accentForeground | --jaw-color-accent-foreground | Accent text |
border | --jaw-color-border | Borders and dividers |
input | --jaw-color-input | Input field borders |
ring | --jaw-color-ring | Focus ring color |
destructive | --jaw-color-destructive | Error/danger backgrounds |
destructiveForeground | --jaw-color-destructive-foreground | Error/danger text |
destructiveHover | --jaw-color-destructive-hover | Destructive button hover state |
success | --jaw-color-success | Success state |
successForeground | --jaw-color-success-foreground | Success text |
warning | --jaw-color-warning | Warning state |
warningForeground | --jaw-color-warning-foreground | Warning text |
info | --jaw-color-info | Info state |
infoForeground | --jaw-color-info-foreground | Info text |
positive | --jaw-color-positive | Incoming asset amounts ("You get") |
negative | --jaw-color-negative | Outgoing asset amounts ("You send") |
scrim | --jaw-color-scrim | Modal overlay backdrop |
halo | --jaw-color-halo | Animated edge glow on the dialog card |
identiconTile | --jaw-color-identicon-tile | Tile behind account identicons |
identiconRing | --jaw-color-identicon-ring | Hairline ring around the identicon tile |
shadow | --jaw-color-shadow | Elevation shadow color |
Border radius and font come from the borderRadius and fontStack props (CSS variables --jaw-radius and --jaw-font-family).
How Accent Color Works
When you set accentColor, the SDK colors the primary buttons, links, hover tints, and focus rings from it, and picks a contrasting text color automatically. Dark accents are lightened slightly in dark mode for visibility.
To override the auto-picked text color, pass accentColorForeground:
theme: {
accentColor: '#1e1e2e',
accentColorForeground: '#ffffff', // force white text
}Related Configuration
- mode - Authentication mode (theming works in both AppSpecific and CrossPlatform)
- AppSpecific - AppSpecific mode setup
- appName - App name shown in dialogs
- appLogoUrl - App logo shown in dialogs