@chem-po/react-native 0.0.29 → 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 +52 -73
- package/lib/commonjs/components/form/input/Editable.js.map +1 -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/multipleSelect/index.js +7 -2
- package/lib/commonjs/components/form/input/multipleSelect/index.js.map +1 -1
- package/lib/commonjs/components/form/input/select/index.js +1 -1
- package/lib/commonjs/components/form/input/select/index.js.map +1 -1
- package/lib/commonjs/components/form/input/text/index.js +3 -2
- package/lib/commonjs/components/form/input/text/index.js.map +1 -1
- package/lib/commonjs/components/form/input/text/textarea.js +1 -12
- package/lib/commonjs/components/form/input/text/textarea.js.map +1 -1
- package/lib/commonjs/components/form/input/text/useWebAutoResize.js +5 -6
- package/lib/commonjs/components/form/input/text/useWebAutoResize.js.map +1 -1
- 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 +6 -6
- 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 +52 -73
- package/lib/module/components/form/input/Editable.js.map +1 -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/multipleSelect/index.js +7 -2
- package/lib/module/components/form/input/multipleSelect/index.js.map +1 -1
- package/lib/module/components/form/input/select/index.js +1 -1
- package/lib/module/components/form/input/select/index.js.map +1 -1
- package/lib/module/components/form/input/text/index.js +3 -2
- package/lib/module/components/form/input/text/index.js.map +1 -1
- package/lib/module/components/form/input/text/textarea.js +2 -13
- package/lib/module/components/form/input/text/textarea.js.map +1 -1
- package/lib/module/components/form/input/text/useWebAutoResize.js +5 -6
- package/lib/module/components/form/input/text/useWebAutoResize.js.map +1 -1
- 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 +6 -6
- 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 -14
- 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/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.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/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 +47 -86
- package/src/components/form/input/StandaloneInput.tsx +4 -13
- package/src/components/form/input/datetime/index.tsx +7 -2
- package/src/components/form/input/multipleSelect/index.tsx +13 -2
- package/src/components/form/input/select/index.tsx +1 -1
- package/src/components/form/input/text/index.tsx +3 -2
- package/src/components/form/input/text/textarea.tsx +3 -15
- package/src/components/form/input/text/useWebAutoResize.tsx +5 -6
- 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 +6 -6
- 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,8 +9,10 @@ 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'
|
|
@@ -24,7 +28,9 @@ export const Editable = <T extends Field>({
|
|
|
24
28
|
onEditOpen,
|
|
25
29
|
containerStyle,
|
|
26
30
|
size,
|
|
27
|
-
|
|
31
|
+
CustomInput,
|
|
32
|
+
CustomView,
|
|
33
|
+
}: EditableProps<ViewStyle, TextStyle, T>) => {
|
|
28
34
|
const {
|
|
29
35
|
inputRef,
|
|
30
36
|
setValue,
|
|
@@ -36,7 +42,6 @@ export const Editable = <T extends Field>({
|
|
|
36
42
|
isEditing,
|
|
37
43
|
value,
|
|
38
44
|
setEditHovered,
|
|
39
|
-
submitValue,
|
|
40
45
|
submit,
|
|
41
46
|
} = useEditable({
|
|
42
47
|
value: initValue,
|
|
@@ -48,6 +53,7 @@ export const Editable = <T extends Field>({
|
|
|
48
53
|
})
|
|
49
54
|
|
|
50
55
|
const alwaysEditing = useMemo(() => {
|
|
56
|
+
if (!field) return false
|
|
51
57
|
switch (field._type) {
|
|
52
58
|
case 'file':
|
|
53
59
|
case 'boolean':
|
|
@@ -57,29 +63,6 @@ export const Editable = <T extends Field>({
|
|
|
57
63
|
}
|
|
58
64
|
}, [field])
|
|
59
65
|
|
|
60
|
-
const shouldSubmitOnChange = useMemo(() => {
|
|
61
|
-
if (alwaysEditing) return true
|
|
62
|
-
switch (field._type) {
|
|
63
|
-
case 'select':
|
|
64
|
-
case 'date':
|
|
65
|
-
case 'time':
|
|
66
|
-
case 'datetime':
|
|
67
|
-
return true
|
|
68
|
-
default:
|
|
69
|
-
return false
|
|
70
|
-
}
|
|
71
|
-
}, [field, alwaysEditing])
|
|
72
|
-
|
|
73
|
-
const noCloseButton = useMemo(() => {
|
|
74
|
-
if (alwaysEditing) return true
|
|
75
|
-
switch (field._type) {
|
|
76
|
-
case 'select':
|
|
77
|
-
return true
|
|
78
|
-
default:
|
|
79
|
-
return false
|
|
80
|
-
}
|
|
81
|
-
}, [field, alwaysEditing])
|
|
82
|
-
|
|
83
66
|
useEffect(() => {
|
|
84
67
|
if (isEditing) {
|
|
85
68
|
inputRef.current?.focus()
|
|
@@ -90,92 +73,77 @@ export const Editable = <T extends Field>({
|
|
|
90
73
|
const editingBorderColor = useColorModeValue('#00000055', '#ffffff55')
|
|
91
74
|
const submitColor = useThemeValue('colors.accent.600')
|
|
92
75
|
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
}, [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
|
+
)
|
|
105
86
|
|
|
106
|
-
const
|
|
107
|
-
() =>
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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],
|
|
112
96
|
)
|
|
113
97
|
|
|
98
|
+
console.log({ isEditing })
|
|
99
|
+
|
|
114
100
|
return (
|
|
115
|
-
<View
|
|
116
|
-
style={[
|
|
117
|
-
styles.container,
|
|
118
|
-
{
|
|
119
|
-
borderColor: editHovered && !isEditing ? editingBorderColor : 'transparent',
|
|
120
|
-
},
|
|
121
|
-
containerStyle,
|
|
122
|
-
]}>
|
|
101
|
+
<View style={[styles.container, containerStyle]}>
|
|
123
102
|
<View style={styles.contentContainer}>
|
|
124
103
|
<View
|
|
125
104
|
style={[
|
|
126
105
|
styles.inputContainer,
|
|
127
106
|
{
|
|
128
107
|
opacity: isLoading ? 0 : 1,
|
|
129
|
-
borderColor: isEditing ? editingBorderColor : 'transparent',
|
|
108
|
+
borderColor: isEditing || editHovered ? editingBorderColor : 'transparent',
|
|
130
109
|
},
|
|
131
110
|
]}>
|
|
132
111
|
{isEditing || alwaysEditing ? (
|
|
133
|
-
<
|
|
112
|
+
<RenderInput
|
|
113
|
+
onChange={setValue}
|
|
134
114
|
ref={inputRef}
|
|
135
115
|
value={value}
|
|
136
116
|
inEditable
|
|
137
|
-
field={editableField}
|
|
138
117
|
style={style}
|
|
139
118
|
size={size}
|
|
140
|
-
onChange={shouldSubmitOnChange ? v => submitValue(v) : setValue}
|
|
141
|
-
onBlur={handleBlur}
|
|
142
119
|
/>
|
|
143
120
|
) : (
|
|
144
|
-
<
|
|
121
|
+
<RenderView inEditable noLabel size={size} value={value} />
|
|
145
122
|
)}
|
|
146
123
|
</View>
|
|
147
124
|
{!alwaysEditing && (
|
|
148
125
|
<View style={styles.buttonsContainer}>
|
|
149
|
-
{isEditing
|
|
126
|
+
<CollapseHorizontal in={!isEditing}>
|
|
150
127
|
<TouchableOpacity
|
|
151
|
-
style={styles.editButton}
|
|
152
128
|
onPress={() => {
|
|
153
129
|
handleEditOpen()
|
|
154
130
|
}}
|
|
131
|
+
style={styles.submitButton}
|
|
155
132
|
onPressIn={() => setEditHovered(true)}
|
|
156
133
|
onPressOut={() => setEditHovered(false)}>
|
|
157
134
|
<Ionicons name="create-outline" size={20} color={iconColor} />
|
|
158
135
|
</TouchableOpacity>
|
|
159
|
-
|
|
160
|
-
{
|
|
136
|
+
</CollapseHorizontal>
|
|
137
|
+
<CollapseHorizontal in={isEditing} style={styles.submitButtonContainer}>
|
|
161
138
|
<TouchableOpacity
|
|
162
|
-
style={styles.editButton}
|
|
163
139
|
onPress={() => {
|
|
164
140
|
handleEditClose()
|
|
165
141
|
}}
|
|
142
|
+
style={styles.submitButton}
|
|
166
143
|
onPressIn={() => setEditHovered(true)}
|
|
167
144
|
onPressOut={() => setEditHovered(false)}>
|
|
168
145
|
<Ionicons name="close" size={20} color={iconColor} />
|
|
169
146
|
</TouchableOpacity>
|
|
170
|
-
)}
|
|
171
|
-
<View
|
|
172
|
-
style={[
|
|
173
|
-
styles.submitButtonContainer,
|
|
174
|
-
{
|
|
175
|
-
width: isEditing ? 26 : 0,
|
|
176
|
-
opacity: isEditing ? 1 : 0,
|
|
177
|
-
},
|
|
178
|
-
]}>
|
|
179
147
|
<TouchableOpacity
|
|
180
148
|
style={[styles.submitButton, { backgroundColor: submitColor }]}
|
|
181
149
|
onPress={() => {
|
|
@@ -183,7 +151,7 @@ export const Editable = <T extends Field>({
|
|
|
183
151
|
}}>
|
|
184
152
|
<Ionicons name="checkmark" size={20} color="#fff" />
|
|
185
153
|
</TouchableOpacity>
|
|
186
|
-
</
|
|
154
|
+
</CollapseHorizontal>
|
|
187
155
|
</View>
|
|
188
156
|
)}
|
|
189
157
|
<LoadingOverlay loading={isLoading} />
|
|
@@ -196,20 +164,16 @@ export const Editable = <T extends Field>({
|
|
|
196
164
|
const styles = StyleSheet.create({
|
|
197
165
|
container: {
|
|
198
166
|
borderRadius: 4,
|
|
199
|
-
borderWidth: 1,
|
|
200
|
-
borderStyle: 'dashed',
|
|
201
167
|
width: '100%',
|
|
202
168
|
},
|
|
203
169
|
buttonsContainer: {
|
|
204
170
|
flexDirection: 'row',
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
marginLeft: 5,
|
|
171
|
+
justifyContent: 'center',
|
|
172
|
+
paddingTop: 6,
|
|
208
173
|
},
|
|
209
174
|
contentContainer: {
|
|
210
175
|
flexDirection: 'row',
|
|
211
|
-
|
|
212
|
-
paddingHorizontal: 4,
|
|
176
|
+
gap: 10,
|
|
213
177
|
position: 'relative',
|
|
214
178
|
width: '100%',
|
|
215
179
|
},
|
|
@@ -219,13 +183,10 @@ const styles = StyleSheet.create({
|
|
|
219
183
|
borderWidth: 1,
|
|
220
184
|
borderStyle: 'dashed',
|
|
221
185
|
},
|
|
222
|
-
editButton: {
|
|
223
|
-
padding: 4,
|
|
224
|
-
},
|
|
225
186
|
submitButtonContainer: {
|
|
226
|
-
|
|
227
|
-
alignItems: 'center',
|
|
187
|
+
flexDirection: 'row',
|
|
228
188
|
overflow: 'hidden',
|
|
189
|
+
gap: 12,
|
|
229
190
|
},
|
|
230
191
|
submitButton: {
|
|
231
192
|
width: 24,
|
|
@@ -1,24 +1,15 @@
|
|
|
1
|
-
import { InputRef
|
|
2
|
-
import { Field, useStandaloneInput } from '@chem-po/react'
|
|
1
|
+
import { InputRef } from '@chem-po/core'
|
|
2
|
+
import { BaseCustomInputProps, Field, useStandaloneInput } from '@chem-po/react'
|
|
3
3
|
import React, { ForwardedRef, forwardRef } from 'react'
|
|
4
|
-
import {
|
|
4
|
+
import { TextStyle, ViewStyle } from 'react-native'
|
|
5
5
|
import { Input } from './input'
|
|
6
6
|
|
|
7
7
|
interface StandaloneInputProps<
|
|
8
8
|
T extends Field,
|
|
9
9
|
ContainerStyle extends ViewStyle = ViewStyle,
|
|
10
10
|
InputStyle extends TextStyle = TextStyle,
|
|
11
|
-
> {
|
|
12
|
-
onChange: (v?: any) => void
|
|
13
|
-
value?: any
|
|
11
|
+
> extends BaseCustomInputProps<T['defaultValue'], ContainerStyle, InputStyle> {
|
|
14
12
|
field: T
|
|
15
|
-
onBlur?: () => void
|
|
16
|
-
onFocus?: () => void
|
|
17
|
-
theme?: 'basic' | 'detailed'
|
|
18
|
-
inEditable?: boolean
|
|
19
|
-
style?: StyleProp<ContainerStyle>
|
|
20
|
-
inputStyle?: StyleProp<InputStyle>
|
|
21
|
-
size?: InputSize
|
|
22
13
|
}
|
|
23
14
|
|
|
24
15
|
const StandaloneInputBase = <
|
|
@@ -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}
|
|
@@ -102,13 +102,21 @@ const BaseMultipleSelectComponent = <T extends MultipleSelectField>(
|
|
|
102
102
|
)
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
const selectedOptions = useMemo(() => {
|
|
106
|
+
return options.filter(o => value?.includes(o.value))
|
|
107
|
+
}, [options, value])
|
|
108
|
+
|
|
105
109
|
return (
|
|
106
110
|
<View style={[styles.wrapper]}>
|
|
107
111
|
<MultiSelect
|
|
108
112
|
ref={inputRef}
|
|
109
113
|
style={[inputStyles, { borderColor }]}
|
|
110
114
|
placeholderStyle={[text, { color: value?.length ? textColor : placeholderColor }]}
|
|
111
|
-
containerStyle={{
|
|
115
|
+
containerStyle={{
|
|
116
|
+
backgroundColor: menuBg,
|
|
117
|
+
boxShadow: `0 0 10px ${borderColor}`,
|
|
118
|
+
borderWidth: 0,
|
|
119
|
+
}}
|
|
112
120
|
inputSearchStyle={[styles.inputSearch, text, { backgroundColor: inputBg, borderWidth: 0 }]}
|
|
113
121
|
iconStyle={styles.iconStyle}
|
|
114
122
|
data={options}
|
|
@@ -117,7 +125,9 @@ const BaseMultipleSelectComponent = <T extends MultipleSelectField>(
|
|
|
117
125
|
maxHeight={300}
|
|
118
126
|
labelField="label"
|
|
119
127
|
valueField="value"
|
|
120
|
-
placeholder={
|
|
128
|
+
placeholder={
|
|
129
|
+
selectedOptions.length ? selectedOptions.map(v => v.label).join(', ') : placeholder
|
|
130
|
+
}
|
|
121
131
|
searchPlaceholder={searchPlaceholder ?? placeholder}
|
|
122
132
|
value={value ?? []}
|
|
123
133
|
onChange={updated => {
|
|
@@ -198,6 +208,7 @@ const styles = StyleSheet.create({
|
|
|
198
208
|
borderWidth: 1,
|
|
199
209
|
alignItems: 'center',
|
|
200
210
|
marginTop: 4,
|
|
211
|
+
marginBottom: 4,
|
|
201
212
|
marginHorizontal: 4,
|
|
202
213
|
},
|
|
203
214
|
optionClearContainer: {
|
|
@@ -24,7 +24,7 @@ export const TextComponent = forwardRef<InputRef, FieldProps<TextField>>(
|
|
|
24
24
|
inputRef.current?.focus()
|
|
25
25
|
},
|
|
26
26
|
blur: () => {
|
|
27
|
-
inputRef.current?.
|
|
27
|
+
inputRef.current?.clear()
|
|
28
28
|
},
|
|
29
29
|
}))
|
|
30
30
|
|
|
@@ -34,7 +34,7 @@ export const TextComponent = forwardRef<InputRef, FieldProps<TextField>>(
|
|
|
34
34
|
if (type === 'textarea') {
|
|
35
35
|
return (
|
|
36
36
|
<TextAreaComponent
|
|
37
|
-
ref={
|
|
37
|
+
ref={inputRef}
|
|
38
38
|
formSize={formSize}
|
|
39
39
|
inputStyle={inputStyle}
|
|
40
40
|
inEditable={inEditable}
|
|
@@ -51,6 +51,7 @@ export const TextComponent = forwardRef<InputRef, FieldProps<TextField>>(
|
|
|
51
51
|
ref={inputRef}
|
|
52
52
|
style={[inputStyles, { color }, inputStyle]}
|
|
53
53
|
secureTextEntry={isHidden}
|
|
54
|
+
selectTextOnFocus={inEditable}
|
|
54
55
|
placeholderTextColor={placeholderColor}
|
|
55
56
|
placeholder={placeholder}
|
|
56
57
|
value={value ?? ''}
|
|
@@ -1,33 +1,21 @@
|
|
|
1
|
-
import { InputRef } from '@chem-po/core'
|
|
2
1
|
import { TextField, usePlaceholderColor, useTextColor } from '@chem-po/react'
|
|
3
|
-
import React, { forwardRef
|
|
2
|
+
import React, { forwardRef } from 'react'
|
|
4
3
|
import { TextInput, View } from 'react-native'
|
|
5
4
|
import { FieldProps } from '../../types'
|
|
6
5
|
import { useInputStyles } from '../hooks/useInputStyles'
|
|
7
6
|
import { AutoResizeTextarea } from './AutoResizeTextarea'
|
|
8
7
|
|
|
9
|
-
export const TextAreaComponent = forwardRef<
|
|
8
|
+
export const TextAreaComponent = forwardRef<TextInput, FieldProps<TextField>>(
|
|
10
9
|
({ input, field, inEditable, formSize, inputStyle, style }, ref) => {
|
|
11
|
-
const inputRef = useRef<TextInput>(null)
|
|
12
10
|
const { text, container } = useInputStyles(inEditable, field.size, formSize)
|
|
13
11
|
const { value, onChange, ...inputProps } = input
|
|
14
|
-
|
|
15
|
-
useImperativeHandle(ref, () => ({
|
|
16
|
-
focus: () => {
|
|
17
|
-
inputRef.current?.focus()
|
|
18
|
-
},
|
|
19
|
-
blur: () => {
|
|
20
|
-
inputRef.current?.blur()
|
|
21
|
-
},
|
|
22
|
-
}))
|
|
23
|
-
|
|
24
12
|
const placeholderColor = usePlaceholderColor()
|
|
25
13
|
const color = useTextColor()
|
|
26
14
|
|
|
27
15
|
return (
|
|
28
16
|
<View style={[container, style]}>
|
|
29
17
|
<AutoResizeTextarea
|
|
30
|
-
ref={
|
|
18
|
+
ref={ref}
|
|
31
19
|
style={[{ color, ...text }, inputStyle]}
|
|
32
20
|
placeholder={field.placeholder}
|
|
33
21
|
placeholderTextColor={placeholderColor}
|
|
@@ -38,25 +38,24 @@ export const useWebAutoResize = (
|
|
|
38
38
|
onChangeText: ((e: string) => void) | undefined,
|
|
39
39
|
style: StyleProp<TextStyle> | undefined,
|
|
40
40
|
) => {
|
|
41
|
-
const
|
|
41
|
+
const flattenedStyle = useMemo(() => StyleSheet.flatten(style), [style])
|
|
42
|
+
const [height, setHeight] = useState((flattenedStyle.fontSize ?? 18) + 4)
|
|
42
43
|
const spanRef = useRef<HTMLSpanElement>(
|
|
43
44
|
Platform.OS === 'web' ? document.createElement('span') : null,
|
|
44
45
|
)
|
|
45
46
|
|
|
46
47
|
useEffect(() => {
|
|
47
48
|
if (Platform.OS === 'web' && spanRef.current) {
|
|
48
|
-
updateSpanStyle(spanRef.current,
|
|
49
|
-
...StyleSheet.flatten(style),
|
|
50
|
-
})
|
|
49
|
+
updateSpanStyle(spanRef.current, flattenedStyle)
|
|
51
50
|
}
|
|
52
|
-
}, [
|
|
51
|
+
}, [flattenedStyle])
|
|
53
52
|
const handleChange = useMemo(
|
|
54
53
|
() =>
|
|
55
54
|
Platform.OS === 'web'
|
|
56
55
|
? (e: string) => {
|
|
57
56
|
if (spanRef.current) {
|
|
58
57
|
const height = getWebTextHeight(e, spanRef)
|
|
59
|
-
setHeight(height ?? 18)
|
|
58
|
+
setHeight((height ?? 18) + 4)
|
|
60
59
|
if (onChangeText) onChangeText(e)
|
|
61
60
|
}
|
|
62
61
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { ImageViewOptions, InputSize } from '@chem-po/core'
|
|
2
|
-
import { FileField } from '@chem-po/react'
|
|
2
|
+
import { FileField, usePlaceholderColor } from '@chem-po/react'
|
|
3
3
|
import React, { useMemo } from 'react'
|
|
4
4
|
import { StyleSheet, Text, View, ViewStyle } from 'react-native'
|
|
5
|
+
import { Txt } from '../../text/Txt'
|
|
5
6
|
import { FileView } from '../input/file'
|
|
7
|
+
import { useInputStyles } from '../input/hooks/useInputStyles'
|
|
6
8
|
|
|
7
9
|
const styles = StyleSheet.create({
|
|
8
10
|
container: {
|
|
@@ -16,9 +18,6 @@ const styles = StyleSheet.create({
|
|
|
16
18
|
opacity: 0.7,
|
|
17
19
|
fontWeight: '600',
|
|
18
20
|
},
|
|
19
|
-
emptyText: {
|
|
20
|
-
opacity: 0.7,
|
|
21
|
-
},
|
|
22
21
|
fileContainer: {
|
|
23
22
|
padding: 4,
|
|
24
23
|
},
|
|
@@ -59,6 +58,9 @@ export const FileFieldView = ({
|
|
|
59
58
|
[imageOptions, size, sizeProp],
|
|
60
59
|
)
|
|
61
60
|
|
|
61
|
+
const { text, container } = useInputStyles(false, field.size, sizeProp)
|
|
62
|
+
const placeholderColor = usePlaceholderColor()
|
|
63
|
+
|
|
62
64
|
return (
|
|
63
65
|
<View style={[value ? styles.container : styles.rowContainer, style]}>
|
|
64
66
|
{!noLabel && <Text style={styles.label}>{placeholder}</Text>}
|
|
@@ -67,7 +69,9 @@ export const FileFieldView = ({
|
|
|
67
69
|
<FileView imageOptions={options} value={value} />
|
|
68
70
|
</View>
|
|
69
71
|
) : (
|
|
70
|
-
<
|
|
72
|
+
<View style={container}>
|
|
73
|
+
<Txt style={[text, { color: placeholderColor }]}>None</Txt>
|
|
74
|
+
</View>
|
|
71
75
|
)}
|
|
72
76
|
</View>
|
|
73
77
|
)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { displayField, InputSize } from '@chem-po/core'
|
|
2
|
-
import { Field, FormatField } from '@chem-po/react'
|
|
2
|
+
import { Field, FormatField, usePlaceholderColor } from '@chem-po/react'
|
|
3
3
|
import React, { useMemo } from 'react'
|
|
4
4
|
import { StyleSheet, View, ViewStyle } from 'react-native'
|
|
5
5
|
import { Txt } from '../../text'
|
|
@@ -22,30 +22,33 @@ const DefaultFieldView = ({
|
|
|
22
22
|
noLabel,
|
|
23
23
|
style,
|
|
24
24
|
size: sizeProp,
|
|
25
|
+
inEditable,
|
|
25
26
|
}: {
|
|
26
27
|
field: Field
|
|
27
28
|
value: any
|
|
28
29
|
noLabel?: boolean
|
|
29
30
|
style?: ViewStyle
|
|
30
31
|
size?: InputSize
|
|
32
|
+
inEditable?: boolean
|
|
31
33
|
}) => {
|
|
32
34
|
const { placeholder } = field
|
|
33
35
|
|
|
34
|
-
const { text } = useInputStyles(
|
|
36
|
+
const { text, container: containerStyles } = useInputStyles(inEditable, field.size, sizeProp)
|
|
35
37
|
const formatted = useMemo(() => {
|
|
36
38
|
const format = displayField[field._type] as FormatField<Field>
|
|
37
39
|
if (!format) return value
|
|
38
40
|
return format(field, value)
|
|
39
41
|
}, [value, field])
|
|
40
42
|
|
|
43
|
+
const placeholderColor = usePlaceholderColor()
|
|
41
44
|
const hasValue = useMemo(() => {
|
|
42
45
|
return value !== null && value !== undefined && value !== ''
|
|
43
46
|
}, [value])
|
|
44
47
|
|
|
45
48
|
return (
|
|
46
|
-
<View style={[styles.container, style]}>
|
|
49
|
+
<View style={[styles.container, containerStyles, { backgroundColor: 'transparent' }, style]}>
|
|
47
50
|
{!noLabel && <Txt style={[inputViewStyles.label, text]}>{placeholder}</Txt>}
|
|
48
|
-
<Txt style={[hasValue ?
|
|
51
|
+
<Txt style={[text, { color: hasValue ? undefined : placeholderColor }]}>
|
|
49
52
|
{hasValue ? formatted : 'None'}
|
|
50
53
|
</Txt>
|
|
51
54
|
</View>
|
|
@@ -58,17 +61,26 @@ export const FieldView = ({
|
|
|
58
61
|
noLabel,
|
|
59
62
|
style,
|
|
60
63
|
size,
|
|
64
|
+
inEditable,
|
|
61
65
|
}: {
|
|
62
66
|
field: Field
|
|
63
|
-
value
|
|
67
|
+
value?: any
|
|
64
68
|
noLabel?: boolean
|
|
65
69
|
style?: ViewStyle
|
|
66
70
|
size?: InputSize
|
|
71
|
+
inEditable?: boolean
|
|
67
72
|
}) => {
|
|
68
73
|
switch (field._type) {
|
|
69
74
|
case 'select':
|
|
70
75
|
return (
|
|
71
|
-
<SelectFieldView
|
|
76
|
+
<SelectFieldView
|
|
77
|
+
style={style}
|
|
78
|
+
field={field}
|
|
79
|
+
value={value}
|
|
80
|
+
noLabel={noLabel}
|
|
81
|
+
size={size}
|
|
82
|
+
inEditable={inEditable}
|
|
83
|
+
/>
|
|
72
84
|
)
|
|
73
85
|
case 'multipleSelect':
|
|
74
86
|
return (
|
|
@@ -86,7 +98,14 @@ export const FieldView = ({
|
|
|
86
98
|
)
|
|
87
99
|
default:
|
|
88
100
|
return (
|
|
89
|
-
<DefaultFieldView
|
|
101
|
+
<DefaultFieldView
|
|
102
|
+
style={style}
|
|
103
|
+
field={field}
|
|
104
|
+
value={value}
|
|
105
|
+
noLabel={noLabel}
|
|
106
|
+
size={size}
|
|
107
|
+
inEditable={inEditable}
|
|
108
|
+
/>
|
|
90
109
|
)
|
|
91
110
|
}
|
|
92
111
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { InputSize } from '@chem-po/core'
|
|
2
|
-
import { MultipleSelectField, useColorMode } from '@chem-po/react'
|
|
2
|
+
import { MultipleSelectField, useColorMode, usePlaceholderColor } from '@chem-po/react'
|
|
3
3
|
import { useMemo } from 'react'
|
|
4
4
|
import React, { StyleSheet, Text, View, ViewStyle } from 'react-native'
|
|
5
|
+
import { Txt } from '../../text/Txt'
|
|
5
6
|
import { useInputStyles } from '../input/hooks/useInputStyles'
|
|
6
7
|
import { SelectedOptionContainer } from '../input/multipleSelect'
|
|
7
8
|
import { DefaultRenderOption } from './select'
|
|
@@ -12,6 +13,7 @@ const styles = StyleSheet.create({
|
|
|
12
13
|
flexWrap: 'wrap',
|
|
13
14
|
alignItems: 'center',
|
|
14
15
|
maxWidth: '100%',
|
|
16
|
+
backgroundColor: 'transparent',
|
|
15
17
|
},
|
|
16
18
|
label: {
|
|
17
19
|
paddingRight: 8,
|
|
@@ -27,9 +29,6 @@ const styles = StyleSheet.create({
|
|
|
27
29
|
marginTop: 2,
|
|
28
30
|
marginHorizontal: 2,
|
|
29
31
|
},
|
|
30
|
-
emptyText: {
|
|
31
|
-
opacity: 0.6,
|
|
32
|
-
},
|
|
33
32
|
})
|
|
34
33
|
|
|
35
34
|
export const MultipleSelectFieldView = <F extends MultipleSelectField>({
|
|
@@ -48,13 +47,14 @@ export const MultipleSelectFieldView = <F extends MultipleSelectField>({
|
|
|
48
47
|
const { placeholder, renderOption: customRender, options } = field
|
|
49
48
|
const selectedOptions = options.filter(o => value?.includes(o.value))
|
|
50
49
|
const colorMode = useColorMode()
|
|
51
|
-
const { size,
|
|
50
|
+
const { size, text, container } = useInputStyles(true, field.size, sizeProp)
|
|
51
|
+
const placeholderColor = usePlaceholderColor()
|
|
52
52
|
const selectedOptionStyle = useMemo<ViewStyle>(() => {
|
|
53
53
|
return {
|
|
54
|
-
paddingHorizontal:
|
|
55
|
-
paddingVertical:
|
|
54
|
+
paddingHorizontal: container.paddingHorizontal,
|
|
55
|
+
paddingVertical: container.paddingVertical,
|
|
56
56
|
}
|
|
57
|
-
}, [
|
|
57
|
+
}, [container])
|
|
58
58
|
const RenderOption = useMemo(() => customRender ?? DefaultRenderOption, [customRender])
|
|
59
59
|
return (
|
|
60
60
|
<View style={[styles.container, style]}>
|
|
@@ -74,7 +74,9 @@ export const MultipleSelectFieldView = <F extends MultipleSelectField>({
|
|
|
74
74
|
))}
|
|
75
75
|
</View>
|
|
76
76
|
) : (
|
|
77
|
-
<
|
|
77
|
+
<View style={container}>
|
|
78
|
+
<Txt style={[text, { color: placeholderColor }]}>None</Txt>
|
|
79
|
+
</View>
|
|
78
80
|
)}
|
|
79
81
|
</View>
|
|
80
82
|
)
|
|
@@ -10,6 +10,7 @@ const styles = StyleSheet.create({
|
|
|
10
10
|
container: {
|
|
11
11
|
flexDirection: 'row',
|
|
12
12
|
alignItems: 'center',
|
|
13
|
+
backgroundColor: 'transparent',
|
|
13
14
|
},
|
|
14
15
|
label: {
|
|
15
16
|
paddingRight: 10,
|
|
@@ -32,17 +33,19 @@ export const SelectFieldView = ({
|
|
|
32
33
|
noLabel,
|
|
33
34
|
style,
|
|
34
35
|
size: sizeProp,
|
|
36
|
+
inEditable,
|
|
35
37
|
}: {
|
|
36
38
|
field: SelectField
|
|
37
39
|
value: any
|
|
38
40
|
noLabel?: boolean
|
|
39
41
|
style?: ViewStyle
|
|
40
42
|
size?: InputSize
|
|
43
|
+
inEditable?: boolean
|
|
41
44
|
}) => {
|
|
42
45
|
const { placeholder, renderOption: customRender } = field
|
|
43
46
|
const colorMode = useColorMode()
|
|
44
47
|
const placeholderColor = usePlaceholderColor()
|
|
45
|
-
const { size, text } = useInputStyles(
|
|
48
|
+
const { size, text, container } = useInputStyles(inEditable, field.size, sizeProp)
|
|
46
49
|
const selectedOption = field.options.find(o => o.value === value)
|
|
47
50
|
const RenderOption = customRender ?? DefaultRenderOption
|
|
48
51
|
return (
|
|
@@ -59,7 +62,9 @@ export const SelectFieldView = ({
|
|
|
59
62
|
size={size}
|
|
60
63
|
/>
|
|
61
64
|
) : (
|
|
62
|
-
<
|
|
65
|
+
<View style={container}>
|
|
66
|
+
<Txt style={[text, { color: placeholderColor }]}>None</Txt>
|
|
67
|
+
</View>
|
|
63
68
|
)}
|
|
64
69
|
</View>
|
|
65
70
|
)
|