chaincss 1.13.2 → 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 +239 -114
- 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 -109
- package/browser/commonProps.js +0 -14
- package/browser/index.js +0 -3
- package/browser/react-hooks.js +0 -162
- package/browser/rtt.js +0 -370
- package/node/atomic-optimizer.js +0 -391
- package/node/btt.js +0 -962
- package/node/cache-manager.js +0 -56
- package/node/chaincss.js +0 -489
- package/node/css-properties.json +0 -633
- 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 -106
- 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 -277
package/node/atomic-optimizer.js
DELETED
|
@@ -1,391 +0,0 @@
|
|
|
1
|
-
const crypto = require('crypto');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
|
|
5
|
-
function hashKey(key) {
|
|
6
|
-
return crypto.createHash('sha1').update(key).digest('hex').slice(0, 6);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
function kebab(s) {
|
|
10
|
-
return s.replace(/([A-Z])/g, '-$1').toLowerCase();
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
class AtomicOptimizer {
|
|
14
|
-
constructor(options = {}) {
|
|
15
|
-
this.options = {
|
|
16
|
-
enabled: true,
|
|
17
|
-
threshold: 3, // Default threshold
|
|
18
|
-
naming: 'hash', // 'hash' | 'readable'
|
|
19
|
-
cache: true,
|
|
20
|
-
cachePath: './.chaincss-cache',
|
|
21
|
-
minify: true,
|
|
22
|
-
alwaysAtomic: [], // Force these props to be atomic
|
|
23
|
-
neverAtomic: [ // Never make these atomic
|
|
24
|
-
'content', 'animation', 'transition', 'keyframes',
|
|
25
|
-
'counterIncrement', 'counterReset'
|
|
26
|
-
],
|
|
27
|
-
...options
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
this.usageCount = new Map(); // prop:value -> count
|
|
31
|
-
this.atomicClasses = new Map(); // prop:value -> { className, prop, value, usageCount }
|
|
32
|
-
this.stats = {
|
|
33
|
-
totalStyles: 0,
|
|
34
|
-
atomicStyles: 0,
|
|
35
|
-
standardStyles: 0,
|
|
36
|
-
uniqueProperties: 0,
|
|
37
|
-
savings: 0
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
if (this.options.cache) {
|
|
41
|
-
this.loadCache();
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// ============================================================================
|
|
46
|
-
// Cache Management
|
|
47
|
-
// ============================================================================
|
|
48
|
-
|
|
49
|
-
loadCache() {
|
|
50
|
-
try {
|
|
51
|
-
if (!fs.existsSync(this.options.cachePath)) return;
|
|
52
|
-
|
|
53
|
-
const data = JSON.parse(fs.readFileSync(this.options.cachePath, 'utf8'));
|
|
54
|
-
|
|
55
|
-
// Version check
|
|
56
|
-
if (data.version !== '1.0.0') {
|
|
57
|
-
console.log('Cache version mismatch, creating new cache');
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Check if config changed
|
|
62
|
-
if (data.config?.threshold !== this.options.threshold) {
|
|
63
|
-
console.log(`Cache threshold (${data.config?.threshold}) differs from current (${this.options.threshold})`);
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
this.atomicClasses = new Map(data.atomicClasses || []);
|
|
68
|
-
this.stats = data.stats || this.stats;
|
|
69
|
-
|
|
70
|
-
const cacheTime = new Date(data.timestamp).toLocaleString();
|
|
71
|
-
console.log(`✅ Loaded ${this.atomicClasses.size} atomic classes from cache (${cacheTime})`);
|
|
72
|
-
|
|
73
|
-
} catch (err) {
|
|
74
|
-
console.log('Could not load cache:', err.message);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
saveCache() {
|
|
79
|
-
if (!this.options.cache) return;
|
|
80
|
-
|
|
81
|
-
try {
|
|
82
|
-
const cacheDir = path.dirname(this.options.cachePath);
|
|
83
|
-
if (!fs.existsSync(cacheDir)) {
|
|
84
|
-
fs.mkdirSync(cacheDir, { recursive: true });
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Clean up old cache files (keep last 5)
|
|
88
|
-
if (fs.existsSync(cacheDir)) {
|
|
89
|
-
const files = fs.readdirSync(cacheDir)
|
|
90
|
-
.filter(f => f.startsWith('.chaincss-cache'))
|
|
91
|
-
.map(f => ({
|
|
92
|
-
name: f,
|
|
93
|
-
time: fs.statSync(path.join(cacheDir, f)).mtime.getTime()
|
|
94
|
-
}))
|
|
95
|
-
.sort((a, b) => b.time - a.time);
|
|
96
|
-
|
|
97
|
-
// Keep only the 5 most recent cache files
|
|
98
|
-
files.slice(5).forEach(f => {
|
|
99
|
-
try { fs.unlinkSync(path.join(cacheDir, f.name)); } catch {}
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const cache = {
|
|
104
|
-
version: '1.0.0',
|
|
105
|
-
timestamp: Date.now(),
|
|
106
|
-
atomicClasses: Array.from(this.atomicClasses.entries()),
|
|
107
|
-
stats: this.stats,
|
|
108
|
-
config: {
|
|
109
|
-
threshold: this.options.threshold,
|
|
110
|
-
naming: this.options.naming
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
fs.writeFileSync(this.options.cachePath, JSON.stringify(cache, null, 2), 'utf8');
|
|
115
|
-
} catch (err) {
|
|
116
|
-
console.log('Could not save cache:', err.message);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// ============================================================================
|
|
121
|
-
// Style Tracking
|
|
122
|
-
// ============================================================================
|
|
123
|
-
|
|
124
|
-
trackStyles(styles) {
|
|
125
|
-
const styleArray = Array.isArray(styles) ? styles : Object.values(styles);
|
|
126
|
-
|
|
127
|
-
for (const style of styleArray) {
|
|
128
|
-
if (!style || !style.selectors) continue;
|
|
129
|
-
|
|
130
|
-
for (const [prop, value] of Object.entries(style)) {
|
|
131
|
-
if (prop === 'selectors' || prop === 'atRules' || prop === 'hover') continue;
|
|
132
|
-
|
|
133
|
-
const key = `${prop}:${value}`;
|
|
134
|
-
this.usageCount.set(key, (this.usageCount.get(key) || 0) + 1);
|
|
135
|
-
this.stats.totalStyles++;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
this.stats.uniqueProperties = this.usageCount.size;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
shouldBeAtomic(prop, value) {
|
|
143
|
-
// Never atomic
|
|
144
|
-
if (this.options.neverAtomic.includes(prop)) return false;
|
|
145
|
-
|
|
146
|
-
// Always atomic
|
|
147
|
-
if (this.options.alwaysAtomic.includes(prop)) return true;
|
|
148
|
-
|
|
149
|
-
// Critical props that need higher threshold
|
|
150
|
-
const criticalProps = ['position', 'display', 'flex', 'grid', 'zIndex', 'top', 'left', 'right', 'bottom'];
|
|
151
|
-
const isCritical = criticalProps.includes(prop);
|
|
152
|
-
|
|
153
|
-
const key = `${prop}:${value}`;
|
|
154
|
-
const usage = this.usageCount.get(key) || 0;
|
|
155
|
-
|
|
156
|
-
// Critical props need double threshold to be atomic
|
|
157
|
-
if (isCritical && usage < this.options.threshold * 2) {
|
|
158
|
-
return false;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
return usage >= this.options.threshold;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
generateClassName(prop, value) {
|
|
165
|
-
const key = `${prop}:${value}`;
|
|
166
|
-
|
|
167
|
-
if (this.options.naming === 'hash') {
|
|
168
|
-
return `c_${hashKey(key)}`;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Readable naming
|
|
172
|
-
const kebabProp = kebab(prop);
|
|
173
|
-
const safeValue = String(value).replace(/[^a-z0-9_-]/gi, '-').slice(0, 30);
|
|
174
|
-
return `${kebabProp}-${safeValue}`;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
getOrCreateAtomic(prop, value) {
|
|
178
|
-
const key = `${prop}:${value}`;
|
|
179
|
-
|
|
180
|
-
if (!this.atomicClasses.has(key)) {
|
|
181
|
-
const className = this.generateClassName(prop, value);
|
|
182
|
-
this.atomicClasses.set(key, {
|
|
183
|
-
className,
|
|
184
|
-
prop,
|
|
185
|
-
value,
|
|
186
|
-
usageCount: this.usageCount.get(key) || 0
|
|
187
|
-
});
|
|
188
|
-
this.stats.atomicStyles++;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
return this.atomicClasses.get(key).className;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// ============================================================================
|
|
195
|
-
// CSS Generation
|
|
196
|
-
// ============================================================================
|
|
197
|
-
|
|
198
|
-
generateAtomicCSS() {
|
|
199
|
-
let css = '';
|
|
200
|
-
const sortedClasses = Array.from(this.atomicClasses.values())
|
|
201
|
-
.sort((a, b) => b.usageCount - a.usageCount);
|
|
202
|
-
|
|
203
|
-
for (const atomic of sortedClasses) {
|
|
204
|
-
const kebabProp = kebab(atomic.prop);
|
|
205
|
-
css += `.${atomic.className}{${kebabProp}:${atomic.value}${this.options.minify ? '' : ';'}}\n`;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
return css;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
generateComponentCSS(componentName, style, selectors) {
|
|
212
|
-
const atomicClasses = [];
|
|
213
|
-
const standardStyles = {};
|
|
214
|
-
const hoverStyles = {};
|
|
215
|
-
|
|
216
|
-
// Separate styles
|
|
217
|
-
for (const [prop, value] of Object.entries(style)) {
|
|
218
|
-
if (prop === 'selectors' || prop === 'atRules') continue;
|
|
219
|
-
|
|
220
|
-
if (prop === 'hover' && typeof value === 'object') {
|
|
221
|
-
// Handle hover styles
|
|
222
|
-
for (const [hoverProp, hoverValue] of Object.entries(value)) {
|
|
223
|
-
if (this.shouldBeAtomic(hoverProp, hoverValue)) {
|
|
224
|
-
atomicClasses.push(this.getOrCreateAtomic(hoverProp, hoverValue));
|
|
225
|
-
} else {
|
|
226
|
-
hoverStyles[hoverProp] = hoverValue;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
} else if (this.shouldBeAtomic(prop, value)) {
|
|
230
|
-
atomicClasses.push(this.getOrCreateAtomic(prop, value));
|
|
231
|
-
} else {
|
|
232
|
-
standardStyles[prop] = value;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// Generate CSS
|
|
237
|
-
let componentCSS = '';
|
|
238
|
-
const selectorStr = selectors.join(', ');
|
|
239
|
-
|
|
240
|
-
if (atomicClasses.length > 0 || Object.keys(standardStyles).length > 0) {
|
|
241
|
-
componentCSS += `${selectorStr} {\n`;
|
|
242
|
-
|
|
243
|
-
// Atomic classes (inlined for specificity)
|
|
244
|
-
for (const className of atomicClasses) {
|
|
245
|
-
const atomic = this.findAtomicByClassName(className);
|
|
246
|
-
if (atomic) {
|
|
247
|
-
const kebabProp = kebab(atomic.prop);
|
|
248
|
-
componentCSS += ` ${kebabProp}: ${atomic.value};\n`;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// Standard styles
|
|
253
|
-
for (const [prop, value] of Object.entries(standardStyles)) {
|
|
254
|
-
const kebabProp = kebab(prop);
|
|
255
|
-
componentCSS += ` ${kebabProp}: ${value};\n`;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
componentCSS += `}\n`;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
// Hover styles
|
|
262
|
-
if (Object.keys(hoverStyles).length > 0) {
|
|
263
|
-
componentCSS += `${selectorStr}:hover {\n`;
|
|
264
|
-
for (const [prop, value] of Object.entries(hoverStyles)) {
|
|
265
|
-
const kebabProp = kebab(prop);
|
|
266
|
-
componentCSS += ` ${kebabProp}: ${value};\n`;
|
|
267
|
-
}
|
|
268
|
-
componentCSS += `}\n`;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
return componentCSS;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
findAtomicByClassName(className) {
|
|
275
|
-
for (const atomic of this.atomicClasses.values()) {
|
|
276
|
-
if (atomic.className === className) return atomic;
|
|
277
|
-
}
|
|
278
|
-
return null;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
validateStyleOrder(originalStyles, atomicStyles) {
|
|
282
|
-
const originalProps = new Set();
|
|
283
|
-
const atomicProps = new Set();
|
|
284
|
-
|
|
285
|
-
const styleArray = Array.isArray(originalStyles) ? originalStyles : Object.values(originalStyles);
|
|
286
|
-
for (const style of styleArray) {
|
|
287
|
-
if (!style) continue;
|
|
288
|
-
for (const prop of Object.keys(style)) {
|
|
289
|
-
if (prop !== 'selectors' && prop !== 'atRules' && prop !== 'hover') {
|
|
290
|
-
originalProps.add(prop);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
for (const atomic of this.atomicClasses.values()) {
|
|
296
|
-
atomicProps.add(atomic.prop);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
const missingProps = [...originalProps].filter(p => !atomicProps.has(p));
|
|
300
|
-
if (missingProps.length > 0) {
|
|
301
|
-
console.warn('⚠️ Missing atomic classes for:', missingProps.slice(0, 10));
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
getStats() {
|
|
306
|
-
const savings = this.stats.totalStyles > 0
|
|
307
|
-
? ((this.stats.totalStyles - this.stats.atomicStyles) / this.stats.totalStyles * 100).toFixed(1)
|
|
308
|
-
: 0;
|
|
309
|
-
|
|
310
|
-
return {
|
|
311
|
-
totalStyles: this.stats.totalStyles,
|
|
312
|
-
atomicStyles: this.stats.atomicStyles,
|
|
313
|
-
standardStyles: this.stats.standardStyles,
|
|
314
|
-
uniqueProperties: this.stats.uniqueProperties,
|
|
315
|
-
savings: `${savings}%`
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
// ============================================================================
|
|
320
|
-
// Main Optimize Method
|
|
321
|
-
// ============================================================================
|
|
322
|
-
|
|
323
|
-
optimize(stylesInput) {
|
|
324
|
-
if (!this.options.enabled) {
|
|
325
|
-
return {
|
|
326
|
-
css: '',
|
|
327
|
-
map: {},
|
|
328
|
-
stats: this.getStats(),
|
|
329
|
-
atomicCSS: ''
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
// Normalize input to array
|
|
334
|
-
const styleArray = Array.isArray(stylesInput)
|
|
335
|
-
? stylesInput
|
|
336
|
-
: typeof stylesInput === 'object'
|
|
337
|
-
? Object.values(stylesInput)
|
|
338
|
-
: [];
|
|
339
|
-
|
|
340
|
-
// Track usage counts
|
|
341
|
-
this.trackStyles(styleArray);
|
|
342
|
-
|
|
343
|
-
// Generate CSS
|
|
344
|
-
let atomicCSS = this.generateAtomicCSS();
|
|
345
|
-
let componentCSS = '';
|
|
346
|
-
const classMap = {};
|
|
347
|
-
|
|
348
|
-
for (const style of styleArray) {
|
|
349
|
-
if (!style || !style.selectors) continue;
|
|
350
|
-
|
|
351
|
-
const selectors = style.selectors;
|
|
352
|
-
const selectorKey = selectors.join(', ');
|
|
353
|
-
|
|
354
|
-
// Generate component CSS
|
|
355
|
-
componentCSS += this.generateComponentCSS(style.name || 'component', style, selectors);
|
|
356
|
-
|
|
357
|
-
// Build class map for users
|
|
358
|
-
const atomicClassesForSelector = [];
|
|
359
|
-
for (const [prop, value] of Object.entries(style)) {
|
|
360
|
-
if (prop === 'selectors' || prop === 'atRules' || prop === 'hover') continue;
|
|
361
|
-
if (this.shouldBeAtomic(prop, value)) {
|
|
362
|
-
atomicClassesForSelector.push(this.getOrCreateAtomic(prop, value));
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
classMap[selectorKey] = atomicClassesForSelector.join(' ');
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
// Validation
|
|
369
|
-
this.validateStyleOrder(styleArray);
|
|
370
|
-
|
|
371
|
-
// Save cache
|
|
372
|
-
if (this.options.cache) {
|
|
373
|
-
this.saveCache();
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
// Calculate savings
|
|
377
|
-
const savings = this.stats.totalStyles > 0
|
|
378
|
-
? ((this.stats.totalStyles - this.atomicClasses.size) / this.stats.totalStyles * 100).toFixed(1)
|
|
379
|
-
: 0;
|
|
380
|
-
|
|
381
|
-
return {
|
|
382
|
-
css: (atomicCSS + componentCSS).trim(),
|
|
383
|
-
map: classMap,
|
|
384
|
-
stats: this.getStats(),
|
|
385
|
-
atomicCSS: atomicCSS.trim(),
|
|
386
|
-
componentCSS: componentCSS.trim()
|
|
387
|
-
};
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
module.exports = { AtomicOptimizer };
|