@ccrf01/react-native-template 0.0.16

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 (233) hide show
  1. package/.github/workflows/npm-publish.yml +28 -0
  2. package/.vscode/settings.json +15 -0
  3. package/README.md +58 -0
  4. package/package.json +16 -0
  5. package/template/.bundle/config +2 -0
  6. package/template/.env.development +1 -0
  7. package/template/.env.production +1 -0
  8. package/template/.eslintrc.js +392 -0
  9. package/template/.java-version +1 -0
  10. package/template/.prettierrc.js +5 -0
  11. package/template/.ruby-version +1 -0
  12. package/template/.watchmanconfig +1 -0
  13. package/template/Gemfile +23 -0
  14. package/template/Gemfile.lock +330 -0
  15. package/template/README.md +97 -0
  16. package/template/ReactotronConfig.js +17 -0
  17. package/template/__tests__/App.test.tsx +13 -0
  18. package/template/_gitignore +75 -0
  19. package/template/_node-version +1 -0
  20. package/template/android/app/build.gradle +162 -0
  21. package/template/android/app/debug.keystore +0 -0
  22. package/template/android/app/proguard-rules.pro +10 -0
  23. package/template/android/app/src/debug/AndroidManifest.xml +9 -0
  24. package/template/android/app/src/main/AndroidManifest.xml +26 -0
  25. package/template/android/app/src/main/java/com/projectname/MainActivity.kt +30 -0
  26. package/template/android/app/src/main/java/com/projectname/MainApplication.kt +27 -0
  27. package/template/android/app/src/main/res/drawable/rn_edit_text_material.xml +37 -0
  28. package/template/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  29. package/template/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  30. package/template/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  31. package/template/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  32. package/template/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  33. package/template/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  34. package/template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  35. package/template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  36. package/template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  37. package/template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  38. package/template/android/app/src/main/res/values/strings.xml +3 -0
  39. package/template/android/app/src/main/res/values/styles.xml +9 -0
  40. package/template/android/build.gradle +37 -0
  41. package/template/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  42. package/template/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  43. package/template/android/gradle.properties +48 -0
  44. package/template/android/gradlew +251 -0
  45. package/template/android/gradlew.bat +99 -0
  46. package/template/android/keystore/keystore.properties +4 -0
  47. package/template/android/settings.gradle +6 -0
  48. package/template/android/version.properties +2 -0
  49. package/template/app.json +4 -0
  50. package/template/babel.config.js +38 -0
  51. package/template/fastlane/Fastfile +136 -0
  52. package/template/fastlane/Pluginfile +9 -0
  53. package/template/fastlane/README.md +46 -0
  54. package/template/index.js +9 -0
  55. package/template/ios/.xcode.env +11 -0
  56. package/template/ios/Podfile +35 -0
  57. package/template/ios/Podfile.lock +3669 -0
  58. package/template/ios/ProjectName/AppDelegate.swift +48 -0
  59. package/template/ios/ProjectName/Images.xcassets/AppIcon.appiconset/Contents.json +53 -0
  60. package/template/ios/ProjectName/Images.xcassets/Contents.json +6 -0
  61. package/template/ios/ProjectName/Info.plist +66 -0
  62. package/template/ios/ProjectName/LaunchScreen.storyboard +47 -0
  63. package/template/ios/ProjectName/PrivacyInfo.xcprivacy +47 -0
  64. package/template/ios/ProjectName.xcodeproj/project.pbxproj +482 -0
  65. package/template/ios/ProjectName.xcodeproj/xcshareddata/xcschemes/ProjectName.xcscheme +88 -0
  66. package/template/ios/ProjectName.xcworkspace/contents.xcworkspacedata +10 -0
  67. package/template/jest.config.js +3 -0
  68. package/template/metro.config.js +20 -0
  69. package/template/package-lock.json +17073 -0
  70. package/template/package.json +156 -0
  71. package/template/src/@types/emotion.d.ts +12 -0
  72. package/template/src/@types/env.d.ts +3 -0
  73. package/template/src/@types/redux-persist-transform-immutable.d.ts +1 -0
  74. package/template/src/@types/typing.d.ts +17 -0
  75. package/template/src/AppContainer.tsx +109 -0
  76. package/template/src/assets/images/143.png +0 -0
  77. package/template/src/assets/index.ts +13 -0
  78. package/template/src/components/basic/BackButton/index.tsx +34 -0
  79. package/template/src/components/basic/Body/index.tsx +68 -0
  80. package/template/src/components/basic/Button/index.tsx +181 -0
  81. package/template/src/components/basic/Button/utils.ts +78 -0
  82. package/template/src/components/basic/ButtonGroup/index.tsx +182 -0
  83. package/template/src/components/basic/Card/index.tsx +3 -0
  84. package/template/src/components/basic/Container/index.tsx +38 -0
  85. package/template/src/components/basic/Content/index.tsx +87 -0
  86. package/template/src/components/basic/DropDown/index.tsx +354 -0
  87. package/template/src/components/basic/ExpandableOverlay/index.tsx +113 -0
  88. package/template/src/components/basic/Header/index.tsx +216 -0
  89. package/template/src/components/basic/Header/styles.ts +0 -0
  90. package/template/src/components/basic/Icons/index.tsx +131 -0
  91. package/template/src/components/basic/InputLabel/index.tsx +19 -0
  92. package/template/src/components/basic/LoadingOverlay/index.tsx +68 -0
  93. package/template/src/components/basic/MaterialTextInput/index.tsx +153 -0
  94. package/template/src/components/basic/NumberInput/index.tsx +53 -0
  95. package/template/src/components/basic/Picker/PickerContext.ts +7 -0
  96. package/template/src/components/basic/Picker/PickerHeader.tsx +130 -0
  97. package/template/src/components/basic/Picker/PickerItem.tsx +105 -0
  98. package/template/src/components/basic/Picker/PickerItemsList.tsx +135 -0
  99. package/template/src/components/basic/Picker/PickerPresenter.ts +54 -0
  100. package/template/src/components/basic/Picker/hooks/useImperativePickerHandle.ts +27 -0
  101. package/template/src/components/basic/Picker/hooks/usePickerLabel.ts +74 -0
  102. package/template/src/components/basic/Picker/hooks/usePickerSearch.ts +37 -0
  103. package/template/src/components/basic/Picker/hooks/usePickerSelection.ts +57 -0
  104. package/template/src/components/basic/Picker/index.tsx +284 -0
  105. package/template/src/components/basic/Picker/types.tsx +229 -0
  106. package/template/src/components/basic/PressableOpacity/index.tsx +20 -0
  107. package/template/src/components/basic/RootDialog/Dialog.tsx +246 -0
  108. package/template/src/components/basic/RootDialog/Manager.tsx +110 -0
  109. package/template/src/components/basic/RootDialog/animations/Animation.ts +29 -0
  110. package/template/src/components/basic/RootDialog/animations/FadeAnimation.ts +40 -0
  111. package/template/src/components/basic/RootDialog/animations/ScaleAnimation.ts +37 -0
  112. package/template/src/components/basic/RootDialog/animations/SlideAnimation.ts +89 -0
  113. package/template/src/components/basic/RootDialog/components/Backdrop.tsx +60 -0
  114. package/template/src/components/basic/RootDialog/components/BaseDialog.tsx +564 -0
  115. package/template/src/components/basic/RootDialog/components/BottomDialog.tsx +32 -0
  116. package/template/src/components/basic/RootDialog/components/DialogButton.tsx +87 -0
  117. package/template/src/components/basic/RootDialog/components/DialogContent.tsx +26 -0
  118. package/template/src/components/basic/RootDialog/components/DialogContext.tsx +8 -0
  119. package/template/src/components/basic/RootDialog/components/DialogFooter.tsx +42 -0
  120. package/template/src/components/basic/RootDialog/components/DialogTitle.tsx +53 -0
  121. package/template/src/components/basic/RootDialog/components/DraggableView.tsx +271 -0
  122. package/template/src/components/basic/RootDialog/index.ts +21 -0
  123. package/template/src/components/basic/RootDialog/type.ts +102 -0
  124. package/template/src/components/basic/Text/index.tsx +8 -0
  125. package/template/src/components/basic/index.ts +35 -0
  126. package/template/src/configs/constants/type/APIStatus.type.ts +8 -0
  127. package/template/src/configs/constants/type/Locale.type.ts +7 -0
  128. package/template/src/configs/constants/type/StorageKey.type.ts +7 -0
  129. package/template/src/configs/constants/type/ThemeType.type.ts +6 -0
  130. package/template/src/configs/constants/type/index.ts +11 -0
  131. package/template/src/configs/index.ts +22 -0
  132. package/template/src/contexts/ThemeContext.ts +6 -0
  133. package/template/src/hooks/useAppLoading.ts +26 -0
  134. package/template/src/hooks/useAppState.ts +36 -0
  135. package/template/src/hooks/useArray.ts +47 -0
  136. package/template/src/hooks/useAsync.ts +42 -0
  137. package/template/src/hooks/useAsyncStorage.ts +41 -0
  138. package/template/src/hooks/useBoolean.ts +21 -0
  139. package/template/src/hooks/useBuildTheme.ts +249 -0
  140. package/template/src/hooks/useCountDown.ts +111 -0
  141. package/template/src/hooks/useCounter.ts +27 -0
  142. package/template/src/hooks/useDebounce.ts +25 -0
  143. package/template/src/hooks/useDebouncedValidate.ts +32 -0
  144. package/template/src/hooks/useDebugInformation.ts +38 -0
  145. package/template/src/hooks/useDeviceToken.ts +20 -0
  146. package/template/src/hooks/useEncryptedStorage.ts +41 -0
  147. package/template/src/hooks/useFontFamily.ts +13 -0
  148. package/template/src/hooks/useHttp.ts +18 -0
  149. package/template/src/hooks/useInterval.ts +24 -0
  150. package/template/src/hooks/useIsForeground.ts +17 -0
  151. package/template/src/hooks/useMMKVStorage.ts +0 -0
  152. package/template/src/hooks/usePrevious.ts +12 -0
  153. package/template/src/hooks/useRenderCount.ts +10 -0
  154. package/template/src/hooks/useTheme.ts +17 -0
  155. package/template/src/hooks/useTimeCountDown.ts +91 -0
  156. package/template/src/index.tsx +65 -0
  157. package/template/src/infrastructures/NetClient/AbstractClient.ts +66 -0
  158. package/template/src/infrastructures/NetClient/ApiResponse.ts +16 -0
  159. package/template/src/infrastructures/NetClient/ApisauceClient.ts +76 -0
  160. package/template/src/infrastructures/NetClient/AxiosClient.ts +80 -0
  161. package/template/src/infrastructures/NetClient/FetchNetClient.ts +120 -0
  162. package/template/src/infrastructures/NetClient/config.ts +3 -0
  163. package/template/src/infrastructures/NetClient/interfaces/INetClient.ts +6 -0
  164. package/template/src/infrastructures/Storage/IStorage.ts +7 -0
  165. package/template/src/infrastructures/Storage/MMKVStorage.ts +41 -0
  166. package/template/src/infrastructures/common/Timeout.ts +27 -0
  167. package/template/src/infrastructures/common/colorUtils.ts +82 -0
  168. package/template/src/infrastructures/common/dateUtils.ts +39 -0
  169. package/template/src/infrastructures/common/logger.ts +115 -0
  170. package/template/src/locales/en-US/general.json +26 -0
  171. package/template/src/locales/en-US/index.ts +9 -0
  172. package/template/src/locales/en-US/screens.json +4 -0
  173. package/template/src/locales/en-US/setting.json +3 -0
  174. package/template/src/locales/i18n.ts +109 -0
  175. package/template/src/locales/zh-TW/general.json +26 -0
  176. package/template/src/locales/zh-TW/index.ts +9 -0
  177. package/template/src/locales/zh-TW/screens.json +4 -0
  178. package/template/src/locales/zh-TW/setting.json +3 -0
  179. package/template/src/models/index.ts +5 -0
  180. package/template/src/models/request.model.ts +50 -0
  181. package/template/src/navigators/DrawerNav/DrawerContent.tsx +66 -0
  182. package/template/src/navigators/DrawerNav/DrawerItem.tsx +261 -0
  183. package/template/src/navigators/DrawerNav/index.tsx +39 -0
  184. package/template/src/navigators/DrawerNav/props.ts +12 -0
  185. package/template/src/navigators/DrawerNav/types.ts +8 -0
  186. package/template/src/navigators/MainBottomTabNav/index.tsx +83 -0
  187. package/template/src/navigators/MainBottomTabNav/props.ts +16 -0
  188. package/template/src/navigators/MainBottomTabNav/types.ts +6 -0
  189. package/template/src/navigators/RootStack.tsx +43 -0
  190. package/template/src/navigators/index.tsx +40 -0
  191. package/template/src/navigators/props.ts +14 -0
  192. package/template/src/navigators/types.ts +18 -0
  193. package/template/src/navigators/utils.ts +68 -0
  194. package/template/src/redux/api/api.ts +41 -0
  195. package/template/src/redux/reducers/appSlice.ts +26 -0
  196. package/template/src/redux/reducers/index.ts +21 -0
  197. package/template/src/redux/reducers/nonPersistSlice.ts +51 -0
  198. package/template/src/redux/reducers/settingSlice.ts +48 -0
  199. package/template/src/redux/reducers/themeSlice.ts +55 -0
  200. package/template/src/redux/saga/index.ts +5 -0
  201. package/template/src/redux/saga/settingSaga.ts +21 -0
  202. package/template/src/redux/selectors/app.ts +9 -0
  203. package/template/src/redux/selectors/nonPersist.ts +23 -0
  204. package/template/src/redux/selectors/setting.ts +29 -0
  205. package/template/src/redux/selectors/theme.ts +13 -0
  206. package/template/src/redux/store/index.ts +79 -0
  207. package/template/src/redux/store/types.d.ts +5 -0
  208. package/template/src/screens/Home/index.tsx +146 -0
  209. package/template/src/screens/Settings/components/Item.tsx +45 -0
  210. package/template/src/screens/Settings/index.tsx +97 -0
  211. package/template/src/screens/Splash/index.tsx +53 -0
  212. package/template/src/services/Dialogs.tsx +226 -0
  213. package/template/src/services/PermissionCheck.ts +257 -0
  214. package/template/src/theme/Common.ts +48 -0
  215. package/template/src/theme/Fonts.ts +196 -0
  216. package/template/src/theme/Gutters.ts +63 -0
  217. package/template/src/theme/Icons.ts +28 -0
  218. package/template/src/theme/Images.ts +13 -0
  219. package/template/src/theme/Layout.ts +106 -0
  220. package/template/src/theme/Variables.ts +167 -0
  221. package/template/src/theme/components/Buttons.ts +37 -0
  222. package/template/src/theme/index.ts +8 -0
  223. package/template/src/theme/metrics.ts +57 -0
  224. package/template/src/theme/themes/default_dark/Images.ts +7 -0
  225. package/template/src/theme/themes/default_dark/Variables.ts +84 -0
  226. package/template/src/theme/themes/default_dark/index.ts +2 -0
  227. package/template/src/theme/themes/index.ts +8 -0
  228. package/template/src/theme/types.ts +152 -0
  229. package/template/src/utils/encrypt-helper.ts +118 -0
  230. package/template/src/utils/index.ts +76 -0
  231. package/template/src/utils/sys-info-data.ts +17 -0
  232. package/template/tsconfig.json +44 -0
  233. package/template.config.js +8 -0
