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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {View, type ColorValue} from 'react-native'
|
|
1
|
+
import {StyleSheet, TextStyle, View, type ColorValue} from 'react-native'
|
|
2
2
|
import Svg, {
|
|
3
3
|
Defs,
|
|
4
4
|
LinearGradient,
|
|
@@ -8,16 +8,23 @@ import Svg, {
|
|
|
8
8
|
} from 'react-native-svg'
|
|
9
9
|
import {withUnistyles} from 'react-native-unistyles'
|
|
10
10
|
import {gradientTextTokens} from '../theme/GradientText.recipe'
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
NestedColorsType,
|
|
13
|
+
PalettesWithNestedKeys,
|
|
14
|
+
ThemeType,
|
|
15
|
+
} from '../style/varia/types'
|
|
12
16
|
import {resolveColor, resolveFontSize} from '../style/varia/utils'
|
|
17
|
+
import {ThemeColors} from '../style/varia/types'
|
|
13
18
|
|
|
14
19
|
interface GradientTextProps {
|
|
15
20
|
colorPalette: PalettesWithNestedKeys
|
|
16
21
|
variant?: keyof typeof gradientTextTokens.variants.variant
|
|
17
22
|
direction?: keyof typeof gradientTextTokens.variants.direction
|
|
18
|
-
colors:
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
colors: NestedColorsType
|
|
24
|
+
startColor?: ThemeColors
|
|
25
|
+
endColor?: ThemeColors
|
|
26
|
+
fontSizes: ThemeType['fontSizes']
|
|
27
|
+
fontSize?: TextStyle['fontSize']
|
|
21
28
|
children?: React.ReactNode
|
|
22
29
|
size?: keyof typeof gradientTextTokens.variants.size
|
|
23
30
|
}
|
|
@@ -28,13 +35,24 @@ const BaseGradientText = ({
|
|
|
28
35
|
colorPalette = 'accent',
|
|
29
36
|
direction = gradientTextTokens.defaultProps.direction,
|
|
30
37
|
colors,
|
|
38
|
+
startColor,
|
|
39
|
+
endColor,
|
|
31
40
|
fontSizes,
|
|
32
41
|
children,
|
|
33
42
|
size = gradientTextTokens.defaultProps.size,
|
|
34
43
|
}: GradientTextProps) => {
|
|
35
44
|
const colorValue = gradientTextTokens.variants.variant[variant]
|
|
36
|
-
|
|
37
|
-
const
|
|
45
|
+
|
|
46
|
+
const resolvedStartColor = resolveColor(
|
|
47
|
+
startColor || colorValue.startColor,
|
|
48
|
+
colors,
|
|
49
|
+
colorPalette,
|
|
50
|
+
)
|
|
51
|
+
const resolvedEndColor = resolveColor(
|
|
52
|
+
endColor || colorValue.endColor,
|
|
53
|
+
colors,
|
|
54
|
+
colorPalette,
|
|
55
|
+
)
|
|
38
56
|
|
|
39
57
|
const fontSizeValue = gradientTextTokens.variants.size[size].fontSize
|
|
40
58
|
const resolvedFontSize = fontSize || resolveFontSize(fontSizeValue, fontSizes)
|
|
@@ -42,8 +60,8 @@ const BaseGradientText = ({
|
|
|
42
60
|
const directionVariant = gradientTextTokens.variants.direction[direction]
|
|
43
61
|
|
|
44
62
|
return (
|
|
45
|
-
<View style={
|
|
46
|
-
<View style={
|
|
63
|
+
<View style={styles.root}>
|
|
64
|
+
<View style={styles.innerContainer}>
|
|
47
65
|
<Svg height={resolvedFontSize + 20} width="100%">
|
|
48
66
|
<Defs>
|
|
49
67
|
<LinearGradient
|
|
@@ -52,8 +70,8 @@ const BaseGradientText = ({
|
|
|
52
70
|
y1={directionVariant?.y1 as NumberProp}
|
|
53
71
|
x2={directionVariant?.x2 as NumberProp}
|
|
54
72
|
y2={directionVariant?.y2 as NumberProp}>
|
|
55
|
-
<Stop offset="0%" stopColor={
|
|
56
|
-
<Stop offset="100%" stopColor={
|
|
73
|
+
<Stop offset="0%" stopColor={resolvedStartColor as ColorValue} />
|
|
74
|
+
<Stop offset="100%" stopColor={resolvedEndColor as ColorValue} />
|
|
57
75
|
</LinearGradient>
|
|
58
76
|
</Defs>
|
|
59
77
|
<Text
|
|
@@ -74,6 +92,15 @@ const BaseGradientText = ({
|
|
|
74
92
|
)
|
|
75
93
|
}
|
|
76
94
|
|
|
95
|
+
const styles = StyleSheet.create({
|
|
96
|
+
root: {
|
|
97
|
+
flexDirection: 'row',
|
|
98
|
+
},
|
|
99
|
+
innerContainer: {
|
|
100
|
+
width: '100%',
|
|
101
|
+
},
|
|
102
|
+
})
|
|
103
|
+
|
|
77
104
|
const GradientText = withUnistyles(BaseGradientText, theme => ({
|
|
78
105
|
colors: theme.colors,
|
|
79
106
|
fontSizes: theme.fontSizes,
|
|
@@ -7,20 +7,20 @@ import {
|
|
|
7
7
|
type ReactNode,
|
|
8
8
|
} from 'react'
|
|
9
9
|
import Svg from 'react-native-svg'
|
|
10
|
-
import {View} from 'react-native'
|
|
11
|
-
import {withUnistyles} from 'react-native-unistyles'
|
|
10
|
+
import {StyleProp, View, ViewStyle} from 'react-native'
|
|
11
|
+
import {StyleSheet, withUnistyles} from 'react-native-unistyles'
|
|
12
12
|
import {IconTokens} from '../theme/IconWrapper.recipe'
|
|
13
13
|
import {
|
|
14
14
|
NestedColorsType,
|
|
15
15
|
PalettesWithNestedKeys,
|
|
16
16
|
ThemeColors,
|
|
17
|
+
ThemeType,
|
|
17
18
|
} from '../style/varia/types'
|
|
18
19
|
import {resolveColor} from '../style/varia/utils'
|
|
19
20
|
|
|
20
21
|
interface SVGChildProps {
|
|
21
22
|
color?: string
|
|
22
23
|
}
|
|
23
|
-
|
|
24
24
|
export type IconWrapperProps = {
|
|
25
25
|
variant?: keyof typeof IconTokens.variants.variant
|
|
26
26
|
size?: number
|
|
@@ -30,7 +30,8 @@ export type IconWrapperProps = {
|
|
|
30
30
|
scale?: number
|
|
31
31
|
color?: ThemeColors
|
|
32
32
|
rotation?: number
|
|
33
|
-
colors?:
|
|
33
|
+
colors?: NestedColorsType
|
|
34
|
+
style?: StyleProp<ViewStyle>
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
/**
|
|
@@ -50,12 +51,13 @@ const Icon = ({
|
|
|
50
51
|
color,
|
|
51
52
|
rotation,
|
|
52
53
|
colors,
|
|
54
|
+
style,
|
|
53
55
|
...rest
|
|
54
56
|
}: IconWrapperProps) => {
|
|
55
57
|
const colorValue = IconTokens.variants.variant[variant].color
|
|
56
58
|
const resolvedColor = color
|
|
57
|
-
? resolveColor(color, colors, colorPalette)
|
|
58
|
-
: resolveColor(colorValue, colors, colorPalette)
|
|
59
|
+
? resolveColor(color, colors as NestedColorsType, colorPalette)
|
|
60
|
+
: resolveColor(colorValue, colors as NestedColorsType, colorPalette)
|
|
59
61
|
|
|
60
62
|
const width = IconTokens.variants.sizeVariant[sizeVariant].width ?? 0
|
|
61
63
|
const height = IconTokens.variants.sizeVariant[sizeVariant].height ?? 0
|
|
@@ -63,14 +65,7 @@ const Icon = ({
|
|
|
63
65
|
// const viewBoxHeight = IconTokens.variants.size[size].viewBoxHeight ?? 0
|
|
64
66
|
|
|
65
67
|
return (
|
|
66
|
-
<View
|
|
67
|
-
style={{
|
|
68
|
-
width: size || width,
|
|
69
|
-
height: size || height,
|
|
70
|
-
justifyContent: 'center',
|
|
71
|
-
alignItems: 'center',
|
|
72
|
-
transform: rotation ? [{rotate: `${rotation}deg`}] : [],
|
|
73
|
-
}}>
|
|
68
|
+
<View style={[styles.root(size, width, height, rotation), style]}>
|
|
74
69
|
<Svg
|
|
75
70
|
width={size || width}
|
|
76
71
|
height={size || height}
|
|
@@ -105,6 +100,17 @@ const Icon = ({
|
|
|
105
100
|
|
|
106
101
|
export default Icon
|
|
107
102
|
|
|
103
|
+
const styles = StyleSheet.create({
|
|
104
|
+
root: (size, width, height, rotation) => ({
|
|
105
|
+
width: size || width,
|
|
106
|
+
height: size || height,
|
|
107
|
+
justifyContent: 'center',
|
|
108
|
+
alignItems: 'center',
|
|
109
|
+
...(rotation && {transform: [{rotate: `${rotation}deg`}]}),
|
|
110
|
+
// transform: rotation ? [{rotate: `${rotation}deg`}] : [],
|
|
111
|
+
}),
|
|
112
|
+
})
|
|
113
|
+
|
|
108
114
|
export const ThemedIcon = withUnistyles(Icon, theme => ({
|
|
109
115
|
colors: theme.colors,
|
|
110
116
|
}))
|
package/lib/components/Input.tsx
CHANGED
|
@@ -5,85 +5,141 @@ import {
|
|
|
5
5
|
TextInput,
|
|
6
6
|
TextInputProps,
|
|
7
7
|
TextStyle,
|
|
8
|
+
View,
|
|
8
9
|
type ViewStyle,
|
|
9
10
|
} from 'react-native'
|
|
10
11
|
import {StyleSheet, UnistylesVariants} from 'react-native-unistyles'
|
|
11
12
|
import {InputStyles, InputDefaultVariants} from '../theme/Input.recipe'
|
|
12
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
AlignSelf,
|
|
15
|
+
Flex,
|
|
16
|
+
MaxWidth,
|
|
17
|
+
PalettesWithNestedKeys,
|
|
18
|
+
StackDirection,
|
|
19
|
+
} from '../style/varia/types'
|
|
13
20
|
import {useState} from 'react'
|
|
14
|
-
import {
|
|
21
|
+
import {IconWrapperProps} from './IconWrapper'
|
|
15
22
|
|
|
16
23
|
type InputVariants = UnistylesVariants<typeof InputStyles>
|
|
17
24
|
|
|
18
25
|
type InputProps = InputVariants &
|
|
19
26
|
TextInputProps & {
|
|
20
27
|
colorPalette?: PalettesWithNestedKeys
|
|
21
|
-
|
|
28
|
+
onChangeText?: (value: string) => void
|
|
22
29
|
placeholder: string
|
|
23
30
|
inputMode?: InputModeOptions
|
|
24
31
|
keyboardType?: KeyboardTypeOptions
|
|
25
|
-
flex?:
|
|
26
|
-
maxWidth?:
|
|
32
|
+
flex?: Flex
|
|
33
|
+
maxWidth?: MaxWidth
|
|
27
34
|
password?: boolean
|
|
28
35
|
onFocus?: () => void
|
|
29
36
|
onBlur?: () => void
|
|
30
|
-
value:
|
|
37
|
+
value: string
|
|
31
38
|
disabled?: boolean
|
|
32
39
|
containerMixins?: StyleProp<ViewStyle> | StyleProp<ViewStyle>[]
|
|
40
|
+
alignSelf?: AlignSelf
|
|
33
41
|
labelMixins?:
|
|
34
42
|
| StyleProp<ViewStyle>
|
|
35
43
|
| StyleProp<ViewStyle>[]
|
|
36
44
|
| StyleProp<TextStyle>
|
|
37
45
|
| StyleProp<TextStyle>[]
|
|
38
46
|
inputMixins?: StyleProp<ViewStyle> | StyleProp<ViewStyle>[]
|
|
47
|
+
icon?: {
|
|
48
|
+
component: React.ComponentType<IconWrapperProps>
|
|
49
|
+
position?: 'left' | 'right'
|
|
50
|
+
scale?: number
|
|
51
|
+
rotation?: number
|
|
52
|
+
size?: number
|
|
53
|
+
}
|
|
54
|
+
style?: StyleProp<ViewStyle>
|
|
55
|
+
direction?: StackDirection
|
|
39
56
|
}
|
|
40
57
|
|
|
41
58
|
const Input = ({
|
|
42
59
|
colorPalette = 'accent',
|
|
43
60
|
size = InputDefaultVariants.size,
|
|
61
|
+
variant = InputDefaultVariants.variant,
|
|
44
62
|
placeholder,
|
|
45
|
-
|
|
46
|
-
inputMode,
|
|
63
|
+
onChangeText,
|
|
64
|
+
inputMode = 'text',
|
|
47
65
|
keyboardType,
|
|
48
|
-
flex =
|
|
66
|
+
flex = 0,
|
|
49
67
|
maxWidth = '100%',
|
|
50
68
|
password = false,
|
|
51
69
|
onFocus = () => {},
|
|
52
70
|
onBlur = () => {},
|
|
53
71
|
value,
|
|
54
72
|
containerMixins,
|
|
73
|
+
alignSelf = 'auto',
|
|
55
74
|
labelMixins,
|
|
56
75
|
inputMixins,
|
|
57
76
|
disabled,
|
|
58
77
|
invalid,
|
|
78
|
+
style,
|
|
79
|
+
icon,
|
|
80
|
+
textAlignVertical = 'center',
|
|
81
|
+
direction = 'column',
|
|
59
82
|
...props
|
|
60
83
|
}: InputProps) => {
|
|
61
84
|
const [focused, setFocused] = useState(false)
|
|
62
85
|
InputStyles.useVariants({
|
|
63
86
|
size,
|
|
87
|
+
variant,
|
|
64
88
|
focused,
|
|
65
89
|
disabled,
|
|
66
90
|
invalid,
|
|
67
91
|
})
|
|
92
|
+
const iconPosition = icon ? !icon.position && 'left' : null
|
|
68
93
|
|
|
69
94
|
const placeholderStyle = InputStyles.placeholder(colorPalette) as {
|
|
70
95
|
color: string
|
|
71
96
|
}
|
|
72
97
|
const placeholderColor = placeholderStyle.color
|
|
73
98
|
|
|
99
|
+
const inputResolvedVariantStyle = InputStyles.input(colorPalette) as {
|
|
100
|
+
paddingHorizontal?: number
|
|
101
|
+
}
|
|
102
|
+
const paddingHorizontal = inputResolvedVariantStyle.paddingHorizontal ?? 0
|
|
103
|
+
|
|
104
|
+
const IconComponent = icon?.component
|
|
105
|
+
const IconRendered = IconComponent ? (
|
|
106
|
+
<IconComponent
|
|
107
|
+
{...{
|
|
108
|
+
rotation: icon.rotation,
|
|
109
|
+
scale: icon.scale,
|
|
110
|
+
colorPalette,
|
|
111
|
+
size: icon.size,
|
|
112
|
+
color: InputStyles.input(colorPalette).color,
|
|
113
|
+
style: styles.icon(iconPosition, paddingHorizontal, textAlignVertical),
|
|
114
|
+
}}
|
|
115
|
+
/>
|
|
116
|
+
) : null
|
|
117
|
+
|
|
118
|
+
console.log(
|
|
119
|
+
iconPosition === 'left'
|
|
120
|
+
? (icon?.size || 0) + paddingHorizontal * 2
|
|
121
|
+
: paddingHorizontal,
|
|
122
|
+
)
|
|
123
|
+
|
|
74
124
|
return (
|
|
75
|
-
<
|
|
76
|
-
style={
|
|
77
|
-
|
|
78
|
-
flexShrink: 0,
|
|
79
|
-
alignSelf: 'stretch',
|
|
80
|
-
}}>
|
|
125
|
+
<View
|
|
126
|
+
style={styles.container(flex, direction, alignSelf, textAlignVertical)}>
|
|
127
|
+
{IconRendered}
|
|
81
128
|
<TextInput
|
|
82
129
|
editable={!disabled}
|
|
83
130
|
style={[
|
|
84
|
-
styles.input(
|
|
131
|
+
styles.input(
|
|
132
|
+
flex,
|
|
133
|
+
maxWidth,
|
|
134
|
+
iconPosition,
|
|
135
|
+
paddingHorizontal,
|
|
136
|
+
textAlignVertical,
|
|
137
|
+
(icon?.size || 0) + paddingHorizontal * 2,
|
|
138
|
+
alignSelf,
|
|
139
|
+
),
|
|
85
140
|
InputStyles.input(colorPalette),
|
|
86
141
|
inputMixins && inputMixins,
|
|
142
|
+
style && style,
|
|
87
143
|
]}
|
|
88
144
|
value={value}
|
|
89
145
|
placeholder={placeholder}
|
|
@@ -99,23 +155,48 @@ const Input = ({
|
|
|
99
155
|
onBlur()
|
|
100
156
|
setFocused(false)
|
|
101
157
|
}}
|
|
102
|
-
onChangeText={
|
|
103
|
-
multiline={false}
|
|
158
|
+
onChangeText={onChangeText}
|
|
104
159
|
{...props}
|
|
105
160
|
/>
|
|
106
|
-
</
|
|
161
|
+
</View>
|
|
107
162
|
)
|
|
108
163
|
}
|
|
109
164
|
|
|
110
165
|
const styles = StyleSheet.create({
|
|
111
|
-
|
|
166
|
+
container: (flex, direction, alignSelf, textAlignVertical) => ({
|
|
167
|
+
flex,
|
|
168
|
+
flexDirection: direction,
|
|
169
|
+
alignSelf,
|
|
170
|
+
alignItems: 'stretch',
|
|
171
|
+
justifyContent:
|
|
172
|
+
textAlignVertical === 'center'
|
|
173
|
+
? 'center'
|
|
174
|
+
: textAlignVertical === 'bottom'
|
|
175
|
+
? 'flex-end'
|
|
176
|
+
: 'flex-start',
|
|
177
|
+
}),
|
|
178
|
+
input: (
|
|
112
179
|
flex,
|
|
113
|
-
paddingVertical: 0,
|
|
114
|
-
flexDirection: 'row',
|
|
115
|
-
flexGrow: 1,
|
|
116
|
-
flexShrink: 0,
|
|
117
|
-
alignSelf: 'stretch',
|
|
118
180
|
maxWidth,
|
|
181
|
+
iconPosition,
|
|
182
|
+
paddingHorizontal,
|
|
183
|
+
textAlignVertical,
|
|
184
|
+
padding,
|
|
185
|
+
alignSelf,
|
|
186
|
+
) => ({
|
|
187
|
+
flex,
|
|
188
|
+
paddingLeft: iconPosition === 'left' ? padding : paddingHorizontal,
|
|
189
|
+
paddingRight: iconPosition === 'right' ? padding : paddingHorizontal,
|
|
190
|
+
textAlignVertical,
|
|
191
|
+
maxWidth,
|
|
192
|
+
alignSelf,
|
|
193
|
+
}),
|
|
194
|
+
icon: (iconPosition, paddingHorizontal, textAlignVertical) => ({
|
|
195
|
+
position: 'absolute',
|
|
196
|
+
...(iconPosition === 'left' && {left: paddingHorizontal}),
|
|
197
|
+
...(iconPosition === 'right' && {right: paddingHorizontal}),
|
|
198
|
+
top: textAlignVertical !== 'top' ? 'auto' : 10,
|
|
199
|
+
bottom: textAlignVertical !== 'bottom' ? 'auto' : 10,
|
|
119
200
|
}),
|
|
120
201
|
})
|
|
121
202
|
|
|
@@ -1,19 +1,32 @@
|
|
|
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
|
}
|
|
24
|
+
|
|
25
|
+
interface IconProps {
|
|
26
|
+
color?: string
|
|
27
|
+
size?: number
|
|
28
|
+
}
|
|
29
|
+
|
|
17
30
|
type PublicTriggerProps = {
|
|
18
31
|
children?: React.ReactNode
|
|
19
32
|
variant?: NumberInputVariants['variant']
|
|
@@ -30,6 +43,9 @@ type SimpleNumberInputProps = NumberInputVariants & {
|
|
|
30
43
|
flex?: number
|
|
31
44
|
min?: number
|
|
32
45
|
max?: number
|
|
46
|
+
alignSelf?: AlignSelf
|
|
47
|
+
style?: StyleProp<ViewStyle>
|
|
48
|
+
direction?: 'row' | 'column'
|
|
33
49
|
}
|
|
34
50
|
|
|
35
51
|
export const SimpleNumberInputContext = createContext<{
|
|
@@ -42,12 +58,16 @@ export const SimpleNumberInputContext = createContext<{
|
|
|
42
58
|
distribution?: NumberInputVariants['distribution']
|
|
43
59
|
min?: number
|
|
44
60
|
max?: number
|
|
61
|
+
flex?: number
|
|
62
|
+
alignSelf?: AlignSelf
|
|
63
|
+
direction?: StackDirection
|
|
45
64
|
}>({
|
|
46
65
|
value: 0,
|
|
47
66
|
setValue: () => {},
|
|
48
67
|
onBlur: undefined,
|
|
49
68
|
min: undefined,
|
|
50
69
|
max: undefined,
|
|
70
|
+
flex: 0,
|
|
51
71
|
})
|
|
52
72
|
|
|
53
73
|
function useSimpleNumberInputContext() {
|
|
@@ -69,9 +89,12 @@ const NumberInput = {
|
|
|
69
89
|
variant = NumberInputDefaultVariants.variant,
|
|
70
90
|
size = NumberInputDefaultVariants.size,
|
|
71
91
|
children,
|
|
72
|
-
flex =
|
|
92
|
+
flex = 0,
|
|
73
93
|
min,
|
|
74
94
|
max,
|
|
95
|
+
alignSelf = 'auto',
|
|
96
|
+
direction = 'column',
|
|
97
|
+
style,
|
|
75
98
|
}: React.PropsWithChildren<SimpleNumberInputProps>) => {
|
|
76
99
|
NumberInputStyles.useVariants({variant, size, distribution})
|
|
77
100
|
const [internalValue, setInternalValue] = useState<number>(defaultValue)
|
|
@@ -97,11 +120,15 @@ const NumberInput = {
|
|
|
97
120
|
variant,
|
|
98
121
|
size,
|
|
99
122
|
distribution,
|
|
123
|
+
flex,
|
|
124
|
+
alignSelf,
|
|
125
|
+
direction,
|
|
100
126
|
}}>
|
|
101
127
|
<View
|
|
102
128
|
style={[
|
|
103
|
-
simpleNumberInputstyles.rootContainer(flex),
|
|
129
|
+
simpleNumberInputstyles.rootContainer(flex, alignSelf),
|
|
104
130
|
NumberInputStyles.container(colorPalette),
|
|
131
|
+
style || {},
|
|
105
132
|
]}>
|
|
106
133
|
{children}
|
|
107
134
|
</View>
|
|
@@ -120,7 +147,26 @@ const NumberInput = {
|
|
|
120
147
|
distribution,
|
|
121
148
|
min,
|
|
122
149
|
max,
|
|
150
|
+
style,
|
|
151
|
+
flex,
|
|
152
|
+
alignSelf,
|
|
153
|
+
direction,
|
|
123
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
|
+
|
|
124
170
|
const handleChangeText = (text: string) => {
|
|
125
171
|
const numeric = text.replace(/[^0-9]/g, '')
|
|
126
172
|
let num = numeric === '' ? 0 : parseInt(numeric, 10)
|
|
@@ -132,8 +178,9 @@ const NumberInput = {
|
|
|
132
178
|
return (
|
|
133
179
|
<TextInput
|
|
134
180
|
style={[
|
|
135
|
-
simpleNumberInputstyles.input,
|
|
181
|
+
simpleNumberInputstyles.input(childFlex as number),
|
|
136
182
|
NumberInputStyles.input(colorPalette),
|
|
183
|
+
style || {},
|
|
137
184
|
]}
|
|
138
185
|
keyboardType="numeric"
|
|
139
186
|
value={value.toString()}
|
|
@@ -153,10 +200,20 @@ const NumberInput = {
|
|
|
153
200
|
distribution = NumberInputDefaultVariants.distribution,
|
|
154
201
|
colorPalette = 'accent',
|
|
155
202
|
children,
|
|
156
|
-
min,
|
|
157
203
|
max,
|
|
158
204
|
} = {...useSimpleNumberInputContext(), ...props}
|
|
159
205
|
NumberInputStyles.useVariants({variant, size, distribution})
|
|
206
|
+
|
|
207
|
+
const color = (NumberInputStyles.buttons(colorPalette) as {color: string})
|
|
208
|
+
.color
|
|
209
|
+
|
|
210
|
+
const iconElement = children || <IncreaseTriggerIcon />
|
|
211
|
+
const iconWithProps = React.isValidElement<IconProps>(iconElement)
|
|
212
|
+
? React.cloneElement(iconElement, {
|
|
213
|
+
color,
|
|
214
|
+
})
|
|
215
|
+
: iconElement
|
|
216
|
+
|
|
160
217
|
return (
|
|
161
218
|
<Pressable
|
|
162
219
|
onPress={() => setValue(value + 1)}
|
|
@@ -166,7 +223,7 @@ const NumberInput = {
|
|
|
166
223
|
NumberInputStyles.buttons(colorPalette),
|
|
167
224
|
NumberInputStyles.increaseTrigger(colorPalette),
|
|
168
225
|
]}>
|
|
169
|
-
{
|
|
226
|
+
{iconWithProps}
|
|
170
227
|
</Pressable>
|
|
171
228
|
)
|
|
172
229
|
},
|
|
@@ -181,9 +238,19 @@ const NumberInput = {
|
|
|
181
238
|
colorPalette = 'accent',
|
|
182
239
|
children,
|
|
183
240
|
min,
|
|
184
|
-
max,
|
|
185
241
|
} = {...useSimpleNumberInputContext(), ...props}
|
|
186
242
|
NumberInputStyles.useVariants({variant, size, distribution})
|
|
243
|
+
|
|
244
|
+
const color = (NumberInputStyles.buttons(colorPalette) as {color: string})
|
|
245
|
+
.color
|
|
246
|
+
|
|
247
|
+
const iconElement = children || <DecreaseTriggerIcon />
|
|
248
|
+
const iconWithProps = React.isValidElement<IconProps>(iconElement)
|
|
249
|
+
? React.cloneElement(iconElement, {
|
|
250
|
+
color,
|
|
251
|
+
})
|
|
252
|
+
: iconElement
|
|
253
|
+
|
|
187
254
|
return (
|
|
188
255
|
<Pressable
|
|
189
256
|
onPress={() => setValue(value - 1)}
|
|
@@ -193,31 +260,33 @@ const NumberInput = {
|
|
|
193
260
|
NumberInputStyles.buttons(colorPalette),
|
|
194
261
|
NumberInputStyles.decreaseTrigger(colorPalette),
|
|
195
262
|
]}>
|
|
196
|
-
{
|
|
263
|
+
{iconWithProps}
|
|
197
264
|
</Pressable>
|
|
198
265
|
)
|
|
199
266
|
},
|
|
200
267
|
}
|
|
201
268
|
|
|
202
|
-
const IncreaseTriggerIcon = () => {
|
|
203
|
-
return <Plus
|
|
269
|
+
const IncreaseTriggerIcon = ({color}: {color?: string}) => {
|
|
270
|
+
return <Plus color={color} />
|
|
204
271
|
}
|
|
205
272
|
|
|
206
|
-
const DecreaseTriggerIcon = () => {
|
|
207
|
-
return <Minus
|
|
273
|
+
const DecreaseTriggerIcon = ({color}: {color?: string}) => {
|
|
274
|
+
return <Minus color={color} />
|
|
208
275
|
}
|
|
209
276
|
|
|
210
277
|
export default NumberInput
|
|
211
278
|
|
|
212
279
|
const simpleNumberInputstyles = StyleSheet.create({
|
|
213
|
-
rootContainer: (flex: number) => ({
|
|
280
|
+
rootContainer: (flex: number, alignSelf?: AlignSelf) => ({
|
|
214
281
|
flexDirection: 'row',
|
|
215
|
-
|
|
216
|
-
alignSelf
|
|
282
|
+
flex,
|
|
283
|
+
alignSelf,
|
|
284
|
+
alignItems: 'stretch',
|
|
217
285
|
}),
|
|
218
|
-
input: {
|
|
286
|
+
input: (flex: number) => ({
|
|
219
287
|
paddingVertical: 0,
|
|
220
|
-
|
|
288
|
+
flex,
|
|
289
|
+
}),
|
|
221
290
|
button: {
|
|
222
291
|
justifyContent: 'center',
|
|
223
292
|
alignItems: 'center',
|