@blinkdotnew/mobile-ui 2.0.0-alpha.12 → 2.0.0-alpha.13
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/dist/index.d.mts +88 -1
- package/dist/index.d.ts +88 -1
- package/dist/index.js +610 -115
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +525 -35
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -8,13 +8,13 @@ var blinkConfig = createTamagui({
|
|
|
8
8
|
// src/index.ts
|
|
9
9
|
import { defaultConfig as defaultConfig2 } from "@tamagui/config/v5";
|
|
10
10
|
import {
|
|
11
|
-
View as
|
|
11
|
+
View as View7,
|
|
12
12
|
Stack,
|
|
13
13
|
SizableStack,
|
|
14
14
|
ThemeableStack,
|
|
15
15
|
Frame,
|
|
16
|
-
XStack as
|
|
17
|
-
YStack as
|
|
16
|
+
XStack as XStack41,
|
|
17
|
+
YStack as YStack45,
|
|
18
18
|
ZStack,
|
|
19
19
|
ScrollView as ScrollView7,
|
|
20
20
|
Circle as Circle9,
|
|
@@ -38,22 +38,22 @@ import {
|
|
|
38
38
|
H6 as H62,
|
|
39
39
|
Heading,
|
|
40
40
|
Paragraph,
|
|
41
|
-
SizableText as
|
|
41
|
+
SizableText as SizableText48,
|
|
42
42
|
Text,
|
|
43
43
|
Label,
|
|
44
44
|
Button as Button11,
|
|
45
45
|
Input as Input5,
|
|
46
46
|
TextArea,
|
|
47
|
-
Switch as
|
|
47
|
+
Switch as Switch3,
|
|
48
48
|
Checkbox,
|
|
49
|
-
Slider,
|
|
49
|
+
Slider as Slider2,
|
|
50
50
|
RadioGroup,
|
|
51
51
|
Select,
|
|
52
52
|
Fieldset,
|
|
53
53
|
Form,
|
|
54
54
|
Card as Card2,
|
|
55
55
|
Avatar as Avatar2,
|
|
56
|
-
Separator as
|
|
56
|
+
Separator as Separator7,
|
|
57
57
|
Image as Image9,
|
|
58
58
|
Progress,
|
|
59
59
|
Spinner as Spinner2,
|
|
@@ -76,7 +76,7 @@ import {
|
|
|
76
76
|
Adapt,
|
|
77
77
|
VisuallyHidden,
|
|
78
78
|
Unspaced,
|
|
79
|
-
Theme,
|
|
79
|
+
Theme as Theme2,
|
|
80
80
|
TamaguiProvider,
|
|
81
81
|
TamaguiProvider as TamaguiProvider2,
|
|
82
82
|
createTamagui as createTamagui2,
|
|
@@ -89,7 +89,7 @@ import {
|
|
|
89
89
|
addTheme,
|
|
90
90
|
updateTheme,
|
|
91
91
|
replaceTheme,
|
|
92
|
-
styled as
|
|
92
|
+
styled as styled14,
|
|
93
93
|
withStaticProperties as withStaticProperties2,
|
|
94
94
|
isWeb,
|
|
95
95
|
isClient,
|
|
@@ -100,7 +100,7 @@ import {
|
|
|
100
100
|
composeRefs,
|
|
101
101
|
composeEventHandlers,
|
|
102
102
|
useTheme,
|
|
103
|
-
useMedia,
|
|
103
|
+
useMedia as useMedia2,
|
|
104
104
|
useThemeName,
|
|
105
105
|
useControllableState,
|
|
106
106
|
useEvent,
|
|
@@ -2311,21 +2311,26 @@ function ChipGroup({ chips, selected = [], onSelectionChange, multiSelect = true
|
|
|
2311
2311
|
}
|
|
2312
2312
|
|
|
2313
2313
|
// src/patterns/OTPInput.tsx
|
|
2314
|
-
import { useCallback as useCallback4, useRef as useRef2 } from "react";
|
|
2314
|
+
import { useCallback as useCallback4, useRef as useRef2, useState as useState11 } from "react";
|
|
2315
|
+
import { Platform } from "react-native";
|
|
2315
2316
|
import { Input as Input3, SizableText as SizableText40, XStack as XStack33, YStack as YStack37 } from "tamagui";
|
|
2316
2317
|
import { jsx as jsx46, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
2317
2318
|
function OTPInput({ length = 6, value = "", onChange, onComplete, error, autoFocus, secureEntry }) {
|
|
2318
2319
|
const inputRef = useRef2(null);
|
|
2320
|
+
const [focused, setFocused] = useState11(false);
|
|
2319
2321
|
const digits = value.padEnd(length, " ").slice(0, length);
|
|
2320
2322
|
const handleChange = useCallback4((text) => {
|
|
2321
2323
|
const cleaned = text.replace(/\D/g, "").slice(0, length);
|
|
2322
2324
|
onChange?.(cleaned);
|
|
2323
2325
|
if (cleaned.length === length) onComplete?.(cleaned);
|
|
2324
2326
|
}, [length, onChange, onComplete]);
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
+
const focusInput = useCallback4(() => {
|
|
2328
|
+
inputRef.current?.focus();
|
|
2329
|
+
}, []);
|
|
2330
|
+
return /* @__PURE__ */ jsxs37(YStack37, { position: "relative", children: [
|
|
2331
|
+
/* @__PURE__ */ jsx46(XStack33, { gap: "$2", justifyContent: "center", children: Array.from({ length }, (_, i) => {
|
|
2327
2332
|
const char = digits[i]?.trim();
|
|
2328
|
-
const
|
|
2333
|
+
const isCursor = focused && value.length === i;
|
|
2329
2334
|
return /* @__PURE__ */ jsxs37(
|
|
2330
2335
|
YStack37,
|
|
2331
2336
|
{
|
|
@@ -2333,20 +2338,59 @@ function OTPInput({ length = 6, value = "", onChange, onComplete, error, autoFoc
|
|
|
2333
2338
|
height: 56,
|
|
2334
2339
|
borderRadius: "$3",
|
|
2335
2340
|
borderWidth: 2,
|
|
2336
|
-
borderColor: error ? "$red9" :
|
|
2337
|
-
backgroundColor: error ? "$red2" : "$color2",
|
|
2341
|
+
borderColor: error ? "$red9" : isCursor ? "$color9" : char ? "$color7" : "$color5",
|
|
2342
|
+
backgroundColor: error ? "$red2" : isCursor ? "$color2" : "$color1",
|
|
2338
2343
|
alignItems: "center",
|
|
2339
2344
|
justifyContent: "center",
|
|
2340
2345
|
animation: "quick",
|
|
2346
|
+
pointerEvents: "none",
|
|
2341
2347
|
children: [
|
|
2342
2348
|
/* @__PURE__ */ jsx46(SizableText40, { size: "$7", fontWeight: "600", color: "$color12", children: char ? secureEntry ? "\u25CF" : char : "" }),
|
|
2343
|
-
|
|
2349
|
+
isCursor && /* @__PURE__ */ jsx46(
|
|
2350
|
+
YStack37,
|
|
2351
|
+
{
|
|
2352
|
+
position: "absolute",
|
|
2353
|
+
bottom: 10,
|
|
2354
|
+
width: 20,
|
|
2355
|
+
height: 2,
|
|
2356
|
+
backgroundColor: "$color9",
|
|
2357
|
+
animation: "quick"
|
|
2358
|
+
}
|
|
2359
|
+
)
|
|
2344
2360
|
]
|
|
2345
2361
|
},
|
|
2346
2362
|
i
|
|
2347
2363
|
);
|
|
2348
2364
|
}) }),
|
|
2349
|
-
/* @__PURE__ */ jsx46(
|
|
2365
|
+
Platform.OS === "web" ? /* @__PURE__ */ jsx46(
|
|
2366
|
+
"input",
|
|
2367
|
+
{
|
|
2368
|
+
ref: inputRef,
|
|
2369
|
+
type: "text",
|
|
2370
|
+
inputMode: "numeric",
|
|
2371
|
+
pattern: "[0-9]*",
|
|
2372
|
+
autoComplete: "one-time-code",
|
|
2373
|
+
maxLength: length,
|
|
2374
|
+
value,
|
|
2375
|
+
autoFocus,
|
|
2376
|
+
onChange: (e) => handleChange(e.target.value),
|
|
2377
|
+
onFocus: () => setFocused(true),
|
|
2378
|
+
onBlur: () => setFocused(false),
|
|
2379
|
+
style: {
|
|
2380
|
+
position: "absolute",
|
|
2381
|
+
top: 0,
|
|
2382
|
+
left: 0,
|
|
2383
|
+
right: 0,
|
|
2384
|
+
bottom: 0,
|
|
2385
|
+
width: "100%",
|
|
2386
|
+
height: "100%",
|
|
2387
|
+
opacity: 0,
|
|
2388
|
+
fontSize: 16,
|
|
2389
|
+
caretColor: "transparent",
|
|
2390
|
+
cursor: "pointer"
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
) : /* @__PURE__ */ jsx46(
|
|
2350
2394
|
Input3,
|
|
2351
2395
|
{
|
|
2352
2396
|
ref: inputRef,
|
|
@@ -2355,17 +2399,22 @@ function OTPInput({ length = 6, value = "", onChange, onComplete, error, autoFoc
|
|
|
2355
2399
|
keyboardType: "number-pad",
|
|
2356
2400
|
maxLength: length,
|
|
2357
2401
|
autoFocus,
|
|
2402
|
+
onFocus: () => setFocused(true),
|
|
2403
|
+
onBlur: () => setFocused(false),
|
|
2358
2404
|
position: "absolute",
|
|
2405
|
+
top: 0,
|
|
2406
|
+
left: 0,
|
|
2407
|
+
right: 0,
|
|
2408
|
+
bottom: 0,
|
|
2359
2409
|
opacity: 0,
|
|
2360
|
-
|
|
2361
|
-
height: 1
|
|
2410
|
+
fontSize: 16
|
|
2362
2411
|
}
|
|
2363
2412
|
)
|
|
2364
2413
|
] });
|
|
2365
2414
|
}
|
|
2366
2415
|
|
|
2367
2416
|
// src/patterns/PasswordInput.tsx
|
|
2368
|
-
import { useState as
|
|
2417
|
+
import { useState as useState12, useCallback as useCallback5 } from "react";
|
|
2369
2418
|
import { Input as Input4, SizableText as SizableText41, XStack as XStack34, YStack as YStack38 } from "tamagui";
|
|
2370
2419
|
import { jsx as jsx47, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
2371
2420
|
function getStrength(pw) {
|
|
@@ -2376,7 +2425,7 @@ function getStrength(pw) {
|
|
|
2376
2425
|
return { label: "Strong", color: "$green9", width: "100%" };
|
|
2377
2426
|
}
|
|
2378
2427
|
function PasswordInput({ value = "", onChangeText, placeholder = "Password", label, error, size = "$4", strengthIndicator }) {
|
|
2379
|
-
const [visible, setVisible] =
|
|
2428
|
+
const [visible, setVisible] = useState12(false);
|
|
2380
2429
|
const toggle = useCallback5(() => setVisible((v) => !v), []);
|
|
2381
2430
|
const strength = getStrength(value);
|
|
2382
2431
|
return /* @__PURE__ */ jsxs38(YStack38, { gap: "$1.5", children: [
|
|
@@ -2475,7 +2524,7 @@ function AvatarGroup({ avatars, max = 4, size = 36, overlap = 10 }) {
|
|
|
2475
2524
|
}
|
|
2476
2525
|
|
|
2477
2526
|
// src/patterns/SwipeCards.tsx
|
|
2478
|
-
import { useState as
|
|
2527
|
+
import { useState as useState13, useCallback as useCallback6 } from "react";
|
|
2479
2528
|
import { Circle as Circle8, SizableText as SizableText43, XStack as XStack36, YStack as YStack39 } from "tamagui";
|
|
2480
2529
|
import { jsx as jsx49, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
2481
2530
|
var STACK_SIZE = 3;
|
|
@@ -2494,8 +2543,8 @@ function SwipeCards({
|
|
|
2494
2543
|
rightLabel = "Like",
|
|
2495
2544
|
emptyMessage = "No more cards"
|
|
2496
2545
|
}) {
|
|
2497
|
-
const [index, setIndex] =
|
|
2498
|
-
const [exitDir, setExitDir] =
|
|
2546
|
+
const [index, setIndex] = useState13(0);
|
|
2547
|
+
const [exitDir, setExitDir] = useState13(null);
|
|
2499
2548
|
const remaining = items.slice(index);
|
|
2500
2549
|
const isEmpty = remaining.length === 0;
|
|
2501
2550
|
const handleSwipe = useCallback6((dir) => {
|
|
@@ -2650,6 +2699,442 @@ function GlassCard({
|
|
|
2650
2699
|
}
|
|
2651
2700
|
);
|
|
2652
2701
|
}
|
|
2702
|
+
|
|
2703
|
+
// src/patterns/DataTable.tsx
|
|
2704
|
+
import { useMemo, useState as useState14 } from "react";
|
|
2705
|
+
import { SizableText as SizableText44, Separator as Separator5, XStack as XStack37, YStack as YStack41, useMedia, styled as styled13, View as View6 } from "tamagui";
|
|
2706
|
+
import { jsx as jsx51, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
2707
|
+
var TH = styled13(View6, { padding: "$3", justifyContent: "center" });
|
|
2708
|
+
var TD = styled13(View6, { padding: "$3", justifyContent: "center" });
|
|
2709
|
+
function StatusBadge({ status }) {
|
|
2710
|
+
const isActive = status.toLowerCase() === "active";
|
|
2711
|
+
return /* @__PURE__ */ jsxs41(XStack37, { gap: "$2", alignItems: "center", children: [
|
|
2712
|
+
/* @__PURE__ */ jsx51(
|
|
2713
|
+
View6,
|
|
2714
|
+
{
|
|
2715
|
+
width: 8,
|
|
2716
|
+
height: 8,
|
|
2717
|
+
borderRadius: 4,
|
|
2718
|
+
backgroundColor: isActive ? "$green9" : "$orange9"
|
|
2719
|
+
}
|
|
2720
|
+
),
|
|
2721
|
+
/* @__PURE__ */ jsx51(SizableText44, { size: "$3", color: "$color11", children: status })
|
|
2722
|
+
] });
|
|
2723
|
+
}
|
|
2724
|
+
function HeaderCell({ col, sort, onSort }) {
|
|
2725
|
+
const active = sort?.key === col.key;
|
|
2726
|
+
const indicator = active ? sort.dir === "asc" ? " \u25B2" : " \u25BC" : "";
|
|
2727
|
+
return /* @__PURE__ */ jsx51(
|
|
2728
|
+
TH,
|
|
2729
|
+
{
|
|
2730
|
+
width: col.width,
|
|
2731
|
+
flexDirection: "row",
|
|
2732
|
+
alignItems: "center",
|
|
2733
|
+
cursor: col.sortable ? "pointer" : void 0,
|
|
2734
|
+
onPress: col.sortable ? onSort : void 0,
|
|
2735
|
+
pressStyle: col.sortable ? { opacity: 0.7 } : void 0,
|
|
2736
|
+
children: /* @__PURE__ */ jsxs41(
|
|
2737
|
+
SizableText44,
|
|
2738
|
+
{
|
|
2739
|
+
size: "$2",
|
|
2740
|
+
fontWeight: "700",
|
|
2741
|
+
color: active ? "$color12" : "$color9",
|
|
2742
|
+
textTransform: "uppercase",
|
|
2743
|
+
letterSpacing: 0.5,
|
|
2744
|
+
children: [
|
|
2745
|
+
col.header,
|
|
2746
|
+
indicator
|
|
2747
|
+
]
|
|
2748
|
+
}
|
|
2749
|
+
)
|
|
2750
|
+
},
|
|
2751
|
+
col.key
|
|
2752
|
+
);
|
|
2753
|
+
}
|
|
2754
|
+
function TableRow({ row, columns, onPress, odd }) {
|
|
2755
|
+
return /* @__PURE__ */ jsx51(
|
|
2756
|
+
XStack37,
|
|
2757
|
+
{
|
|
2758
|
+
backgroundColor: odd ? "$color2" : "transparent",
|
|
2759
|
+
borderBottomWidth: 0.5,
|
|
2760
|
+
borderColor: "$color4",
|
|
2761
|
+
hoverStyle: { backgroundColor: "$color3" },
|
|
2762
|
+
cursor: onPress ? "pointer" : void 0,
|
|
2763
|
+
onPress: onPress ? () => onPress(row) : void 0,
|
|
2764
|
+
pressStyle: onPress ? { opacity: 0.85 } : void 0,
|
|
2765
|
+
animation: "quick",
|
|
2766
|
+
children: columns.map((col) => /* @__PURE__ */ jsx51(TD, { width: col.width, flex: col.width ? void 0 : 1, children: col.render ? col.render(row[col.key], row) : /* @__PURE__ */ jsx51(SizableText44, { size: "$3", color: "$color11", children: String(row[col.key] ?? "") }) }, col.key))
|
|
2767
|
+
}
|
|
2768
|
+
);
|
|
2769
|
+
}
|
|
2770
|
+
function CardRow({ row, columns, onPress }) {
|
|
2771
|
+
return /* @__PURE__ */ jsx51(
|
|
2772
|
+
YStack41,
|
|
2773
|
+
{
|
|
2774
|
+
backgroundColor: "$color1",
|
|
2775
|
+
borderRadius: "$4",
|
|
2776
|
+
borderWidth: 1,
|
|
2777
|
+
borderColor: "$color4",
|
|
2778
|
+
padding: "$3",
|
|
2779
|
+
gap: "$2",
|
|
2780
|
+
onPress: onPress ? () => onPress(row) : void 0,
|
|
2781
|
+
pressStyle: onPress ? { scale: 0.98, opacity: 0.9 } : void 0,
|
|
2782
|
+
animation: "quick",
|
|
2783
|
+
children: columns.map((col, i) => /* @__PURE__ */ jsxs41(YStack41, { children: [
|
|
2784
|
+
i > 0 && /* @__PURE__ */ jsx51(Separator5, { marginVertical: "$1.5", borderColor: "$color4" }),
|
|
2785
|
+
/* @__PURE__ */ jsxs41(XStack37, { justifyContent: "space-between", alignItems: "center", children: [
|
|
2786
|
+
/* @__PURE__ */ jsx51(SizableText44, { size: "$2", color: "$color9", fontWeight: "600", children: col.header }),
|
|
2787
|
+
col.render ? col.render(row[col.key], row) : /* @__PURE__ */ jsx51(SizableText44, { size: "$3", color: "$color11", children: String(row[col.key] ?? "") })
|
|
2788
|
+
] })
|
|
2789
|
+
] }, col.key))
|
|
2790
|
+
}
|
|
2791
|
+
);
|
|
2792
|
+
}
|
|
2793
|
+
function DataTable({ columns, data, onRowPress, emptyMessage = "No data" }) {
|
|
2794
|
+
const [sort, setSort] = useState14(null);
|
|
2795
|
+
const media = useMedia();
|
|
2796
|
+
const isSmall = media.sm;
|
|
2797
|
+
const sorted = useMemo(() => {
|
|
2798
|
+
if (!sort) return data;
|
|
2799
|
+
return [...data].sort((a, b) => {
|
|
2800
|
+
const av = a[sort.key], bv = b[sort.key];
|
|
2801
|
+
const cmp = typeof av === "number" && typeof bv === "number" ? av - bv : String(av ?? "").localeCompare(String(bv ?? ""));
|
|
2802
|
+
return sort.dir === "asc" ? cmp : -cmp;
|
|
2803
|
+
});
|
|
2804
|
+
}, [data, sort]);
|
|
2805
|
+
const toggleSort = (key) => setSort((s) => s?.key === key ? { key, dir: s.dir === "asc" ? "desc" : "asc" } : { key, dir: "asc" });
|
|
2806
|
+
if (!data.length) {
|
|
2807
|
+
return /* @__PURE__ */ jsx51(YStack41, { padding: "$6", alignItems: "center", children: /* @__PURE__ */ jsx51(SizableText44, { size: "$4", color: "$color9", children: emptyMessage }) });
|
|
2808
|
+
}
|
|
2809
|
+
if (isSmall) {
|
|
2810
|
+
return /* @__PURE__ */ jsx51(YStack41, { gap: "$3", children: sorted.map((row, i) => /* @__PURE__ */ jsx51(CardRow, { row, columns, onPress: onRowPress }, i)) });
|
|
2811
|
+
}
|
|
2812
|
+
return /* @__PURE__ */ jsxs41(YStack41, { borderWidth: 1, borderColor: "$color4", borderRadius: "$4", overflow: "hidden", children: [
|
|
2813
|
+
/* @__PURE__ */ jsx51(XStack37, { backgroundColor: "$color1", borderBottomWidth: 1, borderColor: "$color4", children: columns.map((col) => /* @__PURE__ */ jsx51(HeaderCell, { col, sort, onSort: () => toggleSort(col.key) }, col.key)) }),
|
|
2814
|
+
sorted.map((row, i) => /* @__PURE__ */ jsx51(TableRow, { row, columns, onPress: onRowPress, odd: i % 2 === 1 }, i))
|
|
2815
|
+
] });
|
|
2816
|
+
}
|
|
2817
|
+
|
|
2818
|
+
// src/patterns/DatePicker.tsx
|
|
2819
|
+
import { useCallback as useCallback7, useMemo as useMemo2, useState as useState15 } from "react";
|
|
2820
|
+
import { SizableText as SizableText45, XStack as XStack38, YStack as YStack42 } from "tamagui";
|
|
2821
|
+
import { jsx as jsx52, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
2822
|
+
var MONTH_NAMES = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
2823
|
+
var DAY_LABELS_SUN = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
2824
|
+
var DAY_LABELS_MON = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
|
|
2825
|
+
function daysInMonth(year, month) {
|
|
2826
|
+
return new Date(year, month + 1, 0).getDate();
|
|
2827
|
+
}
|
|
2828
|
+
function sameDay(a, b) {
|
|
2829
|
+
return a ? a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate() : false;
|
|
2830
|
+
}
|
|
2831
|
+
function buildGrid(year, month, startDay) {
|
|
2832
|
+
const total = daysInMonth(year, month);
|
|
2833
|
+
const firstWeekday = new Date(year, month, 1).getDay();
|
|
2834
|
+
const offset = (firstWeekday - startDay + 7) % 7;
|
|
2835
|
+
const prevTotal = daysInMonth(year, month - 1);
|
|
2836
|
+
const cells = [];
|
|
2837
|
+
for (let i = offset - 1; i >= 0; i--)
|
|
2838
|
+
cells.push({ day: prevTotal - i, month: month - 1, year: month === 0 ? year - 1 : year, outside: true });
|
|
2839
|
+
for (let d = 1; d <= total; d++)
|
|
2840
|
+
cells.push({ day: d, month, year, outside: false });
|
|
2841
|
+
while (cells.length < 42)
|
|
2842
|
+
cells.push({ day: cells.length - offset - total + 1, month: month + 1, year: month === 11 ? year + 1 : year, outside: true });
|
|
2843
|
+
return cells;
|
|
2844
|
+
}
|
|
2845
|
+
function NavButton({ label, onPress }) {
|
|
2846
|
+
return /* @__PURE__ */ jsx52(
|
|
2847
|
+
XStack38,
|
|
2848
|
+
{
|
|
2849
|
+
width: 36,
|
|
2850
|
+
height: 36,
|
|
2851
|
+
borderRadius: "$10",
|
|
2852
|
+
alignItems: "center",
|
|
2853
|
+
justifyContent: "center",
|
|
2854
|
+
backgroundColor: "$color3",
|
|
2855
|
+
pressStyle: { scale: 0.92, backgroundColor: "$color5" },
|
|
2856
|
+
animation: "quick",
|
|
2857
|
+
onPress,
|
|
2858
|
+
cursor: "pointer",
|
|
2859
|
+
children: /* @__PURE__ */ jsx52(SizableText45, { size: "$5", color: "$color11", fontWeight: "600", children: label })
|
|
2860
|
+
}
|
|
2861
|
+
);
|
|
2862
|
+
}
|
|
2863
|
+
function DatePicker({ value, onDateChange, minDate, maxDate, startDay = 1 }) {
|
|
2864
|
+
const today = useMemo2(() => /* @__PURE__ */ new Date(), []);
|
|
2865
|
+
const [viewMonth, setViewMonth] = useState15(value?.getMonth() ?? today.getMonth());
|
|
2866
|
+
const [viewYear, setViewYear] = useState15(value?.getFullYear() ?? today.getFullYear());
|
|
2867
|
+
const headers = startDay === 1 ? DAY_LABELS_MON : DAY_LABELS_SUN;
|
|
2868
|
+
const grid = useMemo2(() => buildGrid(viewYear, viewMonth, startDay), [viewYear, viewMonth, startDay]);
|
|
2869
|
+
const navigate = useCallback7((dir) => {
|
|
2870
|
+
setViewMonth((m) => {
|
|
2871
|
+
const next = m + dir;
|
|
2872
|
+
if (next < 0) {
|
|
2873
|
+
setViewYear((y) => y - 1);
|
|
2874
|
+
return 11;
|
|
2875
|
+
}
|
|
2876
|
+
if (next > 11) {
|
|
2877
|
+
setViewYear((y) => y + 1);
|
|
2878
|
+
return 0;
|
|
2879
|
+
}
|
|
2880
|
+
return next;
|
|
2881
|
+
});
|
|
2882
|
+
}, []);
|
|
2883
|
+
const isDisabled = useCallback7((d) => {
|
|
2884
|
+
if (minDate && d < new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate())) return true;
|
|
2885
|
+
if (maxDate && d > new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate())) return true;
|
|
2886
|
+
return false;
|
|
2887
|
+
}, [minDate, maxDate]);
|
|
2888
|
+
return /* @__PURE__ */ jsxs42(YStack42, { backgroundColor: "$color2", borderRadius: "$4", padding: "$3", gap: "$2", animation: "quick", children: [
|
|
2889
|
+
/* @__PURE__ */ jsxs42(XStack38, { alignItems: "center", justifyContent: "space-between", children: [
|
|
2890
|
+
/* @__PURE__ */ jsx52(NavButton, { label: "\u2039", onPress: () => navigate(-1) }),
|
|
2891
|
+
/* @__PURE__ */ jsxs42(SizableText45, { size: "$4", fontWeight: "700", color: "$color12", children: [
|
|
2892
|
+
MONTH_NAMES[viewMonth],
|
|
2893
|
+
" ",
|
|
2894
|
+
viewYear
|
|
2895
|
+
] }),
|
|
2896
|
+
/* @__PURE__ */ jsx52(NavButton, { label: "\u203A", onPress: () => navigate(1) })
|
|
2897
|
+
] }),
|
|
2898
|
+
/* @__PURE__ */ jsx52(XStack38, { children: headers.map((h) => /* @__PURE__ */ jsx52(SizableText45, { size: "$2", color: "$color8", fontWeight: "600", textAlign: "center", flex: 1, children: h }, h)) }),
|
|
2899
|
+
Array.from({ length: Math.ceil(grid.length / 7) }, (_, row) => /* @__PURE__ */ jsx52(XStack38, { children: grid.slice(row * 7, row * 7 + 7).map((cell, i) => {
|
|
2900
|
+
const date = new Date(cell.year, cell.month, cell.day);
|
|
2901
|
+
const selected = sameDay(value, date);
|
|
2902
|
+
const isToday = sameDay(today, date);
|
|
2903
|
+
const disabled = cell.outside || isDisabled(date);
|
|
2904
|
+
return /* @__PURE__ */ jsx52(YStack42, { flex: 1, alignItems: "center", paddingVertical: "$0.5", children: /* @__PURE__ */ jsx52(
|
|
2905
|
+
XStack38,
|
|
2906
|
+
{
|
|
2907
|
+
width: 40,
|
|
2908
|
+
height: 40,
|
|
2909
|
+
borderRadius: "$10",
|
|
2910
|
+
alignItems: "center",
|
|
2911
|
+
justifyContent: "center",
|
|
2912
|
+
backgroundColor: selected ? "$color9" : "transparent",
|
|
2913
|
+
borderWidth: isToday && !selected ? 1.5 : 0,
|
|
2914
|
+
borderColor: "$color9",
|
|
2915
|
+
pressStyle: disabled ? void 0 : { scale: 0.9, backgroundColor: selected ? "$color10" : "$color4" },
|
|
2916
|
+
animation: "quick",
|
|
2917
|
+
opacity: disabled ? 0.35 : 1,
|
|
2918
|
+
cursor: disabled ? "default" : "pointer",
|
|
2919
|
+
onPress: disabled ? void 0 : () => onDateChange?.(date),
|
|
2920
|
+
children: /* @__PURE__ */ jsx52(
|
|
2921
|
+
SizableText45,
|
|
2922
|
+
{
|
|
2923
|
+
size: "$3",
|
|
2924
|
+
fontWeight: selected || isToday ? "700" : "400",
|
|
2925
|
+
color: selected ? "white" : cell.outside ? "$color5" : "$color12",
|
|
2926
|
+
children: cell.day
|
|
2927
|
+
}
|
|
2928
|
+
)
|
|
2929
|
+
}
|
|
2930
|
+
) }, `${row}-${i}`);
|
|
2931
|
+
}) }, row))
|
|
2932
|
+
] });
|
|
2933
|
+
}
|
|
2934
|
+
|
|
2935
|
+
// src/patterns/EventCard.tsx
|
|
2936
|
+
import { SizableText as SizableText46, Theme, XStack as XStack39, YStack as YStack43 } from "tamagui";
|
|
2937
|
+
import { jsx as jsx53, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
2938
|
+
var THEME_MAP = {
|
|
2939
|
+
purple: "purple",
|
|
2940
|
+
green: "green",
|
|
2941
|
+
blue: "blue",
|
|
2942
|
+
orange: "orange",
|
|
2943
|
+
red: "red",
|
|
2944
|
+
pink: "pink"
|
|
2945
|
+
};
|
|
2946
|
+
function ParticipantDots({ count, max }) {
|
|
2947
|
+
const dots = Math.min(count, 5);
|
|
2948
|
+
return /* @__PURE__ */ jsxs43(XStack39, { alignItems: "center", gap: "$1.5", children: [
|
|
2949
|
+
/* @__PURE__ */ jsx53(XStack39, { children: Array.from({ length: dots }, (_, i) => /* @__PURE__ */ jsx53(
|
|
2950
|
+
YStack43,
|
|
2951
|
+
{
|
|
2952
|
+
width: 22,
|
|
2953
|
+
height: 22,
|
|
2954
|
+
borderRadius: 11,
|
|
2955
|
+
backgroundColor: "$color7",
|
|
2956
|
+
borderWidth: 2,
|
|
2957
|
+
borderColor: "$color4",
|
|
2958
|
+
marginLeft: i > 0 ? -8 : 0,
|
|
2959
|
+
alignItems: "center",
|
|
2960
|
+
justifyContent: "center",
|
|
2961
|
+
children: /* @__PURE__ */ jsx53(SizableText46, { size: "$1", color: "$color1", fontWeight: "700", children: String.fromCharCode(65 + i) })
|
|
2962
|
+
},
|
|
2963
|
+
i
|
|
2964
|
+
)) }),
|
|
2965
|
+
/* @__PURE__ */ jsxs43(SizableText46, { size: "$2", color: "$color11", fontWeight: "500", children: [
|
|
2966
|
+
count,
|
|
2967
|
+
max ? `/${max}` : ""
|
|
2968
|
+
] })
|
|
2969
|
+
] });
|
|
2970
|
+
}
|
|
2971
|
+
function CardInner({ title, subtitle, time, location, label, participants, maxParticipants, onPress, actions }) {
|
|
2972
|
+
return /* @__PURE__ */ jsxs43(
|
|
2973
|
+
YStack43,
|
|
2974
|
+
{
|
|
2975
|
+
backgroundColor: "$color4",
|
|
2976
|
+
borderRadius: "$5",
|
|
2977
|
+
padding: "$4",
|
|
2978
|
+
gap: "$3",
|
|
2979
|
+
borderWidth: 1,
|
|
2980
|
+
borderColor: "$color7",
|
|
2981
|
+
onPress,
|
|
2982
|
+
animation: "quick",
|
|
2983
|
+
pressStyle: onPress ? { scale: 0.97, opacity: 0.9 } : void 0,
|
|
2984
|
+
cursor: onPress ? "pointer" : void 0,
|
|
2985
|
+
children: [
|
|
2986
|
+
/* @__PURE__ */ jsxs43(XStack39, { justifyContent: "space-between", alignItems: "flex-start", children: [
|
|
2987
|
+
/* @__PURE__ */ jsxs43(YStack43, { flex: 1, gap: "$1", children: [
|
|
2988
|
+
/* @__PURE__ */ jsx53(SizableText46, { size: "$6", fontWeight: "700", color: "$color12", children: title }),
|
|
2989
|
+
subtitle && /* @__PURE__ */ jsx53(SizableText46, { size: "$3", color: "$color11", opacity: 0.8, children: subtitle })
|
|
2990
|
+
] }),
|
|
2991
|
+
time && /* @__PURE__ */ jsx53(YStack43, { backgroundColor: "$color6", paddingHorizontal: "$2.5", paddingVertical: "$1.5", borderRadius: "$3", children: /* @__PURE__ */ jsx53(SizableText46, { size: "$2", fontWeight: "600", color: "$color12", children: time }) })
|
|
2992
|
+
] }),
|
|
2993
|
+
/* @__PURE__ */ jsxs43(XStack39, { gap: "$4", alignItems: "center", flexWrap: "wrap", children: [
|
|
2994
|
+
location && /* @__PURE__ */ jsxs43(XStack39, { gap: "$1.5", alignItems: "center", children: [
|
|
2995
|
+
/* @__PURE__ */ jsx53(SizableText46, { size: "$3", children: "\u{1F4CD}" }),
|
|
2996
|
+
/* @__PURE__ */ jsx53(SizableText46, { size: "$3", color: "$color11", children: location })
|
|
2997
|
+
] }),
|
|
2998
|
+
participants !== void 0 && /* @__PURE__ */ jsx53(ParticipantDots, { count: participants, max: maxParticipants })
|
|
2999
|
+
] }),
|
|
3000
|
+
(label || actions) && /* @__PURE__ */ jsxs43(XStack39, { justifyContent: "space-between", alignItems: "center", children: [
|
|
3001
|
+
label ? /* @__PURE__ */ jsx53(XStack39, { backgroundColor: "$color6", paddingHorizontal: "$2.5", paddingVertical: "$1", borderRadius: "$10", children: /* @__PURE__ */ jsx53(SizableText46, { size: "$2", fontWeight: "600", color: "$color11", children: label }) }) : /* @__PURE__ */ jsx53(YStack43, {}),
|
|
3002
|
+
actions
|
|
3003
|
+
] })
|
|
3004
|
+
]
|
|
3005
|
+
}
|
|
3006
|
+
);
|
|
3007
|
+
}
|
|
3008
|
+
function EventCard({ theme = "purple", ...props }) {
|
|
3009
|
+
return /* @__PURE__ */ jsx53(Theme, { name: THEME_MAP[theme], children: /* @__PURE__ */ jsx53(CardInner, { ...props }) });
|
|
3010
|
+
}
|
|
3011
|
+
|
|
3012
|
+
// src/patterns/UserPreferences.tsx
|
|
3013
|
+
import { Separator as Separator6, SizableText as SizableText47, Slider, Switch as Switch2, XStack as XStack40, YStack as YStack44 } from "tamagui";
|
|
3014
|
+
import { jsx as jsx54, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
3015
|
+
function ItemLabel({ title, description, color }) {
|
|
3016
|
+
return /* @__PURE__ */ jsxs44(YStack44, { flex: 1, gap: "$1", children: [
|
|
3017
|
+
/* @__PURE__ */ jsx54(SizableText47, { size: "$4", fontWeight: "500", color: color ?? "$color12", children: title }),
|
|
3018
|
+
description && /* @__PURE__ */ jsx54(SizableText47, { size: "$2", color: "$color9", children: description })
|
|
3019
|
+
] });
|
|
3020
|
+
}
|
|
3021
|
+
function ToggleRow({ item }) {
|
|
3022
|
+
return /* @__PURE__ */ jsxs44(XStack40, { alignItems: "center", gap: "$3", paddingVertical: "$3", paddingHorizontal: "$4", children: [
|
|
3023
|
+
/* @__PURE__ */ jsx54(ItemLabel, { title: item.title, description: item.description }),
|
|
3024
|
+
/* @__PURE__ */ jsx54(Switch2, { size: "$3", checked: item.value, onCheckedChange: item.onValueChange, children: /* @__PURE__ */ jsx54(Switch2.Thumb, { animation: "quick" }) })
|
|
3025
|
+
] });
|
|
3026
|
+
}
|
|
3027
|
+
function SelectRow({ item }) {
|
|
3028
|
+
const current = item.options.find((o) => o.value === item.value);
|
|
3029
|
+
return /* @__PURE__ */ jsxs44(
|
|
3030
|
+
XStack40,
|
|
3031
|
+
{
|
|
3032
|
+
alignItems: "center",
|
|
3033
|
+
gap: "$3",
|
|
3034
|
+
paddingVertical: "$3",
|
|
3035
|
+
paddingHorizontal: "$4",
|
|
3036
|
+
pressStyle: { backgroundColor: "$color3" },
|
|
3037
|
+
animation: "quick",
|
|
3038
|
+
cursor: "pointer",
|
|
3039
|
+
onPress: () => {
|
|
3040
|
+
const idx = item.options.findIndex((o) => o.value === item.value);
|
|
3041
|
+
const next = item.options[(idx + 1) % item.options.length];
|
|
3042
|
+
if (next) item.onValueChange(next.value);
|
|
3043
|
+
},
|
|
3044
|
+
children: [
|
|
3045
|
+
/* @__PURE__ */ jsx54(ItemLabel, { title: item.title, description: item.description }),
|
|
3046
|
+
/* @__PURE__ */ jsx54(SizableText47, { size: "$3", color: "$color9", fontWeight: "500", children: current?.label ?? item.value }),
|
|
3047
|
+
/* @__PURE__ */ jsx54(SizableText47, { size: "$4", color: "$color8", children: "\u203A" })
|
|
3048
|
+
]
|
|
3049
|
+
}
|
|
3050
|
+
);
|
|
3051
|
+
}
|
|
3052
|
+
function SliderRow({ item }) {
|
|
3053
|
+
const min = item.min ?? 0;
|
|
3054
|
+
const max = item.max ?? 100;
|
|
3055
|
+
return /* @__PURE__ */ jsxs44(YStack44, { gap: "$2", paddingVertical: "$3", paddingHorizontal: "$4", children: [
|
|
3056
|
+
/* @__PURE__ */ jsxs44(XStack40, { justifyContent: "space-between", alignItems: "center", children: [
|
|
3057
|
+
/* @__PURE__ */ jsx54(ItemLabel, { title: item.title, description: item.description }),
|
|
3058
|
+
/* @__PURE__ */ jsx54(SizableText47, { size: "$3", fontWeight: "600", color: "$color11", children: item.value })
|
|
3059
|
+
] }),
|
|
3060
|
+
/* @__PURE__ */ jsxs44(
|
|
3061
|
+
Slider,
|
|
3062
|
+
{
|
|
3063
|
+
value: [item.value],
|
|
3064
|
+
min,
|
|
3065
|
+
max,
|
|
3066
|
+
step: 1,
|
|
3067
|
+
onValueChange: ([v]) => {
|
|
3068
|
+
if (v !== void 0) item.onValueChange(v);
|
|
3069
|
+
},
|
|
3070
|
+
children: [
|
|
3071
|
+
/* @__PURE__ */ jsx54(Slider.Track, { backgroundColor: "$color4", height: 4, children: /* @__PURE__ */ jsx54(Slider.TrackActive, { backgroundColor: "$color9" }) }),
|
|
3072
|
+
/* @__PURE__ */ jsx54(Slider.Thumb, { index: 0, size: "$1.5", backgroundColor: "$color9", borderWidth: 0, circular: true })
|
|
3073
|
+
]
|
|
3074
|
+
}
|
|
3075
|
+
)
|
|
3076
|
+
] });
|
|
3077
|
+
}
|
|
3078
|
+
function ActionRow({ item }) {
|
|
3079
|
+
return /* @__PURE__ */ jsxs44(
|
|
3080
|
+
XStack40,
|
|
3081
|
+
{
|
|
3082
|
+
alignItems: "center",
|
|
3083
|
+
gap: "$3",
|
|
3084
|
+
paddingVertical: "$3",
|
|
3085
|
+
paddingHorizontal: "$4",
|
|
3086
|
+
pressStyle: { backgroundColor: "$color3" },
|
|
3087
|
+
animation: "quick",
|
|
3088
|
+
cursor: "pointer",
|
|
3089
|
+
onPress: item.onPress,
|
|
3090
|
+
children: [
|
|
3091
|
+
/* @__PURE__ */ jsx54(
|
|
3092
|
+
ItemLabel,
|
|
3093
|
+
{
|
|
3094
|
+
title: item.title,
|
|
3095
|
+
description: item.description,
|
|
3096
|
+
color: item.destructive ? "$red10" : void 0
|
|
3097
|
+
}
|
|
3098
|
+
),
|
|
3099
|
+
/* @__PURE__ */ jsx54(SizableText47, { size: "$4", color: "$color8", children: "\u203A" })
|
|
3100
|
+
]
|
|
3101
|
+
}
|
|
3102
|
+
);
|
|
3103
|
+
}
|
|
3104
|
+
function PreferenceRow({ item }) {
|
|
3105
|
+
switch (item.type) {
|
|
3106
|
+
case "toggle":
|
|
3107
|
+
return /* @__PURE__ */ jsx54(ToggleRow, { item });
|
|
3108
|
+
case "select":
|
|
3109
|
+
return /* @__PURE__ */ jsx54(SelectRow, { item });
|
|
3110
|
+
case "slider":
|
|
3111
|
+
return /* @__PURE__ */ jsx54(SliderRow, { item });
|
|
3112
|
+
case "action":
|
|
3113
|
+
return /* @__PURE__ */ jsx54(ActionRow, { item });
|
|
3114
|
+
}
|
|
3115
|
+
}
|
|
3116
|
+
function UserPreferences({ sections }) {
|
|
3117
|
+
return /* @__PURE__ */ jsx54(YStack44, { gap: "$5", children: sections.map((section, si) => /* @__PURE__ */ jsxs44(YStack44, { gap: "$2", children: [
|
|
3118
|
+
/* @__PURE__ */ jsxs44(YStack44, { paddingHorizontal: "$1", gap: "$0.5", children: [
|
|
3119
|
+
/* @__PURE__ */ jsx54(SizableText47, { size: "$2", fontWeight: "600", color: "$color9", textTransform: "uppercase", children: section.title }),
|
|
3120
|
+
section.description && /* @__PURE__ */ jsx54(SizableText47, { size: "$2", color: "$color8", children: section.description })
|
|
3121
|
+
] }),
|
|
3122
|
+
/* @__PURE__ */ jsx54(
|
|
3123
|
+
YStack44,
|
|
3124
|
+
{
|
|
3125
|
+
backgroundColor: "$color2",
|
|
3126
|
+
borderRadius: "$4",
|
|
3127
|
+
overflow: "hidden",
|
|
3128
|
+
borderWidth: 1,
|
|
3129
|
+
borderColor: "$color4",
|
|
3130
|
+
children: section.items.map((item, ii) => /* @__PURE__ */ jsxs44(YStack44, { children: [
|
|
3131
|
+
/* @__PURE__ */ jsx54(PreferenceRow, { item }),
|
|
3132
|
+
ii < section.items.length - 1 && /* @__PURE__ */ jsx54(Separator6, { borderColor: "$color4" })
|
|
3133
|
+
] }, item.id))
|
|
3134
|
+
}
|
|
3135
|
+
)
|
|
3136
|
+
] }, si)) });
|
|
3137
|
+
}
|
|
2653
3138
|
export {
|
|
2654
3139
|
Accordion,
|
|
2655
3140
|
ActionSheet,
|
|
@@ -2686,11 +3171,14 @@ export {
|
|
|
2686
3171
|
ConfirmDialog,
|
|
2687
3172
|
Container,
|
|
2688
3173
|
CountdownBanner,
|
|
3174
|
+
DataTable,
|
|
3175
|
+
DatePicker,
|
|
2689
3176
|
Dialog,
|
|
2690
3177
|
DialogProvider,
|
|
2691
3178
|
Divider,
|
|
2692
3179
|
EmptyState,
|
|
2693
3180
|
EnsureFlexed,
|
|
3181
|
+
EventCard,
|
|
2694
3182
|
Fieldset,
|
|
2695
3183
|
FloatingActionButton,
|
|
2696
3184
|
Footer,
|
|
@@ -2747,22 +3235,23 @@ export {
|
|
|
2747
3235
|
Section,
|
|
2748
3236
|
Select,
|
|
2749
3237
|
SepHeading,
|
|
2750
|
-
|
|
3238
|
+
Separator7 as Separator,
|
|
2751
3239
|
SettingsScreen,
|
|
2752
3240
|
Sheet3 as Sheet,
|
|
2753
3241
|
SizableStack,
|
|
2754
|
-
|
|
3242
|
+
SizableText48 as SizableText,
|
|
2755
3243
|
Skeleton,
|
|
2756
|
-
Slider,
|
|
3244
|
+
Slider2 as Slider,
|
|
2757
3245
|
Spacer,
|
|
2758
3246
|
Spinner2 as Spinner,
|
|
2759
3247
|
Square,
|
|
2760
3248
|
Stack,
|
|
3249
|
+
StatusBadge,
|
|
2761
3250
|
StepPageLayout,
|
|
2762
3251
|
SubHeading,
|
|
2763
3252
|
SwipeCards,
|
|
2764
3253
|
SwipeableRow,
|
|
2765
|
-
|
|
3254
|
+
Switch3 as Switch,
|
|
2766
3255
|
TabBar,
|
|
2767
3256
|
Tabs,
|
|
2768
3257
|
Image9 as TamaguiImage,
|
|
@@ -2771,18 +3260,19 @@ export {
|
|
|
2771
3260
|
TestimonialCard,
|
|
2772
3261
|
Text,
|
|
2773
3262
|
TextArea,
|
|
2774
|
-
Theme,
|
|
3263
|
+
Theme2 as Theme,
|
|
2775
3264
|
ThemeableStack,
|
|
2776
3265
|
ToggleGroup,
|
|
2777
3266
|
Tooltip,
|
|
2778
3267
|
TooltipSimple,
|
|
2779
3268
|
Unspaced,
|
|
2780
|
-
|
|
3269
|
+
UserPreferences,
|
|
3270
|
+
View7 as View,
|
|
2781
3271
|
VisuallyHidden,
|
|
2782
3272
|
XGroup,
|
|
2783
|
-
|
|
3273
|
+
XStack41 as XStack,
|
|
2784
3274
|
YGroup,
|
|
2785
|
-
|
|
3275
|
+
YStack45 as YStack,
|
|
2786
3276
|
ZStack,
|
|
2787
3277
|
addTheme,
|
|
2788
3278
|
blinkConfig,
|
|
@@ -2804,7 +3294,7 @@ export {
|
|
|
2804
3294
|
isWeb,
|
|
2805
3295
|
replaceTheme,
|
|
2806
3296
|
showError,
|
|
2807
|
-
|
|
3297
|
+
styled14 as styled,
|
|
2808
3298
|
defaultConfig2 as tamaguiDefaultConfig,
|
|
2809
3299
|
toast,
|
|
2810
3300
|
updateTheme,
|
|
@@ -2818,7 +3308,7 @@ export {
|
|
|
2818
3308
|
useForceUpdate,
|
|
2819
3309
|
useIsPresent,
|
|
2820
3310
|
useIsomorphicLayoutEffect,
|
|
2821
|
-
useMedia,
|
|
3311
|
+
useMedia2 as useMedia,
|
|
2822
3312
|
usePresence,
|
|
2823
3313
|
useTheme,
|
|
2824
3314
|
useThemeName,
|