Add getDiffProps for ScrollView component (#51168)

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

See title

Changelog: [Internal]

Reviewed By: rshest

Differential Revision: D74327336

fbshipit-source-id: 9e306400578ac6d83c49537ab2c38e86209fbcfd
This commit is contained in:
Nick Lefever
2025-05-08 09:37:26 -07:00
committed by Facebook GitHub Bot
parent 4591bb2909
commit 0dbfcda6c6
3 changed files with 277 additions and 1 deletions
@@ -224,7 +224,8 @@ jni::local_ref<jobject> getProps(
auto* newProps = newShadowView.props.get();
if ((ReactNativeFeatureFlags::enablePropsUpdateReconciliationAndroid()) &&
(strcmp(newShadowView.componentName, "View") == 0 ||
strcmp(newShadowView.componentName, "Image") == 0)) {
strcmp(newShadowView.componentName, "Image") == 0 ||
strcmp(newShadowView.componentName, "ScrollView") == 0)) {
return ReadableNativeMap::newObjectCxxArgs(
newProps->getDiffProps(oldProps));
}
@@ -592,4 +592,273 @@ SharedDebugStringConvertibleList ScrollViewProps::getDebugProps() const {
}
#endif
#ifdef ANDROID
static folly::dynamic convertScrollViewMaintainVisibleContentPosition(
const ScrollViewMaintainVisibleContentPosition& value) {
folly::dynamic result = folly::dynamic::object();
result["minIndexForVisible"] = value.minIndexForVisible;
if (value.autoscrollToTopThreshold.has_value()) {
result["autoscrollToTopThreshold"] = value.autoscrollToTopThreshold.value();
}
return result;
}
static folly::dynamic convertEdgeInsets(const EdgeInsets& edgeInsets) {
folly::dynamic edgeInsetsResult = folly::dynamic::object();
edgeInsetsResult["left"] = edgeInsets.left;
edgeInsetsResult["top"] = edgeInsets.top;
edgeInsetsResult["right"] = edgeInsets.right;
edgeInsetsResult["bottom"] = edgeInsets.bottom;
return edgeInsetsResult;
}
static folly::dynamic convertPoint(const Point& point) {
folly::dynamic pointResult = folly::dynamic::object();
pointResult["y"] = point.y;
pointResult["x"] = point.x;
return pointResult;
}
folly::dynamic ScrollViewProps::getDiffProps(const Props* prevProps) const {
static const auto defaultProps = ScrollViewProps();
const ScrollViewProps* oldProps = prevProps == nullptr
? &defaultProps
: static_cast<const ScrollViewProps*>(prevProps);
folly::dynamic result = ViewProps::getDiffProps(oldProps);
if (alwaysBounceHorizontal != oldProps->alwaysBounceHorizontal) {
result["alwaysBounceHorizontal"] = alwaysBounceHorizontal;
}
if (alwaysBounceVertical != oldProps->alwaysBounceVertical) {
result["alwaysBounceVertical"] = alwaysBounceVertical;
}
if (bounces != oldProps->bounces) {
result["bounces"] = bounces;
}
if (bouncesZoom != oldProps->bouncesZoom) {
result["bouncesZoom"] = bouncesZoom;
}
if (canCancelContentTouches != oldProps->canCancelContentTouches) {
result["canCancelContentTouches"] = canCancelContentTouches;
}
if (centerContent != oldProps->centerContent) {
result["centerContent"] = centerContent;
}
if (automaticallyAdjustContentInsets !=
oldProps->automaticallyAdjustContentInsets) {
result["automaticallyAdjustContentInsets"] =
automaticallyAdjustContentInsets;
}
if (automaticallyAdjustsScrollIndicatorInsets !=
oldProps->automaticallyAdjustsScrollIndicatorInsets) {
result["automaticallyAdjustsScrollIndicatorInsets"] =
automaticallyAdjustsScrollIndicatorInsets;
}
if (automaticallyAdjustKeyboardInsets !=
oldProps->automaticallyAdjustKeyboardInsets) {
result["automaticallyAdjustKeyboardInsets"] =
automaticallyAdjustKeyboardInsets;
}
if (decelerationRate != oldProps->decelerationRate) {
result["decelerationRate"] = decelerationRate;
}
if (endDraggingSensitivityMultiplier !=
oldProps->endDraggingSensitivityMultiplier) {
result["endDraggingSensitivityMultiplier"] =
endDraggingSensitivityMultiplier;
}
if (directionalLockEnabled != oldProps->directionalLockEnabled) {
result["directionalLockEnabled"] = directionalLockEnabled;
}
if (indicatorStyle != oldProps->indicatorStyle) {
switch (indicatorStyle) {
case ScrollViewIndicatorStyle::Default:
result["indicatorStyle"] = "default";
break;
case ScrollViewIndicatorStyle::Black:
result["indicatorStyle"] = "black";
break;
case ScrollViewIndicatorStyle::White:
result["indicatorStyle"] = "white";
break;
}
}
if (keyboardDismissMode != oldProps->keyboardDismissMode) {
switch (keyboardDismissMode) {
case ScrollViewKeyboardDismissMode::None:
result["keyboardDismissMode"] = "none";
break;
case ScrollViewKeyboardDismissMode::OnDrag:
result["keyboardDismissMode"] = "on-drag";
break;
case ScrollViewKeyboardDismissMode::Interactive:
result["keyboardDismissMode"] = "interactive";
break;
}
}
if (maintainVisibleContentPosition !=
oldProps->maintainVisibleContentPosition) {
if (maintainVisibleContentPosition.has_value()) {
result["maintainVisibleContentPosition"] =
convertScrollViewMaintainVisibleContentPosition(
maintainVisibleContentPosition.value());
} else {
result["maintainVisibleContentPosition"] = folly::dynamic(nullptr);
}
}
if (maximumZoomScale != oldProps->maximumZoomScale) {
result["maximumZoomScale"] = maximumZoomScale;
}
if (minimumZoomScale != oldProps->minimumZoomScale) {
result["minimumZoomScale"] = minimumZoomScale;
}
if (scrollEnabled != oldProps->scrollEnabled) {
result["scrollEnabled"] = scrollEnabled;
}
if (pagingEnabled != oldProps->pagingEnabled) {
result["pagingEnabled"] = pagingEnabled;
}
if (pinchGestureEnabled != oldProps->pinchGestureEnabled) {
result["pinchGestureEnabled"] = pinchGestureEnabled;
}
if (scrollsToTop != oldProps->scrollsToTop) {
result["scrollsToTop"] = scrollsToTop;
}
if (showsHorizontalScrollIndicator !=
oldProps->showsHorizontalScrollIndicator) {
result["showsHorizontalScrollIndicator"] = showsHorizontalScrollIndicator;
}
if (showsVerticalScrollIndicator != oldProps->showsVerticalScrollIndicator) {
result["showsVerticalScrollIndicator"] = showsVerticalScrollIndicator;
}
if (persistentScrollbar != oldProps->persistentScrollbar) {
result["persistentScrollbar"] = persistentScrollbar;
}
if (horizontal != oldProps->horizontal) {
result["horizontal"] = horizontal;
}
if (scrollEventThrottle != oldProps->scrollEventThrottle) {
result["scrollEventThrottle"] = scrollEventThrottle;
}
if (zoomScale != oldProps->zoomScale) {
result["zoomScale"] = zoomScale;
}
if (contentInset != oldProps->contentInset) {
result["contentInset"] = convertEdgeInsets(contentInset);
}
if (contentOffset != oldProps->contentOffset) {
result["contentOffset"] = convertPoint(contentOffset);
}
if (scrollIndicatorInsets != oldProps->scrollIndicatorInsets) {
result["scrollIndicatorInsets"] = convertEdgeInsets(scrollIndicatorInsets);
}
if (snapToInterval != oldProps->snapToInterval) {
result["snapToInterval"] = snapToInterval;
}
if (snapToAlignment != oldProps->snapToAlignment) {
switch (snapToAlignment) {
case ScrollViewSnapToAlignment::Start:
result["snapToAlignment"] = "start";
break;
case ScrollViewSnapToAlignment::Center:
result["snapToAlignment"] = "center";
break;
case ScrollViewSnapToAlignment::End:
result["snapToAlignment"] = "end";
break;
}
}
if (disableIntervalMomentum != oldProps->disableIntervalMomentum) {
result["disableIntervalMomentum"] = disableIntervalMomentum;
}
if (snapToOffsets != oldProps->snapToOffsets) {
auto snapToOffsetsArray = folly::dynamic::array();
for (const auto& snapToOffset : snapToOffsets) {
snapToOffsetsArray.push_back(snapToOffset);
}
result["snapToOffsets"] = snapToOffsetsArray;
}
if (snapToStart != oldProps->snapToStart) {
result["snapToStart"] = snapToStart;
}
if (snapToEnd != oldProps->snapToEnd) {
result["snapToEnd"] = snapToEnd;
}
if (contentInsetAdjustmentBehavior !=
oldProps->contentInsetAdjustmentBehavior) {
switch (contentInsetAdjustmentBehavior) {
case ContentInsetAdjustmentBehavior::Never:
result["contentInsetAdjustmentBehavior"] = "never";
break;
case ContentInsetAdjustmentBehavior::Automatic:
result["contentInsetAdjustmentBehavior"] = "automatic";
break;
case ContentInsetAdjustmentBehavior::ScrollableAxes:
result["contentInsetAdjustmentBehavior"] = "scrollableAxes";
break;
case ContentInsetAdjustmentBehavior::Always:
result["contentInsetAdjustmentBehavior"] = "always";
break;
}
}
if (scrollToOverflowEnabled != oldProps->scrollToOverflowEnabled) {
result["scrollToOverflowEnabled"] = scrollToOverflowEnabled;
}
if (isInvertedVirtualizedList != oldProps->isInvertedVirtualizedList) {
result["isInvertedVirtualizedList"] = isInvertedVirtualizedList;
}
if (sendMomentumEvents != oldProps->sendMomentumEvents) {
result["sendMomentumEvents"] = sendMomentumEvents;
}
if (nestedScrollEnabled != oldProps->nestedScrollEnabled) {
result["nestedScrollEnabled"] = nestedScrollEnabled;
}
return result;
}
#endif
} // namespace facebook::react
@@ -82,6 +82,12 @@ class ScrollViewProps final : public ViewProps {
#if RN_DEBUG_STRING_CONVERTIBLE
SharedDebugStringConvertibleList getDebugProps() const override;
#endif
#ifdef ANDROID
folly::dynamic getDiffProps(const Props* prevProps) const override;
#endif
};
} // namespace facebook::react