@aurora-ds/theme 2.0.0 → 3.0.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.md +506 -546
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +277 -415
- package/dist/index.d.ts +277 -415
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/README.dev.md +0 -424
package/README.md
CHANGED
|
@@ -1,95 +1,203 @@
|
|
|
1
|
-
# Aurora Theme
|
|
1
|
+
# 🎨 Aurora DS Theme
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
> **A flexible, type-safe theming system for React applications**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@aurora-ds/theme)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
- 🎯 **Color Scales** - 20 color scales with 12 shades each (25-950)
|
|
9
|
-
- ⚡ **Optimized Performance** - LRU caching, static style deduplication
|
|
10
|
-
- 🖥️ **SSR Support** - Server-side rendering compatible
|
|
11
|
-
- 📦 **Lightweight** - No runtime dependencies besides React
|
|
12
|
-
- 🔒 **Type-safe** - Full TypeScript support with generics
|
|
13
|
-
- 🎨 **Ready to Use** - Default palette with semantic color tokens
|
|
9
|
+
Aurora DS Theme is a modern theming library that provides **automatic type inference**, **flexible customization**, and **zero boilerplate** for your design system.
|
|
14
10
|
|
|
15
|
-
|
|
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
|
+
|
|
25
|
+
## 📦 Installation
|
|
16
26
|
|
|
17
27
|
```bash
|
|
18
28
|
npm install @aurora-ds/theme
|
|
19
29
|
```
|
|
20
30
|
|
|
21
|
-
|
|
31
|
+
```bash
|
|
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)
|
|
44
|
+
|
|
45
|
+
#### Option A: Use defaults (fastest)
|
|
46
|
+
```typescript
|
|
47
|
+
import { createTheme } from '@aurora-ds/theme'
|
|
48
|
+
|
|
49
|
+
const theme = createTheme()
|
|
50
|
+
// ✅ Ready to use! Includes 37 semantic colors
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
#### Option B: Customize or expand the default palette
|
|
54
|
+
```typescript
|
|
55
|
+
import { createTheme, defaultPalette } from '@aurora-ds/theme'
|
|
56
|
+
|
|
57
|
+
const theme = createTheme({
|
|
58
|
+
colors: {
|
|
59
|
+
...defaultPalette,
|
|
60
|
+
primary: '#007bff', // Your brand color
|
|
61
|
+
primaryHover: '#0056b3',
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
#### Option C: Define your own colors
|
|
67
|
+
```typescript
|
|
68
|
+
import { createTheme } from '@aurora-ds/theme'
|
|
69
|
+
|
|
70
|
+
const theme = createTheme({
|
|
71
|
+
colors: {
|
|
72
|
+
primary: '#007bff',
|
|
73
|
+
background: '#ffffff',
|
|
74
|
+
text: '#212529',
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 2. Provide the theme to your app
|
|
22
80
|
|
|
23
81
|
```tsx
|
|
24
|
-
import {
|
|
82
|
+
import { ThemeProvider } from '@aurora-ds/theme'
|
|
83
|
+
import { theme } from './theme'
|
|
84
|
+
|
|
85
|
+
function App() {
|
|
86
|
+
return (
|
|
87
|
+
<ThemeProvider theme={theme}>
|
|
88
|
+
<YourApp />
|
|
89
|
+
</ThemeProvider>
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### 3. Use the theme in components
|
|
25
95
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
<App />
|
|
29
|
-
</ThemeProvider>
|
|
96
|
+
```tsx
|
|
97
|
+
import { useTheme, createStyles } from '@aurora-ds/theme'
|
|
30
98
|
|
|
31
|
-
//
|
|
32
|
-
const
|
|
33
|
-
|
|
99
|
+
// With createStyles
|
|
100
|
+
const useStyles = createStyles((theme) => ({
|
|
101
|
+
button: {
|
|
102
|
+
backgroundColor: theme.colors.primary,
|
|
34
103
|
padding: theme.spacing.md,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
},
|
|
104
|
+
borderRadius: theme.radius.md,
|
|
105
|
+
}
|
|
38
106
|
}))
|
|
39
107
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return <
|
|
108
|
+
function Button() {
|
|
109
|
+
const styles = useStyles()
|
|
110
|
+
return <button className={styles.button}>Click me</button>
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// With useTheme hook
|
|
114
|
+
function Card() {
|
|
115
|
+
const theme = useTheme()
|
|
116
|
+
|
|
117
|
+
return (
|
|
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
|
+
)
|
|
43
126
|
}
|
|
44
127
|
```
|
|
45
128
|
|
|
46
129
|
---
|
|
47
130
|
|
|
48
|
-
##
|
|
131
|
+
## 📚 Core Concepts
|
|
132
|
+
|
|
133
|
+
### Theme Structure
|
|
134
|
+
|
|
135
|
+
A theme consists of **design tokens** organized into categories:
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
{
|
|
139
|
+
colors: { ... }, // Color palette
|
|
140
|
+
spacing: { ... }, // Spacing scale
|
|
141
|
+
radius: { ... }, // Border radius scale
|
|
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
|
+
}
|
|
151
|
+
```
|
|
49
152
|
|
|
50
|
-
|
|
153
|
+
**All tokens are optional** - if you don't specify a value, sensible defaults are used.
|
|
51
154
|
|
|
52
|
-
###
|
|
155
|
+
### Type Inference (Automatic!)
|
|
53
156
|
|
|
54
|
-
**
|
|
55
|
-
- `gray` - Pure neutral, universal default
|
|
56
|
-
- `slate` - Cool/blue undertone, tech & corporate
|
|
57
|
-
- `stone` - Warm undertone, lifestyle & natural
|
|
157
|
+
TypeScript **automatically infers** your theme structure:
|
|
58
158
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
159
|
+
```typescript
|
|
160
|
+
const theme = createTheme({
|
|
161
|
+
colors: {
|
|
162
|
+
brand: '#007bff',
|
|
163
|
+
danger: '#dc3545'
|
|
164
|
+
}
|
|
165
|
+
})
|
|
166
|
+
```
|
|
63
167
|
|
|
64
|
-
|
|
168
|
+
## 🎨 Working with Colors
|
|
65
169
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
//
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
170
|
+
### Default Palette
|
|
171
|
+
|
|
172
|
+
Aurora DS provides `defaultPalette` with **37 semantic color tokens**:
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
import { defaultPalette } from '@aurora-ds/theme'
|
|
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
|
|
79
186
|
```
|
|
80
187
|
|
|
81
|
-
###
|
|
188
|
+
### Color Scales
|
|
82
189
|
|
|
83
|
-
|
|
84
|
-
|
|
190
|
+
Aurora DS includes **color scales** with 11 shades (50-950) for each color:
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
import { createTheme, colors } from '@aurora-ds/theme'
|
|
85
194
|
|
|
86
|
-
const
|
|
195
|
+
const theme = createTheme({
|
|
87
196
|
colors: {
|
|
88
|
-
primary: colors.
|
|
89
|
-
primaryHover: colors.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
// ... other colors
|
|
197
|
+
primary: colors.blue[600],
|
|
198
|
+
primaryHover: colors.blue[700],
|
|
199
|
+
background: colors.slate[50],
|
|
200
|
+
text: colors.slate[900],
|
|
93
201
|
}
|
|
94
202
|
})
|
|
95
203
|
```
|
|
@@ -98,46 +206,23 @@ const myTheme = createTheme(defaultTheme, {
|
|
|
98
206
|
|
|
99
207
|
All color scales with their hex values (25-950 shades):
|
|
100
208
|
|
|
101
|
-
#### Neutrals
|
|
102
|
-
|
|
103
209
|
| Scale | 25 | 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950 |
|
|
104
210
|
|-------|----|----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
|
|
105
211
|
| **gray** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
106
212
|
| **slate** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
107
213
|
| **stone** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
108
|
-
|
|
109
|
-
#### Warm Colors
|
|
110
|
-
|
|
111
|
-
| Scale | 25 | 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950 |
|
|
112
|
-
|-------|----|----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
|
|
113
214
|
| **red** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
114
215
|
| **orange** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
115
216
|
| **amber** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
116
217
|
| **yellow** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
117
|
-
|
|
118
|
-
#### Green Colors
|
|
119
|
-
|
|
120
|
-
| Scale | 25 | 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950 |
|
|
121
|
-
|-------|----|----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
|
|
122
218
|
| **lime** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
123
219
|
| **green** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
124
220
|
| **emerald** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
125
221
|
| **teal** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
126
|
-
|
|
127
|
-
#### Blue Colors
|
|
128
|
-
|
|
129
|
-
| Scale | 25 | 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950 |
|
|
130
|
-
|-------|----|----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
|
|
131
222
|
| **cyan** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
132
|
-
| **sky** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
133
223
|
| **blue** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
134
224
|
| **indigo** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
135
225
|
| **violet** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
136
|
-
|
|
137
|
-
#### Purple & Pink Colors
|
|
138
|
-
|
|
139
|
-
| Scale | 25 | 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950 |
|
|
140
|
-
|-------|----|----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
|
|
141
226
|
| **purple** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
142
227
|
| **fuchsia** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
143
228
|
| **pink** |  |  |  |  |  |  |  |  |  |  |  |  |
|
|
@@ -145,575 +230,450 @@ All color scales with their hex values (25-950 shades):
|
|
|
145
230
|
|
|
146
231
|
---
|
|
147
232
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
defaultBreakpoints,
|
|
172
|
-
} from '@aurora-ds/theme'
|
|
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
|
+
})
|
|
173
256
|
```
|
|
174
257
|
|
|
175
|
-
|
|
258
|
+
---
|
|
176
259
|
|
|
177
|
-
|
|
178
|
-
import { defaultTheme, defaultPalette, createTheme } from '@aurora-ds/theme'
|
|
260
|
+
## Multiple Themes (e.g., Light & Dark)
|
|
179
261
|
|
|
180
|
-
|
|
181
|
-
colors: {
|
|
182
|
-
...defaultPalette,
|
|
183
|
-
primary: '#your-brand-color',
|
|
184
|
-
primaryHover: '#your-brand-hover',
|
|
185
|
-
},
|
|
186
|
-
})
|
|
187
|
-
```
|
|
262
|
+
Use the `satisfies` pattern to ensure consistent structure:
|
|
188
263
|
|
|
189
|
-
|
|
264
|
+
```typescript
|
|
265
|
+
import { createTheme, colors } from '@aurora-ds/theme'
|
|
190
266
|
|
|
191
|
-
|
|
192
|
-
|
|
267
|
+
// Define your color structure
|
|
268
|
+
type AppColors = {
|
|
269
|
+
primary: string
|
|
270
|
+
background: string
|
|
271
|
+
surface: string
|
|
272
|
+
text: string
|
|
273
|
+
}
|
|
193
274
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
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
|
|
200
283
|
})
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
### Mix and Match
|
|
204
284
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
defaultSpacing,
|
|
208
|
-
defaultRadius,
|
|
209
|
-
defaultShadows,
|
|
210
|
-
colors,
|
|
211
|
-
createTheme,
|
|
212
|
-
defaultTheme,
|
|
213
|
-
} from '@aurora-ds/theme'
|
|
214
|
-
|
|
215
|
-
const myTheme = createTheme(defaultTheme, {
|
|
285
|
+
// Dark theme - TypeScript ensures same structure
|
|
286
|
+
const darkTheme = createTheme({
|
|
216
287
|
colors: {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
}
|
|
222
|
-
spacing: defaultSpacing, // Keep default spacing
|
|
223
|
-
radius: {
|
|
224
|
-
...defaultRadius,
|
|
225
|
-
md: '8px', // More rounded
|
|
226
|
-
},
|
|
288
|
+
primary: colors.blue[500],
|
|
289
|
+
background: colors.slate[950],
|
|
290
|
+
surface: colors.slate[900],
|
|
291
|
+
text: colors.slate[50],
|
|
292
|
+
} satisfies AppColors
|
|
227
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
|
+
}
|
|
228
302
|
```
|
|
229
303
|
|
|
230
304
|
---
|
|
231
305
|
|
|
232
|
-
##
|
|
233
|
-
|
|
234
|
-
Need a completely different color token structure? Aurora supports **full customization** where you can define your own semantic tokens without inheriting `BaseColors`.
|
|
235
|
-
|
|
236
|
-
### Option 1: Replace Mode
|
|
306
|
+
## 💡 Typing Your Theme with `typeof`
|
|
237
307
|
|
|
238
|
-
|
|
308
|
+
Aurora DS uses **type inference** for maximum type safety. Always use `typeof` to extract your theme type.
|
|
239
309
|
|
|
240
|
-
|
|
241
|
-
import { createTheme, defaultTheme } from '@aurora-ds/theme'
|
|
310
|
+
### The Standard Pattern
|
|
242
311
|
|
|
243
|
-
|
|
244
|
-
|
|
312
|
+
```typescript
|
|
313
|
+
// 1. Create your theme
|
|
314
|
+
const appTheme = createTheme({
|
|
245
315
|
colors: {
|
|
246
|
-
brand:
|
|
247
|
-
|
|
248
|
-
surface:
|
|
249
|
-
text:
|
|
316
|
+
brand: colors.blue[600],
|
|
317
|
+
accent: colors.emerald[500],
|
|
318
|
+
surface: colors.white,
|
|
319
|
+
text: colors.slate[900],
|
|
250
320
|
},
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
### Option 2: Custom Theme Function
|
|
321
|
+
spacing: {
|
|
322
|
+
tight: '4px',
|
|
323
|
+
normal: '16px',
|
|
324
|
+
relaxed: '32px',
|
|
325
|
+
}
|
|
326
|
+
})
|
|
258
327
|
|
|
259
|
-
|
|
328
|
+
// 2. Extract the type with typeof
|
|
329
|
+
export type AppTheme = typeof appTheme
|
|
260
330
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
// 1. Define your own color token structure
|
|
266
|
-
type MyBrandColors = {
|
|
267
|
-
brand: string
|
|
268
|
-
brandHover: string
|
|
269
|
-
brandActive: string
|
|
270
|
-
surface: string
|
|
271
|
-
surfaceElevated: string
|
|
272
|
-
textPrimary: string
|
|
273
|
-
textSecondary: string
|
|
274
|
-
border: string
|
|
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'
|
|
275
335
|
}
|
|
276
336
|
|
|
277
|
-
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
surfaceElevated: '#f8f9fa',
|
|
285
|
-
textPrimary: '#212529',
|
|
286
|
-
textSecondary: '#6c757d',
|
|
287
|
-
border: '#dee2e6',
|
|
288
|
-
},
|
|
289
|
-
// Other tokens use defaults, or provide your own:
|
|
290
|
-
// spacing: { ... },
|
|
291
|
-
// radius: { ... },
|
|
292
|
-
})
|
|
293
|
-
|
|
294
|
-
// 3. TypeScript knows your exact token structure!
|
|
295
|
-
myTheme.colors.brand // ✅ OK - string
|
|
296
|
-
myTheme.colors.primary // ❌ Error - property doesn't exist
|
|
297
|
-
|
|
298
|
-
// 4. Type your theme for components
|
|
299
|
-
type MyTheme = typeof myTheme
|
|
300
|
-
// or: type MyTheme = CustomTheme<MyBrandColors>
|
|
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
|
+
}
|
|
301
344
|
```
|
|
302
345
|
|
|
303
|
-
###
|
|
346
|
+
### Why `typeof` is the only way
|
|
304
347
|
|
|
305
|
-
|
|
306
|
-
|
|
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
|
|
307
353
|
|
|
308
|
-
|
|
309
|
-
|
|
354
|
+
```typescript
|
|
355
|
+
const myTheme = createTheme({
|
|
356
|
+
colors: { brand: '#FF0000', accent: '#00FF00' }
|
|
357
|
+
})
|
|
310
358
|
|
|
311
|
-
|
|
312
|
-
const STYLES = createStyles((theme) => ({
|
|
313
|
-
button: {
|
|
314
|
-
backgroundColor: theme.colors.brand, // ✅ TypeScript knows!
|
|
315
|
-
color: theme.colors.textPrimary, // ✅ Works
|
|
316
|
-
// backgroundColor: theme.colors.primary, // ❌ Would error
|
|
317
|
-
},
|
|
318
|
-
}))
|
|
359
|
+
type MyTheme = typeof myTheme
|
|
319
360
|
|
|
320
|
-
//
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
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
|
|
324
366
|
}
|
|
325
367
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
</ThemeProvider>
|
|
368
|
+
const invalid: { color: ColorKeys } = {
|
|
369
|
+
color: 'primary' // ❌ Error: 'primary' doesn't exist!
|
|
370
|
+
}
|
|
330
371
|
```
|
|
331
372
|
|
|
332
|
-
###
|
|
373
|
+
### Best Practice: Export from a single file
|
|
333
374
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
// src/theme.ts
|
|
338
|
-
import {
|
|
339
|
-
createCustomTheme,
|
|
340
|
-
createTypedStyles,
|
|
341
|
-
ThemeProvider as BaseThemeProvider,
|
|
342
|
-
useTheme as baseUseTheme,
|
|
343
|
-
} from '@aurora-ds/theme'
|
|
344
|
-
import type { CustomTheme } from '@aurora-ds/theme'
|
|
345
|
-
|
|
346
|
-
// 1. Define your color tokens
|
|
347
|
-
type MyColors = {
|
|
348
|
-
brand: string
|
|
349
|
-
brandHover: string
|
|
350
|
-
brandActive: string
|
|
351
|
-
surface: string
|
|
352
|
-
surfaceElevated: string
|
|
353
|
-
textPrimary: string
|
|
354
|
-
textSecondary: string
|
|
355
|
-
border: string
|
|
356
|
-
}
|
|
375
|
+
```typescript
|
|
376
|
+
// src/theme.ts - Single source of truth
|
|
377
|
+
import { createTheme, colors } from '@aurora-ds/theme'
|
|
357
378
|
|
|
358
|
-
|
|
359
|
-
export const theme = createCustomTheme<MyColors>({
|
|
379
|
+
export const appTheme = createTheme({
|
|
360
380
|
colors: {
|
|
361
|
-
brand:
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
textPrimary: '#212529',
|
|
367
|
-
textSecondary: '#6c757d',
|
|
368
|
-
border: '#dee2e6',
|
|
369
|
-
},
|
|
381
|
+
brand: colors.blue[600],
|
|
382
|
+
accent: colors.emerald[500],
|
|
383
|
+
surface: colors.white,
|
|
384
|
+
text: colors.slate[900],
|
|
385
|
+
}
|
|
370
386
|
})
|
|
371
387
|
|
|
372
|
-
|
|
373
|
-
export type MyTheme = typeof theme
|
|
374
|
-
export const createStyles = createTypedStyles<MyTheme>()
|
|
375
|
-
export const useTheme = () => baseUseTheme<MyTheme>()
|
|
376
|
-
export const ThemeProvider = BaseThemeProvider
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
Then use in your components:
|
|
388
|
+
export type AppTheme = typeof appTheme
|
|
380
389
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
import { createStyles } from '../theme'
|
|
384
|
-
|
|
385
|
-
// No need to specify <MyTheme> - it's already typed!
|
|
386
|
-
const STYLES = createStyles((theme) => ({
|
|
387
|
-
root: {
|
|
388
|
-
backgroundColor: theme.colors.brand,
|
|
389
|
-
color: theme.colors.textPrimary,
|
|
390
|
-
padding: theme.spacing.md,
|
|
391
|
-
borderRadius: theme.radius.md,
|
|
392
|
-
':hover': {
|
|
393
|
-
backgroundColor: theme.colors.brandHover,
|
|
394
|
-
},
|
|
395
|
-
},
|
|
396
|
-
}))
|
|
390
|
+
// src/components/Button.tsx - Import and use
|
|
391
|
+
import type { AppTheme } from '../theme'
|
|
397
392
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
393
|
+
type ButtonProps = {
|
|
394
|
+
color: keyof AppTheme['colors'] // ✅ Type-safe!
|
|
395
|
+
}
|
|
401
396
|
```
|
|
402
397
|
|
|
403
|
-
###
|
|
404
|
-
|
|
405
|
-
| Approach | Use Case |
|
|
406
|
-
|----------|----------|
|
|
407
|
-
| `createTheme()` (default merge) | Extend default tokens, keep compatibility |
|
|
408
|
-
| `createTheme()` with `{ mode: 'replace' }` | Quick replacement without type safety |
|
|
409
|
-
| `createCustomTheme<T>()` | Full type safety with custom token structure |
|
|
410
|
-
| `createTypedStyles<T>()` | Pre-type your `createStyles` for DX (recommended with custom themes) |
|
|
411
|
-
|
|
412
|
-
---
|
|
398
|
+
### Alternative: Type-First Approach
|
|
413
399
|
|
|
414
|
-
|
|
400
|
+
You can define the type first, then create themes matching it:
|
|
415
401
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
| `secondary`, `secondaryHover`, `secondaryActive`, `secondarySubtle`, `secondaryDisabled`, `onSecondary` | Secondary actions |
|
|
422
|
-
| `background`, `surface`, `surfaceHover`, `surfaceActive` | Surfaces |
|
|
423
|
-
| `text`, `textSecondary`, `textTertiary` | Text hierarchy |
|
|
424
|
-
| `border` | Borders |
|
|
425
|
-
| `success`, `successSubtle` | Success state |
|
|
426
|
-
| `warning`, `warningSubtle` | Warning state |
|
|
427
|
-
| `error`, `errorHover`, `errorSubtle`, `onError` | Error state |
|
|
428
|
-
| `info`, `infoSubtle` | Info state |
|
|
429
|
-
| `link`, `linkHover`, `linkActive`, `linkDisabled` | Links |
|
|
430
|
-
| `disabled`, `disabledText` | Disabled states |
|
|
431
|
-
|
|
432
|
-
### Spacing
|
|
433
|
-
|
|
434
|
-
```tsx
|
|
435
|
-
spacing: {
|
|
436
|
-
none: '0',
|
|
437
|
-
'2xs': '0.125rem', // 2px
|
|
438
|
-
xs: '0.25rem', // 4px
|
|
439
|
-
sm: '0.5rem', // 8px
|
|
440
|
-
md: '1rem', // 16px
|
|
441
|
-
lg: '1.5rem', // 24px
|
|
442
|
-
xl: '2rem', // 32px
|
|
443
|
-
'2xl': '3rem', // 48px
|
|
444
|
-
'3xl': '4rem', // 64px
|
|
445
|
-
'4xl': '6rem', // 96px
|
|
446
|
-
'5xl': '8rem', // 128px
|
|
402
|
+
```typescript
|
|
403
|
+
// 1. Define type structure
|
|
404
|
+
type AppTheme = {
|
|
405
|
+
colors: { brand: string; accent: string }
|
|
406
|
+
spacing: { tight: string; normal: string }
|
|
447
407
|
}
|
|
448
|
-
```
|
|
449
408
|
|
|
450
|
-
|
|
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
|
|
451
414
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
none: 0, // Fully transparent
|
|
455
|
-
lowest: 0.05, // Very subtle
|
|
456
|
-
low: 0.1, // Subtle
|
|
457
|
-
medium: 0.25, // Noticeable
|
|
458
|
-
high: 0.5, // Semi-transparent
|
|
459
|
-
higher: 0.75, // Mostly opaque
|
|
460
|
-
full: 1, // Fully opaque
|
|
461
|
-
}
|
|
415
|
+
// 3. Use AppTheme directly
|
|
416
|
+
type Props = { color: keyof AppTheme['colors'] }
|
|
462
417
|
```
|
|
463
418
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
| Token | Values |
|
|
467
|
-
|-------|--------|
|
|
468
|
-
| `radius` | `none`, `xs`, `sm`, `md`, `lg`, `xl`, `2xl`, `full` |
|
|
469
|
-
| `shadows` | `none`, `xs`, `sm`, `md`, `lg`, `xl`, `2xl`, `inner`, `focus` |
|
|
470
|
-
| `fontSize` | `2xs`, `xs`, `sm`, `md`, `lg`, `xl`, `2xl`, `3xl`, `4xl`, `5xl` |
|
|
471
|
-
| `fontWeight` | `light`, `regular`, `medium`, `semibold`, `bold` |
|
|
472
|
-
| `lineHeight` | `none`, `tight`, `normal`, `relaxed`, `loose` |
|
|
473
|
-
| `zIndex` | `behind`, `base`, `dropdown`, `sticky`, `overlay`, `modal`, `popover`, `tooltip`, `toast` |
|
|
474
|
-
| `transition` | `fast`, `normal`, `slow` |
|
|
475
|
-
| `opacity` | `none`, `lowest`, `low`, `medium`, `high`, `higher`, `full` |
|
|
476
|
-
| `breakpoints` | `xs`, `sm`, `md`, `lg`, `xl`, `2xl` |
|
|
419
|
+
See [examples/type-first-approach.md](./examples/type-first-approach.md) for details.
|
|
477
420
|
|
|
478
421
|
---
|
|
479
422
|
|
|
480
|
-
|
|
423
|
+
### ⚠️ Important: Theme Structure Consistency
|
|
481
424
|
|
|
482
|
-
|
|
425
|
+
**When using multiple themes in your app, ALL themes MUST have the same token structure.**
|
|
483
426
|
|
|
484
|
-
|
|
485
|
-
import type { BaseColors, ExtendTheme } from '@aurora-ds/theme'
|
|
427
|
+
This applies to **ALL tokens**: `colors`, `spacing`, `radius`, `shadows`, `fontSize`, `fontWeight`, etc.
|
|
486
428
|
|
|
487
|
-
|
|
488
|
-
type MyColors = BaseColors & {
|
|
489
|
-
brand: string
|
|
490
|
-
brandHover: string
|
|
491
|
-
}
|
|
429
|
+
#### ❌ Bad Practice - Inconsistent structures
|
|
492
430
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
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
|
+
})
|
|
497
440
|
|
|
498
|
-
//
|
|
499
|
-
const
|
|
500
|
-
|
|
501
|
-
|
|
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
|
|
502
447
|
},
|
|
503
|
-
|
|
448
|
+
spacing: {
|
|
449
|
+
tight: '4px', // ❌ Different token names
|
|
450
|
+
normal: '8px', // ❌ Different from theme1
|
|
451
|
+
}
|
|
452
|
+
})
|
|
504
453
|
|
|
505
|
-
//
|
|
506
|
-
const
|
|
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
|
+
}))
|
|
507
461
|
```
|
|
508
462
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
## Dynamic Styles
|
|
463
|
+
#### ✅ Good Practice
|
|
512
464
|
|
|
513
|
-
|
|
514
|
-
const STYLES = createStyles((theme) => ({
|
|
515
|
-
button: (variant: 'primary' | 'secondary', size: 'sm' | 'md' | 'lg') => ({
|
|
516
|
-
backgroundColor: theme.colors[variant],
|
|
517
|
-
padding: theme.spacing[size],
|
|
518
|
-
borderRadius: theme.radius.md,
|
|
519
|
-
transition: theme.transition.fast,
|
|
520
|
-
}),
|
|
521
|
-
}))
|
|
465
|
+
**Define a common type and use `satisfies`** (Recommended)
|
|
522
466
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
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
|
+
}
|
|
526
483
|
|
|
527
|
-
|
|
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
|
|
528
498
|
|
|
529
|
-
|
|
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
|
|
530
512
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
//
|
|
535
|
-
const html = renderToString(<App />)
|
|
536
|
-
const styles = getSSRStyles()
|
|
537
|
-
|
|
538
|
-
const fullHtml = `
|
|
539
|
-
<!DOCTYPE html>
|
|
540
|
-
<html>
|
|
541
|
-
<head>
|
|
542
|
-
<style id="aurora-styles">${styles}</style>
|
|
543
|
-
</head>
|
|
544
|
-
<body>${html}</body>
|
|
545
|
-
</html>
|
|
546
|
-
`
|
|
547
|
-
|
|
548
|
-
clearSSRRules() // Reset for next request
|
|
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
|
|
549
517
|
```
|
|
550
518
|
|
|
551
|
-
---
|
|
552
519
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
| `BaseColors` | Color token type |
|
|
561
|
-
| `BaseSpacing` | Spacing token type |
|
|
562
|
-
| `BaseOpacity` | Opacity token type |
|
|
563
|
-
| `BaseBreakpoints` | Breakpoints token type |
|
|
564
|
-
| `ColorScale` | Color scale type (25-950) |
|
|
565
|
-
| `ColorName` | Union of color scale names |
|
|
566
|
-
| `ExtendTheme<T>` | Helper to extend theme |
|
|
567
|
-
| `DeepPartial<T>` | For partial overrides |
|
|
568
|
-
| `CustomTheme<TColors, ...>` | Generic type for fully custom themes |
|
|
569
|
-
| `CustomThemeBase<TColors>` | Base type for custom color themes |
|
|
570
|
-
| `CreateThemeOptions` | Options for `createTheme()` (`{ mode: 'merge' \| 'replace' }`) |
|
|
571
|
-
|
|
572
|
-
### Components & Hooks
|
|
573
|
-
|
|
574
|
-
| Export | Description |
|
|
575
|
-
|--------|-------------|
|
|
576
|
-
| `ThemeProvider` | Theme context provider |
|
|
577
|
-
| `useTheme<T>()` | Access current theme |
|
|
578
|
-
|
|
579
|
-
### Theme Creation
|
|
580
|
-
|
|
581
|
-
| Export | Description |
|
|
582
|
-
|--------|-------------|
|
|
583
|
-
| `createTheme(base, overrides, options?)` | Create theme by merging/replacing base with overrides |
|
|
584
|
-
| `createCustomTheme<TColors>(config)` | Create theme with fully custom color tokens |
|
|
585
|
-
| `mergeThemes(base, ...overrides)` | Merge multiple theme overrides |
|
|
586
|
-
| `createThemeVariant(overrides)` | Create a reusable theme variant factory |
|
|
587
|
-
|
|
588
|
-
### Styling
|
|
589
|
-
|
|
590
|
-
| Export | Description |
|
|
591
|
-
|--------|-------------|
|
|
592
|
-
| `createStyles<T>()` | Create themed styles |
|
|
593
|
-
| `createTypedStyles<T>()` | Create a pre-typed `createStyles` function for custom themes |
|
|
594
|
-
| `keyframes()` | CSS keyframe animations |
|
|
595
|
-
| `fontFace()` | @font-face rules |
|
|
596
|
-
| `cssVariables()` | CSS custom properties |
|
|
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**
|
|
597
527
|
|
|
598
528
|
---
|
|
599
529
|
|
|
600
|
-
##
|
|
530
|
+
## 🔧 Customizing Tokens
|
|
601
531
|
|
|
602
|
-
|
|
532
|
+
### Customize any token independently
|
|
603
533
|
|
|
604
|
-
|
|
534
|
+
You can customize **any token** without affecting others:
|
|
605
535
|
|
|
606
|
-
|
|
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
|
+
})
|
|
607
546
|
|
|
608
|
-
|
|
547
|
+
// Just radius
|
|
548
|
+
const theme = createTheme({
|
|
549
|
+
radius: {
|
|
550
|
+
none: '0',
|
|
551
|
+
sm: '4px',
|
|
552
|
+
md: '8px',
|
|
553
|
+
full: '9999px',
|
|
554
|
+
}
|
|
555
|
+
})
|
|
609
556
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
import { colors, createTheme, defaultTheme } from '@aurora-ds/theme'
|
|
616
|
-
|
|
617
|
-
const myTheme = createTheme(defaultTheme, {
|
|
618
|
-
colors: {
|
|
619
|
-
primary: colors.indigo[600],
|
|
620
|
-
primaryHover: colors.indigo[700],
|
|
621
|
-
// ... full control over all tokens
|
|
622
|
-
}
|
|
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' },
|
|
623
562
|
})
|
|
624
563
|
```
|
|
625
564
|
|
|
626
|
-
|
|
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`
|
|
627
586
|
|
|
628
587
|
```tsx
|
|
629
|
-
|
|
630
|
-
import { indigo, blue } from '@aurora-ds/theme'
|
|
588
|
+
import { createStyles } from '@aurora-ds/theme'
|
|
631
589
|
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
colors.
|
|
635
|
-
|
|
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
|
+
}
|
|
636
607
|
```
|
|
637
608
|
|
|
638
|
-
|
|
609
|
+
### Pseudo-classes and Media Queries
|
|
639
610
|
|
|
640
611
|
```tsx
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
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
|
+
}))
|
|
648
625
|
```
|
|
649
626
|
|
|
650
|
-
|
|
627
|
+
---
|
|
628
|
+
|
|
629
|
+
## 📘 API Reference
|
|
651
630
|
|
|
652
|
-
|
|
653
|
-
- ❌ Accent colors (5 tokens): `accent`, `accentHover`, `accentActive`, `onAccent`, `accentSubtle`
|
|
654
|
-
- ❌ Tertiary colors (6 tokens): `tertiary`, `tertiaryHover`, `tertiaryActive`, `onTertiary`, `tertiarySubtle`, `tertiaryDisabled`
|
|
655
|
-
- ❌ Extra surface (2): `elevated`, `overlay`
|
|
656
|
-
- ❌ Extra text (1): `textInverse`
|
|
657
|
-
- ❌ Extra borders (3): `borderHover`, `borderFocus`, `borderSubtle`
|
|
658
|
-
- ❌ Extra semantic (6): `onSuccess`, `successHover`, `onWarning`, `warningHover`, `onInfo`, `infoHover`
|
|
659
|
-
- ❌ Extra interactive (3): `linkVisited`, `linkDisabled`, `focus`
|
|
631
|
+
### `createTheme(config?)`
|
|
660
632
|
|
|
661
|
-
|
|
633
|
+
Creates a theme. All parameters optional.
|
|
662
634
|
|
|
663
|
-
```
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
// ✅ v2 - Use existing tokens or extend theme
|
|
670
|
-
theme.colors.primary // Use existing
|
|
671
|
-
theme.colors.secondary // Use existing
|
|
672
|
-
theme.colors.surface // Use existing
|
|
673
|
-
|
|
674
|
-
// OR extend if needed:
|
|
675
|
-
const myTheme = createTheme(defaultTheme, {
|
|
676
|
-
colors: {
|
|
677
|
-
...defaultTheme.colors,
|
|
678
|
-
accent: colors.cyan[500],
|
|
679
|
-
tertiary: colors.violet[500],
|
|
680
|
-
elevated: colors.slate[100],
|
|
681
|
-
}
|
|
635
|
+
```typescript
|
|
636
|
+
createTheme({
|
|
637
|
+
colors?: Record<string, string>
|
|
638
|
+
spacing?: Record<string, string>
|
|
639
|
+
radius?: Record<string, string>
|
|
640
|
+
// ... other tokens
|
|
682
641
|
})
|
|
683
642
|
```
|
|
684
643
|
|
|
685
|
-
###
|
|
644
|
+
### `<ThemeProvider theme={theme}>`
|
|
686
645
|
|
|
687
|
-
|
|
688
|
-
```tsx
|
|
689
|
-
// Before: import { indigo } from '@aurora-ds/theme'
|
|
690
|
-
// After: import { colors } from '@aurora-ds/theme'
|
|
691
|
-
// colors.indigo[500]
|
|
692
|
-
```
|
|
646
|
+
Provides theme to component tree.
|
|
693
647
|
|
|
694
|
-
|
|
648
|
+
### `useTheme()`
|
|
695
649
|
|
|
696
|
-
|
|
650
|
+
Hook to access current theme.
|
|
697
651
|
|
|
698
|
-
|
|
652
|
+
### `createStyles(stylesOrCreator)`
|
|
699
653
|
|
|
700
|
-
|
|
701
|
-
```bash
|
|
702
|
-
npm run typecheck # Catch type errors
|
|
703
|
-
npm run build # Ensure no import errors
|
|
704
|
-
npm test # Run tests
|
|
705
|
-
```
|
|
654
|
+
Creates component styles with theme access.
|
|
706
655
|
|
|
707
|
-
###
|
|
656
|
+
### `keyframes(definition)`
|
|
708
657
|
|
|
709
|
-
|
|
710
|
-
- 🎯 **More flexible** - Full control over color tokens
|
|
711
|
-
- ⚡ **Better tree-shaking** - Optimized exports
|
|
712
|
-
- 🧩 **Simpler** - Fewer built-in tokens = less decision fatigue
|
|
658
|
+
Creates CSS keyframes animation.
|
|
713
659
|
|
|
714
|
-
|
|
660
|
+
### `fontFace(definition)`
|
|
661
|
+
|
|
662
|
+
Registers custom font face.
|
|
663
|
+
|
|
664
|
+
---
|
|
665
|
+
|
|
666
|
+
## 📄 License
|
|
715
667
|
|
|
716
668
|
MIT
|
|
717
669
|
|
|
670
|
+
---
|
|
671
|
+
|
|
672
|
+
## 🔗 Links
|
|
718
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)
|
|
719
678
|
|
|
679
|
+
---
|