@codeleap/mobile 1.3.1 → 1.4.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 (197) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc.js +3 -0
  3. package/.vscode/settings.json +11 -0
  4. package/CodeLeap-Mobile-Packages.code-workspace +8 -0
  5. package/dist/components/ActivityIndicator.js +9 -6
  6. package/dist/components/ActivityIndicator.js.map +1 -1
  7. package/dist/components/Animated.d.ts +1 -89
  8. package/dist/components/Animated.js +2 -2
  9. package/dist/components/Animated.js.map +1 -1
  10. package/dist/components/Button.d.ts +107 -98
  11. package/dist/components/Button.js +29 -9
  12. package/dist/components/Button.js.map +1 -1
  13. package/dist/components/Checkbox/index.d.ts +1 -1
  14. package/dist/components/Checkbox/index.js +7 -8
  15. package/dist/components/Checkbox/index.js.map +1 -1
  16. package/dist/components/Checkbox/styles.d.ts +47 -43
  17. package/dist/components/Checkbox/styles.js +8 -8
  18. package/dist/components/Checkbox/styles.js.map +1 -1
  19. package/dist/components/ContentView.js +4 -2
  20. package/dist/components/ContentView.js.map +1 -1
  21. package/dist/components/FileInput.d.ts +10 -3
  22. package/dist/components/FileInput.js +94 -32
  23. package/dist/components/FileInput.js.map +1 -1
  24. package/dist/components/Icon.d.ts +4 -6
  25. package/dist/components/Icon.js +25 -11
  26. package/dist/components/Icon.js.map +1 -1
  27. package/dist/components/Image.d.ts +7 -6
  28. package/dist/components/Image.js +4 -4
  29. package/dist/components/Image.js.map +1 -1
  30. package/dist/components/List.d.ts +11 -0
  31. package/dist/components/List.js +77 -0
  32. package/dist/components/List.js.map +1 -0
  33. package/dist/components/Modal/index.d.ts +2 -1
  34. package/dist/components/Modal/index.js +23 -30
  35. package/dist/components/Modal/index.js.map +1 -1
  36. package/dist/components/Modal/styles.d.ts +51 -47
  37. package/dist/components/Modal/styles.js +13 -18
  38. package/dist/components/Modal/styles.js.map +1 -1
  39. package/dist/components/Navigation/Navigation.d.ts +3 -0
  40. package/dist/components/Navigation/Navigation.js +76 -0
  41. package/dist/components/Navigation/Navigation.js.map +1 -0
  42. package/dist/components/Navigation/constants.d.ts +5 -0
  43. package/dist/components/Navigation/constants.js +11 -0
  44. package/dist/components/Navigation/constants.js.map +1 -0
  45. package/dist/components/Navigation/index.d.ts +3 -0
  46. package/dist/components/Navigation/index.js +16 -0
  47. package/dist/components/Navigation/index.js.map +1 -0
  48. package/dist/components/Navigation/types.d.ts +26 -0
  49. package/dist/components/Navigation/types.js +8 -0
  50. package/dist/components/Navigation/types.js.map +1 -0
  51. package/dist/components/Navigation/utils.d.ts +3 -0
  52. package/dist/components/Navigation/utils.js +67 -0
  53. package/dist/components/Navigation/utils.js.map +1 -0
  54. package/dist/components/Overlay.d.ts +5 -5
  55. package/dist/components/Overlay.js +13 -15
  56. package/dist/components/Overlay.js.map +1 -1
  57. package/dist/components/Pager/index.d.ts +19 -0
  58. package/dist/components/Pager/index.js +164 -0
  59. package/dist/components/Pager/index.js.map +1 -0
  60. package/dist/components/Pager/styles.d.ts +51 -0
  61. package/dist/components/Pager/styles.js +44 -0
  62. package/dist/components/Pager/styles.js.map +1 -0
  63. package/dist/components/RadioInput/index.d.ts +1 -0
  64. package/dist/components/RadioInput/index.js +13 -19
  65. package/dist/components/RadioInput/index.js.map +1 -1
  66. package/dist/components/RadioInput/styles.d.ts +48 -44
  67. package/dist/components/RadioInput/styles.js +4 -4
  68. package/dist/components/RadioInput/styles.js.map +1 -1
  69. package/dist/components/Scroll.d.ts +3 -2
  70. package/dist/components/Scroll.js +11 -8
  71. package/dist/components/Scroll.js.map +1 -1
  72. package/dist/components/Sections.d.ts +11 -0
  73. package/dist/components/Sections.js +77 -0
  74. package/dist/components/Sections.js.map +1 -0
  75. package/dist/components/Select/index.d.ts +5 -2
  76. package/dist/components/Select/index.js +118 -5
  77. package/dist/components/Select/index.js.map +1 -1
  78. package/dist/components/Select/styles.d.ts +9 -0
  79. package/dist/components/Select/styles.js +57 -0
  80. package/dist/components/Select/styles.js.map +1 -0
  81. package/dist/components/Select/types.d.ts +33 -0
  82. package/dist/components/Select/types.js +3 -0
  83. package/dist/components/Select/types.js.map +1 -0
  84. package/dist/components/Slider/Mark.d.ts +3 -0
  85. package/dist/components/Slider/Mark.js +32 -0
  86. package/dist/components/Slider/Mark.js.map +1 -0
  87. package/dist/components/Slider/Thumb.d.ts +7 -0
  88. package/dist/components/Slider/Thumb.js +30 -0
  89. package/dist/components/Slider/Thumb.js.map +1 -0
  90. package/dist/components/Slider/index.d.ts +3 -0
  91. package/dist/components/Slider/index.js +94 -0
  92. package/dist/components/Slider/index.js.map +1 -0
  93. package/dist/components/{Slider.d.ts → Slider/types.d.ts} +12 -7
  94. package/dist/components/Slider/types.js +3 -0
  95. package/dist/components/Slider/types.js.map +1 -0
  96. package/dist/components/Switch.d.ts +2 -2
  97. package/dist/components/Switch.js +6 -7
  98. package/dist/components/Switch.js.map +1 -1
  99. package/dist/components/Text.js +5 -5
  100. package/dist/components/Text.js.map +1 -1
  101. package/dist/components/TextInput.d.ts +108 -94
  102. package/dist/components/TextInput.js +28 -25
  103. package/dist/components/TextInput.js.map +1 -1
  104. package/dist/components/Touchable.d.ts +1 -0
  105. package/dist/components/Touchable.js +9 -11
  106. package/dist/components/Touchable.js.map +1 -1
  107. package/dist/components/View.d.ts +97 -175
  108. package/dist/components/View.js +4 -4
  109. package/dist/components/View.js.map +1 -1
  110. package/dist/components/{index.d.ts → components.d.ts} +3 -0
  111. package/dist/components/{index.js → components.js} +4 -1
  112. package/dist/components/components.js.map +1 -0
  113. package/dist/index.d.ts +3 -1
  114. package/dist/index.js +5 -2
  115. package/dist/index.js.map +1 -1
  116. package/dist/modules/documentPicker.d.ts +3 -1
  117. package/dist/modules/documentPicker.js +6 -4
  118. package/dist/modules/documentPicker.js.map +1 -1
  119. package/dist/modules/fastImage.js +1 -1
  120. package/dist/modules/fastImage.js.map +1 -1
  121. package/dist/modules/reactNavigation.d.ts +3 -0
  122. package/dist/modules/reactNavigation.js +11 -0
  123. package/dist/modules/reactNavigation.js.map +1 -0
  124. package/dist/modules/types/fileTypes.d.ts +138 -0
  125. package/dist/modules/types/fileTypes.js +3 -0
  126. package/dist/modules/types/fileTypes.js.map +1 -0
  127. package/dist/types/utility.d.ts +1 -1
  128. package/dist/utils/OSAlert.d.ts +3 -3
  129. package/dist/utils/OSAlert.js.map +1 -1
  130. package/dist/utils/misc.d.ts +2 -0
  131. package/dist/utils/misc.js +26 -0
  132. package/dist/utils/misc.js.map +1 -0
  133. package/dist/utils/styles.js +1 -1
  134. package/dist/utils/styles.js.map +1 -1
  135. package/package.json +6 -3
  136. package/src/components/ActivityIndicator.tsx +38 -28
  137. package/src/components/Animated.tsx +22 -19
  138. package/src/components/Button.tsx +67 -34
  139. package/src/components/Checkbox/index.tsx +60 -48
  140. package/src/components/Checkbox/styles.ts +39 -30
  141. package/src/components/ContentView.tsx +24 -18
  142. package/src/components/FileInput.tsx +161 -52
  143. package/src/components/Icon.tsx +36 -23
  144. package/src/components/Image.tsx +42 -36
  145. package/src/components/List.tsx +100 -0
  146. package/src/components/Modal/index.tsx +109 -94
  147. package/src/components/Modal/styles.ts +62 -66
  148. package/src/components/Navigation/Navigation.tsx +51 -0
  149. package/src/components/Navigation/constants.ts +8 -0
  150. package/src/components/Navigation/index.tsx +3 -0
  151. package/src/components/Navigation/types.ts +37 -0
  152. package/src/components/Navigation/utils.tsx +54 -0
  153. package/src/components/Overlay.tsx +68 -64
  154. package/src/components/Pager/index.tsx +241 -0
  155. package/src/components/Pager/styles.ts +51 -0
  156. package/src/components/RadioInput/index.tsx +76 -52
  157. package/src/components/RadioInput/styles.ts +23 -18
  158. package/src/components/Scroll.tsx +84 -73
  159. package/src/components/Select/index.tsx +179 -6
  160. package/src/components/Select/styles.ts +81 -0
  161. package/src/components/Select/types.ts +41 -0
  162. package/src/components/Slider/Mark.tsx +46 -0
  163. package/src/components/Slider/Thumb.tsx +29 -0
  164. package/src/components/Slider/index.tsx +123 -0
  165. package/src/components/Slider/types.ts +25 -0
  166. package/src/components/Switch.tsx +63 -54
  167. package/src/components/Text.tsx +22 -23
  168. package/src/components/TextInput.tsx +195 -198
  169. package/src/components/Touchable.tsx +43 -30
  170. package/src/components/View.tsx +32 -29
  171. package/src/components/components.ts +26 -0
  172. package/src/index.ts +6 -3
  173. package/src/modules/documentPicker.ts +8 -2
  174. package/src/modules/fastImage.ts +2 -2
  175. package/src/modules/index.d.ts +496 -0
  176. package/src/modules/reactNavigation.ts +4 -0
  177. package/src/modules/types/documentPicker.d.ts +215 -0
  178. package/src/modules/types/fileTypes.ts +138 -0
  179. package/src/types/utility.ts +2 -2
  180. package/src/utils/OSAlert.ts +35 -33
  181. package/src/utils/misc.ts +24 -0
  182. package/src/utils/styles.ts +14 -17
  183. package/dist/components/Drawer.d.ts +0 -23
  184. package/dist/components/Drawer.js +0 -78
  185. package/dist/components/Drawer.js.map +0 -1
  186. package/dist/components/Navigation.d.ts +0 -30
  187. package/dist/components/Navigation.js +0 -126
  188. package/dist/components/Navigation.js.map +0 -1
  189. package/dist/components/Slider.js +0 -130
  190. package/dist/components/Slider.js.map +0 -1
  191. package/dist/components/index.js.map +0 -1
  192. package/dist/modules/cropPicker.d.ts +0 -1
  193. package/dist/modules/cropPicker.js +0 -10
  194. package/dist/modules/cropPicker.js.map +0 -1
  195. package/src/components/Navigation.tsx +0 -125
  196. package/src/components/Slider.tsx +0 -198
  197. package/src/components/index.ts +0 -23
