@onekeyfe/react-native-pager-view 6.7.0-alpha.382 → 6.7.0-alpha.383

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
@@ -917,6 +917,19 @@ fallback debounce, including replacement-state restoration. Other collection
917
917
  fallbacks keep that safety delay. Caller insets and retained logical offsets
918
918
  remain governed by the existing restoration policy.
919
919
 
920
+ A verified, mounted NativeList with usable vertical bounds is a scroll-owner
921
+ boundary. Its React container slots may contain independent Fabric scroll views,
922
+ NativeScroller views or nested pagers; those descendants MUST NOT replace that
923
+ NativeList as the enclosing page's owner or receive its shared header. Candidate
924
+ priority between sibling page owners remains unchanged, including an explicit
925
+ NativeScroller sibling. Pages without an enclosing NativeList retain nested-pager
926
+ active-owner delegation. This boundary does not change scroll offsets, insets,
927
+ shared-header collapse or per-page body memory.
928
+
929
+ Status: implemented and verified by production-native UIKit regressions on
930
+ iOS 27.1 for footer insertion, explicit-sibling priority and nested-pager
931
+ delegation. Full App and physical-device visual acceptance are reported separately.
932
+
920
933
  When the active scroll owner is removed before its replacement becomes usable,
921
934
  the pager MUST retain bounded recovery (at most 12 retries per recovery round,
922
935
  spaced 100 ms apart). Clearing the completed mount's reattachment flag MUST NOT
@@ -3691,6 +3691,8 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
3691
3691
  resolution.tier = isMountedNativeList
3692
3692
  ? RNCScrollCandidateTierVerifiedNativeList
3693
3693
  : RNCScrollCandidateTierGenericFallback;
3694
+ // React slots inside a verified list may own independent scroll views.
3695
+ if (isMountedNativeList) return resolution;
3694
3696
  }
3695
3697
  }
3696
3698
  }
@@ -1,6 +1,7 @@
1
1
  #import <XCTest/XCTest.h>
2
2
  #import "RNCCollapsiblePagerViewComponentView.h"
3
3
  #import "RNCNativeScrollerComponentView.h"
4
+ #import <React/RCTScrollViewComponentView.h>
4
5
  #import <react/renderer/components/pagerview/Props.h>
5
6
  #import <react/renderer/mounting/MountingTransaction.h>
6
7
 
@@ -13,6 +14,7 @@ using namespace facebook::react;
13
14
  withSurfaceTelemetry:(const SurfaceTelemetry &)telemetry;
14
15
  - (UIScrollView *)findExplicitNativeScrollerInView:(UIView *)view;
15
16
  - (UIScrollView *)findVerticalScrollViewInView:(UIView *)view;
17
+ - (UIScrollView *)verticalScrollViewForPageAtIndex:(NSInteger)pageIndex;
16
18
  - (void)attachScrollObserverForCurrentPage;
17
19
  - (void)attachScrollObserverForCurrentPageAfterTransition:(BOOL)selectionSettled;
18
20
  - (void)detachScrollObserver;
@@ -789,4 +791,85 @@ using namespace facebook::react;
789
791
  XCTAssertNil([pager valueForKey:@"releasedPageScrollStates"][@"page-0"]);
790
792
  }
791
793
 
