@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.
Files changed (88) hide show
  1. package/lib/commonjs/components/button/ActionButton.js +103 -38
  2. package/lib/commonjs/components/button/ActionButton.js.map +1 -1
  3. package/lib/commonjs/components/button/ButtonText.js +52 -0
  4. package/lib/commonjs/components/button/ButtonText.js.map +1 -0
  5. package/lib/commonjs/components/button/DeleteButton.js +26 -80
  6. package/lib/commonjs/components/button/DeleteButton.js.map +1 -1
  7. package/lib/commonjs/components/button/LoadingButton.js +8 -107
  8. package/lib/commonjs/components/button/LoadingButton.js.map +1 -1
  9. package/lib/commonjs/components/button/hooks.js +56 -0
  10. package/lib/commonjs/components/button/hooks.js.map +1 -0
  11. package/lib/commonjs/components/button/index.js +11 -0
  12. package/lib/commonjs/components/button/index.js.map +1 -1
  13. package/lib/commonjs/components/form/input/hooks/useInputStyles.js +3 -15
  14. package/lib/commonjs/components/form/input/hooks/useInputStyles.js.map +1 -1
  15. package/lib/commonjs/components/loading/CircularProgress.js.map +1 -1
  16. package/lib/commonjs/components/loading/LoadingOverlay.js +8 -5
  17. package/lib/commonjs/components/loading/LoadingOverlay.js.map +1 -1
  18. package/lib/commonjs/contexts/fonts.js +29 -0
  19. package/lib/commonjs/contexts/fonts.js.map +1 -0
  20. package/lib/commonjs/contexts/root.js +35 -24
  21. package/lib/commonjs/contexts/root.js.map +1 -1
  22. package/lib/commonjs/hooks/useFadeIn.js +1 -1
  23. package/lib/commonjs/hooks/useFadeIn.js.map +1 -1
  24. package/lib/commonjs/hooks/useFont.js +26 -0
  25. package/lib/commonjs/hooks/useFont.js.map +1 -0
  26. package/lib/module/components/button/ActionButton.js +100 -35
  27. package/lib/module/components/button/ActionButton.js.map +1 -1
  28. package/lib/module/components/button/ButtonText.js +44 -0
  29. package/lib/module/components/button/ButtonText.js.map +1 -0
  30. package/lib/module/components/button/DeleteButton.js +28 -82
  31. package/lib/module/components/button/DeleteButton.js.map +1 -1
  32. package/lib/module/components/button/LoadingButton.js +10 -109
  33. package/lib/module/components/button/LoadingButton.js.map +1 -1
  34. package/lib/module/components/button/hooks.js +45 -0
  35. package/lib/module/components/button/hooks.js.map +1 -0
  36. package/lib/module/components/button/index.js +1 -0
  37. package/lib/module/components/button/index.js.map +1 -1
  38. package/lib/module/components/form/input/hooks/useInputStyles.js +3 -15
  39. package/lib/module/components/form/input/hooks/useInputStyles.js.map +1 -1
  40. package/lib/module/components/loading/CircularProgress.js.map +1 -1
  41. package/lib/module/components/loading/LoadingOverlay.js +8 -5
  42. package/lib/module/components/loading/LoadingOverlay.js.map +1 -1
  43. package/lib/module/contexts/fonts.js +20 -0
  44. package/lib/module/contexts/fonts.js.map +1 -0
  45. package/lib/module/contexts/root.js +35 -24
  46. package/lib/module/contexts/root.js.map +1 -1
  47. package/lib/module/hooks/useFadeIn.js +1 -1
  48. package/lib/module/hooks/useFadeIn.js.map +1 -1
  49. package/lib/module/hooks/useFont.js +19 -0
  50. package/lib/module/hooks/useFont.js.map +1 -0
  51. package/lib/typescript/components/button/ActionButton.d.ts +14 -5
  52. package/lib/typescript/components/button/ActionButton.d.ts.map +1 -1
  53. package/lib/typescript/components/button/ButtonText.d.ts +14 -0
  54. package/lib/typescript/components/button/ButtonText.d.ts.map +1 -0
  55. package/lib/typescript/components/button/DeleteButton.d.ts +4 -6
  56. package/lib/typescript/components/button/DeleteButton.d.ts.map +1 -1
  57. package/lib/typescript/components/button/LoadingButton.d.ts +4 -17
  58. package/lib/typescript/components/button/LoadingButton.d.ts.map +1 -1
  59. package/lib/typescript/components/button/hooks.d.ts +7 -0
  60. package/lib/typescript/components/button/hooks.d.ts.map +1 -0
  61. package/lib/typescript/components/button/index.d.ts +1 -0
  62. package/lib/typescript/components/button/index.d.ts.map +1 -1
  63. package/lib/typescript/components/form/input/hooks/useInputStyles.d.ts +0 -9
  64. package/lib/typescript/components/form/input/hooks/useInputStyles.d.ts.map +1 -1
  65. package/lib/typescript/components/loading/CircularProgress.d.ts +3 -2
  66. package/lib/typescript/components/loading/CircularProgress.d.ts.map +1 -1
  67. package/lib/typescript/components/loading/LoadingOverlay.d.ts +5 -2
  68. package/lib/typescript/components/loading/LoadingOverlay.d.ts.map +1 -1
  69. package/lib/typescript/contexts/fonts.d.ts +9 -0
  70. package/lib/typescript/contexts/fonts.d.ts.map +1 -0
  71. package/lib/typescript/contexts/root.d.ts +2 -1
  72. package/lib/typescript/contexts/root.d.ts.map +1 -1
  73. package/lib/typescript/hooks/useFont.d.ts +6 -0
  74. package/lib/typescript/hooks/useFont.d.ts.map +1 -0
  75. package/package.json +3 -3
  76. package/src/components/button/ActionButton.tsx +131 -45
  77. package/src/components/button/ButtonText.tsx +60 -0
  78. package/src/components/button/DeleteButton.tsx +49 -115
  79. package/src/components/button/LoadingButton.tsx +10 -156
  80. package/src/components/button/hooks.ts +66 -0
  81. package/src/components/button/index.ts +1 -0
  82. package/src/components/form/input/hooks/useInputStyles.ts +3 -16
  83. package/src/components/loading/CircularProgress.tsx +7 -5
  84. package/src/components/loading/LoadingOverlay.tsx +13 -4
  85. package/src/contexts/fonts.tsx +23 -0
  86. package/src/contexts/root.tsx +45 -30
  87. package/src/hooks/useFadeIn.ts +1 -1
  88. 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, useMemo, useRef, useState } from 'react'
