@codeleap/mobile 1.9.24 → 1.9.27

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 (210) hide show
  1. package/CodeLeap-Mobile-Packages.code-workspace +7 -7
  2. package/dist/components/ActivityIndicator.d.ts +13 -13
  3. package/dist/components/ActivityIndicator.js +54 -54
  4. package/dist/components/ActivityIndicator.js.map +0 -0
  5. package/dist/components/Animated.d.ts +123 -15
  6. package/dist/components/Animated.js +58 -58
  7. package/dist/components/Animated.js.map +0 -0
  8. package/dist/components/Button.d.ts +132 -125
  9. package/dist/components/Button.js +93 -82
  10. package/dist/components/Button.js.map +1 -1
  11. package/dist/components/Checkbox/index.d.ts +15 -15
  12. package/dist/components/Checkbox/index.js +79 -77
  13. package/dist/components/Checkbox/index.js.map +1 -1
  14. package/dist/components/Checkbox/styles.d.ts +55 -55
  15. package/dist/components/Checkbox/styles.js +51 -48
  16. package/dist/components/Checkbox/styles.js.map +1 -1
  17. package/dist/components/ContentView.d.ts +10 -10
  18. package/dist/components/ContentView.js +50 -50
  19. package/dist/components/ContentView.js.map +0 -0
  20. package/dist/components/EmptyPlaceholder.d.ts +12 -0
  21. package/dist/components/EmptyPlaceholder.js +54 -0
  22. package/dist/components/EmptyPlaceholder.js.map +1 -0
  23. package/dist/components/FileInput.d.ts +31 -28
  24. package/dist/components/FileInput.js +230 -195
  25. package/dist/components/FileInput.js.map +1 -1
  26. package/dist/components/Gap.d.ts +8 -0
  27. package/dist/components/Gap.js +60 -0
  28. package/dist/components/Gap.js.map +1 -0
  29. package/dist/components/Icon.d.ts +12 -12
  30. package/dist/components/Icon.js +70 -70
  31. package/dist/components/Icon.js.map +0 -0
  32. package/dist/components/Image.d.ts +18 -18
  33. package/dist/components/Image.js +59 -59
  34. package/dist/components/Image.js.map +0 -0
  35. package/dist/components/List.d.ts +14 -14
  36. package/dist/components/List.js +84 -83
  37. package/dist/components/List.js.map +1 -1
  38. package/dist/components/Modal/index.d.ts +27 -26
  39. package/dist/components/Modal/index.js +113 -112
  40. package/dist/components/Modal/index.js.map +1 -1
  41. package/dist/components/Modal/styles.d.ts +69 -69
  42. package/dist/components/Modal/styles.js +64 -64
  43. package/dist/components/Modal/styles.js.map +0 -0
  44. package/dist/components/Navigation/Navigation.d.ts +3 -3
  45. package/dist/components/Navigation/Navigation.js +87 -87
  46. package/dist/components/Navigation/Navigation.js.map +0 -0
  47. package/dist/components/Navigation/constants.d.ts +5 -5
  48. package/dist/components/Navigation/constants.js +10 -10
  49. package/dist/components/Navigation/constants.js.map +0 -0
  50. package/dist/components/Navigation/index.d.ts +3 -3
  51. package/dist/components/Navigation/index.js +19 -19
  52. package/dist/components/Navigation/index.js.map +0 -0
  53. package/dist/components/Navigation/types.d.ts +26 -26
  54. package/dist/components/Navigation/types.js +7 -7
  55. package/dist/components/Navigation/types.js.map +0 -0
  56. package/dist/components/Navigation/utils.d.ts +3 -3
  57. package/dist/components/Navigation/utils.js +69 -69
  58. package/dist/components/Navigation/utils.js.map +0 -0
  59. package/dist/components/NewPager/index.d.ts +26 -0
  60. package/dist/components/NewPager/index.js +92 -0
  61. package/dist/components/NewPager/index.js.map +1 -0
  62. package/dist/components/NewPager/styles.d.ts +87 -0
  63. package/dist/components/NewPager/styles.js +70 -0
  64. package/dist/components/NewPager/styles.js.map +1 -0
  65. package/dist/components/Overlay.d.ts +16 -16
  66. package/dist/components/Overlay.js +69 -69
  67. package/dist/components/Overlay.js.map +0 -0
  68. package/dist/components/Pager/index.d.ts +20 -20
  69. package/dist/components/Pager/index.js +167 -167
  70. package/dist/components/Pager/index.js.map +0 -0
  71. package/dist/components/Pager/styles.d.ts +54 -54
  72. package/dist/components/Pager/styles.js +43 -43
  73. package/dist/components/Pager/styles.js.map +0 -0
  74. package/dist/components/RadioInput/index.d.ts +26 -26
  75. package/dist/components/RadioInput/index.js +72 -72
  76. package/dist/components/RadioInput/index.js.map +0 -0
  77. package/dist/components/RadioInput/styles.d.ts +57 -57
  78. package/dist/components/RadioInput/styles.js +44 -44
  79. package/dist/components/RadioInput/styles.js.map +0 -0
  80. package/dist/components/Scroll.d.ts +13 -13
  81. package/dist/components/Scroll.js +81 -81
  82. package/dist/components/Scroll.js.map +0 -0
  83. package/dist/components/Sections.d.ts +11 -11
  84. package/dist/components/Sections.js +80 -80
  85. package/dist/components/Sections.js.map +0 -0
  86. package/dist/components/Select/index.d.ts +5 -5
  87. package/dist/components/Select/index.js +150 -150
  88. package/dist/components/Select/index.js.map +0 -0
  89. package/dist/components/Select/styles.d.ts +9 -9
  90. package/dist/components/Select/styles.js +56 -56
  91. package/dist/components/Select/styles.js.map +0 -0
  92. package/dist/components/Select/types.d.ts +40 -40
  93. package/dist/components/Select/types.js +2 -2
  94. package/dist/components/Select/types.js.map +0 -0
  95. package/dist/components/Slider/Mark.d.ts +3 -3
  96. package/dist/components/Slider/Mark.js +31 -31
  97. package/dist/components/Slider/Mark.js.map +0 -0
  98. package/dist/components/Slider/Thumb.d.ts +7 -7
  99. package/dist/components/Slider/Thumb.js +29 -29
  100. package/dist/components/Slider/Thumb.js.map +0 -0
  101. package/dist/components/Slider/index.d.ts +3 -3
  102. package/dist/components/Slider/index.js +97 -97
  103. package/dist/components/Slider/index.js.map +0 -0
  104. package/dist/components/Slider/types.d.ts +25 -25
  105. package/dist/components/Slider/types.js +2 -2
  106. package/dist/components/Slider/types.js.map +0 -0
  107. package/dist/components/Switch.d.ts +13 -13
  108. package/dist/components/Switch.js +75 -75
  109. package/dist/components/Switch.js.map +0 -0
  110. package/dist/components/Text.d.ts +12 -12
  111. package/dist/components/Text.js +52 -52
  112. package/dist/components/Text.js.map +0 -0
  113. package/dist/components/TextInput.d.ts +183 -183
  114. package/dist/components/TextInput.js +180 -178
  115. package/dist/components/TextInput.js.map +1 -1
  116. package/dist/components/Touchable.d.ts +14 -14
  117. package/dist/components/Touchable.js +75 -61
  118. package/dist/components/Touchable.js.map +1 -1
  119. package/dist/components/View.d.ts +123 -120
  120. package/dist/components/View.js +55 -54
  121. package/dist/components/View.js.map +1 -1
  122. package/dist/components/components.d.ts +27 -25
  123. package/dist/components/components.js +43 -41
  124. package/dist/components/components.js.map +1 -1
  125. package/dist/index.d.ts +5 -5
  126. package/dist/index.js +28 -28
  127. package/dist/index.js.map +0 -0
  128. package/dist/modules/documentPicker.d.ts +3 -3
  129. package/dist/modules/documentPicker.js +11 -11
  130. package/dist/modules/documentPicker.js.map +0 -0
  131. package/dist/modules/fastImage.d.ts +1 -1
  132. package/dist/modules/fastImage.js +9 -9
  133. package/dist/modules/fastImage.js.map +0 -0
  134. package/dist/modules/reactNavigation.d.ts +3 -3
  135. package/dist/modules/reactNavigation.js +10 -10
  136. package/dist/modules/reactNavigation.js.map +0 -0
  137. package/dist/modules/textInputMask.d.ts +9 -12
  138. package/dist/modules/textInputMask.js +7 -7
  139. package/dist/modules/types/fileTypes.d.ts +138 -138
  140. package/dist/modules/types/fileTypes.js +2 -2
  141. package/dist/modules/types/fileTypes.js.map +0 -0
  142. package/dist/modules/types/textInputMask.d.ts +7 -12
  143. package/dist/modules/types/textInputMask.js +2 -2
  144. package/dist/types/utility.d.ts +2 -2
  145. package/dist/types/utility.js +2 -2
  146. package/dist/types/utility.js.map +0 -0
  147. package/dist/utils/OSAlert.d.ts +31 -31
  148. package/dist/utils/OSAlert.js +141 -141
  149. package/dist/utils/OSAlert.js.map +0 -0
  150. package/dist/utils/misc.d.ts +2 -2
  151. package/dist/utils/misc.js +25 -25
  152. package/dist/utils/misc.js.map +0 -0
  153. package/dist/utils/styles.d.ts +1 -1
  154. package/dist/utils/styles.js +12 -12
  155. package/dist/utils/styles.js.map +0 -0
  156. package/package.json +42 -40
  157. package/src/components/ActivityIndicator.tsx +46 -46
  158. package/src/components/Animated.tsx +34 -34
  159. package/src/components/Button.tsx +117 -95
  160. package/src/components/Checkbox/index.tsx +85 -85
  161. package/src/components/Checkbox/styles.ts +76 -76
  162. package/src/components/ContentView.tsx +58 -58
  163. package/src/components/EmptyPlaceholder.tsx +53 -0
  164. package/src/components/FileInput.tsx +230 -230
  165. package/src/components/Gap.tsx +40 -0
  166. package/src/components/Icon.tsx +58 -58
  167. package/src/components/Image.tsx +61 -61
  168. package/src/components/List.tsx +116 -111
  169. package/src/components/Modal/index.tsx +164 -161
  170. package/src/components/Modal/styles.ts +133 -133
  171. package/src/components/Navigation/Navigation.tsx +58 -58
  172. package/src/components/Navigation/constants.ts +8 -8
  173. package/src/components/Navigation/index.tsx +3 -3
  174. package/src/components/Navigation/types.ts +35 -35
  175. package/src/components/Navigation/utils.tsx +59 -59
  176. package/src/components/NewPager/index.tsx +123 -0
  177. package/src/components/NewPager/styles.ts +76 -0
  178. package/src/components/Overlay.tsx +77 -77
  179. package/src/components/Pager/index.tsx +242 -242
  180. package/src/components/Pager/styles.ts +51 -51
  181. package/src/components/RadioInput/index.tsx +101 -101
  182. package/src/components/RadioInput/styles.ts +67 -67
  183. package/src/components/Scroll.tsx +106 -106
  184. package/src/components/Sections.tsx +101 -101
  185. package/src/components/Select/index.tsx +195 -195
  186. package/src/components/Select/styles.ts +81 -81
  187. package/src/components/Select/types.ts +46 -46
  188. package/src/components/Slider/Mark.tsx +46 -46
  189. package/src/components/Slider/Thumb.tsx +29 -29
  190. package/src/components/Slider/index.tsx +123 -123
  191. package/src/components/Slider/types.ts +25 -25
  192. package/src/components/Switch.tsx +81 -81
  193. package/src/components/Text.tsx +30 -30
  194. package/src/components/TextInput.tsx +247 -247
  195. package/src/components/Touchable.tsx +78 -66
  196. package/src/components/View.tsx +48 -46
  197. package/src/components/components.ts +28 -26
  198. package/src/index.ts +6 -6
  199. package/src/modules/documentPicker.ts +7 -7
  200. package/src/modules/fastImage.ts +2 -2
  201. package/src/modules/index.d.ts +496 -496
  202. package/src/modules/reactNavigation.ts +4 -4
  203. package/src/modules/textInputMask.ts +9 -9
  204. package/src/modules/types/documentPicker.d.ts +215 -215
  205. package/src/modules/types/fileTypes.ts +138 -138
  206. package/src/modules/types/textInputMask.ts +9 -13
  207. package/src/types/utility.ts +3 -3
  208. package/src/utils/OSAlert.ts +180 -180
  209. package/src/utils/misc.ts +24 -24
  210. package/src/utils/styles.ts +14 -14
