@colorye/react-native-css 0.3.1 → 0.3.2

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.
Files changed (37) hide show
  1. package/crates/transformer/index.js +1 -0
  2. package/crates/transformer/transformer.darwin-arm64.node +0 -0
  3. package/crates/transformer/transformer.darwin-x64.node +0 -0
  4. package/crates/transformer/transformer.linux-x64-gnu.node +0 -0
  5. package/crates/transformer/transformer.node +0 -0
  6. package/crates/transformer/transformer.win32-x64-msvc.node +0 -0
  7. package/dist/babel.js +68 -159
  8. package/dist/index.d.ts +22 -8
  9. package/dist/interop.js +17 -5
  10. package/dist/metro.js +55 -0
  11. package/dist/transformer-runtime.js +170 -18
  12. package/dist/transformer.js +73 -20
  13. package/package.json +3 -1
  14. package/src/babel.js +71 -224
  15. package/src/index.d.ts +22 -8
  16. package/src/interop.js +13 -1
  17. package/src/metro.js +42 -0
  18. package/src/transformer-runtime.js +169 -15
  19. package/src/transformer.js +75 -15
  20. package/dist/features/build-transform.js +0 -575
  21. package/dist/features/css-calc.js +0 -539
  22. package/dist/features/css-media.js +0 -77
  23. package/dist/features/css-transform.js +0 -426
  24. package/dist/features/css-vars.js +0 -153
  25. package/dist/features/stylesheet.js +0 -45
  26. package/dist/utils/babel.js +0 -363
  27. package/dist/utils/css.js +0 -263
  28. package/dist/utils/helper.js +0 -11
  29. package/src/features/build-transform.js +0 -536
  30. package/src/features/css-calc.js +0 -490
  31. package/src/features/css-media.js +0 -78
  32. package/src/features/css-transform.js +0 -446
  33. package/src/features/css-vars.js +0 -138
  34. package/src/features/stylesheet.js +0 -29
  35. package/src/utils/babel.js +0 -425
  36. package/src/utils/css.js +0 -221
  37. package/src/utils/helper.js +0 -3