@@ -0,0 +1,25 @@
1
+ import { ComponentVariants, Form, SliderComposition, SliderStyles } from '@codeleap/common'
2
+ import { SliderProps as RNSliderProps } from '@miblanchard/react-native-slider/lib/types'
3
+ import { StylesOf } from '../../types/utility'
4
+ import { ViewProps } from '../View'
5
+ export type SliderProps = Partial<Omit<RNSliderProps, 'value' | 'onValueChange'>> & {
6
+ debounce?: number;
7
+ labels: string[];
8
+ value: number;
9
+ valueOverThumb?: boolean;
10
+ showMarks?: boolean;
11
+ onValueChange: (val: number) => void;
12
+ label: Form.Label;
13
+ formatTooltip?: (val: number) => React.ReactNode;
14
+ variants?: ComponentVariants<typeof SliderStyles>['variants'];
15
+ styles?: StylesOf<SliderComposition>;
16
+ style?: ViewProps['style'];
17
+ tooltipVisibilityWindow?: number
18
+ };
19
+
20
+ export type SliderMarkProps = {
21
+ sliderProps: SliderProps;
22
+ index: number;
23
+ styles: SliderProps['styles'];
24
+ variantStyles: SliderProps['styles'];
25
+ };
@@ -1,73 +1,82 @@
1
1
  import * as React from 'react'
