@onekeyfe/react-native-pager-view 3.0.179-alpha.302 → 3.0.179-alpha.303

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.
@@ -206,6 +206,16 @@ class CollapsiblePagerViewManager : ViewGroupManager<CollapsiblePagerHost>(),
206
206
  view?.stickyHeaderHeightPx = PixelUtil.toPixelFromDIP(value.toDouble()).roundToInt()
207
207
  }
208
208
 
209
+ // The scroll-edge effect and external overlay are UIKit-only.
210
+ @ReactProp(name = "topScrollEdgeHard", defaultBoolean = false)
211
+ override fun setTopScrollEdgeHard(view: CollapsiblePagerHost?, value: Boolean) = Unit
212
+ @ReactProp(name = "topOverlayColorScheme")
213
+ override fun setTopOverlayColorScheme(view: CollapsiblePagerHost?, value: String?) = Unit
214
+ @ReactProp(name = "topOverlayHeight", defaultDouble = 0.0)
215
+ override fun setTopOverlayHeight(view: CollapsiblePagerHost?, value: Double) = Unit
216
+ @ReactProp(name = "externalTopOverlayTag", defaultInt = 0)
217
+ override fun setExternalTopOverlayTag(view: CollapsiblePagerHost?, value: Int) = Unit
218
+
209
219
  @ReactProp(name = "pageKeys")
