From 0c51a4dee21025edfb0cc4cf2cf580ef8c43aa3f Mon Sep 17 00:00:00 2001 From: doslin Date: Thu, 11 Jun 2026 11:44:23 +0800 Subject: [PATCH 1/4] =?UTF-8?q?pref(rn):=20=E4=BC=98=E5=8C=96=E5=85=A8?= =?UTF-8?q?=E5=B0=BA=E5=AF=B8=20linear-gradient=20=E8=83=8C=E6=99=AF?= =?UTF-8?q?=E6=B8=B2=E6=9F=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/runtime/components/react/mpx-view.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx index f8a7f0e1bc..379ceb56d0 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx @@ -155,7 +155,7 @@ const isNeedLayout = (preImageInfo: PreImageInfo): boolean => { isPercent(bp[1]) || isPercent(bp[3]) || isDiagonalAngle(linearInfo) || - (type === 'linear' && (isPercent(height) || isPercent(width))) + (type === 'linear' && (isPercent(height) || isPercent(width)) && !(width === '100%' && height === '100%')) } const checkNeedLayout = (preImageInfo: PreImageInfo) => { @@ -288,7 +288,9 @@ function backgroundSize (imageProps: ImageProps, preImageInfo: PreImageInfo, ima } else { // 数值类型 ImageStyle // 数值类型设置为 stretch imageProps.resizeMode = 'stretch' - if (type === 'linear' && (!layoutWidth || !layoutHeight) && (isPercent(width) || isPercent(height))) { + if (type === 'linear' && width === '100%' && height === '100%' && (!layoutWidth || !layoutHeight)) { + dimensions = StyleSheet.absoluteFillObject as unknown as { width: NumberVal, height: NumberVal } + } else if (type === 'linear' && (!layoutWidth || !layoutHeight) && (isPercent(width) || isPercent(height))) { // ios 上 linear 组件只要重新触发渲染,在渲染过程中外层容器 width 或者 height 被设置为 0,通过设置 % 的方式会渲染不出来,即使后面再更新为正常宽高也渲染不出来 // 所以 hack 手动先将 linear 宽高也设置为 0,后面再更新为正确的数值或 %。 dimensions = { From 5a9c82525ddd9e2691940a41641d61b76f5b7f3c Mon Sep 17 00:00:00 2001 From: doslin Date: Wed, 9 Sep 2026 11:07:25 +0800 Subject: [PATCH 2/4] =?UTF-8?q?fix(rn):=20=E9=99=90=E5=88=B6=E5=85=A8?= =?UTF-8?q?=E5=B0=BA=E5=AF=B8=E6=B8=90=E5=8F=98=E4=BC=98=E5=8C=96=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=EF=BC=8C=E4=BF=AE=E5=A4=8D=E8=83=8C=E6=99=AF=E5=81=8F?= =?UTF-8?q?=E7=A7=BB=E5=B9=B6=E4=BF=9D=E7=95=99=E9=9B=B6=E5=B0=BA=E5=AF=B8?= =?UTF-8?q?=E4=BF=9D=E6=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/runtime/components/react/mpx-view.tsx | 19 ++++--- .../react-native/mpx-view-gradient.spec.ts | 53 +++++++++++++++++++ 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx index a178839506..2d22febcea 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx @@ -172,13 +172,21 @@ const isPercent = (val: string | number | undefined): val is string => typeof va const isBackgroundSizeKeyword = (val: string | number): boolean => typeof val === 'string' && /^cover|contain$/.test(val) +const isFullSizeGradient = ({ type, sizeList, backgroundPosition, linearInfo }: PreImageInfo): boolean => { + // 四边撑满仅适用于无偏移、无需计算对角方向的全尺寸渐变。 + return type === 'linear' && sizeList[0] === '100%' && sizeList[1] === '100%' && + !(linearInfo?.direction && diagonalAngleMap[linearInfo.direction]) && + (!backgroundPosition.length || (backgroundPosition[1] === 0 && backgroundPosition[3] === 0)) +} + const isNeedLayout = (preImageInfo: PreImageInfo): boolean => { const { sizeList, backgroundPosition, type } = preImageInfo const [width, height] = sizeList const bp = backgroundPosition if (type === 'linear') { - return !(Number.isFinite(width) && Number.isFinite(height)) || isPercent(bp[1]) || isPercent(bp[3]) + return !isFullSizeGradient(preImageInfo) && + (!(Number.isFinite(width) && Number.isFinite(height)) || isPercent(bp[1]) || isPercent(bp[3])) } // 含有百分号,center 需计算布局 @@ -284,10 +292,7 @@ function backgroundSize (imageProps: ImageProps, preImageInfo: PreImageInfo, ima const { width: layoutWidth, height: layoutHeight } = layoutInfo || {} const { width: imageSizeWidth, height: imageSizeHeight } = imageSize || {} const [width, height] = sizeList - let dimensions: { - width: NumberVal, - height: NumberVal - } | null = { width: 0, height: 0 } + let dimensions: ImageStyle | null = { width: 0, height: 0 } // 枚举值 if (typeof width === 'string' && ['cover', 'contain'].includes(width)) { @@ -317,7 +322,9 @@ function backgroundSize (imageProps: ImageProps, preImageInfo: PreImageInfo, ima dimensions = calculateSize(width as number, imageSizeHeight / imageSizeWidth, layoutInfo?.width, true) if (!dimensions) return } else { // 数值类型 ImageStyle - if (type === 'linear' && (!layoutWidth || !layoutHeight) && (isPercent(width) || isPercent(height))) { + if (isFullSizeGradient(preImageInfo)) { + dimensions = StyleSheet.absoluteFillObject + } else if (type === 'linear' && (!layoutWidth || !layoutHeight) && (isPercent(width) || isPercent(height))) { // ios 上 linear 组件只要重新触发渲染,在渲染过程中外层容器 width 或者 height 被设置为 0,通过设置 % 的方式会渲染不出来,即使后面再更新为正常宽高也渲染不出来 // 所以 hack 手动先将 linear 宽高也设置为 0,后面再更新为正确的数值或 %。 dimensions = { diff --git a/packages/webpack-plugin/test/runtime/react-native/mpx-view-gradient.spec.ts b/packages/webpack-plugin/test/runtime/react-native/mpx-view-gradient.spec.ts index 8c7bf1ebd8..7f0facc73a 100644 --- a/packages/webpack-plugin/test/runtime/react-native/mpx-view-gradient.spec.ts +++ b/packages/webpack-plugin/test/runtime/react-native/mpx-view-gradient.spec.ts @@ -102,3 +102,56 @@ describe('mpx-view linear-gradient parser', () => { act(() => renderer!.unmount()) }) }) + +describe('mpx-view full-size gradient layout', () => { + const render = (style: Record = {}) => React.createElement(MpxView, { + 'enable-background': true, + style: Object.assign({ width: 200, height: 100, backgroundImage: 'linear-gradient(90deg, red, blue)' }, style) + }) + const fillStyle = { position: 'absolute', left: 0, right: 0, top: 0, bottom: 0 } + + test.each([ + [undefined], [['auto']], [['cover']], [['contain']], [['100%', '100%']] + ])('renders full-size gradient immediately for %j', (backgroundSize) => { + let renderer: ReactTestRenderer + act(() => { renderer = create(render(backgroundSize ? { backgroundSize } : {})) }) + expect(renderer!.root.findByType('LinearGradient').props.style).toEqual(fillStyle) + act(() => renderer!.root.findAllByType('View')[1].props.onLayout(layoutEvent(200, 100))) + act(() => renderer!.update(render({ backgroundSize, backgroundImage: 'linear-gradient(90deg, green, blue)' }))) + expect(renderer!.root.findByType('LinearGradient').props.style).toEqual(fillStyle) + act(() => renderer!.unmount()) + }) + + test.each([ + ['left', 20, 'top', 0], ['right', 20, 'bottom', 10], ['left', -20, 'top', 0] + ])('keeps full dimensions for offset %s %s %s %s', (x, dx, y, dy) => { + let renderer: ReactTestRenderer + act(() => { renderer = create(render({ backgroundPosition: [x, dx, y, dy] })) }) + expect(renderer!.root.findAllByType('LinearGradient')).toHaveLength(0) + act(() => renderer!.root.findAllByType('View')[1].props.onLayout(layoutEvent(200, 100))) + expect(renderer!.root.findByType('LinearGradient').props.style).toEqual({ position: 'absolute', width: '100%', height: '100%', [x]: dx, [y]: dy }) + act(() => renderer!.root.findAllByType('View')[1].props.onLayout(layoutEvent(0, 100))) + expect(renderer!.root.findByType('LinearGradient').props.style).toMatchObject({ width: 0, height: 0 }) + act(() => renderer!.root.findAllByType('View')[1].props.onLayout(layoutEvent(200, 100))) + expect(renderer!.root.findByType('LinearGradient').props.style).toMatchObject({ width: '100%', height: '100%' }) + act(() => renderer!.unmount()) + }) + + test('switches between fill and layout-dependent styles using the cached layout', () => { + let renderer: ReactTestRenderer + act(() => { renderer = create(render()) }) + expect(renderer!.root.findByType('LinearGradient').props.style).toEqual(fillStyle) + act(() => renderer!.root.findAllByType('View')[1].props.onLayout(layoutEvent(200, 100))) + act(() => renderer!.update(render({ backgroundSize: ['50%', '100%'], backgroundPosition: ['center', 'center'] }))) + expect(renderer!.root.findByType('LinearGradient').props.style).toEqual({ position: 'absolute', width: '50%', height: '100%', left: 50, top: 0 }) + act(() => renderer!.update(render())) + expect(renderer!.root.findByType('LinearGradient').props.style).toEqual(fillStyle) + act(() => renderer!.root.findAllByType('View')[1].props.onLayout(layoutEvent(0, 100))) + act(() => renderer!.update(render({ backgroundImage: 'linear-gradient(90deg, green, blue)' }))) + expect(renderer!.root.findByType('LinearGradient').props.style).toEqual(fillStyle) + act(() => renderer!.root.findAllByType('View')[1].props.onLayout(layoutEvent(200, 100))) + act(() => renderer!.update(render({ backgroundPosition: ['center', 'center'] }))) + expect(renderer!.root.findByType('LinearGradient').props.style).toEqual({ position: 'absolute', width: '100%', height: '100%', left: 0, top: 0 }) + act(() => renderer!.unmount()) + }) +}) From efa3b9c1f92a44a83c408da264e31e3d1e0893b4 Mon Sep 17 00:00:00 2001 From: doslin Date: Wed, 9 Sep 2026 17:15:38 +0800 Subject: [PATCH 3/4] fix: enhance iOS gradient handling for zero size and visibility restoration --- .../lib/runtime/components/react/mpx-view.tsx | 10 +++++-- .../react-native/mpx-view-gradient.spec.ts | 26 ++++++++++++++++++- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx index 2d22febcea..6f71c2457b 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx @@ -174,7 +174,7 @@ const isBackgroundSizeKeyword = (val: string | number): boolean => typeof val == const isFullSizeGradient = ({ type, sizeList, backgroundPosition, linearInfo }: PreImageInfo): boolean => { // 四边撑满仅适用于无偏移、无需计算对角方向的全尺寸渐变。 - return type === 'linear' && sizeList[0] === '100%' && sizeList[1] === '100%' && + return __mpx_mode__ !== 'ios' && type === 'linear' && sizeList[0] === '100%' && sizeList[1] === '100%' && !(linearInfo?.direction && diagonalAngleMap[linearInfo.direction]) && (!backgroundPosition.length || (backgroundPosition[1] === 0 && backgroundPosition[3] === 0)) } @@ -324,6 +324,11 @@ function backgroundSize (imageProps: ImageProps, preImageInfo: PreImageInfo, ima } else { // 数值类型 ImageStyle if (isFullSizeGradient(preImageInfo)) { dimensions = StyleSheet.absoluteFillObject + } else if (__mpx_mode__ === 'ios' && type === 'linear') { + dimensions = { + width: calcPercent(width as NumberVal, layoutWidth || 0), + height: calcPercent(height as NumberVal, layoutHeight || 0) + } } else if (type === 'linear' && (!layoutWidth || !layoutHeight) && (isPercent(width) || isPercent(height))) { // ios 上 linear 组件只要重新触发渲染,在渲染过程中外层容器 width 或者 height 被设置为 0,通过设置 % 的方式会渲染不出来,即使后面再更新为正常宽高也渲染不出来 // 所以 hack 手动先将 linear 宽高也设置为 0,后面再更新为正确的数值或 %。 @@ -763,7 +768,8 @@ function useWrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record 0 && layoutInfo.height > 0)))) return createElement(View, backgroundProps) return createElement(View, backgroundProps, type === 'linear' ? createElement(LinearGradient, extendObject({ useAngle: true }, imageProps as LinearImageProps)) diff --git a/packages/webpack-plugin/test/runtime/react-native/mpx-view-gradient.spec.ts b/packages/webpack-plugin/test/runtime/react-native/mpx-view-gradient.spec.ts index 7f0facc73a..9886ef47d6 100644 --- a/packages/webpack-plugin/test/runtime/react-native/mpx-view-gradient.spec.ts +++ b/packages/webpack-plugin/test/runtime/react-native/mpx-view-gradient.spec.ts @@ -97,13 +97,15 @@ describe('mpx-view linear-gradient parser', () => { act(() => renderer!.root.findAllByType('View')[1].props.onLayout(layoutEvent(200, 100))) const gradient = renderer!.root.findByType('LinearGradient') - expect(gradient.props.style).toMatchObject({ width: '100%', height: '100%' }) + expect(gradient.props.style).toMatchObject({ width: 200, height: 100 }) expect(gradient.props.angle).toBeCloseTo(26.565) act(() => renderer!.unmount()) }) }) describe('mpx-view full-size gradient layout', () => { + beforeEach(() => { global.__mpx_mode__ = 'android' }) + afterEach(() => { global.__mpx_mode__ = 'ios' }) const render = (style: Record = {}) => React.createElement(MpxView, { 'enable-background': true, style: Object.assign({ width: 200, height: 100, backgroundImage: 'linear-gradient(90deg, red, blue)' }, style) @@ -155,3 +157,25 @@ describe('mpx-view full-size gradient layout', () => { act(() => renderer!.unmount()) }) }) + +describe('iOS gradient visibility restoration', () => { + test('does not mount at zero size and remounts with numeric size after restoration', () => { + let renderer: ReactTestRenderer + act(() => { + renderer = create(React.createElement(MpxView, { + 'enable-background': true, + style: { width: 100, height: 100, backgroundImage: 'linear-gradient(179deg, #fff 0%, #000 76%)', backgroundSize: ['100%', '100%'] } + })) + }) + expect(renderer!.root.findAllByType('LinearGradient')).toHaveLength(0) + ;[0, 98, 0, 98].forEach(height => { + act(() => renderer!.root.findAllByType('View')[1].props.onLayout(layoutEvent(98, height))) + if (height) { + expect(renderer!.root.findByType('LinearGradient').props.style).toMatchObject({ width: 98, height: 98 }) + } else { + expect(renderer!.root.findAllByType('LinearGradient')).toHaveLength(0) + } + }) + act(() => renderer!.unmount()) + }) +}) From 53707713b2489ba503dd96e33d40ce74ad96bf77 Mon Sep 17 00:00:00 2001 From: doslin Date: Mon, 14 Sep 2026 17:05:16 +0800 Subject: [PATCH 4/4] refactor: update gradient layout handling for iOS and improve test cases --- .../lib/runtime/components/react/mpx-view.tsx | 33 ++++--------------- .../react-native/mpx-view-gradient.spec.ts | 30 ++++++++++++----- 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx index 6f71c2457b..2c6b575860 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx @@ -172,21 +172,14 @@ const isPercent = (val: string | number | undefined): val is string => typeof va const isBackgroundSizeKeyword = (val: string | number): boolean => typeof val === 'string' && /^cover|contain$/.test(val) -const isFullSizeGradient = ({ type, sizeList, backgroundPosition, linearInfo }: PreImageInfo): boolean => { - // 四边撑满仅适用于无偏移、无需计算对角方向的全尺寸渐变。 - return __mpx_mode__ !== 'ios' && type === 'linear' && sizeList[0] === '100%' && sizeList[1] === '100%' && - !(linearInfo?.direction && diagonalAngleMap[linearInfo.direction]) && - (!backgroundPosition.length || (backgroundPosition[1] === 0 && backgroundPosition[3] === 0)) -} - const isNeedLayout = (preImageInfo: PreImageInfo): boolean => { - const { sizeList, backgroundPosition, type } = preImageInfo + const { sizeList, backgroundPosition, type, linearInfo } = preImageInfo const [width, height] = sizeList const bp = backgroundPosition if (type === 'linear') { - return !isFullSizeGradient(preImageInfo) && - (!(Number.isFinite(width) && Number.isFinite(height)) || isPercent(bp[1]) || isPercent(bp[3])) + return ((__mpx_mode__ === 'ios' || (linearInfo?.direction && diagonalAngleMap[linearInfo.direction])) && + !(Number.isFinite(width) && Number.isFinite(height))) || isPercent(bp[1]) || isPercent(bp[3]) } // 含有百分号,center 需计算布局 @@ -322,20 +315,9 @@ function backgroundSize (imageProps: ImageProps, preImageInfo: PreImageInfo, ima dimensions = calculateSize(width as number, imageSizeHeight / imageSizeWidth, layoutInfo?.width, true) if (!dimensions) return } else { // 数值类型 ImageStyle - if (isFullSizeGradient(preImageInfo)) { - dimensions = StyleSheet.absoluteFillObject - } else if (__mpx_mode__ === 'ios' && type === 'linear') { - dimensions = { - width: calcPercent(width as NumberVal, layoutWidth || 0), - height: calcPercent(height as NumberVal, layoutHeight || 0) - } - } else if (type === 'linear' && (!layoutWidth || !layoutHeight) && (isPercent(width) || isPercent(height))) { - // ios 上 linear 组件只要重新触发渲染,在渲染过程中外层容器 width 或者 height 被设置为 0,通过设置 % 的方式会渲染不出来,即使后面再更新为正常宽高也渲染不出来 - // 所以 hack 手动先将 linear 宽高也设置为 0,后面再更新为正确的数值或 %。 - dimensions = { - width: 0, - height: 0 - } as { width: NumberVal, height: NumberVal } + if (__mpx_mode__ === 'ios' && type === 'linear' && (!layoutWidth || !layoutHeight) && (isPercent(width) || isPercent(height))) { + // iOS 百分比渐变在零尺寸布局下先归零,布局恢复后再使用百分比。 + dimensions = { width: 0, height: 0 } } else { dimensions = { width: isPercent(width) ? width : +width, @@ -768,8 +750,7 @@ function useWrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record 0 && layoutInfo.height > 0)))) return createElement(View, backgroundProps) + if (type === 'linear' && pending) return createElement(View, backgroundProps) return createElement(View, backgroundProps, type === 'linear' ? createElement(LinearGradient, extendObject({ useAngle: true }, imageProps as LinearImageProps)) diff --git a/packages/webpack-plugin/test/runtime/react-native/mpx-view-gradient.spec.ts b/packages/webpack-plugin/test/runtime/react-native/mpx-view-gradient.spec.ts index 9886ef47d6..fda1ffd588 100644 --- a/packages/webpack-plugin/test/runtime/react-native/mpx-view-gradient.spec.ts +++ b/packages/webpack-plugin/test/runtime/react-native/mpx-view-gradient.spec.ts @@ -97,20 +97,20 @@ describe('mpx-view linear-gradient parser', () => { act(() => renderer!.root.findAllByType('View')[1].props.onLayout(layoutEvent(200, 100))) const gradient = renderer!.root.findByType('LinearGradient') - expect(gradient.props.style).toMatchObject({ width: 200, height: 100 }) + expect(gradient.props.style).toMatchObject({ width: '100%', height: '100%' }) expect(gradient.props.angle).toBeCloseTo(26.565) act(() => renderer!.unmount()) }) }) -describe('mpx-view full-size gradient layout', () => { - beforeEach(() => { global.__mpx_mode__ = 'android' }) +describe.each(['android', 'harmony'])('%s gradient layout', (platform) => { + beforeEach(() => { global.__mpx_mode__ = platform }) afterEach(() => { global.__mpx_mode__ = 'ios' }) const render = (style: Record = {}) => React.createElement(MpxView, { 'enable-background': true, style: Object.assign({ width: 200, height: 100, backgroundImage: 'linear-gradient(90deg, red, blue)' }, style) }) - const fillStyle = { position: 'absolute', left: 0, right: 0, top: 0, bottom: 0 } + const fillStyle = { position: 'absolute', width: '100%', height: '100%', left: 0, top: 0 } test.each([ [undefined], [['auto']], [['cover']], [['contain']], [['100%', '100%']] @@ -129,16 +129,28 @@ describe('mpx-view full-size gradient layout', () => { ])('keeps full dimensions for offset %s %s %s %s', (x, dx, y, dy) => { let renderer: ReactTestRenderer act(() => { renderer = create(render({ backgroundPosition: [x, dx, y, dy] })) }) - expect(renderer!.root.findAllByType('LinearGradient')).toHaveLength(0) + expect(renderer!.root.findByType('LinearGradient').props.style).toEqual({ position: 'absolute', width: '100%', height: '100%', [x]: dx, [y]: dy }) act(() => renderer!.root.findAllByType('View')[1].props.onLayout(layoutEvent(200, 100))) expect(renderer!.root.findByType('LinearGradient').props.style).toEqual({ position: 'absolute', width: '100%', height: '100%', [x]: dx, [y]: dy }) act(() => renderer!.root.findAllByType('View')[1].props.onLayout(layoutEvent(0, 100))) - expect(renderer!.root.findByType('LinearGradient').props.style).toMatchObject({ width: 0, height: 0 }) + expect(renderer!.root.findByType('LinearGradient').props.style).toMatchObject({ width: '100%', height: '100%' }) act(() => renderer!.root.findAllByType('View')[1].props.onLayout(layoutEvent(200, 100))) expect(renderer!.root.findByType('LinearGradient').props.style).toMatchObject({ width: '100%', height: '100%' }) act(() => renderer!.unmount()) }) + test('keeps layout for diagonal angles but renders partial percentages immediately', () => { + let renderer: ReactTestRenderer + act(() => { renderer = create(renderGradient(['100%', '100%'])) }) + expect(renderer!.root.findAllByType('LinearGradient')).toHaveLength(0) + act(() => renderer!.root.findAllByType('View')[1].props.onLayout(layoutEvent(200, 100))) + expect(renderer!.root.findByType('LinearGradient').props.angle).toBeCloseTo(26.565) + act(() => renderer!.unmount()) + act(() => { renderer = create(render({ backgroundSize: ['50%', '75%'] })) }) + expect(renderer!.root.findByType('LinearGradient').props.style).toMatchObject({ width: '50%', height: '75%' }) + act(() => renderer!.unmount()) + }) + test('switches between fill and layout-dependent styles using the cached layout', () => { let renderer: ReactTestRenderer act(() => { renderer = create(render()) }) @@ -159,7 +171,7 @@ describe('mpx-view full-size gradient layout', () => { }) describe('iOS gradient visibility restoration', () => { - test('does not mount at zero size and remounts with numeric size after restoration', () => { + test('waits for layout then keeps the gradient mounted with zero or percentage dimensions', () => { let renderer: ReactTestRenderer act(() => { renderer = create(React.createElement(MpxView, { @@ -171,9 +183,9 @@ describe('iOS gradient visibility restoration', () => { ;[0, 98, 0, 98].forEach(height => { act(() => renderer!.root.findAllByType('View')[1].props.onLayout(layoutEvent(98, height))) if (height) { - expect(renderer!.root.findByType('LinearGradient').props.style).toMatchObject({ width: 98, height: 98 }) + expect(renderer!.root.findByType('LinearGradient').props.style).toMatchObject({ width: '100%', height: '100%' }) } else { - expect(renderer!.root.findAllByType('LinearGradient')).toHaveLength(0) + expect(renderer!.root.findByType('LinearGradient').props.style).toMatchObject({ width: 0, height: 0 }) } }) act(() => renderer!.unmount())