react-native-varia 0.5.1 → 0.6.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.
Files changed (31) hide show
  1. package/lib/components/{ui/Accordion.tsx → Accordion.tsx} +55 -27
  2. package/lib/components/{ui/Badge.tsx → Badge.tsx} +12 -6
  3. package/lib/components/{ui/Button.tsx → Button.tsx} +18 -6
  4. package/lib/components/{ui/Checkbox.tsx → Checkbox.tsx} +22 -4
  5. package/lib/components/{ui/CircleProgress.tsx → CircleProgress.tsx} +7 -3
  6. package/lib/components/{ui/Divider.tsx → Divider.tsx} +7 -3
  7. package/lib/components/{ui/Drawer.tsx → Drawer.tsx} +73 -25
  8. package/lib/components/{ui/Field.tsx → Field.tsx} +12 -6
  9. package/lib/components/{ui/FloatingAction.tsx → FloatingAction.tsx} +15 -4
  10. package/lib/components/{ui/GradientBackground.tsx → GradientBackground.tsx} +1 -1
  11. package/lib/components/{ui/GradientText.tsx → GradientText.tsx} +15 -5
  12. package/lib/components/{ui/IconWrapper.tsx → IconWrapper.tsx} +2 -2
  13. package/lib/components/{ui/Input.tsx → Input.tsx} +11 -6
  14. package/lib/components/{ui/Link.tsx → Link.tsx} +7 -7
  15. package/lib/components/{ui/Modal.tsx → Modal.tsx} +42 -13
  16. package/lib/components/{ui/NumberInput.tsx → NumberInput.tsx} +44 -23
  17. package/lib/components/{ui/RadioGroup.tsx → RadioGroup.tsx} +35 -6
  18. package/lib/components/{ui/ReText.tsx → ReText.tsx} +1 -1
  19. package/lib/components/{ui/Select.tsx → Select.tsx} +61 -8
  20. package/lib/components/Slider.tsx +500 -0
  21. package/lib/components/{ui/Slideshow.tsx → Slideshow.tsx} +12 -3
  22. package/lib/components/{ui/Switch.tsx → Switch.tsx} +15 -3
  23. package/lib/components/{ui/Text.tsx → Text.tsx} +2 -2
  24. package/lib/components/{ui/Toast.tsx → Toast.tsx} +14 -3
  25. package/lib/components/context/Field.tsx +4 -2
  26. package/lib/varia/types.ts +6 -0
  27. package/lib/varia/utils.ts +7 -0
  28. package/package.json +1 -1
  29. package/lib/components/ui/Slider.tsx +0 -498
  30. package/lib/components/ui/context/Field.tsx +0 -27
  31. /package/lib/components/{ui/Spinner.tsx → Spinner.tsx} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-varia",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "bin": {
5
5
  "varia": "bin/cli.js"
6
6
  },
