@retray-dev/ui-kit 3.1.0 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMPONENTS.md +1792 -659
- package/README.md +8 -7
- package/dist/index.d.mts +269 -89
- package/dist/index.d.ts +269 -89
- package/dist/index.js +1034 -312
- package/dist/index.mjs +1031 -314
- package/package.json +3 -2
- package/src/components/Accordion/Accordion.tsx +1 -1
- package/src/components/AlertBanner/AlertBanner.tsx +50 -45
- package/src/components/Avatar/Avatar.tsx +61 -17
- package/src/components/Badge/Badge.tsx +17 -15
- package/src/components/Button/Button.tsx +31 -42
- package/src/components/Card/Card.tsx +4 -4
- package/src/components/CategoryStrip/CategoryStrip.tsx +185 -0
- package/src/components/CategoryStrip/index.ts +2 -0
- package/src/components/Checkbox/Checkbox.tsx +44 -16
- package/src/components/Chip/Chip.tsx +1 -1
- package/src/components/ConfirmDialog/ConfirmDialog.tsx +4 -4
- package/src/components/CurrencyDisplay/CurrencyDisplay.tsx +1 -0
- package/src/components/CurrencyInput/CurrencyInput.tsx +6 -4
- package/src/components/EmptyState/EmptyState.tsx +9 -9
- package/src/components/IconButton/IconButton.tsx +74 -34
- package/src/components/Input/Input.tsx +15 -13
- package/src/components/LabelValue/LabelValue.tsx +1 -1
- package/src/components/ListItem/ListItem.tsx +5 -5
- package/src/components/MediaCard/MediaCard.tsx +249 -0
- package/src/components/MediaCard/index.ts +2 -0
- package/src/components/Pressable/Pressable.tsx +100 -0
- package/src/components/Pressable/index.ts +1 -0
- package/src/components/Progress/Progress.tsx +14 -7
- package/src/components/RadioGroup/RadioGroup.tsx +1 -1
- package/src/components/Select/Select.tsx +5 -5
- package/src/components/Sheet/Sheet.tsx +3 -9
- package/src/components/Skeleton/Skeleton.tsx +34 -7
- package/src/components/Slider/Slider.tsx +2 -2
- package/src/components/Spinner/Spinner.tsx +1 -1
- package/src/components/Switch/Switch.tsx +31 -4
- package/src/components/Tabs/Tabs.tsx +63 -45
- package/src/components/Text/Text.tsx +59 -10
- package/src/components/Textarea/Textarea.tsx +4 -3
- package/src/components/Toast/Toast.tsx +77 -36
- package/src/components/Toggle/Toggle.tsx +3 -3
- package/src/index.ts +8 -2
- package/src/theme/ThemeProvider.tsx +11 -10
- package/src/theme/colorUtils.ts +80 -0
- package/src/theme/colors.ts +76 -35
- package/src/theme/index.ts +2 -2
- package/src/theme/types.ts +27 -13
- package/src/tokens.ts +150 -13
- package/src/utils/hover.ts +25 -0
package/dist/index.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,6 @@ function Sheet({
|
|
|
1757
2159
|
title,
|
|
1758
2160
|
description,
|
|
1759
2161
|
children,
|
|
1760
|
-
snapPoints = ["50%"],
|
|
1761
2162
|
style
|
|
1762
2163
|
}) {
|
|
1763
2164
|
const { colors } = useTheme();
|
|
@@ -1783,14 +2184,14 @@ function Sheet({
|
|
|
1783
2184
|
bottomSheet.BottomSheetModal,
|
|
1784
2185
|
{
|
|
1785
2186
|
ref,
|
|
1786
|
-
|
|
2187
|
+
enableDynamicSizing: true,
|
|
1787
2188
|
onDismiss: onClose,
|
|
1788
2189
|
backdropComponent: renderBackdrop,
|
|
1789
2190
|
backgroundStyle: [styles21.background, { backgroundColor: colors.card }],
|
|
1790
2191
|
handleIndicatorStyle: [styles21.handle, { backgroundColor: colors.border }],
|
|
1791
2192
|
enablePanDownToClose: true
|
|
1792
2193
|
},
|
|
1793
|
-
/* @__PURE__ */ React25__default.default.createElement(bottomSheet.BottomSheetView, { style: [styles21.content, style] }, 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.
|
|
2194
|
+
/* @__PURE__ */ React25__default.default.createElement(bottomSheet.BottomSheetView, { style: [styles21.content, style] }, 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, children)
|
|
1794
2195
|
);
|
|
1795
2196
|
}
|
|
1796
2197
|
var styles21 = reactNative.StyleSheet.create({
|
|
@@ -1889,14 +2290,14 @@ function Select({
|
|
|
1889
2290
|
{
|
|
1890
2291
|
style: [
|
|
1891
2292
|
styles22.triggerText,
|
|
1892
|
-
{ color: selected ? colors.foreground : colors.
|
|
2293
|
+
{ color: selected ? colors.foreground : colors.foregroundMuted }
|
|
1893
2294
|
],
|
|
1894
2295
|
numberOfLines: 1,
|
|
1895
2296
|
allowFontScaling: true
|
|
1896
2297
|
},
|
|
1897
2298
|
selected?.label ?? placeholder
|
|
1898
2299
|
),
|
|
1899
|
-
/* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-with-circle-down", size: 20, color: colors.
|
|
2300
|
+
/* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-with-circle-down", size: 20, color: colors.foregroundMuted })
|
|
1900
2301
|
)) : null, isIOS ? /* @__PURE__ */ React25__default.default.createElement(
|
|
1901
2302
|
reactNative.Modal,
|
|
1902
2303
|
{
|
|
@@ -1913,7 +2314,7 @@ function Select({
|
|
|
1913
2314
|
onValueChange: (val) => setPendingValue(val),
|
|
1914
2315
|
itemStyle: { color: colors.foreground }
|
|
1915
2316
|
},
|
|
1916
|
-
!value ? /* @__PURE__ */ React25__default.default.createElement(picker.Picker.Item, { label: placeholder, value: "", color: colors.
|
|
2317
|
+
!value ? /* @__PURE__ */ React25__default.default.createElement(picker.Picker.Item, { label: placeholder, value: "", color: colors.foregroundMuted, enabled: false }) : null,
|
|
1917
2318
|
options.map((o) => /* @__PURE__ */ React25__default.default.createElement(
|
|
1918
2319
|
picker.Picker.Item,
|
|
1919
2320
|
{
|
|
@@ -1921,7 +2322,7 @@ function Select({
|
|
|
1921
2322
|
label: o.label,
|
|
1922
2323
|
value: o.value,
|
|
1923
2324
|
enabled: !o.disabled,
|
|
1924
|
-
color: o.disabled ? colors.
|
|
2325
|
+
color: o.disabled ? colors.foregroundMuted : colors.foreground
|
|
1925
2326
|
}
|
|
1926
2327
|
))
|
|
1927
2328
|
))
|
|
@@ -1965,7 +2366,7 @@ function Select({
|
|
|
1965
2366
|
styles22.webPicker,
|
|
1966
2367
|
{
|
|
1967
2368
|
borderColor: error ? colors.destructive : colors.border,
|
|
1968
|
-
color: selected ? colors.foreground : colors.
|
|
2369
|
+
color: selected ? colors.foreground : colors.foregroundMuted,
|
|
1969
2370
|
backgroundColor: colors.background,
|
|
1970
2371
|
opacity: disabled ? 0.45 : 1
|
|
1971
2372
|
}
|
|
@@ -2100,19 +2501,39 @@ function ToastNotification({ item, onDismiss }) {
|
|
|
2100
2501
|
}));
|
|
2101
2502
|
const variant = item.variant ?? "default";
|
|
2102
2503
|
const bgColor = {
|
|
2103
|
-
default: colors.
|
|
2504
|
+
default: colors.card,
|
|
2505
|
+
destructive: colors.destructiveTint,
|
|
2506
|
+
success: colors.successTint,
|
|
2507
|
+
warning: colors.warningTint
|
|
2508
|
+
}[variant];
|
|
2509
|
+
const borderColor = {
|
|
2510
|
+
default: colors.border,
|
|
2104
2511
|
destructive: colors.destructiveBorder,
|
|
2105
|
-
success: colors.successBorder
|
|
2512
|
+
success: colors.successBorder,
|
|
2513
|
+
warning: colors.warningBorder
|
|
2106
2514
|
}[variant];
|
|
2107
|
-
const
|
|
2108
|
-
default: colors.
|
|
2109
|
-
destructive:
|
|
2110
|
-
success:
|
|
2515
|
+
const accentColor = {
|
|
2516
|
+
default: colors.primary,
|
|
2517
|
+
destructive: colors.destructive,
|
|
2518
|
+
success: colors.success,
|
|
2519
|
+
warning: colors.warning
|
|
2111
2520
|
}[variant];
|
|
2112
|
-
const
|
|
2113
|
-
const
|
|
2114
|
-
const
|
|
2115
|
-
|
|
2521
|
+
const titleColor = variant === "default" ? colors.foreground : accentColor;
|
|
2522
|
+
const descColor = variant === "default" ? colors.foregroundMuted : accentColor;
|
|
2523
|
+
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 });
|
|
2524
|
+
const leftIcon = item.iconName ? renderIcon(item.iconName, 16, item.iconColor ?? accentColor) : item.icon ?? defaultIcon;
|
|
2525
|
+
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(
|
|
2526
|
+
reactNative.TouchableOpacity,
|
|
2527
|
+
{
|
|
2528
|
+
onPress: () => {
|
|
2529
|
+
item.action.onPress();
|
|
2530
|
+
onDismiss();
|
|
2531
|
+
},
|
|
2532
|
+
style: styles23.actionButton,
|
|
2533
|
+
touchSoundDisabled: true
|
|
2534
|
+
},
|
|
2535
|
+
/* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles23.actionLabel, { color: accentColor }], allowFontScaling: true }, item.action.label)
|
|
2536
|
+
), /* @__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 }))));
|
|
2116
2537
|
}
|
|
2117
2538
|
function ToastProvider({ children }) {
|
|
2118
2539
|
const [toasts, setToasts] = React25.useState([]);
|
|
@@ -2123,6 +2544,8 @@ function ToastProvider({ children }) {
|
|
|
2123
2544
|
notificationSuccess();
|
|
2124
2545
|
} else if (item.variant === "destructive") {
|
|
2125
2546
|
notificationError();
|
|
2547
|
+
} else if (item.variant === "warning") {
|
|
2548
|
+
notificationError();
|
|
2126
2549
|
} else {
|
|
2127
2550
|
impactLight();
|
|
2128
2551
|
}
|
|
@@ -2149,38 +2572,52 @@ var styles23 = reactNative.StyleSheet.create({
|
|
|
2149
2572
|
},
|
|
2150
2573
|
toast: {
|
|
2151
2574
|
flexDirection: "row",
|
|
2152
|
-
alignItems: "
|
|
2153
|
-
borderRadius: ms(
|
|
2154
|
-
borderWidth:
|
|
2155
|
-
paddingHorizontal: s(
|
|
2156
|
-
paddingVertical: vs(
|
|
2575
|
+
alignItems: "flex-start",
|
|
2576
|
+
borderRadius: ms(10),
|
|
2577
|
+
borderWidth: 0.5,
|
|
2578
|
+
paddingHorizontal: s(12),
|
|
2579
|
+
paddingVertical: vs(10),
|
|
2157
2580
|
shadowColor: "#000",
|
|
2158
|
-
shadowOffset: { width: 0, height:
|
|
2159
|
-
shadowOpacity: 0.
|
|
2160
|
-
shadowRadius:
|
|
2161
|
-
elevation:
|
|
2581
|
+
shadowOffset: { width: 0, height: 2 },
|
|
2582
|
+
shadowOpacity: 0.06,
|
|
2583
|
+
shadowRadius: 4,
|
|
2584
|
+
elevation: 3
|
|
2162
2585
|
},
|
|
2163
2586
|
toastContent: {
|
|
2164
2587
|
flex: 1,
|
|
2165
|
-
gap: vs(
|
|
2588
|
+
gap: vs(2)
|
|
2166
2589
|
},
|
|
2167
2590
|
leftIconContainer: {
|
|
2168
|
-
|
|
2591
|
+
marginTop: vs(1),
|
|
2169
2592
|
alignItems: "center",
|
|
2170
2593
|
justifyContent: "center",
|
|
2171
2594
|
marginRight: s(10)
|
|
2172
2595
|
},
|
|
2173
2596
|
toastTitle: {
|
|
2174
|
-
fontFamily: "Poppins-
|
|
2175
|
-
fontSize: ms(
|
|
2597
|
+
fontFamily: "Poppins-Medium",
|
|
2598
|
+
fontSize: ms(13),
|
|
2599
|
+
lineHeight: ms(18)
|
|
2176
2600
|
},
|
|
2177
2601
|
toastDescription: {
|
|
2178
2602
|
fontFamily: "Poppins-Regular",
|
|
2179
|
-
fontSize: ms(
|
|
2603
|
+
fontSize: ms(12),
|
|
2604
|
+
lineHeight: ms(17),
|
|
2605
|
+
opacity: 0.85
|
|
2180
2606
|
},
|
|
2181
|
-
|
|
2182
|
-
|
|
2607
|
+
actionButton: {
|
|
2608
|
+
paddingHorizontal: s(8),
|
|
2609
|
+
paddingVertical: vs(4),
|
|
2183
2610
|
marginLeft: s(4)
|
|
2611
|
+
},
|
|
2612
|
+
actionLabel: {
|
|
2613
|
+
fontFamily: "Poppins-Medium",
|
|
2614
|
+
fontSize: ms(12),
|
|
2615
|
+
textDecorationLine: "underline"
|
|
2616
|
+
},
|
|
2617
|
+
dismissButton: {
|
|
2618
|
+
padding: s(6),
|
|
2619
|
+
marginLeft: s(2),
|
|
2620
|
+
marginTop: vs(0)
|
|
2184
2621
|
}
|
|
2185
2622
|
});
|
|
2186
2623
|
function formatCurrency(raw, separator) {
|
|
@@ -2214,7 +2651,7 @@ function CurrencyInput({
|
|
|
2214
2651
|
onChangeValue?.(isNaN(raw) ? 0 : raw);
|
|
2215
2652
|
};
|
|
2216
2653
|
const inputStyle = size === "large" ? { fontFamily: "Poppins-Regular", fontSize: ms(36) } : { fontFamily: "Poppins-Regular" };
|
|
2217
|
-
const dollarIcon = renderIcon("dollar-sign", size === "large" ? 24 : 16, colors.
|
|
2654
|
+
const dollarIcon = renderIcon("dollar-sign", size === "large" ? 24 : 16, colors.foregroundMuted);
|
|
2218
2655
|
const displayValue = value && prefix && value.startsWith(prefix) ? value.slice(prefix.length) : value;
|
|
2219
2656
|
return /* @__PURE__ */ React25__default.default.createElement(
|
|
2220
2657
|
Input,
|
|
@@ -2229,7 +2666,7 @@ function CurrencyInput({
|
|
|
2229
2666
|
editable,
|
|
2230
2667
|
prefix: dollarIcon,
|
|
2231
2668
|
containerStyle,
|
|
2232
|
-
inputWrapperStyle: size === "large" ? { paddingVertical:
|
|
2669
|
+
inputWrapperStyle: size === "large" ? { paddingVertical: vs(16), minHeight: 72 } : void 0,
|
|
2233
2670
|
style: [inputStyle, style]
|
|
2234
2671
|
}
|
|
2235
2672
|
);
|
|
@@ -2255,7 +2692,8 @@ var styles24 = reactNative.StyleSheet.create({
|
|
|
2255
2692
|
container: {},
|
|
2256
2693
|
amount: {
|
|
2257
2694
|
fontFamily: "Poppins-Bold",
|
|
2258
|
-
fontSize: ms(56)
|
|
2695
|
+
fontSize: ms(56),
|
|
2696
|
+
letterSpacing: -2
|
|
2259
2697
|
}
|
|
2260
2698
|
});
|
|
2261
2699
|
var nativeDriver10 = reactNative.Platform.OS !== "web";
|
|
@@ -2305,7 +2743,7 @@ function ListItem({
|
|
|
2305
2743
|
onPress?.();
|
|
2306
2744
|
};
|
|
2307
2745
|
const effectiveLeft = leftIcon ? renderIcon(leftIcon, 24, leftIconColor ?? colors.foreground) : leftRender ?? icon;
|
|
2308
|
-
const effectiveRight = rightIcon ? renderIcon(rightIcon, 24, rightIconColor ?? colors.
|
|
2746
|
+
const effectiveRight = rightIcon ? renderIcon(rightIcon, 24, rightIconColor ?? colors.foregroundMuted) : rightRender ?? trailing;
|
|
2309
2747
|
const cardStyle = variant === "card" ? {
|
|
2310
2748
|
backgroundColor: colors.card,
|
|
2311
2749
|
borderRadius: 12,
|
|
@@ -2340,7 +2778,7 @@ function ListItem({
|
|
|
2340
2778
|
), subtitle ? /* @__PURE__ */ React25__default.default.createElement(
|
|
2341
2779
|
reactNative.Text,
|
|
2342
2780
|
{
|
|
2343
|
-
style: [styles25.subtitle, { color: colors.
|
|
2781
|
+
style: [styles25.subtitle, { color: colors.foregroundMuted }, subtitleStyle],
|
|
2344
2782
|
numberOfLines: 2,
|
|
2345
2783
|
allowFontScaling: true
|
|
2346
2784
|
},
|
|
@@ -2348,7 +2786,7 @@ function ListItem({
|
|
|
2348
2786
|
) : null, caption ? /* @__PURE__ */ React25__default.default.createElement(
|
|
2349
2787
|
reactNative.Text,
|
|
2350
2788
|
{
|
|
2351
|
-
style: [styles25.caption, { color: colors.
|
|
2789
|
+
style: [styles25.caption, { color: colors.foregroundMuted }, captionStyle],
|
|
2352
2790
|
numberOfLines: 1,
|
|
2353
2791
|
allowFontScaling: true
|
|
2354
2792
|
},
|
|
@@ -2357,11 +2795,11 @@ function ListItem({
|
|
|
2357
2795
|
effectiveRight !== void 0 ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles25.rightContainer }, typeof effectiveRight === "string" ? /* @__PURE__ */ React25__default.default.createElement(
|
|
2358
2796
|
reactNative.Text,
|
|
2359
2797
|
{
|
|
2360
|
-
style: [styles25.rightText, { color: colors.
|
|
2798
|
+
style: [styles25.rightText, { color: colors.foregroundMuted }],
|
|
2361
2799
|
allowFontScaling: true
|
|
2362
2800
|
},
|
|
2363
2801
|
effectiveRight
|
|
2364
|
-
) : effectiveRight) : showChevron ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-with-circle-right", size: 20, color: colors.
|
|
2802
|
+
) : effectiveRight) : showChevron ? /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-with-circle-right", size: 20, color: colors.foregroundMuted }) : null
|
|
2365
2803
|
), showSeparator ? /* @__PURE__ */ React25__default.default.createElement(
|
|
2366
2804
|
reactNative.View,
|
|
2367
2805
|
{
|
|
@@ -2463,7 +2901,7 @@ function Chip({ label, selected = false, onPress, icon, iconName, style }) {
|
|
|
2463
2901
|
};
|
|
2464
2902
|
const backgroundColor = pressAnim.interpolate({
|
|
2465
2903
|
inputRange: [0, 1],
|
|
2466
|
-
outputRange: [colors.
|
|
2904
|
+
outputRange: [colors.surface, colors.primary]
|
|
2467
2905
|
});
|
|
2468
2906
|
const textColor = pressAnim.interpolate({
|
|
2469
2907
|
inputRange: [0, 1],
|
|
@@ -2578,18 +3016,18 @@ function ConfirmDialog({
|
|
|
2578
3016
|
bottomSheet.BottomSheetModal,
|
|
2579
3017
|
{
|
|
2580
3018
|
ref,
|
|
2581
|
-
|
|
3019
|
+
enableDynamicSizing: true,
|
|
2582
3020
|
onDismiss: onCancel,
|
|
2583
3021
|
backdropComponent: renderBackdrop,
|
|
2584
3022
|
backgroundStyle: [styles27.background, { backgroundColor: colors.card }],
|
|
2585
3023
|
handleIndicatorStyle: [styles27.handle, { backgroundColor: colors.border }],
|
|
2586
3024
|
enablePanDownToClose: true
|
|
2587
3025
|
},
|
|
2588
|
-
/* @__PURE__ */ React25__default.default.createElement(bottomSheet.BottomSheetView, { style: styles27.content }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles27.title, { color: colors.
|
|
3026
|
+
/* @__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(
|
|
2589
3027
|
Button,
|
|
2590
3028
|
{
|
|
2591
3029
|
label: cancelLabel,
|
|
2592
|
-
variant: "
|
|
3030
|
+
variant: "secondary",
|
|
2593
3031
|
fullWidth: true,
|
|
2594
3032
|
onPress: onCancel,
|
|
2595
3033
|
icon: /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "x", size: 15, color: colors.foreground })
|
|
@@ -2645,7 +3083,7 @@ var styles27 = reactNative.StyleSheet.create({
|
|
|
2645
3083
|
});
|
|
2646
3084
|
function LabelValue({ label, value, style }) {
|
|
2647
3085
|
const { colors } = useTheme();
|
|
2648
|
-
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles28.container, style] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles28.label, { color: colors.
|
|
3086
|
+
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);
|
|
2649
3087
|
}
|
|
2650
3088
|
var styles28 = reactNative.StyleSheet.create({
|
|
2651
3089
|
container: {
|
|
@@ -2738,64 +3176,343 @@ var styles29 = reactNative.StyleSheet.create({
|
|
|
2738
3176
|
minWidth: s(160)
|
|
2739
3177
|
}
|
|
2740
3178
|
});
|
|
3179
|
+
function useHover() {
|
|
3180
|
+
const [hovered, setHovered] = React25.useState(false);
|
|
3181
|
+
const onMouseEnter = React25.useCallback(() => setHovered(true), []);
|
|
3182
|
+
const onMouseLeave = React25.useCallback(() => setHovered(false), []);
|
|
3183
|
+
if (reactNative.Platform.OS !== "web") {
|
|
3184
|
+
return { hovered: false, hoverHandlers: {} };
|
|
3185
|
+
}
|
|
3186
|
+
return { hovered, hoverHandlers: { onMouseEnter, onMouseLeave } };
|
|
3187
|
+
}
|
|
2741
3188
|
|
|
2742
|
-
// src/
|
|
2743
|
-
var
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
"
|
|
2750
|
-
"3xl": 48
|
|
2751
|
-
};
|
|
2752
|
-
var ICON_SIZES = {
|
|
2753
|
-
sm: 14,
|
|
2754
|
-
md: 18,
|
|
2755
|
-
lg: 22,
|
|
2756
|
-
xl: 28,
|
|
2757
|
-
"2xl": 32
|
|
2758
|
-
};
|
|
2759
|
-
var RADIUS = {
|
|
2760
|
-
sm: 4,
|
|
2761
|
-
md: 8,
|
|
2762
|
-
lg: 12,
|
|
2763
|
-
xl: 16,
|
|
2764
|
-
full: 9999
|
|
3189
|
+
// src/components/MediaCard/MediaCard.tsx
|
|
3190
|
+
var nativeDriver12 = reactNative.Platform.OS !== "web";
|
|
3191
|
+
var aspectRatioMap = {
|
|
3192
|
+
"1:1": 1,
|
|
3193
|
+
"4:3": 3 / 4,
|
|
3194
|
+
"16:9": 9 / 16,
|
|
3195
|
+
"4:5": 5 / 4,
|
|
3196
|
+
"3:2": 2 / 3
|
|
2765
3197
|
};
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
3198
|
+
function MediaCard({
|
|
3199
|
+
imageSource,
|
|
3200
|
+
aspectRatio = "4:3",
|
|
3201
|
+
badge,
|
|
3202
|
+
actionIcon,
|
|
3203
|
+
actionIconName,
|
|
3204
|
+
actionActive = false,
|
|
3205
|
+
onActionPress,
|
|
3206
|
+
title,
|
|
3207
|
+
subtitle,
|
|
3208
|
+
caption,
|
|
3209
|
+
onPress,
|
|
3210
|
+
style,
|
|
3211
|
+
imageStyle,
|
|
3212
|
+
footer
|
|
3213
|
+
}) {
|
|
3214
|
+
const { colors } = useTheme();
|
|
3215
|
+
const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
|
|
3216
|
+
const { hovered, hoverHandlers } = useHover();
|
|
3217
|
+
const handlePressIn = () => {
|
|
3218
|
+
if (!onPress) return;
|
|
3219
|
+
reactNative.Animated.spring(scale2, { toValue: 0.98, useNativeDriver: nativeDriver12, speed: 40, bounciness: 0 }).start();
|
|
3220
|
+
};
|
|
3221
|
+
const handlePressOut = () => {
|
|
3222
|
+
if (!onPress) return;
|
|
3223
|
+
reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver12, speed: 40, bounciness: 4 }).start();
|
|
3224
|
+
};
|
|
3225
|
+
const handlePress = () => {
|
|
3226
|
+
if (!onPress) return;
|
|
3227
|
+
impactLight();
|
|
3228
|
+
onPress();
|
|
3229
|
+
};
|
|
3230
|
+
const ratio = aspectRatioMap[aspectRatio];
|
|
3231
|
+
const resolvedActionIcon = actionIconName ? renderIcon(actionIconName, 18, actionActive ? colors.primary : colors.background) : actionIcon ?? renderIcon("heart", 18, actionActive ? colors.primary : colors.background);
|
|
3232
|
+
const cardContent = /* @__PURE__ */ React25__default.default.createElement(
|
|
3233
|
+
reactNative.View,
|
|
3234
|
+
{
|
|
3235
|
+
style: [
|
|
3236
|
+
styles30.card,
|
|
3237
|
+
hovered && styles30.cardHovered,
|
|
3238
|
+
style
|
|
3239
|
+
],
|
|
3240
|
+
...reactNative.Platform.OS === "web" ? hoverHandlers : {}
|
|
3241
|
+
},
|
|
3242
|
+
/* @__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(
|
|
3243
|
+
reactNative.Image,
|
|
3244
|
+
{
|
|
3245
|
+
source: imageSource,
|
|
3246
|
+
style: styles30.image,
|
|
3247
|
+
resizeMode: "cover"
|
|
3248
|
+
}
|
|
3249
|
+
) : /* @__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(
|
|
3250
|
+
reactNative.TouchableOpacity,
|
|
3251
|
+
{
|
|
3252
|
+
style: [styles30.actionButton, { backgroundColor: "rgba(0,0,0,0.24)" }],
|
|
3253
|
+
onPress: () => {
|
|
3254
|
+
impactLight();
|
|
3255
|
+
onActionPress?.();
|
|
3256
|
+
},
|
|
3257
|
+
activeOpacity: 0.8,
|
|
3258
|
+
touchSoundDisabled: true
|
|
3259
|
+
},
|
|
3260
|
+
resolvedActionIcon
|
|
3261
|
+
)),
|
|
3262
|
+
(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)
|
|
3263
|
+
);
|
|
3264
|
+
if (onPress) {
|
|
3265
|
+
return /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25__default.default.createElement(
|
|
3266
|
+
reactNative.TouchableOpacity,
|
|
3267
|
+
{
|
|
3268
|
+
onPress: handlePress,
|
|
3269
|
+
onPressIn: handlePressIn,
|
|
3270
|
+
onPressOut: handlePressOut,
|
|
3271
|
+
activeOpacity: 1,
|
|
3272
|
+
touchSoundDisabled: true
|
|
3273
|
+
},
|
|
3274
|
+
cardContent
|
|
3275
|
+
));
|
|
3276
|
+
}
|
|
3277
|
+
return cardContent;
|
|
3278
|
+
}
|
|
3279
|
+
var styles30 = reactNative.StyleSheet.create({
|
|
3280
|
+
card: {
|
|
3281
|
+
borderRadius: RADIUS.md,
|
|
3282
|
+
// 14px — Airbnb property card spec
|
|
3283
|
+
overflow: "hidden",
|
|
3284
|
+
backgroundColor: "transparent"
|
|
2773
3285
|
},
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
shadowOpacity: 0.12,
|
|
2778
|
-
shadowRadius: 8,
|
|
2779
|
-
elevation: 5
|
|
3286
|
+
cardHovered: {
|
|
3287
|
+
// Web hover: lift shadow
|
|
3288
|
+
...SHADOWS.md
|
|
2780
3289
|
},
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
shadowOpacity: 0.2,
|
|
2785
|
-
shadowRadius: 16,
|
|
2786
|
-
elevation: 10
|
|
3290
|
+
imageContainer: {
|
|
3291
|
+
borderRadius: RADIUS.md,
|
|
3292
|
+
overflow: "hidden"
|
|
2787
3293
|
},
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
3294
|
+
image: {
|
|
3295
|
+
width: "100%",
|
|
3296
|
+
height: "100%"
|
|
3297
|
+
},
|
|
3298
|
+
imagePlaceholder: {
|
|
3299
|
+
width: "100%",
|
|
3300
|
+
height: "100%"
|
|
3301
|
+
},
|
|
3302
|
+
badgeContainer: {
|
|
3303
|
+
position: "absolute",
|
|
3304
|
+
top: s(8),
|
|
3305
|
+
left: s(8)
|
|
3306
|
+
},
|
|
3307
|
+
actionButton: {
|
|
3308
|
+
position: "absolute",
|
|
3309
|
+
top: s(8),
|
|
3310
|
+
right: s(8),
|
|
3311
|
+
width: s(32),
|
|
3312
|
+
height: s(32),
|
|
3313
|
+
borderRadius: 9999,
|
|
3314
|
+
alignItems: "center",
|
|
3315
|
+
justifyContent: "center"
|
|
3316
|
+
},
|
|
3317
|
+
meta: {
|
|
3318
|
+
paddingTop: vs(8),
|
|
3319
|
+
gap: vs(2)
|
|
3320
|
+
},
|
|
3321
|
+
title: {
|
|
3322
|
+
fontFamily: "Poppins-SemiBold",
|
|
3323
|
+
fontSize: ms(14),
|
|
3324
|
+
lineHeight: mvs(20)
|
|
3325
|
+
},
|
|
3326
|
+
subtitle: {
|
|
3327
|
+
fontFamily: "Poppins-Regular",
|
|
3328
|
+
fontSize: ms(13),
|
|
3329
|
+
lineHeight: mvs(18)
|
|
3330
|
+
},
|
|
3331
|
+
caption: {
|
|
3332
|
+
fontFamily: "Poppins-Regular",
|
|
3333
|
+
fontSize: ms(12),
|
|
3334
|
+
lineHeight: mvs(16)
|
|
2794
3335
|
}
|
|
2795
|
-
};
|
|
2796
|
-
var
|
|
2797
|
-
|
|
2798
|
-
|
|
3336
|
+
});
|
|
3337
|
+
var nativeDriver13 = reactNative.Platform.OS !== "web";
|
|
3338
|
+
function CategoryChip({
|
|
3339
|
+
item,
|
|
3340
|
+
selected,
|
|
3341
|
+
onPress
|
|
3342
|
+
}) {
|
|
3343
|
+
const { colors } = useTheme();
|
|
3344
|
+
const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
|
|
3345
|
+
const handlePressIn = () => {
|
|
3346
|
+
reactNative.Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver13, speed: 40, bounciness: 0 }).start();
|
|
3347
|
+
};
|
|
3348
|
+
const handlePressOut = () => {
|
|
3349
|
+
reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver13, speed: 40, bounciness: 4 }).start();
|
|
3350
|
+
};
|
|
3351
|
+
const bgColor = selected ? colors.primary : colors.surface;
|
|
3352
|
+
const textColor = selected ? colors.primaryForeground : colors.foregroundSubtle;
|
|
3353
|
+
const borderColor = selected ? colors.primary : colors.border;
|
|
3354
|
+
const resolvedIcon = typeof item.icon === "string" ? renderIcon(item.icon, 16, textColor) : item.icon ?? null;
|
|
3355
|
+
return /* @__PURE__ */ React25__default.default.createElement(reactNative.Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25__default.default.createElement(
|
|
3356
|
+
reactNative.TouchableOpacity,
|
|
3357
|
+
{
|
|
3358
|
+
style: [
|
|
3359
|
+
styles31.chip,
|
|
3360
|
+
{
|
|
3361
|
+
backgroundColor: bgColor,
|
|
3362
|
+
borderColor
|
|
3363
|
+
}
|
|
3364
|
+
],
|
|
3365
|
+
onPress,
|
|
3366
|
+
onPressIn: handlePressIn,
|
|
3367
|
+
onPressOut: handlePressOut,
|
|
3368
|
+
activeOpacity: 1,
|
|
3369
|
+
touchSoundDisabled: true
|
|
3370
|
+
},
|
|
3371
|
+
resolvedIcon && /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles31.chipIcon }, resolvedIcon),
|
|
3372
|
+
/* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles31.chipLabel, { color: textColor }], allowFontScaling: true }, item.label),
|
|
3373
|
+
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)))
|
|
3374
|
+
));
|
|
3375
|
+
}
|
|
3376
|
+
function CategoryStrip({
|
|
3377
|
+
categories,
|
|
3378
|
+
value,
|
|
3379
|
+
onValueChange,
|
|
3380
|
+
multiSelect = false,
|
|
3381
|
+
style,
|
|
3382
|
+
itemStyle
|
|
3383
|
+
}) {
|
|
3384
|
+
const selected = Array.isArray(value) ? value : value ? [value] : [];
|
|
3385
|
+
const handlePress = (v) => {
|
|
3386
|
+
selectionAsync();
|
|
3387
|
+
if (multiSelect) {
|
|
3388
|
+
const current = Array.isArray(value) ? value : value ? [value] : [];
|
|
3389
|
+
const next = current.includes(v) ? current.filter((x) => x !== v) : [...current, v];
|
|
3390
|
+
onValueChange?.(next);
|
|
3391
|
+
} else {
|
|
3392
|
+
onValueChange?.(v === value ? "" : v);
|
|
3393
|
+
}
|
|
3394
|
+
};
|
|
3395
|
+
return /* @__PURE__ */ React25__default.default.createElement(
|
|
3396
|
+
reactNative.ScrollView,
|
|
3397
|
+
{
|
|
3398
|
+
horizontal: true,
|
|
3399
|
+
showsHorizontalScrollIndicator: false,
|
|
3400
|
+
contentContainerStyle: [styles31.container, style],
|
|
3401
|
+
style: styles31.scroll
|
|
3402
|
+
},
|
|
3403
|
+
categories.map((cat) => /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { key: cat.value, style: itemStyle }, /* @__PURE__ */ React25__default.default.createElement(
|
|
3404
|
+
CategoryChip,
|
|
3405
|
+
{
|
|
3406
|
+
item: cat,
|
|
3407
|
+
selected: selected.includes(cat.value),
|
|
3408
|
+
onPress: () => handlePress(cat.value)
|
|
3409
|
+
}
|
|
3410
|
+
)))
|
|
3411
|
+
);
|
|
3412
|
+
}
|
|
3413
|
+
var styles31 = reactNative.StyleSheet.create({
|
|
3414
|
+
scroll: {
|
|
3415
|
+
flexGrow: 0
|
|
3416
|
+
},
|
|
3417
|
+
container: {
|
|
3418
|
+
flexDirection: "row",
|
|
3419
|
+
gap: s(8),
|
|
3420
|
+
paddingHorizontal: s(4),
|
|
3421
|
+
paddingVertical: vs(4)
|
|
3422
|
+
},
|
|
3423
|
+
chip: {
|
|
3424
|
+
flexDirection: "row",
|
|
3425
|
+
alignItems: "center",
|
|
3426
|
+
borderRadius: RADIUS.full,
|
|
3427
|
+
borderWidth: 1,
|
|
3428
|
+
paddingHorizontal: s(14),
|
|
3429
|
+
paddingVertical: vs(8),
|
|
3430
|
+
gap: s(6)
|
|
3431
|
+
},
|
|
3432
|
+
chipIcon: {
|
|
3433
|
+
alignItems: "center",
|
|
3434
|
+
justifyContent: "center"
|
|
3435
|
+
},
|
|
3436
|
+
chipLabel: {
|
|
3437
|
+
fontFamily: "Poppins-Medium",
|
|
3438
|
+
fontSize: ms(13)
|
|
3439
|
+
},
|
|
3440
|
+
chipBadge: {
|
|
3441
|
+
minWidth: 16,
|
|
3442
|
+
height: 16,
|
|
3443
|
+
borderRadius: 9999,
|
|
3444
|
+
paddingHorizontal: 3,
|
|
3445
|
+
alignItems: "center",
|
|
3446
|
+
justifyContent: "center"
|
|
3447
|
+
},
|
|
3448
|
+
chipBadgeText: {
|
|
3449
|
+
fontFamily: "Poppins-Bold",
|
|
3450
|
+
fontSize: ms(9),
|
|
3451
|
+
lineHeight: 14
|
|
3452
|
+
}
|
|
3453
|
+
});
|
|
3454
|
+
var nativeDriver14 = reactNative.Platform.OS !== "web";
|
|
3455
|
+
function Pressable2({
|
|
3456
|
+
children,
|
|
3457
|
+
onPress,
|
|
3458
|
+
pressScale = 0.98,
|
|
3459
|
+
bounciness = 4,
|
|
3460
|
+
haptics = true,
|
|
3461
|
+
style,
|
|
3462
|
+
disabled,
|
|
3463
|
+
hoverScale = 1.02,
|
|
3464
|
+
...touchableProps
|
|
3465
|
+
}) {
|
|
3466
|
+
const scale2 = React25.useRef(new reactNative.Animated.Value(1)).current;
|
|
3467
|
+
const { hovered, hoverHandlers } = useHover();
|
|
3468
|
+
const handlePressIn = () => {
|
|
3469
|
+
if (disabled) return;
|
|
3470
|
+
reactNative.Animated.spring(scale2, {
|
|
3471
|
+
toValue: pressScale,
|
|
3472
|
+
useNativeDriver: nativeDriver14,
|
|
3473
|
+
speed: 40,
|
|
3474
|
+
bounciness: 0
|
|
3475
|
+
}).start();
|
|
3476
|
+
};
|
|
3477
|
+
const handlePressOut = () => {
|
|
3478
|
+
if (disabled) return;
|
|
3479
|
+
reactNative.Animated.spring(scale2, {
|
|
3480
|
+
toValue: 1,
|
|
3481
|
+
useNativeDriver: nativeDriver14,
|
|
3482
|
+
speed: 40,
|
|
3483
|
+
bounciness
|
|
3484
|
+
}).start();
|
|
3485
|
+
};
|
|
3486
|
+
const handlePress = () => {
|
|
3487
|
+
if (disabled || !onPress) return;
|
|
3488
|
+
if (haptics) impactLight();
|
|
3489
|
+
onPress();
|
|
3490
|
+
};
|
|
3491
|
+
const hoverScaleValue = hovered && hoverScale !== 1 ? hoverScale : 1;
|
|
3492
|
+
return /* @__PURE__ */ React25__default.default.createElement(
|
|
3493
|
+
reactNative.Animated.View,
|
|
3494
|
+
{
|
|
3495
|
+
style: [
|
|
3496
|
+
{ transform: [{ scale: reactNative.Animated.multiply(scale2, hoverScaleValue) }] },
|
|
3497
|
+
style
|
|
3498
|
+
],
|
|
3499
|
+
...reactNative.Platform.OS === "web" ? hoverHandlers : {}
|
|
3500
|
+
},
|
|
3501
|
+
/* @__PURE__ */ React25__default.default.createElement(
|
|
3502
|
+
reactNative.TouchableOpacity,
|
|
3503
|
+
{
|
|
3504
|
+
onPress: handlePress,
|
|
3505
|
+
onPressIn: handlePressIn,
|
|
3506
|
+
onPressOut: handlePressOut,
|
|
3507
|
+
activeOpacity: 1,
|
|
3508
|
+
disabled,
|
|
3509
|
+
touchSoundDisabled: true,
|
|
3510
|
+
...touchableProps
|
|
3511
|
+
},
|
|
3512
|
+
children
|
|
3513
|
+
)
|
|
3514
|
+
);
|
|
3515
|
+
}
|
|
2799
3516
|
|
|
2800
3517
|
Object.defineProperty(exports, "BottomSheetModalProvider", {
|
|
2801
3518
|
enumerable: true,
|
|
@@ -2813,6 +3530,7 @@ exports.CardDescription = CardDescription;
|
|
|
2813
3530
|
exports.CardFooter = CardFooter;
|
|
2814
3531
|
exports.CardHeader = CardHeader;
|
|
2815
3532
|
exports.CardTitle = CardTitle;
|
|
3533
|
+
exports.CategoryStrip = CategoryStrip;
|
|
2816
3534
|
exports.Checkbox = Checkbox;
|
|
2817
3535
|
exports.Chip = Chip;
|
|
2818
3536
|
exports.ChipGroup = ChipGroup;
|
|
@@ -2827,7 +3545,9 @@ exports.IconButton = IconButton;
|
|
|
2827
3545
|
exports.Input = Input;
|
|
2828
3546
|
exports.LabelValue = LabelValue;
|
|
2829
3547
|
exports.ListItem = ListItem;
|
|
3548
|
+
exports.MediaCard = MediaCard;
|
|
2830
3549
|
exports.MonthPicker = MonthPicker;
|
|
3550
|
+
exports.Pressable = Pressable2;
|
|
2831
3551
|
exports.Progress = Progress;
|
|
2832
3552
|
exports.RADIUS = RADIUS;
|
|
2833
3553
|
exports.RadioGroup = RadioGroup;
|
|
@@ -2840,15 +3560,17 @@ exports.Skeleton = Skeleton;
|
|
|
2840
3560
|
exports.Slider = Slider;
|
|
2841
3561
|
exports.Spinner = Spinner;
|
|
2842
3562
|
exports.Switch = Switch;
|
|
3563
|
+
exports.TYPOGRAPHY = TYPOGRAPHY;
|
|
2843
3564
|
exports.Tabs = Tabs;
|
|
2844
3565
|
exports.TabsContent = TabsContent;
|
|
2845
|
-
exports.Text =
|
|
3566
|
+
exports.Text = Text3;
|
|
2846
3567
|
exports.Textarea = Textarea;
|
|
2847
3568
|
exports.ThemeProvider = ThemeProvider;
|
|
2848
3569
|
exports.ToastProvider = ToastProvider;
|
|
2849
3570
|
exports.Toggle = Toggle;
|
|
2850
3571
|
exports.defaultDark = defaultDark;
|
|
2851
3572
|
exports.defaultLight = defaultLight;
|
|
3573
|
+
exports.deriveColors = deriveColors;
|
|
2852
3574
|
exports.renderIcon = renderIcon;
|
|
2853
3575
|
exports.useTheme = useTheme;
|
|
2854
3576
|
exports.useToast = useToast;
|