@chem-po/react-native 0.0.30 → 0.0.32

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 (154) 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 +2 -1
  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 +4 -6
  12. package/lib/commonjs/components/form/input/Editable.js.map +1 -1
  13. package/lib/commonjs/components/form/input/common/InputClearButton.js +2 -1
  14. package/lib/commonjs/components/form/input/common/InputClearButton.js.map +1 -1
  15. package/lib/commonjs/components/form/input/date/index.js +23 -10
  16. package/lib/commonjs/components/form/input/date/index.js.map +1 -1
  17. package/lib/commonjs/components/form/input/datetime/index.js +27 -11
  18. package/lib/commonjs/components/form/input/datetime/index.js.map +1 -1
  19. package/lib/commonjs/components/form/input/file/index.js +31 -28
  20. package/lib/commonjs/components/form/input/file/index.js.map +1 -1
  21. package/lib/commonjs/components/form/input/hooks/useInputStyles.js +5 -6
  22. package/lib/commonjs/components/form/input/hooks/useInputStyles.js.map +1 -1
  23. package/lib/commonjs/components/form/input/input.js +3 -3
  24. package/lib/commonjs/components/form/input/input.js.map +1 -1
  25. package/lib/commonjs/components/form/input/multipleSelect/index.js +35 -23
  26. package/lib/commonjs/components/form/input/multipleSelect/index.js.map +1 -1
  27. package/lib/commonjs/components/form/input/socialMedia/index.js +3 -2
  28. package/lib/commonjs/components/form/input/socialMedia/index.js.map +1 -1
  29. package/lib/commonjs/components/form/input/text/AutoResizeTextarea.js +1 -6
  30. package/lib/commonjs/components/form/input/text/AutoResizeTextarea.js.map +1 -1
  31. package/lib/commonjs/components/form/input/text/index.js +2 -1
  32. package/lib/commonjs/components/form/input/text/index.js.map +1 -1
  33. package/lib/commonjs/components/form/input/text/textarea.js +2 -1
  34. package/lib/commonjs/components/form/input/text/textarea.js.map +1 -1
  35. package/lib/commonjs/components/form/input/text/useWebAutoResize.js +4 -4
  36. package/lib/commonjs/components/form/input/text/useWebAutoResize.js.map +1 -1
  37. package/lib/commonjs/components/form/input/time/index.js +2 -1
  38. package/lib/commonjs/components/form/input/time/index.js.map +1 -1
  39. package/lib/commonjs/components/form/view/select.js +6 -2
  40. package/lib/commonjs/components/form/view/select.js.map +1 -1
  41. package/lib/commonjs/components/image/ImageViewModal.js +22 -16
  42. package/lib/commonjs/components/image/ImageViewModal.js.map +1 -1
  43. package/lib/commonjs/components/layout/CollapseHorizontal.js +23 -11
  44. package/lib/commonjs/components/layout/CollapseHorizontal.js.map +1 -1
  45. package/lib/commonjs/components/loading/LoadingImage.js +20 -13
  46. package/lib/commonjs/components/loading/LoadingImage.js.map +1 -1
  47. package/lib/commonjs/components/theme/colorMode/DarkModeToggle.js +2 -1
  48. package/lib/commonjs/components/theme/colorMode/DarkModeToggle.js.map +1 -1
  49. package/lib/commonjs/utils/downloadFile.js +36 -26
  50. package/lib/commonjs/utils/downloadFile.js.map +1 -1
  51. package/lib/module/components/button/DeleteButton.js +8 -9
  52. package/lib/module/components/button/DeleteButton.js.map +1 -1
  53. package/lib/module/components/button/LoadingButton.js +4 -4
  54. package/lib/module/components/button/LoadingButton.js.map +1 -1
  55. package/lib/module/components/button/Toggle.js +3 -2
  56. package/lib/module/components/button/Toggle.js.map +1 -1
  57. package/lib/module/components/form/Form.js +31 -5
  58. package/lib/module/components/form/Form.js.map +1 -1
  59. package/lib/module/components/form/FormFooter.js +4 -3
  60. package/lib/module/components/form/FormFooter.js.map +1 -1
  61. package/lib/module/components/form/input/Editable.js +5 -7
  62. package/lib/module/components/form/input/Editable.js.map +1 -1
  63. package/lib/module/components/form/input/common/InputClearButton.js +3 -2
  64. package/lib/module/components/form/input/common/InputClearButton.js.map +1 -1
  65. package/lib/module/components/form/input/date/index.js +24 -11
  66. package/lib/module/components/form/input/date/index.js.map +1 -1
  67. package/lib/module/components/form/input/datetime/index.js +29 -13
  68. package/lib/module/components/form/input/datetime/index.js.map +1 -1
  69. package/lib/module/components/form/input/file/index.js +33 -30
  70. package/lib/module/components/form/input/file/index.js.map +1 -1
  71. package/lib/module/components/form/input/hooks/useInputStyles.js +5 -6
  72. package/lib/module/components/form/input/hooks/useInputStyles.js.map +1 -1
  73. package/lib/module/components/form/input/input.js +3 -3
  74. package/lib/module/components/form/input/input.js.map +1 -1
  75. package/lib/module/components/form/input/multipleSelect/index.js +35 -23
  76. package/lib/module/components/form/input/multipleSelect/index.js.map +1 -1
  77. package/lib/module/components/form/input/socialMedia/index.js +4 -3
  78. package/lib/module/components/form/input/socialMedia/index.js.map +1 -1
  79. package/lib/module/components/form/input/text/AutoResizeTextarea.js +1 -6
  80. package/lib/module/components/form/input/text/AutoResizeTextarea.js.map +1 -1
  81. package/lib/module/components/form/input/text/index.js +3 -2
  82. package/lib/module/components/form/input/text/index.js.map +1 -1
  83. package/lib/module/components/form/input/text/textarea.js +2 -1
  84. package/lib/module/components/form/input/text/textarea.js.map +1 -1
  85. package/lib/module/components/form/input/text/useWebAutoResize.js +4 -4
  86. package/lib/module/components/form/input/text/useWebAutoResize.js.map +1 -1
  87. package/lib/module/components/form/input/time/index.js +3 -2
  88. package/lib/module/components/form/input/time/index.js.map +1 -1
  89. package/lib/module/components/form/view/select.js +6 -2
  90. package/lib/module/components/form/view/select.js.map +1 -1
  91. package/lib/module/components/image/ImageViewModal.js +24 -18
  92. package/lib/module/components/image/ImageViewModal.js.map +1 -1
  93. package/lib/module/components/layout/CollapseHorizontal.js +24 -12
  94. package/lib/module/components/layout/CollapseHorizontal.js.map +1 -1
  95. package/lib/module/components/loading/LoadingImage.js +21 -14
  96. package/lib/module/components/loading/LoadingImage.js.map +1 -1
  97. package/lib/module/components/theme/colorMode/DarkModeToggle.js +3 -2
  98. package/lib/module/components/theme/colorMode/DarkModeToggle.js.map +1 -1
  99. package/lib/module/utils/downloadFile.js +35 -25
  100. package/lib/module/utils/downloadFile.js.map +1 -1
  101. package/lib/typescript/components/button/DeleteButton.d.ts.map +1 -1
  102. package/lib/typescript/components/button/LoadingButton.d.ts.map +1 -1
  103. package/lib/typescript/components/button/Toggle.d.ts.map +1 -1
  104. package/lib/typescript/components/form/Form.d.ts.map +1 -1
  105. package/lib/typescript/components/form/FormFooter.d.ts.map +1 -1
  106. package/lib/typescript/components/form/input/Editable.d.ts.map +1 -1
  107. package/lib/typescript/components/form/input/common/InputClearButton.d.ts.map +1 -1
  108. package/lib/typescript/components/form/input/date/index.d.ts.map +1 -1
  109. package/lib/typescript/components/form/input/datetime/index.d.ts.map +1 -1
  110. package/lib/typescript/components/form/input/file/index.d.ts +2 -1
  111. package/lib/typescript/components/form/input/file/index.d.ts.map +1 -1
  112. package/lib/typescript/components/form/input/hooks/useInputStyles.d.ts +3 -6
  113. package/lib/typescript/components/form/input/hooks/useInputStyles.d.ts.map +1 -1
  114. package/lib/typescript/components/form/input/multipleSelect/index.d.ts.map +1 -1
  115. package/lib/typescript/components/form/input/socialMedia/index.d.ts.map +1 -1
  116. package/lib/typescript/components/form/input/text/AutoResizeTextarea.d.ts.map +1 -1
  117. package/lib/typescript/components/form/input/text/index.d.ts.map +1 -1
  118. package/lib/typescript/components/form/input/text/useWebAutoResize.d.ts +2 -3
  119. package/lib/typescript/components/form/input/text/useWebAutoResize.d.ts.map +1 -1
  120. package/lib/typescript/components/form/input/time/index.d.ts.map +1 -1
  121. package/lib/typescript/components/form/view/select.d.ts.map +1 -1
  122. package/lib/typescript/components/image/ImageViewModal.d.ts.map +1 -1
  123. package/lib/typescript/components/layout/CollapseHorizontal.d.ts.map +1 -1
  124. package/lib/typescript/components/loading/LoadingImage.d.ts +4 -1
  125. package/lib/typescript/components/loading/LoadingImage.d.ts.map +1 -1
  126. package/lib/typescript/components/theme/colorMode/DarkModeToggle.d.ts.map +1 -1
  127. package/lib/typescript/utils/downloadFile.d.ts +2 -2
  128. package/lib/typescript/utils/downloadFile.d.ts.map +1 -1
  129. package/package.json +5 -4
  130. package/src/components/button/DeleteButton.tsx +12 -25
  131. package/src/components/button/LoadingButton.tsx +4 -5
  132. package/src/components/button/Toggle.tsx +4 -3
  133. package/src/components/form/Form.tsx +31 -11
  134. package/src/components/form/FormFooter.tsx +6 -5
  135. package/src/components/form/input/Editable.tsx +8 -9
  136. package/src/components/form/input/common/InputClearButton.tsx +4 -3
  137. package/src/components/form/input/date/index.tsx +24 -11
  138. package/src/components/form/input/datetime/index.tsx +33 -16
  139. package/src/components/form/input/file/index.tsx +38 -36
  140. package/src/components/form/input/hooks/useInputStyles.ts +10 -7
  141. package/src/components/form/input/input.tsx +2 -2
  142. package/src/components/form/input/multipleSelect/index.tsx +35 -35
  143. package/src/components/form/input/socialMedia/index.tsx +6 -5
  144. package/src/components/form/input/text/AutoResizeTextarea.tsx +1 -5
  145. package/src/components/form/input/text/index.tsx +4 -3
  146. package/src/components/form/input/text/textarea.tsx +1 -1
  147. package/src/components/form/input/text/useWebAutoResize.tsx +6 -4
  148. package/src/components/form/input/time/index.tsx +4 -3
  149. package/src/components/form/view/select.tsx +5 -1
  150. package/src/components/image/ImageViewModal.tsx +60 -51
  151. package/src/components/layout/CollapseHorizontal.tsx +20 -10
  152. package/src/components/loading/LoadingImage.tsx +19 -19
  153. package/src/components/theme/colorMode/DarkModeToggle.tsx +4 -3
  154. package/src/utils/downloadFile.ts +41 -31
