@onekeyfe/react-native-pager-view 3.0.157-alpha.256 → 3.0.157-alpha.258

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.
Files changed (33) hide show
  1. package/README.md +51 -4
  2. package/android/src/main/java/com/reactnativepagerview/CollapsiblePagerHost.kt +254 -8
  3. package/android/src/main/java/com/reactnativepagerview/NativeScrollerScrollAwayInsets.kt +24 -0
  4. package/android/src/main/java/com/reactnativepagerview/NativeScrollerView.kt +573 -0
  5. package/android/src/main/java/com/reactnativepagerview/NativeScrollerViewManager.kt +130 -0
  6. package/android/src/main/java/com/reactnativepagerview/PagerViewViewPackage.kt +1 -1
  7. package/android/src/main/jni/CMakeLists.txt +19 -0
  8. package/android/src/main/jni/pagerview.h +11 -0
  9. package/android/src/main/res/values/native_scroll_coordinator_ids.xml +1 -0
  10. package/android/src/test/java/com/reactnativepagerview/NativeScrollerScrollAwayInsetsTest.kt +38 -0
  11. package/common/cpp/react/renderer/components/pagerview/RNCNativeScrollerComponentDescriptor.h +8 -0
  12. package/common/cpp/react/renderer/components/pagerview/RNCNativeScrollerShadowNode.cpp +15 -0
  13. package/common/cpp/react/renderer/components/pagerview/RNCNativeScrollerShadowNode.h +23 -0
  14. package/common/cpp/react/renderer/components/pagerview/RNCNativeScrollerState.h +33 -0
  15. package/docs/SPEC.md +268 -1
  16. package/ios/RNCCollapsiblePagerViewComponentView.mm +187 -1
  17. package/ios/RNCNativeScrollerComponentView.h +17 -0
  18. package/ios/RNCNativeScrollerComponentView.mm +479 -0
  19. package/ios/tests/RNCCollapsiblePagerPressCancellationTests.mm +346 -0
  20. package/ios/tests/RNCCollapsiblePagerPressCancellationWiringTests.mm +109 -0
  21. package/ios/tests/RNCNativeScrollerTests.mm +252 -0
  22. package/lib/module/CollapsiblePagerView.js +1 -1
  23. package/lib/module/NativeScroller.js +171 -11
  24. package/lib/module/NativeScrollerNativeComponent.ts +101 -0
  25. package/lib/typescript/src/CollapsiblePagerView.d.ts +2 -3
  26. package/lib/typescript/src/NativeScroller.d.ts +15 -7
  27. package/lib/typescript/src/NativeScrollerNativeComponent.d.ts +79 -0
  28. package/package.json +6 -3
  29. package/react-native-pager-view.podspec +2 -1
  30. package/react-native.config.js +15 -0
  31. package/src/CollapsiblePagerView.tsx +4 -4
  32. package/src/NativeScroller.tsx +291 -14
  33. package/src/NativeScrollerNativeComponent.ts +101 -0
