diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm index 7c09d9cf73ef..22d461797ee7 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm @@ -261,7 +261,14 @@ - (void)boundsDidChange:(CGRect)newBounds } if (_state != nullptr) { - auto newState = ModalHostViewState{RCTSizeFromCGSize(newBounds.size)}; + CGPoint viewportOffset = CGPointZero; + UIView *modalView = _viewController.view; + if (modalView && modalView.window) { + CGRect frameInWindow = [modalView convertRect:modalView.bounds toView:nil]; + viewportOffset = frameInWindow.origin; + } + auto newState = ModalHostViewState{ + RCTSizeFromCGSize(newBounds.size), facebook::react::Point{(Float)viewportOffset.x, (Float)viewportOffset.y}}; _state->updateState(std::move(newState)); } } diff --git a/packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewShadowNode.cpp index 3598549813af..bbdfe2ac73d0 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewShadowNode.cpp @@ -14,4 +14,9 @@ namespace facebook::react { extern const char ModalHostViewComponentName[] = "ModalHostView"; +Transform ModalHostViewShadowNode::getTransform() const { + auto viewportOffset = getStateData().viewportOffset; + return Transform::Translate(viewportOffset.x, viewportOffset.y, 0); +} + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewShadowNode.h b/packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewShadowNode.h index 0b767161d136..8ff8ec2dae5c 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewShadowNode.h +++ b/packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewShadowNode.h @@ -38,6 +38,8 @@ class ModalHostViewShadowNode final : public ConcreteViewShadowNode< traits.set(ShadowNodeTraits::Trait::Unstable_uncullableView); return traits; } + + Transform getTransform() const override; }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewState.cpp b/packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewState.cpp index 9f5bff0bfac8..b70e5cc57dc8 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewState.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewState.cpp @@ -16,7 +16,8 @@ ModalHostViewState::ModalHostViewState() #ifdef RN_SERIALIZABLE_STATE folly::dynamic ModalHostViewState::getDynamic() const { return folly::dynamic::object("screenWidth", screenSize.width)( - "screenHeight", screenSize.height); + "screenHeight", screenSize.height)("viewportOffsetX", viewportOffset.x)( + "viewportOffsetY", viewportOffset.y); } #endif diff --git a/packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewState.h b/packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewState.h index 8631094fd8d0..f1b75be27399 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewState.h +++ b/packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewState.h @@ -27,15 +27,21 @@ class ModalHostViewState final { ModalHostViewState(); ModalHostViewState(Size screenSize_) : screenSize(screenSize_) {}; + ModalHostViewState(Size screenSize_, Point viewportOffset_) + : screenSize(screenSize_), viewportOffset(viewportOffset_) {}; #ifdef RN_SERIALIZABLE_STATE ModalHostViewState(const ModalHostViewState &previousState, folly::dynamic data) : screenSize( - Size{.width = (Float)data["screenWidth"].getDouble(), .height = (Float)data["screenHeight"].getDouble()}) { - }; + Size{.width = (Float)data["screenWidth"].getDouble(), .height = (Float)data["screenHeight"].getDouble()}), + viewportOffset( + Point{ + .x = data.count("viewportOffsetX") ? (Float)data["viewportOffsetX"].getDouble() : 0.0f, + .y = data.count("viewportOffsetY") ? (Float)data["viewportOffsetY"].getDouble() : 0.0f}) {}; #endif const Size screenSize{}; + const Point viewportOffset{}; #ifdef RN_SERIALIZABLE_STATE folly::dynamic getDynamic() const; diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api index 011a67c223d2..14346926b147 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api @@ -2758,12 +2758,15 @@ class facebook::react::ModalHostViewShadowNode : public facebook::react::Concret public ModalHostViewShadowNode(const facebook::react::ShadowNode& sourceShadowNode, const facebook::react::ShadowNodeFragment& fragment); public ModalHostViewShadowNode(const facebook::react::ShadowNodeFragment& fragment, const facebook::react::ShadowNodeFamily::Shared& family, facebook::react::ShadowNodeTraits traits); public static facebook::react::ShadowNodeTraits BaseTraits(); + public virtual facebook::react::Transform getTransform() const override; } class facebook::react::ModalHostViewState { public ModalHostViewState(); public ModalHostViewState(const facebook::react::ModalHostViewState& previousState, folly::dynamic data); public ModalHostViewState(facebook::react::Size screenSize_); + public ModalHostViewState(facebook::react::Size screenSize_, facebook::react::Point viewportOffset_); + public const facebook::react::Point viewportOffset; public const facebook::react::Size screenSize; public folly::dynamic getDynamic() const; public using Shared = std::shared_ptr; diff --git a/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api index 4293fa4df491..46165866e9fd 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api @@ -4974,11 +4974,14 @@ class facebook::react::ModalHostViewShadowNode : public facebook::react::Concret public ModalHostViewShadowNode(const facebook::react::ShadowNode& sourceShadowNode, const facebook::react::ShadowNodeFragment& fragment); public ModalHostViewShadowNode(const facebook::react::ShadowNodeFragment& fragment, const facebook::react::ShadowNodeFamily::Shared& family, facebook::react::ShadowNodeTraits traits); public static facebook::react::ShadowNodeTraits BaseTraits(); + public virtual facebook::react::Transform getTransform() const override; } class facebook::react::ModalHostViewState { public ModalHostViewState(); public ModalHostViewState(facebook::react::Size screenSize_); + public ModalHostViewState(facebook::react::Size screenSize_, facebook::react::Point viewportOffset_); + public const facebook::react::Point viewportOffset; public const facebook::react::Size screenSize; public using Shared = std::shared_ptr; } diff --git a/scripts/cxx-api/api-snapshots/ReactCommonFrameworksCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonFrameworksCxx.api index b3011c1fec07..696b0476ead2 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonFrameworksCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonFrameworksCxx.api @@ -1646,11 +1646,14 @@ class facebook::react::ModalHostViewShadowNode : public facebook::react::Concret public ModalHostViewShadowNode(const facebook::react::ShadowNode& sourceShadowNode, const facebook::react::ShadowNodeFragment& fragment); public ModalHostViewShadowNode(const facebook::react::ShadowNodeFragment& fragment, const facebook::react::ShadowNodeFamily::Shared& family, facebook::react::ShadowNodeTraits traits); public static facebook::react::ShadowNodeTraits BaseTraits(); + public virtual facebook::react::Transform getTransform() const override; } class facebook::react::ModalHostViewState { public ModalHostViewState(); public ModalHostViewState(facebook::react::Size screenSize_); + public ModalHostViewState(facebook::react::Size screenSize_, facebook::react::Point viewportOffset_); + public const facebook::react::Point viewportOffset; public const facebook::react::Size screenSize; public using Shared = std::shared_ptr; }