chaincss 2.4.0 → 2.4.1

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/dist/cli/index.js CHANGED
@@ -276,11 +276,27 @@ function compileToCSS(styleObject, options = {}) {
276
276
  ...properties
277
277
  } = styleObject;
278
278
  const effectiveSelector = selectors?.join(", ") || scope;
279
- const mainDeclarations = compileDeclarations(properties, indent, options);
279
+ const pseudoClasses = {};
280
+ const regularProps = {};
281
+ for (const [key, value] of Object.entries(properties)) {
282
+ if (key.startsWith("&:")) {
283
+ pseudoClasses[key.substring(1)] = value;
284
+ } else if (!key.startsWith("_")) {
285
+ regularProps[key] = value;
286
+ }
287
+ }
288
+ const mainDeclarations = compileDeclarations(regularProps, indent, options);
280
289
  if (mainDeclarations.length > 0 && effectiveSelector) {
281
290
  const source = options.sourceMap && options.sourceFile ? `/* ${options.sourceFile} */${newline}` : "";
282
291
  parts.push(`${source}${effectiveSelector} {${newline}${mainDeclarations.join(newline)}${newline}}`);
283
292
  }
293
+ for (const [pseudo, pseudoStyles] of Object.entries(pseudoClasses)) {
294
+ const pseudoSelector = `${effectiveSelector}${pseudo}`;
295
+ const pseudoDeclarations = compileDeclarations(pseudoStyles, indent, options);
296
+ if (pseudoDeclarations.length > 0) {
297
+ parts.push(`${pseudoSelector} {${newline}${pseudoDeclarations.join(newline)}${newline}}`);
298
+ }
299
+ }
284
300
  for (const rule of _atRules) {
285
301
  const compiled = compileAtRule(rule, effectiveSelector, indent, newline, options);
286
302
  if (compiled) parts.push(compiled);
@@ -300,16 +316,6 @@ function compileDeclarations(properties, indent, options) {
300
316
  for (const [prop, value] of Object.entries(properties)) {
301
317
  if (prop.startsWith("_")) continue;
302
318
  if (typeof value === "function") continue;
303
- if (prop.startsWith("&:")) {
304
- const pseudo = prop.substring(1);
305
- const pseudoLines = compileDeclarations(value, indent + indent, options);
306
- if (pseudoLines.length > 0) {
307
- lines.push(`${indent}${pseudo} {`);
308
- lines.push(...pseudoLines);
309
- lines.push(`${indent}}`);
310
- }
311
- continue;
312
- }
313
319
  if (typeof value === "object" && value !== null && !Array.isArray(value)) {
314
320
  continue;
315
321
  }
@@ -1592,11 +1592,27 @@ function compileToCSS(styleObject, options = {}) {
1592
1592
  ...properties
1593
1593
  } = styleObject;
1594
1594
  const effectiveSelector = selectors?.join(", ") || scope;
1595
- const mainDeclarations = compileDeclarations(properties, indent, options);
1595
+ const pseudoClasses = {};
1596
+ const regularProps = {};
1597
+ for (const [key, value] of Object.entries(properties)) {
1598
+ if (key.startsWith("&:")) {
1599
+ pseudoClasses[key.substring(1)] = value;
1600
+ } else if (!key.startsWith("_")) {
1601
+ regularProps[key] = value;
1602
+ }
1603
+ }
1604
+ const mainDeclarations = compileDeclarations(regularProps, indent, options);
1596
1605
  if (mainDeclarations.length > 0 && effectiveSelector) {
1597
1606
  const source = options.sourceMap && options.sourceFile ? `/* ${options.sourceFile} */${newline}` : "";
1598
1607
  parts.push(`${source}${effectiveSelector} {${newline}${mainDeclarations.join(newline)}${newline}}`);
1599
1608
  }
1609
+ for (const [pseudo, pseudoStyles] of Object.entries(pseudoClasses)) {
1610
+ const pseudoSelector = `${effectiveSelector}${pseudo}`;
1611
+ const pseudoDeclarations = compileDeclarations(pseudoStyles, indent, options);
1612
+ if (pseudoDeclarations.length > 0) {
1613
+ parts.push(`${pseudoSelector} {${newline}${pseudoDeclarations.join(newline)}${newline}}`);
1614
+ }
1615
+ }
1600
1616
  for (const rule of _atRules) {
1601
1617
  const compiled = compileAtRule(rule, effectiveSelector, indent, newline, options);
1602
1618
  if (compiled) parts.push(compiled);
@@ -1616,16 +1632,6 @@ function compileDeclarations(properties, indent, options) {
1616
1632
  for (const [prop, value] of Object.entries(properties)) {
1617
1633
  if (prop.startsWith("_")) continue;
1618
1634
  if (typeof value === "function") continue;
1619
- if (prop.startsWith("&:")) {
1620
- const pseudo = prop.substring(1);
1621
- const pseudoLines = compileDeclarations(value, indent + indent, options);
1622
- if (pseudoLines.length > 0) {
1623
- lines.push(`${indent}${pseudo} {`);
1624
- lines.push(...pseudoLines);
1625
- lines.push(`${indent}}`);
1626
- }
1627
- continue;
1628
- }
1629
1635
  if (typeof value === "object" && value !== null && !Array.isArray(value)) {
1630
1636
  continue;
1631
1637
  }
package/dist/index.js CHANGED
@@ -1525,11 +1525,27 @@ function compileToCSS(styleObject, options = {}) {
1525
1525
  ...properties
1526
1526
  } = styleObject;
1527
1527
  const effectiveSelector = selectors?.join(", ") || scope;
1528
- const mainDeclarations = compileDeclarations(properties, indent, options);
1528
+ const pseudoClasses = {};
1529
+ const regularProps = {};
1530
+ for (const [key, value] of Object.entries(properties)) {
1531
+ if (key.startsWith("&:")) {
1532
+ pseudoClasses[key.substring(1)] = value;
1533
+ } else if (!key.startsWith("_")) {
1534
+ regularProps[key] = value;
1535
+ }
1536
+ }
1537
+ const mainDeclarations = compileDeclarations(regularProps, indent, options);
1529
1538
  if (mainDeclarations.length > 0 && effectiveSelector) {
1530
1539
  const source = options.sourceMap && options.sourceFile ? `/* ${options.sourceFile} */${newline}` : "";
1531
1540
  parts.push(`${source}${effectiveSelector} {${newline}${mainDeclarations.join(newline)}${newline}}`);
1532
1541
  }
1542
+ for (const [pseudo, pseudoStyles] of Object.entries(pseudoClasses)) {
1543
+ const pseudoSelector = `${effectiveSelector}${pseudo}`;
1544
+ const pseudoDeclarations = compileDeclarations(pseudoStyles, indent, options);
1545
+ if (pseudoDeclarations.length > 0) {
1546
+ parts.push(`${pseudoSelector} {${newline}${pseudoDeclarations.join(newline)}${newline}}`);
1547
+ }
1548
+ }
1533
1549
  for (const rule of _atRules) {
1534
1550
  const compiled = compileAtRule(rule, effectiveSelector, indent, newline, options);
1535
1551
  if (compiled) parts.push(compiled);
@@ -1549,16 +1565,6 @@ function compileDeclarations(properties, indent, options) {
1549
1565
  for (const [prop, value] of Object.entries(properties)) {
1550
1566
  if (prop.startsWith("_")) continue;
1551
1567
  if (typeof value === "function") continue;
1552
- if (prop.startsWith("&:")) {
1553
- const pseudo = prop.substring(1);
1554
- const pseudoLines = compileDeclarations(value, indent + indent, options);
1555
- if (pseudoLines.length > 0) {
1556
- lines.push(`${indent}${pseudo} {`);
1557
- lines.push(...pseudoLines);
1558
- lines.push(`${indent}}`);
1559
- }
1560
- continue;
1561
- }
1562
1568
  if (typeof value === "object" && value !== null && !Array.isArray(value)) {
1563
1569
  continue;
1564
1570
  }
@@ -249,11 +249,27 @@ function compileToCSS(styleObject, options = {}) {
249
249
  ...properties
250
250
  } = styleObject;
251
251
  const effectiveSelector = selectors?.join(", ") || scope;
252
- const mainDeclarations = compileDeclarations(properties, indent, options);
252
+ const pseudoClasses = {};
253
+ const regularProps = {};
254
+ for (const [key, value] of Object.entries(properties)) {
255
+ if (key.startsWith("&:")) {
256
+ pseudoClasses[key.substring(1)] = value;
257
+ } else if (!key.startsWith("_")) {
258
+ regularProps[key] = value;
259
+ }
260
+ }
261
+ const mainDeclarations = compileDeclarations(regularProps, indent, options);
253
262
  if (mainDeclarations.length > 0 && effectiveSelector) {
254
263
  const source = options.sourceMap && options.sourceFile ? `/* ${options.sourceFile} */${newline}` : "";
255
264
  parts.push(`${source}${effectiveSelector} {${newline}${mainDeclarations.join(newline)}${newline}}`);
256
265
  }
266
+ for (const [pseudo, pseudoStyles] of Object.entries(pseudoClasses)) {
267
+ const pseudoSelector = `${effectiveSelector}${pseudo}`;
268
+ const pseudoDeclarations = compileDeclarations(pseudoStyles, indent, options);
269
+ if (pseudoDeclarations.length > 0) {
270
+ parts.push(`${pseudoSelector} {${newline}${pseudoDeclarations.join(newline)}${newline}}`);
271
+ }
272
+ }
257
273
  for (const rule of _atRules) {
258
274
  const compiled = compileAtRule(rule, effectiveSelector, indent, newline, options);
259
275
  if (compiled) parts.push(compiled);
@@ -273,16 +289,6 @@ function compileDeclarations(properties, indent, options) {
273
289
  for (const [prop, value] of Object.entries(properties)) {
274
290
  if (prop.startsWith("_")) continue;
275
291
  if (typeof value === "function") continue;
276
- if (prop.startsWith("&:")) {
277
- const pseudo = prop.substring(1);
278
- const pseudoLines = compileDeclarations(value, indent + indent, options);
279
- if (pseudoLines.length > 0) {
280
- lines.push(`${indent}${pseudo} {`);
281
- lines.push(...pseudoLines);
282
- lines.push(`${indent}}`);
283
- }
284
- continue;
285
- }
286
292
  if (typeof value === "object" && value !== null && !Array.isArray(value)) {
287
293
  continue;
288
294
  }
@@ -54,11 +54,27 @@ function compileToCSS(styleObject, options = {}) {
54
54
  ...properties
55
55
  } = styleObject;
56
56
  const effectiveSelector = selectors?.join(", ") || scope;
57
- const mainDeclarations = compileDeclarations(properties, indent, options);
57
+ const pseudoClasses = {};
58
+ const regularProps = {};
59
+ for (const [key, value] of Object.entries(properties)) {
60
+ if (key.startsWith("&:")) {
61
+ pseudoClasses[key.substring(1)] = value;
62
+ } else if (!key.startsWith("_")) {
63
+ regularProps[key] = value;
64
+ }
65
+ }
66
+ const mainDeclarations = compileDeclarations(regularProps, indent, options);
58
67
  if (mainDeclarations.length > 0 && effectiveSelector) {
59
68
  const source = options.sourceMap && options.sourceFile ? `/* ${options.sourceFile} */${newline}` : "";
60
69
  parts.push(`${source}${effectiveSelector} {${newline}${mainDeclarations.join(newline)}${newline}}`);
61
70
  }
71
+ for (const [pseudo, pseudoStyles] of Object.entries(pseudoClasses)) {
72
+ const pseudoSelector = `${effectiveSelector}${pseudo}`;
73
+ const pseudoDeclarations = compileDeclarations(pseudoStyles, indent, options);
74
+ if (pseudoDeclarations.length > 0) {
75
+ parts.push(`${pseudoSelector} {${newline}${pseudoDeclarations.join(newline)}${newline}}`);
76
+ }
77
+ }
62
78
  for (const rule of _atRules) {
63
79
  const compiled = compileAtRule(rule, effectiveSelector, indent, newline, options);
64
80
  if (compiled) parts.push(compiled);
@@ -78,16 +94,6 @@ function compileDeclarations(properties, indent, options) {
78
94
  for (const [prop, value] of Object.entries(properties)) {
79
95
  if (prop.startsWith("_")) continue;
80
96
  if (typeof value === "function") continue;
81
- if (prop.startsWith("&:")) {
82
- const pseudo = prop.substring(1);
83
- const pseudoLines = compileDeclarations(value, indent + indent, options);
84
- if (pseudoLines.length > 0) {
85
- lines.push(`${indent}${pseudo} {`);
86
- lines.push(...pseudoLines);
87
- lines.push(`${indent}}`);
88
- }
89
- continue;
90
- }
91
97
  if (typeof value === "object" && value !== null && !Array.isArray(value)) {
92
98
  continue;
93
99
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chaincss",
3
- "version": "2.4.0",
3
+ "version": "2.4.1",
4
4
  "description": "ChainCSS - The first CSS-in-JS library with true auto-detection mixed mode. Zero runtime by default, dynamic when you need it.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -67,8 +67,19 @@ export function compileToCSS(
67
67
  // Use explicit selectors if provided, otherwise use scopeSelector
68
68
  const effectiveSelector = selectors?.join(', ') || scope;
69
69
 
70
- // Generate main declarations
71
- const mainDeclarations = compileDeclarations(properties, indent, options);
70
+ // Separate pseudo-classes (&:hover, &:focus) from regular properties
71
+ const pseudoClasses: Record<string, Record<string, any>> = {};
72
+ const regularProps: Record<string, any> = {};
73
+ for (const [key, value] of Object.entries(properties)) {
74
+ if (key.startsWith('&:')) {
75
+ pseudoClasses[key.substring(1)] = value as Record<string, any>; // :hover, :focus
76
+ } else if (!key.startsWith('_')) {
77
+ regularProps[key] = value;
78
+ }
79
+ }
80
+
81
+ // Generate main declarations (without pseudo-classes)
82
+ const mainDeclarations = compileDeclarations(regularProps, indent, options);
72
83
 
73
84
  if (mainDeclarations.length > 0 && effectiveSelector) {
74
85
  const source = options.sourceMap && options.sourceFile
@@ -77,6 +88,15 @@ export function compileToCSS(
77
88
  parts.push(`${source}${effectiveSelector} {${newline}${mainDeclarations.join(newline)}${newline}}`);
78
89
  }
79
90
 
91
+ // Generate pseudo-class rules as separate selectors
92
+ for (const [pseudo, pseudoStyles] of Object.entries(pseudoClasses)) {
93
+ const pseudoSelector = `${effectiveSelector}${pseudo}`;
94
+ const pseudoDeclarations = compileDeclarations(pseudoStyles, indent, options);
95
+ if (pseudoDeclarations.length > 0) {
96
+ parts.push(`${pseudoSelector} {${newline}${pseudoDeclarations.join(newline)}${newline}}`);
97
+ }
98
+ }
99
+
80
100
  // Process at-rules
81
101
  for (const rule of _atRules) {
82
102
  const compiled = compileAtRule(rule, effectiveSelector, indent, newline, options);
@@ -116,21 +136,9 @@ function compileDeclarations(
116
136
  // Skip functions (can't compile to static CSS)
117
137
  if (typeof value === 'function') continue;
118
138
 
119
- // Handle pseudo-classes (&:hover, &:focus, etc.)
120
- if (prop.startsWith('&:')) {
121
- const pseudo = prop.substring(1); // :hover
122
- const pseudoLines = compileDeclarations(value, indent + indent, options);
123
- if (pseudoLines.length > 0) {
124
- lines.push(`${indent}${pseudo} {`);
125
- lines.push(...pseudoLines);
126
- lines.push(`${indent}}`);
127
- }
128
- continue;
129
- }
130
-
131
139
  // Handle nested objects (could be nested pseudo-elements)
132
140
  if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
133
- // Skip — handled by nested rules
141
+ // Skip — handled by nested rules or pseudo-class extraction
134
142
  continue;
135
143
  }
136
144