diff --git a/packages/react-native/Libraries/StyleSheet/__tests__/processBackgroundImage-itest.js b/packages/react-native/Libraries/StyleSheet/__tests__/processBackgroundImage-itest.js index 08a0ca0b9700..2614d334dd9a 100644 --- a/packages/react-native/Libraries/StyleSheet/__tests__/processBackgroundImage-itest.js +++ b/packages/react-native/Libraries/StyleSheet/__tests__/processBackgroundImage-itest.js @@ -999,6 +999,22 @@ describe('processBackgroundImage', () => { expect(result[0].type).toEqual('radial-gradient'); }); + it('should handle radial gradient with explicit size and position', () => { + const input = 'radial-gradient(circle 100px at 25% 75%, red, blue)'; + const result = processBackgroundImage(input); + expect(result[0].shape).toEqual('circle'); + expect(result[0].size).toEqual({x: 100, y: 100}); + expect(result[0].position).toEqual({left: '25%', top: '75%'}); + }); + + it('should handle radial gradient with two explicit sizes and position', () => { + const input = 'radial-gradient(50px 100px at left bottom, red, blue)'; + const result = processBackgroundImage(input); + expect(result[0].shape).toEqual('ellipse'); + expect(result[0].size).toEqual({x: 50, y: 100}); + expect(result[0].position).toEqual({left: '0%', top: '100%'}); + }); + // 1. position syntax: [ left | center | right | top | bottom | ] it('should handle radial gradient position length syntax', () => { const input = 'radial-gradient(circle at 20px, red, blue)'; diff --git a/packages/react-native/Libraries/StyleSheet/processBackgroundImage.js b/packages/react-native/Libraries/StyleSheet/processBackgroundImage.js index f733c96c9645..421884005bbe 100644 --- a/packages/react-native/Libraries/StyleSheet/processBackgroundImage.js +++ b/packages/react-native/Libraries/StyleSheet/processBackgroundImage.js @@ -348,6 +348,11 @@ function parseRadialGradientCSSString( size = {x: sizeX, y: sizeY}; } else { hasExplicitSingleSize = true; + // The token after the size is not a second size value (e.g. 'at' or a + // shape keyword). Put it back so the loop can process it, otherwise + // the position would be silently dropped and its values re-parsed as + // a new size. + firstPartTokens.unshift(token); } } else if (tokenTrimmed === 'at') { let top: string | number;