tailwind-to-style 3.2.0 → 3.2.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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * tailwind-to-style v3.2.0
2
+ * tailwind-to-style v3.2.1
3
3
  * Runtime Tailwind CSS to inline styles converter
4
4
  *
5
5
  * @author Bigetion
@@ -8342,7 +8342,7 @@ function processClass(cls, selector, styles) {
8342
8342
 
8343
8343
  // Get cssObject from singleton cache
8344
8344
  const cssObject = tailwindCache.getOrGenerate(generateTailwindCssString, convertCssToObject);
8345
- let declarations = cssObject[baseClassName] || cssObject[baseClassName.replace(ESCAPE_SLASH_REGEX, "\\$1")] || cssObject[baseClassName.replace(ESCAPE_DOT_REGEX, "\\.")];
8345
+ let declarations = cssObject[baseClassName] || cssObject[baseClassName.replace(ESCAPE_SLASH_REGEX, "\\/")] || cssObject[baseClassName.replace(ESCAPE_DOT_REGEX, "\\.")];
8346
8346
  if (!declarations && baseClassName.includes("[")) {
8347
8347
  const match = CUSTOM_VALUE_FULL_REGEX.exec(baseClassName);
8348
8348
  if (match) {
@@ -8564,11 +8564,26 @@ function flattenStyleObject(obj) {
8564
8564
  flatArray.push(item);
8565
8565
  } else if (isSelectorObject(item)) {
8566
8566
  const nested = flattenStyleObject(item, currentSelector);
8567
- Object.assign(result, nested);
8567
+ // Merge nested results, handling & that resolves to same selector
8568
+ for (const ns in nested) {
8569
+ if (ns === currentSelector) {
8570
+ // & resolved to same selector — include in this array
8571
+ if (Array.isArray(nested[ns])) {
8572
+ flatArray.push(...nested[ns]);
8573
+ } else {
8574
+ flatArray.push(nested[ns]);
8575
+ }
8576
+ } else {
8577
+ result[ns] = nested[ns];
8578
+ }
8579
+ }
8568
8580
  }
8569
8581
  }
8570
8582
  if (flatArray.length > 0) {
8571
8583
  result[currentSelector] = result[currentSelector] || [];
8584
+ if (!Array.isArray(result[currentSelector])) {
8585
+ result[currentSelector] = [result[currentSelector]];
8586
+ }
8572
8587
  result[currentSelector].push(...flatArray);
8573
8588
  }
8574
8589
  } else if (isSelectorObject(val)) {
@@ -8700,6 +8715,20 @@ function twsxNoCache(obj) {
8700
8715
  // Process each selector within the media query
8701
8716
  for (const innerSelector in val) {
8702
8717
  const innerVal = val[innerSelector];
8718
+
8719
+ // Handle @css string directive inside media queries
8720
+ if (typeof innerVal === "string") {
8721
+ const trimmedInner = innerVal.trim();
8722
+ if (trimmedInner.startsWith('@css')) {
8723
+ const cssMatch = trimmedInner.match(/^@css\s*\{([\s\S]*)\}\s*$/);
8724
+ if (cssMatch) {
8725
+ const rawCss = cssMatch[1].trim();
8726
+ styles[selector][innerSelector] = styles[selector][innerSelector] || '';
8727
+ styles[selector][innerSelector] += rawCss.split(';').filter(d => d.trim()).map(d => d.trim() + ';').join(' ') + '\n';
8728
+ continue;
8729
+ }
8730
+ }
8731
+ }
8703
8732
  const baseClass = typeof innerVal === "string" ? expandGroupedClass(innerVal) : "";
8704
8733
 
8705
8734
  // Process Tailwind classes for this selector
@@ -8739,6 +8768,17 @@ function twsxNoCache(obj) {
8739
8768
  } else if (Array.isArray(val)) {
8740
8769
  for (const item of val) {
8741
8770
  if (typeof item === "string") {
8771
+ // Handle @css strings inside arrays
8772
+ const trimmedItem = item.trim();
8773
+ if (trimmedItem.startsWith('@css')) {
8774
+ const cssMatch = trimmedItem.match(/^@css\s*\{([\s\S]*)\}\s*$/);
8775
+ if (cssMatch) {
8776
+ const rawCss = cssMatch[1].trim();
8777
+ styles[selector] = styles[selector] || '';
8778
+ styles[selector] += rawCss.split(';').filter(d => d.trim()).map(d => d.trim() + ';').join(' ') + '\n';
8779
+ continue;
8780
+ }
8781
+ }
8742
8782
  baseClass += (baseClass ? " " : "") + expandGroupedClass(item);
8743
8783
  } else if (typeof item === "object" && item !== null) {
8744
8784
  Object.assign(nested, item);
@@ -9293,6 +9333,9 @@ function twsxVariantsNoCache(className) {
9293
9333
  // Skip if it's the default value
9294
9334
  if (value === defaultVariants[key]) continue;
9295
9335
 
9336
+ // Skip if the variant value doesn't exist in the variant options
9337
+ if (!variants[key].hasOwnProperty(value) && value !== true && value !== "true" && value !== false && value !== "false") continue;
9338
+
9296
9339
  // Handle boolean variants
9297
9340
  if (value === true || value === "true") {
9298
9341
  variantParts.push(key);
@@ -9502,30 +9545,11 @@ function autoInjectCss(cssString) {
9502
9545
  document.head.appendChild(styleTag);
9503
9546
  }
9504
9547
 
9505
- // Use insertRule for better performance (avoids full stylesheet reparse)
9506
- try {
9507
- const sheet = styleTag.sheet;
9508
- if (sheet) {
9509
- // Split CSS by closing brace to insert individual rules
9510
- const rules = cssString.split('}').filter(r => r.trim());
9511
- for (const rule of rules) {
9512
- const trimmed = rule.trim();
9513
- if (trimmed) {
9514
- try {
9515
- sheet.insertRule(trimmed + '}', sheet.cssRules.length);
9516
- } catch (e) {
9517
- // Fallback for complex rules (e.g., @keyframes, @media)
9518
- styleTag.textContent += `\n${trimmed}}`;
9519
- }
9520
- }
9521
- }
9522
- } else {
9523
- styleTag.textContent += `\n${cssString}`;
9524
- }
9525
- } catch (e) {
9526
- // Ultimate fallback
9527
- styleTag.textContent += `\n${cssString}`;
9528
- }
9548
+ // Append CSS to style tag using textContent for reliability
9549
+ // Note: insertRule + textContent mixing destroys CSSOM rules,
9550
+ // so we use textContent exclusively for consistent behavior
9551
+ // with @keyframes, @media, and other nested CSS blocks.
9552
+ styleTag.textContent += `\n${cssString}`;
9529
9553
 
9530
9554
  // Log injection stats periodically
9531
9555
  if (injectedCssHashSet.size % 10 === 0) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * tailwind-to-style v3.2.0
2
+ * tailwind-to-style v3.2.1
3
3
  * Runtime Tailwind CSS to inline styles converter
4
4
  *
5
5
  * @author Bigetion
@@ -8340,7 +8340,7 @@ function processClass(cls, selector, styles) {
8340
8340
 
8341
8341
  // Get cssObject from singleton cache
8342
8342
  const cssObject = tailwindCache.getOrGenerate(generateTailwindCssString, convertCssToObject);
8343
- let declarations = cssObject[baseClassName] || cssObject[baseClassName.replace(ESCAPE_SLASH_REGEX, "\\$1")] || cssObject[baseClassName.replace(ESCAPE_DOT_REGEX, "\\.")];
8343
+ let declarations = cssObject[baseClassName] || cssObject[baseClassName.replace(ESCAPE_SLASH_REGEX, "\\/")] || cssObject[baseClassName.replace(ESCAPE_DOT_REGEX, "\\.")];
8344
8344
  if (!declarations && baseClassName.includes("[")) {
8345
8345
  const match = CUSTOM_VALUE_FULL_REGEX.exec(baseClassName);
8346
8346
  if (match) {
@@ -8562,11 +8562,26 @@ function flattenStyleObject(obj) {
8562
8562
  flatArray.push(item);
8563
8563
  } else if (isSelectorObject(item)) {
8564
8564
  const nested = flattenStyleObject(item, currentSelector);
8565
- Object.assign(result, nested);
8565
+ // Merge nested results, handling & that resolves to same selector
8566
+ for (const ns in nested) {
8567
+ if (ns === currentSelector) {
8568
+ // & resolved to same selector — include in this array
8569
+ if (Array.isArray(nested[ns])) {
8570
+ flatArray.push(...nested[ns]);
8571
+ } else {
8572
+ flatArray.push(nested[ns]);
8573
+ }
8574
+ } else {
8575
+ result[ns] = nested[ns];
8576
+ }
8577
+ }
8566
8578
  }
8567
8579
  }
8568
8580
  if (flatArray.length > 0) {
8569
8581
  result[currentSelector] = result[currentSelector] || [];
8582
+ if (!Array.isArray(result[currentSelector])) {
8583
+ result[currentSelector] = [result[currentSelector]];
8584
+ }
8570
8585
  result[currentSelector].push(...flatArray);
8571
8586
  }
8572
8587
  } else if (isSelectorObject(val)) {
@@ -8698,6 +8713,20 @@ function twsxNoCache(obj) {
8698
8713
  // Process each selector within the media query
8699
8714
  for (const innerSelector in val) {
8700
8715
  const innerVal = val[innerSelector];
8716
+
8717
+ // Handle @css string directive inside media queries
8718
+ if (typeof innerVal === "string") {
8719
+ const trimmedInner = innerVal.trim();
8720
+ if (trimmedInner.startsWith('@css')) {
8721
+ const cssMatch = trimmedInner.match(/^@css\s*\{([\s\S]*)\}\s*$/);
8722
+ if (cssMatch) {
8723
+ const rawCss = cssMatch[1].trim();
8724
+ styles[selector][innerSelector] = styles[selector][innerSelector] || '';
8725
+ styles[selector][innerSelector] += rawCss.split(';').filter(d => d.trim()).map(d => d.trim() + ';').join(' ') + '\n';
8726
+ continue;
8727
+ }
8728
+ }
8729
+ }
8701
8730
  const baseClass = typeof innerVal === "string" ? expandGroupedClass(innerVal) : "";
8702
8731
 
8703
8732
  // Process Tailwind classes for this selector
@@ -8737,6 +8766,17 @@ function twsxNoCache(obj) {
8737
8766
  } else if (Array.isArray(val)) {
8738
8767
  for (const item of val) {
8739
8768
  if (typeof item === "string") {
8769
+ // Handle @css strings inside arrays
8770
+ const trimmedItem = item.trim();
8771
+ if (trimmedItem.startsWith('@css')) {
8772
+ const cssMatch = trimmedItem.match(/^@css\s*\{([\s\S]*)\}\s*$/);
8773
+ if (cssMatch) {
8774
+ const rawCss = cssMatch[1].trim();
8775
+ styles[selector] = styles[selector] || '';
8776
+ styles[selector] += rawCss.split(';').filter(d => d.trim()).map(d => d.trim() + ';').join(' ') + '\n';
8777
+ continue;
8778
+ }
8779
+ }
8740
8780
  baseClass += (baseClass ? " " : "") + expandGroupedClass(item);
8741
8781
  } else if (typeof item === "object" && item !== null) {
8742
8782
  Object.assign(nested, item);
@@ -9291,6 +9331,9 @@ function twsxVariantsNoCache(className) {
9291
9331
  // Skip if it's the default value
9292
9332
  if (value === defaultVariants[key]) continue;
9293
9333
 
9334
+ // Skip if the variant value doesn't exist in the variant options
9335
+ if (!variants[key].hasOwnProperty(value) && value !== true && value !== "true" && value !== false && value !== "false") continue;
9336
+
9294
9337
  // Handle boolean variants
9295
9338
  if (value === true || value === "true") {
9296
9339
  variantParts.push(key);
@@ -9500,30 +9543,11 @@ function autoInjectCss(cssString) {
9500
9543
  document.head.appendChild(styleTag);
9501
9544
  }
9502
9545
 
9503
- // Use insertRule for better performance (avoids full stylesheet reparse)
9504
- try {
9505
- const sheet = styleTag.sheet;
9506
- if (sheet) {
9507
- // Split CSS by closing brace to insert individual rules
9508
- const rules = cssString.split('}').filter(r => r.trim());
9509
- for (const rule of rules) {
9510
- const trimmed = rule.trim();
9511
- if (trimmed) {
9512
- try {
9513
- sheet.insertRule(trimmed + '}', sheet.cssRules.length);
9514
- } catch (e) {
9515
- // Fallback for complex rules (e.g., @keyframes, @media)
9516
- styleTag.textContent += `\n${trimmed}}`;
9517
- }
9518
- }
9519
- }
9520
- } else {
9521
- styleTag.textContent += `\n${cssString}`;
9522
- }
9523
- } catch (e) {
9524
- // Ultimate fallback
9525
- styleTag.textContent += `\n${cssString}`;
9526
- }
9546
+ // Append CSS to style tag using textContent for reliability
9547
+ // Note: insertRule + textContent mixing destroys CSSOM rules,
9548
+ // so we use textContent exclusively for consistent behavior
9549
+ // with @keyframes, @media, and other nested CSS blocks.
9550
+ styleTag.textContent += `\n${cssString}`;
9527
9551
 
9528
9552
  // Log injection stats periodically
9529
9553
  if (injectedCssHashSet.size % 10 === 0) {