@@ -10,7 +10,8 @@ import {
10
10
  } from '@chem-po/react'
11
11
  import { Ionicons } from '@expo/vector-icons'
12
12
  import React, { ForwardedRef, useCallback, useEffect, useMemo } from 'react'
13
- import { StyleSheet, TextStyle, TouchableOpacity, View, ViewStyle } from 'react-native'
13
+ import { StyleSheet, TextStyle, View, ViewStyle } from 'react-native'
14
+ import { Pressable } from 'react-native-gesture-handler'
14
15
  import { CustomInputProps } from '../../../types/forms'
15
16
  import { CollapseHorizontal } from '../../layout/CollapseHorizontal'
16
17
  import { LoadingOverlay } from '../../loading/LoadingOverlay'
@@ -95,8 +96,6 @@ export const Editable = <T extends Field>({
95
96
  [CustomView, field],
96
97
  )
97
98
 
98
- console.log({ isEditing })
99
-
100
99
  return (
101
100
  <View style={[styles.container, containerStyle]}>
102
101
  <View style={styles.contentContainer}>
@@ -124,7 +123,7 @@ export const Editable = <T extends Field>({
124
123
  {!alwaysEditing && (
125
124
  <View style={styles.buttonsContainer}>
126
125
  <CollapseHorizontal in={!isEditing}>
127
- <TouchableOpacity
126
+ <Pressable
128
127
  onPress={() => {
129
128
  handleEditOpen()
130
129
  }}
@@ -132,10 +131,10 @@ export const Editable = <T extends Field>({
132
131
  onPressIn={() => setEditHovered(true)}
133
132
  onPressOut={() => setEditHovered(false)}>
134
133
  <Ionicons name="create-outline" size={20} color={iconColor} />
135
- </TouchableOpacity>
134
+ </Pressable>
136
135
  </CollapseHorizontal>
137
136
  <CollapseHorizontal in={isEditing} style={styles.submitButtonContainer}>
138
- <TouchableOpacity
137
+ <Pressable
139
138
  onPress={() => {
140
139
  handleEditClose()
141
140
  }}
@@ -143,14 +142,14 @@ export const Editable = <T extends Field>({
143
142
  onPressIn={() => setEditHovered(true)}
144
143
  onPressOut={() => setEditHovered(false)}>
145
144
  <Ionicons name="close" size={20} color={iconColor} />
146
- </TouchableOpacity>
147
- <TouchableOpacity
145
+ </Pressable>
146
+ <Pressable
148
147
  style={[styles.submitButton, { backgroundColor: submitColor }]}
149
148
  onPress={() => {
150
149
  submit()
151
150
  }}>
152
151
  <Ionicons name="checkmark" size={20} color="#fff" />
153
- </TouchableOpacity>
152
+ </Pressable>
154
153
  </CollapseHorizontal>
155
154
  </View>
156
155
  )}
@@ -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,10 +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'
6
- import { Pressable } from 'react-native-gesture-handler'
5
+ import { StyleSheet, Text, View } from 'react-native'
6
+ import { Gesture, GestureDetector, Pressable } from 'react-native-gesture-handler'
7
7
  import { Portal } from 'react-native-paper'
8
8
  import { DatePickerModal, TimePickerModal } from 'react-native-paper-dates'
9
+ import { runOnJS } from 'react-native-reanimated'
9
10
  import { FieldProps } from '../../types'
10
11
  import { DateInputClearButton } from '../common/InputClearButton'
11
12
  import { useInputColor } from '../hooks/useInputColor'
@@ -64,11 +65,21 @@ export const DateTimeInput = forwardRef<InputRef, FieldProps<DateTimeField>>(
64
65
  )
65
66
 
66
67
  const handleDismiss = useCallback(() => {
67
- setShowDatePicker(true)
68
+ setShowDatePicker(false)
68
69
  setShowTimePicker(false)
69
70
  onBlur()
70
71
  }, [onBlur])
71
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
+
72
83
  const date = useMemo(() => (value ? new Date(value) : undefined), [value])
73
84
 
74
85
  const formattedValue = useMemo(() => {
@@ -84,22 +95,25 @@ export const DateTimeInput = forwardRef<InputRef, FieldProps<DateTimeField>>(
84
95
  const iconColor = useIconColor()
85
96
  const inputColor = useInputColor(value)
86
97
 
98
+ const mainTap = Gesture.Tap().onStart(() => {
99
+ runOnJS(handleFocusDate)()
100
+ })
101
+
87
102
  return (
88
103
  <View style={styles.container}>
89
- <TouchableOpacity
90
- style={[styles.button, inputStyles]}
91
- onPress={() => {
92
- setShowDatePicker(true)
93
- onFocus()
94
- }}>
95
- <Text style={[styles.text, text, { color: inputColor }]}>
96
- {formattedValue ?? placeholder}
97
- </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>
98
112
  <View style={buttonContainer}>
99
- <Pressable onPress={() => setShowDatePicker(true)}>
113
+ <Pressable onPress={handleFocusDate}>
100
114
  <Ionicons name="calendar" size={iconSize} color={iconColor} />
101
115
  </Pressable>
102
- <Pressable onPress={() => setShowTimePicker(true)}>
116
+ <Pressable onPress={handleFocusTime}>
103
117
  <Ionicons name="time" size={iconSize} color={iconColor} />
104
118
  </Pressable>
105
119
  {optional && value ? (
@@ -110,7 +124,7 @@ export const DateTimeInput = forwardRef<InputRef, FieldProps<DateTimeField>>(
110
124
  />
111
125
  ) : null}
112
126
  </View>
113
- </TouchableOpacity>
127
+ </View>
114
128
  <Portal>
115
129
  {showDatePicker && (
116
130
  <DatePickerModal
@@ -153,7 +167,10 @@ const styles = StyleSheet.create({
153
167
  justifyContent: 'space-between',
154
168
  width: '100%',
155
169
  },
156
- text: {
170
+ textContainer: {
157
171
  flex: 1,
158
172
  },
173
+ text: {
174
+ width: '100%',
175
+ },
159
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 { Platform, 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
@@ -93,7 +96,10 @@ export const FileView = ({
93
96
 
94
97
  try {
95
98
  await downloadFile(url, filename, fileType)
96
- showSuccess('File downloaded successfully')
99
+ if (Platform.OS === 'android') {
100
+ showSuccess('File downloaded successfully')
101
+ return
102
+ }
97
103
  } catch (error: unknown) {
98
104
  if (error instanceof Error) {
99
105
  console.error('Error downloading file:', error.message)
@@ -104,26 +110,22 @@ export const FileView = ({
104
110
  }
105
111
  }, [url, value, showError, showSuccess])
106
112
  if (!value || missingFile) {
107
- return <NoFileView hasUpload={hasUpload} />
113
+ return <NoFileView onPress={onUploadPress} hasUpload={hasUpload} />
108
114
  }
109
115
 
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
- )
124
- }
125
-
126
- return (
116
+ const body = value.type?.startsWith('image/') ? (
117
+ <LoadingImage
118
+ withDownload={withDownload}
119
+ filename={value.filename}
120
+ src={url}
121
+ fileType={value.type}
122
+ loadingOverride={loading}
123
+ width={imageOptions?.width ?? 120}
124
+ height={imageOptions?.height ?? 120}
125
+ withFullView={withFullView}
126
+ style={styles.image}
127
+ />
128
+ ) : (
127
129
  <View style={[styles.fileContainer, { borderColor, backgroundColor }, nonImageContainerStyle]}>
128
130
  <View style={styles.iconContainer}>
129
131
  <Ionicons name="document" size={24} color={iconColor} />
@@ -134,25 +136,25 @@ export const FileView = ({
134
136
  </Text>
135
137
  </View>
136
138
  {withDownload && (
137
- <TouchableOpacity
139
+ <Pressable
138
140
  style={styles.downloadButton}
139
141
  onPress={() => void handleDownload()}
140
142
  disabled={loading}>
141
143
  <Ionicons name="download" size={20} color={iconColor} />
142
- </TouchableOpacity>
144
+ </Pressable>
143
145
  )}
144
146
  </View>
145
147
  )
148
+
149
+ return onUploadPress ? <Pressable onPress={onUploadPress}>{body}</Pressable> : body
146
150
  }
147
151
 
148
152
  export const FileComponent = forwardRef<InputRef, FieldProps<FileField>>(
149
153
  ({ input: { value, onChange }, field }, ref) => {
150
- const [loading, setLoading] = useState(false)
151
154
  const { imageOptions } = field || {}
152
155
 
153
156
  const handlePickFile = useCallback(async () => {
154
157
  try {
155
- setLoading(true)
156
158
  let result: ImagePicker.ImagePickerResult | DocumentPicker.DocumentPickerResult
157
159
 
158
160
  if (field.accept?.includes('image')) {
@@ -193,8 +195,6 @@ export const FileComponent = forwardRef<InputRef, FieldProps<FileField>>(
193
195
  if (error instanceof Error) {
194
196
  console.error('Error picking file:', error.message)
195
197
  }
196
- } finally {
197
- setLoading(false)
198
198
  }
199
199
  }, [field, onChange, value])
200
200
 
@@ -227,12 +227,14 @@ export const FileComponent = forwardRef<InputRef, FieldProps<FileField>>(
227
227
  return (
228
228
  <View style={[styles.container, { borderColor }]}>
229
229
  <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>
230
+ <View style={styles.contentContainer}>
231
+ <FileView
232
+ hasUpload
233
+ onUploadPress={() => void handlePickFile()}
234
+ imageOptions={imgOptions}
235
+ value={value}
236
+ />
237
+ </View>
236
238
  </View>
237
239
  )
238
240
  },
@@ -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',
@@ -48,20 +48,17 @@ const BaseMultipleSelectComponent = <T extends MultipleSelectField>(
48
48
 
49
49
  const colorMode = useColorMode()
50
50
  const inputRef = useRef<IDropdownRef>(null)
51
- const {
52
- container: inputStyles,
53
- iconSize,
54
- clearButtonSize,
55
- text,
56
- buttonContainer,
57
- size,
58
- } = useInputStyles(inEditable, field.size, formSize)
51
+ const { container, iconSize, clearButtonSize, text, buttonContainer, size } = useInputStyles(
52
+ inEditable,
53
+ field.size,
54
+ formSize,
55
+ )
59
56
  const iconColor = useIconColor()
60
57
  const textColor = useTextColor()
61
58
  const placeholderColor = usePlaceholderColor()
62
59
  const menuBg = useBackgroundColor(100)
63
60
  const inputBg = useBackgroundColor(50)
64
- const selectedOptionBg = useColorModeValue('#ffffff55', '#ffffff22')
61
+ const selectedOptionBg = useColorModeValue('#ffffff22', '#ffffff22')
65
62
  const borderColor = useBorderColor()
66
63
 
67
64
  useImperativeHandle(ref, () => ({
@@ -73,13 +70,6 @@ const BaseMultipleSelectComponent = <T extends MultipleSelectField>(
73
70
  },
74
71
  }))
75
72
 
76
- const defaultSelectedOptionStyle = useMemo(() => {
77
- return {
78
- paddingVertical: inputStyles.paddingVertical,
79
- paddingHorizontal: inputStyles.paddingHorizontal,
80
- }
81
- }, [inputStyles])
82
-
83
73
  const RenderOptionText = (
84
74
  props: RenderSelectOptionProps<T['options'][number]['value'], T['options'][number]>,
85
75
  ) => {
@@ -96,9 +86,9 @@ const BaseMultipleSelectComponent = <T extends MultipleSelectField>(
96
86
  return RenderOption(props)
97
87
  }
98
88
  return (
99
- <>
100
- <Txt style={[defaultSelectedOptionStyle, text]}>{props.option.label}</Txt>
101
- </>
89
+ <View style={{ padding: 6 }}>
90
+ <Txt style={[text]}>{props.option.label}</Txt>
91
+ </View>
102
92
  )
103
93
  }
104
94
 
@@ -110,11 +100,11 @@ const BaseMultipleSelectComponent = <T extends MultipleSelectField>(
110
100
  <View style={[styles.wrapper]}>
111
101
  <MultiSelect
112
102
  ref={inputRef}
113
- style={[inputStyles, { borderColor }]}
103
+ style={[container, { borderColor, boxShadow: `0 0 10px ${borderColor}`, borderWidth: 0 }]}
114
104
  placeholderStyle={[text, { color: value?.length ? textColor : placeholderColor }]}
115
105
  containerStyle={{
116
106
  backgroundColor: menuBg,
117
- boxShadow: `0 0 10px ${borderColor}`,
107
+ boxShadow: `0 0 6px ${borderColor}`,
118
108
  borderWidth: 0,
119
109
  }}
120
110
  inputSearchStyle={[styles.inputSearch, text, { backgroundColor: inputBg, borderWidth: 0 }]}
@@ -135,21 +125,33 @@ const BaseMultipleSelectComponent = <T extends MultipleSelectField>(
135
125
  }}
136
126
  onFocus={onFocus}
137
127
  onBlur={onBlur}
128
+ itemContainerStyle={{
129
+ backgroundColor: menuBg,
130
+ borderTopWidth: 1,
131
+ borderColor: borderColor,
132
+ }}
138
133
  renderItem={(item, selected) => (
139
- <View style={{ backgroundColor: menuBg }}>
140
- <View style={{ backgroundColor: selected ? selectedOptionBg : 'transparent' }}>
141
- <RenderOptionText
142
- value={item.value}
143
- option={item}
144
- colorMode={colorMode}
145
- isSelected={!!selected}
146
- size={size}
147
- />
148
- </View>
134
+ <View
135
+ style={{
136
+ backgroundColor: selected ? selectedOptionBg : 'transparent',
137
+ paddingVertical: 8,
138
+ paddingHorizontal: 12,
139
+ flexDirection: 'row',
140
+ alignItems: 'center',
141
+ width: '100%',
142
+ }}>
143
+ <RenderOptionText
144
+ value={item.value}
145
+ option={item}
146
+ colorMode={colorMode}
147
+ isSelected={!!selected}
148
+ size={size}
149
+ />
150
+ {selected ? <Ionicons name="checkmark" size={iconSize} color={iconColor} /> : null}
149
151
  </View>
150
152
  )}
151
153
  renderSelectedItem={item => (
152
- <SelectedOptionContainer>
154
+ <SelectedOptionContainer style={{ marginTop: 10 }}>
153
155
  <RenderSelectedOptionText
154
156
  value={item.value}
155
157
  option={item}
@@ -189,7 +191,7 @@ const styles = StyleSheet.create({
189
191
  width: '100%',
190
192
  },
191
193
  defaultOption: {
192
- padding: 10,
194
+ flex: 1,
193
195
  },
194
196
  iconStyle: {
195
197
  width: 20,
@@ -198,7 +200,6 @@ const styles = StyleSheet.create({
198
200
  inputSearch: {
199
201
  paddingVertical: 4,
200
202
  minHeight: 0,
201
- height: 'auto',
202
203
  outlineWidth: 0,
203
204
  fontSize: 16,
204
205
  },
@@ -216,7 +217,6 @@ const styles = StyleSheet.create({
216
217
  borderLeftWidth: 1,
217
218
  borderTopRightRadius: 8,
218
219
  borderBottomRightRadius: 8,
219
- height: '100%',
220
220
  justifyContent: 'center',
221
221
  },
222
222
  })
@@ -9,7 +9,8 @@ import React, {
9
9
  useMemo,
10
10
  useState,
11
11
  } from 'react'
12
- import { Modal, StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native'
12
+ import { Modal, StyleSheet, Text, TextInput, View } from 'react-native'
13
+ import { Pressable } from 'react-native-gesture-handler'
13
14
  import { FieldProps } from '../../types'
14
15
  const siteToIcon: Record<SocialMediaSites, string> = {
15
16
  facebook: 'facebook',
@@ -42,11 +43,11 @@ const SocialMediaSiteInput: FC<{
42
43
 
43
44
  return (
44
45
  <>
45
- <TouchableOpacity
46
+ <Pressable
46
47
  style={[styles.iconButton, !handle && styles.iconButtonInactive]}
47
48
  onPress={() => onModalClose()}>
48
49
  <Text style={styles.iconText}>{siteToIcon[site]}</Text>
49
- </TouchableOpacity>
50
+ </Pressable>
50
51
 
51
52
  <Modal
52
53
  visible={isModalVisible}
@@ -65,9 +66,9 @@ const SocialMediaSiteInput: FC<{
65
66
  autoCapitalize="none"
66
67
  autoCorrect={false}
67
68
  />
68
- <TouchableOpacity style={styles.closeButton} onPress={onModalClose}>
69
+ <Pressable style={styles.closeButton} onPress={onModalClose}>
69
70
  <Text style={styles.closeButtonText}>Close</Text>
70
- </TouchableOpacity>
71
+ </Pressable>
71
72
  </View>
72
73
  </View>
73
74
  </Modal>
@@ -10,7 +10,7 @@ export const AutoResizeTextarea = forwardRef<TextInput, TextInputProps>(
10
10
  ({ style, value, onChangeText, ...props }, ref) => {
11
11
  const textColor = useTextColor()
12
12
 
13
- const { handleChange, height, setHeight } = useWebAutoResize(onChangeText, style)
13
+ const { handleChange, height } = useWebAutoResize(onChangeText, style)
14
14
 
15
15
  const iconColor = useIconColor()
16
16
 
@@ -18,9 +18,6 @@ export const AutoResizeTextarea = forwardRef<TextInput, TextInputProps>(
18
18
  <TextInput
19
19
  ref={ref}
20
20
  cursorColor={iconColor}
21
- onContentSizeChange={e => {
22
- setHeight(e.nativeEvent.contentSize.height)
23
- }}
24
21
  multiline
25
22
  style={[styles.textarea, { color: textColor, height }, style]}
26
23
  value={value}
@@ -33,7 +30,6 @@ export const AutoResizeTextarea = forwardRef<TextInput, TextInputProps>(
33
30
  const styles = StyleSheet.create({
34
31
  textarea: {
35
32
  width: '100%',
36
- minHeight: 18,
37
33
  backgroundColor: 'transparent',
38
34
  textAlignVertical: 'top',
39
35
  outlineWidth: 0,