@codeleap/mobile 3.16.0 → 3.17.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeleap/mobile",
3
- "version": "3.16.0",
3
+ "version": "3.17.0",
4
4
  "main": "src/index.ts",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -1,7 +1,7 @@
1
1
  import {
2
+ AnyFunction,
2
3
  ComponentVariants,
3
4
  onUpdate,
4
- PropsOf,
5
5
  TypeGuards,
6
6
  useDefaultComponentStyle,
7
7
  useWarning,
@@ -16,7 +16,6 @@ import {
16
16
  StyleSheet,
17
17
  } from 'react-native'
18
18
  import { StylesOf } from '../../types/utility'
19
- import { ScrollProps } from '../Scroll'
20
19
  import { View } from '../View'
21
20
  import { PagerPresets, PagerComposition } from './styles'
22
21
  export * from './styles'
@@ -29,9 +28,10 @@ export type PageProps = {
29
28
  page: number
30
29
  index: number
31
30
  isPrevious: boolean
32
-
33
31
  }
34
32
 
33
+ type ScrollEvent = NativeSyntheticEvent<NativeScrollEvent>
34
+
35
35
  export type PagerProps = React.PropsWithChildren<{
36
36
  variants?: ComponentVariants<typeof PagerPresets>['variants']
37
37
  styles?: StylesOf<PagerComposition>
@@ -43,9 +43,14 @@ export type PagerProps = React.PropsWithChildren<{
43
43
  renderPageWrapper?: React.FC<PageProps>
44
44
  pageWrapperProps?: any
45
45
  width?: number
46
- onScroll: ScrollProps['onScroll']
46
+ onScroll?: (event: ScrollEvent, args: { isLeft: boolean; isRight: boolean; x: number }) => void
47
47
  /** If TRUE render page, nextPage and prevPage only */
48
48
  windowing?: boolean
49
+ scrollRightEnabled?: boolean
50
+ scrollLeftEnabled?: boolean
51
+ scrollDirectionThrottle?: number
52
+ onSwipeLastPage?: (event: ScrollEvent) => void
53
+ waitEventDispatchTimeout?: number
49
54
  } & ScrollViewProps>
50
55
 
51
56
  const defaultProps: Partial<PagerProps> = {
@@ -54,8 +59,12 @@ const defaultProps: Partial<PagerProps> = {
54
59
  page: 0,
55
60
  returnEarly: true,
56
61
  windowing: false,
57
- scrollEnabled: true,
58
62
  keyboardShouldPersistTaps: 'handled',
63
+ scrollEnabled: true,
64
+ scrollRightEnabled: true,
65
+ scrollLeftEnabled: true,
66
+ scrollDirectionThrottle: 650,
67
+ waitEventDispatchTimeout: 250,
59
68
  }
60
69
 
61
70
  export const Pager = (pagerProps: PagerProps) => {
@@ -72,6 +81,12 @@ export const Pager = (pagerProps: PagerProps) => {
72
81
  windowing = false,
73
82
  setPage,
74
83
  scrollEnabled = true,
84
+ scrollLeftEnabled,
85
+ scrollRightEnabled,
86
+ onScroll,
87
+ scrollDirectionThrottle,
88
+ onSwipeLastPage,
89
+ waitEventDispatchTimeout,
75
90
  } = {
76
91
  ...defaultProps,
77
92
  ...pagerProps,
@@ -80,6 +95,10 @@ export const Pager = (pagerProps: PagerProps) => {
80
95
  const childArr = React.Children.toArray(children)
81
96
  const scrollRef = useRef<ScrollView>(null)
82
97
  const [positionX, setPositionX] = React.useState(0)
98
+ const [scrollPositionX, setScrollPositionX] = React.useState(0)
99
+ const [_scrollEnabled, setScrollEnabled] = React.useState(true)
100
+
101
+ const waitEventDispatch = useRef(false)
83
102
 
84
103
  const variantStyles = useDefaultComponentStyle<'u:Pager', typeof PagerPresets>(
85
104
  'u:Pager',
@@ -97,7 +116,6 @@ export const Pager = (pagerProps: PagerProps) => {
97
116
 
98
117
  if (!validWidth) {
99
118
  width = windowWidth
100
-
101
119
  }
102
120
 
103
121
  useWarning(
@@ -112,18 +130,62 @@ export const Pager = (pagerProps: PagerProps) => {
112
130
 
113
131
  const WrapperComponent = renderPageWrapper || View
114
132
 
115
- const handleScrollEnd = useCallback(
116
- ({ nativeEvent }: NativeSyntheticEvent<NativeScrollEvent>) => {
117
- const x = nativeEvent.contentOffset.x
118
- const toPage = Math.ceil(x / width)
133
+ const hasScrollDirectionDisabled = !scrollLeftEnabled || !scrollRightEnabled
134
+
135
+ const handleScrollEnd = useCallback((event: ScrollEvent) => {
136
+ if (waitEventDispatch.current === true) return null
137
+
138
+ waitEventDispatch.current = true
139
+
140
+ const x = event?.nativeEvent.contentOffset.x
141
+ const toPage = Math.floor(((Math.round(x)) / Math.round(width)))
142
+
143
+ const length = childArr.length - 1
144
+
145
+ if (toPage >= length && TypeGuards.isFunction(onSwipeLastPage) && page >= length) {
146
+ onSwipeLastPage?.(event)
147
+ } else if (toPage !== page && toPage <= length) {
148
+ setPage(toPage)
149
+ setPositionX(toPage * width)
150
+ }
151
+
152
+ setTimeout(() => {
153
+ waitEventDispatch.current = false
154
+ }, waitEventDispatchTimeout)
155
+ }, [childArr, page, setPage, waitEventDispatch.current])
119
156
 
120
- if (toPage !== page && toPage <= childArr.length - 1 && !!scrollEnabled) {
121
- setPage(toPage)
122
- setPositionX(toPage * width)
157
+ const handleScroll = (event: ScrollEvent) => {
158
+ const scrollX = event?.nativeEvent?.contentOffset?.x
159
+
160
+ if (!_scrollEnabled) {
161
+ setScrollPositionX(scrollX)
162
+ return null
163
+ }
164
+
165
+ const isRight = scrollX < scrollPositionX
166
+ const isLeft = scrollX > scrollPositionX
167
+
168
+ if (TypeGuards.isFunction(onScroll)) onScroll?.(event, { isLeft, isRight, x: scrollX })
169
+
170
+ if (hasScrollDirectionDisabled) {
171
+ if (isRight && !scrollRightEnabled || isLeft && !scrollLeftEnabled) {
172
+ setScrollEnabled(false)
173
+
174
+ setTimeout(() => {
175
+ scrollRef.current.scrollTo({
176
+ x: positionX,
177
+ animated: true,
178
+ })
179
+
180
+ setTimeout(() => {
181
+ setScrollEnabled(true)
182
+ }, scrollDirectionThrottle)
183
+ })
123
184
  }
124
- },
125
- [childArr, page, setPage],
126
- )
185
+ }
186
+
187
+ setScrollPositionX(scrollX)
188
+ }
127
189
 
128
190
  onUpdate(() => {
129
191
  const x = width * page
@@ -142,12 +204,12 @@ export const Pager = (pagerProps: PagerProps) => {
142
204
  horizontal
143
205
  pagingEnabled
144
206
  onMomentumScrollEnd={handleScrollEnd}
145
- scrollEventThrottle={300}
207
+ scrollEventThrottle={hasScrollDirectionDisabled ? 2000 : 300}
146
208
  showsHorizontalScrollIndicator={false}
147
209
  style={[variantStyles.wrapper, style]}
148
210
  {...pagerProps}
149
- scrollEnabled={childArr.length > 1 && scrollEnabled}
150
-
211
+ onScroll={handleScroll}
212
+ scrollEnabled={childArr.length > 1 && scrollEnabled && _scrollEnabled}
151
213
  >
152
214
  {childArr.map((child: PagerProps['children'][number], index) => {
153
215