@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.
Files changed (122) hide show
  1. package/lib/commonjs/components/button/Toggle.js +19 -16
  2. package/lib/commonjs/components/button/Toggle.js.map +1 -1
  3. package/lib/commonjs/components/form/input/Editable.js +52 -73
  4. package/lib/commonjs/components/form/input/Editable.js.map +1 -1
  5. package/lib/commonjs/components/form/input/StandaloneInput.js.map +1 -1
  6. package/lib/commonjs/components/form/input/datetime/index.js +7 -2
  7. package/lib/commonjs/components/form/input/datetime/index.js.map +1 -1
  8. package/lib/commonjs/components/form/input/multipleSelect/index.js +7 -2
  9. package/lib/commonjs/components/form/input/multipleSelect/index.js.map +1 -1
  10. package/lib/commonjs/components/form/input/select/index.js +1 -1
  11. package/lib/commonjs/components/form/input/select/index.js.map +1 -1
  12. package/lib/commonjs/components/form/input/text/index.js +3 -2
  13. package/lib/commonjs/components/form/input/text/index.js.map +1 -1
  14. package/lib/commonjs/components/form/input/text/textarea.js +1 -12
  15. package/lib/commonjs/components/form/input/text/textarea.js.map +1 -1
  16. package/lib/commonjs/components/form/input/text/useWebAutoResize.js +5 -6
  17. package/lib/commonjs/components/form/input/text/useWebAutoResize.js.map +1 -1
  18. package/lib/commonjs/components/form/view/file.js +21 -12
  19. package/lib/commonjs/components/form/view/file.js.map +1 -1
  20. package/lib/commonjs/components/form/view/index.js +29 -18
  21. package/lib/commonjs/components/form/view/index.js.map +1 -1
  22. package/lib/commonjs/components/form/view/multipleSelect.js +17 -13
  23. package/lib/commonjs/components/form/view/multipleSelect.js.map +1 -1
  24. package/lib/commonjs/components/form/view/select.js +14 -7
  25. package/lib/commonjs/components/form/view/select.js.map +1 -1
  26. package/lib/commonjs/components/form/view/styles.js +0 -3
  27. package/lib/commonjs/components/form/view/styles.js.map +1 -1
  28. package/lib/commonjs/components/layout/CollapseHorizontal.js +72 -0
  29. package/lib/commonjs/components/layout/CollapseHorizontal.js.map +1 -0
  30. package/lib/commonjs/contexts/root.js +6 -6
  31. package/lib/commonjs/contexts/root.js.map +1 -1
  32. package/lib/commonjs/index.js +11 -0
  33. package/lib/commonjs/index.js.map +1 -1
  34. package/lib/commonjs/types/forms.js +6 -0
  35. package/lib/commonjs/types/forms.js.map +1 -0
  36. package/lib/commonjs/types/index.js +17 -0
  37. package/lib/commonjs/types/index.js.map +1 -0
  38. package/lib/module/components/button/Toggle.js +21 -18
  39. package/lib/module/components/button/Toggle.js.map +1 -1
  40. package/lib/module/components/form/input/Editable.js +52 -73
  41. package/lib/module/components/form/input/Editable.js.map +1 -1
  42. package/lib/module/components/form/input/StandaloneInput.js.map +1 -1
  43. package/lib/module/components/form/input/datetime/index.js +7 -2
  44. package/lib/module/components/form/input/datetime/index.js.map +1 -1
  45. package/lib/module/components/form/input/multipleSelect/index.js +7 -2
  46. package/lib/module/components/form/input/multipleSelect/index.js.map +1 -1
  47. package/lib/module/components/form/input/select/index.js +1 -1
  48. package/lib/module/components/form/input/select/index.js.map +1 -1
  49. package/lib/module/components/form/input/text/index.js +3 -2
  50. package/lib/module/components/form/input/text/index.js.map +1 -1
  51. package/lib/module/components/form/input/text/textarea.js +2 -13
  52. package/lib/module/components/form/input/text/textarea.js.map +1 -1
  53. package/lib/module/components/form/input/text/useWebAutoResize.js +5 -6
  54. package/lib/module/components/form/input/text/useWebAutoResize.js.map +1 -1
  55. package/lib/module/components/form/view/file.js +15 -6
  56. package/lib/module/components/form/view/file.js.map +1 -1
  57. package/lib/module/components/form/view/index.js +19 -8
  58. package/lib/module/components/form/view/index.js.map +1 -1
  59. package/lib/module/components/form/view/multipleSelect.js +18 -14
  60. package/lib/module/components/form/view/multipleSelect.js.map +1 -1
  61. package/lib/module/components/form/view/select.js +14 -7
  62. package/lib/module/components/form/view/select.js.map +1 -1
  63. package/lib/module/components/form/view/styles.js +0 -3
  64. package/lib/module/components/form/view/styles.js.map +1 -1
  65. package/lib/module/components/layout/CollapseHorizontal.js +64 -0
  66. package/lib/module/components/layout/CollapseHorizontal.js.map +1 -0
  67. package/lib/module/contexts/root.js +6 -6
  68. package/lib/module/contexts/root.js.map +1 -1
  69. package/lib/module/index.js +1 -0
  70. package/lib/module/index.js.map +1 -1
  71. package/lib/module/types/forms.js +2 -0
  72. package/lib/module/types/forms.js.map +1 -0
  73. package/lib/module/types/index.js +2 -0
  74. package/lib/module/types/index.js.map +1 -0
  75. package/lib/typescript/components/button/Toggle.d.ts +5 -2
  76. package/lib/typescript/components/button/Toggle.d.ts.map +1 -1
  77. package/lib/typescript/components/form/input/Editable.d.ts +2 -2
  78. package/lib/typescript/components/form/input/Editable.d.ts.map +1 -1
  79. package/lib/typescript/components/form/input/StandaloneInput.d.ts +5 -14
  80. package/lib/typescript/components/form/input/StandaloneInput.d.ts.map +1 -1
  81. package/lib/typescript/components/form/input/datetime/index.d.ts.map +1 -1
  82. package/lib/typescript/components/form/input/multipleSelect/index.d.ts.map +1 -1
  83. package/lib/typescript/components/form/input/text/index.d.ts.map +1 -1
  84. package/lib/typescript/components/form/input/text/textarea.d.ts +2 -2
  85. package/lib/typescript/components/form/input/text/textarea.d.ts.map +1 -1
  86. package/lib/typescript/components/form/input/text/useWebAutoResize.d.ts.map +1 -1
  87. package/lib/typescript/components/form/view/file.d.ts.map +1 -1
  88. package/lib/typescript/components/form/view/index.d.ts +3 -2
  89. package/lib/typescript/components/form/view/index.d.ts.map +1 -1
  90. package/lib/typescript/components/form/view/multipleSelect.d.ts.map +1 -1
  91. package/lib/typescript/components/form/view/select.d.ts +2 -1
  92. package/lib/typescript/components/form/view/select.d.ts.map +1 -1
  93. package/lib/typescript/components/form/view/styles.d.ts +0 -3
  94. package/lib/typescript/components/form/view/styles.d.ts.map +1 -1
  95. package/lib/typescript/components/layout/CollapseHorizontal.d.ts +9 -0
  96. package/lib/typescript/components/layout/CollapseHorizontal.d.ts.map +1 -0
  97. package/lib/typescript/index.d.ts +1 -0
  98. package/lib/typescript/index.d.ts.map +1 -1
  99. package/lib/typescript/types/forms.d.ts +5 -0
  100. package/lib/typescript/types/forms.d.ts.map +1 -0
  101. package/lib/typescript/types/index.d.ts +2 -0
  102. package/lib/typescript/types/index.d.ts.map +1 -0
  103. package/package.json +3 -3
  104. package/src/components/button/Toggle.tsx +21 -17
  105. package/src/components/form/input/Editable.tsx +47 -86
  106. package/src/components/form/input/StandaloneInput.tsx +4 -13
  107. package/src/components/form/input/datetime/index.tsx +7 -2
  108. package/src/components/form/input/multipleSelect/index.tsx +13 -2
  109. package/src/components/form/input/select/index.tsx +1 -1
  110. package/src/components/form/input/text/index.tsx +3 -2
  111. package/src/components/form/input/text/textarea.tsx +3 -15
  112. package/src/components/form/input/text/useWebAutoResize.tsx +5 -6
  113. package/src/components/form/view/file.tsx +9 -5
  114. package/src/components/form/view/index.tsx +26 -7
  115. package/src/components/form/view/multipleSelect.tsx +11 -9
  116. package/src/components/form/view/select.tsx +7 -2
  117. package/src/components/form/view/styles.ts +0 -3
  118. package/src/components/layout/CollapseHorizontal.tsx +82 -0
  119. package/src/contexts/root.tsx +6 -6
  120. package/src/index.ts +1 -0
  121. package/src/types/forms.ts +14 -0
  122. 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