@@ -1,425 +0,0 @@
1
- import Runtime from "../transformer-runtime.js";
2
-
3
- export function isImportOrRequire(statement) {
4
- return (
5
- statement.isImportDeclaration() ||
6
- statement.node?.declarations?.[0]?.init?.callee?.name === "require"
7
- );
8
- }
9
-
10
- export function isFragmentElement(t, elementName) {
11
- return (
12
- (t.isJSXIdentifier(elementName) &&
13
- (elementName.name === "Fragment" || elementName.name === "React.Fragment")) ||
14
- (t.isJSXMemberExpression(elementName) &&
15
- elementName.object.name === "React" &&
16
- elementName.property.name === "Fragment") ||
17
- t.isJSXIdentifier(elementName, { name: "" }) // JSX shorthand fragment
18
- );
19
- }
20
-
21
- export function isRootLevelJSXElement(path) {
22
- let currentPath = path;
23
-
24
- while (currentPath.parentPath) {
25
- const parent = currentPath.parentPath;
26
-
27
- if (parent.isReturnStatement()) return true;
28
- if (parent.isArrowFunctionExpression() && parent.node.body === currentPath.node) return true;
29
- if (parent.isJSXElement() && parent !== path) return false;
30
-
31
- if (
32
- parent.isConditionalExpression() ||
33
- parent.isLogicalExpression() ||
34
- parent.isParenthesizedExpression()
35
- ) {
36
- currentPath = parent;
37
- continue;
38
- }
39
-
40
- currentPath = parent;
41
- }
42
-
43
- return false;
44
- }
45
-
46
- // ============================================================================
47
- // Static style detection helpers
48
- // ============================================================================
49
-
50
- /**
51
- * Check if className is a static string literal
52
- */
53
- export function isStaticClassName(t, classNameAttr) {
54
- if (!classNameAttr) return false;
55
- if (t.isStringLiteral(classNameAttr.value)) return true;
56
- if (
57
- t.isJSXExpressionContainer(classNameAttr.value) &&
58
- t.isStringLiteral(classNameAttr.value.expression)
59
- ) {
60
- return true;
61
- }
62
- return false;
63
- }
64
-
65
- /**
66
- * Get static className string value
67
- */
68
- export function getStaticClassNameValue(t, classNameAttr) {
69
- if (!classNameAttr) return null;
70
- if (t.isStringLiteral(classNameAttr.value)) return classNameAttr.value.value;
71
- if (
72
- t.isJSXExpressionContainer(classNameAttr.value) &&
73
- t.isStringLiteral(classNameAttr.value.expression)
74
- ) {
75
- return classNameAttr.value.expression.value;
76
- }
77
- return null;
78
- }
79
-
80
- /**
81
- * Check if a class is fully static (no dynamic breakpoint / dark mode queries)
82
- */
83
- export function isClassStatic(stylesheet, className) {
84
- if (!className) return true;
85
- if (
86
- className === "group" ||
87
- className.startsWith("group") ||
88
- className.startsWith("peer") ||
89
- className.startsWith("active:") ||
90
- className.startsWith("pressed:") ||
91
- className.startsWith("disabled:") ||
92
- className.startsWith("dark:") ||
93
- className.startsWith("light:") ||
94
- className.startsWith("sm:") ||
95
- className.startsWith("md:") ||
96
- className.startsWith("lg:") ||
97
- className.startsWith("xl:") ||
98
- className.startsWith("2xl:") ||
99
- className.startsWith("portrait:") ||
100
- className.startsWith("landscape:")
101
- ) {
102
- return false;
103
- }
104
- return true;
105
- }
106
-
107
- /**
108
- * Check if all classes in className string are static
109
- */
110
- export function areAllClassesStatic(stylesheet, classNameValue) {
111
- if (!classNameValue || !stylesheet) return false;
112
- const classes = classNameValue.trim().split(/\s+/).filter(Boolean);
113
- return classes.every((cls) => isClassStatic(stylesheet, cls));
114
- }
115
-
116
- /**
117
- * Compute merged static styles from className string using Runtime compiler
118
- */
119
- export function computeStaticStyles(stylesheet, classNameValue) {
120
- if (!classNameValue || !stylesheet) return {};
121
- try {
122
- const computed = Runtime.getStyle(stylesheet, [undefined, classNameValue, undefined]);
123
- return computed || {};
124
- } catch {
125
- return {};
126
- }
127
- }
128
-
129
- /**
130
- * Inlines static className and contentContainerClassName attributes directly into styles
131
- */
132
- export function inlineStaticAttributes(path, state, t) {
133
- if (!state.stylesheetData) return;
134
-
135
- const openingElement = path.node.openingElement;
136
- const stylesheet = state.stylesheetData;
137
-
138
- const classPropMappings = [
139
- { classProp: "className", styleProp: "style" },
140
- { classProp: "contentContainerClassName", styleProp: "contentContainerStyle" },
141
- ];
142
-
143
- for (const { classProp, styleProp } of classPropMappings) {
144
- const classAttrIndex = openingElement.attributes.findIndex(
145
- (attr) => t.isJSXAttribute(attr) && attr.name?.name === classProp,
146
- );
147
- if (classAttrIndex === -1) continue;
148
-
149
- const classAttr = openingElement.attributes[classAttrIndex];
150
- if (!isStaticClassName(t, classAttr)) continue;
151
-
152
- const classValue = getStaticClassNameValue(t, classAttr);
153
- if (!classValue || !areAllClassesStatic(stylesheet, classValue)) continue;
154
-
155
- const staticStyles = computeStaticStyles(stylesheet, classValue);
156
- if (!staticStyles || Object.keys(staticStyles).length === 0) continue;
157
-
158
- const styleAST = objectToAST(t, staticStyles);
159
-
160
- // Find existing style prop if present
161
- const existingStyle = openingElement.attributes.find(
162
- (attr) => t.isJSXAttribute(attr) && attr.name?.name === styleProp,
163
- );
164
-
165
- if (existingStyle) {
166
- const currentVal = t.isJSXExpressionContainer(existingStyle.value)
167
- ? existingStyle.value.expression
168
- : existingStyle.value;
169
- existingStyle.value = t.jsxExpressionContainer(
170
- t.arrayExpression([styleAST, currentVal]),
171
- );
172
- } else {
173
- openingElement.attributes.push(
174
- t.jsxAttribute(t.jsxIdentifier(styleProp), t.jsxExpressionContainer(styleAST)),
175
- );
176
- }
177
-
178
- // Remove the static class attribute to achieve zero runtime parsing
179
- openingElement.attributes.splice(classAttrIndex, 1);
180
- }
181
- }
182
-
183
- /**
184
- * Convert JavaScript object to Babel AST
185
- */
186
- export function objectToAST(t, obj) {
187
- if (obj === null || obj === undefined) return t.nullLiteral();
188
-
189
- if (Array.isArray(obj)) {
190
- return t.arrayExpression(obj.map((item) => objectToAST(t, item)));
191
- }
192
-
193
- if (typeof obj === "object") {
194
- return t.objectExpression(
195
- Object.entries(obj).map(([key, value]) =>
196
- t.objectProperty(
197
- /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? t.identifier(key) : t.stringLiteral(key),
198
- objectToAST(t, value),
199
- ),
200
- ),
201
- );
202
- }
203
-
204
- if (typeof obj === "string") return t.stringLiteral(obj);
205
- if (typeof obj === "number") return t.numericLiteral(obj);
206
- if (typeof obj === "boolean") return t.booleanLiteral(obj);
207
-
208
- return t.nullLiteral();
209
- }
210
-
211
- /**
212
- * Try to get static style info for an element
213
- * Returns { staticStyles, hasInheritStyle, inlineStyleExpr } or null if not static
214
- */
215
- export function tryGetStaticStyleInfo(path, state, t) {
216
- const openingElement = path.node.openingElement;
217
-
218
- const classNameAttr = openingElement.attributes.find(
219
- (attr) => t.isJSXAttribute(attr) && attr.name?.name === "className",
220
- );
221
-
222
- // Check if className is static
223
- if (!isStaticClassName(t, classNameAttr)) return null;
224
-
225
- // Get stylesheet
226
- const stylesheet = state.stylesheetData;
227
- if (!stylesheet) return null;
228
-
229
- const classNameValue = getStaticClassNameValue(t, classNameAttr);
230
- if (!classNameValue) return null;
231
-
232
- // Check if all classes are fully static
233
- if (!areAllClassesStatic(stylesheet, classNameValue)) return null;
234
-
235
- // Compute static styles from className
236
- const staticStyles = computeStaticStyles(stylesheet, classNameValue);
237
-
238
- // Get inheritStyle attribute (for mergeStyles call)
239
- const inheritStyleAttr = openingElement.attributes.find(
240
- (attr) => t.isJSXAttribute(attr) && attr.name?.name === "inheritStyle",
241
- );
242
-
243
- // Get style attribute
244
- const styleAttr = openingElement.attributes.find(
245
- (attr) => t.isJSXAttribute(attr) && attr.name?.name === "style",
246
- );
247
-
248
- return {
249
- staticStyles,
250
- inheritStyleAttr,
251
- styleAttr,
252
- };
253
- }
254
-
255
- /**
256
- * Generate mergeStyles(inheritStyle, staticStyles, inlineStyle) expression
257
- */
258
- export function getStaticMergeExpression(path, state, t, staticInfo) {
259
- const { staticStyles, inheritStyleAttr, styleAttr } = staticInfo;
260
-
261
- // Get inheritStyle expression
262
- const propInheritStyle = getMemoizedInheritStyleExpression(path, t);
263
- const inheritStyleExpr = inheritStyleAttr?.value?.expression;
264
-
265
- // Build inheritStyle array: [props.inheritStyle, explicitInheritStyle]
266
- let inheritArg;
267
- if (propInheritStyle || inheritStyleExpr) {
268
- inheritArg = t.arrayExpression([
269
- propInheritStyle || t.nullLiteral(),
270
- inheritStyleExpr || t.nullLiteral(),
271
- ]);
272
- } else {
273
- inheritArg = t.nullLiteral();
274
- }
275
-
276
- // Static styles as inline object
277
- const staticArg =
278
- Object.keys(staticStyles).length > 0 ? objectToAST(t, staticStyles) : t.nullLiteral();
279
-
280
- // Inline style expression
281
- const inlineArg = styleAttr?.value?.expression || t.nullLiteral();
282
-
283
- // mergeStyles(inheritStyle, staticStyles, inlineStyle)
284
- return t.callExpression(state.mergeStylesId, [inheritArg, staticArg, inlineArg]);
285
- }
286
-
287
- // ============================================================================
288
- // InheritStyle helpers
289
- // ============================================================================
290
-
291
- const inheritStyleMemo = new WeakMap();
292
-
293
- function getMemoizedInheritStyleExpression(path, t) {
294
- let currentPath = path;
295
- let funcPath = null;
296
- while (currentPath && !funcPath) {
297
- if (currentPath.isFunction()) {
298
- funcPath = currentPath;
299
- break;
300
- }
301
- currentPath = currentPath.parentPath;
302
- }
303
- if (!funcPath) return undefined;
304
-
305
- if (inheritStyleMemo.has(funcPath.node)) {
306
- return inheritStyleMemo.get(funcPath.node);
307
- }
308
-
309
- let result;
310
- const params = funcPath.node.params;
311
- let parentPath = funcPath.parentPath;
312
-
313
- if (
314
- parentPath &&
315
- parentPath.isCallExpression() &&
316
- parentPath.node.callee &&
317
- parentPath.node.callee.type === "Identifier" &&
318
- ["useMemo", "useCallback"].includes(parentPath.node.callee.name)
319
- ) {
320
- result = undefined;
321
- } else if (params.length === 0) {
322
- funcPath.node.params = [t.identifier("props")];
323
- result = t.memberExpression(t.identifier("props"), t.identifier("inheritStyle"), false, false);
324
- } else if (params.length > 0) {
325
- const firstParam = params[0];
326
- if (t.isIdentifier(firstParam)) {
327
- result = t.memberExpression(firstParam, t.identifier("inheritStyle"), false, false);
328
- } else if (t.isObjectPattern(firstParam)) {
329
- const restElement = firstParam.properties.find((p) => t.isRestElement(p));
330
- if (restElement) {
331
- result = t.memberExpression(
332
- restElement.argument,
333
- t.identifier("inheritStyle"),
334
- false,
335
- false,
336
- );
337
- } else {
338
- const restProp = t.restElement(t.identifier("rest"));
339
- firstParam.properties.push(restProp);
340
- result = t.memberExpression(
341
- t.identifier("rest"),
342
- t.identifier("inheritStyle"),
343
- false,
344
- false,
345
- );
346
- }
347
- }
348
- }
349
-
350
- inheritStyleMemo.set(funcPath.node, result);
351
- return result;
352
- }
353
-
354
- // ============================================================================
355
- // Style expression generators (for dynamic/fallback cases)
356
- // ============================================================================
357
-
358
- export function getStyleExpression(path, state, t) {
359
- const openingElement = path.node.openingElement;
360
- const elementName = openingElement.name;
361
-
362
- const propInheritStyle = getMemoizedInheritStyleExpression(path, t);
363
- const inheritStyle = openingElement.attributes.find((attr) => attr.name?.name === "inheritStyle");
364
- const className = openingElement.attributes.find((attr) => attr.name?.name === "className");
365
- const style = openingElement.attributes.find((attr) => attr.name?.name === "style");
366
-
367
- return t.callExpression(state.getStyleId, [
368
- state.stylesheetId,
369
- t.arrayExpression([
370
- t.arrayExpression([
371
- propInheritStyle || t.nullLiteral(),
372
- (inheritStyle && inheritStyle.value.expression) || t.nullLiteral(),
373
- ]),
374
- (className &&
375
- (t.isStringLiteral(className.value)
376
- ? t.stringLiteral(className.value.value)
377
- : className.value.expression)) ||
378
- t.nullLiteral(),
379
- (style && style.value.expression) || t.nullLiteral(),
380
- t.isJSXIdentifier(elementName)
381
- ? t.stringLiteral(elementName.name)
382
- : t.isJSXMemberExpression(elementName)
383
- ? t.stringLiteral(`${elementName.object.name}.${elementName.property.name}`)
384
- : t.stringLiteral("Unknown"),
385
- ]),
386
- ]);
387
- }
388
-
389
- export function getInheritStyleExpression(path, state, t) {
390
- const openingElement = path.node.openingElement;
391
- const inheritStyle = openingElement.attributes.find((attr) => attr.name?.name === "inheritStyle");
392
-
393
- const propInheritStyle = getMemoizedInheritStyleExpression(path, t);
394
- const inheritStyleExpr = inheritStyle?.value?.expression || propInheritStyle;
395
-
396
- const classNameAttr = openingElement.attributes.find((attr) => attr.name?.name === "className");
397
- const styleAttr = openingElement.attributes.find((attr) => attr.name?.name === "style");
398
-
399
- return t.callExpression(state.getInheritStyleId, [
400
- t.callExpression(state.getStyleId, [
401
- state.stylesheetId,
402
- t.arrayExpression([
403
- inheritStyleExpr || t.nullLiteral(),
404
- (classNameAttr?.value &&
405
- (t.isStringLiteral(classNameAttr.value)
406
- ? t.stringLiteral(classNameAttr.value.value)
407
- : classNameAttr.value.expression)) ||
408
- t.nullLiteral(),
409
- styleAttr?.value?.expression || t.nullLiteral(),
410
- t.isJSXIdentifier(openingElement.name)
411
- ? t.stringLiteral(openingElement.name.name)
412
- : t.isJSXMemberExpression(openingElement.name)
413
- ? t.stringLiteral(
414
- `${openingElement.name.object.name}.${openingElement.name.property.name}`,
415
- )
416
- : t.stringLiteral("Unknown"),
417
- ]),
418
- ]),
419
- ]);
420
- }
421
-
422
- export function getRootInheritStyleExpression(path, t) {
423
- const propInheritStyle = getMemoizedInheritStyleExpression(path, t);
424
- return propInheritStyle || t.identifier("undefined");
425
- }
package/src/utils/css.js DELETED
@@ -1,221 +0,0 @@
1
- import { transform } from "lightningcss";
2
- import { camelize } from "./helper";
3
-
4
- /**
5
- * Unwrap @layer and @supports blocks to expose standard CSS rules
6
- */
7
- function flattenBlocks(cssStr) {
8
- let result = "";
9
- let i = 0;
10
- const len = cssStr.length;
11
-
12
- while (i < len) {
13
- // Skip comments
14
- if (cssStr[i] === "/" && cssStr[i + 1] === "*") {
15
- const commentEnd = cssStr.indexOf("*/", i + 2);
16
- if (commentEnd === -1) {
17
- result += cssStr.substring(i);
18
- break;
19
- }
20
- result += cssStr.substring(i, commentEnd + 2);
21
- i = commentEnd + 2;
22
- continue;
23
- }
24
-
25
- // Skip strings
26
- if (cssStr[i] === '"' || cssStr[i] === "'") {
27
- const char = cssStr[i];
28
- let strEnd = i + 1;
29
- while (strEnd < len) {
30
- if (cssStr[strEnd] === "\\") {
31
- strEnd += 2;
32
- } else if (cssStr[strEnd] === char) {
33
- strEnd++;
34
- break;
35
- } else {
36
- strEnd++;
37
- }
38
- }
39
- result += cssStr.substring(i, strEnd);
40
- i = strEnd;
41
- continue;
42
- }
43
-
44
- // Check for at-rules
45
- if (cssStr[i] === "@") {
46
- const remaining = cssStr.substring(i);
47
- const layerMatch = remaining.match(/^@(layer|supports|property)[^{]*\{/i);
48
- if (layerMatch) {
49
- const layerType = layerMatch[1].toLowerCase();
50
- // Skip @layer base entirely because React Native views should not inherit browser base resets (* { border: 0 solid; margin: 0 })
51
- const isLayerBase = /^@layer\s+base\s*\{/i.test(layerMatch[0]);
52
- if (layerType === "property" || isLayerBase) {
53
- let braceCount = 1;
54
- let j = i + layerMatch[0].length;
55
- while (j < len && braceCount > 0) {
56
- if (cssStr[j] === "{") braceCount++;
57
- else if (cssStr[j] === "}") braceCount--;
58
- j++;
59
- }
60
- i = j;
61
- continue;
62
- }
63
-
64
- let braceCount = 1;
65
- let j = i + layerMatch[0].length;
66
- let innerContent = "";
67
- while (j < len && braceCount > 0) {
68
- if (cssStr[j] === "{") braceCount++;
69
- else if (cssStr[j] === "}") braceCount--;
70
- if (braceCount > 0) innerContent += cssStr[j];
71
- j++;
72
- }
73
- result += flattenBlocks(innerContent);
74
- i = j;
75
- continue;
76
- }
77
- }
78
-
79
- result += cssStr[i];
80
- i++;
81
- }
82
-
83
- return result;
84
- }
85
-
86
- /**
87
- * Parse and lower modern CSS using LightningCSS (Rust-based engine)
88
- * Handles OKLCH, color-mix, CSS nesting, @layer, and @media range queries
89
- */
90
- export function parseStylesheetWithLightning(rawCss) {
91
- const transformed = transform({
92
- filename: "input.css",
93
- code: Buffer.from(rawCss),
94
- targets: {
95
- safari: 14 << 16,
96
- },
97
- minify: false,
98
- });
99
-
100
- const cssText = flattenBlocks(transformed.code.toString());
101
- const rawStylesheet = {};
102
-
103
- const cleanSelector = (sel) => {
104
- if (sel.includes(":root")) return [":root"];
105
-
106
- let s = sel.trim();
107
- if (!s.startsWith(".")) return [];
108
-
109
- // Strip leading dot
110
- s = s.slice(1);
111
-
112
- // Extract class name (handling escaped chars like active\:scale-95, w-\[48\%\], etc.)
113
- let classPart = "";
114
- let i = 0;
115
- while (i < s.length) {
116
- if (s[i] === "\\") {
117
- if (i + 1 < s.length) {
118
- classPart += s[i + 1];
119
- i += 2;
120
- continue;
121
- }
122
- }
123
- if (s[i] === ":" || s[i] === " " || s[i] === ">" || s[i] === "~" || s[i] === "+") {
124
- break;
125
- }
126
- classPart += s[i];
127
- i++;
128
- }
129
-
130
- if (!classPart) return [];
131
-
132
- const names = [classPart];
133
-
134
- // For variants like disabled:bg-navy-300 or active:opacity-80, also register the base class name
135
- if (
136
- classPart.startsWith("disabled:") ||
137
- classPart.startsWith("active:") ||
138
- classPart.startsWith("pressed:")
139
- ) {
140
- const base = classPart.replace(/^(disabled|active|pressed):/, "");
141
- if (base && !names.includes(base)) {
142
- names.push(base);
143
- }
144
- }
145
-
146
- return names;
147
- };
148
-
149
- const parseDeclarations = (bodyText) => {
150
- const decls = {};
151
- const parts = bodyText.split(";");
152
- for (const part of parts) {
153
- const trimmed = part.trim();
154
- if (!trimmed) continue;
155
- const colonIdx = trimmed.indexOf(":");
156
- if (colonIdx === -1) continue;
157
- const prop = trimmed.slice(0, colonIdx).trim();
158
- const val = trimmed.slice(colonIdx + 1).trim();
159
- if (!prop || !val) continue;
160
-
161
- if (prop.startsWith("--")) {
162
- decls[prop] = val;
163
- } else {
164
- decls[camelize(prop)] = val;
165
- }
166
- }
167
- return decls;
168
- };
169
-
170
- // 1. Separate media query blocks
171
- const mediaBlocks = [];
172
- const noMediaCss = cssText.replace(/@media\s*([^{]+)\{([\s\S]+?\}\s*)\}/g, (_, query, inner) => {
173
- mediaBlocks.push({ query: query.trim(), inner });
174
- return "";
175
- });
176
-
177
- // 2. Parse regular rules
178
- const ruleRe = /([^{}]+)\{([^{}]+)\}/g;
179
- let match;
180
- while ((match = ruleRe.exec(noMediaCss)) !== null) {
181
- const rawSelectors = match[1].trim();
182
- const body = match[2].trim();
183
- if (rawSelectors.startsWith("@")) continue;
184
-
185
- const selectors = rawSelectors.split(",").map((s) => s.trim());
186
- const decls = parseDeclarations(body);
187
-
188
- for (const sel of selectors) {
189
- if (!sel.startsWith(".") && !sel.includes(":root")) continue;
190
- const names = cleanSelector(sel);
191
- for (const name of names) {
192
- rawStylesheet[name] = { ...rawStylesheet[name], ...decls };
193
- }
194
- }
195
- }
196
-
197
- // 3. Parse media query rules
198
- for (const mb of mediaBlocks) {
199
- let mMatch;
200
- const mRuleRe = /([^{}]+)\{([^{}]+)\}/g;
201
- while ((mMatch = mRuleRe.exec(mb.inner)) !== null) {
202
- const rawSelectors = mMatch[1].trim();
203
- const body = mMatch[2].trim();
204
- const selectors = rawSelectors.split(",").map((s) => s.trim());
205
- const decls = parseDeclarations(body);
206
-
207
- for (const sel of selectors) {
208
- if (!sel.startsWith(".") && !sel.includes(":root")) continue;
209
- const names = cleanSelector(sel);
210
- for (const name of names) {
211
- rawStylesheet[name] = {
212
- ...rawStylesheet[name],
213
- [`@media ${mb.query}`]: decls,
214
- };
215
- }
216
- }
217
- }
218
- }
219
-
220
- return rawStylesheet;
221
- }
@@ -1,3 +0,0 @@
1
- export function camelize(str) {
2
- return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (_, chr) => chr.toUpperCase());
3
- }