@codeleap/mobile 2.3.0 → 2.3.2

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 (126) hide show
  1. package/dist/components/Button/index.d.ts +0 -1
  2. package/dist/components/Button/index.js +5 -12
  3. package/dist/components/Button/index.js.map +1 -1
  4. package/dist/components/List/styles.js +1 -1
  5. package/dist/components/List/styles.js.map +1 -1
  6. package/dist/components/Touchable/index.js +11 -9
  7. package/dist/components/Touchable/index.js.map +1 -1
  8. package/dist/utils/theme.d.ts +1 -0
  9. package/dist/utils/theme.js +7 -2
  10. package/dist/utils/theme.js.map +1 -1
  11. package/package.json +1 -1
  12. package/src/components/ActionIcon/index.tsx +32 -0
  13. package/src/components/ActionIcon/styles.ts +97 -0
  14. package/src/components/ActivityIndicator/index.tsx +50 -0
  15. package/src/components/ActivityIndicator/styles.ts +68 -0
  16. package/src/components/Animated.tsx +34 -0
  17. package/src/components/AutoComplete/index.tsx +163 -0
  18. package/src/components/AutoComplete/styles.ts +44 -0
  19. package/src/components/Backdrop/index.tsx +48 -0
  20. package/src/components/Backdrop/styles.ts +33 -0
  21. package/src/components/Button/index.tsx +154 -0
  22. package/src/components/Button/styles.ts +129 -0
  23. package/src/components/Calendar/index.tsx +65 -0
  24. package/src/components/Calendar/style.ts +35 -0
  25. package/src/components/Calendar/types.ts +102 -0
  26. package/src/components/Checkbox/index.tsx +91 -0
  27. package/src/components/Checkbox/styles.ts +81 -0
  28. package/src/components/ContentView/index.tsx +63 -0
  29. package/src/components/ContentView/styles.ts +24 -0
  30. package/src/components/Drawer/index.tsx +33 -0
  31. package/src/components/Drawer/styles.ts +43 -0
  32. package/src/components/EmptyPlaceholder/index.tsx +88 -0
  33. package/src/components/EmptyPlaceholder/styles.ts +58 -0
  34. package/src/components/FileInput/index.tsx +181 -0
  35. package/src/components/FileInput/styles.ts +15 -0
  36. package/src/components/Grid/index.tsx +117 -0
  37. package/src/components/Grid/styles.ts +11 -0
  38. package/src/components/Icon/index.tsx +69 -0
  39. package/src/components/Icon/styles.ts +57 -0
  40. package/src/components/Image/index.tsx +91 -0
  41. package/src/components/Image/styles.ts +20 -0
  42. package/src/components/ImageView/Spotlight.tsx +157 -0
  43. package/src/components/ImageView/component.tsx +38 -0
  44. package/src/components/ImageView/index.ts +2 -0
  45. package/src/components/InputLabel/index.tsx +38 -0
  46. package/src/components/InputLabel/styles.ts +19 -0
  47. package/src/components/List/PaginationIndicator.tsx +71 -0
  48. package/src/components/List/index.tsx +114 -0
  49. package/src/components/List/styles.ts +19 -0
  50. package/src/components/Modal/index.tsx +218 -0
  51. package/src/components/Modal/styles.ts +153 -0
  52. package/src/components/MultiSelect/index.tsx +138 -0
  53. package/src/components/MultiSelect/styles.ts +18 -0
  54. package/src/components/MultiSelect/types.ts +42 -0
  55. package/src/components/Navigation/Navigation.tsx +54 -0
  56. package/src/components/Navigation/constants.ts +8 -0
  57. package/src/components/Navigation/index.tsx +3 -0
  58. package/src/components/Navigation/types.ts +35 -0
  59. package/src/components/Navigation/utils.tsx +57 -0
  60. package/src/components/Pager/index.tsx +121 -0
  61. package/src/components/Pager/styles.ts +81 -0
  62. package/src/components/RadioInput/index.tsx +106 -0
  63. package/src/components/RadioInput/styles.ts +67 -0
  64. package/src/components/Scroll/index.tsx +124 -0
  65. package/src/components/Scroll/styles.ts +18 -0
  66. package/src/components/Sections/index.tsx +91 -0
  67. package/src/components/SegmentedControl/index.tsx +204 -0
  68. package/src/components/SegmentedControl/styles.ts +89 -0
  69. package/src/components/Select/index.tsx +167 -0
  70. package/src/components/Select/styles.ts +62 -0
  71. package/src/components/Select/types.ts +43 -0
  72. package/src/components/Slider/Mark.tsx +46 -0
  73. package/src/components/Slider/Thumb.tsx +29 -0
  74. package/src/components/Slider/index.tsx +130 -0
  75. package/src/components/Slider/styles.ts +76 -0
  76. package/src/components/Slider/types.ts +30 -0
  77. package/src/components/Switch/index.tsx +91 -0
  78. package/src/components/Switch/styles.ts +38 -0
  79. package/src/components/Text/index.tsx +97 -0
  80. package/src/components/Text/styles.ts +50 -0
  81. package/src/components/TextInput/index.tsx +319 -0
  82. package/src/components/TextInput/styles.ts +127 -0
  83. package/src/components/Touchable/index.tsx +174 -0
  84. package/src/components/Touchable/styles.ts +28 -0
  85. package/src/components/View/index.tsx +103 -0
  86. package/src/components/View/styles.ts +24 -0
  87. package/src/components/components.ts +42 -0
  88. package/src/components/defaultStyles.ts +62 -0
  89. package/src/components/legacy/Modal/index.tsx +163 -0
  90. package/src/components/legacy/Modal/styles.ts +125 -0
  91. package/src/components/legacy/Pager/index.tsx +242 -0
  92. package/src/components/legacy/Pager/styles.ts +51 -0
  93. package/src/components/legacy/index.ts +2 -0
  94. package/src/modules/documentPicker.ts +7 -0
  95. package/src/modules/fastImage.ts +2 -0
  96. package/src/modules/imageCropPicker.d.ts +497 -0
  97. package/src/modules/index.d.ts +682 -0
  98. package/src/modules/reactNavigation.ts +15 -0
  99. package/src/modules/textInputMask.ts +11 -0
  100. package/src/modules/types/documentPicker.d.ts +215 -0
  101. package/src/modules/types/fileTypes.ts +138 -0
  102. package/src/modules/types/textInputMask.ts +9 -0
  103. package/src/types/index.ts +1 -0
  104. package/src/types/utility.ts +9 -0
  105. package/src/utils/KeyboardAware/context.tsx +75 -0
  106. package/src/utils/KeyboardAware/index.ts +17 -0
  107. package/src/utils/KeyboardAware/keyboardHooks.ts +124 -0
  108. package/src/utils/KeyboardAware/lib/KeyboardAwareFlatList.ts +4 -0
  109. package/src/utils/KeyboardAware/lib/KeyboardAwareHOC.tsx +618 -0
  110. package/src/utils/KeyboardAware/lib/KeyboardAwareInterface.ts +13 -0
  111. package/src/utils/KeyboardAware/lib/KeyboardAwareScrollView.ts +6 -0
  112. package/src/utils/KeyboardAware/lib/KeyboardAwareSectionList.ts +6 -0
  113. package/src/utils/KeyboardAware/types.ts +159 -0
  114. package/src/utils/ModalManager/components.tsx +112 -0
  115. package/src/utils/ModalManager/context.tsx +260 -0
  116. package/src/utils/ModalManager/index.ts +16 -0
  117. package/src/utils/OSAlert.ts +180 -0
  118. package/src/utils/PermissionManager/context.tsx +302 -0
  119. package/src/utils/PermissionManager/index.ts +20 -0
  120. package/src/utils/PermissionManager/types.ts +24 -0
  121. package/src/utils/hooks.ts +163 -0
  122. package/src/utils/index.ts +11 -0
  123. package/src/utils/input.ts +51 -0
  124. package/src/utils/misc.ts +83 -0
  125. package/src/utils/notifications.ts +206 -0
  126. package/src/utils/theme.ts +58 -0
