@chem-po/react-native 0.0.29 → 0.0.31

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 (215) hide show
  1. package/lib/commonjs/components/button/DeleteButton.js +7 -8
  2. package/lib/commonjs/components/button/DeleteButton.js.map +1 -1
  3. package/lib/commonjs/components/button/LoadingButton.js +3 -3
  4. package/lib/commonjs/components/button/LoadingButton.js.map +1 -1
  5. package/lib/commonjs/components/button/Toggle.js +21 -17
  6. package/lib/commonjs/components/button/Toggle.js.map +1 -1
  7. package/lib/commonjs/components/form/Form.js +30 -4
  8. package/lib/commonjs/components/form/Form.js.map +1 -1
  9. package/lib/commonjs/components/form/FormFooter.js +3 -2
  10. package/lib/commonjs/components/form/FormFooter.js.map +1 -1
  11. package/lib/commonjs/components/form/input/Editable.js +50 -73
  12. package/lib/commonjs/components/form/input/Editable.js.map +1 -1
  13. package/lib/commonjs/components/form/input/StandaloneInput.js.map +1 -1
  14. package/lib/commonjs/components/form/input/common/InputClearButton.js +2 -1
  15. package/lib/commonjs/components/form/input/common/InputClearButton.js.map +1 -1
  16. package/lib/commonjs/components/form/input/date/index.js +23 -10
  17. package/lib/commonjs/components/form/input/date/index.js.map +1 -1
  18. package/lib/commonjs/components/form/input/datetime/index.js +32 -11
  19. package/lib/commonjs/components/form/input/datetime/index.js.map +1 -1
  20. package/lib/commonjs/components/form/input/file/index.js +27 -27
  21. package/lib/commonjs/components/form/input/file/index.js.map +1 -1
  22. package/lib/commonjs/components/form/input/hooks/useInputStyles.js +5 -6
  23. package/lib/commonjs/components/form/input/hooks/useInputStyles.js.map +1 -1
  24. package/lib/commonjs/components/form/input/input.js +3 -3
  25. package/lib/commonjs/components/form/input/input.js.map +1 -1
  26. package/lib/commonjs/components/form/input/multipleSelect/index.js +41 -24
  27. package/lib/commonjs/components/form/input/multipleSelect/index.js.map +1 -1
  28. package/lib/commonjs/components/form/input/select/index.js +1 -1
  29. package/lib/commonjs/components/form/input/select/index.js.map +1 -1
  30. package/lib/commonjs/components/form/input/socialMedia/index.js +3 -2
  31. package/lib/commonjs/components/form/input/socialMedia/index.js.map +1 -1
  32. package/lib/commonjs/components/form/input/text/AutoResizeTextarea.js +1 -6
  33. package/lib/commonjs/components/form/input/text/AutoResizeTextarea.js.map +1 -1
  34. package/lib/commonjs/components/form/input/text/index.js +5 -3
  35. package/lib/commonjs/components/form/input/text/index.js.map +1 -1
  36. package/lib/commonjs/components/form/input/text/textarea.js +3 -13
  37. package/lib/commonjs/components/form/input/text/textarea.js.map +1 -1
  38. package/lib/commonjs/components/form/input/text/useWebAutoResize.js +7 -8
  39. package/lib/commonjs/components/form/input/text/useWebAutoResize.js.map +1 -1
  40. package/lib/commonjs/components/form/input/time/index.js +2 -1
  41. package/lib/commonjs/components/form/input/time/index.js.map +1 -1
  42. package/lib/commonjs/components/form/view/file.js +21 -12
  43. package/lib/commonjs/components/form/view/file.js.map +1 -1
  44. package/lib/commonjs/components/form/view/index.js +29 -18
  45. package/lib/commonjs/components/form/view/index.js.map +1 -1
  46. package/lib/commonjs/components/form/view/multipleSelect.js +17 -13
  47. package/lib/commonjs/components/form/view/multipleSelect.js.map +1 -1
  48. package/lib/commonjs/components/form/view/select.js +20 -9
  49. package/lib/commonjs/components/form/view/select.js.map +1 -1
  50. package/lib/commonjs/components/form/view/styles.js +0 -3
  51. package/lib/commonjs/components/form/view/styles.js.map +1 -1
  52. package/lib/commonjs/components/image/ImageViewModal.js +18 -15
  53. package/lib/commonjs/components/image/ImageViewModal.js.map +1 -1
  54. package/lib/commonjs/components/layout/CollapseHorizontal.js +84 -0
  55. package/lib/commonjs/components/layout/CollapseHorizontal.js.map +1 -0
  56. package/lib/commonjs/components/loading/LoadingImage.js +20 -13
  57. package/lib/commonjs/components/loading/LoadingImage.js.map +1 -1
  58. package/lib/commonjs/components/theme/colorMode/DarkModeToggle.js +2 -1
  59. package/lib/commonjs/components/theme/colorMode/DarkModeToggle.js.map +1 -1
  60. package/lib/commonjs/contexts/root.js +6 -6
  61. package/lib/commonjs/contexts/root.js.map +1 -1
  62. package/lib/commonjs/index.js +11 -0
  63. package/lib/commonjs/index.js.map +1 -1
  64. package/lib/commonjs/types/forms.js +6 -0
  65. package/lib/commonjs/types/forms.js.map +1 -0
  66. package/lib/commonjs/types/index.js +17 -0
  67. package/lib/commonjs/types/index.js.map +1 -0
  68. package/lib/module/components/button/DeleteButton.js +8 -9
  69. package/lib/module/components/button/DeleteButton.js.map +1 -1
  70. package/lib/module/components/button/LoadingButton.js +4 -4
  71. package/lib/module/components/button/LoadingButton.js.map +1 -1
  72. package/lib/module/components/button/Toggle.js +24 -20
  73. package/lib/module/components/button/Toggle.js.map +1 -1
  74. package/lib/module/components/form/Form.js +31 -5
  75. package/lib/module/components/form/Form.js.map +1 -1
  76. package/lib/module/components/form/FormFooter.js +4 -3
  77. package/lib/module/components/form/FormFooter.js.map +1 -1
  78. package/lib/module/components/form/input/Editable.js +51 -74
  79. package/lib/module/components/form/input/Editable.js.map +1 -1
  80. package/lib/module/components/form/input/StandaloneInput.js.map +1 -1
  81. package/lib/module/components/form/input/common/InputClearButton.js +3 -2
  82. package/lib/module/components/form/input/common/InputClearButton.js.map +1 -1
  83. package/lib/module/components/form/input/date/index.js +24 -11
  84. package/lib/module/components/form/input/date/index.js.map +1 -1
  85. package/lib/module/components/form/input/datetime/index.js +33 -12
  86. package/lib/module/components/form/input/datetime/index.js.map +1 -1
  87. package/lib/module/components/form/input/file/index.js +29 -29
  88. package/lib/module/components/form/input/file/index.js.map +1 -1
  89. package/lib/module/components/form/input/hooks/useInputStyles.js +5 -6
  90. package/lib/module/components/form/input/hooks/useInputStyles.js.map +1 -1
  91. package/lib/module/components/form/input/input.js +3 -3
  92. package/lib/module/components/form/input/input.js.map +1 -1
  93. package/lib/module/components/form/input/multipleSelect/index.js +41 -24
  94. package/lib/module/components/form/input/multipleSelect/index.js.map +1 -1
  95. package/lib/module/components/form/input/select/index.js +1 -1
  96. package/lib/module/components/form/input/select/index.js.map +1 -1
  97. package/lib/module/components/form/input/socialMedia/index.js +4 -3
  98. package/lib/module/components/form/input/socialMedia/index.js.map +1 -1
  99. package/lib/module/components/form/input/text/AutoResizeTextarea.js +1 -6
  100. package/lib/module/components/form/input/text/AutoResizeTextarea.js.map +1 -1
  101. package/lib/module/components/form/input/text/index.js +6 -4
  102. package/lib/module/components/form/input/text/index.js.map +1 -1
  103. package/lib/module/components/form/input/text/textarea.js +4 -14
  104. package/lib/module/components/form/input/text/textarea.js.map +1 -1
  105. package/lib/module/components/form/input/text/useWebAutoResize.js +7 -8
  106. package/lib/module/components/form/input/text/useWebAutoResize.js.map +1 -1
  107. package/lib/module/components/form/input/time/index.js +3 -2
  108. package/lib/module/components/form/input/time/index.js.map +1 -1
  109. package/lib/module/components/form/view/file.js +15 -6
  110. package/lib/module/components/form/view/file.js.map +1 -1
  111. package/lib/module/components/form/view/index.js +19 -8
  112. package/lib/module/components/form/view/index.js.map +1 -1
  113. package/lib/module/components/form/view/multipleSelect.js +18 -14
  114. package/lib/module/components/form/view/multipleSelect.js.map +1 -1
  115. package/lib/module/components/form/view/select.js +20 -9
  116. package/lib/module/components/form/view/select.js.map +1 -1
  117. package/lib/module/components/form/view/styles.js +0 -3
  118. package/lib/module/components/form/view/styles.js.map +1 -1
  119. package/lib/module/components/image/ImageViewModal.js +20 -17
  120. package/lib/module/components/image/ImageViewModal.js.map +1 -1
  121. package/lib/module/components/layout/CollapseHorizontal.js +76 -0
  122. package/lib/module/components/layout/CollapseHorizontal.js.map +1 -0
  123. package/lib/module/components/loading/LoadingImage.js +21 -14
  124. package/lib/module/components/loading/LoadingImage.js.map +1 -1
  125. package/lib/module/components/theme/colorMode/DarkModeToggle.js +3 -2
  126. package/lib/module/components/theme/colorMode/DarkModeToggle.js.map +1 -1
  127. package/lib/module/contexts/root.js +6 -6
  128. package/lib/module/contexts/root.js.map +1 -1
  129. package/lib/module/index.js +1 -0
  130. package/lib/module/index.js.map +1 -1
  131. package/lib/module/types/forms.js +2 -0
  132. package/lib/module/types/forms.js.map +1 -0
  133. package/lib/module/types/index.js +2 -0
  134. package/lib/module/types/index.js.map +1 -0
  135. package/lib/typescript/components/button/DeleteButton.d.ts.map +1 -1
  136. package/lib/typescript/components/button/LoadingButton.d.ts.map +1 -1
  137. package/lib/typescript/components/button/Toggle.d.ts +5 -2
  138. package/lib/typescript/components/button/Toggle.d.ts.map +1 -1
  139. package/lib/typescript/components/form/Form.d.ts.map +1 -1
  140. package/lib/typescript/components/form/FormFooter.d.ts.map +1 -1
  141. package/lib/typescript/components/form/input/Editable.d.ts +2 -2
  142. package/lib/typescript/components/form/input/Editable.d.ts.map +1 -1
  143. package/lib/typescript/components/form/input/StandaloneInput.d.ts +5 -14
  144. package/lib/typescript/components/form/input/StandaloneInput.d.ts.map +1 -1
  145. package/lib/typescript/components/form/input/common/InputClearButton.d.ts.map +1 -1
  146. package/lib/typescript/components/form/input/date/index.d.ts.map +1 -1
  147. package/lib/typescript/components/form/input/datetime/index.d.ts.map +1 -1
  148. package/lib/typescript/components/form/input/file/index.d.ts +2 -1
  149. package/lib/typescript/components/form/input/file/index.d.ts.map +1 -1
  150. package/lib/typescript/components/form/input/hooks/useInputStyles.d.ts +3 -6
  151. package/lib/typescript/components/form/input/hooks/useInputStyles.d.ts.map +1 -1
  152. package/lib/typescript/components/form/input/multipleSelect/index.d.ts.map +1 -1
  153. package/lib/typescript/components/form/input/socialMedia/index.d.ts.map +1 -1
  154. package/lib/typescript/components/form/input/text/AutoResizeTextarea.d.ts.map +1 -1
  155. package/lib/typescript/components/form/input/text/index.d.ts.map +1 -1
  156. package/lib/typescript/components/form/input/text/textarea.d.ts +2 -2
  157. package/lib/typescript/components/form/input/text/textarea.d.ts.map +1 -1
  158. package/lib/typescript/components/form/input/text/useWebAutoResize.d.ts +2 -3
  159. package/lib/typescript/components/form/input/text/useWebAutoResize.d.ts.map +1 -1
  160. package/lib/typescript/components/form/input/time/index.d.ts.map +1 -1
  161. package/lib/typescript/components/form/view/file.d.ts.map +1 -1
  162. package/lib/typescript/components/form/view/index.d.ts +3 -2
  163. package/lib/typescript/components/form/view/index.d.ts.map +1 -1
  164. package/lib/typescript/components/form/view/multipleSelect.d.ts.map +1 -1
  165. package/lib/typescript/components/form/view/select.d.ts +2 -1
  166. package/lib/typescript/components/form/view/select.d.ts.map +1 -1
  167. package/lib/typescript/components/form/view/styles.d.ts +0 -3
  168. package/lib/typescript/components/form/view/styles.d.ts.map +1 -1
  169. package/lib/typescript/components/image/ImageViewModal.d.ts.map +1 -1
  170. package/lib/typescript/components/layout/CollapseHorizontal.d.ts +9 -0
  171. package/lib/typescript/components/layout/CollapseHorizontal.d.ts.map +1 -0
  172. package/lib/typescript/components/loading/LoadingImage.d.ts +4 -1
  173. package/lib/typescript/components/loading/LoadingImage.d.ts.map +1 -1
  174. package/lib/typescript/components/theme/colorMode/DarkModeToggle.d.ts.map +1 -1
  175. package/lib/typescript/index.d.ts +1 -0
  176. package/lib/typescript/index.d.ts.map +1 -1
  177. package/lib/typescript/types/forms.d.ts +5 -0
  178. package/lib/typescript/types/forms.d.ts.map +1 -0
  179. package/lib/typescript/types/index.d.ts +2 -0
  180. package/lib/typescript/types/index.d.ts.map +1 -0
  181. package/package.json +4 -4
  182. package/src/components/button/DeleteButton.tsx +12 -25
  183. package/src/components/button/LoadingButton.tsx +4 -5
  184. package/src/components/button/Toggle.tsx +24 -19
  185. package/src/components/form/Form.tsx +31 -11
  186. package/src/components/form/FormFooter.tsx +6 -5
  187. package/src/components/form/input/Editable.tsx +52 -92
  188. package/src/components/form/input/StandaloneInput.tsx +4 -13
  189. package/src/components/form/input/common/InputClearButton.tsx +4 -3
  190. package/src/components/form/input/date/index.tsx +24 -11
  191. package/src/components/form/input/datetime/index.tsx +37 -15
  192. package/src/components/form/input/file/index.tsx +34 -35
  193. package/src/components/form/input/hooks/useInputStyles.ts +10 -7
  194. package/src/components/form/input/input.tsx +2 -2
  195. package/src/components/form/input/multipleSelect/index.tsx +47 -36
  196. package/src/components/form/input/select/index.tsx +1 -1
  197. package/src/components/form/input/socialMedia/index.tsx +6 -5
  198. package/src/components/form/input/text/AutoResizeTextarea.tsx +1 -5
  199. package/src/components/form/input/text/index.tsx +7 -5
  200. package/src/components/form/input/text/textarea.tsx +4 -16
  201. package/src/components/form/input/text/useWebAutoResize.tsx +9 -8
  202. package/src/components/form/input/time/index.tsx +4 -3
  203. package/src/components/form/view/file.tsx +9 -5
  204. package/src/components/form/view/index.tsx +26 -7
  205. package/src/components/form/view/multipleSelect.tsx +11 -9
  206. package/src/components/form/view/select.tsx +12 -3
  207. package/src/components/form/view/styles.ts +0 -3
  208. package/src/components/image/ImageViewModal.tsx +56 -50
  209. package/src/components/layout/CollapseHorizontal.tsx +92 -0
  210. package/src/components/loading/LoadingImage.tsx +19 -19
  211. package/src/components/theme/colorMode/DarkModeToggle.tsx +4 -3
  212. package/src/contexts/root.tsx +6 -6
  213. package/src/index.ts +1 -0
  214. package/src/types/forms.ts +14 -0
  215. package/src/types/index.ts +1 -0