- }: EditableProps<ViewStyle, T>) => {
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 handleBlur = useCallback(() => {
94
- switch (field._type) {
95
- case 'select':
96
- case 'date':
97
- case 'time':
98
- case 'datetime':
99
- handleEditClose()
100
- break
101
- default:
102
- break
103
- }
104
- }, [field, handleEditClose])
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 editableField = useMemo(
107
- () => ({
108
- ...field,
109
- // optional: false,
110
- }),
111
- [field],
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
- <StandaloneInput
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
- <FieldView noLabel style={style} size={size} field={field} value={value} />
121
+ <RenderView inEditable noLabel size={size} value={value} />
145
122
  )}
146
123
  </View>
147
124
  {!alwaysEditing && (
148
125
  <View style={styles.buttonsContainer}>
149
- {isEditing ? null : (
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
- {noCloseButton || !isEditing ? null : (
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
- </View>
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
- alignItems: 'center',
206
- gap: 4,
207
- marginLeft: 5,
171
+ justifyContent: 'center',
172
+ paddingTop: 6,
208
173
  },
209
174
  contentContainer: {
210
175
  flexDirection: 'row',
211
- alignItems: 'center',
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
- justifyContent: 'center',
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, InputSize } from '@chem-po/core'
2
- import { Field, useStandaloneInput } from '@chem-po/react'
1
+ import { InputRef } from '@chem-po/core'
2
+ import { BaseCustomInputProps, Field, useStandaloneInput } from '@chem-po/react'
3
3
  import React, { ForwardedRef, forwardRef } from 'react'
4
- import { StyleProp, TextStyle, ViewStyle } from 'react-native'
4
+ import { TextStyle, ViewStyle } from 'react-native'
5
5
  import { Input } from './input'
6
6
 
7
7
  interface StandaloneInputProps<
8
8
  T extends Field,
9
9
  ContainerStyle extends ViewStyle = ViewStyle,
10
10
  InputStyle extends TextStyle = TextStyle,
11
- > {
12
- onChange: (v?: any) => void
13
- value?: any
11
+ > extends BaseCustomInputProps<T['defaultValue'], ContainerStyle, InputStyle> {
14
12
  field: T
15
- onBlur?: () => void
16
- onFocus?: () => void
17
- theme?: 'basic' | 'detailed'
18
- inEditable?: boolean
19
- style?: StyleProp<ContainerStyle>
20
- inputStyle?: StyleProp<InputStyle>
21
- size?: InputSize
22
13
  }
23
14
 
24
15
  const StandaloneInputBase = <
@@ -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
- <Ionicons name="calendar" size={iconSize} color={iconColor} />
99
- <Ionicons name="time" size={iconSize} color={iconColor} />
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={{ backgroundColor: menuBg, boxShadow: `0 0 10px ${borderColor}` }}
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={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: {
@@ -120,7 +120,7 @@ const BaseSelectComponent = <T extends SelectField>(
120
120
  size={iconSize}
121
121
  color={iconColor}
122
122
  />
123
- {optional && value && !inEditable ? (
123
+ {optional && value ? (
124
124
  <InputClearButton
125
125
  size={clearButtonSize}
126
126
  onPress={() => {
@@ -24,7 +24,7 @@ export const TextComponent = forwardRef<InputRef, FieldProps<TextField>>(
24
24
  inputRef.current?.focus()
25
25
  },
26
26
  blur: () => {
27
- inputRef.current?.blur()
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={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, useImperativeHandle, useRef } from 'react'
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<InputRef, FieldProps<TextField>>(
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={inputRef}
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 [height, setHeight] = useState(18)
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
- }, [style])
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
- <Text style={styles.emptyText}>None</Text>
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(false, field.size, sizeProp)
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 ? inputViewStyles.value : inputViewStyles.valueEmpty, text]}>
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: any
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 style={style} field={field} value={value} noLabel={noLabel} size={size} />
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 style={style} field={field} value={value} noLabel={noLabel} size={size} />
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, container: inputStyles, text } = useInputStyles(undefined, field.size, sizeProp)
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: inputStyles.paddingHorizontal,
55
- paddingVertical: inputStyles.paddingVertical,
54
+ paddingHorizontal: container.paddingHorizontal,
55
+ paddingVertical: container.paddingVertical,
56
56
  }
57
- }, [inputStyles])
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
- <Text style={[styles.emptyText, text]}>None</Text>
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(false, field.size, sizeProp)
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
- <Txt style={inputViewStyles.valueEmpty}>None</Txt>
65
+ <View style={container}>
66
+ <Txt style={[text, { color: placeholderColor }]}>None</Txt>
67
+ </View>
63
68
  )}
64
69
  </View>
65
70
  )