@onekeyfe/react-native-pager-view 3.0.112 → 3.0.113
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 +40 -0
- package/android/src/main/java/com/reactnativepagerview/CollapsiblePagerHost.kt +503 -0
- package/android/src/main/java/com/reactnativepagerview/CollapsiblePagerViewManager.kt +215 -0
- package/android/src/main/java/com/reactnativepagerview/PagerViewViewPackage.kt +1 -1
- package/android/src/main/java/com/reactnativepagerview/event/CollapsibleStateChangedEvent.kt +39 -0
- package/ios/RNCCollapsiblePagerViewComponentView.h +9 -0
- package/ios/RNCCollapsiblePagerViewComponentView.mm +738 -0
- package/lib/module/CollapsiblePagerView.js +152 -0
- package/lib/module/CollapsiblePagerView.web.js +364 -0
- package/lib/module/CollapsiblePagerViewNativeComponent.ts +85 -0
- package/lib/module/PagerView.web.js +177 -0
- package/lib/module/index.js +2 -1
- package/lib/module/index.web.js +6 -0
- package/lib/module/usePagerView.js +1 -1
- package/lib/typescript/src/CollapsiblePagerView.d.ts +58 -0
- package/lib/typescript/src/CollapsiblePagerView.web.d.ts +93 -0
- package/lib/typescript/src/CollapsiblePagerViewNativeComponent.d.ts +50 -0
- package/lib/typescript/src/PagerView.web.d.ts +55 -0
- package/lib/typescript/src/index.d.ts +5 -4
- package/lib/typescript/src/index.web.d.ts +5 -0
- package/package.json +5 -2
- package/src/CollapsiblePagerView.tsx +258 -0
- package/src/CollapsiblePagerView.web.tsx +559 -0
- package/src/CollapsiblePagerViewNativeComponent.ts +85 -0
- package/src/PagerView.web.tsx +280 -0
- package/src/index.tsx +5 -4
- package/src/index.web.tsx +12 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { I18nManager, Keyboard, StyleSheet, View } from "react-native";
|
|
3
|
+
import type * as ReactNative from "react-native";
|
|
4
|
+
|
|
5
|
+
export type PagerViewOnPageScrollEventData = Readonly<{
|
|
6
|
+
position: number;
|
|
7
|
+
offset: number;
|
|
8
|
+
}>;
|
|
9
|
+
|
|
10
|
+
export type PagerViewOnPageSelectedEventData = Readonly<{
|
|
11
|
+
position: number;
|
|
12
|
+
}>;
|
|
13
|
+
|
|
14
|
+
export type PageScrollStateChangedNativeEventData = Readonly<{
|
|
15
|
+
pageScrollState: "idle" | "dragging" | "settling";
|
|
16
|
+
}>;
|
|
17
|
+
|
|
18
|
+
export interface PagerViewProps extends ReactNative.ViewProps {
|
|
19
|
+
scrollEnabled?: boolean;
|
|
20
|
+
layoutDirection?: "ltr" | "rtl" | "locale";
|
|
21
|
+
initialPage?: number;
|
|
22
|
+
orientation?: "horizontal" | "vertical";
|
|
23
|
+
offscreenPageLimit?: number;
|
|
24
|
+
pageMargin?: number;
|
|
25
|
+
overScrollMode?: "auto" | "always" | "never";
|
|
26
|
+
overdrag?: boolean;
|
|
27
|
+
keyboardDismissMode?: "none" | "on-drag";
|
|
28
|
+
scrollSensitivity?: number;
|
|
29
|
+
nestedScrollEnabled?: boolean;
|
|
30
|
+
onPageScroll?: (
|
|
31
|
+
event: ReactNative.NativeSyntheticEvent<PagerViewOnPageScrollEventData>
|
|
32
|
+
) => void;
|
|
33
|
+
onPageSelected?: (
|
|
34
|
+
event: ReactNative.NativeSyntheticEvent<PagerViewOnPageSelectedEventData>
|
|
35
|
+
) => void;
|
|
36
|
+
onPageScrollStateChanged?: (
|
|
37
|
+
event: ReactNative.NativeSyntheticEvent<PageScrollStateChangedNativeEventData>
|
|
38
|
+
) => void;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
type State = Readonly<{
|
|
42
|
+
selectedPage: number;
|
|
43
|
+
animateTransition: boolean;
|
|
44
|
+
}>;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Web fallback for the ordinary PagerView API. All pages stay mounted, matching
|
|
48
|
+
* the package's pre-existing PagerView lifetime contract.
|
|
49
|
+
*/
|
|
50
|
+
export class PagerView extends React.Component<PagerViewProps, State> {
|
|
51
|
+
state: State = {
|
|
52
|
+
selectedPage: Math.max(0, Math.trunc(this.props.initialPage ?? 0)),
|
|
53
|
+
animateTransition: true,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
private pointerStart: Readonly<{ x: number; y: number }> | null = null;
|
|
57
|
+
private scrollEnabled = this.props.scrollEnabled ?? true;
|
|
58
|
+
|
|
59
|
+
componentDidUpdate(previousProps: PagerViewProps) {
|
|
60
|
+
if (previousProps.scrollEnabled !== this.props.scrollEnabled) {
|
|
61
|
+
this.scrollEnabled = this.props.scrollEnabled ?? true;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const pageCount = React.Children.count(this.props.children);
|
|
65
|
+
if (pageCount > 0 && this.state.selectedPage >= pageCount) {
|
|
66
|
+
this.setState({
|
|
67
|
+
selectedPage: pageCount - 1,
|
|
68
|
+
animateTransition: false,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public setPage = (selectedPage: number) => {
|
|
74
|
+
this.selectPage(selectedPage, true);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
public setPageWithoutAnimation = (selectedPage: number) => {
|
|
78
|
+
this.selectPage(selectedPage, false);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
public setScrollEnabled = (scrollEnabled: boolean) => {
|
|
82
|
+
this.scrollEnabled = scrollEnabled;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
private nativeEvent<T>(nativeEvent: T) {
|
|
86
|
+
return { nativeEvent } as ReactNative.NativeSyntheticEvent<T>;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private selectPage(selectedPage: number, animated: boolean) {
|
|
90
|
+
const pageCount = React.Children.count(this.props.children);
|
|
91
|
+
const position = Math.trunc(selectedPage);
|
|
92
|
+
if (
|
|
93
|
+
position < 0 ||
|
|
94
|
+
position >= pageCount ||
|
|
95
|
+
position === this.state.selectedPage
|
|
96
|
+
) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
this.props.onPageScrollStateChanged?.(
|
|
101
|
+
this.nativeEvent<PageScrollStateChangedNativeEventData>({
|
|
102
|
+
pageScrollState: animated ? "settling" : "idle",
|
|
103
|
+
})
|
|
104
|
+
);
|
|
105
|
+
this.setState(
|
|
106
|
+
{ selectedPage: position, animateTransition: animated },
|
|
107
|
+
() => {
|
|
108
|
+
this.props.onPageScroll?.(
|
|
109
|
+
this.nativeEvent<PagerViewOnPageScrollEventData>({
|
|
110
|
+
position,
|
|
111
|
+
offset: 0,
|
|
112
|
+
})
|
|
113
|
+
);
|
|
114
|
+
this.props.onPageSelected?.(
|
|
115
|
+
this.nativeEvent<PagerViewOnPageSelectedEventData>({ position })
|
|
116
|
+
);
|
|
117
|
+
if (animated) {
|
|
118
|
+
this.props.onPageScrollStateChanged?.(
|
|
119
|
+
this.nativeEvent<PageScrollStateChangedNativeEventData>({
|
|
120
|
+
pageScrollState: "idle",
|
|
121
|
+
})
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private onTouchStart = (event: ReactNative.GestureResponderEvent) => {
|
|
129
|
+
if (!this.scrollEnabled) return;
|
|
130
|
+
this.pointerStart = {
|
|
131
|
+
x: event.nativeEvent.pageX,
|
|
132
|
+
y: event.nativeEvent.pageY,
|
|
133
|
+
};
|
|
134
|
+
if (this.props.keyboardDismissMode === "on-drag") Keyboard.dismiss();
|
|
135
|
+
this.props.onPageScrollStateChanged?.(
|
|
136
|
+
this.nativeEvent<PageScrollStateChangedNativeEventData>({
|
|
137
|
+
pageScrollState: "dragging",
|
|
138
|
+
})
|
|
139
|
+
);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
private onTouchEnd = (event: ReactNative.GestureResponderEvent) => {
|
|
143
|
+
const start = this.pointerStart;
|
|
144
|
+
this.pointerStart = null;
|
|
145
|
+
if (!start || !this.scrollEnabled) return;
|
|
146
|
+
|
|
147
|
+
const vertical = this.props.orientation === "vertical";
|
|
148
|
+
const delta = vertical
|
|
149
|
+
? event.nativeEvent.pageY - start.y
|
|
150
|
+
: event.nativeEvent.pageX - start.x;
|
|
151
|
+
const isRTL =
|
|
152
|
+
!vertical &&
|
|
153
|
+
(this.props.layoutDirection === "rtl" ||
|
|
154
|
+
((!this.props.layoutDirection ||
|
|
155
|
+
this.props.layoutDirection === "locale") &&
|
|
156
|
+
I18nManager.isRTL));
|
|
157
|
+
const direction = Math.abs(delta) >= 40 ? (delta < 0 ? 1 : -1) : 0;
|
|
158
|
+
const next = this.state.selectedPage + (isRTL ? -direction : direction);
|
|
159
|
+
if (
|
|
160
|
+
direction === 0 ||
|
|
161
|
+
next < 0 ||
|
|
162
|
+
next >= React.Children.count(this.props.children)
|
|
163
|
+
) {
|
|
164
|
+
this.props.onPageScrollStateChanged?.(
|
|
165
|
+
this.nativeEvent<PageScrollStateChangedNativeEventData>({
|
|
166
|
+
pageScrollState: "idle",
|
|
167
|
+
})
|
|
168
|
+
);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
this.selectPage(next, true);
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
render() {
|
|
175
|
+
const {
|
|
176
|
+
children,
|
|
177
|
+
style,
|
|
178
|
+
orientation = "horizontal",
|
|
179
|
+
pageMargin = 0,
|
|
180
|
+
scrollEnabled: _scrollEnabled,
|
|
181
|
+
initialPage: _initialPage,
|
|
182
|
+
layoutDirection: _layoutDirection,
|
|
183
|
+
offscreenPageLimit: _offscreenPageLimit,
|
|
184
|
+
overScrollMode: _overScrollMode,
|
|
185
|
+
overdrag: _overdrag,
|
|
186
|
+
keyboardDismissMode: _keyboardDismissMode,
|
|
187
|
+
scrollSensitivity: _scrollSensitivity,
|
|
188
|
+
nestedScrollEnabled: _nestedScrollEnabled,
|
|
189
|
+
onPageScroll: _onPageScroll,
|
|
190
|
+
onPageSelected: _onPageSelected,
|
|
191
|
+
onPageScrollStateChanged: _onPageScrollStateChanged,
|
|
192
|
+
...viewProps
|
|
193
|
+
} = this.props;
|
|
194
|
+
const pages = React.Children.toArray(children);
|
|
195
|
+
const vertical = orientation === "vertical";
|
|
196
|
+
const pageExtent = pages.length > 0 ? `${100 / pages.length}%` : "100%";
|
|
197
|
+
const transform = vertical
|
|
198
|
+
? [
|
|
199
|
+
{
|
|
200
|
+
translateY: `${
|
|
201
|
+
(-this.state.selectedPage * 100) / Math.max(1, pages.length)
|
|
202
|
+
}%`,
|
|
203
|
+
},
|
|
204
|
+
]
|
|
205
|
+
: [
|
|
206
|
+
{
|
|
207
|
+
translateX: `${
|
|
208
|
+
(-this.state.selectedPage * 100) / Math.max(1, pages.length)
|
|
209
|
+
}%`,
|
|
210
|
+
},
|
|
211
|
+
];
|
|
212
|
+
|
|
213
|
+
return (
|
|
214
|
+
<View {...viewProps} style={[styles.root, style]}>
|
|
215
|
+
<View
|
|
216
|
+
style={[
|
|
217
|
+
styles.track,
|
|
218
|
+
vertical ? styles.verticalTrack : styles.horizontalTrack,
|
|
219
|
+
vertical
|
|
220
|
+
? { height: `${Math.max(1, pages.length) * 100}%` }
|
|
221
|
+
: { width: `${Math.max(1, pages.length) * 100}%` },
|
|
222
|
+
{
|
|
223
|
+
transform,
|
|
224
|
+
transitionProperty: "transform",
|
|
225
|
+
transitionDuration: this.state.animateTransition
|
|
226
|
+
? "240ms"
|
|
227
|
+
: "0ms",
|
|
228
|
+
} as never,
|
|
229
|
+
]}
|
|
230
|
+
onTouchStart={this.onTouchStart}
|
|
231
|
+
onTouchEnd={this.onTouchEnd}
|
|
232
|
+
>
|
|
233
|
+
{pages.map((page, index) => (
|
|
234
|
+
<View
|
|
235
|
+
key={React.isValidElement(page) ? page.key ?? index : index}
|
|
236
|
+
style={[
|
|
237
|
+
styles.page,
|
|
238
|
+
vertical
|
|
239
|
+
? { height: pageExtent, paddingVertical: pageMargin / 2 }
|
|
240
|
+
: { width: pageExtent, paddingHorizontal: pageMargin / 2 },
|
|
241
|
+
]}
|
|
242
|
+
>
|
|
243
|
+
{page}
|
|
244
|
+
</View>
|
|
245
|
+
))}
|
|
246
|
+
</View>
|
|
247
|
+
</View>
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const styles = StyleSheet.create({
|
|
253
|
+
root: {
|
|
254
|
+
overflow: "hidden",
|
|
255
|
+
},
|
|
256
|
+
track: {
|
|
257
|
+
flex: 1,
|
|
258
|
+
},
|
|
259
|
+
horizontalTrack: {
|
|
260
|
+
flexDirection: "row",
|
|
261
|
+
height: "100%",
|
|
262
|
+
},
|
|
263
|
+
verticalTrack: {
|
|
264
|
+
flexDirection: "column",
|
|
265
|
+
width: "100%",
|
|
266
|
+
},
|
|
267
|
+
page: {
|
|
268
|
+
flexShrink: 0,
|
|
269
|
+
minWidth: 0,
|
|
270
|
+
minHeight: 0,
|
|
271
|
+
overflow: "hidden",
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
export type PagerViewOnPageScrollEvent =
|
|
276
|
+
ReactNative.NativeSyntheticEvent<PagerViewOnPageScrollEventData>;
|
|
277
|
+
export type PagerViewOnPageSelectedEvent =
|
|
278
|
+
ReactNative.NativeSyntheticEvent<PagerViewOnPageSelectedEventData>;
|
|
279
|
+
export type PageScrollStateChangedNativeEvent =
|
|
280
|
+
ReactNative.NativeSyntheticEvent<PageScrollStateChangedNativeEventData>;
|
package/src/index.tsx
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import type * as ReactNative from
|
|
2
|
-
import { PagerView } from
|
|
1
|
+
import type * as ReactNative from "react-native";
|
|
2
|
+
import { PagerView } from "./PagerView";
|
|
3
3
|
export default PagerView;
|
|
4
|
-
export * from
|
|
4
|
+
export * from "./usePagerView";
|
|
5
|
+
export * from "./CollapsiblePagerView";
|
|
5
6
|
|
|
6
7
|
import type {
|
|
7
8
|
OnPageScrollEventData as PagerViewOnPageScrollEventData,
|
|
8
9
|
OnPageSelectedEventData as PagerViewOnPageSelectedEventData,
|
|
9
10
|
OnPageScrollStateChangedEventData as PageScrollStateChangedNativeEventData,
|
|
10
11
|
NativeProps,
|
|
11
|
-
} from
|
|
12
|
+
} from "./PagerViewNativeComponent";
|
|
12
13
|
|
|
13
14
|
export type {
|
|
14
15
|
PagerViewOnPageScrollEventData,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { PagerView as default, PagerView } from "./PagerView.web";
|
|
2
|
+
export type {
|
|
3
|
+
PagerViewProps,
|
|
4
|
+
PagerViewOnPageScrollEvent,
|
|
5
|
+
PagerViewOnPageScrollEventData,
|
|
6
|
+
PagerViewOnPageSelectedEvent,
|
|
7
|
+
PagerViewOnPageSelectedEventData,
|
|
8
|
+
PageScrollStateChangedNativeEvent,
|
|
9
|
+
PageScrollStateChangedNativeEventData,
|
|
10
|
+
} from "./PagerView.web";
|
|
11
|
+
export * from "./usePagerView";
|
|
12
|
+
export * from "./CollapsiblePagerView.web";
|