react-native-capped-scrollview 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- import { forwardRef, useEffect, useRef, useImperativeHandle } from 'react';
3
+ import { useEffect, useRef } from 'react';
4
4
  import { ScrollView } from 'react-native';
5
5
  import NativeCappedScrollView from "./NativeCappedScrollView.js";
6
6
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -8,12 +8,12 @@ import { jsx as _jsx } from "react/jsx-runtime";
8
8
  // "no capper installed at all." Negative values are unreachable from the
9
9
  // public [0, 1] range, so this is unambiguous on the native side.
10
10
  const NO_CAP_SENTINEL = -1;
11
- export const CappedScrollView = /*#__PURE__*/forwardRef(function CappedScrollView({
11
+ export function CappedScrollView({
12
+ ref,
12
13
  maxVelocity,
13
14
  ...rest
14
- }, ref) {
15
+ }) {
15
16
  const innerRef = useRef(null);
16
- useImperativeHandle(ref, () => innerRef.current);
17
17
  useEffect(() => {
18
18
  const handle = innerRef.current?.getScrollableNode?.();
19
19
  if (handle == null) {
@@ -23,8 +23,15 @@ export const CappedScrollView = /*#__PURE__*/forwardRef(function CappedScrollVie
23
23
  NativeCappedScrollView.setMaxVelocity(handle, value);
24
24
  }, [maxVelocity]);
25
25
  return /*#__PURE__*/_jsx(ScrollView, {
26
- ref: innerRef,
26
+ ref: node => {
27
+ innerRef.current = node;
28
+ if (typeof ref === 'function') {
29
+ ref(node);
30
+ } else if (ref != null) {
31
+ ref.current = node;
32
+ }
33
+ },
27
34
  ...rest
28
35
  });
29
- });
36
+ }
30
37
  //# sourceMappingURL=CappedScrollView.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["forwardRef","useEffect","useRef","useImperativeHandle","ScrollView","NativeCappedScrollView","jsx","_jsx","NO_CAP_SENTINEL","CappedScrollView","maxVelocity","rest","ref","innerRef","current","handle","getScrollableNode","value","setMaxVelocity"],"sourceRoot":"../../src","sources":["CappedScrollView.tsx"],"mappings":";;AAAA,SACEA,UAAU,EACVC,SAAS,EACTC,MAAM,EACNC,mBAAmB,QAGd,OAAO;AACd,SAASC,UAAU,QAA8B,cAAc;AAC/D,OAAOC,sBAAsB,MAAM,6BAA0B;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAwB9D;AACA;AACA;AACA,MAAMC,eAAe,GAAG,CAAC,CAAC;AAE1B,OAAO,MAAMC,gBAAgB,gBAAGT,UAAU,CAAC,SAASS,gBAAgBA,CAClE;EAAEC,WAAW;EAAE,GAAGC;AAA4B,CAAC,EAC/CC,GAA6B,EAC7B;EACA,MAAMC,QAAQ,GAAGX,MAAM,CAA6B,IAAI,CAAC;EAEzDC,mBAAmB,CAACS,GAAG,EAAE,MAAMC,QAAQ,CAACC,OAA8B,CAAC;EAEvEb,SAAS,CAAC,MAAM;IACd,MAAMc,MAAM,GAAGF,QAAQ,CAACC,OAAO,EAAEE,iBAAiB,GAAG,CAAC;IACtD,IAAID,MAAM,IAAI,IAAI,EAAE;MAClB;IACF;IACA,MAAME,KAAK,GAAGP,WAAW,IAAI,IAAI,GAAGF,eAAe,GAAGE,WAAW;IACjEL,sBAAsB,CAACa,cAAc,CAACH,MAAM,EAAEE,KAAK,CAAC;EACtD,CAAC,EAAE,CAACP,WAAW,CAAC,CAAC;EAEjB,oBAAOH,IAAA,CAACH,UAAU;IAACQ,GAAG,EAAEC,QAAS;IAAA,GAAKF;EAAI,CAAG,CAAC;AAChD,CAAC,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["useEffect","useRef","ScrollView","NativeCappedScrollView","jsx","_jsx","NO_CAP_SENTINEL","CappedScrollView","ref","maxVelocity","rest","innerRef","handle","current","getScrollableNode","value","setMaxVelocity","node"],"sourceRoot":"../../src","sources":["CappedScrollView.tsx"],"mappings":";;AAAA,SAASA,SAAS,EAAEC,MAAM,QAAqC,OAAO;AACtE,SAASC,UAAU,QAA8B,cAAc;AAC/D,OAAOC,sBAAsB,MAAM,6BAA0B;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAyB9D;AACA;AACA;AACA,MAAMC,eAAe,GAAG,CAAC,CAAC;AAE1B,OAAO,SAASC,gBAAgBA,CAAC;EAC/BC,GAAG;EACHC,WAAW;EACX,GAAGC;AACkB,CAAC,EAAE;EACxB,MAAMC,QAAQ,GAAGV,MAAM,CAA6B,IAAI,CAAC;EAEzDD,SAAS,CAAC,MAAM;IACd,MAAMY,MAAM,GAAGD,QAAQ,CAACE,OAAO,EAAEC,iBAAiB,GAAG,CAAC;IACtD,IAAIF,MAAM,IAAI,IAAI,EAAE;MAClB;IACF;IACA,MAAMG,KAAK,GAAGN,WAAW,IAAI,IAAI,GAAGH,eAAe,GAAGG,WAAW;IACjEN,sBAAsB,CAACa,cAAc,CAACJ,MAAM,EAAEG,KAAK,CAAC;EACtD,CAAC,EAAE,CAACN,WAAW,CAAC,CAAC;EAEjB,oBACEJ,IAAA,CAACH,UAAU;IACTM,GAAG,EAAGS,IAAI,IAAK;MACbN,QAAQ,CAACE,OAAO,GAAGI,IAAI;MACvB,IAAI,OAAOT,GAAG,KAAK,UAAU,EAAE;QAC7BA,GAAG,CAACS,IAAI,CAAC;MACX,CAAC,MAAM,IAAIT,GAAG,IAAI,IAAI,EAAE;QACtBA,GAAG,CAACK,OAAO,GAAGI,IAAI;MACpB;IACF,CAAE;IAAA,GACEP;EAAI,CACT,CAAC;AAEN","ignoreList":[]}
@@ -1,7 +1,8 @@
1
- import { type ComponentRef } from 'react';
1
+ import { type ComponentRef, type Ref } from 'react';
2
2
  import { ScrollView, type ScrollViewProps } from 'react-native';
3
3
  export type CappedScrollViewRef = ComponentRef<typeof ScrollView>;
4
4
  export type CappedScrollViewProps = ScrollViewProps & {
5
+ ref?: Ref<CappedScrollViewRef>;
5
6
  /**
6
7
  * Fling velocity cap as a normalized fraction in [0, 1], or `null` to
7
8
  * disable the cap mechanism entirely.
@@ -20,229 +21,5 @@ export type CappedScrollViewProps = ScrollViewProps & {
20
21
  */
21
22
  maxVelocity?: number | null;
22
23
  };
23
- export declare const CappedScrollView: import("react").ForwardRefExoticComponent<Readonly<Omit<Omit<Readonly<Omit<Readonly<{
24
- onAccessibilityAction?: ((event: import("react-native").AccessibilityActionEvent) => unknown) | undefined;
25
- onAccessibilityTap?: (() => unknown) | undefined;
26
- onLayout?: ((event: import("react-native").LayoutChangeEvent) => unknown) | undefined;
27
- onMagicTap?: (() => unknown) | undefined;
28
- onAccessibilityEscape?: (() => unknown) | undefined;
29
- }>, "onMoveShouldSetResponder" | "onMoveShouldSetResponderCapture" | "onResponderGrant" | "onResponderMove" | "onResponderReject" | "onResponderRelease" | "onResponderStart" | "onResponderEnd" | "onResponderTerminate" | "onResponderTerminationRequest" | "onStartShouldSetResponder" | "onStartShouldSetResponderCapture" | "onMouseEnter" | "onMouseLeave" | "onClick" | "onClickCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onBlur" | "onBlurCapture" | "onFocus" | "onFocusCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "nativeBackgroundAndroid" | "nativeForegroundAndroid" | "renderToHardwareTextureAndroid" | "hasTVPreferredFocus" | "nextFocusDown" | "nextFocusForward" | "nextFocusLeft" | "nextFocusRight" | "nextFocusUp" | "focusable" | "tabIndex" | "shouldRasterizeIOS" | "accessibilityIgnoresInvertColors" | "accessibilityViewIsModal" | "accessibilityShowsLargeContentViewer" | "accessibilityLargeContentTitle" | "aria-modal" | "accessibilityElementsHidden" | "accessibilityLanguage" | "accessibilityRespondsToUserInteraction" | "accessible" | "accessibilityLabel" | "accessibilityHint" | "aria-label" | "accessibilityRole" | "role" | "accessibilityState" | "accessibilityValue" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "accessibilityActions" | "aria-busy" | "aria-checked" | "aria-disabled" | "aria-expanded" | "aria-selected" | "aria-hidden" | "accessibilityLabelledBy" | "aria-labelledby" | "accessibilityLiveRegion" | "aria-live" | "importantForAccessibility" | "screenReaderFocusable" | "children" | "style" | "collapsable" | "collapsableChildren" | "id" | "testID" | "nativeID" | "needsOffscreenAlphaCompositing" | "hitSlop" | "pointerEvents" | "removeClippedSubviews" | "experimental_accessibilityOrder"> & Omit<Readonly<{
30
- onMoveShouldSetResponder?: ((e: import("react-native").GestureResponderEvent) => boolean) | undefined;
31
- onMoveShouldSetResponderCapture?: ((e: import("react-native").GestureResponderEvent) => boolean) | undefined;
32
- onResponderGrant?: ((e: import("react-native").GestureResponderEvent) => void | boolean) | undefined;
33
- onResponderMove?: ((e: import("react-native").GestureResponderEvent) => void) | undefined;
34
- onResponderReject?: ((e: import("react-native").GestureResponderEvent) => void) | undefined;
35
- onResponderRelease?: ((e: import("react-native").GestureResponderEvent) => void) | undefined;
36
- onResponderStart?: ((e: import("react-native").GestureResponderEvent) => void) | undefined;
37
- onResponderEnd?: ((e: import("react-native").GestureResponderEvent) => void) | undefined;
38
- onResponderTerminate?: ((e: import("react-native").GestureResponderEvent) => void) | undefined;
39
- onResponderTerminationRequest?: ((e: import("react-native").GestureResponderEvent) => boolean) | undefined;
40
- onStartShouldSetResponder?: ((e: import("react-native").GestureResponderEvent) => boolean) | undefined;
41
- onStartShouldSetResponderCapture?: ((e: import("react-native").GestureResponderEvent) => boolean) | undefined;
42
- }>, "onMouseEnter" | "onMouseLeave" | "onClick" | "onClickCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onBlur" | "onBlurCapture" | "onFocus" | "onFocusCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "nativeBackgroundAndroid" | "nativeForegroundAndroid" | "renderToHardwareTextureAndroid" | "hasTVPreferredFocus" | "nextFocusDown" | "nextFocusForward" | "nextFocusLeft" | "nextFocusRight" | "nextFocusUp" | "focusable" | "tabIndex" | "shouldRasterizeIOS" | "accessibilityIgnoresInvertColors" | "accessibilityViewIsModal" | "accessibilityShowsLargeContentViewer" | "accessibilityLargeContentTitle" | "aria-modal" | "accessibilityElementsHidden" | "accessibilityLanguage" | "accessibilityRespondsToUserInteraction" | "accessible" | "accessibilityLabel" | "accessibilityHint" | "aria-label" | "accessibilityRole" | "role" | "accessibilityState" | "accessibilityValue" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "accessibilityActions" | "aria-busy" | "aria-checked" | "aria-disabled" | "aria-expanded" | "aria-selected" | "aria-hidden" | "accessibilityLabelledBy" | "aria-labelledby" | "accessibilityLiveRegion" | "aria-live" | "importantForAccessibility" | "screenReaderFocusable" | "children" | "style" | "collapsable" | "collapsableChildren" | "id" | "testID" | "nativeID" | "needsOffscreenAlphaCompositing" | "hitSlop" | "pointerEvents" | "removeClippedSubviews" | "experimental_accessibilityOrder"> & Omit<Readonly<{
43
- onMouseEnter?: ((event: import("react-native").MouseEvent) => void) | undefined;
44
- onMouseLeave?: ((event: import("react-native").MouseEvent) => void) | undefined;
45
- }>, "onClick" | "onClickCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onBlur" | "onBlurCapture" | "onFocus" | "onFocusCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "nativeBackgroundAndroid" | "nativeForegroundAndroid" | "renderToHardwareTextureAndroid" | "hasTVPreferredFocus" | "nextFocusDown" | "nextFocusForward" | "nextFocusLeft" | "nextFocusRight" | "nextFocusUp" | "focusable" | "tabIndex" | "shouldRasterizeIOS" | "accessibilityIgnoresInvertColors" | "accessibilityViewIsModal" | "accessibilityShowsLargeContentViewer" | "accessibilityLargeContentTitle" | "aria-modal" | "accessibilityElementsHidden" | "accessibilityLanguage" | "accessibilityRespondsToUserInteraction" | "accessible" | "accessibilityLabel" | "accessibilityHint" | "aria-label" | "accessibilityRole" | "role" | "accessibilityState" | "accessibilityValue" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "accessibilityActions" | "aria-busy" | "aria-checked" | "aria-disabled" | "aria-expanded" | "aria-selected" | "aria-hidden" | "accessibilityLabelledBy" | "aria-labelledby" | "accessibilityLiveRegion" | "aria-live" | "importantForAccessibility" | "screenReaderFocusable" | "children" | "style" | "collapsable" | "collapsableChildren" | "id" | "testID" | "nativeID" | "needsOffscreenAlphaCompositing" | "hitSlop" | "pointerEvents" | "removeClippedSubviews" | "experimental_accessibilityOrder"> & Omit<Readonly<{
46
- onClick?: ((event: import("react-native").PointerEvent) => void) | undefined;
47
- onClickCapture?: ((event: import("react-native").PointerEvent) => void) | undefined;
48
- onPointerEnter?: ((event: import("react-native").PointerEvent) => void) | undefined;
49
- onPointerEnterCapture?: ((event: import("react-native").PointerEvent) => void) | undefined;
50
- onPointerLeave?: ((event: import("react-native").PointerEvent) => void) | undefined;
51
- onPointerLeaveCapture?: ((event: import("react-native").PointerEvent) => void) | undefined;
52
- onPointerMove?: ((event: import("react-native").PointerEvent) => void) | undefined;
53
- onPointerMoveCapture?: ((event: import("react-native").PointerEvent) => void) | undefined;
54
- onPointerCancel?: ((e: import("react-native").PointerEvent) => void) | undefined;
55
- onPointerCancelCapture?: ((e: import("react-native").PointerEvent) => void) | undefined;
56
- onPointerDown?: ((e: import("react-native").PointerEvent) => void) | undefined;
57
- onPointerDownCapture?: ((e: import("react-native").PointerEvent) => void) | undefined;
58
- onPointerUp?: ((e: import("react-native").PointerEvent) => void) | undefined;
59
- onPointerUpCapture?: ((e: import("react-native").PointerEvent) => void) | undefined;
60
- onPointerOver?: ((e: import("react-native").PointerEvent) => void) | undefined;
61
- onPointerOverCapture?: ((e: import("react-native").PointerEvent) => void) | undefined;
62
- onPointerOut?: ((e: import("react-native").PointerEvent) => void) | undefined;
63
- onPointerOutCapture?: ((e: import("react-native").PointerEvent) => void) | undefined;
64
- onGotPointerCapture?: ((e: import("react-native").PointerEvent) => void) | undefined;
65
- onGotPointerCaptureCapture?: ((e: import("react-native").PointerEvent) => void) | undefined;
66
- onLostPointerCapture?: ((e: import("react-native").PointerEvent) => void) | undefined;
67
- onLostPointerCaptureCapture?: ((e: import("react-native").PointerEvent) => void) | undefined;
68
- }>, "onClick" | "onBlur" | "onBlurCapture" | "onFocus" | "onFocusCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "nativeBackgroundAndroid" | "nativeForegroundAndroid" | "renderToHardwareTextureAndroid" | "hasTVPreferredFocus" | "nextFocusDown" | "nextFocusForward" | "nextFocusLeft" | "nextFocusRight" | "nextFocusUp" | "focusable" | "tabIndex" | "shouldRasterizeIOS" | "accessibilityIgnoresInvertColors" | "accessibilityViewIsModal" | "accessibilityShowsLargeContentViewer" | "accessibilityLargeContentTitle" | "aria-modal" | "accessibilityElementsHidden" | "accessibilityLanguage" | "accessibilityRespondsToUserInteraction" | "accessible" | "accessibilityLabel" | "accessibilityHint" | "aria-label" | "accessibilityRole" | "role" | "accessibilityState" | "accessibilityValue" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "accessibilityActions" | "aria-busy" | "aria-checked" | "aria-disabled" | "aria-expanded" | "aria-selected" | "aria-hidden" | "accessibilityLabelledBy" | "aria-labelledby" | "accessibilityLiveRegion" | "aria-live" | "importantForAccessibility" | "screenReaderFocusable" | "children" | "style" | "collapsable" | "collapsableChildren" | "id" | "testID" | "nativeID" | "needsOffscreenAlphaCompositing" | "hitSlop" | "pointerEvents" | "removeClippedSubviews" | "experimental_accessibilityOrder"> & Omit<Readonly<{
69
- onBlur?: ((event: import("react-native").BlurEvent) => void) | undefined;
70
- onBlurCapture?: ((event: import("react-native").BlurEvent) => void) | undefined;
71
- onFocus?: ((event: import("react-native").FocusEvent) => void) | undefined;
72
- onFocusCapture?: ((event: import("react-native").FocusEvent) => void) | undefined;
73
- }>, "onClick" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "nativeBackgroundAndroid" | "nativeForegroundAndroid" | "renderToHardwareTextureAndroid" | "hasTVPreferredFocus" | "nextFocusDown" | "nextFocusForward" | "nextFocusLeft" | "nextFocusRight" | "nextFocusUp" | "focusable" | "tabIndex" | "shouldRasterizeIOS" | "accessibilityIgnoresInvertColors" | "accessibilityViewIsModal" | "accessibilityShowsLargeContentViewer" | "accessibilityLargeContentTitle" | "aria-modal" | "accessibilityElementsHidden" | "accessibilityLanguage" | "accessibilityRespondsToUserInteraction" | "accessible" | "accessibilityLabel" | "accessibilityHint" | "aria-label" | "accessibilityRole" | "role" | "accessibilityState" | "accessibilityValue" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "accessibilityActions" | "aria-busy" | "aria-checked" | "aria-disabled" | "aria-expanded" | "aria-selected" | "aria-hidden" | "accessibilityLabelledBy" | "aria-labelledby" | "accessibilityLiveRegion" | "aria-live" | "importantForAccessibility" | "screenReaderFocusable" | "children" | "style" | "collapsable" | "collapsableChildren" | "id" | "testID" | "nativeID" | "needsOffscreenAlphaCompositing" | "hitSlop" | "pointerEvents" | "removeClippedSubviews" | "experimental_accessibilityOrder"> & Omit<Readonly<{
74
- onTouchCancel?: ((e: import("react-native").GestureResponderEvent) => void) | undefined;
75
- onTouchCancelCapture?: ((e: import("react-native").GestureResponderEvent) => void) | undefined;
76
- onTouchEnd?: ((e: import("react-native").GestureResponderEvent) => void) | undefined;
77
- onTouchEndCapture?: ((e: import("react-native").GestureResponderEvent) => void) | undefined;
78
- onTouchMove?: ((e: import("react-native").GestureResponderEvent) => void) | undefined;
79
- onTouchMoveCapture?: ((e: import("react-native").GestureResponderEvent) => void) | undefined;
80
- onTouchStart?: ((e: import("react-native").GestureResponderEvent) => void) | undefined;
81
- onTouchStartCapture?: ((e: import("react-native").GestureResponderEvent) => void) | undefined;
82
- }>, "onClick" | "nativeBackgroundAndroid" | "nativeForegroundAndroid" | "renderToHardwareTextureAndroid" | "hasTVPreferredFocus" | "nextFocusDown" | "nextFocusForward" | "nextFocusLeft" | "nextFocusRight" | "nextFocusUp" | "focusable" | "tabIndex" | "shouldRasterizeIOS" | "accessibilityIgnoresInvertColors" | "accessibilityViewIsModal" | "accessibilityShowsLargeContentViewer" | "accessibilityLargeContentTitle" | "aria-modal" | "accessibilityElementsHidden" | "accessibilityLanguage" | "accessibilityRespondsToUserInteraction" | "accessible" | "accessibilityLabel" | "accessibilityHint" | "aria-label" | "accessibilityRole" | "role" | "accessibilityState" | "accessibilityValue" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "accessibilityActions" | "aria-busy" | "aria-checked" | "aria-disabled" | "aria-expanded" | "aria-selected" | "aria-hidden" | "accessibilityLabelledBy" | "aria-labelledby" | "accessibilityLiveRegion" | "aria-live" | "importantForAccessibility" | "screenReaderFocusable" | "children" | "style" | "collapsable" | "collapsableChildren" | "id" | "testID" | "nativeID" | "needsOffscreenAlphaCompositing" | "hitSlop" | "pointerEvents" | "removeClippedSubviews" | "experimental_accessibilityOrder"> & Omit<Readonly<{
83
- nativeBackgroundAndroid?: import("react-native/types_generated/Libraries/Components/View/ViewPropTypes").AndroidDrawable | undefined;
84
- nativeForegroundAndroid?: import("react-native/types_generated/Libraries/Components/View/ViewPropTypes").AndroidDrawable | undefined;
85
- renderToHardwareTextureAndroid?: boolean | undefined;
86
- hasTVPreferredFocus?: boolean | undefined;
87
- nextFocusDown?: number | undefined;
88
- nextFocusForward?: number | undefined;
89
- nextFocusLeft?: number | undefined;
90
- nextFocusRight?: number | undefined;
91
- nextFocusUp?: number | undefined;
92
- focusable?: boolean | undefined;
93
- tabIndex?: 0 | -1;
94
- onClick?: ((event: import("react-native").GestureResponderEvent) => unknown) | undefined;
95
- }>, "shouldRasterizeIOS" | "accessibilityIgnoresInvertColors" | "accessibilityViewIsModal" | "accessibilityShowsLargeContentViewer" | "accessibilityLargeContentTitle" | "aria-modal" | "accessibilityElementsHidden" | "accessibilityLanguage" | "accessibilityRespondsToUserInteraction" | "accessible" | "accessibilityLabel" | "accessibilityHint" | "aria-label" | "accessibilityRole" | "role" | "accessibilityState" | "accessibilityValue" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "accessibilityActions" | "aria-busy" | "aria-checked" | "aria-disabled" | "aria-expanded" | "aria-selected" | "aria-hidden" | "accessibilityLabelledBy" | "aria-labelledby" | "accessibilityLiveRegion" | "aria-live" | "importantForAccessibility" | "screenReaderFocusable" | "children" | "style" | "collapsable" | "collapsableChildren" | "id" | "testID" | "nativeID" | "needsOffscreenAlphaCompositing" | "hitSlop" | "pointerEvents" | "removeClippedSubviews" | "experimental_accessibilityOrder"> & Omit<Readonly<{
96
- shouldRasterizeIOS?: boolean | undefined;
97
- }>, "accessibilityIgnoresInvertColors" | "accessibilityViewIsModal" | "accessibilityShowsLargeContentViewer" | "accessibilityLargeContentTitle" | "aria-modal" | "accessibilityElementsHidden" | "accessibilityLanguage" | "accessibilityRespondsToUserInteraction" | "accessible" | "accessibilityLabel" | "accessibilityHint" | "aria-label" | "accessibilityRole" | "role" | "accessibilityState" | "accessibilityValue" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "accessibilityActions" | "aria-busy" | "aria-checked" | "aria-disabled" | "aria-expanded" | "aria-selected" | "aria-hidden" | "accessibilityLabelledBy" | "aria-labelledby" | "accessibilityLiveRegion" | "aria-live" | "importantForAccessibility" | "screenReaderFocusable" | "children" | "style" | "collapsable" | "collapsableChildren" | "id" | "testID" | "nativeID" | "needsOffscreenAlphaCompositing" | "hitSlop" | "pointerEvents" | "removeClippedSubviews" | "experimental_accessibilityOrder"> & Omit<Readonly<Omit<Readonly<{
98
- accessibilityLabelledBy?: (string | undefined) | (Array<string> | undefined);
99
- "aria-labelledby"?: string | undefined;
100
- accessibilityLiveRegion?: ("none" | "polite" | "assertive") | undefined;
101
- "aria-live"?: ("polite" | "assertive" | "off") | undefined;
102
- importantForAccessibility?: ("auto" | "yes" | "no" | "no-hide-descendants") | undefined;
103
- screenReaderFocusable?: boolean;
104
- }>, "accessibilityIgnoresInvertColors" | "accessibilityViewIsModal" | "accessibilityShowsLargeContentViewer" | "accessibilityLargeContentTitle" | "aria-modal" | "accessibilityElementsHidden" | "accessibilityLanguage" | "accessibilityRespondsToUserInteraction" | "accessible" | "accessibilityLabel" | "accessibilityHint" | "aria-label" | "accessibilityRole" | "role" | "accessibilityState" | "accessibilityValue" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "accessibilityActions" | "aria-busy" | "aria-checked" | "aria-disabled" | "aria-expanded" | "aria-selected" | "aria-hidden"> & Omit<Readonly<{
105
- accessibilityIgnoresInvertColors?: boolean | undefined;
106
- accessibilityViewIsModal?: boolean | undefined;
107
- accessibilityShowsLargeContentViewer?: boolean | undefined;
108
- accessibilityLargeContentTitle?: string | undefined;
109
- "aria-modal"?: boolean | undefined;
110
- accessibilityElementsHidden?: boolean | undefined;
111
- accessibilityLanguage?: string | undefined;
112
- accessibilityRespondsToUserInteraction?: boolean | undefined;
113
- }>, "accessible" | "accessibilityLabel" | "accessibilityHint" | "aria-label" | "accessibilityRole" | "role" | "accessibilityState" | "accessibilityValue" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "accessibilityActions" | "aria-busy" | "aria-checked" | "aria-disabled" | "aria-expanded" | "aria-selected" | "aria-hidden"> & {
114
- accessible?: boolean | undefined;
115
- accessibilityLabel?: string | undefined;
116
- accessibilityHint?: string | undefined;
117
- "aria-label"?: string | undefined;
118
- accessibilityRole?: import("react-native").AccessibilityRole | undefined;
119
- role?: import("react-native").Role | undefined;
120
- accessibilityState?: import("react-native").AccessibilityState | undefined;
121
- accessibilityValue?: import("react-native").AccessibilityValue | undefined;
122
- "aria-valuemax"?: import("react-native").AccessibilityValue["max"] | undefined;
123
- "aria-valuemin"?: import("react-native").AccessibilityValue["min"] | undefined;
124
- "aria-valuenow"?: import("react-native").AccessibilityValue["now"] | undefined;
125
- "aria-valuetext"?: import("react-native").AccessibilityValue["text"] | undefined;
126
- accessibilityActions?: ReadonlyArray<import("react-native/types_generated/Libraries/Components/View/ViewAccessibility").AccessibilityActionInfo> | undefined;
127
- "aria-busy"?: boolean | undefined;
128
- "aria-checked"?: (boolean | undefined) | "mixed";
129
- "aria-disabled"?: boolean | undefined;
130
- "aria-expanded"?: boolean | undefined;
131
- "aria-selected"?: boolean | undefined;
132
- "aria-hidden"?: boolean | undefined;
133
- }>, "children" | "style" | "collapsable" | "collapsableChildren" | "id" | "testID" | "nativeID" | "needsOffscreenAlphaCompositing" | "hitSlop" | "pointerEvents" | "removeClippedSubviews" | "experimental_accessibilityOrder"> & Omit<Readonly<{
134
- children?: React.ReactNode;
135
- style?: import("react-native/types_generated/Libraries/StyleSheet/StyleSheet").ViewStyleProp | undefined;
136
- collapsable?: boolean | undefined;
137
- collapsableChildren?: boolean | undefined;
138
- id?: string;
139
- testID?: string | undefined;
140
- nativeID?: string | undefined;
141
- needsOffscreenAlphaCompositing?: boolean | undefined;
142
- hitSlop?: import("react-native/types_generated/Libraries/StyleSheet/EdgeInsetsPropType").EdgeInsetsOrSizeProp | undefined;
143
- pointerEvents?: ("auto" | "box-none" | "box-only" | "none") | undefined;
144
- removeClippedSubviews?: boolean | undefined;
145
- experimental_accessibilityOrder?: Array<string> | undefined;
146
- }>, never>>, "experimental_accessibilityOrder">, "children" | "removeClippedSubviews" | "automaticallyAdjustContentInsets" | "automaticallyAdjustKeyboardInsets" | "automaticallyAdjustsScrollIndicatorInsets" | "contentInset" | "bounces" | "disableScrollViewPanResponder" | "bouncesZoom" | "alwaysBounceHorizontal" | "alwaysBounceVertical" | "centerContent" | "indicatorStyle" | "directionalLockEnabled" | "canCancelContentTouches" | "maximumZoomScale" | "minimumZoomScale" | "pinchGestureEnabled" | "scrollIndicatorInsets" | "scrollToOverflowEnabled" | "scrollsToTop" | "onScrollToTop" | "showsHorizontalScrollIndicator" | "zoomScale" | "contentInsetAdjustmentBehavior" | "nestedScrollEnabled" | "endFillColor" | "scrollPerfTag" | "overScrollMode" | "persistentScrollbar" | "fadingEdgeLength" | "contentContainerStyle" | "contentOffset" | "disableIntervalMomentum" | "decelerationRate" | "experimental_endDraggingSensitivityMultiplier" | "horizontal" | "invertStickyHeaders" | "keyboardDismissMode" | "keyboardShouldPersistTaps" | "maintainVisibleContentPosition" | "onMomentumScrollBegin" | "onMomentumScrollEnd" | "onScroll" | "onScrollBeginDrag" | "onScrollEndDrag" | "onContentSizeChange" | "onKeyboardDidShow" | "onKeyboardDidHide" | "onKeyboardWillShow" | "onKeyboardWillHide" | "pagingEnabled" | "scrollEnabled" | "scrollEventThrottle" | "showsVerticalScrollIndicator" | "stickyHeaderHiddenOnScroll" | "stickyHeaderIndices" | "StickyHeaderComponent" | "snapToAlignment" | "snapToInterval" | "snapToOffsets" | "snapToStart" | "snapToEnd" | "refreshControl" | "innerViewRef" | "scrollViewRef"> & Omit<Readonly<{
147
- automaticallyAdjustContentInsets?: boolean | undefined;
148
- automaticallyAdjustKeyboardInsets?: boolean | undefined;
149
- automaticallyAdjustsScrollIndicatorInsets?: boolean | undefined;
150
- contentInset?: import("react-native/types_generated/Libraries/StyleSheet/EdgeInsetsPropType").EdgeInsetsProp | undefined;
151
- bounces?: boolean | undefined;
152
- disableScrollViewPanResponder?: boolean | undefined;
153
- bouncesZoom?: boolean | undefined;
154
- alwaysBounceHorizontal?: boolean | undefined;
155
- alwaysBounceVertical?: boolean | undefined;
156
- centerContent?: boolean | undefined;
157
- indicatorStyle?: ("default" | "black" | "white") | undefined;
158
- directionalLockEnabled?: boolean | undefined;
159
- canCancelContentTouches?: boolean | undefined;
160
- maximumZoomScale?: number | undefined;
161
- minimumZoomScale?: number | undefined;
162
- pinchGestureEnabled?: boolean | undefined;
163
- scrollIndicatorInsets?: import("react-native/types_generated/Libraries/StyleSheet/EdgeInsetsPropType").EdgeInsetsProp | undefined;
164
- scrollToOverflowEnabled?: boolean | undefined;
165
- scrollsToTop?: boolean | undefined;
166
- onScrollToTop?: (event: import("react-native").ScrollEvent) => void;
167
- showsHorizontalScrollIndicator?: boolean | undefined;
168
- zoomScale?: number | undefined;
169
- contentInsetAdjustmentBehavior?: ("automatic" | "scrollableAxes" | "never" | "always") | undefined;
170
- }>, "children" | "removeClippedSubviews" | "nestedScrollEnabled" | "endFillColor" | "scrollPerfTag" | "overScrollMode" | "persistentScrollbar" | "fadingEdgeLength" | "contentContainerStyle" | "contentOffset" | "disableIntervalMomentum" | "decelerationRate" | "experimental_endDraggingSensitivityMultiplier" | "horizontal" | "invertStickyHeaders" | "keyboardDismissMode" | "keyboardShouldPersistTaps" | "maintainVisibleContentPosition" | "onMomentumScrollBegin" | "onMomentumScrollEnd" | "onScroll" | "onScrollBeginDrag" | "onScrollEndDrag" | "onContentSizeChange" | "onKeyboardDidShow" | "onKeyboardDidHide" | "onKeyboardWillShow" | "onKeyboardWillHide" | "pagingEnabled" | "scrollEnabled" | "scrollEventThrottle" | "showsVerticalScrollIndicator" | "stickyHeaderHiddenOnScroll" | "stickyHeaderIndices" | "StickyHeaderComponent" | "snapToAlignment" | "snapToInterval" | "snapToOffsets" | "snapToStart" | "snapToEnd" | "refreshControl" | "innerViewRef" | "scrollViewRef"> & Omit<Readonly<{
171
- nestedScrollEnabled?: boolean | undefined;
172
- endFillColor?: import("react-native").ColorValue | undefined;
173
- scrollPerfTag?: string | undefined;
174
- overScrollMode?: ("auto" | "always" | "never") | undefined;
175
- persistentScrollbar?: boolean | undefined;
176
- fadingEdgeLength?: (number | undefined) | {
177
- start: number;
178
- end: number;
179
- };
180
- }>, "children" | "removeClippedSubviews" | "contentContainerStyle" | "contentOffset" | "disableIntervalMomentum" | "decelerationRate" | "experimental_endDraggingSensitivityMultiplier" | "horizontal" | "invertStickyHeaders" | "keyboardDismissMode" | "keyboardShouldPersistTaps" | "maintainVisibleContentPosition" | "onMomentumScrollBegin" | "onMomentumScrollEnd" | "onScroll" | "onScrollBeginDrag" | "onScrollEndDrag" | "onContentSizeChange" | "onKeyboardDidShow" | "onKeyboardDidHide" | "onKeyboardWillShow" | "onKeyboardWillHide" | "pagingEnabled" | "scrollEnabled" | "scrollEventThrottle" | "showsVerticalScrollIndicator" | "stickyHeaderHiddenOnScroll" | "stickyHeaderIndices" | "StickyHeaderComponent" | "snapToAlignment" | "snapToInterval" | "snapToOffsets" | "snapToStart" | "snapToEnd" | "refreshControl" | "innerViewRef" | "scrollViewRef"> & Omit<Readonly<{
181
- contentContainerStyle?: import("react-native/types_generated/Libraries/StyleSheet/StyleSheet").ViewStyleProp | undefined;
182
- contentOffset?: import("react-native/types_generated/Libraries/StyleSheet/PointPropType").PointProp | undefined;
183
- disableIntervalMomentum?: boolean | undefined;
184
- decelerationRate?: import("react-native/types_generated/Libraries/Components/ScrollView/ScrollView").DecelerationRateType | undefined;
185
- experimental_endDraggingSensitivityMultiplier?: number | undefined;
186
- horizontal?: boolean | undefined;
187
- invertStickyHeaders?: boolean | undefined;
188
- keyboardDismissMode?: ("none" | "on-drag" | "interactive") | undefined;
189
- keyboardShouldPersistTaps?: ("always" | "never" | "handled" | true | false) | undefined;
190
- maintainVisibleContentPosition?: Readonly<{
191
- minIndexForVisible: number;
192
- autoscrollToTopThreshold?: number | undefined;
193
- }> | undefined;
194
- onMomentumScrollBegin?: ((event: import("react-native").ScrollEvent) => void) | undefined;
195
- onMomentumScrollEnd?: ((event: import("react-native").ScrollEvent) => void) | undefined;
196
- onScroll?: ((event: import("react-native").ScrollEvent) => void) | undefined;
197
- onScrollBeginDrag?: ((event: import("react-native").ScrollEvent) => void) | undefined;
198
- onScrollEndDrag?: ((event: import("react-native").ScrollEvent) => void) | undefined;
199
- onContentSizeChange?: (contentWidth: number, contentHeight: number) => void;
200
- onKeyboardDidShow?: (event: import("react-native").KeyboardEvent) => void;
201
- onKeyboardDidHide?: (event: import("react-native").KeyboardEvent) => void;
202
- onKeyboardWillShow?: (event: import("react-native").KeyboardEvent) => void;
203
- onKeyboardWillHide?: (event: import("react-native").KeyboardEvent) => void;
204
- pagingEnabled?: boolean | undefined;
205
- scrollEnabled?: boolean | undefined;
206
- scrollEventThrottle?: number | undefined;
207
- showsVerticalScrollIndicator?: boolean | undefined;
208
- stickyHeaderHiddenOnScroll?: boolean | undefined;
209
- stickyHeaderIndices?: ReadonlyArray<number> | undefined;
210
- StickyHeaderComponent?: (props: Omit<import("react-native/types_generated/Libraries/Components/ScrollView/ScrollViewStickyHeader").ScrollViewStickyHeaderProps, keyof {
211
- ref?: React.Ref<Readonly<{
212
- setNextHeaderY: ($$PARAM_0$$: number) => void;
213
- }>>;
214
- }> & {
215
- ref?: React.Ref<Readonly<{
216
- setNextHeaderY: ($$PARAM_0$$: number) => void;
217
- }>>;
218
- }) => React.ReactNode;
219
- snapToAlignment?: ("start" | "center" | "end") | undefined;
220
- snapToInterval?: number | undefined;
221
- snapToOffsets?: ReadonlyArray<number> | undefined;
222
- snapToStart?: boolean | undefined;
223
- snapToEnd?: boolean | undefined;
224
- removeClippedSubviews?: boolean | undefined;
225
- refreshControl?: React.JSX.Element | undefined;
226
- children?: React.ReactNode;
227
- innerViewRef?: React.Ref<import("react-native/types_generated/src/private/webapis/dom/nodes/ReactNativeElement").default>;
228
- scrollViewRef?: React.Ref<import("react-native/types_generated/Libraries/Components/ScrollView/ScrollView").PublicScrollViewInstance>;
229
- }>, never>> & {
230
- /**
231
- * Fling velocity cap as a normalized fraction in [0, 1], or `null` to
232
- * disable the cap mechanism entirely.
233
- *
234
- * The reference maximum is 8000 dp/s on Android and 8000 pt/s on iOS
235
- * (same logical unit), so the same `maxVelocity` value produces the same
236
- * visual scroll speed on both platforms.
237
- *
238
- * - `null` / `undefined` (default) — no capper installed; behaves exactly
239
- * like a plain RN `ScrollView`.
240
- * - `1` — capper installed at the reference maximum. Human-paced flings
241
- * pass through untouched.
242
- * - `0` — list cannot fling at all.
243
- * - `0 < x < 1` — peak fling velocity is clamped to `x × 8000` (dp/s on
244
- * Android, pt/s on iOS). Fling distance scales linearly with `x`.
245
- */
246
- maxVelocity?: number | null;
247
- } & import("react").RefAttributes<import("react-native/types_generated/Libraries/Components/ScrollView/ScrollView").PublicScrollViewInstance>>;
24
+ export declare function CappedScrollView({ ref, maxVelocity, ...rest }: CappedScrollViewProps): import("react/jsx-runtime").JSX.Element;
248
25
  //# sourceMappingURL=CappedScrollView.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CappedScrollView.d.ts","sourceRoot":"","sources":["../../../src/CappedScrollView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,YAAY,EAElB,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAGhE,MAAM,MAAM,mBAAmB,GAAG,YAAY,CAAC,OAAO,UAAU,CAAC,CAAC;AAElE,MAAM,MAAM,qBAAqB,GAAG,eAAe,GAAG;IACpD;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,CAAC;AAOF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAmB4jb,CAAC;;;;;;;;;;;;;;;;;;;WAA74K,CAAC;;;;WAA6F,CAAC;;;;;;;;;;;;;;;IA3C1yQ;;;;;;;;;;;;;;;OAeG;kBACW,MAAM,GAAG,IAAI;8IA0B3B,CAAC"}
