@retray-dev/ui-kit 2.5.1 → 2.5.2
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 +2 -2
- package/dist/index.js +374 -362
- package/dist/index.mjs +362 -331
- package/package.json +23 -21
- package/src/components/Accordion/Accordion.tsx +61 -57
- package/src/components/Alert/Alert.tsx +11 -10
- package/src/components/AlertBanner/AlertBanner.tsx +9 -8
- package/src/components/Avatar/Avatar.tsx +9 -8
- package/src/components/Badge/Badge.tsx +11 -10
- package/src/components/Button/Button.tsx +10 -9
- package/src/components/Card/Card.tsx +12 -11
- package/src/components/Checkbox/Checkbox.tsx +16 -13
- package/src/components/Chip/Chip.tsx +8 -7
- package/src/components/ConfirmDialog/ConfirmDialog.tsx +12 -11
- package/src/components/CurrencyDisplay/CurrencyDisplay.tsx +2 -1
- package/src/components/CurrencyInput/CurrencyInput.tsx +2 -1
- package/src/components/EmptyState/EmptyState.tsx +19 -18
- package/src/components/Input/Input.tsx +15 -14
- package/src/components/LabelValue/LabelValue.tsx +6 -5
- package/src/components/ListItem/ListItem.tsx +20 -19
- package/src/components/MonthPicker/MonthPicker.tsx +9 -8
- package/src/components/Progress/Progress.tsx +2 -1
- package/src/components/RadioGroup/RadioGroup.tsx +18 -15
- package/src/components/Select/Select.tsx +25 -24
- package/src/components/Sheet/Sheet.tsx +15 -14
- package/src/components/Slider/Slider.tsx +7 -6
- package/src/components/Switch/Switch.tsx +7 -6
- package/src/components/Tabs/Tabs.tsx +17 -14
- package/src/components/Text/Text.tsx +7 -6
- package/src/components/Textarea/Textarea.tsx +9 -8
- package/src/components/Toast/Toast.tsx +19 -18
- package/src/components/Toggle/Toggle.tsx +9 -8
- package/src/utils/haptics.ts +32 -0
- package/src/utils/scaling.ts +26 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React, { useRef } from 'react'
|
|
2
2
|
import { View, Text, StyleSheet, ViewStyle } from 'react-native'
|
|
3
3
|
import RNSlider from '@react-native-community/slider'
|
|
4
|
-
import
|
|
4
|
+
import { selectionAsync as hapticSelection } from '../../utils/haptics'
|
|
5
5
|
import { useTheme } from '../../theme'
|
|
6
|
+
import { vs, ms } from '../../utils/scaling'
|
|
6
7
|
|
|
7
8
|
export interface SliderProps {
|
|
8
9
|
value?: number
|
|
@@ -39,7 +40,7 @@ export function Slider({
|
|
|
39
40
|
const handleValueChange = (v: number) => {
|
|
40
41
|
if (step && v !== lastSteppedValue.current) {
|
|
41
42
|
lastSteppedValue.current = v
|
|
42
|
-
|
|
43
|
+
hapticSelection()
|
|
43
44
|
}
|
|
44
45
|
onValueChange?.(v)
|
|
45
46
|
}
|
|
@@ -82,7 +83,7 @@ export function Slider({
|
|
|
82
83
|
|
|
83
84
|
const styles = StyleSheet.create({
|
|
84
85
|
wrapper: {
|
|
85
|
-
gap: 8,
|
|
86
|
+
gap: vs(8),
|
|
86
87
|
},
|
|
87
88
|
header: {
|
|
88
89
|
flexDirection: 'row',
|
|
@@ -90,16 +91,16 @@ const styles = StyleSheet.create({
|
|
|
90
91
|
alignItems: 'center',
|
|
91
92
|
},
|
|
92
93
|
label: {
|
|
93
|
-
fontSize: 15,
|
|
94
|
+
fontSize: ms(15),
|
|
94
95
|
fontWeight: '500',
|
|
95
96
|
},
|
|
96
97
|
valueText: {
|
|
97
|
-
fontSize: 14,
|
|
98
|
+
fontSize: ms(14),
|
|
98
99
|
fontWeight: '500',
|
|
99
100
|
},
|
|
100
101
|
slider: {
|
|
101
102
|
width: '100%',
|
|
102
|
-
height: 40,
|
|
103
|
+
height: vs(40),
|
|
103
104
|
},
|
|
104
105
|
disabled: {
|
|
105
106
|
opacity: 0.45,
|
|
@@ -2,13 +2,14 @@ import React, { useEffect, useRef } from 'react'
|
|
|
2
2
|
import { TouchableOpacity, Animated, StyleSheet, ViewStyle, Platform, View } from 'react-native'
|
|
3
3
|
|
|
4
4
|
const nativeDriver = Platform.OS !== 'web'
|
|
5
|
-
import
|
|
5
|
+
import { selectionAsync as hapticSelection } from '../../utils/haptics'
|
|
6
6
|
import { useTheme } from '../../theme'
|
|
7
|
+
import { s, vs } from '../../utils/scaling'
|
|
7
8
|
|
|
8
|
-
const TRACK_WIDTH = 60
|
|
9
|
-
const TRACK_HEIGHT = 36
|
|
10
|
-
const THUMB_SIZE = 28
|
|
11
|
-
const THUMB_OFFSET = 4
|
|
9
|
+
const TRACK_WIDTH = s(60)
|
|
10
|
+
const TRACK_HEIGHT = vs(36)
|
|
11
|
+
const THUMB_SIZE = s(28)
|
|
12
|
+
const THUMB_OFFSET = s(4)
|
|
12
13
|
const THUMB_TRAVEL = TRACK_WIDTH - THUMB_SIZE - THUMB_OFFSET * 2
|
|
13
14
|
|
|
14
15
|
export interface SwitchProps {
|
|
@@ -47,7 +48,7 @@ export function Switch({ checked = false, onCheckedChange, disabled, style }: Sw
|
|
|
47
48
|
<View style={[{ opacity: disabled ? 0.45 : 1 }, style]}>
|
|
48
49
|
<TouchableOpacity
|
|
49
50
|
onPress={() => {
|
|
50
|
-
|
|
51
|
+
hapticSelection()
|
|
51
52
|
onCheckedChange?.(!checked)
|
|
52
53
|
}}
|
|
53
54
|
disabled={disabled}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import React, { useState, useRef, useEffect } from 'react'
|
|
2
|
-
import { View, TouchableOpacity, Text, Animated, StyleSheet, ViewStyle } from 'react-native'
|
|
3
|
-
import
|
|
2
|
+
import { View, TouchableOpacity, Text, Animated, StyleSheet, ViewStyle, Platform } from 'react-native'
|
|
3
|
+
import { selectionAsync as hapticSelection } from '../../utils/haptics'
|
|
4
|
+
|
|
5
|
+
const nativeDriver = Platform.OS !== 'web'
|
|
4
6
|
import { useTheme } from '../../theme'
|
|
7
|
+
import { s, vs, ms } from '../../utils/scaling'
|
|
5
8
|
|
|
6
9
|
export interface TabItem {
|
|
7
10
|
label: string
|
|
@@ -43,11 +46,11 @@ function TabTrigger({
|
|
|
43
46
|
const scale = useRef(new Animated.Value(1)).current
|
|
44
47
|
|
|
45
48
|
const handlePressIn = () => {
|
|
46
|
-
Animated.spring(scale, { toValue: 0.95, useNativeDriver:
|
|
49
|
+
Animated.spring(scale, { toValue: 0.95, useNativeDriver: nativeDriver, speed: 40, bounciness: 0 }).start()
|
|
47
50
|
}
|
|
48
51
|
|
|
49
52
|
const handlePressOut = () => {
|
|
50
|
-
Animated.spring(scale, { toValue: 1, useNativeDriver:
|
|
53
|
+
Animated.spring(scale, { toValue: 1, useNativeDriver: nativeDriver, speed: 40, bounciness: 4 }).start()
|
|
51
54
|
}
|
|
52
55
|
|
|
53
56
|
return (
|
|
@@ -123,7 +126,7 @@ export function Tabs({ tabs, value, onValueChange, children, style }: TabsProps)
|
|
|
123
126
|
}, [active])
|
|
124
127
|
|
|
125
128
|
const handlePress = (v: string) => {
|
|
126
|
-
|
|
129
|
+
hapticSelection()
|
|
127
130
|
if (!value) setInternal(v)
|
|
128
131
|
onValueChange?.(v)
|
|
129
132
|
}
|
|
@@ -180,16 +183,16 @@ export function TabsContent({ value, activeValue, children, style }: TabsContent
|
|
|
180
183
|
const styles = StyleSheet.create({
|
|
181
184
|
list: {
|
|
182
185
|
flexDirection: 'row',
|
|
183
|
-
borderRadius: 12,
|
|
184
|
-
padding: 4,
|
|
185
|
-
gap: 4,
|
|
186
|
+
borderRadius: ms(12),
|
|
187
|
+
padding: s(4),
|
|
188
|
+
gap: s(4),
|
|
186
189
|
},
|
|
187
190
|
pill: {},
|
|
188
191
|
trigger: {
|
|
189
192
|
flex: 1,
|
|
190
|
-
paddingVertical: 12,
|
|
191
|
-
paddingHorizontal: 16,
|
|
192
|
-
borderRadius: 8,
|
|
193
|
+
paddingVertical: vs(12),
|
|
194
|
+
paddingHorizontal: s(16),
|
|
195
|
+
borderRadius: ms(8),
|
|
193
196
|
alignItems: 'center',
|
|
194
197
|
justifyContent: 'center',
|
|
195
198
|
zIndex: 1,
|
|
@@ -198,15 +201,15 @@ const styles = StyleSheet.create({
|
|
|
198
201
|
flexDirection: 'row',
|
|
199
202
|
alignItems: 'center',
|
|
200
203
|
justifyContent: 'center',
|
|
201
|
-
gap: 8,
|
|
204
|
+
gap: s(8),
|
|
202
205
|
},
|
|
203
206
|
triggerIcon: {
|
|
204
|
-
marginRight: 6,
|
|
207
|
+
marginRight: s(6),
|
|
205
208
|
alignItems: 'center',
|
|
206
209
|
justifyContent: 'center',
|
|
207
210
|
},
|
|
208
211
|
triggerLabel: {
|
|
209
|
-
fontSize: 15,
|
|
212
|
+
fontSize: ms(15),
|
|
210
213
|
fontWeight: '400',
|
|
211
214
|
},
|
|
212
215
|
activeTriggerLabel: {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { Text as RNText, TextProps as RNTextProps, TextStyle } from 'react-native'
|
|
3
3
|
import { useTheme } from '../../theme'
|
|
4
|
+
import { ms, mvs } from '../../utils/scaling'
|
|
4
5
|
|
|
5
6
|
export type TextVariant = 'h1' | 'h2' | 'h3' | 'body' | 'caption' | 'label'
|
|
6
7
|
|
|
@@ -10,12 +11,12 @@ export interface TextProps extends RNTextProps {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
const variantStyles: Record<TextVariant, TextStyle> = {
|
|
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 },
|
|
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) },
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
export function Text({ variant = 'body', color, style, children, ...props }: TextProps) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useState } from 'react'
|
|
2
2
|
import { TextInput, View, Text, StyleSheet, TextInputProps, ViewStyle, Platform } from 'react-native'
|
|
3
3
|
import { useTheme } from '../../theme'
|
|
4
|
+
import { s, vs, ms } from '../../utils/scaling'
|
|
4
5
|
|
|
5
6
|
const webInputResetStyle: any =
|
|
6
7
|
Platform.OS === 'web'
|
|
@@ -50,7 +51,7 @@ export function Textarea({
|
|
|
50
51
|
: colors.border,
|
|
51
52
|
color: colors.foreground,
|
|
52
53
|
backgroundColor: colors.background,
|
|
53
|
-
minHeight: rows * 30,
|
|
54
|
+
minHeight: rows * vs(30),
|
|
54
55
|
},
|
|
55
56
|
webInputResetStyle,
|
|
56
57
|
style,
|
|
@@ -79,20 +80,20 @@ export function Textarea({
|
|
|
79
80
|
|
|
80
81
|
const styles = StyleSheet.create({
|
|
81
82
|
container: {
|
|
82
|
-
gap: 8,
|
|
83
|
+
gap: vs(8),
|
|
83
84
|
},
|
|
84
85
|
label: {
|
|
85
|
-
fontSize: 15,
|
|
86
|
+
fontSize: ms(15),
|
|
86
87
|
fontWeight: '500',
|
|
87
88
|
},
|
|
88
89
|
input: {
|
|
89
90
|
borderWidth: 1.5,
|
|
90
|
-
borderRadius: 8,
|
|
91
|
-
paddingHorizontal: 16,
|
|
92
|
-
paddingVertical: 14,
|
|
93
|
-
fontSize: 17,
|
|
91
|
+
borderRadius: ms(8),
|
|
92
|
+
paddingHorizontal: s(16),
|
|
93
|
+
paddingVertical: vs(14),
|
|
94
|
+
fontSize: ms(17),
|
|
94
95
|
},
|
|
95
96
|
helperText: {
|
|
96
|
-
fontSize: 13,
|
|
97
|
+
fontSize: ms(13),
|
|
97
98
|
},
|
|
98
99
|
})
|
|
@@ -11,8 +11,9 @@ import Animated, {
|
|
|
11
11
|
import { scheduleOnRN } from 'react-native-worklets'
|
|
12
12
|
import { Gesture, GestureDetector } from 'react-native-gesture-handler'
|
|
13
13
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
14
|
-
import
|
|
14
|
+
import { notificationSuccess, notificationError, impactLight } from '../../utils/haptics'
|
|
15
15
|
import { useTheme } from '../../theme'
|
|
16
|
+
import { s, vs, ms } from '../../utils/scaling'
|
|
16
17
|
|
|
17
18
|
export type ToastVariant = 'default' | 'destructive' | 'success'
|
|
18
19
|
|
|
@@ -148,11 +149,11 @@ export function ToastProvider({ children }: ToastProviderProps) {
|
|
|
148
149
|
const toast = useCallback((item: Omit<ToastItem, 'id'>) => {
|
|
149
150
|
const id = Math.random().toString(36).slice(2)
|
|
150
151
|
if (item.variant === 'success') {
|
|
151
|
-
|
|
152
|
+
notificationSuccess()
|
|
152
153
|
} else if (item.variant === 'destructive') {
|
|
153
|
-
|
|
154
|
+
notificationError()
|
|
154
155
|
} else {
|
|
155
|
-
|
|
156
|
+
impactLight()
|
|
156
157
|
}
|
|
157
158
|
setToasts((prev) => [{ ...item, id }, ...prev].slice(0, 3))
|
|
158
159
|
}, [])
|
|
@@ -176,23 +177,23 @@ export function ToastProvider({ children }: ToastProviderProps) {
|
|
|
176
177
|
const styles = StyleSheet.create({
|
|
177
178
|
container: {
|
|
178
179
|
position: 'absolute',
|
|
179
|
-
left: 16,
|
|
180
|
-
right: 16,
|
|
181
|
-
gap: 8,
|
|
180
|
+
left: s(16),
|
|
181
|
+
right: s(16),
|
|
182
|
+
gap: vs(8),
|
|
182
183
|
zIndex: 9999,
|
|
183
184
|
},
|
|
184
185
|
containerWeb: {
|
|
185
186
|
left: undefined,
|
|
186
187
|
right: undefined,
|
|
187
188
|
alignSelf: 'center',
|
|
188
|
-
width: 400,
|
|
189
|
+
width: s(400),
|
|
189
190
|
},
|
|
190
191
|
toast: {
|
|
191
192
|
flexDirection: 'row',
|
|
192
193
|
alignItems: 'center',
|
|
193
|
-
borderRadius: 16,
|
|
194
|
-
paddingHorizontal: 20,
|
|
195
|
-
paddingVertical: 14,
|
|
194
|
+
borderRadius: ms(16),
|
|
195
|
+
paddingHorizontal: s(20),
|
|
196
|
+
paddingVertical: vs(14),
|
|
196
197
|
shadowColor: '#000',
|
|
197
198
|
shadowOffset: { width: 0, height: 4 },
|
|
198
199
|
shadowOpacity: 0.15,
|
|
@@ -201,23 +202,23 @@ const styles = StyleSheet.create({
|
|
|
201
202
|
},
|
|
202
203
|
toastContent: {
|
|
203
204
|
flex: 1,
|
|
204
|
-
gap: 4,
|
|
205
|
+
gap: vs(4),
|
|
205
206
|
},
|
|
206
207
|
leftIconContainer: {
|
|
207
|
-
width: 40,
|
|
208
|
+
width: s(40),
|
|
208
209
|
alignItems: 'center',
|
|
209
210
|
justifyContent: 'center',
|
|
210
|
-
marginRight: 8,
|
|
211
|
+
marginRight: s(8),
|
|
211
212
|
},
|
|
212
213
|
toastTitle: {
|
|
213
|
-
fontSize: 15,
|
|
214
|
+
fontSize: ms(15),
|
|
214
215
|
fontWeight: '600',
|
|
215
216
|
},
|
|
216
217
|
toastDescription: {
|
|
217
|
-
fontSize: 14,
|
|
218
|
+
fontSize: ms(14),
|
|
218
219
|
},
|
|
219
220
|
dismissButton: {
|
|
220
|
-
padding: 8,
|
|
221
|
-
marginLeft: 4,
|
|
221
|
+
padding: s(8),
|
|
222
|
+
marginLeft: s(4),
|
|
222
223
|
},
|
|
223
224
|
})
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React, { useRef, useEffect } from 'react'
|
|
2
2
|
import { TouchableOpacity, Animated, StyleSheet, TouchableOpacityProps, ViewStyle, View, Easing } from 'react-native'
|
|
3
3
|
import { FontAwesome5 } from '@expo/vector-icons'
|
|
4
|
-
import
|
|
4
|
+
import { selectionAsync as hapticSelection } from '../../utils/haptics'
|
|
5
5
|
import { useTheme } from '../../theme'
|
|
6
|
+
import { s, vs, ms } from '../../utils/scaling'
|
|
6
7
|
|
|
7
8
|
export type ToggleVariant = 'default' | 'outline'
|
|
8
9
|
export type ToggleSize = 'sm' | 'md' | 'lg'
|
|
@@ -20,9 +21,9 @@ export interface ToggleProps extends TouchableOpacityProps {
|
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
const sizeStyles: Record<ToggleSize, ViewStyle> = {
|
|
23
|
-
sm: { paddingHorizontal: 12, paddingVertical: 8, minWidth: 40, minHeight: 40 },
|
|
24
|
-
md: { paddingHorizontal: 16, paddingVertical: 12, minWidth: 44, minHeight: 44 },
|
|
25
|
-
lg: { paddingHorizontal: 20, paddingVertical: 14, minWidth: 48, minHeight: 48 },
|
|
24
|
+
sm: { paddingHorizontal: s(12), paddingVertical: vs(8), minWidth: s(40), minHeight: vs(40) },
|
|
25
|
+
md: { paddingHorizontal: s(16), paddingVertical: vs(12), minWidth: s(44), minHeight: vs(44) },
|
|
26
|
+
lg: { paddingHorizontal: s(20), paddingVertical: vs(14), minWidth: s(48), minHeight: vs(48) },
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
export function Toggle({
|
|
@@ -101,7 +102,7 @@ export function Toggle({
|
|
|
101
102
|
<Animated.View style={[{ transform: [{ scale }] }, disabled && styles.disabled, style]}>
|
|
102
103
|
<TouchableOpacity
|
|
103
104
|
onPress={() => {
|
|
104
|
-
|
|
105
|
+
hapticSelection()
|
|
105
106
|
onPressedChange?.(!pressed)
|
|
106
107
|
}}
|
|
107
108
|
onPressIn={handlePressIn}
|
|
@@ -130,19 +131,19 @@ export function Toggle({
|
|
|
130
131
|
|
|
131
132
|
const styles = StyleSheet.create({
|
|
132
133
|
base: {
|
|
133
|
-
borderRadius: 8,
|
|
134
|
+
borderRadius: ms(8),
|
|
134
135
|
},
|
|
135
136
|
inner: {
|
|
136
137
|
flexDirection: 'row',
|
|
137
138
|
alignItems: 'center',
|
|
138
139
|
justifyContent: 'center',
|
|
139
|
-
gap: 8,
|
|
140
|
+
gap: s(8),
|
|
140
141
|
},
|
|
141
142
|
disabled: {
|
|
142
143
|
opacity: 0.45,
|
|
143
144
|
},
|
|
144
145
|
label: {
|
|
145
|
-
fontSize: 14,
|
|
146
|
+
fontSize: ms(14),
|
|
146
147
|
fontWeight: '500',
|
|
147
148
|
},
|
|
148
149
|
})
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Platform } from 'react-native'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Web-safe haptics helpers. All calls are no-ops on web since expo-haptics
|
|
5
|
+
* is a native-only module and throws on web.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
let Haptics: typeof import('expo-haptics') | null = null
|
|
9
|
+
|
|
10
|
+
if (Platform.OS !== 'web') {
|
|
11
|
+
Haptics = require('expo-haptics')
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function selectionAsync(): void {
|
|
15
|
+
Haptics?.selectionAsync()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function impactLight(): void {
|
|
19
|
+
Haptics?.impactAsync(Haptics.ImpactFeedbackStyle.Light)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function impactMedium(): void {
|
|
23
|
+
Haptics?.impactAsync(Haptics.ImpactFeedbackStyle.Medium)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function notificationSuccess(): void {
|
|
27
|
+
Haptics?.notificationAsync(Haptics.NotificationFeedbackType.Success)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function notificationError(): void {
|
|
31
|
+
Haptics?.notificationAsync(Haptics.NotificationFeedbackType.Error)
|
|
32
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Platform } from 'react-native'
|
|
2
|
+
import {
|
|
3
|
+
scale,
|
|
4
|
+
verticalScale,
|
|
5
|
+
moderateScale,
|
|
6
|
+
moderateVerticalScale,
|
|
7
|
+
} from 'react-native-size-matters'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Scaling utilities wrapping react-native-size-matters.
|
|
11
|
+
*
|
|
12
|
+
* On native: scales relative to guideline base 350×680 (~5" mobile).
|
|
13
|
+
* On web: identity functions — no scaling, values used as-is (px in web = pt on a standard display).
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* s(n) — scale horizontal values (paddingHorizontal, width, gap)
|
|
17
|
+
* vs(n) — scale vertical values (paddingVertical, height, minHeight)
|
|
18
|
+
* ms(n) — moderate scale (fontSize, borderRadius)
|
|
19
|
+
* mvs(n) — moderate vertical scale (lineHeight)
|
|
20
|
+
*/
|
|
21
|
+
const isWeb = Platform.OS === 'web'
|
|
22
|
+
|
|
23
|
+
export const s = isWeb ? (n: number) => n : scale
|
|
24
|
+
export const vs = isWeb ? (n: number) => n : verticalScale
|
|
25
|
+
export const ms = isWeb ? (n: number, _factor?: number) => n : moderateScale
|
|
26
|
+
export const mvs = isWeb ? (n: number, _factor?: number) => n : moderateVerticalScale
|