@chem-po/react-native 0.0.52 → 0.0.53

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 (98) hide show
  1. package/package.json +5 -20
  2. package/src/components/box/Center.tsx +0 -19
  3. package/src/components/box/CollapseHorizontal.tsx +0 -44
  4. package/src/components/box/ContentBox.tsx +0 -24
  5. package/src/components/box/DropShadow.tsx +0 -28
  6. package/src/components/box/ExpandOnMount.tsx +0 -74
  7. package/src/components/box/Expandable.tsx +0 -143
  8. package/src/components/box/FullSizeContainer.tsx +0 -64
  9. package/src/components/box/index.ts +0 -7
  10. package/src/components/button/ActionButton.tsx +0 -196
  11. package/src/components/button/ButtonText.tsx +0 -60
  12. package/src/components/button/DeleteButton.tsx +0 -288
  13. package/src/components/button/LoadingButton.tsx +0 -41
  14. package/src/components/button/Toggle.tsx +0 -109
  15. package/src/components/button/hooks.ts +0 -66
  16. package/src/components/button/index.ts +0 -5
  17. package/src/components/feed/FeedContentPane.tsx +0 -97
  18. package/src/components/feed/MediaFeed.tsx +0 -199
  19. package/src/components/feed/MediaFeedBackground.tsx +0 -136
  20. package/src/components/feed/MediaFeedRefresh.tsx +0 -113
  21. package/src/components/feed/constants.ts +0 -2
  22. package/src/components/feed/context.tsx +0 -19
  23. package/src/components/feed/hooks.ts +0 -279
  24. package/src/components/feed/index.ts +0 -2
  25. package/src/components/form/Condition.tsx +0 -27
  26. package/src/components/form/Field.tsx +0 -44
  27. package/src/components/form/Form.tsx +0 -452
  28. package/src/components/form/FormFooter.tsx +0 -164
  29. package/src/components/form/UploadProgress/index.tsx +0 -50
  30. package/src/components/form/index.ts +0 -3
  31. package/src/components/form/input/Editable.tsx +0 -206
  32. package/src/components/form/input/InputSlider.tsx +0 -71
  33. package/src/components/form/input/OptionalTag.tsx +0 -43
  34. package/src/components/form/input/StandaloneInput.tsx +0 -49
  35. package/src/components/form/input/boolean/index.tsx +0 -53
  36. package/src/components/form/input/color/index.tsx +0 -145
  37. package/src/components/form/input/common/InputClearButton.tsx +0 -57
  38. package/src/components/form/input/date/index.tsx +0 -125
  39. package/src/components/form/input/datetime/index.tsx +0 -176
  40. package/src/components/form/input/file/index.tsx +0 -310
  41. package/src/components/form/input/hooks/index.ts +0 -2
  42. package/src/components/form/input/hooks/useInputColor.ts +0 -7
  43. package/src/components/form/input/hooks/useInputImperativeHandle.ts +0 -22
  44. package/src/components/form/input/hooks/useInputStyles.ts +0 -114
  45. package/src/components/form/input/index.ts +0 -4
  46. package/src/components/form/input/input.tsx +0 -218
  47. package/src/components/form/input/multipleSelect/index.tsx +0 -221
  48. package/src/components/form/input/number/index.tsx +0 -108
  49. package/src/components/form/input/select/index.tsx +0 -152
  50. package/src/components/form/input/socialMedia/index.tsx +0 -235
  51. package/src/components/form/input/text/AutoResizeTextarea.tsx +0 -41
  52. package/src/components/form/input/text/index.tsx +0 -99
  53. package/src/components/form/input/text/textarea.tsx +0 -32
  54. package/src/components/form/input/text/useWebAutoResize.tsx +0 -73
  55. package/src/components/form/input/time/index.tsx +0 -125
  56. package/src/components/form/types.ts +0 -8
  57. package/src/components/form/view/file.tsx +0 -80
  58. package/src/components/form/view/index.tsx +0 -125
  59. package/src/components/form/view/multipleSelect.tsx +0 -85
  60. package/src/components/form/view/select.tsx +0 -83
  61. package/src/components/form/view/styles.ts +0 -12
  62. package/src/components/icons/index.tsx +0 -28
  63. package/src/components/image/ImageViewModal.tsx +0 -319
  64. package/src/components/image/index.ts +0 -1
  65. package/src/components/index.ts +0 -8
  66. package/src/components/layout/CollapseHorizontal.tsx +0 -92
  67. package/src/components/loading/CircularProgress.tsx +0 -56
  68. package/src/components/loading/Loading.tsx +0 -146
  69. package/src/components/loading/LoadingImage.tsx +0 -163
  70. package/src/components/loading/LoadingOverlay.tsx +0 -74
  71. package/src/components/loading/LoadingSwitch.tsx +0 -110
  72. package/src/components/loading/ProgressBar.tsx +0 -75
  73. package/src/components/loading/index.ts +0 -6
  74. package/src/components/text/AnimatedText.tsx +0 -68
  75. package/src/components/text/Txt.tsx +0 -12
  76. package/src/components/text/index.ts +0 -1
  77. package/src/components/theme/colorMode/DarkModeToggle.tsx +0 -47
  78. package/src/components/theme/colorMode/index.ts +0 -1
  79. package/src/components/theme/index.ts +0 -1
  80. package/src/constants/index.ts +0 -1
  81. package/src/constants/toast.ts +0 -24
  82. package/src/contexts/fonts.tsx +0 -23
  83. package/src/contexts/index.ts +0 -1
  84. package/src/contexts/root.tsx +0 -190
  85. package/src/hooks/index.ts +0 -3
  86. package/src/hooks/useFadeIn.ts +0 -48
  87. package/src/hooks/useFont.ts +0 -25
  88. package/src/hooks/useRefreshFontScale.ts +0 -39
  89. package/src/hooks/useThemeState.ts +0 -43
  90. package/src/index.ts +0 -6
  91. package/src/store/index.ts +0 -2
  92. package/src/store/useFontScale.ts +0 -8
  93. package/src/store/useScreen.ts +0 -25
  94. package/src/styles/fill.ts +0 -19
  95. package/src/types/forms.ts +0 -14
  96. package/src/types/index.ts +0 -1
  97. package/src/utils/downloadFile.ts +0 -61
  98. package/src/utils/downloadFileLegacy.ts +0 -66
