From b62794a3c5411a290a0510ef1420165864bd07ab Mon Sep 17 00:00:00 2001 From: Durvesh Pilankar Date: Mon, 29 Jun 2026 17:52:47 -0700 Subject: [PATCH] Fix zero-unit stripping inside functions after the first MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit normalizeZeroDimensions must not strip the unit from a zero inside a function (e.g. calc(0px + 1%) — a unitless 0 can't be added to a %). It tracks the active function via endFunction, but the guard `node.type === 'function' && !endFunction` only ever recorded the FIRST function. For a later function, endFunction had already been reset to 0, so its children were treated as outside a function and their units were stripped — emitting invalid CSS like `max(1px,2px) calc(0 + 1%)`. Track every function with Math.max(endFunction, sourceEndIndex); the existing reset still clears it once walking moves past the last function, so bare zeros outside functions are still normalized. Adds a regression test (fails before / passes after). --- .../__tests__/transform-value-normalization-test.js | 10 ++++++++++ .../src/shared/utils/normalizers/zero-dimensions.js | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/@stylexjs/babel-plugin/__tests__/transform-value-normalization-test.js b/packages/@stylexjs/babel-plugin/__tests__/transform-value-normalization-test.js index 60a577e15..104f706e4 100644 --- a/packages/@stylexjs/babel-plugin/__tests__/transform-value-normalization-test.js +++ b/packages/@stylexjs/babel-plugin/__tests__/transform-value-normalization-test.js @@ -95,6 +95,16 @@ describe('@stylexjs/babel-plugin', () => { `); }); + test('preserves zero units inside a non-first function', () => { + const code = transform(` + import stylex from 'stylex'; + const styles = stylex.create({ x: { width: 'max(1px, 2px) calc(0px + 1%)' } }); + `); + // calc(0 + 1%) is invalid CSS — a unitless 0 cannot be added to a %. + expect(code).toContain('calc(0px + 1%)'); + expect(code).not.toContain('calc(0 + 1%)'); + }); + test('0 timings are all "0s"', () => { expect( transform(` diff --git a/packages/@stylexjs/babel-plugin/src/shared/utils/normalizers/zero-dimensions.js b/packages/@stylexjs/babel-plugin/src/shared/utils/normalizers/zero-dimensions.js index 4d355f2d8..2d6d84c1b 100644 --- a/packages/@stylexjs/babel-plugin/src/shared/utils/normalizers/zero-dimensions.js +++ b/packages/@stylexjs/babel-plugin/src/shared/utils/normalizers/zero-dimensions.js @@ -32,8 +32,8 @@ export default function normalizeZeroDimensions( let endFunction = 0; ast.walk((node) => { - if (node.type === 'function' && !endFunction) { - endFunction = node.sourceEndIndex ?? 0; + if (node.type === 'function') { + endFunction = Math.max(endFunction, node.sourceEndIndex ?? 0); } if (endFunction > 0 && node.sourceIndex > endFunction) { endFunction = 0;