react-native-varia 0.2.2 → 0.2.4
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/bin/cli.js +316 -139
- package/lib/components/Accordion.tsx +113 -0
- package/lib/components/Button.tsx +19 -8
- package/lib/components/CircleProgress.tsx +46 -28
- package/lib/components/Divider.tsx +18 -15
- package/lib/components/Drawer.tsx +496 -0
- package/lib/components/Field.tsx +24 -39
- package/lib/components/GradientBackground.tsx +25 -7
- package/lib/components/GradientText.tsx +38 -11
- package/lib/components/IconWrapper.tsx +20 -14
- package/lib/components/Input.tsx +106 -25
- package/lib/components/NumberInput.tsx +88 -19
- package/lib/components/OldSlider.tsx +327 -0
- package/lib/components/RadioGroup.tsx +55 -17
- package/lib/components/ReText.tsx +1 -1
- package/lib/components/Select.tsx +58 -22
- package/lib/components/Slider.tsx +176 -115
- package/lib/components/Slideshow.tsx +68 -69
- package/lib/components/SlidingDrawer.tsx +72 -29
- package/lib/components/Spinner.tsx +6 -2
- package/lib/components/Toast.tsx +89 -0
- package/lib/components/context/Field.tsx +27 -0
- package/lib/icons/Minus.tsx +24 -0
- package/lib/icons/Plus.tsx +23 -0
- package/lib/theme/Button.recipe.tsx +11 -1
- package/lib/theme/CircleProgress.recipe.tsx +3 -3
- package/lib/theme/Field.recipe.tsx +17 -2
- package/lib/theme/Input.recipe.tsx +12 -3
- package/lib/theme/NumberInput.recipe.tsx +9 -4
- package/lib/theme/RadioGroup.recipe.tsx +7 -1
- package/lib/theme/Select.recipe.tsx +7 -7
- package/lib/theme/Slider.recipe.tsx +366 -22
- package/lib/theme/Slideshow.recipe.tsx +1 -1
- package/lib/theme/SlidingDrawer.recipe.tsx +58 -4
- package/lib/theme/Toast.recipe.tsx +71 -0
- package/package.json +3 -2
- package/lib/components/NewSelect.tsx +0 -202
- package/lib/components/index.tsx +0 -83
- package/lib/components/layoutTest.tsx +0 -74
- package/lib/theme/Button.recipe-old.tsx +0 -67
|
@@ -3,6 +3,7 @@ import {type LayoutChangeEvent, View} from 'react-native'
|
|
|
3
3
|
import {StyleSheet, UnistylesVariants} from 'react-native-unistyles'
|
|
4
4
|
import {Gesture, GestureDetector} from 'react-native-gesture-handler'
|
|
5
5
|
import Animated, {
|
|
6
|
+
useAnimatedReaction,
|
|
6
7
|
useAnimatedStyle,
|
|
7
8
|
useSharedValue,
|
|
8
9
|
} from 'react-native-reanimated'
|
|
@@ -12,6 +13,11 @@ import {PalettesWithNestedKeys} from '../style/varia/types'
|
|
|
12
13
|
|
|
13
14
|
type SliderVariants = UnistylesVariants<typeof SliderStyles>
|
|
14
15
|
|
|
16
|
+
type ThumbStyleExtended = ReturnType<typeof SliderStyles.thumb> & {
|
|
17
|
+
width: number
|
|
18
|
+
height: number
|
|
19
|
+
}
|
|
20
|
+
|
|
15
21
|
type SliderProps = SliderVariants & {
|
|
16
22
|
colorPalette?: PalettesWithNestedKeys
|
|
17
23
|
thickness?: number
|
|
@@ -23,7 +29,6 @@ type SliderProps = SliderVariants & {
|
|
|
23
29
|
height: number
|
|
24
30
|
}
|
|
25
31
|
thumbChildren?: React.ReactNode
|
|
26
|
-
axis: 'x' | 'y'
|
|
27
32
|
steps?: number
|
|
28
33
|
value?: number
|
|
29
34
|
onValueChange?: (value: number) => void
|
|
@@ -42,36 +47,34 @@ const Slider = ({
|
|
|
42
47
|
onValueChange,
|
|
43
48
|
onSlidingComplete,
|
|
44
49
|
}: SliderProps) => {
|
|
45
|
-
let styles
|
|
46
|
-
if (axis === 'x') {
|
|
47
|
-
|
|
48
|
-
} else {
|
|
49
|
-
|
|
50
|
-
}
|
|
50
|
+
// let styles
|
|
51
|
+
// if (axis === 'x') {
|
|
52
|
+
// styles = stylesX
|
|
53
|
+
// } else {
|
|
54
|
+
// styles = stylesY
|
|
55
|
+
// }
|
|
51
56
|
SliderStyles.useVariants({
|
|
52
57
|
size,
|
|
53
58
|
variant,
|
|
59
|
+
axis,
|
|
54
60
|
})
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
styles.useVariants({
|
|
62
|
+
axis,
|
|
63
|
+
})
|
|
64
|
+
const thumbStyle = SliderStyles.thumb(colorPalette) as ThumbStyleExtended
|
|
58
65
|
|
|
59
|
-
const halfSize =
|
|
60
|
-
|
|
61
|
-
width: thumbStyle.width,
|
|
62
|
-
height: thumbStyle.height,
|
|
63
|
-
}
|
|
64
|
-
const maximumTrackWidth = maximumTrackStyle.height ?? 0
|
|
65
|
-
const minimumTrackWidth = minimumTrackStyle.height ?? 0
|
|
66
|
+
const halfSize =
|
|
67
|
+
axis === 'x' ? (thumbStyle.width ?? 0) / 2 : (thumbStyle.height ?? 0) / 2
|
|
66
68
|
const context = useSharedValue({x: 0})
|
|
67
69
|
const translate = useSharedValue(value)
|
|
68
70
|
const trackLength = useSharedValue(0)
|
|
69
71
|
const isInsideChild = useSharedValue(false)
|
|
70
72
|
|
|
71
|
-
const handleTrackLayout = (event: LayoutChangeEvent) => {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
// const handleTrackLayout = (event: LayoutChangeEvent) => {
|
|
74
|
+
// const {width, height} = event.nativeEvent.layout
|
|
75
|
+
// console.log('🚀 ~ handleTrackLayout ~ width:', width)
|
|
76
|
+
// trackLength.value = axis === 'x' ? width : height
|
|
77
|
+
// }
|
|
75
78
|
|
|
76
79
|
const slideGesture = Gesture.Pan()
|
|
77
80
|
.onTouchesDown(() => {
|
|
@@ -81,6 +84,7 @@ const Slider = ({
|
|
|
81
84
|
context.value.x = translate.value
|
|
82
85
|
})
|
|
83
86
|
.onUpdate(e => {
|
|
87
|
+
// console.log('e', e.translationX)
|
|
84
88
|
const stepLength = steps ? trackLength.value / steps : 1
|
|
85
89
|
const delta = axis === 'y' ? -e.translationY : e.translationX
|
|
86
90
|
|
|
@@ -161,17 +165,18 @@ const Slider = ({
|
|
|
161
165
|
return (
|
|
162
166
|
<View
|
|
163
167
|
style={[
|
|
164
|
-
styles.container(
|
|
168
|
+
styles.container(halfSize),
|
|
165
169
|
SliderStyles.container(colorPalette),
|
|
166
170
|
]}>
|
|
167
171
|
{axis === 'x' && <View style={{width: halfSize}} />}
|
|
168
172
|
<GestureDetector gesture={tapGesture}>
|
|
169
173
|
<View
|
|
170
174
|
style={[
|
|
171
|
-
styles.maximumTrack(
|
|
175
|
+
styles.maximumTrack(),
|
|
172
176
|
SliderStyles.maximumTrack(colorPalette),
|
|
173
177
|
]}
|
|
174
|
-
onLayout={handleTrackLayout}
|
|
178
|
+
// onLayout={handleTrackLayout}
|
|
179
|
+
>
|
|
175
180
|
{steps && (
|
|
176
181
|
<View style={styles.steps}>
|
|
177
182
|
{Array.from({length: steps + 1}, (_, index) => index).map(
|
|
@@ -189,7 +194,7 @@ const Slider = ({
|
|
|
189
194
|
)}
|
|
190
195
|
<Animated.View
|
|
191
196
|
style={[
|
|
192
|
-
styles.minimumTrack(halfSize
|
|
197
|
+
styles.minimumTrack(halfSize),
|
|
193
198
|
SliderStyles.minimumTrack(colorPalette, opacityTrack),
|
|
194
199
|
animatedTrack,
|
|
195
200
|
]}>
|
|
@@ -197,7 +202,7 @@ const Slider = ({
|
|
|
197
202
|
<View
|
|
198
203
|
style={[
|
|
199
204
|
SliderStyles.thumb(colorPalette),
|
|
200
|
-
styles.thumb(halfSize
|
|
205
|
+
styles.thumb(halfSize),
|
|
201
206
|
]}>
|
|
202
207
|
{ThumbChildren || null}
|
|
203
208
|
</View>
|
|
@@ -210,115 +215,171 @@ const Slider = ({
|
|
|
210
215
|
)
|
|
211
216
|
}
|
|
212
217
|
|
|
213
|
-
const
|
|
214
|
-
container: (
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
left: halfSize * -1,
|
|
234
|
-
bottom: 'auto',
|
|
235
|
-
paddingBottom: 0,
|
|
236
|
-
paddingLeft: halfSize,
|
|
237
|
-
borderBottomLeftRadius: 20,
|
|
238
|
-
borderBottomRightRadius: 0,
|
|
239
|
-
borderTopLeftRadius: 20,
|
|
240
|
-
justifyContent: 'center',
|
|
241
|
-
}),
|
|
242
|
-
thumb: (halfSize, thumbSize) => ({
|
|
243
|
-
width: halfSize ? thumbSize.width : thumbSize.width,
|
|
244
|
-
height: thumbSize.height,
|
|
245
|
-
borderRadius: 25,
|
|
246
|
-
position: 'absolute',
|
|
247
|
-
right: 0,
|
|
248
|
-
zIndex: 2,
|
|
249
|
-
transform: [{translateX: '50%'}],
|
|
250
|
-
}),
|
|
251
|
-
steps: {
|
|
252
|
-
width: '100%',
|
|
253
|
-
height: '100%',
|
|
254
|
-
flexDirection: 'row',
|
|
255
|
-
justifyContent: 'space-between',
|
|
256
|
-
alignItems: 'center',
|
|
257
|
-
zIndex: 0,
|
|
258
|
-
position: 'absolute',
|
|
259
|
-
},
|
|
260
|
-
step: (index, length) => ({
|
|
261
|
-
width: 1,
|
|
262
|
-
height: '100%',
|
|
263
|
-
backgroundColor:
|
|
264
|
-
index === 0 || index === length ? 'transparent' : theme.colors.fg.default,
|
|
218
|
+
const styles = StyleSheet.create(theme => ({
|
|
219
|
+
container: (halfSize: number) => ({
|
|
220
|
+
variants: {
|
|
221
|
+
axis: {
|
|
222
|
+
x: {
|
|
223
|
+
maxWidth: 'auto',
|
|
224
|
+
width: '100%',
|
|
225
|
+
paddingTop: 0,
|
|
226
|
+
paddingRight: halfSize,
|
|
227
|
+
flexDirection: 'row',
|
|
228
|
+
},
|
|
229
|
+
y: {
|
|
230
|
+
maxHeight: 'auto',
|
|
231
|
+
height: '100%',
|
|
232
|
+
paddingTop: halfSize,
|
|
233
|
+
paddingRight: 0,
|
|
234
|
+
flexDirection: 'column',
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
},
|
|
265
238
|
}),
|
|
266
|
-
|
|
267
|
-
const stylesY = StyleSheet.create(theme => ({
|
|
268
|
-
container: (maximumTrackWidth, halfSize) => ({
|
|
269
|
-
flex: 1,
|
|
270
|
-
maxWidth: maximumTrackWidth,
|
|
271
|
-
maxHeight: 'auto',
|
|
272
|
-
borderRadius: 22,
|
|
273
|
-
width: '100%',
|
|
274
|
-
height: '100%',
|
|
275
|
-
paddingTop: halfSize,
|
|
276
|
-
paddingRight: 0,
|
|
277
|
-
flexDirection: 'column',
|
|
278
|
-
}),
|
|
279
|
-
maximumTrack: maximumTrackWidth => ({
|
|
239
|
+
maximumTrack: () => ({
|
|
280
240
|
flex: 1,
|
|
281
241
|
justifyContent: 'center',
|
|
282
|
-
alignItems: 'center',
|
|
283
242
|
position: 'relative',
|
|
284
|
-
|
|
243
|
+
variants: {
|
|
244
|
+
axis: {
|
|
245
|
+
x: {},
|
|
246
|
+
y: {
|
|
247
|
+
alignItems: 'center',
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
},
|
|
285
251
|
}),
|
|
286
|
-
minimumTrack: (halfSize
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
252
|
+
minimumTrack: (halfSize: number) => ({
|
|
253
|
+
variants: {
|
|
254
|
+
axis: {
|
|
255
|
+
x: {
|
|
256
|
+
width: '100%',
|
|
257
|
+
left: halfSize * -1,
|
|
258
|
+
bottom: 'auto',
|
|
259
|
+
paddingBottom: 0,
|
|
260
|
+
paddingLeft: halfSize,
|
|
261
|
+
borderBottomLeftRadius: 20,
|
|
262
|
+
borderBottomRightRadius: 0,
|
|
263
|
+
borderTopLeftRadius: 20,
|
|
264
|
+
justifyContent: 'center',
|
|
265
|
+
},
|
|
266
|
+
y: {
|
|
267
|
+
position: 'absolute',
|
|
268
|
+
height: '100%',
|
|
269
|
+
left: 'auto',
|
|
270
|
+
bottom: halfSize * -1,
|
|
271
|
+
paddingBottom: halfSize,
|
|
272
|
+
paddingLeft: 0,
|
|
273
|
+
borderBottomLeftRadius: 20,
|
|
274
|
+
borderBottomRightRadius: 20,
|
|
275
|
+
borderTopLeftRadius: 0,
|
|
276
|
+
alignItems: 'center',
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
},
|
|
298
280
|
}),
|
|
299
|
-
thumb:
|
|
281
|
+
thumb: halfSize => ({
|
|
300
282
|
borderRadius: 25,
|
|
301
283
|
position: 'absolute',
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
284
|
+
variants: {
|
|
285
|
+
axis: {
|
|
286
|
+
x: {
|
|
287
|
+
right: 0,
|
|
288
|
+
zIndex: 2,
|
|
289
|
+
transform: [{translateX: '50%'}],
|
|
290
|
+
},
|
|
291
|
+
y: {
|
|
292
|
+
top: 0,
|
|
293
|
+
zIndex: 2,
|
|
294
|
+
transform: [{translateY: halfSize * -1}],
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
},
|
|
307
298
|
}),
|
|
308
299
|
steps: {
|
|
309
300
|
width: '100%',
|
|
310
301
|
height: '100%',
|
|
311
|
-
flexDirection: 'column',
|
|
312
302
|
justifyContent: 'space-between',
|
|
313
303
|
alignItems: 'center',
|
|
314
304
|
zIndex: 0,
|
|
305
|
+
variants: {
|
|
306
|
+
axis: {
|
|
307
|
+
x: {
|
|
308
|
+
flexDirection: 'row',
|
|
309
|
+
position: 'absolute',
|
|
310
|
+
},
|
|
311
|
+
y: {
|
|
312
|
+
flexDirection: 'column',
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
},
|
|
315
316
|
},
|
|
316
317
|
step: (index, length) => ({
|
|
317
|
-
width: '100%',
|
|
318
|
-
height: 1,
|
|
319
318
|
backgroundColor:
|
|
320
319
|
index === 0 || index === length ? 'transparent' : theme.colors.fg.default,
|
|
320
|
+
variants: {
|
|
321
|
+
axis: {
|
|
322
|
+
x: {
|
|
323
|
+
width: 1,
|
|
324
|
+
height: '100%',
|
|
325
|
+
},
|
|
326
|
+
y: {
|
|
327
|
+
width: '100%',
|
|
328
|
+
height: 1,
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
},
|
|
321
332
|
}),
|
|
322
333
|
}))
|
|
334
|
+
// const stylesY = StyleSheet.create(theme => ({
|
|
335
|
+
// container: halfSize => ({
|
|
336
|
+
// maxHeight: 'auto',
|
|
337
|
+
// height: '100%',
|
|
338
|
+
// paddingTop: halfSize,
|
|
339
|
+
// paddingRight: 0,
|
|
340
|
+
// flexDirection: 'column',
|
|
341
|
+
// }),
|
|
342
|
+
// maximumTrack: () => ({
|
|
343
|
+
// flex: 1,
|
|
344
|
+
// justifyContent: 'center',
|
|
345
|
+
// alignItems: 'center',
|
|
346
|
+
// position: 'relative',
|
|
347
|
+
// // borderWidth: 1,
|
|
348
|
+
// // borderColor: 'yellow',
|
|
349
|
+
// }),
|
|
350
|
+
// minimumTrack: halfSize => ({
|
|
351
|
+
// position: 'absolute',
|
|
352
|
+
// height: '100%',
|
|
353
|
+
// left: 'auto',
|
|
354
|
+
// bottom: halfSize * -1,
|
|
355
|
+
// paddingBottom: halfSize,
|
|
356
|
+
// paddingLeft: 0,
|
|
357
|
+
// borderBottomLeftRadius: 20,
|
|
358
|
+
// borderBottomRightRadius: 20,
|
|
359
|
+
// borderTopLeftRadius: 0,
|
|
360
|
+
// alignItems: 'center',
|
|
361
|
+
// }),
|
|
362
|
+
// thumb: halfSize => ({
|
|
363
|
+
// borderRadius: 25,
|
|
364
|
+
// position: 'absolute',
|
|
365
|
+
// top: 0,
|
|
366
|
+
// zIndex: 2,
|
|
367
|
+
// transform: [{translateY: halfSize * -1}],
|
|
368
|
+
// }),
|
|
369
|
+
// steps: {
|
|
370
|
+
// width: '100%',
|
|
371
|
+
// height: '100%',
|
|
372
|
+
// justifyContent: 'space-between',
|
|
373
|
+
// alignItems: 'center',
|
|
374
|
+
// zIndex: 0,
|
|
375
|
+
// flexDirection: 'column',
|
|
376
|
+
// },
|
|
377
|
+
// step: (index, length) => ({
|
|
378
|
+
// width: '100%',
|
|
379
|
+
// height: 1,
|
|
380
|
+
// backgroundColor:
|
|
381
|
+
// index === 0 || index === length ? 'transparent' : theme.colors.fg.default,
|
|
382
|
+
// }),
|
|
383
|
+
// }))
|
|
323
384
|
|
|
324
385
|
export default Slider
|
|
@@ -7,7 +7,7 @@ import Animated, {
|
|
|
7
7
|
withSpring,
|
|
8
8
|
withTiming,
|
|
9
9
|
} from 'react-native-reanimated'
|
|
10
|
-
import {
|
|
10
|
+
import {scheduleOnRN} from 'react-native-worklets'
|
|
11
11
|
import {StyleSheet, UnistylesVariants} from 'react-native-unistyles'
|
|
12
12
|
import {Gesture, GestureDetector} from 'react-native-gesture-handler'
|
|
13
13
|
import {SlideshowStyles, SlideshowTokens} from '../theme/Slideshow.recipe'
|
|
@@ -20,30 +20,21 @@ export type SlideshowRef = {
|
|
|
20
20
|
|
|
21
21
|
type SlideshowVariants = UnistylesVariants<typeof SlideshowStyles>
|
|
22
22
|
|
|
23
|
+
type Axis = 'x' | 'y'
|
|
24
|
+
|
|
23
25
|
type SlideshowProps = SlideshowVariants & {
|
|
26
|
+
axis?: Axis
|
|
24
27
|
animation?: keyof typeof SlideshowTokens.variants.animation
|
|
25
28
|
colorPalette?: PalettesWithNestedKeys
|
|
26
29
|
allowGestures?: boolean
|
|
27
30
|
flex?: number
|
|
28
31
|
onSlideChange?: (index: number) => void
|
|
29
|
-
slideContainerType?: any
|
|
30
32
|
children: ReactNode
|
|
31
|
-
ref?: React.RefObject<SlideshowRef>
|
|
33
|
+
ref?: React.RefObject<SlideshowRef | null>
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
/**
|
|
35
|
-
* Flex Wrapper
|
|
36
|
-
* @param colorScheme ? string: color scheme
|
|
37
|
-
* @param animation ? string: animation props
|
|
38
|
-
* @param allowGestures ? boolean: allow gestures
|
|
39
|
-
* @param flex ? number: flex value
|
|
40
|
-
* @param onSlideChange ? function: callback function
|
|
41
|
-
* @param slideContainerType ? color scheme
|
|
42
|
-
* @param children ? react children
|
|
43
|
-
* @param ref ? react ref
|
|
44
|
-
* @returns Slideshow react component
|
|
45
|
-
*/
|
|
46
36
|
const Slideshow = ({
|
|
37
|
+
axis = 'x',
|
|
47
38
|
colorPalette = 'accent',
|
|
48
39
|
variant = 'solid',
|
|
49
40
|
allowGestures = true,
|
|
@@ -53,6 +44,8 @@ const Slideshow = ({
|
|
|
53
44
|
children,
|
|
54
45
|
ref,
|
|
55
46
|
}: SlideshowProps) => {
|
|
47
|
+
const isHorizontal = axis === 'x'
|
|
48
|
+
|
|
56
49
|
const slides = Children.toArray(children)
|
|
57
50
|
const NUM_PAGES = slides.length
|
|
58
51
|
const scalingFactor = 1 / NUM_PAGES
|
|
@@ -62,17 +55,17 @@ const Slideshow = ({
|
|
|
62
55
|
})
|
|
63
56
|
|
|
64
57
|
const [containerWidth, setContainerWidth] = useState(0)
|
|
58
|
+
const [containerHeight, setContainerHeight] = useState(0)
|
|
59
|
+
|
|
60
|
+
const dimension = isHorizontal ? containerWidth : containerHeight
|
|
61
|
+
const slideSize = 100 / NUM_PAGES
|
|
65
62
|
|
|
66
|
-
const
|
|
67
|
-
const translateX = useSharedValue(0)
|
|
63
|
+
const translate = useSharedValue(0)
|
|
68
64
|
const currentSlide = useSharedValue(0)
|
|
69
65
|
|
|
70
66
|
type AnimationType = 'withSpring' | 'withTiming'
|
|
67
|
+
const animations = {withSpring, withTiming}
|
|
71
68
|
|
|
72
|
-
const animations = {
|
|
73
|
-
withSpring,
|
|
74
|
-
withTiming,
|
|
75
|
-
}
|
|
76
69
|
const animationVariant =
|
|
77
70
|
SlideshowTokens.variants?.animation && animation
|
|
78
71
|
? SlideshowTokens.variants.animation[animation]
|
|
@@ -88,18 +81,14 @@ const Slideshow = ({
|
|
|
88
81
|
const animateSlide = (destination: number) => {
|
|
89
82
|
'worklet'
|
|
90
83
|
|
|
91
|
-
if (
|
|
92
|
-
animationVariant
|
|
93
|
-
animationVariant.type &&
|
|
94
|
-
animations[animationVariant.type]
|
|
95
|
-
) {
|
|
96
|
-
translateX.value = animations[animationVariant.type](
|
|
84
|
+
if (animationVariant.type && animations[animationVariant.type]) {
|
|
85
|
+
translate.value = animations[animationVariant.type](
|
|
97
86
|
destination,
|
|
98
87
|
animationVariant.props,
|
|
99
88
|
)
|
|
100
89
|
|
|
101
90
|
if (onSlideChange) {
|
|
102
|
-
|
|
91
|
+
scheduleOnRN(onSlideChange, (destination / 100) * NUM_PAGES * -1)
|
|
103
92
|
}
|
|
104
93
|
}
|
|
105
94
|
}
|
|
@@ -107,68 +96,73 @@ const Slideshow = ({
|
|
|
107
96
|
useAnimatedReaction(
|
|
108
97
|
() => currentSlide.value,
|
|
109
98
|
() => {
|
|
110
|
-
animateSlide(-currentSlide.value *
|
|
99
|
+
animateSlide(-currentSlide.value * slideSize)
|
|
111
100
|
},
|
|
112
101
|
)
|
|
113
102
|
|
|
114
|
-
const
|
|
103
|
+
const nextSlide = () => {
|
|
115
104
|
'worklet'
|
|
116
|
-
if (currentSlide.value > 0)
|
|
117
|
-
currentSlide.value -= 1
|
|
118
|
-
}
|
|
105
|
+
if (currentSlide.value > 0) currentSlide.value -= 1
|
|
119
106
|
}
|
|
120
|
-
|
|
107
|
+
|
|
108
|
+
const prevSlide = () => {
|
|
121
109
|
'worklet'
|
|
122
|
-
if (currentSlide.value < NUM_PAGES - 1)
|
|
123
|
-
currentSlide.value += 1
|
|
124
|
-
}
|
|
110
|
+
if (currentSlide.value < NUM_PAGES - 1) currentSlide.value += 1
|
|
125
111
|
}
|
|
126
112
|
|
|
127
|
-
const context = useSharedValue({x: 0
|
|
113
|
+
const context = useSharedValue({x: 0})
|
|
128
114
|
const velocityThreshold = 500
|
|
129
115
|
|
|
130
116
|
const slideGesture = Gesture.Pan()
|
|
131
117
|
.enabled(allowGestures)
|
|
132
118
|
.onBegin(() => {
|
|
133
|
-
context.value.x =
|
|
119
|
+
context.value.x = translate.value
|
|
134
120
|
})
|
|
135
121
|
.onUpdate(e => {
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
122
|
+
const translation = isHorizontal ? e.translationX : e.translationY
|
|
123
|
+
|
|
124
|
+
const pixelToPercentage = (translation / dimension) * 100 * scalingFactor
|
|
125
|
+
|
|
126
|
+
translate.value = context.value.x + pixelToPercentage
|
|
139
127
|
})
|
|
140
|
-
.onEnd(({velocityX, translationX}) => {
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
128
|
+
.onEnd(({velocityX, velocityY, translationX, translationY}) => {
|
|
129
|
+
const translation = isHorizontal ? translationX : translationY
|
|
130
|
+
const velocity = isHorizontal ? velocityX : velocityY
|
|
131
|
+
|
|
132
|
+
const pixelToPercentage = (translation / dimension) * 100 * scalingFactor
|
|
144
133
|
|
|
134
|
+
const slideWidthPercentage = 100 / NUM_PAGES
|
|
145
135
|
const currentIndex = Math.round(-context.value.x / slideWidthPercentage)
|
|
146
136
|
|
|
147
137
|
let targetIndex
|
|
148
|
-
if (Math.abs(
|
|
149
|
-
targetIndex =
|
|
138
|
+
if (Math.abs(velocity) > velocityThreshold) {
|
|
139
|
+
targetIndex = velocity > 0 ? currentIndex - 1 : currentIndex + 1
|
|
150
140
|
} else {
|
|
151
|
-
const
|
|
152
|
-
|
|
141
|
+
const crossed = Math.abs(pixelToPercentage) > slideWidthPercentage / 2
|
|
142
|
+
|
|
153
143
|
targetIndex =
|
|
154
|
-
|
|
144
|
+
crossed && pixelToPercentage < 0
|
|
155
145
|
? currentIndex + 1
|
|
156
|
-
:
|
|
146
|
+
: crossed
|
|
157
147
|
? currentIndex - 1
|
|
158
148
|
: currentIndex
|
|
159
149
|
}
|
|
150
|
+
|
|
160
151
|
targetIndex = Math.max(0, Math.min(NUM_PAGES - 1, targetIndex))
|
|
152
|
+
|
|
161
153
|
animateSlide(-targetIndex * slideWidthPercentage)
|
|
162
154
|
currentSlide.value = targetIndex
|
|
163
155
|
})
|
|
164
156
|
|
|
165
|
-
const animatedStyle = useAnimatedStyle(() =>
|
|
166
|
-
|
|
167
|
-
|
|
157
|
+
const animatedStyle = useAnimatedStyle(() =>
|
|
158
|
+
isHorizontal
|
|
159
|
+
? {transform: [{translateX: `${translate.value}%`}]}
|
|
160
|
+
: {transform: [{translateY: `${translate.value}%`}]},
|
|
161
|
+
)
|
|
168
162
|
|
|
169
163
|
useImperativeHandle(ref, () => ({
|
|
170
|
-
handlePrev,
|
|
171
|
-
handleNext,
|
|
164
|
+
handlePrev: nextSlide,
|
|
165
|
+
handleNext: prevSlide,
|
|
172
166
|
}))
|
|
173
167
|
|
|
174
168
|
return (
|
|
@@ -176,17 +170,20 @@ const Slideshow = ({
|
|
|
176
170
|
<GestureDetector gesture={slideGesture}>
|
|
177
171
|
<View
|
|
178
172
|
style={[styles.container(), SlideshowStyles.container(colorPalette)]}
|
|
179
|
-
onLayout={e =>
|
|
173
|
+
onLayout={e => {
|
|
174
|
+
setContainerWidth(e.nativeEvent.layout.width)
|
|
175
|
+
setContainerHeight(e.nativeEvent.layout.height)
|
|
176
|
+
}}>
|
|
180
177
|
<Animated.View
|
|
181
178
|
style={[
|
|
182
|
-
styles.slidesContainer(`${NUM_PAGES * 100}
|
|
179
|
+
styles.slidesContainer(`${NUM_PAGES * 100}%`, isHorizontal),
|
|
183
180
|
animatedStyle,
|
|
184
181
|
]}>
|
|
185
182
|
{slides.map((Slide, index) => (
|
|
186
183
|
<View
|
|
187
184
|
key={index}
|
|
188
185
|
style={[
|
|
189
|
-
styles.slide(`${
|
|
186
|
+
styles.slide(`${slideSize}%`, isHorizontal),
|
|
190
187
|
SlideshowStyles.slideContainer(colorPalette),
|
|
191
188
|
]}>
|
|
192
189
|
{Slide}
|
|
@@ -206,24 +203,26 @@ const styles = StyleSheet.create({
|
|
|
206
203
|
flex,
|
|
207
204
|
flexDirection: 'row',
|
|
208
205
|
}),
|
|
206
|
+
|
|
209
207
|
container: () => ({
|
|
210
|
-
zIndex: 1,
|
|
211
208
|
width: '100%',
|
|
212
209
|
height: '100%',
|
|
213
210
|
overflow: 'hidden',
|
|
214
211
|
justifyContent: 'flex-start',
|
|
215
212
|
alignItems: 'flex-start',
|
|
216
|
-
backgroundColor: 'white',
|
|
217
|
-
borderRadius: 16,
|
|
218
213
|
}),
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
214
|
+
|
|
215
|
+
slidesContainer: (size, isHorizontal) => ({
|
|
216
|
+
flexDirection: isHorizontal ? 'row' : 'column',
|
|
217
|
+
width: isHorizontal ? size : '100%',
|
|
218
|
+
minHeight: isHorizontal ? '100%' : size,
|
|
222
219
|
flex: 1,
|
|
223
220
|
}),
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
221
|
+
|
|
222
|
+
slide: (size, isHorizontal) => ({
|
|
223
|
+
overflow: 'hidden',
|
|
224
|
+
width: isHorizontal ? size : '100%',
|
|
225
|
+
height: isHorizontal ? '100%' : size,
|
|
227
226
|
justifyContent: 'center',
|
|
228
227
|
alignItems: 'center',
|
|
229
228
|
}),
|