@aurora-ds/theme 3.0.0 → 3.1.0
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/README.dev.md +424 -0
- package/README.md +102 -587
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -585
- package/dist/index.d.ts +59 -585
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,211 +1,167 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Aurora Theme
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A performant, type-safe, and **fully customizable** CSS-in-JS theme library for React.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
[](https://opensource.org/licenses/MIT)
|
|
7
|
-
[](https://www.typescriptlang.org/)
|
|
5
|
+
## Features
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
- ⚡ **Performant** - LRU caching, static style deduplication
|
|
8
|
+
- 🔒 **Type-safe** - Full TypeScript support with module augmentation
|
|
9
|
+
- 🎨 **Flexible** - Define your own theme structure
|
|
10
|
+
- 📦 **Lightweight** - No runtime dependencies besides React
|
|
10
11
|
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## ✨ Key Features
|
|
14
|
-
|
|
15
|
-
- 🎯 **Simple API**
|
|
16
|
-
- 🔮 **Automatic type inference**: TypeScript knows your exact theme structure
|
|
17
|
-
- 🎨 **Optional defaults**: Start instantly with `defaultPalette` (37 semantic colors)
|
|
18
|
-
- 🔧 **Ultra-flexible**: Customize any token independently
|
|
19
|
-
- 📦 **Lightweight**
|
|
20
|
-
- ⚡ **Zero-runtime overhead**: Pure JavaScript, no runtime theme merging
|
|
21
|
-
- 🎭 **CSS-in-JS**: Runtime style generation with SSR support
|
|
22
|
-
|
|
23
|
-
---
|
|
24
12
|
|
|
25
|
-
##
|
|
13
|
+
## Installation
|
|
26
14
|
|
|
27
15
|
```bash
|
|
28
16
|
npm install @aurora-ds/theme
|
|
29
17
|
```
|
|
30
18
|
|
|
31
|
-
|
|
32
|
-
yarn add @aurora-ds/theme
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
pnpm add @aurora-ds/theme
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## 🚀 Quick Start
|
|
42
|
-
|
|
43
|
-
### 1. Create your theme (3 options)
|
|
19
|
+
## Quick Start
|
|
44
20
|
|
|
45
|
-
#### Option A: Use defaults (fastest)
|
|
46
21
|
```typescript
|
|
22
|
+
// theme.ts
|
|
47
23
|
import { createTheme } from '@aurora-ds/theme'
|
|
48
24
|
|
|
49
|
-
|
|
50
|
-
|
|
25
|
+
// 1. Define your theme type
|
|
26
|
+
type MyTheme = {
|
|
27
|
+
colors: {
|
|
28
|
+
primary: string
|
|
29
|
+
secondary: string
|
|
30
|
+
background: string
|
|
31
|
+
text: string
|
|
32
|
+
}
|
|
33
|
+
spacing: {
|
|
34
|
+
sm: string
|
|
35
|
+
md: string
|
|
36
|
+
lg: string
|
|
37
|
+
}
|
|
38
|
+
}
|
|
51
39
|
```
|
|
52
|
-
|
|
53
|
-
#### Option B: Customize or expand the default palette
|
|
54
40
|
```typescript
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
...defaultPalette,
|
|
60
|
-
primary: '#007bff', // Your brand color
|
|
61
|
-
primaryHover: '#0056b3',
|
|
41
|
+
// 2. Module augmentation (required for autocomplete)
|
|
42
|
+
declare module '@aurora-ds/theme' {
|
|
43
|
+
interface ThemeRegistry {
|
|
44
|
+
theme: MyTheme
|
|
62
45
|
}
|
|
63
|
-
}
|
|
46
|
+
}
|
|
64
47
|
```
|
|
65
48
|
|
|
66
|
-
#### Option C: Define your own colors
|
|
67
49
|
```typescript
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const theme = createTheme({
|
|
50
|
+
// 3. Create your themes (type is inferred automatically!)
|
|
51
|
+
export const lightTheme = createTheme({
|
|
71
52
|
colors: {
|
|
72
|
-
primary: '#
|
|
53
|
+
primary: '#6366f1',
|
|
54
|
+
secondary: '#64748b',
|
|
73
55
|
background: '#ffffff',
|
|
74
|
-
text: '#
|
|
75
|
-
}
|
|
56
|
+
text: '#09090b',
|
|
57
|
+
},
|
|
58
|
+
spacing: {
|
|
59
|
+
sm: '0.5rem',
|
|
60
|
+
md: '1rem',
|
|
61
|
+
lg: '1.5rem',
|
|
62
|
+
},
|
|
76
63
|
})
|
|
77
64
|
```
|
|
78
65
|
|
|
79
|
-
### 2. Provide the theme to your app
|
|
80
|
-
|
|
81
66
|
```tsx
|
|
82
|
-
|
|
83
|
-
import {
|
|
67
|
+
// App.tsx
|
|
68
|
+
import { ThemeProvider, createStyles } from '@aurora-ds/theme'
|
|
69
|
+
import { lightTheme } from './theme'
|
|
70
|
+
|
|
71
|
+
const styles = createStyles((theme) => ({
|
|
72
|
+
container: {
|
|
73
|
+
padding: theme.spacing.md, // ✅ Autocomplete!
|
|
74
|
+
backgroundColor: theme.colors.background,
|
|
75
|
+
color: theme.colors.text,
|
|
76
|
+
},
|
|
77
|
+
button: {
|
|
78
|
+
backgroundColor: theme.colors.primary,
|
|
79
|
+
padding: theme.spacing.sm,
|
|
80
|
+
':hover': {
|
|
81
|
+
opacity: 0.9
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}))
|
|
84
85
|
|
|
85
86
|
function App() {
|
|
86
87
|
return (
|
|
87
|
-
<ThemeProvider theme={
|
|
88
|
-
<
|
|
88
|
+
<ThemeProvider theme={lightTheme}>
|
|
89
|
+
<div className={styles.container}>
|
|
90
|
+
<button className={styles.button}>Click me</button>
|
|
91
|
+
</div>
|
|
89
92
|
</ThemeProvider>
|
|
90
93
|
)
|
|
91
94
|
}
|
|
92
95
|
```
|
|
93
96
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
```tsx
|
|
97
|
-
import { useTheme, createStyles } from '@aurora-ds/theme'
|
|
97
|
+
## API
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
const useStyles = createStyles((theme) => ({
|
|
101
|
-
button: {
|
|
102
|
-
backgroundColor: theme.colors.primary,
|
|
103
|
-
padding: theme.spacing.md,
|
|
104
|
-
borderRadius: theme.radius.md,
|
|
105
|
-
}
|
|
106
|
-
}))
|
|
99
|
+
### `createTheme(values)`
|
|
107
100
|
|
|
108
|
-
|
|
109
|
-
const styles = useStyles()
|
|
110
|
-
return <button className={styles.button}>Click me</button>
|
|
111
|
-
}
|
|
101
|
+
Creates a theme. Type is inferred from `ThemeRegistry`.
|
|
112
102
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
<div style={{
|
|
119
|
-
backgroundColor: theme.colors.background,
|
|
120
|
-
padding: theme.spacing.lg,
|
|
121
|
-
borderRadius: theme.radius.lg,
|
|
122
|
-
}}>
|
|
123
|
-
Card content
|
|
124
|
-
</div>
|
|
125
|
-
)
|
|
126
|
-
}
|
|
103
|
+
```typescript
|
|
104
|
+
const theme = createTheme({
|
|
105
|
+
colors: { primary: '#007bff' },
|
|
106
|
+
spacing: { sm: '8px' }
|
|
107
|
+
})
|
|
127
108
|
```
|
|
128
109
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
## 📚 Core Concepts
|
|
132
|
-
|
|
133
|
-
### Theme Structure
|
|
110
|
+
### `createStyles((theme) => styles)`
|
|
134
111
|
|
|
135
|
-
|
|
112
|
+
Creates CSS classes from a style object.
|
|
136
113
|
|
|
137
114
|
```typescript
|
|
138
|
-
{
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
shadows: { ... }, // Box shadow scale
|
|
143
|
-
fontSize: { ... }, // Font size scale
|
|
144
|
-
fontWeight: { ... }, // Font weight scale
|
|
145
|
-
lineHeight: { ... }, // Line height scale
|
|
146
|
-
zIndex: { ... }, // Z-index scale
|
|
147
|
-
transition: { ... }, // Transition presets
|
|
148
|
-
opacity: { ... }, // Opacity scale
|
|
149
|
-
breakpoints: { ... }, // Responsive breakpoints
|
|
150
|
-
}
|
|
115
|
+
const styles = createStyles((theme) => ({
|
|
116
|
+
root: { color: theme.colors.primary }
|
|
117
|
+
}))
|
|
118
|
+
// styles.root → "root-abc123"
|
|
151
119
|
```
|
|
152
120
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
### Type Inference (Automatic!)
|
|
121
|
+
### `useTheme()`
|
|
156
122
|
|
|
157
|
-
|
|
123
|
+
Hook to access the current theme in components.
|
|
158
124
|
|
|
159
125
|
```typescript
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
})
|
|
126
|
+
function Component() {
|
|
127
|
+
const theme = useTheme()
|
|
128
|
+
return <div style={{ color: theme.colors.primary }} />
|
|
129
|
+
}
|
|
166
130
|
```
|
|
167
131
|
|
|
168
|
-
|
|
132
|
+
### `ThemeProvider`
|
|
169
133
|
|
|
170
|
-
|
|
134
|
+
Provides the theme to your app.
|
|
171
135
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
// Colors included:
|
|
178
|
-
// - Surface: background, surface, surfaceHover, surfaceActive
|
|
179
|
-
// - Text: text, textSecondary, textTertiary
|
|
180
|
-
// - Primary: primary, primaryHover, primaryActive, primarySubtle, primaryDisabled, onPrimary
|
|
181
|
-
// - Secondary: secondary, secondaryHover, secondaryActive, secondarySubtle, secondaryDisabled, onSecondary
|
|
182
|
-
// - Semantic: success, warning, error, info (+ subtle variants)
|
|
183
|
-
// - Links: link, linkHover, linkActive, linkDisabled
|
|
184
|
-
// - Borders: border
|
|
185
|
-
// - Disabled: disabled, disabledText
|
|
136
|
+
```tsx
|
|
137
|
+
<ThemeProvider theme={myTheme}>
|
|
138
|
+
<App />
|
|
139
|
+
</ThemeProvider>
|
|
186
140
|
```
|
|
187
141
|
|
|
188
|
-
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
## Color Scales
|
|
189
146
|
|
|
190
|
-
Aurora
|
|
147
|
+
Aurora provides **color scales** with **12 shades each** (25, 50, 100-900, 950).
|
|
191
148
|
|
|
192
149
|
```typescript
|
|
193
|
-
import {
|
|
150
|
+
import { colors } from '@aurora-ds/theme'
|
|
194
151
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
text: colors.slate[900],
|
|
201
|
-
}
|
|
202
|
-
})
|
|
152
|
+
colors.indigo[500] // '#6366f1'
|
|
153
|
+
colors.emerald[400] // '#34d399'
|
|
154
|
+
colors.gray[900] // '#18181b'
|
|
155
|
+
colors.white // '#ffffff'
|
|
156
|
+
colors.black // '#000000'
|
|
203
157
|
```
|
|
204
158
|
|
|
205
159
|
### Complete Color Scales Reference
|
|
206
160
|
|
|
207
161
|
All color scales with their hex values (25-950 shades):
|
|
208
162
|
|
|
163
|
+
#### Neutrals
|
|
164
|
+
|
|
209
165
|
| Scale | 25 | 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950 |
|
|
210
166
|
|-------|----|----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
|
|
211
167
|
| **gray** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
@@ -228,452 +184,11 @@ All color scales with their hex values (25-950 shades):
|
|
|
228
184
|
| **pink** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
229
185
|
| **rose** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
230
186
|
|
|
231
|
-
---
|
|
232
|
-
|
|
233
|
-
```typescript
|
|
234
|
-
// Example: Using multiple shades
|
|
235
|
-
const theme = createTheme({
|
|
236
|
-
colors: {
|
|
237
|
-
// Blues for primary actions
|
|
238
|
-
primary: colors.blue[600],
|
|
239
|
-
primaryHover: colors.blue[700],
|
|
240
|
-
primaryActive: colors.blue[800],
|
|
241
|
-
primarySubtle: colors.blue[50],
|
|
242
|
-
|
|
243
|
-
// Grays for surfaces
|
|
244
|
-
background: colors.slate[50],
|
|
245
|
-
surface: colors.slate[100],
|
|
246
|
-
border: colors.slate[200],
|
|
247
|
-
text: colors.slate[900],
|
|
248
|
-
|
|
249
|
-
// Semantic colors
|
|
250
|
-
success: colors.green[600],
|
|
251
|
-
warning: colors.amber[500],
|
|
252
|
-
error: colors.red[600],
|
|
253
|
-
info: colors.blue[500],
|
|
254
|
-
}
|
|
255
|
-
})
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
---
|
|
259
|
-
|
|
260
|
-
## Multiple Themes (e.g., Light & Dark)
|
|
261
|
-
|
|
262
|
-
Use the `satisfies` pattern to ensure consistent structure:
|
|
263
|
-
|
|
264
|
-
```typescript
|
|
265
|
-
import { createTheme, colors } from '@aurora-ds/theme'
|
|
266
|
-
|
|
267
|
-
// Define your color structure
|
|
268
|
-
type AppColors = {
|
|
269
|
-
primary: string
|
|
270
|
-
background: string
|
|
271
|
-
surface: string
|
|
272
|
-
text: string
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// Light theme
|
|
276
|
-
const lightTheme = createTheme({
|
|
277
|
-
colors: {
|
|
278
|
-
primary: colors.blue[600],
|
|
279
|
-
background: colors.white,
|
|
280
|
-
surface: colors.slate[50],
|
|
281
|
-
text: colors.slate[900],
|
|
282
|
-
} satisfies AppColors
|
|
283
|
-
})
|
|
284
|
-
|
|
285
|
-
// Dark theme - TypeScript ensures same structure
|
|
286
|
-
const darkTheme = createTheme({
|
|
287
|
-
colors: {
|
|
288
|
-
primary: colors.blue[500],
|
|
289
|
-
background: colors.slate[950],
|
|
290
|
-
surface: colors.slate[900],
|
|
291
|
-
text: colors.slate[50],
|
|
292
|
-
} satisfies AppColors
|
|
293
|
-
})
|
|
294
|
-
|
|
295
|
-
// Use in app
|
|
296
|
-
function App() {
|
|
297
|
-
const [isDark, setIsDark] = useState(false)
|
|
298
|
-
const theme = isDark ? darkTheme : lightTheme
|
|
299
|
-
|
|
300
|
-
return <ThemeProvider theme={theme}>...</ThemeProvider>
|
|
301
|
-
}
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
---
|
|
305
|
-
|
|
306
|
-
## 💡 Typing Your Theme with `typeof`
|
|
307
|
-
|
|
308
|
-
Aurora DS uses **type inference** for maximum type safety. Always use `typeof` to extract your theme type.
|
|
309
|
-
|
|
310
|
-
### The Standard Pattern
|
|
311
|
-
|
|
312
|
-
```typescript
|
|
313
|
-
// 1. Create your theme
|
|
314
|
-
const appTheme = createTheme({
|
|
315
|
-
colors: {
|
|
316
|
-
brand: colors.blue[600],
|
|
317
|
-
accent: colors.emerald[500],
|
|
318
|
-
surface: colors.white,
|
|
319
|
-
text: colors.slate[900],
|
|
320
|
-
},
|
|
321
|
-
spacing: {
|
|
322
|
-
tight: '4px',
|
|
323
|
-
normal: '16px',
|
|
324
|
-
relaxed: '32px',
|
|
325
|
-
}
|
|
326
|
-
})
|
|
327
|
-
|
|
328
|
-
// 2. Extract the type with typeof
|
|
329
|
-
export type AppTheme = typeof appTheme
|
|
330
|
-
|
|
331
|
-
// 3. Use it in your components
|
|
332
|
-
type ButtonProps = {
|
|
333
|
-
color: keyof AppTheme['colors'] // 'brand' | 'accent' | 'surface' | 'text'
|
|
334
|
-
gap: keyof AppTheme['spacing'] // 'tight' | 'normal' | 'relaxed'
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
function Button({ color, gap }: ButtonProps) {
|
|
338
|
-
const theme = useTheme()
|
|
339
|
-
return <button style={{
|
|
340
|
-
backgroundColor: theme.colors[color],
|
|
341
|
-
padding: theme.spacing[gap],
|
|
342
|
-
}} />
|
|
343
|
-
}
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
### Why `typeof` is the only way
|
|
347
|
-
|
|
348
|
-
**Type inference gives you:**
|
|
349
|
-
- ✅ **Exact types**: TypeScript knows your exact tokens
|
|
350
|
-
- ✅ **No casts needed**: Everything works automatically
|
|
351
|
-
- ✅ **Better autocomplete**: IDE shows only YOUR tokens
|
|
352
|
-
- ✅ **Compile-time safety**: Can't access tokens that don't exist
|
|
353
|
-
|
|
354
|
-
```typescript
|
|
355
|
-
const myTheme = createTheme({
|
|
356
|
-
colors: { brand: '#FF0000', accent: '#00FF00' }
|
|
357
|
-
})
|
|
358
|
-
|
|
359
|
-
type MyTheme = typeof myTheme
|
|
360
|
-
|
|
361
|
-
// ✅ TypeScript knows EXACTLY what you have
|
|
362
|
-
type ColorKeys = keyof MyTheme['colors'] // 'brand' | 'accent'
|
|
363
|
-
|
|
364
|
-
const props: { color: ColorKeys } = {
|
|
365
|
-
color: 'brand' // ✅ OK
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
const invalid: { color: ColorKeys } = {
|
|
369
|
-
color: 'primary' // ❌ Error: 'primary' doesn't exist!
|
|
370
|
-
}
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
### Best Practice: Export from a single file
|
|
374
|
-
|
|
375
|
-
```typescript
|
|
376
|
-
// src/theme.ts - Single source of truth
|
|
377
|
-
import { createTheme, colors } from '@aurora-ds/theme'
|
|
378
|
-
|
|
379
|
-
export const appTheme = createTheme({
|
|
380
|
-
colors: {
|
|
381
|
-
brand: colors.blue[600],
|
|
382
|
-
accent: colors.emerald[500],
|
|
383
|
-
surface: colors.white,
|
|
384
|
-
text: colors.slate[900],
|
|
385
|
-
}
|
|
386
|
-
})
|
|
387
|
-
|
|
388
|
-
export type AppTheme = typeof appTheme
|
|
389
|
-
|
|
390
|
-
// src/components/Button.tsx - Import and use
|
|
391
|
-
import type { AppTheme } from '../theme'
|
|
392
|
-
|
|
393
|
-
type ButtonProps = {
|
|
394
|
-
color: keyof AppTheme['colors'] // ✅ Type-safe!
|
|
395
|
-
}
|
|
396
187
|
```
|
|
397
|
-
|
|
398
|
-
### Alternative: Type-First Approach
|
|
399
|
-
|
|
400
|
-
You can define the type first, then create themes matching it:
|
|
401
|
-
|
|
402
|
-
```typescript
|
|
403
|
-
// 1. Define type structure
|
|
404
|
-
type AppTheme = {
|
|
405
|
-
colors: { brand: string; accent: string }
|
|
406
|
-
spacing: { tight: string; normal: string }
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
// 2. Create theme (cast needed)
|
|
410
|
-
const theme: AppTheme = createTheme({
|
|
411
|
-
colors: { brand: '#000', accent: '#fff' },
|
|
412
|
-
spacing: { tight: '4px', normal: '16px' }
|
|
413
|
-
}) as unknown as AppTheme
|
|
414
|
-
|
|
415
|
-
// 3. Use AppTheme directly
|
|
416
|
-
type Props = { color: keyof AppTheme['colors'] }
|
|
417
188
|
```
|
|
418
189
|
|
|
419
|
-
See [examples/type-first-approach.md](./examples/type-first-approach.md) for details.
|
|
420
|
-
|
|
421
190
|
---
|
|
422
191
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
**When using multiple themes in your app, ALL themes MUST have the same token structure.**
|
|
426
|
-
|
|
427
|
-
This applies to **ALL tokens**: `colors`, `spacing`, `radius`, `shadows`, `fontSize`, `fontWeight`, etc.
|
|
428
|
-
|
|
429
|
-
#### ❌ Bad Practice - Inconsistent structures
|
|
430
|
-
|
|
431
|
-
```typescript
|
|
432
|
-
// Theme 1: Has 'primary', 'secondary', 'background' colors
|
|
433
|
-
const theme1 = createTheme({
|
|
434
|
-
colors: {
|
|
435
|
-
primary: '#007bff',
|
|
436
|
-
secondary: '#6c757d',
|
|
437
|
-
background: '#ffffff',
|
|
438
|
-
}
|
|
439
|
-
})
|
|
440
|
-
|
|
441
|
-
// Theme 2: Has 'brand', 'surface', 'text' - DIFFERENT TOKENS!
|
|
442
|
-
const theme2 = createTheme({
|
|
443
|
-
colors: {
|
|
444
|
-
brand: '#28a745', // ❌ Different token name
|
|
445
|
-
surface: '#f8f9fa', // ❌ Different token name
|
|
446
|
-
text: '#212529', // ❌ Different token name
|
|
447
|
-
},
|
|
448
|
-
spacing: {
|
|
449
|
-
tight: '4px', // ❌ Different token names
|
|
450
|
-
normal: '8px', // ❌ Different from theme1
|
|
451
|
-
}
|
|
452
|
-
})
|
|
453
|
-
|
|
454
|
-
// ❌ Problem: createStyles won't work with both themes
|
|
455
|
-
const useStyles = createStyles((theme) => ({
|
|
456
|
-
button: {
|
|
457
|
-
backgroundColor: theme.colors.primary, // Works with theme1, BREAKS with theme2
|
|
458
|
-
padding: theme.spacing.sm, // BREAKS if theme2 doesn't have 'sm'
|
|
459
|
-
}
|
|
460
|
-
}))
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
#### ✅ Good Practice
|
|
464
|
-
|
|
465
|
-
**Define a common type and use `satisfies`** (Recommended)
|
|
466
|
-
|
|
467
|
-
```typescript
|
|
468
|
-
// 1. Define your app's complete theme structure
|
|
469
|
-
type AppTheme = {
|
|
470
|
-
colors: {
|
|
471
|
-
primary: string
|
|
472
|
-
background: string
|
|
473
|
-
text: string
|
|
474
|
-
border: string
|
|
475
|
-
}
|
|
476
|
-
spacing: {
|
|
477
|
-
sm: string
|
|
478
|
-
md: string
|
|
479
|
-
lg: string
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
// 2. All themes satisfy this structure
|
|
485
|
-
const lightTheme = createTheme({
|
|
486
|
-
colors: {
|
|
487
|
-
primary: '#007bff',
|
|
488
|
-
background: '#ffffff',
|
|
489
|
-
text: '#000000',
|
|
490
|
-
border: '#dee2e6',
|
|
491
|
-
},
|
|
492
|
-
spacing: {
|
|
493
|
-
sm: '8px',
|
|
494
|
-
md: '16px',
|
|
495
|
-
lg: '24px',
|
|
496
|
-
}
|
|
497
|
-
} satisfies AppTheme) // ✅ TypeScript enforces structure
|
|
498
|
-
|
|
499
|
-
const darkTheme = createTheme({
|
|
500
|
-
colors: {
|
|
501
|
-
primary: '#4dabf7',
|
|
502
|
-
background: '#1a1a1a',
|
|
503
|
-
text: '#ffffff',
|
|
504
|
-
border: '#495057',
|
|
505
|
-
},
|
|
506
|
-
spacing: {
|
|
507
|
-
sm: '8px',
|
|
508
|
-
md: '16px',
|
|
509
|
-
lg: '24px',
|
|
510
|
-
}
|
|
511
|
-
} satisfies AppTheme) // ✅ TypeScript enforces structure
|
|
512
|
-
|
|
513
|
-
// TypeScript will error if you:
|
|
514
|
-
// - Forget a required token (in colors OR spacing)
|
|
515
|
-
// - Add an extra token
|
|
516
|
-
// - Use a different token name
|
|
517
|
-
```
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
### Best Practices Summary
|
|
521
|
-
|
|
522
|
-
1. ✅ **Define a type** for your app's colors and use `satisfies`
|
|
523
|
-
2. ✅ **Or you can use `defaultPalette`** as a base for consistency
|
|
524
|
-
3. ✅ **Same tokens across all themes** - only values change
|
|
525
|
-
4. ❌ **Don't create themes with different token sets**
|
|
526
|
-
5. ❌ **Don't mix token naming schemes**
|
|
527
|
-
|
|
528
|
-
---
|
|
529
|
-
|
|
530
|
-
## 🔧 Customizing Tokens
|
|
531
|
-
|
|
532
|
-
### Customize any token independently
|
|
533
|
-
|
|
534
|
-
You can customize **any token** without affecting others:
|
|
535
|
-
|
|
536
|
-
```typescript
|
|
537
|
-
// Just spacing (uses defaultPalette for colors)
|
|
538
|
-
const theme = createTheme({
|
|
539
|
-
spacing: {
|
|
540
|
-
xs: '0.25rem',
|
|
541
|
-
sm: '0.5rem',
|
|
542
|
-
md: '1rem',
|
|
543
|
-
lg: '2rem',
|
|
544
|
-
}
|
|
545
|
-
})
|
|
546
|
-
|
|
547
|
-
// Just radius
|
|
548
|
-
const theme = createTheme({
|
|
549
|
-
radius: {
|
|
550
|
-
none: '0',
|
|
551
|
-
sm: '4px',
|
|
552
|
-
md: '8px',
|
|
553
|
-
full: '9999px',
|
|
554
|
-
}
|
|
555
|
-
})
|
|
556
|
-
|
|
557
|
-
// Multiple tokens
|
|
558
|
-
const theme = createTheme({
|
|
559
|
-
colors: { primary: '#007bff', background: '#fff' },
|
|
560
|
-
spacing: { sm: '0.5rem', md: '1rem' },
|
|
561
|
-
radius: { sm: '4px', md: '8px' },
|
|
562
|
-
})
|
|
563
|
-
```
|
|
564
|
-
|
|
565
|
-
### Available tokens
|
|
566
|
-
|
|
567
|
-
| Token | Default | Description |
|
|
568
|
-
|-------|---------|-------------|
|
|
569
|
-
| `colors` | `defaultPalette` | Color palette (37 semantic colors) |
|
|
570
|
-
| `spacing` | `defaultSpacing` | Spacing scale (11 sizes) |
|
|
571
|
-
| `radius` | `defaultRadius` | Border radius scale (8 sizes) |
|
|
572
|
-
| `shadows` | `defaultShadows` | Box shadow scale (9 shadows) |
|
|
573
|
-
| `fontSize` | `defaultFontSize` | Font size scale (10 sizes) |
|
|
574
|
-
| `fontWeight` | `defaultFontWeight` | Font weight scale (5 weights) |
|
|
575
|
-
| `lineHeight` | `defaultLineHeight` | Line height scale (5 values) |
|
|
576
|
-
| `zIndex` | `defaultZIndex` | Z-index scale (9 layers) |
|
|
577
|
-
| `transition` | `defaultTransition` | Transition presets (3 presets) |
|
|
578
|
-
| `opacity` | `defaultOpacity` | Opacity scale (7 values) |
|
|
579
|
-
| `breakpoints` | `defaultBreakpoints` | Responsive breakpoints (6 breakpoints) |
|
|
580
|
-
|
|
581
|
-
---
|
|
582
|
-
|
|
583
|
-
## 🎭 Styling Components
|
|
584
|
-
|
|
585
|
-
### Using `createStyles`
|
|
586
|
-
|
|
587
|
-
```tsx
|
|
588
|
-
import { createStyles } from '@aurora-ds/theme'
|
|
589
|
-
|
|
590
|
-
const useStyles = createStyles((theme) => ({
|
|
591
|
-
card: {
|
|
592
|
-
backgroundColor: theme.colors.surface,
|
|
593
|
-
padding: theme.spacing.lg,
|
|
594
|
-
borderRadius: theme.radius.lg,
|
|
595
|
-
boxShadow: theme.shadows.md,
|
|
596
|
-
|
|
597
|
-
':hover': {
|
|
598
|
-
backgroundColor: theme.colors.surfaceHover,
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
}))
|
|
602
|
-
|
|
603
|
-
function Card() {
|
|
604
|
-
const styles = useStyles()
|
|
605
|
-
return <div className={styles.card}>Content</div>
|
|
606
|
-
}
|
|
607
|
-
```
|
|
608
|
-
|
|
609
|
-
### Pseudo-classes and Media Queries
|
|
610
|
-
|
|
611
|
-
```tsx
|
|
612
|
-
const useStyles = createStyles((theme) => ({
|
|
613
|
-
button: {
|
|
614
|
-
padding: theme.spacing.md,
|
|
615
|
-
|
|
616
|
-
':hover': {
|
|
617
|
-
backgroundColor: theme.colors.primaryHover,
|
|
618
|
-
},
|
|
619
|
-
|
|
620
|
-
'@media (min-width: 768px)': {
|
|
621
|
-
padding: theme.spacing.lg,
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
}))
|
|
625
|
-
```
|
|
626
|
-
|
|
627
|
-
---
|
|
628
|
-
|
|
629
|
-
## 📘 API Reference
|
|
630
|
-
|
|
631
|
-
### `createTheme(config?)`
|
|
632
|
-
|
|
633
|
-
Creates a theme. All parameters optional.
|
|
634
|
-
|
|
635
|
-
```typescript
|
|
636
|
-
createTheme({
|
|
637
|
-
colors?: Record<string, string>
|
|
638
|
-
spacing?: Record<string, string>
|
|
639
|
-
radius?: Record<string, string>
|
|
640
|
-
// ... other tokens
|
|
641
|
-
})
|
|
642
|
-
```
|
|
643
|
-
|
|
644
|
-
### `<ThemeProvider theme={theme}>`
|
|
645
|
-
|
|
646
|
-
Provides theme to component tree.
|
|
647
|
-
|
|
648
|
-
### `useTheme()`
|
|
649
|
-
|
|
650
|
-
Hook to access current theme.
|
|
651
|
-
|
|
652
|
-
### `createStyles(stylesOrCreator)`
|
|
653
|
-
|
|
654
|
-
Creates component styles with theme access.
|
|
655
|
-
|
|
656
|
-
### `keyframes(definition)`
|
|
657
|
-
|
|
658
|
-
Creates CSS keyframes animation.
|
|
659
|
-
|
|
660
|
-
### `fontFace(definition)`
|
|
661
|
-
|
|
662
|
-
Registers custom font face.
|
|
663
|
-
|
|
664
|
-
---
|
|
665
|
-
|
|
666
|
-
## 📄 License
|
|
192
|
+
## License
|
|
667
193
|
|
|
668
194
|
MIT
|
|
669
|
-
|
|
670
|
-
---
|
|
671
|
-
|
|
672
|
-
## 🔗 Links
|
|
673
|
-
|
|
674
|
-
- [Migration Guide (V1/V2 → V3)](documentation/MIGRATION-GUIDE.md) - Complete migration guide
|
|
675
|
-
- [Changelog](documentation/CHANGELOG.md) - Version history
|
|
676
|
-
- [GitHub Repository](https://github.com/LilianMrzt/Aurora)
|
|
677
|
-
- [NPM Package](https://www.npmjs.com/package/@aurora-ds/theme)
|
|
678
|
-
|
|
679
|
-
---
|