react-native-varia 0.2.3 → 0.3.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 (43) hide show
  1. package/bin/cli.js +24 -34
  2. package/lib/components/Accordion.tsx +113 -0
  3. package/lib/components/Button.tsx +16 -3
  4. package/lib/components/Checkbox.tsx +12 -7
  5. package/lib/components/CircleProgress.tsx +30 -21
  6. package/lib/components/Divider.tsx +23 -19
  7. package/lib/components/Drawer.tsx +23 -69
  8. package/lib/components/Field.tsx +24 -39
  9. package/lib/components/GradientBackground.tsx +25 -7
  10. package/lib/components/GradientText.tsx +61 -21
  11. package/lib/components/IconWrapper.tsx +20 -14
  12. package/lib/components/Input.tsx +107 -25
  13. package/lib/components/Modal.tsx +4 -10
  14. package/lib/components/NumberInput.tsx +54 -11
  15. package/lib/components/OldSlider.tsx +327 -0
  16. package/lib/components/RadioGroup.tsx +58 -18
  17. package/lib/components/ReText.tsx +1 -1
  18. package/lib/components/Select.tsx +58 -22
  19. package/lib/components/Slider.tsx +273 -138
  20. package/lib/components/Slideshow.tsx +65 -63
  21. package/lib/components/SlidingDrawer.tsx +20 -21
  22. package/lib/components/Spinner.tsx +13 -5
  23. package/lib/components/Toast.tsx +89 -0
  24. package/lib/components/context/Field.tsx +27 -0
  25. package/lib/patterns/index.tsx +16 -5
  26. package/lib/patterns/newPatterns.tsx +285 -0
  27. package/lib/theme/Button.recipe.tsx +11 -1
  28. package/lib/theme/CircleProgress.recipe.tsx +3 -3
  29. package/lib/theme/Drawer.recipe.tsx +107 -0
  30. package/lib/theme/Field.recipe.tsx +17 -2
  31. package/lib/theme/Input.recipe.tsx +12 -3
  32. package/lib/theme/NumberInput.recipe.tsx +8 -3
  33. package/lib/theme/RadioGroup.recipe.tsx +7 -1
  34. package/lib/theme/Select.recipe.tsx +7 -7
  35. package/lib/theme/Slider.recipe.tsx +402 -27
  36. package/lib/theme/Slideshow.recipe.tsx +1 -1
  37. package/lib/theme/Toast.recipe.tsx +71 -0
  38. package/lib/varia/mixins.ts +0 -4
  39. package/lib/varia/types.ts +8 -0
  40. package/lib/varia/utils.ts +66 -0
  41. package/package.json +1 -1
  42. package/lib/theme/Button.recipe-old.tsx +0 -67
  43. package/lib/theme/SlidingDrawer.recipe.tsx +0 -53
@@ -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 {PalettesWithNestedKeys} from '../style/varia/types'
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 {HStack} from '../patterns'
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
- onChange?: (value: string) => void
28
+ onChangeText?: (value: string) => void
22
29
  placeholder: string
23
30
  inputMode?: InputModeOptions
24
31
  keyboardType?: KeyboardTypeOptions
25
- flex?: number
26
- maxWidth?: number | string
32
+ flex?: Flex
33
+ maxWidth?: MaxWidth
27
34
  password?: boolean
28
35
  onFocus?: () => void
29
36
  onBlur?: () => void
30
- value: any
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
- onChange,
46
- inputMode,
63
+ onChangeText,
64
+ inputMode = 'text',
47
65
  keyboardType,
48
- flex = 1,
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
- <HStack
76
- style={{
77
- flexGrow: flex,
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(flex, maxWidth),
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,49 @@ const Input = ({
99
155
  onBlur()
100
156
  setFocused(false)
101
157
  }}
102
- onChangeText={onChange}
103
- multiline={false}
158
+ onChangeText={onChangeText}
104
159
  {...props}
105
160
  />
106
- </HStack>
161
+ </View>
107
162
  )
108
163
  }
109
164
 
110
165
  const styles = StyleSheet.create({
111
- input: (flex, maxWidth) => ({
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
+ outline: 'none'
194
+ }),
195
+ icon: (iconPosition, paddingHorizontal, textAlignVertical) => ({
196
+ position: 'absolute',
197
+ ...(iconPosition === 'left' && {left: paddingHorizontal}),
198
+ ...(iconPosition === 'right' && {right: paddingHorizontal}),
199
+ top: textAlignVertical !== 'top' ? 'auto' : 10,
200
+ bottom: textAlignVertical !== 'bottom' ? 'auto' : 10,
119
201
  }),
120
202
  })
121
203
 
@@ -94,7 +94,7 @@ const ModalOverlay = ({children, ...props}: ModalOverlayProps) => {
94
94
  entering={ModalTokens.animations.variants[animation]?.enteringOverlay}
95
95
  exiting={ModalTokens.animations.variants[animation]?.exitingOverlay}>
96
96
  <TouchableWithoutFeedback onPress={() => setIsOpen(false)}>
97
- <View style={RNStyleSheet.absoluteFillObject} />
97
+ <View style={StyleSheet.absoluteFillObject} />
98
98
  </TouchableWithoutFeedback>
99
99
  {children}
100
100
  </Animated.View>
@@ -151,14 +151,7 @@ type ModalBodyProps = Omit<ModalVariants, 'variant'> & {
151
151
  customStyle?: any
152
152
  }
153
153
 
154
- const ModalBody = ({children, ...props}: ModalBodyProps) => {
155
- const context = useModalContext()
156
- const {colorPalette = 'accent', variant} = {
157
- ...context,
158
- ...props,
159
- }
160
-
161
- ModalStyles.useVariants({variant})
154
+ const ModalBody = ({children}: ModalBodyProps) => {
162
155
  return <View>{children}</View>
163
156
  }
164
157
 
@@ -243,7 +236,7 @@ const styles = StyleSheet.create(theme => {
243
236
  }
244
237
  })
245
238
 
246
- export const Modal = Object.assign(ModalRoot, {
239
+ const Modal = Object.assign(ModalRoot, {
247
240
  Root: ModalRoot,
248
241
  Overlay: ModalOverlay,
249
242
  Content: ModalContent,
@@ -253,3 +246,4 @@ export const Modal = Object.assign(ModalRoot, {
253
246
  CloseTrigger: ModalCloseTrigger,
254
247
  CloseButton: CloseButton,
255
248
  })
249
+ export default Modal
@@ -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 {PalettesWithNestedKeys} from '../style/varia/types'
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 = 1,
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
- flexGrow: flex,
242
- alignSelf: 'flex-start',
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',