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