@onekeyfe/react-native-pager-view 3.0.179-alpha.2026101501 → 3.0.179-alpha.2026101503

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.
package/docs/SPEC.md CHANGED
@@ -36,7 +36,9 @@ outer PagerView transition
36
36
  releases the current edge interaction before moving its shared headers and
37
37
  applying visible-page masks; completion or cancellation reattaches the actual
38
38
  settled owner. An inactive inner pager retains the external header inset while
39
- its edge interaction is released.
39
+ its edge interaction is released. Without an outer PagerView, a standalone
40
+ external-overlay pager owns its edge interaction directly; page-activity and
41
+ transition gates apply only while an outer PagerView is registered.
40
42
 
41
43
  `topOverlayColorScheme` is optional (`"light" | "dark"`) and coordinates the
42
44
  fixed overlay's effective appearance with React theme commits. It does not
@@ -2050,6 +2050,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
2050
2050
  if (@available(iOS 26.0, *)) {
2051
2051
  if (_pendingTopOverlayAppearanceCommit) scrollView = nil;
2052
2052
  BOOL externalOwnerReady = _externalTopOverlayTag <= 0 ||
2053
+ _externalOuterPager == nil ||
2053
2054
  (_externalOuterPageActive && !_externalOuterTransitioning);
2054
2055
  BOOL hasOverlay = _topScrollEdgeHard && self.hasFixedTopOverlay &&
2055
2056
  externalOwnerReady && self.window != nil;
@@ -1,10 +1,15 @@
1
1
  #import <XCTest/XCTest.h>
2
2
 
3
3
  #import "RNCCollapsiblePagerViewComponentView.h"
4
+ #import "RNCPagerViewComponentView.h"
4
5
  #import <react/renderer/components/pagerview/Props.h>
5
6
 
6
7
  using namespace facebook::react;
7
8
 
9
+ @interface RNCCollapsiblePagerViewComponentView (ScrollEdgeTesting)
10
+ - (void)updateTopScrollEdgeForScrollView:(UIScrollView *)scrollView;
11
+ @end
12
+
8
13
  @interface RNCCollapsiblePagerHitTestTests : XCTestCase
9
14
  @property (nonatomic, strong) UIView *root;
10
15
  @property (nonatomic, strong) UIButton *toolbar;
@@ -77,4 +82,48 @@ using namespace facebook::react;
77
82
  XCTAssertNil([self.pager hitTest:CGPointMake(20, 90) withEvent:nil]);
78
83
  }
79
84
 
85
+ - (void)testExternalOverlayWithoutOuterPagerOwnsItsEdgeAndRegisteredOuterStillGates
86
+ {
87
+ if (@available(iOS 26.0, *)) {
88
+ UIWindow *window = [[UIWindow alloc] initWithFrame:self.root.bounds];
89
+ [window addSubview:self.root];
90
+ UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.pager.bounds];
91
+ [self.pager addSubview:scrollView];
92
+ UIScrollEdgeEffectStyle *originalStyle = scrollView.topEdgeEffect.style;
93
+ [self.pager setValue:@YES forKey:@"topScrollEdgeHard"];
94
+ [self.pager setValue:@123 forKey:@"externalTopOverlayTag"];
95
+ [self.pager setValue:@64 forKey:@"externalTopOverlayHeight"];
96
+ [self.pager updateTopScrollEdgeForScrollView:scrollView];
97
+ XCTAssertEqual([self.pager valueForKey:@"topEdgeScrollView"], scrollView);
98
+ UIScrollEdgeElementContainerInteraction *interaction =
99
+ [self.pager valueForKey:@"topEdgeInteraction"];
100
+ XCTAssertEqual(interaction.scrollView, scrollView);
101
+ UIView *host = [self.pager valueForKey:@"topEdgeInteractionHost"];
102
+ XCTAssertTrue([host.interactions containsObject:interaction]);
103
+
104
+ RNCPagerViewComponentView *outer = [RNCPagerViewComponentView new];
105
+ [self.pager setValue:outer forKey:@"externalOuterPager"];
106
+ [self.pager setValue:@NO forKey:@"externalOuterPageActive"];
107
+ [self.pager updateTopScrollEdgeForScrollView:scrollView];
108
+ XCTAssertNil([self.pager valueForKey:@"topEdgeInteraction"]);
109
+ [self.pager setValue:@YES forKey:@"externalOuterPageActive"];
110
+ [self.pager updateTopScrollEdgeForScrollView:scrollView];
111
+ XCTAssertNotNil([self.pager valueForKey:@"topEdgeInteraction"]);
112
+ [self.pager setValue:@YES forKey:@"externalOuterTransitioning"];
113
+ [self.pager updateTopScrollEdgeForScrollView:scrollView];
114
+ XCTAssertNil([self.pager valueForKey:@"topEdgeInteraction"]);
115
+
116
+ [self.pager setValue:nil forKey:@"externalOuterPager"];
117
+ [self.pager updateTopScrollEdgeForScrollView:scrollView];
118
+ XCTAssertNotNil([self.pager valueForKey:@"topEdgeInteraction"]);
119
+ [self.pager removeFromSuperview];
120
+ XCTAssertNil([self.pager valueForKey:@"topEdgeInteraction"]);
121
+ XCTAssertNil([self.pager valueForKey:@"topEdgeScrollView"]);
122
+ XCTAssertEqual(scrollView.topEdgeEffect.style, originalStyle);
123
+ [self.root removeFromSuperview];
124
+ } else {
125
+ XCTSkip(@"Scroll-edge interactions require iOS 26 or newer");
126
+ }
127
+ }
128
+
80
129
  @end
