@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.
Files changed (59) hide show
  1. package/COMPONENTS.md +102 -15
  2. package/README.md +25 -5
  3. package/dist/index.d.mts +36 -6
  4. package/dist/index.d.ts +36 -6
  5. package/dist/index.js +692 -484
  6. package/dist/index.mjs +622 -415
  7. package/package.json +6 -3
  8. package/src/assets/fonts/Poppins-Black.ttf +0 -0
  9. package/src/assets/fonts/Poppins-BlackItalic.ttf +0 -0
  10. package/src/assets/fonts/Poppins-Bold.ttf +0 -0
  11. package/src/assets/fonts/Poppins-BoldItalic.ttf +0 -0
  12. package/src/assets/fonts/Poppins-ExtraBold.ttf +0 -0
  13. package/src/assets/fonts/Poppins-ExtraBoldItalic.ttf +0 -0
  14. package/src/assets/fonts/Poppins-ExtraLight.ttf +0 -0
  15. package/src/assets/fonts/Poppins-ExtraLightItalic.ttf +0 -0
  16. package/src/assets/fonts/Poppins-Italic.ttf +0 -0
  17. package/src/assets/fonts/Poppins-Light.ttf +0 -0
  18. package/src/assets/fonts/Poppins-LightItalic.ttf +0 -0
  19. package/src/assets/fonts/Poppins-Medium.ttf +0 -0
  20. package/src/assets/fonts/Poppins-MediumItalic.ttf +0 -0
  21. package/src/assets/fonts/Poppins-Regular.ttf +0 -0
  22. package/src/assets/fonts/Poppins-SemiBold.ttf +0 -0
  23. package/src/assets/fonts/Poppins-SemiBoldItalic.ttf +0 -0
  24. package/src/assets/fonts/Poppins-Thin.ttf +0 -0
  25. package/src/assets/fonts/Poppins-ThinItalic.ttf +0 -0
  26. package/src/components/Accordion/Accordion.tsx +16 -9
  27. package/src/components/AlertBanner/AlertBanner.tsx +35 -35
  28. package/src/components/Avatar/Avatar.tsx +1 -1
  29. package/src/components/Badge/Badge.tsx +12 -8
  30. package/src/components/Button/Button.tsx +9 -9
  31. package/src/components/Card/Card.tsx +12 -9
  32. package/src/components/Checkbox/Checkbox.tsx +9 -8
  33. package/src/components/Chip/Chip.tsx +22 -6
  34. package/src/components/ConfirmDialog/ConfirmDialog.tsx +86 -38
  35. package/src/components/CurrencyDisplay/CurrencyDisplay.tsx +1 -1
  36. package/src/components/CurrencyInput/CurrencyInput.tsx +11 -4
  37. package/src/components/EmptyState/EmptyState.tsx +2 -1
  38. package/src/components/IconButton/IconButton.tsx +147 -0
  39. package/src/components/IconButton/index.ts +2 -0
  40. package/src/components/Input/Input.tsx +12 -8
  41. package/src/components/LabelValue/LabelValue.tsx +4 -3
  42. package/src/components/ListItem/ListItem.tsx +10 -9
  43. package/src/components/MonthPicker/MonthPicker.tsx +1 -1
  44. package/src/components/RadioGroup/RadioGroup.tsx +36 -35
  45. package/src/components/Select/Select.tsx +19 -21
  46. package/src/components/Sheet/Sheet.tsx +4 -3
  47. package/src/components/Slider/Slider.tsx +3 -3
  48. package/src/components/Spinner/Spinner.tsx +36 -2
  49. package/src/components/Switch/Switch.tsx +4 -4
  50. package/src/components/Tabs/Tabs.tsx +10 -16
  51. package/src/components/Text/Text.tsx +6 -6
  52. package/src/components/Textarea/Textarea.tsx +8 -6
  53. package/src/components/Toast/Toast.tsx +29 -23
  54. package/src/components/Toggle/Toggle.tsx +7 -5
  55. package/src/fonts.ts +30 -0
  56. package/src/index.ts +1 -0
  57. package/src/theme/colors.ts +22 -14
  58. package/src/theme/types.ts +4 -0
  59. 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: true, speed: 40, bounciness: 0 }).start()
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: true, speed: 40, bounciness: 4 }).start()
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
- fontSize: ms(15),
235
- fontWeight: '500',
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.5,
242
+ borderWidth: 1,
242
243
  borderRadius: ms(8),
243
- paddingHorizontal: s(16),
244
- paddingVertical: vs(14),
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
- fontSize: ms(17),
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.5,
293
+ borderWidth: 1,
296
294
  borderRadius: ms(8),
297
- paddingHorizontal: s(16),
298
- paddingVertical: vs(14),
299
- fontSize: ms(17),
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(40),
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
- export function Spinner({ size = 'md', color, ...props }: SpinnerProps) {
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(60)
10
- const TRACK_HEIGHT = vs(36)
11
- const THUMB_SIZE = s(28)
12
- const THUMB_OFFSET = s(4)
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
- <View style={styles.triggerIcon}>
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(12),
194
- paddingHorizontal: s(16),
195
- borderRadius: ms(8),
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(8),
205
- },
206
- triggerIcon: {
207
- marginRight: s(6),
208
- alignItems: 'center',
209
- justifyContent: 'center',
203
+ gap: s(4),
210
204
  },
