Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,21 @@ class SandboxReactNativeView(
val w = right - left
val h = bottom - top
for (i in 0 until childCount) {
getChildAt(i).layout(0, 0, w, h)
val child = getChildAt(i)
// The child is a ReactSurfaceView from a SEPARATE ReactHost. Fabric
// lays our view out by calling layout() directly, without a measure
// pass, so the child never receives onMeasure(). But ReactSurfaceView
// only pushes layout constraints to its surface from onMeasure() (and
// its onLayout() is a no-op until wasMeasured is true). Without an
// explicit measure the nested surface keeps its initial constructor
// constraints and renders blank (regression surfaced on RN 0.85).
// Measure with EXACTLY specs so updateLayoutSpecs() runs with our real
// size, then lay the child out to fill us.
child.measure(
MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY),
)
child.layout(0, 0, w, h)
}
}

Expand Down
9 changes: 7 additions & 2 deletions packages/react-native-sandbox/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
useRef,
} from 'react'
import type {NativeSyntheticEvent} from 'react-native'
import {StyleProp, StyleSheet, View, ViewProps, ViewStyle} from 'react-native'
import {StyleProp, View, ViewProps, ViewStyle} from 'react-native'

import type {NativeSandboxReactNativeViewComponentType} from '../specs/NativeSandboxReactNativeView'
import NativeSandboxReactNativeView, {
Expand Down Expand Up @@ -305,9 +305,14 @@ const SandboxReactNativeView = forwardRef<
return null
}, [])

// The native sandbox view fills the user-styled wrapper as an in-flow
// flex child. It used to be position:absolute (StyleSheet.absoluteFillObject),
// but on RN 0.85 an absolutely-positioned child with all-zero insets no longer
// stretches to a flex-sized parent — it collapses to height 0 and the embedded
// surface renders blank. flex:1 makes it claim the wrapper's space reliably.
const _style: StyleProp<ViewStyle> = useMemo(
() => ({
...StyleSheet.absoluteFillObject,
flex: 1,
}),
[]
)
Expand Down