@@ -0,0 +1,53 @@
1
+ import React, { useMemo } from 'react'
2
+ import { Icon } from './Icon'
3
+ import { View } from './View'
4
+ import { Text } from './Text'
5
+ import { ActivityIndicator } from './ActivityIndicator'
6
+ import {
7
+ ComponentVariants,
8
+ EmptyPlaceholderComposition,
9
+ EmptyPlaceholderStyles,
10
+ getNestedStylesByKey,
11
+ IconPlaceholder,
12
+ useDefaultComponentStyle,
13
+ } from '@codeleap/common'
14
+ import { StyleSheet } from 'react-native'
15
+ import { StylesOf } from '../types/utility'
16
+
17
+ export type EmptyPlaceholderProps = {
18
+ itemName?: string
19
+ title?: string
20
+ loading?: boolean
21
+ styles?: StylesOf<EmptyPlaceholderComposition>
22
+ variants?: ComponentVariants<typeof EmptyPlaceholderStyles>['variants']
23
+ emptyIconName?: IconPlaceholder
24
+ }
25
+
26
+ export const EmptyPlaceholder:React.FC<EmptyPlaceholderProps> = (props: EmptyPlaceholderProps) => {
27
+ const { itemName, title, loading, styles = {}, variants = [], emptyIconName = 'search' } = props
28
+ const emptyText = title || (itemName && `No ${itemName} found.`) || 'No items.'
29
+
30
+ const componentStyles = useDefaultComponentStyle('EmptyPlaceholder', {
31
+ variants,
32
+ transform: StyleSheet.flatten,
33
+ styles,
34
+ })
35
+
36
+ const activityIndicatorStyles = useMemo(() => getNestedStylesByKey('loader', componentStyles)
37
+ , [componentStyles])
38
+
39
+ if (loading) {
40
+ return (
41
+ <View style={[componentStyles.wrapper, componentStyles['wrapper:loading']]} >
42
+ <ActivityIndicator styles={activityIndicatorStyles}/>
43
+ </View>
44
+ )
45
+ }
46
+
47
+ return (
48
+ <View style={componentStyles.wrapper}>
49
+ <Icon name={emptyIconName as IconPlaceholder} style={componentStyles.icon}/>
50
+ <Text text={emptyText} style={componentStyles.text}/>
51
+ </View>
52
+ )
53
+ }
@@ -1,230 +1,230 @@
1
- import React, { forwardRef, useImperativeHandle } from 'react'
2
- import { DocumentPicker, ImageCropPicker } from '../modules/documentPicker'
3
- import {
4
- ComponentVariants,
5
- FileInputComposition,
6
- FileInputStyles,
7
- IconPlaceholder,
8
- MobileInputFile,
9
- parseFilePathData,
10
- useDefaultComponentStyle,
11
- useCodeleapContext,
12
- } from '@codeleap/common'
13
- import { StylesOf } from '../types/utility'
14
- import { Button, ButtonProps } from './Button'
15
- import { View } from './View'
16
- import { InputLabel } from './TextInput'
17
- import OSAlert from '../utils/OSAlert'
18
- import { Options } from 'react-native-image-crop-picker'
19
- import { DocumentPickerOptions } from '../modules/types/documentPicker'
20
-
21
- export type FileInputRef = {
22
- openFilePicker: (string?: 'camera' | 'library') => void
23
- }
24
-
25
- export type FileInputProps = {
26
- label?: string
27
- iconName?: IconPlaceholder
28
- styles?: StylesOf<FileInputComposition>
29
- mode: 'hidden' | 'button'
30
- variants?: ComponentVariants<typeof FileInputStyles>['variants']
31
- onFileSelect(files: MobileInputFile[]): void
32
- options?: DocumentPickerOptions<any>
33
- buttonProps?: ButtonProps
34
- ref?: FileInputRef
35
- placeholder?: string
36
- type?: 'image' | 'anyFile'
37
- alertProps?: Parameters<typeof OSAlert.ask>[0]
38
- pickerOptions?: Partial<Options>
39
- required?: boolean
40
- onOpenCamera?: (resolve: (() => void)) => Promise<void>
41
- onOpenFileSystem?: (resolve: (() => void)) => Promise<void>
42
- onOpenGallery?: (resolve: (() => void)) => Promise<void>
43
- onError?: (error: any) => void
44
- }
45
-
46
- const pickerDefaults = {
47
- width: 300,
48
- height: 400,
49
- cropping: true,
50
- }
51
-
52
- function parsePickerData(data:any):MobileInputFile {
53
-
54
- const filePathData = parseFilePathData(data.path)
55
- const d:MobileInputFile['file'] = {
56
- name: filePathData.name,
57
- size: data.size,
58
- type: data.mime,
59
- uri: data.path,
60
- fileCopyUri: data.path,
61
- }
62
-
63
- return {
64
- file: d,
65
- preview: data.path,
66
- }
67
- }
68
-
69
- export const FileInput = forwardRef<
70
- FileInputRef,
71
- FileInputProps
72
- >((fileInputProps, ref) => {
73
- const {
74
- mode = 'hidden',
75
- onFileSelect,
76
- iconName,
77
- styles,
78
- label,
79
- variants,
80
- options,
81
- type = 'image',
82
- alertProps,
83
- placeholder = 'Select a file',
84
- pickerOptions,
85
- required,
86
- buttonProps,
87
- onOpenCamera = null,
88
- onOpenGallery = null,
89
- onOpenFileSystem = null,
90
- onError,
91
- } = fileInputProps
92
-
93
- const [file, setFile] = React.useState(null)
94
-
95
- const { logger } = useCodeleapContext()
96
-
97
- async function openFileSystem() {
98
- try {
99
- let files = await DocumentPicker.pick(options)
100
- if (!Array.isArray(files)) {
101
- files = [files]
102
- }
103
- setFile(files)
104
- onFileSelect(files.map((file) => ({ preview: file.uri, file })))
105
- } catch (err) {
106
- handleError(err)
107
- }
108
- }
109
-
110
- function handleError(err) {
111
- const warn = DocumentPicker.isCancel(err) || String(err).includes('Error: User cancelled')
112
- if (warn) {
113
- // NOTE yeah, it should not be both of course but just logger.* isn't showing for some reason
114
- logger.warn(err)
115
- console.warn(err)
116
- } else {
117
- // NOTE yeah, it should not be both of course but just logger.* isn't showing for some reason
118
- logger.error(err)
119
- console.error(err)
120
- if (onError) {
121
- onError(err)
122
- } else {
123
- OSAlert.error({
124
- title: 'Error',
125
- body: err.message,
126
- })
127
- }
128
- }
129
- }
130
-
131
- const mergedOptions = {
132
- ...pickerDefaults,
133
- ...pickerOptions,
134
- } as Options
135
-
136
- const handlePickerResolution = data => {
137
- onFileSelect(mergedOptions.multiple ? data.map(parsePickerData) : [
138
- parsePickerData(data),
139
- ])
140
- }
141
- const onPress = (open?: 'camera' | 'library' | 'fs', options?: Options) => {
142
- if (open == 'fs') {
143
- openFileSystem()
144
- } else {
145
- const call = open === 'camera' ? 'openCamera' : 'openPicker'
146
- ImageCropPicker[call]({ ...mergedOptions, ...(options || {}) }).then(handlePickerResolution)
147
- }
148
- }
149
- const openFilePicker = async (imageSource = null) => {
150
- if (type === 'image') {
151
- if (imageSource === 'camera') {
152
- onPress('camera')
153
- } else if (imageSource === 'library') {
154
- onPress('library')
155
- } else {
156
- OSAlert.ask({
157
- title: 'Change Image',
158
- body: 'Do you want to take a new picture or select an existing one?',
159
- ...alertProps,
160
- options: [
161
- {
162
- text: alertProps?.options?.[0]?.text || 'Camera',
163
- onPress: () => {
164
- if (onOpenCamera) {
165
- onOpenCamera(() => onPress('camera'))
166
- } else {
167
- onPress('camera')
168
- }
169
- },
170
- ...alertProps?.options[1],
171
- },
172
- {
173
- text: 'Library',
174
- onPress: () => {
175
- if (onOpenGallery) {
176
- onOpenGallery(() => onPress('library'))
177
- } else {
178
- onPress('library')
179
- }
180
- },
181
- ...alertProps?.options[2],
182
- },
183
- {
184
- text: 'Cancel',
185
- style: 'cancel',
186
- onPress: () => {},
187
- ...alertProps?.options[0],
188
- },
189
- ],
190
- })
191
- }
192
- } else {
193
- if (onOpenFileSystem) {
194
- onOpenFileSystem(() => onPress('fs'))
195
- } else {
196
-
197
- onPress('fs')
198
- }
199
- }
200
-
201
- }
202
-
203
- const variantStyles = useDefaultComponentStyle('FileInput', {
204
- styles,
205
- variants,
206
- })
207
-
208
- useImperativeHandle(ref, () => ({
209
- openFilePicker,
210
- }))
211
-
212
- const filenames = file ? file.map((f) => f.name) : ''
213
- if (mode === 'button') {
214
- return (
215
- <View style={variantStyles.wrapper}>
216
- <InputLabel label={label} style={variantStyles.label} required={required}/>
217
- <Button
218
- onPress={() => openFilePicker()}
219
- text={filenames || placeholder}
220
- debugName={'Open file picker'}
221
- icon={iconName || ('fileInputButton' as IconPlaceholder)}
222
- variants={filenames ? '' : 'icon'}
223
- {...buttonProps}
224
- />
225
- </View>
226
- )
227
- }
228
-
229
- return null
230
- })
1
+ import React, { forwardRef, useImperativeHandle } from 'react'
2
+ import { DocumentPicker, ImageCropPicker } from '../modules/documentPicker'
3
+ import {
4
+ ComponentVariants,
5
+ FileInputComposition,
6
+ FileInputStyles,
7
+ IconPlaceholder,
8
+ MobileInputFile,
9
+ parseFilePathData,
10
+ useDefaultComponentStyle,
11
+ useCodeleapContext,
12
+ } from '@codeleap/common'
13
+ import { StylesOf } from '../types/utility'
14
+ import { Button, ButtonProps } from './Button'
15
+ import { View } from './View'
16
+ import { InputLabel } from './TextInput'
17
+ import OSAlert from '../utils/OSAlert'
18
+ import { Options } from 'react-native-image-crop-picker'
19
+ import { DocumentPickerOptions } from '../modules/types/documentPicker'
20
+
21
+ export type FileInputRef = {
22
+ openFilePicker: (string?: 'camera' | 'library') => void
23
+ }
24
+
25
+ export type FileInputProps = {
26
+ label?: string
27
+ iconName?: IconPlaceholder
28
+ styles?: StylesOf<FileInputComposition>
29
+ mode: 'hidden' | 'button'
30
+ variants?: ComponentVariants<typeof FileInputStyles>['variants']
31
+ onFileSelect(files: MobileInputFile[]): void
32
+ options?: DocumentPickerOptions<any>
33
+ buttonProps?: ButtonProps
34
+ ref?: FileInputRef
35
+ placeholder?: string
36
+ type?: 'image' | 'anyFile'
37
+ alertProps?: Parameters<typeof OSAlert.ask>[0]
38
+ pickerOptions?: Partial<Options>
39
+ required?: boolean
40
+ onOpenCamera?: (resolve: (() => void)) => Promise<void>
41
+ onOpenFileSystem?: (resolve: (() => void)) => Promise<void>
42
+ onOpenGallery?: (resolve: (() => void)) => Promise<void>
43
+ onError?: (error: any) => void
44
+ }
45
+
46
+ const pickerDefaults = {
47
+ width: 300,
48
+ height: 400,
49
+ cropping: true,
50
+ }
51
+
52
+ function parsePickerData(data:any):MobileInputFile {
53
+
54
+ const filePathData = parseFilePathData(data.path)
55
+ const d:MobileInputFile['file'] = {
56
+ name: filePathData.name,
57
+ size: data.size,
58
+ type: data.mime,
59
+ uri: data.path,
60
+ fileCopyUri: data.path,
61
+ }
62
+
63
+ return {
64
+ file: d,
65
+ preview: data.path,
66
+ }
67
+ }
68
+
69
+ export const FileInput = forwardRef<
70
+ FileInputRef,
71
+ FileInputProps
72
+ >((fileInputProps, ref) => {
73
+ const {
74
+ mode = 'hidden',
75
+ onFileSelect,
76
+ iconName,
77
+ styles,
78
+ label,
79
+ variants,
80
+ options,
81
+ type = 'image',
82
+ alertProps,
83
+ placeholder = 'Select a file',
84
+ pickerOptions,
85
+ required,
86
+ buttonProps,
87
+ onOpenCamera = null,
88
+ onOpenGallery = null,
89
+ onOpenFileSystem = null,
90
+ onError,
91
+ } = fileInputProps
92
+
93
+ const [file, setFile] = React.useState(null)
94
+
95
+ const { logger } = useCodeleapContext()
96
+
97
+ async function openFileSystem() {
98
+ try {
99
+ let files = await DocumentPicker.pick(options)
100
+ if (!Array.isArray(files)) {
101
+ files = [files]
102
+ }
103
+ setFile(files)
104
+ onFileSelect(files.map((file) => ({ preview: file.uri, file })))
105
+ } catch (err) {
106
+ handleError(err)
107
+ }
108
+ }
109
+
110
+ function handleError(err) {
111
+ const warn = DocumentPicker.isCancel(err) || String(err).includes('Error: User cancelled')
112
+ if (warn) {
113
+ // NOTE yeah, it should not be both of course but just logger.* isn't showing for some reason
114
+ logger.warn(err)
115
+ console.warn(err)
116
+ } else {
117
+ // NOTE yeah, it should not be both of course but just logger.* isn't showing for some reason
118
+ logger.error(err)
119
+ console.warn(err)
120
+ if (onError) {
121
+ onError(err)
122
+ } else {
123
+ OSAlert.error({
124
+ title: 'Error',
125
+ body: err.message,
126
+ })
127
+ }
128
+ }
129
+ }
130
+
131
+ const mergedOptions = {
132
+ ...pickerDefaults,
133
+ ...pickerOptions,
134
+ } as Options
135
+
136
+ const handlePickerResolution = data => {
137
+ onFileSelect(mergedOptions.multiple ? data.map(parsePickerData) : [
138
+ parsePickerData(data),
139
+ ])
140
+ }
141
+ const onPress = (open?: 'camera' | 'library' | 'fs', options?: Options) => {
142
+ if (open == 'fs') {
143
+ openFileSystem()
144
+ } else {
145
+ const call = open === 'camera' ? 'openCamera' : 'openPicker'
146
+ ImageCropPicker[call]({ ...mergedOptions, ...(options || {}) }).then(handlePickerResolution)
147
+ }
148
+ }
149
+ const openFilePicker = async (imageSource = null) => {
150
+ if (type === 'image') {
151
+ if (imageSource === 'camera') {
152
+ onPress('camera')
153
+ } else if (imageSource === 'library') {
154
+ onPress('library')
155
+ } else {
156
+ OSAlert.ask({
157
+ title: 'Change Image',
158
+ body: 'Do you want to take a new picture or select an existing one?',
159
+ ...alertProps,
160
+ options: [
161
+ {
162
+ text: alertProps?.options?.[0]?.text || 'Camera',
163
+ onPress: () => {
164
+ if (onOpenCamera) {
165
+ onOpenCamera(() => onPress('camera'))
166
+ } else {
167
+ onPress('camera')
168
+ }
169
+ },
170
+ ...alertProps?.options[1],
171
+ },
172
+ {
173
+ text: 'Library',
174
+ onPress: () => {
175
+ if (onOpenGallery) {
176
+ onOpenGallery(() => onPress('library'))
177
+ } else {
178
+ onPress('library')
179
+ }
180
+ },
181
+ ...alertProps?.options[2],
182
+ },
183
+ {
184
+ text: 'Cancel',
185
+ style: 'cancel',
186
+ onPress: () => {},
187
+ ...alertProps?.options[0],
188
+ },
189
+ ],
190
+ })
191
+ }
192
+ } else {
193
+ if (onOpenFileSystem) {
194
+ onOpenFileSystem(() => onPress('fs'))
195
+ } else {
196
+
197
+ onPress('fs')
198
+ }
199
+ }
200
+
201
+ }
202
+
203
+ const variantStyles = useDefaultComponentStyle('FileInput', {
204
+ styles,
205
+ variants,
206
+ })
207
+
208
+ useImperativeHandle(ref, () => ({
209
+ openFilePicker,
210
+ }))
211
+
212
+ const filenames = file ? file.map((f) => f.name) : ''
213
+ if (mode === 'button') {
214
+ return (
215
+ <View style={variantStyles.wrapper}>
216
+ <InputLabel label={label} style={variantStyles.label} required={required}/>
217
+ <Button
218
+ onPress={() => openFilePicker()}
219
+ text={filenames || placeholder}
220
+ debugName={'Open file picker'}
221
+ icon={iconName || ('fileInputButton' as IconPlaceholder)}
222
+ variants={filenames ? '' : 'icon'}
223
+ {...buttonProps}
224
+ />
225
+ </View>
226
+ )
227
+ }
228
+
229
+ return null
230
+ })
@@ -0,0 +1,40 @@
1
+ import React from 'react'
2
+ import { useCodeleapContext } from '@codeleap/common'
3
+ import { View, ViewProps } from './View'
4
+
5
+ type GapProps = ViewProps & {
6
+ value: number
7
+
8
+ defaultProps?: any
9
+ }
10
+
11
+ export const Gap:React.FC<GapProps> = ({ children, value, defaultProps = {}, ...props }) => {
12
+ const { Theme } = useCodeleapContext()
13
+ const horizontal = props.variants?.includes('row')
14
+ return (
15
+ <View {...props}>
16
+ {
17
+ React.Children.toArray(children).map((Element, idx, childArr) => {
18
+ if (React.isValidElement(Element)) {
19
+ const props = { ...Element.props, ...defaultProps }
20
+
21
+ let spacingFunction = horizontal ? 'marginHorizontal' : 'marginVertical'
22
+ switch (idx) {
23
+ case 0:
24
+ spacingFunction = horizontal ? 'marginRight' : 'marginBottom'
25
+ break
26
+ case childArr.length - 1:
27
+ spacingFunction = horizontal ? 'marginLeft' : 'marginTop'
28
+ break
29
+ default:
30
+ break
31
+ }
32
+ props.style = [props.style, Theme.spacing[spacingFunction](value / 2)]
33
+ return React.cloneElement(Element, props)
34
+ }
35
+ return Element
36
+ })
37
+ }
38
+ </View>
39
+ )
40
+ }
@@ -1,58 +1,58 @@
1
- import * as React from 'react'
2
- import {
3
- ComponentVariants,
4
- IconPlaceholder,
5
- IconStyles,
6
- useDefaultComponentStyle,
7
- useCodeleapContext,
8
- arePropsEqual,
9
- } from '@codeleap/common'
10
- import { StyleSheet } from 'react-native'
11
- import { View } from './View'
12
-
13
- export type IconProps = {
14
- name: IconPlaceholder
15
- style?: any
16
- color?: string
17
- variants?: ComponentVariants<typeof IconStyles>['variants']
18
- renderEmptySpace?: boolean
19
- size?: number
20
- }
21
-
22
- export const IconComponent: React.FC<IconProps> = ({ name, style, variants, renderEmptySpace, ...otherProps }) => {
23
- const { Theme, logger } = useCodeleapContext()
24
-
25
- const variantStyles = useDefaultComponentStyle('Icon', {
26
- variants,
27
- transform: StyleSheet.flatten,
28
- styles: {
29
- icon: style,
30
- },
31
- rootElement: 'icon',
32
- })
33
-
34
- if (!name) {
35
- return renderEmptySpace ? <View style={variantStyles.icon}/> : null
36
- }
37
-
38
- const Component = Theme?.icons?.[name]
39
-
40
- if (!Component) {
41
- logger.warn(
42
- `Icon: No icon found in theme for name "${name}".`,
43
- { props: { style, name, variants, variantStyles }},
44
- 'Component',
45
- )
46
- return null
47
- }
48
- return <Component {...otherProps} style={variantStyles.icon} />
49
- }
50
-
51
- function areEqual(prevProps, nextProps) {
52
- const check = ['name', 'style', 'variants', 'renderEmptySpace']
53
- const res = arePropsEqual(prevProps, nextProps, { check })
54
- return res
55
- }
56
-
57
- export const Icon = React.memo(IconComponent, areEqual)
58
-
1
+ import * as React from 'react'
2
+ import {
3
+ ComponentVariants,
4
+ IconPlaceholder,
5
+ IconStyles,
6
+ useDefaultComponentStyle,
7
+ useCodeleapContext,
8
+ arePropsEqual,
9
+ } from '@codeleap/common'
10
+ import { StyleSheet } from 'react-native'
11
+ import { View } from './View'
12
+
13
+ export type IconProps = {
14
+ name: IconPlaceholder
15
+ style?: any
16
+ color?: string
17
+ variants?: ComponentVariants<typeof IconStyles>['variants']
18
+ renderEmptySpace?: boolean
19
+ size?: number
20
+ }
21
+
22
+ export const IconComponent: React.FC<IconProps> = ({ name, style, variants, renderEmptySpace, ...otherProps }) => {
23
+ const { Theme, logger } = useCodeleapContext()
24
+
25
+ const variantStyles = useDefaultComponentStyle('Icon', {
26
+ variants,
27
+ transform: StyleSheet.flatten,
28
+ styles: {
29
+ icon: style,
30
+ },
31
+ rootElement: 'icon',
32
+ })
33
+
34
+ if (!name) {
35
+ return renderEmptySpace ? <View style={variantStyles.icon}/> : null
36
+ }
37
+
38
+ const Component = Theme?.icons?.[name]
39
+
40
+ if (!Component) {
41
+ logger.warn(
42
+ `Icon: No icon found in theme for name "${name}".`,
43
+ { props: { style, name, variants, variantStyles }},
44
+ 'Component',
45
+ )
46
+ return null
47
+ }
48
+ return <Component {...otherProps} style={variantStyles.icon} />
49
+ }
50
+
51
+ function areEqual(prevProps, nextProps) {
52
+ const check = ['name', 'style', 'variants', 'renderEmptySpace']
53
+ const res = arePropsEqual(prevProps, nextProps, { check })
54
+ return res
55
+ }
56
+
57
+ export const Icon = React.memo(IconComponent, areEqual)
58
+