@@ -0,0 +1,284 @@
1
+ import { useKeyboard } from '@react-native-community/hooks'
2
+ import _ from 'lodash'
3
+ import React, { forwardRef, useCallback, useMemo, useRef, useState } from 'react'
4
+ import { Keyboard, LayoutChangeEvent, TouchableOpacity, View } from 'react-native'
5
+ import { HelperText, Text, TextInput as PTextInput } from 'react-native-paper'
6
+
7
+ import { PressableOpacity } from '@/components/basic'
8
+ import ExpandableOverlay, { ExpandableOverlayMethods, ExpandableOverlayProps } from '@/components/basic/ExpandableOverlay'
9
+
10
+ import MaterialTextInput from '../MaterialTextInput'
11
+ import useImperativePickerHandle from './hooks/useImperativePickerHandle'
12
+ import usePickerLabel from './hooks/usePickerLabel'
13
+ import usePickerSearch from './hooks/usePickerSearch'
14
+ import usePickerSelection from './hooks/usePickerSelection'
15
+ import PickerContext from './PickerContext'
16
+ import PickerItem from './PickerItem'
17
+ import PickerItemsList from './PickerItemsList'
18
+ import { extractPickerItems } from './PickerPresenter'
19
+ import {
20
+ PickerFieldTypes,
21
+ PickerItemProps,
22
+ PickerLayouts,
23
+ PickerMethods,
24
+ PickerModes,
25
+ PickerProps,
26
+ PickerSearchStyle,
27
+ PickerValue,
28
+ } from './types'
29
+
30
+ type PickerStatics = {
31
+ Item: typeof PickerItem
32
+ modes: typeof PickerModes
33
+ fieldTypes: typeof PickerFieldTypes
34
+ extractPickerItems: typeof extractPickerItems
35
+ layouts: typeof PickerLayouts
36
+ }
37
+
38
+ const Picker = forwardRef<ExpandableOverlayMethods, PickerProps>((props: PickerProps, ref) => {
39
+ const {
40
+ accessibilityHint,
41
+ accessibilityLabel,
42
+ children,
43
+ containerStyle,
44
+ disabled,
45
+ fieldType = PickerFieldTypes.form,
46
+ getLabel,
47
+ // useNativePicker,
48
+ headerProps,
49
+ inputProps,
50
+ // customPickerProps,
51
+ layout,
52
+ // labelStyle,
53
+ listProps,
54
+ modalProps,
55
+ mode,
56
+ onChange,
57
+ onPress,
58
+ // renderCustomModal,
59
+ // enableModalBlur,
60
+ // topBarProps,
61
+ // pickerModalProps,
62
+ onSearchChange,
63
+ onShow,
64
+ placeholder,
65
+ renderCustomSearch,
66
+ renderItem,
67
+ renderPicker,
68
+ searchPlaceholder,
69
+ searchStyle,
70
+ selectionLimit,
71
+ showSearch,
72
+ testID = 'Picker',
73
+ useSafeArea,
74
+ useWheelPicker,
75
+ value,
76
+ ...others
77
+ } = props
78
+ const pickerExpandable = useRef<ExpandableOverlayMethods>(null)
79
+ const pickerRef = useImperativePickerHandle(ref, pickerExpandable)
80
+ // const keyboard = useKeyboard()
81
+
82
+ // const { preset } = others
83
+
84
+ const [selectedItemPosition, setSelectedItemPosition] = useState(0)
85
+ const [items, setItems] = useState(extractPickerItems(props))
86
+ React.useEffect(() => {
87
+ setItems(extractPickerItems(props))
88
+ }, [children])
89
+
90
+ const { filteredChildren, onSearchChange: _onSearchChange, setSearchValue } = usePickerSearch({ showSearch, onSearchChange, getLabel, children })
91
+ const { cancelSelect, multiDraftValue, onDoneSelecting, toggleItemSelection } = usePickerSelection({
92
+ value,
93
+ onChange,
94
+ pickerExpandableRef: pickerExpandable,
95
+ setSearchValue,
96
+ mode,
97
+ })
98
+ const { accessibilityInfo, label } = usePickerLabel({
99
+ value,
100
+ items,
101
+ getLabel,
102
+ accessibilityLabel,
103
+ accessibilityHint,
104
+ placeholder,
105
+ })
106
+ const {
107
+ disableErrorText,
108
+ errorColor,
109
+ errorText,
110
+ errorTextStyle,
111
+ hintText,
112
+ hintTextStyle,
113
+ ...restInputProps
114
+ } = inputProps || {}
115
+ const onSelectedItemLayout = useCallback((event: LayoutChangeEvent) => {
116
+ const y = event.nativeEvent.layout.y
117
+ setSelectedItemPosition(y)
118
+ }, [])
119
+
120
+ const contextValue = useMemo(() => {
121
+ // @ts-expect-error cleanup after removing migrate prop
122
+ const pickerValue = typeof value === 'object' && !_.isArray(value) ? value?.value : value
123
+
124
+ return {
125
+ value: mode === PickerModes.MULTI ? multiDraftValue : pickerValue,
126
+ onPress: mode === PickerModes.MULTI ? toggleItemSelection : onDoneSelecting,
127
+ isMultiMode: mode === PickerModes.MULTI,
128
+ getLabel,
129
+ onSelectedLayout: onSelectedItemLayout,
130
+ renderItem,
131
+ selectionLimit,
132
+ }
133
+ }, [
134
+ mode,
135
+ value,
136
+ multiDraftValue,
137
+ renderItem,
138
+ getLabel,
139
+ selectionLimit,
140
+ onSelectedItemLayout,
141
+ toggleItemSelection,
142
+ onDoneSelecting,
143
+ ])
144
+
145
+ // const propsByFieldType = useMemo(() => {
146
+ // if (fieldType === PickerFieldTypes.filter) {
147
+ // return {
148
+ // containerStyle: { flexDirection: 'row' },
149
+ // // labelStyle: Typography.text70,
150
+ // trailingAccessory: themeProps.trailingAccessory ?? <Icon marginL-s1 source={dropdown}/>,
151
+ // }
152
+ // } else if (fieldType === PickerFieldTypes.settings) {
153
+ // return {
154
+ // label: undefined,
155
+ // }
156
+ // }
157
+ // }, [fieldType, preset, themeProps.trailingAccessory])
158
+
159
+ const renderHelperText = useCallback(() => {
160
+ if (!!errorText) {
161
+ return (
162
+ <HelperText
163
+ type="error"
164
+ visible={!!errorText}
165
+ padding={'none'}
166
+ >{errorText}</HelperText>
167
+ )
168
+ } else if (!!hintText) {
169
+ return (
170
+ <HelperText
171
+ type="info"
172
+ visible={!!hintText}
173
+ padding={'none'}
174
+ >{hintText}</HelperText>
175
+ )
176
+ }
177
+
178
+ return null
179
+ }, [errorColor, errorText, errorTextStyle, hintText, hintTextStyle])
180
+ const renderPickerInnerInput = () => {
181
+
182
+ return (
183
+ <>
184
+ <PressableOpacity
185
+ onPress={() => {
186
+ Keyboard.dismiss()
187
+ pickerExpandable.current?.toggleExpandable()
188
+ }}
189
+ >
190
+ <View pointerEvents={'none'}>
191
+ <MaterialTextInput
192
+ value={label ?? ''}
193
+ right={<PTextInput.Icon icon="chevron-down" />}
194
+ disableErrorText
195
+ {...restInputProps}
196
+ />
197
+ </View>
198
+ </PressableOpacity>
199
+ {renderHelperText()}
200
+ </>
201
+ )
202
+ }
203
+
204
+ const expandableModalContent = useMemo(() => {
205
+ return (
206
+ <PickerItemsList
207
+ testID={`${testID}.modal`}
208
+ items={items}
209
+ showSearch={showSearch}
210
+ searchStyle={searchStyle}
211
+ searchPlaceholder={searchPlaceholder}
212
+ onSearchChange={_onSearchChange}
213
+ renderCustomSearch={renderCustomSearch}
214
+ listProps={listProps}
215
+ layout={layout}
216
+ headerProps={{
217
+ ...headerProps,
218
+ layout,
219
+ onClose: cancelSelect,
220
+ onDone: mode === PickerModes.MULTI ? () => onDoneSelecting(multiDraftValue) : undefined,
221
+ }}
222
+
223
+ >
224
+ {filteredChildren}
225
+ </PickerItemsList>
226
+ )
227
+ }, [
228
+ testID,
229
+ mode,
230
+ selectedItemPosition,
231
+ cancelSelect,
232
+ onDoneSelecting,
233
+ multiDraftValue,
234
+ showSearch,
235
+ searchStyle,
236
+ searchPlaceholder,
237
+ _onSearchChange,
238
+ renderCustomSearch,
239
+ listProps,
240
+ filteredChildren,
241
+ useSafeArea,
242
+ useWheelPicker,
243
+ items,
244
+ layout,
245
+ ])
246
+
247
+ return (
248
+ <PickerContext.Provider value={contextValue}>
249
+ <ExpandableOverlay
250
+ ref={pickerExpandable}
251
+ modalProps={{
252
+ style: {
253
+ flexDirection: 'column',
254
+ justifyContent: 'flex-end',
255
+ },
256
+ ...modalProps,
257
+ }}
258
+ expandableContent={expandableModalContent}
259
+ onPress={onPress}
260
+ disabled={disabled}
261
+ childrenPointEvents={'auto'}
262
+ activeOpacity={1}
263
+ >
264
+ {renderPickerInnerInput()}
265
+ </ExpandableOverlay>
266
+ </PickerContext.Provider>
267
+ )
268
+ }) as React.ForwardRefExoticComponent<PickerProps> & PickerStatics
269
+ Picker.Item = PickerItem
270
+ Picker.modes = PickerModes
271
+ Picker.fieldTypes = PickerFieldTypes
272
+ Picker.extractPickerItems = extractPickerItems
273
+ Picker.layouts = PickerLayouts
274
+ Picker.displayName = 'Picker'
275
+
276
+ const MemoPick = React.memo(Picker) as React.MemoExoticComponent<React.ForwardRefExoticComponent<PickerProps> & PickerStatics> & PickerStatics
277
+ MemoPick.Item = PickerItem
278
+ MemoPick.modes = PickerModes
279
+ MemoPick.fieldTypes = PickerFieldTypes
280
+ MemoPick.extractPickerItems = extractPickerItems
281
+ MemoPick.layouts = PickerLayouts
282
+ MemoPick.displayName = 'Picker'
283
+
284
+ export default MemoPick
@@ -0,0 +1,229 @@
1
+ import { PropsWithChildren, ReactNode } from 'react'
2
+ import { FlatListProps, StyleProp, TextStyle, ViewStyle } from 'react-native'
3
+ import { ModalProps } from 'react-native-modal'
4
+ import { IconSource } from 'react-native-paper/lib/typescript/src/components/Icon'
5
+
6
+ import { MaterialTextInputProps } from '@/components/basic/MaterialTextInput'
7
+
8
+ import { ExpandableOverlayMethods } from '../ExpandableOverlay'
9
+
10
+ type Without<T, K> = Pick<T, Exclude<keyof T, K>>
11
+
12
+ export enum PickerModes {
13
+ SINGLE = 'SINGLE',
14
+ MULTI = 'MULTI'
15
+ }
16
+ export enum PickerFieldTypes {
17
+ form = 'form',
18
+ filter = 'filter',
19
+ settings = 'settings'
20
+ }
21
+ export enum PickerLayouts {
22
+ full = 'full',
23
+ bottomSheet = 'bottomSheet'
24
+ }
25
+ export type PickerSingleValue = string | number
26
+ export type PickerMultiValue = PickerSingleValue[]
27
+ export type PickerValue = PickerSingleValue | PickerMultiValue | undefined
28
+ export type PickerSearchStyle = {
29
+ icon?: number
30
+ color?: string
31
+ placeholderTextColor?: string
32
+ selectionColor?: string
33
+ }
34
+
35
+ type RenderPickerOverloads<ValueType> = ValueType extends PickerValue
36
+ ? (value?: ValueType, label?: string) => React.ReactElement
37
+ : never
38
+ type RenderPicker = RenderPickerOverloads<PickerValue>
39
+ export type PickerOptionItem = {
40
+ value: PickerSingleValue
41
+ label: string
42
+ }
43
+ export type PickerHeaderProps = Pick<PickerBaseProps, 'layout'> & {
44
+ title?: string
45
+ titleStyle?: StyleProp<TextStyle>
46
+ onClose?: () => void
47
+ closeLabel?: string
48
+ closeLabelStyle?: StyleProp<TextStyle>
49
+ closeIcon?: IconSource
50
+ onDone?: () => void
51
+ doneLabel?: string
52
+ doneLabelStyle?: StyleProp<TextStyle>
53
+ doneIcon?: IconSource
54
+ backgroundColor?: string
55
+ }
56
+ export type TextInputPropsWithoutTheme = Without<MaterialTextInputProps, 'theme'>
57
+ export type PickerBaseProps = {
58
+ /**
59
+ * Picker Layout
60
+ */
61
+ layout?: PickerLayouts
62
+ fieldType?: PickerFieldTypes
63
+ /**
64
+ * Picker current value in the shape of {value: ..., label: ...}, for custom shape use 'getItemValue' prop
65
+ */
66
+ value?: PickerValue
67
+ /**
68
+ * Callback for when picker value change
69
+ */
70
+ onChange?: (value: PickerValue) => void
71
+ /**
72
+ * SINGLE mode or MULTI mode
73
+ */
74
+ mode?: PickerModes
75
+ /**
76
+ * Picker title
77
+ */
78
+ title?: string
79
+ /**
80
+ * Limit the number of selected items
81
+ */
82
+ selectionLimit?: number
83
+ placeholder?: string
84
+ renderPicker?: RenderPicker
85
+
86
+ inputProps?: TextInputPropsWithoutTheme
87
+ renderItem?: (
88
+ value: PickerValue,
89
+ itemProps: PickerItemProps & {isSelected: boolean; isItemDisabled: boolean},
90
+ label?: string
91
+ ) => React.ReactElement
92
+ /**
93
+ * Add onPress callback for when pressing the picker
94
+ */
95
+ onPress?: () => void
96
+ /**
97
+ * A function that returns the label to show for the selected Picker value
98
+ */
99
+ getLabel?: (value: PickerValue) => string
100
+ /**
101
+ * Show search input to filter picker items by label
102
+ */
103
+ showSearch?: boolean
104
+ /**
105
+ * Style object for the search input (only when passing showSearch)
106
+ */
107
+ searchStyle?: PickerSearchStyle
108
+ /**
109
+ * Placeholder text for the search input (only when passing showSearch)
110
+ */
111
+ searchPlaceholder?: string
112
+ /**
113
+ * callback for picker modal search input text change (only when passing showSearch)
114
+ */
115
+ onSearchChange?: (searchValue: string) => void
116
+ /**
117
+ * Render custom search input (only when passing showSearch)
118
+ */
119
+ renderCustomSearch?: (props: PickerItemsListProps) => React.ReactElement
120
+ // /**
121
+ // * @deprecated pass useWheelPicker prop instead
122
+ // * Allow to use the native picker solution (different style for iOS and Android)
123
+ // */
124
+ // useNativePicker?: boolean;
125
+ /**
126
+ * Use wheel picker instead of a list picker
127
+ */
128
+ useWheelPicker?: boolean
129
+ /**
130
+ * Pass props to the list component that wraps the picker options (allows to control FlatList behavior)
131
+ */
132
+ listProps?: Partial<FlatListProps<any>>
133
+ /**
134
+ * Custom container style
135
+ */
136
+ containerStyle?: StyleProp<ViewStyle>
137
+ /**
138
+ * Callback for modal onShow event
139
+ */
140
+ onShow?: () => void
141
+ /**
142
+ * Add safe area in the Picker modal view
143
+ */
144
+ useSafeArea?: boolean
145
+ /**
146
+ * Component test id
147
+ */
148
+ testID?: string
149
+ // children?: ReactNode | undefined
150
+ accessibilityLabel?: string
151
+ accessibilityHint?: string
152
+ modalProps?: Partial<ModalProps>
153
+ disabled?: boolean
154
+ headerProps?: Partial<PickerHeaderProps>
155
+ }
156
+ export type PickerPropsWithSingle = Omit<PickerBaseProps, 'onChange'> & {
157
+ mode?: PickerModes.SINGLE
158
+ value?: PickerSingleValue
159
+ onChange?: (value: PickerSingleValue) => void
160
+ }
161
+
162
+ export type PickerPropsWithMulti = Omit<PickerBaseProps, 'onChange'> & {
163
+ mode?: PickerModes.MULTI
164
+ value?: PickerMultiValue
165
+ onChange?: (value: PickerMultiValue) => void
166
+ }
167
+
168
+ export type PickerProps = PropsWithChildren<PickerPropsWithSingle | PickerPropsWithMulti>
169
+ export type PickerItemProps = {
170
+ /**
171
+ * Item's value
172
+ */
173
+ value: PickerSingleValue
174
+ /**
175
+ * Item's label
176
+ */
177
+ label: string
178
+ /**
179
+ * Item's label style
180
+ */
181
+ labelStyle?: StyleProp<TextStyle>
182
+ /**
183
+ * Custom function for the item label (e.g (value) => customLabel)
184
+ */
185
+ getItemLabel?: PickerProps['getLabel']
186
+ /**
187
+ * @deprecated Function to return the value out of the item value prop when value is custom shaped.
188
+ */
189
+ // getItemValue?: PickerProps['getItemValue']
190
+ /**
191
+ * Render custom item
192
+ */
193
+ renderItem?: PickerProps['renderItem']
194
+ /**
195
+ * Pass to change the selected icon
196
+ */
197
+ selectedIcon?: IconSource
198
+ /**
199
+ * Pass to change the selected icon color
200
+ */
201
+ selectedIconColor?: string
202
+ /**
203
+ * Is the item disabled
204
+ */
205
+ disabled?: boolean
206
+ /**
207
+ * Callback for onPress action
208
+ */
209
+ onPress?: () => void
210
+ /**
211
+ * Component test id
212
+ */
213
+ testID?: string
214
+ }
215
+ export type PickerContextProps =
216
+ Pick<PickerProps, 'value'|'renderItem'|'selectionLimit'|'getLabel'> & {
217
+ onPress: (value: PickerSingleValue) => void
218
+ isMultiMode: boolean
219
+ onSelectedLayout: (event: any) => any
220
+ selectionLimit: PickerProps['selectionLimit']
221
+ }
222
+
223
+ export type PickerItemsListProps = Pick<
224
+ PropsWithChildren<PickerProps>,
225
+ 'testID'|'showSearch'|'listProps'|'children'|'searchStyle'|'searchPlaceholder'|'onSearchChange'|'renderCustomSearch'|'headerProps'|'layout'
226
+ > & {
227
+ items?: PickerOptionItem[]
228
+ }
229
+ export type PickerMethods = ExpandableOverlayMethods
@@ -0,0 +1,20 @@
1
+ import React, { PropsWithChildren } from 'react'
2
+ import { PressableOpacity as RawPressableOpacity, PressableOpacityProps as RawPressableOpacityProps } from 'react-native-pressable-opacity'
3
+
4
+ type Props = PropsWithChildren<RawPressableOpacityProps>
5
+ const PressableOpacity = (props: Props) => {
6
+ const {
7
+ activeOpacity = 0.5,
8
+ children,
9
+ disabledOpacity = 1,
10
+ ...rest
11
+ } = props
12
+
13
+ return (
14
+ <RawPressableOpacity {...rest} activeOpacity={activeOpacity} disabledOpacity={disabledOpacity}>
15
+ {children}
16
+ </RawPressableOpacity>
17
+ )
18
+ }
19
+
20
+ export default PressableOpacity