@onekeyfe/react-native-pager-view 6.7.0-alpha.327 → 6.7.0-alpha.335
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/README.md +9 -0
- package/docs/SPEC.md +82 -8
- package/ios/RNCCollapsiblePagerViewComponentView.mm +257 -2
- package/ios/RNCNativeScrollerComponentView.mm +24 -0
- package/ios/tests/RNCCollapsiblePagerFirstFrameTests.mm +124 -0
- package/ios/tests/RNCCollapsiblePagerHitTestTests.mm +160 -0
- package/ios/tests/RNCCollapsiblePagerRefreshControlTests.mm +50 -0
- package/lib/module/CollapsiblePagerView.js +12 -3
- package/lib/module/CollapsiblePagerView.web.js +428 -37
- package/lib/module/NativeScroller.web.js +16 -3
- package/lib/module/WebCollapsiblePagerPage.js +182 -0
- package/lib/module/index.js +2 -0
- package/lib/module/index.native.js +9 -0
- package/lib/module/index.web.js +2 -0
- package/lib/typescript/src/CollapsiblePagerView.d.ts +4 -2
- package/lib/typescript/src/CollapsiblePagerView.web.d.ts +64 -3
- package/lib/typescript/src/WebCollapsiblePagerPage.d.ts +42 -0
- package/lib/typescript/src/index.d.ts +4 -0
- package/lib/typescript/src/index.native.d.ts +13 -0
- package/lib/typescript/src/index.web.d.ts +4 -0
- package/package.json +6 -4
- package/src/CollapsiblePagerView.tsx +31 -4
- package/src/CollapsiblePagerView.web.tsx +638 -49
- package/src/NativeScroller.web.tsx +24 -2
- package/src/WebCollapsiblePagerPage.tsx +258 -0
- package/src/index.native.tsx +30 -0
- package/src/index.tsx +4 -0
- package/src/index.web.tsx +4 -0
|
@@ -6,20 +6,33 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
6
6
|
export const NativeScroller = /*#__PURE__*/React.forwardRef(function NativeScroller(inputProps, ref) {
|
|
7
7
|
const {
|
|
8
8
|
dataSet,
|
|
9
|
-
pagerScrollKey
|
|
9
|
+
pagerScrollKey,
|
|
10
10
|
topOverlay: _topOverlay,
|
|
11
11
|
topScrollEdgeEffect: _topScrollEdgeEffect,
|
|
12
12
|
...props
|
|
13
13
|
} = inputProps;
|
|
14
|
+
const scrollRef = React.useRef(null);
|
|
15
|
+
const setRef = React.useCallback(node => {
|
|
16
|
+
scrollRef.current = node;
|
|
17
|
+
if (typeof ref === "function") ref(node);else if (ref) ref.current = node;
|
|
18
|
+
}, [ref]);
|
|
19
|
+
React.useLayoutEffect(() => {
|
|
20
|
+
const element = scrollRef.current?.getScrollableNode();
|
|
21
|
+
const EventConstructor = element?.ownerDocument?.defaultView?.Event;
|
|
22
|
+
if (EventConstructor) element.dispatchEvent(new EventConstructor("ok-collapsible-pager-scroll-key-changed", {
|
|
23
|
+
bubbles: true
|
|
24
|
+
}));
|
|
25
|
+
}, [pagerScrollKey]);
|
|
14
26
|
const webDataProps = {
|
|
15
27
|
dataSet: {
|
|
16
28
|
...dataSet,
|
|
17
|
-
collapsiblePagerScroll: "true"
|
|
29
|
+
collapsiblePagerScroll: "true",
|
|
30
|
+
collapsiblePagerScrollKey: pagerScrollKey ?? ""
|
|
18
31
|
}
|
|
19
32
|
};
|
|
20
33
|
return /*#__PURE__*/_jsx(ScrollView, {
|
|
21
34
|
...props,
|
|
22
|
-
ref:
|
|
35
|
+
ref: setRef,
|
|
23
36
|
...webDataProps
|
|
24
37
|
});
|
|
25
38
|
});
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
+
const PageContext = /*#__PURE__*/React.createContext(null);
|
|
6
|
+
export function useWebCollapsiblePagerPage() {
|
|
7
|
+
return React.useContext(PageContext);
|
|
8
|
+
}
|
|
9
|
+
export function WebCollapsiblePagerPage({
|
|
10
|
+
children,
|
|
11
|
+
pageKey,
|
|
12
|
+
isFocused,
|
|
13
|
+
isRouteActive,
|
|
14
|
+
headerHeight,
|
|
15
|
+
stickyHeaderHeight,
|
|
16
|
+
onBridge,
|
|
17
|
+
onGeometryChange,
|
|
18
|
+
onScroll,
|
|
19
|
+
onUserInput
|
|
20
|
+
}) {
|
|
21
|
+
const [owner, setOwner] = React.useState(null);
|
|
22
|
+
const ownerRef = React.useRef(null);
|
|
23
|
+
const [registered, setRegistered] = React.useState(null);
|
|
24
|
+
const registeredRef = React.useRef(registered);
|
|
25
|
+
const observerRef = React.useRef(null);
|
|
26
|
+
const observedContentRef = React.useRef(null);
|
|
27
|
+
const frameRef = React.useRef(null);
|
|
28
|
+
const disposedRef = React.useRef(false);
|
|
29
|
+
const [pendingRouteScrollTop, setPendingRouteScrollTop] = React.useState(null);
|
|
30
|
+
const [metrics, setMetrics] = React.useState({
|
|
31
|
+
width: 0,
|
|
32
|
+
height: 0,
|
|
33
|
+
scrollTop: 0
|
|
34
|
+
});
|
|
35
|
+
const inputsRef = React.useRef({
|
|
36
|
+
pageKey,
|
|
37
|
+
headerHeight,
|
|
38
|
+
stickyHeaderHeight,
|
|
39
|
+
onGeometryChange,
|
|
40
|
+
onScroll,
|
|
41
|
+
onUserInput
|
|
42
|
+
});
|
|
43
|
+
inputsRef.current = {
|
|
44
|
+
pageKey,
|
|
45
|
+
headerHeight,
|
|
46
|
+
stickyHeaderHeight,
|
|
47
|
+
onGeometryChange,
|
|
48
|
+
onScroll,
|
|
49
|
+
onUserInput
|
|
50
|
+
};
|
|
51
|
+
const measure = React.useCallback(() => {
|
|
52
|
+
frameRef.current = null;
|
|
53
|
+
if (disposedRef.current) return;
|
|
54
|
+
const current = ownerRef.current;
|
|
55
|
+
if (!current?.isConnected) return;
|
|
56
|
+
const ownerRect = current.getBoundingClientRect();
|
|
57
|
+
const candidate = registeredRef.current?.element;
|
|
58
|
+
const content = candidate?.isConnected && current.contains(candidate) ? candidate : null;
|
|
59
|
+
const contentRect = (content ?? current.firstElementChild)?.getBoundingClientRect();
|
|
60
|
+
const inputs = inputsRef.current;
|
|
61
|
+
const pinnedBottom = ownerRect.top + Math.max(0, inputs.headerHeight - current.scrollTop) + inputs.stickyHeaderHeight;
|
|
62
|
+
const visibleTop = Math.max(ownerRect.top, pinnedBottom, contentRect?.top ?? 0);
|
|
63
|
+
const next = {
|
|
64
|
+
width: current.clientWidth,
|
|
65
|
+
height: Math.max(0, ownerRect.bottom - visibleTop),
|
|
66
|
+
scrollTop: Math.max(0, pinnedBottom - (contentRect?.top ?? pinnedBottom))
|
|
67
|
+
};
|
|
68
|
+
setMetrics(previous => previous.width === next.width && previous.height === next.height && previous.scrollTop === next.scrollTop ? previous : next);
|
|
69
|
+
inputs.onGeometryChange(inputs.pageKey);
|
|
70
|
+
}, []);
|
|
71
|
+
const requestMeasure = React.useCallback(() => {
|
|
72
|
+
if (!disposedRef.current && frameRef.current === null) frameRef.current = requestAnimationFrame(measure);
|
|
73
|
+
}, [measure]);
|
|
74
|
+
const syncContentObservation = React.useCallback(() => {
|
|
75
|
+
const observer = observerRef.current;
|
|
76
|
+
const current = ownerRef.current;
|
|
77
|
+
if (!observer || !current) return;
|
|
78
|
+
const candidate = registeredRef.current?.element;
|
|
79
|
+
const content = candidate?.isConnected && current.contains(candidate) ? candidate : current.firstElementChild;
|
|
80
|
+
const next = typeof HTMLElement !== "undefined" && content instanceof HTMLElement ? content : null;
|
|
81
|
+
if (observedContentRef.current === next) return;
|
|
82
|
+
if (observedContentRef.current) observer.unobserve(observedContentRef.current);
|
|
83
|
+
observedContentRef.current = next;
|
|
84
|
+
if (next) observer.observe(next);
|
|
85
|
+
}, []);
|
|
86
|
+
const registerContent = React.useCallback((element, height) => {
|
|
87
|
+
const entry = {
|
|
88
|
+
element,
|
|
89
|
+
height: height !== undefined && Number.isFinite(height) && height >= 0 ? height : undefined
|
|
90
|
+
};
|
|
91
|
+
registeredRef.current = entry;
|
|
92
|
+
setRegistered(entry);
|
|
93
|
+
syncContentObservation();
|
|
94
|
+
requestMeasure();
|
|
95
|
+
return () => {
|
|
96
|
+
if (registeredRef.current !== entry) return;
|
|
97
|
+
registeredRef.current = null;
|
|
98
|
+
setRegistered(null);
|
|
99
|
+
syncContentObservation();
|
|
100
|
+
requestMeasure();
|
|
101
|
+
};
|
|
102
|
+
}, [requestMeasure, syncContentObservation]);
|
|
103
|
+
const bridge = React.useMemo(() => ({
|
|
104
|
+
setOwner: next => {
|
|
105
|
+
if (ownerRef.current === next) return;
|
|
106
|
+
ownerRef.current = next;
|
|
107
|
+
setOwner(next);
|
|
108
|
+
requestMeasure();
|
|
109
|
+
},
|
|
110
|
+
requestMeasure,
|
|
111
|
+
setPendingRouteScrollTop
|
|
112
|
+
}), [requestMeasure]);
|
|
113
|
+
React.useLayoutEffect(() => {
|
|
114
|
+
disposedRef.current = false;
|
|
115
|
+
return () => {
|
|
116
|
+
disposedRef.current = true;
|
|
117
|
+
if (frameRef.current !== null) cancelAnimationFrame(frameRef.current);
|
|
118
|
+
frameRef.current = null;
|
|
119
|
+
};
|
|
120
|
+
}, []);
|
|
121
|
+
React.useLayoutEffect(() => {
|
|
122
|
+
onBridge(pageKey, bridge);
|
|
123
|
+
return () => onBridge(pageKey, null);
|
|
124
|
+
}, [bridge, onBridge, pageKey]);
|
|
125
|
+
React.useLayoutEffect(() => {
|
|
126
|
+
if (!owner) return undefined;
|
|
127
|
+
const observer = new ResizeObserver(requestMeasure);
|
|
128
|
+
observerRef.current = observer;
|
|
129
|
+
observer.observe(owner);
|
|
130
|
+
syncContentObservation();
|
|
131
|
+
const handleScroll = () => {
|
|
132
|
+
if (ownerRef.current !== owner) return;
|
|
133
|
+
const inputs = inputsRef.current;
|
|
134
|
+
inputs.onScroll(inputs.pageKey, owner.scrollTop);
|
|
135
|
+
requestMeasure();
|
|
136
|
+
};
|
|
137
|
+
const handleKey = event => {
|
|
138
|
+
if (["ArrowUp", "ArrowDown", "PageUp", "PageDown", "Home", "End", " "].includes(event.key)) inputsRef.current.onUserInput(inputsRef.current.pageKey);
|
|
139
|
+
};
|
|
140
|
+
const handleUserInput = () => inputsRef.current.onUserInput(inputsRef.current.pageKey);
|
|
141
|
+
owner.addEventListener("scroll", handleScroll, {
|
|
142
|
+
passive: true
|
|
143
|
+
});
|
|
144
|
+
owner.addEventListener("touchstart", handleUserInput, {
|
|
145
|
+
passive: true
|
|
146
|
+
});
|
|
147
|
+
owner.addEventListener("pointerdown", handleUserInput);
|
|
148
|
+
owner.addEventListener("keydown", handleKey);
|
|
149
|
+
owner.addEventListener("ok-collapsible-pager-user-scroll", handleUserInput);
|
|
150
|
+
owner.addEventListener("ok-collapsible-pager-insets-changed", requestMeasure);
|
|
151
|
+
requestMeasure();
|
|
152
|
+
return () => {
|
|
153
|
+
observer.disconnect();
|
|
154
|
+
observerRef.current = null;
|
|
155
|
+
observedContentRef.current = null;
|
|
156
|
+
owner.removeEventListener("scroll", handleScroll);
|
|
157
|
+
owner.removeEventListener("touchstart", handleUserInput);
|
|
158
|
+
owner.removeEventListener("pointerdown", handleUserInput);
|
|
159
|
+
owner.removeEventListener("keydown", handleKey);
|
|
160
|
+
owner.removeEventListener("ok-collapsible-pager-user-scroll", handleUserInput);
|
|
161
|
+
owner.removeEventListener("ok-collapsible-pager-insets-changed", requestMeasure);
|
|
162
|
+
if (frameRef.current !== null) cancelAnimationFrame(frameRef.current);
|
|
163
|
+
frameRef.current = null;
|
|
164
|
+
};
|
|
165
|
+
}, [owner, requestMeasure, syncContentObservation]);
|
|
166
|
+
React.useLayoutEffect(requestMeasure, [isFocused, isRouteActive, headerHeight, stickyHeaderHeight, requestMeasure]);
|
|
167
|
+
const value = React.useMemo(() => ({
|
|
168
|
+
isFocused,
|
|
169
|
+
isRouteActive,
|
|
170
|
+
owner,
|
|
171
|
+
content: registered?.element.isConnected && owner?.contains(registered.element) ? registered.element : null,
|
|
172
|
+
contentHeight: registered?.height,
|
|
173
|
+
...metrics,
|
|
174
|
+
pendingRouteScrollTop,
|
|
175
|
+
registerContent
|
|
176
|
+
}), [isFocused, isRouteActive, owner, registered, metrics, pendingRouteScrollTop, registerContent]);
|
|
177
|
+
return /*#__PURE__*/_jsx(PageContext.Provider, {
|
|
178
|
+
value: value,
|
|
179
|
+
children: children
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=WebCollapsiblePagerPage.js.map
|
package/lib/module/index.js
CHANGED
|
@@ -5,5 +5,7 @@ export default PagerView;
|
|
|
5
5
|
export * from "./usePagerView.js";
|
|
6
6
|
export * from './CollapsiblePagerView';
|
|
7
7
|
export * from './NativeScroller';
|
|
8
|
+
export { CollapsiblePagerView as WebCollapsiblePagerView } from "./CollapsiblePagerView.web.js";
|
|
9
|
+
export { useWebCollapsiblePagerPage } from "./WebCollapsiblePagerPage.js";
|
|
8
10
|
export { ScrollEdgeEffect } from "./ScrollEdgeEffect.js";
|
|
9
11
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { PagerView } from "./PagerView";
|
|
4
|
+
export default PagerView;
|
|
5
|
+
export * from "./usePagerView.js";
|
|
6
|
+
export * from "./CollapsiblePagerView";
|
|
7
|
+
export * from "./NativeScroller";
|
|
8
|
+
export { ScrollEdgeEffect } from "./ScrollEdgeEffect.js";
|
|
9
|
+
//# sourceMappingURL=index.native.js.map
|
package/lib/module/index.web.js
CHANGED
|
@@ -4,5 +4,7 @@ export { PagerView as default, PagerView } from "./PagerView.web.js";
|
|
|
4
4
|
export * from "./usePagerView.js";
|
|
5
5
|
export * from "./CollapsiblePagerView.web.js";
|
|
6
6
|
export * from "./NativeScroller.web.js";
|
|
7
|
+
export { CollapsiblePagerView as WebCollapsiblePagerView } from "./CollapsiblePagerView.web.js";
|
|
8
|
+
export { useWebCollapsiblePagerPage } from "./WebCollapsiblePagerPage.js";
|
|
7
9
|
export { ScrollEdgeEffect } from "./ScrollEdgeEffect.js";
|
|
8
10
|
//# sourceMappingURL=index.web.js.map
|
|
@@ -67,6 +67,8 @@ export interface CollapsiblePagerViewProps extends Omit<NativeProps, "children"
|
|
|
67
67
|
stickyHeaderHeight: number;
|
|
68
68
|
/** Fixed content above the collapsible header on iOS 26 and newer. */
|
|
69
69
|
topOverlay?: React.ReactNode;
|
|
70
|
+
/** Known overlay height to reserve until its first layout measurement. */
|
|
71
|
+
topOverlayHeightHint?: number;
|
|
70
72
|
/** Existing fixed header shared with a parent pager on iOS 26 and newer. */
|
|
71
73
|
externalTopOverlayTag?: number;
|
|
72
74
|
/** Selects UIKit's top scroll-edge effect on iOS 26 and newer. */
|
|
@@ -102,7 +104,7 @@ export interface CollapsiblePagerViewProps extends Omit<NativeProps, "children"
|
|
|
102
104
|
type State = {
|
|
103
105
|
selectedPage: number;
|
|
104
106
|
transientRetainedPages: readonly number[];
|
|
105
|
-
topOverlayHeight: number;
|
|
107
|
+
topOverlayHeight: number | null;
|
|
106
108
|
};
|
|
107
109
|
/**
|
|
108
110
|
* Pager variant whose vertical header coordination is performed by the native
|
|
@@ -120,7 +122,7 @@ export declare class CollapsiblePagerView extends React.PureComponent<Collapsibl
|
|
|
120
122
|
private nativePagerScrollState;
|
|
121
123
|
private nativeTabCommandQueuedDuringScroll;
|
|
122
124
|
componentDidMount(): void;
|
|
123
|
-
componentDidUpdate(): void;
|
|
125
|
+
componentDidUpdate(previousProps: CollapsiblePagerViewProps): void;
|
|
124
126
|
setPage: (selectedPage: number) => void;
|
|
125
127
|
setPageWithoutAnimation: (selectedPage: number) => void;
|
|
126
128
|
scrollToPageTop: (options?: Readonly<{
|
|
@@ -38,8 +38,9 @@ export type CollapsiblePagerMountState = Readonly<{
|
|
|
38
38
|
export interface CollapsiblePagerViewProps extends Omit<WebCollapsiblePagerNativeProps, "children" | "headerHeight" | "stickyHeaderHeight" | "pageKeys" | "retainedPages" | "layoutDirection"> {
|
|
39
39
|
header: React.ReactNode;
|
|
40
40
|
stickyHeader: React.ReactNode;
|
|
41
|
-
headerHeight
|
|
42
|
-
stickyHeaderHeight
|
|
41
|
+
headerHeight?: number;
|
|
42
|
+
stickyHeaderHeight?: number;
|
|
43
|
+
isActive?: boolean;
|
|
43
44
|
topOverlay?: React.ReactNode;
|
|
44
45
|
topScrollEdgeEffect?: `${ScrollEdgeEffect}`;
|
|
45
46
|
topOverlayColorScheme?: "light" | "dark";
|
|
@@ -53,16 +54,42 @@ type State = {
|
|
|
53
54
|
selectedPage: number;
|
|
54
55
|
animateTransition: boolean;
|
|
55
56
|
};
|
|
57
|
+
type WebRouteTarget = Readonly<{
|
|
58
|
+
key: string;
|
|
59
|
+
identity: string;
|
|
60
|
+
owner: HTMLElement;
|
|
61
|
+
generation: number;
|
|
62
|
+
top: number;
|
|
63
|
+
}>;
|
|
56
64
|
/** Web counterpart of the native collapsible pager contract. */
|
|
57
65
|
export declare class CollapsiblePagerView extends React.PureComponent<CollapsiblePagerViewProps, State> {
|
|
58
66
|
state: State;
|
|
59
67
|
private root;
|
|
60
68
|
private track;
|
|
69
|
+
private headerSlot;
|
|
70
|
+
private stickySlot;
|
|
71
|
+
private cssTimelineSupported;
|
|
72
|
+
private overlayTouch;
|
|
61
73
|
private touchStartX;
|
|
62
74
|
private touchStartY;
|
|
63
75
|
private horizontalTouch;
|
|
64
76
|
private pageOffsets;
|
|
65
77
|
private pageHosts;
|
|
78
|
+
private pageScrollIdentities;
|
|
79
|
+
private pageBridges;
|
|
80
|
+
private ownerRecords;
|
|
81
|
+
private ownerGeneration;
|
|
82
|
+
private lastRawTops;
|
|
83
|
+
private routeTarget;
|
|
84
|
+
private measuredHeaderHeight;
|
|
85
|
+
private measuredStickyHeight;
|
|
86
|
+
private headerMeasured;
|
|
87
|
+
private stickyMeasured;
|
|
88
|
+
private headerContent;
|
|
89
|
+
private stickyContent;
|
|
90
|
+
private chromeObserver;
|
|
91
|
+
private chromeMeasureFrame;
|
|
92
|
+
private disposed;
|
|
66
93
|
private sharedHeaderOffset;
|
|
67
94
|
private selectionRestoreToken;
|
|
68
95
|
private bodyAlignment;
|
|
@@ -74,9 +101,32 @@ export declare class CollapsiblePagerView extends React.PureComponent<Collapsibl
|
|
|
74
101
|
private pageScrollState;
|
|
75
102
|
private configuredScrollElement;
|
|
76
103
|
private readonly timelineName;
|
|
104
|
+
private get headerHeight();
|
|
105
|
+
private get hasExplicitHeaderHeight();
|
|
106
|
+
private get stickyHeaderHeight();
|
|
107
|
+
private get hasExplicitStickyHeaderHeight();
|
|
108
|
+
getSnapshotBeforeUpdate(previousProps: CollapsiblePagerViewProps): Readonly<{
|
|
109
|
+
key: string;
|
|
110
|
+
identity: string;
|
|
111
|
+
owner: HTMLElement;
|
|
112
|
+
generation: number;
|
|
113
|
+
top: number;
|
|
114
|
+
}> | null;
|
|
77
115
|
componentDidMount(): void;
|
|
78
|
-
componentDidUpdate(previousProps: CollapsiblePagerViewProps): void;
|
|
116
|
+
componentDidUpdate(previousProps: CollapsiblePagerViewProps, _previousState: State, routeSnapshot: WebRouteTarget | null): void;
|
|
79
117
|
componentWillUnmount(): void;
|
|
118
|
+
private setHeaderContent;
|
|
119
|
+
private setStickyContent;
|
|
120
|
+
private observeChrome;
|
|
121
|
+
private scheduleChromeMeasurement;
|
|
122
|
+
private onPageBridge;
|
|
123
|
+
private setRouteTarget;
|
|
124
|
+
private syncPageOwner;
|
|
125
|
+
private captureRouteTarget;
|
|
126
|
+
restoreScrollPosition: () => boolean;
|
|
127
|
+
private onPageScroll;
|
|
128
|
+
private onPageGeometryChange;
|
|
129
|
+
private onPageUserInput;
|
|
80
130
|
setPage: (selectedPage: number) => void;
|
|
81
131
|
setPageWithoutAnimation: (selectedPage: number) => void;
|
|
82
132
|
scrollToPageTop: (options?: Readonly<{
|
|
@@ -101,9 +151,20 @@ export declare class CollapsiblePagerView extends React.PureComponent<Collapsibl
|
|
|
101
151
|
private onTrackTransitionEnd;
|
|
102
152
|
private setTrack;
|
|
103
153
|
private pageScrollElement;
|
|
154
|
+
private setRoot;
|
|
155
|
+
private overlayTarget;
|
|
156
|
+
private nestedScrollConsumes;
|
|
157
|
+
private scrollOverlayOwner;
|
|
158
|
+
private onOverlayWheel;
|
|
159
|
+
private onOverlayTouchStart;
|
|
160
|
+
private onOverlayTouchMove;
|
|
161
|
+
private onOverlayTouchEnd;
|
|
162
|
+
private synchronizeScrollOwnerIdentity;
|
|
163
|
+
private onScrollOwnerIdentityChanged;
|
|
104
164
|
private notifyInsetsChanged;
|
|
105
165
|
private restoreConfiguredScrollElement;
|
|
106
166
|
private configureActiveScrollElement;
|
|
167
|
+
private syncFallbackHeader;
|
|
107
168
|
private scheduleScrollConfiguration;
|
|
108
169
|
private takeOverVerticalScroll;
|
|
109
170
|
private onListScrollCommandAccepted;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export type WebCollapsiblePagerPageState = Readonly<{
|
|
3
|
+
isFocused: boolean;
|
|
4
|
+
isRouteActive: boolean;
|
|
5
|
+
owner: HTMLElement | null;
|
|
6
|
+
content: HTMLElement | null;
|
|
7
|
+
contentHeight?: number;
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
scrollTop: number;
|
|
11
|
+
pendingRouteScrollTop: number | null;
|
|
12
|
+
registerContent: (element: HTMLElement, explicitHeight?: number) => () => void;
|
|
13
|
+
}>;
|
|
14
|
+
export type WebCollapsiblePagerPageBridge = Readonly<{
|
|
15
|
+
setOwner: (owner: HTMLElement | null) => void;
|
|
16
|
+
requestMeasure: () => void;
|
|
17
|
+
setPendingRouteScrollTop: (top: number | null) => void;
|
|
18
|
+
}>;
|
|
19
|
+
export declare function useWebCollapsiblePagerPage(): Readonly<{
|
|
20
|
+
isFocused: boolean;
|
|
21
|
+
isRouteActive: boolean;
|
|
22
|
+
owner: HTMLElement | null;
|
|
23
|
+
content: HTMLElement | null;
|
|
24
|
+
contentHeight?: number;
|
|
25
|
+
width: number;
|
|
26
|
+
height: number;
|
|
27
|
+
scrollTop: number;
|
|
28
|
+
pendingRouteScrollTop: number | null;
|
|
29
|
+
registerContent: (element: HTMLElement, explicitHeight?: number) => () => void;
|
|
30
|
+
}> | null;
|
|
31
|
+
export declare function WebCollapsiblePagerPage({ children, pageKey, isFocused, isRouteActive, headerHeight, stickyHeaderHeight, onBridge, onGeometryChange, onScroll, onUserInput, }: React.PropsWithChildren<{
|
|
32
|
+
pageKey: string;
|
|
33
|
+
isFocused: boolean;
|
|
34
|
+
isRouteActive: boolean;
|
|
35
|
+
headerHeight: number;
|
|
36
|
+
stickyHeaderHeight: number;
|
|
37
|
+
onBridge: (key: string, bridge: WebCollapsiblePagerPageBridge | null) => void;
|
|
38
|
+
onGeometryChange: (key: string) => void;
|
|
39
|
+
onScroll: (key: string, top: number) => void;
|
|
40
|
+
onUserInput: (key: string) => void;
|
|
41
|
+
}>): import("react/jsx-runtime").JSX.Element;
|
|
42
|
+
//# sourceMappingURL=WebCollapsiblePagerPage.d.ts.map
|
|
@@ -4,6 +4,10 @@ export default PagerView;
|
|
|
4
4
|
export * from './usePagerView';
|
|
5
5
|
export * from './CollapsiblePagerView';
|
|
6
6
|
export * from './NativeScroller';
|
|
7
|
+
export { CollapsiblePagerView as WebCollapsiblePagerView } from './CollapsiblePagerView.web';
|
|
8
|
+
export type { CollapsiblePagerViewProps as WebCollapsiblePagerViewProps } from './CollapsiblePagerView.web';
|
|
9
|
+
export { useWebCollapsiblePagerPage } from './WebCollapsiblePagerPage';
|
|
10
|
+
export type { WebCollapsiblePagerPageState } from './WebCollapsiblePagerPage';
|
|
7
11
|
import type { OnPageScrollEventData as PagerViewOnPageScrollEventData, OnPageSelectedEventData as PagerViewOnPageSelectedEventData, OnPageScrollStateChangedEventData as PageScrollStateChangedNativeEventData, NativeProps } from './PagerViewNativeComponent';
|
|
8
12
|
export type { PagerViewOnPageScrollEventData, PagerViewOnPageSelectedEventData, PageScrollStateChangedNativeEventData, NativeProps as PagerViewProps, };
|
|
9
13
|
export type PagerViewOnPageScrollEvent = ReactNative.NativeSyntheticEvent<PagerViewOnPageScrollEventData>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type * as ReactNative from "react-native";
|
|
2
|
+
import { PagerView } from "./PagerView";
|
|
3
|
+
export default PagerView;
|
|
4
|
+
export * from "./usePagerView";
|
|
5
|
+
export * from "./CollapsiblePagerView";
|
|
6
|
+
export * from "./NativeScroller";
|
|
7
|
+
import type { OnPageScrollEventData as PagerViewOnPageScrollEventData, OnPageSelectedEventData as PagerViewOnPageSelectedEventData, OnPageScrollStateChangedEventData as PageScrollStateChangedNativeEventData, NativeProps } from "./PagerViewNativeComponent";
|
|
8
|
+
export type { PagerViewOnPageScrollEventData, PagerViewOnPageSelectedEventData, PageScrollStateChangedNativeEventData, NativeProps as PagerViewProps, };
|
|
9
|
+
export type PagerViewOnPageScrollEvent = ReactNative.NativeSyntheticEvent<PagerViewOnPageScrollEventData>;
|
|
10
|
+
export type PagerViewOnPageSelectedEvent = ReactNative.NativeSyntheticEvent<PagerViewOnPageSelectedEventData>;
|
|
11
|
+
export type PageScrollStateChangedNativeEvent = ReactNative.NativeSyntheticEvent<PageScrollStateChangedNativeEventData>;
|
|
12
|
+
export { ScrollEdgeEffect } from "./ScrollEdgeEffect";
|
|
13
|
+
//# sourceMappingURL=index.native.d.ts.map
|
|
@@ -3,5 +3,9 @@ export type { PagerViewProps, PagerViewOnPageScrollEvent, PagerViewOnPageScrollE
|
|
|
3
3
|
export * from "./usePagerView";
|
|
4
4
|
export * from "./CollapsiblePagerView.web";
|
|
5
5
|
export * from "./NativeScroller.web";
|
|
6
|
+
export { CollapsiblePagerView as WebCollapsiblePagerView } from "./CollapsiblePagerView.web";
|
|
7
|
+
export type { CollapsiblePagerViewProps as WebCollapsiblePagerViewProps } from "./CollapsiblePagerView.web";
|
|
8
|
+
export { useWebCollapsiblePagerPage } from "./WebCollapsiblePagerPage";
|
|
9
|
+
export type { WebCollapsiblePagerPageState } from "./WebCollapsiblePagerPage";
|
|
6
10
|
export { ScrollEdgeEffect } from "./ScrollEdgeEffect";
|
|
7
11
|
//# sourceMappingURL=index.web.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/react-native-pager-view",
|
|
3
|
-
"version": "6.7.0-alpha.
|
|
3
|
+
"version": "6.7.0-alpha.335",
|
|
4
4
|
"description": "React Native wrapper for Android and iOS ViewPager",
|
|
5
5
|
"source": "./src/index.tsx",
|
|
6
6
|
"main": "./lib/module/index.js",
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
"sideEffects": false,
|
|
10
10
|
"exports": {
|
|
11
11
|
".": {
|
|
12
|
-
"source": "./src/index.tsx",
|
|
13
12
|
"types": "./lib/typescript/src/index.d.ts",
|
|
13
|
+
"react-native": "./lib/module/index.native.js",
|
|
14
|
+
"source": "./src/index.tsx",
|
|
14
15
|
"browser": "./lib/module/index.web.js",
|
|
15
16
|
"default": "./lib/module/index.js"
|
|
16
17
|
},
|
|
@@ -72,7 +73,7 @@
|
|
|
72
73
|
"typescript": "^5.9.2"
|
|
73
74
|
},
|
|
74
75
|
"peerDependencies": {
|
|
75
|
-
"@onekeyfe/react-native-native-logger": "6.7.0-alpha.
|
|
76
|
+
"@onekeyfe/react-native-native-logger": "6.7.0-alpha.335",
|
|
76
77
|
"react": "*",
|
|
77
78
|
"react-native": "*"
|
|
78
79
|
},
|
|
@@ -108,5 +109,6 @@
|
|
|
108
109
|
"RNCNativeScroller": "RNCNativeScrollerComponentView"
|
|
109
110
|
}
|
|
110
111
|
}
|
|
111
|
-
}
|
|
112
|
+
},
|
|
113
|
+
"react-native": "./lib/module/index.native.js"
|
|
112
114
|
}
|
|
@@ -120,6 +120,8 @@ export interface CollapsiblePagerViewProps
|
|
|
120
120
|
stickyHeaderHeight: number;
|
|
121
121
|
/** Fixed content above the collapsible header on iOS 26 and newer. */
|
|
122
122
|
topOverlay?: React.ReactNode;
|
|
123
|
+
/** Known overlay height to reserve until its first layout measurement. */
|
|
124
|
+
topOverlayHeightHint?: number;
|
|
123
125
|
/** Existing fixed header shared with a parent pager on iOS 26 and newer. */
|
|
124
126
|
externalTopOverlayTag?: number;
|
|
125
127
|
/** Selects UIKit's top scroll-edge effect on iOS 26 and newer. */
|
|
@@ -158,7 +160,7 @@ export interface CollapsiblePagerViewProps
|
|
|
158
160
|
type State = {
|
|
159
161
|
selectedPage: number;
|
|
160
162
|
transientRetainedPages: readonly number[];
|
|
161
|
-
topOverlayHeight: number;
|
|
163
|
+
topOverlayHeight: number | null;
|
|
162
164
|
};
|
|
163
165
|
|
|
164
166
|
const pageIndex = (value: number) => {
|
|
@@ -186,7 +188,7 @@ export class CollapsiblePagerView extends React.PureComponent<
|
|
|
186
188
|
State
|
|
187
189
|
> {
|
|
188
190
|
state: State = {
|
|
189
|
-
topOverlayHeight:
|
|
191
|
+
topOverlayHeight: null,
|
|
190
192
|
selectedPage: clampedPageIndex(
|
|
191
193
|
this.props.initialPage ?? 0,
|
|
192
194
|
React.Children.toArray(this.props.children).length
|
|
@@ -219,7 +221,22 @@ export class CollapsiblePagerView extends React.PureComponent<
|
|
|
219
221
|
this.notifyMountedPagesChanged();
|
|
220
222
|
}
|
|
221
223
|
|
|
222
|
-
componentDidUpdate() {
|
|
224
|
+
componentDidUpdate(previousProps: CollapsiblePagerViewProps) {
|
|
225
|
+
const previousOverlayEnabled =
|
|
226
|
+
previousProps.topOverlay != null &&
|
|
227
|
+
(previousProps.topScrollEdgeEffect === "hard" ||
|
|
228
|
+
previousProps.topScrollEdgeEffect === "soft");
|
|
229
|
+
const overlayEnabled =
|
|
230
|
+
this.props.topOverlay != null &&
|
|
231
|
+
(this.props.topScrollEdgeEffect === "hard" ||
|
|
232
|
+
this.props.topScrollEdgeEffect === "soft");
|
|
233
|
+
if (
|
|
234
|
+
previousOverlayEnabled &&
|
|
235
|
+
!overlayEnabled &&
|
|
236
|
+
this.state.topOverlayHeight !== null
|
|
237
|
+
) {
|
|
238
|
+
this.setState({ topOverlayHeight: null });
|
|
239
|
+
}
|
|
223
240
|
const pageCount = this.pages().length;
|
|
224
241
|
const selectedPage = clampedPageIndex(this.state.selectedPage, pageCount);
|
|
225
242
|
if (selectedPage !== this.state.selectedPage) {
|
|
@@ -473,6 +490,7 @@ export class CollapsiblePagerView extends React.PureComponent<
|
|
|
473
490
|
headerHeight,
|
|
474
491
|
stickyHeaderHeight,
|
|
475
492
|
topOverlay,
|
|
493
|
+
topOverlayHeightHint,
|
|
476
494
|
externalTopOverlayTag,
|
|
477
495
|
topScrollEdgeEffect,
|
|
478
496
|
topOverlayColorScheme,
|
|
@@ -498,6 +516,11 @@ export class CollapsiblePagerView extends React.PureComponent<
|
|
|
498
516
|
supportsTopScrollEdge &&
|
|
499
517
|
(topScrollEdgeEffect === "hard" || topScrollEdgeEffect === "soft");
|
|
500
518
|
const hasTopOverlay = scrollEdgeEnabled && topOverlay != null;
|
|
519
|
+
const initialTopOverlayHeight =
|
|
520
|
+
typeof topOverlayHeightHint === "number" &&
|
|
521
|
+
Number.isFinite(topOverlayHeightHint)
|
|
522
|
+
? Math.max(0, Math.ceil(topOverlayHeightHint))
|
|
523
|
+
: 0;
|
|
501
524
|
const pageKeys = pages.map(pageKey);
|
|
502
525
|
const retained = new Set(this.mountedPages(pages.length));
|
|
503
526
|
const deducedLayoutDirection =
|
|
@@ -542,7 +565,11 @@ export class CollapsiblePagerView extends React.PureComponent<
|
|
|
542
565
|
topOverlayColorScheme={
|
|
543
566
|
scrollEdgeEnabled ? topOverlayColorScheme : undefined
|
|
544
567
|
}
|
|
545
|
-
topOverlayHeight={
|
|
568
|
+
topOverlayHeight={
|
|
569
|
+
hasTopOverlay
|
|
570
|
+
? this.state.topOverlayHeight ?? initialTopOverlayHeight
|
|
571
|
+
: 0
|
|
572
|
+
}
|
|
546
573
|
externalTopOverlayTag={
|
|
547
574
|
supportsTopScrollEdge && !hasTopOverlay
|
|
548
575
|
? externalTopOverlayTag ?? 0
|