@onekeyfe/react-native-pager-view 3.0.122 → 3.0.124

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.
@@ -185,6 +185,13 @@ export class CollapsiblePagerView extends React.PureComponent<
185
185
 
186
186
  private latestNativeTabTarget: number | null = null;
187
187
 
188
+ private latestNativeSelectedPage = this.state.selectedPage;
189
+
190
+ private nativePagerScrollState: OnPageScrollStateChangedEventData["pageScrollState"] =
191
+ "idle";
192
+
193
+ private nativeTabCommandQueuedDuringScroll = false;
194
+
188
195
  componentDidMount() {
189
196
  this.notifyMountedPagesChanged();
190
197
  }
@@ -256,6 +263,8 @@ export class CollapsiblePagerView extends React.PureComponent<
256
263
 
257
264
  private dispatchNativeTabPageCommand(position: number, animated: boolean) {
258
265
  const commandId = ++this.nativeTabCommandId;
266
+ this.nativeTabCommandQueuedDuringScroll =
267
+ this.nativePagerScrollState !== "idle";
259
268
  this.latestNativeTabTarget = position;
260
269
  this.setState(
261
270
  (state) => ({
@@ -331,6 +340,7 @@ export class CollapsiblePagerView extends React.PureComponent<
331
340
  event.nativeEvent.position,
332
341
  this.pages().length
333
342
  );
343
+ this.latestNativeSelectedPage = position;
334
344
  if (
335
345
  position !== this.state.selectedPage ||
336
346
  this.state.transientRetainedPages.length > 0
@@ -339,6 +349,7 @@ export class CollapsiblePagerView extends React.PureComponent<
339
349
  const transitionComplete = pendingTarget === position;
340
350
  if (transitionComplete) {
341
351
  this.latestNativeTabTarget = null;
352
+ this.nativeTabCommandQueuedDuringScroll = false;
342
353
  }
343
354
  this.setState(
344
355
  {
@@ -354,9 +365,46 @@ export class CollapsiblePagerView extends React.PureComponent<
354
365
  this.props.onPageSelected?.(event);
355
366
  };
356
367
 
368
+ private onPageScrollStateChanged = (
369
+ event: ReactNative.NativeSyntheticEvent<OnPageScrollStateChangedEventData>
370
+ ) => {
371
+ const scrollState = event.nativeEvent.pageScrollState;
372
+ const queuedDuringPreviousScroll = this.nativeTabCommandQueuedDuringScroll;
373
+ this.nativePagerScrollState = scrollState;
374
+ // Native drains tab commands queued during an active drag after reporting
375
+ // that drag as idle. Preserve the newer target through that first idle.
376
+ if (
377
+ scrollState === "idle" &&
378
+ this.latestNativeTabTarget !== null &&
379
+ this.latestNativeTabTarget !== this.latestNativeSelectedPage &&
380
+ !queuedDuringPreviousScroll
381
+ ) {
382
+ ++this.nativeTabCommandId;
383
+ this.latestNativeTabTarget = null;
384
+ this.setState(
385
+ { transientRetainedPages: [] },
386
+ this.notifyMountedPagesChanged
387
+ );
388
+ }
389
+ if (scrollState === "idle") {
390
+ this.nativeTabCommandQueuedDuringScroll = false;
391
+ }
392
+ this.props.onPageScrollStateChanged?.(event);
393
+ };
394
+
357
395
  private onNativeTabPress = (
358
396
  event: ReactNative.NativeSyntheticEvent<OnNativeTabPressEventData>
359
397
  ) => {
398
+ const position = pageIndex(event.nativeEvent.position);
399
+ if (
400
+ position !== null &&
401
+ position >= 0 &&
402
+ position < this.pages().length &&
403
+ (position !== this.state.selectedPage ||
404
+ this.latestNativeTabTarget !== null)
405
+ ) {
406
+ this.dispatchNativeTabPageCommand(position, true);
407
+ }
360
408
  this.props.onNativeTabPress?.(event);
361
409
  };
362
410
 
@@ -377,6 +425,7 @@ export class CollapsiblePagerView extends React.PureComponent<
377
425
  pageRetentionDistance: _pageRetentionDistance,
378
426
  onMountedPagesChanged: _onMountedPagesChanged,
379
427
  onPageSelected: _onPageSelected,
428
+ onPageScrollStateChanged: _onPageScrollStateChanged,
380
429
  nativeTabBar,
381
430
  onNativeTabPress: _onNativeTabPress,
382
431
  nativeSubHeader,
@@ -431,6 +480,7 @@ export class CollapsiblePagerView extends React.PureComponent<
431
480
  pageKeys={JSON.stringify(pageKeys)}
432
481
  retainedPages={JSON.stringify([...retained])}
433
482
  onPageSelected={this.onPageSelected}
483
+ onPageScrollStateChanged={this.onPageScrollStateChanged}
434
484
  nativeTabBarItems={
435
485
  nativeTabBarEnabled ? JSON.stringify(nativeTabBar.items) : undefined
436
486
  }
@@ -0,0 +1,35 @@
1
+ import * as React from "react";
2
+ import { ScrollView, type ScrollViewProps } from "react-native";
3
+
4
+ export const NATIVE_SCROLLER_NATIVE_ID_PREFIX =
5
+ "rnc-collapsible-pager-native-scroller";
6
+
7
+ export interface NativeScrollerProps extends ScrollViewProps {
8
+ /** Stable identity used when a page replaces or remounts its primary scroller. */
9
+ pagerScrollKey?: string;
10
+ }
11
+
12
+ /**
13
+ * Primary non-virtualized vertical scroller for a CollapsiblePagerView page.
14
+ */
15
+ export const NativeScroller = React.forwardRef<
16
+ React.ElementRef<typeof ScrollView>,
17
+ NativeScrollerProps
18
+ >(function NativeScroller(
19
+ { nativeID, nestedScrollEnabled = true, pagerScrollKey, ...props },
20
+ ref
21
+ ) {
22
+ const generatedId = React.useId();
23
+ const scrollKey = pagerScrollKey ?? nativeID ?? generatedId;
24
+
25
+ return (
26
+ <ScrollView
27
+ {...props}
28
+ ref={ref}
29
+ nativeID={`${NATIVE_SCROLLER_NATIVE_ID_PREFIX}:${scrollKey}`}
30
+ nestedScrollEnabled={nestedScrollEnabled}
31
+ />
32
+ );
33
+ });
34
+
35
+ NativeScroller.displayName = "NativeScroller";
@@ -0,0 +1,31 @@
1
+ import * as React from "react";
2
+ import { ScrollView } from "react-native";
3
+
4
+ import type { NativeScrollerProps } from "./NativeScroller";
5
+
6
+ type NativeScrollerWebProps = NativeScrollerProps & {
7
+ dataSet?: Record<string, string>;
8
+ };
9
+
10
+ export const NativeScroller = React.forwardRef<
11
+ React.ElementRef<typeof ScrollView>,
12
+ NativeScrollerProps
13
+ >(function NativeScroller(inputProps, ref) {
14
+ const {
15
+ dataSet,
16
+ pagerScrollKey: _pagerScrollKey,
17
+ ...props
18
+ } = inputProps as NativeScrollerWebProps;
19
+ const webDataProps = {
20
+ dataSet: {
21
+ ...dataSet,
22
+ collapsiblePagerScroll: "true",
23
+ },
24
+ };
25
+
26
+ return <ScrollView {...props} ref={ref} {...webDataProps} />;
27
+ });
28
+
29
+ NativeScroller.displayName = "NativeScroller";
30
+
31
+ export type { NativeScrollerProps } from "./NativeScroller";
package/src/index.tsx CHANGED
@@ -3,6 +3,7 @@ import { PagerView } from './PagerView';
3
3
  export default PagerView;
4
4
  export * from './usePagerView';
5
5
  export * from './CollapsiblePagerView';
6
+ export * from './NativeScroller';
6
7
 
7
8
  import type {
8
9
  OnPageScrollEventData as PagerViewOnPageScrollEventData,
package/src/index.web.tsx CHANGED
@@ -10,3 +10,4 @@ export type {
10
10
  } from "./PagerView.web";
11
11
  export * from "./usePagerView";
12
12
  export * from "./CollapsiblePagerView.web";
13
+ export * from "./NativeScroller.web";