@@ -0,0 +1,79 @@
1
+ import type * as React from "react";
2
+ import { type ColorValue, type HostComponent, type ViewProps } from "react-native";
3
+ import type { DirectEventHandler, Double, WithDefault } from "react-native/Libraries/Types/CodegenTypes";
4
+ export type NativeScrollerScrollEvent = Readonly<{
5
+ contentInset: Readonly<{
6
+ top: Double;
7
+ right: Double;
8
+ bottom: Double;
9
+ left: Double;
10
+ }>;
11
+ contentOffset: Readonly<{
12
+ x: Double;
13
+ y: Double;
14
+ }>;
15
+ contentSize: Readonly<{
16
+ width: Double;
17
+ height: Double;
18
+ }>;
19
+ layoutMeasurement: Readonly<{
20
+ width: Double;
21
+ height: Double;
22
+ }>;
23
+ velocity: Readonly<{
24
+ x: Double;
25
+ y: Double;
26
+ }>;
27
+ targetContentOffset: Readonly<{
28
+ x: Double;
29
+ y: Double;
30
+ }>;
31
+ zoomScale: Double;
32
+ }>;
33
+ export interface NativeProps extends ViewProps {
34
+ contentWidth?: WithDefault<Double, 0>;
35
+ contentHeight?: WithDefault<Double, 0>;
36
+ scrollEnabled?: WithDefault<boolean, true>;
37
+ nestedScrollEnabled?: WithDefault<boolean, true>;
38
+ showsVerticalScrollIndicator?: WithDefault<boolean, true>;
39
+ showsHorizontalScrollIndicator?: WithDefault<boolean, false>;
40
+ bounces?: WithDefault<boolean, true>;
41
+ alwaysBounceVertical?: WithDefault<boolean, true>;
42
+ keyboardDismissMode?: WithDefault<"none" | "on-drag" | "interactive", "none">;
43
+ keyboardShouldPersistTaps?: WithDefault<"never" | "always" | "handled", "never">;
44
+ scrollEventThrottle?: WithDefault<Double, 0>;
45
+ decelerationRate?: WithDefault<Double, 0.998>;
46
+ contentInsetTop?: WithDefault<Double, 0>;
47
+ contentInsetRight?: WithDefault<Double, 0>;
48
+ contentInsetBottom?: WithDefault<Double, 0>;
49
+ contentInsetLeft?: WithDefault<Double, 0>;
50
+ refreshEnabled?: WithDefault<boolean, false>;
51
+ refreshing?: WithDefault<boolean, false>;
52
+ refreshTintColor?: ColorValue;
53
+ refreshColors?: ReadonlyArray<ColorValue>;
54
+ refreshProgressBackgroundColor?: ColorValue;
55
+ refreshProgressViewOffset?: WithDefault<Double, 0>;
56
+ refreshTitle?: string;
57
+ refreshTitleColor?: ColorValue;
58
+ refreshSize?: WithDefault<"default" | "large", "default">;
59
+ onContentViewportChange?: DirectEventHandler<Readonly<{
60
+ height: Double;
61
+ }>>;
62
+ onRefresh?: DirectEventHandler<null>;
63
+ onScroll?: DirectEventHandler<NativeScrollerScrollEvent>;
64
+ onScrollBeginDrag?: DirectEventHandler<NativeScrollerScrollEvent>;
65
+ onScrollEndDrag?: DirectEventHandler<NativeScrollerScrollEvent>;
66
+ onMomentumScrollBegin?: DirectEventHandler<NativeScrollerScrollEvent>;
67
+ onMomentumScrollEnd?: DirectEventHandler<NativeScrollerScrollEvent>;
68
+ }
69
+ type NativeScrollerHost = HostComponent<NativeProps>;
70
+ export interface NativeCommands {
71
+ scrollTo: (viewRef: React.ElementRef<NativeScrollerHost>, x: Double, y: Double, animated: boolean) => void;
72
+ scrollToEnd: (viewRef: React.ElementRef<NativeScrollerHost>, animated: boolean) => void;
73
+ flashScrollIndicators: (viewRef: React.ElementRef<NativeScrollerHost>) => void;
74
+ setRefreshState: (viewRef: React.ElementRef<NativeScrollerHost>, refreshing: boolean) => void;
75
+ }
76
+ export declare const Commands: NativeCommands;
77
+ declare const _default: NativeScrollerHost;
78
+ export default _default;
79
+ //# sourceMappingURL=NativeScrollerNativeComponent.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/react-native-pager-view",
3
- "version": "3.0.157-alpha.256",
3
+ "version": "3.0.157-alpha.258",
4
4
  "description": "React Native wrapper for Android and iOS ViewPager",
5
5
  "source": "./src/index.tsx",
6
6
  "main": "./lib/module/index.js",
@@ -33,7 +33,9 @@
33
33
  "!**/__fixtures__",
34
34
  "!**/__mocks__",
35
35
  "!**/.*",
36
- "!**/*.map"
36
+ "!**/*.map",
37
+ "common",
38
+ "react-native.config.js"
37
39
  ],
38
40
  "scripts": {
39
41
  "clean": "del-cli lib",
@@ -99,7 +101,8 @@
99
101
  "ios": {
100
102
  "componentProvider": {
101
103
  "RNCViewPager": "RNCPagerViewComponentView",
102
- "RNCCollapsiblePagerView": "RNCCollapsiblePagerViewComponentView"
104
+ "RNCCollapsiblePagerView": "RNCCollapsiblePagerViewComponentView",
105
+ "RNCNativeScroller": "RNCNativeScrollerComponentView"
103
106
  }
104
107
  }
105
108
  }