2
- import { SwitchStyles,SwitchComposition, ComponentVariants, useComponentStyle, StylesOf, useStyle, FormTypes, useValidate } from '@codeleap/common'
2
+ import {
3
+ SwitchStyles,
4
+ SwitchComposition,
5
+ ComponentVariants,
6
+ useDefaultComponentStyle,
7
+ StylesOf,
8
+ useCodeleapContext,
9
+ FormTypes,
10
+ useValidate,
11
+ } from '@codeleap/common'
3
12
  import { ComponentPropsWithRef, forwardRef, ReactNode } from 'react'
4
13
  import { StyleSheet, Switch as NativeSwitch } from 'react-native'
5
- import { InputLabel, FormError} from './TextInput'
14
+ import { InputLabel, FormError } from './TextInput'
6
15
  import { View } from './View'
7
16
 
8
-
9
17
  type NativeSwitchProps = Omit<
10
- ComponentPropsWithRef<typeof NativeSwitch>,
11
- 'thumbColor'|'trackColor'
12
- >
18
+ ComponentPropsWithRef<typeof NativeSwitch>,
19
+ 'thumbColor' | 'trackColor'
20
+ >;
13
21
  type SwitchProps = NativeSwitchProps & {
14
- variants?: ComponentVariants<typeof SwitchStyles>['variants']
15
- label?: ReactNode
16
- styles?: StylesOf<SwitchComposition>
17
- validate?: FormTypes.ValidatorFunction | string
18
- }
22
+ variants?: ComponentVariants<typeof SwitchStyles>['variants'];
23
+ label?: ReactNode;
24
+ styles?: StylesOf<SwitchComposition>;
25
+ validate?: FormTypes.ValidatorFunctionWithoutForm | string;
26
+ };
27
+
19
28
 