@@ -216,7 +216,7 @@ export class CollapsiblePagerView extends React.PureComponent {
216
216
  ...nativeProps
217
217
  } = this.props;
218
218
  const pages = this.pages();
219
- const supportsTopScrollEdge = Platform.OS === "ios" && Number(Platform.Version) >= 26;
219
+ const supportsTopScrollEdge = Platform.OS === "ios" && parseInt(String(Platform.Version), 10) >= 26;
220
220
  const hardScrollEdge = supportsTopScrollEdge && topScrollEdgeEffect === "hard";
221
221
  const hasTopOverlay = hardScrollEdge && topOverlay != null;
222
222
  const pageKeys = pages.map(pageKey);
@@ -59,7 +59,7 @@ export const NativeScroller = /*#__PURE__*/React.forwardRef(function NativeScrol
59
59
  height: 0
60
60
  });
61
61
  const [topOverlayHeight, setTopOverlayHeight] = React.useState(0);
62
- const hasTopOverlay = Platform.OS === "ios" && Number(Platform.Version) >= 26 && topScrollEdgeEffect === "hard" && topOverlay != null;
62
+ const hasTopOverlay = Platform.OS === "ios" && parseInt(String(Platform.Version), 10) >= 26 && topScrollEdgeEffect === "hard" && topOverlay != null;
63
63
  const [refreshEpoch, requestRefreshSync] = React.useReducer(value => value + 1, 0);
64
64
  const contentSizeRef = React.useRef(contentSize);
65
65
  const scrolledSinceGrant = React.useRef(false);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/react-native-pager-view",
3
- "version": "3.0.179-alpha.2026101501",
3
+ "version": "3.0.179-alpha.2026101503",
4
4
  "description": "React Native wrapper for Android and iOS ViewPager",
5
5
  "source": "./src/index.tsx",
6
6
  "main": "./lib/module/index.js",
@@ -72,7 +72,7 @@
72
72
  "typescript": "^5.9.2"
73
73
  },
74
74
  "peerDependencies": {
75
- "@onekeyfe/react-native-native-logger": "3.0.179-alpha.2026101501",
75
+ "@onekeyfe/react-native-native-logger": "3.0.179-alpha.2026101503",
76
76
  "react": "*",
77
77
  "react-native": "*"
78
78
  },
@@ -492,7 +492,7 @@ export class CollapsiblePagerView extends React.PureComponent<
492
492
  } = this.props;
493
493
  const pages = this.pages();
494
494
  const supportsTopScrollEdge =
495
- Platform.OS === "ios" && Number(Platform.Version) >= 26;
495
+ Platform.OS === "ios" && parseInt(String(Platform.Version), 10) >= 26;
496
496
  const hardScrollEdge = supportsTopScrollEdge && topScrollEdgeEffect === "hard";
497
497
  const hasTopOverlay = hardScrollEdge && topOverlay != null;
498
498
  const pageKeys = pages.map(pageKey);
@@ -117,7 +117,7 @@ export const NativeScroller = React.forwardRef<
117
117
  const [contentSize, setContentSize] = React.useState({ width: 0, height: 0 });
118
118
  const [topOverlayHeight, setTopOverlayHeight] = React.useState(0);
119
119
  const hasTopOverlay =
120
- Platform.OS === "ios" && Number(Platform.Version) >= 26 &&
120
+ Platform.OS === "ios" && parseInt(String(Platform.Version), 10) >= 26 &&
121
121
  topScrollEdgeEffect === "hard" && topOverlay != null;
122
122
  const [refreshEpoch, requestRefreshSync] = React.useReducer(
123
123
  (value: number) => value + 1,