210
220
  override fun setPageKeys(view: CollapsiblePagerHost?, value: String?) {
211
221
  view ?: return
@@ -49,6 +49,10 @@ class NativeScrollerViewManager : ViewGroupManager<NativeScrollerView>(),
49
49
  override fun setContentWidth(view: NativeScrollerView, value: Double) = view.setContentSize(width = view.dip(value))
50
50
  @ReactProp(name = "contentHeight")
51
51
  override fun setContentHeight(view: NativeScrollerView, value: Double) = view.setContentSize(height = view.dip(value))
52
+ @ReactProp(name = "topScrollEdgeHard", defaultBoolean = false)
53
+ override fun setTopScrollEdgeHard(view: NativeScrollerView, value: Boolean) = Unit
54
+ @ReactProp(name = "topOverlayHeight", defaultDouble = 0.0)
55
+ override fun setTopOverlayHeight(view: NativeScrollerView, value: Double) = Unit
52
56
  @ReactProp(name = "scrollEnabled", defaultBoolean = true)
53
57
  override fun setScrollEnabled(view: NativeScrollerView, value: Boolean) = view.setScrollEnabled(value)
54
58
  @ReactProp(name = "nestedScrollEnabled", defaultBoolean = true)
package/docs/SPEC.md CHANGED
@@ -1,7 +1,73 @@
1
1
  # PagerView native scrolling contract
2
2
 
3
3
  Existing PagerView and CollapsiblePagerView APIs are documented in README.md.
4
- The sections below define native coordination boundaries without new React props.
4
+ The sections below define native coordination boundaries and the optional
5
+ scroll-edge props.
6
+
7
+ ## iOS 26 top scroll edge overlay
8
+
9
+ `CollapsiblePagerView` and standalone `NativeScroller` accept the optional
10
+ `topScrollEdgeEffect="hard"` with a fixed `topOverlay` React child. Both are
11
+ disabled by default. On iOS 26 or newer, a local overlay remains fixed at the
12
+ top of the viewport while the owned vertical `UIScrollView` can draw behind it.
13
+ The component measures the overlay's Fabric layout height and owns the
14
+ corresponding top content inset. It binds UIKit's
15
+ `UIScrollEdgeElementContainerInteraction` to that exact scroll view and selects
16
+ the hard top edge style. A pager owns the effect and inset for its current page;
17
+ its nested NativeList or NativeScroller must not opt into another top overlay.
18
+ Invisible, noninteractive native labels let UIKit recognize the React-drawn
19
+ overlay and sticky header as scroll-edge elements. The pager does not add an
20
+ auxiliary full-area glass or opaque material. It clips scrolling assets above
21
+ the fixed overlay boundary; during horizontal transitions it clips its owned
22
+ visible page hosts below the current sticky boundary so text cannot pass in
23
+ front of the fixed controls. Masked assets must not intercept their hit targets.
24
+
25
+ For an iOS 26 pager whose fixed header is rendered by a sibling in the same
26
+ React surface, `externalTopOverlayTag` may identify that header's native view.
27
+ The pager weakly observes its geometry in the same window, retaining its own
28
+ noninteractive native proxy for UIKit recognition without reparenting or
29
+ modifying the React header. The measured external header bottom supplies the
30
+ top inset and sticky anchor. A local `topOverlay` takes precedence. The tag
31
+ alone never enables the effect: `topScrollEdgeEffect="hard"` controls the
32
+ interaction, while valid external geometry can reserve the top inset before
33
+ the effect is enabled. Before the tag and height are ready, the caller keeps
34
+ its existing layout; an unresolved native tag has zero external height. An
35
+ outer PagerView transition
36
+ releases the current edge interaction before moving its shared headers and
37
+ applying visible-page masks; completion or cancellation reattaches the actual
38
+ settled owner. An inactive inner pager retains the external header inset while
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.
42
+
43
+ `topOverlayColorScheme` is optional (`"light" | "dark"`) and coordinates the
44
+ fixed overlay's effective appearance with React theme commits. It does not
45
+ change the requested style, scroll owner, content inset or page identity.
46
+ When a smooth shared header reaches the overlay boundary, the existing sticky
47
+ React and native tab views move together into a view pinned to the active
48
+ scroll view. Their identities, scroll-view gesture ancestry and hit targets
49
+ remain intact; the collapsible header stays in the scrolling header host.
50
+ Without a local or external overlay, `topScrollEdgeEffect="hard"` may protect
51
+ only the genuinely pinned sticky header; it must not consume a page as a
52
+ synthetic overlay slot or change the collapsible banner distance.
53
+ Changing pages, replacing the active list or recycling returns those views to
54
+ the shared host before their old scroll-edge interaction is released.
55
+ The measured overlay height is excluded from the collapsible header distance:
56
+ `header` remains collapsible and `stickyHeader` pins immediately below the
57
+ overlay. Selection, cancellation, reuse and disposal rebind or release the
58
+ interaction and restore any prior scroll-edge style. Native scroll/refresh
59
+ coordination continues on the main thread without per-frame JavaScript work.
60
+
61
+ On iOS before 26, the external tag is not forwarded to native. On iOS before
62
+ 26, Android and Web the new props have no scroll-edge effect.
63
+ The caller retains its existing layout on those platforms. Android generated
64
+ view managers accept the optional props as no-op setters without changing
65
+ their scroll or gesture behavior. Without a fixed overlay or pinned sticky
66
+ header, the current scroll/inset behavior is unchanged. A valid external tag
67
+ can reserve its measured geometry even while `topScrollEdgeEffect` is off.
68
+ Acceptance requires real iOS 26 scrolling, partial collapse, short/empty page,
69
+ refresh, page transition/cancellation, dynamic tabs and light/dark checks;
70
+ source and build checks alone do not establish visual correctness.
5
71
 
6
72
  ## Smooth shared-header and per-page body memory
7
73
 
@@ -283,6 +349,16 @@ scroller. Header forwarding can recover to the vertical list when vertical
283
349
  movement becomes dominant. An inner horizontal viewport that can consume a
284
350
  confirmed horizontal drag MUST have priority over the Home page pager.
285
351
 
352
+ On iOS, when a nested CollapsiblePagerView has an actual outer PagerView
353
+ ancestor, its existing outer-pager protector also covers touches that begin in
354
+ the inner page body. It may protect only a horizontal direction with another
355
+ inner page available. At the first or last inner page, an outward drag remains
356
+ available to the outer pager; vertical drags and ordinary taps are unchanged.
357
+ This body protection must not activate merely because nested scrolling is
358
+ enabled, since Home also enables nested scrolling without an outer PagerView.
359
+ The direction guard and its 32-point threshold remain unchanged. Android keeps
360
+ its existing nested gesture implementation.
361
+
286
362
  This intent confirmation MUST NOT add a second lazy-mount progress threshold.
287
363
  Once native horizontal dragging begins, the first nonzero page progress MUST
288
364
  prepare the target page on both platforms, as specified below.