chaincss 2.0.6 → 2.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/CHANGELOG.md +30 -0
- package/CODE_OF_CONDUCT.md +21 -0
- package/CONTRIBUTING.md +28 -0
- package/README.md +454 -231
- package/demo/demo/node_modules/caniuse-db/fulldata-json/data-2.0.json +1 -0
- package/demo/index.html +16 -0
- package/demo/package.json +20 -0
- package/demo/src/App.tsx +117 -0
- package/demo/src/chaincss-barrel.ts +9 -0
- package/demo/src/main.tsx +8 -0
- package/demo/src/styles.chain.ts +300 -0
- package/demo/vite.config.ts +46 -0
- package/dist/cli/commands/build.d.ts +0 -1
- package/dist/cli/commands/cache.d.ts +1 -0
- package/dist/cli/commands/init.d.ts +6 -3
- package/dist/cli/commands/timeline.d.ts +0 -1
- package/dist/cli/commands/watch.d.ts +0 -1
- package/dist/cli/index.d.ts +0 -1
- package/dist/cli/index.js +3213 -5296
- package/dist/cli/types.d.ts +51 -20
- package/dist/cli/utils/config-loader.d.ts +0 -1
- package/dist/cli/utils/file-utils.d.ts +27 -3
- package/dist/cli/utils/logger.d.ts +0 -1
- package/dist/compiler/Chain.d.ts +215 -0
- package/dist/compiler/animations.d.ts +76 -0
- package/dist/compiler/atomic-optimizer.d.ts +47 -12
- package/dist/compiler/breakpoints.d.ts +46 -0
- package/dist/compiler/btt.d.ts +36 -60
- package/dist/compiler/cache-manager.d.ts +58 -4
- package/dist/compiler/commonProps.d.ts +0 -1
- package/dist/compiler/content-addressable-cache.d.ts +78 -0
- package/dist/compiler/helpers.d.ts +54 -0
- package/dist/compiler/index.d.ts +16 -9
- package/dist/compiler/index.js +4450 -4316
- package/dist/compiler/prefixer.d.ts +17 -1
- package/dist/compiler/shorthands.d.ts +28 -0
- package/dist/compiler/suggestions.d.ts +43 -0
- package/dist/compiler/theme-contract.d.ts +16 -27
- package/dist/compiler/token-resolver.d.ts +69 -0
- package/dist/compiler/tokens.d.ts +33 -8
- package/dist/core/auto-detector.d.ts +34 -0
- package/dist/core/common-utils.d.ts +97 -0
- package/dist/core/compiler.d.ts +63 -23
- package/dist/core/constants.d.ts +137 -36
- package/dist/core/smart-chain.d.ts +3 -0
- package/dist/core/types.d.ts +122 -15
- package/dist/core/utils.d.ts +134 -17
- package/dist/index.d.ts +52 -8
- package/dist/index.js +7090 -5578
- package/dist/plugins/vite.d.ts +7 -5
- package/dist/plugins/vite.js +2964 -25641
- package/dist/plugins/webpack.d.ts +24 -1
- package/dist/plugins/webpack.js +209 -72
- package/dist/runtime/Chain.d.ts +32 -0
- package/dist/runtime/auto-hooks.d.ts +11 -0
- package/dist/runtime/hmr.d.ts +22 -2
- package/dist/runtime/index.d.ts +3 -2
- package/dist/runtime/index.js +3649 -301
- package/dist/runtime/injector.d.ts +39 -71
- package/dist/runtime/react.d.ts +17 -12
- package/dist/runtime/svelte.d.ts +15 -0
- package/dist/runtime/types.d.ts +126 -4
- package/dist/runtime/utils.d.ts +0 -1
- package/dist/runtime/vue.d.ts +34 -14
- package/package.json +59 -66
- package/src/cli/commands/build.ts +133 -0
- package/src/cli/commands/cache.ts +371 -0
- package/src/cli/commands/init.ts +230 -0
- package/src/cli/commands/timeline.ts +435 -0
- package/src/cli/commands/watch.ts +211 -0
- package/src/cli/index.ts +226 -0
- package/src/cli/types.ts +100 -0
- package/src/cli/utils/config-loader.ts +174 -0
- package/src/cli/utils/file-utils.ts +139 -0
- package/src/cli/utils/logger.ts +74 -0
- package/src/compiler/Chain.ts +831 -0
- package/src/compiler/animations.ts +517 -0
- package/src/compiler/atomic-optimizer.ts +786 -0
- package/src/compiler/breakpoints.ts +347 -0
- package/src/compiler/btt.ts +1147 -0
- package/src/compiler/cache-manager.ts +446 -0
- package/src/compiler/commonProps.ts +18 -0
- package/src/compiler/content-addressable-cache.ts +478 -0
- package/src/compiler/helpers.ts +407 -0
- package/src/compiler/index.ts +72 -0
- package/src/compiler/prefixer.ts +724 -0
- package/src/compiler/shorthands.ts +558 -0
- package/src/compiler/suggestions.ts +436 -0
- package/src/compiler/theme-contract.ts +197 -0
- package/src/compiler/token-resolver.ts +241 -0
- package/src/compiler/tokens.ts +612 -0
- package/src/core/auto-detector.ts +187 -0
- package/src/core/common-utils.ts +423 -0
- package/src/core/compiler.ts +835 -0
- package/src/core/constants.ts +424 -0
- package/src/core/index.ts +107 -0
- package/src/core/smart-chain.ts +163 -0
- package/src/core/types.ts +257 -0
- package/src/core/utils.ts +598 -0
- package/src/index.ts +208 -0
- package/src/plugins/vite.d.ts +316 -0
- package/src/plugins/vite.ts +424 -0
- package/src/plugins/webpack.d.ts +289 -0
- package/src/plugins/webpack.ts +416 -0
- package/src/runtime/Chain.ts +242 -0
- package/src/runtime/auto-hooks.tsx +127 -0
- package/src/runtime/auto-vue.ts +72 -0
- package/src/runtime/hmr.ts +212 -0
- package/src/runtime/index.ts +82 -0
- package/src/runtime/injector.ts +273 -0
- package/src/runtime/react.tsx +269 -0
- package/src/runtime/svelte.ts +15 -0
- package/src/runtime/types.ts +256 -0
- package/src/runtime/utils.ts +128 -0
- package/src/runtime/vite-env.d.ts +120 -0
- package/src/runtime/vue.ts +231 -0
- package/tsconfig.build.json +41 -0
- package/tsconfig.json +25 -0
- package/tsconfig.runtimes.json +18 -0
- package/dist/cli/cli.cjs +0 -7
- package/dist/cli/commands/build.d.ts.map +0 -1
- package/dist/cli/commands/compile.d.ts +0 -3
- package/dist/cli/commands/compile.d.ts.map +0 -1
- package/dist/cli/commands/init.d.ts.map +0 -1
- package/dist/cli/commands/timeline.d.ts.map +0 -1
- package/dist/cli/commands/watch.d.ts.map +0 -1
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/types.d.ts.map +0 -1
- package/dist/cli/utils/config-loader.d.ts.map +0 -1
- package/dist/cli/utils/file-utils.d.ts.map +0 -1
- package/dist/cli/utils/logger.d.ts.map +0 -1
- package/dist/compiler/atomic-optimizer.d.ts.map +0 -1
- package/dist/compiler/btt.d.ts.map +0 -1
- package/dist/compiler/cache-manager.d.ts.map +0 -1
- package/dist/compiler/commonProps.d.ts.map +0 -1
- package/dist/compiler/index.d.ts.map +0 -1
- package/dist/compiler/prefixer.d.ts.map +0 -1
- package/dist/compiler/theme-contract.d.ts.map +0 -1
- package/dist/compiler/tokens.d.ts.map +0 -1
- package/dist/compiler/types.d.ts +0 -57
- package/dist/compiler/types.d.ts.map +0 -1
- package/dist/core/compiler.d.ts.map +0 -1
- package/dist/core/constants.d.ts.map +0 -1
- package/dist/core/index.d.ts +0 -4
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/types.d.ts.map +0 -1
- package/dist/core/utils.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/plugins/vite.d.ts.map +0 -1
- package/dist/plugins/webpack.d.ts.map +0 -1
- package/dist/runtime/hmr.d.ts.map +0 -1
- package/dist/runtime/index.d.ts.map +0 -1
- package/dist/runtime/injector.d.ts.map +0 -1
- package/dist/runtime/react.d.ts.map +0 -1
- package/dist/runtime/react.js +0 -270
- package/dist/runtime/types.d.ts.map +0 -1
- package/dist/runtime/utils.d.ts.map +0 -1
- package/dist/runtime/vue.d.ts.map +0 -1
- package/dist/runtime/vue.js +0 -232
|
@@ -0,0 +1,612 @@
|
|
|
1
|
+
// src/compiler/tokens.ts
|
|
2
|
+
// Types
|
|
3
|
+
export interface TokenColors {
|
|
4
|
+
[key: string]: string | Record<string, string>;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface TokenSpacing {
|
|
8
|
+
[key: string]: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface TokenTypography {
|
|
12
|
+
fontFamily: Record<string, string>;
|
|
13
|
+
fontSize: Record<string, string>;
|
|
14
|
+
fontWeight: Record<string, string>;
|
|
15
|
+
lineHeight: Record<string, string>;
|
|
16
|
+
letterSpacing?: Record<string, string>; // Add this optional property
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface TokenBreakpoints {
|
|
20
|
+
[key: string]: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface TokenZIndex {
|
|
24
|
+
[key: string]: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface TokenShadows {
|
|
28
|
+
[key: string]: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface TokenBorderRadius {
|
|
32
|
+
[key: string]: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface TokensStructure {
|
|
36
|
+
colors: TokenColors;
|
|
37
|
+
spacing: TokenSpacing;
|
|
38
|
+
typography: TokenTypography;
|
|
39
|
+
breakpoints: TokenBreakpoints;
|
|
40
|
+
zIndex: TokenZIndex;
|
|
41
|
+
shadows: TokenShadows;
|
|
42
|
+
borderRadius: TokenBorderRadius;
|
|
43
|
+
[key: string]: any;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface TokenValue {
|
|
47
|
+
value: any;
|
|
48
|
+
description?: string;
|
|
49
|
+
deprecated?: boolean;
|
|
50
|
+
aliases?: string[];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export type FlattenedTokens = Record<string, string>;
|
|
54
|
+
|
|
55
|
+
// Default tokens (kept as immutable constant)
|
|
56
|
+
export const defaultTokens: TokensStructure = {
|
|
57
|
+
colors: {
|
|
58
|
+
primary: '#667eea',
|
|
59
|
+
secondary: '#764ba2',
|
|
60
|
+
success: '#48bb78',
|
|
61
|
+
danger: '#f56565',
|
|
62
|
+
warning: '#ed8936',
|
|
63
|
+
info: '#4299e1',
|
|
64
|
+
light: '#f7fafc',
|
|
65
|
+
dark: '#1a202c',
|
|
66
|
+
white: '#ffffff',
|
|
67
|
+
black: '#000000',
|
|
68
|
+
gray: {
|
|
69
|
+
50: '#f9fafb',
|
|
70
|
+
100: '#f7fafc',
|
|
71
|
+
200: '#edf2f7',
|
|
72
|
+
300: '#e2e8f0',
|
|
73
|
+
400: '#cbd5e0',
|
|
74
|
+
500: '#a0aec0',
|
|
75
|
+
600: '#718096',
|
|
76
|
+
700: '#4a5568',
|
|
77
|
+
800: '#2d3748',
|
|
78
|
+
900: '#1a202c'
|
|
79
|
+
},
|
|
80
|
+
blue: {
|
|
81
|
+
50: '#eff6ff',
|
|
82
|
+
100: '#dbeafe',
|
|
83
|
+
200: '#bfdbfe',
|
|
84
|
+
300: '#93c5fd',
|
|
85
|
+
400: '#60a5fa',
|
|
86
|
+
500: '#3b82f6',
|
|
87
|
+
600: '#2563eb',
|
|
88
|
+
700: '#1d4ed8',
|
|
89
|
+
800: '#1e40af',
|
|
90
|
+
900: '#1e3a8a'
|
|
91
|
+
},
|
|
92
|
+
green: {
|
|
93
|
+
50: '#f0fdf4',
|
|
94
|
+
100: '#dcfce7',
|
|
95
|
+
200: '#bbf7d0',
|
|
96
|
+
300: '#86efac',
|
|
97
|
+
400: '#4ade80',
|
|
98
|
+
500: '#22c55e',
|
|
99
|
+
600: '#16a34a',
|
|
100
|
+
700: '#15803d',
|
|
101
|
+
800: '#166534',
|
|
102
|
+
900: '#14532d'
|
|
103
|
+
},
|
|
104
|
+
red: {
|
|
105
|
+
50: '#fef2f2',
|
|
106
|
+
100: '#fee2e2',
|
|
107
|
+
200: '#fecaca',
|
|
108
|
+
300: '#fca5a5',
|
|
109
|
+
400: '#f87171',
|
|
110
|
+
500: '#ef4444',
|
|
111
|
+
600: '#dc2626',
|
|
112
|
+
700: '#b91c1c',
|
|
113
|
+
800: '#991b1b',
|
|
114
|
+
900: '#7f1d1d'
|
|
115
|
+
},
|
|
116
|
+
yellow: {
|
|
117
|
+
50: '#fefce8',
|
|
118
|
+
100: '#fef9c3',
|
|
119
|
+
200: '#fef08a',
|
|
120
|
+
300: '#fde047',
|
|
121
|
+
400: '#facc15',
|
|
122
|
+
500: '#eab308',
|
|
123
|
+
600: '#ca8a04',
|
|
124
|
+
700: '#a16207',
|
|
125
|
+
800: '#854d0e',
|
|
126
|
+
900: '#713f12'
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
spacing: {
|
|
131
|
+
0: '0',
|
|
132
|
+
0.5: '0.125rem',
|
|
133
|
+
1: '0.25rem',
|
|
134
|
+
1.5: '0.375rem',
|
|
135
|
+
2: '0.5rem',
|
|
136
|
+
2.5: '0.625rem',
|
|
137
|
+
3: '0.75rem',
|
|
138
|
+
3.5: '0.875rem',
|
|
139
|
+
4: '1rem',
|
|
140
|
+
5: '1.25rem',
|
|
141
|
+
6: '1.5rem',
|
|
142
|
+
7: '1.75rem',
|
|
143
|
+
8: '2rem',
|
|
144
|
+
9: '2.25rem',
|
|
145
|
+
10: '2.5rem',
|
|
146
|
+
11: '2.75rem',
|
|
147
|
+
12: '3rem',
|
|
148
|
+
14: '3.5rem',
|
|
149
|
+
16: '4rem',
|
|
150
|
+
20: '5rem',
|
|
151
|
+
24: '6rem',
|
|
152
|
+
28: '7rem',
|
|
153
|
+
32: '8rem',
|
|
154
|
+
36: '9rem',
|
|
155
|
+
40: '10rem',
|
|
156
|
+
44: '11rem',
|
|
157
|
+
48: '12rem',
|
|
158
|
+
52: '13rem',
|
|
159
|
+
56: '14rem',
|
|
160
|
+
60: '15rem',
|
|
161
|
+
64: '16rem',
|
|
162
|
+
72: '18rem',
|
|
163
|
+
80: '20rem',
|
|
164
|
+
96: '24rem',
|
|
165
|
+
xs: '0.5rem',
|
|
166
|
+
sm: '1rem',
|
|
167
|
+
md: '1.5rem',
|
|
168
|
+
lg: '2rem',
|
|
169
|
+
xl: '3rem',
|
|
170
|
+
'2xl': '4rem',
|
|
171
|
+
'3xl': '6rem',
|
|
172
|
+
'4xl': '8rem',
|
|
173
|
+
'5xl': '10rem'
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
typography: {
|
|
177
|
+
fontFamily: {
|
|
178
|
+
sans: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
|
|
179
|
+
serif: 'Georgia, Cambria, "Times New Roman", Times, serif',
|
|
180
|
+
mono: 'SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
|
|
181
|
+
system: 'system-ui, -apple-system, sans-serif'
|
|
182
|
+
},
|
|
183
|
+
fontSize: {
|
|
184
|
+
xs: '0.75rem',
|
|
185
|
+
sm: '0.875rem',
|
|
186
|
+
base: '1rem',
|
|
187
|
+
lg: '1.125rem',
|
|
188
|
+
xl: '1.25rem',
|
|
189
|
+
'2xl': '1.5rem',
|
|
190
|
+
'3xl': '1.875rem',
|
|
191
|
+
'4xl': '2.25rem',
|
|
192
|
+
'5xl': '3rem',
|
|
193
|
+
'6xl': '3.75rem',
|
|
194
|
+
'7xl': '4.5rem',
|
|
195
|
+
'8xl': '6rem',
|
|
196
|
+
'9xl': '8rem'
|
|
197
|
+
},
|
|
198
|
+
fontWeight: {
|
|
199
|
+
hairline: '100',
|
|
200
|
+
thin: '200',
|
|
201
|
+
light: '300',
|
|
202
|
+
normal: '400',
|
|
203
|
+
medium: '500',
|
|
204
|
+
semibold: '600',
|
|
205
|
+
bold: '700',
|
|
206
|
+
extrabold: '800',
|
|
207
|
+
black: '900'
|
|
208
|
+
},
|
|
209
|
+
lineHeight: {
|
|
210
|
+
none: '1',
|
|
211
|
+
tight: '1.25',
|
|
212
|
+
snug: '1.375',
|
|
213
|
+
normal: '1.5',
|
|
214
|
+
relaxed: '1.625',
|
|
215
|
+
loose: '2',
|
|
216
|
+
3: '.75rem',
|
|
217
|
+
4: '1rem',
|
|
218
|
+
5: '1.25rem',
|
|
219
|
+
6: '1.5rem',
|
|
220
|
+
7: '1.75rem',
|
|
221
|
+
8: '2rem',
|
|
222
|
+
9: '2.25rem',
|
|
223
|
+
10: '2.5rem'
|
|
224
|
+
},
|
|
225
|
+
letterSpacing: {
|
|
226
|
+
tighter: '-0.05em',
|
|
227
|
+
tight: '-0.025em',
|
|
228
|
+
normal: '0',
|
|
229
|
+
wide: '0.025em',
|
|
230
|
+
wider: '0.05em',
|
|
231
|
+
widest: '0.1em'
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
|
|
235
|
+
breakpoints: {
|
|
236
|
+
sm: '640px',
|
|
237
|
+
md: '768px',
|
|
238
|
+
lg: '1024px',
|
|
239
|
+
xl: '1280px',
|
|
240
|
+
'2xl': '1536px',
|
|
241
|
+
'3xl': '1920px',
|
|
242
|
+
mobile: '640px',
|
|
243
|
+
tablet: '768px',
|
|
244
|
+
desktop: '1024px',
|
|
245
|
+
wide: '1280px'
|
|
246
|
+
},
|
|
247
|
+
|
|
248
|
+
zIndex: {
|
|
249
|
+
0: '0',
|
|
250
|
+
10: '10',
|
|
251
|
+
20: '20',
|
|
252
|
+
30: '30',
|
|
253
|
+
40: '40',
|
|
254
|
+
50: '50',
|
|
255
|
+
auto: 'auto',
|
|
256
|
+
dropdown: '1000',
|
|
257
|
+
sticky: '1020',
|
|
258
|
+
fixed: '1030',
|
|
259
|
+
modal: '1040',
|
|
260
|
+
popover: '1050',
|
|
261
|
+
tooltip: '1060',
|
|
262
|
+
toast: '1070',
|
|
263
|
+
overlay: '1080'
|
|
264
|
+
},
|
|
265
|
+
|
|
266
|
+
shadows: {
|
|
267
|
+
xs: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
|
|
268
|
+
sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
|
|
269
|
+
base: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
|
|
270
|
+
md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
|
|
271
|
+
lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
|
|
272
|
+
xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
|
|
273
|
+
'2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
|
|
274
|
+
inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)',
|
|
275
|
+
none: 'none',
|
|
276
|
+
'glow-sm': '0 0 10px rgba(102, 126, 234, 0.5)',
|
|
277
|
+
'glow-md': '0 0 20px rgba(102, 126, 234, 0.5)',
|
|
278
|
+
'glow-lg': '0 0 30px rgba(102, 126, 234, 0.5)'
|
|
279
|
+
},
|
|
280
|
+
|
|
281
|
+
borderRadius: {
|
|
282
|
+
none: '0',
|
|
283
|
+
sm: '0.125rem',
|
|
284
|
+
base: '0.25rem',
|
|
285
|
+
md: '0.375rem',
|
|
286
|
+
lg: '0.5rem',
|
|
287
|
+
xl: '0.75rem',
|
|
288
|
+
'2xl': '1rem',
|
|
289
|
+
'3xl': '1.5rem',
|
|
290
|
+
'4xl': '2rem',
|
|
291
|
+
full: '9999px'
|
|
292
|
+
},
|
|
293
|
+
|
|
294
|
+
// Additional animation presets
|
|
295
|
+
animations: {
|
|
296
|
+
fade: {
|
|
297
|
+
'0%': { opacity: 0 },
|
|
298
|
+
'100%': { opacity: 1 }
|
|
299
|
+
},
|
|
300
|
+
slideUp: {
|
|
301
|
+
'0%': { transform: 'translateY(20px)', opacity: 0 },
|
|
302
|
+
'100%': { transform: 'translateY(0)', opacity: 1 }
|
|
303
|
+
},
|
|
304
|
+
slideDown: {
|
|
305
|
+
'0%': { transform: 'translateY(-20px)', opacity: 0 },
|
|
306
|
+
'100%': { transform: 'translateY(0)', opacity: 1 }
|
|
307
|
+
},
|
|
308
|
+
slideLeft: {
|
|
309
|
+
'0%': { transform: 'translateX(20px)', opacity: 0 },
|
|
310
|
+
'100%': { transform: 'translateX(0)', opacity: 1 }
|
|
311
|
+
},
|
|
312
|
+
slideRight: {
|
|
313
|
+
'0%': { transform: 'translateX(-20px)', opacity: 0 },
|
|
314
|
+
'100%': { transform: 'translateX(0)', opacity: 1 }
|
|
315
|
+
},
|
|
316
|
+
scale: {
|
|
317
|
+
'0%': { transform: 'scale(0.95)', opacity: 0 },
|
|
318
|
+
'100%': { transform: 'scale(1)', opacity: 1 }
|
|
319
|
+
},
|
|
320
|
+
bounce: {
|
|
321
|
+
'0%, 100%': { transform: 'translateY(0)' },
|
|
322
|
+
'50%': { transform: 'translateY(-25%)' }
|
|
323
|
+
},
|
|
324
|
+
pulse: {
|
|
325
|
+
'0%, 100%': { opacity: 1 },
|
|
326
|
+
'50%': { opacity: 0.5 }
|
|
327
|
+
},
|
|
328
|
+
spin: {
|
|
329
|
+
'0%': { transform: 'rotate(0deg)' },
|
|
330
|
+
'100%': { transform: 'rotate(360deg)' }
|
|
331
|
+
},
|
|
332
|
+
shimmer: {
|
|
333
|
+
'0%': { backgroundPosition: '-200% 0' },
|
|
334
|
+
'100%': { backgroundPosition: '200% 0' }
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
export class DesignTokens {
|
|
340
|
+
private customTokens: TokensStructure;
|
|
341
|
+
private customFlattened: FlattenedTokens;
|
|
342
|
+
private defaultFlattened: FlattenedTokens;
|
|
343
|
+
private tokenCache: Map<string, string> = new Map();
|
|
344
|
+
|
|
345
|
+
constructor(customTokens: Partial<TokensStructure> = {}) {
|
|
346
|
+
// Deep clone custom tokens to prevent mutation
|
|
347
|
+
this.customTokens = this.deepClone(customTokens) as TokensStructure;
|
|
348
|
+
|
|
349
|
+
// Flatten both token sets
|
|
350
|
+
this.customFlattened = this.flattenTokens(this.customTokens);
|
|
351
|
+
this.defaultFlattened = this.flattenTokens(defaultTokens);
|
|
352
|
+
|
|
353
|
+
// Freeze to prevent modifications
|
|
354
|
+
Object.freeze(this.customTokens);
|
|
355
|
+
Object.freeze(this.customFlattened);
|
|
356
|
+
Object.freeze(this.defaultFlattened);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Deep clone objects
|
|
360
|
+
private deepClone<T>(obj: T): T {
|
|
361
|
+
if (obj === null || typeof obj !== 'object') return obj;
|
|
362
|
+
if (Array.isArray(obj)) return obj.map(item => this.deepClone(item)) as any;
|
|
363
|
+
|
|
364
|
+
const cloned: any = {};
|
|
365
|
+
for (const key in obj) {
|
|
366
|
+
if (obj.hasOwnProperty(key)) {
|
|
367
|
+
cloned[key] = this.deepClone(obj[key]);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
return cloned;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Deep freeze to prevent accidental modifications
|
|
374
|
+
private deepFreeze<T extends object>(obj: T): T {
|
|
375
|
+
Object.keys(obj).forEach(key => {
|
|
376
|
+
const value = (obj as any)[key];
|
|
377
|
+
if (typeof value === 'object' && value !== null && !Object.isFrozen(value)) {
|
|
378
|
+
this.deepFreeze(value);
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
return Object.freeze(obj);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Flatten nested tokens for easy access
|
|
385
|
+
flattenTokens(obj: Record<string, any>, prefix: string = ''): FlattenedTokens {
|
|
386
|
+
const result: FlattenedTokens = {};
|
|
387
|
+
|
|
388
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
389
|
+
const prefixed = prefix ? `${prefix}.${key}` : key;
|
|
390
|
+
|
|
391
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
392
|
+
// Recursively flatten nested objects
|
|
393
|
+
Object.assign(result, this.flattenTokens(value, prefixed));
|
|
394
|
+
} else {
|
|
395
|
+
result[prefixed] = String(value);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
return result;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Get token value by path (e.g., 'colors.primary')
|
|
403
|
+
// Checks custom tokens first, then falls back to default tokens
|
|
404
|
+
get(path: string, defaultValue: string = ''): string {
|
|
405
|
+
// Check cache first
|
|
406
|
+
if (this.tokenCache.has(path)) {
|
|
407
|
+
return this.tokenCache.get(path)!;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
let value: string | undefined;
|
|
411
|
+
|
|
412
|
+
// First try custom tokens
|
|
413
|
+
if (path in this.customFlattened) {
|
|
414
|
+
value = this.customFlattened[path];
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Then try default tokens
|
|
418
|
+
if (value === undefined && path in this.defaultFlattened) {
|
|
419
|
+
value = this.defaultFlattened[path];
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// Handle token references (e.g., "$colors.primary")
|
|
423
|
+
if (value && value.startsWith('$')) {
|
|
424
|
+
const refPath = value.substring(1);
|
|
425
|
+
value = this.get(refPath, defaultValue);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
const result = value !== undefined ? value : defaultValue;
|
|
429
|
+
|
|
430
|
+
// Cache the result
|
|
431
|
+
this.tokenCache.set(path, result);
|
|
432
|
+
|
|
433
|
+
return result;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// Get token with type safety
|
|
437
|
+
getColor(path: string, defaultValue: string = '#000000'): string {
|
|
438
|
+
return this.get(`colors.${path}`, defaultValue);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
getSpacing(path: string, defaultValue: string = '0'): string {
|
|
442
|
+
return this.get(`spacing.${path}`, defaultValue);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
getFontSize(path: string, defaultValue: string = '1rem'): string {
|
|
446
|
+
return this.get(`typography.fontSize.${path}`, defaultValue);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
getFontWeight(path: string, defaultValue: string = '400'): string {
|
|
450
|
+
return this.get(`typography.fontWeight.${path}`, defaultValue);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
getLineHeight(path: string, defaultValue: string = '1.5'): string {
|
|
454
|
+
return this.get(`typography.lineHeight.${path}`, defaultValue);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
getBreakpoint(path: string, defaultValue: string = '768px'): string {
|
|
458
|
+
return this.get(`breakpoints.${path}`, defaultValue);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
getZIndex(path: string, defaultValue: string = '0'): string {
|
|
462
|
+
return this.get(`zIndex.${path}`, defaultValue);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
getShadow(path: string, defaultValue: string = 'none'): string {
|
|
466
|
+
return this.get(`shadows.${path}`, defaultValue);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
getBorderRadius(path: string, defaultValue: string = '0'): string {
|
|
470
|
+
return this.get(`borderRadius.${path}`, defaultValue);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// Get all custom tokens (as flattened object)
|
|
474
|
+
getCustomTokens(): FlattenedTokens {
|
|
475
|
+
return { ...this.customFlattened };
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Get all default tokens (as flattened object)
|
|
479
|
+
getDefaultTokens(): FlattenedTokens {
|
|
480
|
+
return { ...this.defaultFlattened };
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// Check if a token exists (in either custom or default)
|
|
484
|
+
has(path: string): boolean {
|
|
485
|
+
return path in this.customFlattened || path in this.defaultFlattened;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// Generate CSS variables from tokens (combines both custom and default)
|
|
489
|
+
toCSSVariables(prefix: string = 'chain'): string {
|
|
490
|
+
let css = ':root {\n';
|
|
491
|
+
|
|
492
|
+
// Combine both token sets (custom overrides default)
|
|
493
|
+
const allTokens = { ...this.defaultFlattened, ...this.customFlattened };
|
|
494
|
+
|
|
495
|
+
for (const [key, value] of Object.entries(allTokens)) {
|
|
496
|
+
const varName = `--${prefix}-${key.replace(/\./g, '-')}`;
|
|
497
|
+
css += ` ${varName}: ${value};\n`;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
css += '}\n';
|
|
501
|
+
return css;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// Generate media queries from breakpoints
|
|
505
|
+
toMediaQueries(): Record<string, string> {
|
|
506
|
+
const queries: Record<string, string> = {};
|
|
507
|
+
|
|
508
|
+
for (const [name, value] of Object.entries(this.customFlattened)) {
|
|
509
|
+
if (name.startsWith('breakpoints.')) {
|
|
510
|
+
const breakpointName = name.replace('breakpoints.', '');
|
|
511
|
+
queries[breakpointName] = value;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
return queries;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// Create a theme variant (overrides on top of defaults + custom)
|
|
519
|
+
createTheme(name: string, overrides: Record<string, string>): DesignTokens {
|
|
520
|
+
// Start with current custom tokens, then apply overrides
|
|
521
|
+
const newCustomTokens = this.deepClone(this.customTokens);
|
|
522
|
+
|
|
523
|
+
// Apply overrides to nested structure
|
|
524
|
+
for (const [path, value] of Object.entries(overrides)) {
|
|
525
|
+
const parts = path.split('.');
|
|
526
|
+
let current: any = newCustomTokens;
|
|
527
|
+
|
|
528
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
529
|
+
if (!current[parts[i]]) {
|
|
530
|
+
current[parts[i]] = {};
|
|
531
|
+
}
|
|
532
|
+
current = current[parts[i]];
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
current[parts[parts.length - 1]] = value;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
return new DesignTokens(newCustomTokens);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// Merge with another token set
|
|
542
|
+
merge(tokens: Partial<TokensStructure>): DesignTokens {
|
|
543
|
+
const merged = this.deepClone(this.customTokens);
|
|
544
|
+
|
|
545
|
+
const deepMerge = (target: any, source: any) => {
|
|
546
|
+
for (const key in source) {
|
|
547
|
+
if (source.hasOwnProperty(key)) {
|
|
548
|
+
if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
|
|
549
|
+
if (!target[key]) target[key] = {};
|
|
550
|
+
deepMerge(target[key], source[key]);
|
|
551
|
+
} else {
|
|
552
|
+
target[key] = source[key];
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
|
|
558
|
+
deepMerge(merged, tokens);
|
|
559
|
+
return new DesignTokens(merged);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// Clear cache
|
|
563
|
+
clearCache(): void {
|
|
564
|
+
this.tokenCache.clear();
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
// Get token path suggestions for autocomplete
|
|
568
|
+
getSuggestions(partialPath: string): string[] {
|
|
569
|
+
const allTokens = { ...this.defaultFlattened, ...this.customFlattened };
|
|
570
|
+
const suggestions: string[] = [];
|
|
571
|
+
|
|
572
|
+
for (const key of Object.keys(allTokens)) {
|
|
573
|
+
if (key.includes(partialPath)) {
|
|
574
|
+
suggestions.push(key);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
return suggestions.sort();
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// Singleton instance with default tokens
|
|
583
|
+
export const tokens = new DesignTokens(defaultTokens);
|
|
584
|
+
|
|
585
|
+
// Token utility functions
|
|
586
|
+
export function createTokens(customTokens: Partial<TokensStructure>): DesignTokens {
|
|
587
|
+
return new DesignTokens(customTokens);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// Helper to resolve token references in strings
|
|
591
|
+
export function resolveTokenReferences(
|
|
592
|
+
value: string,
|
|
593
|
+
tokens: DesignTokens,
|
|
594
|
+
prefix: string = '$'
|
|
595
|
+
): string {
|
|
596
|
+
if (typeof value !== 'string') return String(value);
|
|
597
|
+
|
|
598
|
+
const tokenRegex = new RegExp(`${prefix}([a-zA-Z0-9.-]+)`, 'g');
|
|
599
|
+
|
|
600
|
+
return value.replace(tokenRegex, (match, tokenPath) => {
|
|
601
|
+
const resolved = tokens.get(tokenPath);
|
|
602
|
+
return resolved !== undefined ? resolved : match;
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
// Type guard to check if value is a token reference
|
|
607
|
+
export function isTokenReference(value: any, prefix: string = '$'): boolean {
|
|
608
|
+
return typeof value === 'string' && value.startsWith(prefix);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// ESM Export
|
|
612
|
+
export { DesignTokens as default };
|