@retray-dev/ui-kit 2.7.0 → 3.0.0
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/COMPONENTS.md +102 -15
- package/README.md +25 -5
- package/dist/index.d.mts +36 -6
- package/dist/index.d.ts +36 -6
- package/dist/index.js +692 -484
- package/dist/index.mjs +622 -415
- package/package.json +6 -3
- package/src/assets/fonts/Poppins-Black.ttf +0 -0
- package/src/assets/fonts/Poppins-BlackItalic.ttf +0 -0
- package/src/assets/fonts/Poppins-Bold.ttf +0 -0
- package/src/assets/fonts/Poppins-BoldItalic.ttf +0 -0
- package/src/assets/fonts/Poppins-ExtraBold.ttf +0 -0
- package/src/assets/fonts/Poppins-ExtraBoldItalic.ttf +0 -0
- package/src/assets/fonts/Poppins-ExtraLight.ttf +0 -0
- package/src/assets/fonts/Poppins-ExtraLightItalic.ttf +0 -0
- package/src/assets/fonts/Poppins-Italic.ttf +0 -0
- package/src/assets/fonts/Poppins-Light.ttf +0 -0
- package/src/assets/fonts/Poppins-LightItalic.ttf +0 -0
- package/src/assets/fonts/Poppins-Medium.ttf +0 -0
- package/src/assets/fonts/Poppins-MediumItalic.ttf +0 -0
- package/src/assets/fonts/Poppins-Regular.ttf +0 -0
- package/src/assets/fonts/Poppins-SemiBold.ttf +0 -0
- package/src/assets/fonts/Poppins-SemiBoldItalic.ttf +0 -0
- package/src/assets/fonts/Poppins-Thin.ttf +0 -0
- package/src/assets/fonts/Poppins-ThinItalic.ttf +0 -0
- package/src/components/Accordion/Accordion.tsx +16 -9
- package/src/components/AlertBanner/AlertBanner.tsx +35 -35
- package/src/components/Avatar/Avatar.tsx +1 -1
- package/src/components/Badge/Badge.tsx +12 -8
- package/src/components/Button/Button.tsx +9 -9
- package/src/components/Card/Card.tsx +12 -9
- package/src/components/Checkbox/Checkbox.tsx +9 -8
- package/src/components/Chip/Chip.tsx +22 -6
- package/src/components/ConfirmDialog/ConfirmDialog.tsx +86 -38
- package/src/components/CurrencyDisplay/CurrencyDisplay.tsx +1 -1
- package/src/components/CurrencyInput/CurrencyInput.tsx +11 -4
- package/src/components/EmptyState/EmptyState.tsx +2 -1
- package/src/components/IconButton/IconButton.tsx +147 -0
- package/src/components/IconButton/index.ts +2 -0
- package/src/components/Input/Input.tsx +12 -8
- package/src/components/LabelValue/LabelValue.tsx +4 -3
- package/src/components/ListItem/ListItem.tsx +10 -9
- package/src/components/MonthPicker/MonthPicker.tsx +1 -1
- package/src/components/RadioGroup/RadioGroup.tsx +36 -35
- package/src/components/Select/Select.tsx +19 -21
- package/src/components/Sheet/Sheet.tsx +4 -3
- package/src/components/Slider/Slider.tsx +3 -3
- package/src/components/Spinner/Spinner.tsx +36 -2
- package/src/components/Switch/Switch.tsx +4 -4
- package/src/components/Tabs/Tabs.tsx +10 -16
- package/src/components/Text/Text.tsx +6 -6
- package/src/components/Textarea/Textarea.tsx +8 -6
- package/src/components/Toast/Toast.tsx +29 -23
- package/src/components/Toggle/Toggle.tsx +7 -5
- package/src/fonts.ts +30 -0
- package/src/index.ts +1 -0
- package/src/theme/colors.ts +22 -14
- package/src/theme/types.ts +4 -0
- package/src/components/Alert/Alert.tsx +0 -84
|
@@ -9,6 +9,7 @@ import { s, vs, ms } from '../../utils/scaling'
|
|
|
9
9
|
const isIOS = Platform.OS === 'ios'
|
|
10
10
|
const isAndroid = Platform.OS === 'android'
|
|
11
11
|
const isWeb = Platform.OS === 'web'
|
|
12
|
+
const nativeDriver = Platform.OS !== 'web'
|
|
12
13
|
|
|
13
14
|
export interface SelectOption {
|
|
14
15
|
label: string
|
|
@@ -47,11 +48,11 @@ export function Select({
|
|
|
47
48
|
|
|
48
49
|
const handlePressIn = () => {
|
|
49
50
|
if (disabled) return
|
|
50
|
-
Animated.spring(scale, { toValue: 0.95, useNativeDriver:
|
|
51
|
+
Animated.spring(scale, { toValue: 0.95, useNativeDriver: nativeDriver, speed: 40, bounciness: 0 }).start()
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
const handlePressOut = () => {
|
|
54
|
-
Animated.spring(scale, { toValue: 1, useNativeDriver:
|
|
55
|
+
Animated.spring(scale, { toValue: 1, useNativeDriver: nativeDriver, speed: 40, bounciness: 4 }).start()
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
const handleOpen = () => {
|
|
@@ -79,7 +80,7 @@ export function Select({
|
|
|
79
80
|
|
|
80
81
|
return (
|
|
81
82
|
<View style={[styles.container, style]}>
|
|
82
|
-
{label ? <Text style={[styles.label, { color: colors.foreground }]}>{label}</Text> : null}
|
|
83
|
+
{label ? <Text style={[styles.label, { color: colors.foreground }]} allowFontScaling={true}>{label}</Text> : null}
|
|
83
84
|
|
|
84
85
|
{/* Trigger button — shown on iOS and Android only */}
|
|
85
86
|
{!isWeb ? (
|
|
@@ -220,7 +221,7 @@ export function Select({
|
|
|
220
221
|
) : null}
|
|
221
222
|
|
|
222
223
|
{error ? (
|
|
223
|
-
<Text style={[styles.helperText, { color: colors.destructive }]}>{error}</Text>
|
|
224
|
+
<Text style={[styles.helperText, { color: colors.destructive }]} allowFontScaling={true}>{error}</Text>
|
|
224
225
|
) : null}
|
|
225
226
|
</View>
|
|
226
227
|
)
|
|
@@ -231,31 +232,28 @@ const styles = StyleSheet.create({
|
|
|
231
232
|
gap: vs(8),
|
|
232
233
|
},
|
|
233
234
|
label: {
|
|
234
|
-
|
|
235
|
-
|
|
235
|
+
fontFamily: 'Poppins-Medium',
|
|
236
|
+
fontSize: ms(13),
|
|
236
237
|
},
|
|
237
238
|
trigger: {
|
|
238
239
|
flexDirection: 'row',
|
|
239
240
|
alignItems: 'center',
|
|
240
241
|
justifyContent: 'space-between',
|
|
241
|
-
borderWidth: 1
|
|
242
|
+
borderWidth: 1,
|
|
242
243
|
borderRadius: ms(8),
|
|
243
|
-
paddingHorizontal: s(
|
|
244
|
-
paddingVertical: vs(
|
|
245
|
-
shadowColor: '#000',
|
|
246
|
-
shadowOffset: { width: 0, height: 1 },
|
|
247
|
-
shadowOpacity: 0.04,
|
|
248
|
-
shadowRadius: 2,
|
|
249
|
-
elevation: 1,
|
|
244
|
+
paddingHorizontal: s(14),
|
|
245
|
+
paddingVertical: vs(11),
|
|
250
246
|
},
|
|
251
247
|
triggerText: {
|
|
252
|
-
|
|
248
|
+
fontFamily: 'Poppins-Regular',
|
|
249
|
+
fontSize: ms(15),
|
|
253
250
|
flex: 1,
|
|
254
251
|
},
|
|
255
252
|
chevron: {
|
|
256
253
|
marginLeft: s(8),
|
|
257
254
|
},
|
|
258
255
|
helperText: {
|
|
256
|
+
fontFamily: 'Poppins-Regular',
|
|
259
257
|
fontSize: ms(13),
|
|
260
258
|
},
|
|
261
259
|
iosBackdrop: {
|
|
@@ -276,15 +274,15 @@ const styles = StyleSheet.create({
|
|
|
276
274
|
borderBottomWidth: 1,
|
|
277
275
|
},
|
|
278
276
|
iosToolbarTitle: {
|
|
277
|
+
fontFamily: 'Poppins-SemiBold',
|
|
279
278
|
fontSize: ms(17),
|
|
280
|
-
fontWeight: '600',
|
|
281
279
|
},
|
|
282
280
|
iosDoneBtn: {
|
|
283
281
|
padding: s(4),
|
|
284
282
|
},
|
|
285
283
|
iosDoneBtnText: {
|
|
284
|
+
fontFamily: 'Poppins-SemiBold',
|
|
286
285
|
fontSize: ms(17),
|
|
287
|
-
fontWeight: '600',
|
|
288
286
|
},
|
|
289
287
|
androidHiddenPicker: {
|
|
290
288
|
height: 0,
|
|
@@ -292,10 +290,10 @@ const styles = StyleSheet.create({
|
|
|
292
290
|
position: 'absolute',
|
|
293
291
|
},
|
|
294
292
|
webPicker: {
|
|
295
|
-
borderWidth: 1
|
|
293
|
+
borderWidth: 1,
|
|
296
294
|
borderRadius: ms(8),
|
|
297
|
-
paddingHorizontal: s(
|
|
298
|
-
paddingVertical: vs(
|
|
299
|
-
fontSize: ms(
|
|
295
|
+
paddingHorizontal: s(14),
|
|
296
|
+
paddingVertical: vs(11),
|
|
297
|
+
fontSize: ms(15),
|
|
300
298
|
},
|
|
301
299
|
})
|
|
@@ -72,10 +72,10 @@ export function Sheet({
|
|
|
72
72
|
{title || description ? (
|
|
73
73
|
<View style={styles.header}>
|
|
74
74
|
{title ? (
|
|
75
|
-
<Text style={[styles.title, { color: colors.cardForeground }]}>{title}</Text>
|
|
75
|
+
<Text style={[styles.title, { color: colors.cardForeground }]} allowFontScaling={true}>{title}</Text>
|
|
76
76
|
) : null}
|
|
77
77
|
{description ? (
|
|
78
|
-
<Text style={[styles.description, { color: colors.mutedForeground }]}>
|
|
78
|
+
<Text style={[styles.description, { color: colors.mutedForeground }]} allowFontScaling={true}>
|
|
79
79
|
{description}
|
|
80
80
|
</Text>
|
|
81
81
|
) : null}
|
|
@@ -106,10 +106,11 @@ const styles = StyleSheet.create({
|
|
|
106
106
|
marginBottom: vs(16),
|
|
107
107
|
},
|
|
108
108
|
title: {
|
|
109
|
+
fontFamily: 'Poppins-SemiBold',
|
|
109
110
|
fontSize: ms(18),
|
|
110
|
-
fontWeight: '600',
|
|
111
111
|
},
|
|
112
112
|
description: {
|
|
113
|
+
fontFamily: 'Poppins-Regular',
|
|
113
114
|
fontSize: ms(14),
|
|
114
115
|
lineHeight: mvs(20),
|
|
115
116
|
},
|
|
@@ -91,16 +91,16 @@ const styles = StyleSheet.create({
|
|
|
91
91
|
alignItems: 'center',
|
|
92
92
|
},
|
|
93
93
|
label: {
|
|
94
|
+
fontFamily: 'Poppins-Medium',
|
|
94
95
|
fontSize: ms(15),
|
|
95
|
-
fontWeight: '500',
|
|
96
96
|
},
|
|
97
97
|
valueText: {
|
|
98
|
+
fontFamily: 'Poppins-Medium',
|
|
98
99
|
fontSize: ms(14),
|
|
99
|
-
fontWeight: '500',
|
|
100
100
|
},
|
|
101
101
|
slider: {
|
|
102
102
|
width: '100%',
|
|
103
|
-
height: vs(
|
|
103
|
+
height: vs(60),
|
|
104
104
|
},
|
|
105
105
|
disabled: {
|
|
106
106
|
opacity: 0.45,
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { ActivityIndicator, ActivityIndicatorProps } from 'react-native'
|
|
2
|
+
import { ActivityIndicator, ActivityIndicatorProps, View, Text, StyleSheet } from 'react-native'
|
|
3
3
|
import { useTheme } from '../../theme'
|
|
4
|
+
import { vs, ms, mvs } from '../../utils/scaling'
|
|
4
5
|
|
|
5
6
|
export type SpinnerSize = 'sm' | 'md' | 'lg'
|
|
6
7
|
|
|
7
8
|
export interface SpinnerProps extends Omit<ActivityIndicatorProps, 'size'> {
|
|
8
9
|
size?: SpinnerSize
|
|
9
10
|
color?: string
|
|
11
|
+
label?: string
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
const sizeMap: Record<SpinnerSize, 'small' | 'large'> = {
|
|
@@ -15,7 +17,39 @@ const sizeMap: Record<SpinnerSize, 'small' | 'large'> = {
|
|
|
15
17
|
lg: 'large',
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
const labelFontSize: Record<SpinnerSize, number> = {
|
|
21
|
+
sm: ms(11),
|
|
22
|
+
md: ms(13),
|
|
23
|
+
lg: ms(14),
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function Spinner({ size = 'md', color, label, ...props }: SpinnerProps) {
|
|
19
27
|
const { colors } = useTheme()
|
|
28
|
+
|
|
29
|
+
if (label) {
|
|
30
|
+
return (
|
|
31
|
+
<View style={styles.wrapper}>
|
|
32
|
+
<ActivityIndicator size={sizeMap[size]} color={color ?? colors.primary} {...props} />
|
|
33
|
+
<Text
|
|
34
|
+
style={[styles.label, { color: colors.mutedForeground, fontSize: labelFontSize[size] }]}
|
|
35
|
+
allowFontScaling={true}
|
|
36
|
+
>
|
|
37
|
+
{label}
|
|
38
|
+
</Text>
|
|
39
|
+
</View>
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
|
|
20
43
|
return <ActivityIndicator size={sizeMap[size]} color={color ?? colors.primary} {...props} />
|
|
21
44
|
}
|
|
45
|
+
|
|
46
|
+
const styles = StyleSheet.create({
|
|
47
|
+
wrapper: {
|
|
48
|
+
alignItems: 'center',
|
|
49
|
+
gap: vs(6),
|
|
50
|
+
},
|
|
51
|
+
label: {
|
|
52
|
+
fontFamily: 'Poppins-Regular',
|
|
53
|
+
lineHeight: mvs(18),
|
|
54
|
+
},
|
|
55
|
+
})
|
|
@@ -6,10 +6,10 @@ import { selectionAsync as hapticSelection } from '../../utils/haptics'
|
|
|
6
6
|
import { useTheme } from '../../theme'
|
|
7
7
|
import { s, vs } from '../../utils/scaling'
|
|
8
8
|
|
|
9
|
-
const TRACK_WIDTH = s(
|
|
10
|
-
const TRACK_HEIGHT =
|
|
11
|
-
const THUMB_SIZE = s(
|
|
12
|
-
const THUMB_OFFSET = s(
|
|
9
|
+
const TRACK_WIDTH = s(52)
|
|
10
|
+
const TRACK_HEIGHT = s(30)
|
|
11
|
+
const THUMB_SIZE = s(24)
|
|
12
|
+
const THUMB_OFFSET = s(3)
|
|
13
13
|
const THUMB_TRAVEL = TRACK_WIDTH - THUMB_SIZE - THUMB_OFFSET * 2
|
|
14
14
|
|
|
15
15
|
export interface SwitchProps {
|
|
@@ -9,7 +9,7 @@ import { s, vs, ms } from '../../utils/scaling'
|
|
|
9
9
|
export interface TabItem {
|
|
10
10
|
label: string
|
|
11
11
|
value: string
|
|
12
|
-
icon?: React.ReactNode
|
|
12
|
+
icon?: React.ReactNode | ((active: boolean) => React.ReactNode)
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export interface TabsProps {
|
|
@@ -66,9 +66,7 @@ function TabTrigger({
|
|
|
66
66
|
<Animated.View style={{ transform: [{ scale }] }}>
|
|
67
67
|
<View style={styles.triggerInner}>
|
|
68
68
|
{tab.icon ? (
|
|
69
|
-
|
|
70
|
-
{(typeof tab.icon === 'function' ? (tab.icon as any)(isActive) : tab.icon) as React.ReactNode}
|
|
71
|
-
</View>
|
|
69
|
+
(typeof tab.icon === 'function' ? (tab.icon as any)(isActive) : tab.icon) as React.ReactNode
|
|
72
70
|
) : null}
|
|
73
71
|
<Text
|
|
74
72
|
style={[
|
|
@@ -76,6 +74,7 @@ function TabTrigger({
|
|
|
76
74
|
{ color: isActive ? colors.foreground : colors.mutedForeground },
|
|
77
75
|
isActive && styles.activeTriggerLabel,
|
|
78
76
|
]}
|
|
77
|
+
allowFontScaling={true}
|
|
79
78
|
>
|
|
80
79
|
{tab.label}
|
|
81
80
|
</Text>
|
|
@@ -190,9 +189,9 @@ const styles = StyleSheet.create({
|
|
|
190
189
|
pill: {},
|
|
191
190
|
trigger: {
|
|
192
191
|
flex: 1,
|
|
193
|
-
paddingVertical: vs(
|
|
194
|
-
paddingHorizontal: s(
|
|
195
|
-
borderRadius: ms(
|
|
192
|
+
paddingVertical: vs(7),
|
|
193
|
+
paddingHorizontal: s(10),
|
|
194
|
+
borderRadius: ms(6),
|
|
196
195
|
alignItems: 'center',
|
|
197
196
|
justifyContent: 'center',
|
|
198
197
|
zIndex: 1,
|
|
@@ -201,18 +200,13 @@ const styles = StyleSheet.create({
|
|
|
201
200
|
flexDirection: 'row',
|
|
202
201
|
alignItems: 'center',
|
|
203
202
|
justifyContent: 'center',
|
|
204
|
-
gap: s(
|
|
205
|
-
},
|
|
206
|
-
triggerIcon: {
|
|
207
|
-
marginRight: s(6),
|
|
208
|
-
alignItems: 'center',
|
|
209
|
-
justifyContent: 'center',
|
|
203
|
+
gap: s(4),
|
|
210
204
|
},
|
|
211
205
|
triggerLabel: {
|
|
212
|
-
|
|
213
|
-
|
|
206
|
+
fontFamily: 'Poppins-Regular',
|
|
207
|
+
fontSize: ms(13),
|
|
214
208
|
},
|
|
215
209
|
activeTriggerLabel: {
|
|
216
|
-
|
|
210
|
+
fontFamily: 'Poppins-Medium',
|
|
217
211
|
},
|
|
218
212
|
})
|
|
@@ -11,12 +11,12 @@ export interface TextProps extends RNTextProps {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
const variantStyles: Record<TextVariant, TextStyle> = {
|
|
14
|
-
h1:
|
|
15
|
-
h2:
|
|
16
|
-
h3:
|
|
17
|
-
body:
|
|
18
|
-
caption: { fontSize: ms(13),
|
|
19
|
-
label:
|
|
14
|
+
h1: { fontFamily: 'Poppins-Bold', fontSize: ms(40), lineHeight: mvs(52) },
|
|
15
|
+
h2: { fontFamily: 'Poppins-Bold', fontSize: ms(28), lineHeight: mvs(36) },
|
|
16
|
+
h3: { fontFamily: 'Poppins-SemiBold', fontSize: ms(22), lineHeight: mvs(30) },
|
|
17
|
+
body: { fontFamily: 'Poppins-Regular', fontSize: ms(17), lineHeight: mvs(26) },
|
|
18
|
+
caption: { fontFamily: 'Poppins-Regular', fontSize: ms(13), lineHeight: mvs(20) },
|
|
19
|
+
label: { fontFamily: 'Poppins-Medium', fontSize: ms(15), lineHeight: mvs(22) },
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export function Text({ variant = 'body', color, style, children, ...props }: TextProps) {
|
|
@@ -83,17 +83,19 @@ const styles = StyleSheet.create({
|
|
|
83
83
|
gap: vs(8),
|
|
84
84
|
},
|
|
85
85
|
label: {
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
fontFamily: 'Poppins-Medium',
|
|
87
|
+
fontSize: ms(13),
|
|
88
88
|
},
|
|
89
89
|
input: {
|
|
90
|
-
|
|
90
|
+
fontFamily: 'Poppins-Regular',
|
|
91
|
+
borderWidth: 1,
|
|
91
92
|
borderRadius: ms(8),
|
|
92
|
-
paddingHorizontal: s(
|
|
93
|
-
paddingVertical: vs(
|
|
94
|
-
fontSize: ms(
|
|
93
|
+
paddingHorizontal: s(14),
|
|
94
|
+
paddingVertical: vs(11),
|
|
95
|
+
fontSize: ms(15),
|
|
95
96
|
},
|
|
96
97
|
helperText: {
|
|
98
|
+
fontFamily: 'Poppins-Regular',
|
|
97
99
|
fontSize: ms(13),
|
|
98
100
|
},
|
|
99
101
|
})
|
|
@@ -96,25 +96,29 @@ function ToastNotification({ item, onDismiss }: { item: ToastItem; onDismiss: ()
|
|
|
96
96
|
transform: [{ translateY: translateY.value }, { translateX: translateX.value }],
|
|
97
97
|
}))
|
|
98
98
|
|
|
99
|
+
const variant = item.variant ?? 'default'
|
|
100
|
+
|
|
99
101
|
const bgColor = {
|
|
100
102
|
default: colors.foreground,
|
|
101
|
-
destructive: colors.
|
|
102
|
-
success: colors.
|
|
103
|
-
}[
|
|
103
|
+
destructive: colors.destructiveBorder,
|
|
104
|
+
success: colors.successBorder,
|
|
105
|
+
}[variant]
|
|
104
106
|
|
|
105
107
|
const textColor = {
|
|
106
108
|
default: colors.background,
|
|
107
|
-
destructive:
|
|
108
|
-
success:
|
|
109
|
-
}[
|
|
109
|
+
destructive: '#991b1b',
|
|
110
|
+
success: '#166534',
|
|
111
|
+
}[variant]
|
|
112
|
+
|
|
113
|
+
const borderColor = textColor
|
|
110
114
|
|
|
111
115
|
const defaultIcon =
|
|
112
|
-
|
|
113
|
-
<FontAwesome5 name="check-circle" size={
|
|
114
|
-
) :
|
|
115
|
-
<
|
|
116
|
+
variant === 'success' ? (
|
|
117
|
+
<FontAwesome5 name="check-circle" size={18} color={textColor} />
|
|
118
|
+
) : variant === 'destructive' ? (
|
|
119
|
+
<AntDesign name="exclamation-circle" size={18} color={textColor} />
|
|
116
120
|
) : (
|
|
117
|
-
<Entypo name="info-with-circle" size={
|
|
121
|
+
<Entypo name="info-with-circle" size={18} color={textColor} />
|
|
118
122
|
)
|
|
119
123
|
|
|
120
124
|
const leftIcon: React.ReactNode = item.iconName
|
|
@@ -123,14 +127,14 @@ function ToastNotification({ item, onDismiss }: { item: ToastItem; onDismiss: ()
|
|
|
123
127
|
|
|
124
128
|
return (
|
|
125
129
|
<GestureDetector gesture={panGesture}>
|
|
126
|
-
<Animated.View style={[styles.toast, { backgroundColor: bgColor }, animatedStyle]}>
|
|
130
|
+
<Animated.View style={[styles.toast, { backgroundColor: bgColor, borderColor }, animatedStyle]}>
|
|
127
131
|
<View style={styles.leftIconContainer}>{leftIcon}</View>
|
|
128
132
|
<View style={styles.toastContent}>
|
|
129
133
|
{item.title ? (
|
|
130
|
-
<Text style={[styles.toastTitle, { color: textColor }]}>{item.title}</Text>
|
|
134
|
+
<Text style={[styles.toastTitle, { color: textColor }]} allowFontScaling={true}>{item.title}</Text>
|
|
131
135
|
) : null}
|
|
132
136
|
{item.description ? (
|
|
133
|
-
<Text style={[styles.toastDescription, { color: textColor, opacity: 0.85 }]}>
|
|
137
|
+
<Text style={[styles.toastDescription, { color: textColor, opacity: 0.85 }]} allowFontScaling={true}>
|
|
134
138
|
{item.description}
|
|
135
139
|
</Text>
|
|
136
140
|
) : null}
|
|
@@ -201,30 +205,32 @@ const styles = StyleSheet.create({
|
|
|
201
205
|
toast: {
|
|
202
206
|
flexDirection: 'row',
|
|
203
207
|
alignItems: 'center',
|
|
204
|
-
borderRadius: ms(
|
|
205
|
-
|
|
206
|
-
|
|
208
|
+
borderRadius: ms(12),
|
|
209
|
+
borderWidth: 1,
|
|
210
|
+
paddingHorizontal: s(14),
|
|
211
|
+
paddingVertical: vs(12),
|
|
207
212
|
shadowColor: '#000',
|
|
208
|
-
shadowOffset: { width: 0, height:
|
|
209
|
-
shadowOpacity: 0.
|
|
213
|
+
shadowOffset: { width: 0, height: 3 },
|
|
214
|
+
shadowOpacity: 0.10,
|
|
210
215
|
shadowRadius: 8,
|
|
211
|
-
elevation:
|
|
216
|
+
elevation: 5,
|
|
212
217
|
},
|
|
213
218
|
toastContent: {
|
|
214
219
|
flex: 1,
|
|
215
220
|
gap: vs(4),
|
|
216
221
|
},
|
|
217
222
|
leftIconContainer: {
|
|
218
|
-
width: s(
|
|
223
|
+
width: s(28),
|
|
219
224
|
alignItems: 'center',
|
|
220
225
|
justifyContent: 'center',
|
|
221
|
-
marginRight: s(
|
|
226
|
+
marginRight: s(10),
|
|
222
227
|
},
|
|
223
228
|
toastTitle: {
|
|
229
|
+
fontFamily: 'Poppins-SemiBold',
|
|
224
230
|
fontSize: ms(15),
|
|
225
|
-
fontWeight: '600',
|
|
226
231
|
},
|
|
227
232
|
toastDescription: {
|
|
233
|
+
fontFamily: 'Poppins-Regular',
|
|
228
234
|
fontSize: ms(14),
|
|
229
235
|
},
|
|
230
236
|
dismissButton: {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import React, { useRef, useEffect } from 'react'
|
|
2
|
-
import { TouchableOpacity, Animated, StyleSheet, TouchableOpacityProps, ViewStyle, View, Easing } from 'react-native'
|
|
2
|
+
import { TouchableOpacity, Animated, StyleSheet, TouchableOpacityProps, ViewStyle, View, Easing, Platform } from 'react-native'
|
|
3
|
+
|
|
4
|
+
const nativeDriver = Platform.OS !== 'web'
|
|
3
5
|
import { FontAwesome5 } from '@expo/vector-icons'
|
|
4
6
|
import { selectionAsync as hapticSelection } from '../../utils/haptics'
|
|
5
7
|
import { useTheme } from '../../theme'
|
|
@@ -75,11 +77,11 @@ export function Toggle({
|
|
|
75
77
|
|
|
76
78
|
const handlePressIn = () => {
|
|
77
79
|
if (disabled) return
|
|
78
|
-
Animated.spring(scale, { toValue: 0.95, useNativeDriver:
|
|
80
|
+
Animated.spring(scale, { toValue: 0.95, useNativeDriver: nativeDriver, speed: 40, bounciness: 0 }).start()
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
const handlePressOut = () => {
|
|
82
|
-
Animated.spring(scale, { toValue: 1, useNativeDriver:
|
|
84
|
+
Animated.spring(scale, { toValue: 1, useNativeDriver: nativeDriver, speed: 40, bounciness: 4 }).start()
|
|
83
85
|
}
|
|
84
86
|
|
|
85
87
|
// Keep borderWidth constant at 2 to prevent layout jumps when pressing.
|
|
@@ -146,7 +148,7 @@ export function Toggle({
|
|
|
146
148
|
>
|
|
147
149
|
<View style={styles.inner}>
|
|
148
150
|
<LeftIcon />
|
|
149
|
-
{label ? <Animated.Text style={[styles.label, { color: textColor }]}>{label}</Animated.Text> : null}
|
|
151
|
+
{label ? <Animated.Text style={[styles.label, { color: textColor }]} allowFontScaling={true}>{label}</Animated.Text> : null}
|
|
150
152
|
</View>
|
|
151
153
|
</Animated.View>
|
|
152
154
|
</TouchableOpacity>
|
|
@@ -168,7 +170,7 @@ const styles = StyleSheet.create({
|
|
|
168
170
|
opacity: 0.45,
|
|
169
171
|
},
|
|
170
172
|
label: {
|
|
173
|
+
fontFamily: 'Poppins-Medium',
|
|
171
174
|
fontSize: ms(14),
|
|
172
|
-
fontWeight: '500',
|
|
173
175
|
},
|
|
174
176
|
})
|
package/src/fonts.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Poppins font family required by @retray-dev/ui-kit components.
|
|
3
|
+
*
|
|
4
|
+
* Consumer apps must load these fonts at app root using expo-font:
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* import { useFonts } from 'expo-font'
|
|
8
|
+
* import { PoppinsFonts } from '@retray-dev/ui-kit'
|
|
9
|
+
*
|
|
10
|
+
* function App() {
|
|
11
|
+
* const [fontsLoaded] = useFonts(PoppinsFonts)
|
|
12
|
+
* if (!fontsLoaded) return null
|
|
13
|
+
* // render app
|
|
14
|
+
* }
|
|
15
|
+
*/
|
|
16
|
+
export const PoppinsFonts = {
|
|
17
|
+
'Poppins-Thin': require('./assets/fonts/Poppins-Thin.ttf'),
|
|
18
|
+
'Poppins-ExtraLight': require('./assets/fonts/Poppins-ExtraLight.ttf'),
|
|
19
|
+
'Poppins-Light': require('./assets/fonts/Poppins-Light.ttf'),
|
|
20
|
+
'Poppins-Regular': require('./assets/fonts/Poppins-Regular.ttf'),
|
|
21
|
+
'Poppins-Medium': require('./assets/fonts/Poppins-Medium.ttf'),
|
|
22
|
+
'Poppins-SemiBold': require('./assets/fonts/Poppins-SemiBold.ttf'),
|
|
23
|
+
'Poppins-Bold': require('./assets/fonts/Poppins-Bold.ttf'),
|
|
24
|
+
'Poppins-ExtraBold': require('./assets/fonts/Poppins-ExtraBold.ttf'),
|
|
25
|
+
'Poppins-Black': require('./assets/fonts/Poppins-Black.ttf'),
|
|
26
|
+
'Poppins-Italic': require('./assets/fonts/Poppins-Italic.ttf'),
|
|
27
|
+
'Poppins-MediumItalic': require('./assets/fonts/Poppins-MediumItalic.ttf'),
|
|
28
|
+
'Poppins-SemiBoldItalic': require('./assets/fonts/Poppins-SemiBoldItalic.ttf'),
|
|
29
|
+
'Poppins-BoldItalic': require('./assets/fonts/Poppins-BoldItalic.ttf'),
|
|
30
|
+
} as const
|
package/src/index.ts
CHANGED
package/src/theme/colors.ts
CHANGED
|
@@ -15,32 +15,40 @@ export const defaultLight: ThemeColors = {
|
|
|
15
15
|
accent: '#e4e4e4',
|
|
16
16
|
accentForeground: '#171717',
|
|
17
17
|
destructive: '#ef4444',
|
|
18
|
-
destructiveForeground: '#
|
|
18
|
+
destructiveForeground: '#ffffff',
|
|
19
19
|
border: '#e5e5e5',
|
|
20
20
|
input: '#e5e5e5',
|
|
21
21
|
ring: '#1a1a1a',
|
|
22
|
-
success: '#
|
|
23
|
-
successForeground: '#
|
|
22
|
+
success: '#1a7a45',
|
|
23
|
+
successForeground: '#ffffff',
|
|
24
|
+
destructiveTint: '#fff5f5',
|
|
25
|
+
destructiveBorder: '#fecaca',
|
|
26
|
+
successTint: '#f0fdf4',
|
|
27
|
+
successBorder: '#bbf7d0',
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
export const defaultDark: ThemeColors = {
|
|
27
|
-
background: '#
|
|
31
|
+
background: '#0f0f0f',
|
|
28
32
|
foreground: '#fafafa',
|
|
29
|
-
card: '#
|
|
33
|
+
card: '#1c1c1c',
|
|
30
34
|
cardForeground: '#fafafa',
|
|
31
35
|
primary: '#fafafa',
|
|
32
|
-
primaryForeground: '#
|
|
33
|
-
secondary: '#
|
|
36
|
+
primaryForeground: '#0f0f0f',
|
|
37
|
+
secondary: '#272727',
|
|
34
38
|
secondaryForeground: '#fafafa',
|
|
35
|
-
muted: '#
|
|
36
|
-
mutedForeground: '#
|
|
37
|
-
accent: '#
|
|
39
|
+
muted: '#272727',
|
|
40
|
+
mutedForeground: '#9a9a9a',
|
|
41
|
+
accent: '#2e2e2e',
|
|
38
42
|
accentForeground: '#fafafa',
|
|
39
43
|
destructive: '#dc2626',
|
|
40
|
-
destructiveForeground: '#
|
|
41
|
-
border: '#
|
|
44
|
+
destructiveForeground: '#ffffff',
|
|
45
|
+
border: '#303030',
|
|
42
46
|
input: '#2a2a2a',
|
|
43
47
|
ring: '#fafafa',
|
|
44
|
-
success: '#
|
|
45
|
-
successForeground: '#
|
|
48
|
+
success: '#166534',
|
|
49
|
+
successForeground: '#ffffff',
|
|
50
|
+
destructiveTint: '#3b0a0a',
|
|
51
|
+
destructiveBorder: '#7f1d1d',
|
|
52
|
+
successTint: '#052e16',
|
|
53
|
+
successBorder: '#166534',
|
|
46
54
|
}
|
package/src/theme/types.ts
CHANGED
|
@@ -18,6 +18,10 @@ export type ThemeColors = {
|
|
|
18
18
|
ring: string
|
|
19
19
|
success: string
|
|
20
20
|
successForeground: string
|
|
21
|
+
destructiveTint: string
|
|
22
|
+
destructiveBorder: string
|
|
23
|
+
successTint: string
|
|
24
|
+
successBorder: string
|
|
21
25
|
}
|
|
22
26
|
|
|
23
27
|
// Theme overrides: consumers may supply partial or full `ThemeColors` objects
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { View, Text, StyleSheet, ViewStyle } from 'react-native'
|
|
3
|
-
import { useTheme } from '../../theme'
|
|
4
|
-
import { s, vs, ms, mvs } from '../../utils/scaling'
|
|
5
|
-
|
|
6
|
-
export type AlertBannerVariant = 'default' | 'destructive' | 'success'
|
|
7
|
-
|
|
8
|
-
export interface AlertBannerProps {
|
|
9
|
-
title?: string
|
|
10
|
-
description?: string
|
|
11
|
-
variant?: AlertBannerVariant
|
|
12
|
-
icon?: React.ReactNode
|
|
13
|
-
style?: ViewStyle
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function AlertBanner({ title, description, variant = 'default', icon, style }: AlertBannerProps) {
|
|
17
|
-
const { colors } = useTheme()
|
|
18
|
-
|
|
19
|
-
const borderColor =
|
|
20
|
-
variant === 'destructive' ? colors.destructive
|
|
21
|
-
: variant === 'success' ? colors.success
|
|
22
|
-
: colors.border
|
|
23
|
-
|
|
24
|
-
const titleColor =
|
|
25
|
-
variant === 'destructive' ? colors.destructive
|
|
26
|
-
: variant === 'success' ? colors.success
|
|
27
|
-
: colors.foreground
|
|
28
|
-
|
|
29
|
-
const descColor =
|
|
30
|
-
variant === 'destructive' ? colors.destructive
|
|
31
|
-
: variant === 'success' ? colors.success
|
|
32
|
-
: colors.mutedForeground
|
|
33
|
-
|
|
34
|
-
const defaultIcon =
|
|
35
|
-
variant === 'destructive' ? '⚠' : variant === 'success' ? '✓' : 'ℹ'
|
|
36
|
-
|
|
37
|
-
return (
|
|
38
|
-
<View style={[styles.container, { backgroundColor: colors.card, borderColor }, style]}>
|
|
39
|
-
{icon ? (
|
|
40
|
-
<View style={styles.icon}>{icon}</View>
|
|
41
|
-
) : (
|
|
42
|
-
<View style={styles.icon}>
|
|
43
|
-
<Text style={[styles.defaultIcon, { color: titleColor }]} allowFontScaling={true}>{defaultIcon}</Text>
|
|
44
|
-
</View>
|
|
45
|
-
)}
|
|
46
|
-
<View style={styles.content}>
|
|
47
|
-
{title ? <Text style={[styles.title, { color: titleColor }]} allowFontScaling={true}>{title}</Text> : null}
|
|
48
|
-
{description ? (
|
|
49
|
-
<Text style={[styles.description, { color: descColor }]} allowFontScaling={true}>{description}</Text>
|
|
50
|
-
) : null}
|
|
51
|
-
</View>
|
|
52
|
-
</View>
|
|
53
|
-
)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const styles = StyleSheet.create({
|
|
57
|
-
container: {
|
|
58
|
-
flexDirection: 'row',
|
|
59
|
-
borderWidth: 1,
|
|
60
|
-
borderRadius: ms(8),
|
|
61
|
-
padding: s(16),
|
|
62
|
-
gap: s(12),
|
|
63
|
-
},
|
|
64
|
-
icon: {
|
|
65
|
-
marginTop: vs(2),
|
|
66
|
-
},
|
|
67
|
-
content: {
|
|
68
|
-
flex: 1,
|
|
69
|
-
gap: vs(4),
|
|
70
|
-
},
|
|
71
|
-
title: {
|
|
72
|
-
fontSize: ms(14),
|
|
73
|
-
fontWeight: '500',
|
|
74
|
-
lineHeight: mvs(20),
|
|
75
|
-
},
|
|
76
|
-
description: {
|
|
77
|
-
fontSize: ms(14),
|
|
78
|
-
lineHeight: mvs(20),
|
|
79
|
-
},
|
|
80
|
-
defaultIcon: {
|
|
81
|
-
fontSize: ms(18),
|
|
82
|
-
fontWeight: '700',
|
|
83
|
-
},
|
|
84
|
-
})
|