@@ -1,125 +0,0 @@
1
- import { getDateString, InputRef } from '@chem-po/core'
2
- import { DateField, useIconColor } from '@chem-po/react'
3
- import { Ionicons } from '@expo/vector-icons'
4
- import React, { forwardRef, useImperativeHandle, useMemo } from 'react'
5
- import { StyleSheet, Text, View } from 'react-native'
6
- import { Gesture, GestureDetector } from 'react-native-gesture-handler'
7
- import { Portal } from 'react-native-paper'
8
- import { DatePickerModal } from 'react-native-paper-dates'
9
- import { scheduleOnRN } from 'react-native-worklets'
10
- import { FieldProps } from '../../types'
11
- import { DateInputClearButton } from '../common/InputClearButton'
12
- import { useInputColor } from '../hooks/useInputColor'
13
- import { useInputStyles } from '../hooks/useInputStyles'
14
-
15
- // const parseDate = (date?: Date) =>
16
- // date
17
- // ? `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(
18
- // date.getDate(),
19
- // ).padStart(2, '0')}`
20
- // : undefined
21
-
22
- export const DateInput = forwardRef<InputRef, FieldProps<DateField>>(
23
- (
24
- {
25
- input: { onChange, value, onFocus, onBlur },
26
- field: { placeholder, minDate, maxDate, optional, size },
27
- meta: { active },
28
- formSize,
29
- inEditable,
30
- },
31
- ref,
32
- ) => {
33
- const date = useMemo(() => (value ? new Date(`${value}T00:00:00.000`) : undefined), [value])
34
- const {
35
- container: inputStyles,
36
- iconSize,
37
- text,
38
- clearButtonSize,
39
- buttonContainer,
40
- } = useInputStyles(inEditable, size, formSize)
41
-
42
- useImperativeHandle(ref, () => ({
43
- focus: () => {
44
- onFocus()
45
- },
46
- blur: () => {
47
- onBlur()
48
- },
49
- }))
50
-
51
- const iconColor = useIconColor()
52
- const inputColor = useInputColor(value)
53
-
54
- const minDateObj = minDate === 'now' ? new Date() : minDate ? new Date(minDate) : undefined
55
- const maxDateObj = maxDate === 'now' ? new Date() : maxDate ? new Date(maxDate) : undefined
56
-
57
- const mainTap = Gesture.Tap().onStart(() => {
58
- scheduleOnRN(onFocus)
59
- })
60
-
61
- return (
62
- <View style={styles.container}>
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>
72
- <View style={buttonContainer}>
73
- {optional && value ? (
74
- <DateInputClearButton
75
- size={clearButtonSize}
76
- onPress={() => onChange(null)}
77
- isActive={!!value}
78
- />
79
- ) : null}
80
- </View>
81
- </View>
82
- <Portal>
83
- <DatePickerModal
84
- locale="en"
85
- label="Date"
86
- date={date}
87
- startYear={minDateObj?.getFullYear()}
88
- endYear={maxDateObj?.getFullYear()}
89
- mode="single"
90
- onConfirm={d => {
91
- onChange(d?.date?.toISOString()?.split('T')[0] ?? null)
92
- onBlur()
93
- }}
94
- onDismiss={onBlur}
95
- visible={active}
96
- />
97
- </Portal>
98
- </View>
99
- )
100
- },
101
- )
102
-
103
- DateInput.displayName = 'DateInput'
104
-
105
- const styles = StyleSheet.create({
106
- container: {
107
- width: '100%',
108
- },
109
- button: {
110
- flexDirection: 'row',
111
- alignItems: 'center',
112
- justifyContent: 'space-between',
113
- gap: 8,
114
- width: '100%',
115
- },
116
- textContainer: {
117
- flex: 1,
118
- flexDirection: 'row',
119
- alignItems: 'center',
120
- gap: 8,
121
- },
122
- text: {
123
- flex: 1,
124
- },
125
- })
@@ -1,176 +0,0 @@
1
- import { getDateTimeString, InputRef } from '@chem-po/core'
2
- import { DateTimeField, useIconColor } from '@chem-po/react'
3
- import { Ionicons } from '@expo/vector-icons'
4
- import React, { forwardRef, useCallback, useImperativeHandle, useMemo, useState } from 'react'
5
- import { StyleSheet, Text, View } from 'react-native'
6
- import { Gesture, GestureDetector, Pressable } from 'react-native-gesture-handler'
7
- import { Portal } from 'react-native-paper'
8
- import { DatePickerModal, TimePickerModal } from 'react-native-paper-dates'
9
- import { scheduleOnRN } from 'react-native-worklets'
10
- import { FieldProps } from '../../types'
11
- import { DateInputClearButton } from '../common/InputClearButton'
12
- import { useInputColor } from '../hooks/useInputColor'
13
- import { useInputStyles } from '../hooks/useInputStyles'
14
-
15
- export const DateTimeInput = forwardRef<InputRef, FieldProps<DateTimeField>>(
16
- (
17
- { input: { value, onBlur, onChange, onFocus }, field, meta: { active }, formSize, inEditable },
18
- ref,
19
- ) => {
20
- const { placeholder, optional } = field
21
- const [showDatePicker, setShowDatePicker] = useState(true)
22
- const [showTimePicker, setShowTimePicker] = useState(false)
23
- const {
24
- container: inputStyles,
25
- iconSize,
26
- text,
27
- clearButtonSize,
28
- buttonContainer,
29
- } = useInputStyles(inEditable, field.size, formSize)
30
-
31
- const selectedDate = useMemo(() => (value ? new Date(value) : new Date()), [value])
32
- useImperativeHandle(ref, () => ({
33
- focus: () => {
34
- onFocus()
35
- },
36
- blur: () => {
37
- onBlur()
38
- },
39
- }))
40
-
41
- const handleDateChange = useCallback(
42
- (date: string | null) => {
43
- if (date) {
44
- const newDate = new Date(date)
45
- onChange(newDate.toISOString())
46
- setShowTimePicker(true)
47
- } else {
48
- onBlur()
49
- }
50
- setShowDatePicker(false)
51
- },
52
- [onChange, onBlur],
53
- )
54
-
55
- const handleTimeChange = useCallback(
56
- ({ hours, minutes }: { hours: number; minutes: number }) => {
57
- const newDate = selectedDate ? new Date(selectedDate) : new Date()
58
- newDate.setHours(hours)
59
- newDate.setMinutes(minutes)
60
- onChange(newDate.toISOString())
61
- setShowTimePicker(false)
62
- onBlur()
63
- },
64
- [onChange, onBlur, selectedDate],
65
- )
66
-
67
- const handleDismiss = useCallback(() => {
68
- setShowDatePicker(false)
69
- setShowTimePicker(false)
70
- onBlur()
71
- }, [onBlur])
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
-
83
- const date = useMemo(() => (value ? new Date(value) : undefined), [value])
84
-
85
- const formattedValue = useMemo(() => {
86
- if (!value) return null
87
- return getDateTimeString(value)
88
- }, [value])
89
-
90
- const hourMinute = useMemo(() => {
91
- if (!date) return { hours: 0, minutes: 0 }
92
- return { hours: date.getHours(), minutes: date.getMinutes() }
93
- }, [date])
94
-
95
- const iconColor = useIconColor()
96
- const inputColor = useInputColor(value)
97
-
98
- const mainTap = Gesture.Tap().onStart(() => {
99
- scheduleOnRN(handleFocusDate)
100
- })
101
-
102
- return (
103
- <View style={styles.container}>
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>
112
- <View style={buttonContainer}>
113
- <Pressable onPress={handleFocusDate}>
114
- <Ionicons name="calendar" size={iconSize} color={iconColor} />
115
- </Pressable>
116
- <Pressable onPress={handleFocusTime}>
117
- <Ionicons name="time" size={iconSize} color={iconColor} />
118
- </Pressable>
119
- {optional && value ? (
120
- <DateInputClearButton
121
- size={clearButtonSize}
122
- onPress={() => onChange(null)}
123
- isActive={!!value}
124
- />
125
- ) : null}
126
- </View>
127
- </View>
128
- <Portal>
129
- {showDatePicker && (
130
- <DatePickerModal
131
- locale="en"
132
- label="Date"
133
- date={date}
134
- mode="single"
135
- onConfirm={d => {
136
- handleDateChange(d?.date?.toISOString()?.split('T')[0] ?? null)
137
- }}
138
- onDismiss={handleDismiss}
139
- visible={active && showDatePicker}
140
- />
141
- )}
142
- {showTimePicker && (
143
- <TimePickerModal
144
- visible={active && showTimePicker}
145
- onDismiss={handleDismiss}
146
- locale="en-US"
147
- onConfirm={handleTimeChange}
148
- hours={hourMinute.hours}
149
- minutes={hourMinute.minutes}
150
- />
151
- )}
152
- </Portal>
153
- </View>
154
- )
155
- },
156
- )
157
-
158
- DateTimeInput.displayName = 'DateTimeInput'
159
-
160
- const styles = StyleSheet.create({
161
- container: {
162
- width: '100%',
163
- },
164
- button: {
165
- flexDirection: 'row',
166
- alignItems: 'center',
167
- justifyContent: 'space-between',
168
- width: '100%',
169
- },
170
- textContainer: {
171
- flex: 1,
172
- },
173
- text: {
174
- width: '100%',
175
- },
176
- })
@@ -1,310 +0,0 @@
1
- import { FileValue, ImageViewOptions, InputRef, LocalFileValue } from '@chem-po/core'
2
- import {
3
- FileField,
4
- useBackgroundColor,
5
- useBorderColor,
6
- useIconColor,
7
- useObjectUrl,
8
- usePlaceholderColor,
9
- useTextColor,
10
- useToast,
11
- } from '@chem-po/react'
12
- import { Ionicons } from '@expo/vector-icons'
13
- import * as DocumentPicker from 'expo-document-picker'
14
- import * as ImagePicker from 'expo-image-picker'
15
- import React, { forwardRef, useCallback, useImperativeHandle, useMemo } from 'react'
16
- import { Platform, StyleProp, StyleSheet, Text, TextStyle, View, ViewStyle } from 'react-native'
17
- import { Pressable } from 'react-native-gesture-handler'
18
- import { useFontScale } from '../../../../store/useFontScale'
19
- import { downloadFile } from '../../../../utils/downloadFile'
20
- import { LoadingImage } from '../../../loading/LoadingImage'
21
- import { FieldProps } from '../../types'
22
-
23
- const fallbackAccept =
24
- 'image/jpg,image/jpeg,image/png,image/svg,image/gif,application/pdf,audio/mp3,audio/wav,audio/x-wav,audio/webm,audio/ogg'
25
- const generateAccept = (field: FileField) => {
26
- if (!field.accept) return fallbackAccept
27
- const accept: string[] = []
28
- if (field.accept.includes('image')) {
29
- accept.push('image/jpg', 'image/jpeg', 'image/png', 'image/svg', 'image/gif')
30
- }
31
- if (field.accept.includes('pdf')) accept.push('application/pdf')
32
- if (field.accept.includes('audio')) {
33
- accept.push('audio/mp3', 'audio/wav', 'audio/x-wav', 'audio/webm', 'audio/ogg')
34
- }
35
- return accept.join(',')
36
- }
37
-
38
- const NoFileView = ({ hasUpload, onPress }: { hasUpload?: boolean; onPress?: () => void }) => {
39
- const textColor = useTextColor()
40
- const iconColor = useIconColor()
41
- const borderColor = useBorderColor()
42
- const fontScale = useFontScale(s => s.fontScale)
43
- return (
44
- <Pressable style={[styles.noFileContainer, { borderColor }]} onPress={onPress}>
45
- <Text style={[styles.noFileText, { color: textColor }]}>
46
- {hasUpload ? 'Tap to upload file' : 'No file uploaded'}
47
- </Text>
48
- <Ionicons name="cloud-upload" size={24 * fontScale} color={iconColor} />
49
- </Pressable>
50
- )
51
- }
52
-
53
- export const FileView = ({
54
- value,
55
- hasUpload,
56
- imageOptions,
57
- withFullView,
58
- nonImageContainerStyle,
59
- withDownload,
60
- onUploadPress,
61
- textStyle,
62
- }: {
63
- value?: FileValue | null
64
- hasUpload?: boolean
65
- imageOptions?: ImageViewOptions
66
- withFullView?: boolean
67
- nonImageContainerStyle?: StyleProp<ViewStyle>
68
- withDownload?: boolean
69
- onUploadPress?: () => void
70
- textStyle?: StyleProp<TextStyle>
71
- }) => {
72
- const { storagePath, dataUrl } = value ?? {}
73
- const missingFile = !dataUrl && !storagePath
74
-
75
- const { url, loading } = useObjectUrl(value)
76
- const { showError, showSuccess } = useToast()
77
-
78
- const iconColor = useIconColor()
79
- const fileNameColor = useTextColor()
80
- const borderColor = useBorderColor()
81
- const backgroundColor = useBackgroundColor(100)
82
-
83
- const handleDownload = useCallback(async () => {
84
- if (!url) {
85
- showError('File URL is not available')
86
- return
87
- }
88
-
89
- const filename = value?.filename?.split('/').pop()?.replace(/\s+/g, '_')
90
- if (!filename) {
91
- showError('Filename is not available')
92
- return
93
- }
94
-
95
- const fileType = value?.type
96
- if (!fileType) {
97
- showError('File type is not available')
98
- return
99
- }
100
-
101
- try {
102
- await downloadFile(url, filename, fileType)
103
- if (Platform.OS === 'android') {
104
- showSuccess('File downloaded successfully')
105
- return
106
- }
107
- } catch (error: unknown) {
108
- if (error instanceof Error) {
109
- console.error('Error downloading file:', error.message)
110
- } else {
111
- console.error('Error downloading file:', String(error))
112
- }
113
- showError('Failed to download file')
114
- }
115
- }, [url, value, showError, showSuccess])
116
- if (!value || missingFile) {
117
- return <NoFileView onPress={onUploadPress} hasUpload={hasUpload} />
118
- }
119
-
120
- const body = value.type?.startsWith('image/') ? (
121
- <LoadingImage
122
- withDownload={withDownload}
123
- filename={value.filename}
124
- src={url}
125
- fileType={value.type}
126
- loadingOverride={loading}
127
- width={imageOptions?.width ?? 120}
128
- height={imageOptions?.height ?? 120}
129
- withFullView={withFullView}
130
- style={styles.image}
131
- />
132
- ) : (
133
- <View style={[styles.fileContainer, { borderColor, backgroundColor }, nonImageContainerStyle]}>
134
- <View style={styles.iconContainer}>
135
- <Ionicons name="document" size={24} color={iconColor} />
136
- </View>
137
- <View style={styles.filenameContainer}>
138
- <Text numberOfLines={1} style={[styles.filename, { color: fileNameColor }, textStyle]}>
139
- {value.filename}
140
- </Text>
141
- </View>
142
- {withDownload && (
143
- <Pressable
144
- style={styles.downloadButton}
145
- onPress={() => void handleDownload()}
146
- disabled={loading}>
147
- <Ionicons name="download" size={20} color={iconColor} />
148
- </Pressable>
149
- )}
150
- </View>
151
- )
152
-
153
- return onUploadPress ? <Pressable onPress={onUploadPress}>{body}</Pressable> : body
154
- }
155
-
156
- export const FileComponent = forwardRef<InputRef, FieldProps<FileField>>(
157
- ({ input: { value, onChange }, field }, ref) => {
158
- const { imageOptions } = field || {}
159
-
160
- const handlePickFile = useCallback(async () => {
161
- try {
162
- let result: ImagePicker.ImagePickerResult | DocumentPicker.DocumentPickerResult
163
-
164
- if (field.accept?.includes('image')) {
165
- result = await ImagePicker.launchImageLibraryAsync({
166
- mediaTypes: ['images'],
167
- allowsEditing: true,
168
- quality: 1,
169
- base64: true,
170
- })
171
-
172
- if (!result.canceled && result.assets[0]) {
173
- const asset = result.assets[0]
174
-
175
- const fileExtension = asset.uri.split('.').pop() ?? 'jpeg'
176
- const fileName = asset.uri.split('/').pop() ?? 'image'
177
-
178
- onChange({
179
- dataUrl: asset.uri,
180
- type: asset.mimeType ?? `image/${fileExtension}`,
181
- filename: fileName,
182
- } as LocalFileValue)
183
- }
184
- } else {
185
- result = await DocumentPicker.getDocumentAsync({
186
- type: generateAccept(field),
187
- })
188
-
189
- if (!result.canceled) {
190
- onChange({
191
- ...value,
192
- dataUrl: result.assets[0].uri,
193
- type: result.assets[0].mimeType,
194
- filename: result.assets[0].name,
195
- })
196
- }
197
- }
198
- } catch (error: unknown) {
199
- if (error instanceof Error) {
200
- console.error('Error picking file:', error.message)
201
- }
202
- }
203
- }, [field, onChange, value])
204
-
205
- useImperativeHandle(ref, () => ({
206
- focus: () => {
207
- void handlePickFile()
208
- },
209
- blur: () => {},
210
- }))
211
-
212
- const isImageField = useMemo(
213
- () => field.accept?.length === 1 && field.accept[0] === 'image',
214
- [field],
215
- )
216
-
217
- const imgOptions = useMemo(
218
- () =>
219
- isImageField || value?.type?.startsWith('image/')
220
- ? {
221
- height: 120,
222
- ...imageOptions,
223
- }
224
- : undefined,
225
- [imageOptions, isImageField, value],
226
- )
227
-
228
- const placeholderColor = usePlaceholderColor()
229
- const borderColor = useBorderColor()
230
-
231
- return (
232
- <View style={[styles.container, { borderColor }]}>
233
- <Text style={[styles.placeholder, { color: placeholderColor }]}>{field.placeholder}</Text>
234
- <View style={styles.contentContainer}>
235
- <FileView
236
- hasUpload
237
- onUploadPress={() => void handlePickFile()}
238
- imageOptions={imgOptions}
239
- value={value}
240
- />
241
- </View>
242
- </View>
243
- )
244
- },
245
- )
246
-
247
- FileComponent.displayName = 'FileComponent'
248
-
249
- const styles = StyleSheet.create({
250
- container: {
251
- width: '100%',
252
- alignItems: 'center',
253
- justifyContent: 'center',
254
- },
255
- placeholder: {
256
- fontSize: 14,
257
- opacity: 0.8,
258
- marginBottom: 4,
259
- },
260
- contentContainer: {
261
- width: '100%',
262
- position: 'relative',
263
- alignItems: 'center',
264
- justifyContent: 'center',
265
- padding: 8,
266
- overflow: 'hidden',
267
- },
268
- noFileContainer: {
269
- flexDirection: 'row',
270
- alignItems: 'center',
271
- justifyContent: 'center',
272
- padding: 16,
273
- borderWidth: 1,
274
- borderRadius: 4,
275
- borderStyle: 'dashed',
276
- },
277
- noFileText: {
278
- fontSize: 14,
279
- textAlign: 'center',
280
- opacity: 0.8,
281
- marginRight: 10,
282
- },
283
- fileContainer: {
284
- flexDirection: 'row',
285
- alignItems: 'center',
286
- borderWidth: 1,
287
- borderRadius: 4,
288
- maxWidth: '100%',
289
- overflow: 'hidden',
290
- },
291
- filenameContainer: {
292
- flex: 1,
293
- paddingRight: 4,
294
- justifyContent: 'center',
295
- },
296
- filename: {
297
- fontSize: 14,
298
- },
299
- iconContainer: {
300
- padding: 4,
301
- },
302
- downloadButton: {
303
- padding: 8,
304
- marginLeft: 4,
305
- },
306
- image: {
307
- borderRadius: 4,
308
- overflow: 'hidden',
309
- },
310
- })
@@ -1,2 +0,0 @@
1
- export * from './useInputImperativeHandle'
2
- export * from './useInputStyles'
@@ -1,7 +0,0 @@
1
- import { usePlaceholderColor, useTextColor } from '@chem-po/react'
2
-
3
- export const useInputColor = (value?: any) => {
4
- const textColor = useTextColor()
5
- const placeholderColor = usePlaceholderColor()
6
- return value !== undefined && value !== null && value !== '' ? textColor : placeholderColor
7
- }
@@ -1,22 +0,0 @@
1
- import { InputRef } from '@chem-po/core'
2
- import { ForwardedRef, useImperativeHandle, useRef } from 'react'
3
- import { TextInput } from 'react-native'
4
-
5
- export const useInputImperativeHandle = (ref: ForwardedRef<InputRef>) => {
6
- const inputRef = useRef<TextInput>(null)
7
-
8
- useImperativeHandle<InputRef, InputRef>(
9
- ref,
10
- () => ({
11
- focus: () => {
12
- inputRef.current?.focus()
13
- },
14
- blur: () => {
15
- inputRef.current?.blur()
16
- },
17
- }),
18
- [],
19
- )
20
-
21
- return inputRef
22
- }