@onekeyfe/react-native-pager-view 3.0.177 → 3.0.179-alpha.20261015

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,71 @@
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.
40
+
41
+ `topOverlayColorScheme` is optional (`"light" | "dark"`) and coordinates the
42
+ fixed overlay's effective appearance with React theme commits. It does not
43
+ change the requested style, scroll owner, content inset or page identity.
44
+ When a smooth shared header reaches the overlay boundary, the existing sticky
45
+ React and native tab views move together into a view pinned to the active
46
+ scroll view. Their identities, scroll-view gesture ancestry and hit targets
47
+ remain intact; the collapsible header stays in the scrolling header host.
48
+ Without a local or external overlay, `topScrollEdgeEffect="hard"` may protect
49
+ only the genuinely pinned sticky header; it must not consume a page as a
50
+ synthetic overlay slot or change the collapsible banner distance.
51
+ Changing pages, replacing the active list or recycling returns those views to
52
+ the shared host before their old scroll-edge interaction is released.
53
+ The measured overlay height is excluded from the collapsible header distance:
54
+ `header` remains collapsible and `stickyHeader` pins immediately below the
55
+ overlay. Selection, cancellation, reuse and disposal rebind or release the
56
+ interaction and restore any prior scroll-edge style. Native scroll/refresh
57
+ coordination continues on the main thread without per-frame JavaScript work.
58
+
59
+ On iOS before 26, the external tag is not forwarded to native. On iOS before
60
+ 26, Android and Web the new props have no scroll-edge effect.
61
+ The caller retains its existing layout on those platforms. Android generated
62
+ view managers accept the optional props as no-op setters without changing
63
+ their scroll or gesture behavior. Without a fixed overlay or pinned sticky
64
+ header, the current scroll/inset behavior is unchanged. A valid external tag
65
+ can reserve its measured geometry even while `topScrollEdgeEffect` is off.
66
+ Acceptance requires real iOS 26 scrolling, partial collapse, short/empty page,
67
+ refresh, page transition/cancellation, dynamic tabs and light/dark checks;
68
+ source and build checks alone do not establish visual correctness.
5
69
 
6
70
  ## Smooth shared-header and per-page body memory
7
71
 
@@ -283,6 +347,16 @@ scroller. Header forwarding can recover to the vertical list when vertical
283
347
  movement becomes dominant. An inner horizontal viewport that can consume a
284
348
  confirmed horizontal drag MUST have priority over the Home page pager.
285
349
 
350
+ On iOS, when a nested CollapsiblePagerView has an actual outer PagerView
351
+ ancestor, its existing outer-pager protector also covers touches that begin in
352
+ the inner page body. It may protect only a horizontal direction with another
353
+ inner page available. At the first or last inner page, an outward drag remains
354
+ available to the outer pager; vertical drags and ordinary taps are unchanged.
355
+ This body protection must not activate merely because nested scrolling is
356
+ enabled, since Home also enables nested scrolling without an outer PagerView.
357
+ The direction guard and its 32-point threshold remain unchanged. Android keeps
358
+ its existing nested gesture implementation.
359
+
286
360
  This intent confirmation MUST NOT add a second lazy-mount progress threshold.
287
361
  Once native horizontal dragging begins, the first nonzero page progress MUST
288
362
  prepare the target page on both platforms, as specified below.