@onekeyfe/react-native-pager-view 3.0.113 → 3.0.114
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 +0 -40
- package/android/src/main/java/com/reactnativepagerview/PagerViewViewPackage.kt +1 -1
- package/lib/module/index.js +1 -2
- package/lib/module/usePagerView.js +1 -1
- package/lib/typescript/src/index.d.ts +4 -5
- package/package.json +2 -5
- package/src/index.tsx +4 -5
- package/android/src/main/java/com/reactnativepagerview/CollapsiblePagerHost.kt +0 -503
- package/android/src/main/java/com/reactnativepagerview/CollapsiblePagerViewManager.kt +0 -215
- package/android/src/main/java/com/reactnativepagerview/event/CollapsibleStateChangedEvent.kt +0 -39
- package/ios/RNCCollapsiblePagerViewComponentView.h +0 -9
- package/ios/RNCCollapsiblePagerViewComponentView.mm +0 -738
- package/lib/module/CollapsiblePagerView.js +0 -152
- package/lib/module/CollapsiblePagerView.web.js +0 -364
- package/lib/module/CollapsiblePagerViewNativeComponent.ts +0 -85
- package/lib/module/PagerView.web.js +0 -177
- package/lib/module/index.web.js +0 -6
- package/lib/typescript/src/CollapsiblePagerView.d.ts +0 -58
- package/lib/typescript/src/CollapsiblePagerView.web.d.ts +0 -93
- package/lib/typescript/src/CollapsiblePagerViewNativeComponent.d.ts +0 -50
- package/lib/typescript/src/PagerView.web.d.ts +0 -55
- package/lib/typescript/src/index.web.d.ts +0 -5
- package/src/CollapsiblePagerView.tsx +0 -258
- package/src/CollapsiblePagerView.web.tsx +0 -559
- package/src/CollapsiblePagerViewNativeComponent.ts +0 -85
- package/src/PagerView.web.tsx +0 -280
- package/src/index.web.tsx +0 -12
|
@@ -1,559 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { I18nManager, StyleSheet, View } from "react-native";
|
|
3
|
-
import type * as ReactNative from "react-native";
|
|
4
|
-
|
|
5
|
-
export type OnPageScrollEventData = Readonly<{
|
|
6
|
-
position: number;
|
|
7
|
-
offset: number;
|
|
8
|
-
}>;
|
|
9
|
-
|
|
10
|
-
export type OnPageSelectedEventData = Readonly<{
|
|
11
|
-
position: number;
|
|
12
|
-
}>;
|
|
13
|
-
|
|
14
|
-
export type OnPageScrollStateChangedEventData = Readonly<{
|
|
15
|
-
pageScrollState: "idle" | "dragging" | "settling";
|
|
16
|
-
}>;
|
|
17
|
-
|
|
18
|
-
export type OnCollapsibleStateChangedEventData = Readonly<{
|
|
19
|
-
position: number;
|
|
20
|
-
headerOffset: number;
|
|
21
|
-
nativePageCount: number;
|
|
22
|
-
attachedPageCount: number;
|
|
23
|
-
observedScrollableCount: number;
|
|
24
|
-
retainedPages: string;
|
|
25
|
-
reason: string;
|
|
26
|
-
}>;
|
|
27
|
-
|
|
28
|
-
interface WebCollapsiblePagerNativeProps extends ReactNative.ViewProps {
|
|
29
|
-
scrollEnabled?: boolean;
|
|
30
|
-
initialPage?: number;
|
|
31
|
-
offscreenPageLimit?: number;
|
|
32
|
-
onPageScroll?: (
|
|
33
|
-
event: ReactNative.NativeSyntheticEvent<OnPageScrollEventData>
|
|
34
|
-
) => void;
|
|
35
|
-
onPageSelected?: (
|
|
36
|
-
event: ReactNative.NativeSyntheticEvent<OnPageSelectedEventData>
|
|
37
|
-
) => void;
|
|
38
|
-
onPageScrollStateChanged?: (
|
|
39
|
-
event: ReactNative.NativeSyntheticEvent<OnPageScrollStateChangedEventData>
|
|
40
|
-
) => void;
|
|
41
|
-
onCollapsibleStateChanged?: (
|
|
42
|
-
event: ReactNative.NativeSyntheticEvent<OnCollapsibleStateChangedEventData>
|
|
43
|
-
) => void;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export type CollapsiblePagerDiagnostics =
|
|
47
|
-
ReactNative.NativeSyntheticEvent<OnCollapsibleStateChangedEventData>;
|
|
48
|
-
|
|
49
|
-
export type CollapsiblePagerMountState = Readonly<{
|
|
50
|
-
position: number;
|
|
51
|
-
mountedPages: readonly number[];
|
|
52
|
-
pageKeys: readonly string[];
|
|
53
|
-
}>;
|
|
54
|
-
|
|
55
|
-
export interface CollapsiblePagerViewProps
|
|
56
|
-
extends Omit<
|
|
57
|
-
WebCollapsiblePagerNativeProps,
|
|
58
|
-
| "children"
|
|
59
|
-
| "headerHeight"
|
|
60
|
-
| "stickyHeaderHeight"
|
|
61
|
-
| "pageKeys"
|
|
62
|
-
| "retainedPages"
|
|
63
|
-
| "layoutDirection"
|
|
64
|
-
> {
|
|
65
|
-
header: React.ReactNode;
|
|
66
|
-
stickyHeader: React.ReactNode;
|
|
67
|
-
headerHeight: number;
|
|
68
|
-
stickyHeaderHeight: number;
|
|
69
|
-
pageRetentionDistance?: number;
|
|
70
|
-
layoutDirection?: "ltr" | "rtl" | "locale";
|
|
71
|
-
children?: React.ReactNode;
|
|
72
|
-
onMountedPagesChanged?: (state: CollapsiblePagerMountState) => void;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
type State = {
|
|
76
|
-
selectedPage: number;
|
|
77
|
-
animateTransition: boolean;
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
type ConfiguredScrollElement = Readonly<{
|
|
81
|
-
element: HTMLElement;
|
|
82
|
-
paddingTop: string;
|
|
83
|
-
boxSizing: string;
|
|
84
|
-
scrollTimelineName: string;
|
|
85
|
-
scrollTimelineAxis: string;
|
|
86
|
-
}>;
|
|
87
|
-
|
|
88
|
-
const COLLAPSE_ANIMATION_NAME = "ok-collapsible-pager-collapse";
|
|
89
|
-
const COLLAPSE_STYLE_ID = "ok-collapsible-pager-styles";
|
|
90
|
-
let collapsiblePagerWebInstance = 0;
|
|
91
|
-
|
|
92
|
-
const timelineStyle = (element: HTMLElement) =>
|
|
93
|
-
element.style as CSSStyleDeclaration & {
|
|
94
|
-
scrollTimelineName: string;
|
|
95
|
-
scrollTimelineAxis: string;
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
function ensureCollapseAnimation(document: Document) {
|
|
99
|
-
if (document.getElementById(COLLAPSE_STYLE_ID)) return;
|
|
100
|
-
const style = document.createElement("style");
|
|
101
|
-
style.id = COLLAPSE_STYLE_ID;
|
|
102
|
-
style.textContent = `@keyframes ${COLLAPSE_ANIMATION_NAME}{from{transform:translateY(0)}to{transform:translateY(calc(-1 * var(--ok-collapsible-header-height)))}}`;
|
|
103
|
-
document.head.appendChild(style);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const pageKey = (child: React.ReactNode, index: number) => {
|
|
107
|
-
if (React.isValidElement(child) && child.key != null)
|
|
108
|
-
return String(child.key);
|
|
109
|
-
return `page-${index}`;
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
/** Web counterpart of the native collapsible pager contract. */
|
|
113
|
-
export class CollapsiblePagerView extends React.PureComponent<
|
|
114
|
-
CollapsiblePagerViewProps,
|
|
115
|
-
State
|
|
116
|
-
> {
|
|
117
|
-
state: State = {
|
|
118
|
-
selectedPage: Math.max(0, this.props.initialPage ?? 0),
|
|
119
|
-
animateTransition: true,
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
private root: HTMLElement | null = null;
|
|
123
|
-
private touchStartX: number | null = null;
|
|
124
|
-
private touchStartY: number | null = null;
|
|
125
|
-
private pageOffsets = new Map<string, number>();
|
|
126
|
-
private pageHosts = new Map<number, HTMLElement>();
|
|
127
|
-
private sharedHeaderOffset = 0;
|
|
128
|
-
private scrollEnabled = this.props.scrollEnabled ?? true;
|
|
129
|
-
private lastMountSignature: string | null = null;
|
|
130
|
-
private configureFrame: number | null = null;
|
|
131
|
-
private configuredScrollElement: ConfiguredScrollElement | null = null;
|
|
132
|
-
private readonly timelineName = `--ok-collapsible-pager-${++collapsiblePagerWebInstance}`;
|
|
133
|
-
|
|
134
|
-
componentDidMount() {
|
|
135
|
-
if (this.root) ensureCollapseAnimation(this.root.ownerDocument);
|
|
136
|
-
this.scheduleScrollConfiguration();
|
|
137
|
-
this.notifyMountedPagesChanged();
|
|
138
|
-
this.emitDiagnostics("mounted");
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
componentDidUpdate(previousProps: CollapsiblePagerViewProps) {
|
|
142
|
-
if (previousProps.scrollEnabled !== this.props.scrollEnabled) {
|
|
143
|
-
this.scrollEnabled = this.props.scrollEnabled ?? true;
|
|
144
|
-
}
|
|
145
|
-
this.scheduleScrollConfiguration();
|
|
146
|
-
this.notifyMountedPagesChanged();
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
componentWillUnmount() {
|
|
150
|
-
this.savePageOffset(this.state.selectedPage);
|
|
151
|
-
if (this.configureFrame !== null) {
|
|
152
|
-
cancelAnimationFrame(this.configureFrame);
|
|
153
|
-
this.configureFrame = null;
|
|
154
|
-
}
|
|
155
|
-
this.restoreConfiguredScrollElement();
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
public setPage = (selectedPage: number) => {
|
|
159
|
-
this.selectPage(selectedPage, true);
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
public setPageWithoutAnimation = (selectedPage: number) => {
|
|
163
|
-
this.selectPage(selectedPage, false);
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
public setScrollEnabled = (scrollEnabled: boolean) => {
|
|
167
|
-
this.scrollEnabled = scrollEnabled;
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
private pages() {
|
|
171
|
-
return React.Children.toArray(this.props.children);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
private retentionDistance() {
|
|
175
|
-
return Math.max(0, Math.floor(this.props.pageRetentionDistance ?? 1));
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
private mountedPages(
|
|
179
|
-
pageCount = this.pages().length,
|
|
180
|
-
selected = this.state.selectedPage
|
|
181
|
-
) {
|
|
182
|
-
const mounted: number[] = [];
|
|
183
|
-
const distance = this.retentionDistance();
|
|
184
|
-
for (let index = 0; index < pageCount; index += 1) {
|
|
185
|
-
if (Math.abs(index - selected) <= distance) mounted.push(index);
|
|
186
|
-
}
|
|
187
|
-
return mounted;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
private nativeEvent<T>(nativeEvent: T) {
|
|
191
|
-
return { nativeEvent } as ReactNative.NativeSyntheticEvent<T>;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
private pageScrollElement(index: number) {
|
|
195
|
-
const pageHost = this.pageHosts.get(index);
|
|
196
|
-
return (
|
|
197
|
-
pageHost?.querySelector<HTMLElement>(
|
|
198
|
-
".ok-native-list-viewport, [data-collapsible-pager-scroll]"
|
|
199
|
-
) ?? pageHost
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
private restoreConfiguredScrollElement() {
|
|
204
|
-
const configured = this.configuredScrollElement;
|
|
205
|
-
if (!configured) return;
|
|
206
|
-
configured.element.removeEventListener(
|
|
207
|
-
"scrollend",
|
|
208
|
-
this.onVerticalScrollSettled
|
|
209
|
-
);
|
|
210
|
-
const style = timelineStyle(configured.element);
|
|
211
|
-
style.paddingTop = configured.paddingTop;
|
|
212
|
-
style.boxSizing = configured.boxSizing;
|
|
213
|
-
style.scrollTimelineName = configured.scrollTimelineName;
|
|
214
|
-
style.scrollTimelineAxis = configured.scrollTimelineAxis;
|
|
215
|
-
configured.element.removeAttribute("data-collapsible-pager-active");
|
|
216
|
-
this.configuredScrollElement = null;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
private configureActiveScrollElement = () => {
|
|
220
|
-
this.configureFrame = null;
|
|
221
|
-
const element = this.pageScrollElement(this.state.selectedPage);
|
|
222
|
-
if (!element) return;
|
|
223
|
-
if (this.configuredScrollElement?.element !== element) {
|
|
224
|
-
this.restoreConfiguredScrollElement();
|
|
225
|
-
const style = timelineStyle(element);
|
|
226
|
-
this.configuredScrollElement = {
|
|
227
|
-
element,
|
|
228
|
-
paddingTop: style.paddingTop,
|
|
229
|
-
boxSizing: style.boxSizing,
|
|
230
|
-
scrollTimelineName: style.scrollTimelineName,
|
|
231
|
-
scrollTimelineAxis: style.scrollTimelineAxis,
|
|
232
|
-
};
|
|
233
|
-
element.addEventListener("scrollend", this.onVerticalScrollSettled);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
const style = timelineStyle(element);
|
|
237
|
-
style.paddingTop = `${Math.max(
|
|
238
|
-
0,
|
|
239
|
-
this.props.headerHeight + this.props.stickyHeaderHeight
|
|
240
|
-
)}px`;
|
|
241
|
-
style.boxSizing = "border-box";
|
|
242
|
-
style.scrollTimelineName = this.timelineName;
|
|
243
|
-
style.scrollTimelineAxis = "block";
|
|
244
|
-
element.setAttribute("data-collapsible-pager-active", "true");
|
|
245
|
-
};
|
|
246
|
-
|
|
247
|
-
private scheduleScrollConfiguration() {
|
|
248
|
-
if (this.configureFrame !== null) return;
|
|
249
|
-
if (typeof requestAnimationFrame === "function") {
|
|
250
|
-
this.configureFrame = requestAnimationFrame(
|
|
251
|
-
this.configureActiveScrollElement
|
|
252
|
-
);
|
|
253
|
-
} else {
|
|
254
|
-
this.configureActiveScrollElement();
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
private onVerticalScrollSettled = () => {
|
|
259
|
-
this.savePageOffset(this.state.selectedPage);
|
|
260
|
-
this.emitDiagnostics("scroll-settled");
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
private savePageOffset(index: number) {
|
|
264
|
-
const key = this.pages().map(pageKey)[index];
|
|
265
|
-
const scrollElement = this.pageScrollElement(index);
|
|
266
|
-
if (key && scrollElement) {
|
|
267
|
-
this.pageOffsets.set(key, scrollElement.scrollTop);
|
|
268
|
-
this.sharedHeaderOffset = Math.min(
|
|
269
|
-
Math.max(scrollElement.scrollTop, 0),
|
|
270
|
-
Math.max(0, this.props.headerHeight)
|
|
271
|
-
);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
private restorePageOffset(index: number) {
|
|
276
|
-
const key = this.pages().map(pageKey)[index];
|
|
277
|
-
const scrollElement = this.pageScrollElement(index);
|
|
278
|
-
if (!key || !scrollElement) return;
|
|
279
|
-
scrollElement.scrollTop = Math.max(
|
|
280
|
-
this.pageOffsets.get(key) ?? this.sharedHeaderOffset,
|
|
281
|
-
this.sharedHeaderOffset
|
|
282
|
-
);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
private selectPage(selectedPage: number, animated: boolean) {
|
|
286
|
-
const pages = this.pages();
|
|
287
|
-
if (
|
|
288
|
-
selectedPage < 0 ||
|
|
289
|
-
selectedPage >= pages.length ||
|
|
290
|
-
selectedPage === this.state.selectedPage
|
|
291
|
-
) {
|
|
292
|
-
return;
|
|
293
|
-
}
|
|
294
|
-
this.savePageOffset(this.state.selectedPage);
|
|
295
|
-
|
|
296
|
-
this.props.onPageScrollStateChanged?.(
|
|
297
|
-
this.nativeEvent<OnPageScrollStateChangedEventData>({
|
|
298
|
-
pageScrollState: animated ? "settling" : "idle",
|
|
299
|
-
})
|
|
300
|
-
);
|
|
301
|
-
this.setState({ selectedPage, animateTransition: animated }, () => {
|
|
302
|
-
this.scheduleScrollConfiguration();
|
|
303
|
-
const restore = () => {
|
|
304
|
-
this.configureActiveScrollElement();
|
|
305
|
-
this.restorePageOffset(selectedPage);
|
|
306
|
-
};
|
|
307
|
-
if (typeof requestAnimationFrame === "function") {
|
|
308
|
-
requestAnimationFrame(restore);
|
|
309
|
-
} else {
|
|
310
|
-
setTimeout(restore, 0);
|
|
311
|
-
}
|
|
312
|
-
this.props.onPageSelected?.(
|
|
313
|
-
this.nativeEvent<OnPageSelectedEventData>({ position: selectedPage })
|
|
314
|
-
);
|
|
315
|
-
this.props.onPageScroll?.(
|
|
316
|
-
this.nativeEvent<OnPageScrollEventData>({
|
|
317
|
-
position: selectedPage,
|
|
318
|
-
offset: 0,
|
|
319
|
-
})
|
|
320
|
-
);
|
|
321
|
-
if (animated) {
|
|
322
|
-
this.props.onPageScrollStateChanged?.(
|
|
323
|
-
this.nativeEvent<OnPageScrollStateChangedEventData>({
|
|
324
|
-
pageScrollState: "idle",
|
|
325
|
-
})
|
|
326
|
-
);
|
|
327
|
-
}
|
|
328
|
-
this.notifyMountedPagesChanged();
|
|
329
|
-
this.emitDiagnostics("page-selected");
|
|
330
|
-
});
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
private notifyMountedPagesChanged = () => {
|
|
334
|
-
if (!this.props.onMountedPagesChanged) return;
|
|
335
|
-
const pages = this.pages();
|
|
336
|
-
const state = {
|
|
337
|
-
position: this.state.selectedPage,
|
|
338
|
-
mountedPages: this.mountedPages(pages.length),
|
|
339
|
-
pageKeys: pages.map(pageKey),
|
|
340
|
-
};
|
|
341
|
-
const signature = JSON.stringify(state);
|
|
342
|
-
if (signature === this.lastMountSignature) return;
|
|
343
|
-
this.lastMountSignature = signature;
|
|
344
|
-
this.props.onMountedPagesChanged(state);
|
|
345
|
-
};
|
|
346
|
-
|
|
347
|
-
private emitDiagnostics(reason: string) {
|
|
348
|
-
const pages = this.pages();
|
|
349
|
-
const retainedPages = this.mountedPages(pages.length);
|
|
350
|
-
this.props.onCollapsibleStateChanged?.(
|
|
351
|
-
this.nativeEvent<OnCollapsibleStateChangedEventData>({
|
|
352
|
-
position: this.state.selectedPage,
|
|
353
|
-
headerOffset: Math.min(
|
|
354
|
-
Math.max(
|
|
355
|
-
this.pageScrollElement(this.state.selectedPage)?.scrollTop ?? 0,
|
|
356
|
-
0
|
|
357
|
-
),
|
|
358
|
-
Math.max(0, this.props.headerHeight)
|
|
359
|
-
),
|
|
360
|
-
nativePageCount: pages.length,
|
|
361
|
-
attachedPageCount: retainedPages.length,
|
|
362
|
-
observedScrollableCount: retainedPages.reduce(
|
|
363
|
-
(count, index) => count + (this.pageScrollElement(index) ? 1 : 0),
|
|
364
|
-
0
|
|
365
|
-
),
|
|
366
|
-
retainedPages: JSON.stringify(retainedPages),
|
|
367
|
-
reason,
|
|
368
|
-
})
|
|
369
|
-
);
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
private onTouchStart = (event: ReactNative.GestureResponderEvent) => {
|
|
373
|
-
if (!this.scrollEnabled) return;
|
|
374
|
-
const touch = event.nativeEvent.touches[0];
|
|
375
|
-
if (!touch) return;
|
|
376
|
-
this.touchStartX = touch.pageX;
|
|
377
|
-
this.touchStartY = touch.pageY;
|
|
378
|
-
this.props.onPageScrollStateChanged?.(
|
|
379
|
-
this.nativeEvent<OnPageScrollStateChangedEventData>({
|
|
380
|
-
pageScrollState: "dragging",
|
|
381
|
-
})
|
|
382
|
-
);
|
|
383
|
-
};
|
|
384
|
-
|
|
385
|
-
private onTouchEnd = (event: ReactNative.GestureResponderEvent) => {
|
|
386
|
-
if (this.touchStartX == null || !this.scrollEnabled) return;
|
|
387
|
-
const touch = event.nativeEvent.changedTouches[0];
|
|
388
|
-
if (!touch) return;
|
|
389
|
-
const delta = touch.pageX - this.touchStartX;
|
|
390
|
-
const verticalDelta = touch.pageY - (this.touchStartY ?? touch.pageY);
|
|
391
|
-
this.touchStartX = null;
|
|
392
|
-
this.touchStartY = null;
|
|
393
|
-
const rtl =
|
|
394
|
-
this.props.layoutDirection === "rtl" ||
|
|
395
|
-
(!this.props.layoutDirection && I18nManager.isRTL);
|
|
396
|
-
const direction = Math.abs(delta) >= 40 && Math.abs(delta) > Math.abs(verticalDelta)
|
|
397
|
-
? (delta < 0 ? 1 : -1)
|
|
398
|
-
: 0;
|
|
399
|
-
const next = this.state.selectedPage + (rtl ? -direction : direction);
|
|
400
|
-
if (direction === 0 || next < 0 || next >= this.pages().length) {
|
|
401
|
-
this.props.onPageScrollStateChanged?.(
|
|
402
|
-
this.nativeEvent<OnPageScrollStateChangedEventData>({
|
|
403
|
-
pageScrollState: "idle",
|
|
404
|
-
})
|
|
405
|
-
);
|
|
406
|
-
return;
|
|
407
|
-
}
|
|
408
|
-
this.selectPage(next, true);
|
|
409
|
-
};
|
|
410
|
-
|
|
411
|
-
render() {
|
|
412
|
-
const { header, stickyHeader, style, testID, accessibilityLabel } =
|
|
413
|
-
this.props;
|
|
414
|
-
const pages = this.pages();
|
|
415
|
-
const keys = pages.map(pageKey);
|
|
416
|
-
const retained = new Set(this.mountedPages(pages.length));
|
|
417
|
-
const pageWidth = pages.length > 0 ? `${100 / pages.length}%` : "100%";
|
|
418
|
-
const collapseAnimation = {
|
|
419
|
-
"--ok-collapsible-header-height": `${Math.max(
|
|
420
|
-
0,
|
|
421
|
-
this.props.headerHeight
|
|
422
|
-
)}px`,
|
|
423
|
-
animationName: COLLAPSE_ANIMATION_NAME,
|
|
424
|
-
animationDuration: "auto",
|
|
425
|
-
animationFillMode: "both",
|
|
426
|
-
animationTimingFunction: "linear",
|
|
427
|
-
animationTimeline: this.timelineName,
|
|
428
|
-
animationRange: `0px ${Math.max(1, this.props.headerHeight)}px`,
|
|
429
|
-
} as never;
|
|
430
|
-
const trackStyle = [
|
|
431
|
-
styles.track,
|
|
432
|
-
{
|
|
433
|
-
width: `${Math.max(1, pages.length) * 100}%`,
|
|
434
|
-
transform: [
|
|
435
|
-
{
|
|
436
|
-
translateX: `${
|
|
437
|
-
(-this.state.selectedPage * 100) / Math.max(1, pages.length)
|
|
438
|
-
}%`,
|
|
439
|
-
},
|
|
440
|
-
],
|
|
441
|
-
transitionProperty: "transform",
|
|
442
|
-
transitionDuration: this.state.animateTransition ? "240ms" : "0ms",
|
|
443
|
-
},
|
|
444
|
-
] as never;
|
|
445
|
-
|
|
446
|
-
return (
|
|
447
|
-
<View
|
|
448
|
-
ref={(node) => {
|
|
449
|
-
this.root = node as unknown as HTMLElement | null;
|
|
450
|
-
}}
|
|
451
|
-
style={[
|
|
452
|
-
styles.root,
|
|
453
|
-
{ timelineScope: this.timelineName } as never,
|
|
454
|
-
style,
|
|
455
|
-
]}
|
|
456
|
-
testID={testID}
|
|
457
|
-
accessibilityLabel={accessibilityLabel}
|
|
458
|
-
>
|
|
459
|
-
<View
|
|
460
|
-
style={[
|
|
461
|
-
styles.header,
|
|
462
|
-
{ height: Math.max(0, this.props.headerHeight) },
|
|
463
|
-
collapseAnimation,
|
|
464
|
-
]}
|
|
465
|
-
>
|
|
466
|
-
{header}
|
|
467
|
-
</View>
|
|
468
|
-
<View
|
|
469
|
-
style={[
|
|
470
|
-
styles.sticky,
|
|
471
|
-
{
|
|
472
|
-
top: Math.max(0, this.props.headerHeight),
|
|
473
|
-
height: Math.max(0, this.props.stickyHeaderHeight),
|
|
474
|
-
},
|
|
475
|
-
collapseAnimation,
|
|
476
|
-
]}
|
|
477
|
-
>
|
|
478
|
-
{stickyHeader}
|
|
479
|
-
</View>
|
|
480
|
-
<View
|
|
481
|
-
style={trackStyle}
|
|
482
|
-
onTouchStart={this.onTouchStart}
|
|
483
|
-
onTouchEnd={this.onTouchEnd}
|
|
484
|
-
onTouchCancel={() => {
|
|
485
|
-
this.touchStartX = null;
|
|
486
|
-
this.touchStartY = null;
|
|
487
|
-
}}
|
|
488
|
-
>
|
|
489
|
-
{pages.map((page, index) => (
|
|
490
|
-
<View
|
|
491
|
-
key={keys[index]}
|
|
492
|
-
ref={(node) => {
|
|
493
|
-
if (node) {
|
|
494
|
-
const host = node as unknown as HTMLElement;
|
|
495
|
-
host.inert = index !== this.state.selectedPage;
|
|
496
|
-
this.pageHosts.set(index, host);
|
|
497
|
-
} else {
|
|
498
|
-
this.pageHosts.delete(index);
|
|
499
|
-
}
|
|
500
|
-
}}
|
|
501
|
-
style={[styles.page, { width: pageWidth }]}
|
|
502
|
-
aria-hidden={index !== this.state.selectedPage}
|
|
503
|
-
>
|
|
504
|
-
{retained.has(index) ? page : null}
|
|
505
|
-
</View>
|
|
506
|
-
))}
|
|
507
|
-
</View>
|
|
508
|
-
</View>
|
|
509
|
-
);
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
const styles = StyleSheet.create({
|
|
514
|
-
root: {
|
|
515
|
-
flex: 1,
|
|
516
|
-
overflow: "hidden",
|
|
517
|
-
position: "relative",
|
|
518
|
-
} as never,
|
|
519
|
-
header: {
|
|
520
|
-
position: "absolute",
|
|
521
|
-
left: 0,
|
|
522
|
-
right: 0,
|
|
523
|
-
top: 0,
|
|
524
|
-
zIndex: 3,
|
|
525
|
-
overflow: "hidden",
|
|
526
|
-
} as never,
|
|
527
|
-
sticky: {
|
|
528
|
-
position: "absolute",
|
|
529
|
-
left: 0,
|
|
530
|
-
right: 0,
|
|
531
|
-
zIndex: 4,
|
|
532
|
-
overflow: "hidden",
|
|
533
|
-
} as never,
|
|
534
|
-
track: {
|
|
535
|
-
position: "absolute",
|
|
536
|
-
inset: 0,
|
|
537
|
-
display: "flex",
|
|
538
|
-
flexDirection: "row",
|
|
539
|
-
alignItems: "stretch",
|
|
540
|
-
touchAction: "pan-y",
|
|
541
|
-
} as never,
|
|
542
|
-
page: {
|
|
543
|
-
flexShrink: 0,
|
|
544
|
-
minWidth: 0,
|
|
545
|
-
minHeight: 0,
|
|
546
|
-
height: "100%",
|
|
547
|
-
display: "flex",
|
|
548
|
-
position: "relative",
|
|
549
|
-
overflowY: "auto",
|
|
550
|
-
overflowX: "hidden",
|
|
551
|
-
} as never,
|
|
552
|
-
});
|
|
553
|
-
|
|
554
|
-
export type CollapsiblePagerViewOnPageScrollEvent =
|
|
555
|
-
ReactNative.NativeSyntheticEvent<OnPageScrollEventData>;
|
|
556
|
-
export type CollapsiblePagerViewOnPageSelectedEvent =
|
|
557
|
-
ReactNative.NativeSyntheticEvent<OnPageSelectedEventData>;
|
|
558
|
-
export type CollapsiblePagerViewOnPageScrollStateChangedEvent =
|
|
559
|
-
ReactNative.NativeSyntheticEvent<OnPageScrollStateChangedEventData>;
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import type * as React from "react";
|
|
2
|
-
import {
|
|
3
|
-
codegenNativeCommands,
|
|
4
|
-
codegenNativeComponent,
|
|
5
|
-
type HostComponent,
|
|
6
|
-
type ViewProps,
|
|
7
|
-
} from "react-native";
|
|
8
|
-
|
|
9
|
-
import type {
|
|
10
|
-
DirectEventHandler,
|
|
11
|
-
Double,
|
|
12
|
-
Int32,
|
|
13
|
-
WithDefault,
|
|
14
|
-
} from "react-native/Libraries/Types/CodegenTypes";
|
|
15
|
-
|
|
16
|
-
export type OnPageScrollEventData = Readonly<{
|
|
17
|
-
position: Double;
|
|
18
|
-
offset: Double;
|
|
19
|
-
}>;
|
|
20
|
-
|
|
21
|
-
export type OnPageSelectedEventData = Readonly<{
|
|
22
|
-
position: Double;
|
|
23
|
-
}>;
|
|
24
|
-
|
|
25
|
-
export type OnPageScrollStateChangedEventData = Readonly<{
|
|
26
|
-
pageScrollState: "idle" | "dragging" | "settling";
|
|
27
|
-
}>;
|
|
28
|
-
|
|
29
|
-
export type OnCollapsibleStateChangedEventData = Readonly<{
|
|
30
|
-
position: Int32;
|
|
31
|
-
headerOffset: Double;
|
|
32
|
-
nativePageCount: Int32;
|
|
33
|
-
attachedPageCount: Int32;
|
|
34
|
-
observedScrollableCount: Int32;
|
|
35
|
-
retainedPages: string;
|
|
36
|
-
reason: string;
|
|
37
|
-
}>;
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Internal native props. Consumers should use CollapsiblePagerViewProps from
|
|
41
|
-
* CollapsiblePagerView instead of mounting this host component directly.
|
|
42
|
-
*/
|
|
43
|
-
export interface NativeProps extends ViewProps {
|
|
44
|
-
scrollEnabled?: WithDefault<boolean, true>;
|
|
45
|
-
layoutDirection?: WithDefault<"ltr" | "rtl", "ltr">;
|
|
46
|
-
initialPage?: Int32;
|
|
47
|
-
offscreenPageLimit?: Int32;
|
|
48
|
-
headerHeight?: Int32;
|
|
49
|
-
stickyHeaderHeight?: Int32;
|
|
50
|
-
pageKeys?: string;
|
|
51
|
-
retainedPages?: string;
|
|
52
|
-
onPageScroll?: DirectEventHandler<OnPageScrollEventData>;
|
|
53
|
-
onPageSelected?: DirectEventHandler<OnPageSelectedEventData>;
|
|
54
|
-
onPageScrollStateChanged?: DirectEventHandler<OnPageScrollStateChangedEventData>;
|
|
55
|
-
onCollapsibleStateChanged?: DirectEventHandler<OnCollapsibleStateChangedEventData>;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
type CollapsiblePagerViewNativeType = HostComponent<NativeProps>;
|
|
59
|
-
|
|
60
|
-
export interface NativeCommands {
|
|
61
|
-
setPage: (
|
|
62
|
-
viewRef: React.ElementRef<CollapsiblePagerViewNativeType>,
|
|
63
|
-
selectedPage: Int32
|
|
64
|
-
) => void;
|
|
65
|
-
setPageWithoutAnimation: (
|
|
66
|
-
viewRef: React.ElementRef<CollapsiblePagerViewNativeType>,
|
|
67
|
-
selectedPage: Int32
|
|
68
|
-
) => void;
|
|
69
|
-
setScrollEnabledImperatively: (
|
|
70
|
-
viewRef: React.ElementRef<CollapsiblePagerViewNativeType>,
|
|
71
|
-
scrollEnabled: boolean
|
|
72
|
-
) => void;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export const Commands: NativeCommands = codegenNativeCommands<NativeCommands>({
|
|
76
|
-
supportedCommands: [
|
|
77
|
-
"setPage",
|
|
78
|
-
"setPageWithoutAnimation",
|
|
79
|
-
"setScrollEnabledImperatively",
|
|
80
|
-
],
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
export default codegenNativeComponent<NativeProps>(
|
|
84
|
-
"RNCCollapsiblePagerView"
|
|
85
|
-
) as HostComponent<NativeProps>;
|