From 0c6f0a9ac1efef9a3e263a6a4768e425837b3390 Mon Sep 17 00:00:00 2001 From: LeSingh1 Date: Tue, 14 Jul 2026 21:05:43 -0700 Subject: [PATCH] [style-value-parser] Fix BorderRadiusShorthand.toString dropping vertical radii The secondary (post-"/") string sStr was initialized from the horizontal radii instead of the vertical ones. When the vertical radii have no symmetry (all four distinct), none of the reassignment branches fire, so sStr kept the horizontal values, made pStr === sStr, and the whole value collapsed to just the horizontal radii -- silently dropping the vertical radii (e.g. "10px 20px 30px 40px / 40px 30px 20px 10px" serialized as "10px 20px 30px 40px"). Initialize sStr from the vertical radii to match the reassignment branches. --- .../__tests__/border-radius.test.js | 25 +++++++++++++++++++ .../src/properties/border-radius.js | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/packages/style-value-parser/src/properties/__tests__/border-radius.test.js b/packages/style-value-parser/src/properties/__tests__/border-radius.test.js index f4dc6ef7d..2e9e49a64 100644 --- a/packages/style-value-parser/src/properties/__tests__/border-radius.test.js +++ b/packages/style-value-parser/src/properties/__tests__/border-radius.test.js @@ -351,4 +351,29 @@ describe('Test CSS property shorthand: `border-radius`', () => { ), ); }); + + describe('serialization: `BorderRadiusShorthand.toString`', () => { + const roundTrip = (input: string): string => + BorderRadiusShorthand.parse.parseToEnd(input).toString(); + + test('symmetric radii serialize without a `/`', () => { + expect(roundTrip('10px')).toBe('10px'); + expect(roundTrip('10px 20px')).toBe('10px 20px'); + expect(roundTrip('10px 20px 30px')).toBe('10px 20px 30px'); + expect(roundTrip('10px 20px 30px 40px')).toBe('10px 20px 30px 40px'); + }); + + test('asymmetric radii keep the vertical values after the `/`', () => { + // Regression: the vertical (post-slash) radii were previously rendered + // using the horizontal values, which collapsed the whole value back to + // the horizontal radii and dropped the vertical radii entirely. + expect(roundTrip('10px 20px 30px 40px / 40px 30px 20px 10px')).toBe( + '10px 20px 30px 40px / 40px 30px 20px 10px', + ); + expect(roundTrip('10px / 20px')).toBe('10px / 20px'); + expect(roundTrip('10px 20px / 30px 40px')).toBe( + '10px 20px / 30px 40px', + ); + }); + }); }); diff --git a/packages/style-value-parser/src/properties/border-radius.js b/packages/style-value-parser/src/properties/border-radius.js index cfe200831..cf3f9169e 100644 --- a/packages/style-value-parser/src/properties/border-radius.js +++ b/packages/style-value-parser/src/properties/border-radius.js @@ -106,7 +106,7 @@ export class BorderRadiusShorthand { const verticalBottomRight = this.verticalBottomRight.toString(); const verticalBottomLeft = this.verticalBottomLeft.toString(); - let sStr = `${horizontalTopLeft} ${horizontalTopRight} ${horizontalBottomRight} ${horizontalBottomLeft}`; + let sStr = `${verticalTopLeft} ${verticalTopRight} ${verticalBottomRight} ${verticalBottomLeft}`; // All three are the same if ( verticalTopLeft === verticalTopRight &&