chaincss 1.13.3 → 2.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/CHANGELOG.md +81 -0
- package/LICENSE +2 -3
- package/README.md +238 -105
- package/dist/cli/commands/build.d.ts +3 -0
- package/dist/cli/commands/build.d.ts.map +1 -0
- package/dist/cli/commands/compile.d.ts +3 -0
- package/dist/cli/commands/compile.d.ts.map +1 -0
- package/dist/cli/commands/init.d.ts +5 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/timeline.d.ts +2 -0
- package/dist/cli/commands/timeline.d.ts.map +1 -0
- package/dist/cli/commands/watch.d.ts +6 -0
- package/dist/cli/commands/watch.d.ts.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +5960 -0
- package/dist/cli/types.d.ts +51 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/utils/config-loader.d.ts +8 -0
- package/dist/cli/utils/config-loader.d.ts.map +1 -0
- package/dist/cli/utils/file-utils.d.ts +9 -0
- package/dist/cli/utils/file-utils.d.ts.map +1 -0
- package/dist/cli/utils/logger.d.ts +17 -0
- package/dist/cli/utils/logger.d.ts.map +1 -0
- package/dist/compiler/atomic-optimizer.d.ts +76 -0
- package/dist/compiler/atomic-optimizer.d.ts.map +1 -0
- package/dist/compiler/btt.d.ts +138 -0
- package/dist/compiler/btt.d.ts.map +1 -0
- package/dist/compiler/cache-manager.d.ts +20 -0
- package/dist/compiler/cache-manager.d.ts.map +1 -0
- package/dist/compiler/commonProps.d.ts +2 -0
- package/dist/compiler/commonProps.d.ts.map +1 -0
- package/dist/compiler/index.d.ts +12 -0
- package/dist/compiler/index.d.ts.map +1 -0
- package/dist/compiler/index.js +5177 -0
- package/dist/compiler/prefixer.d.ts +42 -0
- package/dist/compiler/prefixer.d.ts.map +1 -0
- package/dist/compiler/theme-contract.d.ts +61 -0
- package/dist/compiler/theme-contract.d.ts.map +1 -0
- package/dist/compiler/tokens.d.ts +52 -0
- package/dist/compiler/tokens.d.ts.map +1 -0
- package/dist/compiler/types.d.ts +57 -0
- package/dist/compiler/types.d.ts.map +1 -0
- package/dist/core/compiler.d.ts +32 -0
- package/dist/core/compiler.d.ts.map +1 -0
- package/dist/core/constants.d.ts +129 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/types.d.ts +88 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/utils.d.ts +37 -0
- package/dist/core/utils.d.ts.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5667 -0
- package/dist/plugins/vite.d.ts +11 -0
- package/dist/plugins/vite.d.ts.map +1 -0
- package/dist/plugins/vite.js +25839 -0
- package/dist/plugins/webpack.d.ts +45 -0
- package/dist/plugins/webpack.d.ts.map +1 -0
- package/dist/plugins/webpack.js +107 -0
- package/dist/runtime/hmr.d.ts +3 -0
- package/dist/runtime/hmr.d.ts.map +1 -0
- package/dist/runtime/index.d.ts +15 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +552 -0
- package/dist/runtime/injector.d.ts +85 -0
- package/dist/runtime/injector.d.ts.map +1 -0
- package/dist/runtime/react.d.ts +54 -0
- package/dist/runtime/react.d.ts.map +1 -0
- package/dist/runtime/react.js +270 -0
- package/dist/runtime/types.d.ts +45 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime/utils.d.ts +62 -0
- package/dist/runtime/utils.d.ts.map +1 -0
- package/dist/runtime/vue.d.ts +52 -0
- package/dist/runtime/vue.d.ts.map +1 -0
- package/dist/runtime/vue.js +232 -0
- package/package.json +90 -119
- package/browser/commonProps.js +0 -14
- package/browser/index.js +0 -3
- package/browser/react-hooks.js +0 -162
- package/browser/rtt.js +0 -400
- package/browser/vue-composables.js +0 -200
- package/node/atomic-optimizer.js +0 -526
- package/node/btt.js +0 -1009
- package/node/cache-manager.js +0 -56
- package/node/chaincss.js +0 -642
- package/node/index.js +0 -2
- package/node/loaders/chaincss-loader.js +0 -62
- package/node/plugins/next-plugin.js +0 -120
- package/node/plugins/vite-plugin.js +0 -383
- package/node/plugins/webpack-plugin.js +0 -41
- package/node/prefixer.js +0 -237
- package/node/strVal.js +0 -92
- package/node/theme-validator.js +0 -32
- package/shared/theme-contract.js +0 -98
- package/shared/tokens.cjs +0 -256
- package/shared/tokens.mjs +0 -320
- package/types.d.ts +0 -325
package/browser/rtt.js
DELETED
|
@@ -1,400 +0,0 @@
|
|
|
1
|
-
import { tokens as importedTokens, DesignTokens } from '../shared/tokens.mjs';
|
|
2
|
-
|
|
3
|
-
let cachedProperties = null;
|
|
4
|
-
|
|
5
|
-
const loadCSSProperties = async () => {
|
|
6
|
-
// Return cached if already loaded
|
|
7
|
-
if (cachedProperties !== null) {
|
|
8
|
-
return cachedProperties;
|
|
9
|
-
}
|
|
10
|
-
// Try CDN first (only once)
|
|
11
|
-
try {
|
|
12
|
-
const controller = new AbortController();
|
|
13
|
-
const timeoutId = setTimeout(() => controller.abort(), 3000); // 3 second timeout
|
|
14
|
-
|
|
15
|
-
const response = await fetch('https://raw.githubusercontent.com/mdn/data/main/css/properties.json', {
|
|
16
|
-
signal: controller.signal
|
|
17
|
-
});
|
|
18
|
-
clearTimeout(timeoutId);
|
|
19
|
-
|
|
20
|
-
if (response.ok) {
|
|
21
|
-
const data = await response.json();
|
|
22
|
-
const allProperties = Object.keys(data);
|
|
23
|
-
const baseProperties = new Set();
|
|
24
|
-
|
|
25
|
-
allProperties.forEach(prop => {
|
|
26
|
-
const baseProp = prop.replace(/^-(webkit|moz|ms|o)-/, '');
|
|
27
|
-
baseProperties.add(baseProp);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
cachedProperties = Array.from(baseProperties).sort();
|
|
31
|
-
//console.log(`Loaded ${cachedProperties.length} CSS properties from CDN`);
|
|
32
|
-
return cachedProperties;
|
|
33
|
-
}
|
|
34
|
-
} catch (error) {
|
|
35
|
-
console.log('CDN failed, using fallback CSS property list');
|
|
36
|
-
// Use hardcoded fallback (always works)
|
|
37
|
-
const { COMMON_CSS_PROPERTIES } = await import('./commonProps.js');
|
|
38
|
-
cachedProperties = COMMON_CSS_PROPERTIES;
|
|
39
|
-
return cachedProperties;
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const chain = {
|
|
44
|
-
cssOutput: undefined,
|
|
45
|
-
catcher: {},
|
|
46
|
-
cachedValidProperties: [],
|
|
47
|
-
async initializeProperties() {
|
|
48
|
-
if (this.cachedValidProperties.length > 0) {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const properties = await loadCSSProperties();
|
|
53
|
-
this.cachedValidProperties = properties;
|
|
54
|
-
},
|
|
55
|
-
getCachedProperties() {
|
|
56
|
-
return this.cachedValidProperties;
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
// Start initialization (non-blocking)
|
|
61
|
-
chain.initializeProperties().catch(err => {
|
|
62
|
-
console.error('Failed to load CSS properties:', err.message);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
const resolveToken = (value, useTokens) => {
|
|
66
|
-
if (!useTokens || typeof value !== 'string' || !value.startsWith('$')) {
|
|
67
|
-
return value;
|
|
68
|
-
}
|
|
69
|
-
const tokenPath = value.slice(1);
|
|
70
|
-
const tokenValue = tokens.get(tokenPath);
|
|
71
|
-
if (!tokenValue) {
|
|
72
|
-
return value;
|
|
73
|
-
}
|
|
74
|
-
return tokenValue;
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
function $(useTokens = true) {
|
|
78
|
-
const catcher = {};
|
|
79
|
-
const validProperties = chain.cachedValidProperties;
|
|
80
|
-
|
|
81
|
-
const handler = {
|
|
82
|
-
get: (target, prop) => {
|
|
83
|
-
if (prop === 'block') {
|
|
84
|
-
return function(...args) {
|
|
85
|
-
if (args.length === 0) {
|
|
86
|
-
const result = { ...catcher };
|
|
87
|
-
Object.keys(catcher).forEach(key => delete catcher[key]);
|
|
88
|
-
return result;
|
|
89
|
-
}
|
|
90
|
-
const result = {
|
|
91
|
-
selectors: args,
|
|
92
|
-
...catcher
|
|
93
|
-
};
|
|
94
|
-
Object.keys(catcher).forEach(key => delete catcher[key]);
|
|
95
|
-
return result;
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (prop === 'hover') {
|
|
100
|
-
return () => {
|
|
101
|
-
const hoverCatcher = {};
|
|
102
|
-
const hoverHandler = {
|
|
103
|
-
get: (hoverTarget, hoverProp) => {
|
|
104
|
-
if (hoverProp === 'end') {
|
|
105
|
-
return () => {
|
|
106
|
-
catcher.hover = { ...hoverCatcher };
|
|
107
|
-
Object.keys(hoverCatcher).forEach(key => delete hoverCatcher[key]);
|
|
108
|
-
return proxy;
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
const cssProperty = hoverProp.replace(/([A-Z])/g, '-$1').toLowerCase();
|
|
112
|
-
if (validProperties && validProperties.length > 0 && !validProperties.includes(cssProperty)) {
|
|
113
|
-
console.warn(`Warning: '${cssProperty}' may not be a valid CSS property`);
|
|
114
|
-
}
|
|
115
|
-
return (value) => {
|
|
116
|
-
hoverCatcher[hoverProp] = resolveToken(value, useTokens);
|
|
117
|
-
return hoverProxy;
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
const hoverProxy = new Proxy({}, hoverHandler);
|
|
122
|
-
return hoverProxy;
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (prop === 'end') {
|
|
127
|
-
return () => {
|
|
128
|
-
return proxy;
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (prop === 'select') {
|
|
133
|
-
return function(selector) {
|
|
134
|
-
const props = {};
|
|
135
|
-
const selectorProxy = new Proxy({}, {
|
|
136
|
-
get: (target, methodProp) => {
|
|
137
|
-
if (methodProp === 'block') {
|
|
138
|
-
return function() {
|
|
139
|
-
return {
|
|
140
|
-
selectors: [selector],
|
|
141
|
-
...props
|
|
142
|
-
};
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
return function(value) {
|
|
146
|
-
props[methodProp] = resolveToken(value, useTokens);
|
|
147
|
-
return selectorProxy;
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
return selectorProxy;
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// At-Rules
|
|
156
|
-
if (prop === 'media') {
|
|
157
|
-
return function(query, callback) {
|
|
158
|
-
const subChain = $(useTokens);
|
|
159
|
-
const result = callback(subChain);
|
|
160
|
-
if (!catcher.atRules) catcher.atRules = [];
|
|
161
|
-
catcher.atRules.push({
|
|
162
|
-
type: 'media',
|
|
163
|
-
query: query,
|
|
164
|
-
styles: result
|
|
165
|
-
});
|
|
166
|
-
return proxy;
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
if (prop === 'keyframes') {
|
|
171
|
-
return function(name, callback) {
|
|
172
|
-
const keyframeContext = { _keyframeSteps: {} };
|
|
173
|
-
const keyframeProxy = new Proxy(keyframeContext, {
|
|
174
|
-
get: (target, stepProp) => {
|
|
175
|
-
if (stepProp === 'from' || stepProp === 'to') {
|
|
176
|
-
return function(stepCallback) {
|
|
177
|
-
const subChain = $(useTokens);
|
|
178
|
-
const properties = stepCallback(subChain).block();
|
|
179
|
-
target._keyframeSteps[stepProp] = properties;
|
|
180
|
-
return keyframeProxy;
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
if (stepProp === 'percent') {
|
|
184
|
-
return function(value, stepCallback) {
|
|
185
|
-
const subChain = $(useTokens);
|
|
186
|
-
const properties = stepCallback(subChain).block();
|
|
187
|
-
target._keyframeSteps[`${value}%`] = properties;
|
|
188
|
-
return keyframeProxy;
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
return undefined;
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
callback(keyframeProxy);
|
|
195
|
-
if (!catcher.atRules) catcher.atRules = [];
|
|
196
|
-
catcher.atRules.push({
|
|
197
|
-
type: 'keyframes',
|
|
198
|
-
name: name,
|
|
199
|
-
steps: keyframeContext._keyframeSteps
|
|
200
|
-
});
|
|
201
|
-
return proxy;
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
if (prop === 'fontFace') {
|
|
206
|
-
return function(callback) {
|
|
207
|
-
const subChain = $(useTokens);
|
|
208
|
-
const fontProps = callback(subChain).block();
|
|
209
|
-
if (!catcher.atRules) catcher.atRules = [];
|
|
210
|
-
catcher.atRules.push({
|
|
211
|
-
type: 'font-face',
|
|
212
|
-
properties: fontProps
|
|
213
|
-
});
|
|
214
|
-
return proxy;
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if (prop === 'supports') {
|
|
219
|
-
return function(condition, callback) {
|
|
220
|
-
const subChain = $(useTokens);
|
|
221
|
-
const styles = callback(subChain);
|
|
222
|
-
if (!catcher.atRules) catcher.atRules = [];
|
|
223
|
-
catcher.atRules.push({
|
|
224
|
-
type: 'supports',
|
|
225
|
-
condition: condition,
|
|
226
|
-
styles: styles
|
|
227
|
-
});
|
|
228
|
-
return proxy;
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
if (prop === 'container') {
|
|
233
|
-
return function(condition, callback) {
|
|
234
|
-
const subChain = $(useTokens);
|
|
235
|
-
const styles = callback(subChain);
|
|
236
|
-
if (!catcher.atRules) catcher.atRules = [];
|
|
237
|
-
catcher.atRules.push({
|
|
238
|
-
type: 'container',
|
|
239
|
-
condition: condition,
|
|
240
|
-
styles: styles
|
|
241
|
-
});
|
|
242
|
-
return proxy;
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
if (prop === 'layer') {
|
|
247
|
-
return function(name, callback) {
|
|
248
|
-
const subChain = $(useTokens);
|
|
249
|
-
const styles = callback(subChain);
|
|
250
|
-
if (!catcher.atRules) catcher.atRules = [];
|
|
251
|
-
catcher.atRules.push({
|
|
252
|
-
type: 'layer',
|
|
253
|
-
name: name,
|
|
254
|
-
styles: styles
|
|
255
|
-
});
|
|
256
|
-
return proxy;
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
if (prop === 'counterStyle') {
|
|
261
|
-
return function(name, callback) {
|
|
262
|
-
const subChain = $(useTokens);
|
|
263
|
-
const properties = callback(subChain).block();
|
|
264
|
-
if (!catcher.atRules) catcher.atRules = [];
|
|
265
|
-
catcher.atRules.push({
|
|
266
|
-
type: 'counter-style',
|
|
267
|
-
name: name,
|
|
268
|
-
properties: properties
|
|
269
|
-
});
|
|
270
|
-
return proxy;
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
if (prop === 'property') {
|
|
275
|
-
return function(name, callback) {
|
|
276
|
-
const subChain = $(useTokens);
|
|
277
|
-
const descriptors = callback(subChain).block();
|
|
278
|
-
if (!catcher.atRules) catcher.atRules = [];
|
|
279
|
-
catcher.atRules.push({
|
|
280
|
-
type: 'property',
|
|
281
|
-
name: name,
|
|
282
|
-
descriptors: descriptors
|
|
283
|
-
});
|
|
284
|
-
return proxy;
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
const cssProperty = prop.replace(/([A-Z])/g, '-$1').toLowerCase();
|
|
289
|
-
if (validProperties && validProperties.length > 0 && !validProperties.includes(cssProperty)) {
|
|
290
|
-
console.warn(`Warning: '${cssProperty}' may not be a valid CSS property`);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
return function(value) {
|
|
294
|
-
catcher[prop] = resolveToken(value, useTokens);
|
|
295
|
-
return proxy;
|
|
296
|
-
};
|
|
297
|
-
}
|
|
298
|
-
};
|
|
299
|
-
|
|
300
|
-
const proxy = new Proxy({}, handler);
|
|
301
|
-
return proxy;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
const run = (...args) => {
|
|
305
|
-
let cssOutput = '';
|
|
306
|
-
|
|
307
|
-
args.forEach((value) => {
|
|
308
|
-
if (value && value.selectors) {
|
|
309
|
-
let normalStyles = '';
|
|
310
|
-
let hoverStyles = '';
|
|
311
|
-
|
|
312
|
-
// Separate normal properties from hover
|
|
313
|
-
for (let key in value) {
|
|
314
|
-
if (key === 'selectors') continue;
|
|
315
|
-
|
|
316
|
-
if (key === 'hover' && typeof value[key] === 'object') {
|
|
317
|
-
// Build hover styles separately
|
|
318
|
-
hoverStyles = `${value.selectors.join(', ')}:hover {\n`;
|
|
319
|
-
for (let hoverKey in value[key]) {
|
|
320
|
-
const kebabKey = hoverKey.replace(/([A-Z])/g, '-$1').toLowerCase();
|
|
321
|
-
hoverStyles += ` ${kebabKey}: ${value[key][hoverKey]};\n`;
|
|
322
|
-
}
|
|
323
|
-
hoverStyles += `}\n`;
|
|
324
|
-
} else {
|
|
325
|
-
// Build normal styles
|
|
326
|
-
const kebabKey = key.replace(/([A-Z])/g, '-$1').toLowerCase();
|
|
327
|
-
normalStyles += ` ${kebabKey}: ${value[key]};\n`;
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
// Output normal styles
|
|
332
|
-
if (normalStyles) {
|
|
333
|
-
cssOutput += `${value.selectors.join(', ')} {\n${normalStyles}}\n`;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
// Output hover styles
|
|
337
|
-
if (hoverStyles) {
|
|
338
|
-
cssOutput += hoverStyles;
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
chain.cssOutput = cssOutput.trim();
|
|
344
|
-
return cssOutput.trim();
|
|
345
|
-
};
|
|
346
|
-
|
|
347
|
-
const compile = (obj) => {
|
|
348
|
-
let cssString = '';
|
|
349
|
-
for (const key in obj) {
|
|
350
|
-
if (obj.hasOwnProperty(key)) {
|
|
351
|
-
const element = obj[key];
|
|
352
|
-
let selectors = element.selectors || [];
|
|
353
|
-
|
|
354
|
-
// Generate normal styles
|
|
355
|
-
let normalCSS = '';
|
|
356
|
-
for (let prop in element) {
|
|
357
|
-
if (element.hasOwnProperty(prop) && prop !== 'selectors' && prop !== 'hover') {
|
|
358
|
-
const kebabKey = prop.replace(/([A-Z])/g, '-$1').toLowerCase();
|
|
359
|
-
normalCSS += ` ${kebabKey}: ${element[prop]};\n`;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
if (normalCSS) {
|
|
363
|
-
cssString += `${selectors.join(', ')} {\n${normalCSS}}\n`;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
// Generate hover styles
|
|
367
|
-
if (element.hover && typeof element.hover === 'object') {
|
|
368
|
-
let hoverCSS = '';
|
|
369
|
-
for (let prop in element.hover) {
|
|
370
|
-
if (element.hover.hasOwnProperty(prop) && prop !== 'selectors') {
|
|
371
|
-
const kebabKey = prop.replace(/([A-Z])/g, '-$1').toLowerCase();
|
|
372
|
-
hoverCSS += ` ${kebabKey}: ${element.hover[prop]};\n`;
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
if (hoverCSS) {
|
|
376
|
-
const hoverSelectors = selectors.map(s => `${s}:hover`);
|
|
377
|
-
cssString += `${hoverSelectors.join(', ')} {\n${hoverCSS}}\n`;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
chain.cssOutput = cssString.trim();
|
|
383
|
-
return cssString.trim();
|
|
384
|
-
};
|
|
385
|
-
|
|
386
|
-
function createTokens(tokenValues) {
|
|
387
|
-
const tokenObj = new DesignTokens(tokenValues);
|
|
388
|
-
return tokenObj;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
const tokens = importedTokens;
|
|
392
|
-
|
|
393
|
-
export {
|
|
394
|
-
chain,
|
|
395
|
-
$,
|
|
396
|
-
run,
|
|
397
|
-
compile,
|
|
398
|
-
tokens,
|
|
399
|
-
createTokens
|
|
400
|
-
};
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
import { computed, inject, provide, ref, watch } from 'vue';
|
|
2
|
-
|
|
3
|
-
// Symbol for providing the global ChainCSS instance
|
|
4
|
-
const CHAIN_CSS_KEY = Symbol('chaincss');
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Core function to process styles and generate class names
|
|
8
|
-
*/
|
|
9
|
-
function processStyles(styles, atomic = true) {
|
|
10
|
-
const result = {};
|
|
11
|
-
|
|
12
|
-
for (const [key, styleFn] of Object.entries(styles)) {
|
|
13
|
-
if (typeof styleFn === 'function') {
|
|
14
|
-
result[key] = styleFn();
|
|
15
|
-
} else if (styleFn && typeof styleFn === 'object') {
|
|
16
|
-
// If it's already processed, use it
|
|
17
|
-
result[key] = styleFn;
|
|
18
|
-
} else {
|
|
19
|
-
result[key] = styleFn;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return result;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Main composable for using ChainCSS in Vue components
|
|
28
|
-
* @param {Object|Ref|ComputedRef} styles - Style definitions
|
|
29
|
-
* @param {Object} options - Configuration options
|
|
30
|
-
* @returns {Object} - Classes object
|
|
31
|
-
*/
|
|
32
|
-
export function useAtomicClasses(styles, options = {}) {
|
|
33
|
-
const { atomic = true, global = false } = options;
|
|
34
|
-
|
|
35
|
-
// Get global ChainCSS instance if available
|
|
36
|
-
const chainCSS = inject(CHAIN_CSS_KEY, null);
|
|
37
|
-
|
|
38
|
-
// Create reactive classes
|
|
39
|
-
const classes = computed(() => {
|
|
40
|
-
// Resolve styles if it's a ref or computed
|
|
41
|
-
const resolvedStyles = typeof styles === 'function'
|
|
42
|
-
? styles()
|
|
43
|
-
: styles?.value || styles;
|
|
44
|
-
|
|
45
|
-
// Process the styles
|
|
46
|
-
const processed = processStyles(resolvedStyles, atomic);
|
|
47
|
-
|
|
48
|
-
// If we have a global ChainCSS instance, register styles
|
|
49
|
-
if (chainCSS && typeof chainCSS.register === 'function') {
|
|
50
|
-
chainCSS.register(processed, { atomic, global });
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return processed;
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
return {
|
|
57
|
-
classes,
|
|
58
|
-
// Helper to get specific class
|
|
59
|
-
cx: (name) => classes.value[name],
|
|
60
|
-
// Helper to combine multiple classes
|
|
61
|
-
cn: (...names) => names.map(name => classes.value[name]).filter(Boolean).join(' ')
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Component for injecting global styles
|
|
67
|
-
*/
|
|
68
|
-
export const ChainCSSGlobal = {
|
|
69
|
-
name: 'ChainCSSGlobal',
|
|
70
|
-
props: {
|
|
71
|
-
styles: {
|
|
72
|
-
type: Object,
|
|
73
|
-
required: true
|
|
74
|
-
},
|
|
75
|
-
atomic: {
|
|
76
|
-
type: Boolean,
|
|
77
|
-
default: true
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
setup(props) {
|
|
81
|
-
// Create a computed ref for styles
|
|
82
|
-
const globalStyles = computed(() => props.styles);
|
|
83
|
-
|
|
84
|
-
// Process and inject styles
|
|
85
|
-
const processedStyles = computed(() => {
|
|
86
|
-
return processStyles(globalStyles.value, props.atomic);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
// Provide ChainCSS instance to children
|
|
90
|
-
const chainCSSInstance = {
|
|
91
|
-
register: (styles, options) => {
|
|
92
|
-
// This would integrate with your actual ChainCSS runtime
|
|
93
|
-
console.log('Registering styles:', styles, options);
|
|
94
|
-
// TODO: Connect to actual ChainCSS runtime
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
provide(CHAIN_CSS_KEY, chainCSSInstance);
|
|
99
|
-
|
|
100
|
-
// In development, log the styles
|
|
101
|
-
if (process.env.NODE_ENV === 'development') {
|
|
102
|
-
watch(processedStyles, (styles) => {
|
|
103
|
-
console.log('[ChainCSS] Global styles registered:', styles);
|
|
104
|
-
}, { immediate: true });
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// This component doesn't render anything
|
|
108
|
-
return () => null;
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Create a themed component with ChainCSS styles
|
|
114
|
-
* @param {Object|Function} styles - Style definitions
|
|
115
|
-
* @param {Object} options - Component options
|
|
116
|
-
* @returns {Object} - Vue component
|
|
117
|
-
*/
|
|
118
|
-
export function createStyledComponent(styles, options = {}) {
|
|
119
|
-
const { name = 'StyledComponent', atomic = true } = options;
|
|
120
|
-
|
|
121
|
-
return {
|
|
122
|
-
name,
|
|
123
|
-
props: {
|
|
124
|
-
as: {
|
|
125
|
-
type: String,
|
|
126
|
-
default: 'div'
|
|
127
|
-
},
|
|
128
|
-
className: {
|
|
129
|
-
type: String,
|
|
130
|
-
default: ''
|
|
131
|
-
},
|
|
132
|
-
...options.props
|
|
133
|
-
},
|
|
134
|
-
setup(props, { slots, attrs }) {
|
|
135
|
-
// Resolve styles (can be a function that receives props)
|
|
136
|
-
const resolvedStyles = computed(() => {
|
|
137
|
-
if (typeof styles === 'function') {
|
|
138
|
-
return styles(props);
|
|
139
|
-
}
|
|
140
|
-
return styles;
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
const { classes, cn } = useAtomicClasses(resolvedStyles, { atomic });
|
|
144
|
-
|
|
145
|
-
// Combine classes
|
|
146
|
-
const combinedClasses = computed(() => {
|
|
147
|
-
return cn('root', props.className);
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
return () => {
|
|
151
|
-
const tag = props.as;
|
|
152
|
-
const componentProps = {
|
|
153
|
-
...attrs,
|
|
154
|
-
class: combinedClasses.value
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
// Remove props that shouldn't be passed to DOM elements
|
|
158
|
-
delete componentProps.as;
|
|
159
|
-
|
|
160
|
-
return h(tag, componentProps, slots.default?.());
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Create a reactive theme system
|
|
168
|
-
* @param {Object} themes - Theme definitions
|
|
169
|
-
* @returns {Object} - Theme utilities
|
|
170
|
-
*/
|
|
171
|
-
export function createTheme(themes) {
|
|
172
|
-
const currentTheme = ref(Object.keys(themes)[0] || 'light');
|
|
173
|
-
|
|
174
|
-
const themeStyles = computed(() => {
|
|
175
|
-
return themes[currentTheme.value] || {};
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
const setTheme = (themeName) => {
|
|
179
|
-
if (themes[themeName]) {
|
|
180
|
-
currentTheme.value = themeName;
|
|
181
|
-
}
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
const toggleTheme = () => {
|
|
185
|
-
const keys = Object.keys(themes);
|
|
186
|
-
const currentIndex = keys.indexOf(currentTheme.value);
|
|
187
|
-
const nextIndex = (currentIndex + 1) % keys.length;
|
|
188
|
-
currentTheme.value = keys[nextIndex];
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
return {
|
|
192
|
-
currentTheme: readonly(currentTheme),
|
|
193
|
-
themeStyles,
|
|
194
|
-
setTheme,
|
|
195
|
-
toggleTheme
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// Import Vue's h function for createStyledComponent
|
|
200
|
-
import { h, readonly } from 'vue';
|