@idealyst/theme 1.0.39 → 1.0.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +447 -0
- package/LLM-ACCESS-GUIDE.md +208 -0
- package/README.md +633 -0
- package/package.json +5 -2
- package/src/README.md +138 -0
- package/src/colors.md +353 -0
- package/src/defaultThemes.md +407 -0
- package/src/themeBuilder.md +400 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
# Theme Builder
|
|
2
|
+
|
|
3
|
+
The core theme creation and extension utilities for building comprehensive theme objects.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The theme builder provides the fundamental functions for creating, extending, and customizing themes. It handles color resolution, intent mapping, and theme structure generation.
|
|
8
|
+
|
|
9
|
+
## Key Functions
|
|
10
|
+
|
|
11
|
+
### createTheme
|
|
12
|
+
|
|
13
|
+
Creates a complete theme from a configuration object.
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { createTheme, generateColorPalette } from './themeBuilder';
|
|
17
|
+
|
|
18
|
+
const theme = createTheme({
|
|
19
|
+
palettes: {
|
|
20
|
+
blue: generateColorPalette('#3b82f6'),
|
|
21
|
+
green: generateColorPalette('#22c55e'),
|
|
22
|
+
red: generateColorPalette('#ef4444'),
|
|
23
|
+
gray: generateColorPalette('#6b7280'),
|
|
24
|
+
},
|
|
25
|
+
intents: {
|
|
26
|
+
primary: 'blue',
|
|
27
|
+
success: 'green',
|
|
28
|
+
error: 'red',
|
|
29
|
+
neutral: 'gray',
|
|
30
|
+
},
|
|
31
|
+
// Optional: custom typography, spacing, etc.
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Parameters:**
|
|
36
|
+
- `config: ThemeConfig` - Theme configuration object
|
|
37
|
+
|
|
38
|
+
**Returns:**
|
|
39
|
+
- Complete `AppTheme` object with all theme properties
|
|
40
|
+
|
|
41
|
+
### extendTheme
|
|
42
|
+
|
|
43
|
+
Extends an existing theme with new or modified properties.
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
import { extendTheme, defaultLightTheme } from './themeBuilder';
|
|
47
|
+
|
|
48
|
+
const customTheme = extendTheme(defaultLightTheme, {
|
|
49
|
+
palettes: {
|
|
50
|
+
brand: generateColorPalette('#8b5cf6'), // Add brand color
|
|
51
|
+
},
|
|
52
|
+
intents: {
|
|
53
|
+
primary: 'brand', // Override primary intent
|
|
54
|
+
},
|
|
55
|
+
typography: {
|
|
56
|
+
fontFamily: {
|
|
57
|
+
sans: 'Helvetica, Arial, sans-serif', // Custom font
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Parameters:**
|
|
64
|
+
- `baseTheme: AppTheme` - Base theme to extend
|
|
65
|
+
- `overrides: Partial<ThemeConfig>` - Properties to override
|
|
66
|
+
|
|
67
|
+
**Returns:**
|
|
68
|
+
- Extended `AppTheme` with merged properties
|
|
69
|
+
|
|
70
|
+
### generateColorPalette
|
|
71
|
+
|
|
72
|
+
Generates a complete 10-shade color palette from a single base color.
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
import { generateColorPalette } from './themeBuilder';
|
|
76
|
+
|
|
77
|
+
const brandPalette = generateColorPalette('#8b5cf6');
|
|
78
|
+
// Returns:
|
|
79
|
+
// {
|
|
80
|
+
// 50: '#faf7ff', // Lightest
|
|
81
|
+
// 100: '#f3e8ff',
|
|
82
|
+
// 200: '#e9d5ff',
|
|
83
|
+
// 300: '#d8b4fe',
|
|
84
|
+
// 400: '#c084fc',
|
|
85
|
+
// 500: '#8b5cf6', // Base color (input)
|
|
86
|
+
// 600: '#7c3aed',
|
|
87
|
+
// 700: '#6d28d9',
|
|
88
|
+
// 800: '#5b21b6',
|
|
89
|
+
// 900: '#581c87', // Darkest
|
|
90
|
+
// }
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Parameters:**
|
|
94
|
+
- `baseColor: string` - Hex color string (e.g., '#8b5cf6')
|
|
95
|
+
|
|
96
|
+
**Returns:**
|
|
97
|
+
- `ThemeColorPalette` object with shades 50-900
|
|
98
|
+
|
|
99
|
+
## Color Resolution Functions
|
|
100
|
+
|
|
101
|
+
### createLightResolvedIntents
|
|
102
|
+
|
|
103
|
+
Creates intent color mappings optimized for light themes.
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
import { createLightResolvedIntents } from './themeBuilder';
|
|
107
|
+
|
|
108
|
+
const lightIntents = createLightResolvedIntents({
|
|
109
|
+
blue: generateColorPalette('#3b82f6'),
|
|
110
|
+
green: generateColorPalette('#22c55e'),
|
|
111
|
+
red: generateColorPalette('#ef4444'),
|
|
112
|
+
amber: generateColorPalette('#f59e0b'),
|
|
113
|
+
gray: generateColorPalette('#6b7280'),
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### createDarkResolvedIntents
|
|
118
|
+
|
|
119
|
+
Creates intent color mappings optimized for dark themes.
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
import { createDarkResolvedIntents } from './themeBuilder';
|
|
123
|
+
|
|
124
|
+
const darkIntents = createDarkResolvedIntents({
|
|
125
|
+
blue: generateColorPalette('#3b82f6'),
|
|
126
|
+
green: generateColorPalette('#22c55e'),
|
|
127
|
+
red: generateColorPalette('#ef4444'),
|
|
128
|
+
amber: generateColorPalette('#f59e0b'),
|
|
129
|
+
gray: generateColorPalette('#374151'), // Darker gray for dark theme
|
|
130
|
+
});
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### createLightResolvedColors
|
|
134
|
+
|
|
135
|
+
Creates component color system for light themes.
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
const lightColors = createLightResolvedColors(palettes, intents);
|
|
139
|
+
// Returns structured color system for text, surface, border, interactive
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### createDarkResolvedColors
|
|
143
|
+
|
|
144
|
+
Creates component color system for dark themes.
|
|
145
|
+
|
|
146
|
+
```tsx
|
|
147
|
+
const darkColors = createDarkResolvedColors(palettes, intents);
|
|
148
|
+
// Returns structured color system optimized for dark backgrounds
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Theme Configuration Types
|
|
152
|
+
|
|
153
|
+
### ThemeConfig
|
|
154
|
+
|
|
155
|
+
Configuration object for creating themes:
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
interface ThemeConfig {
|
|
159
|
+
palettes: Record<string, ThemeColorPalette>;
|
|
160
|
+
intents: Record<string, string>; // Maps intent names to palette names
|
|
161
|
+
|
|
162
|
+
// Optional overrides
|
|
163
|
+
typography?: Partial<TypographySystem>;
|
|
164
|
+
spacing?: Partial<SpacingSystem>;
|
|
165
|
+
borderRadius?: Partial<BorderRadiusSystem>;
|
|
166
|
+
shadows?: Partial<ShadowSystem>;
|
|
167
|
+
transitions?: Partial<TransitionSystem>;
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### ThemeColorPalette
|
|
172
|
+
|
|
173
|
+
10-shade color palette structure:
|
|
174
|
+
|
|
175
|
+
```tsx
|
|
176
|
+
interface ThemeColorPalette {
|
|
177
|
+
50: string; // Lightest shade
|
|
178
|
+
100: string;
|
|
179
|
+
200: string;
|
|
180
|
+
300: string;
|
|
181
|
+
400: string;
|
|
182
|
+
500: string; // Base color
|
|
183
|
+
600: string;
|
|
184
|
+
700: string;
|
|
185
|
+
800: string;
|
|
186
|
+
900: string; // Darkest shade
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### ResolvedIntent
|
|
191
|
+
|
|
192
|
+
Complete intent color mapping:
|
|
193
|
+
|
|
194
|
+
```tsx
|
|
195
|
+
interface ResolvedIntent {
|
|
196
|
+
main: string; // Primary color
|
|
197
|
+
on: string; // Text color on main
|
|
198
|
+
container: string; // Container background
|
|
199
|
+
onContainer: string; // Text on container
|
|
200
|
+
light: string; // Light variant
|
|
201
|
+
dark: string; // Dark variant
|
|
202
|
+
border: string; // Border color
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Advanced Usage
|
|
207
|
+
|
|
208
|
+
### Custom Theme with Brand Colors
|
|
209
|
+
|
|
210
|
+
```tsx
|
|
211
|
+
const brandTheme = createTheme({
|
|
212
|
+
palettes: {
|
|
213
|
+
brand: generateColorPalette('#ff6b6b'), // Coral brand
|
|
214
|
+
accent: generateColorPalette('#4ecdc4'), // Teal accent
|
|
215
|
+
neutral: generateColorPalette('#95a5a6'), // Cool gray
|
|
216
|
+
success: generateColorPalette('#2ecc71'), // Green
|
|
217
|
+
error: generateColorPalette('#e74c3c'), // Red
|
|
218
|
+
warning: generateColorPalette('#f39c12'), // Orange
|
|
219
|
+
},
|
|
220
|
+
intents: {
|
|
221
|
+
primary: 'brand',
|
|
222
|
+
secondary: 'accent',
|
|
223
|
+
neutral: 'neutral',
|
|
224
|
+
success: 'success',
|
|
225
|
+
error: 'error',
|
|
226
|
+
warning: 'warning',
|
|
227
|
+
},
|
|
228
|
+
typography: {
|
|
229
|
+
fontFamily: {
|
|
230
|
+
sans: 'Inter, system-ui, sans-serif',
|
|
231
|
+
mono: 'JetBrains Mono, monospace',
|
|
232
|
+
},
|
|
233
|
+
fontSize: {
|
|
234
|
+
xs: 11,
|
|
235
|
+
sm: 13,
|
|
236
|
+
md: 15,
|
|
237
|
+
lg: 17,
|
|
238
|
+
xl: 19,
|
|
239
|
+
xxl: 23,
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
spacing: {
|
|
243
|
+
xs: 2,
|
|
244
|
+
sm: 6,
|
|
245
|
+
md: 12,
|
|
246
|
+
lg: 20,
|
|
247
|
+
xl: 32,
|
|
248
|
+
xxl: 52,
|
|
249
|
+
},
|
|
250
|
+
});
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Theme Variants
|
|
254
|
+
|
|
255
|
+
```tsx
|
|
256
|
+
// Create base theme
|
|
257
|
+
const baseTheme = createTheme(baseConfig);
|
|
258
|
+
|
|
259
|
+
// Create high contrast variant
|
|
260
|
+
const highContrastTheme = extendTheme(baseTheme, {
|
|
261
|
+
colors: {
|
|
262
|
+
text: {
|
|
263
|
+
primary: '#000000', // Pure black
|
|
264
|
+
secondary: '#1a1a1a', // Near black
|
|
265
|
+
},
|
|
266
|
+
border: {
|
|
267
|
+
primary: '#000000', // Black borders
|
|
268
|
+
focus: '#0066cc', // High contrast blue
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// Create compact variant
|
|
274
|
+
const compactTheme = extendTheme(baseTheme, {
|
|
275
|
+
spacing: {
|
|
276
|
+
xs: 2,
|
|
277
|
+
sm: 4,
|
|
278
|
+
md: 8,
|
|
279
|
+
lg: 12,
|
|
280
|
+
xl: 16,
|
|
281
|
+
xxl: 24,
|
|
282
|
+
},
|
|
283
|
+
typography: {
|
|
284
|
+
fontSize: {
|
|
285
|
+
xs: 10,
|
|
286
|
+
sm: 12,
|
|
287
|
+
md: 14,
|
|
288
|
+
lg: 16,
|
|
289
|
+
xl: 18,
|
|
290
|
+
xxl: 20,
|
|
291
|
+
},
|
|
292
|
+
},
|
|
293
|
+
});
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Dynamic Theme Generation
|
|
297
|
+
|
|
298
|
+
```tsx
|
|
299
|
+
function createBrandTheme(brandColor: string, accentColor: string) {
|
|
300
|
+
return createTheme({
|
|
301
|
+
palettes: {
|
|
302
|
+
brand: generateColorPalette(brandColor),
|
|
303
|
+
accent: generateColorPalette(accentColor),
|
|
304
|
+
neutral: generateColorPalette('#6b7280'),
|
|
305
|
+
success: generateColorPalette('#22c55e'),
|
|
306
|
+
error: generateColorPalette('#ef4444'),
|
|
307
|
+
warning: generateColorPalette('#f59e0b'),
|
|
308
|
+
},
|
|
309
|
+
intents: {
|
|
310
|
+
primary: 'brand',
|
|
311
|
+
secondary: 'accent',
|
|
312
|
+
neutral: 'neutral',
|
|
313
|
+
success: 'success',
|
|
314
|
+
error: 'error',
|
|
315
|
+
warning: 'warning',
|
|
316
|
+
},
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Generate themes dynamically
|
|
321
|
+
const redTheme = createBrandTheme('#e53e3e', '#4299e1');
|
|
322
|
+
const purpleTheme = createBrandTheme('#8b5cf6', '#06b6d4');
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
## Color Utility Functions
|
|
326
|
+
|
|
327
|
+
### lighten
|
|
328
|
+
|
|
329
|
+
Lightens a color by a specified percentage:
|
|
330
|
+
|
|
331
|
+
```tsx
|
|
332
|
+
import { lighten } from './colorResolver';
|
|
333
|
+
|
|
334
|
+
const lightBlue = lighten('#3b82f6', 0.2); // 20% lighter
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### darken
|
|
338
|
+
|
|
339
|
+
Darkens a color by a specified percentage:
|
|
340
|
+
|
|
341
|
+
```tsx
|
|
342
|
+
import { darken } from './colorResolver';
|
|
343
|
+
|
|
344
|
+
const darkBlue = darken('#3b82f6', 0.2); // 20% darker
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## Best Practices
|
|
348
|
+
|
|
349
|
+
1. **Use generateColorPalette**: Always generate complete palettes for consistency
|
|
350
|
+
2. **Start with defaults**: Extend default themes rather than creating from scratch
|
|
351
|
+
3. **Intent mapping**: Use semantic intent names (primary, success, error, etc.)
|
|
352
|
+
4. **Type safety**: Leverage TypeScript for theme validation
|
|
353
|
+
5. **Performance**: Create themes once and reuse them
|
|
354
|
+
6. **Accessibility**: Ensure sufficient contrast in custom color combinations
|
|
355
|
+
|
|
356
|
+
## Common Patterns
|
|
357
|
+
|
|
358
|
+
### Corporate Branding
|
|
359
|
+
|
|
360
|
+
```tsx
|
|
361
|
+
const corporateTheme = extendTheme(defaultLightTheme, {
|
|
362
|
+
palettes: {
|
|
363
|
+
corporate: generateColorPalette('#1a365d'), // Navy corporate color
|
|
364
|
+
},
|
|
365
|
+
intents: {
|
|
366
|
+
primary: 'corporate',
|
|
367
|
+
},
|
|
368
|
+
typography: {
|
|
369
|
+
fontFamily: {
|
|
370
|
+
sans: 'Helvetica Neue, Arial, sans-serif',
|
|
371
|
+
},
|
|
372
|
+
},
|
|
373
|
+
});
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### Accessibility-First Theme
|
|
377
|
+
|
|
378
|
+
```tsx
|
|
379
|
+
const accessibleTheme = extendTheme(defaultLightTheme, {
|
|
380
|
+
colors: {
|
|
381
|
+
text: {
|
|
382
|
+
primary: '#000000', // Pure black for maximum contrast
|
|
383
|
+
secondary: '#4a4a4a', // Dark gray with good contrast
|
|
384
|
+
},
|
|
385
|
+
border: {
|
|
386
|
+
focus: '#005fcc', // High contrast focus indicator
|
|
387
|
+
},
|
|
388
|
+
},
|
|
389
|
+
typography: {
|
|
390
|
+
fontSize: {
|
|
391
|
+
xs: 14, // Minimum 14px for readability
|
|
392
|
+
sm: 16,
|
|
393
|
+
md: 18,
|
|
394
|
+
lg: 20,
|
|
395
|
+
xl: 24,
|
|
396
|
+
xxl: 28,
|
|
397
|
+
},
|
|
398
|
+
},
|
|
399
|
+
});
|
|
400
|
+
```
|