@chem-po/react-native 0.0.15 → 0.0.17

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 (171) hide show
  1. package/lib/commonjs/components/button/DeleteButton.js +1 -1
  2. package/lib/commonjs/components/button/DeleteButton.js.map +1 -1
  3. package/lib/commonjs/components/button/LoadingButton.js +2 -1
  4. package/lib/commonjs/components/button/LoadingButton.js.map +1 -1
  5. package/lib/commonjs/components/feed/MediaFeed.js +1 -1
  6. package/lib/commonjs/components/feed/MediaFeed.js.map +1 -1
  7. package/lib/commonjs/components/form/Field.js +4 -2
  8. package/lib/commonjs/components/form/Field.js.map +1 -1
  9. package/lib/commonjs/components/form/Form.js +20 -7
  10. package/lib/commonjs/components/form/Form.js.map +1 -1
  11. package/lib/commonjs/components/form/input/Editable.js +24 -7
  12. package/lib/commonjs/components/form/input/Editable.js.map +1 -1
  13. package/lib/commonjs/components/form/input/common/InputClearButton.js +10 -5
  14. package/lib/commonjs/components/form/input/common/InputClearButton.js.map +1 -1
  15. package/lib/commonjs/components/form/input/date/index.js +23 -15
  16. package/lib/commonjs/components/form/input/date/index.js.map +1 -1
  17. package/lib/commonjs/components/form/input/datetime/index.js +22 -18
  18. package/lib/commonjs/components/form/input/datetime/index.js.map +1 -1
  19. package/lib/commonjs/components/form/input/hooks/index.js +4 -4
  20. package/lib/commonjs/components/form/input/hooks/index.js.map +1 -1
  21. package/lib/commonjs/components/form/input/hooks/useInputStyles.js +111 -0
  22. package/lib/commonjs/components/form/input/hooks/useInputStyles.js.map +1 -0
  23. package/lib/commonjs/components/form/input/input.js +46 -11
  24. package/lib/commonjs/components/form/input/input.js.map +1 -1
  25. package/lib/commonjs/components/form/input/multipleSelect/index.js +162 -44
  26. package/lib/commonjs/components/form/input/multipleSelect/index.js.map +1 -1
  27. package/lib/commonjs/components/form/input/number/index.js +10 -5
  28. package/lib/commonjs/components/form/input/number/index.js.map +1 -1
  29. package/lib/commonjs/components/form/input/select/index.js +86 -173
  30. package/lib/commonjs/components/form/input/select/index.js.map +1 -1
  31. package/lib/commonjs/components/form/input/text/index.js +7 -5
  32. package/lib/commonjs/components/form/input/text/index.js.map +1 -1
  33. package/lib/commonjs/components/form/input/text/textarea.js +10 -5
  34. package/lib/commonjs/components/form/input/text/textarea.js.map +1 -1
  35. package/lib/commonjs/components/form/input/time/index.js +22 -13
  36. package/lib/commonjs/components/form/input/time/index.js.map +1 -1
  37. package/lib/commonjs/components/form/view/file.js +18 -4
  38. package/lib/commonjs/components/form/view/file.js.map +1 -1
  39. package/lib/commonjs/components/form/view/index.js +24 -23
  40. package/lib/commonjs/components/form/view/index.js.map +1 -1
  41. package/lib/commonjs/components/form/view/multipleSelect.js +38 -10
  42. package/lib/commonjs/components/form/view/multipleSelect.js.map +1 -1
  43. package/lib/commonjs/components/form/view/select.js +24 -9
  44. package/lib/commonjs/components/form/view/select.js.map +1 -1
  45. package/lib/commonjs/components/form/view/styles.js +21 -0
  46. package/lib/commonjs/components/form/view/styles.js.map +1 -0
  47. package/lib/commonjs/contexts/root.js +0 -6
  48. package/lib/commonjs/contexts/root.js.map +1 -1
  49. package/lib/module/components/button/DeleteButton.js +1 -1
  50. package/lib/module/components/button/DeleteButton.js.map +1 -1
  51. package/lib/module/components/button/LoadingButton.js +2 -1
  52. package/lib/module/components/button/LoadingButton.js.map +1 -1
  53. package/lib/module/components/feed/MediaFeed.js +1 -1
  54. package/lib/module/components/feed/MediaFeed.js.map +1 -1
  55. package/lib/module/components/form/Field.js +4 -2
  56. package/lib/module/components/form/Field.js.map +1 -1
  57. package/lib/module/components/form/Form.js +20 -7
  58. package/lib/module/components/form/Form.js.map +1 -1
  59. package/lib/module/components/form/input/Editable.js +24 -7
  60. package/lib/module/components/form/input/Editable.js.map +1 -1
  61. package/lib/module/components/form/input/common/InputClearButton.js +11 -6
  62. package/lib/module/components/form/input/common/InputClearButton.js.map +1 -1
  63. package/lib/module/components/form/input/date/index.js +23 -15
  64. package/lib/module/components/form/input/date/index.js.map +1 -1
  65. package/lib/module/components/form/input/datetime/index.js +22 -18
  66. package/lib/module/components/form/input/datetime/index.js.map +1 -1
  67. package/lib/module/components/form/input/hooks/index.js +1 -1
  68. package/lib/module/components/form/input/hooks/index.js.map +1 -1
  69. package/lib/module/components/form/input/hooks/useInputStyles.js +104 -0
  70. package/lib/module/components/form/input/hooks/useInputStyles.js.map +1 -0
  71. package/lib/module/components/form/input/input.js +48 -13
  72. package/lib/module/components/form/input/input.js.map +1 -1
  73. package/lib/module/components/form/input/multipleSelect/index.js +163 -46
  74. package/lib/module/components/form/input/multipleSelect/index.js.map +1 -1
  75. package/lib/module/components/form/input/number/index.js +10 -5
  76. package/lib/module/components/form/input/number/index.js.map +1 -1
  77. package/lib/module/components/form/input/select/index.js +88 -175
  78. package/lib/module/components/form/input/select/index.js.map +1 -1
  79. package/lib/module/components/form/input/text/index.js +7 -5
  80. package/lib/module/components/form/input/text/index.js.map +1 -1
  81. package/lib/module/components/form/input/text/textarea.js +11 -6
  82. package/lib/module/components/form/input/text/textarea.js.map +1 -1
  83. package/lib/module/components/form/input/time/index.js +22 -13
  84. package/lib/module/components/form/input/time/index.js.map +1 -1
  85. package/lib/module/components/form/view/file.js +18 -4
  86. package/lib/module/components/form/view/file.js.map +1 -1
  87. package/lib/module/components/form/view/index.js +25 -24
  88. package/lib/module/components/form/view/index.js.map +1 -1
  89. package/lib/module/components/form/view/multipleSelect.js +38 -10
  90. package/lib/module/components/form/view/multipleSelect.js.map +1 -1
  91. package/lib/module/components/form/view/select.js +23 -9
  92. package/lib/module/components/form/view/select.js.map +1 -1
  93. package/lib/module/components/form/view/styles.js +15 -0
  94. package/lib/module/components/form/view/styles.js.map +1 -0
  95. package/lib/module/contexts/root.js +0 -6
  96. package/lib/module/contexts/root.js.map +1 -1
  97. package/lib/typescript/components/button/LoadingButton.d.ts +1 -0
  98. package/lib/typescript/components/button/LoadingButton.d.ts.map +1 -1
  99. package/lib/typescript/components/form/Field.d.ts +2 -1
  100. package/lib/typescript/components/form/Field.d.ts.map +1 -1
  101. package/lib/typescript/components/form/Form.d.ts +7 -4
  102. package/lib/typescript/components/form/Form.d.ts.map +1 -1
  103. package/lib/typescript/components/form/input/Editable.d.ts +1 -1
  104. package/lib/typescript/components/form/input/Editable.d.ts.map +1 -1
  105. package/lib/typescript/components/form/input/common/InputClearButton.d.ts +4 -2
  106. package/lib/typescript/components/form/input/common/InputClearButton.d.ts.map +1 -1
  107. package/lib/typescript/components/form/input/date/index.d.ts.map +1 -1
  108. package/lib/typescript/components/form/input/datetime/index.d.ts.map +1 -1
  109. package/lib/typescript/components/form/input/hooks/index.d.ts +1 -1
  110. package/lib/typescript/components/form/input/hooks/index.d.ts.map +1 -1
  111. package/lib/typescript/components/form/input/hooks/useInputStyles.d.ts +61 -0
  112. package/lib/typescript/components/form/input/hooks/useInputStyles.d.ts.map +1 -0
  113. package/lib/typescript/components/form/input/input.d.ts.map +1 -1
  114. package/lib/typescript/components/form/input/multipleSelect/index.d.ts +6 -1
  115. package/lib/typescript/components/form/input/multipleSelect/index.d.ts.map +1 -1
  116. package/lib/typescript/components/form/input/number/index.d.ts.map +1 -1
  117. package/lib/typescript/components/form/input/select/index.d.ts.map +1 -1
  118. package/lib/typescript/components/form/input/text/index.d.ts.map +1 -1
  119. package/lib/typescript/components/form/input/text/textarea.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/file.d.ts +3 -1
  122. package/lib/typescript/components/form/view/file.d.ts.map +1 -1
  123. package/lib/typescript/components/form/view/index.d.ts +3 -1
  124. package/lib/typescript/components/form/view/index.d.ts.map +1 -1
  125. package/lib/typescript/components/form/view/multipleSelect.d.ts +5 -3
  126. package/lib/typescript/components/form/view/multipleSelect.d.ts.map +1 -1
  127. package/lib/typescript/components/form/view/select.d.ts +4 -1
  128. package/lib/typescript/components/form/view/select.d.ts.map +1 -1
  129. package/lib/typescript/components/form/view/styles.d.ts +14 -0
  130. package/lib/typescript/components/form/view/styles.d.ts.map +1 -0
  131. package/lib/typescript/contexts/root.d.ts +2 -2
  132. package/lib/typescript/contexts/root.d.ts.map +1 -1
  133. package/package.json +16 -27
  134. package/src/components/button/DeleteButton.tsx +1 -1
  135. package/src/components/button/LoadingButton.tsx +4 -1
  136. package/src/components/feed/MediaFeed.tsx +1 -1
  137. package/src/components/form/Field.tsx +3 -2
  138. package/src/components/form/Form.tsx +41 -11
  139. package/src/components/form/input/Editable.tsx +23 -6
  140. package/src/components/form/input/common/InputClearButton.tsx +12 -4
  141. package/src/components/form/input/date/index.tsx +23 -12
  142. package/src/components/form/input/datetime/index.tsx +27 -14
  143. package/src/components/form/input/hooks/index.ts +1 -1
  144. package/src/components/form/input/hooks/useInputStyles.ts +124 -0
  145. package/src/components/form/input/input.tsx +54 -25
  146. package/src/components/form/input/multipleSelect/index.tsx +189 -60
  147. package/src/components/form/input/number/index.tsx +5 -4
  148. package/src/components/form/input/select/index.tsx +90 -166
  149. package/src/components/form/input/text/index.tsx +4 -9
  150. package/src/components/form/input/text/textarea.tsx +18 -16
  151. package/src/components/form/input/time/index.tsx +31 -11
  152. package/src/components/form/view/file.tsx +19 -4
  153. package/src/components/form/view/index.tsx +36 -22
  154. package/src/components/form/view/multipleSelect.tsx +42 -15
  155. package/src/components/form/view/select.tsx +28 -11
  156. package/src/components/form/view/styles.ts +15 -0
  157. package/src/contexts/root.tsx +6 -13
  158. package/lib/commonjs/components/form/input/hooks/useInputStyle.js +0 -50
  159. package/lib/commonjs/components/form/input/hooks/useInputStyle.js.map +0 -1
  160. package/lib/commonjs/components/form/input/styles.js +0 -17
  161. package/lib/commonjs/components/form/input/styles.js.map +0 -1
  162. package/lib/module/components/form/input/hooks/useInputStyle.js +0 -43
  163. package/lib/module/components/form/input/hooks/useInputStyle.js.map +0 -1
  164. package/lib/module/components/form/input/styles.js +0 -11
  165. package/lib/module/components/form/input/styles.js.map +0 -1
  166. package/lib/typescript/components/form/input/hooks/useInputStyle.d.ts +0 -9
  167. package/lib/typescript/components/form/input/hooks/useInputStyle.d.ts.map +0 -1
  168. package/lib/typescript/components/form/input/styles.d.ts +0 -10
  169. package/lib/typescript/components/form/input/styles.d.ts.map +0 -1
  170. package/src/components/form/input/hooks/useInputStyle.ts +0 -40
  171. package/src/components/form/input/styles.ts +0 -11
