@retray-dev/ui-kit 1.6.0 → 1.7.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retray-dev/ui-kit",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "Personal UI Kit for React Native / Expo",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -52,7 +52,7 @@
52
52
  "fast-xml-parser": "^5.5.7",
53
53
  "react": "19.1.0",
54
54
  "react-native": "0.81.5",
55
- "react-native-worklets": "0.8.1"
55
+ "react-native-worklets": "0.5.1"
56
56
  },
57
57
  "onlyBuiltDependencies": [
58
58
  "esbuild"
@@ -62,12 +62,12 @@
62
62
  "@gorhom/bottom-sheet": "^5.0.0",
63
63
  "@types/react": "^19.1.0",
64
64
  "expo-haptics": "~15.0.8",
65
- "expo-linear-gradient": "~14.1.5",
66
- "react": "18.2.0",
67
- "react-native": "0.74.0",
68
- "react-native-gesture-handler": "~2.30.0",
69
- "react-native-reanimated": "~4.3.0",
70
- "react-native-worklets": "~0.8.1",
65
+ "expo-linear-gradient": "~15.0.8",
66
+ "react": "19.1.0",
67
+ "react-native": "0.81.5",
68
+ "react-native-gesture-handler": "~2.28.0",
69
+ "react-native-reanimated": "~4.1.1",
70
+ "react-native-worklets": "~0.5.1",
71
71
  "react-native-safe-area-context": "~5.6.2",
72
72
  "eslint": "^9.0.0",
73
73
  "@eslint/js": "^9.0.0",
@@ -154,19 +154,19 @@ const styles = StyleSheet.create({
154
154
  flexDirection: 'row',
155
155
  justifyContent: 'space-between',
156
156
  alignItems: 'center',
157
- paddingVertical: 16,
157
+ paddingVertical: 20,
158
158
  },
159
159
  triggerText: {
160
- fontSize: 15,
160
+ fontSize: 17,
161
161
  fontWeight: '500',
162
162
  flex: 1,
163
163
  },
164
164
  chevron: {
165
- fontSize: 16,
165
+ fontSize: 18,
166
166
  marginLeft: 8,
167
167
  },
168
168
  content: {
169
- paddingBottom: 16,
169
+ paddingBottom: 20,
170
170
  position: 'absolute',
171
171
  width: '100%',
172
172
  },
@@ -21,7 +21,15 @@ export function Alert({ title, description, variant = 'default', icon, style }:
21
21
 
22
22
  return (
23
23
  <View style={[styles.container, { backgroundColor: colors.card, borderColor }, style]}>
24
- {icon ? <View style={styles.icon}>{icon}</View> : null}
24
+ {icon ? (
25
+ <View style={styles.icon}>{icon}</View>
26
+ ) : (
27
+ <View style={styles.icon}>
28
+ <Text style={[styles.defaultIcon, { color: titleColor }]}>
29
+ {variant === 'destructive' ? '⚠' : 'ℹ'}
30
+ </Text>
31
+ </View>
32
+ )}
25
33
  <View style={styles.content}>
26
34
  {title ? <Text style={[styles.title, { color: titleColor }]}>{title}</Text> : null}
27
35
  {description ? (
@@ -56,4 +64,8 @@ const styles = StyleSheet.create({
56
64
  fontSize: 14,
57
65
  lineHeight: 20,
58
66
  },
67
+ defaultIcon: {
68
+ fontSize: 18,
69
+ fontWeight: '700',
70
+ },
59
71
  })
@@ -14,17 +14,17 @@ export interface AvatarProps {
14
14
  }
15
15
 
16
16
  const sizeMap: Record<AvatarSize, number> = {
17
- sm: 24,
18
- md: 32,
19
- lg: 48,
20
- xl: 64,
17
+ sm: 28,
18
+ md: 40,
19
+ lg: 56,
20
+ xl: 72,
21
21
  }
22
22
 
23
23
  const fontSizeMap: Record<AvatarSize, number> = {
24
- sm: 10,
25
- md: 13,
26
- lg: 18,
27
- xl: 24,
24
+ sm: 12,
25
+ md: 16,
26
+ lg: 22,
27
+ xl: 28,
28
28
  }
29
29
 
30
30
  export function Avatar({ src, fallback, size = 'md', style }: AvatarProps) {
@@ -36,13 +36,13 @@ export function Badge({ label, variant = 'default', style }: BadgeProps) {
36
36
 
37
37
  const styles = StyleSheet.create({
38
38
  container: {
39
- borderRadius: 6,
40
- paddingHorizontal: 8,
41
- paddingVertical: 2,
39
+ borderRadius: 8,
40
+ paddingHorizontal: 10,
41
+ paddingVertical: 4,
42
42
  alignSelf: 'flex-start',
43
43
  },
44
44
  label: {
45
- fontSize: 12,
45
+ fontSize: 13,
46
46
  fontWeight: '500',
47
47
  },
48
48
  })
@@ -28,21 +28,21 @@ export interface ButtonProps extends TouchableOpacityProps {
28
28
  /** Replaces the label with a spinner and forces `disabled`. */
29
29
  loading?: boolean
30
30
  fullWidth?: boolean
31
- /** Icon rendered alongside the label. */
32
- icon?: React.ReactNode
31
+ /** Icon rendered alongside the label. Can be a ReactNode or a render function `(props) => ReactNode`. */
32
+ icon?: React.ReactNode | ((props: { label: string; size: ButtonSize; variant: ButtonVariant }) => React.ReactNode)
33
33
  /** Side the icon appears on. Defaults to `'left'`. */
34
34
  iconPosition?: 'left' | 'right'
35
35
  }
36
36
 
37
37
  const containerSizeStyles: Record<ButtonSize, ViewStyle> = {
38
- sm: { paddingHorizontal: 16, paddingVertical: 10 },
39
- md: { paddingHorizontal: 20, paddingVertical: 14 },
40
- lg: { paddingHorizontal: 28, paddingVertical: 18 },
38
+ sm: { paddingHorizontal: 20, paddingVertical: 12 },
39
+ md: { paddingHorizontal: 24, paddingVertical: 16 },
40
+ lg: { paddingHorizontal: 32, paddingVertical: 20 },
41
41
  }
42
42
 
43
43
  const labelSizeStyles: Record<ButtonSize, TextStyle> = {
44
- sm: { fontSize: 14 },
45
- md: { fontSize: 16 },
44
+ sm: { fontSize: 15 },
45
+ md: { fontSize: 17 },
46
46
  lg: { fontSize: 18 },
47
47
  }
48
48
 
@@ -122,9 +122,9 @@ export function Button({
122
122
  <ActivityIndicator size="small" color={spinnerColor} />
123
123
  ) : (
124
124
  <>
125
- {icon && iconPosition === 'left' && <>{icon}</>}
125
+ {icon && iconPosition === 'left' && <>{typeof icon === 'function' ? icon({ label, size, variant }) : icon}</>}
126
126
  <Text style={[styles.label, labelVariantStyle, labelSizeStyles[size], icon ? styles.labelWithIcon : undefined]}>{label}</Text>
127
- {icon && iconPosition === 'right' && <>{icon}</>}
127
+ {icon && iconPosition === 'right' && <>{typeof icon === 'function' ? icon({ label, size, variant }) : icon}</>}
128
128
  </>
129
129
  )}
130
130
  </TouchableOpacity>
@@ -134,7 +134,7 @@ export function Button({
134
134
 
135
135
  const styles = StyleSheet.create({
136
136
  base: {
137
- borderRadius: 8,
137
+ borderRadius: 999,
138
138
  alignItems: 'center',
139
139
  justifyContent: 'center',
140
140
  flexDirection: 'row',
@@ -69,7 +69,7 @@ export function CardFooter({ children, style }: CardFooterProps) {
69
69
 
70
70
  const styles = StyleSheet.create({
71
71
  card: {
72
- borderRadius: 12,
72
+ borderRadius: 20,
73
73
  borderWidth: 1,
74
74
  shadowColor: '#000',
75
75
  shadowOffset: { width: 0, height: 1 },
@@ -78,24 +78,24 @@ const styles = StyleSheet.create({
78
78
  elevation: 1,
79
79
  },
80
80
  header: {
81
- padding: 24,
81
+ padding: 28,
82
82
  paddingBottom: 0,
83
- gap: 6,
83
+ gap: 8,
84
84
  },
85
85
  title: {
86
- fontSize: 18,
86
+ fontSize: 20,
87
87
  fontWeight: '600',
88
- lineHeight: 24,
88
+ lineHeight: 28,
89
89
  },
90
90
  description: {
91
- fontSize: 14,
92
- lineHeight: 20,
91
+ fontSize: 15,
92
+ lineHeight: 22,
93
93
  },
94
94
  content: {
95
- padding: 24,
95
+ padding: 28,
96
96
  },
97
97
  footer: {
98
- padding: 24,
98
+ padding: 28,
99
99
  paddingTop: 0,
100
100
  flexDirection: 'row',
101
101
  alignItems: 'center',
@@ -74,25 +74,25 @@ const styles = StyleSheet.create({
74
74
  row: {
75
75
  flexDirection: 'row',
76
76
  alignItems: 'center',
77
- gap: 10,
77
+ gap: 12,
78
78
  },
79
79
  box: {
80
- width: 24,
81
- height: 24,
82
- borderRadius: 6,
80
+ width: 28,
81
+ height: 28,
82
+ borderRadius: 8,
83
83
  borderWidth: 1.5,
84
84
  alignItems: 'center',
85
85
  justifyContent: 'center',
86
86
  },
87
87
  checkmark: {
88
- width: 13,
89
- height: 8,
88
+ width: 15,
89
+ height: 9,
90
90
  borderLeftWidth: 2,
91
91
  borderBottomWidth: 2,
92
92
  transform: [{ rotate: '-45deg' }, { translateY: -1 }],
93
93
  },
94
94
  label: {
95
- fontSize: 14,
96
- lineHeight: 20,
95
+ fontSize: 15,
96
+ lineHeight: 22,
97
97
  },
98
98
  })
@@ -0,0 +1,46 @@
1
+ import React from 'react'
2
+ import { View, Text, StyleSheet, ViewStyle } from 'react-native'
3
+ import { useTheme } from '../../theme'
4
+
5
+ export interface CurrencyDisplayProps {
6
+ value: number | string
7
+ /** Symbol prepended to the formatted value. Defaults to `'$'`. */
8
+ prefix?: string
9
+ /** When true, shows two decimal places separated by a comma (e.g. `$25.000,00`). Defaults to `false`. */
10
+ showDecimals?: boolean
11
+ style?: ViewStyle
12
+ }
13
+
14
+ function formatValue(value: number | string, prefix: string, showDecimals: boolean): string {
15
+ const num = typeof value === 'string' ? parseFloat(value.replace(/[^0-9.-]/g, '')) : value
16
+ if (isNaN(num)) return `${prefix}0`
17
+ const abs = Math.abs(num)
18
+ const sign = num < 0 ? '-' : ''
19
+ const intPart = Math.floor(abs).toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.')
20
+ if (showDecimals) {
21
+ const decStr = (abs % 1).toFixed(2).slice(2)
22
+ return `${sign}${prefix}${intPart},${decStr}`
23
+ }
24
+ return `${sign}${prefix}${intPart}`
25
+ }
26
+
27
+ export function CurrencyDisplay({ value, prefix = '$', showDecimals = false, style }: CurrencyDisplayProps) {
28
+ const { colors } = useTheme()
29
+ const formatted = formatValue(value, prefix, showDecimals)
30
+
31
+ return (
32
+ <View style={[styles.container, style]}>
33
+ <Text style={[styles.amount, { color: colors.foreground }]} allowFontScaling={true}>
34
+ {formatted}
35
+ </Text>
36
+ </View>
37
+ )
38
+ }
39
+
40
+ const styles = StyleSheet.create({
41
+ container: {},
42
+ amount: {
43
+ fontSize: 56,
44
+ fontWeight: '700',
45
+ },
46
+ })
@@ -0,0 +1 @@
1
+ export * from './CurrencyDisplay'
@@ -0,0 +1,66 @@
1
+ import React from 'react'
2
+ import { ViewStyle } from 'react-native'
3
+ import { Input } from '../Input'
4
+
5
+ export interface CurrencyInputLargeProps {
6
+ value?: string
7
+ onChangeText?: (formatted: string) => void
8
+ /** Called with the parsed numeric value (no separators, no prefix). */
9
+ onChangeValue?: (raw: number) => void
10
+ /** Symbol prepended to the formatted value. Defaults to `'$'`. */
11
+ prefix?: string
12
+ /** Character used to separate groups of three digits. Defaults to `'.'`. */
13
+ thousandsSeparator?: '.' | ','
14
+ label?: string
15
+ /** Red helper text; also changes input border to destructive color. */
16
+ error?: string
17
+ hint?: string
18
+ placeholder?: string
19
+ editable?: boolean
20
+ containerStyle?: ViewStyle
21
+ }
22
+
23
+ function formatCurrency(raw: string, separator: '.' | ','): string {
24
+ const digits = raw.replace(/\D/g, '')
25
+ if (!digits) return ''
26
+ return digits.replace(/\B(?=(\d{3})+(?!\d))/g, separator)
27
+ }
28
+
29
+ export function CurrencyInputLarge({
30
+ value,
31
+ onChangeText,
32
+ onChangeValue,
33
+ prefix = '$',
34
+ thousandsSeparator = '.',
35
+ label,
36
+ error,
37
+ hint,
38
+ placeholder,
39
+ editable,
40
+ containerStyle,
41
+ }: CurrencyInputLargeProps) {
42
+ const handleChange = (text: string) => {
43
+ const withoutPrefix = prefix && text.startsWith(prefix) ? text.slice(prefix.length) : text
44
+ const formatted = formatCurrency(withoutPrefix, thousandsSeparator)
45
+ const display = formatted ? `${prefix}${formatted}` : ''
46
+ onChangeText?.(display)
47
+ const separatorRegex = new RegExp(`\\${thousandsSeparator}`, 'g')
48
+ const raw = parseFloat(formatted.replace(separatorRegex, '') || '0')
49
+ onChangeValue?.(isNaN(raw) ? 0 : raw)
50
+ }
51
+
52
+ return (
53
+ <Input
54
+ value={value}
55
+ onChangeText={handleChange}
56
+ keyboardType="numeric"
57
+ label={label}
58
+ error={error}
59
+ hint={hint}
60
+ placeholder={placeholder ?? `${prefix}0`}
61
+ editable={editable}
62
+ containerStyle={containerStyle}
63
+ style={{ fontSize: 36 }}
64
+ />
65
+ )
66
+ }
@@ -0,0 +1 @@
1
+ export * from './CurrencyInputLarge'
@@ -53,21 +53,21 @@ export function Input({ label, error, hint, containerStyle, style, onFocus, onBl
53
53
 
54
54
  const styles = StyleSheet.create({
55
55
  container: {
56
- gap: 4,
56
+ gap: 6,
57
57
  },
58
58
  label: {
59
- fontSize: 14,
59
+ fontSize: 15,
60
60
  fontWeight: '500',
61
- marginBottom: 4,
61
+ marginBottom: 6,
62
62
  },
63
63
  input: {
64
64
  borderWidth: 1.5,
65
- borderRadius: 8,
66
- paddingHorizontal: 16,
67
- paddingVertical: 14,
68
- fontSize: 16,
65
+ borderRadius: 14,
66
+ paddingHorizontal: 20,
67
+ paddingVertical: 16,
68
+ fontSize: 17,
69
69
  },
70
70
  helperText: {
71
- fontSize: 12,
71
+ fontSize: 13,
72
72
  },
73
73
  })
@@ -163,10 +163,10 @@ export function Select({
163
163
 
164
164
  const styles = StyleSheet.create({
165
165
  container: {
166
- gap: 4,
166
+ gap: 6,
167
167
  },
168
168
  label: {
169
- fontSize: 14,
169
+ fontSize: 15,
170
170
  fontWeight: '500',
171
171
  marginBottom: 2,
172
172
  },
@@ -175,24 +175,24 @@ const styles = StyleSheet.create({
175
175
  alignItems: 'center',
176
176
  justifyContent: 'space-between',
177
177
  borderWidth: 1.5,
178
- borderRadius: 8,
179
- paddingHorizontal: 16,
180
- paddingVertical: 14,
178
+ borderRadius: 14,
179
+ paddingHorizontal: 20,
180
+ paddingVertical: 16,
181
181
  },
182
182
  triggerText: {
183
- fontSize: 16,
183
+ fontSize: 17,
184
184
  flex: 1,
185
185
  },
186
186
  chevron: {
187
- fontSize: 14,
187
+ fontSize: 16,
188
188
  marginLeft: 8,
189
189
  },
190
190
  helperText: {
191
- fontSize: 12,
191
+ fontSize: 13,
192
192
  },
193
193
  sheetBackground: {
194
- borderTopLeftRadius: 16,
195
- borderTopRightRadius: 16,
194
+ borderTopLeftRadius: 24,
195
+ borderTopRightRadius: 24,
196
196
  },
197
197
  sheetHandle: {
198
198
  width: 36,
@@ -200,32 +200,32 @@ const styles = StyleSheet.create({
200
200
  borderRadius: 2,
201
201
  },
202
202
  sheetContent: {
203
- paddingHorizontal: 16,
204
- paddingBottom: 32,
203
+ paddingHorizontal: 20,
204
+ paddingBottom: 36,
205
205
  },
206
206
  sheetTitle: {
207
- fontSize: 16,
207
+ fontSize: 17,
208
208
  fontWeight: '600',
209
- paddingVertical: 12,
209
+ paddingVertical: 16,
210
210
  paddingHorizontal: 4,
211
211
  },
212
212
  option: {
213
213
  flexDirection: 'row',
214
214
  alignItems: 'center',
215
215
  justifyContent: 'space-between',
216
- paddingHorizontal: 12,
217
- paddingVertical: 14,
218
- borderRadius: 8,
216
+ paddingHorizontal: 16,
217
+ paddingVertical: 16,
218
+ borderRadius: 12,
219
219
  },
220
220
  optionText: {
221
- fontSize: 15,
221
+ fontSize: 17,
222
222
  flex: 1,
223
223
  },
224
224
  disabledOption: {
225
225
  opacity: 0.45,
226
226
  },
227
227
  checkmark: {
228
- fontSize: 14,
228
+ fontSize: 16,
229
229
  fontWeight: '600',
230
230
  marginLeft: 8,
231
231
  },
@@ -3,9 +3,9 @@ import { TouchableOpacity, Animated, StyleSheet, ViewStyle } from 'react-native'
3
3
  import * as Haptics from 'expo-haptics'
4
4
  import { useTheme } from '../../theme'
5
5
 
6
- const TRACK_WIDTH = 56
7
- const TRACK_HEIGHT = 32
8
- const THUMB_SIZE = 24
6
+ const TRACK_WIDTH = 60
7
+ const TRACK_HEIGHT = 36
8
+ const THUMB_SIZE = 28
9
9
  const THUMB_OFFSET = 4
10
10
  const THUMB_TRAVEL = TRACK_WIDTH - THUMB_SIZE - THUMB_OFFSET * 2
11
11
 
@@ -70,10 +70,13 @@ const styles = StyleSheet.create({
70
70
  width: TRACK_WIDTH,
71
71
  height: TRACK_HEIGHT,
72
72
  borderRadius: TRACK_HEIGHT / 2,
73
- justifyContent: 'center',
74
- paddingHorizontal: THUMB_OFFSET,
73
+ // No justifyContent/alignItems — thumb uses absolute positioning
74
+ // so the track's flex layout doesn't interfere with translateX animation
75
75
  },
76
76
  thumb: {
77
+ position: 'absolute',
78
+ top: THUMB_OFFSET,
79
+ left: THUMB_OFFSET,
77
80
  width: THUMB_SIZE,
78
81
  height: THUMB_SIZE,
79
82
  borderRadius: THUMB_SIZE / 2,
@@ -6,6 +6,7 @@ import { useTheme } from '../../theme'
6
6
  export interface TabItem {
7
7
  label: string
8
8
  value: string
9
+ icon?: React.ReactNode
9
10
  }
10
11
 
11
12
  export interface TabsProps {
@@ -60,15 +61,22 @@ function TabTrigger({
60
61
  touchSoundDisabled={true}
61
62
  >
62
63
  <Animated.View style={{ transform: [{ scale }] }}>
63
- <Text
64
- style={[
65
- styles.triggerLabel,
66
- { color: isActive ? colors.foreground : colors.mutedForeground },
67
- isActive && styles.activeTriggerLabel,
68
- ]}
69
- >
70
- {tab.label}
71
- </Text>
64
+ <View style={styles.triggerInner}>
65
+ {tab.icon ? (
66
+ <View style={styles.triggerIcon}>
67
+ {(typeof tab.icon === 'function' ? (tab.icon as any)(isActive) : tab.icon) as React.ReactNode}
68
+ </View>
69
+ ) : null}
70
+ <Text
71
+ style={[
72
+ styles.triggerLabel,
73
+ { color: isActive ? colors.foreground : colors.mutedForeground },
74
+ isActive && styles.activeTriggerLabel,
75
+ ]}
76
+ >
77
+ {tab.label}
78
+ </Text>
79
+ </View>
72
80
  </Animated.View>
73
81
  </TouchableOpacity>
74
82
  )
@@ -133,7 +141,7 @@ export function Tabs({ tabs, value, onValueChange, children, style }: TabsProps)
133
141
  bottom: 4,
134
142
  left: pillX,
135
143
  width: pillWidth,
136
- borderRadius: 6,
144
+ borderRadius: 8,
137
145
  shadowColor: '#000',
138
146
  shadowOffset: { width: 0, height: 1 },
139
147
  shadowOpacity: 0.1,
@@ -172,22 +180,33 @@ export function TabsContent({ value, activeValue, children, style }: TabsContent
172
180
  const styles = StyleSheet.create({
173
181
  list: {
174
182
  flexDirection: 'row',
175
- borderRadius: 8,
183
+ borderRadius: 12,
176
184
  padding: 4,
177
185
  gap: 4,
178
186
  },
179
187
  pill: {},
180
188
  trigger: {
181
189
  flex: 1,
182
- paddingVertical: 8,
183
- paddingHorizontal: 12,
184
- borderRadius: 6,
190
+ paddingVertical: 12,
191
+ paddingHorizontal: 16,
192
+ borderRadius: 8,
185
193
  alignItems: 'center',
186
194
  justifyContent: 'center',
187
195
  zIndex: 1,
188
196
  },
197
+ triggerInner: {
198
+ flexDirection: 'row',
199
+ alignItems: 'center',
200
+ justifyContent: 'center',
201
+ gap: 8,
202
+ },
203
+ triggerIcon: {
204
+ marginRight: 6,
205
+ alignItems: 'center',
206
+ justifyContent: 'center',
207
+ },
189
208
  triggerLabel: {
190
- fontSize: 14,
209
+ fontSize: 15,
191
210
  fontWeight: '400',
192
211
  },
193
212
  activeTriggerLabel: {
@@ -10,12 +10,12 @@ export interface TextProps extends RNTextProps {
10
10
  }
11
11
 
12
12
  const variantStyles: Record<TextVariant, TextStyle> = {
13
- h1: { fontSize: 32, fontWeight: '700', lineHeight: 44 },
14
- h2: { fontSize: 24, fontWeight: '700', lineHeight: 32 },
15
- h3: { fontSize: 20, fontWeight: '600', lineHeight: 28 },
16
- body: { fontSize: 16, fontWeight: '400', lineHeight: 24 },
17
- caption: { fontSize: 12, fontWeight: '400', lineHeight: 18 },
18
- label: { fontSize: 14, fontWeight: '500', lineHeight: 20 },
13
+ h1: { fontSize: 40, fontWeight: '700', lineHeight: 52 },
14
+ h2: { fontSize: 28, fontWeight: '700', lineHeight: 36 },
15
+ h3: { fontSize: 22, fontWeight: '600', lineHeight: 30 },
16
+ body: { fontSize: 17, fontWeight: '400', lineHeight: 26 },
17
+ caption: { fontSize: 13, fontWeight: '400', lineHeight: 20 },
18
+ label: { fontSize: 15, fontWeight: '500', lineHeight: 22 },
19
19
  }
20
20
 
21
21
  export function Text({ variant = 'body', color, style, children, ...props }: TextProps) {
@@ -41,7 +41,7 @@ export function Textarea({
41
41
  borderColor: error ? colors.destructive : focused ? colors.ring : colors.border,
42
42
  color: colors.foreground,
43
43
  backgroundColor: colors.background,
44
- minHeight: rows * 28,
44
+ minHeight: rows * 30,
45
45
  },
46
46
  style,
47
47
  ]}
@@ -69,21 +69,21 @@ export function Textarea({
69
69
 
70
70
  const styles = StyleSheet.create({
71
71
  container: {
72
- gap: 4,
72
+ gap: 6,
73
73
  },
74
74
  label: {
75
- fontSize: 14,
75
+ fontSize: 15,
76
76
  fontWeight: '500',
77
- marginBottom: 4,
77
+ marginBottom: 6,
78
78
  },
79
79
  input: {
80
80
  borderWidth: 1.5,
81
- borderRadius: 8,
82
- paddingHorizontal: 16,
83
- paddingVertical: 14,
84
- fontSize: 16,
81
+ borderRadius: 14,
82
+ paddingHorizontal: 20,
83
+ paddingVertical: 16,
84
+ fontSize: 17,
85
85
  },
86
86
  helperText: {
87
- fontSize: 12,
87
+ fontSize: 13,
88
88
  },
89
89
  })