0
# Theme Management
1
2
Create and manage design tokens with type-safe theme references and dynamic theme switching. The theme system provides a structured approach to managing colors, spacing, typography, and other design tokens across your application.
3
4
## Capabilities
5
6
### Create Theme
7
8
Creates theme objects for design token management with optional naming.
9
10
```typescript { .api }
11
/**
12
* Creates a theme object with design tokens
13
* @param theme - Object containing design token scales
14
* @returns Theme object with className, selector, and token properties
15
*/
16
function createTheme(theme: ThemeObject): string & ThemeTokens & ThemeMetadata;
17
18
/**
19
* Creates a named theme object with design tokens
20
* @param name - Theme name for CSS class generation
21
* @param theme - Object containing design token scales
22
* @returns Named theme object with className, selector, and token properties
23
*/
24
function createTheme(name: string, theme: ThemeObject): string & ThemeTokens & ThemeMetadata;
25
26
interface ThemeObject {
27
colors?: { [token: string]: string };
28
space?: { [token: string]: string };
29
fontSizes?: { [token: string]: string };
30
fonts?: { [token: string]: string };
31
fontWeights?: { [token: string]: string | number };
32
lineHeights?: { [token: string]: string | number };
33
letterSpacings?: { [token: string]: string };
34
sizes?: { [token: string]: string };
35
borderWidths?: { [token: string]: string };
36
borderStyles?: { [token: string]: string };
37
radii?: { [token: string]: string };
38
shadows?: { [token: string]: string };
39
zIndices?: { [token: string]: number };
40
transitions?: { [token: string]: string };
41
}
42
43
interface ThemeMetadata {
44
/** CSS class name for applying this theme */
45
className: string;
46
/** CSS selector for targeting this theme */
47
selector: string;
48
}
49
```
50
51
**Usage Examples:**
52
53
```typescript
54
import { createTheme } from "@stitches/react";
55
56
// Create default theme
57
const lightTheme = createTheme({
58
colors: {
59
primary: 'blue',
60
secondary: 'gray',
61
background: 'white',
62
text: 'black',
63
success: 'green',
64
warning: 'orange',
65
danger: 'red'
66
},
67
space: {
68
1: '4px',
69
2: '8px',
70
3: '12px',
71
4: '16px',
72
5: '24px',
73
6: '32px'
74
},
75
fontSizes: {
76
xs: '12px',
77
sm: '14px',
78
md: '16px',
79
lg: '18px',
80
xl: '20px',
81
'2xl': '24px'
82
},
83
fonts: {
84
sans: 'system-ui, sans-serif',
85
mono: 'Monaco, monospace'
86
}
87
});
88
89
// Create named theme variant
90
const darkTheme = createTheme('dark', {
91
colors: {
92
primary: 'lightblue',
93
secondary: 'lightgray',
94
background: '#1a1a1a',
95
text: 'white',
96
success: 'lightgreen',
97
warning: 'yellow',
98
danger: 'lightcoral'
99
}
100
});
101
102
// Apply theme to document or container
103
document.body.className = darkTheme;
104
// or
105
<div className={darkTheme}>
106
<App />
107
</div>
108
```
109
110
### Theme Tokens
111
112
Access theme tokens with type-safe references and auto-completion.
113
114
```typescript { .api }
115
interface ThemeTokens {
116
[scale: string]: {
117
[token: string]: ThemeToken;
118
};
119
}
120
121
interface ThemeToken {
122
/** The token value */
123
value: string;
124
/** CSS custom property name */
125
variable: string;
126
/** Scale name this token belongs to */
127
scale: string;
128
/** Token name within the scale */
129
token: string;
130
}
131
```
132
133
**Usage Examples:**
134
135
```typescript
136
const theme = createTheme({
137
colors: {
138
primary: 'blue',
139
secondary: 'gray'
140
},
141
space: {
142
sm: '8px',
143
md: '16px',
144
lg: '24px'
145
}
146
});
147
148
// Access theme tokens
149
console.log(theme.colors.primary.value); // 'blue'
150
console.log(theme.colors.primary.variable); // '--colors-primary'
151
console.log(theme.space.md.value); // '16px'
152
153
// Use tokens in styles with $ prefix
154
const Button = styled('button', {
155
backgroundColor: '$colors$primary',
156
padding: '$space$md',
157
color: '$colors$secondary'
158
});
159
160
// Or use in CSS function
161
const cardStyles = css({
162
backgroundColor: '$colors$background',
163
padding: '$space$lg',
164
borderRadius: '$radii$md'
165
});
166
```
167
168
### Default Theme Map
169
170
Map CSS properties to theme scales for automatic token resolution.
171
172
```typescript { .api }
173
interface DefaultThemeMap {
174
// Spacing properties
175
gap: 'space';
176
margin: 'space';
177
padding: 'space';
178
top: 'space';
179
right: 'space';
180
bottom: 'space';
181
left: 'space';
182
183
// Color properties
184
color: 'colors';
185
backgroundColor: 'colors';
186
borderColor: 'colors';
187
188
// Typography properties
189
fontSize: 'fontSizes';
190
fontFamily: 'fonts';
191
fontWeight: 'fontWeights';
192
lineHeight: 'lineHeights';
193
letterSpacing: 'letterSpacings';
194
195
// Size properties
196
width: 'sizes';
197
height: 'sizes';
198
minWidth: 'sizes';
199
maxWidth: 'sizes';
200
201
// Border properties
202
borderWidth: 'borderWidths';
203
borderRadius: 'radii';
204
205
// Shadow and effects
206
boxShadow: 'shadows';
207
zIndex: 'zIndices';
208
transition: 'transitions';
209
}
210
211
const defaultThemeMap: DefaultThemeMap;
212
```
213
214
**Usage Examples:**
215
216
```typescript
217
// Theme map allows shorthand token references
218
const Button = styled('button', {
219
// These automatically map to theme scales via defaultThemeMap
220
fontSize: '$md', // Maps to $fontSizes$md
221
padding: '$lg', // Maps to $space$lg
222
backgroundColor: '$primary', // Maps to $colors$primary
223
borderRadius: '$sm' // Maps to $radii$sm
224
});
225
226
// Custom theme map configuration
227
const { styled } = createStitches({
228
themeMap: {
229
...defaultThemeMap,
230
// Custom mappings
231
opacity: 'opacity',
232
transform: 'transforms'
233
},
234
theme: {
235
opacity: {
236
low: '0.5',
237
high: '0.9'
238
},
239
transforms: {
240
scale: 'scale(1.1)',
241
rotate: 'rotate(45deg)'
242
}
243
}
244
});
245
```
246
247
### Dynamic Theme Switching
248
249
Switch between themes dynamically at runtime.
250
251
**Usage Examples:**
252
253
```typescript
254
import { useState } from 'react';
255
256
const lightTheme = createTheme({
257
colors: {
258
background: 'white',
259
text: 'black',
260
primary: 'blue'
261
}
262
});
263
264
const darkTheme = createTheme('dark', {
265
colors: {
266
background: '#1a1a1a',
267
text: 'white',
268
primary: 'lightblue'
269
}
270
});
271
272
function ThemeProvider({ children }) {
273
const [isDark, setIsDark] = useState(false);
274
const currentTheme = isDark ? darkTheme : lightTheme;
275
276
return (
277
<div className={currentTheme}>
278
<button onClick={() => setIsDark(!isDark)}>
279
Switch to {isDark ? 'Light' : 'Dark'} Theme
280
</button>
281
{children}
282
</div>
283
);
284
}
285
```
286
287
### Theme Inheritance
288
289
Extend existing themes with additional or overridden tokens.
290
291
**Usage Examples:**
292
293
```typescript
294
const baseTheme = createTheme({
295
colors: {
296
primary: 'blue',
297
secondary: 'gray',
298
background: 'white'
299
},
300
space: {
301
sm: '8px',
302
md: '16px',
303
lg: '24px'
304
}
305
});
306
307
// Extend with additional tokens
308
const extendedTheme = createTheme('extended', {
309
colors: {
310
...baseTheme.colors,
311
tertiary: 'green', // Add new color
312
primary: 'darkblue' // Override existing color
313
},
314
space: {
315
...baseTheme.space,
316
xl: '32px', // Add new spacing
317
xxl: '48px'
318
},
319
// Add completely new scale
320
fontSizes: {
321
sm: '14px',
322
md: '16px',
323
lg: '18px'
324
}
325
});
326
```
327
328
### CSS Custom Properties
329
330
Themes generate CSS custom properties for external integration.
331
332
**Usage Examples:**
333
334
```typescript
335
const theme = createTheme({
336
colors: {
337
primary: 'blue',
338
secondary: 'gray'
339
},
340
space: {
341
md: '16px',
342
lg: '24px'
343
}
344
});
345
346
// CSS custom properties are automatically generated:
347
// --colors-primary: blue;
348
// --colors-secondary: gray;
349
// --space-md: 16px;
350
// --space-lg: 24px;
351
352
// Use in regular CSS
353
const regularCSS = `
354
.my-component {
355
background-color: var(--colors-primary);
356
padding: var(--space-lg);
357
}
358
`;
359
360
// Or in CSS-in-JS
361
const Component = styled('div', {
362
backgroundColor: 'var(--colors-primary)',
363
padding: 'var(--space-lg)'
364
});
365
```
366
367
### Server-Side Rendering
368
369
Handle theme application during server-side rendering.
370
371
**Usage Examples:**
372
373
```typescript
374
// On the server
375
import { getCssText } from "@stitches/react";
376
377
const theme = createTheme({
378
colors: { primary: 'blue' }
379
});
380
381
// Apply theme class to HTML
382
const html = `
383
<html>
384
<head>
385
<style>${getCssText()}</style>
386
</head>
387
<body class="${theme}">
388
<div id="root">${renderToString(<App />)}</div>
389
</body>
390
</html>
391
`;
392
393
// On the client - hydration will work correctly
394
ReactDOM.hydrate(<App />, document.getElementById('root'));
395
```
396
397
## Type Safety
398
399
```typescript { .api }
400
// Theme token type with scale and token information
401
interface ThemeToken<Token, Value, Scale, Prefix> {
402
/** Token name prefixed for CSS custom property */
403
readonly [Symbol.toPrimitive]: () => string;
404
/** Scale this token belongs to */
405
scale: Scale;
406
/** Token name within the scale */
407
token: Token;
408
/** Token value */
409
value: Value;
410
/** CSS custom property variable name */
411
variable: string;
412
}
413
414
// Type-safe theme value references
415
type ScaleValue<Scale, Config = null> =
416
Config extends null
417
? { readonly [K in $$ScaleValue]: Scale }
418
: Scale extends keyof Config['theme']
419
? `$${string & keyof Config['theme'][Scale]}`
420
: never;
421
422
// Property value with theme support
423
type PropertyValue<Property extends keyof CSSProperties, Config = null> =
424
Config extends null
425
? { readonly [K in $$PropertyValue]: Property }
426
: CSS<Config['media'], Config['theme'], Config['themeMap'], Config['utils']>[Property];
427
```
428
429
**Usage Examples:**
430
431
```typescript
432
// Type-safe theme token access
433
const theme = createTheme({
434
colors: {
435
primary: 'blue',
436
secondary: 'gray'
437
}
438
});
439
440
// TypeScript ensures token exists
441
const Button = styled('button', {
442
backgroundColor: '$colors$primary', // ✓ Valid
443
// backgroundColor: '$colors$invalid', // ✗ TypeScript error
444
});
445
446
// Extract theme type for other uses
447
type MyTheme = typeof theme;
448
type ColorTokens = keyof MyTheme['colors']; // 'primary' | 'secondary'
449
```