@retray-dev/ui-kit 4.0.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 +1791 -663
- package/README.md +4 -3
- package/dist/index.d.mts +268 -83
- package/dist/index.d.ts +268 -83
- package/dist/index.js +1032 -309
- package/dist/index.mjs +1029 -311
- 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 +3 -3
- 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 +2 -2
- 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
|
|
@@ -1789,7 +2191,7 @@ function Sheet({
|
|
|
1789
2191
|
handleIndicatorStyle: [styles21.handle, { backgroundColor: colors.border }],
|
|
1790
2192
|
enablePanDownToClose: true
|
|
1791
2193
|
},
|
|
1792
|
-
/* @__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)
|
|
1793
2195
|
);
|
|
1794
2196
|
}
|
|
1795
2197
|
var styles21 = reactNative.StyleSheet.create({
|
|
@@ -1888,14 +2290,14 @@ function Select({
|
|
|
1888
2290
|
{
|
|
1889
2291
|
style: [
|
|
1890
2292
|
styles22.triggerText,
|
|
1891
|
-
{ color: selected ? colors.foreground : colors.
|
|
2293
|
+
{ color: selected ? colors.foreground : colors.foregroundMuted }
|
|
1892
2294
|
],
|
|
1893
2295
|
numberOfLines: 1,
|
|
1894
2296
|
allowFontScaling: true
|
|
1895
2297
|
},
|
|
1896
2298
|
selected?.label ?? placeholder
|
|
1897
2299
|
),
|
|
1898
|
-
/* @__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 })
|
|
1899
2301
|
)) : null, isIOS ? /* @__PURE__ */ React25__default.default.createElement(
|
|
1900
2302
|
reactNative.Modal,
|
|
1901
2303
|
{
|
|
@@ -1912,7 +2314,7 @@ function Select({
|
|
|
1912
2314
|
onValueChange: (val) => setPendingValue(val),
|
|
1913
2315
|
itemStyle: { color: colors.foreground }
|
|
1914
2316
|
},
|
|
1915
|
-
!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,
|
|
1916
2318
|
options.map((o) => /* @__PURE__ */ React25__default.default.createElement(
|
|
1917
2319
|
picker.Picker.Item,
|
|
1918
2320
|
{
|
|
@@ -1920,7 +2322,7 @@ function Select({
|
|
|
1920
2322
|
label: o.label,
|
|
1921
2323
|
value: o.value,
|
|
1922
2324
|
enabled: !o.disabled,
|
|
1923
|
-
color: o.disabled ? colors.
|
|
2325
|
+
color: o.disabled ? colors.foregroundMuted : colors.foreground
|
|
1924
2326
|
}
|
|
1925
2327
|
))
|
|
1926
2328
|
))
|
|
@@ -1964,7 +2366,7 @@ function Select({
|
|
|
1964
2366
|
styles22.webPicker,
|
|
1965
2367
|
{
|
|
1966
2368
|
borderColor: error ? colors.destructive : colors.border,
|
|
1967
|
-
color: selected ? colors.foreground : colors.
|
|
2369
|
+
color: selected ? colors.foreground : colors.foregroundMuted,
|
|
1968
2370
|
backgroundColor: colors.background,
|
|
1969
2371
|
opacity: disabled ? 0.45 : 1
|
|
1970
2372
|
}
|
|
@@ -2099,19 +2501,39 @@ function ToastNotification({ item, onDismiss }) {
|
|
|
2099
2501
|
}));
|
|
2100
2502
|
const variant = item.variant ?? "default";
|
|
2101
2503
|
const bgColor = {
|
|
2102
|
-
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,
|
|
2103
2511
|
destructive: colors.destructiveBorder,
|
|
2104
|
-
success: colors.successBorder
|
|
2512
|
+
success: colors.successBorder,
|
|
2513
|
+
warning: colors.warningBorder
|
|
2105
2514
|
}[variant];
|
|
2106
|
-
const
|
|
2107
|
-
default: colors.
|
|
2108
|
-
destructive:
|
|
2109
|
-
success:
|
|
2515
|
+
const accentColor = {
|
|
2516
|
+
default: colors.primary,
|
|
2517
|
+
destructive: colors.destructive,
|
|
2518
|
+
success: colors.success,
|
|
2519
|
+
warning: colors.warning
|
|
2110
2520
|
}[variant];
|
|
2111
|
-
const
|
|
2112
|
-
const
|
|
2113
|
-
const
|
|
2114
|
-
|
|
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 }))));
|
|
2115
2537
|
}
|
|
2116
2538
|
function ToastProvider({ children }) {
|
|
2117
2539
|
const [toasts, setToasts] = React25.useState([]);
|
|
@@ -2122,6 +2544,8 @@ function ToastProvider({ children }) {
|
|
|
2122
2544
|
notificationSuccess();
|
|
2123
2545
|
} else if (item.variant === "destructive") {
|
|
2124
2546
|
notificationError();
|
|
2547
|
+
} else if (item.variant === "warning") {
|
|
2548
|
+
notificationError();
|
|
2125
2549
|
} else {
|
|
2126
2550
|
impactLight();
|
|
2127
2551
|
}
|
|
@@ -2148,38 +2572,52 @@ var styles23 = reactNative.StyleSheet.create({
|
|
|
2148
2572
|
},
|
|
2149
2573
|
toast: {
|
|
2150
2574
|
flexDirection: "row",
|
|
2151
|
-
alignItems: "
|
|
2152
|
-
borderRadius: ms(
|
|
2153
|
-
borderWidth:
|
|
2154
|
-
paddingHorizontal: s(
|
|
2155
|
-
paddingVertical: vs(
|
|
2575
|
+
alignItems: "flex-start",
|
|
2576
|
+
borderRadius: ms(10),
|
|
2577
|
+
borderWidth: 0.5,
|
|
2578
|
+
paddingHorizontal: s(12),
|
|
2579
|
+
paddingVertical: vs(10),
|
|
2156
2580
|
shadowColor: "#000",
|
|
2157
|
-
shadowOffset: { width: 0, height:
|
|
2158
|
-
shadowOpacity: 0.
|
|
2159
|
-
shadowRadius:
|
|
2160
|
-
elevation:
|
|
2581
|
+
shadowOffset: { width: 0, height: 2 },
|
|
2582
|
+
shadowOpacity: 0.06,
|
|
2583
|
+
shadowRadius: 4,
|
|
2584
|
+
elevation: 3
|
|
2161
2585
|
},
|
|
2162
2586
|
toastContent: {
|
|
2163
2587
|
flex: 1,
|
|
2164
|
-
gap: vs(
|
|
2588
|
+
gap: vs(2)
|
|
2165
2589
|
},
|
|
2166
2590
|
leftIconContainer: {
|
|
2167
|
-
|
|
2591
|
+
marginTop: vs(1),
|
|
2168
2592
|
alignItems: "center",
|
|
2169
2593
|
justifyContent: "center",
|
|
2170
2594
|
marginRight: s(10)
|
|
2171
2595
|
},
|
|
2172
2596
|
toastTitle: {
|
|
2173
|
-
fontFamily: "Poppins-
|
|
2174
|
-
fontSize: ms(
|
|
2597
|
+
fontFamily: "Poppins-Medium",
|
|
2598
|
+
fontSize: ms(13),
|
|
2599
|
+
lineHeight: ms(18)
|
|
2175
2600
|
},
|
|
2176
2601
|
toastDescription: {
|
|
2177
2602
|
fontFamily: "Poppins-Regular",
|
|
2178
|
-
fontSize: ms(
|
|
2603
|
+
fontSize: ms(12),
|
|
2604
|
+
lineHeight: ms(17),
|
|
2605
|
+
opacity: 0.85
|
|
2179
2606
|
},
|
|
2180
|
-
|
|
2181
|
-
|
|
2607
|
+
actionButton: {
|
|
2608
|
+
paddingHorizontal: s(8),
|
|
2609
|
+
paddingVertical: vs(4),
|
|
2182
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)
|
|
2183
2621
|
}
|
|
2184
2622
|
});
|
|
2185
2623
|
function formatCurrency(raw, separator) {
|
|
@@ -2213,7 +2651,7 @@ function CurrencyInput({
|
|
|
2213
2651
|
onChangeValue?.(isNaN(raw) ? 0 : raw);
|
|
2214
2652
|
};
|
|
2215
2653
|
const inputStyle = size === "large" ? { fontFamily: "Poppins-Regular", fontSize: ms(36) } : { fontFamily: "Poppins-Regular" };
|
|
2216
|
-
const dollarIcon = renderIcon("dollar-sign", size === "large" ? 24 : 16, colors.
|
|
2654
|
+
const dollarIcon = renderIcon("dollar-sign", size === "large" ? 24 : 16, colors.foregroundMuted);
|
|
2217
2655
|
const displayValue = value && prefix && value.startsWith(prefix) ? value.slice(prefix.length) : value;
|
|
2218
2656
|
return /* @__PURE__ */ React25__default.default.createElement(
|
|
2219
2657
|
Input,
|
|
@@ -2228,7 +2666,7 @@ function CurrencyInput({
|
|
|
2228
2666
|
editable,
|
|
2229
2667
|
prefix: dollarIcon,
|
|
2230
2668
|
containerStyle,
|
|
2231
|
-
inputWrapperStyle: size === "large" ? { paddingVertical:
|
|
2669
|
+
inputWrapperStyle: size === "large" ? { paddingVertical: vs(16), minHeight: 72 } : void 0,
|
|
2232
2670
|
style: [inputStyle, style]
|
|
2233
2671
|
}
|
|
2234
2672
|
);
|
|
@@ -2254,7 +2692,8 @@ var styles24 = reactNative.StyleSheet.create({
|
|
|
2254
2692
|
container: {},
|
|
2255
2693
|
amount: {
|
|
2256
2694
|
fontFamily: "Poppins-Bold",
|
|
2257
|
-
fontSize: ms(56)
|
|
2695
|
+
fontSize: ms(56),
|
|
2696
|
+
letterSpacing: -2
|
|
2258
2697
|
}
|
|
2259
2698
|
});
|
|
2260
2699
|
var nativeDriver10 = reactNative.Platform.OS !== "web";
|
|
@@ -2304,7 +2743,7 @@ function ListItem({
|
|
|
2304
2743
|
onPress?.();
|
|
2305
2744
|
};
|
|
2306
2745
|
const effectiveLeft = leftIcon ? renderIcon(leftIcon, 24, leftIconColor ?? colors.foreground) : leftRender ?? icon;
|
|
2307
|
-
const effectiveRight = rightIcon ? renderIcon(rightIcon, 24, rightIconColor ?? colors.
|
|
2746
|
+
const effectiveRight = rightIcon ? renderIcon(rightIcon, 24, rightIconColor ?? colors.foregroundMuted) : rightRender ?? trailing;
|
|
2308
2747
|
const cardStyle = variant === "card" ? {
|
|
2309
2748
|
backgroundColor: colors.card,
|
|
2310
2749
|
borderRadius: 12,
|
|
@@ -2339,7 +2778,7 @@ function ListItem({
|
|
|
2339
2778
|
), subtitle ? /* @__PURE__ */ React25__default.default.createElement(
|
|
2340
2779
|
reactNative.Text,
|
|
2341
2780
|
{
|
|
2342
|
-
style: [styles25.subtitle, { color: colors.
|
|
2781
|
+
style: [styles25.subtitle, { color: colors.foregroundMuted }, subtitleStyle],
|
|
2343
2782
|
numberOfLines: 2,
|
|
2344
2783
|
allowFontScaling: true
|
|
2345
2784
|
},
|
|
@@ -2347,7 +2786,7 @@ function ListItem({
|
|
|
2347
2786
|
) : null, caption ? /* @__PURE__ */ React25__default.default.createElement(
|
|
2348
2787
|
reactNative.Text,
|
|
2349
2788
|
{
|
|
2350
|
-
style: [styles25.caption, { color: colors.
|
|
2789
|
+
style: [styles25.caption, { color: colors.foregroundMuted }, captionStyle],
|
|
2351
2790
|
numberOfLines: 1,
|
|
2352
2791
|
allowFontScaling: true
|
|
2353
2792
|
},
|
|
@@ -2356,11 +2795,11 @@ function ListItem({
|
|
|
2356
2795
|
effectiveRight !== void 0 ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles25.rightContainer }, typeof effectiveRight === "string" ? /* @__PURE__ */ React25__default.default.createElement(
|
|
2357
2796
|
reactNative.Text,
|
|
2358
2797
|
{
|
|
2359
|
-
style: [styles25.rightText, { color: colors.
|
|
2798
|
+
style: [styles25.rightText, { color: colors.foregroundMuted }],
|
|
2360
2799
|
allowFontScaling: true
|
|
2361
2800
|
},
|
|
2362
2801
|
effectiveRight
|
|
2363
|
-
) : 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
|
|
2364
2803
|
), showSeparator ? /* @__PURE__ */ React25__default.default.createElement(
|
|
2365
2804
|
reactNative.View,
|
|
2366
2805
|
{
|
|
@@ -2462,7 +2901,7 @@ function Chip({ label, selected = false, onPress, icon, iconName, style }) {
|
|
|
2462
2901
|
};
|
|
2463
2902
|
const backgroundColor = pressAnim.interpolate({
|
|
2464
2903
|
inputRange: [0, 1],
|
|
2465
|
-
outputRange: [colors.
|
|
2904
|
+
outputRange: [colors.surface, colors.primary]
|
|
2466
2905
|
});
|
|
2467
2906
|
const textColor = pressAnim.interpolate({
|
|
2468
2907
|
inputRange: [0, 1],
|
|
@@ -2584,11 +3023,11 @@ function ConfirmDialog({
|
|
|
2584
3023
|
handleIndicatorStyle: [styles27.handle, { backgroundColor: colors.border }],
|
|
2585
3024
|
enablePanDownToClose: true
|
|
2586
3025
|
},
|
|
2587
|
-
/* @__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(
|
|
2588
3027
|
Button,
|
|
2589
3028
|
{
|
|
2590
3029
|
label: cancelLabel,
|
|
2591
|
-
variant: "
|
|
3030
|
+
variant: "secondary",
|
|
2592
3031
|
fullWidth: true,
|
|
2593
3032
|
onPress: onCancel,
|
|
2594
3033
|
icon: /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "x", size: 15, color: colors.foreground })
|
|
@@ -2644,7 +3083,7 @@ var styles27 = reactNative.StyleSheet.create({
|
|
|
2644
3083
|
});
|
|
2645
3084
|
function LabelValue({ label, value, style }) {
|
|
2646
3085
|
const { colors } = useTheme();
|
|
2647
|
-
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles28.container, style] }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles28.label, { color: colors.
|
|
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);
|
|
2648
3087
|
}
|
|
2649
3088
|
var styles28 = reactNative.StyleSheet.create({
|
|
2650
3089
|
container: {
|
|
@@ -2737,64 +3176,343 @@ var styles29 = reactNative.StyleSheet.create({
|
|
|
2737
3176
|
minWidth: s(160)
|
|
2738
3177
|
}
|
|
2739
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
|
+
}
|
|
2740
3188
|
|
|
2741
|
-
// src/
|
|
2742
|
-
var
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
"
|
|
2749
|
-
"3xl": 48
|
|
2750
|
-
};
|
|
2751
|
-
var ICON_SIZES = {
|
|
2752
|
-
sm: 14,
|
|
2753
|
-
md: 18,
|
|
2754
|
-
lg: 22,
|
|
2755
|
-
xl: 28,
|
|
2756
|
-
"2xl": 32
|
|
2757
|
-
};
|
|
2758
|
-
var RADIUS = {
|
|
2759
|
-
sm: 4,
|
|
2760
|
-
md: 8,
|
|
2761
|
-
lg: 12,
|
|
2762
|
-
xl: 16,
|
|
2763
|
-
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
|
|
2764
3197
|
};
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
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"
|
|
2772
3285
|
},
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
shadowOpacity: 0.12,
|
|
2777
|
-
shadowRadius: 8,
|
|
2778
|
-
elevation: 5
|
|
3286
|
+
cardHovered: {
|
|
3287
|
+
// Web hover: lift shadow
|
|
3288
|
+
...SHADOWS.md
|
|
2779
3289
|
},
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
shadowOpacity: 0.2,
|
|
2784
|
-
shadowRadius: 16,
|
|
2785
|
-
elevation: 10
|
|
3290
|
+
imageContainer: {
|
|
3291
|
+
borderRadius: RADIUS.md,
|
|
3292
|
+
overflow: "hidden"
|
|
2786
3293
|
},
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
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)
|
|
2793
3335
|
}
|
|
2794
|
-
};
|
|
2795
|
-
var
|
|
2796
|
-
|
|
2797
|
-
|
|
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
|
+
}
|
|
2798
3516
|
|
|
2799
3517
|
Object.defineProperty(exports, "BottomSheetModalProvider", {
|
|
2800
3518
|
enumerable: true,
|
|
@@ -2812,6 +3530,7 @@ exports.CardDescription = CardDescription;
|
|
|
2812
3530
|
exports.CardFooter = CardFooter;
|
|
2813
3531
|
exports.CardHeader = CardHeader;
|
|
2814
3532
|
exports.CardTitle = CardTitle;
|
|
3533
|
+
exports.CategoryStrip = CategoryStrip;
|
|
2815
3534
|
exports.Checkbox = Checkbox;
|
|
2816
3535
|
exports.Chip = Chip;
|
|
2817
3536
|
exports.ChipGroup = ChipGroup;
|
|
@@ -2826,7 +3545,9 @@ exports.IconButton = IconButton;
|
|
|
2826
3545
|
exports.Input = Input;
|
|
2827
3546
|
exports.LabelValue = LabelValue;
|
|
2828
3547
|
exports.ListItem = ListItem;
|
|
3548
|
+
exports.MediaCard = MediaCard;
|
|
2829
3549
|
exports.MonthPicker = MonthPicker;
|
|
3550
|
+
exports.Pressable = Pressable2;
|
|
2830
3551
|
exports.Progress = Progress;
|
|
2831
3552
|
exports.RADIUS = RADIUS;
|
|
2832
3553
|
exports.RadioGroup = RadioGroup;
|
|
@@ -2839,15 +3560,17 @@ exports.Skeleton = Skeleton;
|
|
|
2839
3560
|
exports.Slider = Slider;
|
|
2840
3561
|
exports.Spinner = Spinner;
|
|
2841
3562
|
exports.Switch = Switch;
|
|
3563
|
+
exports.TYPOGRAPHY = TYPOGRAPHY;
|
|
2842
3564
|
exports.Tabs = Tabs;
|
|
2843
3565
|
exports.TabsContent = TabsContent;
|
|
2844
|
-
exports.Text =
|
|
3566
|
+
exports.Text = Text3;
|
|
2845
3567
|
exports.Textarea = Textarea;
|
|
2846
3568
|
exports.ThemeProvider = ThemeProvider;
|
|
2847
3569
|
exports.ToastProvider = ToastProvider;
|
|
2848
3570
|
exports.Toggle = Toggle;
|
|
2849
3571
|
exports.defaultDark = defaultDark;
|
|
2850
3572
|
exports.defaultLight = defaultLight;
|
|
3573
|
+
exports.deriveColors = deriveColors;
|
|
2851
3574
|
exports.renderIcon = renderIcon;
|
|
2852
3575
|
exports.useTheme = useTheme;
|
|
2853
3576
|
exports.useToast = useToast;
|