@retray-dev/ui-kit 3.1.0 → 5.1.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 +1792 -659
- package/README.md +8 -7
- package/dist/index.d.mts +269 -89
- package/dist/index.d.ts +269 -89
- package/dist/index.js +1034 -312
- package/dist/index.mjs +1031 -314
- package/package.json +3 -2
- package/src/components/Accordion/Accordion.tsx +1 -1
- package/src/components/AlertBanner/AlertBanner.tsx +50 -45
- package/src/components/Avatar/Avatar.tsx +61 -17
- package/src/components/Badge/Badge.tsx +17 -15
- package/src/components/Button/Button.tsx +31 -42
- package/src/components/Card/Card.tsx +4 -4
- package/src/components/CategoryStrip/CategoryStrip.tsx +185 -0
- package/src/components/CategoryStrip/index.ts +2 -0
- package/src/components/Checkbox/Checkbox.tsx +44 -16
- package/src/components/Chip/Chip.tsx +1 -1
- package/src/components/ConfirmDialog/ConfirmDialog.tsx +4 -4
- package/src/components/CurrencyDisplay/CurrencyDisplay.tsx +1 -0
- package/src/components/CurrencyInput/CurrencyInput.tsx +6 -4
- package/src/components/EmptyState/EmptyState.tsx +9 -9
- package/src/components/IconButton/IconButton.tsx +74 -34
- package/src/components/Input/Input.tsx +15 -13
- package/src/components/LabelValue/LabelValue.tsx +1 -1
- package/src/components/ListItem/ListItem.tsx +5 -5
- package/src/components/MediaCard/MediaCard.tsx +249 -0
- package/src/components/MediaCard/index.ts +2 -0
- package/src/components/Pressable/Pressable.tsx +100 -0
- package/src/components/Pressable/index.ts +1 -0
- package/src/components/Progress/Progress.tsx +14 -7
- package/src/components/RadioGroup/RadioGroup.tsx +1 -1
- package/src/components/Select/Select.tsx +5 -5
- package/src/components/Sheet/Sheet.tsx +3 -9
- package/src/components/Skeleton/Skeleton.tsx +34 -7
- package/src/components/Slider/Slider.tsx +2 -2
- package/src/components/Spinner/Spinner.tsx +1 -1
- package/src/components/Switch/Switch.tsx +31 -4
- package/src/components/Tabs/Tabs.tsx +63 -45
- package/src/components/Text/Text.tsx +59 -10
- package/src/components/Textarea/Textarea.tsx +4 -3
- package/src/components/Toast/Toast.tsx +77 -36
- package/src/components/Toggle/Toggle.tsx +3 -3
- package/src/index.ts +8 -2
- package/src/theme/ThemeProvider.tsx +11 -10
- package/src/theme/colorUtils.ts +80 -0
- package/src/theme/colors.ts +76 -35
- package/src/theme/index.ts +2 -2
- package/src/theme/types.ts +27 -13
- package/src/tokens.ts +150 -13
- package/src/utils/hover.ts +25 -0
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React25, { createContext, useMemo, useContext, useRef, useState, useEffect, useCallback } from 'react';
|
|
2
|
-
import { Platform, StyleSheet, useColorScheme, Animated, TouchableOpacity, ActivityIndicator, Text, View, TextInput, Image, Easing, Modal, Pressable } from 'react-native';
|
|
2
|
+
import { Platform, StyleSheet, useColorScheme, Animated, TouchableOpacity, ActivityIndicator, Text, View, TextInput, Image, Easing, Modal, ScrollView, Pressable } from 'react-native';
|
|
3
3
|
import { verticalScale, scale, moderateScale, moderateVerticalScale } from 'react-native-size-matters';
|
|
4
4
|
import AntDesign from '@expo/vector-icons/AntDesign';
|
|
5
5
|
import Entypo from '@expo/vector-icons/Entypo';
|
|
@@ -7,7 +7,7 @@ import Feather from '@expo/vector-icons/Feather';
|
|
|
7
7
|
import FontAwesome5 from '@expo/vector-icons/FontAwesome5';
|
|
8
8
|
import MaterialIcons from '@expo/vector-icons/MaterialIcons';
|
|
9
9
|
import Ionicons from '@expo/vector-icons/Ionicons';
|
|
10
|
-
import { AntDesign as AntDesign$1,
|
|
10
|
+
import { AntDesign as AntDesign$1, Feather as Feather$1, Entypo as Entypo$1, FontAwesome5 as FontAwesome5$1, MaterialIcons as MaterialIcons$1 } from '@expo/vector-icons';
|
|
11
11
|
import { LinearGradient } from 'expo-linear-gradient';
|
|
12
12
|
import Animated11, { useSharedValue, useDerivedValue, withTiming, Easing as Easing$1, useAnimatedStyle, withSpring } from 'react-native-reanimated';
|
|
13
13
|
import RNSlider from '@react-native-community/slider';
|
|
@@ -20,61 +20,125 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
|
20
20
|
|
|
21
21
|
// src/theme/ThemeProvider.tsx
|
|
22
22
|
|
|
23
|
+
// src/theme/colorUtils.ts
|
|
24
|
+
function hexToRgb(hex) {
|
|
25
|
+
const clean = hex.replace("#", "");
|
|
26
|
+
const full = clean.length === 3 ? clean.split("").map((c) => c + c).join("") : clean;
|
|
27
|
+
if (full.length !== 6) return null;
|
|
28
|
+
return {
|
|
29
|
+
r: parseInt(full.slice(0, 2), 16),
|
|
30
|
+
g: parseInt(full.slice(2, 4), 16),
|
|
31
|
+
b: parseInt(full.slice(4, 6), 16)
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function componentToHex(c) {
|
|
35
|
+
return Math.round(Math.max(0, Math.min(255, c))).toString(16).padStart(2, "0");
|
|
36
|
+
}
|
|
37
|
+
function rgbToHex(r, g, b) {
|
|
38
|
+
return `#${componentToHex(r)}${componentToHex(g)}${componentToHex(b)}`;
|
|
39
|
+
}
|
|
40
|
+
function withAlphaOnWhite(hex, alpha) {
|
|
41
|
+
const rgb = hexToRgb(hex);
|
|
42
|
+
if (!rgb) return hex;
|
|
43
|
+
const r = rgb.r * alpha + 255 * (1 - alpha);
|
|
44
|
+
const g = rgb.g * alpha + 255 * (1 - alpha);
|
|
45
|
+
const b = rgb.b * alpha + 255 * (1 - alpha);
|
|
46
|
+
return rgbToHex(r, g, b);
|
|
47
|
+
}
|
|
48
|
+
function withAlphaOnDark(hex, alpha, bgHex = "#0f0f0f") {
|
|
49
|
+
const rgb = hexToRgb(hex);
|
|
50
|
+
const bg = hexToRgb(bgHex);
|
|
51
|
+
if (!rgb || !bg) return hex;
|
|
52
|
+
const r = rgb.r * alpha + bg.r * (1 - alpha);
|
|
53
|
+
const g = rgb.g * alpha + bg.g * (1 - alpha);
|
|
54
|
+
const b = rgb.b * alpha + bg.b * (1 - alpha);
|
|
55
|
+
return rgbToHex(r, g, b);
|
|
56
|
+
}
|
|
57
|
+
function mixWithBackground(fgHex, bgHex, opacity) {
|
|
58
|
+
const fg = hexToRgb(fgHex);
|
|
59
|
+
const bg = hexToRgb(bgHex);
|
|
60
|
+
if (!fg || !bg) return fgHex;
|
|
61
|
+
const r = fg.r * opacity + bg.r * (1 - opacity);
|
|
62
|
+
const g = fg.g * opacity + bg.g * (1 - opacity);
|
|
63
|
+
const b = fg.b * opacity + bg.b * (1 - opacity);
|
|
64
|
+
return rgbToHex(r, g, b);
|
|
65
|
+
}
|
|
66
|
+
function lighten(hex, amount) {
|
|
67
|
+
return withAlphaOnWhite(hex, 1 - amount);
|
|
68
|
+
}
|
|
69
|
+
function darken(hex, amount) {
|
|
70
|
+
const rgb = hexToRgb(hex);
|
|
71
|
+
if (!rgb) return hex;
|
|
72
|
+
return rgbToHex(rgb.r * (1 - amount), rgb.g * (1 - amount), rgb.b * (1 - amount));
|
|
73
|
+
}
|
|
74
|
+
|
|
23
75
|
// src/theme/colors.ts
|
|
24
76
|
var defaultLight = {
|
|
25
77
|
background: "#ffffff",
|
|
26
|
-
foreground: "#
|
|
78
|
+
foreground: "#222222",
|
|
79
|
+
// Airbnb ink — deep near-black, never pure black
|
|
27
80
|
card: "#ffffff",
|
|
28
|
-
cardForeground: "#171717",
|
|
29
81
|
primary: "#1a1a1a",
|
|
82
|
+
// Near-black primary — clean, premium default
|
|
30
83
|
primaryForeground: "#ffffff",
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
mutedForeground: "#a2a2a2",
|
|
35
|
-
accent: "#e4e4e4",
|
|
36
|
-
accentForeground: "#171717",
|
|
37
|
-
destructive: "#ef4444",
|
|
84
|
+
border: "#dddddd",
|
|
85
|
+
// Airbnb hairline — light, airy
|
|
86
|
+
destructive: "#e53935",
|
|
38
87
|
destructiveForeground: "#ffffff",
|
|
39
|
-
border: "#e5e5e5",
|
|
40
|
-
input: "#e5e5e5",
|
|
41
|
-
ring: "#1a1a1a",
|
|
42
88
|
success: "#1a7a45",
|
|
43
89
|
successForeground: "#ffffff",
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
successTint: "#f0fdf4",
|
|
47
|
-
successBorder: "#bbf7d0"
|
|
90
|
+
warning: "#e67e00",
|
|
91
|
+
warningForeground: "#ffffff"
|
|
48
92
|
};
|
|
49
93
|
var defaultDark = {
|
|
50
94
|
background: "#0f0f0f",
|
|
51
95
|
foreground: "#fafafa",
|
|
52
96
|
card: "#1c1c1c",
|
|
53
|
-
cardForeground: "#fafafa",
|
|
54
97
|
primary: "#fafafa",
|
|
55
98
|
primaryForeground: "#0f0f0f",
|
|
56
|
-
secondary: "#272727",
|
|
57
|
-
secondaryForeground: "#fafafa",
|
|
58
|
-
muted: "#272727",
|
|
59
|
-
mutedForeground: "#9a9a9a",
|
|
60
|
-
accent: "#2e2e2e",
|
|
61
|
-
accentForeground: "#fafafa",
|
|
62
|
-
destructive: "#dc2626",
|
|
63
|
-
destructiveForeground: "#ffffff",
|
|
64
99
|
border: "#303030",
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
success: "#
|
|
100
|
+
destructive: "#ef5350",
|
|
101
|
+
destructiveForeground: "#ffffff",
|
|
102
|
+
success: "#2e7d52",
|
|
68
103
|
successForeground: "#ffffff",
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
successTint: "#052e16",
|
|
72
|
-
successBorder: "#166534"
|
|
104
|
+
warning: "#f57c00",
|
|
105
|
+
warningForeground: "#ffffff"
|
|
73
106
|
};
|
|
107
|
+
function deriveColors(t, scheme) {
|
|
108
|
+
const dark = scheme === "dark";
|
|
109
|
+
const bg = t.background;
|
|
110
|
+
const foregroundSubtle = mixWithBackground(t.foreground, bg, 0.55);
|
|
111
|
+
const foregroundMuted = mixWithBackground(t.foreground, bg, 0.38);
|
|
112
|
+
const surface = dark ? lighten(bg, -0.06) : darken(bg, 0.04);
|
|
113
|
+
const surfaceStrong = dark ? lighten(bg, -0.12) : darken(bg, 0.08);
|
|
114
|
+
const destructiveTint = dark ? withAlphaOnDark(t.destructive, 0.15, bg) : withAlphaOnWhite(t.destructive, 0.08);
|
|
115
|
+
const destructiveBorder = dark ? withAlphaOnDark(t.destructive, 0.45, bg) : withAlphaOnWhite(t.destructive, 0.3);
|
|
116
|
+
const successTint = dark ? withAlphaOnDark(t.success, 0.15, bg) : withAlphaOnWhite(t.success, 0.08);
|
|
117
|
+
const successBorder = dark ? withAlphaOnDark(t.success, 0.45, bg) : withAlphaOnWhite(t.success, 0.3);
|
|
118
|
+
const warningTint = dark ? withAlphaOnDark(t.warning, 0.15, bg) : withAlphaOnWhite(t.warning, 0.08);
|
|
119
|
+
const warningBorder = dark ? withAlphaOnDark(t.warning, 0.45, bg) : withAlphaOnWhite(t.warning, 0.3);
|
|
120
|
+
return {
|
|
121
|
+
...t,
|
|
122
|
+
foregroundSubtle,
|
|
123
|
+
foregroundMuted,
|
|
124
|
+
surface,
|
|
125
|
+
surfaceStrong,
|
|
126
|
+
destructiveTint,
|
|
127
|
+
destructiveBorder,
|
|
128
|
+
successTint,
|
|
129
|
+
successBorder,
|
|
130
|
+
warningTint,
|
|
131
|
+
warningBorder,
|
|
132
|
+
ring: t.primary,
|
|
133
|
+
// focus ring always = primary
|
|
134
|
+
input: t.border
|
|
135
|
+
// input border always = border
|
|
136
|
+
};
|
|
137
|
+
}
|
|
74
138
|
|
|
75
139
|
// src/theme/ThemeProvider.tsx
|
|
76
140
|
var ThemeContext = createContext({
|
|
77
|
-
colors: defaultLight,
|
|
141
|
+
colors: deriveColors(defaultLight, "light"),
|
|
78
142
|
colorScheme: "light"
|
|
79
143
|
});
|
|
80
144
|
function ThemeProvider({ children, theme, colorScheme = "system" }) {
|
|
@@ -83,7 +147,8 @@ function ThemeProvider({ children, theme, colorScheme = "system" }) {
|
|
|
83
147
|
const colors = useMemo(() => {
|
|
84
148
|
const base = resolvedScheme === "dark" ? defaultDark : defaultLight;
|
|
85
149
|
const override = resolvedScheme === "dark" ? theme?.dark : theme?.light;
|
|
86
|
-
|
|
150
|
+
const merged = override ? { ...base, ...override } : base;
|
|
151
|
+
return deriveColors(merged, resolvedScheme);
|
|
87
152
|
}, [resolvedScheme, theme]);
|
|
88
153
|
return /* @__PURE__ */ React25.createElement(ThemeContext.Provider, { value: { colors, colorScheme: resolvedScheme } }, children);
|
|
89
154
|
}
|
|
@@ -163,17 +228,194 @@ function renderIcon(name, size, color) {
|
|
|
163
228
|
return React25.createElement(Icon, { name, size, color });
|
|
164
229
|
}
|
|
165
230
|
|
|
231
|
+
// src/tokens.ts
|
|
232
|
+
var SPACING = {
|
|
233
|
+
xxs: 2,
|
|
234
|
+
xs: 4,
|
|
235
|
+
sm: 8,
|
|
236
|
+
md: 12,
|
|
237
|
+
base: 16,
|
|
238
|
+
lg: 24,
|
|
239
|
+
xl: 32,
|
|
240
|
+
xxl: 48,
|
|
241
|
+
section: 64
|
|
242
|
+
};
|
|
243
|
+
var ICON_SIZES = {
|
|
244
|
+
sm: 14,
|
|
245
|
+
md: 18,
|
|
246
|
+
lg: 22,
|
|
247
|
+
xl: 28,
|
|
248
|
+
"2xl": 32
|
|
249
|
+
};
|
|
250
|
+
var RADIUS = {
|
|
251
|
+
none: 0,
|
|
252
|
+
xs: 4,
|
|
253
|
+
sm: 8,
|
|
254
|
+
md: 14,
|
|
255
|
+
lg: 20,
|
|
256
|
+
xl: 32,
|
|
257
|
+
full: 9999
|
|
258
|
+
};
|
|
259
|
+
var SHADOWS = {
|
|
260
|
+
sm: {
|
|
261
|
+
shadowColor: "#000",
|
|
262
|
+
shadowOffset: { width: 0, height: 1 },
|
|
263
|
+
shadowOpacity: 0.06,
|
|
264
|
+
shadowRadius: 4,
|
|
265
|
+
elevation: 2
|
|
266
|
+
},
|
|
267
|
+
md: {
|
|
268
|
+
shadowColor: "#000",
|
|
269
|
+
shadowOffset: { width: 0, height: 2 },
|
|
270
|
+
shadowOpacity: 0.1,
|
|
271
|
+
shadowRadius: 8,
|
|
272
|
+
elevation: 5
|
|
273
|
+
},
|
|
274
|
+
lg: {
|
|
275
|
+
shadowColor: "#000",
|
|
276
|
+
shadowOffset: { width: 0, height: 6 },
|
|
277
|
+
shadowOpacity: 0.16,
|
|
278
|
+
shadowRadius: 16,
|
|
279
|
+
elevation: 10
|
|
280
|
+
},
|
|
281
|
+
xl: {
|
|
282
|
+
shadowColor: "#000",
|
|
283
|
+
shadowOffset: { width: 0, height: 12 },
|
|
284
|
+
shadowOpacity: 0.24,
|
|
285
|
+
shadowRadius: 24,
|
|
286
|
+
elevation: 18
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
var BREAKPOINTS = {
|
|
290
|
+
wide: 700
|
|
291
|
+
};
|
|
292
|
+
var TYPOGRAPHY = {
|
|
293
|
+
"display-hero": {
|
|
294
|
+
fontFamily: "Poppins-Bold",
|
|
295
|
+
fontSize: 64,
|
|
296
|
+
fontWeight: "700",
|
|
297
|
+
lineHeight: 70,
|
|
298
|
+
letterSpacing: -1
|
|
299
|
+
},
|
|
300
|
+
"display-xl": {
|
|
301
|
+
fontFamily: "Poppins-Bold",
|
|
302
|
+
fontSize: 28,
|
|
303
|
+
fontWeight: "700",
|
|
304
|
+
lineHeight: 40,
|
|
305
|
+
letterSpacing: 0
|
|
306
|
+
},
|
|
307
|
+
"display-lg": {
|
|
308
|
+
fontFamily: "Poppins-Medium",
|
|
309
|
+
fontSize: 22,
|
|
310
|
+
fontWeight: "500",
|
|
311
|
+
lineHeight: 26,
|
|
312
|
+
letterSpacing: -0.44
|
|
313
|
+
},
|
|
314
|
+
"display-md": {
|
|
315
|
+
fontFamily: "Poppins-Bold",
|
|
316
|
+
fontSize: 21,
|
|
317
|
+
fontWeight: "700",
|
|
318
|
+
lineHeight: 30,
|
|
319
|
+
letterSpacing: 0
|
|
320
|
+
},
|
|
321
|
+
"display-sm": {
|
|
322
|
+
fontFamily: "Poppins-SemiBold",
|
|
323
|
+
fontSize: 20,
|
|
324
|
+
fontWeight: "600",
|
|
325
|
+
lineHeight: 24,
|
|
326
|
+
letterSpacing: -0.18
|
|
327
|
+
},
|
|
328
|
+
"title-md": {
|
|
329
|
+
fontFamily: "Poppins-SemiBold",
|
|
330
|
+
fontSize: 16,
|
|
331
|
+
fontWeight: "600",
|
|
332
|
+
lineHeight: 20,
|
|
333
|
+
letterSpacing: 0
|
|
334
|
+
},
|
|
335
|
+
"title-sm": {
|
|
336
|
+
fontFamily: "Poppins-Medium",
|
|
337
|
+
fontSize: 16,
|
|
338
|
+
fontWeight: "500",
|
|
339
|
+
lineHeight: 20,
|
|
340
|
+
letterSpacing: 0
|
|
341
|
+
},
|
|
342
|
+
"body-md": {
|
|
343
|
+
fontFamily: "Poppins-Regular",
|
|
344
|
+
fontSize: 16,
|
|
345
|
+
fontWeight: "400",
|
|
346
|
+
lineHeight: 24,
|
|
347
|
+
letterSpacing: 0
|
|
348
|
+
},
|
|
349
|
+
"body-sm": {
|
|
350
|
+
fontFamily: "Poppins-Regular",
|
|
351
|
+
fontSize: 14,
|
|
352
|
+
fontWeight: "400",
|
|
353
|
+
lineHeight: 20,
|
|
354
|
+
letterSpacing: 0
|
|
355
|
+
},
|
|
356
|
+
caption: {
|
|
357
|
+
fontFamily: "Poppins-Medium",
|
|
358
|
+
fontSize: 14,
|
|
359
|
+
fontWeight: "500",
|
|
360
|
+
lineHeight: 18,
|
|
361
|
+
letterSpacing: 0
|
|
362
|
+
},
|
|
363
|
+
"caption-sm": {
|
|
364
|
+
fontFamily: "Poppins-Regular",
|
|
365
|
+
fontSize: 13,
|
|
366
|
+
fontWeight: "400",
|
|
367
|
+
lineHeight: 16,
|
|
368
|
+
letterSpacing: 0
|
|
369
|
+
},
|
|
370
|
+
"badge-text": {
|
|
371
|
+
fontFamily: "Poppins-SemiBold",
|
|
372
|
+
fontSize: 11,
|
|
373
|
+
fontWeight: "600",
|
|
374
|
+
lineHeight: 13,
|
|
375
|
+
letterSpacing: 0
|
|
376
|
+
},
|
|
377
|
+
"micro-label": {
|
|
378
|
+
fontFamily: "Poppins-Bold",
|
|
379
|
+
fontSize: 12,
|
|
380
|
+
fontWeight: "700",
|
|
381
|
+
lineHeight: 16,
|
|
382
|
+
letterSpacing: 0
|
|
383
|
+
},
|
|
384
|
+
"uppercase-tag": {
|
|
385
|
+
fontFamily: "Poppins-Bold",
|
|
386
|
+
fontSize: 8,
|
|
387
|
+
fontWeight: "700",
|
|
388
|
+
lineHeight: 10,
|
|
389
|
+
letterSpacing: 0.32,
|
|
390
|
+
textTransform: "uppercase"
|
|
391
|
+
},
|
|
392
|
+
"button-lg": {
|
|
393
|
+
fontFamily: "Poppins-Medium",
|
|
394
|
+
fontSize: 16,
|
|
395
|
+
fontWeight: "500",
|
|
396
|
+
lineHeight: 20,
|
|
397
|
+
letterSpacing: 0
|
|
398
|
+
},
|
|
399
|
+
"button-sm": {
|
|
400
|
+
fontFamily: "Poppins-Medium",
|
|
401
|
+
fontSize: 14,
|
|
402
|
+
fontWeight: "500",
|
|
403
|
+
lineHeight: 18,
|
|
404
|
+
letterSpacing: 0
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
|
|
166
408
|
// src/components/Button/Button.tsx
|
|
167
409
|
var nativeDriver = Platform.OS !== "web";
|
|
168
410
|
var containerSizeStyles = {
|
|
169
|
-
sm: { paddingHorizontal: s(
|
|
170
|
-
md: { paddingHorizontal: s(
|
|
171
|
-
lg: { paddingHorizontal: s(
|
|
411
|
+
sm: { paddingHorizontal: s(16), paddingVertical: vs(10), minHeight: 40 },
|
|
412
|
+
md: { paddingHorizontal: s(24), paddingVertical: vs(14), minHeight: 48 },
|
|
413
|
+
lg: { paddingHorizontal: s(28), paddingVertical: vs(16), minHeight: 56 }
|
|
172
414
|
};
|
|
173
415
|
var labelSizeStyles = {
|
|
174
|
-
sm: { fontSize: ms(
|
|
175
|
-
md: { fontSize: ms(
|
|
176
|
-
lg: { fontSize: ms(
|
|
416
|
+
sm: { ...TYPOGRAPHY["button-sm"], fontSize: ms(TYPOGRAPHY["button-sm"].fontSize) },
|
|
417
|
+
md: { ...TYPOGRAPHY["button-lg"], fontSize: ms(TYPOGRAPHY["button-lg"].fontSize) },
|
|
418
|
+
lg: { ...TYPOGRAPHY["button-lg"], fontSize: ms(TYPOGRAPHY["button-lg"].fontSize + 1) }
|
|
177
419
|
};
|
|
178
420
|
var iconSizeMap = { sm: 16, md: 18, lg: 20 };
|
|
179
421
|
function Button({
|
|
@@ -196,12 +438,7 @@ function Button({
|
|
|
196
438
|
const scale2 = useRef(new Animated.Value(1)).current;
|
|
197
439
|
const handlePressIn = () => {
|
|
198
440
|
if (isDisabled) return;
|
|
199
|
-
Animated.spring(scale2, {
|
|
200
|
-
toValue: 0.95,
|
|
201
|
-
useNativeDriver: nativeDriver,
|
|
202
|
-
speed: 40,
|
|
203
|
-
bounciness: 0
|
|
204
|
-
}).start();
|
|
441
|
+
Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver, speed: 40, bounciness: 0 }).start();
|
|
205
442
|
};
|
|
206
443
|
const handlePressOut = () => {
|
|
207
444
|
Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver, speed: 40, bounciness: 4 }).start();
|
|
@@ -212,20 +449,18 @@ function Button({
|
|
|
212
449
|
};
|
|
213
450
|
const containerVariantStyle = {
|
|
214
451
|
primary: { backgroundColor: colors.primary },
|
|
215
|
-
secondary: { backgroundColor: colors.
|
|
216
|
-
|
|
217
|
-
ghost: { backgroundColor: "transparent" },
|
|
452
|
+
secondary: { backgroundColor: "transparent", borderWidth: 1.5, borderColor: colors.primary },
|
|
453
|
+
text: { backgroundColor: "transparent" },
|
|
218
454
|
destructive: { backgroundColor: colors.destructive }
|
|
219
455
|
}[variant];
|
|
220
456
|
const labelVariantStyle = {
|
|
221
457
|
primary: { color: colors.primaryForeground },
|
|
222
|
-
secondary: { color: colors.
|
|
223
|
-
|
|
224
|
-
ghost: { color: colors.foreground },
|
|
458
|
+
secondary: { color: colors.primary },
|
|
459
|
+
text: { color: colors.foreground },
|
|
225
460
|
destructive: { color: colors.destructiveForeground }
|
|
226
461
|
}[variant];
|
|
227
462
|
const effectiveIcon = iconName ? renderIcon(iconName, iconSizeMap[size], iconColor ?? labelVariantStyle.color) : typeof icon === "function" ? icon({ label, size, variant }) : icon;
|
|
228
|
-
const spinnerColor = variant === "destructive" ? colors.destructiveForeground : variant === "primary"
|
|
463
|
+
const spinnerColor = variant === "destructive" ? colors.destructiveForeground : variant === "primary" ? colors.primaryForeground : colors.foreground;
|
|
229
464
|
return /* @__PURE__ */ React25.createElement(Animated.View, { style: [fullWidth && styles.fullWidth, { transform: [{ scale: scale2 }] }] }, /* @__PURE__ */ React25.createElement(
|
|
230
465
|
TouchableOpacity,
|
|
231
466
|
{
|
|
@@ -245,12 +480,20 @@ function Button({
|
|
|
245
480
|
onPressOut: handlePressOut,
|
|
246
481
|
...props
|
|
247
482
|
},
|
|
248
|
-
loading ? /* @__PURE__ */ React25.createElement(ActivityIndicator, { size: "small", color: spinnerColor }) : /* @__PURE__ */ React25.createElement(React25.Fragment, null, effectiveIcon && iconPosition === "left" && /* @__PURE__ */ React25.createElement(React25.Fragment, null, effectiveIcon), /* @__PURE__ */ React25.createElement(
|
|
483
|
+
loading ? /* @__PURE__ */ React25.createElement(ActivityIndicator, { size: "small", color: spinnerColor }) : /* @__PURE__ */ React25.createElement(React25.Fragment, null, effectiveIcon && iconPosition === "left" && /* @__PURE__ */ React25.createElement(React25.Fragment, null, effectiveIcon), /* @__PURE__ */ React25.createElement(
|
|
484
|
+
Text,
|
|
485
|
+
{
|
|
486
|
+
style: [styles.label, labelVariantStyle, labelSizeStyles[size], effectiveIcon ? styles.labelWithIcon : void 0],
|
|
487
|
+
allowFontScaling: true
|
|
488
|
+
},
|
|
489
|
+
label
|
|
490
|
+
), effectiveIcon && iconPosition === "right" && /* @__PURE__ */ React25.createElement(React25.Fragment, null, effectiveIcon))
|
|
249
491
|
));
|
|
250
492
|
}
|
|
251
493
|
var styles = StyleSheet.create({
|
|
252
494
|
base: {
|
|
253
|
-
borderRadius:
|
|
495
|
+
borderRadius: RADIUS.xl,
|
|
496
|
+
// 32px — pill-shaped primary CTA (Airbnb spec)
|
|
254
497
|
alignItems: "center",
|
|
255
498
|
justifyContent: "center",
|
|
256
499
|
flexDirection: "row"
|
|
@@ -259,18 +502,18 @@ var styles = StyleSheet.create({
|
|
|
259
502
|
width: "100%"
|
|
260
503
|
},
|
|
261
504
|
disabled: {
|
|
262
|
-
opacity: 0.
|
|
505
|
+
opacity: 0.45
|
|
263
506
|
},
|
|
264
507
|
label: {
|
|
265
|
-
fontFamily: "Poppins-
|
|
508
|
+
fontFamily: "Poppins-Medium"
|
|
266
509
|
},
|
|
267
510
|
labelWithIcon: {
|
|
268
|
-
marginHorizontal: s(
|
|
511
|
+
marginHorizontal: s(6)
|
|
269
512
|
}
|
|
270
513
|
});
|
|
271
514
|
var nativeDriver2 = Platform.OS !== "web";
|
|
272
515
|
var sizeMap = {
|
|
273
|
-
sm: { container: s(
|
|
516
|
+
sm: { container: s(32), icon: 16 },
|
|
274
517
|
md: { container: s(44), icon: 20 },
|
|
275
518
|
lg: { container: s(52), icon: 24 }
|
|
276
519
|
};
|
|
@@ -281,6 +524,7 @@ function IconButton({
|
|
|
281
524
|
variant = "primary",
|
|
282
525
|
size = "md",
|
|
283
526
|
loading = false,
|
|
527
|
+
badge,
|
|
284
528
|
disabled,
|
|
285
529
|
style,
|
|
286
530
|
onPress,
|
|
@@ -291,20 +535,10 @@ function IconButton({
|
|
|
291
535
|
const scale2 = useRef(new Animated.Value(1)).current;
|
|
292
536
|
const handlePressIn = () => {
|
|
293
537
|
if (isDisabled) return;
|
|
294
|
-
Animated.spring(scale2, {
|
|
295
|
-
toValue: 0.95,
|
|
296
|
-
useNativeDriver: nativeDriver2,
|
|
297
|
-
speed: 40,
|
|
298
|
-
bounciness: 0
|
|
299
|
-
}).start();
|
|
538
|
+
Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver2, speed: 40, bounciness: 0 }).start();
|
|
300
539
|
};
|
|
301
540
|
const handlePressOut = () => {
|
|
302
|
-
Animated.spring(scale2, {
|
|
303
|
-
toValue: 1,
|
|
304
|
-
useNativeDriver: nativeDriver2,
|
|
305
|
-
speed: 40,
|
|
306
|
-
bounciness: 4
|
|
307
|
-
}).start();
|
|
541
|
+
Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver2, speed: 40, bounciness: 4 }).start();
|
|
308
542
|
};
|
|
309
543
|
const handlePress = (e) => {
|
|
310
544
|
impactLight();
|
|
@@ -312,22 +546,25 @@ function IconButton({
|
|
|
312
546
|
};
|
|
313
547
|
const containerVariantStyle = {
|
|
314
548
|
primary: { backgroundColor: colors.primary },
|
|
315
|
-
secondary: { backgroundColor: colors.
|
|
549
|
+
secondary: { backgroundColor: colors.surface },
|
|
316
550
|
outline: { backgroundColor: "transparent", borderWidth: 1.5, borderColor: colors.border },
|
|
317
|
-
|
|
551
|
+
text: { backgroundColor: "transparent" },
|
|
318
552
|
destructive: { backgroundColor: colors.destructive }
|
|
319
553
|
}[variant];
|
|
320
554
|
const defaultIconColor = {
|
|
321
555
|
primary: colors.primaryForeground,
|
|
322
|
-
secondary: colors.
|
|
556
|
+
secondary: colors.foreground,
|
|
323
557
|
outline: colors.foreground,
|
|
324
|
-
|
|
558
|
+
text: colors.foreground,
|
|
325
559
|
destructive: colors.destructiveForeground
|
|
326
560
|
}[variant];
|
|
327
|
-
const spinnerColor = variant === "destructive" ? colors.destructiveForeground : variant === "primary"
|
|
561
|
+
const spinnerColor = variant === "destructive" ? colors.destructiveForeground : variant === "primary" ? colors.primaryForeground : colors.foreground;
|
|
328
562
|
const { container: containerSize, icon: iconSize } = sizeMap[size];
|
|
329
563
|
const resolvedIcon = iconName ? renderIcon(iconName, iconSize, iconColor ?? defaultIconColor) : icon;
|
|
330
|
-
|
|
564
|
+
const showBadge = badge !== void 0 && badge !== false && badge !== 0;
|
|
565
|
+
const badgeCount = typeof badge === "number" ? Math.min(badge, 99) : null;
|
|
566
|
+
const showCount = typeof badge === "number" && badge > 0;
|
|
567
|
+
return /* @__PURE__ */ React25.createElement(Animated.View, { style: [styles2.wrapper, { transform: [{ scale: scale2 }] }] }, /* @__PURE__ */ React25.createElement(
|
|
331
568
|
TouchableOpacity,
|
|
332
569
|
{
|
|
333
570
|
style: [
|
|
@@ -346,33 +583,93 @@ function IconButton({
|
|
|
346
583
|
...props
|
|
347
584
|
},
|
|
348
585
|
loading ? /* @__PURE__ */ React25.createElement(ActivityIndicator, { size: "small", color: spinnerColor }) : resolvedIcon
|
|
349
|
-
)
|
|
586
|
+
), showBadge && /* @__PURE__ */ React25.createElement(View, { style: [
|
|
587
|
+
styles2.badge,
|
|
588
|
+
{ backgroundColor: colors.primary },
|
|
589
|
+
showCount ? styles2.badgeCount : styles2.badgeDot
|
|
590
|
+
] }, showCount && /* @__PURE__ */ React25.createElement(Text, { style: [styles2.badgeText, { color: colors.primaryForeground }] }, badgeCount)));
|
|
350
591
|
}
|
|
351
592
|
var styles2 = StyleSheet.create({
|
|
593
|
+
wrapper: {
|
|
594
|
+
alignSelf: "flex-start"
|
|
595
|
+
},
|
|
352
596
|
base: {
|
|
353
|
-
borderRadius:
|
|
597
|
+
borderRadius: 9999,
|
|
354
598
|
alignItems: "center",
|
|
355
599
|
justifyContent: "center"
|
|
356
600
|
},
|
|
357
601
|
disabled: {
|
|
358
|
-
opacity: 0.
|
|
602
|
+
opacity: 0.45
|
|
603
|
+
},
|
|
604
|
+
badge: {
|
|
605
|
+
position: "absolute",
|
|
606
|
+
top: -2,
|
|
607
|
+
right: -2,
|
|
608
|
+
alignItems: "center",
|
|
609
|
+
justifyContent: "center"
|
|
610
|
+
},
|
|
611
|
+
badgeDot: {
|
|
612
|
+
width: 8,
|
|
613
|
+
height: 8,
|
|
614
|
+
borderRadius: 9999
|
|
615
|
+
},
|
|
616
|
+
badgeCount: {
|
|
617
|
+
minWidth: 16,
|
|
618
|
+
height: 16,
|
|
619
|
+
borderRadius: 9999,
|
|
620
|
+
paddingHorizontal: 3
|
|
621
|
+
},
|
|
622
|
+
badgeText: {
|
|
623
|
+
fontFamily: "Poppins-Bold",
|
|
624
|
+
fontSize: ms(9),
|
|
625
|
+
lineHeight: 14
|
|
359
626
|
}
|
|
360
627
|
});
|
|
361
628
|
var variantStyles = {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
629
|
+
"display-hero": { ...TYPOGRAPHY["display-hero"], fontSize: ms(TYPOGRAPHY["display-hero"].fontSize), lineHeight: mvs(TYPOGRAPHY["display-hero"].lineHeight) },
|
|
630
|
+
"display-xl": { ...TYPOGRAPHY["display-xl"], fontSize: ms(TYPOGRAPHY["display-xl"].fontSize), lineHeight: mvs(TYPOGRAPHY["display-xl"].lineHeight) },
|
|
631
|
+
"display-lg": { ...TYPOGRAPHY["display-lg"], fontSize: ms(TYPOGRAPHY["display-lg"].fontSize), lineHeight: mvs(TYPOGRAPHY["display-lg"].lineHeight) },
|
|
632
|
+
"display-md": { ...TYPOGRAPHY["display-md"], fontSize: ms(TYPOGRAPHY["display-md"].fontSize), lineHeight: mvs(TYPOGRAPHY["display-md"].lineHeight) },
|
|
633
|
+
"display-sm": { ...TYPOGRAPHY["display-sm"], fontSize: ms(TYPOGRAPHY["display-sm"].fontSize), lineHeight: mvs(TYPOGRAPHY["display-sm"].lineHeight) },
|
|
634
|
+
"title-md": { ...TYPOGRAPHY["title-md"], fontSize: ms(TYPOGRAPHY["title-md"].fontSize), lineHeight: mvs(TYPOGRAPHY["title-md"].lineHeight) },
|
|
635
|
+
"title-sm": { ...TYPOGRAPHY["title-sm"], fontSize: ms(TYPOGRAPHY["title-sm"].fontSize), lineHeight: mvs(TYPOGRAPHY["title-sm"].lineHeight) },
|
|
636
|
+
"body-md": { ...TYPOGRAPHY["body-md"], fontSize: ms(TYPOGRAPHY["body-md"].fontSize), lineHeight: mvs(TYPOGRAPHY["body-md"].lineHeight) },
|
|
637
|
+
"body-sm": { ...TYPOGRAPHY["body-sm"], fontSize: ms(TYPOGRAPHY["body-sm"].fontSize), lineHeight: mvs(TYPOGRAPHY["body-sm"].lineHeight) },
|
|
638
|
+
caption: { ...TYPOGRAPHY["caption"], fontSize: ms(TYPOGRAPHY["caption"].fontSize), lineHeight: mvs(TYPOGRAPHY["caption"].lineHeight) },
|
|
639
|
+
"caption-sm": { ...TYPOGRAPHY["caption-sm"], fontSize: ms(TYPOGRAPHY["caption-sm"].fontSize), lineHeight: mvs(TYPOGRAPHY["caption-sm"].lineHeight) },
|
|
640
|
+
"badge-text": { ...TYPOGRAPHY["badge-text"], fontSize: ms(TYPOGRAPHY["badge-text"].fontSize), lineHeight: mvs(TYPOGRAPHY["badge-text"].lineHeight) },
|
|
641
|
+
"micro-label": { ...TYPOGRAPHY["micro-label"], fontSize: ms(TYPOGRAPHY["micro-label"].fontSize), lineHeight: mvs(TYPOGRAPHY["micro-label"].lineHeight) },
|
|
642
|
+
"uppercase-tag": { ...TYPOGRAPHY["uppercase-tag"], fontSize: ms(TYPOGRAPHY["uppercase-tag"].fontSize), lineHeight: mvs(TYPOGRAPHY["uppercase-tag"].lineHeight) },
|
|
643
|
+
"button-lg": { ...TYPOGRAPHY["button-lg"], fontSize: ms(TYPOGRAPHY["button-lg"].fontSize), lineHeight: mvs(TYPOGRAPHY["button-lg"].lineHeight) },
|
|
644
|
+
"button-sm": { ...TYPOGRAPHY["button-sm"], fontSize: ms(TYPOGRAPHY["button-sm"].fontSize), lineHeight: mvs(TYPOGRAPHY["button-sm"].lineHeight) }
|
|
368
645
|
};
|
|
369
|
-
|
|
646
|
+
var defaultColorVariant = {
|
|
647
|
+
"display-hero": "foreground",
|
|
648
|
+
"display-xl": "foreground",
|
|
649
|
+
"display-lg": "foreground",
|
|
650
|
+
"display-md": "foreground",
|
|
651
|
+
"display-sm": "foreground",
|
|
652
|
+
"title-md": "foreground",
|
|
653
|
+
"title-sm": "foreground",
|
|
654
|
+
"body-md": "foregroundSubtle",
|
|
655
|
+
// running text — slightly softer
|
|
656
|
+
"body-sm": "foregroundSubtle",
|
|
657
|
+
caption: "foregroundMuted",
|
|
658
|
+
"caption-sm": "foregroundMuted",
|
|
659
|
+
"badge-text": "foreground",
|
|
660
|
+
"micro-label": "foreground",
|
|
661
|
+
"uppercase-tag": "foregroundMuted",
|
|
662
|
+
"button-lg": "foreground",
|
|
663
|
+
"button-sm": "foreground"
|
|
664
|
+
};
|
|
665
|
+
function Text3({ variant = "body-md", color, style, children, ...props }) {
|
|
370
666
|
const { colors } = useTheme();
|
|
371
|
-
const
|
|
667
|
+
const colorKey = defaultColorVariant[variant] ?? "foreground";
|
|
668
|
+
const resolvedColor = color ?? colors[colorKey];
|
|
372
669
|
return /* @__PURE__ */ React25.createElement(
|
|
373
670
|
Text,
|
|
374
671
|
{
|
|
375
|
-
style: [variantStyles[variant], { color:
|
|
672
|
+
style: [variantStyles[variant], { color: resolvedColor }, style],
|
|
376
673
|
allowFontScaling: true,
|
|
377
674
|
...props
|
|
378
675
|
},
|
|
@@ -386,21 +683,21 @@ function Input({ label, error, hint, prefix, suffix, prefixStyle, suffixStyle, p
|
|
|
386
683
|
const [showPassword, setShowPassword] = useState(false);
|
|
387
684
|
const isPassword = type === "password";
|
|
388
685
|
const effectiveSecure = isPassword ? !showPassword : secureTextEntry;
|
|
389
|
-
const effectivePrefix = prefixIcon ? renderIcon(prefixIcon, 20, prefixIconColor ?? colors.
|
|
390
|
-
const effectiveSuffix = isPassword && !suffix && !suffixIcon ? /* @__PURE__ */ React25.createElement(TouchableOpacity, { onPress: () => setShowPassword(!showPassword), style: styles3.passwordToggle, activeOpacity: 0.6 }, /* @__PURE__ */ React25.createElement(AntDesign$1, { name: showPassword ? "eye" : "eye-invisible", size: 20, color: colors.
|
|
686
|
+
const effectivePrefix = prefixIcon ? renderIcon(prefixIcon, 20, prefixIconColor ?? colors.foregroundMuted) : prefix;
|
|
687
|
+
const effectiveSuffix = isPassword && !suffix && !suffixIcon ? /* @__PURE__ */ React25.createElement(TouchableOpacity, { onPress: () => setShowPassword(!showPassword), style: styles3.passwordToggle, activeOpacity: 0.6 }, /* @__PURE__ */ React25.createElement(AntDesign$1, { name: showPassword ? "eye" : "eye-invisible", size: 20, color: colors.foregroundMuted })) : suffixIcon ? renderIcon(suffixIcon, 20, suffixIconColor ?? colors.foregroundMuted) : suffix;
|
|
391
688
|
return /* @__PURE__ */ React25.createElement(View, { style: [styles3.container, containerStyle] }, label ? /* @__PURE__ */ React25.createElement(Text, { style: [styles3.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React25.createElement(
|
|
392
689
|
View,
|
|
393
690
|
{
|
|
394
691
|
style: [
|
|
395
692
|
styles3.inputWrapper,
|
|
396
693
|
{
|
|
397
|
-
borderColor: error ? colors.destructive : focused ? colors.
|
|
694
|
+
borderColor: error ? colors.destructive : focused ? colors.primary : colors.border,
|
|
398
695
|
backgroundColor: colors.background
|
|
399
696
|
},
|
|
400
697
|
inputWrapperStyle
|
|
401
698
|
]
|
|
402
699
|
},
|
|
403
|
-
effectivePrefix ? typeof effectivePrefix === "string" ? /* @__PURE__ */ React25.createElement(Text, { style: [styles3.prefixText, { color: colors.
|
|
700
|
+
effectivePrefix ? typeof effectivePrefix === "string" ? /* @__PURE__ */ React25.createElement(Text, { style: [styles3.prefixText, { color: colors.foregroundMuted }, prefixStyle], allowFontScaling: true }, effectivePrefix) : /* @__PURE__ */ React25.createElement(View, { style: styles3.prefixContainer }, effectivePrefix) : null,
|
|
404
701
|
/* @__PURE__ */ React25.createElement(
|
|
405
702
|
TextInput,
|
|
406
703
|
{
|
|
@@ -420,14 +717,14 @@ function Input({ label, error, hint, prefix, suffix, prefixStyle, suffixStyle, p
|
|
|
420
717
|
setFocused(false);
|
|
421
718
|
onBlur?.(e);
|
|
422
719
|
},
|
|
423
|
-
placeholderTextColor: colors.
|
|
720
|
+
placeholderTextColor: colors.foregroundMuted,
|
|
424
721
|
allowFontScaling: true,
|
|
425
722
|
secureTextEntry: effectiveSecure,
|
|
426
723
|
...props
|
|
427
724
|
}
|
|
428
725
|
),
|
|
429
|
-
effectiveSuffix ? typeof effectiveSuffix === "string" ? /* @__PURE__ */ React25.createElement(Text, { style: [styles3.suffixText, { color: colors.
|
|
430
|
-
), error ? /* @__PURE__ */ React25.createElement(Text, { style: [styles3.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React25.createElement(Text, { style: [styles3.helperText, { color: colors.
|
|
726
|
+
effectiveSuffix ? typeof effectiveSuffix === "string" ? /* @__PURE__ */ React25.createElement(Text, { style: [styles3.suffixText, { color: colors.foregroundMuted }, suffixStyle], allowFontScaling: true }, effectiveSuffix) : /* @__PURE__ */ React25.createElement(View, { style: styles3.suffixContainer }, effectiveSuffix) : null
|
|
727
|
+
), error ? /* @__PURE__ */ React25.createElement(Text, { style: [styles3.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React25.createElement(Text, { style: [styles3.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
|
|
431
728
|
}
|
|
432
729
|
var styles3 = StyleSheet.create({
|
|
433
730
|
container: {
|
|
@@ -435,21 +732,24 @@ var styles3 = StyleSheet.create({
|
|
|
435
732
|
},
|
|
436
733
|
label: {
|
|
437
734
|
fontFamily: "Poppins-Medium",
|
|
438
|
-
fontSize: ms(
|
|
735
|
+
fontSize: ms(14)
|
|
736
|
+
// caption size for input labels
|
|
439
737
|
},
|
|
440
738
|
inputWrapper: {
|
|
441
739
|
flexDirection: "row",
|
|
442
740
|
alignItems: "center",
|
|
443
|
-
borderWidth:
|
|
444
|
-
borderRadius:
|
|
741
|
+
borderWidth: 2,
|
|
742
|
+
borderRadius: 8,
|
|
445
743
|
paddingHorizontal: s(14),
|
|
446
|
-
paddingVertical: vs(11)
|
|
744
|
+
paddingVertical: vs(11),
|
|
745
|
+
minHeight: 48
|
|
447
746
|
},
|
|
448
747
|
input: {
|
|
449
748
|
fontFamily: "Poppins-Regular",
|
|
450
749
|
flex: 1,
|
|
451
|
-
fontSize: ms(
|
|
452
|
-
paddingVertical:
|
|
750
|
+
fontSize: ms(16),
|
|
751
|
+
paddingVertical: vs(2),
|
|
752
|
+
includeFontPadding: false
|
|
453
753
|
},
|
|
454
754
|
prefixContainer: {
|
|
455
755
|
marginRight: s(8)
|
|
@@ -495,23 +795,25 @@ function Badge({ label, children, variant = "default", size = "md", icon, iconNa
|
|
|
495
795
|
const { colors } = useTheme();
|
|
496
796
|
const containerStyle = {
|
|
497
797
|
default: { backgroundColor: colors.primary },
|
|
498
|
-
secondary: { backgroundColor: colors.
|
|
798
|
+
secondary: { backgroundColor: colors.surface },
|
|
499
799
|
destructive: { backgroundColor: colors.destructive },
|
|
500
800
|
outline: { backgroundColor: "transparent", borderWidth: 1, borderColor: colors.border },
|
|
501
801
|
success: { backgroundColor: colors.success },
|
|
502
|
-
warning: { backgroundColor:
|
|
802
|
+
warning: { backgroundColor: colors.warning },
|
|
503
803
|
successOutline: { backgroundColor: colors.successTint, borderWidth: 1, borderColor: colors.successBorder },
|
|
504
|
-
destructiveOutline: { backgroundColor: colors.destructiveTint, borderWidth: 1, borderColor: colors.destructiveBorder }
|
|
804
|
+
destructiveOutline: { backgroundColor: colors.destructiveTint, borderWidth: 1, borderColor: colors.destructiveBorder },
|
|
805
|
+
warningOutline: { backgroundColor: colors.warningTint, borderWidth: 1, borderColor: colors.warningBorder }
|
|
505
806
|
}[variant];
|
|
506
807
|
const textColor = {
|
|
507
808
|
default: colors.primaryForeground,
|
|
508
|
-
secondary: colors.
|
|
809
|
+
secondary: colors.foreground,
|
|
509
810
|
destructive: colors.destructiveForeground,
|
|
510
811
|
outline: colors.foreground,
|
|
511
812
|
success: colors.successForeground,
|
|
512
|
-
warning:
|
|
813
|
+
warning: colors.warningForeground,
|
|
513
814
|
successOutline: colors.success,
|
|
514
|
-
destructiveOutline: colors.destructive
|
|
815
|
+
destructiveOutline: colors.destructive,
|
|
816
|
+
warningOutline: colors.warning
|
|
515
817
|
}[variant];
|
|
516
818
|
const effectiveIcon = iconName ? renderIcon(iconName, sizeIconSize[size], iconColor ?? textColor) : icon;
|
|
517
819
|
const content = children ?? label;
|
|
@@ -572,7 +874,7 @@ function Card({ children, variant = "elevated", onPress, style }) {
|
|
|
572
874
|
elevation: 0
|
|
573
875
|
},
|
|
574
876
|
filled: {
|
|
575
|
-
backgroundColor: colors.
|
|
877
|
+
backgroundColor: colors.surfaceStrong,
|
|
576
878
|
borderColor: colors.border,
|
|
577
879
|
shadowOpacity: 0,
|
|
578
880
|
elevation: 0
|
|
@@ -599,11 +901,11 @@ function CardHeader({ children, style }) {
|
|
|
599
901
|
}
|
|
600
902
|
function CardTitle({ children, style }) {
|
|
601
903
|
const { colors } = useTheme();
|
|
602
|
-
return /* @__PURE__ */ React25.createElement(Text, { style: [styles5.title, { color: colors.
|
|
904
|
+
return /* @__PURE__ */ React25.createElement(Text, { style: [styles5.title, { color: colors.foreground }, style], allowFontScaling: true }, children);
|
|
603
905
|
}
|
|
604
906
|
function CardDescription({ children, style }) {
|
|
605
907
|
const { colors } = useTheme();
|
|
606
|
-
return /* @__PURE__ */ React25.createElement(Text, { style: [styles5.description, { color: colors.
|
|
908
|
+
return /* @__PURE__ */ React25.createElement(Text, { style: [styles5.description, { color: colors.foregroundMuted }, style], allowFontScaling: true }, children);
|
|
607
909
|
}
|
|
608
910
|
function CardContent({ children, style }) {
|
|
609
911
|
return /* @__PURE__ */ React25.createElement(View, { style: [styles5.content, style] }, children);
|
|
@@ -613,7 +915,8 @@ function CardFooter({ children, style }) {
|
|
|
613
915
|
}
|
|
614
916
|
var styles5 = StyleSheet.create({
|
|
615
917
|
card: {
|
|
616
|
-
borderRadius:
|
|
918
|
+
borderRadius: 14,
|
|
919
|
+
// RADIUS.md — Airbnb property card spec
|
|
617
920
|
borderWidth: 1
|
|
618
921
|
},
|
|
619
922
|
header: {
|
|
@@ -682,7 +985,7 @@ function Spinner({ size = "md", color, label, ...props }) {
|
|
|
682
985
|
return /* @__PURE__ */ React25.createElement(View, { style: styles7.wrapper }, /* @__PURE__ */ React25.createElement(ActivityIndicator, { size: sizeMap2[size], color: color ?? colors.primary, ...props }), /* @__PURE__ */ React25.createElement(
|
|
683
986
|
Text,
|
|
684
987
|
{
|
|
685
|
-
style: [styles7.label, { color: colors.
|
|
988
|
+
style: [styles7.label, { color: colors.foregroundMuted, fontSize: labelFontSize[size] }],
|
|
686
989
|
allowFontScaling: true
|
|
687
990
|
},
|
|
688
991
|
label
|
|
@@ -700,18 +1003,21 @@ var styles7 = StyleSheet.create({
|
|
|
700
1003
|
lineHeight: mvs(18)
|
|
701
1004
|
}
|
|
702
1005
|
});
|
|
703
|
-
function Skeleton({
|
|
1006
|
+
function Skeleton({
|
|
1007
|
+
width = "100%",
|
|
1008
|
+
height = 16,
|
|
1009
|
+
borderRadius = 6,
|
|
1010
|
+
preset = "base",
|
|
1011
|
+
diameter = 40,
|
|
1012
|
+
style
|
|
1013
|
+
}) {
|
|
704
1014
|
const { colors, colorScheme } = useTheme();
|
|
705
1015
|
const shimmerAnim = useRef(new Animated.Value(0)).current;
|
|
706
1016
|
const [containerWidth, setContainerWidth] = useState(300);
|
|
707
1017
|
const shimmerHighlight = colorScheme === "dark" ? "rgba(255,255,255,0.08)" : "rgba(255,255,255,0.7)";
|
|
708
1018
|
useEffect(() => {
|
|
709
1019
|
const animation = Animated.loop(
|
|
710
|
-
Animated.timing(shimmerAnim, {
|
|
711
|
-
toValue: 1,
|
|
712
|
-
duration: 1200,
|
|
713
|
-
useNativeDriver: true
|
|
714
|
-
})
|
|
1020
|
+
Animated.timing(shimmerAnim, { toValue: 1, duration: 1200, useNativeDriver: true })
|
|
715
1021
|
);
|
|
716
1022
|
animation.start();
|
|
717
1023
|
return () => animation.stop();
|
|
@@ -720,12 +1026,15 @@ function Skeleton({ width = "100%", height = 16, borderRadius = 6, style }) {
|
|
|
720
1026
|
inputRange: [0, 1],
|
|
721
1027
|
outputRange: [-containerWidth, containerWidth]
|
|
722
1028
|
});
|
|
1029
|
+
const resolvedWidth = preset === "circle" ? s(diameter) : preset === "text" ? "60%" : width;
|
|
1030
|
+
const resolvedHeight = preset === "circle" ? s(diameter) : preset === "text" ? 14 : height;
|
|
1031
|
+
const resolvedRadius = preset === "circle" ? 9999 : preset === "text" ? 4 : borderRadius;
|
|
723
1032
|
return /* @__PURE__ */ React25.createElement(
|
|
724
1033
|
View,
|
|
725
1034
|
{
|
|
726
1035
|
style: [
|
|
727
1036
|
styles8.base,
|
|
728
|
-
{ width, height, borderRadius, backgroundColor: colors.
|
|
1037
|
+
{ width: resolvedWidth, height: resolvedHeight, borderRadius: resolvedRadius, backgroundColor: colors.surface },
|
|
729
1038
|
style
|
|
730
1039
|
],
|
|
731
1040
|
onLayout: (e) => setContainerWidth(e.nativeEvent.layout.width)
|
|
@@ -758,19 +1067,32 @@ var fontSizeMap = {
|
|
|
758
1067
|
lg: ms(22),
|
|
759
1068
|
xl: ms(28)
|
|
760
1069
|
};
|
|
761
|
-
|
|
1070
|
+
var statusSizeMap = {
|
|
1071
|
+
sm: 8,
|
|
1072
|
+
md: 10,
|
|
1073
|
+
lg: 13,
|
|
1074
|
+
xl: 16
|
|
1075
|
+
};
|
|
1076
|
+
function Avatar({ src, fallback, size = "md", status, style }) {
|
|
762
1077
|
const { colors } = useTheme();
|
|
763
1078
|
const [imageError, setImageError] = useState(false);
|
|
764
1079
|
const dimension = sizeMap3[size];
|
|
765
1080
|
const showFallback = !src || imageError;
|
|
1081
|
+
const statusSize = statusSizeMap[size];
|
|
1082
|
+
const statusColor = {
|
|
1083
|
+
online: "#22c55e",
|
|
1084
|
+
offline: "transparent",
|
|
1085
|
+
busy: colors.destructive,
|
|
1086
|
+
away: colors.warning
|
|
1087
|
+
};
|
|
766
1088
|
const containerStyle = {
|
|
767
1089
|
width: dimension,
|
|
768
1090
|
height: dimension,
|
|
769
1091
|
borderRadius: dimension / 2,
|
|
770
|
-
backgroundColor: colors.
|
|
1092
|
+
backgroundColor: colors.surface,
|
|
771
1093
|
overflow: "hidden"
|
|
772
1094
|
};
|
|
773
|
-
return /* @__PURE__ */ React25.createElement(View, { style: [styles9.
|
|
1095
|
+
return /* @__PURE__ */ React25.createElement(View, { style: [styles9.wrapper, style] }, /* @__PURE__ */ React25.createElement(View, { style: [styles9.base, containerStyle] }, !showFallback ? /* @__PURE__ */ React25.createElement(
|
|
774
1096
|
Image,
|
|
775
1097
|
{
|
|
776
1098
|
source: { uri: src },
|
|
@@ -780,64 +1102,86 @@ function Avatar({ src, fallback, size = "md", style }) {
|
|
|
780
1102
|
) : /* @__PURE__ */ React25.createElement(
|
|
781
1103
|
Text,
|
|
782
1104
|
{
|
|
783
|
-
style: [styles9.fallback, { color: colors.
|
|
1105
|
+
style: [styles9.fallback, { color: colors.foregroundMuted, fontSize: fontSizeMap[size] }],
|
|
784
1106
|
allowFontScaling: true
|
|
785
1107
|
},
|
|
786
1108
|
fallback?.slice(0, 2).toUpperCase() ?? "?"
|
|
1109
|
+
)), status && /* @__PURE__ */ React25.createElement(
|
|
1110
|
+
View,
|
|
1111
|
+
{
|
|
1112
|
+
style: [
|
|
1113
|
+
styles9.statusDot,
|
|
1114
|
+
{
|
|
1115
|
+
width: statusSize,
|
|
1116
|
+
height: statusSize,
|
|
1117
|
+
borderRadius: statusSize / 2,
|
|
1118
|
+
backgroundColor: statusColor[status],
|
|
1119
|
+
borderWidth: status === "offline" ? 2 : 1.5,
|
|
1120
|
+
borderColor: status === "offline" ? colors.border : colors.background
|
|
1121
|
+
}
|
|
1122
|
+
]
|
|
1123
|
+
}
|
|
787
1124
|
));
|
|
788
1125
|
}
|
|
789
1126
|
var styles9 = StyleSheet.create({
|
|
1127
|
+
wrapper: {
|
|
1128
|
+
alignSelf: "flex-start",
|
|
1129
|
+
position: "relative"
|
|
1130
|
+
},
|
|
790
1131
|
base: {
|
|
791
1132
|
alignItems: "center",
|
|
792
1133
|
justifyContent: "center"
|
|
793
1134
|
},
|
|
794
1135
|
fallback: {
|
|
795
1136
|
fontFamily: "Poppins-Medium"
|
|
1137
|
+
},
|
|
1138
|
+
statusDot: {
|
|
1139
|
+
position: "absolute",
|
|
1140
|
+
bottom: 0,
|
|
1141
|
+
right: 0
|
|
796
1142
|
}
|
|
797
1143
|
});
|
|
798
1144
|
function AlertBanner({ title, description, variant = "default", icon, iconName, iconColor, style }) {
|
|
799
1145
|
const { colors } = useTheme();
|
|
800
|
-
const bgColor = variant === "destructive" ? colors.
|
|
801
|
-
const
|
|
802
|
-
const
|
|
803
|
-
const
|
|
804
|
-
const
|
|
805
|
-
|
|
1146
|
+
const bgColor = variant === "destructive" ? colors.destructiveTint : variant === "success" ? colors.successTint : variant === "warning" ? colors.warningTint : colors.card;
|
|
1147
|
+
const borderColor = variant === "destructive" ? colors.destructiveBorder : variant === "success" ? colors.successBorder : variant === "warning" ? colors.warningBorder : colors.border;
|
|
1148
|
+
const accentColor = variant === "destructive" ? colors.destructive : variant === "success" ? colors.success : variant === "warning" ? colors.warning : colors.primary;
|
|
1149
|
+
const titleColor = variant === "default" ? colors.foreground : accentColor;
|
|
1150
|
+
const descColor = variant === "default" ? colors.foregroundMuted : accentColor;
|
|
1151
|
+
const defaultIcon = variant === "success" ? /* @__PURE__ */ React25.createElement(FontAwesome5$1, { name: "check-circle", size: 16, color: accentColor }) : variant === "destructive" ? /* @__PURE__ */ React25.createElement(MaterialIcons$1, { name: "error-outline", size: 17, color: accentColor }) : variant === "warning" ? /* @__PURE__ */ React25.createElement(MaterialIcons$1, { name: "warning-amber", size: 17, color: accentColor }) : /* @__PURE__ */ React25.createElement(Entypo$1, { name: "info-with-circle", size: 16, color: accentColor });
|
|
1152
|
+
const effectiveIcon = iconName ? renderIcon(iconName, 16, iconColor ?? accentColor) : icon ?? defaultIcon;
|
|
1153
|
+
return /* @__PURE__ */ React25.createElement(View, { style: [styles10.container, { backgroundColor: bgColor, borderColor }, style] }, /* @__PURE__ */ React25.createElement(View, { style: styles10.iconSlot }, effectiveIcon), /* @__PURE__ */ React25.createElement(View, { style: styles10.content }, /* @__PURE__ */ React25.createElement(Text, { style: [styles10.title, { color: titleColor }], allowFontScaling: true }, title), description ? /* @__PURE__ */ React25.createElement(Text, { style: [styles10.description, { color: descColor }], allowFontScaling: true }, description) : null));
|
|
806
1154
|
}
|
|
807
1155
|
var styles10 = StyleSheet.create({
|
|
808
1156
|
container: {
|
|
809
|
-
borderWidth: 1,
|
|
810
|
-
borderRadius: ms(12),
|
|
811
|
-
paddingHorizontal: s(14),
|
|
812
|
-
paddingVertical: vs(12),
|
|
813
|
-
gap: vs(8),
|
|
814
|
-
shadowColor: "#000",
|
|
815
|
-
shadowOffset: { width: 0, height: 3 },
|
|
816
|
-
shadowOpacity: 0.1,
|
|
817
|
-
shadowRadius: 8,
|
|
818
|
-
elevation: 5
|
|
819
|
-
},
|
|
820
|
-
header: {
|
|
821
1157
|
flexDirection: "row",
|
|
822
|
-
alignItems: "
|
|
1158
|
+
alignItems: "flex-start",
|
|
1159
|
+
borderWidth: 0.5,
|
|
1160
|
+
borderRadius: 10,
|
|
1161
|
+
paddingHorizontal: s(12),
|
|
1162
|
+
paddingVertical: vs(10),
|
|
823
1163
|
gap: s(10)
|
|
824
1164
|
},
|
|
825
|
-
|
|
826
|
-
marginTop:
|
|
1165
|
+
iconSlot: {
|
|
1166
|
+
marginTop: vs(1)
|
|
1167
|
+
},
|
|
1168
|
+
content: {
|
|
1169
|
+
flex: 1,
|
|
1170
|
+
gap: vs(2)
|
|
827
1171
|
},
|
|
828
1172
|
title: {
|
|
829
|
-
fontFamily: "Poppins-
|
|
830
|
-
fontSize: ms(
|
|
831
|
-
lineHeight:
|
|
832
|
-
flex: 1
|
|
1173
|
+
fontFamily: "Poppins-Medium",
|
|
1174
|
+
fontSize: ms(13),
|
|
1175
|
+
lineHeight: ms(18)
|
|
833
1176
|
},
|
|
834
1177
|
description: {
|
|
835
1178
|
fontFamily: "Poppins-Regular",
|
|
836
|
-
fontSize: ms(
|
|
837
|
-
lineHeight:
|
|
1179
|
+
fontSize: ms(12),
|
|
1180
|
+
lineHeight: ms(17),
|
|
1181
|
+
opacity: 0.85
|
|
838
1182
|
}
|
|
839
1183
|
});
|
|
840
|
-
function Progress({ value = 0, max = 100, style }) {
|
|
1184
|
+
function Progress({ value = 0, max = 100, variant = "default", style }) {
|
|
841
1185
|
const { colors } = useTheme();
|
|
842
1186
|
const percent = Math.min(Math.max(value / max * 100, 0), 100);
|
|
843
1187
|
const [trackWidth, setTrackWidth] = useState(0);
|
|
@@ -851,16 +1195,17 @@ function Progress({ value = 0, max = 100, style }) {
|
|
|
851
1195
|
bounciness: 0
|
|
852
1196
|
}).start();
|
|
853
1197
|
}, [percent, trackWidth]);
|
|
1198
|
+
const indicatorColor = variant === "success" ? colors.success : variant === "warning" ? colors.warning : variant === "destructive" ? colors.destructive : colors.primary;
|
|
854
1199
|
return /* @__PURE__ */ React25.createElement(
|
|
855
1200
|
View,
|
|
856
1201
|
{
|
|
857
|
-
style: [styles11.track, { backgroundColor: colors.
|
|
1202
|
+
style: [styles11.track, { backgroundColor: colors.surface }, style],
|
|
858
1203
|
onLayout: (e) => setTrackWidth(e.nativeEvent.layout.width)
|
|
859
1204
|
},
|
|
860
1205
|
/* @__PURE__ */ React25.createElement(
|
|
861
1206
|
Animated.View,
|
|
862
1207
|
{
|
|
863
|
-
style: [styles11.indicator, { width: animatedWidth, backgroundColor:
|
|
1208
|
+
style: [styles11.indicator, { width: animatedWidth, backgroundColor: indicatorColor }]
|
|
864
1209
|
}
|
|
865
1210
|
)
|
|
866
1211
|
);
|
|
@@ -868,19 +1213,19 @@ function Progress({ value = 0, max = 100, style }) {
|
|
|
868
1213
|
var styles11 = StyleSheet.create({
|
|
869
1214
|
track: {
|
|
870
1215
|
height: vs(8),
|
|
871
|
-
borderRadius:
|
|
1216
|
+
borderRadius: 9999,
|
|
872
1217
|
overflow: "hidden",
|
|
873
1218
|
width: "100%"
|
|
874
1219
|
},
|
|
875
1220
|
indicator: {
|
|
876
1221
|
height: "100%",
|
|
877
|
-
borderRadius:
|
|
1222
|
+
borderRadius: 9999
|
|
878
1223
|
}
|
|
879
1224
|
});
|
|
880
1225
|
function EmptyState({ icon, iconName, iconColor, title, description, action, size = "default", style }) {
|
|
881
1226
|
const { colors } = useTheme();
|
|
882
1227
|
const isCompact = size === "compact";
|
|
883
|
-
const effectiveIcon = iconName ? renderIcon(iconName, isCompact ? 32 : 48, iconColor ?? colors.
|
|
1228
|
+
const effectiveIcon = iconName ? renderIcon(iconName, isCompact ? 32 : 48, iconColor ?? colors.foregroundMuted) : icon;
|
|
884
1229
|
return /* @__PURE__ */ React25.createElement(
|
|
885
1230
|
View,
|
|
886
1231
|
{
|
|
@@ -897,7 +1242,7 @@ function EmptyState({ icon, iconName, iconColor, title, description, action, siz
|
|
|
897
1242
|
style: [
|
|
898
1243
|
styles12.iconWrapper,
|
|
899
1244
|
isCompact && styles12.iconWrapperCompact,
|
|
900
|
-
{ backgroundColor: colors.
|
|
1245
|
+
{ backgroundColor: colors.surface }
|
|
901
1246
|
]
|
|
902
1247
|
},
|
|
903
1248
|
effectiveIcon
|
|
@@ -909,7 +1254,7 @@ function EmptyState({ icon, iconName, iconColor, title, description, action, siz
|
|
|
909
1254
|
allowFontScaling: true
|
|
910
1255
|
},
|
|
911
1256
|
title
|
|
912
|
-
), description && !isCompact ? /* @__PURE__ */ React25.createElement(Text, { style: [styles12.description, { color: colors.
|
|
1257
|
+
), description && !isCompact ? /* @__PURE__ */ React25.createElement(Text, { style: [styles12.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null),
|
|
913
1258
|
action && !isCompact ? /* @__PURE__ */ React25.createElement(View, { style: styles12.action }, action) : null
|
|
914
1259
|
);
|
|
915
1260
|
}
|
|
@@ -928,16 +1273,16 @@ var styles12 = StyleSheet.create({
|
|
|
928
1273
|
gap: vs(10)
|
|
929
1274
|
},
|
|
930
1275
|
iconWrapper: {
|
|
931
|
-
width: s(
|
|
932
|
-
height: s(
|
|
933
|
-
borderRadius: ms(
|
|
1276
|
+
width: s(80),
|
|
1277
|
+
height: s(80),
|
|
1278
|
+
borderRadius: ms(20),
|
|
934
1279
|
alignItems: "center",
|
|
935
1280
|
justifyContent: "center"
|
|
936
1281
|
},
|
|
937
1282
|
iconWrapperCompact: {
|
|
938
|
-
width: s(
|
|
939
|
-
height: s(
|
|
940
|
-
borderRadius: ms(
|
|
1283
|
+
width: s(56),
|
|
1284
|
+
height: s(56),
|
|
1285
|
+
borderRadius: ms(14)
|
|
941
1286
|
},
|
|
942
1287
|
textWrapper: {
|
|
943
1288
|
alignItems: "center",
|
|
@@ -1001,11 +1346,11 @@ function Textarea({
|
|
|
1001
1346
|
setFocused(false);
|
|
1002
1347
|
onBlur?.(e);
|
|
1003
1348
|
},
|
|
1004
|
-
placeholderTextColor: colors.
|
|
1349
|
+
placeholderTextColor: colors.foregroundMuted,
|
|
1005
1350
|
allowFontScaling: true,
|
|
1006
1351
|
...props
|
|
1007
1352
|
}
|
|
1008
|
-
), error ? /* @__PURE__ */ React25.createElement(Text, { style: [styles13.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React25.createElement(Text, { style: [styles13.helperText, { color: colors.
|
|
1353
|
+
), error ? /* @__PURE__ */ React25.createElement(Text, { style: [styles13.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React25.createElement(Text, { style: [styles13.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
|
|
1009
1354
|
}
|
|
1010
1355
|
var styles13 = StyleSheet.create({
|
|
1011
1356
|
container: {
|
|
@@ -1017,11 +1362,12 @@ var styles13 = StyleSheet.create({
|
|
|
1017
1362
|
},
|
|
1018
1363
|
input: {
|
|
1019
1364
|
fontFamily: "Poppins-Regular",
|
|
1020
|
-
borderWidth:
|
|
1365
|
+
borderWidth: 2,
|
|
1021
1366
|
borderRadius: ms(8),
|
|
1022
1367
|
paddingHorizontal: s(14),
|
|
1023
1368
|
paddingVertical: vs(11),
|
|
1024
|
-
fontSize: ms(15)
|
|
1369
|
+
fontSize: ms(15),
|
|
1370
|
+
includeFontPadding: false
|
|
1025
1371
|
},
|
|
1026
1372
|
helperText: {
|
|
1027
1373
|
fontFamily: "Poppins-Regular",
|
|
@@ -1038,6 +1384,30 @@ function Checkbox({
|
|
|
1038
1384
|
}) {
|
|
1039
1385
|
const { colors } = useTheme();
|
|
1040
1386
|
const scale2 = useRef(new Animated.Value(1)).current;
|
|
1387
|
+
const bgOpacity = useRef(new Animated.Value(checked ? 1 : 0)).current;
|
|
1388
|
+
const checkOpacity = useRef(new Animated.Value(checked ? 1 : 0)).current;
|
|
1389
|
+
useEffect(() => {
|
|
1390
|
+
Animated.parallel([
|
|
1391
|
+
Animated.timing(bgOpacity, {
|
|
1392
|
+
toValue: checked ? 1 : 0,
|
|
1393
|
+
duration: 150,
|
|
1394
|
+
useNativeDriver: false
|
|
1395
|
+
}),
|
|
1396
|
+
Animated.timing(checkOpacity, {
|
|
1397
|
+
toValue: checked ? 1 : 0,
|
|
1398
|
+
duration: 120,
|
|
1399
|
+
useNativeDriver: false
|
|
1400
|
+
})
|
|
1401
|
+
]).start();
|
|
1402
|
+
}, [checked, bgOpacity, checkOpacity]);
|
|
1403
|
+
const borderColor = bgOpacity.interpolate({
|
|
1404
|
+
inputRange: [0, 1],
|
|
1405
|
+
outputRange: [colors.border, colors.primary]
|
|
1406
|
+
});
|
|
1407
|
+
const backgroundColor = bgOpacity.interpolate({
|
|
1408
|
+
inputRange: [0, 1],
|
|
1409
|
+
outputRange: ["transparent", colors.primary]
|
|
1410
|
+
});
|
|
1041
1411
|
const handlePressIn = () => {
|
|
1042
1412
|
if (disabled) return;
|
|
1043
1413
|
Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver4, speed: 40, bounciness: 0 }).start();
|
|
@@ -1059,25 +1429,24 @@ function Checkbox({
|
|
|
1059
1429
|
activeOpacity: 1,
|
|
1060
1430
|
touchSoundDisabled: true
|
|
1061
1431
|
},
|
|
1062
|
-
/* @__PURE__ */ React25.createElement(
|
|
1432
|
+
/* @__PURE__ */ React25.createElement(Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25.createElement(
|
|
1063
1433
|
Animated.View,
|
|
1064
1434
|
{
|
|
1065
1435
|
style: [
|
|
1066
1436
|
styles14.box,
|
|
1067
1437
|
{
|
|
1068
|
-
borderColor
|
|
1069
|
-
backgroundColor
|
|
1070
|
-
opacity: disabled ? 0.45 : 1
|
|
1071
|
-
transform: [{ scale: scale2 }]
|
|
1438
|
+
borderColor,
|
|
1439
|
+
backgroundColor,
|
|
1440
|
+
opacity: disabled ? 0.45 : 1
|
|
1072
1441
|
}
|
|
1073
1442
|
]
|
|
1074
1443
|
},
|
|
1075
|
-
|
|
1076
|
-
),
|
|
1444
|
+
/* @__PURE__ */ React25.createElement(Animated.View, { style: { opacity: checkOpacity } }, /* @__PURE__ */ React25.createElement(View, { style: [styles14.checkmark, { borderColor: colors.primaryForeground }] }))
|
|
1445
|
+
)),
|
|
1077
1446
|
label ? /* @__PURE__ */ React25.createElement(
|
|
1078
1447
|
Text,
|
|
1079
1448
|
{
|
|
1080
|
-
style: [styles14.label, { color: disabled ? colors.
|
|
1449
|
+
style: [styles14.label, { color: disabled ? colors.foregroundMuted : colors.foreground }],
|
|
1081
1450
|
allowFontScaling: true
|
|
1082
1451
|
},
|
|
1083
1452
|
label
|
|
@@ -1117,10 +1486,13 @@ var TRACK_HEIGHT = s(30);
|
|
|
1117
1486
|
var THUMB_SIZE = s(24);
|
|
1118
1487
|
var THUMB_OFFSET = s(3);
|
|
1119
1488
|
var THUMB_TRAVEL = TRACK_WIDTH - THUMB_SIZE - THUMB_OFFSET * 2;
|
|
1489
|
+
var ICON_SIZE = s(13);
|
|
1120
1490
|
function Switch({ checked = false, onCheckedChange, disabled, style }) {
|
|
1121
1491
|
const { colors } = useTheme();
|
|
1122
1492
|
const translateX = useRef(new Animated.Value(checked ? THUMB_TRAVEL : 0)).current;
|
|
1123
1493
|
const trackOpacity = useRef(new Animated.Value(checked ? 1 : 0)).current;
|
|
1494
|
+
const checkOpacity = useRef(new Animated.Value(checked ? 1 : 0)).current;
|
|
1495
|
+
const crossOpacity = useRef(new Animated.Value(checked ? 0 : 1)).current;
|
|
1124
1496
|
useEffect(() => {
|
|
1125
1497
|
Animated.parallel([
|
|
1126
1498
|
Animated.spring(translateX, {
|
|
@@ -1132,12 +1504,22 @@ function Switch({ checked = false, onCheckedChange, disabled, style }) {
|
|
|
1132
1504
|
toValue: checked ? 1 : 0,
|
|
1133
1505
|
duration: 150,
|
|
1134
1506
|
useNativeDriver: false
|
|
1507
|
+
}),
|
|
1508
|
+
Animated.timing(checkOpacity, {
|
|
1509
|
+
toValue: checked ? 1 : 0,
|
|
1510
|
+
duration: 120,
|
|
1511
|
+
useNativeDriver: true
|
|
1512
|
+
}),
|
|
1513
|
+
Animated.timing(crossOpacity, {
|
|
1514
|
+
toValue: checked ? 0 : 1,
|
|
1515
|
+
duration: 120,
|
|
1516
|
+
useNativeDriver: true
|
|
1135
1517
|
})
|
|
1136
1518
|
]).start();
|
|
1137
|
-
}, [checked, translateX, trackOpacity]);
|
|
1519
|
+
}, [checked, translateX, trackOpacity, checkOpacity, crossOpacity]);
|
|
1138
1520
|
const trackColor = trackOpacity.interpolate({
|
|
1139
1521
|
inputRange: [0, 1],
|
|
1140
|
-
outputRange: [colors.
|
|
1522
|
+
outputRange: [colors.surface, colors.primary]
|
|
1141
1523
|
});
|
|
1142
1524
|
return /* @__PURE__ */ React25.createElement(View, { style: [{ opacity: disabled ? 0.45 : 1 }, style] }, /* @__PURE__ */ React25.createElement(
|
|
1143
1525
|
TouchableOpacity,
|
|
@@ -1158,7 +1540,9 @@ function Switch({ checked = false, onCheckedChange, disabled, style }) {
|
|
|
1158
1540
|
styles15.thumb,
|
|
1159
1541
|
{ backgroundColor: colors.primaryForeground, transform: [{ translateX }] }
|
|
1160
1542
|
]
|
|
1161
|
-
}
|
|
1543
|
+
},
|
|
1544
|
+
/* @__PURE__ */ React25.createElement(Animated.View, { style: [styles15.iconWrapper, { opacity: checkOpacity }] }, /* @__PURE__ */ React25.createElement(Feather$1, { name: "check", size: ICON_SIZE, color: colors.primary })),
|
|
1545
|
+
/* @__PURE__ */ React25.createElement(Animated.View, { style: [styles15.iconWrapper, { opacity: crossOpacity }] }, /* @__PURE__ */ React25.createElement(Feather$1, { name: "x", size: ICON_SIZE, color: colors.foregroundMuted }))
|
|
1162
1546
|
))
|
|
1163
1547
|
));
|
|
1164
1548
|
}
|
|
@@ -1182,7 +1566,12 @@ var styles15 = StyleSheet.create({
|
|
|
1182
1566
|
shadowOffset: { width: 0, height: 1 },
|
|
1183
1567
|
shadowOpacity: 0.15,
|
|
1184
1568
|
shadowRadius: 2,
|
|
1185
|
-
elevation: 2
|
|
1569
|
+
elevation: 2,
|
|
1570
|
+
alignItems: "center",
|
|
1571
|
+
justifyContent: "center"
|
|
1572
|
+
},
|
|
1573
|
+
iconWrapper: {
|
|
1574
|
+
position: "absolute"
|
|
1186
1575
|
}
|
|
1187
1576
|
});
|
|
1188
1577
|
var nativeDriver6 = Platform.OS !== "web";
|
|
@@ -1232,7 +1621,7 @@ function Toggle({
|
|
|
1232
1621
|
});
|
|
1233
1622
|
const backgroundColor = pressAnim.interpolate({
|
|
1234
1623
|
inputRange: [0, 1],
|
|
1235
|
-
outputRange: ["transparent", colors.
|
|
1624
|
+
outputRange: ["transparent", colors.surfaceStrong]
|
|
1236
1625
|
});
|
|
1237
1626
|
const textColor = pressAnim.interpolate({
|
|
1238
1627
|
inputRange: [0, 1],
|
|
@@ -1251,10 +1640,10 @@ function Toggle({
|
|
|
1251
1640
|
if (active) return /* @__PURE__ */ React25.createElement(React25.Fragment, null, active);
|
|
1252
1641
|
return /* @__PURE__ */ React25.createElement(FontAwesome5$1, { name: "check-circle", size: iconSize, color: colors.primary });
|
|
1253
1642
|
}
|
|
1254
|
-
if (iconName) return /* @__PURE__ */ React25.createElement(React25.Fragment, null, renderIcon(iconName, iconSize, iconColor ?? colors.
|
|
1643
|
+
if (iconName) return /* @__PURE__ */ React25.createElement(React25.Fragment, null, renderIcon(iconName, iconSize, iconColor ?? colors.foregroundMuted));
|
|
1255
1644
|
const custom = renderProp(icon);
|
|
1256
1645
|
if (custom) return /* @__PURE__ */ React25.createElement(React25.Fragment, null, custom);
|
|
1257
|
-
return /* @__PURE__ */ React25.createElement(FontAwesome5$1, { name: "circle", size: iconSize, color: colors.
|
|
1646
|
+
return /* @__PURE__ */ React25.createElement(FontAwesome5$1, { name: "circle", size: iconSize, color: colors.foregroundMuted });
|
|
1258
1647
|
};
|
|
1259
1648
|
return /* @__PURE__ */ React25.createElement(Animated.View, { style: [{ transform: [{ scale: scale2 }] }, disabled && styles16.disabled, style] }, /* @__PURE__ */ React25.createElement(
|
|
1260
1649
|
TouchableOpacity,
|
|
@@ -1351,7 +1740,7 @@ function RadioItem({
|
|
|
1351
1740
|
{
|
|
1352
1741
|
style: [
|
|
1353
1742
|
styles17.label,
|
|
1354
|
-
{ color: option.disabled ? colors.
|
|
1743
|
+
{ color: option.disabled ? colors.foregroundMuted : colors.foreground }
|
|
1355
1744
|
],
|
|
1356
1745
|
allowFontScaling: true
|
|
1357
1746
|
},
|
|
@@ -1413,7 +1802,8 @@ function TabTrigger({
|
|
|
1413
1802
|
tab,
|
|
1414
1803
|
isActive,
|
|
1415
1804
|
onPress,
|
|
1416
|
-
onLayout
|
|
1805
|
+
onLayout,
|
|
1806
|
+
variant
|
|
1417
1807
|
}) {
|
|
1418
1808
|
const { colors } = useTheme();
|
|
1419
1809
|
const scale2 = useRef(new Animated.Value(1)).current;
|
|
@@ -1423,10 +1813,15 @@ function TabTrigger({
|
|
|
1423
1813
|
const handlePressOut = () => {
|
|
1424
1814
|
Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver8, speed: 40, bounciness: 4 }).start();
|
|
1425
1815
|
};
|
|
1816
|
+
const isUnderline = variant === "underline";
|
|
1426
1817
|
return /* @__PURE__ */ React25.createElement(
|
|
1427
1818
|
TouchableOpacity,
|
|
1428
1819
|
{
|
|
1429
|
-
style:
|
|
1820
|
+
style: [
|
|
1821
|
+
styles18.trigger,
|
|
1822
|
+
isUnderline && styles18.triggerUnderline,
|
|
1823
|
+
isUnderline && isActive && { borderBottomColor: colors.primary }
|
|
1824
|
+
],
|
|
1430
1825
|
onPress,
|
|
1431
1826
|
onPressIn: handlePressIn,
|
|
1432
1827
|
onPressOut: handlePressOut,
|
|
@@ -1439,8 +1834,8 @@ function TabTrigger({
|
|
|
1439
1834
|
{
|
|
1440
1835
|
style: [
|
|
1441
1836
|
styles18.triggerLabel,
|
|
1442
|
-
{ color: isActive ? colors.foreground : colors.
|
|
1443
|
-
isActive && styles18.activeTriggerLabel
|
|
1837
|
+
{ color: isActive ? colors.foreground : colors.foregroundMuted },
|
|
1838
|
+
isActive && (isUnderline ? styles18.activeTriggerLabelUnderline : styles18.activeTriggerLabel)
|
|
1444
1839
|
],
|
|
1445
1840
|
allowFontScaling: true
|
|
1446
1841
|
},
|
|
@@ -1448,7 +1843,7 @@ function TabTrigger({
|
|
|
1448
1843
|
)))
|
|
1449
1844
|
);
|
|
1450
1845
|
}
|
|
1451
|
-
function Tabs({ tabs, value, onValueChange, children, style }) {
|
|
1846
|
+
function Tabs({ tabs, variant = "pill", value, onValueChange, children, style }) {
|
|
1452
1847
|
const [internal, setInternal] = useState(tabs[0]?.value ?? "");
|
|
1453
1848
|
const { colors } = useTheme();
|
|
1454
1849
|
const active = value ?? internal;
|
|
@@ -1461,18 +1856,8 @@ function Tabs({ tabs, value, onValueChange, children, style }) {
|
|
|
1461
1856
|
if (!layout) return;
|
|
1462
1857
|
if (animate) {
|
|
1463
1858
|
Animated.parallel([
|
|
1464
|
-
Animated.spring(pillX, {
|
|
1465
|
-
|
|
1466
|
-
useNativeDriver: false,
|
|
1467
|
-
speed: 20,
|
|
1468
|
-
bounciness: 0
|
|
1469
|
-
}),
|
|
1470
|
-
Animated.spring(pillWidth, {
|
|
1471
|
-
toValue: layout.width,
|
|
1472
|
-
useNativeDriver: false,
|
|
1473
|
-
speed: 20,
|
|
1474
|
-
bounciness: 0
|
|
1475
|
-
})
|
|
1859
|
+
Animated.spring(pillX, { toValue: layout.x, useNativeDriver: false, speed: 20, bounciness: 0 }),
|
|
1860
|
+
Animated.spring(pillWidth, { toValue: layout.width, useNativeDriver: false, speed: 20, bounciness: 0 })
|
|
1476
1861
|
]).start();
|
|
1477
1862
|
} else {
|
|
1478
1863
|
pillX.setValue(layout.x);
|
|
@@ -1480,16 +1865,16 @@ function Tabs({ tabs, value, onValueChange, children, style }) {
|
|
|
1480
1865
|
}
|
|
1481
1866
|
};
|
|
1482
1867
|
useEffect(() => {
|
|
1483
|
-
if (initialised.current)
|
|
1484
|
-
animatePill(active, true);
|
|
1485
|
-
}
|
|
1868
|
+
if (initialised.current) animatePill(active, true);
|
|
1486
1869
|
}, [active]);
|
|
1487
1870
|
const handlePress = (v) => {
|
|
1488
1871
|
selectionAsync();
|
|
1489
1872
|
if (!value) setInternal(v);
|
|
1490
1873
|
onValueChange?.(v);
|
|
1491
1874
|
};
|
|
1492
|
-
return /* @__PURE__ */ React25.createElement(View, { style }, /* @__PURE__ */ React25.createElement(View, { style: [
|
|
1875
|
+
return /* @__PURE__ */ React25.createElement(View, { style }, /* @__PURE__ */ React25.createElement(View, { style: [
|
|
1876
|
+
variant === "pill" ? [styles18.list, { backgroundColor: colors.surface }] : styles18.listUnderline
|
|
1877
|
+
] }, variant === "pill" && /* @__PURE__ */ React25.createElement(
|
|
1493
1878
|
Animated.View,
|
|
1494
1879
|
{
|
|
1495
1880
|
style: [
|
|
@@ -1504,7 +1889,7 @@ function Tabs({ tabs, value, onValueChange, children, style }) {
|
|
|
1504
1889
|
borderRadius: 8,
|
|
1505
1890
|
shadowColor: "#000",
|
|
1506
1891
|
shadowOffset: { width: 0, height: 1 },
|
|
1507
|
-
shadowOpacity: 0.
|
|
1892
|
+
shadowOpacity: 0.08,
|
|
1508
1893
|
shadowRadius: 2,
|
|
1509
1894
|
elevation: 2
|
|
1510
1895
|
}
|
|
@@ -1517,6 +1902,7 @@ function Tabs({ tabs, value, onValueChange, children, style }) {
|
|
|
1517
1902
|
tab,
|
|
1518
1903
|
isActive: tab.value === active,
|
|
1519
1904
|
onPress: () => handlePress(tab.value),
|
|
1905
|
+
variant,
|
|
1520
1906
|
onLayout: (e) => {
|
|
1521
1907
|
const { x, width } = e.nativeEvent.layout;
|
|
1522
1908
|
tabLayouts.current[tab.value] = { x, width };
|
|
@@ -1535,20 +1921,32 @@ function TabsContent({ value, activeValue, children, style }) {
|
|
|
1535
1921
|
var styles18 = StyleSheet.create({
|
|
1536
1922
|
list: {
|
|
1537
1923
|
flexDirection: "row",
|
|
1538
|
-
borderRadius:
|
|
1924
|
+
borderRadius: 12,
|
|
1539
1925
|
padding: s(4),
|
|
1540
1926
|
gap: s(4)
|
|
1541
1927
|
},
|
|
1928
|
+
listUnderline: {
|
|
1929
|
+
flexDirection: "row",
|
|
1930
|
+
borderBottomWidth: 1
|
|
1931
|
+
},
|
|
1542
1932
|
pill: {},
|
|
1543
1933
|
trigger: {
|
|
1544
1934
|
flex: 1,
|
|
1545
1935
|
paddingVertical: vs(7),
|
|
1546
1936
|
paddingHorizontal: s(10),
|
|
1547
|
-
borderRadius:
|
|
1937
|
+
borderRadius: 8,
|
|
1548
1938
|
alignItems: "center",
|
|
1549
1939
|
justifyContent: "center",
|
|
1550
1940
|
zIndex: 1
|
|
1551
1941
|
},
|
|
1942
|
+
triggerUnderline: {
|
|
1943
|
+
flex: 0,
|
|
1944
|
+
paddingVertical: vs(12),
|
|
1945
|
+
paddingHorizontal: s(16),
|
|
1946
|
+
borderRadius: 0,
|
|
1947
|
+
borderBottomWidth: 2,
|
|
1948
|
+
borderBottomColor: "transparent"
|
|
1949
|
+
},
|
|
1552
1950
|
triggerInner: {
|
|
1553
1951
|
flexDirection: "row",
|
|
1554
1952
|
alignItems: "center",
|
|
@@ -1561,6 +1959,10 @@ var styles18 = StyleSheet.create({
|
|
|
1561
1959
|
},
|
|
1562
1960
|
activeTriggerLabel: {
|
|
1563
1961
|
fontFamily: "Poppins-Medium"
|
|
1962
|
+
},
|
|
1963
|
+
activeTriggerLabelUnderline: {
|
|
1964
|
+
fontFamily: "Poppins-SemiBold",
|
|
1965
|
+
fontSize: ms(14)
|
|
1564
1966
|
}
|
|
1565
1967
|
});
|
|
1566
1968
|
function AccordionItemComponent({
|
|
@@ -1603,7 +2005,7 @@ function AccordionItemComponent({
|
|
|
1603
2005
|
}
|
|
1604
2006
|
},
|
|
1605
2007
|
/* @__PURE__ */ React25.createElement(Text, { style: [styles19.triggerText, { color: colors.foreground }], allowFontScaling: true }, item.trigger),
|
|
1606
|
-
/* @__PURE__ */ React25.createElement(Animated11.View, { style: [styles19.chevron, rotationStyle] }, /* @__PURE__ */ React25.createElement(Entypo$1, { name: "chevron-down", size: 18, color: colors.
|
|
2008
|
+
/* @__PURE__ */ React25.createElement(Animated11.View, { style: [styles19.chevron, rotationStyle] }, /* @__PURE__ */ React25.createElement(Entypo$1, { name: "chevron-down", size: 18, color: colors.foregroundMuted }))
|
|
1607
2009
|
), /* @__PURE__ */ React25.createElement(Animated11.View, { style: bodyStyle }, /* @__PURE__ */ React25.createElement(
|
|
1608
2010
|
View,
|
|
1609
2011
|
{
|
|
@@ -1695,7 +2097,7 @@ function Slider({
|
|
|
1695
2097
|
}
|
|
1696
2098
|
onValueChange?.(v);
|
|
1697
2099
|
};
|
|
1698
|
-
return /* @__PURE__ */ React25.createElement(View, { style: [styles20.wrapper, style], accessibilityLabel }, label || showValue ? /* @__PURE__ */ React25.createElement(View, { style: styles20.header }, label ? /* @__PURE__ */ React25.createElement(Text, { style: [styles20.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, showValue ? /* @__PURE__ */ React25.createElement(Text, { style: [styles20.valueText, { color: colors.
|
|
2100
|
+
return /* @__PURE__ */ React25.createElement(View, { style: [styles20.wrapper, style], accessibilityLabel }, label || showValue ? /* @__PURE__ */ React25.createElement(View, { style: styles20.header }, label ? /* @__PURE__ */ React25.createElement(Text, { style: [styles20.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, showValue ? /* @__PURE__ */ React25.createElement(Text, { style: [styles20.valueText, { color: colors.foregroundMuted }], allowFontScaling: true }, formatValue2(value)) : null) : null, /* @__PURE__ */ React25.createElement(View, { style: disabled ? styles20.disabled : void 0 }, /* @__PURE__ */ React25.createElement(
|
|
1699
2101
|
RNSlider,
|
|
1700
2102
|
{
|
|
1701
2103
|
value,
|
|
@@ -1706,7 +2108,7 @@ function Slider({
|
|
|
1706
2108
|
onValueChange: handleValueChange,
|
|
1707
2109
|
onSlidingComplete,
|
|
1708
2110
|
minimumTrackTintColor: colors.primary,
|
|
1709
|
-
maximumTrackTintColor: colors.
|
|
2111
|
+
maximumTrackTintColor: colors.surface,
|
|
1710
2112
|
thumbTintColor: colors.primary,
|
|
1711
2113
|
style: styles20.slider,
|
|
1712
2114
|
accessibilityLabel
|
|
@@ -1744,7 +2146,6 @@ function Sheet({
|
|
|
1744
2146
|
title,
|
|
1745
2147
|
description,
|
|
1746
2148
|
children,
|
|
1747
|
-
snapPoints = ["50%"],
|
|
1748
2149
|
style
|
|
1749
2150
|
}) {
|
|
1750
2151
|
const { colors } = useTheme();
|
|
@@ -1770,14 +2171,14 @@ function Sheet({
|
|
|
1770
2171
|
BottomSheetModal,
|
|
1771
2172
|
{
|
|
1772
2173
|
ref,
|
|
1773
|
-
|
|
2174
|
+
enableDynamicSizing: true,
|
|
1774
2175
|
onDismiss: onClose,
|
|
1775
2176
|
backdropComponent: renderBackdrop,
|
|
1776
2177
|
backgroundStyle: [styles21.background, { backgroundColor: colors.card }],
|
|
1777
2178
|
handleIndicatorStyle: [styles21.handle, { backgroundColor: colors.border }],
|
|
1778
2179
|
enablePanDownToClose: true
|
|
1779
2180
|
},
|
|
1780
|
-
/* @__PURE__ */ React25.createElement(BottomSheetView, { style: [styles21.content, style] }, title || description ? /* @__PURE__ */ React25.createElement(View, { style: styles21.header }, title ? /* @__PURE__ */ React25.createElement(Text, { style: [styles21.title, { color: colors.
|
|
2181
|
+
/* @__PURE__ */ React25.createElement(BottomSheetView, { style: [styles21.content, style] }, title || description ? /* @__PURE__ */ React25.createElement(View, { style: styles21.header }, title ? /* @__PURE__ */ React25.createElement(Text, { style: [styles21.title, { color: colors.foreground }], allowFontScaling: true }, title) : null, description ? /* @__PURE__ */ React25.createElement(Text, { style: [styles21.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null) : null, children)
|
|
1781
2182
|
);
|
|
1782
2183
|
}
|
|
1783
2184
|
var styles21 = StyleSheet.create({
|
|
@@ -1876,14 +2277,14 @@ function Select({
|
|
|
1876
2277
|
{
|
|
1877
2278
|
style: [
|
|
1878
2279
|
styles22.triggerText,
|
|
1879
|
-
{ color: selected ? colors.foreground : colors.
|
|
2280
|
+
{ color: selected ? colors.foreground : colors.foregroundMuted }
|
|
1880
2281
|
],
|
|
1881
2282
|
numberOfLines: 1,
|
|
1882
2283
|
allowFontScaling: true
|
|
1883
2284
|
},
|
|
1884
2285
|
selected?.label ?? placeholder
|
|
1885
2286
|
),
|
|
1886
|
-
/* @__PURE__ */ React25.createElement(Entypo$1, { name: "chevron-with-circle-down", size: 20, color: colors.
|
|
2287
|
+
/* @__PURE__ */ React25.createElement(Entypo$1, { name: "chevron-with-circle-down", size: 20, color: colors.foregroundMuted })
|
|
1887
2288
|
)) : null, isIOS ? /* @__PURE__ */ React25.createElement(
|
|
1888
2289
|
Modal,
|
|
1889
2290
|
{
|
|
@@ -1900,7 +2301,7 @@ function Select({
|
|
|
1900
2301
|
onValueChange: (val) => setPendingValue(val),
|
|
1901
2302
|
itemStyle: { color: colors.foreground }
|
|
1902
2303
|
},
|
|
1903
|
-
!value ? /* @__PURE__ */ React25.createElement(Picker.Item, { label: placeholder, value: "", color: colors.
|
|
2304
|
+
!value ? /* @__PURE__ */ React25.createElement(Picker.Item, { label: placeholder, value: "", color: colors.foregroundMuted, enabled: false }) : null,
|
|
1904
2305
|
options.map((o) => /* @__PURE__ */ React25.createElement(
|
|
1905
2306
|
Picker.Item,
|
|
1906
2307
|
{
|
|
@@ -1908,7 +2309,7 @@ function Select({
|
|
|
1908
2309
|
label: o.label,
|
|
1909
2310
|
value: o.value,
|
|
1910
2311
|
enabled: !o.disabled,
|
|
1911
|
-
color: o.disabled ? colors.
|
|
2312
|
+
color: o.disabled ? colors.foregroundMuted : colors.foreground
|
|
1912
2313
|
}
|
|
1913
2314
|
))
|
|
1914
2315
|
))
|
|
@@ -1952,7 +2353,7 @@ function Select({
|
|
|
1952
2353
|
styles22.webPicker,
|
|
1953
2354
|
{
|
|
1954
2355
|
borderColor: error ? colors.destructive : colors.border,
|
|
1955
|
-
color: selected ? colors.foreground : colors.
|
|
2356
|
+
color: selected ? colors.foreground : colors.foregroundMuted,
|
|
1956
2357
|
backgroundColor: colors.background,
|
|
1957
2358
|
opacity: disabled ? 0.45 : 1
|
|
1958
2359
|
}
|
|
@@ -2087,19 +2488,39 @@ function ToastNotification({ item, onDismiss }) {
|
|
|
2087
2488
|
}));
|
|
2088
2489
|
const variant = item.variant ?? "default";
|
|
2089
2490
|
const bgColor = {
|
|
2090
|
-
default: colors.
|
|
2491
|
+
default: colors.card,
|
|
2492
|
+
destructive: colors.destructiveTint,
|
|
2493
|
+
success: colors.successTint,
|
|
2494
|
+
warning: colors.warningTint
|
|
2495
|
+
}[variant];
|
|
2496
|
+
const borderColor = {
|
|
2497
|
+
default: colors.border,
|
|
2091
2498
|
destructive: colors.destructiveBorder,
|
|
2092
|
-
success: colors.successBorder
|
|
2499
|
+
success: colors.successBorder,
|
|
2500
|
+
warning: colors.warningBorder
|
|
2093
2501
|
}[variant];
|
|
2094
|
-
const
|
|
2095
|
-
default: colors.
|
|
2096
|
-
destructive:
|
|
2097
|
-
success:
|
|
2502
|
+
const accentColor = {
|
|
2503
|
+
default: colors.primary,
|
|
2504
|
+
destructive: colors.destructive,
|
|
2505
|
+
success: colors.success,
|
|
2506
|
+
warning: colors.warning
|
|
2098
2507
|
}[variant];
|
|
2099
|
-
const
|
|
2100
|
-
const
|
|
2101
|
-
const
|
|
2102
|
-
|
|
2508
|
+
const titleColor = variant === "default" ? colors.foreground : accentColor;
|
|
2509
|
+
const descColor = variant === "default" ? colors.foregroundMuted : accentColor;
|
|
2510
|
+
const defaultIcon = variant === "success" ? /* @__PURE__ */ React25.createElement(FontAwesome5$1, { name: "check-circle", size: 16, color: accentColor }) : variant === "destructive" ? /* @__PURE__ */ React25.createElement(AntDesign$1, { name: "exclamation-circle", size: 16, color: accentColor }) : variant === "warning" ? /* @__PURE__ */ React25.createElement(MaterialIcons$1, { name: "warning-amber", size: 17, color: accentColor }) : /* @__PURE__ */ React25.createElement(Entypo$1, { name: "info-with-circle", size: 16, color: accentColor });
|
|
2511
|
+
const leftIcon = item.iconName ? renderIcon(item.iconName, 16, item.iconColor ?? accentColor) : item.icon ?? defaultIcon;
|
|
2512
|
+
return /* @__PURE__ */ React25.createElement(GestureDetector, { gesture: panGesture }, /* @__PURE__ */ React25.createElement(Animated11.View, { style: [styles23.toast, { backgroundColor: bgColor, borderColor }, animatedStyle] }, /* @__PURE__ */ React25.createElement(View, { style: styles23.leftIconContainer }, leftIcon), /* @__PURE__ */ React25.createElement(View, { style: styles23.toastContent }, item.title ? /* @__PURE__ */ React25.createElement(Text, { style: [styles23.toastTitle, { color: titleColor }], allowFontScaling: true }, item.title) : null, item.description ? /* @__PURE__ */ React25.createElement(Text, { style: [styles23.toastDescription, { color: descColor }], allowFontScaling: true }, item.description) : null), item.action && /* @__PURE__ */ React25.createElement(
|
|
2513
|
+
TouchableOpacity,
|
|
2514
|
+
{
|
|
2515
|
+
onPress: () => {
|
|
2516
|
+
item.action.onPress();
|
|
2517
|
+
onDismiss();
|
|
2518
|
+
},
|
|
2519
|
+
style: styles23.actionButton,
|
|
2520
|
+
touchSoundDisabled: true
|
|
2521
|
+
},
|
|
2522
|
+
/* @__PURE__ */ React25.createElement(Text, { style: [styles23.actionLabel, { color: accentColor }], allowFontScaling: true }, item.action.label)
|
|
2523
|
+
), /* @__PURE__ */ React25.createElement(TouchableOpacity, { onPress: onDismiss, style: styles23.dismissButton, touchSoundDisabled: true }, /* @__PURE__ */ React25.createElement(AntDesign$1, { name: "close-circle", size: 16, color: descColor }))));
|
|
2103
2524
|
}
|
|
2104
2525
|
function ToastProvider({ children }) {
|
|
2105
2526
|
const [toasts, setToasts] = useState([]);
|
|
@@ -2110,6 +2531,8 @@ function ToastProvider({ children }) {
|
|
|
2110
2531
|
notificationSuccess();
|
|
2111
2532
|
} else if (item.variant === "destructive") {
|
|
2112
2533
|
notificationError();
|
|
2534
|
+
} else if (item.variant === "warning") {
|
|
2535
|
+
notificationError();
|
|
2113
2536
|
} else {
|
|
2114
2537
|
impactLight();
|
|
2115
2538
|
}
|
|
@@ -2136,38 +2559,52 @@ var styles23 = StyleSheet.create({
|
|
|
2136
2559
|
},
|
|
2137
2560
|
toast: {
|
|
2138
2561
|
flexDirection: "row",
|
|
2139
|
-
alignItems: "
|
|
2140
|
-
borderRadius: ms(
|
|
2141
|
-
borderWidth:
|
|
2142
|
-
paddingHorizontal: s(
|
|
2143
|
-
paddingVertical: vs(
|
|
2562
|
+
alignItems: "flex-start",
|
|
2563
|
+
borderRadius: ms(10),
|
|
2564
|
+
borderWidth: 0.5,
|
|
2565
|
+
paddingHorizontal: s(12),
|
|
2566
|
+
paddingVertical: vs(10),
|
|
2144
2567
|
shadowColor: "#000",
|
|
2145
|
-
shadowOffset: { width: 0, height:
|
|
2146
|
-
shadowOpacity: 0.
|
|
2147
|
-
shadowRadius:
|
|
2148
|
-
elevation:
|
|
2568
|
+
shadowOffset: { width: 0, height: 2 },
|
|
2569
|
+
shadowOpacity: 0.06,
|
|
2570
|
+
shadowRadius: 4,
|
|
2571
|
+
elevation: 3
|
|
2149
2572
|
},
|
|
2150
2573
|
toastContent: {
|
|
2151
2574
|
flex: 1,
|
|
2152
|
-
gap: vs(
|
|
2575
|
+
gap: vs(2)
|
|
2153
2576
|
},
|
|
2154
2577
|
leftIconContainer: {
|
|
2155
|
-
|
|
2578
|
+
marginTop: vs(1),
|
|
2156
2579
|
alignItems: "center",
|
|
2157
2580
|
justifyContent: "center",
|
|
2158
2581
|
marginRight: s(10)
|
|
2159
2582
|
},
|
|
2160
2583
|
toastTitle: {
|
|
2161
|
-
fontFamily: "Poppins-
|
|
2162
|
-
fontSize: ms(
|
|
2584
|
+
fontFamily: "Poppins-Medium",
|
|
2585
|
+
fontSize: ms(13),
|
|
2586
|
+
lineHeight: ms(18)
|
|
2163
2587
|
},
|
|
2164
2588
|
toastDescription: {
|
|
2165
2589
|
fontFamily: "Poppins-Regular",
|
|
2166
|
-
fontSize: ms(
|
|
2590
|
+
fontSize: ms(12),
|
|
2591
|
+
lineHeight: ms(17),
|
|
2592
|
+
opacity: 0.85
|
|
2167
2593
|
},
|
|
2168
|
-
|
|
2169
|
-
|
|
2594
|
+
actionButton: {
|
|
2595
|
+
paddingHorizontal: s(8),
|
|
2596
|
+
paddingVertical: vs(4),
|
|
2170
2597
|
marginLeft: s(4)
|
|
2598
|
+
},
|
|
2599
|
+
actionLabel: {
|
|
2600
|
+
fontFamily: "Poppins-Medium",
|
|
2601
|
+
fontSize: ms(12),
|
|
2602
|
+
textDecorationLine: "underline"
|
|
2603
|
+
},
|
|
2604
|
+
dismissButton: {
|
|
2605
|
+
padding: s(6),
|
|
2606
|
+
marginLeft: s(2),
|
|
2607
|
+
marginTop: vs(0)
|
|
2171
2608
|
}
|
|
2172
2609
|
});
|
|
2173
2610
|
function formatCurrency(raw, separator) {
|
|
@@ -2201,7 +2638,7 @@ function CurrencyInput({
|
|
|
2201
2638
|
onChangeValue?.(isNaN(raw) ? 0 : raw);
|
|
2202
2639
|
};
|
|
2203
2640
|
const inputStyle = size === "large" ? { fontFamily: "Poppins-Regular", fontSize: ms(36) } : { fontFamily: "Poppins-Regular" };
|
|
2204
|
-
const dollarIcon = renderIcon("dollar-sign", size === "large" ? 24 : 16, colors.
|
|
2641
|
+
const dollarIcon = renderIcon("dollar-sign", size === "large" ? 24 : 16, colors.foregroundMuted);
|
|
2205
2642
|
const displayValue = value && prefix && value.startsWith(prefix) ? value.slice(prefix.length) : value;
|
|
2206
2643
|
return /* @__PURE__ */ React25.createElement(
|
|
2207
2644
|
Input,
|
|
@@ -2216,7 +2653,7 @@ function CurrencyInput({
|
|
|
2216
2653
|
editable,
|
|
2217
2654
|
prefix: dollarIcon,
|
|
2218
2655
|
containerStyle,
|
|
2219
|
-
inputWrapperStyle: size === "large" ? { paddingVertical:
|
|
2656
|
+
inputWrapperStyle: size === "large" ? { paddingVertical: vs(16), minHeight: 72 } : void 0,
|
|
2220
2657
|
style: [inputStyle, style]
|
|
2221
2658
|
}
|
|
2222
2659
|
);
|
|
@@ -2242,7 +2679,8 @@ var styles24 = StyleSheet.create({
|
|
|
2242
2679
|
container: {},
|
|
2243
2680
|
amount: {
|
|
2244
2681
|
fontFamily: "Poppins-Bold",
|
|
2245
|
-
fontSize: ms(56)
|
|
2682
|
+
fontSize: ms(56),
|
|
2683
|
+
letterSpacing: -2
|
|
2246
2684
|
}
|
|
2247
2685
|
});
|
|
2248
2686
|
var nativeDriver10 = Platform.OS !== "web";
|
|
@@ -2292,7 +2730,7 @@ function ListItem({
|
|
|
2292
2730
|
onPress?.();
|
|
2293
2731
|
};
|
|
2294
2732
|
const effectiveLeft = leftIcon ? renderIcon(leftIcon, 24, leftIconColor ?? colors.foreground) : leftRender ?? icon;
|
|
2295
|
-
const effectiveRight = rightIcon ? renderIcon(rightIcon, 24, rightIconColor ?? colors.
|
|
2733
|
+
const effectiveRight = rightIcon ? renderIcon(rightIcon, 24, rightIconColor ?? colors.foregroundMuted) : rightRender ?? trailing;
|
|
2296
2734
|
const cardStyle = variant === "card" ? {
|
|
2297
2735
|
backgroundColor: colors.card,
|
|
2298
2736
|
borderRadius: 12,
|
|
@@ -2327,7 +2765,7 @@ function ListItem({
|
|
|
2327
2765
|
), subtitle ? /* @__PURE__ */ React25.createElement(
|
|
2328
2766
|
Text,
|
|
2329
2767
|
{
|
|
2330
|
-
style: [styles25.subtitle, { color: colors.
|
|
2768
|
+
style: [styles25.subtitle, { color: colors.foregroundMuted }, subtitleStyle],
|
|
2331
2769
|
numberOfLines: 2,
|
|
2332
2770
|
allowFontScaling: true
|
|
2333
2771
|
},
|
|
@@ -2335,7 +2773,7 @@ function ListItem({
|
|
|
2335
2773
|
) : null, caption ? /* @__PURE__ */ React25.createElement(
|
|
2336
2774
|
Text,
|
|
2337
2775
|
{
|
|
2338
|
-
style: [styles25.caption, { color: colors.
|
|
2776
|
+
style: [styles25.caption, { color: colors.foregroundMuted }, captionStyle],
|
|
2339
2777
|
numberOfLines: 1,
|
|
2340
2778
|
allowFontScaling: true
|
|
2341
2779
|
},
|
|
@@ -2344,11 +2782,11 @@ function ListItem({
|
|
|
2344
2782
|
effectiveRight !== void 0 ? /* @__PURE__ */ React25.createElement(View, { style: styles25.rightContainer }, typeof effectiveRight === "string" ? /* @__PURE__ */ React25.createElement(
|
|
2345
2783
|
Text,
|
|
2346
2784
|
{
|
|
2347
|
-
style: [styles25.rightText, { color: colors.
|
|
2785
|
+
style: [styles25.rightText, { color: colors.foregroundMuted }],
|
|
2348
2786
|
allowFontScaling: true
|
|
2349
2787
|
},
|
|
2350
2788
|
effectiveRight
|
|
2351
|
-
) : effectiveRight) : showChevron ? /* @__PURE__ */ React25.createElement(Entypo$1, { name: "chevron-with-circle-right", size: 20, color: colors.
|
|
2789
|
+
) : effectiveRight) : showChevron ? /* @__PURE__ */ React25.createElement(Entypo$1, { name: "chevron-with-circle-right", size: 20, color: colors.foregroundMuted }) : null
|
|
2352
2790
|
), showSeparator ? /* @__PURE__ */ React25.createElement(
|
|
2353
2791
|
View,
|
|
2354
2792
|
{
|
|
@@ -2450,7 +2888,7 @@ function Chip({ label, selected = false, onPress, icon, iconName, style }) {
|
|
|
2450
2888
|
};
|
|
2451
2889
|
const backgroundColor = pressAnim.interpolate({
|
|
2452
2890
|
inputRange: [0, 1],
|
|
2453
|
-
outputRange: [colors.
|
|
2891
|
+
outputRange: [colors.surface, colors.primary]
|
|
2454
2892
|
});
|
|
2455
2893
|
const textColor = pressAnim.interpolate({
|
|
2456
2894
|
inputRange: [0, 1],
|
|
@@ -2565,18 +3003,18 @@ function ConfirmDialog({
|
|
|
2565
3003
|
BottomSheetModal,
|
|
2566
3004
|
{
|
|
2567
3005
|
ref,
|
|
2568
|
-
|
|
3006
|
+
enableDynamicSizing: true,
|
|
2569
3007
|
onDismiss: onCancel,
|
|
2570
3008
|
backdropComponent: renderBackdrop,
|
|
2571
3009
|
backgroundStyle: [styles27.background, { backgroundColor: colors.card }],
|
|
2572
3010
|
handleIndicatorStyle: [styles27.handle, { backgroundColor: colors.border }],
|
|
2573
3011
|
enablePanDownToClose: true
|
|
2574
3012
|
},
|
|
2575
|
-
/* @__PURE__ */ React25.createElement(BottomSheetView, { style: styles27.content }, /* @__PURE__ */ React25.createElement(Text, { style: [styles27.title, { color: colors.
|
|
3013
|
+
/* @__PURE__ */ React25.createElement(BottomSheetView, { style: styles27.content }, /* @__PURE__ */ React25.createElement(Text, { style: [styles27.title, { color: colors.foreground }], allowFontScaling: true }, title), description ? /* @__PURE__ */ React25.createElement(Text, { style: [styles27.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null, /* @__PURE__ */ React25.createElement(View, { style: styles27.actions }, /* @__PURE__ */ React25.createElement(
|
|
2576
3014
|
Button,
|
|
2577
3015
|
{
|
|
2578
3016
|
label: cancelLabel,
|
|
2579
|
-
variant: "
|
|
3017
|
+
variant: "secondary",
|
|
2580
3018
|
fullWidth: true,
|
|
2581
3019
|
onPress: onCancel,
|
|
2582
3020
|
icon: /* @__PURE__ */ React25.createElement(Feather$1, { name: "x", size: 15, color: colors.foreground })
|
|
@@ -2632,7 +3070,7 @@ var styles27 = StyleSheet.create({
|
|
|
2632
3070
|
});
|
|
2633
3071
|
function LabelValue({ label, value, style }) {
|
|
2634
3072
|
const { colors } = useTheme();
|
|
2635
|
-
return /* @__PURE__ */ React25.createElement(View, { style: [styles28.container, style] }, /* @__PURE__ */ React25.createElement(Text, { style: [styles28.label, { color: colors.
|
|
3073
|
+
return /* @__PURE__ */ React25.createElement(View, { style: [styles28.container, style] }, /* @__PURE__ */ React25.createElement(Text, { style: [styles28.label, { color: colors.foregroundMuted }], allowFontScaling: true }, label), typeof value === "string" ? /* @__PURE__ */ React25.createElement(Text, { style: [styles28.value, { color: colors.foreground }], allowFontScaling: true }, value) : value);
|
|
2636
3074
|
}
|
|
2637
3075
|
var styles28 = StyleSheet.create({
|
|
2638
3076
|
container: {
|
|
@@ -2725,63 +3163,342 @@ var styles29 = StyleSheet.create({
|
|
|
2725
3163
|
minWidth: s(160)
|
|
2726
3164
|
}
|
|
2727
3165
|
});
|
|
3166
|
+
function useHover() {
|
|
3167
|
+
const [hovered, setHovered] = useState(false);
|
|
3168
|
+
const onMouseEnter = useCallback(() => setHovered(true), []);
|
|
3169
|
+
const onMouseLeave = useCallback(() => setHovered(false), []);
|
|
3170
|
+
if (Platform.OS !== "web") {
|
|
3171
|
+
return { hovered: false, hoverHandlers: {} };
|
|
3172
|
+
}
|
|
3173
|
+
return { hovered, hoverHandlers: { onMouseEnter, onMouseLeave } };
|
|
3174
|
+
}
|
|
2728
3175
|
|
|
2729
|
-
// src/
|
|
2730
|
-
var
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
"
|
|
2737
|
-
"3xl": 48
|
|
2738
|
-
};
|
|
2739
|
-
var ICON_SIZES = {
|
|
2740
|
-
sm: 14,
|
|
2741
|
-
md: 18,
|
|
2742
|
-
lg: 22,
|
|
2743
|
-
xl: 28,
|
|
2744
|
-
"2xl": 32
|
|
2745
|
-
};
|
|
2746
|
-
var RADIUS = {
|
|
2747
|
-
sm: 4,
|
|
2748
|
-
md: 8,
|
|
2749
|
-
lg: 12,
|
|
2750
|
-
xl: 16,
|
|
2751
|
-
full: 9999
|
|
3176
|
+
// src/components/MediaCard/MediaCard.tsx
|
|
3177
|
+
var nativeDriver12 = Platform.OS !== "web";
|
|
3178
|
+
var aspectRatioMap = {
|
|
3179
|
+
"1:1": 1,
|
|
3180
|
+
"4:3": 3 / 4,
|
|
3181
|
+
"16:9": 9 / 16,
|
|
3182
|
+
"4:5": 5 / 4,
|
|
3183
|
+
"3:2": 2 / 3
|
|
2752
3184
|
};
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
3185
|
+
function MediaCard({
|
|
3186
|
+
imageSource,
|
|
3187
|
+
aspectRatio = "4:3",
|
|
3188
|
+
badge,
|
|
3189
|
+
actionIcon,
|
|
3190
|
+
actionIconName,
|
|
3191
|
+
actionActive = false,
|
|
3192
|
+
onActionPress,
|
|
3193
|
+
title,
|
|
3194
|
+
subtitle,
|
|
3195
|
+
caption,
|
|
3196
|
+
onPress,
|
|
3197
|
+
style,
|
|
3198
|
+
imageStyle,
|
|
3199
|
+
footer
|
|
3200
|
+
}) {
|
|
3201
|
+
const { colors } = useTheme();
|
|
3202
|
+
const scale2 = useRef(new Animated.Value(1)).current;
|
|
3203
|
+
const { hovered, hoverHandlers } = useHover();
|
|
3204
|
+
const handlePressIn = () => {
|
|
3205
|
+
if (!onPress) return;
|
|
3206
|
+
Animated.spring(scale2, { toValue: 0.98, useNativeDriver: nativeDriver12, speed: 40, bounciness: 0 }).start();
|
|
3207
|
+
};
|
|
3208
|
+
const handlePressOut = () => {
|
|
3209
|
+
if (!onPress) return;
|
|
3210
|
+
Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver12, speed: 40, bounciness: 4 }).start();
|
|
3211
|
+
};
|
|
3212
|
+
const handlePress = () => {
|
|
3213
|
+
if (!onPress) return;
|
|
3214
|
+
impactLight();
|
|
3215
|
+
onPress();
|
|
3216
|
+
};
|
|
3217
|
+
const ratio = aspectRatioMap[aspectRatio];
|
|
3218
|
+
const resolvedActionIcon = actionIconName ? renderIcon(actionIconName, 18, actionActive ? colors.primary : colors.background) : actionIcon ?? renderIcon("heart", 18, actionActive ? colors.primary : colors.background);
|
|
3219
|
+
const cardContent = /* @__PURE__ */ React25.createElement(
|
|
3220
|
+
View,
|
|
3221
|
+
{
|
|
3222
|
+
style: [
|
|
3223
|
+
styles30.card,
|
|
3224
|
+
hovered && styles30.cardHovered,
|
|
3225
|
+
style
|
|
3226
|
+
],
|
|
3227
|
+
...Platform.OS === "web" ? hoverHandlers : {}
|
|
3228
|
+
},
|
|
3229
|
+
/* @__PURE__ */ React25.createElement(View, { style: [styles30.imageContainer, imageStyle] }, /* @__PURE__ */ React25.createElement(View, { style: { paddingTop: `${ratio * 100}%` } }, /* @__PURE__ */ React25.createElement(View, { style: StyleSheet.absoluteFill }, imageSource ? /* @__PURE__ */ React25.createElement(
|
|
3230
|
+
Image,
|
|
3231
|
+
{
|
|
3232
|
+
source: imageSource,
|
|
3233
|
+
style: styles30.image,
|
|
3234
|
+
resizeMode: "cover"
|
|
3235
|
+
}
|
|
3236
|
+
) : /* @__PURE__ */ React25.createElement(View, { style: [styles30.imagePlaceholder, { backgroundColor: colors.surface }] }))), badge && /* @__PURE__ */ React25.createElement(View, { style: styles30.badgeContainer }, badge), (onActionPress || actionIcon || actionIconName) && /* @__PURE__ */ React25.createElement(
|
|
3237
|
+
TouchableOpacity,
|
|
3238
|
+
{
|
|
3239
|
+
style: [styles30.actionButton, { backgroundColor: "rgba(0,0,0,0.24)" }],
|
|
3240
|
+
onPress: () => {
|
|
3241
|
+
impactLight();
|
|
3242
|
+
onActionPress?.();
|
|
3243
|
+
},
|
|
3244
|
+
activeOpacity: 0.8,
|
|
3245
|
+
touchSoundDisabled: true
|
|
3246
|
+
},
|
|
3247
|
+
resolvedActionIcon
|
|
3248
|
+
)),
|
|
3249
|
+
(title || subtitle || caption || footer) && /* @__PURE__ */ React25.createElement(View, { style: styles30.meta }, title ? /* @__PURE__ */ React25.createElement(Text, { style: [styles30.title, { color: colors.foreground }], numberOfLines: 2, allowFontScaling: true }, title) : null, subtitle ? /* @__PURE__ */ React25.createElement(Text, { style: [styles30.subtitle, { color: colors.foregroundSubtle }], numberOfLines: 1, allowFontScaling: true }, subtitle) : null, caption ? /* @__PURE__ */ React25.createElement(Text, { style: [styles30.caption, { color: colors.foregroundMuted }], numberOfLines: 1, allowFontScaling: true }, caption) : null, footer)
|
|
3250
|
+
);
|
|
3251
|
+
if (onPress) {
|
|
3252
|
+
return /* @__PURE__ */ React25.createElement(Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25.createElement(
|
|
3253
|
+
TouchableOpacity,
|
|
3254
|
+
{
|
|
3255
|
+
onPress: handlePress,
|
|
3256
|
+
onPressIn: handlePressIn,
|
|
3257
|
+
onPressOut: handlePressOut,
|
|
3258
|
+
activeOpacity: 1,
|
|
3259
|
+
touchSoundDisabled: true
|
|
3260
|
+
},
|
|
3261
|
+
cardContent
|
|
3262
|
+
));
|
|
3263
|
+
}
|
|
3264
|
+
return cardContent;
|
|
3265
|
+
}
|
|
3266
|
+
var styles30 = StyleSheet.create({
|
|
3267
|
+
card: {
|
|
3268
|
+
borderRadius: RADIUS.md,
|
|
3269
|
+
// 14px — Airbnb property card spec
|
|
3270
|
+
overflow: "hidden",
|
|
3271
|
+
backgroundColor: "transparent"
|
|
2760
3272
|
},
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
shadowOpacity: 0.12,
|
|
2765
|
-
shadowRadius: 8,
|
|
2766
|
-
elevation: 5
|
|
3273
|
+
cardHovered: {
|
|
3274
|
+
// Web hover: lift shadow
|
|
3275
|
+
...SHADOWS.md
|
|
2767
3276
|
},
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
shadowOpacity: 0.2,
|
|
2772
|
-
shadowRadius: 16,
|
|
2773
|
-
elevation: 10
|
|
3277
|
+
imageContainer: {
|
|
3278
|
+
borderRadius: RADIUS.md,
|
|
3279
|
+
overflow: "hidden"
|
|
2774
3280
|
},
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
3281
|
+
image: {
|
|
3282
|
+
width: "100%",
|
|
3283
|
+
height: "100%"
|
|
3284
|
+
},
|
|
3285
|
+
imagePlaceholder: {
|
|
3286
|
+
width: "100%",
|
|
3287
|
+
height: "100%"
|
|
3288
|
+
},
|
|
3289
|
+
badgeContainer: {
|
|
3290
|
+
position: "absolute",
|
|
3291
|
+
top: s(8),
|
|
3292
|
+
left: s(8)
|
|
3293
|
+
},
|
|
3294
|
+
actionButton: {
|
|
3295
|
+
position: "absolute",
|
|
3296
|
+
top: s(8),
|
|
3297
|
+
right: s(8),
|
|
3298
|
+
width: s(32),
|
|
3299
|
+
height: s(32),
|
|
3300
|
+
borderRadius: 9999,
|
|
3301
|
+
alignItems: "center",
|
|
3302
|
+
justifyContent: "center"
|
|
3303
|
+
},
|
|
3304
|
+
meta: {
|
|
3305
|
+
paddingTop: vs(8),
|
|
3306
|
+
gap: vs(2)
|
|
3307
|
+
},
|
|
3308
|
+
title: {
|
|
3309
|
+
fontFamily: "Poppins-SemiBold",
|
|
3310
|
+
fontSize: ms(14),
|
|
3311
|
+
lineHeight: mvs(20)
|
|
3312
|
+
},
|
|
3313
|
+
subtitle: {
|
|
3314
|
+
fontFamily: "Poppins-Regular",
|
|
3315
|
+
fontSize: ms(13),
|
|
3316
|
+
lineHeight: mvs(18)
|
|
3317
|
+
},
|
|
3318
|
+
caption: {
|
|
3319
|
+
fontFamily: "Poppins-Regular",
|
|
3320
|
+
fontSize: ms(12),
|
|
3321
|
+
lineHeight: mvs(16)
|
|
2781
3322
|
}
|
|
2782
|
-
};
|
|
2783
|
-
var
|
|
2784
|
-
|
|
2785
|
-
|
|
3323
|
+
});
|
|
3324
|
+
var nativeDriver13 = Platform.OS !== "web";
|
|
3325
|
+
function CategoryChip({
|
|
3326
|
+
item,
|
|
3327
|
+
selected,
|
|
3328
|
+
onPress
|
|
3329
|
+
}) {
|
|
3330
|
+
const { colors } = useTheme();
|
|
3331
|
+
const scale2 = useRef(new Animated.Value(1)).current;
|
|
3332
|
+
const handlePressIn = () => {
|
|
3333
|
+
Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver13, speed: 40, bounciness: 0 }).start();
|
|
3334
|
+
};
|
|
3335
|
+
const handlePressOut = () => {
|
|
3336
|
+
Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver13, speed: 40, bounciness: 4 }).start();
|
|
3337
|
+
};
|
|
3338
|
+
const bgColor = selected ? colors.primary : colors.surface;
|
|
3339
|
+
const textColor = selected ? colors.primaryForeground : colors.foregroundSubtle;
|
|
3340
|
+
const borderColor = selected ? colors.primary : colors.border;
|
|
3341
|
+
const resolvedIcon = typeof item.icon === "string" ? renderIcon(item.icon, 16, textColor) : item.icon ?? null;
|
|
3342
|
+
return /* @__PURE__ */ React25.createElement(Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25.createElement(
|
|
3343
|
+
TouchableOpacity,
|
|
3344
|
+
{
|
|
3345
|
+
style: [
|
|
3346
|
+
styles31.chip,
|
|
3347
|
+
{
|
|
3348
|
+
backgroundColor: bgColor,
|
|
3349
|
+
borderColor
|
|
3350
|
+
}
|
|
3351
|
+
],
|
|
3352
|
+
onPress,
|
|
3353
|
+
onPressIn: handlePressIn,
|
|
3354
|
+
onPressOut: handlePressOut,
|
|
3355
|
+
activeOpacity: 1,
|
|
3356
|
+
touchSoundDisabled: true
|
|
3357
|
+
},
|
|
3358
|
+
resolvedIcon && /* @__PURE__ */ React25.createElement(View, { style: styles31.chipIcon }, resolvedIcon),
|
|
3359
|
+
/* @__PURE__ */ React25.createElement(Text, { style: [styles31.chipLabel, { color: textColor }], allowFontScaling: true }, item.label),
|
|
3360
|
+
item.badge !== void 0 && item.badge > 0 && /* @__PURE__ */ React25.createElement(View, { style: [styles31.chipBadge, { backgroundColor: colors.primary }] }, /* @__PURE__ */ React25.createElement(Text, { style: [styles31.chipBadgeText, { color: colors.primaryForeground }] }, Math.min(item.badge, 99)))
|
|
3361
|
+
));
|
|
3362
|
+
}
|
|
3363
|
+
function CategoryStrip({
|
|
3364
|
+
categories,
|
|
3365
|
+
value,
|
|
3366
|
+
onValueChange,
|
|
3367
|
+
multiSelect = false,
|
|
3368
|
+
style,
|
|
3369
|
+
itemStyle
|
|
3370
|
+
}) {
|
|
3371
|
+
const selected = Array.isArray(value) ? value : value ? [value] : [];
|
|
3372
|
+
const handlePress = (v) => {
|
|
3373
|
+
selectionAsync();
|
|
3374
|
+
if (multiSelect) {
|
|
3375
|
+
const current = Array.isArray(value) ? value : value ? [value] : [];
|
|
3376
|
+
const next = current.includes(v) ? current.filter((x) => x !== v) : [...current, v];
|
|
3377
|
+
onValueChange?.(next);
|
|
3378
|
+
} else {
|
|
3379
|
+
onValueChange?.(v === value ? "" : v);
|
|
3380
|
+
}
|
|
3381
|
+
};
|
|
3382
|
+
return /* @__PURE__ */ React25.createElement(
|
|
3383
|
+
ScrollView,
|
|
3384
|
+
{
|
|
3385
|
+
horizontal: true,
|
|
3386
|
+
showsHorizontalScrollIndicator: false,
|
|
3387
|
+
contentContainerStyle: [styles31.container, style],
|
|
3388
|
+
style: styles31.scroll
|
|
3389
|
+
},
|
|
3390
|
+
categories.map((cat) => /* @__PURE__ */ React25.createElement(View, { key: cat.value, style: itemStyle }, /* @__PURE__ */ React25.createElement(
|
|
3391
|
+
CategoryChip,
|
|
3392
|
+
{
|
|
3393
|
+
item: cat,
|
|
3394
|
+
selected: selected.includes(cat.value),
|
|
3395
|
+
onPress: () => handlePress(cat.value)
|
|
3396
|
+
}
|
|
3397
|
+
)))
|
|
3398
|
+
);
|
|
3399
|
+
}
|
|
3400
|
+
var styles31 = StyleSheet.create({
|
|
3401
|
+
scroll: {
|
|
3402
|
+
flexGrow: 0
|
|
3403
|
+
},
|
|
3404
|
+
container: {
|
|
3405
|
+
flexDirection: "row",
|
|
3406
|
+
gap: s(8),
|
|
3407
|
+
paddingHorizontal: s(4),
|
|
3408
|
+
paddingVertical: vs(4)
|
|
3409
|
+
},
|
|
3410
|
+
chip: {
|
|
3411
|
+
flexDirection: "row",
|
|
3412
|
+
alignItems: "center",
|
|
3413
|
+
borderRadius: RADIUS.full,
|
|
3414
|
+
borderWidth: 1,
|
|
3415
|
+
paddingHorizontal: s(14),
|
|
3416
|
+
paddingVertical: vs(8),
|
|
3417
|
+
gap: s(6)
|
|
3418
|
+
},
|
|
3419
|
+
chipIcon: {
|
|
3420
|
+
alignItems: "center",
|
|
3421
|
+
justifyContent: "center"
|
|
3422
|
+
},
|
|
3423
|
+
chipLabel: {
|
|
3424
|
+
fontFamily: "Poppins-Medium",
|
|
3425
|
+
fontSize: ms(13)
|
|
3426
|
+
},
|
|
3427
|
+
chipBadge: {
|
|
3428
|
+
minWidth: 16,
|
|
3429
|
+
height: 16,
|
|
3430
|
+
borderRadius: 9999,
|
|
3431
|
+
paddingHorizontal: 3,
|
|
3432
|
+
alignItems: "center",
|
|
3433
|
+
justifyContent: "center"
|
|
3434
|
+
},
|
|
3435
|
+
chipBadgeText: {
|
|
3436
|
+
fontFamily: "Poppins-Bold",
|
|
3437
|
+
fontSize: ms(9),
|
|
3438
|
+
lineHeight: 14
|
|
3439
|
+
}
|
|
3440
|
+
});
|
|
3441
|
+
var nativeDriver14 = Platform.OS !== "web";
|
|
3442
|
+
function Pressable2({
|
|
3443
|
+
children,
|
|
3444
|
+
onPress,
|
|
3445
|
+
pressScale = 0.98,
|
|
3446
|
+
bounciness = 4,
|
|
3447
|
+
haptics = true,
|
|
3448
|
+
style,
|
|
3449
|
+
disabled,
|
|
3450
|
+
hoverScale = 1.02,
|
|
3451
|
+
...touchableProps
|
|
3452
|
+
}) {
|
|
3453
|
+
const scale2 = useRef(new Animated.Value(1)).current;
|
|
3454
|
+
const { hovered, hoverHandlers } = useHover();
|
|
3455
|
+
const handlePressIn = () => {
|
|
3456
|
+
if (disabled) return;
|
|
3457
|
+
Animated.spring(scale2, {
|
|
3458
|
+
toValue: pressScale,
|
|
3459
|
+
useNativeDriver: nativeDriver14,
|
|
3460
|
+
speed: 40,
|
|
3461
|
+
bounciness: 0
|
|
3462
|
+
}).start();
|
|
3463
|
+
};
|
|
3464
|
+
const handlePressOut = () => {
|
|
3465
|
+
if (disabled) return;
|
|
3466
|
+
Animated.spring(scale2, {
|
|
3467
|
+
toValue: 1,
|
|
3468
|
+
useNativeDriver: nativeDriver14,
|
|
3469
|
+
speed: 40,
|
|
3470
|
+
bounciness
|
|
3471
|
+
}).start();
|
|
3472
|
+
};
|
|
3473
|
+
const handlePress = () => {
|
|
3474
|
+
if (disabled || !onPress) return;
|
|
3475
|
+
if (haptics) impactLight();
|
|
3476
|
+
onPress();
|
|
3477
|
+
};
|
|
3478
|
+
const hoverScaleValue = hovered && hoverScale !== 1 ? hoverScale : 1;
|
|
3479
|
+
return /* @__PURE__ */ React25.createElement(
|
|
3480
|
+
Animated.View,
|
|
3481
|
+
{
|
|
3482
|
+
style: [
|
|
3483
|
+
{ transform: [{ scale: Animated.multiply(scale2, hoverScaleValue) }] },
|
|
3484
|
+
style
|
|
3485
|
+
],
|
|
3486
|
+
...Platform.OS === "web" ? hoverHandlers : {}
|
|
3487
|
+
},
|
|
3488
|
+
/* @__PURE__ */ React25.createElement(
|
|
3489
|
+
TouchableOpacity,
|
|
3490
|
+
{
|
|
3491
|
+
onPress: handlePress,
|
|
3492
|
+
onPressIn: handlePressIn,
|
|
3493
|
+
onPressOut: handlePressOut,
|
|
3494
|
+
activeOpacity: 1,
|
|
3495
|
+
disabled,
|
|
3496
|
+
touchSoundDisabled: true,
|
|
3497
|
+
...touchableProps
|
|
3498
|
+
},
|
|
3499
|
+
children
|
|
3500
|
+
)
|
|
3501
|
+
);
|
|
3502
|
+
}
|
|
2786
3503
|
|
|
2787
|
-
export { Accordion, AlertBanner, Avatar, BREAKPOINTS, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Chip, ChipGroup, ConfirmDialog, CurrencyDisplay, CurrencyInput, CurrencyInput as CurrencyInputLarge, EmptyState, ICON_SIZES, Icon, IconButton, Input, LabelValue, ListItem, MonthPicker, Progress, RADIUS, RadioGroup, SHADOWS, SPACING, Select, Separator, Sheet, Skeleton, Slider, Spinner, Switch, Tabs, TabsContent,
|
|
3504
|
+
export { Accordion, AlertBanner, Avatar, BREAKPOINTS, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CategoryStrip, Checkbox, Chip, ChipGroup, ConfirmDialog, CurrencyDisplay, CurrencyInput, CurrencyInput as CurrencyInputLarge, EmptyState, ICON_SIZES, Icon, IconButton, Input, LabelValue, ListItem, MediaCard, MonthPicker, Pressable2 as Pressable, Progress, RADIUS, RadioGroup, SHADOWS, SPACING, Select, Separator, Sheet, Skeleton, Slider, Spinner, Switch, TYPOGRAPHY, Tabs, TabsContent, Text3 as Text, Textarea, ThemeProvider, ToastProvider, Toggle, defaultDark, defaultLight, deriveColors, renderIcon, useTheme, useToast };
|