diff --git a/.changeset/brown-poets-scream.md b/.changeset/brown-poets-scream.md new file mode 100644 index 000000000..3532b32c6 --- /dev/null +++ b/.changeset/brown-poets-scream.md @@ -0,0 +1,6 @@ +--- +'@twind/core': patch +'@twind/preset-tailwind': patch +--- + +properly normalize subtraction followed by a variable (fixes #429) diff --git a/packages/core/src/rules.ts b/packages/core/src/rules.ts index 8d39cd9dd..8b980440e 100644 --- a/packages/core/src/rules.ts +++ b/packages/core/src/rules.ts @@ -636,6 +636,7 @@ function camelize(value: string): string { return value.replace(/-./g, (x) => x[1].toUpperCase()) } +const cssVariableRE = /var\((--.+?)[,)]/g /** * @internal * @param value @@ -662,11 +663,15 @@ export function normalize(value: string): string { // Add spaces around operators inside math functions like calc() that do not follow an operator // or '('. - .replace(/(calc|min|max|clamp)\(.+\)/g, (match) => - match.replace( - /(-?\d*\.?\d(?!\b-.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g, - '$1 $2 ', - ), - ) + .replace(/(calc|min|max|clamp)\(.+\)/g, (match) => { + const vars: string[] = [] + return match + .replace(cssVariableRE, (match, g1) => { + vars.push(g1) + return match.replace(g1, '--v') + }) + .replace(/(-?\d*\.?\d(?!\b-\d.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g, '$1 $2 ') + .replace(cssVariableRE, (match, g1) => match.replace(g1, vars.shift() as string)) + }) ) } diff --git a/packages/preset-tailwind/src/rules.test.json b/packages/preset-tailwind/src/rules.test.json index 4f7fc531d..d5d69f9ef 100644 --- a/packages/preset-tailwind/src/rules.test.json +++ b/packages/preset-tailwind/src/rules.test.json @@ -1095,6 +1095,9 @@ "w-[calc((100%+2rem)/2)]": ".w-\\[calc\\(\\(100\\%\\+2rem\\)\\/2\\)\\]{width:calc((100% + 2rem) / 2)}", "w-[calc(var(--index,1)*0.2s)]": ".w-\\[calc\\(var\\(--index\\,1\\)\\*0\\.2s\\)\\]{width:calc(var(--index,1) * 0.2s)}", "w-[calc(var(--index)*0.2s)]": ".w-\\[calc\\(var\\(--index\\)\\*0\\.2s\\)\\]{width:calc(var(--index) * 0.2s)}", + "w-[calc(1-var(--something)*0.5)]": ".w-\\[calc\\(1-var\\(--something\\)\\*0\\.5\\)\\]{width:calc(1 - var(--something) * 0.5)}", + "w-[calc(1-(var(--something)*0.5))]": ".w-\\[calc\\(1-\\(var\\(--something\\)\\*0\\.5\\)\\)\\]{width:calc(1 - (var(--something) * 0.5))}", + "w-[calc(1-((12-3)*0.5))]": ".w-\\[calc\\(1-\\(\\(12-3\\)\\*0\\.5\\)\\)\\]{width:calc(1 - ((12 - 3) * 0.5))}", "bg-[#1da1f2]": ".bg-\\[\\#1da1f2\\]{--tw-bg-opacity:1;background-color:rgba(29,161,242,var(--tw-bg-opacity))}", "translate-x-[-650px]": [ "*,::before,::after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-transform:translateX(var(--tw-translate-x)) translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}",