react-native-varia 0.2.3 → 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 +24 -34
- package/lib/components/Accordion.tsx +113 -0
- package/lib/components/Button.tsx +10 -1
- package/lib/components/CircleProgress.tsx +30 -21
- package/lib/components/Divider.tsx +18 -15
- package/lib/components/Drawer.tsx +5 -48
- 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 +54 -11
- 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 +65 -63
- package/lib/components/SlidingDrawer.tsx +20 -21
- package/lib/components/Spinner.tsx +6 -2
- package/lib/components/Toast.tsx +89 -0
- package/lib/components/context/Field.tsx +27 -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 +8 -3
- 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 +1 -1
- package/lib/theme/Button.recipe-old.tsx +0 -67
|
@@ -1,18 +1,25 @@
|
|
|
1
|
-
import React, {createContext, useContext, useState} from 'react'
|
|
2
|
-
import {View, TextInput, Pressable} from 'react-native'
|
|
1
|
+
import React, {createContext, useContext, useMemo, useState} from 'react'
|
|
2
|
+
import {View, TextInput, Pressable, StyleProp, ViewStyle} from 'react-native'
|
|
3
3
|
import {UnistylesVariants, StyleSheet} from 'react-native-unistyles'
|
|
4
4
|
import {
|
|
5
5
|
NumberInputStyles,
|
|
6
6
|
NumberInputDefaultVariants,
|
|
7
7
|
} from '../theme/NumberInput.recipe'
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
AlignSelf,
|
|
10
|
+
PalettesWithNestedKeys,
|
|
11
|
+
StackDirection,
|
|
12
|
+
} from '../style/varia/types'
|
|
9
13
|
import Plus from '../icons/Plus'
|
|
10
14
|
import Minus from '../icons/Minus'
|
|
15
|
+
import {computeFlexSync} from '../style/varia/utils'
|
|
11
16
|
|
|
12
17
|
type NumberInputVariants = UnistylesVariants<typeof NumberInputStyles>
|
|
13
18
|
|
|
14
19
|
type PublicInputProps = Omit<NumberInputVariants, 'variant' | 'size'> & {
|
|
15
20
|
placeholder?: string
|
|
21
|
+
flex?: number
|
|
22
|
+
style?: StyleProp<ViewStyle>
|
|
16
23
|
}
|
|
17
24
|
|
|
18
25
|
interface IconProps {
|
|
@@ -36,6 +43,9 @@ type SimpleNumberInputProps = NumberInputVariants & {
|
|
|
36
43
|
flex?: number
|
|
37
44
|
min?: number
|
|
38
45
|
max?: number
|
|
46
|
+
alignSelf?: AlignSelf
|
|
47
|
+
style?: StyleProp<ViewStyle>
|
|
48
|
+
direction?: 'row' | 'column'
|
|
39
49
|
}
|
|
40
50
|
|
|
41
51
|
export const SimpleNumberInputContext = createContext<{
|
|
@@ -48,12 +58,16 @@ export const SimpleNumberInputContext = createContext<{
|
|
|
48
58
|
distribution?: NumberInputVariants['distribution']
|
|
49
59
|
min?: number
|
|
50
60
|
max?: number
|
|
61
|
+
flex?: number
|
|
62
|
+
alignSelf?: AlignSelf
|
|
63
|
+
direction?: StackDirection
|
|
51
64
|
}>({
|
|
52
65
|
value: 0,
|
|
53
66
|
setValue: () => {},
|
|
54
67
|
onBlur: undefined,
|
|
55
68
|
min: undefined,
|
|
56
69
|
max: undefined,
|
|
70
|
+
flex: 0,
|
|
57
71
|
})
|
|
58
72
|
|
|
59
73
|
function useSimpleNumberInputContext() {
|
|
@@ -75,9 +89,12 @@ const NumberInput = {
|
|
|
75
89
|
variant = NumberInputDefaultVariants.variant,
|
|
76
90
|
size = NumberInputDefaultVariants.size,
|
|
77
91
|
children,
|
|
78
|
-
flex =
|
|
92
|
+
flex = 0,
|
|
79
93
|
min,
|
|
80
94
|
max,
|
|
95
|
+
alignSelf = 'auto',
|
|
96
|
+
direction = 'column',
|
|
97
|
+
style,
|
|
81
98
|
}: React.PropsWithChildren<SimpleNumberInputProps>) => {
|
|
82
99
|
NumberInputStyles.useVariants({variant, size, distribution})
|
|
83
100
|
const [internalValue, setInternalValue] = useState<number>(defaultValue)
|
|
@@ -103,11 +120,15 @@ const NumberInput = {
|
|
|
103
120
|
variant,
|
|
104
121
|
size,
|
|
105
122
|
distribution,
|
|
123
|
+
flex,
|
|
124
|
+
alignSelf,
|
|
125
|
+
direction,
|
|
106
126
|
}}>
|
|
107
127
|
<View
|
|
108
128
|
style={[
|
|
109
|
-
simpleNumberInputstyles.rootContainer(flex),
|
|
129
|
+
simpleNumberInputstyles.rootContainer(flex, alignSelf),
|
|
110
130
|
NumberInputStyles.container(colorPalette),
|
|
131
|
+
style || {},
|
|
111
132
|
]}>
|
|
112
133
|
{children}
|
|
113
134
|
</View>
|
|
@@ -126,7 +147,26 @@ const NumberInput = {
|
|
|
126
147
|
distribution,
|
|
127
148
|
min,
|
|
128
149
|
max,
|
|
150
|
+
style,
|
|
151
|
+
flex,
|
|
152
|
+
alignSelf,
|
|
153
|
+
direction,
|
|
129
154
|
} = {...useSimpleNumberInputContext(), ...props}
|
|
155
|
+
const resolvedDirection =
|
|
156
|
+
direction === 'row'
|
|
157
|
+
? distribution === 'horizontal'
|
|
158
|
+
? 'row'
|
|
159
|
+
: 'column'
|
|
160
|
+
: 'row'
|
|
161
|
+
|
|
162
|
+
const {flex: childFlex} = useMemo(() => {
|
|
163
|
+
return computeFlexSync(
|
|
164
|
+
flex as number,
|
|
165
|
+
alignSelf,
|
|
166
|
+
resolvedDirection as StackDirection,
|
|
167
|
+
)
|
|
168
|
+
}, [flex, alignSelf, direction])
|
|
169
|
+
|
|
130
170
|
const handleChangeText = (text: string) => {
|
|
131
171
|
const numeric = text.replace(/[^0-9]/g, '')
|
|
132
172
|
let num = numeric === '' ? 0 : parseInt(numeric, 10)
|
|
@@ -138,8 +178,9 @@ const NumberInput = {
|
|
|
138
178
|
return (
|
|
139
179
|
<TextInput
|
|
140
180
|
style={[
|
|
141
|
-
simpleNumberInputstyles.input,
|
|
181
|
+
simpleNumberInputstyles.input(childFlex as number),
|
|
142
182
|
NumberInputStyles.input(colorPalette),
|
|
183
|
+
style || {},
|
|
143
184
|
]}
|
|
144
185
|
keyboardType="numeric"
|
|
145
186
|
value={value.toString()}
|
|
@@ -236,14 +277,16 @@ const DecreaseTriggerIcon = ({color}: {color?: string}) => {
|
|
|
236
277
|
export default NumberInput
|
|
237
278
|
|
|
238
279
|
const simpleNumberInputstyles = StyleSheet.create({
|
|
239
|
-
rootContainer: (flex: number) => ({
|
|
280
|
+
rootContainer: (flex: number, alignSelf?: AlignSelf) => ({
|
|
240
281
|
flexDirection: 'row',
|
|
241
|
-
|
|
242
|
-
alignSelf
|
|
282
|
+
flex,
|
|
283
|
+
alignSelf,
|
|
284
|
+
alignItems: 'stretch',
|
|
243
285
|
}),
|
|
244
|
-
input: {
|
|
286
|
+
input: (flex: number) => ({
|
|
245
287
|
paddingVertical: 0,
|
|
246
|
-
|
|
288
|
+
flex,
|
|
289
|
+
}),
|
|
247
290
|
button: {
|
|
248
291
|
justifyContent: 'center',
|
|
249
292
|
alignItems: 'center',
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import {type LayoutChangeEvent, View} 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/OldSlider.recipe'
|
|
11
|
+
import {PalettesWithNestedKeys} from '../style/varia/types'
|
|
12
|
+
|
|
13
|
+
type SliderVariants = UnistylesVariants<typeof SliderStyles>
|
|
14
|
+
|
|
15
|
+
type SliderProps = SliderVariants & {
|
|
16
|
+
colorPalette?: PalettesWithNestedKeys
|
|
17
|
+
thickness?: number
|
|
18
|
+
minimumTrackThickness?: number
|
|
19
|
+
minimumTrackColor?: string
|
|
20
|
+
displayStepsOnMinimumTrack?: boolean
|
|
21
|
+
thumbSize?: {
|
|
22
|
+
width: number
|
|
23
|
+
height: number
|
|
24
|
+
}
|
|
25
|
+
thumbChildren?: React.ReactNode
|
|
26
|
+
axis: 'x' | 'y'
|
|
27
|
+
steps?: number
|
|
28
|
+
value?: number
|
|
29
|
+
onValueChange?: (value: number) => void
|
|
30
|
+
onSlidingComplete?: (value: number) => void
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const OldSlider = ({
|
|
34
|
+
colorPalette = 'accent',
|
|
35
|
+
variant = SliderDefaultVariants.variant,
|
|
36
|
+
size = SliderDefaultVariants.size,
|
|
37
|
+
displayStepsOnMinimumTrack = false,
|
|
38
|
+
thumbChildren: ThumbChildren,
|
|
39
|
+
axis = 'x',
|
|
40
|
+
value = 0,
|
|
41
|
+
steps,
|
|
42
|
+
onValueChange,
|
|
43
|
+
onSlidingComplete,
|
|
44
|
+
}: SliderProps) => {
|
|
45
|
+
let styles
|
|
46
|
+
if (axis === 'x') {
|
|
47
|
+
styles = stylesX
|
|
48
|
+
} else {
|
|
49
|
+
styles = stylesY
|
|
50
|
+
}
|
|
51
|
+
SliderStyles.useVariants({
|
|
52
|
+
size,
|
|
53
|
+
variant,
|
|
54
|
+
})
|
|
55
|
+
const thumbStyle = SliderStyles.thumb(colorPalette)
|
|
56
|
+
const maximumTrackStyle = SliderStyles.maximumTrack(colorPalette)
|
|
57
|
+
const minimumTrackStyle = SliderStyles.minimumTrack(colorPalette, false)
|
|
58
|
+
|
|
59
|
+
const halfSize = (thumbStyle.width ?? 0) / 2
|
|
60
|
+
const thumbSize = {
|
|
61
|
+
width: thumbStyle.width,
|
|
62
|
+
height: thumbStyle.height,
|
|
63
|
+
}
|
|
64
|
+
const maximumTrackWidth = maximumTrackStyle.height ?? 30
|
|
65
|
+
const minimumTrackWidth = minimumTrackStyle.height ?? 30
|
|
66
|
+
const context = useSharedValue({x: 0})
|
|
67
|
+
const translate = useSharedValue(value)
|
|
68
|
+
const trackLength = useSharedValue(0)
|
|
69
|
+
const isInsideChild = useSharedValue(false)
|
|
70
|
+
|
|
71
|
+
const handleTrackLayout = (event: LayoutChangeEvent) => {
|
|
72
|
+
const {width, height} = event.nativeEvent.layout
|
|
73
|
+
trackLength.value = axis === 'x' ? width : height
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const slideGesture = Gesture.Pan()
|
|
77
|
+
.onTouchesDown(() => {
|
|
78
|
+
isInsideChild.value = true
|
|
79
|
+
})
|
|
80
|
+
.onBegin(() => {
|
|
81
|
+
context.value.x = translate.value
|
|
82
|
+
})
|
|
83
|
+
.onUpdate(e => {
|
|
84
|
+
const stepLength = steps ? trackLength.value / steps : 1
|
|
85
|
+
const delta = axis === 'y' ? -e.translationY : e.translationX
|
|
86
|
+
|
|
87
|
+
const rawValue = Math.max(
|
|
88
|
+
0,
|
|
89
|
+
Math.min(context.value.x + delta, trackLength.value),
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
const snappedValue = steps
|
|
93
|
+
? Math.round(rawValue / stepLength) * stepLength
|
|
94
|
+
: rawValue
|
|
95
|
+
|
|
96
|
+
translate.value = snappedValue
|
|
97
|
+
|
|
98
|
+
if (steps) {
|
|
99
|
+
const stepIndex = Math.round(snappedValue / stepLength)
|
|
100
|
+
onValueChange && runOnJS(onValueChange)(stepIndex)
|
|
101
|
+
} else {
|
|
102
|
+
onValueChange &&
|
|
103
|
+
runOnJS(onValueChange)(
|
|
104
|
+
Math.round((snappedValue / trackLength.value) * 100) / 100,
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
.onEnd(() => {
|
|
109
|
+
const stepLength = steps ? trackLength.value / steps : 1
|
|
110
|
+
|
|
111
|
+
const snappedValue = steps
|
|
112
|
+
? Math.round(translate.value / stepLength)
|
|
113
|
+
: translate.value / trackLength.value
|
|
114
|
+
|
|
115
|
+
onSlidingComplete && runOnJS(onSlidingComplete)(snappedValue)
|
|
116
|
+
})
|
|
117
|
+
.onFinalize(() => {
|
|
118
|
+
isInsideChild.value = false
|
|
119
|
+
})
|
|
120
|
+
const tapGesture = Gesture.Tap()
|
|
121
|
+
.onBegin(e => {
|
|
122
|
+
if (isInsideChild.value) {
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
const tapPosition = axis === 'x' ? e.x : e.y
|
|
126
|
+
const stepLength = steps ? trackLength.value / steps : 1
|
|
127
|
+
|
|
128
|
+
const rawValue =
|
|
129
|
+
axis === 'y'
|
|
130
|
+
? Math.max(
|
|
131
|
+
0,
|
|
132
|
+
Math.min(trackLength.value - tapPosition, trackLength.value),
|
|
133
|
+
)
|
|
134
|
+
: Math.max(0, Math.min(tapPosition, trackLength.value))
|
|
135
|
+
|
|
136
|
+
const snappedValue = steps
|
|
137
|
+
? Math.round(rawValue / stepLength) * stepLength
|
|
138
|
+
: rawValue
|
|
139
|
+
|
|
140
|
+
translate.value = snappedValue
|
|
141
|
+
|
|
142
|
+
if (steps) {
|
|
143
|
+
const stepIndex = Math.round(snappedValue / stepLength)
|
|
144
|
+
onValueChange && runOnJS(onValueChange)(stepIndex)
|
|
145
|
+
onSlidingComplete && runOnJS(onSlidingComplete)(stepIndex)
|
|
146
|
+
} else {
|
|
147
|
+
const normalizedValue =
|
|
148
|
+
Math.round((snappedValue / trackLength.value) * 100) / 100
|
|
149
|
+
onValueChange && runOnJS(onValueChange)(normalizedValue)
|
|
150
|
+
onSlidingComplete && runOnJS(onSlidingComplete)(normalizedValue)
|
|
151
|
+
}
|
|
152
|
+
})
|
|
153
|
+
.simultaneousWithExternalGesture(slideGesture)
|
|
154
|
+
|
|
155
|
+
const animatedTrack = useAnimatedStyle(() => ({
|
|
156
|
+
[axis === 'y' ? 'height' : 'width']: translate.value + halfSize,
|
|
157
|
+
}))
|
|
158
|
+
|
|
159
|
+
const opacityTrack = steps !== undefined && displayStepsOnMinimumTrack
|
|
160
|
+
|
|
161
|
+
return (
|
|
162
|
+
<View
|
|
163
|
+
style={[
|
|
164
|
+
styles.container(maximumTrackWidth, halfSize),
|
|
165
|
+
SliderStyles.container(colorPalette),
|
|
166
|
+
]}>
|
|
167
|
+
{axis === 'x' && <View style={{width: halfSize}} />}
|
|
168
|
+
<GestureDetector gesture={tapGesture}>
|
|
169
|
+
<View
|
|
170
|
+
style={[
|
|
171
|
+
styles.maximumTrack(maximumTrackWidth),
|
|
172
|
+
SliderStyles.maximumTrack(colorPalette),
|
|
173
|
+
]}
|
|
174
|
+
onLayout={handleTrackLayout}>
|
|
175
|
+
{steps && (
|
|
176
|
+
<View style={styles.steps}>
|
|
177
|
+
{Array.from({length: steps + 1}, (_, index) => index).map(
|
|
178
|
+
(_, i) => (
|
|
179
|
+
<View
|
|
180
|
+
key={i}
|
|
181
|
+
style={[
|
|
182
|
+
styles.step(i, steps),
|
|
183
|
+
SliderStyles.step(colorPalette),
|
|
184
|
+
]}
|
|
185
|
+
/>
|
|
186
|
+
),
|
|
187
|
+
)}
|
|
188
|
+
</View>
|
|
189
|
+
)}
|
|
190
|
+
<Animated.View
|
|
191
|
+
style={[
|
|
192
|
+
styles.minimumTrack(halfSize, minimumTrackWidth),
|
|
193
|
+
SliderStyles.minimumTrack(colorPalette, opacityTrack),
|
|
194
|
+
animatedTrack,
|
|
195
|
+
]}>
|
|
196
|
+
<GestureDetector gesture={slideGesture}>
|
|
197
|
+
<View
|
|
198
|
+
style={[
|
|
199
|
+
SliderStyles.thumb(colorPalette),
|
|
200
|
+
styles.thumb(halfSize, thumbSize),
|
|
201
|
+
]}>
|
|
202
|
+
{ThumbChildren || null}
|
|
203
|
+
</View>
|
|
204
|
+
</GestureDetector>
|
|
205
|
+
</Animated.View>
|
|
206
|
+
</View>
|
|
207
|
+
</GestureDetector>
|
|
208
|
+
{axis === 'y' && <View style={{height: halfSize}} />}
|
|
209
|
+
</View>
|
|
210
|
+
)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const stylesX = StyleSheet.create(theme => ({
|
|
214
|
+
container: (thickness, halfSize) => ({
|
|
215
|
+
flex: thickness ? 1 : 1,
|
|
216
|
+
maxWidth: 'auto',
|
|
217
|
+
borderRadius: 22,
|
|
218
|
+
width: '100%',
|
|
219
|
+
height: '100%',
|
|
220
|
+
paddingTop: 0,
|
|
221
|
+
paddingRight: halfSize,
|
|
222
|
+
flexDirection: 'row',
|
|
223
|
+
}),
|
|
224
|
+
maximumTrack: thickness => ({
|
|
225
|
+
flex: thickness ? 1 : 1,
|
|
226
|
+
justifyContent: 'center',
|
|
227
|
+
position: 'relative',
|
|
228
|
+
borderRadius: 22,
|
|
229
|
+
}),
|
|
230
|
+
minimumTrack: (halfSize, minimumTrackThickness) => ({
|
|
231
|
+
height: minimumTrackThickness,
|
|
232
|
+
width: '100%',
|
|
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,
|
|
265
|
+
}),
|
|
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
|
+
borderWidth: 1,
|
|
279
|
+
borderColor: 'yellow',
|
|
280
|
+
// minWidth: 30,
|
|
281
|
+
}),
|
|
282
|
+
maximumTrack: maximumTrackWidth => ({
|
|
283
|
+
flex: 1,
|
|
284
|
+
justifyContent: 'center',
|
|
285
|
+
alignItems: 'center',
|
|
286
|
+
position: 'relative',
|
|
287
|
+
maxWidth: maximumTrackWidth,
|
|
288
|
+
}),
|
|
289
|
+
minimumTrack: (halfSize, minimumTrackWidth) => ({
|
|
290
|
+
position: 'absolute',
|
|
291
|
+
height: '100%',
|
|
292
|
+
width: minimumTrackWidth,
|
|
293
|
+
left: 'auto',
|
|
294
|
+
bottom: halfSize * -1,
|
|
295
|
+
paddingBottom: halfSize,
|
|
296
|
+
paddingLeft: 0,
|
|
297
|
+
borderBottomLeftRadius: 20,
|
|
298
|
+
borderBottomRightRadius: 20,
|
|
299
|
+
borderTopLeftRadius: 0,
|
|
300
|
+
alignItems: 'center',
|
|
301
|
+
}),
|
|
302
|
+
thumb: (halfSize, thumbSize) => ({
|
|
303
|
+
borderRadius: 25,
|
|
304
|
+
position: 'absolute',
|
|
305
|
+
top: 0,
|
|
306
|
+
zIndex: 2,
|
|
307
|
+
transform: [{translateY: halfSize * -1}],
|
|
308
|
+
width: thumbSize.height,
|
|
309
|
+
height: thumbSize.width,
|
|
310
|
+
}),
|
|
311
|
+
steps: {
|
|
312
|
+
width: '100%',
|
|
313
|
+
height: '100%',
|
|
314
|
+
flexDirection: 'column',
|
|
315
|
+
justifyContent: 'space-between',
|
|
316
|
+
alignItems: 'center',
|
|
317
|
+
zIndex: 0,
|
|
318
|
+
},
|
|
319
|
+
step: (index, length) => ({
|
|
320
|
+
width: '100%',
|
|
321
|
+
height: 1,
|
|
322
|
+
backgroundColor:
|
|
323
|
+
index === 0 || index === length ? 'transparent' : theme.colors.fg.default,
|
|
324
|
+
}),
|
|
325
|
+
}))
|
|
326
|
+
|
|
327
|
+
export default OldSlider
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import React, {createContext, useContext, useState, useCallback} from 'react'
|
|
2
|
-
import {View, Text, Pressable} from 'react-native'
|
|
2
|
+
import {View, Text, Pressable, ViewStyle} from 'react-native'
|
|
3
3
|
import {StyleSheet, UnistylesVariants} from 'react-native-unistyles'
|
|
4
4
|
import {
|
|
5
5
|
RadioGroupStyles,
|
|
6
6
|
RadioGroupDefaultVariants,
|
|
7
7
|
} from '../theme/RadioGroup.recipe'
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
AlignSelf,
|
|
10
|
+
PalettesWithNestedKeys,
|
|
11
|
+
StackDirection,
|
|
12
|
+
} from '../style/varia/types'
|
|
9
13
|
|
|
10
14
|
type RadioGroupVariants = UnistylesVariants<typeof RadioGroupStyles>
|
|
11
15
|
|
|
@@ -14,7 +18,12 @@ type RadioGroupRootProps = RadioGroupVariants & {
|
|
|
14
18
|
colorPalette?: PalettesWithNestedKeys
|
|
15
19
|
defaultValue?: string
|
|
16
20
|
onValueChange?: (value: string) => void
|
|
17
|
-
direction?:
|
|
21
|
+
direction?: StackDirection
|
|
22
|
+
flex?: number
|
|
23
|
+
alignSelf?: AlignSelf
|
|
24
|
+
justifyContent?: string
|
|
25
|
+
alignItems?: string
|
|
26
|
+
gap?: number
|
|
18
27
|
}
|
|
19
28
|
|
|
20
29
|
type RadioGroupContextProps = {
|
|
@@ -23,6 +32,8 @@ type RadioGroupContextProps = {
|
|
|
23
32
|
colorPalette: PalettesWithNestedKeys
|
|
24
33
|
variant: RadioGroupVariants['variant']
|
|
25
34
|
size: RadioGroupVariants['size']
|
|
35
|
+
flex: number
|
|
36
|
+
alignSelf?: AlignSelf
|
|
26
37
|
}
|
|
27
38
|
|
|
28
39
|
const RadioGroupContext = createContext<RadioGroupContextProps | null>(null)
|
|
@@ -44,7 +55,12 @@ function Root({
|
|
|
44
55
|
variant = RadioGroupDefaultVariants.variant,
|
|
45
56
|
size = RadioGroupDefaultVariants.size,
|
|
46
57
|
onValueChange,
|
|
47
|
-
|
|
58
|
+
flex = 0,
|
|
59
|
+
alignSelf = 'auto',
|
|
60
|
+
direction = 'column',
|
|
61
|
+
justifyContent,
|
|
62
|
+
alignItems,
|
|
63
|
+
gap,
|
|
48
64
|
}: RadioGroupRootProps) {
|
|
49
65
|
RadioGroupStyles.useVariants({variant, size})
|
|
50
66
|
const [value, setValue] = useState(defaultValue)
|
|
@@ -65,15 +81,22 @@ function Root({
|
|
|
65
81
|
colorPalette,
|
|
66
82
|
variant,
|
|
67
83
|
size,
|
|
84
|
+
flex,
|
|
68
85
|
}
|
|
69
86
|
|
|
70
87
|
return (
|
|
71
88
|
<RadioGroupContext.Provider value={contextValue}>
|
|
72
89
|
<View
|
|
73
90
|
style={[
|
|
74
|
-
styles.root
|
|
91
|
+
styles.root(
|
|
92
|
+
flex,
|
|
93
|
+
direction,
|
|
94
|
+
alignSelf,
|
|
95
|
+
justifyContent as ViewStyle['justifyContent'],
|
|
96
|
+
alignItems as ViewStyle['alignItems'],
|
|
97
|
+
gap,
|
|
98
|
+
),
|
|
75
99
|
RadioGroupStyles.container(colorPalette),
|
|
76
|
-
direction === 'horizontal' && styles.rootHorizontal,
|
|
77
100
|
]}>
|
|
78
101
|
{children}
|
|
79
102
|
</View>
|
|
@@ -99,17 +122,23 @@ function Item({children, value: itemValue}: PublicItemProps) {
|
|
|
99
122
|
|
|
100
123
|
const childrenWithValue = React.Children.map(children, child => {
|
|
101
124
|
if (React.isValidElement(child)) {
|
|
102
|
-
return React.cloneElement(
|
|
103
|
-
itemValue
|
|
104
|
-
|
|
105
|
-
|
|
125
|
+
return React.cloneElement(
|
|
126
|
+
child as React.ReactElement<{itemValue: string; isSelected: boolean}>,
|
|
127
|
+
{
|
|
128
|
+
itemValue,
|
|
129
|
+
isSelected,
|
|
130
|
+
},
|
|
131
|
+
)
|
|
106
132
|
}
|
|
107
133
|
return child
|
|
108
134
|
})
|
|
109
135
|
|
|
110
136
|
return (
|
|
111
137
|
<Pressable
|
|
112
|
-
style={
|
|
138
|
+
style={({pressed}) => [
|
|
139
|
+
styles.item,
|
|
140
|
+
RadioGroupStyles.item(colorPalette, pressed),
|
|
141
|
+
]}
|
|
113
142
|
onPress={() => onValueChange(itemValue)}
|
|
114
143
|
accessibilityRole="radio"
|
|
115
144
|
accessibilityState={{checked: isSelected}}>
|
|
@@ -175,12 +204,21 @@ function ItemText({
|
|
|
175
204
|
}
|
|
176
205
|
|
|
177
206
|
const styles = StyleSheet.create({
|
|
178
|
-
root:
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
207
|
+
root: (
|
|
208
|
+
flex: number,
|
|
209
|
+
direction: StackDirection,
|
|
210
|
+
alignSelf?: AlignSelf,
|
|
211
|
+
justifyContent?: ViewStyle['justifyContent'],
|
|
212
|
+
alignItems?: ViewStyle['alignItems'],
|
|
213
|
+
gap?: number,
|
|
214
|
+
) => ({
|
|
215
|
+
flex,
|
|
216
|
+
flexDirection: direction,
|
|
217
|
+
alignSelf,
|
|
218
|
+
alignItems,
|
|
219
|
+
gap,
|
|
220
|
+
justifyContent,
|
|
221
|
+
}),
|
|
184
222
|
item: {
|
|
185
223
|
flexDirection: 'row',
|
|
186
224
|
alignItems: 'center',
|