diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.cpp index a8ecce51c482f7..6c8a1dd7a5639d 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.cpp @@ -63,9 +63,11 @@ void ScrollViewShadowNode::layout(LayoutContext layoutContext) { updateStateIfNeeded(); } -Point ScrollViewShadowNode::getContentOriginOffset() const { +Point ScrollViewShadowNode::getContentOriginOffset( + bool /*includeTransform*/) const { auto stateData = getStateData(); auto contentOffset = stateData.contentOffset; + return {-contentOffset.x, -contentOffset.y + stateData.scrollAwayPaddingTop}; } diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.h b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.h index cc4d7e119cc2d1..a0fbcf4ca1e9a1 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.h +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.h @@ -37,7 +37,7 @@ class ScrollViewShadowNode final : public ConcreteViewShadowNode< #pragma mark - LayoutableShadowNode void layout(LayoutContext layoutContext) override; - Point getContentOriginOffset() const override; + Point getContentOriginOffset(bool includeTransform) const override; private: void updateStateIfNeeded(); diff --git a/packages/react-native/ReactCommon/react/renderer/core/LayoutableShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/core/LayoutableShadowNode.cpp index 5ddb4c38996850..a62adc2c36e003 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/LayoutableShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/LayoutableShadowNode.cpp @@ -151,7 +151,11 @@ LayoutMetrics LayoutableShadowNode::computeRelativeLayoutMetrics( } if (i != 0 && policy.includeTransform) { - resultFrame.origin += currentShadowNode->getContentOriginOffset(); + // Transformation is not applied here and instead we delegated out in + // getContentOriginOffset. The reason is that for `ScrollViewShadowNode`, + // we need to consider `scrollAwayPaddingTop` which should NOT be included + // in the transform. + resultFrame.origin += currentShadowNode->getContentOriginOffset(true); } if (policy.enableOverflowClipping) { @@ -188,7 +192,8 @@ Transform LayoutableShadowNode::getTransform() const { return Transform::Identity(); } -Point LayoutableShadowNode::getContentOriginOffset() const { +Point LayoutableShadowNode::getContentOriginOffset( + bool /*includeTransform*/) const { return {0, 0}; } @@ -269,7 +274,7 @@ ShadowNode::Shared LayoutableShadowNode::findNodeAtPoint( } auto newPoint = point - transformedFrame.origin - - layoutableShadowNode->getContentOriginOffset(); + layoutableShadowNode->getContentOriginOffset(false); auto sortedChildren = node->getChildren(); std::stable_sort( diff --git a/packages/react-native/ReactCommon/react/renderer/core/LayoutableShadowNode.h b/packages/react-native/ReactCommon/react/renderer/core/LayoutableShadowNode.h index cae02ce15d1ab3..849ccc6aca04f5 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/LayoutableShadowNode.h +++ b/packages/react-native/ReactCommon/react/renderer/core/LayoutableShadowNode.h @@ -123,7 +123,7 @@ class LayoutableShadowNode : public ShadowNode { * `LayoutableShadowNode::getRelativeLayoutMetrics` and * `LayoutableShadowNode::findNodeAtPoint`. */ - virtual Point getContentOriginOffset() const; + virtual Point getContentOriginOffset(bool includeTransform) const; /* * Sets layout metrics for the shadow node. diff --git a/packages/react-native/ReactCommon/react/renderer/core/tests/TestComponent.h b/packages/react-native/ReactCommon/react/renderer/core/tests/TestComponent.h index b3f5fefe499331..061b2fcad68638 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/tests/TestComponent.h +++ b/packages/react-native/ReactCommon/react/renderer/core/tests/TestComponent.h @@ -76,7 +76,8 @@ class TestShadowNode final : public ConcreteViewShadowNode< facebook::react::Point _contentOriginOffset{}; - facebook::react::Point getContentOriginOffset() const override { + facebook::react::Point getContentOriginOffset( + bool /*includeTransform*/) const override { return _contentOriginOffset; } }; diff --git a/packages/react-native/ReactCommon/react/renderer/dom/DOM.cpp b/packages/react-native/ReactCommon/react/renderer/dom/DOM.cpp index 417e19ce2df4bc..37d784cade03c3 100644 --- a/packages/react-native/ReactCommon/react/renderer/dom/DOM.cpp +++ b/packages/react-native/ReactCommon/react/renderer/dom/DOM.cpp @@ -357,7 +357,7 @@ DOMPoint getScrollPosition( return DOMPoint{}; } - auto scrollPosition = layoutableShadowNode->getContentOriginOffset(); + auto scrollPosition = layoutableShadowNode->getContentOriginOffset(false); return DOMPoint{ .x = scrollPosition.x == 0 ? 0 : -scrollPosition.x,