794
+ - (RCTViewComponentView *)addNativeListToPager:(RNCCollapsiblePagerViewComponentView *)pager
795
+ {
796
+ Class nativeListClass = NSClassFromString(@"HybridNativeListComponent");
797
+ XCTAssertNotNil(nativeListClass, @"The real NativeList test dependency must be linked");
798
+ RCTViewComponentView *component = [[nativeListClass alloc] init];
799
+ component.tag = 92001;
800
+ component.frame = CGRectMake(0, 0, 320, 600);
801
+ component.contentView.frame = component.bounds;
802
+ UIViewController *page = [pager valueForKey:@"pageControllers"][0];
803
+ [page.view addSubview:component];
804
+ [component.contentView layoutIfNeeded];
805
+ return component;
806
+ }
807
+
808
+ - (void)testNativeListFooterScrollViewCannotReplacePageOwner
809
+ {
810
+ RNCCollapsiblePagerViewComponentView *pager = [self pagerWithPageCount:1];
811
+ RCTViewComponentView *component = [self addNativeListToPager:pager];
812
+ UICollectionView *list = nil;
813
+ for (UIView *child in component.contentView.subviews) {
814
+ if ([child isKindOfClass:UICollectionView.class]) {
815
+ list = (UICollectionView *)child;
816
+ break;
817
+ }
818
+ }
819
+ XCTAssertTrue([list isKindOfClass:UICollectionView.class]);
820
+ XCTAssertGreaterThan(CGRectGetWidth(list.bounds), 0);
821
+ XCTAssertGreaterThan(CGRectGetHeight(list.bounds), 0);
822
+ XCTAssertEqual(list.delegate, (id)component.contentView);
823
+ XCTAssertTrue([list isDescendantOfView:component.contentView]);
824
+ [pager attachScrollObserverForCurrentPage];
825
+ UIView *header = [pager valueForKey:@"sharedHeaderHostView"];
826
+ XCTAssertNotNil(header);
827
+ XCTAssertEqual([pager valueForKey:@"observedScrollView"], list);
828
+ XCTAssertEqual(header.superview, list);
829
+ CGFloat inset = list.contentInset.top;
830
+ CGFloat offset = list.contentOffset.y;
831
+
832
+ RCTScrollViewComponentView *footerList = [RCTScrollViewComponentView new];
833
+ footerList.tag = 92002;
834
+ footerList.frame = CGRectMake(0, 0, 320, 400);
835
+ footerList.scrollView.frame = footerList.bounds;
836
+ footerList.scrollView.contentSize = CGSizeMake(320, 1000);
837
+ footerList.scrollView.alwaysBounceHorizontal = NO;
838
+ for (NSInteger index = 0; index < 6; index++) {
839
+ UIView *slot = index == 2 ? footerList : [UIView new];
840
+ [component mountChildComponentView:(id)slot index:index];
841
+ }
842
+ XCTAssertTrue([footerList isDescendantOfView:list]);
843
+ XCTAssertEqual([pager verticalScrollViewForPageAtIndex:0], list);
844
+ ShadowView inserted;
845
+ inserted.tag = (Tag)footerList.tag;
846
+ MountingTransaction transaction(1, 2,
847
+ {ShadowViewMutation::InsertMutation((Tag)component.tag, inserted, 2)}, {});
848
+ SurfaceTelemetry telemetry;
849
+ [pager mountingTransactionDidMount:transaction withSurfaceTelemetry:telemetry];
850
+ XCTAssertEqual([pager valueForKey:@"observedScrollView"], list);
851
+ XCTAssertEqual(header.superview, list);
852
+ XCTAssertEqualWithAccuracy(list.contentInset.top, inset, 0.01);
853
+ XCTAssertEqualWithAccuracy(list.contentOffset.y, offset, 0.01);
854
+ XCTAssertEqualWithAccuracy(footerList.scrollView.contentInset.top, 0, 0.01);
855
+ }
856
+
857
+ - (void)testExplicitScrollerSiblingStillPrecedesNativeList
858
+ {
859
+ RNCCollapsiblePagerViewComponentView *pager = [self pagerWithPageCount:1];
860
+ [self addNativeListToPager:pager];
861
+ RNCNativeScrollerComponentView *scroller = [self addScrollerToPager:pager atIndex:0];
862
+ XCTAssertEqual([pager verticalScrollViewForPageAtIndex:0], scroller.scrollView);
863
+ }
864
+
865
+ - (void)testPageWithoutNativeListStillDelegatesToNestedPager
866
+ {
867
+ RNCCollapsiblePagerViewComponentView *outer = [self pagerWithPageCount:1];
868
+ RNCCollapsiblePagerViewComponentView *inner = [self pagerWithPageCount:1];
869
+ RNCNativeScrollerComponentView *scroller = [self addScrollerToPager:inner atIndex:0];
870
+ UIViewController *page = [outer valueForKey:@"pageControllers"][0];
871
+ [page.view addSubview:inner];
872
+ XCTAssertEqual([outer verticalScrollViewForPageAtIndex:0], scroller.scrollView);
873
+ }
874
+
792
875
  @end
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/react-native-pager-view",
3
- "version": "6.7.0-alpha.382",
3
+ "version": "6.7.0-alpha.383",
4
4
  "description": "React Native wrapper for Android and iOS ViewPager",
5
5
  "source": "./src/index.tsx",
6
6
  "main": "./lib/module/index.js",
@@ -73,7 +73,7 @@
73
73
  "typescript": "^5.9.2"
74
74
  },
75
75
  "peerDependencies": {
76
- "@onekeyfe/react-native-native-logger": "6.7.0-alpha.382",
76
+ "@onekeyfe/react-native-native-logger": "6.7.0-alpha.383",
77
77
  "react": "*",
78
78
  "react-native": "*"
79
79
  },
@@ -19,6 +19,7 @@ Pod::Spec.new do |s|
19
19
 
20
20
  s.test_spec "Tests" do |test_spec|
21
21
  test_spec.source_files = "ios/tests/**/*.{m,mm}"
22
+ test_spec.dependency "react-native-native-list"
22
23
  end
23
24
 
24
25
  install_modules_dependencies(s)