211
205
  triggerLabel: {
212
- fontSize: ms(15),
213
- fontWeight: '400',
206
+ fontFamily: 'Poppins-Regular',
207
+ fontSize: ms(13),
214
208
  },
215
209
  activeTriggerLabel: {
216
- fontWeight: '500',
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: { fontSize: ms(40), fontWeight: '700', lineHeight: mvs(52) },
15
- h2: { fontSize: ms(28), fontWeight: '700', lineHeight: mvs(36) },
16
- h3: { fontSize: ms(22), fontWeight: '600', lineHeight: mvs(30) },
17
- body: { fontSize: ms(17), fontWeight: '400', lineHeight: mvs(26) },
18
- caption: { fontSize: ms(13), fontWeight: '400', lineHeight: mvs(20) },
19
- label: { fontSize: ms(15), fontWeight: '500', lineHeight: mvs(22) },
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
- fontSize: ms(15),
87
- fontWeight: '500',
86
+ fontFamily: 'Poppins-Medium',
87
+ fontSize: ms(13),
88
88
  },
89
89
  input: {
90
- borderWidth: 1.5,
90
+ fontFamily: 'Poppins-Regular',
91
+ borderWidth: 1,
91
92
  borderRadius: ms(8),
92
- paddingHorizontal: s(16),
93
- paddingVertical: vs(14),
94
- fontSize: ms(17),
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.destructive,
102
- success: colors.success,
103
- }[item.variant ?? 'default']
103
+ destructive: colors.destructiveBorder,
104
+ success: colors.successBorder,
105
+ }[variant]
104
106
 
105
107
  const textColor = {
106
108
  default: colors.background,
107
- destructive: colors.destructiveForeground,
108
- success: colors.successForeground,
109
- }[item.variant ?? 'default']
109
+ destructive: '#991b1b',
110
+ success: '#166534',
111
+ }[variant]
112
+
113
+ const borderColor = textColor
110
114
 
111
115
  const defaultIcon =
112
- item.variant === 'success' ? (
113
- <FontAwesome5 name="check-circle" size={22} color={textColor} />
114
- ) : item.variant === 'destructive' ? (
115
- <MaterialIcons name="error-outline" size={24} color={textColor} />
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={22} color={textColor} />
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(16),
205
- paddingHorizontal: s(20),
206
- paddingVertical: vs(14),
208
+ borderRadius: ms(12),
209
+ borderWidth: 1,
210
+ paddingHorizontal: s(14),
211
+ paddingVertical: vs(12),
207
212
  shadowColor: '#000',
208
- shadowOffset: { width: 0, height: 4 },
209
- shadowOpacity: 0.15,
213
+ shadowOffset: { width: 0, height: 3 },
214
+ shadowOpacity: 0.10,
210
215
  shadowRadius: 8,
211
- elevation: 6,
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(40),
223
+ width: s(28),
219
224
  alignItems: 'center',
220
225
  justifyContent: 'center',
221
- marginRight: s(8),
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: true, speed: 40, bounciness: 0 }).start()
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: true, speed: 40, bounciness: 4 }).start()
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
@@ -5,6 +5,7 @@ export { defaultLight, defaultDark } from './theme'
5
5
 
6
6
  // Components
7
7
  export * from './components/Button'
8
+ export * from './components/IconButton'
8
9
  export * from './components/Text'
9
10
  export * from './components/Input'
10
11
  export * from './components/Badge'
@@ -15,32 +15,40 @@ export const defaultLight: ThemeColors = {
15
15
  accent: '#e4e4e4',
16
16
  accentForeground: '#171717',
17
17
  destructive: '#ef4444',
18
- destructiveForeground: '#1a1a1a',
18
+ destructiveForeground: '#ffffff',
19
19
  border: '#e5e5e5',
20
20
  input: '#e5e5e5',
21
21
  ring: '#1a1a1a',
22
- success: '#16a34a',
23
- successForeground: '#1a1a1a',
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: '#171717',
31
+ background: '#0f0f0f',
28
32
  foreground: '#fafafa',
29
- card: '#222222',
33
+ card: '#1c1c1c',
30
34
  cardForeground: '#fafafa',
31
35
  primary: '#fafafa',
32
- primaryForeground: '#1a1a1a',
33
- secondary: '#323232',
36
+ primaryForeground: '#0f0f0f',
37
+ secondary: '#272727',
34
38
  secondaryForeground: '#fafafa',
35
- muted: '#323232',
36
- mutedForeground: '#888888',
37
- accent: '#323232',
39
+ muted: '#272727',
40
+ mutedForeground: '#9a9a9a',
41
+ accent: '#2e2e2e',
38
42
  accentForeground: '#fafafa',
39
43
  destructive: '#dc2626',
40
- destructiveForeground: '#1a1a1a',
41
- border: '#2a2a2a',
44
+ destructiveForeground: '#ffffff',
45
+ border: '#303030',
42
46
  input: '#2a2a2a',
43
47
  ring: '#fafafa',
44
- success: '#22c55e',
45
- successForeground: '#1a1a1a',
48
+ success: '#166534',
49
+ successForeground: '#ffffff',
50
+ destructiveTint: '#3b0a0a',
51
+ destructiveBorder: '#7f1d1d',
52
+ successTint: '#052e16',
53
+ successBorder: '#166534',
46
54
  }
@@ -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
- })