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.
package/dist/cx.cjs CHANGED
@@ -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
package/dist/cx.esm.js CHANGED
@@ -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
package/dist/index.cjs CHANGED
@@ -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
@@ -9614,7 +9614,7 @@ function processClass(cls, selector, styles) {
9614
9614
 
9615
9615
  // Get cssObject from singleton cache
9616
9616
  const cssObject = tailwindCache.getOrGenerate(generateTailwindCssString, convertCssToObject);
9617
- let declarations = cssObject[baseClassName] || cssObject[baseClassName.replace(ESCAPE_SLASH_REGEX, "\\$1")] || cssObject[baseClassName.replace(ESCAPE_DOT_REGEX, "\\.")];
9617
+ let declarations = cssObject[baseClassName] || cssObject[baseClassName.replace(ESCAPE_SLASH_REGEX, "\\/")] || cssObject[baseClassName.replace(ESCAPE_DOT_REGEX, "\\.")];
9618
9618
  if (!declarations && baseClassName.includes("[")) {
9619
9619
  const match = CUSTOM_VALUE_FULL_REGEX.exec(baseClassName);
9620
9620
  if (match) {
@@ -9836,11 +9836,26 @@ function flattenStyleObject(obj) {
9836
9836
  flatArray.push(item);
9837
9837
  } else if (isSelectorObject(item)) {
9838
9838
  const nested = flattenStyleObject(item, currentSelector);
9839
- Object.assign(result, nested);
9839
+ // Merge nested results, handling & that resolves to same selector
9840
+ for (const ns in nested) {
9841
+ if (ns === currentSelector) {
9842
+ // & resolved to same selector — include in this array
9843
+ if (Array.isArray(nested[ns])) {
9844
+ flatArray.push(...nested[ns]);
9845
+ } else {
9846
+ flatArray.push(nested[ns]);
9847
+ }
9848
+ } else {
9849
+ result[ns] = nested[ns];
9850
+ }
9851
+ }
9840
9852
  }
9841
9853
  }
9842
9854
  if (flatArray.length > 0) {
9843
9855
  result[currentSelector] = result[currentSelector] || [];
9856
+ if (!Array.isArray(result[currentSelector])) {
9857
+ result[currentSelector] = [result[currentSelector]];
9858
+ }
9844
9859
  result[currentSelector].push(...flatArray);
9845
9860
  }
9846
9861
  } else if (isSelectorObject(val)) {
@@ -9972,6 +9987,20 @@ function twsxNoCache(obj) {
9972
9987
  // Process each selector within the media query
9973
9988
  for (const innerSelector in val) {
9974
9989
  const innerVal = val[innerSelector];
9990
+
9991
+ // Handle @css string directive inside media queries
9992
+ if (typeof innerVal === "string") {
9993
+ const trimmedInner = innerVal.trim();
9994
+ if (trimmedInner.startsWith('@css')) {
9995
+ const cssMatch = trimmedInner.match(/^@css\s*\{([\s\S]*)\}\s*$/);
9996
+ if (cssMatch) {
9997
+ const rawCss = cssMatch[1].trim();
9998
+ styles[selector][innerSelector] = styles[selector][innerSelector] || '';
9999
+ styles[selector][innerSelector] += rawCss.split(';').filter(d => d.trim()).map(d => d.trim() + ';').join(' ') + '\n';
10000
+ continue;
10001
+ }
10002
+ }
10003
+ }
9975
10004
  const baseClass = typeof innerVal === "string" ? expandGroupedClass(innerVal) : "";
9976
10005
 
9977
10006
  // Process Tailwind classes for this selector
@@ -10011,6 +10040,17 @@ function twsxNoCache(obj) {
10011
10040
  } else if (Array.isArray(val)) {
10012
10041
  for (const item of val) {
10013
10042
  if (typeof item === "string") {
10043
+ // Handle @css strings inside arrays
10044
+ const trimmedItem = item.trim();
10045
+ if (trimmedItem.startsWith('@css')) {
10046
+ const cssMatch = trimmedItem.match(/^@css\s*\{([\s\S]*)\}\s*$/);
10047
+ if (cssMatch) {
10048
+ const rawCss = cssMatch[1].trim();
10049
+ styles[selector] = styles[selector] || '';
10050
+ styles[selector] += rawCss.split(';').filter(d => d.trim()).map(d => d.trim() + ';').join(' ') + '\n';
10051
+ continue;
10052
+ }
10053
+ }
10014
10054
  baseClass += (baseClass ? " " : "") + expandGroupedClass(item);
10015
10055
  } else if (typeof item === "object" && item !== null) {
10016
10056
  Object.assign(nested, item);
@@ -10565,6 +10605,9 @@ function twsxVariantsNoCache(className) {
10565
10605
  // Skip if it's the default value
10566
10606
  if (value === defaultVariants[key]) continue;
10567
10607
 
10608
+ // Skip if the variant value doesn't exist in the variant options
10609
+ if (!variants[key].hasOwnProperty(value) && value !== true && value !== "true" && value !== false && value !== "false") continue;
10610
+
10568
10611
  // Handle boolean variants
10569
10612
  if (value === true || value === "true") {
10570
10613
  variantParts.push(key);
@@ -10785,30 +10828,11 @@ function autoInjectCss(cssString) {
10785
10828
  document.head.appendChild(styleTag);
10786
10829
  }
10787
10830
 
10788
- // Use insertRule for better performance (avoids full stylesheet reparse)
10789
- try {
10790
- const sheet = styleTag.sheet;
10791
- if (sheet) {
10792
- // Split CSS by closing brace to insert individual rules
10793
- const rules = cssString.split('}').filter(r => r.trim());
10794
- for (const rule of rules) {
10795
- const trimmed = rule.trim();
10796
- if (trimmed) {
10797
- try {
10798
- sheet.insertRule(trimmed + '}', sheet.cssRules.length);
10799
- } catch (e) {
10800
- // Fallback for complex rules (e.g., @keyframes, @media)
10801
- styleTag.textContent += `\n${trimmed}}`;
10802
- }
10803
- }
10804
- }
10805
- } else {
10806
- styleTag.textContent += `\n${cssString}`;
10807
- }
10808
- } catch (e) {
10809
- // Ultimate fallback
10810
- styleTag.textContent += `\n${cssString}`;
10811
- }
10831
+ // Append CSS to style tag using textContent for reliability
10832
+ // Note: insertRule + textContent mixing destroys CSSOM rules,
10833
+ // so we use textContent exclusively for consistent behavior
10834
+ // with @keyframes, @media, and other nested CSS blocks.
10835
+ styleTag.textContent += `\n${cssString}`;
10812
10836
 
10813
10837
  // Log injection stats periodically
10814
10838
  if (injectedCssHashSet.size % 10 === 0) {
package/dist/index.esm.js CHANGED
@@ -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
@@ -9612,7 +9612,7 @@ function processClass(cls, selector, styles) {
9612
9612
 
9613
9613
  // Get cssObject from singleton cache
9614
9614
  const cssObject = tailwindCache.getOrGenerate(generateTailwindCssString, convertCssToObject);
9615
- let declarations = cssObject[baseClassName] || cssObject[baseClassName.replace(ESCAPE_SLASH_REGEX, "\\$1")] || cssObject[baseClassName.replace(ESCAPE_DOT_REGEX, "\\.")];
9615
+ let declarations = cssObject[baseClassName] || cssObject[baseClassName.replace(ESCAPE_SLASH_REGEX, "\\/")] || cssObject[baseClassName.replace(ESCAPE_DOT_REGEX, "\\.")];
9616
9616
  if (!declarations && baseClassName.includes("[")) {
9617
9617
  const match = CUSTOM_VALUE_FULL_REGEX.exec(baseClassName);
9618
9618
  if (match) {
@@ -9834,11 +9834,26 @@ function flattenStyleObject(obj) {
9834
9834
  flatArray.push(item);
9835
9835
  } else if (isSelectorObject(item)) {
9836
9836
  const nested = flattenStyleObject(item, currentSelector);
9837
- Object.assign(result, nested);
9837
+ // Merge nested results, handling & that resolves to same selector
9838
+ for (const ns in nested) {
9839
+ if (ns === currentSelector) {
9840
+ // & resolved to same selector — include in this array
9841
+ if (Array.isArray(nested[ns])) {
9842
+ flatArray.push(...nested[ns]);
9843
+ } else {
9844
+ flatArray.push(nested[ns]);
9845
+ }
9846
+ } else {
9847
+ result[ns] = nested[ns];
9848
+ }
9849
+ }
9838
9850
  }
9839
9851
  }
9840
9852
  if (flatArray.length > 0) {
9841
9853
  result[currentSelector] = result[currentSelector] || [];
9854
+ if (!Array.isArray(result[currentSelector])) {
9855
+ result[currentSelector] = [result[currentSelector]];
9856
+ }
9842
9857
  result[currentSelector].push(...flatArray);
9843
9858
  }
9844
9859
  } else if (isSelectorObject(val)) {
@@ -9970,6 +9985,20 @@ function twsxNoCache(obj) {
9970
9985
  // Process each selector within the media query
9971
9986
  for (const innerSelector in val) {
9972
9987
  const innerVal = val[innerSelector];
9988
+
9989
+ // Handle @css string directive inside media queries
9990
+ if (typeof innerVal === "string") {
9991
+ const trimmedInner = innerVal.trim();
9992
+ if (trimmedInner.startsWith('@css')) {
9993
+ const cssMatch = trimmedInner.match(/^@css\s*\{([\s\S]*)\}\s*$/);
9994
+ if (cssMatch) {
9995
+ const rawCss = cssMatch[1].trim();
9996
+ styles[selector][innerSelector] = styles[selector][innerSelector] || '';
9997
+ styles[selector][innerSelector] += rawCss.split(';').filter(d => d.trim()).map(d => d.trim() + ';').join(' ') + '\n';
9998
+ continue;
9999
+ }
10000
+ }
10001
+ }
9973
10002
  const baseClass = typeof innerVal === "string" ? expandGroupedClass(innerVal) : "";
9974
10003
 
9975
10004
  // Process Tailwind classes for this selector
@@ -10009,6 +10038,17 @@ function twsxNoCache(obj) {
10009
10038
  } else if (Array.isArray(val)) {
10010
10039
  for (const item of val) {
10011
10040
  if (typeof item === "string") {
10041
+ // Handle @css strings inside arrays
10042
+ const trimmedItem = item.trim();
10043
+ if (trimmedItem.startsWith('@css')) {
10044
+ const cssMatch = trimmedItem.match(/^@css\s*\{([\s\S]*)\}\s*$/);
10045
+ if (cssMatch) {
10046
+ const rawCss = cssMatch[1].trim();
10047
+ styles[selector] = styles[selector] || '';
10048
+ styles[selector] += rawCss.split(';').filter(d => d.trim()).map(d => d.trim() + ';').join(' ') + '\n';
10049
+ continue;
10050
+ }
10051
+ }
10012
10052
  baseClass += (baseClass ? " " : "") + expandGroupedClass(item);
10013
10053
  } else if (typeof item === "object" && item !== null) {
10014
10054
  Object.assign(nested, item);
@@ -10563,6 +10603,9 @@ function twsxVariantsNoCache(className) {
10563
10603
  // Skip if it's the default value
10564
10604
  if (value === defaultVariants[key]) continue;
10565
10605
 
10606
+ // Skip if the variant value doesn't exist in the variant options
10607
+ if (!variants[key].hasOwnProperty(value) && value !== true && value !== "true" && value !== false && value !== "false") continue;
10608
+
10566
10609
  // Handle boolean variants
10567
10610
  if (value === true || value === "true") {
10568
10611
  variantParts.push(key);
@@ -10783,30 +10826,11 @@ function autoInjectCss(cssString) {
10783
10826
  document.head.appendChild(styleTag);
10784
10827
  }
10785
10828
 
10786
- // Use insertRule for better performance (avoids full stylesheet reparse)
10787
- try {
10788
- const sheet = styleTag.sheet;
10789
- if (sheet) {
10790
- // Split CSS by closing brace to insert individual rules
10791
- const rules = cssString.split('}').filter(r => r.trim());
10792
- for (const rule of rules) {
10793
- const trimmed = rule.trim();
10794
- if (trimmed) {
10795
- try {
10796
- sheet.insertRule(trimmed + '}', sheet.cssRules.length);
10797
- } catch (e) {
10798
- // Fallback for complex rules (e.g., @keyframes, @media)
10799
- styleTag.textContent += `\n${trimmed}}`;
10800
- }
10801
- }
10802
- }
10803
- } else {
10804
- styleTag.textContent += `\n${cssString}`;
10805
- }
10806
- } catch (e) {
10807
- // Ultimate fallback
10808
- styleTag.textContent += `\n${cssString}`;
10809
- }
10829
+ // Append CSS to style tag using textContent for reliability
10830
+ // Note: insertRule + textContent mixing destroys CSSOM rules,
10831
+ // so we use textContent exclusively for consistent behavior
10832
+ // with @keyframes, @media, and other nested CSS blocks.
10833
+ styleTag.textContent += `\n${cssString}`;
10810
10834
 
10811
10835
  // Log injection stats periodically
10812
10836
  if (injectedCssHashSet.size % 10 === 0) {