@chem-po/react-native 0.0.38 → 0.0.40
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/ActionButton.js +103 -38
- package/lib/commonjs/components/button/ActionButton.js.map +1 -1
- package/lib/commonjs/components/button/ButtonText.js +52 -0
- package/lib/commonjs/components/button/ButtonText.js.map +1 -0
- package/lib/commonjs/components/button/DeleteButton.js +26 -80
- package/lib/commonjs/components/button/DeleteButton.js.map +1 -1
- package/lib/commonjs/components/button/LoadingButton.js +8 -107
- package/lib/commonjs/components/button/LoadingButton.js.map +1 -1
- package/lib/commonjs/components/button/hooks.js +56 -0
- package/lib/commonjs/components/button/hooks.js.map +1 -0
- package/lib/commonjs/components/button/index.js +11 -0
- package/lib/commonjs/components/button/index.js.map +1 -1
- package/lib/commonjs/components/form/input/hooks/useInputStyles.js +3 -15
- package/lib/commonjs/components/form/input/hooks/useInputStyles.js.map +1 -1
- package/lib/commonjs/components/loading/CircularProgress.js.map +1 -1
- package/lib/commonjs/components/loading/LoadingOverlay.js +8 -5
- package/lib/commonjs/components/loading/LoadingOverlay.js.map +1 -1
- package/lib/commonjs/contexts/fonts.js +29 -0
- package/lib/commonjs/contexts/fonts.js.map +1 -0
- package/lib/commonjs/contexts/root.js +35 -24
- package/lib/commonjs/contexts/root.js.map +1 -1
- package/lib/commonjs/hooks/useFadeIn.js +1 -1
- package/lib/commonjs/hooks/useFadeIn.js.map +1 -1
- package/lib/commonjs/hooks/useFont.js +26 -0
- package/lib/commonjs/hooks/useFont.js.map +1 -0
- package/lib/module/components/button/ActionButton.js +100 -35
- package/lib/module/components/button/ActionButton.js.map +1 -1
- package/lib/module/components/button/ButtonText.js +44 -0
- package/lib/module/components/button/ButtonText.js.map +1 -0
- package/lib/module/components/button/DeleteButton.js +28 -82
- package/lib/module/components/button/DeleteButton.js.map +1 -1
- package/lib/module/components/button/LoadingButton.js +10 -109
- package/lib/module/components/button/LoadingButton.js.map +1 -1
- package/lib/module/components/button/hooks.js +45 -0
- package/lib/module/components/button/hooks.js.map +1 -0
- package/lib/module/components/button/index.js +1 -0
- package/lib/module/components/button/index.js.map +1 -1
- package/lib/module/components/form/input/hooks/useInputStyles.js +3 -15
- package/lib/module/components/form/input/hooks/useInputStyles.js.map +1 -1
- package/lib/module/components/loading/CircularProgress.js.map +1 -1
- package/lib/module/components/loading/LoadingOverlay.js +8 -5
- package/lib/module/components/loading/LoadingOverlay.js.map +1 -1
- package/lib/module/contexts/fonts.js +20 -0
- package/lib/module/contexts/fonts.js.map +1 -0
- package/lib/module/contexts/root.js +35 -24
- package/lib/module/contexts/root.js.map +1 -1
- package/lib/module/hooks/useFadeIn.js +1 -1
- package/lib/module/hooks/useFadeIn.js.map +1 -1
- package/lib/module/hooks/useFont.js +19 -0
- package/lib/module/hooks/useFont.js.map +1 -0
- package/lib/typescript/components/button/ActionButton.d.ts +14 -5
- package/lib/typescript/components/button/ActionButton.d.ts.map +1 -1
- package/lib/typescript/components/button/ButtonText.d.ts +14 -0
- package/lib/typescript/components/button/ButtonText.d.ts.map +1 -0
- package/lib/typescript/components/button/DeleteButton.d.ts +4 -6
- package/lib/typescript/components/button/DeleteButton.d.ts.map +1 -1
- package/lib/typescript/components/button/LoadingButton.d.ts +4 -17
- package/lib/typescript/components/button/LoadingButton.d.ts.map +1 -1
- package/lib/typescript/components/button/hooks.d.ts +7 -0
- package/lib/typescript/components/button/hooks.d.ts.map +1 -0
- package/lib/typescript/components/button/index.d.ts +1 -0
- package/lib/typescript/components/button/index.d.ts.map +1 -1
- package/lib/typescript/components/form/input/hooks/useInputStyles.d.ts +0 -9
- package/lib/typescript/components/form/input/hooks/useInputStyles.d.ts.map +1 -1
- package/lib/typescript/components/loading/CircularProgress.d.ts +3 -2
- package/lib/typescript/components/loading/CircularProgress.d.ts.map +1 -1
- package/lib/typescript/components/loading/LoadingOverlay.d.ts +5 -2
- package/lib/typescript/components/loading/LoadingOverlay.d.ts.map +1 -1
- package/lib/typescript/contexts/fonts.d.ts +9 -0
- package/lib/typescript/contexts/fonts.d.ts.map +1 -0
- package/lib/typescript/contexts/root.d.ts +2 -1
- package/lib/typescript/contexts/root.d.ts.map +1 -1
- package/lib/typescript/hooks/useFont.d.ts +6 -0
- package/lib/typescript/hooks/useFont.d.ts.map +1 -0
- package/package.json +3 -3
- package/src/components/button/ActionButton.tsx +131 -45
- package/src/components/button/ButtonText.tsx +60 -0
- package/src/components/button/DeleteButton.tsx +49 -115
- package/src/components/button/LoadingButton.tsx +10 -156
- package/src/components/button/hooks.ts +66 -0
- package/src/components/button/index.ts +1 -0
- package/src/components/form/input/hooks/useInputStyles.ts +3 -16
- package/src/components/loading/CircularProgress.tsx +7 -5
- package/src/components/loading/LoadingOverlay.tsx +13 -4
- package/src/contexts/fonts.tsx +23 -0
- package/src/contexts/root.tsx +45 -30
- package/src/hooks/useFadeIn.ts +1 -1
- package/src/hooks/useFont.ts +25 -0
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { useBackgroundColor, useColorModeValue, useToast } from '@chem-po/react'
|
|
2
2
|
import { Ionicons } from '@expo/vector-icons'
|
|
3
|
-
import React, { ReactNode, useCallback, useEffect,
|
|
4
|
-
import { ActivityIndicator,
|
|
3
|
+
import React, { ReactNode, useCallback, useEffect, useRef, useState } from 'react'
|
|
4
|
+
import { ActivityIndicator, StyleSheet, View } from 'react-native'
|
|
5
5
|
import { Pressable } from 'react-native-gesture-handler'
|
|
6
6
|
import { Modal, Portal } from 'react-native-paper'
|
|
7
7
|
import { Txt } from '../text/Txt'
|
|
8
|
+
import { ActionButton, ActionButtonProps } from './ActionButton'
|
|
9
|
+
import { ButtonText } from './ButtonText'
|
|
8
10
|
|
|
9
11
|
const defaultAlertBodyText = "Are you sure? You can't undo this action afterwards."
|
|
10
12
|
|
|
@@ -61,19 +63,17 @@ export const DeleteConfirmAlert = ({
|
|
|
61
63
|
)
|
|
62
64
|
}
|
|
63
65
|
|
|
64
|
-
export
|
|
66
|
+
export interface DeleteButtonProps extends Omit<ActionButtonProps, 'onPress' | 'loading'> {
|
|
65
67
|
onDelete: (() => Promise<any>) | (() => void)
|
|
66
68
|
itemName: string
|
|
67
69
|
actionName?: string
|
|
68
70
|
noConfirm?: boolean
|
|
69
71
|
text?: string
|
|
70
72
|
alertBody?: string | ReactNode
|
|
71
|
-
style?: ViewStyle
|
|
72
|
-
color?: string
|
|
73
|
-
variant?: 'outline' | 'solid'
|
|
74
73
|
iconSize?: number
|
|
75
74
|
iconProps?: React.ComponentProps<typeof Ionicons>
|
|
76
|
-
}
|
|
75
|
+
}
|
|
76
|
+
export const DeleteButton: React.FC<DeleteButtonProps> = ({
|
|
77
77
|
onDelete,
|
|
78
78
|
itemName,
|
|
79
79
|
noConfirm,
|
|
@@ -85,19 +85,17 @@ export const DeleteButton: React.FC<{
|
|
|
85
85
|
variant = 'outline',
|
|
86
86
|
iconSize = 18,
|
|
87
87
|
iconProps,
|
|
88
|
+
...buttonProps
|
|
88
89
|
}) => {
|
|
90
|
+
const { size, disabledColor, textStyle } = buttonProps
|
|
89
91
|
const { showError } = useToast()
|
|
90
92
|
const [deleteLoading, setDeleteLoading] = useState(false)
|
|
91
93
|
const [confirmActive, setConfirmActive] = useState(false)
|
|
92
94
|
const confirmTimer = useRef<ReturnType<typeof setTimeout> | null>(null)
|
|
93
95
|
const isMounted = useRef(true)
|
|
94
|
-
const contentOpacity = useRef(new Animated.Value(1)).current
|
|
95
|
-
const loaderOpacity = useRef(new Animated.Value(0)).current
|
|
96
96
|
const defaultColor = useColorModeValue('#dd2222', '#ff7777')
|
|
97
97
|
const color = colorProp ?? defaultColor
|
|
98
98
|
|
|
99
|
-
const textColor = useMemo(() => (variant === 'solid' ? 'white' : color), [variant, color])
|
|
100
|
-
|
|
101
99
|
useEffect(() => {
|
|
102
100
|
isMounted.current = true
|
|
103
101
|
|
|
@@ -106,30 +104,11 @@ export const DeleteButton: React.FC<{
|
|
|
106
104
|
}
|
|
107
105
|
}, [])
|
|
108
106
|
|
|
109
|
-
const animateLoading = useCallback(
|
|
110
|
-
(isLoading: boolean) => {
|
|
111
|
-
Animated.parallel([
|
|
112
|
-
Animated.timing(contentOpacity, {
|
|
113
|
-
toValue: isLoading ? 0 : 1,
|
|
114
|
-
duration: 200,
|
|
115
|
-
useNativeDriver: true,
|
|
116
|
-
}),
|
|
117
|
-
Animated.timing(loaderOpacity, {
|
|
118
|
-
toValue: isLoading ? 1 : 0,
|
|
119
|
-
duration: 200,
|
|
120
|
-
useNativeDriver: true,
|
|
121
|
-
}),
|
|
122
|
-
]).start()
|
|
123
|
-
},
|
|
124
|
-
[contentOpacity, loaderOpacity],
|
|
125
|
-
)
|
|
126
|
-
|
|
127
107
|
const handleDelete = useCallback(async () => {
|
|
128
108
|
if (confirmTimer.current) clearTimeout(confirmTimer.current)
|
|
129
109
|
setConfirmActive(false)
|
|
130
110
|
if (onDelete) {
|
|
131
111
|
setDeleteLoading(true)
|
|
132
|
-
animateLoading(true)
|
|
133
112
|
try {
|
|
134
113
|
await onDelete()
|
|
135
114
|
} catch (err: any) {
|
|
@@ -138,86 +117,51 @@ export const DeleteButton: React.FC<{
|
|
|
138
117
|
}
|
|
139
118
|
if (isMounted.current) {
|
|
140
119
|
setDeleteLoading(false)
|
|
141
|
-
animateLoading(false)
|
|
142
120
|
}
|
|
143
121
|
} else {
|
|
144
122
|
console.error('No delete function')
|
|
145
123
|
}
|
|
146
|
-
}, [onDelete,
|
|
124
|
+
}, [onDelete, showError])
|
|
147
125
|
|
|
148
126
|
return (
|
|
149
127
|
<>
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
</
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
</View>
|
|
188
|
-
</Pressable>
|
|
189
|
-
) : (
|
|
190
|
-
<Pressable
|
|
191
|
-
style={[
|
|
192
|
-
styles.iconButton,
|
|
193
|
-
{
|
|
194
|
-
borderColor: color,
|
|
195
|
-
borderWidth: variant === 'outline' ? 1 : 0,
|
|
196
|
-
backgroundColor: variant === 'solid' ? color : 'transparent',
|
|
197
|
-
},
|
|
198
|
-
style,
|
|
199
|
-
]}
|
|
200
|
-
onPress={() => {
|
|
201
|
-
if (noConfirm) handleDelete()
|
|
202
|
-
else setConfirmActive(true)
|
|
203
|
-
}}
|
|
204
|
-
disabled={deleteLoading}>
|
|
205
|
-
<View style={styles.iconButtonContent}>
|
|
206
|
-
<Animated.View style={[styles.contentContainer, { opacity: contentOpacity }]}>
|
|
207
|
-
<Ionicons
|
|
208
|
-
name="trash"
|
|
209
|
-
size={iconSize}
|
|
210
|
-
color={textColor}
|
|
211
|
-
{...iconProps}
|
|
212
|
-
style={[variant === 'solid' ? styles.shadow : {}, iconProps?.style]}
|
|
213
|
-
/>
|
|
214
|
-
</Animated.View>
|
|
215
|
-
<Animated.View style={[styles.loaderContainer, { opacity: loaderOpacity }]}>
|
|
216
|
-
<ActivityIndicator color={textColor} size="small" />
|
|
217
|
-
</Animated.View>
|
|
218
|
-
</View>
|
|
219
|
-
</Pressable>
|
|
220
|
-
)}
|
|
128
|
+
<ActionButton
|
|
129
|
+
style={[
|
|
130
|
+
{
|
|
131
|
+
borderColor: color,
|
|
132
|
+
backgroundColor: variant === 'solid' ? color : 'transparent',
|
|
133
|
+
borderWidth: variant === 'outline' ? 1 : 0,
|
|
134
|
+
},
|
|
135
|
+
style,
|
|
136
|
+
]}
|
|
137
|
+
variant={variant}
|
|
138
|
+
onPress={() => {
|
|
139
|
+
if (noConfirm) handleDelete()
|
|
140
|
+
else setConfirmActive(true)
|
|
141
|
+
}}
|
|
142
|
+
loading={deleteLoading}
|
|
143
|
+
disabled={deleteLoading}
|
|
144
|
+
{...buttonProps}>
|
|
145
|
+
<View style={styles.contentContainer}>
|
|
146
|
+
<Ionicons
|
|
147
|
+
name="trash"
|
|
148
|
+
size={iconSize}
|
|
149
|
+
color={variant === 'solid' ? 'white' : color}
|
|
150
|
+
{...iconProps}
|
|
151
|
+
style={[variant === 'solid' ? styles.shadow : {}, iconProps?.style]}
|
|
152
|
+
/>
|
|
153
|
+
{text ? (
|
|
154
|
+
<ButtonText
|
|
155
|
+
variant={variant}
|
|
156
|
+
color={color}
|
|
157
|
+
disabledColor={disabledColor}
|
|
158
|
+
size={size}
|
|
159
|
+
style={textStyle}>
|
|
160
|
+
{text}
|
|
161
|
+
</ButtonText>
|
|
162
|
+
) : null}
|
|
163
|
+
</View>
|
|
164
|
+
</ActionButton>
|
|
221
165
|
{noConfirm ? null : (
|
|
222
166
|
<DeleteConfirmAlert
|
|
223
167
|
confirmActive={confirmActive}
|
|
@@ -261,6 +205,7 @@ const styles = StyleSheet.create({
|
|
|
261
205
|
},
|
|
262
206
|
buttonContainer: {
|
|
263
207
|
flexDirection: 'row',
|
|
208
|
+
alignItems: 'center',
|
|
264
209
|
justifyContent: 'space-between',
|
|
265
210
|
width: '100%',
|
|
266
211
|
},
|
|
@@ -299,22 +244,11 @@ const styles = StyleSheet.create({
|
|
|
299
244
|
alignItems: 'center',
|
|
300
245
|
borderRadius: 4,
|
|
301
246
|
},
|
|
302
|
-
buttonContent: {
|
|
303
|
-
flexDirection: 'row',
|
|
304
|
-
gap: 3,
|
|
305
|
-
paddingHorizontal: 13,
|
|
306
|
-
paddingVertical: 5,
|
|
307
|
-
borderRadius: 4,
|
|
308
|
-
alignItems: 'center',
|
|
309
|
-
justifyContent: 'center',
|
|
310
|
-
minHeight: 34,
|
|
311
|
-
position: 'relative',
|
|
312
|
-
},
|
|
313
247
|
contentContainer: {
|
|
314
248
|
flexDirection: 'row',
|
|
315
249
|
alignItems: 'center',
|
|
316
250
|
justifyContent: 'center',
|
|
317
|
-
gap:
|
|
251
|
+
gap: 4,
|
|
318
252
|
},
|
|
319
253
|
loaderContainer: {
|
|
320
254
|
...StyleSheet.absoluteFillObject,
|
|
@@ -1,53 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
ActivityIndicator,
|
|
6
|
-
Animated,
|
|
7
|
-
StyleProp,
|
|
8
|
-
StyleSheet,
|
|
9
|
-
Text,
|
|
10
|
-
TextStyle,
|
|
11
|
-
View,
|
|
12
|
-
ViewStyle,
|
|
13
|
-
} from 'react-native'
|
|
14
|
-
import { Pressable } from 'react-native-gesture-handler'
|
|
1
|
+
import { useToast } from '@chem-po/react'
|
|
2
|
+
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
|
3
|
+
import { ActionButton, ActionButtonProps } from './ActionButton'
|
|
15
4
|
|
|
16
|
-
export interface LoadingButtonProps
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
style?: StyleProp<ViewStyle>
|
|
20
|
-
contentStyle?: StyleProp<ViewStyle>
|
|
21
|
-
textStyle?: StyleProp<TextStyle>
|
|
22
|
-
color?: string
|
|
23
|
-
variant?: 'outline' | 'solid'
|
|
24
|
-
icon?: {
|
|
25
|
-
name: React.ComponentProps<typeof Ionicons>['name']
|
|
26
|
-
size?: number
|
|
27
|
-
}
|
|
28
|
-
disabled?: boolean
|
|
29
|
-
iconProps?: React.ComponentProps<typeof Ionicons>
|
|
5
|
+
export interface LoadingButtonProps<ReturnType = any>
|
|
6
|
+
extends Omit<ActionButtonProps, 'onPress' | 'loading'> {
|
|
7
|
+
onPress: () => Promise<ReturnType>
|
|
30
8
|
}
|
|
31
9
|
|
|
32
|
-
export const LoadingButton: React.FC<LoadingButtonProps> = ({
|
|
33
|
-
onPress,
|
|
34
|
-
children,
|
|
35
|
-
style,
|
|
36
|
-
contentStyle,
|
|
37
|
-
textStyle,
|
|
38
|
-
color: colorProp,
|
|
39
|
-
variant = 'outline',
|
|
40
|
-
icon,
|
|
41
|
-
disabled = false,
|
|
42
|
-
iconProps,
|
|
43
|
-
}) => {
|
|
10
|
+
export const LoadingButton: React.FC<LoadingButtonProps> = ({ onPress, ...props }) => {
|
|
44
11
|
const [loading, setLoading] = useState(false)
|
|
45
|
-
const isMounted = useRef(true)
|
|
46
|
-
const contentOpacity = useRef(new Animated.Value(1)).current
|
|
47
|
-
const loaderOpacity = useRef(new Animated.Value(0)).current
|
|
48
|
-
|
|
49
12
|
const { showError } = useToast()
|
|
50
13
|
|
|
14
|
+
const isMounted = useRef(true)
|
|
51
15
|
useEffect(() => {
|
|
52
16
|
isMounted.current = true
|
|
53
17
|
|
|
@@ -56,28 +20,9 @@ export const LoadingButton: React.FC<LoadingButtonProps> = ({
|
|
|
56
20
|
}
|
|
57
21
|
}, [])
|
|
58
22
|
|
|
59
|
-
const animateLoading = useCallback(
|
|
60
|
-
(isLoading: boolean) => {
|
|
61
|
-
Animated.parallel([
|
|
62
|
-
Animated.timing(contentOpacity, {
|
|
63
|
-
toValue: isLoading ? 0 : 1,
|
|
64
|
-
duration: 200,
|
|
65
|
-
useNativeDriver: true,
|
|
66
|
-
}),
|
|
67
|
-
Animated.timing(loaderOpacity, {
|
|
68
|
-
toValue: isLoading ? 1 : 0,
|
|
69
|
-
duration: 200,
|
|
70
|
-
useNativeDriver: true,
|
|
71
|
-
}),
|
|
72
|
-
]).start()
|
|
73
|
-
},
|
|
74
|
-
[contentOpacity, loaderOpacity],
|
|
75
|
-
)
|
|
76
|
-
|
|
77
23
|
const handlePress = useCallback(async () => {
|
|
78
24
|
if (onPress) {
|
|
79
25
|
setLoading(true)
|
|
80
|
-
animateLoading(true)
|
|
81
26
|
try {
|
|
82
27
|
await onPress()
|
|
83
28
|
} catch (err: any) {
|
|
@@ -86,100 +31,9 @@ export const LoadingButton: React.FC<LoadingButtonProps> = ({
|
|
|
86
31
|
}
|
|
87
32
|
if (isMounted.current) {
|
|
88
33
|
setLoading(false)
|
|
89
|
-
animateLoading(false)
|
|
90
34
|
}
|
|
91
35
|
}
|
|
92
|
-
}, [onPress,
|
|
93
|
-
|
|
94
|
-
const fallbackColor = useTextColor()
|
|
95
|
-
const color = useMemo(() => colorProp ?? fallbackColor, [colorProp, fallbackColor])
|
|
96
|
-
const textColor = useMemo(() => (variant === 'solid' ? 'white' : color), [variant, color])
|
|
97
|
-
const backgroundColor = useMemo(
|
|
98
|
-
() => (variant === 'solid' ? color : 'transparent'),
|
|
99
|
-
[variant, color],
|
|
100
|
-
)
|
|
101
|
-
return (
|
|
102
|
-
<Pressable
|
|
103
|
-
style={[
|
|
104
|
-
styles.button,
|
|
105
|
-
{
|
|
106
|
-
opacity: disabled ? 0.6 : 1,
|
|
107
|
-
borderColor: color,
|
|
108
|
-
borderWidth: variant === 'outline' ? 1 : 0,
|
|
109
|
-
backgroundColor,
|
|
110
|
-
},
|
|
111
|
-
style,
|
|
112
|
-
]}
|
|
113
|
-
onPress={() => {
|
|
114
|
-
handlePress()
|
|
115
|
-
}}
|
|
116
|
-
disabled={loading || disabled}>
|
|
117
|
-
<View
|
|
118
|
-
style={[styles.buttonContent, { borderColor: disabled ? '#ccc' : color }, contentStyle]}>
|
|
119
|
-
<Animated.View style={[styles.contentContainer, { opacity: contentOpacity }]}>
|
|
120
|
-
{icon && (
|
|
121
|
-
<Ionicons
|
|
122
|
-
name={icon.name}
|
|
123
|
-
size={icon.size ?? 20}
|
|
124
|
-
color={textColor}
|
|
125
|
-
{...iconProps}
|
|
126
|
-
style={[variant === 'solid' ? styles.shadow : {}, iconProps?.style]}
|
|
127
|
-
/>
|
|
128
|
-
)}
|
|
129
|
-
{typeof children === 'string' ? (
|
|
130
|
-
<Text
|
|
131
|
-
style={[
|
|
132
|
-
styles.buttonText,
|
|
133
|
-
{ color: textColor },
|
|
134
|
-
variant === 'solid' ? styles.shadow : {},
|
|
135
|
-
textStyle,
|
|
136
|
-
]}>
|
|
137
|
-
{children}
|
|
138
|
-
</Text>
|
|
139
|
-
) : (
|
|
140
|
-
children
|
|
141
|
-
)}
|
|
142
|
-
</Animated.View>
|
|
36
|
+
}, [onPress, showError])
|
|
143
37
|
|
|
144
|
-
|
|
145
|
-
<ActivityIndicator color={textColor} size="small" />
|
|
146
|
-
</Animated.View>
|
|
147
|
-
</View>
|
|
148
|
-
</Pressable>
|
|
149
|
-
)
|
|
38
|
+
return <ActionButton onPress={() => void handlePress()} loading={loading} {...props} />
|
|
150
39
|
}
|
|
151
|
-
|
|
152
|
-
const styles = StyleSheet.create({
|
|
153
|
-
button: {
|
|
154
|
-
flexDirection: 'row',
|
|
155
|
-
alignItems: 'center',
|
|
156
|
-
backgroundColor: 'transparent',
|
|
157
|
-
borderRadius: 4,
|
|
158
|
-
paddingHorizontal: 12,
|
|
159
|
-
paddingVertical: 6,
|
|
160
|
-
},
|
|
161
|
-
buttonContent: {
|
|
162
|
-
alignItems: 'center',
|
|
163
|
-
justifyContent: 'center',
|
|
164
|
-
position: 'relative',
|
|
165
|
-
},
|
|
166
|
-
contentContainer: {
|
|
167
|
-
flexDirection: 'row',
|
|
168
|
-
alignItems: 'center',
|
|
169
|
-
justifyContent: 'center',
|
|
170
|
-
gap: 4,
|
|
171
|
-
},
|
|
172
|
-
loaderContainer: {
|
|
173
|
-
...StyleSheet.absoluteFillObject,
|
|
174
|
-
alignItems: 'center',
|
|
175
|
-
justifyContent: 'center',
|
|
176
|
-
},
|
|
177
|
-
buttonText: {
|
|
178
|
-
fontWeight: 'bold',
|
|
179
|
-
},
|
|
180
|
-
shadow: {
|
|
181
|
-
textShadowColor: 'rgba(0, 0, 0, 0.3)',
|
|
182
|
-
textShadowOffset: { width: 1, height: 1 },
|
|
183
|
-
textShadowRadius: 4,
|
|
184
|
-
},
|
|
185
|
-
})
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { ButtonColors } from '@chem-po/core'
|
|
2
|
+
import { useTheme } from '@chem-po/react'
|
|
3
|
+
import { useMemo } from 'react'
|
|
4
|
+
import { useFont } from '../../hooks/useFont'
|
|
5
|
+
|
|
6
|
+
export const useButtonFont = (size: 'lg' | 'md' | 'sm' | 'xs') => {
|
|
7
|
+
const fontSize = useMemo(() => (size === 'xs' ? 'sm' : size), [size])
|
|
8
|
+
const font = useFont('display', fontSize)
|
|
9
|
+
return font
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const useButtonColors = (variant: 'solid' | 'outline') => {
|
|
13
|
+
const { buttons } = useTheme()
|
|
14
|
+
return useMemo(() => buttons[variant], [buttons, variant])
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const useButtonTextColor = (
|
|
18
|
+
colors: ButtonColors,
|
|
19
|
+
variant: 'solid' | 'outline',
|
|
20
|
+
buttonColor: string | undefined,
|
|
21
|
+
disabled: boolean,
|
|
22
|
+
disabledColor: string | undefined,
|
|
23
|
+
) => {
|
|
24
|
+
return useMemo(() => {
|
|
25
|
+
if (disabled) {
|
|
26
|
+
if (disabledColor && variant === 'outline') return disabledColor
|
|
27
|
+
return colors.disabled.text
|
|
28
|
+
}
|
|
29
|
+
if (buttonColor && variant === 'outline') return buttonColor
|
|
30
|
+
return colors.text
|
|
31
|
+
}, [variant, buttonColor, disabledColor, disabled, colors])
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const useButtonBackgroundColor = (
|
|
35
|
+
colors: ButtonColors,
|
|
36
|
+
variant: 'solid' | 'outline',
|
|
37
|
+
buttonColor: string | undefined,
|
|
38
|
+
disabled: boolean,
|
|
39
|
+
disabledColor: string | undefined,
|
|
40
|
+
) => {
|
|
41
|
+
return useMemo(() => {
|
|
42
|
+
if (disabled) {
|
|
43
|
+
if (disabledColor && variant === 'solid') return disabledColor
|
|
44
|
+
return colors.disabled.background
|
|
45
|
+
}
|
|
46
|
+
if (buttonColor && variant === 'solid') return buttonColor
|
|
47
|
+
return colors.background
|
|
48
|
+
}, [variant, buttonColor, disabledColor, disabled, colors])
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const useButtonBorderColor = (
|
|
52
|
+
colors: ButtonColors,
|
|
53
|
+
variant: 'solid' | 'outline',
|
|
54
|
+
buttonColor: string | undefined,
|
|
55
|
+
disabled: boolean,
|
|
56
|
+
disabledColor: string | undefined,
|
|
57
|
+
) => {
|
|
58
|
+
return useMemo(() => {
|
|
59
|
+
if (disabled) {
|
|
60
|
+
if (disabledColor && variant === 'outline') return disabledColor
|
|
61
|
+
return colors.disabled.border
|
|
62
|
+
}
|
|
63
|
+
if (buttonColor && variant === 'outline') return buttonColor
|
|
64
|
+
return colors.border
|
|
65
|
+
}, [variant, buttonColor, disabledColor, disabled, colors])
|
|
66
|
+
}
|
|
@@ -2,6 +2,7 @@ import { InputSize } from '@chem-po/core'
|
|
|
2
2
|
import { useBackgroundColor, useTextColor } from '@chem-po/react'
|
|
3
3
|
import { useMemo } from 'react'
|
|
4
4
|
import { StyleProp, StyleSheet, TextStyle, ViewStyle } from 'react-native'
|
|
5
|
+
import { useFont } from '../../../../hooks/useFont'
|
|
5
6
|
|
|
6
7
|
export const inputStyles = StyleSheet.create({
|
|
7
8
|
input: {
|
|
@@ -26,15 +27,6 @@ export const inputStyles = StyleSheet.create({
|
|
|
26
27
|
padding: 14,
|
|
27
28
|
borderRadius: 8,
|
|
28
29
|
},
|
|
29
|
-
inputTextSmall: {
|
|
30
|
-
fontSize: 14,
|
|
31
|
-
},
|
|
32
|
-
inputTextMedium: {
|
|
33
|
-
fontSize: 16,
|
|
34
|
-
},
|
|
35
|
-
inputTextLarge: {
|
|
36
|
-
fontSize: 18,
|
|
37
|
-
},
|
|
38
30
|
buttonContainer: {
|
|
39
31
|
flexDirection: 'row',
|
|
40
32
|
alignItems: 'center',
|
|
@@ -74,12 +66,6 @@ const editableInputSizeMap = {
|
|
|
74
66
|
lg: inputStyles.inputMedium,
|
|
75
67
|
}
|
|
76
68
|
|
|
77
|
-
const inputTextSizeMap = {
|
|
78
|
-
sm: inputStyles.inputTextSmall,
|
|
79
|
-
md: inputStyles.inputTextMedium,
|
|
80
|
-
lg: inputStyles.inputTextLarge,
|
|
81
|
-
}
|
|
82
|
-
|
|
83
69
|
const buttonContainerSizeMap = {
|
|
84
70
|
sm: inputStyles.buttonContainerSmall,
|
|
85
71
|
md: inputStyles.buttonContainerMedium,
|
|
@@ -106,9 +92,10 @@ export const useInputStyles = (
|
|
|
106
92
|
)
|
|
107
93
|
const textColor = useTextColor()
|
|
108
94
|
const usedSize = size ?? formSize
|
|
95
|
+
const textFont = useFont('body', usedSize)
|
|
109
96
|
return {
|
|
110
97
|
text: {
|
|
111
|
-
...
|
|
98
|
+
...textFont,
|
|
112
99
|
paddingTop: 0,
|
|
113
100
|
paddingBottom: 0,
|
|
114
101
|
color: textColor,
|
|
@@ -9,6 +9,12 @@ import {
|
|
|
9
9
|
ViewStyle,
|
|
10
10
|
} from 'react-native'
|
|
11
11
|
|
|
12
|
+
export interface CircularProgressProps extends ActivityIndicatorProps {
|
|
13
|
+
trackColor?: string
|
|
14
|
+
viewStyle?: StyleProp<ViewStyle>
|
|
15
|
+
visible?: boolean
|
|
16
|
+
}
|
|
17
|
+
|
|
12
18
|
export const CircularProgress = ({
|
|
13
19
|
color,
|
|
14
20
|
trackColor,
|
|
@@ -16,11 +22,7 @@ export const CircularProgress = ({
|
|
|
16
22
|
visible = true,
|
|
17
23
|
viewStyle,
|
|
18
24
|
...props
|
|
19
|
-
}:
|
|
20
|
-
trackColor?: string
|
|
21
|
-
viewStyle?: StyleProp<ViewStyle>
|
|
22
|
-
visible?: boolean
|
|
23
|
-
}) => {
|
|
25
|
+
}: CircularProgressProps) => {
|
|
24
26
|
const defaultTrackColor = useColorModeValue('#959595', '#575757')
|
|
25
27
|
const opacity = useRef(new Animated.Value(visible ? 1 : 0)).current
|
|
26
28
|
|
|
@@ -1,25 +1,31 @@
|
|
|
1
1
|
import React, { useMemo } from 'react'
|
|
2
2
|
import { Animated, StyleProp, StyleSheet, ViewStyle } from 'react-native'
|
|
3
3
|
import { FadeInOptions, useFadeIn } from '../../hooks/useFadeIn'
|
|
4
|
-
import { CircularProgress } from './CircularProgress'
|
|
4
|
+
import { CircularProgress, CircularProgressProps } from './CircularProgress'
|
|
5
5
|
|
|
6
6
|
const loadingFadeInProps: FadeInOptions = {
|
|
7
|
-
activeOpacity: 0.
|
|
7
|
+
activeOpacity: 0.8,
|
|
8
8
|
duration: 100,
|
|
9
9
|
}
|
|
10
10
|
interface LoadingOverlayProps {
|
|
11
11
|
loading: boolean
|
|
12
12
|
fadeOptions?: FadeInOptions
|
|
13
13
|
style?: StyleProp<ViewStyle>
|
|
14
|
+
indicatorProps?: CircularProgressProps
|
|
14
15
|
}
|
|
15
|
-
export const LoadingOverlay = ({
|
|
16
|
+
export const LoadingOverlay = ({
|
|
17
|
+
loading,
|
|
18
|
+
fadeOptions,
|
|
19
|
+
style,
|
|
20
|
+
indicatorProps,
|
|
21
|
+
}: LoadingOverlayProps) => {
|
|
16
22
|
const opts = useMemo(() => ({ ...loadingFadeInProps, ...fadeOptions }), [fadeOptions])
|
|
17
23
|
const opacity = useFadeIn(loading, opts)
|
|
18
24
|
|
|
19
25
|
return (
|
|
20
26
|
<Animated.View
|
|
21
27
|
style={[styles.overlay, style, { opacity, pointerEvents: loading ? 'auto' : 'none' }]}>
|
|
22
|
-
<CircularProgress />
|
|
28
|
+
<CircularProgress {...indicatorProps} />
|
|
23
29
|
</Animated.View>
|
|
24
30
|
)
|
|
25
31
|
}
|
|
@@ -32,11 +38,13 @@ export const WithLoadingOverlay = ({
|
|
|
32
38
|
children,
|
|
33
39
|
style,
|
|
34
40
|
overlayStyle,
|
|
41
|
+
indicatorProps,
|
|
35
42
|
}: {
|
|
36
43
|
loading: boolean
|
|
37
44
|
children: React.ReactNode
|
|
38
45
|
style?: StyleProp<ViewStyle>
|
|
39
46
|
overlayStyle?: StyleProp<ViewStyle>
|
|
47
|
+
indicatorProps?: CircularProgressProps
|
|
40
48
|
}) => {
|
|
41
49
|
const bodyOpacity = useFadeIn(!loading, withOverlayLoadingFadeIn)
|
|
42
50
|
return (
|
|
@@ -46,6 +54,7 @@ export const WithLoadingOverlay = ({
|
|
|
46
54
|
fadeOptions={withOverlayLoadingFadeIn}
|
|
47
55
|
loading={loading}
|
|
48
56
|
style={overlayStyle}
|
|
57
|
+
indicatorProps={indicatorProps}
|
|
49
58
|
/>
|
|
50
59
|
</>
|
|
51
60
|
)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React, { createContext, PropsWithChildren, useContext } from 'react'
|
|
2
|
+
import { MD3Typescale } from 'react-native-paper/lib/typescript/types'
|
|
3
|
+
|
|
4
|
+
export interface ChempoFontsProviderProps {
|
|
5
|
+
fonts: MD3Typescale
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const ChempoFontsContext = createContext<ChempoFontsProviderProps | null>(null)
|
|
9
|
+
|
|
10
|
+
export const ChempoFontsProvider = ({
|
|
11
|
+
children,
|
|
12
|
+
fonts,
|
|
13
|
+
}: PropsWithChildren<ChempoFontsProviderProps>) => {
|
|
14
|
+
return <ChempoFontsContext.Provider value={{ fonts }}>{children}</ChempoFontsContext.Provider>
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const useChempoFonts = () => {
|
|
18
|
+
const context = useContext(ChempoFontsContext)
|
|
19
|
+
if (!context) {
|
|
20
|
+
throw new Error('useChempoFonts must be used within a ChempoFontsProvider')
|
|
21
|
+
}
|
|
22
|
+
return context
|
|
23
|
+
}
|