@@ -1,4 +1,6 @@
1
+ import { InputRef } from '@chem-po/core'
1
2
  import {
3
+ CustomEditableViewProps,
2
4
  EditableProps,
3
5
  Field,
4
6
  useColorModeValue,
@@ -7,8 +9,11 @@ import {
7
9
  useThemeValue,
8
10
  } from '@chem-po/react'
9
11
  import { Ionicons } from '@expo/vector-icons'
10
- import React, { useCallback, useEffect, useMemo } from 'react'
11
- import { StyleSheet, TouchableOpacity, View, ViewStyle } from 'react-native'
12
+ import React, { ForwardedRef, useCallback, useEffect, useMemo } from 'react'
13
+ import { StyleSheet, TextStyle, View, ViewStyle } from 'react-native'
14
+ import { Pressable } from 'react-native-gesture-handler'
15
+ import { CustomInputProps } from '../../../types/forms'
16
+ import { CollapseHorizontal } from '../../layout/CollapseHorizontal'
12
17
  import { LoadingOverlay } from '../../loading/LoadingOverlay'
13
18
  import { UploadProgress } from '../UploadProgress'
14
19
  import { FieldView } from '../view'
@@ -24,7 +29,9 @@ export const Editable = <T extends Field>({
24
29
  onEditOpen,
25
30
  containerStyle,
26
31
  size,
27
- }: EditableProps<ViewStyle, T>) => {
32
+ CustomInput,
33
+ CustomView,
34
+ }: EditableProps<ViewStyle, TextStyle, T>) => {
28
35
  const {
29
36
  inputRef,
30
37
  setValue,
@@ -36,7 +43,6 @@ export const Editable = <T extends Field>({
36
43
  isEditing,
37
44
  value,
38
45
  setEditHovered,
39
- submitValue,
40
46
  submit,
41
47
  } = useEditable({
42
48
  value: initValue,
@@ -48,6 +54,7 @@ export const Editable = <T extends Field>({
48
54
  })
49
55
 
50
56
  const alwaysEditing = useMemo(() => {
57
+ if (!field) return false
51
58
  switch (field._type) {
52
59
  case 'file':
53
60
  case 'boolean':
@@ -57,29 +64,6 @@ export const Editable = <T extends Field>({
57
64
  }
58
65
  }, [field])
59
66
 
60
- const shouldSubmitOnChange = useMemo(() => {
61
- if (alwaysEditing) return true
62
- switch (field._type) {
63
- case 'select':
64
- case 'date':
65
- case 'time':
66
- case 'datetime':
67
- return true
68
- default:
69
- return false
70
- }
71
- }, [field, alwaysEditing])
72
-
73
- const noCloseButton = useMemo(() => {
74
- if (alwaysEditing) return true
75
- switch (field._type) {
76
- case 'select':
77
- return true
78
- default:
79
- return false
80
- }
81
- }, [field, alwaysEditing])
82
-
83
67
  useEffect(() => {
84
68
  if (isEditing) {
85
69
  inputRef.current?.focus()
@@ -90,100 +74,83 @@ export const Editable = <T extends Field>({
90
74
  const editingBorderColor = useColorModeValue('#00000055', '#ffffff55')
91
75
  const submitColor = useThemeValue('colors.accent.600')
92
76
 
93
- const handleBlur = useCallback(() => {
94
- switch (field._type) {
95
- case 'select':
96
- case 'date':
97
- case 'time':
98
- case 'datetime':
99
- handleEditClose()
100
- break
101
- default:
102
- break
103
- }
104
- }, [field, handleEditClose])
77
+ const RenderInput = useCallback(
78
+ (props: CustomInputProps<T['defaultValue']>, ref?: ForwardedRef<InputRef | null>) => {
79
+ if (CustomInput) {
80
+ return <CustomInput {...props} ref={ref} />
81
+ }
82
+ if (!field) throw new Error('Editable component must have a field OR a CustomInput')
83
+ return <StandaloneInput ref={ref} field={field} {...props} />
84
+ },
85
+ [CustomInput, field],
86
+ )
105
87
 
106
- const editableField = useMemo(
107
- () => ({
108
- ...field,
109
- // optional: false,
110
- }),
111
- [field],
88
+ const RenderView = useCallback(
89
+ (props: CustomEditableViewProps<T['defaultValue']>) => {
90
+ if (CustomView) {
91
+ return <CustomView {...props} />
92
+ }
93
+ if (!field) throw new Error('Editable component must have a field OR a CustomView')
94
+ return <FieldView field={field} {...props} />
95
+ },
96
+ [CustomView, field],
112
97
  )
113
98
 
114
99
  return (
115
- <View
116
- style={[
117
- styles.container,
118
- {
119
- borderColor: editHovered && !isEditing ? editingBorderColor : 'transparent',
120
- },
121
- containerStyle,
122
- ]}>
100
+ <View style={[styles.container, containerStyle]}>
123
101
  <View style={styles.contentContainer}>
124
102
  <View
125
103
  style={[
126
104
  styles.inputContainer,
127
105
  {
128
106
  opacity: isLoading ? 0 : 1,
129
- borderColor: isEditing ? editingBorderColor : 'transparent',
107
+ borderColor: isEditing || editHovered ? editingBorderColor : 'transparent',
130
108
  },
131
109
  ]}>
132
110
  {isEditing || alwaysEditing ? (
133
- <StandaloneInput
111
+ <RenderInput
112
+ onChange={setValue}
134
113
  ref={inputRef}
135
114
  value={value}
136
115
  inEditable
137
- field={editableField}
138
116
  style={style}
139
117
  size={size}
140
- onChange={shouldSubmitOnChange ? v => submitValue(v) : setValue}
141
- onBlur={handleBlur}
142
118
  />
143
119
  ) : (
144
- <FieldView noLabel style={style} size={size} field={field} value={value} />
120
+ <RenderView inEditable noLabel size={size} value={value} />
145
121
  )}
146
122
  </View>
147
123
  {!alwaysEditing && (
148
124
  <View style={styles.buttonsContainer}>
149
- {isEditing ? null : (
150
- <TouchableOpacity
151
- style={styles.editButton}
125
+ <CollapseHorizontal in={!isEditing}>
126
+ <Pressable
152
127
  onPress={() => {
153
128
  handleEditOpen()
154
129
  }}
130
+ style={styles.submitButton}
155
131
  onPressIn={() => setEditHovered(true)}
156
132
  onPressOut={() => setEditHovered(false)}>
157
133
  <Ionicons name="create-outline" size={20} color={iconColor} />
158
- </TouchableOpacity>
159
- )}
160
- {noCloseButton || !isEditing ? null : (
161
- <TouchableOpacity
162
- style={styles.editButton}
134
+ </Pressable>
135
+ </CollapseHorizontal>
136
+ <CollapseHorizontal in={isEditing} style={styles.submitButtonContainer}>
137
+ <Pressable
163
138
  onPress={() => {
164
139
  handleEditClose()
165
140
  }}
141
+ style={styles.submitButton}
166
142
  onPressIn={() => setEditHovered(true)}
167
143
  onPressOut={() => setEditHovered(false)}>
168
144
  <Ionicons name="close" size={20} color={iconColor} />
169
- </TouchableOpacity>
170
- )}
171
- <View
172
- style={[
173
- styles.submitButtonContainer,
174
- {
175
- width: isEditing ? 26 : 0,
176
- opacity: isEditing ? 1 : 0,
177
- },
178
- ]}>
179
- <TouchableOpacity
145
+ </Pressable>
146
+ <Pressable
180
147
  style={[styles.submitButton, { backgroundColor: submitColor }]}
181
148
  onPress={() => {
182
149
  submit()
183
150
  }}>
184
151
  <Ionicons name="checkmark" size={20} color="#fff" />
185
- </TouchableOpacity>
186
- </View>
152
+ </Pressable>
153
+ </CollapseHorizontal>
187
154
  </View>
188
155
  )}
189
156
  <LoadingOverlay loading={isLoading} />
@@ -196,20 +163,16 @@ export const Editable = <T extends Field>({
196
163
  const styles = StyleSheet.create({
197
164
  container: {
198
165
  borderRadius: 4,
199
- borderWidth: 1,
200
- borderStyle: 'dashed',
201
166
  width: '100%',
202
167
  },
203
168
  buttonsContainer: {
204
169
  flexDirection: 'row',
205
- alignItems: 'center',
206
- gap: 4,
207
- marginLeft: 5,
170
+ justifyContent: 'center',
171
+ paddingTop: 6,
208
172
  },
209
173
  contentContainer: {
210
174
  flexDirection: 'row',
211
- alignItems: 'center',
212
- paddingHorizontal: 4,
175
+ gap: 10,
213
176
  position: 'relative',
214
177
  width: '100%',
215
178
  },
@@ -219,13 +182,10 @@ const styles = StyleSheet.create({
219
182
  borderWidth: 1,
220
183
  borderStyle: 'dashed',
221
184
  },
222
- editButton: {
223
- padding: 4,
224
- },
225
185
  submitButtonContainer: {
226
- justifyContent: 'center',
227
- alignItems: 'center',
186
+ flexDirection: 'row',
228
187
  overflow: 'hidden',
188
+ gap: 12,
229
189
  },
230
190
  submitButton: {
231
191
  width: 24,
@@ -1,24 +1,15 @@
1
- import { InputRef, InputSize } from '@chem-po/core'
2
- import { Field, useStandaloneInput } from '@chem-po/react'
1
+ import { InputRef } from '@chem-po/core'
2
+ import { BaseCustomInputProps, Field, useStandaloneInput } from '@chem-po/react'
3
3
  import React, { ForwardedRef, forwardRef } from 'react'
4
- import { StyleProp, TextStyle, ViewStyle } from 'react-native'
4
+ import { TextStyle, ViewStyle } from 'react-native'
5
5
  import { Input } from './input'
6
6
 
7
7
  interface StandaloneInputProps<
8
8
  T extends Field,
9
9
  ContainerStyle extends ViewStyle = ViewStyle,
10
10
  InputStyle extends TextStyle = TextStyle,
11
- > {
12
- onChange: (v?: any) => void
13
- value?: any
11
+ > extends BaseCustomInputProps<T['defaultValue'], ContainerStyle, InputStyle> {
14
12
  field: T
15
- onBlur?: () => void
16
- onFocus?: () => void
17
- theme?: 'basic' | 'detailed'
18
- inEditable?: boolean
19
- style?: StyleProp<ContainerStyle>
20
- inputStyle?: StyleProp<InputStyle>
21
- size?: InputSize
22
13
  }
23
14
 
24
15
  const StandaloneInputBase = <
@@ -1,7 +1,8 @@
1
1
  import { useBackgroundColor, useBorderColor, useIconColor } from '@chem-po/react'
2
2
  import { Ionicons } from '@expo/vector-icons'
3
3
  import React from 'react'
4
- import { StyleSheet, TouchableOpacity } from 'react-native'
4
+ import { StyleSheet } from 'react-native'
5
+ import { Pressable } from 'react-native-gesture-handler'
5
6
 
6
7
  export const InputClearButton = ({
7
8
  onPress,
@@ -18,7 +19,7 @@ export const InputClearButton = ({
18
19
  const borderColor = useBorderColor()
19
20
  const backgroundColor = useBackgroundColor(100)
20
21
  return (
21
- <TouchableOpacity
22
+ <Pressable
22
23
  onPress={onPress}
23
24
  style={[
24
25
  styles.closeButton,
@@ -27,7 +28,7 @@ export const InputClearButton = ({
27
28
  hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
28
29
  disabled={!isActive}>
29
30
  <Ionicons name="close" size={size} color={iconColor} style={{ alignSelf: 'center' }} />
30
- </TouchableOpacity>
31
+ </Pressable>
31
32
  )
32
33
  }
33
34
 
@@ -2,9 +2,11 @@ import { getDateString, InputRef } from '@chem-po/core'
2
2
  import { DateField, useIconColor } from '@chem-po/react'
3
3
  import { Ionicons } from '@expo/vector-icons'
4
4
  import React, { forwardRef, useImperativeHandle, useMemo } from 'react'
5
- import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'
5
+ import { StyleSheet, Text, View } from 'react-native'
6
+ import { Gesture, GestureDetector } from 'react-native-gesture-handler'
6
7
  import { Portal } from 'react-native-paper'
7
8
  import { DatePickerModal } from 'react-native-paper-dates'
9
+ import { runOnJS } from 'react-native-reanimated'
8
10
  import { FieldProps } from '../../types'
9
11
  import { DateInputClearButton } from '../common/InputClearButton'
10
12
  import { useInputColor } from '../hooks/useInputColor'
@@ -46,24 +48,28 @@ export const DateInput = forwardRef<InputRef, FieldProps<DateField>>(
46
48
  },
47
49
  }))
48
50
 
49
- const showDialog = () => {
50
- onFocus()
51
- }
52
-
53
51
  const iconColor = useIconColor()
54
52
  const inputColor = useInputColor(value)
55
53
 
56
54
  const minDateObj = minDate === 'now' ? new Date() : minDate ? new Date(minDate) : undefined
57
55
  const maxDateObj = maxDate === 'now' ? new Date() : maxDate ? new Date(maxDate) : undefined
58
56
 
57
+ const mainTap = Gesture.Tap().onStart(() => {
58
+ runOnJS(onFocus)()
59
+ })
60
+
59
61
  return (
60
62
  <View style={styles.container}>
61
- <TouchableOpacity style={[styles.button, inputStyles]} onPress={showDialog}>
62
- <Text style={[styles.text, text, { color: inputColor }]}>
63
- {value ? getDateString(value, 'short') : placeholder}
64
- </Text>
63
+ <View style={[styles.button, inputStyles]}>
64
+ <GestureDetector gesture={mainTap}>
65
+ <View style={styles.textContainer}>
66
+ <Text numberOfLines={1} style={[styles.text, text, { color: inputColor }]}>
67
+ {value ? getDateString(value, 'short') : placeholder}
68
+ </Text>
69
+ <Ionicons name="calendar" size={iconSize} color={iconColor} />
70
+ </View>
71
+ </GestureDetector>
65
72
  <View style={buttonContainer}>
66
- <Ionicons name="calendar" size={iconSize} color={iconColor} />
67
73
  {optional && value ? (
68
74
  <DateInputClearButton
69
75
  size={clearButtonSize}
@@ -72,7 +78,7 @@ export const DateInput = forwardRef<InputRef, FieldProps<DateField>>(
72
78
  />
73
79
  ) : null}
74
80
  </View>
75
- </TouchableOpacity>
81
+ </View>
76
82
  <Portal>
77
83
  <DatePickerModal
78
84
  locale="en"
@@ -104,8 +110,15 @@ const styles = StyleSheet.create({
104
110
  flexDirection: 'row',
105
111
  alignItems: 'center',
106
112
  justifyContent: 'space-between',
113
+ gap: 8,
107
114
  width: '100%',
108
115
  },
116
+ textContainer: {
117
+ flex: 1,
118
+ flexDirection: 'row',
119
+ alignItems: 'center',
120
+ gap: 8,
121
+ },
109
122
  text: {
110
123
  flex: 1,
111
124
  },
@@ -2,9 +2,11 @@ import { getDateTimeString, InputRef } from '@chem-po/core'
2
2
  import { DateTimeField, useIconColor } from '@chem-po/react'
3
3
  import { Ionicons } from '@expo/vector-icons'
4
4
  import React, { forwardRef, useCallback, useImperativeHandle, useMemo, useState } from 'react'
5
- import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'
5
+ import { StyleSheet, Text, View } from 'react-native'
6
+ import { Gesture, GestureDetector, Pressable } from 'react-native-gesture-handler'
6
7
  import { Portal } from 'react-native-paper'
7
8
  import { DatePickerModal, TimePickerModal } from 'react-native-paper-dates'
9
+ import { runOnJS } from 'react-native-reanimated'
8
10
  import { FieldProps } from '../../types'
9
11
  import { DateInputClearButton } from '../common/InputClearButton'
10
12
  import { useInputColor } from '../hooks/useInputColor'
@@ -63,11 +65,21 @@ export const DateTimeInput = forwardRef<InputRef, FieldProps<DateTimeField>>(
63
65
  )
64
66
 
65
67
  const handleDismiss = useCallback(() => {
66
- setShowDatePicker(true)
68
+ setShowDatePicker(false)
67
69
  setShowTimePicker(false)
68
70
  onBlur()
69
71
  }, [onBlur])
70
72
 
73
+ const handleFocusTime = useCallback(() => {
74
+ setShowTimePicker(true)
75
+ onFocus()
76
+ }, [onFocus])
77
+
78
+ const handleFocusDate = useCallback(() => {
79
+ setShowDatePicker(true)
80
+ onFocus()
81
+ }, [onFocus])
82
+
71
83
  const date = useMemo(() => (value ? new Date(value) : undefined), [value])
72
84
 
73
85
  const formattedValue = useMemo(() => {
@@ -83,20 +95,27 @@ export const DateTimeInput = forwardRef<InputRef, FieldProps<DateTimeField>>(
83
95
  const iconColor = useIconColor()
84
96
  const inputColor = useInputColor(value)
85
97
 
98
+ const mainTap = Gesture.Tap().onStart(() => {
99
+ runOnJS(handleFocusDate)()
100
+ })
101
+
86
102
  return (
87
103
  <View style={styles.container}>
88
- <TouchableOpacity
89
- style={[styles.button, inputStyles]}
90
- onPress={() => {
91
- setShowDatePicker(true)
92
- onFocus()
93
- }}>
94
- <Text style={[styles.text, text, { color: inputColor }]}>
95
- {formattedValue ?? placeholder}
96
- </Text>
104
+ <View style={[styles.button, inputStyles]}>
105
+ <GestureDetector gesture={mainTap}>
106
+ <View style={styles.textContainer}>
107
+ <Text numberOfLines={1} style={[styles.text, text, { color: inputColor }]}>
108
+ {formattedValue ?? placeholder}
109
+ </Text>
110
+ </View>
111
+ </GestureDetector>
97
112
  <View style={buttonContainer}>
98
- <Ionicons name="calendar" size={iconSize} color={iconColor} />
99
- <Ionicons name="time" size={iconSize} color={iconColor} />
113
+ <Pressable onPress={handleFocusDate}>
114
+ <Ionicons name="calendar" size={iconSize} color={iconColor} />
115
+ </Pressable>
116
+ <Pressable onPress={handleFocusTime}>
117
+ <Ionicons name="time" size={iconSize} color={iconColor} />
118
+ </Pressable>
100
119
  {optional && value ? (
101
120
  <DateInputClearButton
102
121
  size={clearButtonSize}
@@ -105,7 +124,7 @@ export const DateTimeInput = forwardRef<InputRef, FieldProps<DateTimeField>>(
105
124
  />
106
125
  ) : null}
107
126
  </View>
108
- </TouchableOpacity>
127
+ </View>
109
128
  <Portal>
110
129
  {showDatePicker && (
111
130
  <DatePickerModal
@@ -148,7 +167,10 @@ const styles = StyleSheet.create({
148
167
  justifyContent: 'space-between',
149
168
  width: '100%',
150
169
  },
151
- text: {
170
+ textContainer: {
152
171
  flex: 1,
153
172
  },
173
+ text: {
174
+ width: '100%',
175
+ },
154
176
  })
@@ -12,8 +12,9 @@ import {
12
12
  import { Ionicons } from '@expo/vector-icons'
13
13
  import * as DocumentPicker from 'expo-document-picker'
14
14
  import * as ImagePicker from 'expo-image-picker'
15
- import React, { forwardRef, useCallback, useImperativeHandle, useMemo, useState } from 'react'
16
- import { StyleProp, StyleSheet, Text, TouchableOpacity, View, ViewStyle } from 'react-native'
15
+ import React, { forwardRef, useCallback, useImperativeHandle, useMemo } from 'react'
16
+ import { StyleProp, StyleSheet, Text, View, ViewStyle } from 'react-native'
17
+ import { Pressable } from 'react-native-gesture-handler'
17
18
  import { downloadFile } from '../../../../utils/downloadFile'
18
19
  import { LoadingImage } from '../../../loading/LoadingImage'
19
20
  import { FieldProps } from '../../types'
@@ -33,17 +34,17 @@ const generateAccept = (field: FileField) => {
33
34
  return accept.join(',')
34
35
  }
35
36
 
36
- const NoFileView = ({ hasUpload }: { hasUpload?: boolean }) => {
37
+ const NoFileView = ({ hasUpload, onPress }: { hasUpload?: boolean; onPress?: () => void }) => {
37
38
  const textColor = useTextColor()
38
39
  const iconColor = useIconColor()
39
40
  const borderColor = useBorderColor()
40
41
  return (
41
- <View style={[styles.noFileContainer, { borderColor }]}>
42
+ <Pressable style={[styles.noFileContainer, { borderColor }]} onPress={onPress}>
42
43
  <Text style={[styles.noFileText, { color: textColor }]}>
43
44
  {hasUpload ? 'Tap to upload file' : 'No file uploaded'}
44
45
  </Text>
45
46
  <Ionicons name="cloud-upload" size={24} color={iconColor} />
46
- </View>
47
+ </Pressable>
47
48
  )
48
49
  }
49
50
 
@@ -54,6 +55,7 @@ export const FileView = ({
54
55
  withFullView,
55
56
  nonImageContainerStyle,
56
57
  withDownload,
58
+ onUploadPress,
57
59
  }: {
58
60
  value?: FileValue | null
59
61
  hasUpload?: boolean
@@ -61,6 +63,7 @@ export const FileView = ({
61
63
  withFullView?: boolean
62
64
  nonImageContainerStyle?: StyleProp<ViewStyle>
63
65
  withDownload?: boolean
66
+ onUploadPress?: () => void
64
67
  }) => {
65
68
  const { storagePath, dataUrl } = value ?? {}
66
69
  const missingFile = !dataUrl && !storagePath
@@ -104,26 +107,22 @@ export const FileView = ({
104
107
  }
105
108
  }, [url, value, showError, showSuccess])
106
109
  if (!value || missingFile) {
107
- return <NoFileView hasUpload={hasUpload} />
108
- }
109
-
110
- if (value.type?.startsWith('image/')) {
111
- return (
112
- <LoadingImage
113
- withDownload={withDownload}
114
- filename={value.filename}
115
- src={url}
116
- fileType={value.type}
117
- loadingOverride={loading}
118
- width={imageOptions?.width ?? 120}
119
- height={imageOptions?.height ?? 120}
120
- withFullView={withFullView}
121
- style={styles.image}
122
- />
123
- )
110
+ return <NoFileView onPress={onUploadPress} hasUpload={hasUpload} />
124
111
  }
125
112
 
126
- return (
113
+ const body = value.type?.startsWith('image/') ? (
114
+ <LoadingImage
115
+ withDownload={withDownload}
116
+ filename={value.filename}
117
+ src={url}
118
+ fileType={value.type}
119
+ loadingOverride={loading}
120
+ width={imageOptions?.width ?? 120}
121
+ height={imageOptions?.height ?? 120}
122
+ withFullView={withFullView}
123
+ style={styles.image}
124
+ />
125
+ ) : (
127
126
  <View style={[styles.fileContainer, { borderColor, backgroundColor }, nonImageContainerStyle]}>
128
127
  <View style={styles.iconContainer}>
129
128
  <Ionicons name="document" size={24} color={iconColor} />
@@ -134,25 +133,25 @@ export const FileView = ({
134
133
  </Text>
135
134
  </View>
136
135
  {withDownload && (
137
- <TouchableOpacity
136
+ <Pressable
138
137
  style={styles.downloadButton}
139
138
  onPress={() => void handleDownload()}
140
139
  disabled={loading}>
141
140
  <Ionicons name="download" size={20} color={iconColor} />
142
- </TouchableOpacity>
141
+ </Pressable>
143
142
  )}
144
143
  </View>
145
144
  )
145
+
146
+ return onUploadPress ? <Pressable onPress={onUploadPress}>{body}</Pressable> : body
146
147
  }
147
148
 
148
149
  export const FileComponent = forwardRef<InputRef, FieldProps<FileField>>(
149
150
  ({ input: { value, onChange }, field }, ref) => {
150
- const [loading, setLoading] = useState(false)
151
151
  const { imageOptions } = field || {}
152
152
 
153
153
  const handlePickFile = useCallback(async () => {
154
154
  try {
155
- setLoading(true)
156
155
  let result: ImagePicker.ImagePickerResult | DocumentPicker.DocumentPickerResult
157
156
 
158
157
  if (field.accept?.includes('image')) {
@@ -193,8 +192,6 @@ export const FileComponent = forwardRef<InputRef, FieldProps<FileField>>(
193
192
  if (error instanceof Error) {
194
193
  console.error('Error picking file:', error.message)
195
194
  }
196
- } finally {
197
- setLoading(false)
198
195
  }
199
196
  }, [field, onChange, value])
200
197
 
@@ -227,12 +224,14 @@ export const FileComponent = forwardRef<InputRef, FieldProps<FileField>>(
227
224
  return (
228
225
  <View style={[styles.container, { borderColor }]}>
229
226
  <Text style={[styles.placeholder, { color: placeholderColor }]}>{field.placeholder}</Text>
230
- <TouchableOpacity
231
- style={styles.contentContainer}
232
- onPress={() => void handlePickFile()}
233
- disabled={loading}>
234
- <FileView hasUpload imageOptions={imgOptions} value={value} />
235
- </TouchableOpacity>
227
+ <View style={styles.contentContainer}>
228
+ <FileView
229
+ hasUpload
230
+ onUploadPress={() => void handlePickFile()}
231
+ imageOptions={imgOptions}
232
+ value={value}
233
+ />
234
+ </View>
236
235
  </View>
237
236
  )
238
237
  },
@@ -15,18 +15,15 @@ export const inputStyles = StyleSheet.create({
15
15
  borderRadius: 3,
16
16
  },
17
17
  inputSmall: {
18
- paddingVertical: 6,
19
- paddingHorizontal: 9,
18
+ padding: 8,
20
19
  borderRadius: 4,
21
20
  },
22
21
  inputMedium: {
23
- paddingVertical: 8,
24
- paddingHorizontal: 12,
22
+ padding: 12,
25
23
  borderRadius: 6,
26
24
  },
27
25
  inputLarge: {
28
- paddingVertical: 10,
29
- paddingHorizontal: 14,
26
+ padding: 14,
30
27
  borderRadius: 8,
31
28
  },
32
29
  inputTextSmall: {
@@ -110,7 +107,13 @@ export const useInputStyles = (
110
107
  const textColor = useTextColor()
111
108
  const usedSize = size ?? formSize
112
109
  return {
113
- text: { ...inputTextSizeMap[usedSize], color: textColor, outlineWidth: 0 },
110
+ text: {
111
+ ...inputTextSizeMap[usedSize],
112
+ paddingTop: 0,
113
+ paddingBottom: 0,
114
+ color: textColor,
115
+ outlineWidth: 0,
116
+ },
114
117
  container: {
115
118
  ...inputStyles.input,
116
119
  ...(inEditable ? editableInputSizeMap[usedSize] : inputSizeMap[usedSize]),
@@ -192,11 +192,11 @@ const staticStyles = StyleSheet.create({
192
192
  },
193
193
  inputContainer: {
194
194
  width: '100%',
195
- borderRadius: 4,
196
195
  paddingVertical: 1,
197
- overflow: 'hidden',
196
+ // overflow: 'hidden',
198
197
  },
199
198
  errorText: {
199
+ paddingTop: 3,
200
200
  paddingHorizontal: 8,
201
201
  fontWeight: 500,
202
202
  // backgroundColor: 'red',