1
+ {"version":3,"file":"CappedScrollView.d.ts","sourceRoot":"","sources":["../../../src/CappedScrollView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,YAAY,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAGhE,MAAM,MAAM,mBAAmB,GAAG,YAAY,CAAC,OAAO,UAAU,CAAC,CAAC;AAElE,MAAM,MAAM,qBAAqB,GAAG,eAAe,GAAG;IACpD,GAAG,CAAC,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAC/B;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,CAAC;AAOF,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,WAAW,EACX,GAAG,IAAI,EACR,EAAE,qBAAqB,2CAyBvB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-capped-scrollview",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Drop-in React Native ScrollView that caps fling velocity via a 0-1 maxVelocity prop. Fabric + TurboModules, iOS and Android.",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -1,17 +1,11 @@
1
- import {
2
- forwardRef,
3
- useEffect,
4
- useRef,
5
- useImperativeHandle,
6
- type ComponentRef,
7
- type Ref,
8
- } from 'react';
1
+ import { useEffect, useRef, type ComponentRef, type Ref } from 'react';
9
2
  import { ScrollView, type ScrollViewProps } from 'react-native';
10
3
  import NativeCappedScrollView from './NativeCappedScrollView';
11
4
 
12
5
  export type CappedScrollViewRef = ComponentRef<typeof ScrollView>;
13
6
 
14
7
  export type CappedScrollViewProps = ScrollViewProps & {
8
+ ref?: Ref<CappedScrollViewRef>;
15
9
  /**
16
10
  * Fling velocity cap as a normalized fraction in [0, 1], or `null` to
17
11
  * disable the cap mechanism entirely.
@@ -36,14 +30,13 @@ export type CappedScrollViewProps = ScrollViewProps & {
36
30
  // public [0, 1] range, so this is unambiguous on the native side.
37
31
  const NO_CAP_SENTINEL = -1;
38
32
 
39
- export const CappedScrollView = forwardRef(function CappedScrollView(
40
- { maxVelocity, ...rest }: CappedScrollViewProps,
41
- ref: Ref<CappedScrollViewRef>
42
- ) {
33
+ export function CappedScrollView({
34
+ ref,
35
+ maxVelocity,
36
+ ...rest
37
+ }: CappedScrollViewProps) {
43
38
  const innerRef = useRef<CappedScrollViewRef | null>(null);
44
39
 
45
- useImperativeHandle(ref, () => innerRef.current as CappedScrollViewRef);
46
-
47
40
  useEffect(() => {
48
41
  const handle = innerRef.current?.getScrollableNode?.();
49
42
  if (handle == null) {
@@ -53,5 +46,17 @@ export const CappedScrollView = forwardRef(function CappedScrollView(
53
46
  NativeCappedScrollView.setMaxVelocity(handle, value);
54
47
  }, [maxVelocity]);
55
48
 
56
- return <ScrollView ref={innerRef} {...rest} />;
57
- });
49
+ return (
50
+ <ScrollView
51
+ ref={(node) => {
52
+ innerRef.current = node;
53
+ if (typeof ref === 'function') {
54
+ ref(node);
55
+ } else if (ref != null) {
56
+ ref.current = node;
57
+ }
58
+ }}
59
+ {...rest}
60
+ />
61
+ );
62
+ }