@@ -1,498 +0,0 @@
1
- import React from 'react'
2
- import {type LayoutChangeEvent, View, ViewStyle} from 'react-native'
3
- import {StyleSheet, UnistylesVariants} from 'react-native-unistyles'
4
- import {Gesture, GestureDetector} from 'react-native-gesture-handler'
5
- import Animated, {
6
- useAnimatedStyle,
7
- useSharedValue,
8
- } from 'react-native-reanimated'
9
- import {runOnJS} from 'react-native-worklets'
10
- import {SliderStyles, SliderDefaultVariants} from '../../theme/Slider.recipe'
11
- import {PalettesWithNestedKeys} from '../../style/varia/types'
12
- import {getCompoundVariantValue} from '../../style/varia/utils'
13
-
14
- function throttle<T extends (...args: any[]) => any>(
15
- func: T,
16
- limit = 50,
17
- ): (...args: Parameters<T>) => void {
18
- let inThrottle = false
19
- return (...args: Parameters<T>) => {
20
- if (!inThrottle) {
21
- func(...(args as Parameters<T>))
22
- inThrottle = true
23
- setTimeout(() => {
24
- inThrottle = false
25
- }, limit)
26
- }
27
- }
28
- }
29
-
30
- type SliderVariants = UnistylesVariants<typeof SliderStyles>
31
-
32
- const AnimatedView = Animated.createAnimatedComponent(View)
33
-
34
- type ThumbStyleExtended = ReturnType<typeof SliderStyles.thumb> & {
35
- width: number
36
- height: number
37
- }
38
-
39
- type SliderProps = SliderVariants & {
40
- colorPalette?: PalettesWithNestedKeys
41
- thickness?: number
42
- minimumTrackThickness?: number
43
- minimumTrackColor?: string
44
- thumbSize?: {
45
- width: number
46
- height: number
47
- }
48
- thumbChildren?: React.ReactNode
49
- steps?: number
50
- value?: number
51
- onValueChange?: (value: number) => void
52
- onSlidingComplete?: (value: number) => void
53
- flex?: ViewStyle['flex']
54
- alignSelf?: ViewStyle['alignSelf']
55
- }
56
-
57
- const Slider = ({
58
- colorPalette = 'accent',
59
- variant = SliderDefaultVariants.variant,
60
- size = SliderDefaultVariants.size,
61
- thumbChildren: ThumbChildren,
62
- axis = 'x',
63
- value = 0,
64
- steps,
65
- onValueChange,
66
- onSlidingComplete,
67
- flex = 0,
68
- alignSelf = 'auto',
69
- }: SliderProps) => {
70
- SliderStyles.useVariants({
71
- size,
72
- variant,
73
- axis,
74
- })
75
- styles.useVariants({
76
- axis,
77
- })
78
-
79
- const throttledOnValueChange = React.useMemo(() => {
80
- if (!onValueChange) return undefined
81
- return throttle(onValueChange, 50)
82
- }, [onValueChange])
83
-
84
- // const thumbStyle = SliderStyles.thumb(colorPalette) as ThumbStyleExtended
85
- // const thumbWidth = getVariantValue(SliderStyles.thumb(colorPalette), 'size', size, 'width', true)
86
- const thumbWidth = getCompoundVariantValue(
87
- SliderStyles.thumb(colorPalette),
88
- {axis, size},
89
- 'width',
90
- )
91
- const thumbHeight = getCompoundVariantValue(
92
- SliderStyles.thumb(colorPalette),
93
- {axis, size},
94
- 'height',
95
- )
96
- // const thumbHeight = getVariantValue(SliderStyles.thumb(colorPalette), 'size', size, 'height', true)
97
-
98
- const halfSize = ((axis === 'x' ? thumbWidth : thumbHeight) ?? 0) / 2
99
- const context = useSharedValue({x: 0})
100
- const translate = useSharedValue(value)
101
- const trackLength = useSharedValue(0)
102
- const isInsideChild = useSharedValue(false)
103
-
104
- const handleTrackLayout = (event: LayoutChangeEvent) => {
105
- const {width, height} = event.nativeEvent.layout
106
- trackLength.value = axis === 'x' ? width : height
107
- }
108
-
109
- const slideGesture = Gesture.Pan()
110
- .onTouchesDown(() => {
111
- isInsideChild.value = true
112
- })
113
- .onBegin(() => {
114
- context.value.x = translate.value
115
- })
116
- .onUpdate(e => {
117
- const stepLength = steps ? trackLength.value / steps : 1
118
- const delta = axis === 'y' ? -e.translationY : e.translationX
119
-
120
- const rawValue = Math.max(
121
- 0,
122
- Math.min(context.value.x + delta, trackLength.value),
123
- )
124
-
125
- const snappedValue = steps
126
- ? Math.round(rawValue / stepLength) * stepLength
127
- : rawValue
128
-
129
- translate.value = snappedValue
130
-
131
- if (steps) {
132
- const stepIndex = Math.round(snappedValue / stepLength)
133
- throttledOnValueChange && runOnJS(throttledOnValueChange)(stepIndex)
134
- } else {
135
- throttledOnValueChange &&
136
- runOnJS(throttledOnValueChange)(
137
- Math.round((snappedValue / trackLength.value) * 100) / 100,
138
- )
139
- }
140
- })
141
- .onEnd(() => {
142
- const stepLength = steps ? trackLength.value / steps : 1
143
-
144
- const snappedValue = steps
145
- ? Math.round(translate.value / stepLength)
146
- : translate.value / trackLength.value
147
-
148
- onSlidingComplete && runOnJS(onSlidingComplete)(snappedValue)
149
- })
150
- .onFinalize(() => {
151
- isInsideChild.value = false
152
- })
153
-
154
- const tapGesture = Gesture.Tap()
155
- .onBegin(e => {
156
- if (isInsideChild.value) {
157
- return
158
- }
159
- const tapPosition = axis === 'x' ? e.x : e.y
160
- const stepLength = steps ? trackLength.value / steps : 1
161
-
162
- const rawValue =
163
- axis === 'y'
164
- ? Math.max(
165
- 0,
166
- Math.min(trackLength.value - tapPosition, trackLength.value),
167
- )
168
- : Math.max(0, Math.min(tapPosition, trackLength.value))
169
-
170
- const snappedValue = steps
171
- ? Math.round(rawValue / stepLength) * stepLength
172
- : rawValue
173
-
174
- translate.value = snappedValue
175
-
176
- if (steps) {
177
- const stepIndex = Math.round(snappedValue / stepLength)
178
- onValueChange && runOnJS(onValueChange)(stepIndex)
179
- onSlidingComplete && runOnJS(onSlidingComplete)(stepIndex)
180
- } else {
181
- const normalizedValue =
182
- Math.round((snappedValue / trackLength.value) * 100) / 100
183
- onValueChange && runOnJS(onValueChange)(normalizedValue)
184
- onSlidingComplete && runOnJS(onSlidingComplete)(normalizedValue)
185
- }
186
- })
187
- .simultaneousWithExternalGesture(slideGesture)
188
-
189
- const trackPan = Gesture.Pan()
190
- .onBegin(e => {
191
- if (trackLength.value <= 0) return
192
-
193
- const tapPosition = axis === 'x' ? e.x : e.y
194
- const stepLength = steps ? trackLength.value / steps : 1
195
-
196
- const rawValue =
197
- axis === 'y'
198
- ? Math.max(
199
- 0,
200
- Math.min(trackLength.value - tapPosition, trackLength.value),
201
- )
202
- : Math.max(0, Math.min(tapPosition, trackLength.value))
203
-
204
- const snappedValue = steps
205
- ? Math.round(rawValue / stepLength) * stepLength
206
- : rawValue
207
-
208
- context.value.x = snappedValue
209
- translate.value = snappedValue
210
-
211
- if (steps) {
212
- const stepIndex = Math.round(snappedValue / stepLength)
213
- onValueChange && runOnJS(onValueChange)(stepIndex)
214
- } else {
215
- const normalizedValue =
216
- Math.round((snappedValue / trackLength.value) * 100) / 100
217
- onValueChange && runOnJS(onValueChange)(normalizedValue)
218
- }
219
- })
220
- .onUpdate(e => {
221
- if (trackLength.value <= 0) return
222
-
223
- const stepLength = steps ? trackLength.value / steps : 1
224
- const delta = axis === 'y' ? -e.translationY : e.translationX
225
-
226
- const rawValue = Math.max(
227
- 0,
228
- Math.min(context.value.x + delta, trackLength.value),
229
- )
230
-
231
- if (steps) {
232
- const snappedValue = Math.round(rawValue / stepLength) * stepLength
233
- translate.value = snappedValue
234
-
235
- const stepIndex = Math.round(snappedValue / stepLength)
236
- throttledOnValueChange && runOnJS(throttledOnValueChange)(stepIndex)
237
- } else {
238
- translate.value = rawValue
239
- throttledOnValueChange &&
240
- runOnJS(throttledOnValueChange)(
241
- Math.round((rawValue / trackLength.value) * 100) / 100,
242
- )
243
- }
244
- })
245
- .onEnd(() => {
246
- const stepLength = steps ? trackLength.value / steps : 1
247
-
248
- const snappedValue = steps
249
- ? Math.round(translate.value / stepLength)
250
- : translate.value / trackLength.value
251
-
252
- onSlidingComplete && runOnJS(onSlidingComplete)(snappedValue)
253
- })
254
-
255
- const animatedTrack = useAnimatedStyle(() => {
256
- return {
257
- [axis === 'y' ? 'height' : 'width']: translate.value + halfSize,
258
- }
259
- })
260
-
261
- const animatedThumb = useAnimatedStyle(() => {
262
- if (axis === 'x') {
263
- return {
264
- transform: [{translateX: translate.value - halfSize}],
265
- }
266
- } else {
267
- const translateY = trackLength.value - translate.value - halfSize
268
- return {
269
- transform: [{translateY}],
270
- }
271
- }
272
- })
273
-
274
- return (
275
- <View
276
- testID="varia-slider-container"
277
- style={[
278
- styles.container(halfSize, flex, alignSelf),
279
- SliderStyles.container(colorPalette),
280
- ]}>
281
- {axis === 'x' && <View style={{width: halfSize}} />}
282
- <GestureDetector gesture={Gesture.Simultaneous(trackPan, tapGesture)}>
283
- <View
284
- testID="varia-slider-maximun-track"
285
- style={[
286
- styles.maximumTrack(),
287
- SliderStyles.maximumTrack(colorPalette),
288
- ]}
289
- onLayout={handleTrackLayout}>
290
- <AnimatedView
291
- testID="varia-slider-minimum-track"
292
- style={[
293
- styles.minimumTrack(halfSize),
294
- SliderStyles.minimumTrack(colorPalette),
295
- animatedTrack,
296
- ]}
297
- />
298
-
299
- {steps && (
300
- <View style={[styles.stepsOverlay]} pointerEvents="none">
301
- <View style={styles.steps} testID="varia-slider-steps">
302
- {Array.from({length: steps + 1}, (_, index) => index).map(
303
- (_, i) => (
304
- <View
305
- key={i}
306
- style={[
307
- styles.step(i, steps),
308
- SliderStyles.step(colorPalette),
309
- ]}
310
- />
311
- ),
312
- )}
313
- </View>
314
- </View>
315
- )}
316
- <GestureDetector gesture={slideGesture}>
317
- <View style={styles.thumbContainerFull} testID="varia-slider-tumb">
318
- <AnimatedView style={[animatedThumb, {flex: 1}]}>
319
- <View
320
- style={[
321
- SliderStyles.thumb(colorPalette),
322
- styles.thumb(halfSize),
323
- ]}>
324
- {ThumbChildren || null}
325
- </View>
326
- </AnimatedView>
327
- </View>
328
- </GestureDetector>
329
- </View>
330
- </GestureDetector>
331
- {axis === 'y' && <View style={{height: halfSize}} />}
332
- </View>
333
- )
334
- }
335
-
336
- const styles = StyleSheet.create(theme => ({
337
- container: (
338
- halfSize: number,
339
- flex: ViewStyle['flex'],
340
- alignSelf: ViewStyle['alignSelf'],
341
- ) => ({
342
- flex,
343
- alignSelf,
344
- overflow: 'hidden',
345
- // flexBasis: 'auto',
346
- variants: {
347
- axis: {
348
- x: {
349
- // maxWidth: 'auto',
350
- paddingTop: 0,
351
- paddingRight: halfSize,
352
- flexDirection: 'row',
353
- },
354
- y: {
355
- // maxHeight: 'auto',
356
- // height: '100%',
357
- paddingTop: halfSize,
358
- paddingRight: 0,
359
- flexDirection: 'column',
360
- },
361
- },
362
- },
363
- _web: {
364
- _classNames: 'slider-container-base',
365
- flex: flex === 0 ? undefined : flex,
366
- },
367
- }),
368
- maximumTrack: () => ({
369
- flex: 1,
370
- position: 'relative',
371
- overflow: 'visible',
372
- flexBasis: 'auto',
373
- variants: {
374
- axis: {
375
- x: {
376
- justifyContent: 'center',
377
- },
378
- y: {
379
- justifyContent: 'flex-end',
380
- },
381
- },
382
- },
383
- _web: {
384
- _classNames: 'slider-maximun-track-base',
385
- },
386
- }),
387
- minimumTrack: (halfSize: number) => ({
388
- flexBasis: 'auto',
389
- variants: {
390
- axis: {
391
- x: {
392
- flex: 1,
393
- marginLeft: halfSize * -1,
394
- width: '100%',
395
- bottom: 'auto',
396
- paddingBottom: 0,
397
- paddingLeft: halfSize,
398
- justifyContent: 'center',
399
- alignItems: 'flex-end',
400
- },
401
- y: {
402
- height: '100%',
403
- paddingBottom: halfSize,
404
- marginBottom: halfSize * -1,
405
- paddingLeft: 0,
406
- alignItems: 'flex-start',
407
- },
408
- },
409
- },
410
- _web: {
411
- _classNames: 'slider-minimum-track-base',
412
- },
413
- }),
414
- thumbContainerFull: {
415
- position: 'absolute',
416
- left: 0,
417
- right: 0,
418
- top: 0,
419
- bottom: 0,
420
- zIndex: 2,
421
- _web: {
422
- _classNames: 'thumb-container-full-base',
423
- },
424
- },
425
- thumb: halfSize => ({
426
- variants: {
427
- axis: {
428
- x: {
429
- height: '100%',
430
- justifyContent: 'center',
431
- alignItems: 'center',
432
- },
433
- y: {
434
- width: '100%',
435
- justifyContent: 'center',
436
- alignItems: 'center',
437
- },
438
- },
439
- },
440
- _web: {
441
- _classNames: 'slider-thumb-base',
442
- },
443
- }),
444
-
445
- stepsOverlay: {
446
- position: 'absolute',
447
- left: 0,
448
- right: 0,
449
- top: 0,
450
- bottom: 0,
451
- zIndex: 1,
452
- _web: {
453
- _classNames: 'slider-steps-overlay-base',
454
- },
455
- },
456
- steps: {
457
- width: '100%',
458
- height: '100%',
459
- justifyContent: 'space-between',
460
- alignItems: 'center',
461
- zIndex: 0,
462
- position: 'absolute',
463
- variants: {
464
- axis: {
465
- x: {
466
- flexDirection: 'row',
467
- },
468
- y: {
469
- flexDirection: 'column',
470
- },
471
- },
472
- },
473
- _web: {
474
- _classNames: 'slider-steps-base',
475
- },
476
- },
477
- step: (index, length) => ({
478
- backgroundColor:
479
- index === 0 || index === length ? 'transparent' : theme.colors.fg.default,
480
- variants: {
481
- axis: {
482
- x: {
483
- width: 1,
484
- height: '100%',
485
- },
486
- y: {
487
- width: '100%',
488
- height: 1,
489
- },
490
- },
491
- },
492
- _web: {
493
- _classNames: 'slider-step-base',
494
- },
495
- }),
496
- }))
497
-
498
- export default Slider
@@ -1,27 +0,0 @@
1
- import {createContext, useContext} from 'react'
2
- import {UnistylesVariants} from 'react-native-unistyles'
3
- import {FieldStyles} from '../../../theme/Field.recipe'
4
- import {PalettesWithNestedKeys} from '../../../style/varia/types'
5
-
6
- export type FieldVariants = UnistylesVariants<typeof FieldStyles>
7
-
8
- export type FieldContextType = {
9
- error?: string
10
- variant?: FieldVariants['variant']
11
- size?: FieldVariants['size']
12
- colorPalette?: PalettesWithNestedKeys
13
- }
14
-
15
- const FieldContext = createContext<FieldContextType | undefined>(undefined)
16
-
17
- export function useField() {
18
- const context = useContext(FieldContext)
19
- if (!context) {
20
- throw new Error(
21
- 'Field subcomponents (Label, Error) must be used inside Field.Root',
22
- )
23
- }
24
- return context
25
- }
26
-
27
- export default FieldContext
File without changes