Disable view culling in ScrollView with overflow visible (#51947)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/51947

changelog: [internal]

disable view culling if ScrollView has overflow set to visible

Reviewed By: rubennorte

Differential Revision: D76419519

fbshipit-source-id: 002bde2ab4dda0fc635ae04cb4e34390a0e13d80
This commit is contained in:
Samuel Susla authored and Facebook GitHub Bot committed 2025-06-11 06:35:28 -07:00
1 parent dac60204f3
commit cbc327ce53
2 files changed
+33 -6

No files matched your search

@@ -2534,3 +2534,25 @@ describe('opt out mechanism - Unstable_uncullableView & Unstable_uncullableTrace
);
});
});
describe('culling inside ScrollView with overflow visible', () => {
it('shows view outside of bounds', () => {
const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100});
Fantom.runTask(() => {
root.render(
<ScrollView style={{height: 100, width: 100, overflow: 'visible'}}>
<View
nativeID={'child'}
style={{height: 10, width: 10, marginTop: 145}} // 145 is below the viewport
/>
</ScrollView>,
);
});
// Child is not culled because overflow:visible.
expect(root.takeMountingManagerLogs()).toContain(
'Create {type: "View", nativeID: "child"}',
);
});
});
@@ -23,12 +23,17 @@ CullingContext CullingContext::adjustCullingContextIfNeeded(
if (ReactNativeFeatureFlags::enableViewCulling()) {
if (auto scrollViewShadowNode =
dynamic_cast<const ScrollViewShadowNode*>(pair.shadowNode)) {
cullingContext.frame.origin =
-scrollViewShadowNode->getContentOriginOffset(
/* includeTransform */ true);
cullingContext.frame.size =
scrollViewShadowNode->getLayoutMetrics().frame.size;
cullingContext.transform = Transform::Identity();
if (scrollViewShadowNode->getConcreteProps().yogaStyle.overflow() !=
yoga::Overflow::Visible) {
cullingContext.frame.origin =
-scrollViewShadowNode->getContentOriginOffset(
/* includeTransform */ true);
cullingContext.frame.size =
scrollViewShadowNode->getLayoutMetrics().frame.size;
cullingContext.transform = Transform::Identity();
} else {
cullingContext = {};
}
} else if (pair.shadowView.traits.check(
ShadowNodeTraits::Trait::RootNodeKind)) {
cullingContext = {};