@@ -13,7 +13,8 @@ Pod::Spec.new do |s|
13
13
  s.ios.deployment_target = "15.1"
14
14
  s.source = { :git => "https://github.com/nicholasxuu/app-modules.git", :tag => "#{s.version}" }
15
15
 
16
- s.source_files = "ios/**/*.{h,m,mm}"
16
+ s.source_files = "ios/**/*.{h,m,mm}", "common/cpp/**/*.{h,cpp}"
17
+ s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => '"$(PODS_TARGET_SRCROOT)/common/cpp"' }
17
18
  s.exclude_files = "ios/tests/**/*"
18
19
 
19
20
  s.test_spec "Tests" do |test_spec|
@@ -0,0 +1,15 @@
1
+ module.exports = {
2
+ dependency: {
3
+ platforms: {
4
+ android: {
5
+ libraryName: 'pagerview',
6
+ componentDescriptors: [
7
+ 'RNCViewPagerComponentDescriptor',
8
+ 'RNCCollapsiblePagerViewComponentDescriptor',
9
+ 'RNCNativeScrollerComponentDescriptor',
10
+ ],
11
+ cmakeListsPath: 'src/main/jni/CMakeLists.txt',
12
+ },
13
+ },
14
+ },
15
+ };
@@ -130,9 +130,8 @@ export interface CollapsiblePagerViewProps
130
130
  nativeTabBar?: CollapsiblePagerNativeTabBarConfig;
131
131
  onNativeTabPress?: (event: CollapsiblePagerViewOnNativeTabPressEvent) => void;
132
132
  /**
133
- * Animates the page change started by a native tab press. Defaults to true.
134
- * Set false to jump straight to the pressed page, so a distant tab does not
135
- * scroll through every page in between, including unmounted ones.
133
+ * Defaults to animating adjacent native tab presses and jumping directly to
134
+ * non-adjacent pages. Set true to always animate, or false to always jump.
136
135
  */
137
136
  nativeTabPressAnimationEnabled?: boolean;
138
137
  /** Optional native secondary sticky header for iOS and Android. */
@@ -411,7 +410,8 @@ export class CollapsiblePagerView extends React.PureComponent<
411
410
  ) {
412
411
  this.dispatchNativeTabPageCommand(
413
412
  position,
414
- this.props.nativeTabPressAnimationEnabled ?? true
413
+ this.props.nativeTabPressAnimationEnabled ??
414
+ Math.abs(position - this.state.selectedPage) <= 1
415
415
  );
416
416
  }
417
417
  this.props.onNativeTabPress?.(event);
@@ -1,34 +1,311 @@
1
1
  import * as React from "react";
2
- import { ScrollView, type ScrollViewProps } from "react-native";
2
+ import {
3
+ findNodeHandle,
4
+ Keyboard,
5
+ Platform,
6
+ StyleSheet,
7
+ TextInput,
8
+ View,
9
+ type GestureResponderEvent,
10
+ type NativeMethods,
11
+ type RefreshControlProps,
12
+ type ScrollView,
13
+ type ScrollViewProps,
14
+ type ViewProps,
15
+ } from "react-native";
16
+
17
+ import NativeScrollerHost, { Commands } from "./NativeScrollerNativeComponent";
3
18
 
4
19
  export const NATIVE_SCROLLER_NATIVE_ID_PREFIX =
5
20
  "rnc-collapsible-pager-native-scroller";
6
21
 
