@chem-po/react-native 0.0.28 → 0.0.30
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.
- package/lib/commonjs/components/button/Toggle.js +19 -16
- package/lib/commonjs/components/button/Toggle.js.map +1 -1
- package/lib/commonjs/components/form/input/Editable.js +62 -93
- package/lib/commonjs/components/form/input/Editable.js.map +1 -1
- package/lib/commonjs/components/form/input/StandaloneInput.js +5 -1
- package/lib/commonjs/components/form/input/StandaloneInput.js.map +1 -1
- package/lib/commonjs/components/form/input/datetime/index.js +7 -2
- package/lib/commonjs/components/form/input/datetime/index.js.map +1 -1
- package/lib/commonjs/components/form/input/hooks/useInputStyles.js +2 -1
- package/lib/commonjs/components/form/input/hooks/useInputStyles.js.map +1 -1
- package/lib/commonjs/components/form/input/multipleSelect/index.js +25 -11
- package/lib/commonjs/components/form/input/multipleSelect/index.js.map +1 -1
- package/lib/commonjs/components/form/input/number/index.js +8 -4
- package/lib/commonjs/components/form/input/number/index.js.map +1 -1
- package/lib/commonjs/components/form/input/select/index.js +13 -3
- package/lib/commonjs/components/form/input/select/index.js.map +1 -1
- package/lib/commonjs/components/form/input/text/AutoResizeTextarea.js +54 -0
- package/lib/commonjs/components/form/input/text/AutoResizeTextarea.js.map +1 -0
- package/lib/commonjs/components/form/input/text/index.js +24 -12
- package/lib/commonjs/components/form/input/text/index.js.map +1 -1
- package/lib/commonjs/components/form/input/text/textarea.js +13 -33
- package/lib/commonjs/components/form/input/text/textarea.js.map +1 -1
- package/lib/commonjs/components/form/input/text/useWebAutoResize.js +64 -0
- package/lib/commonjs/components/form/input/text/useWebAutoResize.js.map +1 -0
- package/lib/commonjs/components/form/view/file.js +21 -12
- package/lib/commonjs/components/form/view/file.js.map +1 -1
- package/lib/commonjs/components/form/view/index.js +29 -18
- package/lib/commonjs/components/form/view/index.js.map +1 -1
- package/lib/commonjs/components/form/view/multipleSelect.js +17 -13
- package/lib/commonjs/components/form/view/multipleSelect.js.map +1 -1
- package/lib/commonjs/components/form/view/select.js +14 -7
- package/lib/commonjs/components/form/view/select.js.map +1 -1
- package/lib/commonjs/components/form/view/styles.js +0 -3
- package/lib/commonjs/components/form/view/styles.js.map +1 -1
- package/lib/commonjs/components/layout/CollapseHorizontal.js +72 -0
- package/lib/commonjs/components/layout/CollapseHorizontal.js.map +1 -0
- package/lib/commonjs/contexts/root.js +94 -1
- package/lib/commonjs/contexts/root.js.map +1 -1
- package/lib/commonjs/index.js +11 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/types/forms.js +6 -0
- package/lib/commonjs/types/forms.js.map +1 -0
- package/lib/commonjs/types/index.js +17 -0
- package/lib/commonjs/types/index.js.map +1 -0
- package/lib/module/components/button/Toggle.js +21 -18
- package/lib/module/components/button/Toggle.js.map +1 -1
- package/lib/module/components/form/input/Editable.js +62 -93
- package/lib/module/components/form/input/Editable.js.map +1 -1
- package/lib/module/components/form/input/StandaloneInput.js +5 -1
- package/lib/module/components/form/input/StandaloneInput.js.map +1 -1
- package/lib/module/components/form/input/datetime/index.js +7 -2
- package/lib/module/components/form/input/datetime/index.js.map +1 -1
- package/lib/module/components/form/input/hooks/useInputStyles.js +2 -1
- package/lib/module/components/form/input/hooks/useInputStyles.js.map +1 -1
- package/lib/module/components/form/input/multipleSelect/index.js +25 -11
- package/lib/module/components/form/input/multipleSelect/index.js.map +1 -1
- package/lib/module/components/form/input/number/index.js +8 -4
- package/lib/module/components/form/input/number/index.js.map +1 -1
- package/lib/module/components/form/input/select/index.js +14 -4
- package/lib/module/components/form/input/select/index.js.map +1 -1
- package/lib/module/components/form/input/text/AutoResizeTextarea.js +48 -0
- package/lib/module/components/form/input/text/AutoResizeTextarea.js.map +1 -0
- package/lib/module/components/form/input/text/index.js +24 -12
- package/lib/module/components/form/input/text/index.js.map +1 -1
- package/lib/module/components/form/input/text/textarea.js +15 -35
- package/lib/module/components/form/input/text/textarea.js.map +1 -1
- package/lib/module/components/form/input/text/useWebAutoResize.js +58 -0
- package/lib/module/components/form/input/text/useWebAutoResize.js.map +1 -0
- package/lib/module/components/form/view/file.js +15 -6
- package/lib/module/components/form/view/file.js.map +1 -1
- package/lib/module/components/form/view/index.js +19 -8
- package/lib/module/components/form/view/index.js.map +1 -1
- package/lib/module/components/form/view/multipleSelect.js +18 -14
- package/lib/module/components/form/view/multipleSelect.js.map +1 -1
- package/lib/module/components/form/view/select.js +14 -7
- package/lib/module/components/form/view/select.js.map +1 -1
- package/lib/module/components/form/view/styles.js +0 -3
- package/lib/module/components/form/view/styles.js.map +1 -1
- package/lib/module/components/layout/CollapseHorizontal.js +64 -0
- package/lib/module/components/layout/CollapseHorizontal.js.map +1 -0
- package/lib/module/contexts/root.js +95 -2
- package/lib/module/contexts/root.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/types/forms.js +2 -0
- package/lib/module/types/forms.js.map +1 -0
- package/lib/module/types/index.js +2 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/typescript/components/button/Toggle.d.ts +5 -2
- package/lib/typescript/components/button/Toggle.d.ts.map +1 -1
- package/lib/typescript/components/form/input/Editable.d.ts +2 -2
- package/lib/typescript/components/form/input/Editable.d.ts.map +1 -1
- package/lib/typescript/components/form/input/StandaloneInput.d.ts +5 -12
- package/lib/typescript/components/form/input/StandaloneInput.d.ts.map +1 -1
- package/lib/typescript/components/form/input/datetime/index.d.ts.map +1 -1
- package/lib/typescript/components/form/input/multipleSelect/index.d.ts.map +1 -1
- package/lib/typescript/components/form/input/number/index.d.ts.map +1 -1
- package/lib/typescript/components/form/input/select/index.d.ts.map +1 -1
- package/lib/typescript/components/form/input/text/AutoResizeTextarea.d.ts +4 -0
- package/lib/typescript/components/form/input/text/AutoResizeTextarea.d.ts.map +1 -0
- package/lib/typescript/components/form/input/text/index.d.ts.map +1 -1
- package/lib/typescript/components/form/input/text/textarea.d.ts +2 -2
- package/lib/typescript/components/form/input/text/textarea.d.ts.map +1 -1
- package/lib/typescript/components/form/input/text/useWebAutoResize.d.ts +8 -0
- package/lib/typescript/components/form/input/text/useWebAutoResize.d.ts.map +1 -0
- package/lib/typescript/components/form/types.d.ts +2 -2
- package/lib/typescript/components/form/types.d.ts.map +1 -1
- package/lib/typescript/components/form/view/file.d.ts.map +1 -1
- package/lib/typescript/components/form/view/index.d.ts +3 -2
- package/lib/typescript/components/form/view/index.d.ts.map +1 -1
- package/lib/typescript/components/form/view/multipleSelect.d.ts.map +1 -1
- package/lib/typescript/components/form/view/select.d.ts +2 -1
- package/lib/typescript/components/form/view/select.d.ts.map +1 -1
- package/lib/typescript/components/form/view/styles.d.ts +0 -3
- package/lib/typescript/components/form/view/styles.d.ts.map +1 -1
- package/lib/typescript/components/layout/CollapseHorizontal.d.ts +9 -0
- package/lib/typescript/components/layout/CollapseHorizontal.d.ts.map +1 -0
- package/lib/typescript/contexts/root.d.ts +4 -1
- package/lib/typescript/contexts/root.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +1 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/types/forms.d.ts +5 -0
- package/lib/typescript/types/forms.d.ts.map +1 -0
- package/lib/typescript/types/index.d.ts +2 -0
- package/lib/typescript/types/index.d.ts.map +1 -0
- package/package.json +3 -3
- package/src/components/button/Toggle.tsx +21 -17
- package/src/components/form/input/Editable.tsx +57 -113
- package/src/components/form/input/StandaloneInput.tsx +26 -13
- package/src/components/form/input/datetime/index.tsx +7 -2
- package/src/components/form/input/hooks/useInputStyles.ts +1 -1
- package/src/components/form/input/multipleSelect/index.tsx +34 -20
- package/src/components/form/input/number/index.tsx +20 -4
- package/src/components/form/input/select/index.tsx +15 -3
- package/src/components/form/input/text/AutoResizeTextarea.tsx +45 -0
- package/src/components/form/input/text/index.tsx +35 -17
- package/src/components/form/input/text/textarea.tsx +10 -36
- package/src/components/form/input/text/useWebAutoResize.tsx +71 -0
- package/src/components/form/types.ts +6 -2
- package/src/components/form/view/file.tsx +9 -5
- package/src/components/form/view/index.tsx +26 -7
- package/src/components/form/view/multipleSelect.tsx +11 -9
- package/src/components/form/view/select.tsx +7 -2
- package/src/components/form/view/styles.ts +0 -3
- package/src/components/layout/CollapseHorizontal.tsx +82 -0
- package/src/contexts/root.tsx +101 -3
- package/src/index.ts +1 -0
- package/src/types/forms.ts +14 -0
- 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,14 +9,14 @@ 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, TouchableOpacity, View, ViewStyle } from 'react-native'
|
|
14
|
+
import { CustomInputProps } from '../../../types/forms'
|
|
15
|
+
import { CollapseHorizontal } from '../../layout/CollapseHorizontal'
|
|
12
16
|
import { LoadingOverlay } from '../../loading/LoadingOverlay'
|
|
13
17
|
import { UploadProgress } from '../UploadProgress'
|
|
14
18
|
import { FieldView } from '../view'
|
|
15
19
|
import { StandaloneInput } from './StandaloneInput'
|
|
16
|
-
import { InputClearButton } from './common/InputClearButton'
|
|
17
|
-
import { useInputStyles } from './hooks/useInputStyles'
|
|
18
20
|
|
|
19
21
|
export const Editable = <T extends Field>({
|
|
20
22
|
value: initValue,
|
|
@@ -26,7 +28,9 @@ export const Editable = <T extends Field>({
|
|
|
26
28
|
onEditOpen,
|
|
27
29
|
containerStyle,
|
|
28
30
|
size,
|
|
29
|
-
|
|
31
|
+
CustomInput,
|
|
32
|
+
CustomView,
|
|
33
|
+
}: EditableProps<ViewStyle, TextStyle, T>) => {
|
|
30
34
|
const {
|
|
31
35
|
inputRef,
|
|
32
36
|
setValue,
|
|
@@ -38,7 +42,6 @@ export const Editable = <T extends Field>({
|
|
|
38
42
|
isEditing,
|
|
39
43
|
value,
|
|
40
44
|
setEditHovered,
|
|
41
|
-
submitValue,
|
|
42
45
|
submit,
|
|
43
46
|
} = useEditable({
|
|
44
47
|
value: initValue,
|
|
@@ -50,6 +53,7 @@ export const Editable = <T extends Field>({
|
|
|
50
53
|
})
|
|
51
54
|
|
|
52
55
|
const alwaysEditing = useMemo(() => {
|
|
56
|
+
if (!field) return false
|
|
53
57
|
switch (field._type) {
|
|
54
58
|
case 'file':
|
|
55
59
|
case 'boolean':
|
|
@@ -59,29 +63,6 @@ export const Editable = <T extends Field>({
|
|
|
59
63
|
}
|
|
60
64
|
}, [field])
|
|
61
65
|
|
|
62
|
-
const shouldSubmitOnChange = useMemo(() => {
|
|
63
|
-
if (alwaysEditing) return true
|
|
64
|
-
switch (field._type) {
|
|
65
|
-
case 'select':
|
|
66
|
-
case 'date':
|
|
67
|
-
case 'time':
|
|
68
|
-
case 'datetime':
|
|
69
|
-
return true
|
|
70
|
-
default:
|
|
71
|
-
return false
|
|
72
|
-
}
|
|
73
|
-
}, [field, alwaysEditing])
|
|
74
|
-
|
|
75
|
-
const noCloseButton = useMemo(() => {
|
|
76
|
-
if (alwaysEditing) return true
|
|
77
|
-
switch (field._type) {
|
|
78
|
-
case 'select':
|
|
79
|
-
return true
|
|
80
|
-
default:
|
|
81
|
-
return false
|
|
82
|
-
}
|
|
83
|
-
}, [field, alwaysEditing])
|
|
84
|
-
|
|
85
66
|
useEffect(() => {
|
|
86
67
|
if (isEditing) {
|
|
87
68
|
inputRef.current?.focus()
|
|
@@ -89,110 +70,80 @@ export const Editable = <T extends Field>({
|
|
|
89
70
|
}, [isEditing, inputRef])
|
|
90
71
|
|
|
91
72
|
const iconColor = useIconColor()
|
|
92
|
-
const { clearButtonSize } = useInputStyles(true, field.size, size)
|
|
93
73
|
const editingBorderColor = useColorModeValue('#00000055', '#ffffff55')
|
|
94
|
-
const submitColor = useThemeValue('colors.accent.
|
|
74
|
+
const submitColor = useThemeValue('colors.accent.600')
|
|
95
75
|
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
case 'select':
|
|
107
|
-
case 'date':
|
|
108
|
-
case 'time':
|
|
109
|
-
case 'datetime':
|
|
110
|
-
handleEditClose()
|
|
111
|
-
break
|
|
112
|
-
default:
|
|
113
|
-
break
|
|
114
|
-
}
|
|
115
|
-
}, [field, handleEditClose])
|
|
76
|
+
const RenderInput = useCallback(
|
|
77
|
+
(props: CustomInputProps<T['defaultValue']>, ref?: ForwardedRef<InputRef | null>) => {
|
|
78
|
+
if (CustomInput) {
|
|
79
|
+
return <CustomInput {...props} ref={ref} />
|
|
80
|
+
}
|
|
81
|
+
if (!field) throw new Error('Editable component must have a field OR a CustomInput')
|
|
82
|
+
return <StandaloneInput ref={ref} field={field} {...props} />
|
|
83
|
+
},
|
|
84
|
+
[CustomInput, field],
|
|
85
|
+
)
|
|
116
86
|
|
|
117
|
-
const
|
|
118
|
-
() =>
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
87
|
+
const RenderView = useCallback(
|
|
88
|
+
(props: CustomEditableViewProps<T['defaultValue']>) => {
|
|
89
|
+
if (CustomView) {
|
|
90
|
+
return <CustomView {...props} />
|
|
91
|
+
}
|
|
92
|
+
if (!field) throw new Error('Editable component must have a field OR a CustomView')
|
|
93
|
+
return <FieldView field={field} {...props} />
|
|
94
|
+
},
|
|
95
|
+
[CustomView, field],
|
|
123
96
|
)
|
|
124
97
|
|
|
98
|
+
console.log({ isEditing })
|
|
99
|
+
|
|
125
100
|
return (
|
|
126
|
-
<View
|
|
127
|
-
style={[
|
|
128
|
-
styles.container,
|
|
129
|
-
{
|
|
130
|
-
borderColor: editHovered && !isEditing ? editingBorderColor : 'transparent',
|
|
131
|
-
},
|
|
132
|
-
containerStyle,
|
|
133
|
-
]}>
|
|
101
|
+
<View style={[styles.container, containerStyle]}>
|
|
134
102
|
<View style={styles.contentContainer}>
|
|
135
103
|
<View
|
|
136
104
|
style={[
|
|
137
105
|
styles.inputContainer,
|
|
138
106
|
{
|
|
139
107
|
opacity: isLoading ? 0 : 1,
|
|
140
|
-
borderColor: isEditing ? editingBorderColor : 'transparent',
|
|
108
|
+
borderColor: isEditing || editHovered ? editingBorderColor : 'transparent',
|
|
141
109
|
},
|
|
142
110
|
]}>
|
|
143
111
|
{isEditing || alwaysEditing ? (
|
|
144
|
-
<
|
|
112
|
+
<RenderInput
|
|
113
|
+
onChange={setValue}
|
|
145
114
|
ref={inputRef}
|
|
146
115
|
value={value}
|
|
147
116
|
inEditable
|
|
148
|
-
field={editableField}
|
|
149
117
|
style={style}
|
|
150
|
-
|
|
151
|
-
onBlur={handleBlur}
|
|
118
|
+
size={size}
|
|
152
119
|
/>
|
|
153
120
|
) : (
|
|
154
|
-
<
|
|
121
|
+
<RenderView inEditable noLabel size={size} value={value} />
|
|
155
122
|
)}
|
|
156
123
|
</View>
|
|
157
124
|
{!alwaysEditing && (
|
|
158
125
|
<View style={styles.buttonsContainer}>
|
|
159
|
-
{
|
|
160
|
-
<
|
|
161
|
-
size={clearButtonSize}
|
|
126
|
+
<CollapseHorizontal in={!isEditing}>
|
|
127
|
+
<TouchableOpacity
|
|
162
128
|
onPress={() => {
|
|
163
|
-
|
|
129
|
+
handleEditOpen()
|
|
164
130
|
}}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
131
|
+
style={styles.submitButton}
|
|
132
|
+
onPressIn={() => setEditHovered(true)}
|
|
133
|
+
onPressOut={() => setEditHovered(false)}>
|
|
134
|
+
<Ionicons name="create-outline" size={20} color={iconColor} />
|
|
135
|
+
</TouchableOpacity>
|
|
136
|
+
</CollapseHorizontal>
|
|
137
|
+
<CollapseHorizontal in={isEditing} style={styles.submitButtonContainer}>
|
|
169
138
|
<TouchableOpacity
|
|
170
|
-
style={styles.editButton}
|
|
171
139
|
onPress={() => {
|
|
172
|
-
|
|
173
|
-
setValue(value)
|
|
174
|
-
handleEditClose()
|
|
175
|
-
} else {
|
|
176
|
-
handleEditOpen()
|
|
177
|
-
}
|
|
140
|
+
handleEditClose()
|
|
178
141
|
}}
|
|
142
|
+
style={styles.submitButton}
|
|
179
143
|
onPressIn={() => setEditHovered(true)}
|
|
180
144
|
onPressOut={() => setEditHovered(false)}>
|
|
181
|
-
<Ionicons
|
|
182
|
-
name={isEditing ? 'close' : 'create-outline'}
|
|
183
|
-
size={20}
|
|
184
|
-
color={iconColor}
|
|
185
|
-
/>
|
|
145
|
+
<Ionicons name="close" size={20} color={iconColor} />
|
|
186
146
|
</TouchableOpacity>
|
|
187
|
-
)}
|
|
188
|
-
<View
|
|
189
|
-
style={[
|
|
190
|
-
styles.submitButtonContainer,
|
|
191
|
-
{
|
|
192
|
-
width: isEditing ? 26 : 0,
|
|
193
|
-
opacity: isEditing ? 1 : 0,
|
|
194
|
-
},
|
|
195
|
-
]}>
|
|
196
147
|
<TouchableOpacity
|
|
197
148
|
style={[styles.submitButton, { backgroundColor: submitColor }]}
|
|
198
149
|
onPress={() => {
|
|
@@ -200,7 +151,7 @@ export const Editable = <T extends Field>({
|
|
|
200
151
|
}}>
|
|
201
152
|
<Ionicons name="checkmark" size={20} color="#fff" />
|
|
202
153
|
</TouchableOpacity>
|
|
203
|
-
</
|
|
154
|
+
</CollapseHorizontal>
|
|
204
155
|
</View>
|
|
205
156
|
)}
|
|
206
157
|
<LoadingOverlay loading={isLoading} />
|
|
@@ -213,20 +164,16 @@ export const Editable = <T extends Field>({
|
|
|
213
164
|
const styles = StyleSheet.create({
|
|
214
165
|
container: {
|
|
215
166
|
borderRadius: 4,
|
|
216
|
-
borderWidth: 1,
|
|
217
|
-
borderStyle: 'dashed',
|
|
218
167
|
width: '100%',
|
|
219
168
|
},
|
|
220
169
|
buttonsContainer: {
|
|
221
170
|
flexDirection: 'row',
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
marginLeft: 5,
|
|
171
|
+
justifyContent: 'center',
|
|
172
|
+
paddingTop: 6,
|
|
225
173
|
},
|
|
226
174
|
contentContainer: {
|
|
227
175
|
flexDirection: 'row',
|
|
228
|
-
|
|
229
|
-
paddingHorizontal: 4,
|
|
176
|
+
gap: 10,
|
|
230
177
|
position: 'relative',
|
|
231
178
|
width: '100%',
|
|
232
179
|
},
|
|
@@ -236,13 +183,10 @@ const styles = StyleSheet.create({
|
|
|
236
183
|
borderWidth: 1,
|
|
237
184
|
borderStyle: 'dashed',
|
|
238
185
|
},
|
|
239
|
-
editButton: {
|
|
240
|
-
padding: 4,
|
|
241
|
-
},
|
|
242
186
|
submitButtonContainer: {
|
|
243
|
-
|
|
244
|
-
alignItems: 'center',
|
|
187
|
+
flexDirection: 'row',
|
|
245
188
|
overflow: 'hidden',
|
|
189
|
+
gap: 12,
|
|
246
190
|
},
|
|
247
191
|
submitButton: {
|
|
248
192
|
width: 24,
|
|
@@ -1,22 +1,33 @@
|
|
|
1
1
|
import { InputRef } from '@chem-po/core'
|
|
2
|
-
import { Field, useStandaloneInput } from '@chem-po/react'
|
|
2
|
+
import { BaseCustomInputProps, Field, useStandaloneInput } from '@chem-po/react'
|
|
3
3
|
import React, { ForwardedRef, forwardRef } from 'react'
|
|
4
|
-
import {
|
|
4
|
+
import { TextStyle, ViewStyle } from 'react-native'
|
|
5
5
|
import { Input } from './input'
|
|
6
6
|
|
|
7
|
-
interface StandaloneInputProps
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
theme?: 'basic' | 'detailed'
|
|
14
|
-
inEditable?: boolean
|
|
15
|
-
style?: StyleProp<ViewStyle>
|
|
7
|
+
interface StandaloneInputProps<
|
|
8
|
+
T extends Field,
|
|
9
|
+
ContainerStyle extends ViewStyle = ViewStyle,
|
|
10
|
+
InputStyle extends TextStyle = TextStyle,
|
|
11
|
+
> extends BaseCustomInputProps<T['defaultValue'], ContainerStyle, InputStyle> {
|
|
12
|
+
field: T
|
|
16
13
|
}
|
|
17
14
|
|
|
18
|
-
const StandaloneInputBase =
|
|
19
|
-
|
|
15
|
+
const StandaloneInputBase = <
|
|
16
|
+
T extends Field,
|
|
17
|
+
ContainerStyle extends ViewStyle = ViewStyle,
|
|
18
|
+
InputStyle extends TextStyle = TextStyle,
|
|
19
|
+
>(
|
|
20
|
+
{
|
|
21
|
+
onChange,
|
|
22
|
+
value,
|
|
23
|
+
field,
|
|
24
|
+
onBlur,
|
|
25
|
+
inEditable,
|
|
26
|
+
onFocus,
|
|
27
|
+
style,
|
|
28
|
+
size,
|
|
29
|
+
inputStyle,
|
|
30
|
+
}: StandaloneInputProps<T, ContainerStyle, InputStyle>,
|
|
20
31
|
ref: ForwardedRef<InputRef>,
|
|
21
32
|
) => {
|
|
22
33
|
const { inputProps, meta } = useStandaloneInput(field, value, onChange, onFocus, onBlur)
|
|
@@ -28,6 +39,8 @@ const StandaloneInputBase = (
|
|
|
28
39
|
inEditable={inEditable}
|
|
29
40
|
style={style}
|
|
30
41
|
input={inputProps}
|
|
42
|
+
inputStyle={inputStyle}
|
|
43
|
+
formSize={size}
|
|
31
44
|
meta={meta}
|
|
32
45
|
/>
|
|
33
46
|
)
|
|
@@ -3,6 +3,7 @@ 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
5
|
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'
|
|
6
|
+
import { Pressable } from 'react-native-gesture-handler'
|
|
6
7
|
import { Portal } from 'react-native-paper'
|
|
7
8
|
import { DatePickerModal, TimePickerModal } from 'react-native-paper-dates'
|
|
8
9
|
import { FieldProps } from '../../types'
|
|
@@ -95,8 +96,12 @@ export const DateTimeInput = forwardRef<InputRef, FieldProps<DateTimeField>>(
|
|
|
95
96
|
{formattedValue ?? placeholder}
|
|
96
97
|
</Text>
|
|
97
98
|
<View style={buttonContainer}>
|
|
98
|
-
<
|
|
99
|
-
|
|
99
|
+
<Pressable onPress={() => setShowDatePicker(true)}>
|
|
100
|
+
<Ionicons name="calendar" size={iconSize} color={iconColor} />
|
|
101
|
+
</Pressable>
|
|
102
|
+
<Pressable onPress={() => setShowTimePicker(true)}>
|
|
103
|
+
<Ionicons name="time" size={iconSize} color={iconColor} />
|
|
104
|
+
</Pressable>
|
|
100
105
|
{optional && value ? (
|
|
101
106
|
<DateInputClearButton
|
|
102
107
|
size={clearButtonSize}
|
|
@@ -110,7 +110,7 @@ export const useInputStyles = (
|
|
|
110
110
|
const textColor = useTextColor()
|
|
111
111
|
const usedSize = size ?? formSize
|
|
112
112
|
return {
|
|
113
|
-
text: { ...inputTextSizeMap[usedSize], color: textColor },
|
|
113
|
+
text: { ...inputTextSizeMap[usedSize], color: textColor, outlineWidth: 0 },
|
|
114
114
|
container: {
|
|
115
115
|
...inputStyles.input,
|
|
116
116
|
...(inEditable ? editableInputSizeMap[usedSize] : inputSizeMap[usedSize]),
|
|
@@ -30,7 +30,12 @@ export const SelectedOptionContainer = ({
|
|
|
30
30
|
style,
|
|
31
31
|
}: PropsWithChildren<{ key?: string; style?: StyleProp<ViewStyle> }>) => {
|
|
32
32
|
const borderColor = useBorderColor()
|
|
33
|
-
|
|
33
|
+
const bg = useBackgroundColor(100)
|
|
34
|
+
return (
|
|
35
|
+
<View style={[styles.selectedOption, { borderColor, backgroundColor: bg }, style]}>
|
|
36
|
+
{children}
|
|
37
|
+
</View>
|
|
38
|
+
)
|
|
34
39
|
}
|
|
35
40
|
|
|
36
41
|
const BaseMultipleSelectComponent = <T extends MultipleSelectField>(
|
|
@@ -55,7 +60,8 @@ const BaseMultipleSelectComponent = <T extends MultipleSelectField>(
|
|
|
55
60
|
const textColor = useTextColor()
|
|
56
61
|
const placeholderColor = usePlaceholderColor()
|
|
57
62
|
const menuBg = useBackgroundColor(100)
|
|
58
|
-
const
|
|
63
|
+
const inputBg = useBackgroundColor(50)
|
|
64
|
+
const selectedOptionBg = useColorModeValue('#ffffff55', '#ffffff22')
|
|
59
65
|
const borderColor = useBorderColor()
|
|
60
66
|
|
|
61
67
|
useImperativeHandle(ref, () => ({
|
|
@@ -96,14 +102,22 @@ const BaseMultipleSelectComponent = <T extends MultipleSelectField>(
|
|
|
96
102
|
)
|
|
97
103
|
}
|
|
98
104
|
|
|
105
|
+
const selectedOptions = useMemo(() => {
|
|
106
|
+
return options.filter(o => value?.includes(o.value))
|
|
107
|
+
}, [options, value])
|
|
108
|
+
|
|
99
109
|
return (
|
|
100
110
|
<View style={[styles.wrapper]}>
|
|
101
111
|
<MultiSelect
|
|
102
112
|
ref={inputRef}
|
|
103
113
|
style={[inputStyles, { borderColor }]}
|
|
104
114
|
placeholderStyle={[text, { color: value?.length ? textColor : placeholderColor }]}
|
|
105
|
-
containerStyle={{
|
|
106
|
-
|
|
115
|
+
containerStyle={{
|
|
116
|
+
backgroundColor: menuBg,
|
|
117
|
+
boxShadow: `0 0 10px ${borderColor}`,
|
|
118
|
+
borderWidth: 0,
|
|
119
|
+
}}
|
|
120
|
+
inputSearchStyle={[styles.inputSearch, text, { backgroundColor: inputBg, borderWidth: 0 }]}
|
|
107
121
|
iconStyle={styles.iconStyle}
|
|
108
122
|
data={options}
|
|
109
123
|
search={searchable}
|
|
@@ -111,24 +125,27 @@ const BaseMultipleSelectComponent = <T extends MultipleSelectField>(
|
|
|
111
125
|
maxHeight={300}
|
|
112
126
|
labelField="label"
|
|
113
127
|
valueField="value"
|
|
114
|
-
placeholder={
|
|
128
|
+
placeholder={
|
|
129
|
+
selectedOptions.length ? selectedOptions.map(v => v.label).join(', ') : placeholder
|
|
130
|
+
}
|
|
115
131
|
searchPlaceholder={searchPlaceholder ?? placeholder}
|
|
116
132
|
value={value ?? []}
|
|
117
133
|
onChange={updated => {
|
|
118
134
|
onChange(updated)
|
|
119
135
|
}}
|
|
120
|
-
activeColor={selectedOptionBg}
|
|
121
136
|
onFocus={onFocus}
|
|
122
137
|
onBlur={onBlur}
|
|
123
138
|
renderItem={(item, selected) => (
|
|
124
|
-
<View style={{ backgroundColor:
|
|
125
|
-
<
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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>
|
|
132
149
|
</View>
|
|
133
150
|
)}
|
|
134
151
|
renderSelectedItem={item => (
|
|
@@ -140,11 +157,7 @@ const BaseMultipleSelectComponent = <T extends MultipleSelectField>(
|
|
|
140
157
|
isSelected
|
|
141
158
|
size={size}
|
|
142
159
|
/>
|
|
143
|
-
<View
|
|
144
|
-
style={[
|
|
145
|
-
styles.optionClearContainer,
|
|
146
|
-
{ borderColor, backgroundColor: selectedOptionBg },
|
|
147
|
-
]}>
|
|
160
|
+
<View style={[styles.optionClearContainer, { borderColor }]}>
|
|
148
161
|
<InputClearButton
|
|
149
162
|
size={clearButtonSize}
|
|
150
163
|
onPress={() => {
|
|
@@ -183,10 +196,10 @@ const styles = StyleSheet.create({
|
|
|
183
196
|
height: 20,
|
|
184
197
|
},
|
|
185
198
|
inputSearch: {
|
|
186
|
-
outlineWidth: 0,
|
|
187
199
|
paddingVertical: 4,
|
|
188
200
|
minHeight: 0,
|
|
189
201
|
height: 'auto',
|
|
202
|
+
outlineWidth: 0,
|
|
190
203
|
fontSize: 16,
|
|
191
204
|
},
|
|
192
205
|
selectedOption: {
|
|
@@ -195,6 +208,7 @@ const styles = StyleSheet.create({
|
|
|
195
208
|
borderWidth: 1,
|
|
196
209
|
alignItems: 'center',
|
|
197
210
|
marginTop: 4,
|
|
211
|
+
marginBottom: 4,
|
|
198
212
|
marginHorizontal: 4,
|
|
199
213
|
},
|
|
200
214
|
optionClearContainer: {
|
|
@@ -8,10 +8,25 @@ import { useInputImperativeHandle } from '../hooks/useInputImperativeHandle'
|
|
|
8
8
|
import { useInputStyles } from '../hooks/useInputStyles'
|
|
9
9
|
|
|
10
10
|
export const NumberComponent = forwardRef<InputRef, FieldProps<NumberField> & { prefix?: string }>(
|
|
11
|
-
(
|
|
11
|
+
(
|
|
12
|
+
{
|
|
13
|
+
input: { onChange, value, ...input },
|
|
14
|
+
inputStyle,
|
|
15
|
+
field,
|
|
16
|
+
prefix,
|
|
17
|
+
inEditable,
|
|
18
|
+
style,
|
|
19
|
+
formSize,
|
|
20
|
+
},
|
|
21
|
+
ref,
|
|
22
|
+
) => {
|
|
12
23
|
const { type, defaultValue, placeholder, size } = field
|
|
13
24
|
const color = useTextColor()
|
|
14
|
-
const { container: inputStyles } = useInputStyles(
|
|
25
|
+
const { container: conatinerStyles, text: inputStyles } = useInputStyles(
|
|
26
|
+
inEditable,
|
|
27
|
+
size,
|
|
28
|
+
formSize,
|
|
29
|
+
)
|
|
15
30
|
const inputRef = useInputImperativeHandle(ref)
|
|
16
31
|
const [endsWith, setEndsWith] = useState('')
|
|
17
32
|
const displayed = typeof value === 'number' && !Number.isNaN(value) ? `${value}${endsWith}` : ''
|
|
@@ -22,6 +37,7 @@ export const NumberComponent = forwardRef<InputRef, FieldProps<NumberField> & {
|
|
|
22
37
|
return (
|
|
23
38
|
<InputSlider
|
|
24
39
|
label={placeholder}
|
|
40
|
+
style={style}
|
|
25
41
|
onValueChange={onChange}
|
|
26
42
|
value={value}
|
|
27
43
|
minimumValue={defaultValue}
|
|
@@ -30,11 +46,11 @@ export const NumberComponent = forwardRef<InputRef, FieldProps<NumberField> & {
|
|
|
30
46
|
}
|
|
31
47
|
|
|
32
48
|
return (
|
|
33
|
-
<View style={styles.container}>
|
|
49
|
+
<View style={[styles.container, conatinerStyles, style]}>
|
|
34
50
|
{prefix && <Text style={styles.prefix}>{prefix}</Text>}
|
|
35
51
|
<TextInput
|
|
36
52
|
ref={inputRef}
|
|
37
|
-
style={[inputStyles, { color },
|
|
53
|
+
style={[inputStyles, { color, outlineWidth: 0 }, inputStyle]}
|
|
38
54
|
placeholder={field.placeholder}
|
|
39
55
|
placeholderTextColor={placeholderColor}
|
|
40
56
|
keyboardType="numeric"
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
SelectField,
|
|
4
4
|
useBackgroundColor,
|
|
5
5
|
useBorderColor,
|
|
6
|
+
useColorMode,
|
|
6
7
|
useIconColor,
|
|
7
8
|
usePlaceholderColor,
|
|
8
9
|
} from '@chem-po/react'
|
|
@@ -29,6 +30,7 @@ const BaseSelectComponent = <T extends SelectField>(
|
|
|
29
30
|
} = field
|
|
30
31
|
const { onChange, value, onFocus, onBlur } = input
|
|
31
32
|
const { active } = meta
|
|
33
|
+
const colorMode = useColorMode()
|
|
32
34
|
|
|
33
35
|
const inputRef = useRef<IDropdownRef>(null)
|
|
34
36
|
const {
|
|
@@ -70,8 +72,18 @@ const BaseSelectComponent = <T extends SelectField>(
|
|
|
70
72
|
ref={inputRef}
|
|
71
73
|
style={[inputStyles, { borderColor }]}
|
|
72
74
|
placeholderStyle={[text, { color: placeholderColor }]}
|
|
75
|
+
containerStyle={{
|
|
76
|
+
backgroundColor: menuBg,
|
|
77
|
+
borderWidth: 0,
|
|
78
|
+
borderColor: 'transparent',
|
|
79
|
+
boxShadow: `0 0 10px ${borderColor}`,
|
|
80
|
+
}}
|
|
73
81
|
selectedTextStyle={text}
|
|
74
|
-
inputSearchStyle={[
|
|
82
|
+
inputSearchStyle={[
|
|
83
|
+
styles.inputSearch,
|
|
84
|
+
text,
|
|
85
|
+
{ backgroundColor: selectedOptionBg, borderColor: 'transparent' },
|
|
86
|
+
]}
|
|
75
87
|
iconStyle={styles.iconStyle}
|
|
76
88
|
data={options}
|
|
77
89
|
search={searchable}
|
|
@@ -95,7 +107,7 @@ const BaseSelectComponent = <T extends SelectField>(
|
|
|
95
107
|
<RenderOptionText
|
|
96
108
|
value={item.value}
|
|
97
109
|
option={item}
|
|
98
|
-
colorMode=
|
|
110
|
+
colorMode={colorMode}
|
|
99
111
|
isSelected={!!selected}
|
|
100
112
|
size={size}
|
|
101
113
|
/>
|
|
@@ -114,7 +126,7 @@ const BaseSelectComponent = <T extends SelectField>(
|
|
|
114
126
|
onPress={() => {
|
|
115
127
|
onChange(null)
|
|
116
128
|
}}
|
|
117
|
-
isActive
|
|
129
|
+
isActive
|
|
118
130
|
/>
|
|
119
131
|
) : null}
|
|
120
132
|
</View>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { forwardRef } from 'react'
|
|
2
|
+
import { StyleSheet, TextInput, TextInputProps } from 'react-native'
|
|
3
|
+
|
|
4
|
+
import { useIconColor, useTextColor } from '@chem-po/react'
|
|
5
|
+
|
|
6
|
+
import React from 'react'
|
|
7
|
+
import { useWebAutoResize } from './useWebAutoResize'
|
|
8
|
+
|
|
9
|
+
export const AutoResizeTextarea = forwardRef<TextInput, TextInputProps>(
|
|
10
|
+
({ style, value, onChangeText, ...props }, ref) => {
|
|
11
|
+
const textColor = useTextColor()
|
|
12
|
+
|
|
13
|
+
const { handleChange, height, setHeight } = useWebAutoResize(onChangeText, style)
|
|
14
|
+
|
|
15
|
+
const iconColor = useIconColor()
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<TextInput
|
|
19
|
+
ref={ref}
|
|
20
|
+
cursorColor={iconColor}
|
|
21
|
+
onContentSizeChange={e => {
|
|
22
|
+
setHeight(e.nativeEvent.contentSize.height)
|
|
23
|
+
}}
|
|
24
|
+
multiline
|
|
25
|
+
style={[styles.textarea, { color: textColor, height }, style]}
|
|
26
|
+
value={value}
|
|
27
|
+
onChangeText={handleChange}
|
|
28
|
+
{...props}
|
|
29
|
+
/>
|
|
30
|
+
)
|
|
31
|
+
},
|
|
32
|
+
)
|
|
33
|
+
const styles = StyleSheet.create({
|
|
34
|
+
textarea: {
|
|
35
|
+
width: '100%',
|
|
36
|
+
minHeight: 18,
|
|
37
|
+
backgroundColor: 'transparent',
|
|
38
|
+
textAlignVertical: 'top',
|
|
39
|
+
outlineWidth: 0,
|
|
40
|
+
},
|
|
41
|
+
inEditable: {
|
|
42
|
+
paddingHorizontal: 0,
|
|
43
|
+
paddingVertical: 0,
|
|
44
|
+
},
|
|
45
|
+
})
|