@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
@@ -1,101 +1,101 @@
1
- import * as React from 'react'
2
- import { forwardRef, useState } from 'react'
3
- import {
4
- deepEqual,
5
- onUpdate,
6
- useDefaultComponentStyle,
7
- usePrevious,
8
- useCodeleapContext,
9
- } from '@codeleap/common'
10
- import {
11
- KeyboardAwareSectionListProps,
12
- KeyboardAwareSectionList as KBDView,
13
- // @ts-ignore
14
- } from 'react-native-keyboard-aware-scroll-view'
15
- import { RefreshControl, SectionList } from 'react-native'
16
- import { View, ViewProps } from './View'
17
-
18
- export type SectionListProps = KeyboardAwareSectionListProps<any> &
19
- ViewProps & {
20
- onRefresh?: () => void
21
- refreshTimeout?: number
22
- changeData?: any
23
- separators?: boolean
24
- }
25
-
26
- const KeyboardAwareSectionList =
27
- KBDView as unknown as React.ForwardRefExoticComponent<
28
- ViewProps & {
29
- refreshControl?: JSX.Element
30
- ref?: SectionList
31
- }
32
- >
33
-
34
- export const Sections = forwardRef<SectionList, SectionListProps>(
35
- (flatListProps, ref) => {
36
- const {
37
- variants = [],
38
- style,
39
- refreshTimeout = 3000,
40
- changeData,
41
- ...props
42
- } = flatListProps
43
- const hasRefresh = !!props.onRefresh
44
- const [refreshing, setRefreshing] = useState(false)
45
-
46
- const timer = React.useRef(null)
47
- const previousData = usePrevious(changeData)
48
-
49
- const onRefresh = () => {
50
- if (timer.current) {
51
- clearTimeout(timer.current)
52
- }
53
-
54
- setRefreshing(true)
55
-
56
- props.onRefresh()
57
-
58
- timer.current = setTimeout(() => {
59
- setRefreshing(false)
60
- }, refreshTimeout)
61
- }
62
- onUpdate(() => {
63
- if (refreshing && !deepEqual(previousData, changeData)) {
64
- setRefreshing(false)
65
- if (timer.current) {
66
- clearTimeout(timer.current)
67
- }
68
- }
69
- }, [refreshing, changeData])
70
- const { Theme } = useCodeleapContext()
71
-
72
- const variantStyles = useDefaultComponentStyle('View', {
73
- variants,
74
- })
75
-
76
- const renderSeparator = () => {
77
- return (
78
- <View variants={['separator']}></View>
79
- )
80
- }
81
-
82
- const separatorProp = props.separators
83
- const isEmpty = !props.data || !props.data.length
84
- const separator = !isEmpty && separatorProp == true && renderSeparator
85
-
86
- return (
87
- <KeyboardAwareSectionList
88
- style={[Theme.presets.full, style]}
89
- contentContainerStyle={[variantStyles.wrapper]}
90
- ref={ref as unknown as SectionList}
91
- ItemSeparatorComponent={separator}
92
- {...props}
93
- refreshControl={
94
- hasRefresh && (
95
- <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
96
- )
97
- }
98
- />
99
- )
100
- },
101
- )
1
+ import * as React from 'react'
2
+ import { forwardRef, useState } from 'react'
3
+ import {
4
+ deepEqual,
5
+ onUpdate,
6
+ useDefaultComponentStyle,
7
+ usePrevious,
8
+ useCodeleapContext,
9
+ } from '@codeleap/common'
10
+ import {
11
+ KeyboardAwareSectionListProps,
12
+ KeyboardAwareSectionList as KBDView,
13
+ // @ts-ignore
14
+ } from 'react-native-keyboard-aware-scroll-view'
15
+ import { RefreshControl, SectionList } from 'react-native'
16
+ import { View, ViewProps } from './View'
17
+
18
+ export type SectionListProps = KeyboardAwareSectionListProps<any> &
19
+ ViewProps & {
20
+ onRefresh?: () => void
21
+ refreshTimeout?: number
22
+ changeData?: any
23
+ separators?: boolean
24
+ }
25
+
26
+ const KeyboardAwareSectionList =
27
+ KBDView as unknown as React.ForwardRefExoticComponent<
28
+ ViewProps & {
29
+ refreshControl?: JSX.Element
30
+ ref?: SectionList
31
+ }
32
+ >
33
+
34
+ export const Sections = forwardRef<SectionList, SectionListProps>(
35
+ (flatListProps, ref) => {
36
+ const {
37
+ variants = [],
38
+ style,
39
+ refreshTimeout = 3000,
40
+ changeData,
41
+ ...props
42
+ } = flatListProps
43
+ const hasRefresh = !!props.onRefresh
44
+ const [refreshing, setRefreshing] = useState(false)
45
+
46
+ const timer = React.useRef(null)
47
+ const previousData = usePrevious(changeData)
48
+
49
+ const onRefresh = () => {
50
+ if (timer.current) {
51
+ clearTimeout(timer.current)
52
+ }
53
+
54
+ setRefreshing(true)
55
+
56
+ props.onRefresh()
57
+
58
+ timer.current = setTimeout(() => {
59
+ setRefreshing(false)
60
+ }, refreshTimeout)
61
+ }
62
+ onUpdate(() => {
63
+ if (refreshing && !deepEqual(previousData, changeData)) {
64
+ setRefreshing(false)
65
+ if (timer.current) {
66
+ clearTimeout(timer.current)
67
+ }
68
+ }
69
+ }, [refreshing, changeData])
70
+ const { Theme } = useCodeleapContext()
71
+
72
+ const variantStyles = useDefaultComponentStyle('View', {
73
+ variants,
74
+ })
75
+
76
+ const renderSeparator = () => {
77
+ return (
78
+ <View variants={['separator']}></View>
79
+ )
80
+ }
81
+
82
+ const separatorProp = props.separators
83
+ const isEmpty = !props.data || !props.data.length
84
+ const separator = !isEmpty && separatorProp == true && renderSeparator
85
+
86
+ return (
87
+ <KeyboardAwareSectionList
88
+ style={[Theme.presets.full, style]}
89
+ contentContainerStyle={[variantStyles.wrapper]}
90
+ ref={ref as unknown as SectionList}
91
+ ItemSeparatorComponent={separator}
92
+ {...props}
93
+ refreshControl={
94
+ hasRefresh && (
95
+ <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
96
+ )
97
+ }
98
+ />
99
+ )
100
+ },
101
+ )
@@ -1,195 +1,195 @@
1
- import { IconPlaceholder, useBooleanToggle, getNestedStylesByKey, useDefaultComponentStyle, TypeGuards } from '@codeleap/common'
2
- import React, { useMemo } from 'react'
3
- import { Modal, StyleSheet } from 'react-native'
4
- import { Button } from '../Button'
5
- import { Scroll } from '../Scroll'
6
- import { InputLabel, TextInput } from '../TextInput'
7
- import { Touchable } from '../Touchable'
8
- import { AnimatedView, View } from '../View'
9
- import { MobileSelectStyles } from './styles'
10
- import { CustomSelectProps } from './types'
11
-
12
- export const Select = <T extends string|number = string>(selectProps:CustomSelectProps<T>) => {
13
- const {
14
- value,
15
- onValueChange,
16
- label,
17
- styles = {},
18
- options,
19
- style,
20
- variants,
21
- renderItem,
22
- closeOnSelect = true,
23
- scroll = false,
24
- showClose = true,
25
- showLabelOnModal = true,
26
- placeholder = 'Select',
27
- arrowIconName = 'selectArrow',
28
- footer,
29
- modalCloseIconName = 'close',
30
- header,
31
- closeButtonProps,
32
- modalLabel,
33
- textInputProps = {},
34
- visible = null,
35
- toggle = null,
36
- renderList,
37
- ...props
38
- } = selectProps
39
-
40
- const [_isModalVisible, _setModalVisibility] = useBooleanToggle(false)
41
-
42
- const isModalVisible = visible ?? _isModalVisible
43
- const setModalVisibility = toggle ?? _setModalVisibility
44
-
45
- const variantStyles = useDefaultComponentStyle<'u:MobileSelect', typeof MobileSelectStyles>('u:MobileSelect', {
46
- transform: StyleSheet.flatten,
47
- rootElement: 'inputWrapper',
48
- styles,
49
- variants,
50
- })
51
-
52
- const inputStyles = useMemo(
53
- () => getNestedStylesByKey('input', variantStyles),
54
- [variantStyles],
55
- )
56
-
57
- const closeButtonStyles = useMemo(
58
- () => getNestedStylesByKey('modalCloseButton', variantStyles),
59
- [variantStyles],
60
- )
61
-
62
- const ListComponent = scroll ? Scroll : View
63
-
64
- const close = () => setModalVisibility()
65
- const select = (value) => {
66
-
67
- onValueChange(value)
68
- if (closeOnSelect) {
69
- close()
70
- }
71
- }
72
-
73
- const selectedLabel:string = useMemo(() => {
74
- const current = options.find(o => o.value === value)
75
-
76
- const display = current?.label ?? placeholder
77
-
78
- return TypeGuards.isString(display) ? display : ''
79
- }, [value, placeholder, options])
80
-
81
- return <>
82
- <TextInput
83
-
84
- caretHidden
85
- value={selectedLabel}
86
- rightIcon={{
87
- name: arrowIconName as IconPlaceholder,
88
- }}
89
- editable={false}
90
- touchableWrapper
91
- innerWrapperProps={{
92
- debugName: 'Select',
93
- onPress: close,
94
- }}
95
- pointerEvents={'none'}
96
- label={label}
97
- debugName={'Select input'}
98
- styles={inputStyles}
99
- style={style}
100
- {...textInputProps}
101
- />
102
- <AnimatedView pointerEvents={'none'} transition='opacity' style={[
103
- {
104
- position: 'absolute',
105
- top: 0,
106
- right: 0,
107
- left: 0,
108
- bottom: 0,
109
- },
110
- variantStyles.backdrop,
111
- isModalVisible ? variantStyles['backdrop:visible'] : variantStyles['backdrop:hidden'],
112
- ]} />
113
-
114
- <Modal
115
- animationType='slide'
116
- transparent={true}
117
- visible={isModalVisible}
118
- onRequestClose={() => {
119
- setModalVisibility()
120
- }}
121
- pointerEvents={isModalVisible ? 'auto' : 'none'}
122
- >
123
- <Touchable
124
- onPress={close}
125
- style={{
126
- position: 'absolute',
127
- top: 0,
128
- right: 0,
129
- left: 0,
130
- bottom: 0,
131
- }}
132
- debugName={`Close modal`}
133
- />
134
- <View style={variantStyles.modalWrapper}>
135
-
136
- <View style={variantStyles.modalBox}>
137
- {
138
- (showClose || showLabelOnModal || header) && (
139
- <View style={variantStyles.modalHeader}>
140
- {
141
- header ? header : <>
142
- {showLabelOnModal && <InputLabel label={modalLabel || label} style={variantStyles.modalLabelText}/>}
143
- {showClose && <Button
144
- icon={modalCloseIconName as IconPlaceholder}
145
- onPress={close}
146
- styles={closeButtonStyles}
147
- debugName={'Close modal'}
148
- {...closeButtonProps}
149
- />}
150
- </>
151
- }
152
- </View>
153
- )
154
- }
155
- <ListComponent style={variantStyles.modalList}>
156
- {
157
- renderList ? renderList({
158
- ...selectProps,
159
- isEmpty: !options.length,
160
-
161
- }) : options.map((item, idx) => {
162
- const isSelected = value === item.value
163
- if (renderItem) {
164
- return renderItem({
165
- ...item,
166
- index: idx,
167
- selected: isSelected,
168
- onPress: close,
169
- styles: variantStyles,
170
- })
171
- }
172
-
173
- return <Touchable key={idx} style={[
174
- variantStyles.modalItem,
175
- isSelected && variantStyles['modalItem:selected'],
176
- ]} onPress={() => select(item.value)} debugName={`Select ${item.value}`}>
177
- <InputLabel label={item.label} style={[variantStyles.modalItemText, isSelected && variantStyles['modalItemText:selected']]}/>
178
- </Touchable>
179
- })
180
- }
181
- </ListComponent>
182
-
183
- {
184
- footer && <View style={variantStyles.modalFooter}>
185
- {footer}
186
- </View>
187
- }
188
- </View>
189
- </View>
190
- </Modal>
191
- </>
192
- }
193
-
194
- export * from './styles'
195
- export * from './types'
1
+ import { IconPlaceholder, useBooleanToggle, getNestedStylesByKey, useDefaultComponentStyle, TypeGuards } from '@codeleap/common'
2
+ import React, { useMemo } from 'react'
3
+ import { Modal, StyleSheet } from 'react-native'
4
+ import { Button } from '../Button'
5
+ import { Scroll } from '../Scroll'
6
+ import { InputLabel, TextInput } from '../TextInput'
7
+ import { Touchable } from '../Touchable'
8
+ import { AnimatedView, View } from '../View'
9
+ import { MobileSelectStyles } from './styles'
10
+ import { CustomSelectProps } from './types'
11
+
12
+ export const Select = <T extends string|number = string>(selectProps:CustomSelectProps<T>) => {
13
+ const {
14
+ value,
15
+ onValueChange,
16
+ label,
17
+ styles = {},
18
+ options,
19
+ style,
20
+ variants,
21
+ renderItem,
22
+ closeOnSelect = true,
23
+ scroll = false,
24
+ showClose = true,
25
+ showLabelOnModal = true,
26
+ placeholder = 'Select',
27
+ arrowIconName = 'selectArrow',
28
+ footer,
29
+ modalCloseIconName = 'close',
30
+ header,
31
+ closeButtonProps,
32
+ modalLabel,
33
+ textInputProps = {},
34
+ visible = null,
35
+ toggle = null,
36
+ renderList,
37
+ ...props
38
+ } = selectProps
39
+
40
+ const [_isModalVisible, _setModalVisibility] = useBooleanToggle(false)
41
+
42
+ const isModalVisible = visible ?? _isModalVisible
43
+ const setModalVisibility = toggle ?? _setModalVisibility
44
+
45
+ const variantStyles = useDefaultComponentStyle<'u:MobileSelect', typeof MobileSelectStyles>('u:MobileSelect', {
46
+ transform: StyleSheet.flatten,
47
+ rootElement: 'inputWrapper',
48
+ styles,
49
+ variants,
50
+ })
51
+
52
+ const inputStyles = useMemo(
53
+ () => getNestedStylesByKey('input', variantStyles),
54
+ [variantStyles],
55
+ )
56
+
57
+ const closeButtonStyles = useMemo(
58
+ () => getNestedStylesByKey('modalCloseButton', variantStyles),
59
+ [variantStyles],
60
+ )
61
+
62
+ const ListComponent = scroll ? Scroll : View
63
+
64
+ const close = () => setModalVisibility()
65
+ const select = (value) => {
66
+
67
+ onValueChange(value)
68
+ if (closeOnSelect) {
69
+ close()
70
+ }
71
+ }
72
+
73
+ const selectedLabel:string = useMemo(() => {
74
+ const current = options.find(o => o.value === value)
75
+
76
+ const display = current?.label ?? placeholder
77
+
78
+ return TypeGuards.isString(display) ? display : ''
79
+ }, [value, placeholder, options])
80
+
81
+ return <>
82
+ <TextInput
83
+
84
+ caretHidden
85
+ value={selectedLabel}
86
+ rightIcon={{
87
+ name: arrowIconName as IconPlaceholder,
88
+ }}
89
+ editable={false}
90
+ touchableWrapper
91
+ innerWrapperProps={{
92
+ debugName: 'Select',
93
+ onPress: close,
94
+ }}
95
+ pointerEvents={'none'}
96
+ label={label}
97
+ debugName={'Select input'}
98
+ styles={inputStyles}
99
+ style={style}
100
+ {...textInputProps}
101
+ />
102
+ <AnimatedView pointerEvents={'none'} transition='opacity' style={[
103
+ {
104
+ position: 'absolute',
105
+ top: 0,
106
+ right: 0,
107
+ left: 0,
108
+ bottom: 0,
109
+ },
110
+ variantStyles.backdrop,
111
+ isModalVisible ? variantStyles['backdrop:visible'] : variantStyles['backdrop:hidden'],
112
+ ]} />
113
+
114
+ <Modal
115
+ animationType='slide'
116
+ transparent={true}
117
+ visible={isModalVisible}
118
+ onRequestClose={() => {
119
+ setModalVisibility()
120
+ }}
121
+ pointerEvents={isModalVisible ? 'auto' : 'none'}
122
+ >
123
+ <Touchable
124
+ onPress={close}
125
+ style={{
126
+ position: 'absolute',
127
+ top: 0,
128
+ right: 0,
129
+ left: 0,
130
+ bottom: 0,
131
+ }}
132
+ debugName={`Close modal`}
133
+ />
134
+ <View style={variantStyles.modalWrapper}>
135
+
136
+ <View style={variantStyles.modalBox}>
137
+ {
138
+ (showClose || showLabelOnModal || header) && (
139
+ <View style={variantStyles.modalHeader}>
140
+ {
141
+ header ? header : <>
142
+ {showLabelOnModal && <InputLabel label={modalLabel || label} style={variantStyles.modalLabelText}/>}
143
+ {showClose && <Button
144
+ icon={modalCloseIconName as IconPlaceholder}
145
+ onPress={close}
146
+ styles={closeButtonStyles}
147
+ debugName={'Close modal'}
148
+ {...closeButtonProps}
149
+ />}
150
+ </>
151
+ }
152
+ </View>
153
+ )
154
+ }
155
+ <ListComponent style={variantStyles.modalList}>
156
+ {
157
+ renderList ? renderList({
158
+ ...selectProps,
159
+ isEmpty: !options.length,
160
+
161
+ }) : options.map((item, idx) => {
162
+ const isSelected = value === item.value
163
+ if (renderItem) {
164
+ return renderItem({
165
+ ...item,
166
+ index: idx,
167
+ selected: isSelected,
168
+ onPress: close,
169
+ styles: variantStyles,
170
+ })
171
+ }
172
+
173
+ return <Touchable key={idx} style={[
174
+ variantStyles.modalItem,
175
+ isSelected && variantStyles['modalItem:selected'],
176
+ ]} onPress={() => select(item.value)} debugName={`Select ${item.value}`}>
177
+ <InputLabel label={item.label} style={[variantStyles.modalItemText, isSelected && variantStyles['modalItemText:selected']]}/>
178
+ </Touchable>
179
+ })
180
+ }
181
+ </ListComponent>
182
+
183
+ {
184
+ footer && <View style={variantStyles.modalFooter}>
185
+ {footer}
186
+ </View>
187
+ }
188
+ </View>
189
+ </View>
190
+ </Modal>
191
+ </>
192
+ }
193
+
194
+ export * from './styles'
195
+ export * from './types'