@retray-dev/ui-kit 4.0.0 → 5.2.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 +1806 -663
- package/README.md +14 -10
- package/dist/index.d.mts +274 -85
- package/dist/index.d.ts +274 -85
- package/dist/index.js +1048 -321
- package/dist/index.mjs +1046 -324
- 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 +9 -9
- 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 +35 -15
- 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.js
CHANGED
|
@@ -33,61 +33,125 @@ var RNSlider__default = /*#__PURE__*/_interopDefault(RNSlider);
|
|
|
33
33
|
|
|
34
34
|
// src/theme/ThemeProvider.tsx
|
|
35
35
|
|
|
36
|
+
// src/theme/colorUtils.ts
|
|
37
|
+
function hexToRgb(hex) {
|
|
38
|
+
const clean = hex.replace("#", "");
|
|
39
|
+
const full = clean.length === 3 ? clean.split("").map((c) => c + c).join("") : clean;
|
|
40
|
+
if (full.length !== 6) return null;
|
|
41
|
+
return {
|
|
42
|
+
r: parseInt(full.slice(0, 2), 16),
|
|
43
|
+
g: parseInt(full.slice(2, 4), 16),
|
|
44
|
+
b: parseInt(full.slice(4, 6), 16)
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function componentToHex(c) {
|
|
48
|
+
return Math.round(Math.max(0, Math.min(255, c))).toString(16).padStart(2, "0");
|
|
49
|
+
}
|
|
50
|
+
function rgbToHex(r, g, b) {
|
|
51
|
+
return `#${componentToHex(r)}${componentToHex(g)}${componentToHex(b)}`;
|
|
52
|
+
}
|
|
53
|
+
function withAlphaOnWhite(hex, alpha) {
|
|
54
|
+
const rgb = hexToRgb(hex);
|
|
55
|
+
if (!rgb) return hex;
|
|
56
|
+
const r = rgb.r * alpha + 255 * (1 - alpha);
|
|
57
|
+
const g = rgb.g * alpha + 255 * (1 - alpha);
|
|
58
|
+
const b = rgb.b * alpha + 255 * (1 - alpha);
|
|
59
|
+
return rgbToHex(r, g, b);
|
|
60
|
+
}
|
|
61
|
+
function withAlphaOnDark(hex, alpha, bgHex = "#0f0f0f") {
|
|
62
|
+
const rgb = hexToRgb(hex);
|
|
63
|
+
const bg = hexToRgb(bgHex);
|
|
64
|
+
if (!rgb || !bg) return hex;
|
|
65
|
+
const r = rgb.r * alpha + bg.r * (1 - alpha);
|
|
66
|
+
const g = rgb.g * alpha + bg.g * (1 - alpha);
|
|
67
|
+
const b = rgb.b * alpha + bg.b * (1 - alpha);
|
|
68
|
+
return rgbToHex(r, g, b);
|
|
69
|
+
}
|
|
70
|
+
function mixWithBackground(fgHex, bgHex, opacity) {
|
|
71
|
+
const fg = hexToRgb(fgHex);
|
|
72
|
+
const bg = hexToRgb(bgHex);
|
|
73
|
+
if (!fg || !bg) return fgHex;
|
|
74
|
+
const r = fg.r * opacity + bg.r * (1 - opacity);
|
|
75
|
+
const g = fg.g * opacity + bg.g * (1 - opacity);
|
|
76
|
+
const b = fg.b * opacity + bg.b * (1 - opacity);
|
|
77
|
+
return rgbToHex(r, g, b);
|
|
78
|
+
}
|
|
79
|
+
function lighten(hex, amount) {
|
|
80
|
+
return withAlphaOnWhite(hex, 1 - amount);
|
|
81
|
+
}
|
|
82
|
+
function darken(hex, amount) {
|
|
83
|
+
const rgb = hexToRgb(hex);
|
|
84
|
+
if (!rgb) return hex;
|
|
85
|
+
return rgbToHex(rgb.r * (1 - amount), rgb.g * (1 - amount), rgb.b * (1 - amount));
|
|
86
|
+
}
|
|
87
|
+
|
|
36
88
|
// src/theme/colors.ts
|
|
37
89
|
var defaultLight = {
|
|
38
90
|
background: "#ffffff",
|
|
39
|
-
foreground: "#
|
|
91
|
+
foreground: "#222222",
|
|
92
|
+
// Airbnb ink — deep near-black, never pure black
|
|
40
93
|
card: "#ffffff",
|
|
41
|
-
cardForeground: "#171717",
|
|
42
94
|
primary: "#1a1a1a",
|
|
95
|
+
// Near-black primary — clean, premium default
|
|
43
96
|
primaryForeground: "#ffffff",
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
mutedForeground: "#a2a2a2",
|
|
48
|
-
accent: "#e4e4e4",
|
|
49
|
-
accentForeground: "#171717",
|
|
50
|
-
destructive: "#ef4444",
|
|
97
|
+
border: "#dddddd",
|
|
98
|
+
// Airbnb hairline — light, airy
|
|
99
|
+
destructive: "#e53935",
|
|
51
100
|
destructiveForeground: "#ffffff",
|
|
52
|
-
border: "#e5e5e5",
|
|
53
|
-
input: "#e5e5e5",
|
|
54
|
-
ring: "#1a1a1a",
|
|
55
101
|
success: "#1a7a45",
|
|
56
102
|
successForeground: "#ffffff",
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
successTint: "#f0fdf4",
|
|
60
|
-
successBorder: "#bbf7d0"
|
|
103
|
+
warning: "#e67e00",
|
|
104
|
+
warningForeground: "#ffffff"
|
|
61
105
|
};
|
|
62
106
|
var defaultDark = {
|
|
63
107
|
background: "#0f0f0f",
|
|
64
108
|
foreground: "#fafafa",
|
|
65
109
|
card: "#1c1c1c",
|
|
66
|
-
cardForeground: "#fafafa",
|
|
67
110
|
primary: "#fafafa",
|
|
68
111
|
primaryForeground: "#0f0f0f",
|
|
69
|
-
secondary: "#272727",
|
|
70
|
-
secondaryForeground: "#fafafa",
|
|
71
|
-
muted: "#272727",
|
|
72
|
-
mutedForeground: "#9a9a9a",
|
|
73
|
-
accent: "#2e2e2e",
|
|
74
|
-
accentForeground: "#fafafa",
|
|
75
|
-
destructive: "#dc2626",
|
|
76
|
-
destructiveForeground: "#ffffff",
|
|
77
112
|
border: "#303030",
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
success: "#
|
|
113
|
+
destructive: "#ef5350",
|
|
114
|
+
destructiveForeground: "#ffffff",
|
|
115
|
+
success: "#2e7d52",
|
|
81
116
|
successForeground: "#ffffff",
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
successTint: "#052e16",
|
|
85
|
-
successBorder: "#166534"
|
|
117
|
+
warning: "#f57c00",
|
|
118
|
+
warningForeground: "#ffffff"
|
|
86
119
|
};
|
|
120
|
+
function deriveColors(t, scheme) {
|
|
121
|
+
const dark = scheme === "dark";
|
|
122
|
+
const bg = t.background;
|
|
123
|
+
const foregroundSubtle = mixWithBackground(t.foreground, bg, 0.55);
|
|
124
|
+
const foregroundMuted = mixWithBackground(t.foreground, bg, 0.38);
|
|
125
|
+
const surface = dark ? lighten(bg, -0.06) : darken(bg, 0.04);
|
|
126
|
+
const surfaceStrong = dark ? lighten(bg, -0.12) : darken(bg, 0.08);
|
|
127
|
+
const destructiveTint = dark ? withAlphaOnDark(t.destructive, 0.15, bg) : withAlphaOnWhite(t.destructive, 0.08);
|
|
128
|
+
const destructiveBorder = dark ? withAlphaOnDark(t.destructive, 0.45, bg) : withAlphaOnWhite(t.destructive, 0.3);
|
|
129
|
+
const successTint = dark ? withAlphaOnDark(t.success, 0.15, bg) : withAlphaOnWhite(t.success, 0.08);
|
|
130
|
+
const successBorder = dark ? withAlphaOnDark(t.success, 0.45, bg) : withAlphaOnWhite(t.success, 0.3);
|
|
131
|
+
const warningTint = dark ? withAlphaOnDark(t.warning, 0.15, bg) : withAlphaOnWhite(t.warning, 0.08);
|
|
132
|
+
const warningBorder = dark ? withAlphaOnDark(t.warning, 0.45, bg) : withAlphaOnWhite(t.warning, 0.3);
|
|
133
|
+
return {
|
|
134
|
+
...t,
|
|
135
|
+
foregroundSubtle,
|
|
136
|
+
foregroundMuted,
|
|
137
|
+
surface,
|
|
138
|
+
surfaceStrong,
|
|
139
|
+
destructiveTint,
|
|
140
|
+
destructiveBorder,
|
|
141
|
+
successTint,
|
|
142
|
+
successBorder,
|
|
143
|
+
warningTint,
|
|
144
|
+
warningBorder,
|
|
145
|
+
ring: t.primary,
|
|
146
|
+
// focus ring always = primary
|
|
147
|
+
input: t.border
|
|
148
|
+
// input border always = border
|
|
149
|
+
};
|
|
150
|
+
}
|
|
87
151
|
|
|
88
152
|
// src/theme/ThemeProvider.tsx
|
|
89
153
|
var ThemeContext = React25.createContext({
|
|
90
|
-
colors: defaultLight,
|
|
154
|
+
colors: deriveColors(defaultLight, "light"),
|
|
91
155
|
colorScheme: "light"
|
|
92
156
|
});
|
|
93
157
|
function ThemeProvider({ children, theme, colorScheme = "system" }) {
|
|
@@ -96,7 +160,8 @@ function ThemeProvider({ children, theme, colorScheme = "system" }) {
|
|
|
96
160
|
const colors = React25.useMemo(() => {
|
|
97
161
|
const base = resolvedScheme === "dark" ? defaultDark : defaultLight;
|
|
98
162
|
const override = resolvedScheme === "dark" ? theme?.dark : theme?.light;
|
|
99
|
-
|
|
163
|
+
const merged = override ? { ...base, ...override } : base;
|
|
164
|
+
return deriveColors(merged, resolvedScheme);
|
|
100
165
|
}, [resolvedScheme, theme]);
|
|
101
166
|
return /* @__PURE__ */ React25__default.default.createElement(ThemeContext.Provider, { value: { colors, colorScheme: resolvedScheme } }, children);
|
|
102
167
|
}
|
|
@@ -176,17 +241,194 @@ function renderIcon(name, size, color) {
|
|
|
176
241
|
return React25__default.default.createElement(Icon, { name, size, color });
|
|
177
242
|
}
|
|
178
243
|
|
|
244
|
+
// src/tokens.ts
|
|
245
|
+
var SPACING = {
|
|
246
|
+
xxs: 2,
|
|
247
|
+
xs: 4,
|
|
248
|
+
sm: 8,
|
|
249
|
+
md: 12,
|
|
250
|
+
base: 16,
|
|
251
|
+
lg: 24,
|
|
252
|
+
xl: 32,
|
|
253
|
+
xxl: 48,
|
|
254
|
+
section: 64
|
|
255
|
+
};
|
|
256
|
+
var ICON_SIZES = {
|
|
257
|
+
sm: 14,
|
|
258
|
+
md: 18,
|
|
259
|
+
lg: 22,
|
|
260
|
+
xl: 28,
|
|
261
|
+
"2xl": 32
|
|
262
|
+
};
|
|
263
|
+
var RADIUS = {
|
|
264
|
+
none: 0,
|
|
265
|
+
xs: 4,
|
|
266
|
+
sm: 8,
|
|
267
|
+
md: 14,
|
|
268
|
+
lg: 20,
|
|
269
|
+
xl: 32,
|
|
270
|
+
full: 9999
|
|
271
|
+
};
|
|
272
|
+
var SHADOWS = {
|
|
273
|
+
sm: {
|
|
274
|
+
shadowColor: "#000",
|
|
275
|
+
shadowOffset: { width: 0, height: 1 },
|
|
276
|
+
shadowOpacity: 0.06,
|
|
277
|
+
shadowRadius: 4,
|
|
278
|
+
elevation: 2
|
|
279
|
+
},
|
|
280
|
+
md: {
|
|
281
|
+
shadowColor: "#000",
|
|
282
|
+
shadowOffset: { width: 0, height: 2 },
|
|
283
|
+
shadowOpacity: 0.1,
|
|
284
|
+
shadowRadius: 8,
|
|
285
|
+
elevation: 5
|
|
286
|
+
},
|
|
287
|
+
lg: {
|
|
288
|
+
shadowColor: "#000",
|
|
289
|
+
shadowOffset: { width: 0, height: 6 },
|
|
290
|
+
shadowOpacity: 0.16,
|
|
291
|
+
shadowRadius: 16,
|
|
292
|
+
elevation: 10
|
|
293
|
+
},
|
|
294
|
+
xl: {
|
|
295
|
+
shadowColor: "#000",
|
|
296
|
+
shadowOffset: { width: 0, height: 12 },
|
|
297
|
+
shadowOpacity: 0.24,
|
|
298
|
+
shadowRadius: 24,
|
|
299
|
+
elevation: 18
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
var BREAKPOINTS = {
|
|
303
|
+
wide: 700
|
|
304
|
+
};
|
|
305
|
+
var TYPOGRAPHY = {
|
|
306
|
+
"display-hero": {
|
|
307
|
+
fontFamily: "Poppins-Bold",
|
|
308
|
+
fontSize: 64,
|
|
309
|
+
fontWeight: "700",
|
|
310
|
+
lineHeight: 70,
|
|
311
|
+
letterSpacing: -1
|
|
312
|
+
},
|
|
313
|
+
"display-xl": {
|
|
314
|
+
fontFamily: "Poppins-Bold",
|
|
315
|
+
fontSize: 28,
|
|
316
|
+
fontWeight: "700",
|
|
317
|
+
lineHeight: 40,
|
|
318
|
+
letterSpacing: 0
|
|
319
|
+
},
|
|
320
|
+
"display-lg": {
|
|
321
|
+
fontFamily: "Poppins-Medium",
|
|
322
|
+
fontSize: 22,
|
|
323
|
+
fontWeight: "500",
|
|
324
|
+
lineHeight: 26,
|
|
325
|
+
letterSpacing: -0.44
|
|
326
|
+
},
|
|
327
|
+
"display-md": {
|
|
328
|
+
fontFamily: "Poppins-Bold",
|
|
329
|
+
fontSize: 21,
|
|
330
|
+
fontWeight: "700",
|
|
331
|
+
lineHeight: 30,
|
|
332
|
+
letterSpacing: 0
|
|
333
|
+
},
|
|
334
|
+
"display-sm": {
|
|
335
|
+
fontFamily: "Poppins-SemiBold",
|
|
336
|
+
fontSize: 20,
|
|
337
|
+
fontWeight: "600",
|
|
338
|
+
lineHeight: 24,
|
|
339
|
+
letterSpacing: -0.18
|
|
340
|
+
},
|
|
341
|
+
"title-md": {
|
|
342
|
+
fontFamily: "Poppins-SemiBold",
|
|
343
|
+
fontSize: 16,
|
|
344
|
+
fontWeight: "600",
|
|
345
|
+
lineHeight: 20,
|
|
346
|
+
letterSpacing: 0
|
|
347
|
+
},
|
|
348
|
+
"title-sm": {
|
|
349
|
+
fontFamily: "Poppins-Medium",
|
|
350
|
+
fontSize: 16,
|
|
351
|
+
fontWeight: "500",
|
|
352
|
+
lineHeight: 20,
|
|
353
|
+
letterSpacing: 0
|
|
354
|
+
},
|
|
355
|
+
"body-md": {
|
|
356
|
+
fontFamily: "Poppins-Regular",
|
|
357
|
+
fontSize: 16,
|
|
358
|
+
fontWeight: "400",
|
|
359
|
+
lineHeight: 24,
|
|
360
|
+
letterSpacing: 0
|
|
361
|
+
},
|
|
362
|
+
"body-sm": {
|
|
363
|
+
fontFamily: "Poppins-Regular",
|
|
364
|
+
fontSize: 14,
|
|
365
|
+
fontWeight: "400",
|
|
366
|
+
lineHeight: 20,
|
|
367
|
+
letterSpacing: 0
|
|
368
|
+
},
|
|
369
|
+
caption: {
|
|
370
|
+
fontFamily: "Poppins-Medium",
|
|
371
|
+
fontSize: 14,
|
|
372
|
+
fontWeight: "500",
|
|
373
|
+
lineHeight: 18,
|
|
374
|
+
letterSpacing: 0
|
|
375
|
+
},
|
|
376
|
+
"caption-sm": {
|
|
377
|
+
fontFamily: "Poppins-Regular",
|
|
378
|
+
fontSize: 13,
|
|
379
|
+
fontWeight: "400",
|
|
380
|
+
lineHeight: 16,
|
|
381
|
+
letterSpacing: 0
|
|
382
|
+
},
|
|
383
|
+
"badge-text": {
|
|
384
|
+
fontFamily: "Poppins-SemiBold",
|
|
385
|
+
fontSize: 11,
|
|
386
|
+
fontWeight: "600",
|
|
387
|
+
lineHeight: 13,
|
|
388
|
+
letterSpacing: 0
|
|
389
|
+
},
|
|
390
|
+
"micro-label": {
|
|
391
|
+
fontFamily: "Poppins-Bold",
|
|
392
|
+
fontSize: 12,
|
|
393
|
+
fontWeight: "700",
|
|
394
|
+
lineHeight: 16,
|
|
395
|
+
letterSpacing: 0
|
|
396
|
+
},
|
|
397
|
+
"uppercase-tag": {
|
|
398
|
+
fontFamily: "Poppins-Bold",
|
|
399
|
+
fontSize: 8,
|
|
400
|
+
fontWeight: "700",
|
|
401
|
+
lineHeight: 10,
|
|
402
|
+
letterSpacing: 0.32,
|
|
403
|
+
textTransform: "uppercase"
|
|
404
|
+
},
|
|
405
|
+
"button-lg": {
|
|
406
|
+
fontFamily: "Poppins-Medium",
|
|
407
|
+
fontSize: 16,
|
|
408
|
+
fontWeight: "500",
|
|
409
|
+
lineHeight: 20,
|
|
410
|
+
letterSpacing: 0
|
|
411
|
+
},
|
|
412
|
+
"button-sm": {
|
|
413
|
+
fontFamily: "Poppins-Medium",
|
|
414
|
+
fontSize: 14,
|
|
415
|
+
fontWeight: "500",
|
|
416
|
+
lineHeight: 18,
|
|
417
|
+
letterSpacing: 0
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
|
|
179
421
|
// src/components/Button/Button.tsx
|
|
180
422
|
var nativeDriver = reactNative.Platform.OS !== "web";
|
|
181
423
|
var containerSizeStyles = {
|
|
182
|
-
sm: { paddingHorizontal: s(
|
|
183
|
-
md: { paddingHorizontal: s(
|
|
184
|
-
lg: { paddingHorizontal: s(
|
|
424
|
+
sm: { paddingHorizontal: s(16), paddingVertical: vs(10), minHeight: 40 },
|
|
425
|
+
md: { paddingHorizontal: s(24), paddingVertical: vs(14), minHeight: 48 },
|
|
426
|
+
lg: { paddingHorizontal: s(28), paddingVertical: vs(16), minHeight: 56 }
|
|
185
427
|
};
|
|
186
428
|
var labelSizeStyles = {
|
|
187
|
-
sm: { fontSize: ms(
|
|
188
|
-
md: { fontSize: ms(
|
|
189
|
-
lg: { fontSize: ms(
|
|
429
|
+
sm: { ...TYPOGRAPHY["button-sm"], fontSize: ms(TYPOGRAPHY["button-sm"].fontSize) },
|
|
430
|
+
md: { ...TYPOGRAPHY["button-lg"], fontSize: ms(TYPOGRAPHY["button-lg"].fontSize) },
|
|
431
|
+
lg: { ...TYPOGRAPHY["button-lg"], fontSize: ms(TYPOGRAPHY["button-lg"].fontSize + 1) }
|
|
190
432
|
};
|
|
191
433
|
var iconSizeMap = { sm: 16, md: 18, lg: 20 };
|
|
192
434
|
function Button({
|
|
@@ -209,12 +451,7 @@ function Button({
|
|
|
209
451
|
const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
|
|
210
452
|
const handlePressIn = () => {
|
|
211
453
|
if (isDisabled) return;
|
|
212
|
-
reactNative.Animated.spring(scale2, {
|
|
213
|
-
toValue: 0.95,
|
|
214
|
-
useNativeDriver: nativeDriver,
|
|
215
|
-
speed: 40,
|
|
216
|
-
bounciness: 0
|
|
217
|
-
}).start();
|
|
454
|
+
reactNative.Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver, speed: 40, bounciness: 0 }).start();
|
|
218
455
|
};
|
|
219
456
|
const handlePressOut = () => {
|
|
220
457
|
reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver, speed: 40, bounciness: 4 }).start();
|
|
@@ -225,20 +462,18 @@ function Button({
|
|
|
225
462
|
};
|
|
226
463
|
const containerVariantStyle = {
|
|
227
464
|
primary: { backgroundColor: colors.primary },
|
|
228
|
-
secondary: { backgroundColor: colors.
|
|
229
|
-
|
|
230
|
-
ghost: { backgroundColor: "transparent" },
|
|
465
|
+
secondary: { backgroundColor: "transparent", borderWidth: 1.5, borderColor: colors.primary },
|
|
466
|
+
text: { backgroundColor: "transparent" },
|
|
231
467
|
destructive: { backgroundColor: colors.destructive }
|
|
232
468
|
}[variant];
|
|
233
469
|
const labelVariantStyle = {
|
|
234
470
|
primary: { color: colors.primaryForeground },
|
|
235
|
-
secondary: { color: colors.
|
|
236
|
-
|
|
237
|
-
ghost: { color: colors.foreground },
|
|
471
|
+
secondary: { color: colors.primary },
|
|
472
|
+
text: { color: colors.foreground },
|
|
238
473
|
destructive: { color: colors.destructiveForeground }
|
|
239
474
|
}[variant];
|
|
240
475
|
const effectiveIcon = iconName ? renderIcon(iconName, iconSizeMap[size], iconColor ?? labelVariantStyle.color) : typeof icon === "function" ? icon({ label, size, variant }) : icon;
|
|
241
|
-
const spinnerColor = variant === "destructive" ? colors.destructiveForeground : variant === "primary"
|
|
476
|
+
const spinnerColor = variant === "destructive" ? colors.destructiveForeground : variant === "primary" ? colors.primaryForeground : colors.foreground;
|
|
242
477
|
return /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: [fullWidth && styles.fullWidth, { transform: [{ scale: scale2 }] }] }, /* @__PURE__ */ React25__default.default.createElement(
|
|
243
478
|
reactNative.TouchableOpacity,
|
|
244
479
|
{
|
|
@@ -258,12 +493,20 @@ function Button({
|
|
|
258
493
|
onPressOut: handlePressOut,
|
|
259
494
|
...props
|
|
260
495
|
},
|
|
261
|
-
loading ? /* @__PURE__ */ React25__default.default.createElement(reactNative.ActivityIndicator, { size: "small", color: spinnerColor }) : /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, effectiveIcon && iconPosition === "left" && /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, effectiveIcon), /* @__PURE__ */ React25__default.default.createElement(
|
|
496
|
+
loading ? /* @__PURE__ */ React25__default.default.createElement(reactNative.ActivityIndicator, { size: "small", color: spinnerColor }) : /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, effectiveIcon && iconPosition === "left" && /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, effectiveIcon), /* @__PURE__ */ React25__default.default.createElement(
|
|
497
|
+
reactNative.Text,
|
|
498
|
+
{
|
|
499
|
+
style: [styles.label, labelVariantStyle, labelSizeStyles[size], effectiveIcon ? styles.labelWithIcon : void 0],
|
|
500
|
+
allowFontScaling: true
|
|
501
|
+
},
|
|
502
|
+
label
|
|
503
|
+
), effectiveIcon && iconPosition === "right" && /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, effectiveIcon))
|
|
262
504
|
));
|
|
263
505
|
}
|
|
264
506
|
var styles = reactNative.StyleSheet.create({
|
|
265
507
|
base: {
|
|
266
|
-
borderRadius:
|
|
508
|
+
borderRadius: RADIUS.xl,
|
|
509
|
+
// 32px — pill-shaped primary CTA (Airbnb spec)
|
|
267
510
|
alignItems: "center",
|
|
268
511
|
justifyContent: "center",
|
|
269
512
|
flexDirection: "row"
|
|
@@ -272,18 +515,18 @@ var styles = reactNative.StyleSheet.create({
|
|
|
272
515
|
width: "100%"
|
|
273
516
|
},
|
|
274
517
|
disabled: {
|
|
275
|
-
opacity: 0.
|
|
518
|
+
opacity: 0.45
|
|
276
519
|
},
|
|
277
520
|
label: {
|
|
278
|
-
fontFamily: "Poppins-
|
|
521
|
+
fontFamily: "Poppins-Medium"
|
|
279
522
|
},
|
|
280
523
|
labelWithIcon: {
|
|
281
|
-
marginHorizontal: s(
|
|
524
|
+
marginHorizontal: s(6)
|
|
282
525
|
}
|
|
283
526
|
});
|
|
284
527
|
var nativeDriver2 = reactNative.Platform.OS !== "web";
|
|
285
528
|
var sizeMap = {
|
|
286
|
-
sm: { container: s(
|
|
529
|
+
sm: { container: s(32), icon: 16 },
|
|
287
530
|
md: { container: s(44), icon: 20 },
|
|
288
531
|
lg: { container: s(52), icon: 24 }
|
|
289
532
|
};
|
|
@@ -294,6 +537,7 @@ function IconButton({
|
|
|
294
537
|
variant = "primary",
|
|
295
538
|
size = "md",
|
|
296
539
|
loading = false,
|
|
540
|
+
badge,
|
|
297
541
|
disabled,
|
|
298
542
|
style,
|
|
299
543
|
onPress,
|
|
@@ -304,20 +548,10 @@ function IconButton({
|
|
|
304
548
|
const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
|
|
305
549
|
const handlePressIn = () => {
|
|
306
550
|
if (isDisabled) return;
|
|
307
|
-
reactNative.Animated.spring(scale2, {
|
|
308
|
-
toValue: 0.95,
|
|
309
|
-
useNativeDriver: nativeDriver2,
|
|
310
|
-
speed: 40,
|
|
311
|
-
bounciness: 0
|
|
312
|
-
}).start();
|
|
551
|
+
reactNative.Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver2, speed: 40, bounciness: 0 }).start();
|
|
313
552
|
};
|
|
314
553
|
const handlePressOut = () => {
|
|
315
|
-
reactNative.Animated.spring(scale2, {
|
|
316
|
-
toValue: 1,
|
|
317
|
-
useNativeDriver: nativeDriver2,
|
|
318
|
-
speed: 40,
|
|
319
|
-
bounciness: 4
|
|
320
|
-
}).start();
|
|
554
|
+
reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver2, speed: 40, bounciness: 4 }).start();
|
|
321
555
|
};
|
|
322
556
|
const handlePress = (e) => {
|
|
323
557
|
impactLight();
|
|
@@ -325,22 +559,25 @@ function IconButton({
|
|
|
325
559
|
};
|
|
326
560
|
const containerVariantStyle = {
|
|
327
561
|
primary: { backgroundColor: colors.primary },
|
|
328
|
-
secondary: { backgroundColor: colors.
|
|
562
|
+
secondary: { backgroundColor: colors.surface },
|
|
329
563
|
outline: { backgroundColor: "transparent", borderWidth: 1.5, borderColor: colors.border },
|
|
330
|
-
|
|
564
|
+
text: { backgroundColor: "transparent" },
|
|
331
565
|
destructive: { backgroundColor: colors.destructive }
|
|
332
566
|
}[variant];
|
|
333
567
|
const defaultIconColor = {
|
|
334
568
|
primary: colors.primaryForeground,
|
|
335
|
-
secondary: colors.
|
|
569
|
+
secondary: colors.foreground,
|
|
336
570
|
outline: colors.foreground,
|
|
337
|
-
|
|
571
|
+
text: colors.foreground,
|
|
338
572
|
destructive: colors.destructiveForeground
|
|
339
573
|
}[variant];
|
|
340
|
-
const spinnerColor = variant === "destructive" ? colors.destructiveForeground : variant === "primary"
|
|
574
|
+
const spinnerColor = variant === "destructive" ? colors.destructiveForeground : variant === "primary" ? colors.primaryForeground : colors.foreground;
|
|
341
575
|
const { container: containerSize, icon: iconSize } = sizeMap[size];
|
|
342
576
|
const resolvedIcon = iconName ? renderIcon(iconName, iconSize, iconColor ?? defaultIconColor) : icon;
|
|
343
|
-
|
|
577
|
+
const showBadge = badge !== void 0 && badge !== false && badge !== 0;
|
|
578
|
+
const badgeCount = typeof badge === "number" ? Math.min(badge, 99) : null;
|
|
579
|
+
const showCount = typeof badge === "number" && badge > 0;
|
|
580
|
+
return /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: [styles2.wrapper, { transform: [{ scale: scale2 }] }] }, /* @__PURE__ */ React25__default.default.createElement(
|
|
344
581
|
reactNative.TouchableOpacity,
|
|
345
582
|
{
|
|
346
583
|
style: [
|
|
@@ -359,33 +596,93 @@ function IconButton({
|
|
|
359
596
|
...props
|
|
360
597
|
},
|
|
361
598
|
loading ? /* @__PURE__ */ React25__default.default.createElement(reactNative.ActivityIndicator, { size: "small", color: spinnerColor }) : resolvedIcon
|
|
362
|
-
)
|
|
599
|
+
), showBadge && /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [
|
|
600
|
+
styles2.badge,
|
|
601
|
+
{ backgroundColor: colors.primary },
|
|
602
|
+
showCount ? styles2.badgeCount : styles2.badgeDot
|
|
603
|
+
] }, showCount && /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles2.badgeText, { color: colors.primaryForeground }] }, badgeCount)));
|
|
363
604
|
}
|
|
364
605
|
var styles2 = reactNative.StyleSheet.create({
|
|
606
|
+
wrapper: {
|
|
607
|
+
alignSelf: "flex-start"
|
|
608
|
+
},
|
|
365
609
|
base: {
|
|
366
|
-
borderRadius:
|
|
610
|
+
borderRadius: 9999,
|
|
367
611
|
alignItems: "center",
|
|
368
612
|
justifyContent: "center"
|
|
369
613
|
},
|
|
370
614
|
disabled: {
|
|
371
|
-
opacity: 0.
|
|
615
|
+
opacity: 0.45
|
|
616
|
+
},
|
|
617
|
+
badge: {
|
|
618
|
+
position: "absolute",
|
|
619
|
+
top: -2,
|
|
620
|
+
right: -2,
|
|
621
|
+
alignItems: "center",
|
|
622
|
+
justifyContent: "center"
|
|
623
|
+
},
|
|
624
|
+
badgeDot: {
|
|
625
|
+
width: 8,
|
|
626
|
+
height: 8,
|
|
627
|
+
borderRadius: 9999
|
|
628
|
+
},
|
|
629
|
+
badgeCount: {
|
|
630
|
+
minWidth: 16,
|
|
631
|
+
height: 16,
|
|
632
|
+
borderRadius: 9999,
|
|
633
|
+
paddingHorizontal: 3
|
|
634
|
+
},
|
|
635
|
+
badgeText: {
|
|
636
|
+
fontFamily: "Poppins-Bold",
|
|
637
|
+
fontSize: ms(9),
|
|
638
|
+
lineHeight: 14
|
|
372
639
|
}
|
|
373
640
|
});
|
|
374
641
|
var variantStyles = {
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
642
|
+
"display-hero": { ...TYPOGRAPHY["display-hero"], fontSize: ms(TYPOGRAPHY["display-hero"].fontSize), lineHeight: mvs(TYPOGRAPHY["display-hero"].lineHeight) },
|
|
643
|
+
"display-xl": { ...TYPOGRAPHY["display-xl"], fontSize: ms(TYPOGRAPHY["display-xl"].fontSize), lineHeight: mvs(TYPOGRAPHY["display-xl"].lineHeight) },
|
|
644
|
+
"display-lg": { ...TYPOGRAPHY["display-lg"], fontSize: ms(TYPOGRAPHY["display-lg"].fontSize), lineHeight: mvs(TYPOGRAPHY["display-lg"].lineHeight) },
|
|
645
|
+
"display-md": { ...TYPOGRAPHY["display-md"], fontSize: ms(TYPOGRAPHY["display-md"].fontSize), lineHeight: mvs(TYPOGRAPHY["display-md"].lineHeight) },
|
|
646
|
+
"display-sm": { ...TYPOGRAPHY["display-sm"], fontSize: ms(TYPOGRAPHY["display-sm"].fontSize), lineHeight: mvs(TYPOGRAPHY["display-sm"].lineHeight) },
|
|
647
|
+
"title-md": { ...TYPOGRAPHY["title-md"], fontSize: ms(TYPOGRAPHY["title-md"].fontSize), lineHeight: mvs(TYPOGRAPHY["title-md"].lineHeight) },
|
|
648
|
+
"title-sm": { ...TYPOGRAPHY["title-sm"], fontSize: ms(TYPOGRAPHY["title-sm"].fontSize), lineHeight: mvs(TYPOGRAPHY["title-sm"].lineHeight) },
|
|
649
|
+
"body-md": { ...TYPOGRAPHY["body-md"], fontSize: ms(TYPOGRAPHY["body-md"].fontSize), lineHeight: mvs(TYPOGRAPHY["body-md"].lineHeight) },
|
|
650
|
+
"body-sm": { ...TYPOGRAPHY["body-sm"], fontSize: ms(TYPOGRAPHY["body-sm"].fontSize), lineHeight: mvs(TYPOGRAPHY["body-sm"].lineHeight) },
|
|
651
|
+
caption: { ...TYPOGRAPHY["caption"], fontSize: ms(TYPOGRAPHY["caption"].fontSize), lineHeight: mvs(TYPOGRAPHY["caption"].lineHeight) },
|
|
652
|
+
"caption-sm": { ...TYPOGRAPHY["caption-sm"], fontSize: ms(TYPOGRAPHY["caption-sm"].fontSize), lineHeight: mvs(TYPOGRAPHY["caption-sm"].lineHeight) },
|
|
653
|
+
"badge-text": { ...TYPOGRAPHY["badge-text"], fontSize: ms(TYPOGRAPHY["badge-text"].fontSize), lineHeight: mvs(TYPOGRAPHY["badge-text"].lineHeight) },
|
|
654
|
+
"micro-label": { ...TYPOGRAPHY["micro-label"], fontSize: ms(TYPOGRAPHY["micro-label"].fontSize), lineHeight: mvs(TYPOGRAPHY["micro-label"].lineHeight) },
|
|
655
|
+
"uppercase-tag": { ...TYPOGRAPHY["uppercase-tag"], fontSize: ms(TYPOGRAPHY["uppercase-tag"].fontSize), lineHeight: mvs(TYPOGRAPHY["uppercase-tag"].lineHeight) },
|
|
656
|
+
"button-lg": { ...TYPOGRAPHY["button-lg"], fontSize: ms(TYPOGRAPHY["button-lg"].fontSize), lineHeight: mvs(TYPOGRAPHY["button-lg"].lineHeight) },
|
|
657
|
+
"button-sm": { ...TYPOGRAPHY["button-sm"], fontSize: ms(TYPOGRAPHY["button-sm"].fontSize), lineHeight: mvs(TYPOGRAPHY["button-sm"].lineHeight) }
|
|
381
658
|
};
|
|
382
|
-
|
|
659
|
+
var defaultColorVariant = {
|
|
660
|
+
"display-hero": "foreground",
|
|
661
|
+
"display-xl": "foreground",
|
|
662
|
+
"display-lg": "foreground",
|
|
663
|
+
"display-md": "foreground",
|
|
664
|
+
"display-sm": "foreground",
|
|
665
|
+
"title-md": "foreground",
|
|
666
|
+
"title-sm": "foreground",
|
|
667
|
+
"body-md": "foregroundSubtle",
|
|
668
|
+
// running text — slightly softer
|
|
669
|
+
"body-sm": "foregroundSubtle",
|
|
670
|
+
caption: "foregroundMuted",
|
|
671
|
+
"caption-sm": "foregroundMuted",
|
|
672
|
+
"badge-text": "foreground",
|
|
673
|
+
"micro-label": "foreground",
|
|
674
|
+
"uppercase-tag": "foregroundMuted",
|
|
675
|
+
"button-lg": "foreground",
|
|
676
|
+
"button-sm": "foreground"
|
|
677
|
+
};
|
|
678
|
+
function Text3({ variant = "body-md", color, style, children, ...props }) {
|
|
383
679
|
const { colors } = useTheme();
|
|
384
|
-
const
|
|
680
|
+
const colorKey = defaultColorVariant[variant] ?? "foreground";
|
|
681
|
+
const resolvedColor = color ?? colors[colorKey];
|
|
385
682
|
return /* @__PURE__ */ React25__default.default.createElement(
|
|
386
683
|
reactNative.Text,
|
|
387
684
|
{
|
|
388
|
-
style: [variantStyles[variant], { color:
|
|
685
|
+
style: [variantStyles[variant], { color: resolvedColor }, style],
|
|
389
686
|
allowFontScaling: true,
|
|
390
687
|
...props
|
|
391
688
|
},
|
|
@@ -399,21 +696,21 @@ function Input({ label, error, hint, prefix, suffix, prefixStyle, suffixStyle, p
|
|
|
399
696
|
const [showPassword, setShowPassword] = React25.useState(false);
|
|
400
697
|
const isPassword = type === "password";
|
|
401
698
|
const effectiveSecure = isPassword ? !showPassword : secureTextEntry;
|
|
402
|
-
const effectivePrefix = prefixIcon ? renderIcon(prefixIcon, 20, prefixIconColor ?? colors.
|
|
403
|
-
const effectiveSuffix = isPassword && !suffix && !suffixIcon ? /* @__PURE__ */ React25__default.default.createElement(reactNative.TouchableOpacity, { onPress: () => setShowPassword(!showPassword), style: styles3.passwordToggle, activeOpacity: 0.6 }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.AntDesign, { name: showPassword ? "eye" : "eye-invisible", size: 20, color: colors.
|
|
699
|
+
const effectivePrefix = prefixIcon ? renderIcon(prefixIcon, 20, prefixIconColor ?? colors.foregroundMuted) : prefix;
|
|
700
|
+
const effectiveSuffix = isPassword && !suffix && !suffixIcon ? /* @__PURE__ */ React25__default.default.createElement(reactNative.TouchableOpacity, { onPress: () => setShowPassword(!showPassword), style: styles3.passwordToggle, activeOpacity: 0.6 }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.AntDesign, { name: showPassword ? "eye" : "eye-invisible", size: 20, color: colors.foregroundMuted })) : suffixIcon ? renderIcon(suffixIcon, 20, suffixIconColor ?? colors.foregroundMuted) : suffix;
|
|
404
701
|
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles3.container, containerStyle] }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles3.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React25__default.default.createElement(
|
|
405
702
|
reactNative.View,
|
|
406
703
|
{
|
|
407
704
|
style: [
|
|
408
705
|
styles3.inputWrapper,
|
|
409
706
|
{
|
|
410
|
-
borderColor: error ? colors.destructive : focused ? colors.
|
|
707
|
+
borderColor: error ? colors.destructive : focused ? colors.primary : colors.border,
|
|
411
708
|
backgroundColor: colors.background
|
|
412
709
|
},
|
|
413
710
|
inputWrapperStyle
|
|
414
711
|
]
|
|
415
712
|
},
|
|
416
|
-
effectivePrefix ? typeof effectivePrefix === "string" ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles3.prefixText, { color: colors.
|
|
713
|
+
effectivePrefix ? typeof effectivePrefix === "string" ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles3.prefixText, { color: colors.foregroundMuted }, prefixStyle], allowFontScaling: true }, effectivePrefix) : /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles3.prefixContainer }, effectivePrefix) : null,
|
|
417
714
|
/* @__PURE__ */ React25__default.default.createElement(
|
|
418
715
|
reactNative.TextInput,
|
|
419
716
|
{
|
|
@@ -433,14 +730,14 @@ function Input({ label, error, hint, prefix, suffix, prefixStyle, suffixStyle, p
|
|
|
433
730
|
setFocused(false);
|
|
434
731
|
onBlur?.(e);
|
|
435
732
|
},
|
|
436
|
-
placeholderTextColor: colors.
|
|
733
|
+
placeholderTextColor: colors.foregroundMuted,
|
|
437
734
|
allowFontScaling: true,
|
|
438
735
|
secureTextEntry: effectiveSecure,
|
|
439
736
|
...props
|
|
440
737
|
}
|
|
441
738
|
),
|
|
442
|
-
effectiveSuffix ? typeof effectiveSuffix === "string" ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles3.suffixText, { color: colors.
|
|
443
|
-
), error ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles3.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles3.helperText, { color: colors.
|
|
739
|
+
effectiveSuffix ? typeof effectiveSuffix === "string" ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles3.suffixText, { color: colors.foregroundMuted }, suffixStyle], allowFontScaling: true }, effectiveSuffix) : /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles3.suffixContainer }, effectiveSuffix) : null
|
|
740
|
+
), error ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles3.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles3.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
|
|
444
741
|
}
|
|
445
742
|
var styles3 = reactNative.StyleSheet.create({
|
|
446
743
|
container: {
|
|
@@ -448,21 +745,24 @@ var styles3 = reactNative.StyleSheet.create({
|
|
|
448
745
|
},
|
|
449
746
|
label: {
|
|
450
747
|
fontFamily: "Poppins-Medium",
|
|
451
|
-
fontSize: ms(
|
|
748
|
+
fontSize: ms(14)
|
|
749
|
+
// caption size for input labels
|
|
452
750
|
},
|
|
453
751
|
inputWrapper: {
|
|
454
752
|
flexDirection: "row",
|
|
455
753
|
alignItems: "center",
|
|
456
|
-
borderWidth:
|
|
457
|
-
borderRadius:
|
|
754
|
+
borderWidth: 2,
|
|
755
|
+
borderRadius: 8,
|
|
458
756
|
paddingHorizontal: s(14),
|
|
459
|
-
paddingVertical: vs(11)
|
|
757
|
+
paddingVertical: vs(11),
|
|
758
|
+
minHeight: 48
|
|
460
759
|
},
|
|
461
760
|
input: {
|
|
462
761
|
fontFamily: "Poppins-Regular",
|
|
463
762
|
flex: 1,
|
|
464
|
-
fontSize: ms(
|
|
465
|
-
paddingVertical:
|
|
763
|
+
fontSize: ms(16),
|
|
764
|
+
paddingVertical: vs(2),
|
|
765
|
+
includeFontPadding: false
|
|
466
766
|
},
|
|
467
767
|
prefixContainer: {
|
|
468
768
|
marginRight: s(8)
|
|
@@ -508,23 +808,25 @@ function Badge({ label, children, variant = "default", size = "md", icon, iconNa
|
|
|
508
808
|
const { colors } = useTheme();
|
|
509
809
|
const containerStyle = {
|
|
510
810
|
default: { backgroundColor: colors.primary },
|
|
511
|
-
secondary: { backgroundColor: colors.
|
|
811
|
+
secondary: { backgroundColor: colors.surface },
|
|
512
812
|
destructive: { backgroundColor: colors.destructive },
|
|
513
813
|
outline: { backgroundColor: "transparent", borderWidth: 1, borderColor: colors.border },
|
|
514
814
|
success: { backgroundColor: colors.success },
|
|
515
|
-
warning: { backgroundColor:
|
|
815
|
+
warning: { backgroundColor: colors.warning },
|
|
516
816
|
successOutline: { backgroundColor: colors.successTint, borderWidth: 1, borderColor: colors.successBorder },
|
|
517
|
-
destructiveOutline: { backgroundColor: colors.destructiveTint, borderWidth: 1, borderColor: colors.destructiveBorder }
|
|
817
|
+
destructiveOutline: { backgroundColor: colors.destructiveTint, borderWidth: 1, borderColor: colors.destructiveBorder },
|
|
818
|
+
warningOutline: { backgroundColor: colors.warningTint, borderWidth: 1, borderColor: colors.warningBorder }
|
|
518
819
|
}[variant];
|
|
519
820
|
const textColor = {
|
|
520
821
|
default: colors.primaryForeground,
|
|
521
|
-
secondary: colors.
|
|
822
|
+
secondary: colors.foreground,
|
|
522
823
|
destructive: colors.destructiveForeground,
|
|
523
824
|
outline: colors.foreground,
|
|
524
825
|
success: colors.successForeground,
|
|
525
|
-
warning:
|
|
826
|
+
warning: colors.warningForeground,
|
|
526
827
|
successOutline: colors.success,
|
|
527
|
-
destructiveOutline: colors.destructive
|
|
828
|
+
destructiveOutline: colors.destructive,
|
|
829
|
+
warningOutline: colors.warning
|
|
528
830
|
}[variant];
|
|
529
831
|
const effectiveIcon = iconName ? renderIcon(iconName, sizeIconSize[size], iconColor ?? textColor) : icon;
|
|
530
832
|
const content = children ?? label;
|
|
@@ -585,7 +887,7 @@ function Card({ children, variant = "elevated", onPress, style }) {
|
|
|
585
887
|
elevation: 0
|
|
586
888
|
},
|
|
587
889
|
filled: {
|
|
588
|
-
backgroundColor: colors.
|
|
890
|
+
backgroundColor: colors.surfaceStrong,
|
|
589
891
|
borderColor: colors.border,
|
|
590
892
|
shadowOpacity: 0,
|
|
591
893
|
elevation: 0
|
|
@@ -612,11 +914,11 @@ function CardHeader({ children, style }) {
|
|
|
612
914
|
}
|
|
613
915
|
function CardTitle({ children, style }) {
|
|
614
916
|
const { colors } = useTheme();
|
|
615
|
-
return /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles5.title, { color: colors.
|
|
917
|
+
return /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles5.title, { color: colors.foreground }, style], allowFontScaling: true }, children);
|
|
616
918
|
}
|
|
617
919
|
function CardDescription({ children, style }) {
|
|
618
920
|
const { colors } = useTheme();
|
|
619
|
-
return /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles5.description, { color: colors.
|
|
921
|
+
return /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles5.description, { color: colors.foregroundMuted }, style], allowFontScaling: true }, children);
|
|
620
922
|
}
|
|
621
923
|
function CardContent({ children, style }) {
|
|
622
924
|
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles5.content, style] }, children);
|
|
@@ -626,7 +928,8 @@ function CardFooter({ children, style }) {
|
|
|
626
928
|
}
|
|
627
929
|
var styles5 = reactNative.StyleSheet.create({
|
|
628
930
|
card: {
|
|
629
|
-
borderRadius:
|
|
931
|
+
borderRadius: 14,
|
|
932
|
+
// RADIUS.md — Airbnb property card spec
|
|
630
933
|
borderWidth: 1
|
|
631
934
|
},
|
|
632
935
|
header: {
|
|
@@ -695,7 +998,7 @@ function Spinner({ size = "md", color, label, ...props }) {
|
|
|
695
998
|
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles7.wrapper }, /* @__PURE__ */ React25__default.default.createElement(reactNative.ActivityIndicator, { size: sizeMap2[size], color: color ?? colors.primary, ...props }), /* @__PURE__ */ React25__default.default.createElement(
|
|
696
999
|
reactNative.Text,
|
|
697
1000
|
{
|
|
698
|
-
style: [styles7.label, { color: colors.
|
|
1001
|
+
style: [styles7.label, { color: colors.foregroundMuted, fontSize: labelFontSize[size] }],
|
|
699
1002
|
allowFontScaling: true
|
|
700
1003
|
},
|
|
701
1004
|
label
|
|
@@ -713,18 +1016,21 @@ var styles7 = reactNative.StyleSheet.create({
|
|
|
713
1016
|
lineHeight: mvs(18)
|
|
714
1017
|
}
|
|
715
1018
|
});
|
|
716
|
-
function Skeleton({
|
|
1019
|
+
function Skeleton({
|
|
1020
|
+
width = "100%",
|
|
1021
|
+
height = 16,
|
|
1022
|
+
borderRadius = 6,
|
|
1023
|
+
preset = "base",
|
|
1024
|
+
diameter = 40,
|
|
1025
|
+
style
|
|
1026
|
+
}) {
|
|
717
1027
|
const { colors, colorScheme } = useTheme();
|
|
718
1028
|
const shimmerAnim = React25.useRef(new reactNative.Animated.Value(0)).current;
|
|
719
1029
|
const [containerWidth, setContainerWidth] = React25.useState(300);
|
|
720
1030
|
const shimmerHighlight = colorScheme === "dark" ? "rgba(255,255,255,0.08)" : "rgba(255,255,255,0.7)";
|
|
721
1031
|
React25.useEffect(() => {
|
|
722
1032
|
const animation = reactNative.Animated.loop(
|
|
723
|
-
reactNative.Animated.timing(shimmerAnim, {
|
|
724
|
-
toValue: 1,
|
|
725
|
-
duration: 1200,
|
|
726
|
-
useNativeDriver: true
|
|
727
|
-
})
|
|
1033
|
+
reactNative.Animated.timing(shimmerAnim, { toValue: 1, duration: 1200, useNativeDriver: true })
|
|
728
1034
|
);
|
|
729
1035
|
animation.start();
|
|
730
1036
|
return () => animation.stop();
|
|
@@ -733,12 +1039,15 @@ function Skeleton({ width = "100%", height = 16, borderRadius = 6, style }) {
|
|
|
733
1039
|
inputRange: [0, 1],
|
|
734
1040
|
outputRange: [-containerWidth, containerWidth]
|
|
735
1041
|
});
|
|
1042
|
+
const resolvedWidth = preset === "circle" ? s(diameter) : preset === "text" ? "60%" : width;
|
|
1043
|
+
const resolvedHeight = preset === "circle" ? s(diameter) : preset === "text" ? 14 : height;
|
|
1044
|
+
const resolvedRadius = preset === "circle" ? 9999 : preset === "text" ? 4 : borderRadius;
|
|
736
1045
|
return /* @__PURE__ */ React25__default.default.createElement(
|
|
737
1046
|
reactNative.View,
|
|
738
1047
|
{
|
|
739
1048
|
style: [
|
|
740
1049
|
styles8.base,
|
|
741
|
-
{ width, height, borderRadius, backgroundColor: colors.
|
|
1050
|
+
{ width: resolvedWidth, height: resolvedHeight, borderRadius: resolvedRadius, backgroundColor: colors.surface },
|
|
742
1051
|
style
|
|
743
1052
|
],
|
|
744
1053
|
onLayout: (e) => setContainerWidth(e.nativeEvent.layout.width)
|
|
@@ -771,19 +1080,32 @@ var fontSizeMap = {
|
|
|
771
1080
|
lg: ms(22),
|
|
772
1081
|
xl: ms(28)
|
|
773
1082
|
};
|
|
774
|
-
|
|
1083
|
+
var statusSizeMap = {
|
|
1084
|
+
sm: 8,
|
|
1085
|
+
md: 10,
|
|
1086
|
+
lg: 13,
|
|
1087
|
+
xl: 16
|
|
1088
|
+
};
|
|
1089
|
+
function Avatar({ src, fallback, size = "md", status, style }) {
|
|
775
1090
|
const { colors } = useTheme();
|
|
776
1091
|
const [imageError, setImageError] = React25.useState(false);
|
|
777
1092
|
const dimension = sizeMap3[size];
|
|
778
1093
|
const showFallback = !src || imageError;
|
|
1094
|
+
const statusSize = statusSizeMap[size];
|
|
1095
|
+
const statusColor = {
|
|
1096
|
+
online: "#22c55e",
|
|
1097
|
+
offline: "transparent",
|
|
1098
|
+
busy: colors.destructive,
|
|
1099
|
+
away: colors.warning
|
|
1100
|
+
};
|
|
779
1101
|
const containerStyle = {
|
|
780
1102
|
width: dimension,
|
|
781
1103
|
height: dimension,
|
|
782
1104
|
borderRadius: dimension / 2,
|
|
783
|
-
backgroundColor: colors.
|
|
1105
|
+
backgroundColor: colors.surface,
|
|
784
1106
|
overflow: "hidden"
|
|
785
1107
|
};
|
|
786
|
-
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles9.
|
|
1108
|
+
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles9.wrapper, style] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles9.base, containerStyle] }, !showFallback ? /* @__PURE__ */ React25__default.default.createElement(
|
|
787
1109
|
reactNative.Image,
|
|
788
1110
|
{
|
|
789
1111
|
source: { uri: src },
|
|
@@ -793,64 +1115,86 @@ function Avatar({ src, fallback, size = "md", style }) {
|
|
|
793
1115
|
) : /* @__PURE__ */ React25__default.default.createElement(
|
|
794
1116
|
reactNative.Text,
|
|
795
1117
|
{
|
|
796
|
-
style: [styles9.fallback, { color: colors.
|
|
1118
|
+
style: [styles9.fallback, { color: colors.foregroundMuted, fontSize: fontSizeMap[size] }],
|
|
797
1119
|
allowFontScaling: true
|
|
798
1120
|
},
|
|
799
1121
|
fallback?.slice(0, 2).toUpperCase() ?? "?"
|
|
1122
|
+
)), status && /* @__PURE__ */ React25__default.default.createElement(
|
|
1123
|
+
reactNative.View,
|
|
1124
|
+
{
|
|
1125
|
+
style: [
|
|
1126
|
+
styles9.statusDot,
|
|
1127
|
+
{
|
|
1128
|
+
width: statusSize,
|
|
1129
|
+
height: statusSize,
|
|
1130
|
+
borderRadius: statusSize / 2,
|
|
1131
|
+
backgroundColor: statusColor[status],
|
|
1132
|
+
borderWidth: status === "offline" ? 2 : 1.5,
|
|
1133
|
+
borderColor: status === "offline" ? colors.border : colors.background
|
|
1134
|
+
}
|
|
1135
|
+
]
|
|
1136
|
+
}
|
|
800
1137
|
));
|
|
801
1138
|
}
|
|
802
1139
|
var styles9 = reactNative.StyleSheet.create({
|
|
1140
|
+
wrapper: {
|
|
1141
|
+
alignSelf: "flex-start",
|
|
1142
|
+
position: "relative"
|
|
1143
|
+
},
|
|
803
1144
|
base: {
|
|
804
1145
|
alignItems: "center",
|
|
805
1146
|
justifyContent: "center"
|
|
806
1147
|
},
|
|
807
1148
|
fallback: {
|
|
808
1149
|
fontFamily: "Poppins-Medium"
|
|
1150
|
+
},
|
|
1151
|
+
statusDot: {
|
|
1152
|
+
position: "absolute",
|
|
1153
|
+
bottom: 0,
|
|
1154
|
+
right: 0
|
|
809
1155
|
}
|
|
810
1156
|
});
|
|
811
1157
|
function AlertBanner({ title, description, variant = "default", icon, iconName, iconColor, style }) {
|
|
812
1158
|
const { colors } = useTheme();
|
|
813
|
-
const bgColor = variant === "destructive" ? colors.
|
|
814
|
-
const
|
|
815
|
-
const
|
|
816
|
-
const
|
|
817
|
-
const
|
|
818
|
-
|
|
1159
|
+
const bgColor = variant === "destructive" ? colors.destructiveTint : variant === "success" ? colors.successTint : variant === "warning" ? colors.warningTint : colors.card;
|
|
1160
|
+
const borderColor = variant === "destructive" ? colors.destructiveBorder : variant === "success" ? colors.successBorder : variant === "warning" ? colors.warningBorder : colors.border;
|
|
1161
|
+
const accentColor = variant === "destructive" ? colors.destructive : variant === "success" ? colors.success : variant === "warning" ? colors.warning : colors.primary;
|
|
1162
|
+
const titleColor = variant === "default" ? colors.foreground : accentColor;
|
|
1163
|
+
const descColor = variant === "default" ? colors.foregroundMuted : accentColor;
|
|
1164
|
+
const defaultIcon = variant === "success" ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.FontAwesome5, { name: "check-circle", size: 16, color: accentColor }) : variant === "destructive" ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.MaterialIcons, { name: "error-outline", size: 17, color: accentColor }) : variant === "warning" ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.MaterialIcons, { name: "warning-amber", size: 17, color: accentColor }) : /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "info-with-circle", size: 16, color: accentColor });
|
|
1165
|
+
const effectiveIcon = iconName ? renderIcon(iconName, 16, iconColor ?? accentColor) : icon ?? defaultIcon;
|
|
1166
|
+
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles10.container, { backgroundColor: bgColor, borderColor }, style] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles10.iconSlot }, effectiveIcon), /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles10.content }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles10.title, { color: titleColor }], allowFontScaling: true }, title), description ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles10.description, { color: descColor }], allowFontScaling: true }, description) : null));
|
|
819
1167
|
}
|
|
820
1168
|
var styles10 = reactNative.StyleSheet.create({
|
|
821
1169
|
container: {
|
|
822
|
-
borderWidth: 1,
|
|
823
|
-
borderRadius: ms(12),
|
|
824
|
-
paddingHorizontal: s(14),
|
|
825
|
-
paddingVertical: vs(12),
|
|
826
|
-
gap: vs(8),
|
|
827
|
-
shadowColor: "#000",
|
|
828
|
-
shadowOffset: { width: 0, height: 3 },
|
|
829
|
-
shadowOpacity: 0.1,
|
|
830
|
-
shadowRadius: 8,
|
|
831
|
-
elevation: 5
|
|
832
|
-
},
|
|
833
|
-
header: {
|
|
834
1170
|
flexDirection: "row",
|
|
835
|
-
alignItems: "
|
|
1171
|
+
alignItems: "flex-start",
|
|
1172
|
+
borderWidth: 0.5,
|
|
1173
|
+
borderRadius: 10,
|
|
1174
|
+
paddingHorizontal: s(12),
|
|
1175
|
+
paddingVertical: vs(10),
|
|
836
1176
|
gap: s(10)
|
|
837
1177
|
},
|
|
838
|
-
|
|
839
|
-
marginTop:
|
|
1178
|
+
iconSlot: {
|
|
1179
|
+
marginTop: vs(1)
|
|
1180
|
+
},
|
|
1181
|
+
content: {
|
|
1182
|
+
flex: 1,
|
|
1183
|
+
gap: vs(2)
|
|
840
1184
|
},
|
|
841
1185
|
title: {
|
|
842
|
-
fontFamily: "Poppins-
|
|
843
|
-
fontSize: ms(
|
|
844
|
-
lineHeight:
|
|
845
|
-
flex: 1
|
|
1186
|
+
fontFamily: "Poppins-Medium",
|
|
1187
|
+
fontSize: ms(13),
|
|
1188
|
+
lineHeight: ms(18)
|
|
846
1189
|
},
|
|
847
1190
|
description: {
|
|
848
1191
|
fontFamily: "Poppins-Regular",
|
|
849
|
-
fontSize: ms(
|
|
850
|
-
lineHeight:
|
|
1192
|
+
fontSize: ms(12),
|
|
1193
|
+
lineHeight: ms(17),
|
|
1194
|
+
opacity: 0.85
|
|
851
1195
|
}
|
|
852
1196
|
});
|
|
853
|
-
function Progress({ value = 0, max = 100, style }) {
|
|
1197
|
+
function Progress({ value = 0, max = 100, variant = "default", style }) {
|
|
854
1198
|
const { colors } = useTheme();
|
|
855
1199
|
const percent = Math.min(Math.max(value / max * 100, 0), 100);
|
|
856
1200
|
const [trackWidth, setTrackWidth] = React25.useState(0);
|
|
@@ -864,16 +1208,17 @@ function Progress({ value = 0, max = 100, style }) {
|
|
|
864
1208
|
bounciness: 0
|
|
865
1209
|
}).start();
|
|
866
1210
|
}, [percent, trackWidth]);
|
|
1211
|
+
const indicatorColor = variant === "success" ? colors.success : variant === "warning" ? colors.warning : variant === "destructive" ? colors.destructive : colors.primary;
|
|
867
1212
|
return /* @__PURE__ */ React25__default.default.createElement(
|
|
868
1213
|
reactNative.View,
|
|
869
1214
|
{
|
|
870
|
-
style: [styles11.track, { backgroundColor: colors.
|
|
1215
|
+
style: [styles11.track, { backgroundColor: colors.surface }, style],
|
|
871
1216
|
onLayout: (e) => setTrackWidth(e.nativeEvent.layout.width)
|
|
872
1217
|
},
|
|
873
1218
|
/* @__PURE__ */ React25__default.default.createElement(
|
|
874
1219
|
reactNative.Animated.View,
|
|
875
1220
|
{
|
|
876
|
-
style: [styles11.indicator, { width: animatedWidth, backgroundColor:
|
|
1221
|
+
style: [styles11.indicator, { width: animatedWidth, backgroundColor: indicatorColor }]
|
|
877
1222
|
}
|
|
878
1223
|
)
|
|
879
1224
|
);
|
|
@@ -881,19 +1226,19 @@ function Progress({ value = 0, max = 100, style }) {
|
|
|
881
1226
|
var styles11 = reactNative.StyleSheet.create({
|
|
882
1227
|
track: {
|
|
883
1228
|
height: vs(8),
|
|
884
|
-
borderRadius:
|
|
1229
|
+
borderRadius: 9999,
|
|
885
1230
|
overflow: "hidden",
|
|
886
1231
|
width: "100%"
|
|
887
1232
|
},
|
|
888
1233
|
indicator: {
|
|
889
1234
|
height: "100%",
|
|
890
|
-
borderRadius:
|
|
1235
|
+
borderRadius: 9999
|
|
891
1236
|
}
|
|
892
1237
|
});
|
|
893
1238
|
function EmptyState({ icon, iconName, iconColor, title, description, action, size = "default", style }) {
|
|
894
1239
|
const { colors } = useTheme();
|
|
895
1240
|
const isCompact = size === "compact";
|
|
896
|
-
const effectiveIcon = iconName ? renderIcon(iconName, isCompact ? 32 : 48, iconColor ?? colors.
|
|
1241
|
+
const effectiveIcon = iconName ? renderIcon(iconName, isCompact ? 32 : 48, iconColor ?? colors.foregroundMuted) : icon;
|
|
897
1242
|
return /* @__PURE__ */ React25__default.default.createElement(
|
|
898
1243
|
reactNative.View,
|
|
899
1244
|
{
|
|
@@ -910,7 +1255,7 @@ function EmptyState({ icon, iconName, iconColor, title, description, action, siz
|
|
|
910
1255
|
style: [
|
|
911
1256
|
styles12.iconWrapper,
|
|
912
1257
|
isCompact && styles12.iconWrapperCompact,
|
|
913
|
-
{ backgroundColor: colors.
|
|
1258
|
+
{ backgroundColor: colors.surface }
|
|
914
1259
|
]
|
|
915
1260
|
},
|
|
916
1261
|
effectiveIcon
|
|
@@ -922,7 +1267,7 @@ function EmptyState({ icon, iconName, iconColor, title, description, action, siz
|
|
|
922
1267
|
allowFontScaling: true
|
|
923
1268
|
},
|
|
924
1269
|
title
|
|
925
|
-
), description && !isCompact ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles12.description, { color: colors.
|
|
1270
|
+
), description && !isCompact ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles12.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null),
|
|
926
1271
|
action && !isCompact ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles12.action }, action) : null
|
|
927
1272
|
);
|
|
928
1273
|
}
|
|
@@ -941,16 +1286,16 @@ var styles12 = reactNative.StyleSheet.create({
|
|
|
941
1286
|
gap: vs(10)
|
|
942
1287
|
},
|
|
943
1288
|
iconWrapper: {
|
|
944
|
-
width: s(
|
|
945
|
-
height: s(
|
|
946
|
-
borderRadius: ms(
|
|
1289
|
+
width: s(80),
|
|
1290
|
+
height: s(80),
|
|
1291
|
+
borderRadius: ms(20),
|
|
947
1292
|
alignItems: "center",
|
|
948
1293
|
justifyContent: "center"
|
|
949
1294
|
},
|
|
950
1295
|
iconWrapperCompact: {
|
|
951
|
-
width: s(
|
|
952
|
-
height: s(
|
|
953
|
-
borderRadius: ms(
|
|
1296
|
+
width: s(56),
|
|
1297
|
+
height: s(56),
|
|
1298
|
+
borderRadius: ms(14)
|
|
954
1299
|
},
|
|
955
1300
|
textWrapper: {
|
|
956
1301
|
alignItems: "center",
|
|
@@ -1014,11 +1359,11 @@ function Textarea({
|
|
|
1014
1359
|
setFocused(false);
|
|
1015
1360
|
onBlur?.(e);
|
|
1016
1361
|
},
|
|
1017
|
-
placeholderTextColor: colors.
|
|
1362
|
+
placeholderTextColor: colors.foregroundMuted,
|
|
1018
1363
|
allowFontScaling: true,
|
|
1019
1364
|
...props
|
|
1020
1365
|
}
|
|
1021
|
-
), error ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles13.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles13.helperText, { color: colors.
|
|
1366
|
+
), error ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles13.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles13.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
|
|
1022
1367
|
}
|
|
1023
1368
|
var styles13 = reactNative.StyleSheet.create({
|
|
1024
1369
|
container: {
|
|
@@ -1030,11 +1375,12 @@ var styles13 = reactNative.StyleSheet.create({
|
|
|
1030
1375
|
},
|
|
1031
1376
|
input: {
|
|
1032
1377
|
fontFamily: "Poppins-Regular",
|
|
1033
|
-
borderWidth:
|
|
1378
|
+
borderWidth: 2,
|
|
1034
1379
|
borderRadius: ms(8),
|
|
1035
1380
|
paddingHorizontal: s(14),
|
|
1036
1381
|
paddingVertical: vs(11),
|
|
1037
|
-
fontSize: ms(15)
|
|
1382
|
+
fontSize: ms(15),
|
|
1383
|
+
includeFontPadding: false
|
|
1038
1384
|
},
|
|
1039
1385
|
helperText: {
|
|
1040
1386
|
fontFamily: "Poppins-Regular",
|
|
@@ -1051,6 +1397,30 @@ function Checkbox({
|
|
|
1051
1397
|
}) {
|
|
1052
1398
|
const { colors } = useTheme();
|
|
1053
1399
|
const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
|
|
1400
|
+
const bgOpacity = React25.useRef(new reactNative.Animated.Value(checked ? 1 : 0)).current;
|
|
1401
|
+
const checkOpacity = React25.useRef(new reactNative.Animated.Value(checked ? 1 : 0)).current;
|
|
1402
|
+
React25.useEffect(() => {
|
|
1403
|
+
reactNative.Animated.parallel([
|
|
1404
|
+
reactNative.Animated.timing(bgOpacity, {
|
|
1405
|
+
toValue: checked ? 1 : 0,
|
|
1406
|
+
duration: 150,
|
|
1407
|
+
useNativeDriver: false
|
|
1408
|
+
}),
|
|
1409
|
+
reactNative.Animated.timing(checkOpacity, {
|
|
1410
|
+
toValue: checked ? 1 : 0,
|
|
1411
|
+
duration: 120,
|
|
1412
|
+
useNativeDriver: false
|
|
1413
|
+
})
|
|
1414
|
+
]).start();
|
|
1415
|
+
}, [checked, bgOpacity, checkOpacity]);
|
|
1416
|
+
const borderColor = bgOpacity.interpolate({
|
|
1417
|
+
inputRange: [0, 1],
|
|
1418
|
+
outputRange: [colors.border, colors.primary]
|
|
1419
|
+
});
|
|
1420
|
+
const backgroundColor = bgOpacity.interpolate({
|
|
1421
|
+
inputRange: [0, 1],
|
|
1422
|
+
outputRange: ["transparent", colors.primary]
|
|
1423
|
+
});
|
|
1054
1424
|
const handlePressIn = () => {
|
|
1055
1425
|
if (disabled) return;
|
|
1056
1426
|
reactNative.Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver4, speed: 40, bounciness: 0 }).start();
|
|
@@ -1072,25 +1442,24 @@ function Checkbox({
|
|
|
1072
1442
|
activeOpacity: 1,
|
|
1073
1443
|
touchSoundDisabled: true
|
|
1074
1444
|
},
|
|
1075
|
-
/* @__PURE__ */ React25__default.default.createElement(
|
|
1445
|
+
/* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25__default.default.createElement(
|
|
1076
1446
|
reactNative.Animated.View,
|
|
1077
1447
|
{
|
|
1078
1448
|
style: [
|
|
1079
1449
|
styles14.box,
|
|
1080
1450
|
{
|
|
1081
|
-
borderColor
|
|
1082
|
-
backgroundColor
|
|
1083
|
-
opacity: disabled ? 0.45 : 1
|
|
1084
|
-
transform: [{ scale: scale2 }]
|
|
1451
|
+
borderColor,
|
|
1452
|
+
backgroundColor,
|
|
1453
|
+
opacity: disabled ? 0.45 : 1
|
|
1085
1454
|
}
|
|
1086
1455
|
]
|
|
1087
1456
|
},
|
|
1088
|
-
|
|
1089
|
-
),
|
|
1457
|
+
/* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: { opacity: checkOpacity } }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles14.checkmark, { borderColor: colors.primaryForeground }] }))
|
|
1458
|
+
)),
|
|
1090
1459
|
label ? /* @__PURE__ */ React25__default.default.createElement(
|
|
1091
1460
|
reactNative.Text,
|
|
1092
1461
|
{
|
|
1093
|
-
style: [styles14.label, { color: disabled ? colors.
|
|
1462
|
+
style: [styles14.label, { color: disabled ? colors.foregroundMuted : colors.foreground }],
|
|
1094
1463
|
allowFontScaling: true
|
|
1095
1464
|
},
|
|
1096
1465
|
label
|
|
@@ -1130,10 +1499,13 @@ var TRACK_HEIGHT = s(30);
|
|
|
1130
1499
|
var THUMB_SIZE = s(24);
|
|
1131
1500
|
var THUMB_OFFSET = s(3);
|
|
1132
1501
|
var THUMB_TRAVEL = TRACK_WIDTH - THUMB_SIZE - THUMB_OFFSET * 2;
|
|
1502
|
+
var ICON_SIZE = s(13);
|
|
1133
1503
|
function Switch({ checked = false, onCheckedChange, disabled, style }) {
|
|
1134
1504
|
const { colors } = useTheme();
|
|
1135
1505
|
const translateX = React25.useRef(new reactNative.Animated.Value(checked ? THUMB_TRAVEL : 0)).current;
|
|
1136
1506
|
const trackOpacity = React25.useRef(new reactNative.Animated.Value(checked ? 1 : 0)).current;
|
|
1507
|
+
const checkOpacity = React25.useRef(new reactNative.Animated.Value(checked ? 1 : 0)).current;
|
|
1508
|
+
const crossOpacity = React25.useRef(new reactNative.Animated.Value(checked ? 0 : 1)).current;
|
|
1137
1509
|
React25.useEffect(() => {
|
|
1138
1510
|
reactNative.Animated.parallel([
|
|
1139
1511
|
reactNative.Animated.spring(translateX, {
|
|
@@ -1145,12 +1517,22 @@ function Switch({ checked = false, onCheckedChange, disabled, style }) {
|
|
|
1145
1517
|
toValue: checked ? 1 : 0,
|
|
1146
1518
|
duration: 150,
|
|
1147
1519
|
useNativeDriver: false
|
|
1520
|
+
}),
|
|
1521
|
+
reactNative.Animated.timing(checkOpacity, {
|
|
1522
|
+
toValue: checked ? 1 : 0,
|
|
1523
|
+
duration: 120,
|
|
1524
|
+
useNativeDriver: true
|
|
1525
|
+
}),
|
|
1526
|
+
reactNative.Animated.timing(crossOpacity, {
|
|
1527
|
+
toValue: checked ? 0 : 1,
|
|
1528
|
+
duration: 120,
|
|
1529
|
+
useNativeDriver: true
|
|
1148
1530
|
})
|
|
1149
1531
|
]).start();
|
|
1150
|
-
}, [checked, translateX, trackOpacity]);
|
|
1532
|
+
}, [checked, translateX, trackOpacity, checkOpacity, crossOpacity]);
|
|
1151
1533
|
const trackColor = trackOpacity.interpolate({
|
|
1152
1534
|
inputRange: [0, 1],
|
|
1153
|
-
outputRange: [colors.
|
|
1535
|
+
outputRange: [colors.surface, colors.primary]
|
|
1154
1536
|
});
|
|
1155
1537
|
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [{ opacity: disabled ? 0.45 : 1 }, style] }, /* @__PURE__ */ React25__default.default.createElement(
|
|
1156
1538
|
reactNative.TouchableOpacity,
|
|
@@ -1171,7 +1553,9 @@ function Switch({ checked = false, onCheckedChange, disabled, style }) {
|
|
|
1171
1553
|
styles15.thumb,
|
|
1172
1554
|
{ backgroundColor: colors.primaryForeground, transform: [{ translateX }] }
|
|
1173
1555
|
]
|
|
1174
|
-
}
|
|
1556
|
+
},
|
|
1557
|
+
/* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: [styles15.iconWrapper, { opacity: checkOpacity }] }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "check", size: ICON_SIZE, color: colors.primary })),
|
|
1558
|
+
/* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: [styles15.iconWrapper, { opacity: crossOpacity }] }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "x", size: ICON_SIZE, color: colors.foregroundMuted }))
|
|
1175
1559
|
))
|
|
1176
1560
|
));
|
|
1177
1561
|
}
|
|
@@ -1195,7 +1579,12 @@ var styles15 = reactNative.StyleSheet.create({
|
|
|
1195
1579
|
shadowOffset: { width: 0, height: 1 },
|
|
1196
1580
|
shadowOpacity: 0.15,
|
|
1197
1581
|
shadowRadius: 2,
|
|
1198
|
-
elevation: 2
|
|
1582
|
+
elevation: 2,
|
|
1583
|
+
alignItems: "center",
|
|
1584
|
+
justifyContent: "center"
|
|
1585
|
+
},
|
|
1586
|
+
iconWrapper: {
|
|
1587
|
+
position: "absolute"
|
|
1199
1588
|
}
|
|
1200
1589
|
});
|
|
1201
1590
|
var nativeDriver6 = reactNative.Platform.OS !== "web";
|
|
@@ -1245,7 +1634,7 @@ function Toggle({
|
|
|
1245
1634
|
});
|
|
1246
1635
|
const backgroundColor = pressAnim.interpolate({
|
|
1247
1636
|
inputRange: [0, 1],
|
|
1248
|
-
outputRange: ["transparent", colors.
|
|
1637
|
+
outputRange: ["transparent", colors.surfaceStrong]
|
|
1249
1638
|
});
|
|
1250
1639
|
const textColor = pressAnim.interpolate({
|
|
1251
1640
|
inputRange: [0, 1],
|
|
@@ -1264,10 +1653,10 @@ function Toggle({
|
|
|
1264
1653
|
if (active) return /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, active);
|
|
1265
1654
|
return /* @__PURE__ */ React25__default.default.createElement(vectorIcons.FontAwesome5, { name: "check-circle", size: iconSize, color: colors.primary });
|
|
1266
1655
|
}
|
|
1267
|
-
if (iconName) return /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, renderIcon(iconName, iconSize, iconColor ?? colors.
|
|
1656
|
+
if (iconName) return /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, renderIcon(iconName, iconSize, iconColor ?? colors.foregroundMuted));
|
|
1268
1657
|
const custom = renderProp(icon);
|
|
1269
1658
|
if (custom) return /* @__PURE__ */ React25__default.default.createElement(React25__default.default.Fragment, null, custom);
|
|
1270
|
-
return /* @__PURE__ */ React25__default.default.createElement(vectorIcons.FontAwesome5, { name: "circle", size: iconSize, color: colors.
|
|
1659
|
+
return /* @__PURE__ */ React25__default.default.createElement(vectorIcons.FontAwesome5, { name: "circle", size: iconSize, color: colors.foregroundMuted });
|
|
1271
1660
|
};
|
|
1272
1661
|
return /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: [{ transform: [{ scale: scale2 }] }, disabled && styles16.disabled, style] }, /* @__PURE__ */ React25__default.default.createElement(
|
|
1273
1662
|
reactNative.TouchableOpacity,
|
|
@@ -1364,7 +1753,7 @@ function RadioItem({
|
|
|
1364
1753
|
{
|
|
1365
1754
|
style: [
|
|
1366
1755
|
styles17.label,
|
|
1367
|
-
{ color: option.disabled ? colors.
|
|
1756
|
+
{ color: option.disabled ? colors.foregroundMuted : colors.foreground }
|
|
1368
1757
|
],
|
|
1369
1758
|
allowFontScaling: true
|
|
1370
1759
|
},
|
|
@@ -1426,7 +1815,8 @@ function TabTrigger({
|
|
|
1426
1815
|
tab,
|
|
1427
1816
|
isActive,
|
|
1428
1817
|
onPress,
|
|
1429
|
-
onLayout
|
|
1818
|
+
onLayout,
|
|
1819
|
+
variant
|
|
1430
1820
|
}) {
|
|
1431
1821
|
const { colors } = useTheme();
|
|
1432
1822
|
const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
|
|
@@ -1436,10 +1826,15 @@ function TabTrigger({
|
|
|
1436
1826
|
const handlePressOut = () => {
|
|
1437
1827
|
reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver8, speed: 40, bounciness: 4 }).start();
|
|
1438
1828
|
};
|
|
1829
|
+
const isUnderline = variant === "underline";
|
|
1439
1830
|
return /* @__PURE__ */ React25__default.default.createElement(
|
|
1440
1831
|
reactNative.TouchableOpacity,
|
|
1441
1832
|
{
|
|
1442
|
-
style:
|
|
1833
|
+
style: [
|
|
1834
|
+
styles18.trigger,
|
|
1835
|
+
isUnderline && styles18.triggerUnderline,
|
|
1836
|
+
isUnderline && isActive && { borderBottomColor: colors.primary }
|
|
1837
|
+
],
|
|
1443
1838
|
onPress,
|
|
1444
1839
|
onPressIn: handlePressIn,
|
|
1445
1840
|
onPressOut: handlePressOut,
|
|
@@ -1452,8 +1847,8 @@ function TabTrigger({
|
|
|
1452
1847
|
{
|
|
1453
1848
|
style: [
|
|
1454
1849
|
styles18.triggerLabel,
|
|
1455
|
-
{ color: isActive ? colors.foreground : colors.
|
|
1456
|
-
isActive && styles18.activeTriggerLabel
|
|
1850
|
+
{ color: isActive ? colors.foreground : colors.foregroundMuted },
|
|
1851
|
+
isActive && (isUnderline ? styles18.activeTriggerLabelUnderline : styles18.activeTriggerLabel)
|
|
1457
1852
|
],
|
|
1458
1853
|
allowFontScaling: true
|
|
1459
1854
|
},
|
|
@@ -1461,7 +1856,7 @@ function TabTrigger({
|
|
|
1461
1856
|
)))
|
|
1462
1857
|
);
|
|
1463
1858
|
}
|
|
1464
|
-
function Tabs({ tabs, value, onValueChange, children, style }) {
|
|
1859
|
+
function Tabs({ tabs, variant = "pill", value, onValueChange, children, style }) {
|
|
1465
1860
|
const [internal, setInternal] = React25.useState(tabs[0]?.value ?? "");
|
|
1466
1861
|
const { colors } = useTheme();
|
|
1467
1862
|
const active = value ?? internal;
|
|
@@ -1474,18 +1869,8 @@ function Tabs({ tabs, value, onValueChange, children, style }) {
|
|
|
1474
1869
|
if (!layout) return;
|
|
1475
1870
|
if (animate) {
|
|
1476
1871
|
reactNative.Animated.parallel([
|
|
1477
|
-
reactNative.Animated.spring(pillX, {
|
|
1478
|
-
|
|
1479
|
-
useNativeDriver: false,
|
|
1480
|
-
speed: 20,
|
|
1481
|
-
bounciness: 0
|
|
1482
|
-
}),
|
|
1483
|
-
reactNative.Animated.spring(pillWidth, {
|
|
1484
|
-
toValue: layout.width,
|
|
1485
|
-
useNativeDriver: false,
|
|
1486
|
-
speed: 20,
|
|
1487
|
-
bounciness: 0
|
|
1488
|
-
})
|
|
1872
|
+
reactNative.Animated.spring(pillX, { toValue: layout.x, useNativeDriver: false, speed: 20, bounciness: 0 }),
|
|
1873
|
+
reactNative.Animated.spring(pillWidth, { toValue: layout.width, useNativeDriver: false, speed: 20, bounciness: 0 })
|
|
1489
1874
|
]).start();
|
|
1490
1875
|
} else {
|
|
1491
1876
|
pillX.setValue(layout.x);
|
|
@@ -1493,16 +1878,16 @@ function Tabs({ tabs, value, onValueChange, children, style }) {
|
|
|
1493
1878
|
}
|
|
1494
1879
|
};
|
|
1495
1880
|
React25.useEffect(() => {
|
|
1496
|
-
if (initialised.current)
|
|
1497
|
-
animatePill(active, true);
|
|
1498
|
-
}
|
|
1881
|
+
if (initialised.current) animatePill(active, true);
|
|
1499
1882
|
}, [active]);
|
|
1500
1883
|
const handlePress = (v) => {
|
|
1501
1884
|
selectionAsync();
|
|
1502
1885
|
if (!value) setInternal(v);
|
|
1503
1886
|
onValueChange?.(v);
|
|
1504
1887
|
};
|
|
1505
|
-
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [
|
|
1888
|
+
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [
|
|
1889
|
+
variant === "pill" ? [styles18.list, { backgroundColor: colors.surface }] : styles18.listUnderline
|
|
1890
|
+
] }, variant === "pill" && /* @__PURE__ */ React25__default.default.createElement(
|
|
1506
1891
|
reactNative.Animated.View,
|
|
1507
1892
|
{
|
|
1508
1893
|
style: [
|
|
@@ -1517,7 +1902,7 @@ function Tabs({ tabs, value, onValueChange, children, style }) {
|
|
|
1517
1902
|
borderRadius: 8,
|
|
1518
1903
|
shadowColor: "#000",
|
|
1519
1904
|
shadowOffset: { width: 0, height: 1 },
|
|
1520
|
-
shadowOpacity: 0.
|
|
1905
|
+
shadowOpacity: 0.08,
|
|
1521
1906
|
shadowRadius: 2,
|
|
1522
1907
|
elevation: 2
|
|
1523
1908
|
}
|
|
@@ -1530,6 +1915,7 @@ function Tabs({ tabs, value, onValueChange, children, style }) {
|
|
|
1530
1915
|
tab,
|
|
1531
1916
|
isActive: tab.value === active,
|
|
1532
1917
|
onPress: () => handlePress(tab.value),
|
|
1918
|
+
variant,
|
|
1533
1919
|
onLayout: (e) => {
|
|
1534
1920
|
const { x, width } = e.nativeEvent.layout;
|
|
1535
1921
|
tabLayouts.current[tab.value] = { x, width };
|
|
@@ -1548,20 +1934,32 @@ function TabsContent({ value, activeValue, children, style }) {
|
|
|
1548
1934
|
var styles18 = reactNative.StyleSheet.create({
|
|
1549
1935
|
list: {
|
|
1550
1936
|
flexDirection: "row",
|
|
1551
|
-
borderRadius:
|
|
1937
|
+
borderRadius: 12,
|
|
1552
1938
|
padding: s(4),
|
|
1553
1939
|
gap: s(4)
|
|
1554
1940
|
},
|
|
1941
|
+
listUnderline: {
|
|
1942
|
+
flexDirection: "row",
|
|
1943
|
+
borderBottomWidth: 1
|
|
1944
|
+
},
|
|
1555
1945
|
pill: {},
|
|
1556
1946
|
trigger: {
|
|
1557
1947
|
flex: 1,
|
|
1558
1948
|
paddingVertical: vs(7),
|
|
1559
1949
|
paddingHorizontal: s(10),
|
|
1560
|
-
borderRadius:
|
|
1950
|
+
borderRadius: 8,
|
|
1561
1951
|
alignItems: "center",
|
|
1562
1952
|
justifyContent: "center",
|
|
1563
1953
|
zIndex: 1
|
|
1564
1954
|
},
|
|
1955
|
+
triggerUnderline: {
|
|
1956
|
+
flex: 0,
|
|
1957
|
+
paddingVertical: vs(12),
|
|
1958
|
+
paddingHorizontal: s(16),
|
|
1959
|
+
borderRadius: 0,
|
|
1960
|
+
borderBottomWidth: 2,
|
|
1961
|
+
borderBottomColor: "transparent"
|
|
1962
|
+
},
|
|
1565
1963
|
triggerInner: {
|
|
1566
1964
|
flexDirection: "row",
|
|
1567
1965
|
alignItems: "center",
|
|
@@ -1574,6 +1972,10 @@ var styles18 = reactNative.StyleSheet.create({
|
|
|
1574
1972
|
},
|
|
1575
1973
|
activeTriggerLabel: {
|
|
1576
1974
|
fontFamily: "Poppins-Medium"
|
|
1975
|
+
},
|
|
1976
|
+
activeTriggerLabelUnderline: {
|
|
1977
|
+
fontFamily: "Poppins-SemiBold",
|
|
1978
|
+
fontSize: ms(14)
|
|
1577
1979
|
}
|
|
1578
1980
|
});
|
|
1579
1981
|
function AccordionItemComponent({
|
|
@@ -1616,7 +2018,7 @@ function AccordionItemComponent({
|
|
|
1616
2018
|
}
|
|
1617
2019
|
},
|
|
1618
2020
|
/* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles19.triggerText, { color: colors.foreground }], allowFontScaling: true }, item.trigger),
|
|
1619
|
-
/* @__PURE__ */ React25__default.default.createElement(Animated11__default.default.View, { style: [styles19.chevron, rotationStyle] }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-down", size: 18, color: colors.
|
|
2021
|
+
/* @__PURE__ */ React25__default.default.createElement(Animated11__default.default.View, { style: [styles19.chevron, rotationStyle] }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-down", size: 18, color: colors.foregroundMuted }))
|
|
1620
2022
|
), /* @__PURE__ */ React25__default.default.createElement(Animated11__default.default.View, { style: bodyStyle }, /* @__PURE__ */ React25__default.default.createElement(
|
|
1621
2023
|
reactNative.View,
|
|
1622
2024
|
{
|
|
@@ -1708,7 +2110,7 @@ function Slider({
|
|
|
1708
2110
|
}
|
|
1709
2111
|
onValueChange?.(v);
|
|
1710
2112
|
};
|
|
1711
|
-
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles20.wrapper, style], accessibilityLabel }, label || showValue ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles20.header }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles20.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, showValue ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles20.valueText, { color: colors.
|
|
2113
|
+
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles20.wrapper, style], accessibilityLabel }, label || showValue ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles20.header }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles20.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, showValue ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles20.valueText, { color: colors.foregroundMuted }], allowFontScaling: true }, formatValue2(value)) : null) : null, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: disabled ? styles20.disabled : void 0 }, /* @__PURE__ */ React25__default.default.createElement(
|
|
1712
2114
|
RNSlider__default.default,
|
|
1713
2115
|
{
|
|
1714
2116
|
value,
|
|
@@ -1719,7 +2121,7 @@ function Slider({
|
|
|
1719
2121
|
onValueChange: handleValueChange,
|
|
1720
2122
|
onSlidingComplete,
|
|
1721
2123
|
minimumTrackTintColor: colors.primary,
|
|
1722
|
-
maximumTrackTintColor: colors.
|
|
2124
|
+
maximumTrackTintColor: colors.surface,
|
|
1723
2125
|
thumbTintColor: colors.primary,
|
|
1724
2126
|
style: styles20.slider,
|
|
1725
2127
|
accessibilityLabel
|
|
@@ -1757,7 +2159,9 @@ function Sheet({
|
|
|
1757
2159
|
title,
|
|
1758
2160
|
description,
|
|
1759
2161
|
children,
|
|
1760
|
-
style
|
|
2162
|
+
style,
|
|
2163
|
+
scrollable,
|
|
2164
|
+
maxHeight
|
|
1761
2165
|
}) {
|
|
1762
2166
|
const { colors } = useTheme();
|
|
1763
2167
|
const ref = React25.useRef(null);
|
|
@@ -1778,6 +2182,8 @@ function Sheet({
|
|
|
1778
2182
|
pressBehavior: "close"
|
|
1779
2183
|
}
|
|
1780
2184
|
);
|
|
2185
|
+
const headerNode = title || description ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles21.header }, title ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles21.title, { color: colors.foreground }], allowFontScaling: true }, title) : null, description ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles21.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null) : null;
|
|
2186
|
+
const useScroll = scrollable || !!maxHeight;
|
|
1781
2187
|
return /* @__PURE__ */ React25__default.default.createElement(
|
|
1782
2188
|
bottomSheet.BottomSheetModal,
|
|
1783
2189
|
{
|
|
@@ -1789,7 +2195,7 @@ function Sheet({
|
|
|
1789
2195
|
handleIndicatorStyle: [styles21.handle, { backgroundColor: colors.border }],
|
|
1790
2196
|
enablePanDownToClose: true
|
|
1791
2197
|
},
|
|
1792
|
-
/* @__PURE__ */ React25__default.default.createElement(bottomSheet.BottomSheetView, { style:
|
|
2198
|
+
/* @__PURE__ */ React25__default.default.createElement(bottomSheet.BottomSheetView, { style: maxHeight ? { maxHeight } : void 0 }, useScroll ? /* @__PURE__ */ React25__default.default.createElement(bottomSheet.BottomSheetScrollView, { contentContainerStyle: [styles21.content, style] }, headerNode, children) : /* @__PURE__ */ React25__default.default.createElement(bottomSheet.BottomSheetView, { style: [styles21.content, style] }, headerNode, children))
|
|
1793
2199
|
);
|
|
1794
2200
|
}
|
|
1795
2201
|
var styles21 = reactNative.StyleSheet.create({
|
|
@@ -1888,14 +2294,14 @@ function Select({
|
|
|
1888
2294
|
{
|
|
1889
2295
|
style: [
|
|
1890
2296
|
styles22.triggerText,
|
|
1891
|
-
{ color: selected ? colors.foreground : colors.
|
|
2297
|
+
{ color: selected ? colors.foreground : colors.foregroundMuted }
|
|
1892
2298
|
],
|
|
1893
2299
|
numberOfLines: 1,
|
|
1894
2300
|
allowFontScaling: true
|
|
1895
2301
|
},
|
|
1896
2302
|
selected?.label ?? placeholder
|
|
1897
2303
|
),
|
|
1898
|
-
/* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-with-circle-down", size: 20, color: colors.
|
|
2304
|
+
/* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-with-circle-down", size: 20, color: colors.foregroundMuted })
|
|
1899
2305
|
)) : null, isIOS ? /* @__PURE__ */ React25__default.default.createElement(
|
|
1900
2306
|
reactNative.Modal,
|
|
1901
2307
|
{
|
|
@@ -1912,7 +2318,7 @@ function Select({
|
|
|
1912
2318
|
onValueChange: (val) => setPendingValue(val),
|
|
1913
2319
|
itemStyle: { color: colors.foreground }
|
|
1914
2320
|
},
|
|
1915
|
-
!value ? /* @__PURE__ */ React25__default.default.createElement(picker.Picker.Item, { label: placeholder, value: "", color: colors.
|
|
2321
|
+
!value ? /* @__PURE__ */ React25__default.default.createElement(picker.Picker.Item, { label: placeholder, value: "", color: colors.foregroundMuted, enabled: false }) : null,
|
|
1916
2322
|
options.map((o) => /* @__PURE__ */ React25__default.default.createElement(
|
|
1917
2323
|
picker.Picker.Item,
|
|
1918
2324
|
{
|
|
@@ -1920,7 +2326,7 @@ function Select({
|
|
|
1920
2326
|
label: o.label,
|
|
1921
2327
|
value: o.value,
|
|
1922
2328
|
enabled: !o.disabled,
|
|
1923
|
-
color: o.disabled ? colors.
|
|
2329
|
+
color: o.disabled ? colors.foregroundMuted : colors.foreground
|
|
1924
2330
|
}
|
|
1925
2331
|
))
|
|
1926
2332
|
))
|
|
@@ -1964,7 +2370,7 @@ function Select({
|
|
|
1964
2370
|
styles22.webPicker,
|
|
1965
2371
|
{
|
|
1966
2372
|
borderColor: error ? colors.destructive : colors.border,
|
|
1967
|
-
color: selected ? colors.foreground : colors.
|
|
2373
|
+
color: selected ? colors.foreground : colors.foregroundMuted,
|
|
1968
2374
|
backgroundColor: colors.background,
|
|
1969
2375
|
opacity: disabled ? 0.45 : 1
|
|
1970
2376
|
}
|
|
@@ -2099,22 +2505,42 @@ function ToastNotification({ item, onDismiss }) {
|
|
|
2099
2505
|
}));
|
|
2100
2506
|
const variant = item.variant ?? "default";
|
|
2101
2507
|
const bgColor = {
|
|
2102
|
-
default: colors.
|
|
2508
|
+
default: colors.card,
|
|
2509
|
+
destructive: colors.destructiveTint,
|
|
2510
|
+
success: colors.successTint,
|
|
2511
|
+
warning: colors.warningTint
|
|
2512
|
+
}[variant];
|
|
2513
|
+
const borderColor = {
|
|
2514
|
+
default: colors.border,
|
|
2103
2515
|
destructive: colors.destructiveBorder,
|
|
2104
|
-
success: colors.successBorder
|
|
2516
|
+
success: colors.successBorder,
|
|
2517
|
+
warning: colors.warningBorder
|
|
2105
2518
|
}[variant];
|
|
2106
|
-
const
|
|
2107
|
-
default: colors.
|
|
2108
|
-
destructive:
|
|
2109
|
-
success:
|
|
2519
|
+
const accentColor = {
|
|
2520
|
+
default: colors.primary,
|
|
2521
|
+
destructive: colors.destructive,
|
|
2522
|
+
success: colors.success,
|
|
2523
|
+
warning: colors.warning
|
|
2110
2524
|
}[variant];
|
|
2111
|
-
const
|
|
2112
|
-
const
|
|
2113
|
-
const
|
|
2114
|
-
|
|
2115
|
-
}
|
|
2116
|
-
|
|
2117
|
-
|
|
2525
|
+
const titleColor = variant === "default" ? colors.foreground : accentColor;
|
|
2526
|
+
const descColor = variant === "default" ? colors.foregroundMuted : accentColor;
|
|
2527
|
+
const defaultIcon = variant === "success" ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.FontAwesome5, { name: "check-circle", size: 16, color: accentColor }) : variant === "destructive" ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.AntDesign, { name: "exclamation-circle", size: 16, color: accentColor }) : variant === "warning" ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.MaterialIcons, { name: "warning-amber", size: 17, color: accentColor }) : /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "info-with-circle", size: 16, color: accentColor });
|
|
2528
|
+
const leftIcon = item.iconName ? renderIcon(item.iconName, 16, item.iconColor ?? accentColor) : item.icon ?? defaultIcon;
|
|
2529
|
+
return /* @__PURE__ */ React25__default.default.createElement(reactNativeGestureHandler.GestureDetector, { gesture: panGesture }, /* @__PURE__ */ React25__default.default.createElement(Animated11__default.default.View, { style: [styles23.toast, { backgroundColor: bgColor, borderColor }, animatedStyle] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles23.leftIconContainer }, leftIcon), /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles23.toastContent }, item.title ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles23.toastTitle, { color: titleColor }], allowFontScaling: true }, item.title) : null, item.description ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles23.toastDescription, { color: descColor }], allowFontScaling: true }, item.description) : null), item.action && /* @__PURE__ */ React25__default.default.createElement(
|
|
2530
|
+
reactNative.TouchableOpacity,
|
|
2531
|
+
{
|
|
2532
|
+
onPress: () => {
|
|
2533
|
+
item.action.onPress();
|
|
2534
|
+
onDismiss();
|
|
2535
|
+
},
|
|
2536
|
+
style: styles23.actionButton,
|
|
2537
|
+
touchSoundDisabled: true
|
|
2538
|
+
},
|
|
2539
|
+
/* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles23.actionLabel, { color: accentColor }], allowFontScaling: true }, item.action.label)
|
|
2540
|
+
), /* @__PURE__ */ React25__default.default.createElement(reactNative.TouchableOpacity, { onPress: onDismiss, style: styles23.dismissButton, touchSoundDisabled: true }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.AntDesign, { name: "close-circle", size: 16, color: descColor }))));
|
|
2541
|
+
}
|
|
2542
|
+
function ToastProvider({ children }) {
|
|
2543
|
+
const [toasts, setToasts] = React25.useState([]);
|
|
2118
2544
|
const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
|
|
2119
2545
|
const toast = React25.useCallback((item) => {
|
|
2120
2546
|
const id = Math.random().toString(36).slice(2);
|
|
@@ -2122,6 +2548,8 @@ function ToastProvider({ children }) {
|
|
|
2122
2548
|
notificationSuccess();
|
|
2123
2549
|
} else if (item.variant === "destructive") {
|
|
2124
2550
|
notificationError();
|
|
2551
|
+
} else if (item.variant === "warning") {
|
|
2552
|
+
notificationError();
|
|
2125
2553
|
} else {
|
|
2126
2554
|
impactLight();
|
|
2127
2555
|
}
|
|
@@ -2148,38 +2576,52 @@ var styles23 = reactNative.StyleSheet.create({
|
|
|
2148
2576
|
},
|
|
2149
2577
|
toast: {
|
|
2150
2578
|
flexDirection: "row",
|
|
2151
|
-
alignItems: "
|
|
2152
|
-
borderRadius: ms(
|
|
2153
|
-
borderWidth:
|
|
2154
|
-
paddingHorizontal: s(
|
|
2155
|
-
paddingVertical: vs(
|
|
2579
|
+
alignItems: "flex-start",
|
|
2580
|
+
borderRadius: ms(10),
|
|
2581
|
+
borderWidth: 0.5,
|
|
2582
|
+
paddingHorizontal: s(12),
|
|
2583
|
+
paddingVertical: vs(10),
|
|
2156
2584
|
shadowColor: "#000",
|
|
2157
|
-
shadowOffset: { width: 0, height:
|
|
2158
|
-
shadowOpacity: 0.
|
|
2159
|
-
shadowRadius:
|
|
2160
|
-
elevation:
|
|
2585
|
+
shadowOffset: { width: 0, height: 2 },
|
|
2586
|
+
shadowOpacity: 0.06,
|
|
2587
|
+
shadowRadius: 4,
|
|
2588
|
+
elevation: 3
|
|
2161
2589
|
},
|
|
2162
2590
|
toastContent: {
|
|
2163
2591
|
flex: 1,
|
|
2164
|
-
gap: vs(
|
|
2592
|
+
gap: vs(2)
|
|
2165
2593
|
},
|
|
2166
2594
|
leftIconContainer: {
|
|
2167
|
-
|
|
2595
|
+
marginTop: vs(1),
|
|
2168
2596
|
alignItems: "center",
|
|
2169
2597
|
justifyContent: "center",
|
|
2170
2598
|
marginRight: s(10)
|
|
2171
2599
|
},
|
|
2172
2600
|
toastTitle: {
|
|
2173
|
-
fontFamily: "Poppins-
|
|
2174
|
-
fontSize: ms(
|
|
2601
|
+
fontFamily: "Poppins-Medium",
|
|
2602
|
+
fontSize: ms(13),
|
|
2603
|
+
lineHeight: ms(18)
|
|
2175
2604
|
},
|
|
2176
2605
|
toastDescription: {
|
|
2177
2606
|
fontFamily: "Poppins-Regular",
|
|
2178
|
-
fontSize: ms(
|
|
2607
|
+
fontSize: ms(12),
|
|
2608
|
+
lineHeight: ms(17),
|
|
2609
|
+
opacity: 0.85
|
|
2179
2610
|
},
|
|
2180
|
-
|
|
2181
|
-
|
|
2611
|
+
actionButton: {
|
|
2612
|
+
paddingHorizontal: s(8),
|
|
2613
|
+
paddingVertical: vs(4),
|
|
2182
2614
|
marginLeft: s(4)
|
|
2615
|
+
},
|
|
2616
|
+
actionLabel: {
|
|
2617
|
+
fontFamily: "Poppins-Medium",
|
|
2618
|
+
fontSize: ms(12),
|
|
2619
|
+
textDecorationLine: "underline"
|
|
2620
|
+
},
|
|
2621
|
+
dismissButton: {
|
|
2622
|
+
padding: s(6),
|
|
2623
|
+
marginLeft: s(2),
|
|
2624
|
+
marginTop: vs(0)
|
|
2183
2625
|
}
|
|
2184
2626
|
});
|
|
2185
2627
|
function formatCurrency(raw, separator) {
|
|
@@ -2213,7 +2655,7 @@ function CurrencyInput({
|
|
|
2213
2655
|
onChangeValue?.(isNaN(raw) ? 0 : raw);
|
|
2214
2656
|
};
|
|
2215
2657
|
const inputStyle = size === "large" ? { fontFamily: "Poppins-Regular", fontSize: ms(36) } : { fontFamily: "Poppins-Regular" };
|
|
2216
|
-
const dollarIcon = renderIcon("dollar-sign", size === "large" ? 24 : 16, colors.
|
|
2658
|
+
const dollarIcon = renderIcon("dollar-sign", size === "large" ? 24 : 16, colors.foregroundMuted);
|
|
2217
2659
|
const displayValue = value && prefix && value.startsWith(prefix) ? value.slice(prefix.length) : value;
|
|
2218
2660
|
return /* @__PURE__ */ React25__default.default.createElement(
|
|
2219
2661
|
Input,
|
|
@@ -2228,7 +2670,7 @@ function CurrencyInput({
|
|
|
2228
2670
|
editable,
|
|
2229
2671
|
prefix: dollarIcon,
|
|
2230
2672
|
containerStyle,
|
|
2231
|
-
inputWrapperStyle: size === "large" ? { paddingVertical:
|
|
2673
|
+
inputWrapperStyle: size === "large" ? { paddingVertical: vs(16), minHeight: 72 } : void 0,
|
|
2232
2674
|
style: [inputStyle, style]
|
|
2233
2675
|
}
|
|
2234
2676
|
);
|
|
@@ -2254,7 +2696,8 @@ var styles24 = reactNative.StyleSheet.create({
|
|
|
2254
2696
|
container: {},
|
|
2255
2697
|
amount: {
|
|
2256
2698
|
fontFamily: "Poppins-Bold",
|
|
2257
|
-
fontSize: ms(56)
|
|
2699
|
+
fontSize: ms(56),
|
|
2700
|
+
letterSpacing: -2
|
|
2258
2701
|
}
|
|
2259
2702
|
});
|
|
2260
2703
|
var nativeDriver10 = reactNative.Platform.OS !== "web";
|
|
@@ -2304,7 +2747,7 @@ function ListItem({
|
|
|
2304
2747
|
onPress?.();
|
|
2305
2748
|
};
|
|
2306
2749
|
const effectiveLeft = leftIcon ? renderIcon(leftIcon, 24, leftIconColor ?? colors.foreground) : leftRender ?? icon;
|
|
2307
|
-
const effectiveRight = rightIcon ? renderIcon(rightIcon, 24, rightIconColor ?? colors.
|
|
2750
|
+
const effectiveRight = rightIcon ? renderIcon(rightIcon, 24, rightIconColor ?? colors.foregroundMuted) : rightRender ?? trailing;
|
|
2308
2751
|
const cardStyle = variant === "card" ? {
|
|
2309
2752
|
backgroundColor: colors.card,
|
|
2310
2753
|
borderRadius: 12,
|
|
@@ -2339,7 +2782,7 @@ function ListItem({
|
|
|
2339
2782
|
), subtitle ? /* @__PURE__ */ React25__default.default.createElement(
|
|
2340
2783
|
reactNative.Text,
|
|
2341
2784
|
{
|
|
2342
|
-
style: [styles25.subtitle, { color: colors.
|
|
2785
|
+
style: [styles25.subtitle, { color: colors.foregroundMuted }, subtitleStyle],
|
|
2343
2786
|
numberOfLines: 2,
|
|
2344
2787
|
allowFontScaling: true
|
|
2345
2788
|
},
|
|
@@ -2347,7 +2790,7 @@ function ListItem({
|
|
|
2347
2790
|
) : null, caption ? /* @__PURE__ */ React25__default.default.createElement(
|
|
2348
2791
|
reactNative.Text,
|
|
2349
2792
|
{
|
|
2350
|
-
style: [styles25.caption, { color: colors.
|
|
2793
|
+
style: [styles25.caption, { color: colors.foregroundMuted }, captionStyle],
|
|
2351
2794
|
numberOfLines: 1,
|
|
2352
2795
|
allowFontScaling: true
|
|
2353
2796
|
},
|
|
@@ -2356,11 +2799,11 @@ function ListItem({
|
|
|
2356
2799
|
effectiveRight !== void 0 ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles25.rightContainer }, typeof effectiveRight === "string" ? /* @__PURE__ */ React25__default.default.createElement(
|
|
2357
2800
|
reactNative.Text,
|
|
2358
2801
|
{
|
|
2359
|
-
style: [styles25.rightText, { color: colors.
|
|
2802
|
+
style: [styles25.rightText, { color: colors.foregroundMuted }],
|
|
2360
2803
|
allowFontScaling: true
|
|
2361
2804
|
},
|
|
2362
2805
|
effectiveRight
|
|
2363
|
-
) : effectiveRight) : showChevron ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-with-circle-right", size: 20, color: colors.
|
|
2806
|
+
) : effectiveRight) : showChevron ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-with-circle-right", size: 20, color: colors.foregroundMuted }) : null
|
|
2364
2807
|
), showSeparator ? /* @__PURE__ */ React25__default.default.createElement(
|
|
2365
2808
|
reactNative.View,
|
|
2366
2809
|
{
|
|
@@ -2462,7 +2905,7 @@ function Chip({ label, selected = false, onPress, icon, iconName, style }) {
|
|
|
2462
2905
|
};
|
|
2463
2906
|
const backgroundColor = pressAnim.interpolate({
|
|
2464
2907
|
inputRange: [0, 1],
|
|
2465
|
-
outputRange: [colors.
|
|
2908
|
+
outputRange: [colors.surface, colors.primary]
|
|
2466
2909
|
});
|
|
2467
2910
|
const textColor = pressAnim.interpolate({
|
|
2468
2911
|
inputRange: [0, 1],
|
|
@@ -2584,16 +3027,7 @@ function ConfirmDialog({
|
|
|
2584
3027
|
handleIndicatorStyle: [styles27.handle, { backgroundColor: colors.border }],
|
|
2585
3028
|
enablePanDownToClose: true
|
|
2586
3029
|
},
|
|
2587
|
-
/* @__PURE__ */ React25__default.default.createElement(bottomSheet.BottomSheetView, { style: styles27.content }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles27.title, { color: colors.
|
|
2588
|
-
Button,
|
|
2589
|
-
{
|
|
2590
|
-
label: cancelLabel,
|
|
2591
|
-
variant: "outline",
|
|
2592
|
-
fullWidth: true,
|
|
2593
|
-
onPress: onCancel,
|
|
2594
|
-
icon: /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "x", size: 15, color: colors.foreground })
|
|
2595
|
-
}
|
|
2596
|
-
), /* @__PURE__ */ React25__default.default.createElement(
|
|
3030
|
+
/* @__PURE__ */ React25__default.default.createElement(bottomSheet.BottomSheetView, { style: styles27.content }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles27.title, { color: colors.foreground }], allowFontScaling: true }, title), description ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles27.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles27.actions }, /* @__PURE__ */ React25__default.default.createElement(
|
|
2597
3031
|
Button,
|
|
2598
3032
|
{
|
|
2599
3033
|
label: confirmLabel,
|
|
@@ -2609,6 +3043,15 @@ function ConfirmDialog({
|
|
|
2609
3043
|
}
|
|
2610
3044
|
)
|
|
2611
3045
|
}
|
|
3046
|
+
), /* @__PURE__ */ React25__default.default.createElement(
|
|
3047
|
+
Button,
|
|
3048
|
+
{
|
|
3049
|
+
label: cancelLabel,
|
|
3050
|
+
variant: "secondary",
|
|
3051
|
+
fullWidth: true,
|
|
3052
|
+
onPress: onCancel,
|
|
3053
|
+
icon: /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "x", size: 15, color: colors.foreground })
|
|
3054
|
+
}
|
|
2612
3055
|
)))
|
|
2613
3056
|
);
|
|
2614
3057
|
}
|
|
@@ -2644,7 +3087,7 @@ var styles27 = reactNative.StyleSheet.create({
|
|
|
2644
3087
|
});
|
|
2645
3088
|
function LabelValue({ label, value, style }) {
|
|
2646
3089
|
const { colors } = useTheme();
|
|
2647
|
-
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles28.container, style] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles28.label, { color: colors.
|
|
3090
|
+
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles28.container, style] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles28.label, { color: colors.foregroundMuted }], allowFontScaling: true }, label), typeof value === "string" ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles28.value, { color: colors.foreground }], allowFontScaling: true }, value) : value);
|
|
2648
3091
|
}
|
|
2649
3092
|
var styles28 = reactNative.StyleSheet.create({
|
|
2650
3093
|
container: {
|
|
@@ -2737,64 +3180,343 @@ var styles29 = reactNative.StyleSheet.create({
|
|
|
2737
3180
|
minWidth: s(160)
|
|
2738
3181
|
}
|
|
2739
3182
|
});
|
|
3183
|
+
function useHover() {
|
|
3184
|
+
const [hovered, setHovered] = React25.useState(false);
|
|
3185
|
+
const onMouseEnter = React25.useCallback(() => setHovered(true), []);
|
|
3186
|
+
const onMouseLeave = React25.useCallback(() => setHovered(false), []);
|
|
3187
|
+
if (reactNative.Platform.OS !== "web") {
|
|
3188
|
+
return { hovered: false, hoverHandlers: {} };
|
|
3189
|
+
}
|
|
3190
|
+
return { hovered, hoverHandlers: { onMouseEnter, onMouseLeave } };
|
|
3191
|
+
}
|
|
2740
3192
|
|
|
2741
|
-
// src/
|
|
2742
|
-
var
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
"
|
|
2749
|
-
"3xl": 48
|
|
3193
|
+
// src/components/MediaCard/MediaCard.tsx
|
|
3194
|
+
var nativeDriver12 = reactNative.Platform.OS !== "web";
|
|
3195
|
+
var aspectRatioMap = {
|
|
3196
|
+
"1:1": 1,
|
|
3197
|
+
"4:3": 3 / 4,
|
|
3198
|
+
"16:9": 9 / 16,
|
|
3199
|
+
"4:5": 5 / 4,
|
|
3200
|
+
"3:2": 2 / 3
|
|
2750
3201
|
};
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
3202
|
+
function MediaCard({
|
|
3203
|
+
imageSource,
|
|
3204
|
+
aspectRatio = "4:3",
|
|
3205
|
+
badge,
|
|
3206
|
+
actionIcon,
|
|
3207
|
+
actionIconName,
|
|
3208
|
+
actionActive = false,
|
|
3209
|
+
onActionPress,
|
|
3210
|
+
title,
|
|
3211
|
+
subtitle,
|
|
3212
|
+
caption,
|
|
3213
|
+
onPress,
|
|
3214
|
+
style,
|
|
3215
|
+
imageStyle,
|
|
3216
|
+
footer
|
|
3217
|
+
}) {
|
|
3218
|
+
const { colors } = useTheme();
|
|
3219
|
+
const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
|
|
3220
|
+
const { hovered, hoverHandlers } = useHover();
|
|
3221
|
+
const handlePressIn = () => {
|
|
3222
|
+
if (!onPress) return;
|
|
3223
|
+
reactNative.Animated.spring(scale2, { toValue: 0.98, useNativeDriver: nativeDriver12, speed: 40, bounciness: 0 }).start();
|
|
3224
|
+
};
|
|
3225
|
+
const handlePressOut = () => {
|
|
3226
|
+
if (!onPress) return;
|
|
3227
|
+
reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver12, speed: 40, bounciness: 4 }).start();
|
|
3228
|
+
};
|
|
3229
|
+
const handlePress = () => {
|
|
3230
|
+
if (!onPress) return;
|
|
3231
|
+
impactLight();
|
|
3232
|
+
onPress();
|
|
3233
|
+
};
|
|
3234
|
+
const ratio = aspectRatioMap[aspectRatio];
|
|
3235
|
+
const resolvedActionIcon = actionIconName ? renderIcon(actionIconName, 18, actionActive ? colors.primary : colors.background) : actionIcon ?? renderIcon("heart", 18, actionActive ? colors.primary : colors.background);
|
|
3236
|
+
const cardContent = /* @__PURE__ */ React25__default.default.createElement(
|
|
3237
|
+
reactNative.View,
|
|
3238
|
+
{
|
|
3239
|
+
style: [
|
|
3240
|
+
styles30.card,
|
|
3241
|
+
hovered && styles30.cardHovered,
|
|
3242
|
+
style
|
|
3243
|
+
],
|
|
3244
|
+
...reactNative.Platform.OS === "web" ? hoverHandlers : {}
|
|
3245
|
+
},
|
|
3246
|
+
/* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles30.imageContainer, imageStyle] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: { paddingTop: `${ratio * 100}%` } }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: reactNative.StyleSheet.absoluteFill }, imageSource ? /* @__PURE__ */ React25__default.default.createElement(
|
|
3247
|
+
reactNative.Image,
|
|
3248
|
+
{
|
|
3249
|
+
source: imageSource,
|
|
3250
|
+
style: styles30.image,
|
|
3251
|
+
resizeMode: "cover"
|
|
3252
|
+
}
|
|
3253
|
+
) : /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles30.imagePlaceholder, { backgroundColor: colors.surface }] }))), badge && /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles30.badgeContainer }, badge), (onActionPress || actionIcon || actionIconName) && /* @__PURE__ */ React25__default.default.createElement(
|
|
3254
|
+
reactNative.TouchableOpacity,
|
|
3255
|
+
{
|
|
3256
|
+
style: [styles30.actionButton, { backgroundColor: "rgba(0,0,0,0.24)" }],
|
|
3257
|
+
onPress: () => {
|
|
3258
|
+
impactLight();
|
|
3259
|
+
onActionPress?.();
|
|
3260
|
+
},
|
|
3261
|
+
activeOpacity: 0.8,
|
|
3262
|
+
touchSoundDisabled: true
|
|
3263
|
+
},
|
|
3264
|
+
resolvedActionIcon
|
|
3265
|
+
)),
|
|
3266
|
+
(title || subtitle || caption || footer) && /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles30.meta }, title ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles30.title, { color: colors.foreground }], numberOfLines: 2, allowFontScaling: true }, title) : null, subtitle ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles30.subtitle, { color: colors.foregroundSubtle }], numberOfLines: 1, allowFontScaling: true }, subtitle) : null, caption ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles30.caption, { color: colors.foregroundMuted }], numberOfLines: 1, allowFontScaling: true }, caption) : null, footer)
|
|
3267
|
+
);
|
|
3268
|
+
if (onPress) {
|
|
3269
|
+
return /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25__default.default.createElement(
|
|
3270
|
+
reactNative.TouchableOpacity,
|
|
3271
|
+
{
|
|
3272
|
+
onPress: handlePress,
|
|
3273
|
+
onPressIn: handlePressIn,
|
|
3274
|
+
onPressOut: handlePressOut,
|
|
3275
|
+
activeOpacity: 1,
|
|
3276
|
+
touchSoundDisabled: true
|
|
3277
|
+
},
|
|
3278
|
+
cardContent
|
|
3279
|
+
));
|
|
3280
|
+
}
|
|
3281
|
+
return cardContent;
|
|
3282
|
+
}
|
|
3283
|
+
var styles30 = reactNative.StyleSheet.create({
|
|
3284
|
+
card: {
|
|
3285
|
+
borderRadius: RADIUS.md,
|
|
3286
|
+
// 14px — Airbnb property card spec
|
|
3287
|
+
overflow: "hidden",
|
|
3288
|
+
backgroundColor: "transparent"
|
|
2772
3289
|
},
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
shadowOpacity: 0.12,
|
|
2777
|
-
shadowRadius: 8,
|
|
2778
|
-
elevation: 5
|
|
3290
|
+
cardHovered: {
|
|
3291
|
+
// Web hover: lift shadow
|
|
3292
|
+
...SHADOWS.md
|
|
2779
3293
|
},
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
shadowOpacity: 0.2,
|
|
2784
|
-
shadowRadius: 16,
|
|
2785
|
-
elevation: 10
|
|
3294
|
+
imageContainer: {
|
|
3295
|
+
borderRadius: RADIUS.md,
|
|
3296
|
+
overflow: "hidden"
|
|
2786
3297
|
},
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
3298
|
+
image: {
|
|
3299
|
+
width: "100%",
|
|
3300
|
+
height: "100%"
|
|
3301
|
+
},
|
|
3302
|
+
imagePlaceholder: {
|
|
3303
|
+
width: "100%",
|
|
3304
|
+
height: "100%"
|
|
3305
|
+
},
|
|
3306
|
+
badgeContainer: {
|
|
3307
|
+
position: "absolute",
|
|
3308
|
+
top: s(8),
|
|
3309
|
+
left: s(8)
|
|
3310
|
+
},
|
|
3311
|
+
actionButton: {
|
|
3312
|
+
position: "absolute",
|
|
3313
|
+
top: s(8),
|
|
3314
|
+
right: s(8),
|
|
3315
|
+
width: s(32),
|
|
3316
|
+
height: s(32),
|
|
3317
|
+
borderRadius: 9999,
|
|
3318
|
+
alignItems: "center",
|
|
3319
|
+
justifyContent: "center"
|
|
3320
|
+
},
|
|
3321
|
+
meta: {
|
|
3322
|
+
paddingTop: vs(8),
|
|
3323
|
+
gap: vs(2)
|
|
3324
|
+
},
|
|
3325
|
+
title: {
|
|
3326
|
+
fontFamily: "Poppins-SemiBold",
|
|
3327
|
+
fontSize: ms(14),
|
|
3328
|
+
lineHeight: mvs(20)
|
|
3329
|
+
},
|
|
3330
|
+
subtitle: {
|
|
3331
|
+
fontFamily: "Poppins-Regular",
|
|
3332
|
+
fontSize: ms(13),
|
|
3333
|
+
lineHeight: mvs(18)
|
|
3334
|
+
},
|
|
3335
|
+
caption: {
|
|
3336
|
+
fontFamily: "Poppins-Regular",
|
|
3337
|
+
fontSize: ms(12),
|
|
3338
|
+
lineHeight: mvs(16)
|
|
2793
3339
|
}
|
|
2794
|
-
};
|
|
2795
|
-
var
|
|
2796
|
-
|
|
2797
|
-
|
|
3340
|
+
});
|
|
3341
|
+
var nativeDriver13 = reactNative.Platform.OS !== "web";
|
|
3342
|
+
function CategoryChip({
|
|
3343
|
+
item,
|
|
3344
|
+
selected,
|
|
3345
|
+
onPress
|
|
3346
|
+
}) {
|
|
3347
|
+
const { colors } = useTheme();
|
|
3348
|
+
const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
|
|
3349
|
+
const handlePressIn = () => {
|
|
3350
|
+
reactNative.Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver13, speed: 40, bounciness: 0 }).start();
|
|
3351
|
+
};
|
|
3352
|
+
const handlePressOut = () => {
|
|
3353
|
+
reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver13, speed: 40, bounciness: 4 }).start();
|
|
3354
|
+
};
|
|
3355
|
+
const bgColor = selected ? colors.primary : colors.surface;
|
|
3356
|
+
const textColor = selected ? colors.primaryForeground : colors.foregroundSubtle;
|
|
3357
|
+
const borderColor = selected ? colors.primary : colors.border;
|
|
3358
|
+
const resolvedIcon = typeof item.icon === "string" ? renderIcon(item.icon, 16, textColor) : item.icon ?? null;
|
|
3359
|
+
return /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25__default.default.createElement(
|
|
3360
|
+
reactNative.TouchableOpacity,
|
|
3361
|
+
{
|
|
3362
|
+
style: [
|
|
3363
|
+
styles31.chip,
|
|
3364
|
+
{
|
|
3365
|
+
backgroundColor: bgColor,
|
|
3366
|
+
borderColor
|
|
3367
|
+
}
|
|
3368
|
+
],
|
|
3369
|
+
onPress,
|
|
3370
|
+
onPressIn: handlePressIn,
|
|
3371
|
+
onPressOut: handlePressOut,
|
|
3372
|
+
activeOpacity: 1,
|
|
3373
|
+
touchSoundDisabled: true
|
|
3374
|
+
},
|
|
3375
|
+
resolvedIcon && /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles31.chipIcon }, resolvedIcon),
|
|
3376
|
+
/* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles31.chipLabel, { color: textColor }], allowFontScaling: true }, item.label),
|
|
3377
|
+
item.badge !== void 0 && item.badge > 0 && /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles31.chipBadge, { backgroundColor: colors.primary }] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles31.chipBadgeText, { color: colors.primaryForeground }] }, Math.min(item.badge, 99)))
|
|
3378
|
+
));
|
|
3379
|
+
}
|
|
3380
|
+
function CategoryStrip({
|
|
3381
|
+
categories,
|
|
3382
|
+
value,
|
|
3383
|
+
onValueChange,
|
|
3384
|
+
multiSelect = false,
|
|
3385
|
+
style,
|
|
3386
|
+
itemStyle
|
|
3387
|
+
}) {
|
|
3388
|
+
const selected = Array.isArray(value) ? value : value ? [value] : [];
|
|
3389
|
+
const handlePress = (v) => {
|
|
3390
|
+
selectionAsync();
|
|
3391
|
+
if (multiSelect) {
|
|
3392
|
+
const current = Array.isArray(value) ? value : value ? [value] : [];
|
|
3393
|
+
const next = current.includes(v) ? current.filter((x) => x !== v) : [...current, v];
|
|
3394
|
+
onValueChange?.(next);
|
|
3395
|
+
} else {
|
|
3396
|
+
onValueChange?.(v === value ? "" : v);
|
|
3397
|
+
}
|
|
3398
|
+
};
|
|
3399
|
+
return /* @__PURE__ */ React25__default.default.createElement(
|
|
3400
|
+
reactNative.ScrollView,
|
|
3401
|
+
{
|
|
3402
|
+
horizontal: true,
|
|
3403
|
+
showsHorizontalScrollIndicator: false,
|
|
3404
|
+
contentContainerStyle: [styles31.container, style],
|
|
3405
|
+
style: styles31.scroll
|
|
3406
|
+
},
|
|
3407
|
+
categories.map((cat) => /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { key: cat.value, style: itemStyle }, /* @__PURE__ */ React25__default.default.createElement(
|
|
3408
|
+
CategoryChip,
|
|
3409
|
+
{
|
|
3410
|
+
item: cat,
|
|
3411
|
+
selected: selected.includes(cat.value),
|
|
3412
|
+
onPress: () => handlePress(cat.value)
|
|
3413
|
+
}
|
|
3414
|
+
)))
|
|
3415
|
+
);
|
|
3416
|
+
}
|
|
3417
|
+
var styles31 = reactNative.StyleSheet.create({
|
|
3418
|
+
scroll: {
|
|
3419
|
+
flexGrow: 0
|
|
3420
|
+
},
|
|
3421
|
+
container: {
|
|
3422
|
+
flexDirection: "row",
|
|
3423
|
+
gap: s(8),
|
|
3424
|
+
paddingHorizontal: s(4),
|
|
3425
|
+
paddingVertical: vs(4)
|
|
3426
|
+
},
|
|
3427
|
+
chip: {
|
|
3428
|
+
flexDirection: "row",
|
|
3429
|
+
alignItems: "center",
|
|
3430
|
+
borderRadius: RADIUS.full,
|
|
3431
|
+
borderWidth: 1,
|
|
3432
|
+
paddingHorizontal: s(14),
|
|
3433
|
+
paddingVertical: vs(8),
|
|
3434
|
+
gap: s(6)
|
|
3435
|
+
},
|
|
3436
|
+
chipIcon: {
|
|
3437
|
+
alignItems: "center",
|
|
3438
|
+
justifyContent: "center"
|
|
3439
|
+
},
|
|
3440
|
+
chipLabel: {
|
|
3441
|
+
fontFamily: "Poppins-Medium",
|
|
3442
|
+
fontSize: ms(13)
|
|
3443
|
+
},
|
|
3444
|
+
chipBadge: {
|
|
3445
|
+
minWidth: 16,
|
|
3446
|
+
height: 16,
|
|
3447
|
+
borderRadius: 9999,
|
|
3448
|
+
paddingHorizontal: 3,
|
|
3449
|
+
alignItems: "center",
|
|
3450
|
+
justifyContent: "center"
|
|
3451
|
+
},
|
|
3452
|
+
chipBadgeText: {
|
|
3453
|
+
fontFamily: "Poppins-Bold",
|
|
3454
|
+
fontSize: ms(9),
|
|
3455
|
+
lineHeight: 14
|
|
3456
|
+
}
|
|
3457
|
+
});
|
|
3458
|
+
var nativeDriver14 = reactNative.Platform.OS !== "web";
|
|
3459
|
+
function Pressable2({
|
|
3460
|
+
children,
|
|
3461
|
+
onPress,
|
|
3462
|
+
pressScale = 0.98,
|
|
3463
|
+
bounciness = 4,
|
|
3464
|
+
haptics = true,
|
|
3465
|
+
style,
|
|
3466
|
+
disabled,
|
|
3467
|
+
hoverScale = 1.02,
|
|
3468
|
+
...touchableProps
|
|
3469
|
+
}) {
|
|
3470
|
+
const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
|
|
3471
|
+
const { hovered, hoverHandlers } = useHover();
|
|
3472
|
+
const handlePressIn = () => {
|
|
3473
|
+
if (disabled) return;
|
|
3474
|
+
reactNative.Animated.spring(scale2, {
|
|
3475
|
+
toValue: pressScale,
|
|
3476
|
+
useNativeDriver: nativeDriver14,
|
|
3477
|
+
speed: 40,
|
|
3478
|
+
bounciness: 0
|
|
3479
|
+
}).start();
|
|
3480
|
+
};
|
|
3481
|
+
const handlePressOut = () => {
|
|
3482
|
+
if (disabled) return;
|
|
3483
|
+
reactNative.Animated.spring(scale2, {
|
|
3484
|
+
toValue: 1,
|
|
3485
|
+
useNativeDriver: nativeDriver14,
|
|
3486
|
+
speed: 40,
|
|
3487
|
+
bounciness
|
|
3488
|
+
}).start();
|
|
3489
|
+
};
|
|
3490
|
+
const handlePress = () => {
|
|
3491
|
+
if (disabled || !onPress) return;
|
|
3492
|
+
if (haptics) impactLight();
|
|
3493
|
+
onPress();
|
|
3494
|
+
};
|
|
3495
|
+
const hoverScaleValue = hovered && hoverScale !== 1 ? hoverScale : 1;
|
|
3496
|
+
return /* @__PURE__ */ React25__default.default.createElement(
|
|
3497
|
+
reactNative.Animated.View,
|
|
3498
|
+
{
|
|
3499
|
+
style: [
|
|
3500
|
+
{ transform: [{ scale: reactNative.Animated.multiply(scale2, hoverScaleValue) }] },
|
|
3501
|
+
style
|
|
3502
|
+
],
|
|
3503
|
+
...reactNative.Platform.OS === "web" ? hoverHandlers : {}
|
|
3504
|
+
},
|
|
3505
|
+
/* @__PURE__ */ React25__default.default.createElement(
|
|
3506
|
+
reactNative.TouchableOpacity,
|
|
3507
|
+
{
|
|
3508
|
+
onPress: handlePress,
|
|
3509
|
+
onPressIn: handlePressIn,
|
|
3510
|
+
onPressOut: handlePressOut,
|
|
3511
|
+
activeOpacity: 1,
|
|
3512
|
+
disabled,
|
|
3513
|
+
touchSoundDisabled: true,
|
|
3514
|
+
...touchableProps
|
|
3515
|
+
},
|
|
3516
|
+
children
|
|
3517
|
+
)
|
|
3518
|
+
);
|
|
3519
|
+
}
|
|
2798
3520
|
|
|
2799
3521
|
Object.defineProperty(exports, "BottomSheetModalProvider", {
|
|
2800
3522
|
enumerable: true,
|
|
@@ -2812,6 +3534,7 @@ exports.CardDescription = CardDescription;
|
|
|
2812
3534
|
exports.CardFooter = CardFooter;
|
|
2813
3535
|
exports.CardHeader = CardHeader;
|
|
2814
3536
|
exports.CardTitle = CardTitle;
|
|
3537
|
+
exports.CategoryStrip = CategoryStrip;
|
|
2815
3538
|
exports.Checkbox = Checkbox;
|
|
2816
3539
|
exports.Chip = Chip;
|
|
2817
3540
|
exports.ChipGroup = ChipGroup;
|
|
@@ -2826,7 +3549,9 @@ exports.IconButton = IconButton;
|
|
|
2826
3549
|
exports.Input = Input;
|
|
2827
3550
|
exports.LabelValue = LabelValue;
|
|
2828
3551
|
exports.ListItem = ListItem;
|
|
3552
|
+
exports.MediaCard = MediaCard;
|
|
2829
3553
|
exports.MonthPicker = MonthPicker;
|
|
3554
|
+
exports.Pressable = Pressable2;
|
|
2830
3555
|
exports.Progress = Progress;
|
|
2831
3556
|
exports.RADIUS = RADIUS;
|
|
2832
3557
|
exports.RadioGroup = RadioGroup;
|
|
@@ -2839,15 +3564,17 @@ exports.Skeleton = Skeleton;
|
|
|
2839
3564
|
exports.Slider = Slider;
|
|
2840
3565
|
exports.Spinner = Spinner;
|
|
2841
3566
|
exports.Switch = Switch;
|
|
3567
|
+
exports.TYPOGRAPHY = TYPOGRAPHY;
|
|
2842
3568
|
exports.Tabs = Tabs;
|
|
2843
3569
|
exports.TabsContent = TabsContent;
|
|
2844
|
-
exports.Text =
|
|
3570
|
+
exports.Text = Text3;
|
|
2845
3571
|
exports.Textarea = Textarea;
|
|
2846
3572
|
exports.ThemeProvider = ThemeProvider;
|
|
2847
3573
|
exports.ToastProvider = ToastProvider;
|
|
2848
3574
|
exports.Toggle = Toggle;
|
|
2849
3575
|
exports.defaultDark = defaultDark;
|
|
2850
3576
|
exports.defaultLight = defaultLight;
|
|
3577
|
+
exports.deriveColors = deriveColors;
|
|
2851
3578
|
exports.renderIcon = renderIcon;
|
|
2852
3579
|
exports.useTheme = useTheme;
|
|
2853
3580
|
exports.useToast = useToast;
|