20
- export const Switch = forwardRef<NativeSwitch,SwitchProps>((switchProps,ref) => {
21
- const {
22
- variants = [],
23
- style = {},
24
- styles = {},
25
- validate,
26
- label,
27
- value,
28
- ...props
29
+ export const Switch = forwardRef<NativeSwitch, SwitchProps>(
30
+ (switchProps, ref) => {
31
+ const {
32
+ variants = [],
33
+ style = {},
34
+ styles = {},
35
+ validate,
36
+ label,
37
+ value,
38
+ ...props
29
39
  } = switchProps
30
40
 
31
- const variantStyles = useComponentStyle('Switch', {
32
- variants,
33
-
41
+ const variantStyles = useDefaultComponentStyle('Switch', {
42
+ variants,
34
43
  })
35
- const {error,showError} = useValidate(switchProps.value, validate)
36
- function getStyles(key:SwitchComposition){
37
- return [
38
- variantStyles[key],
39
- styles[key],
40
- key === 'wrapper' ? style : {},
41
- showError ? variantStyles[key + ':error'] : {},
42
- showError ? styles[key + ':error'] : {},
43
- value ? variantStyles[key + ':on'] : {},
44
- value ? styles[key + ':on'] : {},
45
- switchProps.disabled ? variantStyles[key + ':disabled'] : {},
46
- switchProps.disabled ? styles[key + ':disabled'] : {},
47
-
48
- ]
44
+ const { error, showError } = useValidate(switchProps.value, validate)
45
+ function getStyles(key: SwitchComposition) {
46
+ return [
47
+ variantStyles[key],
48
+ styles[key],
49
+ key === 'wrapper' ? style : {},
50
+ showError ? variantStyles[key + ':error'] : {},
51
+ showError ? styles[key + ':error'] : {},
52
+ value ? variantStyles[key + ':on'] : {},
53
+ value ? styles[key + ':on'] : {},
54
+ switchProps.disabled ? variantStyles[key + ':disabled'] : {},
55
+ switchProps.disabled ? styles[key + ':disabled'] : {},
56
+ ]
49
57
  }
50
58
 
51
59
  const inputStyles = getStyles('input')
52
60
 
53
- const {color,backgroundColor} = StyleSheet.flatten(inputStyles)
54
- const {Theme} = useStyle()
61
+ const { color, backgroundColor } = StyleSheet.flatten(inputStyles)
62
+ const { Theme } = useCodeleapContext()
55
63
 
56
64
  const thumbColor = color || Theme.colors.primary
57
- const trackColor = backgroundColor || Theme.colors.gray
58
- return <View style={getStyles('wrapper')}>
65
+ const trackColor = backgroundColor || Theme.colors.gray
66
+ return (
67
+ <View style={getStyles('wrapper')}>
59
68
  <View style={getStyles('inputWrapper')}>
60
-
61
- <NativeSwitch
62
-
63
- thumbColor={thumbColor}
64
- trackColor={{ false:trackColor, true: trackColor}}
65
- ios_backgroundColor={trackColor}
66
- value={value}
67
- {...props}
68
- />
69
- <InputLabel label={label} style={getStyles('label')}/>
69
+ <NativeSwitch
70
+ thumbColor={thumbColor}
71
+ trackColor={{ false: trackColor, true: trackColor }}
72
+ ios_backgroundColor={trackColor}
73
+ value={value}
74
+ {...props}
75
+ />
76
+ <InputLabel label={label} style={getStyles('label')} />
70
77
  </View>
71
- <FormError message={error.message} style={getStyles('error')}/>
72
- </View>
73
- })
78
+ <FormError message={error.message} style={getStyles('error')} />
79
+ </View>
80
+ )
81
+ },
82
+ ) as React.FC<SwitchProps>
@@ -1,31 +1,30 @@
1
1
  import * as React from 'react'
2
2
  import { ComponentPropsWithoutRef, forwardRef } from 'react'
3
- import { ComponentVariants, useComponentStyle, BaseViewProps, TextStyles } from '@codeleap/common'
4
- import { Text as NativeText } from 'react-native'
3
+ import {
4
+ ComponentVariants,
5
+ useDefaultComponentStyle,
6
+ BaseViewProps,
7
+ TextStyles,
8
+ } from '@codeleap/common'
9
+ import { Text as NativeText } from 'react-native'
5
10
 
6
-
7
- export type TextProps =
8
- ComponentPropsWithoutRef<typeof NativeText> &
9
- {
10
- text?: string,
11
- variants?: ComponentVariants <typeof TextStyles>['variants'],
12
- } & BaseViewProps
11
+ export type TextProps = ComponentPropsWithoutRef<typeof NativeText> & {
12
+ text?: string;
13
+ variants?: ComponentVariants<typeof TextStyles>['variants'];
14
+ } & BaseViewProps;
13
15
 
14
16
  export const Text = forwardRef<NativeText, TextProps>((textProps, ref) => {
15
- const {
16
- variants = [],
17
- text,
18
- style,
19
- ...props
20
- } = textProps
21
-
22
- const variantStyles = useComponentStyle('Text', {
17
+ const { variants = [], text, style, ...props } = textProps
18
+
19
+ const variantStyles = useDefaultComponentStyle('Text', {
23
20
  variants,
24
- rootElement : 'text'
21
+ rootElement: 'text',
25
22
  })
26
-
23
+
27
24
  const styles = [variantStyles.text, style]
28
- return <NativeText {...props} style={styles} ref={ref}>
29
- {text}
30
- </NativeText>
31
- })
25
+ return (
26
+ <NativeText {...props} style={styles} ref={ref}>
27
+ {text}
28
+ </NativeText>
29
+ )
30
+ })
@@ -1,206 +1,203 @@
1
1
  import * as React from 'react'
2
- import {
3
- ComponentVariants,
4
- FormTypes,
5
- IconPlaceholder,
6
- TextInputComposition,
7
- TextInputStyles,
8
- useBooleanToggle,
9
- useComponentStyle,
10
- useValidate
11
- } from '@codeleap/common';
12
- import { ComponentPropsWithoutRef, forwardRef, useImperativeHandle, useRef, useState } from 'react'
13
- import { Text } from './Text';
14
- import { View } from './View';
15
- import { Button } from './Button';
16
- import { StylesOf } from '../types/utility';
17
- import { Icon } from './Icon';
18
- import {NativeSyntheticEvent, TextInput as NativeTextInput, TextInputChangeEventData} from 'react-native'
19
-
20
- type IconProp = {name: IconPlaceholder, action?:() => void}
21
-
22
- type NativeProps = ComponentPropsWithoutRef<typeof NativeTextInput>
23
-
24
- export type TextInputProps =
25
- ComponentVariants<typeof TextInputStyles> &
26
- Omit<NativeProps, 'value'> &
27
- {
28
- multiline?: boolean;
29
- onChangeText?: (text: string) => void;
30
- disabled?: boolean;
31
- edited?: boolean;
32
- type?: string;
33
- label?:React.ReactNode
34
-
35
- leftIcon?:IconProp
36
- rightIcon?:IconProp
37
- styles?: StylesOf<TextInputComposition>
38
- validate?: FormTypes.ValidatorFunction | string
39
- value?:string
40
- password?:boolean
41
- visibilityToggle?: boolean
42
- };
43
-
44
- export const TextInput = forwardRef<NativeTextInput, TextInputProps>((rawprops, inputRef) => {
45
- const {
46
- onChange,
47
- type,
48
- value,
49
- onChangeText,
50
- disabled,
51
- edited,
52
- onFocus,
53
- onBlur,
54
- multiline,
55
- responsiveVariants,
56
- variants,
57
- label,
58
- leftIcon,
59
- rightIcon,
60
- styles,
61
- validate,
62
- password,
63
- visibilityToggle,
64
-
65
- ...props
66
- } = rawprops
67
-
68
- const [_ig, setFocus] = useState(false)
69
- const [editedState, setEdited] = useState(edited)
70
-
71
- const input = useRef<any>(null)
72
- const [textIsVisible, setTextVisible] = useBooleanToggle(false)
73
- const variantStyles =useComponentStyle('TextInput', {
74
- variants,
75
- responsiveVariants,
76
- styles,
77
- })
78
- const InputElement = NativeTextInput
79
-
80
- const handleBlur:TextInputProps['onBlur'] = (e) => {
81
- if (!editedState && value) setEdited(true)
82
- setFocus(false)
83
-
84
- if (onBlur) {
85
- onBlur(e)
86
- }
87
- }
88
-
89
- const handleFocus:TextInputProps['onFocus'] = (e) => {
90
- setFocus(true)
91
- if (onFocus) {
92
- onFocus(e)
93
- }
94
- }
95
-
96
- const handleChange = (event:NativeSyntheticEvent<TextInputChangeEventData>) => {
97
- const text = event.nativeEvent.text
98
-
99
- if (onChange) onChange(event)
100
- if (onChangeText) onChangeText(text)
101
- }
102
-
103
-
104
-
105
-
106
- useImperativeHandle(inputRef, () => input.current)
107
-
108
- const {showError, error} = useValidate(value, validate)
109
-
110
-
111
- const leftIconStyle = {
112
- ...variantStyles.icon,
113
- ...(showError ? variantStyles['icon:error'] : {} ),
114
- ...variantStyles.leftIcon,
115
- ...(showError ? variantStyles['leftIcon:error'] : {} ),
116
- }
117
-
118
- const rightIconStyle = {
119
- ...variantStyles.icon,
120
- ...(showError ? variantStyles['icon:error'] : {} ),
121
- ...variantStyles.rightIcon,
122
- ...(showError ? variantStyles['rightIcon:error'] : {} ),
123
- }
124
-
125
- function getStyles(key:TextInputComposition){
126
- const requestedStyles = [variantStyles[key], showError ? variantStyles[key + ':error'] : {}]
127
- return requestedStyles
128
- }
2
+ import {
3
+ ComponentVariants,
4
+ FormTypes,
5
+ IconPlaceholder,
6
+ TextInputComposition,
7
+ TextInputStyles,
8
+ useBooleanToggle,
9
+ useDefaultComponentStyle,
10
+ useValidate,
11
+ } from '@codeleap/common'
12
+ import { ComponentPropsWithoutRef, forwardRef, useImperativeHandle, useRef, useState } from 'react'
13
+ import { Text } from './Text'
14
+ import { View, ViewProps } from './View'
15
+ import { Button } from './Button'
16
+ import { StylesOf } from '../types/utility'
17
+ import { Icon } from './Icon'
18
+ import { NativeSyntheticEvent, StyleSheet, TextInput as NativeTextInput, TextInputChangeEventData } from 'react-native'
19
+ import { Touchable, TouchableProps } from './Touchable'
20
+
21
+ type IconProp = { name: IconPlaceholder, action?: () => void }
22
+
23
+ type NativeProps = ComponentPropsWithoutRef<typeof NativeTextInput>
24
+
25
+ export type TextInputProps =
26
+ ComponentVariants<typeof TextInputStyles> &
27
+ Omit<NativeProps, 'value'> &
28
+ {
29
+ multiline?: boolean;
30
+ onChangeText?: (text: string) => void;
31
+ disabled?: boolean;
32
+ edited?: boolean;
33
+ type?: string;
34
+ label?: React.ReactNode
129
35
 
130
-
131
- return (
132
- <View
133
- style={getStyles('wrapper')}
134
- >
135
- <InputLabel label={label} style={getStyles('label')}/>
136
-
137
- <View style={getStyles('innerWrapper')}>
138
-
139
-
140
- <InputIcon {...leftIcon} style={leftIconStyle}/>
141
- <InputElement
142
- ref={input}
143
- secureTextEntry={password && !textIsVisible}
144
- onChange={handleChange}
145
- value={value}
146
- editable={disabled}
147
- onFocus={handleFocus}
148
- onBlur={handleBlur}
149
- {...props}
150
- style={getStyles('textField')}
151
- />
152
- {
153
- visibilityToggle ?
154
- <InputIcon name={
155
- (textIsVisible ? 'input-visiblity:visible' : 'input-visiblity:hidden') as IconPlaceholder
156
- } action={() => setTextVisible()} style={rightIconStyle}/>
157
- :
158
- <InputIcon {...rightIcon} style={rightIconStyle}/>
159
- }
160
- </View>
161
-
162
- <FormError message={error.message} style={{
163
- ...variantStyles.error,
164
-
165
- }}/>
166
-
167
-
168
- </View>
169
- )
36
+ leftIcon?: IconProp
37
+ rightIcon?: IconProp
38
+ styles?: StylesOf<TextInputComposition>
39
+ validate?: FormTypes.ValidatorFunctionWithoutForm | string
40
+ value?: string
41
+ password?: boolean
42
+ visibilityToggle?: boolean
43
+ touchableWrapper?: boolean
44
+ innerWrapperProps?: TouchableProps | ViewProps
45
+ };
46
+
47
+ export const TextInput = forwardRef<NativeTextInput, TextInputProps>((rawprops, inputRef) => {
48
+ const {
49
+ onChange,
50
+ type,
51
+ value,
52
+ onChangeText,
53
+ disabled,
54
+ edited,
55
+ onFocus,
56
+ onBlur,
57
+ multiline,
58
+ variants,
59
+ label,
60
+ leftIcon,
61
+ rightIcon,
62
+ styles,
63
+ validate,
64
+ password,
65
+ visibilityToggle,
66
+ touchableWrapper,
67
+ innerWrapperProps,
68
+ ...props
69
+ } = rawprops
70
+
71
+ const [isFocused, setFocus] = useState(false)
72
+ const [editedState, setEdited] = useState(edited)
73
+
74
+ const input = useRef<any>(null)
75
+ const [textIsVisible, setTextVisible] = useBooleanToggle(false)
76
+ const variantStyles = useDefaultComponentStyle('TextInput', {
77
+ variants,
78
+ styles,
170
79
  })
171
-
172
- export const FormError = ({message, ...props}) => {
173
-
174
-
175
- if (['number', 'string', 'undefined'].includes(typeof message)){
176
- return <Text text={`${message||' '}`} variants={['p2', 'marginTop:1']} {...props}/>
80
+ const InputElement = NativeTextInput
81
+
82
+ const handleBlur: TextInputProps['onBlur'] = (e) => {
83
+ if (!editedState && value) setEdited(true)
84
+ setFocus(false)
85
+
86
+ if (onBlur) {
87
+ onBlur(e)
177
88
  }
178
- return message
179
89
  }
180
- export const InputIcon:React.FC<{style:any} & IconProp> = ({name, style, action}) => {
181
- if (!name) return null
182
-
183
- if (action){
184
-
185
- return <Button icon={name} onPress={() => action()} styles={{
186
- icon: style,
187
- }} variants={['icon']}/>
188
-
90
+
91
+ const handleFocus: TextInputProps['onFocus'] = (e) => {
92
+ setFocus(true)
93
+ if (onFocus) {
94
+ onFocus(e)
189
95
  }
190
-
191
- return <Icon name={name} style={style}/>
192
96
  }
193
- export const InputLabel = ({label, style}) => {
194
- if (!label) return null
195
-
196
- switch (typeof label){
197
- case 'string':
198
- return <Text style={style} text={label}/>
199
- case 'object':
200
-
201
- return label
202
- default:
203
- return null
204
- }
97
+
98
+ const handleChange = (event: NativeSyntheticEvent<TextInputChangeEventData>) => {
99
+ const text = event.nativeEvent.text
100
+
101
+ if (onChange) onChange(event)
102
+ if (onChangeText) onChangeText(text)
103
+ }
104
+
105
+ useImperativeHandle(inputRef, () => ({...input.current, focus: () => {
106
+ input.current?.focus?.()
107
+ }, isTextInput: true}))
108
+
109
+ const { showError, error } = useValidate(value, validate)
110
+
111
+ const leftIconStyle = {
112
+ ...variantStyles.icon,
113
+ ...(isFocused ? variantStyles['icon:focus'] : {}),
114
+ ...(showError ? variantStyles['icon:error'] : {}),
115
+ ...variantStyles.leftIcon,
116
+ ...(isFocused ? variantStyles['leftIcon:focus'] : {}),
117
+ ...(showError ? variantStyles['leftIcon:error'] : {}),
118
+ }
119
+
120
+ const rightIconStyle = {
121
+ ...variantStyles.icon,
122
+ ...(isFocused ? variantStyles['icon:focus'] : {}),
123
+ ...(showError ? variantStyles['icon:error'] : {}),
124
+ ...variantStyles.rightIcon,
125
+ ...(isFocused ? variantStyles['rightIcon:focus'] : {}),
126
+ ...(showError ? variantStyles['rightIcon:error'] : {}),
127
+ }
128
+
129
+ function getStyles(key: TextInputComposition) {
130
+ const requestedStyles = [
131
+ variantStyles[key],
132
+ isFocused ? variantStyles[key + ':focus'] : {},
133
+ showError ? variantStyles[key + ':error'] : {},
134
+ ]
135
+ return requestedStyles
136
+ }
137
+
138
+ const InnerWrapper = touchableWrapper ? Touchable : View
139
+
140
+ return (
141
+ <View
142
+ style={getStyles('wrapper')}
143
+ >
144
+ <InputLabel label={label} style={getStyles('label')} />
145
+ <InnerWrapper style={getStyles('innerWrapper')} {...innerWrapperProps}>
146
+ <InputIcon {...leftIcon} style={leftIconStyle} />
147
+ <InputElement
148
+ ref={input}
149
+ secureTextEntry={password && !textIsVisible}
150
+ onChange={handleChange}
151
+ value={value}
152
+ editable={disabled}
153
+ onFocus={handleFocus}
154
+ onBlur={handleBlur}
155
+ placeholderTextColor={StyleSheet.flatten(getStyles('placeholder'))?.color}
156
+ {...props}
157
+ style={getStyles('textField')}
158
+ />
159
+ {
160
+ visibilityToggle ?
161
+ <InputIcon name={
162
+ (textIsVisible ? 'input-visiblity:visible' : 'input-visiblity:hidden') as IconPlaceholder
163
+ } action={() => setTextVisible()} style={rightIconStyle} />
164
+ :
165
+ <InputIcon {...rightIcon} style={rightIconStyle} />
166
+ }
167
+ </InnerWrapper>
168
+ <FormError message={error.message} style={{
169
+ ...variantStyles.error,
170
+ }} />
171
+ </View>
172
+ )
173
+ })
174
+
175
+ export const FormError = ({ message, ...props }) => {
176
+ if (['number', 'string', 'undefined'].includes(typeof message)) {
177
+ return <Text text={`${message || ' '}`} variants={['p2', 'marginTop:1']} {...props} />
178
+ }
179
+ return message
180
+ }
181
+
182
+ export const InputIcon: React.FC<{ style: any } & IconProp> = ({ name, style, action }) => {
183
+ if (!name) return null
184
+ if (action) {
185
+ return <Button icon={name} onPress={() => action()} styles={{
186
+ icon: style,
187
+ }} variants={['icon']} />
188
+ }
189
+ return <Icon name={name} style={style} />
190
+ }
191
+
192
+ export const InputLabel = ({ label, style }) => {
193
+ if (!label) return null
194
+
195
+ switch (typeof label) {
196
+ case 'string':
197
+ return <Text style={style} text={label} />
198
+ case 'object':
199
+ return label
200
+ default:
201
+ return null
205
202
  }
206
-
203
+ }