@@ -0,0 +1,91 @@
1
+ import * as React from 'react'
2
+ import {
3
+
4
+ ComponentVariants,
5
+ useDefaultComponentStyle,
6
+ StylesOf,
7
+ useCodeleapContext,
8
+ FormTypes,
9
+ useValidate,
10
+ } from '@codeleap/common'
11
+ import { ComponentPropsWithRef, forwardRef, ReactNode } from 'react'
12
+ import { StyleSheet, Switch as NativeSwitch } from 'react-native'
13
+ import { FormError } from '../TextInput'
14
+ import { View } from '../View'
15
+
16
+ import {
17
+ SwitchStyles,
18
+ SwitchComposition,
19
+ } from './styles'
20
+ import { InputLabel } from '../InputLabel'
21
+ export * from './styles'
22
+ type NativeSwitchProps = Omit<
23
+ ComponentPropsWithRef<typeof NativeSwitch>,
24
+ 'thumbColor' | 'trackColor'
25
+ >
26
+ type SwitchProps = NativeSwitchProps & {
27
+ variants?: ComponentVariants<typeof SwitchStyles>['variants']
28
+ label?: ReactNode
29
+ styles?: StylesOf<SwitchComposition>
30
+ validate?: FormTypes.ValidatorFunctionWithoutForm | string
31
+ }
32
+
33
+ export const Switch = forwardRef<NativeSwitch, SwitchProps>(
34
+ (switchProps, ref) => {
35
+ const {
36
+ variants = [],
37
+ style = {},
38
+ styles = {},
39
+ validate,
40
+ label,
41
+ value,
42
+ ...props
43
+ } = switchProps
44
+
45
+ const variantStyles = useDefaultComponentStyle('Switch', {
46
+ variants,
47
+ })
48
+ const { error, showError } = useValidate(switchProps.value, validate)
49
+ function getStyles(key: SwitchComposition) {
50
+ return [
51
+ variantStyles[key],
52
+ styles[key],
53
+ key === 'wrapper' ? style : {},
54
+ showError ? variantStyles[key + ':error'] : {},
55
+ showError ? styles[key + ':error'] : {},
56
+ value ? variantStyles[key + ':on'] : {},
57
+ value ? styles[key + ':on'] : {},
58
+ switchProps.disabled ? variantStyles[key + ':disabled'] : {},
59
+ switchProps.disabled ? styles[key + ':disabled'] : {},
60
+ ]
61
+ }
62
+
63
+ const inputStyles = getStyles('input')
64
+
65
+ const { color, backgroundColor } = StyleSheet.flatten(inputStyles)
66
+ const { Theme } = useCodeleapContext()
67
+
68
+ const thumbColor = color || Theme.colors.primary
69
+ const trackColor = backgroundColor || Theme.colors.gray
70
+ return (
71
+ <View style={getStyles('wrapper')}>
72
+ <View style={getStyles('inputWrapper')}>
73
+ <NativeSwitch
74
+ thumbColor={thumbColor}
75
+ trackColor={{ false: trackColor, true: trackColor }}
76
+ ios_backgroundColor={trackColor}
77
+ value={value}
78
+ ref={ref}
79
+ {...props}
80
+ />
81
+ <InputLabel label={label} styles={{
82
+ asterisk: getStyles('labelAsterisk'),
83
+ text: getStyles('labelText'),
84
+ wrapper: getStyles('labelWrapper'),
85
+ }} />
86
+ </View>
87
+ <FormError text={error.message} style={getStyles('error')} />
88
+ </View>
89
+ )
90
+ },
91
+ ) as React.FC<SwitchProps>
@@ -0,0 +1,38 @@
1
+ import { createDefaultVariantFactory, includePresets } from '@codeleap/common'
2
+ import { InputLabelComposition } from '../InputLabel'
3
+
4
+ export type SwitchParts = 'wrapper' | `label${Capitalize<InputLabelComposition>}` | 'input' | 'error' | 'inputWrapper'
5
+ export type SwitchComposition =
6
+ | SwitchParts
7
+ | `${SwitchParts}:disabled`
8
+ | `${SwitchParts}:on`
9
+
10
+ const createSwitchStyle = createDefaultVariantFactory<SwitchComposition>()
11
+
12
+ const presets = includePresets((styles) => createSwitchStyle(() => ({ wrapper: styles })),
13
+ )
14
+
15
+ export const SwitchStyles = {
16
+ ...presets,
17
+ default: createSwitchStyle((theme) => ({
18
+ wrapper: {},
19
+ inputWrapper: {
20
+ ...theme.presets.row,
21
+ ...theme.presets.alignCenter,
22
+ },
23
+ labelWrapper: {
24
+ ...theme.spacing.marginLeft(0.5),
25
+ },
26
+ input: {
27
+ color: theme.colors.white,
28
+ backgroundColor: theme.colors.gray,
29
+ },
30
+ 'input:on': {
31
+ color: theme.colors.primary,
32
+ backgroundColor: theme.colors.gray,
33
+ },
34
+ error: {
35
+ color: theme.colors.negative,
36
+ },
37
+ })),
38
+ }
@@ -0,0 +1,97 @@
1
+ import * as React from 'react'
2
+ import { ComponentPropsWithoutRef, forwardRef } from 'react'
3
+ import {
4
+ ComponentVariants,
5
+ useDefaultComponentStyle,
6
+ BaseViewProps,
7
+ TypeGuards,
8
+ useState,
9
+ } from '@codeleap/common'
10
+ import { Animated, GestureResponderEvent, Platform, StyleSheet, Text as NativeText } from 'react-native'
11
+ import { MotiText as _MotiText, MotiProps } from 'moti'
12
+ import { useAnimateColor, usePressableFeedback } from '../../utils'
13
+ import { TextStyles } from './styles'
14
+ import { View } from '../View'
15
+
16
+ export * from './styles'
17
+
18
+ export type TextProps = ComponentPropsWithoutRef<typeof NativeText> & {
19
+ text?: React.ReactNode
20
+ variants?: ComponentVariants<typeof TextStyles>['variants']
21
+ animated?: boolean
22
+ colorChangeConfig?: Partial<Animated.TimingAnimationConfig>
23
+ debugName?: string
24
+ } & BaseViewProps & MotiProps
25
+
26
+ const MotiText = Animated.createAnimatedComponent(_MotiText)
27
+
28
+ export const Text = forwardRef<NativeText, TextProps>((textProps, ref) => {
29
+ const { variants = [], text, children, style, colorChangeConfig, ...props } = textProps
30
+
31
+ const pressPolyfillEnabled = Platform.OS === 'android' && !!props.onPress
32
+
33
+ const [pressed, setPressed] = useState(false)
34
+ const handlePress = (pressed) => {
35
+ if (!pressPolyfillEnabled) return
36
+ return () => {
37
+ if (props.onPress) {
38
+ setPressed(pressed)
39
+
40
+ }
41
+ }
42
+ }
43
+ const variantStyles = useDefaultComponentStyle<'u:Text', typeof TextStyles>('u:Text', {
44
+ variants,
45
+ transform: StyleSheet.flatten,
46
+ rootElement: 'text',
47
+ })
48
+
49
+ const styles = StyleSheet.flatten([variantStyles.text, style])
50
+
51
+ const animatedColor = useAnimateColor(styles.color, colorChangeConfig)
52
+
53
+ if (!!text && !TypeGuards.isString(text)) return <>{text}</>
54
+
55
+ const Component = textProps.animated ? MotiText : NativeText
56
+
57
+ const colorStyle = { color: props.animated ? animatedColor : styles.color }
58
+
59
+ const { getFeedbackStyle } = usePressableFeedback(styles, {
60
+ disabled: !pressPolyfillEnabled,
61
+ feedbackConfig: variantStyles.pressFeedback,
62
+ hightlightPropertyIn: 'color',
63
+ hightlightPropertyOut: 'backgroundColor',
64
+ })
65
+ const feedbackStyle = pressPolyfillEnabled ? getFeedbackStyle(pressed) : undefined
66
+
67
+ return <Component {...props}
68
+ onPressIn={handlePress(true)} onPressOut={handlePress(false)}
69
+ style={[styles, colorStyle, feedbackStyle]}
70
+ // @ts-ignore
71
+ ref={ref}
72
+ >
73
+ {text}
74
+ {children}
75
+ </Component>
76
+
77
+ })
78
+
79
+ // const childArr = React.Children.toArray([
80
+ // text,
81
+ // children,
82
+ // ])
83
+
84
+ // return <View style={[styles, colorStyle]}>
85
+ // {
86
+ // childArr.map((child) => {
87
+ // if (TypeGuards.isString(child)) {
88
+ // // @ts-ignore
89
+ // return <Component {...props} ref={ref}>
90
+ // {child}
91
+ // </Component>
92
+
93
+ // }
94
+ // return child
95
+ // })
96
+ // }
97
+ // </View>
@@ -0,0 +1,50 @@
1
+ import { assignTextStyle, createDefaultVariantFactory, includePresets, shadeColor, StylesOf } from '@codeleap/common'
2
+ import { FeedbackConfig } from '../../utils'
3
+
4
+ export type TextComposition = 'text' | 'touchFeedback'
5
+
6
+ export type TextStylesGen<TCSS = any> = StylesOf<'text', TCSS> & {
7
+ 'pressFeedback'?: FeedbackConfig
8
+ }
9
+
10
+ const createTextStyle = createDefaultVariantFactory<
11
+ TextComposition, TextStylesGen
12
+ >()
13
+
14
+ const presets = includePresets((styles) => createTextStyle(() => ({ text: styles })),
15
+ )
16
+
17
+ export const TextStyles = {
18
+ ...presets,
19
+ default: createTextStyle((theme) => {
20
+ const defaultStyle = assignTextStyle('p1')(theme).text
21
+ return {
22
+ text: {
23
+ fontFamily: theme.typography.fontFamily,
24
+ ...defaultStyle,
25
+ },
26
+ pressFeedback: {
27
+ type: 'highlight',
28
+ brightness: 0,
29
+ shiftOpacity: 0.3,
30
+ },
31
+ }
32
+ }),
33
+ h1: assignTextStyle('h1'),
34
+ h2: assignTextStyle('h2'),
35
+ h3: assignTextStyle('h3'),
36
+ h4: assignTextStyle('h4'),
37
+ h5: assignTextStyle('h5'),
38
+ h6: assignTextStyle('h6'),
39
+ p1: assignTextStyle('p1'),
40
+ p2: assignTextStyle('p2'),
41
+ p3: assignTextStyle('p3'),
42
+ p4: assignTextStyle('p4'),
43
+ link: assignTextStyle('p1'),
44
+ OSAlertBody: createTextStyle((theme) => ({
45
+ text: {
46
+ ...assignTextStyle('p1')(theme).text,
47
+ ...theme.presets.textCenter,
48
+ },
49
+ })),
50
+ }
@@ -0,0 +1,319 @@
1
+ import * as React from 'react'
2
+ import {
3
+ ComponentVariants,
4
+ FormTypes,
5
+ getNestedStylesByKey,
6
+ IconPlaceholder,
7
+
8
+ TypeGuards,
9
+
10
+ useBooleanToggle,
11
+ useDefaultComponentStyle,
12
+ useValidate,
13
+ } from '@codeleap/common'
14
+ import { ComponentPropsWithoutRef, forwardRef, useImperativeHandle, useRef, useState } from 'react'
15
+ import { Text, TextProps } from '../Text'
16
+ import { View, ViewProps } from '../View'
17
+ import { StylesOf } from '../../types'
18
+ import { NativeSyntheticEvent, StyleSheet, TextInput as NativeTextInput, TextInputChangeEventData } from 'react-native'
19
+ import { Touchable, TouchableProps } from '../Touchable'
20
+ import { MaskedTextInput, TextInputMaskProps } from '../../modules/textInputMask'
21
+ import { InputLabel } from '../InputLabel'
22
+
23
+ export * from './styles'
24
+
25
+ import {
26
+ InputIconComposition,
27
+ TextInputComposition,
28
+ TextInputStyles,
29
+ } from './styles'
30
+ import { ActionIcon, ActionIconParts, ActionIconProps } from '../ActionIcon'
31
+
32
+ type NativeProps = ComponentPropsWithoutRef<typeof NativeTextInput>
33
+
34
+ type SubtitleProps = {
35
+ errorProps: TextProps
36
+ styles: Record<'wrapper'|'error'|'subtitle', any>
37
+ }
38
+
39
+ export type TextInputProps =
40
+ Partial<TextInputMaskProps> &
41
+ ComponentVariants<typeof TextInputStyles> &
42
+ Omit<NativeProps, 'value'> &
43
+ {
44
+ multiline?: boolean
45
+ onChangeText?: (text: string) => void
46
+ disabled?: boolean
47
+ edited?: boolean
48
+ type?: string
49
+ label?: React.ReactNode
50
+ debugName: string
51
+ leftIcon?: Partial<ActionIconProps>
52
+ rightIcon?: Partial<ActionIconProps>
53
+ styles?: StylesOf<TextInputComposition>
54
+ validate?: FormTypes.ValidatorFunctionWithoutForm | string
55
+ value?: string
56
+ password?: boolean
57
+ visibilityToggle?: boolean
58
+ touchableWrapper?: boolean
59
+ subtitle?: string | ((props: SubtitleProps) => React.ReactElement)
60
+ onPress?: () => void
61
+ masking?: FormTypes.TextField['masking']
62
+ innerWrapperProps?: ViewProps
63
+ wrapperProps?: TouchableProps
64
+ onChangeMask?: TextInputMaskProps['onChangeText']
65
+ required?:boolean
66
+ }
67
+
68
+ export const TextInput = forwardRef<NativeTextInput, TextInputProps>((rawprops, inputRef) => {
69
+ const {
70
+ onChange,
71
+ value,
72
+ onChangeText,
73
+ disabled,
74
+ edited,
75
+ onFocus,
76
+ onBlur,
77
+ variants,
78
+ label,
79
+ wrapperProps,
80
+ leftIcon,
81
+ rightIcon,
82
+ styles,
83
+ validate,
84
+ password,
85
+ visibilityToggle,
86
+ innerWrapperProps,
87
+ masking,
88
+ subtitle = '',
89
+ onChangeMask,
90
+ debugName,
91
+ required = false,
92
+ ...props
93
+ } = rawprops
94
+
95
+ const [isFocused, setFocus] = useState(false)
96
+ const [editedState, setEdited] = useState(edited)
97
+
98
+ const input = useRef<any>(null)
99
+ const maskInputRef = useRef<any>(null)
100
+ const [textIsVisible, setTextVisible] = useBooleanToggle(false)
101
+ const variantStyles = useDefaultComponentStyle<'u:TextInput', typeof TextInputStyles>('u:TextInput', {
102
+ variants,
103
+ styles,
104
+ transform: StyleSheet.flatten,
105
+ })
106
+ const InputElement = masking ? MaskedTextInput : NativeTextInput
107
+
108
+ const handleBlur: TextInputProps['onBlur'] = (e) => {
109
+ if (!editedState && value) setEdited(true)
110
+ setFocus(false)
111
+
112
+ if (onBlur) {
113
+ onBlur(e)
114
+ }
115
+ }
116
+
117
+ const handleFocus: TextInputProps['onFocus'] = (e) => {
118
+ setFocus(true)
119
+ if (onFocus) {
120
+ onFocus(e)
121
+ }
122
+ }
123
+ const handleMaskChange = (masked, unmasked) => {
124
+
125
+ if (onChangeText) onChangeText(masking?.saveFormatted ? masked : masked)
126
+ if (onChangeMask) onChangeMask(masked, unmasked)
127
+ }
128
+ const handleChange = (event: NativeSyntheticEvent<TextInputChangeEventData>) => {
129
+ const text = event.nativeEvent.text
130
+
131
+ if (onChange) onChange(event)
132
+ if (onChangeText) onChangeText(text)
133
+ }
134
+
135
+ useImperativeHandle(inputRef, () => {
136
+ return {
137
+ ...input.current,
138
+ focus: () => {
139
+ input.current?.focus?.()
140
+ },
141
+ isTextInput: true,
142
+ }
143
+
144
+ }, [!!masking, !!input?.current?.focus])
145
+
146
+ const { showError, error } = useValidate(value, validate)
147
+
148
+ const commonIconStyles = getNestedStylesByKey('icon', variantStyles)
149
+
150
+ const leftIconStyles = getNestedStylesByKey('leftIcon', variantStyles)
151
+
152
+ const rightIconStyles = getNestedStylesByKey('rightIcon', variantStyles)
153
+
154
+ function getStyles(key: TextInputComposition) {
155
+ const requestedStyles = [
156
+ variantStyles[key],
157
+ isFocused ? variantStyles[key + ':focus'] : {},
158
+ showError ? variantStyles[key + ':error'] : {},
159
+ ]
160
+ return StyleSheet.flatten(requestedStyles)
161
+ }
162
+
163
+ function handlePress() {
164
+ if (props.onPress) {
165
+ props.onPress()
166
+ } else {
167
+ input.current?.focus?.()
168
+ }
169
+ }
170
+
171
+ const visibilityToggleProps = visibilityToggle ? {
172
+ onPress: () => setTextVisible(),
173
+ icon: (textIsVisible ? 'input-visiblity:visible' : 'input-visiblity:hidden') as IconPlaceholder,
174
+ debugName: `${debugName} toggle visibility`,
175
+ } : {}
176
+
177
+ const subtitleStyles = {
178
+ error: getStyles('error'),
179
+ wrapper: getStyles('subtitleWrapper'),
180
+ subtitle: getStyles('subtitle'),
181
+
182
+ }
183
+ const errorProps = { text: error.message, style: subtitleStyles.error }
184
+
185
+ const subtitleContent = TypeGuards.isFunction(subtitle) ? subtitle({ styles: subtitleStyles, errorProps }) : <View style={subtitleStyles.wrapper}>
186
+ <FormError {...errorProps}/>
187
+ {TypeGuards.isString(subtitle) ? <Text text={subtitle} style={subtitleStyles.subtitle}/> : (subtitle || null)}
188
+ </View>
189
+ return (
190
+ <Touchable
191
+ style={getStyles('wrapper')}
192
+ debugName={debugName}
193
+ onPress={handlePress}
194
+ {...wrapperProps}
195
+ android_ripple={null}
196
+ noFeedback
197
+ >
198
+ <InputLabel
199
+ label={label}
200
+ styles={{
201
+ wrapper: getStyles('labelWrapper'),
202
+ asterisk: getStyles('labelAsterisk'),
203
+ text: getStyles('labelText'),
204
+ }}
205
+ required={required}
206
+ />
207
+ <View style={getStyles('innerWrapper')} {...innerWrapperProps}>
208
+ <InputIcon
209
+ isFocused={isFocused}
210
+ showError={showError}
211
+ styles={leftIconStyles}
212
+ commonStyles={commonIconStyles}
213
+ debugName={`${debugName} left icon`}
214
+ onPress={() => {}}
215
+ noFeedback={!leftIcon?.onPress}
216
+ {...leftIcon}
217
+ />
218
+ {/* @ts-ignore */}
219
+ <InputElement
220
+
221
+ secureTextEntry={password && !textIsVisible}
222
+ onChange={(e) => masking ? onChange?.(e) : handleChange(e)}
223
+ value={value}
224
+ editable={disabled}
225
+ onFocus={handleFocus}
226
+ onBlur={handleBlur}
227
+ placeholderTextColor={StyleSheet.flatten(getStyles('placeholder'))?.color}
228
+ selectionColor={StyleSheet.flatten(getStyles('selection'))?.color}
229
+ includeRawValueInChangeText={true}
230
+ {...props}
231
+ {...masking}
232
+ {...(!!masking ? {
233
+ onChangeText: handleMaskChange,
234
+ ref: maskInputRef,
235
+ refInput: (inputRef) => {
236
+ // console.log(inputRef)
237
+ if (!!inputRef) {
238
+ input.current = inputRef
239
+
240
+ }
241
+ },
242
+ ...masking,
243
+ } : {
244
+ ref: input,
245
+ })}
246
+ style={getStyles('textField')}
247
+ />
248
+ <InputIcon
249
+ isFocused={isFocused}
250
+ showError={showError}
251
+ styles={rightIconStyles}
252
+ commonStyles={commonIconStyles}
253
+ debugName={`${debugName} right icon`}
254
+ onPress={() => {}}
255
+ noFeedback={!rightIcon?.onPress}
256
+ {...rightIcon}
257
+ {...visibilityToggleProps}
258
+ />
259
+
260
+ </View>
261
+ {subtitleContent}
262
+ </Touchable>
263
+ )
264
+ })
265
+
266
+ export const FormError:React.FC<TextProps> = ({ text, ...props }) => {
267
+ let message = text
268
+ if (TypeGuards.isNumber(message)) {
269
+ message = message.toString()
270
+ }
271
+ if (typeof message === 'undefined') {
272
+ message = ''
273
+ }
274
+
275
+ if (TypeGuards.isString(message)) {
276
+ const text = message ? `${message.charAt(0).toUpperCase() + message.slice(1)}` : ' '
277
+ return <Text text={text} {...props} />
278
+ }
279
+ return <>
280
+ {text}
281
+ </>
282
+ }
283
+
284
+ type InputIconProps = {
285
+ styles: StylesOf<InputIconComposition>
286
+ commonStyles: StylesOf<InputIconComposition>
287
+ isFocused: boolean
288
+ showError: boolean
289
+ } & Omit<ActionIconProps, 'styles'>
290
+
291
+ export const InputIcon:React.FC<InputIconProps> = ({ styles, commonStyles, isFocused, showError, ...props }) => {
292
+ if (!props.icon) return null
293
+
294
+ function getStyles(k: ActionIconParts | '') {
295
+ let key = k
296
+ if (key === 'icon') key = ''
297
+ const requestedStyles = [
298
+ commonStyles[key],
299
+ isFocused ? commonStyles[key + ':focus'] : {},
300
+ showError ? commonStyles[key + ':error'] : {},
301
+ styles[key],
302
+ isFocused ? styles[key + ':focus'] : {},
303
+ showError ? styles[key + ':error'] : {},
304
+ ]
305
+
306
+ return StyleSheet.flatten(requestedStyles)
307
+ }
308
+ const iconStyles = {
309
+ icon: getStyles('icon'),
310
+ touchablePressable: getStyles('touchablePressable'),
311
+ touchableWrapper: getStyles('touchableWrapper'),
312
+ touchableFeedback: getStyles('touchableFeedback'),
313
+ }
314
+
315
+ return <ActionIcon
316
+ styles={iconStyles}
317
+ {...props}
318
+ />
319
+ }