ScrollView: Delete unstable_setEnableSyncOnScroll (#47399)

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

Deletes `unstable_setEnableSyncOnScroll` which we are no longer experirmenting with in React Native.

Changelog:
[Internal] - Deleted `unstable_setEnableSyncOnScroll` on `ScrollView`, which was never part of the React Native Public API.

Reviewed By: tdn120, sammy-SC

Differential Revision: D65449039

fbshipit-source-id: 6608d5ccca477f1da5e0168c4a342cce17014b08
This commit is contained in:
Tim Yung
2024-11-07 00:00:14 -08:00
committed by Facebook GitHub Bot
parent f01b47257a
commit 2dab7b078d
20 changed files with 55 additions and 299 deletions
@@ -31,7 +31,6 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig = {
pagingEnabled: true,
persistentScrollbar: true,
horizontal: true,
enableSyncOnScroll: true,
scrollEnabled: true,
scrollEventThrottle: true,
scrollPerfTag: true,
@@ -8,10 +8,6 @@
* @flow strict-local
*/
import type {
TScrollViewNativeComponentInstance,
TScrollViewNativeImperativeHandle,
} from '../../../src/private/components/useSyncOnScroll';
import type {HostInstance} from '../../Renderer/shims/ReactNativeTypes';
import type {EdgeInsetsProp} from '../../StyleSheet/EdgeInsetsPropType';
import type {PointProp} from '../../StyleSheet/PointPropType';
@@ -46,7 +42,6 @@ import StyleSheet from '../../StyleSheet/StyleSheet';
import Dimensions from '../../Utilities/Dimensions';
import dismissKeyboard from '../../Utilities/dismissKeyboard';
import Platform from '../../Utilities/Platform';
import EventEmitter from '../../vendor/emitter/EventEmitter';
import Keyboard from '../Keyboard/Keyboard';
import TextInputState from '../TextInput/TextInputState';
import processDecelerationRate from './processDecelerationRate';
@@ -152,7 +147,7 @@ export type DecelerationRateType = 'fast' | 'normal' | number;
export type ScrollResponderType = ScrollViewImperativeMethods;
type PublicScrollViewInstance = $ReadOnly<{|
...$Exact<TScrollViewNativeComponentInstance>,
...HostInstance,
...ScrollViewImperativeMethods,
|}>;
@@ -743,10 +738,6 @@ class ScrollView extends React.Component<Props, State> {
_subscriptionKeyboardDidShow: ?EventSubscription = null;
_subscriptionKeyboardDidHide: ?EventSubscription = null;
#onScrollEmitter: ?EventEmitter<{
scroll: [{x: number, y: number}],
}> = null;
state: State = {
layoutHeight: null,
};
@@ -817,8 +808,6 @@ class ScrollView extends React.Component<Props, State> {
if (this._scrollAnimatedValueAttachment) {
this._scrollAnimatedValueAttachment.detach();
}
this.#onScrollEmitter?.removeAllListeners();
}
/**
@@ -844,9 +833,8 @@ class ScrollView extends React.Component<Props, State> {
return this._innerView.nativeInstance;
};
getNativeScrollRef: () => TScrollViewNativeComponentInstance | null = () => {
const {nativeInstance} = this._scrollView;
return nativeInstance == null ? null : nativeInstance.componentRef.current;
getNativeScrollRef: () => HostInstance | null = () => {
return this._scrollView.nativeInstance;
};
/**
@@ -937,20 +925,6 @@ class ScrollView extends React.Component<Props, State> {
Commands.flashScrollIndicators(component);
};
_subscribeToOnScroll: (
callback: ({x: number, y: number}) => void,
) => EventSubscription = callback => {
let onScrollEmitter = this.#onScrollEmitter;
if (onScrollEmitter == null) {
onScrollEmitter = new EventEmitter();
this.#onScrollEmitter = onScrollEmitter;
// This is the first subscription, so make sure the native component is
// also configured to output synchronous scroll events.
this._scrollView.nativeInstance?.unstable_setEnableSyncOnScroll(true);
}
return onScrollEmitter.addListener('scroll', callback);
};
/**
* This method should be used as the callback to onFocus in a TextInputs'
* parent view. Note that any module using this mixin needs to return
@@ -1154,11 +1128,6 @@ class ScrollView extends React.Component<Props, State> {
_handleScroll = (e: ScrollEvent) => {
this._observedScrollSinceBecomingResponder = true;
this.props.onScroll && this.props.onScroll(e);
this.#onScrollEmitter?.emit('scroll', {
x: e.nativeEvent.contentOffset.x,
y: e.nativeEvent.contentOffset.y,
});
};
_handleLayout = (e: LayoutEvent) => {
@@ -1181,45 +1150,36 @@ class ScrollView extends React.Component<Props, State> {
(instance: InnerViewInstance): InnerViewInstance => instance,
);
_scrollView: RefForwarder<
TScrollViewNativeImperativeHandle,
PublicScrollViewInstance | null,
> = createRefForwarder(nativeImperativeHandle => {
const nativeInstance = nativeImperativeHandle.componentRef.current;
if (nativeInstance == null) {
return null;
}
_scrollView: RefForwarder<HostInstance, PublicScrollViewInstance | null> =
createRefForwarder(nativeInstance => {
// This is a hack. Ideally we would forwardRef to the underlying
// host component. However, since ScrollView has it's own methods that can be
// called as well, if we used the standard forwardRef then these
// methods wouldn't be accessible and thus be a breaking change.
//
// Therefore we edit ref to include ScrollView's public methods so that
// they are callable from the ref.
// This is a hack. Ideally we would forwardRef to the underlying
// host component. However, since ScrollView has it's own methods that can be
// called as well, if we used the standard forwardRef then these
// methods wouldn't be accessible and thus be a breaking change.
//
// Therefore we edit ref to include ScrollView's public methods so that
// they are callable from the ref.
// $FlowFixMe[prop-missing] - Known issue with appending custom methods.
const publicInstance: PublicScrollViewInstance = Object.assign(
nativeInstance,
{
getScrollResponder: this.getScrollResponder,
getScrollableNode: this.getScrollableNode,
getInnerViewNode: this.getInnerViewNode,
getInnerViewRef: this.getInnerViewRef,
getNativeScrollRef: this.getNativeScrollRef,
scrollTo: this.scrollTo,
scrollToEnd: this.scrollToEnd,
flashScrollIndicators: this.flashScrollIndicators,
scrollResponderZoomTo: this.scrollResponderZoomTo,
scrollResponderScrollNativeHandleToKeyboard:
this.scrollResponderScrollNativeHandleToKeyboard,
},
);
// $FlowFixMe[prop-missing] - Known issue with appending custom methods.
const publicInstance: PublicScrollViewInstance = Object.assign(
nativeInstance,
{
getScrollResponder: this.getScrollResponder,
getScrollableNode: this.getScrollableNode,
getInnerViewNode: this.getInnerViewNode,
getInnerViewRef: this.getInnerViewRef,
getNativeScrollRef: this.getNativeScrollRef,
scrollTo: this.scrollTo,
scrollToEnd: this.scrollToEnd,
flashScrollIndicators: this.flashScrollIndicators,
scrollResponderZoomTo: this.scrollResponderZoomTo,
// TODO: Replace unstable_subscribeToOnScroll once scrollView.addEventListener('scroll', (e: ScrollEvent) => {}, {passive: false});
unstable_subscribeToOnScroll: this._subscribeToOnScroll,
scrollResponderScrollNativeHandleToKeyboard:
this.scrollResponderScrollNativeHandleToKeyboard,
},
);
return publicInstance;
});
return publicInstance;
});
/**
* Warning, this may be called several times for a single keyboard opening.
@@ -1829,8 +1789,9 @@ class ScrollView extends React.Component<Props, State> {
}
const refreshControl = this.props.refreshControl;
const scrollViewRef: React.RefSetter<TScrollViewNativeImperativeHandle | null> =
this._scrollView.getForwardingRef(this.props.scrollViewRef);
const scrollViewRef = this._scrollView.getForwardingRef(
this.props.scrollViewRef,
);
if (refreshControl) {
if (Platform.OS === 'ios') {
@@ -45,7 +45,6 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig =
diff: require('../../Utilities/differ/pointsDiffer'),
},
decelerationRate: true,
enableSyncOnScroll: true, // Fabric only.
disableIntervalMomentum: true,
maintainVisibleContentPosition: true,
pagingEnabled: true,
@@ -135,7 +134,6 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig =
contentInsetAdjustmentBehavior: true,
decelerationRate: true,
endDraggingSensitivityMultiplier: true,
enableSyncOnScroll: true, // Fabric only.
directionalLockEnabled: true,
disableIntervalMomentum: true,
indicatorStyle: true,
@@ -2042,7 +2042,7 @@ exports[`public API should not change unintentionally Libraries/Components/Scrol
export type DecelerationRateType = \\"fast\\" | \\"normal\\" | number;
export type ScrollResponderType = ScrollViewImperativeMethods;
type PublicScrollViewInstance = $ReadOnly<{|
...$Exact<TScrollViewNativeComponentInstance>,
...HostInstance,
...ScrollViewImperativeMethods,
|}>;
type InnerViewInstance = React.ElementRef<View>;
@@ -2169,7 +2169,7 @@ declare class ScrollView extends React.Component<Props, State> {
getScrollableNode: () => ?number;
getInnerViewNode: () => ?number;
getInnerViewRef: () => InnerViewInstance | null;
getNativeScrollRef: () => TScrollViewNativeComponentInstance | null;
getNativeScrollRef: () => HostInstance | null;
scrollTo: (
options?:
| {
@@ -2184,9 +2184,6 @@ declare class ScrollView extends React.Component<Props, State> {
) => void;
scrollToEnd: (options?: ?{ animated?: boolean, ... }) => void;
flashScrollIndicators: () => void;
_subscribeToOnScroll: (
callback: ({ x: number, y: number }) => void
) => EventSubscription;
scrollResponderScrollNativeHandleToKeyboard: (
nodeHandle: number | HostInstance,
additionalOffset?: number,
@@ -2224,10 +2221,7 @@ declare class ScrollView extends React.Component<Props, State> {
_handleLayout: $FlowFixMe;
_handleContentOnLayout: $FlowFixMe;
_innerView: RefForwarder<InnerViewInstance, InnerViewInstance>;
_scrollView: RefForwarder<
TScrollViewNativeImperativeHandle,
PublicScrollViewInstance | null,
>;
_scrollView: RefForwarder<HostInstance, PublicScrollViewInstance | null>;
scrollResponderKeyboardWillShow: (e: KeyboardEvent) => void;
scrollResponderKeyboardWillHide: (e: KeyboardEvent) => void;
scrollResponderKeyboardDidShow: (e: KeyboardEvent) => void;
@@ -618,31 +618,18 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
const auto &props = static_cast<const ScrollViewProps &>(*_props);
auto scrollMetrics = [self _scrollViewMetrics];
if (props.enableSyncOnScroll) {
[self _updateStateWithContentOffset];
NSTimeInterval now = CACurrentMediaTime();
if ((_lastScrollEventDispatchTime == 0) || (now - _lastScrollEventDispatchTime > _scrollEventThrottle)) {
_lastScrollEventDispatchTime = now;
if (_eventEmitter) {
const auto &eventEmitter = static_cast<const ScrollViewEventEmitter &>(*_eventEmitter);
// TODO: temporary API to unblock testing of synchronous rendering.
eventEmitter.experimental_flushSync([&eventEmitter, &scrollMetrics, &self]() {
[self _updateStateWithContentOffset];
// TODO: temporary API to unblock testing of synchronous rendering.
eventEmitter.experimental_onDiscreteScroll(scrollMetrics);
});
static_cast<const ScrollViewEventEmitter &>(*_eventEmitter).onScroll(scrollMetrics);
}
} else {
[self _updateStateWithContentOffset];
NSTimeInterval now = CACurrentMediaTime();
if ((_lastScrollEventDispatchTime == 0) || (now - _lastScrollEventDispatchTime > _scrollEventThrottle)) {
_lastScrollEventDispatchTime = now;
if (_eventEmitter) {
static_cast<const ScrollViewEventEmitter &>(*_eventEmitter).onScroll(scrollMetrics);
}
RCTSendScrollEventForNativeAnimations_DEPRECATED(scrollView, self.tag, kOnScrollEvent);
}
RCTSendScrollEventForNativeAnimations_DEPRECATED(scrollView, self.tag, kOnScrollEvent);
}
[self _remountChildrenIfNeeded];
@@ -6798,7 +6798,6 @@ public class com/facebook/react/views/scroll/ReactHorizontalScrollView : android
public fun setBorderWidth (IF)V
public fun setDecelerationRate (F)V
public fun setDisableIntervalMomentum (Z)V
public fun setEnableSyncOnScroll (Z)V
public fun setEndFillColor (I)V
public fun setLastScrollDispatchTime (J)V
public fun setMaintainVisibleContentPosition (Lcom/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper$Config;)V
@@ -6846,7 +6845,6 @@ public class com/facebook/react/views/scroll/ReactHorizontalScrollViewManager :
public fun setContentOffset (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;Lcom/facebook/react/bridge/ReadableMap;)V
public fun setDecelerationRate (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;F)V
public fun setDisableIntervalMomentum (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;Z)V
public fun setEnableSyncOnScroll (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;Z)V
public fun setFadingEdgeLength (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;I)V
public fun setHorizontal (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;Z)V
public fun setMaintainVisibleContentPosition (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;Lcom/facebook/react/bridge/ReadableMap;)V
@@ -6921,7 +6919,6 @@ public class com/facebook/react/views/scroll/ReactScrollView : android/widget/Sc
public fun setContentOffset (Lcom/facebook/react/bridge/ReadableMap;)V
public fun setDecelerationRate (F)V
public fun setDisableIntervalMomentum (Z)V
public fun setEnableSyncOnScroll (Z)V
public fun setEndFillColor (I)V
public fun setLastScrollDispatchTime (J)V
public fun setMaintainVisibleContentPosition (Lcom/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper$Config;)V
@@ -7003,7 +7000,6 @@ public final class com/facebook/react/views/scroll/ReactScrollViewHelper {
public static final fun updateFabricScrollState (Landroid/view/ViewGroup;)V
public final fun updateFabricScrollState (Landroid/view/ViewGroup;II)V
public static final fun updateStateOnScrollChanged (Landroid/view/ViewGroup;FF)V
public static final fun updateStateOnScrollChanged (Landroid/view/ViewGroup;FFZ)V
}
public abstract interface class com/facebook/react/views/scroll/ReactScrollViewHelper$HasFlingAnimator {
@@ -7086,7 +7082,6 @@ public class com/facebook/react/views/scroll/ReactScrollViewManager : com/facebo
public fun setContentOffset (Lcom/facebook/react/views/scroll/ReactScrollView;Lcom/facebook/react/bridge/ReadableMap;)V
public fun setDecelerationRate (Lcom/facebook/react/views/scroll/ReactScrollView;F)V
public fun setDisableIntervalMomentum (Lcom/facebook/react/views/scroll/ReactScrollView;Z)V
public fun setEnableSyncOnScroll (Lcom/facebook/react/views/scroll/ReactScrollView;Z)V
public fun setFadingEdgeLength (Lcom/facebook/react/views/scroll/ReactScrollView;I)V
public fun setHorizontal (Lcom/facebook/react/views/scroll/ReactScrollView;Z)V
public fun setIsInvertedVirtualizedList (Lcom/facebook/react/views/scroll/ReactScrollView;Z)V
@@ -7116,13 +7111,13 @@ public final class com/facebook/react/views/scroll/ScrollEvent : com/facebook/re
public static final field Companion Lcom/facebook/react/views/scroll/ScrollEvent$Companion;
public fun canCoalesce ()Z
public fun getEventName ()Ljava/lang/String;
public static final fun obtain (IILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIIIZ)Lcom/facebook/react/views/scroll/ScrollEvent;
public static final fun obtain (IILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIII)Lcom/facebook/react/views/scroll/ScrollEvent;
public static final fun obtain (ILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIII)Lcom/facebook/react/views/scroll/ScrollEvent;
public fun onDispose ()V
}
public final class com/facebook/react/views/scroll/ScrollEvent$Companion {
public final fun obtain (IILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIIIZ)Lcom/facebook/react/views/scroll/ScrollEvent;
public final fun obtain (IILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIII)Lcom/facebook/react/views/scroll/ScrollEvent;
public final fun obtain (ILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIII)Lcom/facebook/react/views/scroll/ScrollEvent;
}
@@ -103,8 +103,6 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
private @Nullable Runnable mPostTouchRunnable;
private boolean mRemoveClippedSubviews;
private boolean mScrollEnabled = true;
private boolean mPreventReentry = false;
private boolean mEnableSyncOnScroll = false;
private boolean mSendMomentumEvents;
private @Nullable FpsListener mFpsListener = null;
private @Nullable String mScrollPerfTag;
@@ -231,10 +229,6 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
mScrollEnabled = scrollEnabled;
}
public void setEnableSyncOnScroll(boolean enableSyncOnScroll) {
mEnableSyncOnScroll = enableSyncOnScroll;
}
public void setPagingEnabled(boolean pagingEnabled) {
mPagingEnabled = pagingEnabled;
}
@@ -492,16 +486,10 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
if (mRemoveClippedSubviews) {
updateClippingRect();
}
if (mPreventReentry) {
return;
}
mPreventReentry = true;
ReactScrollViewHelper.updateStateOnScrollChanged(
this,
mOnScrollDispatchHelper.getXFlingVelocity(),
mOnScrollDispatchHelper.getYFlingVelocity(),
mEnableSyncOnScroll);
mPreventReentry = false;
mOnScrollDispatchHelper.getYFlingVelocity());
}
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
@@ -95,11 +95,6 @@ public class ReactHorizontalScrollViewManager extends ViewGroupManager<ReactHori
view.setDecelerationRate(decelerationRate);
}
@ReactProp(name = "enableSyncOnScroll")
public void setEnableSyncOnScroll(ReactHorizontalScrollView view, boolean enableSyncOnScroll) {
view.setEnableSyncOnScroll(enableSyncOnScroll);
}
@ReactProp(name = "disableIntervalMomentum")
public void setDisableIntervalMomentum(
ReactHorizontalScrollView view, boolean disableIntervalMomentum) {
@@ -102,11 +102,9 @@ public class ReactScrollView extends ScrollView
private @Nullable Runnable mPostTouchRunnable;
private boolean mRemoveClippedSubviews;
private boolean mScrollEnabled = true;
private boolean mPreventReentry = false;
private boolean mSendMomentumEvents;
private @Nullable FpsListener mFpsListener = null;
private @Nullable String mScrollPerfTag;
private boolean mEnableSyncOnScroll = false;
private @Nullable Drawable mEndBackground;
private int mEndFillColor = Color.TRANSPARENT;
private boolean mDisableIntervalMomentum = false;
@@ -210,10 +208,6 @@ public class ReactScrollView extends ScrollView
mScrollPerfTag = scrollPerfTag;
}
public void setEnableSyncOnScroll(boolean enableSyncOnScroll) {
mEnableSyncOnScroll = enableSyncOnScroll;
}
public void setScrollEnabled(boolean scrollEnabled) {
mScrollEnabled = scrollEnabled;
}
@@ -418,16 +412,10 @@ public class ReactScrollView extends ScrollView
if (mRemoveClippedSubviews) {
updateClippingRect();
}
if (mPreventReentry) {
return;
}
mPreventReentry = true;
ReactScrollViewHelper.updateStateOnScrollChanged(
this,
mOnScrollDispatchHelper.getXFlingVelocity(),
mOnScrollDispatchHelper.getYFlingVelocity(),
mEnableSyncOnScroll);
mPreventReentry = false;
mOnScrollDispatchHelper.getYFlingVelocity());
}
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
@@ -103,7 +103,6 @@ public object ReactScrollViewHelper {
scrollEventType: ScrollEventType,
xVelocity: Float,
yVelocity: Float,
experimental_isSynchronous: Boolean = false,
) where T : HasScrollEventThrottle?, T : ViewGroup {
val now = System.currentTimeMillis()
// Throttle the scroll event if scrollEventThrottle is set to be equal or more than 17 ms.
@@ -138,8 +137,7 @@ public object ReactScrollViewHelper {
contentView.width,
contentView.height,
scrollView.width,
scrollView.height,
experimental_isSynchronous))
scrollView.height))
scrollView.lastScrollDispatchTime = now
}
}
@@ -374,29 +372,13 @@ public object ReactScrollViewHelper {
T : HasScrollEventThrottle?,
T : HasScrollState?,
T : HasStateWrapper?,
T : ViewGroup {
updateStateOnScrollChanged(scrollView, xVelocity, yVelocity, false)
}
@JvmStatic
public fun <T> updateStateOnScrollChanged(
scrollView: T,
xVelocity: Float,
yVelocity: Float,
experimental_synchronous: Boolean,
) where
T : HasFlingAnimator?,
T : HasScrollEventThrottle?,
T : HasScrollState?,
T : HasStateWrapper?,
T : ViewGroup {
// Race an UpdateState with every onScroll. This makes it more likely that, in Fabric,
// when JS processes the scroll event, the C++ ShadowNode representation will have a
// "more correct" scroll position. It will frequently be /incorrect/ but this decreases
// the error as much as possible.
updateFabricScrollState(scrollView, scrollView.scrollX, scrollView.scrollY)
emitScrollEvent(
scrollView, ScrollEventType.SCROLL, xVelocity, yVelocity, experimental_synchronous)
emitScrollEvent(scrollView, xVelocity, yVelocity)
}
public fun <T> registerFlingAnimator(scrollView: T) where
@@ -167,11 +167,6 @@ public class ReactScrollViewManager extends ViewGroupManager<ReactScrollView>
view.setScrollPerfTag(scrollPerfTag);
}
@ReactProp(name = "enableSyncOnScroll")
public void setEnableSyncOnScroll(ReactScrollView view, boolean value) {
view.setEnableSyncOnScroll(value);
}
@ReactProp(name = "pagingEnabled")
public void setPagingEnabled(ReactScrollView view, boolean pagingEnabled) {
view.setPagingEnabled(pagingEnabled);
@@ -29,7 +29,6 @@ public class ScrollEvent private constructor() : Event<ScrollEvent>() {
private var scrollViewHeight = 0
private var scrollEventType: ScrollEventType? = null
private var timestamp: Long = 0
private var experimental_isSynchronous = false
override fun onDispose() {
try {
@@ -53,7 +52,6 @@ public class ScrollEvent private constructor() : Event<ScrollEvent>() {
contentHeight: Int,
scrollViewWidth: Int,
scrollViewHeight: Int,
experimental_isSynchronous: Boolean,
) {
super.init(surfaceId, viewTag)
this.scrollEventType = scrollEventType
@@ -66,7 +64,6 @@ public class ScrollEvent private constructor() : Event<ScrollEvent>() {
this.scrollViewWidth = scrollViewWidth
this.scrollViewHeight = scrollViewHeight
this.timestamp = SystemClock.uptimeMillis()
this.experimental_isSynchronous = experimental_isSynchronous
}
override fun getEventName(): String =
@@ -74,10 +71,6 @@ public class ScrollEvent private constructor() : Event<ScrollEvent>() {
override fun canCoalesce(): Boolean = scrollEventType == ScrollEventType.SCROLL
override fun experimental_isSynchronous(): Boolean {
return experimental_isSynchronous
}
override fun getEventData(): WritableMap {
val contentInset = Arguments.createMap()
contentInset.putDouble("top", 0.0)
@@ -125,7 +118,6 @@ public class ScrollEvent private constructor() : Event<ScrollEvent>() {
contentHeight: Int,
scrollViewWidth: Int,
scrollViewHeight: Int,
experimental_isSynchronous: Boolean,
): ScrollEvent =
(EVENTS_POOL.acquire() ?: ScrollEvent()).apply {
init(
@@ -139,8 +131,7 @@ public class ScrollEvent private constructor() : Event<ScrollEvent>() {
contentWidth,
contentHeight,
scrollViewWidth,
scrollViewHeight,
experimental_isSynchronous)
scrollViewHeight)
}
@Deprecated(
@@ -172,7 +163,6 @@ public class ScrollEvent private constructor() : Event<ScrollEvent>() {
contentHeight,
scrollViewWidth,
scrollViewHeight,
false,
)
}
}
@@ -1302,8 +1302,7 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
0, // can't get content width
0, // can't get content height
mReactEditText.getWidth(),
mReactEditText.getHeight(),
false);
mReactEditText.getHeight());
mEventDispatcher.dispatchEvent(event);
@@ -13,14 +13,6 @@ void ScrollViewEventEmitter::onScroll(const ScrollEvent& scrollEvent) const {
dispatchUniqueEvent("scroll", std::make_shared<ScrollEvent>(scrollEvent));
}
void ScrollViewEventEmitter::experimental_onDiscreteScroll(
const ScrollEvent& scrollEvent) const {
dispatchEvent(
"scroll",
std::make_shared<ScrollEvent>(scrollEvent),
RawEvent::Category::Discrete);
}
void ScrollViewEventEmitter::onScrollToTop(
const ScrollEvent& scrollEvent) const {
dispatchUniqueEvent(
@@ -23,7 +23,6 @@ class ScrollViewEventEmitter : public ViewEventEmitter {
using Metrics = ScrollEvent;
void onScroll(const ScrollEvent& scrollEvent) const;
void experimental_onDiscreteScroll(const ScrollEvent& scrollEvent) const;
void onScrollBeginDrag(const ScrollEvent& scrollEvent) const;
void onScrollEndDrag(const ScrollEvent& scrollEvent) const;
void onMomentumScrollBegin(const ScrollEvent& scrollEvent) const;
@@ -120,15 +120,6 @@ ScrollViewProps::ScrollViewProps(
"endDraggingSensitivityMultiplier",
sourceProps.endDraggingSensitivityMultiplier,
(Float)1)),
enableSyncOnScroll(
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.enableSyncOnScroll
: convertRawProp(
context,
rawProps,
"enableSyncOnScroll",
sourceProps.enableSyncOnScroll,
false)),
directionalLockEnabled(
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.directionalLockEnabled
@@ -411,7 +402,6 @@ void ScrollViewProps::setProp(
RAW_SET_PROP_SWITCH_CASE_BASIC(maximumZoomScale);
RAW_SET_PROP_SWITCH_CASE_BASIC(minimumZoomScale);
RAW_SET_PROP_SWITCH_CASE_BASIC(scrollEnabled);
RAW_SET_PROP_SWITCH_CASE_BASIC(enableSyncOnScroll);
RAW_SET_PROP_SWITCH_CASE_BASIC(endDraggingSensitivityMultiplier);
RAW_SET_PROP_SWITCH_CASE_BASIC(pagingEnabled);
RAW_SET_PROP_SWITCH_CASE_BASIC(pinchGestureEnabled);
@@ -43,7 +43,6 @@ class ScrollViewProps final : public ViewProps {
bool automaticallyAdjustKeyboardInsets{false};
Float decelerationRate{0.998f};
Float endDraggingSensitivityMultiplier{1};
bool enableSyncOnScroll{false};
bool directionalLockEnabled{};
ScrollViewIndicatorStyle indicatorStyle{};
ScrollViewKeyboardDismissMode keyboardDismissMode{};
@@ -12,43 +12,18 @@
import type {ScrollViewNativeProps} from '../../../Libraries/Components/ScrollView/ScrollViewNativeComponentType';
import type {ViewProps} from '../../../Libraries/Components/View/ViewPropTypes';
import type {HostComponent} from '../../../Libraries/Renderer/shims/ReactNativeTypes';
import type {TScrollViewNativeImperativeHandle} from './useSyncOnScroll';
import AndroidHorizontalScrollViewNativeComponent from '../../../Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent';
import ScrollContentViewNativeComponent from '../../../Libraries/Components/ScrollView/ScrollContentViewNativeComponent';
import ScrollViewNativeComponent from '../../../Libraries/Components/ScrollView/ScrollViewNativeComponent';
import Platform from '../../../Libraries/Utilities/Platform';
import AndroidHorizontalScrollContentViewNativeComponent from '../specs/components/AndroidHorizontalScrollContentViewNativeComponent';
import useSyncOnScroll from './useSyncOnScroll';
import * as React from 'react';
import {forwardRef} from 'react';
const HScrollViewNativeComponentForPlatform =
export const HScrollViewNativeComponent: HostComponent<ScrollViewNativeProps> =
Platform.OS === 'android'
? AndroidHorizontalScrollViewNativeComponent
: ScrollViewNativeComponent;
// TODO: After upgrading to React 19, remove `forwardRef` from this component.
export const HScrollViewNativeComponent: component(
ref: React.RefSetter<TScrollViewNativeImperativeHandle>,
...ScrollViewNativeProps
) = forwardRef(function HScrollViewNativeComponent(
props: ScrollViewNativeProps,
ref: ?React.RefSetter<TScrollViewNativeImperativeHandle | null>,
): React.Node {
const [componentRef, enableSyncOnScroll] = useSyncOnScroll(ref);
// NOTE: When `useSyncOnScroll` triggers an update, `props` will not have
// changed. Notably, `props.children` will be the same, allowing React to
// bail out during reconciliation.
return (
<HScrollViewNativeComponentForPlatform
{...props}
ref={componentRef}
enableSyncOnScroll={enableSyncOnScroll}
/>
);
});
export const HScrollContentViewNativeComponent: HostComponent<ViewProps> =
Platform.OS === 'android'
? AndroidHorizontalScrollContentViewNativeComponent
@@ -12,36 +12,14 @@
import type {ScrollViewNativeProps} from '../../../Libraries/Components/ScrollView/ScrollViewNativeComponentType';
import type {ViewProps} from '../../../Libraries/Components/View/ViewPropTypes';
import type {HostComponent} from '../../../Libraries/Renderer/shims/ReactNativeTypes';
import type {TScrollViewNativeImperativeHandle} from './useSyncOnScroll';
import ScrollContentViewNativeComponent from '../../../Libraries/Components/ScrollView/ScrollContentViewNativeComponent';
import ScrollViewNativeComponent from '../../../Libraries/Components/ScrollView/ScrollViewNativeComponent';
import View from '../../../Libraries/Components/View/View';
import Platform from '../../../Libraries/Utilities/Platform';
import useSyncOnScroll from './useSyncOnScroll';
import * as React from 'react';
import {forwardRef} from 'react';
// TODO: After upgrading to React 19, remove `forwardRef` from this component.
export const VScrollViewNativeComponent: component(
ref: React.RefSetter<TScrollViewNativeImperativeHandle>,
...props: ScrollViewNativeProps
) = forwardRef(function VScrollViewNativeComponent(
props: ScrollViewNativeProps,
ref: ?React.RefSetter<TScrollViewNativeImperativeHandle | null>,
): React.Node {
const [componentRef, enableSyncOnScroll] = useSyncOnScroll(ref);
// NOTE: When `useSyncOnScroll` triggers an update, `props` will not have
// changed. Notably, `props.children` will be the same, allowing React to
// bail out during reconciliation.
return (
<ScrollViewNativeComponent
{...props}
ref={componentRef}
enableSyncOnScroll={enableSyncOnScroll}
/>
);
});
export const VScrollViewNativeComponent: HostComponent<ScrollViewNativeProps> =
ScrollViewNativeComponent;
export const VScrollContentViewNativeComponent: HostComponent<ViewProps> =
Platform.OS === 'android' ? View : ScrollContentViewNativeComponent;
@@ -1,48 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
* @oncall react_native
*/
import type {ScrollViewNativeProps} from '../../../Libraries/Components/ScrollView/ScrollViewNativeComponentType';
import type {HostComponent} from '../../../Libraries/Renderer/shims/ReactNativeTypes';
import * as React from 'react';
import {useImperativeHandle, useRef, useState} from 'react';
export type TScrollViewNativeComponentInstance = React.ElementRef<
HostComponent<ScrollViewNativeProps>,
>;
export type TScrollViewNativeImperativeHandle = {
componentRef: React.RefObject<TScrollViewNativeComponentInstance | null>,
unstable_setEnableSyncOnScroll: (enabled: true) => void,
};
/**
* Hook used by `HScrollViewNativeComponent` and `VScrollViewNativeComponent`
* to make an implementation of `unstable_setEnableSyncOnScroll` available that
* does not require updating all `ScrollView` children.
*/
export default function useSyncOnScroll(
inputRef: ?React.RefSetter<TScrollViewNativeImperativeHandle | null>,
): [React.RefSetter<TScrollViewNativeComponentInstance | null>, true | void] {
const componentRef = useRef<TScrollViewNativeComponentInstance | null>(null);
const [enableSyncOnScroll, setEnableSyncOnScroll] = useState<true | void>();
useImperativeHandle<TScrollViewNativeImperativeHandle>(inputRef, () => {
return {
componentRef,
unstable_setEnableSyncOnScroll(enabled: true): void {
setEnableSyncOnScroll(enabled);
},
};
}, []);
return [componentRef, enableSyncOnScroll];
}