7
- export interface NativeScrollerProps extends ScrollViewProps {
8
- /** Stable identity used when a page replaces or remounts its primary scroller. */
22
+ /** Supported vertical subset; horizontal, snapping, zoom and sticky rows are not supported. */
23
+ export interface NativeScrollerProps
24
+ extends ViewProps,
25
+ Pick<
26
+ ScrollViewProps,
27
+ | "contentContainerStyle"
28
+ | "onContentSizeChange"
29
+ | "scrollEnabled"
30
+ | "nestedScrollEnabled"
31
+ | "showsVerticalScrollIndicator"
32
+ | "showsHorizontalScrollIndicator"
33
+ | "bounces"
34
+ | "alwaysBounceVertical"
35
+ | "contentInset"
36
+ | "keyboardDismissMode"
37
+ | "keyboardShouldPersistTaps"
38
+ | "scrollEventThrottle"
39
+ | "decelerationRate"
40
+ | "onScroll"
41
+ | "onScrollBeginDrag"
42
+ | "onScrollEndDrag"
43
+ | "onMomentumScrollBegin"
44
+ | "onMomentumScrollEnd"
45
+ > {
9
46
  pagerScrollKey?: string;
47
+ /** iOS only. Android retains AndroidX's native fling physics. */
48
+ decelerationRate?: ScrollViewProps["decelerationRate"];
49
+ /** Standard RefreshControl props are mapped to the independently owned native controller. */
50
+ refreshControl?: React.ReactElement<RefreshControlProps>;
51
+ }
52
+
53
+ type HostRef = React.ElementRef<typeof NativeScrollerHost>;
54
+
55
+ export interface NativeScrollerRef
56
+ extends NativeMethods,
57
+ Pick<
58
+ React.ElementRef<typeof ScrollView>,
59
+ "scrollTo" | "scrollToEnd" | "flashScrollIndicators"
60
+ > {
61
+ getNativeScrollRef(): HostRef | null;
62
+ getScrollableNode(): number | null;
10
63
  }
11
64
 
12
- /**
13
- * Primary non-virtualized vertical scroller for a CollapsiblePagerView page.
14
- */
65
+ // The RN 0.86 JS registry distinguishes another input from an unhandled tap.
66
+ // TextInput.State's public facade does not export this query.
67
+ const textInputState =
68
+ require("react-native/Libraries/Components/TextInput/TextInputState")
69
+ .default as {
70
+ isTextInput(target: GestureResponderEvent["target"]): boolean;
71
+ };
72
+
73
+ const styles = StyleSheet.create({
74
+ viewport: { flexGrow: 1, flexShrink: 1, overflow: "hidden" },
75
+ content: { position: "absolute", top: 0, left: 0, right: 0, flexShrink: 0 },
76
+ });
77
+
15
78
  export const NativeScroller = React.forwardRef<
16
- React.ElementRef<typeof ScrollView>,
79
+ NativeScrollerRef,
17
80
  NativeScrollerProps
18
81
  >(function NativeScroller(
19
- { nativeID, nestedScrollEnabled = true, pagerScrollKey, ...props },
20
- ref
82
+ {
83
+ children,
84
+ nativeID,
85
+ pagerScrollKey,
86
+ style,
87
+ contentContainerStyle,
88
+ onLayout,
89
+ onContentSizeChange,
90
+ refreshControl,
91
+ nestedScrollEnabled = true,
92
+ contentInset,
93
+ decelerationRate = "normal",
94
+ keyboardShouldPersistTaps = "never",
95
+ onScroll,
96
+ onScrollBeginDrag,
97
+ onMomentumScrollBegin,
98
+ onMomentumScrollEnd,
99
+ onStartShouldSetResponder,
100
+ onStartShouldSetResponderCapture,
101
+ onResponderGrant,
102
+ onResponderRelease,
103
+ onResponderTerminationRequest,
104
+ ...props
105
+ },
106
+ forwardedRef
21
107
  ) {
108
+ const hostRef = React.useRef<HostRef>(null);
22
109
  const generatedId = React.useId();
23
- const scrollKey = pagerScrollKey ?? nativeID ?? generatedId;
110
+ const [contentViewportHeight, setContentViewportHeight] = React.useState(0);
111
+ const [contentSize, setContentSize] = React.useState({ width: 0, height: 0 });
112
+ const [refreshEpoch, requestRefreshSync] = React.useReducer(
113
+ (value: number) => value + 1,
114
+ 0
115
+ );
116
+ const contentSizeRef = React.useRef(contentSize);
117
+ const scrolledSinceGrant = React.useRef(false);
118
+ const momentum = React.useRef(false);
119
+ const grantedDuringMomentum = React.useRef(false);
120
+ const persistTaps =
121
+ keyboardShouldPersistTaps === true
122
+ ? "always"
123
+ : keyboardShouldPersistTaps === false
124
+ ? "never"
125
+ : keyboardShouldPersistTaps;
126
+ const contentStyle = StyleSheet.flatten(contentContainerStyle);
127
+ const refresh = refreshControl?.props;
128
+ const rate =
129
+ typeof decelerationRate === "number"
130
+ ? decelerationRate
131
+ : decelerationRate === "fast"
132
+ ? Platform.OS === "ios"
133
+ ? 0.99
134
+ : 0.9
135
+ : Platform.OS === "ios"
136
+ ? 0.998
137
+ : 0.985;
138
+
139
+ React.useEffect(() => {
140
+ if (hostRef.current)
141
+ Commands.setRefreshState(hostRef.current, refresh?.refreshing ?? false);
142
+ }, [refresh?.refreshing, refreshEpoch]);
143
+
144
+ React.useImperativeHandle(
145
+ forwardedRef,
146
+ () => ({
147
+ scrollTo(options, x, animated) {
148
+ const host = hostRef.current;
149
+ if (!host) return;
150
+ if (typeof options === "number") {
151
+ Commands.scrollTo(host, x ?? 0, options, animated !== false);
152
+ } else {
153
+ Commands.scrollTo(
154
+ host,
155
+ options?.x ?? 0,
156
+ options?.y ?? 0,
157
+ options?.animated !== false
158
+ );
159
+ }
160
+ },
161
+ scrollToEnd(options) {
162
+ if (hostRef.current)
163
+ Commands.scrollToEnd(hostRef.current, options?.animated !== false);
164
+ },
165
+ flashScrollIndicators() {
166
+ if (hostRef.current) Commands.flashScrollIndicators(hostRef.current);
167
+ },
168
+ getNativeScrollRef: () => hostRef.current,
169
+ getScrollableNode: () => findNodeHandle(hostRef.current) ?? null,
170
+ measure: (...args) => hostRef.current?.measure(...args),
171
+ measureInWindow: (...args) => hostRef.current?.measureInWindow(...args),
172
+ measureLayout: (...args) => hostRef.current?.measureLayout(...args),
173
+ setNativeProps: (nativeProps) =>
174
+ hostRef.current?.setNativeProps(nativeProps),
175
+ focus: () => hostRef.current?.focus(),
176
+ blur: () => hostRef.current?.blur(),
177
+ }),
178
+ []
179
+ );
180
+
181
+ const keyboardIsDismissible = () =>
182
+ Boolean(
183
+ TextInput.State.currentlyFocusedInput() &&
184
+ (Keyboard.isVisible() ||
185
+ (Platform.OS === "android" && Number(Platform.Version) < 30)) &&
186
+ Keyboard.metrics()?.height !== 0
187
+ );
24
188
 
25
189
  return (
26
- <ScrollView
190
+ <NativeScrollerHost
27
191
  {...props}
28
- ref={ref}
29
- nativeID={`${NATIVE_SCROLLER_NATIVE_ID_PREFIX}:${scrollKey}`}
192
+ ref={hostRef}
193
+ nativeID={`${NATIVE_SCROLLER_NATIVE_ID_PREFIX}:${
194
+ pagerScrollKey ?? nativeID ?? generatedId
195
+ }`}
196
+ style={[styles.viewport, style]}
30
197
  nestedScrollEnabled={nestedScrollEnabled}
31
- />
198
+ contentWidth={contentSize.width}
199
+ contentHeight={contentSize.height}
200
+ contentInsetTop={contentInset?.top ?? 0}
201
+ contentInsetRight={contentInset?.right ?? 0}
202
+ contentInsetBottom={contentInset?.bottom ?? 0}
203
+ contentInsetLeft={contentInset?.left ?? 0}
204
+ decelerationRate={rate}
205
+ keyboardShouldPersistTaps={persistTaps}
206
+ refreshEnabled={Boolean(refresh) && refresh?.enabled !== false}
207
+ refreshing={refresh?.refreshing ?? false}
208
+ refreshTintColor={refresh?.tintColor}
209
+ refreshColors={refresh?.colors}
210
+ refreshProgressBackgroundColor={refresh?.progressBackgroundColor}
211
+ refreshProgressViewOffset={refresh?.progressViewOffset ?? 0}
212
+ refreshTitle={refresh?.title}
213
+ refreshTitleColor={refresh?.titleColor}
214
+ refreshSize={refresh?.size === "large" ? "large" : "default"}
215
+ onRefresh={() => {
216
+ try {
217
+ refresh?.onRefresh?.();
218
+ } finally {
219
+ requestRefreshSync();
220
+ }
221
+ }}
222
+ onLayout={onLayout}
223
+ onContentViewportChange={(event) => {
224
+ const height = event.nativeEvent.height;
225
+ if (!Number.isFinite(height) || height < 0) return;
226
+ setContentViewportHeight((previous) =>
227
+ previous === height ? previous : height
228
+ );
229
+ }}
230
+ onScroll={(event) => {
231
+ scrolledSinceGrant.current = true;
232
+ onScroll?.(event);
233
+ }}
234
+ onScrollBeginDrag={(event) => {
235
+ scrolledSinceGrant.current = true;
236
+ onScrollBeginDrag?.(event);
237
+ }}
238
+ onMomentumScrollBegin={(event) => {
239
+ momentum.current = true;
240
+ onMomentumScrollBegin?.(event);
241
+ }}
242
+ onMomentumScrollEnd={(event) => {
243
+ momentum.current = false;
244
+ onMomentumScrollEnd?.(event);
245
+ }}
246
+ onStartShouldSetResponder={(event) =>
247
+ onStartShouldSetResponder?.(event) ??
248
+ (persistTaps === "handled" &&
249
+ keyboardIsDismissible() &&
250
+ event.target !== TextInput.State.currentlyFocusedInput())
251
+ }
252
+ onStartShouldSetResponderCapture={(event) =>
253
+ onStartShouldSetResponderCapture?.(event) ??
254
+ (momentum.current ||
255
+ (persistTaps === "never" &&
256
+ keyboardIsDismissible() &&
257
+ typeof event.target !== "number" &&
258
+ !textInputState.isTextInput(event.target)))
259
+ }
260
+ onResponderGrant={(event) => {
261
+ scrolledSinceGrant.current = false;
262
+ grantedDuringMomentum.current = momentum.current;
263
+ onResponderGrant?.(event);
264
+ }}
265
+ onResponderRelease={(event) => {
266
+ onResponderRelease?.(event);
267
+ if (
268
+ persistTaps !== "always" &&
269
+ keyboardIsDismissible() &&
270
+ event.target !== TextInput.State.currentlyFocusedInput() &&
271
+ !scrolledSinceGrant.current &&
272
+ !grantedDuringMomentum.current
273
+ )
274
+ Keyboard.dismiss();
275
+ }}
276
+ onResponderTerminationRequest={(event) =>
277
+ onResponderTerminationRequest?.(event) ?? true
278
+ }
279
+ >
280
+ <View
281
+ collapsable={false}
282
+ style={[
283
+ contentContainerStyle,
284
+ (contentStyle?.flexGrow ?? 0) > 0 &&
285
+ (contentStyle?.minHeight === undefined ||
286
+ typeof contentStyle.minHeight === "number")
287
+ ? {
288
+ minHeight: Math.max(
289
+ contentViewportHeight,
290
+ contentStyle?.minHeight ?? 0
291
+ ),
292
+ }
293
+ : undefined,
294
+ styles.content,
295
+ ]}
296
+ onLayout={(event) => {
297
+ const { width, height } = event.nativeEvent.layout;
298
+ const previous = contentSizeRef.current;
299
+ if (previous.width === width && previous.height === height) return;
300
+ const next = { width, height };
301
+ contentSizeRef.current = next;
302
+ setContentSize(next);
303
+ onContentSizeChange?.(width, height);
304
+ }}
305
+ >
306
+ {children}
307
+ </View>
308
+ </NativeScrollerHost>
32
309
  );
33
310
  });
34
311
 
@@ -0,0 +1,101 @@
1
+ import type * as React from "react";
2
+ import {
3
+ codegenNativeCommands,
4
+ codegenNativeComponent,
5
+ type ColorValue,
6
+ type HostComponent,
7
+ type ViewProps,
8
+ } from "react-native";
9
+ import type {
10
+ DirectEventHandler,
11
+ Double,
12
+ WithDefault,
13
+ } from "react-native/Libraries/Types/CodegenTypes";
14
+
15
+ export type NativeScrollerScrollEvent = Readonly<{
16
+ contentInset: Readonly<{
17
+ top: Double;
18
+ right: Double;
19
+ bottom: Double;
20
+ left: Double;
21
+ }>;
22
+ contentOffset: Readonly<{ x: Double; y: Double }>;
23
+ contentSize: Readonly<{ width: Double; height: Double }>;
24
+ layoutMeasurement: Readonly<{ width: Double; height: Double }>;
25
+ velocity: Readonly<{ x: Double; y: Double }>;
26
+ targetContentOffset: Readonly<{ x: Double; y: Double }>;
27
+ zoomScale: Double;
28
+ }>;
29
+
30
+ export interface NativeProps extends ViewProps {
31
+ contentWidth?: WithDefault<Double, 0>;
32
+ contentHeight?: WithDefault<Double, 0>;
33
+ scrollEnabled?: WithDefault<boolean, true>;
34
+ nestedScrollEnabled?: WithDefault<boolean, true>;
35
+ showsVerticalScrollIndicator?: WithDefault<boolean, true>;
36
+ showsHorizontalScrollIndicator?: WithDefault<boolean, false>;
37
+ bounces?: WithDefault<boolean, true>;
38
+ alwaysBounceVertical?: WithDefault<boolean, true>;
39
+ keyboardDismissMode?: WithDefault<"none" | "on-drag" | "interactive", "none">;
40
+ keyboardShouldPersistTaps?: WithDefault<
41
+ "never" | "always" | "handled",
42
+ "never"
43
+ >;
44
+ scrollEventThrottle?: WithDefault<Double, 0>;
45
+ decelerationRate?: WithDefault<Double, 0.998>;
46
+ contentInsetTop?: WithDefault<Double, 0>;
47
+ contentInsetRight?: WithDefault<Double, 0>;
48
+ contentInsetBottom?: WithDefault<Double, 0>;
49
+ contentInsetLeft?: WithDefault<Double, 0>;
50
+ refreshEnabled?: WithDefault<boolean, false>;
51
+ refreshing?: WithDefault<boolean, false>;
52
+ refreshTintColor?: ColorValue;
53
+ refreshColors?: ReadonlyArray<ColorValue>;
54
+ refreshProgressBackgroundColor?: ColorValue;
55
+ refreshProgressViewOffset?: WithDefault<Double, 0>;
56
+ refreshTitle?: string;
57
+ refreshTitleColor?: ColorValue;
58
+ refreshSize?: WithDefault<"default" | "large", "default">;
59
+ onContentViewportChange?: DirectEventHandler<Readonly<{ height: Double }>>;
60
+ onRefresh?: DirectEventHandler<null>;
61
+ onScroll?: DirectEventHandler<NativeScrollerScrollEvent>;
62
+ onScrollBeginDrag?: DirectEventHandler<NativeScrollerScrollEvent>;
63
+ onScrollEndDrag?: DirectEventHandler<NativeScrollerScrollEvent>;
64
+ onMomentumScrollBegin?: DirectEventHandler<NativeScrollerScrollEvent>;
65
+ onMomentumScrollEnd?: DirectEventHandler<NativeScrollerScrollEvent>;
66
+ }
67
+
68
+ type NativeScrollerHost = HostComponent<NativeProps>;
69
+
70
+ export interface NativeCommands {
71
+ scrollTo: (
72
+ viewRef: React.ElementRef<NativeScrollerHost>,
73
+ x: Double,
74
+ y: Double,
75
+ animated: boolean
76
+ ) => void;
77
+ scrollToEnd: (
78
+ viewRef: React.ElementRef<NativeScrollerHost>,
79
+ animated: boolean
80
+ ) => void;
81
+ flashScrollIndicators: (
82
+ viewRef: React.ElementRef<NativeScrollerHost>
83
+ ) => void;
84
+ setRefreshState: (
85
+ viewRef: React.ElementRef<NativeScrollerHost>,
86
+ refreshing: boolean
87
+ ) => void;
88
+ }
89
+
90
+ export const Commands: NativeCommands = codegenNativeCommands<NativeCommands>({
91
+ supportedCommands: [
92
+ "scrollTo",
93
+ "scrollToEnd",
94
+ "flashScrollIndicators",
95
+ "setRefreshState",
96
+ ],
97
+ });
98
+
99
+ export default codegenNativeComponent<NativeProps>("RNCNativeScroller", {
100
+ interfaceOnly: true,
101
+ }) as NativeScrollerHost;