4
- import { ActivityIndicator, Animated, StyleSheet, Text, View, ViewStyle } from 'react-native'
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 const DeleteButton: React.FC<{
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, animateLoading, showError])
124
+ }, [onDelete, showError])
147
125
 
148
126
  return (
149
127
  <>
150
- {text ? (
151
- <Pressable
152
- style={[
153
- styles.button,
154
- {
155
- borderColor: color,
156
- backgroundColor: variant === 'solid' ? color : 'transparent',
157
- borderWidth: variant === 'outline' ? 1 : 0,
158
- },
159
- style,
160
- ]}
161
- onPress={() => {
162
- if (noConfirm) handleDelete()
163
- else setConfirmActive(true)
164
- }}
165
- disabled={deleteLoading}>
166
- <View style={styles.buttonContent}>
167
- <Animated.View style={[styles.contentContainer, { opacity: contentOpacity }]}>
168
- <Ionicons
169
- name="trash"
170
- size={iconSize}
171
- color={textColor}
172
- {...iconProps}
173
- style={[variant === 'solid' ? styles.shadow : {}, iconProps?.style]}
174
- />
175
- <Text
176
- style={[
177
- styles.buttonText,
178
- { color: textColor },
179
- variant === 'solid' ? styles.shadow : undefined,
180
- ]}>
181
- {text}
182
- </Text>
183
- </Animated.View>
184
- <Animated.View style={[styles.loaderContainer, { opacity: loaderOpacity }]}>
185
- <ActivityIndicator color={textColor} size="small" />
186
- </Animated.View>
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: 3,
251
+ gap: 4,
318
252
  },
319
253
  loaderContainer: {
320
254
  ...StyleSheet.absoluteFillObject,
@@ -1,53 +1,17 @@
1
- import { useTextColor, useToast } from '@chem-po/react'
2
- import { Ionicons } from '@expo/vector-icons'
3
- import React, { ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react'
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
- onPress: (() => Promise<any>) | (() => void)
18
- children: ReactNode
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, animateLoading, showError])
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
- <Animated.View style={[styles.loaderContainer, { opacity: loaderOpacity }]}>
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
+ }
@@ -1,4 +1,5 @@
1
1
  export * from './ActionButton'
2
+ export * from './ButtonText'
2
3
  export * from './DeleteButton'
3
4
  export * from './LoadingButton'
4
5
  export * from './Toggle'
@@ -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
- ...inputTextSizeMap[usedSize],
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
- }: ActivityIndicatorProps & {
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.5,
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 = ({ loading, fadeOptions, style }: LoadingOverlayProps) => {
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
+ }