chaincss 2.0.7 → 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 +455 -226
- 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 +3648 -301
- package/dist/runtime/injector.d.ts +39 -72
- 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 -324
- 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 -286
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
// src/compiler/helpers.ts
|
|
2
|
+
// Types
|
|
3
|
+
export type Unit = 'px' | 'rem' | 'em' | '%' | 'vw' | 'vh' | 'vmin' | 'vmax' | 'ch' | 'ex';
|
|
4
|
+
export type MathOperation = 'add' | 'subtract' | 'multiply' | 'divide';
|
|
5
|
+
|
|
6
|
+
export interface CalcOptions {
|
|
7
|
+
precision?: number;
|
|
8
|
+
simplify?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Utility to parse and normalize values
|
|
12
|
+
function normalizeValue(value: any): string {
|
|
13
|
+
if (value === null || value === undefined) return '0';
|
|
14
|
+
if (typeof value === 'number') return `${value}px`;
|
|
15
|
+
return String(value);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Perform calculation with proper unit handling
|
|
19
|
+
function performCalculation(
|
|
20
|
+
a: any,
|
|
21
|
+
b: any,
|
|
22
|
+
operation: MathOperation,
|
|
23
|
+
options: CalcOptions = {}
|
|
24
|
+
): string {
|
|
25
|
+
const valA = normalizeValue(a);
|
|
26
|
+
const valB = normalizeValue(b);
|
|
27
|
+
|
|
28
|
+
let result: string;
|
|
29
|
+
|
|
30
|
+
switch (operation) {
|
|
31
|
+
case 'add':
|
|
32
|
+
result = `calc(${valA} + ${valB})`;
|
|
33
|
+
break;
|
|
34
|
+
case 'subtract':
|
|
35
|
+
result = `calc(${valA} - ${valB})`;
|
|
36
|
+
break;
|
|
37
|
+
case 'multiply':
|
|
38
|
+
result = `calc(${valA} * ${valB})`;
|
|
39
|
+
break;
|
|
40
|
+
case 'divide':
|
|
41
|
+
result = `calc(${valA} / ${valB})`;
|
|
42
|
+
break;
|
|
43
|
+
default:
|
|
44
|
+
result = `calc(${valA} ${operation} ${valB})`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (options.simplify) {
|
|
48
|
+
result = simplifyCalc(result);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Simplify calc expressions when possible
|
|
55
|
+
function simplifyCalc(calcExpr: string): string {
|
|
56
|
+
// Remove unnecessary calc wrappers
|
|
57
|
+
if (calcExpr.startsWith('calc(') && calcExpr.endsWith(')')) {
|
|
58
|
+
const inner = calcExpr.slice(5, -1);
|
|
59
|
+
// If the inner doesn't contain operations, unwrap it
|
|
60
|
+
if (!inner.includes('+') && !inner.includes('-') && !inner.includes('*') && !inner.includes('/')) {
|
|
61
|
+
return inner.trim();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return calcExpr;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Create a calc expression with proper formatting
|
|
68
|
+
function createCalc(expr: string, options: CalcOptions = {}): string {
|
|
69
|
+
let result = `calc(${expr})`;
|
|
70
|
+
if (options.simplify) {
|
|
71
|
+
result = simplifyCalc(result);
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Math helpers for CSS calc() expressions
|
|
77
|
+
export const helpers = {
|
|
78
|
+
// Basic calc
|
|
79
|
+
calc: (expr: string, options?: CalcOptions) => createCalc(expr, options),
|
|
80
|
+
|
|
81
|
+
// Arithmetic operations
|
|
82
|
+
add: (a: any, b: any, options?: CalcOptions) =>
|
|
83
|
+
performCalculation(a, b, 'add', options),
|
|
84
|
+
subtract: (a: any, b: any, options?: CalcOptions) =>
|
|
85
|
+
performCalculation(a, b, 'subtract', options),
|
|
86
|
+
sub: (a: any, b: any, options?: CalcOptions) =>
|
|
87
|
+
performCalculation(a, b, 'subtract', options),
|
|
88
|
+
multiply: (a: any, b: any, options?: CalcOptions) =>
|
|
89
|
+
performCalculation(a, b, 'multiply', options),
|
|
90
|
+
mul: (a: any, b: any, options?: CalcOptions) =>
|
|
91
|
+
performCalculation(a, b, 'multiply', options),
|
|
92
|
+
divide: (a: any, b: any, options?: CalcOptions) =>
|
|
93
|
+
performCalculation(a, b, 'divide', options),
|
|
94
|
+
div: (a: any, b: any, options?: CalcOptions) =>
|
|
95
|
+
performCalculation(a, b, 'divide', options),
|
|
96
|
+
|
|
97
|
+
// Complex operations
|
|
98
|
+
sum: (...values: any[]) => {
|
|
99
|
+
const expr = values.map(v => normalizeValue(v)).join(' + ');
|
|
100
|
+
return createCalc(expr);
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
difference: (a: any, ...rest: any[]) => {
|
|
104
|
+
const expr = [a, ...rest].map(v => normalizeValue(v)).join(' - ');
|
|
105
|
+
return createCalc(expr);
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
product: (...values: any[]) => {
|
|
109
|
+
const expr = values.map(v => normalizeValue(v)).join(' * ');
|
|
110
|
+
return createCalc(expr);
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
quotient: (a: any, ...rest: any[]) => {
|
|
114
|
+
const expr = [a, ...rest].map(v => normalizeValue(v)).join(' / ');
|
|
115
|
+
return createCalc(expr);
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
// Unit helpers with conversion
|
|
119
|
+
mpx: (value: number | string): string => {
|
|
120
|
+
if (typeof value === 'number') return `${value}px`;
|
|
121
|
+
// If it's already a string with a unit, just return it
|
|
122
|
+
if (/^\d+(?:\.\d+)?(?:px|rem|em|%|vw|vh)$/.test(value)) return value;
|
|
123
|
+
// If it's a number string, add px
|
|
124
|
+
if (/^\d+(?:\.\d+)?$/.test(value)) return `${value}px`;
|
|
125
|
+
return value;
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
rem: (value: number | string, base: number = 16): string => {
|
|
129
|
+
if (typeof value === 'number') return `${value}rem`;
|
|
130
|
+
if (/^\d+(?:\.\d+)?rem$/.test(value)) return value;
|
|
131
|
+
if (/^\d+(?:\.\d+)?px$/.test(value)) {
|
|
132
|
+
const px = parseFloat(value);
|
|
133
|
+
return `${px / base}rem`;
|
|
134
|
+
}
|
|
135
|
+
if (/^\d+(?:\.\d+)?$/.test(value)) return `${value}rem`;
|
|
136
|
+
return value;
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
em: (value: number | string, context: number = 16): string => {
|
|
140
|
+
if (typeof value === 'number') return `${value}em`;
|
|
141
|
+
if (/^\d+(?:\.\d+)?em$/.test(value)) return value;
|
|
142
|
+
if (/^\d+(?:\.\d+)?px$/.test(value)) {
|
|
143
|
+
const px = parseFloat(value);
|
|
144
|
+
return `${px / context}em`;
|
|
145
|
+
}
|
|
146
|
+
if (/^\d+(?:\.\d+)?$/.test(value)) return `${value}em`;
|
|
147
|
+
return value;
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
percent: (value: number | string): string => {
|
|
151
|
+
if (typeof value === 'number') return `${value}%`;
|
|
152
|
+
if (/^\d+(?:\.\d+)?%$/.test(value)) return value;
|
|
153
|
+
if (/^\d+(?:\.\d+)?$/.test(value)) return `${value}%`;
|
|
154
|
+
return value;
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
vw: (value: number | string): string => {
|
|
158
|
+
if (typeof value === 'number') return `${value}vw`;
|
|
159
|
+
if (/^\d+(?:\.\d+)?vw$/.test(value)) return value;
|
|
160
|
+
if (/^\d+(?:\.\d+)?$/.test(value)) return `${value}vw`;
|
|
161
|
+
return value;
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
vh: (value: number | string): string => {
|
|
165
|
+
if (typeof value === 'number') return `${value}vh`;
|
|
166
|
+
if (/^\d+(?:\.\d+)?vh$/.test(value)) return value;
|
|
167
|
+
if (/^\d+(?:\.\d+)?$/.test(value)) return `${value}vh`;
|
|
168
|
+
return value;
|
|
169
|
+
},
|
|
170
|
+
|
|
171
|
+
vmin: (value: number | string): string => {
|
|
172
|
+
if (typeof value === 'number') return `${value}vmin`;
|
|
173
|
+
if (/^\d+(?:\.\d+)?vmin$/.test(value)) return value;
|
|
174
|
+
if (/^\d+(?:\.\d+)?$/.test(value)) return `${value}vmin`;
|
|
175
|
+
return value;
|
|
176
|
+
},
|
|
177
|
+
|
|
178
|
+
vmax: (value: number | string): string => {
|
|
179
|
+
if (typeof value === 'number') return `${value}vmax`;
|
|
180
|
+
if (/^\d+(?:\.\d+)?vmax$/.test(value)) return value;
|
|
181
|
+
if (/^\d+(?:\.\d+)?$/.test(value)) return `${value}vmax`;
|
|
182
|
+
return value;
|
|
183
|
+
},
|
|
184
|
+
|
|
185
|
+
ch: (value: number | string): string => {
|
|
186
|
+
if (typeof value === 'number') return `${value}ch`;
|
|
187
|
+
if (/^\d+(?:\.\d+)?ch$/.test(value)) return value;
|
|
188
|
+
if (/^\d+(?:\.\d+)?$/.test(value)) return `${value}ch`;
|
|
189
|
+
return value;
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
ex: (value: number | string): string => {
|
|
193
|
+
if (typeof value === 'number') return `${value}ex`;
|
|
194
|
+
if (/^\d+(?:\.\d+)?ex$/.test(value)) return value;
|
|
195
|
+
if (/^\d+(?:\.\d+)?$/.test(value)) return `${value}ex`;
|
|
196
|
+
return value;
|
|
197
|
+
},
|
|
198
|
+
|
|
199
|
+
// Convert between units
|
|
200
|
+
convert: (value: string | number, fromUnit: Unit, toUnit: Unit, context: number = 16): string => {
|
|
201
|
+
let numericValue: number;
|
|
202
|
+
|
|
203
|
+
if (typeof value === 'number') {
|
|
204
|
+
numericValue = value;
|
|
205
|
+
} else {
|
|
206
|
+
numericValue = parseFloat(value);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Convert to pixels first (base unit)
|
|
210
|
+
let inPx: number;
|
|
211
|
+
switch (fromUnit) {
|
|
212
|
+
case 'px':
|
|
213
|
+
inPx = numericValue;
|
|
214
|
+
break;
|
|
215
|
+
case 'rem':
|
|
216
|
+
inPx = numericValue * context;
|
|
217
|
+
break;
|
|
218
|
+
case 'em':
|
|
219
|
+
inPx = numericValue * context;
|
|
220
|
+
break;
|
|
221
|
+
case '%':
|
|
222
|
+
inPx = (numericValue / 100) * context;
|
|
223
|
+
break;
|
|
224
|
+
case 'vw':
|
|
225
|
+
inPx = (numericValue / 100) * 1920; // Assume 1920px viewport
|
|
226
|
+
break;
|
|
227
|
+
case 'vh':
|
|
228
|
+
inPx = (numericValue / 100) * 1080; // Assume 1080px viewport
|
|
229
|
+
break;
|
|
230
|
+
default:
|
|
231
|
+
inPx = numericValue;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Convert from pixels to target unit
|
|
235
|
+
let result: number;
|
|
236
|
+
switch (toUnit) {
|
|
237
|
+
case 'px':
|
|
238
|
+
result = inPx;
|
|
239
|
+
break;
|
|
240
|
+
case 'rem':
|
|
241
|
+
result = inPx / context;
|
|
242
|
+
break;
|
|
243
|
+
case 'em':
|
|
244
|
+
result = inPx / context;
|
|
245
|
+
break;
|
|
246
|
+
case '%':
|
|
247
|
+
result = (inPx / context) * 100;
|
|
248
|
+
break;
|
|
249
|
+
case 'vw':
|
|
250
|
+
result = (inPx / 1920) * 100;
|
|
251
|
+
break;
|
|
252
|
+
case 'vh':
|
|
253
|
+
result = (inPx / 1080) * 100;
|
|
254
|
+
break;
|
|
255
|
+
default:
|
|
256
|
+
result = inPx;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Format result
|
|
260
|
+
if (Math.abs(result - Math.round(result)) < 0.01) {
|
|
261
|
+
return `${Math.round(result)}${toUnit}`;
|
|
262
|
+
}
|
|
263
|
+
return `${result.toFixed(2)}${toUnit}`;
|
|
264
|
+
},
|
|
265
|
+
|
|
266
|
+
// Min/Max/Clamp with better formatting
|
|
267
|
+
min: (...values: any[]) => {
|
|
268
|
+
const formatted = values.map(v => normalizeValue(v)).join(', ');
|
|
269
|
+
return `min(${formatted})`;
|
|
270
|
+
},
|
|
271
|
+
|
|
272
|
+
max: (...values: any[]) => {
|
|
273
|
+
const formatted = values.map(v => normalizeValue(v)).join(', ');
|
|
274
|
+
return `max(${formatted})`;
|
|
275
|
+
},
|
|
276
|
+
|
|
277
|
+
clamp: (min: any, preferred: any, max: any, options?: CalcOptions) => {
|
|
278
|
+
const minVal = normalizeValue(min);
|
|
279
|
+
const prefVal = normalizeValue(preferred);
|
|
280
|
+
const maxVal = normalizeValue(max);
|
|
281
|
+
let result = `clamp(${minVal}, ${prefVal}, ${maxVal})`;
|
|
282
|
+
if (options?.simplify) {
|
|
283
|
+
result = simplifyCalc(result);
|
|
284
|
+
}
|
|
285
|
+
return result;
|
|
286
|
+
},
|
|
287
|
+
|
|
288
|
+
// Rounding helpers
|
|
289
|
+
round: (value: number | string, precision: number = 2): string => {
|
|
290
|
+
const num = typeof value === 'number' ? value : parseFloat(value);
|
|
291
|
+
return num.toFixed(precision);
|
|
292
|
+
},
|
|
293
|
+
|
|
294
|
+
ceil: (value: number | string): string => {
|
|
295
|
+
const num = typeof value === 'number' ? value : parseFloat(value);
|
|
296
|
+
return Math.ceil(num).toString();
|
|
297
|
+
},
|
|
298
|
+
|
|
299
|
+
floor: (value: number | string): string => {
|
|
300
|
+
const num = typeof value === 'number' ? value : parseFloat(value);
|
|
301
|
+
return Math.floor(num).toString();
|
|
302
|
+
},
|
|
303
|
+
|
|
304
|
+
// Color helpers (returns CSS color values)
|
|
305
|
+
rgba: (r: number, g: number, b: number, a: number = 1): string => {
|
|
306
|
+
return `rgba(${r}, ${g}, ${b}, ${a})`;
|
|
307
|
+
},
|
|
308
|
+
|
|
309
|
+
hsla: (h: number, s: number, l: number, a: number = 1): string => {
|
|
310
|
+
return `hsla(${h}, ${s}%, ${l}%, ${a})`;
|
|
311
|
+
},
|
|
312
|
+
|
|
313
|
+
// String helpers
|
|
314
|
+
url: (path: string): string => {
|
|
315
|
+
return `url(${path})`;
|
|
316
|
+
},
|
|
317
|
+
|
|
318
|
+
format: (strings: TemplateStringsArray, ...values: any[]): string => {
|
|
319
|
+
let result = '';
|
|
320
|
+
for (let i = 0; i < strings.length; i++) {
|
|
321
|
+
result += strings[i];
|
|
322
|
+
if (i < values.length) {
|
|
323
|
+
result += normalizeValue(values[i]);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return result;
|
|
327
|
+
},
|
|
328
|
+
|
|
329
|
+
// Conditional helpers
|
|
330
|
+
if: (condition: boolean, trueValue: any, falseValue: any): any => {
|
|
331
|
+
return condition ? trueValue : falseValue;
|
|
332
|
+
},
|
|
333
|
+
|
|
334
|
+
// String manipulation
|
|
335
|
+
camelToKebab: (str: string): string => {
|
|
336
|
+
return str.replace(/([A-Z])/g, '-$1').toLowerCase();
|
|
337
|
+
},
|
|
338
|
+
|
|
339
|
+
kebabToCamel: (str: string): string => {
|
|
340
|
+
return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
341
|
+
},
|
|
342
|
+
|
|
343
|
+
toPx: (value: number | string): string => {
|
|
344
|
+
if (typeof value === 'number') return `${value}px`;
|
|
345
|
+
if (/^\d+(?:\.\d+)?$/.test(value)) return `${value}px`;
|
|
346
|
+
return value;
|
|
347
|
+
},
|
|
348
|
+
|
|
349
|
+
toRem: (value: number | string, base: number = 16): string => {
|
|
350
|
+
if (typeof value === 'number') return `${value / base}rem`;
|
|
351
|
+
if (/^\d+(?:\.\d+)?px$/.test(value)) {
|
|
352
|
+
const px = parseFloat(value);
|
|
353
|
+
return `${px / base}rem`;
|
|
354
|
+
}
|
|
355
|
+
if (/^\d+(?:\.\d+)?$/.test(value)) {
|
|
356
|
+
const numValue = typeof value === 'string' ? parseFloat(value) : value;
|
|
357
|
+
return `${numValue / base}rem`;
|
|
358
|
+
}
|
|
359
|
+
return value;
|
|
360
|
+
},
|
|
361
|
+
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
// Type for math helper functions
|
|
365
|
+
export type MathHelpers = typeof helpers;
|
|
366
|
+
|
|
367
|
+
// Helper function to create a value with unit
|
|
368
|
+
export function withUnit(value: number | string, unit: Unit): string {
|
|
369
|
+
if (typeof value === 'string' && /^\d+(?:\.\d+)?[a-z%]+$/.test(value)) {
|
|
370
|
+
return value; // Already has a unit
|
|
371
|
+
}
|
|
372
|
+
const num = typeof value === 'number' ? value : parseFloat(value);
|
|
373
|
+
return `${num}${unit}`;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Helper to extract numeric value from a CSS value
|
|
377
|
+
export function extractNumeric(value: string): number {
|
|
378
|
+
const match = value.match(/^(\d+(?:\.\d+)?)/);
|
|
379
|
+
return match ? parseFloat(match[1]) : 0;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Helper to extract unit from a CSS value
|
|
383
|
+
export function extractUnit(value: string): Unit | null {
|
|
384
|
+
const match = value.match(/[a-z%]+$/);
|
|
385
|
+
return match ? (match[0] as Unit) : null;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// Create a fluid typography formula
|
|
389
|
+
export function fluidType(
|
|
390
|
+
minSize: number,
|
|
391
|
+
maxSize: number,
|
|
392
|
+
minWidth: number = 320,
|
|
393
|
+
maxWidth: number = 1280,
|
|
394
|
+
unit: 'px' | 'rem' = 'px'
|
|
395
|
+
): string {
|
|
396
|
+
const slope = (maxSize - minSize) / (maxWidth - minWidth);
|
|
397
|
+
const intercept = minSize - slope * minWidth;
|
|
398
|
+
|
|
399
|
+
const slopeVw = slope * 100;
|
|
400
|
+
const result = `clamp(${minSize}${unit}, ${slopeVw.toFixed(2)}vw + ${intercept.toFixed(2)}${unit}, ${maxSize}${unit})`;
|
|
401
|
+
|
|
402
|
+
return result;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Export default helpers
|
|
406
|
+
export default helpers;export const toPx = (v: number | string) => typeof v === "number" ? `${v}px` : v;
|
|
407
|
+
export const toRem = (v: number | string) => typeof v === "number" ? `${v/16}rem` : v;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// src/compiler/index.ts
|
|
2
|
+
|
|
3
|
+
// Export all compiler modules
|
|
4
|
+
export {
|
|
5
|
+
chain,
|
|
6
|
+
chains,
|
|
7
|
+
run,
|
|
8
|
+
compile,
|
|
9
|
+
createTokens,
|
|
10
|
+
configureAtomic,
|
|
11
|
+
setAtomicOptimizer,
|
|
12
|
+
recipe,
|
|
13
|
+
tokens,
|
|
14
|
+
enableDebug,
|
|
15
|
+
setBreakpoints,
|
|
16
|
+
enableTimeline,
|
|
17
|
+
getStyleHistory,
|
|
18
|
+
getStyleChanges,
|
|
19
|
+
getStyleDiff,
|
|
20
|
+
exportTimeline,
|
|
21
|
+
clearTimeline,
|
|
22
|
+
setSourceComments
|
|
23
|
+
} from './btt.js';
|
|
24
|
+
|
|
25
|
+
// Export atomic optimizer
|
|
26
|
+
export { AtomicOptimizer } from './atomic-optimizer.js';
|
|
27
|
+
export type {
|
|
28
|
+
AtomicClass,
|
|
29
|
+
AtomicOptimizerOptions,
|
|
30
|
+
AtomicOptimizerStats,
|
|
31
|
+
ComponentClassMapEntry,
|
|
32
|
+
OptimizeResult
|
|
33
|
+
} from './atomic-optimizer.js';
|
|
34
|
+
|
|
35
|
+
// Export prefixer
|
|
36
|
+
export { ChainCSSPrefixer } from './prefixer.js';
|
|
37
|
+
export type { PrefixerConfig, PrefixerResult } from './prefixer.js';
|
|
38
|
+
|
|
39
|
+
// Export tokens (single source - don't duplicate)
|
|
40
|
+
export { DesignTokens, createTokens as createDesignTokens } from './tokens.js';
|
|
41
|
+
export type { TokensStructure, FlattenedTokens } from './tokens.js';
|
|
42
|
+
|
|
43
|
+
// Export theme contract
|
|
44
|
+
export { createThemeContract, validateTheme, createTheme, Theme } from './theme-contract.js';
|
|
45
|
+
export type { ThemeContract, ThemeTokens } from './theme-contract.js';
|
|
46
|
+
|
|
47
|
+
// Export cache managers
|
|
48
|
+
export { CacheManager } from './cache-manager.js';
|
|
49
|
+
export { PersistentCache } from './content-addressable-cache.js';
|
|
50
|
+
export type { CacheData, CacheOptions } from './cache-manager.js';
|
|
51
|
+
export type { PersistentCacheOptions, PersistentCacheEntry } from './content-addressable-cache.js';
|
|
52
|
+
|
|
53
|
+
// Export shorthands
|
|
54
|
+
export { shorthandMap, macros, handleShorthand, isShorthand, expandShorthand, getAvailableShorthands } from './shorthands.js';
|
|
55
|
+
|
|
56
|
+
// Export helpers
|
|
57
|
+
export { helpers } from './helpers.js';
|
|
58
|
+
|
|
59
|
+
// Export animations
|
|
60
|
+
export { animationPresets, createAnimation, getAnimationPreset, hasAnimationPreset, getAnimationPresetNames } from './animations.js';
|
|
61
|
+
|
|
62
|
+
// Export breakpoints
|
|
63
|
+
export { setBreakpoints as setBreakpointsUtil, getBreakpoint, getAllBreakpoints, resetBreakpoints, addBreakpoint, removeBreakpoint } from './breakpoints.js';
|
|
64
|
+
|
|
65
|
+
// Export suggestions
|
|
66
|
+
export { getSuggestion, getSuggestions, getPropertySuggestion, getShorthandSuggestion } from './suggestions.js';
|
|
67
|
+
|
|
68
|
+
// Export token resolver
|
|
69
|
+
export { resolveToken, setTokenContext, getTokenContext, clearTokenContext, TokenResolver } from './token-resolver.js';
|
|
70
|
+
|
|
71
|
+
// Note: component-gen.ts is intentionally not exported as it's deprecated
|
|
72
|
+
// Use the component generation in btt.ts instead
|