diff --git a/packages/react-native/src/private/components/virtualview/VirtualView.js b/packages/react-native/src/private/components/virtualview/VirtualView.js index c8652578eae..51183386877 100644 --- a/packages/react-native/src/private/components/virtualview/VirtualView.js +++ b/packages/react-native/src/private/components/virtualview/VirtualView.js @@ -56,6 +56,7 @@ const VirtualViewNativeComponent: typeof VirtualViewClassicNativeComponent = type VirtualViewComponent = component( children?: React.Node, + hiddenStyle?: (targetRect: Rect) => ViewStyleProp, nativeID?: string, ref?: ?React.RefSetter>, style?: ?ViewStyleProp, @@ -63,16 +64,21 @@ type VirtualViewComponent = component( removeClippedSubviews?: boolean, ); -type HiddenHeight = number; const NotHidden = null; +type HiddenStyle = Exclude; -type State = HiddenHeight | typeof NotHidden; +type State = HiddenStyle | typeof NotHidden; + +function defaultHiddenStyle(targetRect: Rect): ViewStyleProp { + return {minHeight: targetRect.height, minWidth: targetRect.width}; +} function createVirtualView(initialState: State): VirtualViewComponent { const initialHidden = initialState !== NotHidden; component VirtualView( children?: React.Node, + hiddenStyle: (targetRect: Rect) => ViewStyleProp = defaultHiddenStyle, nativeID?: string, ref?: ?React.RefSetter>, style?: ?ViewStyleProp, @@ -112,9 +118,8 @@ function createVirtualView(initialState: State): VirtualViewComponent { }); } VirtualViewMode.Hidden => { - const {height} = event.nativeEvent.targetRect; startTransition(() => { - setState(height as HiddenHeight); + setState(hiddenStyle(event.nativeEvent.targetRect) ?? {}); emitModeChange?.(); }); } @@ -134,9 +139,7 @@ function createVirtualView(initialState: State): VirtualViewComponent { } style={ isHidden - ? StyleSheet.compose(style, { - height: Math.abs(nullthrows(state) as HiddenHeight), - }) + ? StyleSheet.compose(style, nullthrows(state) as HiddenStyle) : style } onModeChange={handleModeChange}> @@ -159,8 +162,10 @@ function createVirtualView(initialState: State): VirtualViewComponent { export default createVirtualView(NotHidden) as VirtualViewComponent; -export function createHiddenVirtualView(height: number): VirtualViewComponent { - return createVirtualView(height as HiddenHeight); +export function createHiddenVirtualView( + style: ViewStyleProp, +): VirtualViewComponent { + return createVirtualView((style ?? {}) as HiddenStyle); } export const _logs: {states?: Array} = {}; diff --git a/packages/react-native/src/private/components/virtualview/__tests__/VirtualView-itest.js b/packages/react-native/src/private/components/virtualview/__tests__/VirtualView-itest.js index a7b5516f77b..9a861bc3c89 100644 --- a/packages/react-native/src/private/components/virtualview/__tests__/VirtualView-itest.js +++ b/packages/react-native/src/private/components/virtualview/__tests__/VirtualView-itest.js @@ -119,19 +119,19 @@ describe('mode changes', () => { }); describe('styles', () => { - test('does not set height when visible', () => { + test('does not set styles when visible', () => { const root = Fantom.createRoot(); Fantom.runTask(() => { root.render(); }); - expect(root.getRenderedOutput({props: ['height']}).toJSX()).toEqual( - , - ); + expect( + root.getRenderedOutput({props: ['minHeight', 'minWidth']}).toJSX(), + ).toEqual(); }); - test('does not set height when prerendered', () => { + test('does not set styles when prerendered', () => { const root = Fantom.createRoot(); const viewRef = createRef>(); @@ -141,12 +141,12 @@ describe('styles', () => { dispatchModeChangeEvent(viewRef.current, VirtualViewMode.Prerender); - expect(root.getRenderedOutput({props: ['height']}).toJSX()).toEqual( - , - ); + expect( + root.getRenderedOutput({props: ['minHeight', 'minWidth']}).toJSX(), + ).toEqual(); }); - test('sets height when hidden', () => { + test('sets styles when hidden', () => { const root = Fantom.createRoot(); const viewRef = createRef>(); @@ -156,9 +156,9 @@ describe('styles', () => { dispatchModeChangeEvent(viewRef.current, VirtualViewMode.Hidden); - expect(root.getRenderedOutput({props: ['height']}).toJSX()).toEqual( - , - ); + expect( + root.getRenderedOutput({props: ['minHeight', 'minWidth']}).toJSX(), + ).toEqual(); }); });