@@ -8,7 +8,7 @@ import { DatePickerModal } from 'react-native-paper-dates'
8
8
  import { FieldProps } from '../../types'
9
9
  import { DateInputClearButton } from '../common/InputClearButton'
10
10
  import { useInputColor } from '../hooks/useInputColor'
11
- import { inputStyles } from '../styles'
11
+ import { useInputStyles } from '../hooks/useInputStyles'
12
12
 
13
13
  // const parseDate = (date?: Date) =>
14
14
  // date
@@ -21,12 +21,21 @@ export const DateInput = forwardRef<InputRef, FieldProps<DateField>>(
21
21
  (
22
22
  {
23
23
  input: { onChange, value, onFocus, onBlur },
24
- field: { placeholder, minDate, maxDate, optional },
24
+ field: { placeholder, minDate, maxDate, optional, size },
25
25
  meta: { active },
26
+ formSize,
27
+ inEditable,
26
28
  },
27
29
  ref,
28
30
  ) => {
29
31
  const date = useMemo(() => (value ? new Date(`${value}T00:00:00.000`) : undefined), [value])
32
+ const {
33
+ container: inputStyles,
34
+ iconSize,
35
+ text,
36
+ clearButtonSize,
37
+ buttonContainer,
38
+ } = useInputStyles(inEditable, size, formSize)
30
39
 
31
40
  useImperativeHandle(ref, () => ({
32
41
  focus: () => {
@@ -49,14 +58,20 @@ export const DateInput = forwardRef<InputRef, FieldProps<DateField>>(
49
58
 
50
59
  return (
51
60
  <View style={styles.container}>
52
- <TouchableOpacity style={[styles.button, inputStyles.input]} onPress={showDialog}>
53
- <Text style={[styles.text, { color: inputColor }]}>
61
+ <TouchableOpacity style={[styles.button, inputStyles]} onPress={showDialog}>
62
+ <Text style={[styles.text, text, { color: inputColor }]}>
54
63
  {value ? getDateString(value, 'short') : placeholder}
55
64
  </Text>
56
- <Ionicons name="calendar" size={20} color={iconColor} style={styles.icon} />
57
- {optional && value ? (
58
- <DateInputClearButton onPress={() => onChange(null)} isActive />
59
- ) : null}
65
+ <View style={buttonContainer}>
66
+ <Ionicons name="calendar" size={iconSize} color={iconColor} />
67
+ {optional && value ? (
68
+ <DateInputClearButton
69
+ size={clearButtonSize}
70
+ onPress={() => onChange(null)}
71
+ isActive={!!value}
72
+ />
73
+ ) : null}
74
+ </View>
60
75
  </TouchableOpacity>
61
76
  <Portal>
62
77
  <DatePickerModal
@@ -92,10 +107,6 @@ const styles = StyleSheet.create({
92
107
  width: '100%',
93
108
  },
94
109
  text: {
95
- fontSize: 16,
96
110
  flex: 1,
97
111
  },
98
- icon: {
99
- marginRight: 10,
100
- },
101
112
  })
@@ -8,14 +8,23 @@ import { DatePickerModal, TimePickerModal } from 'react-native-paper-dates'
8
8
  import { FieldProps } from '../../types'
9
9
  import { DateInputClearButton } from '../common/InputClearButton'
10
10
  import { useInputColor } from '../hooks/useInputColor'
11
- import { inputStyles } from '../styles'
11
+ import { useInputStyles } from '../hooks/useInputStyles'
12
12
 
13
13
  export const DateTimeInput = forwardRef<InputRef, FieldProps<DateTimeField>>(
14
- ({ input: { value, onBlur, onChange, onFocus }, field, meta: { active } }, ref) => {
14
+ (
15
+ { input: { value, onBlur, onChange, onFocus }, field, meta: { active }, formSize, inEditable },
16
+ ref,
17
+ ) => {
15
18
  const { placeholder, optional } = field
16
19
  const [showDatePicker, setShowDatePicker] = useState(true)
17
20
  const [showTimePicker, setShowTimePicker] = useState(false)
18
- // const [selectedDate] = useState<Date>(value ? new Date(value) : new Date())
21
+ const {
22
+ container: inputStyles,
23
+ iconSize,
24
+ text,
25
+ clearButtonSize,
26
+ buttonContainer,
27
+ } = useInputStyles(inEditable, field.size, formSize)
19
28
 
20
29
  const selectedDate = useMemo(() => (value ? new Date(value) : new Date()), [value])
21
30
  useImperativeHandle(ref, () => ({
@@ -77,17 +86,25 @@ export const DateTimeInput = forwardRef<InputRef, FieldProps<DateTimeField>>(
77
86
  return (
78
87
  <View style={styles.container}>
79
88
  <TouchableOpacity
80
- style={[styles.button, inputStyles.input]}
89
+ style={[styles.button, inputStyles]}
81
90
  onPress={() => {
82
91
  setShowDatePicker(true)
83
92
  onFocus()
84
93
  }}>
85
- <Text style={[styles.text, { color: inputColor }]}>{formattedValue ?? placeholder}</Text>
86
- <Ionicons name="calendar" size={20} color={iconColor} style={styles.icon} />
87
- <Ionicons name="time" size={20} color={iconColor} style={styles.icon} />
88
- {optional && value ? (
89
- <DateInputClearButton onPress={() => onChange(null)} isActive={!!value} />
90
- ) : null}
94
+ <Text style={[styles.text, text, { color: inputColor }]}>
95
+ {formattedValue ?? placeholder}
96
+ </Text>
97
+ <View style={buttonContainer}>
98
+ <Ionicons name="calendar" size={iconSize} color={iconColor} />
99
+ <Ionicons name="time" size={iconSize} color={iconColor} />
100
+ {optional && value ? (
101
+ <DateInputClearButton
102
+ size={clearButtonSize}
103
+ onPress={() => onChange(null)}
104
+ isActive={!!value}
105
+ />
106
+ ) : null}
107
+ </View>
91
108
  </TouchableOpacity>
92
109
  <Portal>
93
110
  {showDatePicker && (
@@ -132,10 +149,6 @@ const styles = StyleSheet.create({
132
149
  width: '100%',
133
150
  },
134
151
  text: {
135
- fontSize: 16,
136
152
  flex: 1,
137
153
  },
138
- icon: {
139
- marginRight: 10,
140
- },
141
154
  })
@@ -1,2 +1,2 @@
1
1
  export * from './useInputImperativeHandle'
2
- export * from './useInputStyle'
2
+ export * from './useInputStyles'
@@ -0,0 +1,124 @@
1
+ import { InputSize } from '@chem-po/core'
2
+ import { useBackgroundColor, useTextColor } from '@chem-po/react'
3
+ import { useMemo } from 'react'
4
+ import { StyleProp, StyleSheet, TextStyle, ViewStyle } from 'react-native'
5
+
6
+ export const inputStyles = StyleSheet.create({
7
+ input: {
8
+ width: '100%',
9
+ fontSize: 16,
10
+ outlineWidth: 0,
11
+ },
12
+ inputXSmall: {
13
+ paddingVertical: 4,
14
+ paddingHorizontal: 6,
15
+ borderRadius: 3,
16
+ },
17
+ inputSmall: {
18
+ paddingVertical: 6,
19
+ paddingHorizontal: 9,
20
+ borderRadius: 4,
21
+ },
22
+ inputMedium: {
23
+ paddingVertical: 8,
24
+ paddingHorizontal: 12,
25
+ borderRadius: 6,
26
+ },
27
+ inputLarge: {
28
+ paddingVertical: 10,
29
+ paddingHorizontal: 14,
30
+ borderRadius: 8,
31
+ },
32
+ inputTextSmall: {
33
+ fontSize: 14,
34
+ },
35
+ inputTextMedium: {
36
+ fontSize: 16,
37
+ },
38
+ inputTextLarge: {
39
+ fontSize: 18,
40
+ },
41
+ buttonContainer: {
42
+ flexDirection: 'row',
43
+ alignItems: 'center',
44
+ },
45
+ buttonContainerSmall: {
46
+ gap: 6,
47
+ },
48
+ buttonContainerMedium: {
49
+ gap: 8,
50
+ },
51
+ buttonContainerLarge: {
52
+ gap: 10,
53
+ },
54
+ })
55
+
56
+ const iconSizeMap = {
57
+ sm: 16,
58
+ md: 20,
59
+ lg: 24,
60
+ }
61
+
62
+ const clearButtonSizeMap = {
63
+ sm: 12,
64
+ md: 14,
65
+ lg: 16,
66
+ }
67
+
68
+ const inputSizeMap = {
69
+ sm: inputStyles.inputSmall,
70
+ md: inputStyles.inputMedium,
71
+ lg: inputStyles.inputLarge,
72
+ }
73
+
74
+ const editableInputSizeMap = {
75
+ sm: inputStyles.inputXSmall,
76
+ md: inputStyles.inputSmall,
77
+ lg: inputStyles.inputMedium,
78
+ }
79
+
80
+ const inputTextSizeMap = {
81
+ sm: inputStyles.inputTextSmall,
82
+ md: inputStyles.inputTextMedium,
83
+ lg: inputStyles.inputTextLarge,
84
+ }
85
+
86
+ const buttonContainerSizeMap = {
87
+ sm: inputStyles.buttonContainerSmall,
88
+ md: inputStyles.buttonContainerMedium,
89
+ lg: inputStyles.buttonContainerLarge,
90
+ }
91
+
92
+ export interface UseInputStyles {
93
+ text: TextStyle
94
+ container: ViewStyle
95
+ size: InputSize
96
+ iconSize: number
97
+ clearButtonSize: number
98
+ buttonContainer: StyleProp<ViewStyle>
99
+ }
100
+ export const useInputStyles = (
101
+ inEditable: boolean | undefined,
102
+ size: InputSize | undefined,
103
+ formSize: InputSize = 'md',
104
+ ): UseInputStyles => {
105
+ const formElementBg = useBackgroundColor(150)
106
+ const bg = useMemo(
107
+ () => (inEditable ? 'transparent' : formElementBg),
108
+ [inEditable, formElementBg],
109
+ )
110
+ const textColor = useTextColor()
111
+ const usedSize = size ?? formSize
112
+ return {
113
+ text: { ...inputTextSizeMap[usedSize], color: textColor },
114
+ container: {
115
+ ...inputStyles.input,
116
+ ...(inEditable ? editableInputSizeMap[usedSize] : inputSizeMap[usedSize]),
117
+ backgroundColor: bg,
118
+ },
119
+ size: usedSize,
120
+ iconSize: iconSizeMap[usedSize],
121
+ clearButtonSize: clearButtonSizeMap[usedSize],
122
+ buttonContainer: [inputStyles.buttonContainer, buttonContainerSizeMap[usedSize]],
123
+ }
124
+ }
@@ -1,15 +1,10 @@
1
- import { FieldType, InputRef } from '@chem-po/core'
2
- import {
3
- Field,
4
- TypedField,
5
- useBackgroundColor,
6
- usePlaceholderColor,
7
- useThemeValue,
8
- } from '@chem-po/react'
1
+ import { FieldType, formatField, InputRef, parseField } from '@chem-po/core'
2
+ import { Field, FormatField, TypedField, usePlaceholderColor, useThemeValue } from '@chem-po/react'
9
3
  import React, {
10
4
  ForwardedRef,
11
5
  forwardRef,
12
6
  ForwardRefExoticComponent,
7
+ useCallback,
13
8
  useEffect,
14
9
  useMemo,
15
10
  } from 'react'
@@ -21,6 +16,7 @@ import { ColorComponent } from './color'
21
16
  import { DateInput } from './date'
22
17
  import { DateTimeInput } from './datetime'
23
18
  import { FileComponent } from './file'
19
+ import { useInputStyles } from './hooks/useInputStyles'
24
20
  import { MultipleSelectComponent } from './multipleSelect'
25
21
  import { CurrencyAmountComponent, NumberComponent } from './number'
26
22
  import { SelectComponent } from './select'
@@ -52,6 +48,7 @@ const InputBase = <T extends Field>(props: FieldProps<T>, ref: ForwardedRef<Inpu
52
48
  meta: { error, active, touched },
53
49
  input,
54
50
  inEditable,
51
+ formSize,
55
52
  style,
56
53
  } = props
57
54
 
@@ -60,7 +57,6 @@ const InputBase = <T extends Field>(props: FieldProps<T>, ref: ForwardedRef<Inpu
60
57
  const placeholderColor = usePlaceholderColor()
61
58
  const activeColor = useThemeValue('colors.accent.400')
62
59
  const errorColor = useThemeValue('colors.error.400')
63
-
64
60
  const shadowColorAnim = useMemo(() => new Animated.Value(0), [])
65
61
 
66
62
  const displayedError = useMemo(() => {
@@ -91,7 +87,7 @@ const InputBase = <T extends Field>(props: FieldProps<T>, ref: ForwardedRef<Inpu
91
87
  [value, _type],
92
88
  )
93
89
 
94
- const bg = useBackgroundColor(150)
90
+ // const bg = useBackgroundColor(150)
95
91
 
96
92
  const animatedStyles = useMemo(() => {
97
93
  if (inEditable) return {}
@@ -109,15 +105,43 @@ const InputBase = <T extends Field>(props: FieldProps<T>, ref: ForwardedRef<Inpu
109
105
  shadowOpacity: 1,
110
106
  shadowRadius: 4,
111
107
  elevation: 5,
112
- backgroundColor: bg,
108
+ // backgroundColor: bg,
113
109
  } as Animated.WithAnimatedValue<ViewStyle>
114
110
  default:
115
111
  return {}
116
112
  }
117
- }, [_type, animatedShadowColor, inEditable, bg])
113
+ }, [_type, animatedShadowColor, inEditable])
118
114
 
119
115
  const Component = useMemo(() => Components[_type] as ComponentType<T>, [_type])
120
116
 
117
+ const parse = useCallback(
118
+ (raw: any) => {
119
+ const defaultParse = parseField[field._type]
120
+ if (!defaultParse) return raw
121
+ return defaultParse(field, raw)
122
+ },
123
+ [field],
124
+ )
125
+
126
+ const { text } = useInputStyles(inEditable, field.size, formSize)
127
+
128
+ const format = useCallback(
129
+ (raw: any) => {
130
+ const defaultFormat = formatField[field._type] as FormatField<T>
131
+ if (!defaultFormat) return raw
132
+ return defaultFormat(field, raw)
133
+ },
134
+ [field],
135
+ )
136
+
137
+ const formattedValue = useMemo(() => format(value), [value, format])
138
+ const onChange = useCallback(
139
+ (v: any) => {
140
+ input.onChange(parse(v))
141
+ },
142
+ [input, parse],
143
+ )
144
+
121
145
  return (
122
146
  <View style={[staticStyles.container, style]}>
123
147
  {Label && !inEditable ? (
@@ -138,18 +162,18 @@ const InputBase = <T extends Field>(props: FieldProps<T>, ref: ForwardedRef<Inpu
138
162
  </AnimatedText>
139
163
  )}
140
164
  <Animated.View style={[staticStyles.inputContainer, animatedStyles]}>
141
- <Component ref={ref} {...props} />
165
+ <Component ref={ref} {...props} input={{ ...input, onChange, value: formattedValue }} />
142
166
  </Animated.View>
143
- {!inEditable && (
144
- <AnimatedText
145
- style={staticStyles.errorText}
146
- show={!!displayedError}
147
- color={errorColor}
148
- height={18}
149
- marginBottom={0}>
150
- {displayedError}
151
- </AnimatedText>
152
- )}
167
+ {/* {!inEditable && ( */}
168
+ <AnimatedText
169
+ style={[staticStyles.errorText, { fontSize: text.fontSize ?? 14 }]}
170
+ show={!!displayedError}
171
+ color={errorColor}
172
+ height={(text.fontSize ?? 14) + 5}
173
+ marginBottom={inEditable ? 10 : 0}>
174
+ {displayedError}
175
+ </AnimatedText>
176
+ {/* )} */}
153
177
  {/* {optional && !inEditable ? <OptionalTag field={field} value={value} /> : null} */}
154
178
  </View>
155
179
  )
@@ -159,7 +183,6 @@ const staticStyles = StyleSheet.create({
159
183
  container: {
160
184
  position: 'relative',
161
185
  width: '100%',
162
- paddingHorizontal: 4,
163
186
  // backgroundColor: 'blue',
164
187
  },
165
188
  label: {
@@ -174,8 +197,14 @@ const staticStyles = StyleSheet.create({
174
197
  overflow: 'hidden',
175
198
  },
176
199
  errorText: {
200
+ paddingHorizontal: 8,
201
+ fontWeight: 500,
202
+ // backgroundColor: 'red',
203
+ },
204
+ errorTextEditable: {
177
205
  fontSize: 14,
178
- paddingHorizontal: 4,
206
+ paddingHorizontal: 6,
207
+ paddingBottom: 8,
179
208
  fontWeight: 500,
180
209
  // backgroundColor: 'red',
181
210
  },
@@ -1,79 +1,208 @@
1
- import { InputRef } from '@chem-po/core'
2
- import { MultipleSelectField, useColorMode, usePlaceholderColor } from '@chem-po/react'
3
- import React, { forwardRef, useImperativeHandle } from 'react'
4
- import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'
1
+ import { InputRef, RenderSelectOptionProps } from '@chem-po/core'
2
+ import {
3
+ MultipleSelectField,
4
+ useBackgroundColor,
5
+ useBorderColor,
6
+ useColorMode,
7
+ useColorModeValue,
8
+ useIconColor,
9
+ usePlaceholderColor,
10
+ useTextColor,
11
+ } from '@chem-po/react'
12
+ import { Ionicons } from '@expo/vector-icons'
13
+ import React, {
14
+ ForwardedRef,
15
+ forwardRef,
16
+ PropsWithChildren,
17
+ useImperativeHandle,
18
+ useMemo,
19
+ useRef,
20
+ } from 'react'
21
+ import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native'
22
+ import { IDropdownRef, MultiSelect } from 'react-native-element-dropdown'
23
+ import { Txt } from '../../../text/Txt'
5
24
  import { FieldProps } from '../../types'
25
+ import { InputClearButton } from '../common/InputClearButton'
26
+ import { useInputStyles } from '../hooks/useInputStyles'
6
27
 
7
- export const MultipleSelectComponent = forwardRef<InputRef, FieldProps<MultipleSelectField>>(
8
- ({ field, input, inEditable }, ref) => {
9
- const { options, renderOption: RenderOption, getOptionKey } = field
10
- const { onChange, value, onFocus, onBlur } = input
11
- const colorMode = useColorMode()
28
+ export const SelectedOptionContainer = ({
29
+ children,
30
+ style,
31
+ }: PropsWithChildren<{ key?: string; style?: StyleProp<ViewStyle> }>) => {
32
+ const borderColor = useBorderColor()
33
+ return <View style={[styles.selectedOption, { borderColor }, style]}>{children}</View>
34
+ }
12
35
 
13
- const placeholderColor = usePlaceholderColor()
36
+ const BaseMultipleSelectComponent = <T extends MultipleSelectField>(
37
+ { field, input, meta, formSize, inEditable }: FieldProps<T>,
38
+ ref: ForwardedRef<InputRef>,
39
+ ) => {
40
+ const { placeholder, options, renderOption: RenderOption, searchable, searchPlaceholder } = field
41
+ const { onChange, value, onFocus, onBlur } = input
42
+ const { active } = meta
14
43
 
15
- useImperativeHandle(ref, () => ({
16
- focus: () => {
17
- onFocus()
18
- },
19
- blur: () => {
20
- onBlur()
21
- },
22
- }))
44
+ const colorMode = useColorMode()
45
+ const inputRef = useRef<IDropdownRef>(null)
46
+ const {
47
+ container: inputStyles,
48
+ iconSize,
49
+ clearButtonSize,
50
+ text,
51
+ buttonContainer,
52
+ size,
53
+ } = useInputStyles(inEditable, field.size, formSize)
54
+ const iconColor = useIconColor()
55
+ const textColor = useTextColor()
56
+ const placeholderColor = usePlaceholderColor()
57
+ const menuBg = useBackgroundColor(100)
58
+ const selectedOptionBg = useColorModeValue('#ffffff77', '#ffffff15')
59
+ const borderColor = useBorderColor()
23
60
 
24
- const handleOptionPress = (option: any) => {
25
- onChange(
26
- value?.includes(option) ? value.filter(v => v !== option) : [...(value ?? []), option],
27
- )
61
+ useImperativeHandle(ref, () => ({
62
+ focus: () => {
63
+ inputRef.current?.open()
64
+ },
65
+ blur: () => {
66
+ inputRef.current?.close()
67
+ },
68
+ }))
69
+
70
+ const defaultSelectedOptionStyle = useMemo(() => {
71
+ return {
72
+ paddingVertical: inputStyles.paddingVertical,
73
+ paddingHorizontal: inputStyles.paddingHorizontal,
28
74
  }
75
+ }, [inputStyles])
29
76
 
30
- const body = (
31
- <View style={styles.container}>
32
- {options.map(o => (
33
- <TouchableOpacity
34
- key={getOptionKey ? getOptionKey(o) : o}
35
- style={[styles.option, value?.includes(o) && styles.selectedOption]}
36
- onPress={() => handleOptionPress(o)}>
37
- <RenderOption value={o} colorMode={colorMode} isSelected={!!value?.includes(o)} />
38
- </TouchableOpacity>
39
- ))}
40
- </View>
41
- )
77
+ const RenderOptionText = (
78
+ props: RenderSelectOptionProps<T['options'][number]['value'], T['options'][number]>,
79
+ ) => {
80
+ if (typeof RenderOption === 'function') {
81
+ return RenderOption(props)
82
+ }
83
+ return <Txt style={[styles.defaultOption, text]}>{props.option.label}</Txt>
84
+ }
42
85
 
43
- return inEditable ? (
44
- <View style={styles.editableContainer}>
45
- <Text style={[styles.placeholder, { color: placeholderColor }]}>{field.placeholder}</Text>
46
- {body}
47
- </View>
48
- ) : (
49
- body
86
+ const RenderSelectedOptionText = (
87
+ props: RenderSelectOptionProps<T['options'][number]['value'], T['options'][number]>,
88
+ ) => {
89
+ if (typeof RenderOption === 'function') {
90
+ return RenderOption(props)
91
+ }
92
+ return (
93
+ <>
94
+ <Txt style={[defaultSelectedOptionStyle, text]}>{props.option.label}</Txt>
95
+ </>
50
96
  )
51
- },
52
- )
97
+ }
98
+
99
+ return (
100
+ <View style={[styles.wrapper]}>
101
+ <MultiSelect
102
+ ref={inputRef}
103
+ style={[inputStyles, { borderColor }]}
104
+ placeholderStyle={[text, { color: value?.length ? textColor : placeholderColor }]}
105
+ containerStyle={{ backgroundColor: menuBg }}
106
+ inputSearchStyle={[styles.inputSearch, text]}
107
+ iconStyle={styles.iconStyle}
108
+ data={options}
109
+ search={searchable}
110
+ searchField={searchable ? 'label' : undefined}
111
+ maxHeight={300}
112
+ labelField="label"
113
+ valueField="value"
114
+ placeholder={placeholder}
115
+ searchPlaceholder={searchPlaceholder ?? placeholder}
116
+ value={value ?? []}
117
+ onChange={updated => {
118
+ onChange(updated)
119
+ }}
120
+ activeColor={selectedOptionBg}
121
+ onFocus={onFocus}
122
+ onBlur={onBlur}
123
+ renderItem={(item, selected) => (
124
+ <View style={{ backgroundColor: selected ? selectedOptionBg : menuBg }}>
125
+ <RenderOptionText
126
+ value={item.value}
127
+ option={item}
128
+ colorMode={colorMode}
129
+ isSelected={!!selected}
130
+ size={size}
131
+ />
132
+ </View>
133
+ )}
134
+ renderSelectedItem={item => (
135
+ <SelectedOptionContainer>
136
+ <RenderSelectedOptionText
137
+ value={item.value}
138
+ option={item}
139
+ colorMode={colorMode}
140
+ isSelected
141
+ size={size}
142
+ />
143
+ <View
144
+ style={[
145
+ styles.optionClearContainer,
146
+ { borderColor, backgroundColor: selectedOptionBg },
147
+ ]}>
148
+ <InputClearButton
149
+ size={clearButtonSize}
150
+ onPress={() => {
151
+ onChange(value?.filter(v => v !== item.value))
152
+ }}
153
+ isActive
154
+ />
155
+ </View>
156
+ </SelectedOptionContainer>
157
+ )}
158
+ renderRightIcon={() => (
159
+ <View style={buttonContainer}>
160
+ <Ionicons
161
+ name={active ? 'chevron-up' : 'chevron-down'}
162
+ size={iconSize}
163
+ color={iconColor}
164
+ />
165
+ </View>
166
+ )}
167
+ />
168
+ </View>
169
+ )
170
+ }
171
+
172
+ export const MultipleSelectComponent = forwardRef(BaseMultipleSelectComponent)
53
173
 
54
174
  const styles = StyleSheet.create({
55
- container: {
175
+ wrapper: {
56
176
  width: '100%',
57
- flexDirection: 'row',
58
- flexWrap: 'wrap',
59
- gap: 4,
60
177
  },
61
- editableContainer: {
62
- width: '100%',
63
- paddingVertical: 2,
178
+ defaultOption: {
179
+ padding: 10,
64
180
  },
65
- placeholder: {
66
- fontSize: 14,
67
- fontWeight: '600',
68
- opacity: 0.8,
69
- paddingHorizontal: 8,
70
- marginBottom: 4,
181
+ iconStyle: {
182
+ width: 20,
183
+ height: 20,
71
184
  },
72
- option: {
73
- padding: 4,
74
- opacity: 0.7,
185
+ inputSearch: {
186
+ outlineWidth: 0,
187
+ paddingVertical: 4,
188
+ minHeight: 0,
189
+ height: 'auto',
190
+ fontSize: 16,
75
191
  },
76
192
  selectedOption: {
77
- opacity: 1,
193
+ flexDirection: 'row',
194
+ borderRadius: 4,
195
+ borderWidth: 1,
196
+ alignItems: 'center',
197
+ marginTop: 4,
198
+ marginHorizontal: 4,
199
+ },
200
+ optionClearContainer: {
201
+ paddingHorizontal: 8,
202
+ borderLeftWidth: 1,
203
+ borderTopRightRadius: 8,
204
+ borderBottomRightRadius: 8,
205
+ height: '100%',
206
+ justifyContent: 'center',
78
207
  },
79
208
  })