@blinkdotnew/mobile-ui 2.0.0-alpha.1 → 2.0.0-alpha.2

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.mjs CHANGED
@@ -1,347 +1,96 @@
1
1
  // src/config/tamagui.config.ts
2
+ import { defaultConfig } from "@tamagui/config/v5";
2
3
  import { createTamagui } from "tamagui";
3
-
4
- // src/config/tokens.ts
5
- import { createTokens } from "tamagui";
6
- var tokens = createTokens({
7
- color: {
8
- white: "#FFFFFF",
9
- black: "#000000",
10
- transparent: "transparent"
11
- },
12
- space: {
13
- 0: 0,
14
- 0.5: 2,
15
- 1: 4,
16
- 1.5: 6,
17
- 2: 8,
18
- 2.5: 10,
19
- 3: 12,
20
- 3.5: 14,
21
- 4: 16,
22
- 5: 20,
23
- 6: 24,
24
- 7: 28,
25
- 8: 32,
26
- 9: 36,
27
- 10: 40,
28
- 12: 48,
29
- 16: 64,
30
- true: 16,
31
- "-1": -4,
32
- "-2": -8,
33
- "-3": -12,
34
- "-4": -16
35
- },
36
- size: {
37
- 0: 0,
38
- 1: 4,
39
- 2: 8,
40
- 3: 12,
41
- 4: 16,
42
- 5: 20,
43
- 6: 24,
44
- 7: 28,
45
- 8: 32,
46
- 9: 36,
47
- 10: 40,
48
- 11: 44,
49
- 12: 48,
50
- 14: 56,
51
- 16: 64,
52
- 20: 80,
53
- true: 44
54
- },
55
- radius: {
56
- 0: 0,
57
- 1: 2,
58
- 2: 4,
59
- 3: 6,
60
- 4: 8,
61
- 5: 10,
62
- 6: 12,
63
- 7: 16,
64
- 8: 20,
65
- 9: 24,
66
- 10: 9999,
67
- true: 12
68
- },
69
- zIndex: {
70
- 0: 0,
71
- 1: 100,
72
- 2: 200,
73
- 3: 300,
74
- 4: 400,
75
- 5: 500
76
- }
77
- });
78
-
79
- // src/config/themes.ts
80
- var oceanLight = {
81
- background: "#FFFFFF",
82
- backgroundHover: "#F8FAFC",
83
- backgroundPress: "#F1F5F9",
84
- color: "#0F172A",
85
- colorHover: "#1E293B",
86
- colorPress: "#334155",
87
- primary: "#0D9488",
88
- primaryHover: "#0F766E",
89
- primaryPress: "#115E59",
90
- secondary: "#F0F9FF",
91
- secondaryHover: "#E0F2FE",
92
- secondaryPress: "#BAE6FD",
93
- accent: "#2DD4BF",
94
- surface: "#F8FAFC",
95
- surfaceHover: "#F1F5F9",
96
- card: "#FFFFFF",
97
- cardHover: "#F8FAFC",
98
- border: "#E2E8F0",
99
- borderHover: "#CBD5E1",
100
- textPrimary: "#0F172A",
101
- textSecondary: "#475569",
102
- textMuted: "#94A3B8",
103
- textInverse: "#FFFFFF",
104
- error: "#EF4444",
105
- errorHover: "#DC2626",
106
- success: "#10B981",
107
- successHover: "#059669",
108
- warning: "#F59E0B",
109
- warningHover: "#D97706",
110
- highlight: "#0D9488",
111
- overlay: "rgba(0,0,0,0.5)",
112
- shadowColor: "rgba(0,0,0,0.1)"
113
- };
114
- var oceanDark = {
115
- background: "#0F172A",
116
- backgroundHover: "#1E293B",
117
- backgroundPress: "#334155",
118
- color: "#F8FAFC",
119
- colorHover: "#E2E8F0",
120
- colorPress: "#CBD5E1",
121
- primary: "#14B8A6",
122
- primaryHover: "#2DD4BF",
123
- primaryPress: "#0D9488",
124
- secondary: "#1E293B",
125
- secondaryHover: "#334155",
126
- secondaryPress: "#475569",
127
- accent: "#2DD4BF",
128
- surface: "#1E293B",
129
- surfaceHover: "#334155",
130
- card: "#1E293B",
131
- cardHover: "#334155",
132
- border: "#334155",
133
- borderHover: "#475569",
134
- textPrimary: "#F8FAFC",
135
- textSecondary: "#94A3B8",
136
- textMuted: "#64748B",
137
- textInverse: "#0F172A",
138
- error: "#F87171",
139
- errorHover: "#EF4444",
140
- success: "#34D399",
141
- successHover: "#10B981",
142
- warning: "#FBBF24",
143
- warningHover: "#F59E0B",
144
- highlight: "#14B8A6",
145
- overlay: "rgba(0,0,0,0.7)",
146
- shadowColor: "rgba(0,0,0,0.3)"
147
- };
148
- var themes = {
149
- light: oceanLight,
150
- dark: oceanDark
151
- };
152
-
153
- // src/config/fonts.ts
154
- import { createFont } from "tamagui";
155
- var outfitFont = createFont({
156
- family: "Outfit, System",
157
- size: {
158
- 1: 11,
159
- 2: 12,
160
- 3: 13,
161
- 4: 14,
162
- 5: 15,
163
- 6: 16,
164
- 7: 18,
165
- 8: 20,
166
- 9: 22,
167
- 10: 28,
168
- 11: 36,
169
- 12: 48,
170
- true: 15
171
- },
172
- lineHeight: {
173
- 1: 16,
174
- 2: 18,
175
- 3: 20,
176
- 4: 22,
177
- 5: 23,
178
- 6: 24,
179
- 7: 26,
180
- 8: 28,
181
- 9: 30,
182
- 10: 36,
183
- 11: 44,
184
- 12: 56,
185
- true: 23
186
- },
187
- weight: {
188
- 1: "400",
189
- 2: "500",
190
- 3: "600",
191
- 4: "700",
192
- 5: "800",
193
- true: "400"
194
- },
195
- letterSpacing: {
196
- 1: 0,
197
- 2: -0.2,
198
- 3: -0.4,
199
- 4: -0.6,
200
- true: 0
201
- }
202
- });
203
-
204
- // src/config/tamagui.config.ts
205
4
  var blinkConfig = createTamagui({
206
- tokens,
207
- themes,
208
- fonts: {
209
- heading: outfitFont,
210
- body: outfitFont
211
- },
212
- media: {
213
- xs: { maxWidth: 660 },
214
- sm: { maxWidth: 860 },
215
- md: { maxWidth: 980 },
216
- lg: { maxWidth: 1120 },
217
- gtSm: { minWidth: 861 },
218
- short: { maxHeight: 820 }
219
- },
220
- shorthands: {
221
- px: "paddingHorizontal",
222
- py: "paddingVertical",
223
- mx: "marginHorizontal",
224
- my: "marginVertical",
225
- bg: "backgroundColor",
226
- br: "borderRadius",
227
- f: "flex",
228
- w: "width",
229
- h: "height"
230
- }
5
+ ...defaultConfig
231
6
  });
232
7
 
233
8
  // src/primitives/Button.tsx
234
- import { styled, View, Text, withStaticProperties } from "tamagui";
235
- var ButtonFrame = styled(View, {
236
- name: "BlinkButton",
237
- tag: "button",
238
- alignItems: "center",
239
- justifyContent: "center",
240
- flexDirection: "row",
241
- gap: "$2",
9
+ import { Button as TamaguiButton, styled } from "tamagui";
10
+ var Button = styled(TamaguiButton, {
11
+ borderWidth: 0,
242
12
  cursor: "pointer",
243
- pressStyle: { opacity: 0.8, scale: 0.98 },
13
+ focusVisibleStyle: {
14
+ outlineWidth: 2,
15
+ outlineStyle: "solid",
16
+ outlineColor: "$color8"
17
+ },
244
18
  variants: {
245
19
  variant: {
20
+ default: {
21
+ backgroundColor: "$color3",
22
+ hoverStyle: { backgroundColor: "$color4" },
23
+ pressStyle: { backgroundColor: "$color2", opacity: 0.8 }
24
+ },
246
25
  primary: {
247
- backgroundColor: "$primary"
26
+ backgroundColor: "$color9",
27
+ color: "$color1",
28
+ hoverStyle: { backgroundColor: "$color10" },
29
+ pressStyle: { backgroundColor: "$color8", opacity: 0.9 }
248
30
  },
249
- secondary: {
250
- backgroundColor: "$secondary"
31
+ outlined: {
32
+ backgroundColor: "transparent",
33
+ borderWidth: 2,
34
+ borderColor: "$color6",
35
+ hoverStyle: { borderColor: "$color8" },
36
+ pressStyle: { borderColor: "$color4", opacity: 0.8 }
251
37
  },
252
- outline: {
38
+ transparent: {
253
39
  backgroundColor: "transparent",
254
- borderWidth: 1,
255
- borderColor: "$border"
40
+ hoverStyle: { backgroundColor: "$color2" },
41
+ pressStyle: { backgroundColor: "$color1", opacity: 0.8 }
256
42
  },
257
- ghost: {
258
- backgroundColor: "transparent"
43
+ floating: {
44
+ backgroundColor: "$color4",
45
+ shadowColor: "$shadow2",
46
+ shadowRadius: 5,
47
+ shadowOffset: { height: 2, width: 0 },
48
+ hoverStyle: { backgroundColor: "$color5" },
49
+ pressStyle: { backgroundColor: "$color3", opacity: 0.9 }
259
50
  },
260
51
  destructive: {
261
- backgroundColor: "$error"
52
+ backgroundColor: "$red9",
53
+ color: "$color1",
54
+ hoverStyle: { backgroundColor: "$red10" },
55
+ pressStyle: { backgroundColor: "$red8", opacity: 0.9 }
262
56
  }
263
57
  },
264
58
  size: {
265
- sm: {
266
- height: "$8",
267
- paddingHorizontal: "$3",
268
- borderRadius: "$4"
269
- },
270
- md: {
271
- height: "$11",
272
- paddingHorizontal: "$4",
273
- borderRadius: "$6"
274
- },
275
- lg: {
276
- height: "$14",
277
- paddingHorizontal: "$6",
278
- borderRadius: "$7"
279
- }
59
+ sm: { height: "$3", paddingHorizontal: "$3", borderRadius: "$3" },
60
+ md: { height: "$4", paddingHorizontal: "$4", borderRadius: "$4" },
61
+ lg: { height: "$5", paddingHorizontal: "$5", borderRadius: "$5" }
280
62
  },
281
63
  fullWidth: {
282
64
  true: { width: "100%" }
283
- },
284
- disabled: {
285
- true: { opacity: 0.5, pointerEvents: "none" }
286
65
  }
287
66
  },
288
67
  defaultVariants: {
289
- variant: "primary",
68
+ variant: "default",
290
69
  size: "md"
291
70
  }
292
71
  });
293
- var ButtonText = styled(Text, {
294
- name: "BlinkButtonText",
295
- fontFamily: "$body",
296
- fontWeight: "600",
297
- textAlign: "center",
298
- variants: {
299
- variant: {
300
- primary: { color: "$textInverse" },
301
- secondary: { color: "$textPrimary" },
302
- outline: { color: "$textPrimary" },
303
- ghost: { color: "$textPrimary" },
304
- destructive: { color: "$textInverse" }
305
- },
306
- size: {
307
- sm: { fontSize: "$3" },
308
- md: { fontSize: "$5" },
309
- lg: { fontSize: "$6" }
310
- }
311
- },
312
- defaultVariants: {
313
- variant: "primary",
314
- size: "md"
315
- }
316
- });
317
- var Button = withStaticProperties(ButtonFrame, {
318
- Text: ButtonText
319
- });
320
72
 
321
73
  // src/primitives/Text.tsx
322
- import { styled as styled2, Text as Text2 } from "tamagui";
323
- var BlinkText = styled2(Text2, {
74
+ import { SizableText, styled as styled2 } from "tamagui";
75
+ var BlinkText = styled2(SizableText, {
324
76
  name: "BlinkText",
325
- fontFamily: "$body",
326
- color: "$color",
327
77
  variants: {
328
78
  variant: {
329
- display: { fontSize: "$12", fontWeight: "800", letterSpacing: "$4" },
330
- h1: { fontSize: "$10", fontWeight: "700", letterSpacing: "$3" },
331
- h2: { fontSize: "$9", fontWeight: "700", letterSpacing: "$2" },
332
- h3: { fontSize: "$7", fontWeight: "600" },
333
- h4: { fontSize: "$6", fontWeight: "600" },
334
- body: { fontSize: "$5", fontWeight: "400" },
335
- bodySmall: { fontSize: "$4", fontWeight: "400" },
336
- caption: { fontSize: "$3", fontWeight: "400", color: "$textSecondary" },
337
- small: { fontSize: "$2", fontWeight: "400", color: "$textMuted" },
338
- tiny: { fontSize: "$1", fontWeight: "400", color: "$textMuted" }
79
+ display: { size: "$10", fontWeight: "800" },
80
+ h1: { size: "$9", fontWeight: "700" },
81
+ h2: { size: "$8", fontWeight: "700" },
82
+ h3: { size: "$7", fontWeight: "600" },
83
+ h4: { size: "$6", fontWeight: "600" },
84
+ body: { size: "$5", fontWeight: "400" },
85
+ bodySmall: { size: "$4", fontWeight: "400" },
86
+ caption: { size: "$3", fontWeight: "400", color: "$color10" },
87
+ small: { size: "$2", fontWeight: "400", color: "$color9" }
339
88
  },
340
89
  muted: {
341
- true: { color: "$textMuted" }
90
+ true: { color: "$color9" }
342
91
  },
343
92
  secondary: {
344
- true: { color: "$textSecondary" }
93
+ true: { color: "$color10" }
345
94
  },
346
95
  center: {
347
96
  true: { textAlign: "center" }
@@ -356,30 +105,30 @@ var BlinkText = styled2(Text2, {
356
105
  });
357
106
 
358
107
  // src/primitives/Card.tsx
359
- import { styled as styled3, View as View2, withStaticProperties as withStaticProperties2 } from "tamagui";
360
- var CardFrame = styled3(View2, {
108
+ import { styled as styled3, View, withStaticProperties } from "tamagui";
109
+ var CardFrame = styled3(View, {
361
110
  name: "BlinkCard",
362
- backgroundColor: "$card",
111
+ backgroundColor: "$color2",
112
+ borderRadius: "$4",
363
113
  overflow: "hidden",
364
114
  variants: {
365
115
  variant: {
366
116
  flat: {},
367
117
  elevated: {
368
- shadowColor: "$shadowColor",
118
+ shadowColor: "$shadow2",
369
119
  shadowOffset: { width: 0, height: 2 },
370
- shadowOpacity: 0.1,
371
120
  shadowRadius: 8,
372
121
  elevation: 3
373
122
  },
374
123
  outlined: {
375
124
  borderWidth: 1,
376
- borderColor: "$border"
125
+ borderColor: "$color5"
377
126
  }
378
127
  },
379
128
  size: {
380
- sm: { borderRadius: "$4", padding: "$3" },
381
- md: { borderRadius: "$6", padding: "$4" },
382
- lg: { borderRadius: "$7", padding: "$5" }
129
+ sm: { borderRadius: "$3", padding: "$3" },
130
+ md: { borderRadius: "$4", padding: "$4" },
131
+ lg: { borderRadius: "$5", padding: "$5" }
383
132
  },
384
133
  pressable: {
385
134
  true: {
@@ -393,88 +142,71 @@ var CardFrame = styled3(View2, {
393
142
  size: "md"
394
143
  }
395
144
  });
396
- var CardHeader = styled3(View2, {
397
- name: "BlinkCardHeader",
398
- paddingBottom: "$3"
399
- });
400
- var CardContent = styled3(View2, {
401
- name: "BlinkCardContent"
402
- });
403
- var CardFooter = styled3(View2, {
145
+ var CardHeader = styled3(View, { name: "BlinkCardHeader", paddingBottom: "$3" });
146
+ var CardContent = styled3(View, { name: "BlinkCardContent" });
147
+ var CardFooter = styled3(View, {
404
148
  name: "BlinkCardFooter",
405
149
  paddingTop: "$3",
406
150
  flexDirection: "row",
407
151
  alignItems: "center",
408
152
  gap: "$2"
409
153
  });
410
- var Card = withStaticProperties2(CardFrame, {
154
+ var Card = withStaticProperties(CardFrame, {
411
155
  Header: CardHeader,
412
156
  Content: CardContent,
413
157
  Footer: CardFooter
414
158
  });
415
159
 
416
160
  // src/primitives/Input.tsx
417
- import { styled as styled4, View as View3, Text as Text3, Input as TamaguiInput } from "tamagui";
161
+ import { Input as TamaguiInput, styled as styled4, View as View2, SizableText as SizableText2 } from "tamagui";
418
162
  import { jsx, jsxs } from "react/jsx-runtime";
419
- var InputFrame = styled4(View3, {
163
+ var InputFrame = styled4(View2, {
420
164
  name: "BlinkInputFrame",
421
165
  gap: "$1.5"
422
166
  });
423
- var InputLabel = styled4(Text3, {
167
+ var InputLabel = styled4(SizableText2, {
424
168
  name: "BlinkInputLabel",
425
- fontFamily: "$body",
426
- fontSize: "$4",
169
+ size: "$4",
427
170
  fontWeight: "500",
428
- color: "$textSecondary"
171
+ color: "$color11"
429
172
  });
430
173
  var InputField = styled4(TamaguiInput, {
431
174
  name: "BlinkInput",
432
- fontFamily: "$body",
433
- fontSize: "$5",
434
- color: "$color",
435
- backgroundColor: "$background",
436
- borderWidth: 1,
437
- borderColor: "$border",
438
- borderRadius: "$6",
439
- height: "$14",
440
- paddingHorizontal: "$4",
441
- placeholderTextColor: "$textMuted",
442
- focusStyle: {
443
- borderColor: "$primary",
444
- borderWidth: 2
175
+ height: 50,
176
+ size: "$5",
177
+ borderWidth: 0.5,
178
+ borderColor: "$color5",
179
+ borderRadius: "$4",
180
+ backgroundColor: "$color1",
181
+ placeholderTextColor: "$color8",
182
+ focusVisibleStyle: {
183
+ outlineWidth: 3,
184
+ outlineStyle: "solid",
185
+ outlineColor: "$background04",
186
+ outlineOffset: 1,
187
+ borderWidth: 0.5,
188
+ borderColor: "$color7"
445
189
  },
446
190
  variants: {
447
191
  hasError: {
448
192
  true: {
449
- borderColor: "$error",
450
- focusStyle: { borderColor: "$error" }
193
+ borderColor: "$red9",
194
+ focusVisibleStyle: { borderColor: "$red9" }
451
195
  }
452
196
  },
453
197
  variant: {
454
198
  default: {},
455
199
  filled: {
456
- backgroundColor: "$surface",
200
+ backgroundColor: "$color2",
457
201
  borderColor: "transparent",
458
- focusStyle: { borderColor: "$primary" }
202
+ focusVisibleStyle: { borderColor: "$color7" }
459
203
  }
460
204
  }
461
205
  },
462
- defaultVariants: {
463
- variant: "default"
464
- }
465
- });
466
- var InputError = styled4(Text3, {
467
- name: "BlinkInputError",
468
- fontFamily: "$body",
469
- fontSize: "$2",
470
- color: "$error"
471
- });
472
- var InputHint = styled4(Text3, {
473
- name: "BlinkInputHint",
474
- fontFamily: "$body",
475
- fontSize: "$2",
476
- color: "$textMuted"
206
+ defaultVariants: { variant: "default" }
477
207
  });
208
+ var InputError = styled4(SizableText2, { name: "BlinkInputError", size: "$2", color: "$red10" });
209
+ var InputHint = styled4(SizableText2, { name: "BlinkInputHint", size: "$2", color: "$color9" });
478
210
  function Input({ label, error, hint, ...props }) {
479
211
  return /* @__PURE__ */ jsxs(InputFrame, { children: [
480
212
  label && /* @__PURE__ */ jsx(InputLabel, { children: label }),
@@ -485,69 +217,651 @@ function Input({ label, error, hint, ...props }) {
485
217
  }
486
218
 
487
219
  // src/primitives/Avatar.tsx
488
- import { styled as styled5, View as View4, Text as Text4, Image } from "tamagui";
220
+ import { memo } from "react";
221
+ import { Circle, Image, SizableText as SizableText3 } from "tamagui";
489
222
  import { jsx as jsx2 } from "react/jsx-runtime";
490
- var AvatarFrame = styled5(View4, {
491
- name: "BlinkAvatar",
492
- alignItems: "center",
493
- justifyContent: "center",
494
- overflow: "hidden",
495
- backgroundColor: "$primary",
223
+ var simpleSizes = {
224
+ xs: 24,
225
+ sm: 32,
226
+ md: 40,
227
+ lg: 48,
228
+ xl: 64
229
+ };
230
+ function getSize(size) {
231
+ if (typeof size === "number") return size;
232
+ return simpleSizes[size] ?? 40;
233
+ }
234
+ var Avatar = memo(({ uri, name, size: sizeIn = "md" }) => {
235
+ const size = getSize(sizeIn);
236
+ return /* @__PURE__ */ jsx2(
237
+ Circle,
238
+ {
239
+ size,
240
+ overflow: "hidden",
241
+ backgroundColor: "$color4",
242
+ alignItems: "center",
243
+ justifyContent: "center",
244
+ children: uri ? /* @__PURE__ */ jsx2(
245
+ Image,
246
+ {
247
+ source: { uri },
248
+ width: size,
249
+ height: size,
250
+ objectFit: "cover"
251
+ }
252
+ ) : /* @__PURE__ */ jsx2(
253
+ SizableText3,
254
+ {
255
+ size: "$3",
256
+ fontWeight: "600",
257
+ color: "$color11",
258
+ children: name ? name.split(" ").map((p) => p[0]).join("").toUpperCase().slice(0, 2) : "?"
259
+ }
260
+ )
261
+ }
262
+ );
263
+ });
264
+
265
+ // src/interface/Headings.tsx
266
+ import { Separator, SizableText as SizableText4, XStack, styled as styled5 } from "tamagui";
267
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
268
+ var H1 = styled5(SizableText4, {
269
+ name: "BlinkH1",
270
+ role: "heading",
271
+ fontFamily: "$heading",
272
+ size: "$10",
273
+ fontWeight: "700"
274
+ });
275
+ var H2 = styled5(SizableText4, {
276
+ name: "BlinkH2",
277
+ role: "heading",
278
+ fontFamily: "$heading",
279
+ size: "$9",
280
+ fontWeight: "700"
281
+ });
282
+ var H3 = styled5(SizableText4, {
283
+ name: "BlinkH3",
284
+ role: "heading",
285
+ fontFamily: "$heading",
286
+ size: "$8",
287
+ fontWeight: "600"
288
+ });
289
+ var H4 = styled5(SizableText4, {
290
+ name: "BlinkH4",
291
+ role: "heading",
292
+ fontFamily: "$heading",
293
+ size: "$6",
294
+ fontWeight: "600"
295
+ });
296
+ var H5 = styled5(SizableText4, {
297
+ name: "BlinkH5",
298
+ role: "heading",
299
+ fontFamily: "$heading",
300
+ size: "$5",
301
+ fontWeight: "500"
302
+ });
303
+ var H6 = styled5(SizableText4, {
304
+ name: "BlinkH6",
305
+ role: "heading",
306
+ fontFamily: "$heading",
307
+ size: "$4",
308
+ fontWeight: "500"
309
+ });
310
+ var SubHeading = styled5(SizableText4, {
311
+ name: "BlinkSubHeading",
312
+ size: "$5",
313
+ color: "$color10",
314
+ fontWeight: "300",
315
+ $lg: { size: "$6" }
316
+ });
317
+ function SepHeading({ children }) {
318
+ return /* @__PURE__ */ jsxs2(XStack, { marginTop: "$6", marginBottom: "$4", alignItems: "center", gap: "$6", children: [
319
+ /* @__PURE__ */ jsx3(H3, { size: "$4", color: "$color10", children }),
320
+ /* @__PURE__ */ jsx3(Separator, { opacity: 0.5 })
321
+ ] });
322
+ }
323
+
324
+ // src/interface/PageContainer.tsx
325
+ import { styled as styled6, YStack } from "tamagui";
326
+ var PageContainer = styled6(YStack, {
327
+ name: "BlinkPageContainer",
328
+ position: "relative",
329
+ marginHorizontal: "auto",
330
+ flex: 1,
331
+ flexBasis: "auto",
332
+ paddingHorizontal: "$4",
333
+ width: "100%",
334
+ minWidth: 380,
335
+ $md: { maxWidth: 760 },
336
+ $lg: { maxWidth: 860 },
337
+ $xl: { maxWidth: 1140 }
338
+ });
339
+ var PageMainContainer = styled6(PageContainer, {
340
+ name: "BlinkPageMainContainer",
341
+ role: "main"
342
+ });
343
+
344
+ // src/interface/Dialog.tsx
345
+ import { useState, useEffect } from "react";
346
+ import { AlertDialog, Button as Button2, XStack as XStack2, YStack as YStack2 } from "tamagui";
347
+ import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
348
+ var globalShowDialog = null;
349
+ function DialogProvider({ children }) {
350
+ const [state, setState] = useState({
351
+ type: null,
352
+ title: "",
353
+ description: ""
354
+ });
355
+ useEffect(() => {
356
+ globalShowDialog = (newState) => setState({ ...newState, resolve: newState.resolve });
357
+ return () => {
358
+ globalShowDialog = null;
359
+ };
360
+ }, []);
361
+ const handleClose = (confirmed) => {
362
+ if (!state.resolve) return;
363
+ const resolve = state.resolve;
364
+ setState({ type: null, title: "", description: "" });
365
+ resolve(confirmed);
366
+ };
367
+ return /* @__PURE__ */ jsxs3(Fragment, { children: [
368
+ children,
369
+ /* @__PURE__ */ jsx4(
370
+ AlertDialog,
371
+ {
372
+ open: state.type !== null,
373
+ onOpenChange: (open) => {
374
+ if (!open && state.type !== null) handleClose(false);
375
+ },
376
+ children: /* @__PURE__ */ jsxs3(AlertDialog.Portal, { children: [
377
+ /* @__PURE__ */ jsx4(
378
+ AlertDialog.Overlay,
379
+ {
380
+ opacity: 0.5,
381
+ enterStyle: { opacity: 0 },
382
+ exitStyle: { opacity: 0 }
383
+ },
384
+ "overlay"
385
+ ),
386
+ /* @__PURE__ */ jsx4(
387
+ AlertDialog.Content,
388
+ {
389
+ bordered: true,
390
+ elevate: true,
391
+ enterStyle: { x: 0, y: -20, opacity: 0, scale: 0.9 },
392
+ exitStyle: { x: 0, y: 10, opacity: 0, scale: 0.95 },
393
+ x: 0,
394
+ scale: 1,
395
+ opacity: 1,
396
+ y: 0,
397
+ width: "90%",
398
+ maxWidth: 400,
399
+ children: /* @__PURE__ */ jsxs3(YStack2, { gap: "$4", children: [
400
+ /* @__PURE__ */ jsx4(AlertDialog.Title, { size: "$6", children: state.title }),
401
+ /* @__PURE__ */ jsx4(AlertDialog.Description, { size: "$3", color: "$color11", children: state.description }),
402
+ /* @__PURE__ */ jsx4(XStack2, { gap: "$3", justifyContent: "flex-end", children: state.type === "confirm" ? /* @__PURE__ */ jsxs3(Fragment, { children: [
403
+ /* @__PURE__ */ jsx4(Button2, { onPress: () => handleClose(false), children: "Cancel" }),
404
+ /* @__PURE__ */ jsx4(Button2, { theme: "blue", onPress: () => handleClose(true), children: "Confirm" })
405
+ ] }) : /* @__PURE__ */ jsx4(Button2, { theme: "blue", onPress: () => handleClose(false), children: "OK" }) })
406
+ ] })
407
+ },
408
+ "content"
409
+ )
410
+ ] })
411
+ }
412
+ )
413
+ ] });
414
+ }
415
+ var showError = (error, title = "Error") => {
416
+ let description = "An unexpected error occurred";
417
+ if (error instanceof Error) description = error.message;
418
+ else if (typeof error === "string") description = error;
419
+ else if (error && typeof error === "object" && "message" in error)
420
+ description = String(error.message);
421
+ if (globalShowDialog) globalShowDialog({ type: "error", title, description });
422
+ else console.error(`${title}: ${description}`);
423
+ };
424
+ var dialogConfirm = async (props) => {
425
+ const { title = "Confirm", description = "Are you sure?" } = props;
426
+ if (!globalShowDialog) {
427
+ console.error("DialogProvider not mounted");
428
+ return false;
429
+ }
430
+ return new Promise((resolve) => {
431
+ globalShowDialog({ type: "confirm", title, description, resolve });
432
+ });
433
+ };
434
+
435
+ // src/interface/Pressable.tsx
436
+ import { styled as styled7, View as View3 } from "tamagui";
437
+ var Pressable = styled7(View3, {
438
+ name: "BlinkPressable",
439
+ hitSlop: 10,
440
+ pressStyle: { opacity: 0.5 }
441
+ });
442
+
443
+ // src/interface/Image.tsx
444
+ import { styled as styled8, Image as TamaguiImage } from "tamagui";
445
+ var Image2 = styled8(TamaguiImage, {
446
+ name: "BlinkImage"
447
+ });
448
+
449
+ // src/interface/Separator.tsx
450
+ import { Separator as TamaguiSeparator, styled as styled9 } from "tamagui";
451
+ var Separator2 = styled9(TamaguiSeparator, {
452
+ name: "BlinkSeparator"
453
+ });
454
+
455
+ // src/interface/Badge.tsx
456
+ import { styled as styled10, SizableText as SizableText5, View as View4 } from "tamagui";
457
+ import { jsx as jsx5 } from "react/jsx-runtime";
458
+ var BadgeFrame = styled10(View4, {
459
+ name: "BlinkBadge",
460
+ paddingHorizontal: "$2",
461
+ paddingVertical: "$1",
462
+ borderRadius: "$10",
463
+ backgroundColor: "$color3",
464
+ alignSelf: "flex-start",
496
465
  variants: {
497
- size: {
498
- xs: { width: 24, height: 24, borderRadius: 12 },
499
- sm: { width: 32, height: 32, borderRadius: 16 },
500
- md: { width: 40, height: 40, borderRadius: 20 },
501
- lg: { width: 48, height: 48, borderRadius: 24 },
502
- xl: { width: 64, height: 64, borderRadius: 32 },
503
- xxl: { width: 80, height: 80, borderRadius: 40 }
466
+ variant: {
467
+ default: { backgroundColor: "$color3" },
468
+ success: { backgroundColor: "$green3" },
469
+ warning: { backgroundColor: "$yellow3" },
470
+ error: { backgroundColor: "$red3" },
471
+ info: { backgroundColor: "$blue3" }
504
472
  }
505
473
  },
506
- defaultVariants: {
507
- size: "md"
508
- }
474
+ defaultVariants: { variant: "default" }
509
475
  });
510
- var AvatarInitials = styled5(Text4, {
511
- name: "BlinkAvatarInitials",
512
- fontFamily: "$body",
476
+ var BadgeText = styled10(SizableText5, {
477
+ name: "BlinkBadgeText",
478
+ size: "$2",
513
479
  fontWeight: "600",
514
- color: "$textInverse",
480
+ color: "$color11"
481
+ });
482
+ function Badge({ children, variant = "default" }) {
483
+ return /* @__PURE__ */ jsx5(BadgeFrame, { variant, children: /* @__PURE__ */ jsx5(BadgeText, { children }) });
484
+ }
485
+
486
+ // src/layouts/StepPageLayout.tsx
487
+ import { SizableText as SizableText6, YStack as YStack3 } from "tamagui";
488
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
489
+ function StepPageLayout({ title, description, children, bottom }) {
490
+ return /* @__PURE__ */ jsxs4(YStack3, { flex: 1, padding: "$4", maxWidth: 500, marginHorizontal: "auto", width: "100%", children: [
491
+ /* @__PURE__ */ jsx6(YStack3, { gap: "$5", children: /* @__PURE__ */ jsxs4(YStack3, { gap: "$2", children: [
492
+ /* @__PURE__ */ jsx6(SizableText6, { size: "$8", fontWeight: "700", children: title }),
493
+ description && /* @__PURE__ */ jsx6(SizableText6, { size: "$5", fontWeight: "400", color: "$color10", children: description })
494
+ ] }) }),
495
+ /* @__PURE__ */ jsx6(YStack3, { paddingTop: "$5", gap: "$4", children }),
496
+ bottom && /* @__PURE__ */ jsx6(YStack3, { paddingTop: "$4", children: bottom })
497
+ ] });
498
+ }
499
+
500
+ // src/layouts/ScreenLayout.tsx
501
+ import { styled as styled11, YStack as YStack4 } from "tamagui";
502
+ var ScreenLayout = styled11(YStack4, {
503
+ name: "BlinkScreenLayout",
504
+ flex: 1,
505
+ backgroundColor: "$background",
515
506
  variants: {
516
- size: {
517
- xs: { fontSize: 10 },
518
- sm: { fontSize: 12 },
519
- md: { fontSize: 14 },
520
- lg: { fontSize: 18 },
521
- xl: { fontSize: 24 },
522
- xxl: { fontSize: 30 }
507
+ padded: {
508
+ true: { padding: "$4" }
509
+ },
510
+ centered: {
511
+ true: { alignItems: "center", justifyContent: "center" }
512
+ },
513
+ safe: {
514
+ true: { paddingTop: "$6" }
523
515
  }
524
- },
525
- defaultVariants: {
526
- size: "md"
527
516
  }
528
517
  });
529
- function getInitials(name) {
530
- return name.split(" ").map((p) => p[0]).join("").toUpperCase().slice(0, 2);
518
+
519
+ // src/layouts/Section.tsx
520
+ import { SizableText as SizableText7, YStack as YStack5 } from "tamagui";
521
+ import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
522
+ function Section({ title, description, children, gap = "$3" }) {
523
+ return /* @__PURE__ */ jsxs5(YStack5, { gap, children: [
524
+ title && /* @__PURE__ */ jsxs5(YStack5, { gap: "$1", children: [
525
+ /* @__PURE__ */ jsx7(SizableText7, { size: "$5", fontWeight: "600", color: "$color12", children: title }),
526
+ description && /* @__PURE__ */ jsx7(SizableText7, { size: "$3", color: "$color9", children: description })
527
+ ] }),
528
+ children
529
+ ] });
531
530
  }
532
- function Avatar({ uri, name, size = "md", ...props }) {
533
- if (uri) {
534
- return /* @__PURE__ */ jsx2(AvatarFrame, { size, ...props, children: /* @__PURE__ */ jsx2(
535
- Image,
536
- {
537
- source: { uri },
538
- style: { width: "100%", height: "100%" },
539
- resizeMode: "cover"
531
+
532
+ // src/layouts/ListItem.tsx
533
+ import { styled as styled12, SizableText as SizableText8, XStack as XStack3, YStack as YStack6, View as View5 } from "tamagui";
534
+ import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
535
+ var ListItemFrame = styled12(XStack3, {
536
+ name: "BlinkListItem",
537
+ alignItems: "center",
538
+ gap: "$3",
539
+ padding: "$3",
540
+ borderRadius: "$3",
541
+ variants: {
542
+ pressable: {
543
+ true: {
544
+ cursor: "pointer",
545
+ hoverStyle: { backgroundColor: "$color2" },
546
+ pressStyle: { backgroundColor: "$color3", opacity: 0.9 }
540
547
  }
541
- ) });
548
+ }
542
549
  }
543
- return /* @__PURE__ */ jsx2(AvatarFrame, { size, ...props, children: /* @__PURE__ */ jsx2(AvatarInitials, { size, children: name ? getInitials(name) : "?" }) });
550
+ });
551
+ function ListItem({ icon, title, subtitle, right, onPress }) {
552
+ return /* @__PURE__ */ jsxs6(ListItemFrame, { pressable: !!onPress, onPress, children: [
553
+ icon && /* @__PURE__ */ jsx8(View5, { children: icon }),
554
+ /* @__PURE__ */ jsxs6(YStack6, { flex: 1, gap: "$1", children: [
555
+ /* @__PURE__ */ jsx8(SizableText8, { size: "$4", fontWeight: "500", color: "$color12", children: title }),
556
+ subtitle && /* @__PURE__ */ jsx8(SizableText8, { size: "$2", color: "$color9", children: subtitle })
557
+ ] }),
558
+ right
559
+ ] });
560
+ }
561
+
562
+ // src/layouts/Divider.tsx
563
+ import { Separator as Separator3, SizableText as SizableText9, XStack as XStack4 } from "tamagui";
564
+ import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
565
+ function Divider({ label }) {
566
+ if (!label) return /* @__PURE__ */ jsx9(Separator3, { borderColor: "$color4" });
567
+ return /* @__PURE__ */ jsxs7(XStack4, { alignItems: "center", gap: "$3", children: [
568
+ /* @__PURE__ */ jsx9(Separator3, { flex: 1, borderColor: "$color4" }),
569
+ /* @__PURE__ */ jsx9(SizableText9, { size: "$2", color: "$color9", children: label }),
570
+ /* @__PURE__ */ jsx9(Separator3, { flex: 1, borderColor: "$color4" })
571
+ ] });
572
+ }
573
+
574
+ // src/layouts/KeyboardStickyFooter.tsx
575
+ import { YStack as YStack7 } from "tamagui";
576
+ import { jsx as jsx10 } from "react/jsx-runtime";
577
+ function KeyboardStickyFooter({ children, offset }) {
578
+ return /* @__PURE__ */ jsx10(YStack7, { maxWidth: 500, alignSelf: "center", paddingTop: "$8", paddingBottom: "$4", style: { paddingBottom: offset }, children });
579
+ }
580
+
581
+ // src/patterns/PaywallScreen.tsx
582
+ import { Button as Button3, SizableText as SizableText10, XStack as XStack5, YStack as YStack8, Circle as Circle2 } from "tamagui";
583
+ import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
584
+ function PaywallScreen({
585
+ title = "Upgrade Your Experience",
586
+ subtitle = "Choose the plan that works for you",
587
+ plans,
588
+ selectedPlan,
589
+ onSelectPlan,
590
+ onContinue,
591
+ onRestore,
592
+ continueLabel = "Continue"
593
+ }) {
594
+ return /* @__PURE__ */ jsxs8(YStack8, { flex: 1, padding: "$4", gap: "$5", backgroundColor: "$background", children: [
595
+ /* @__PURE__ */ jsxs8(YStack8, { gap: "$2", paddingTop: "$6", children: [
596
+ /* @__PURE__ */ jsx11(SizableText10, { size: "$9", fontWeight: "700", textAlign: "center", children: title }),
597
+ /* @__PURE__ */ jsx11(SizableText10, { size: "$4", color: "$color10", textAlign: "center", children: subtitle })
598
+ ] }),
599
+ /* @__PURE__ */ jsx11(YStack8, { gap: "$3", flex: 1, children: plans.map((plan) => /* @__PURE__ */ jsxs8(
600
+ YStack8,
601
+ {
602
+ padding: "$4",
603
+ borderRadius: "$5",
604
+ borderWidth: 2,
605
+ borderColor: selectedPlan === plan.id ? "$color9" : "$color4",
606
+ backgroundColor: selectedPlan === plan.id ? "$color2" : "$color1",
607
+ pressStyle: { scale: 0.98 },
608
+ onPress: () => onSelectPlan?.(plan.id),
609
+ cursor: "pointer",
610
+ children: [
611
+ /* @__PURE__ */ jsxs8(XStack5, { justifyContent: "space-between", alignItems: "center", children: [
612
+ /* @__PURE__ */ jsxs8(YStack8, { children: [
613
+ /* @__PURE__ */ jsx11(SizableText10, { size: "$5", fontWeight: "600", children: plan.name }),
614
+ /* @__PURE__ */ jsxs8(XStack5, { alignItems: "baseline", gap: "$1", children: [
615
+ /* @__PURE__ */ jsx11(SizableText10, { size: "$8", fontWeight: "700", children: plan.price }),
616
+ /* @__PURE__ */ jsxs8(SizableText10, { size: "$3", color: "$color9", children: [
617
+ "/",
618
+ plan.period
619
+ ] })
620
+ ] })
621
+ ] }),
622
+ plan.popular && /* @__PURE__ */ jsx11(YStack8, { backgroundColor: "$color9", paddingHorizontal: "$2", paddingVertical: "$1", borderRadius: "$10", children: /* @__PURE__ */ jsx11(SizableText10, { size: "$1", color: "$color1", fontWeight: "600", children: "POPULAR" }) })
623
+ ] }),
624
+ /* @__PURE__ */ jsx11(YStack8, { gap: "$2", paddingTop: "$3", children: plan.features.map((feature, i) => /* @__PURE__ */ jsxs8(XStack5, { gap: "$2", alignItems: "center", children: [
625
+ /* @__PURE__ */ jsx11(Circle2, { size: 6, backgroundColor: "$green9" }),
626
+ /* @__PURE__ */ jsx11(SizableText10, { size: "$3", color: "$color11", children: feature })
627
+ ] }, i)) })
628
+ ]
629
+ },
630
+ plan.id
631
+ )) }),
632
+ /* @__PURE__ */ jsxs8(YStack8, { gap: "$3", paddingBottom: "$4", children: [
633
+ /* @__PURE__ */ jsx11(
634
+ Button3,
635
+ {
636
+ size: "$5",
637
+ backgroundColor: "$color9",
638
+ color: "$color1",
639
+ onPress: onContinue,
640
+ hoverStyle: { backgroundColor: "$color10" },
641
+ pressStyle: { backgroundColor: "$color8" },
642
+ borderRadius: "$5",
643
+ children: continueLabel
644
+ }
645
+ ),
646
+ onRestore && /* @__PURE__ */ jsx11(Button3, { size: "$3", chromeless: true, onPress: onRestore, children: /* @__PURE__ */ jsx11(SizableText10, { size: "$3", color: "$color9", children: "Restore Purchases" }) })
647
+ ] })
648
+ ] });
649
+ }
650
+
651
+ // src/patterns/OnboardingCarousel.tsx
652
+ import { useState as useState2 } from "react";
653
+ import { Button as Button4, SizableText as SizableText11, XStack as XStack6, YStack as YStack9, Circle as Circle3 } from "tamagui";
654
+ import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
655
+ function OnboardingCarousel({
656
+ steps,
657
+ onComplete,
658
+ onSkip,
659
+ completeLabel = "Get Started",
660
+ skipLabel = "Skip",
661
+ nextLabel = "Next"
662
+ }) {
663
+ const [current, setCurrent] = useState2(0);
664
+ const isLast = current === steps.length - 1;
665
+ const step = steps[current];
666
+ return /* @__PURE__ */ jsxs9(YStack9, { flex: 1, backgroundColor: "$background", padding: "$4", justifyContent: "space-between", children: [
667
+ /* @__PURE__ */ jsx12(XStack6, { justifyContent: "flex-end", paddingTop: "$4", children: !isLast && onSkip && /* @__PURE__ */ jsx12(Button4, { chromeless: true, onPress: onSkip, children: /* @__PURE__ */ jsx12(SizableText11, { size: "$4", color: "$color9", children: skipLabel }) }) }),
668
+ /* @__PURE__ */ jsxs9(YStack9, { flex: 1, alignItems: "center", justifyContent: "center", gap: "$5", paddingHorizontal: "$4", children: [
669
+ step?.icon && /* @__PURE__ */ jsx12(Circle3, { size: 120, backgroundColor: "$color2", alignItems: "center", justifyContent: "center", children: step.icon }),
670
+ /* @__PURE__ */ jsxs9(YStack9, { gap: "$3", alignItems: "center", children: [
671
+ /* @__PURE__ */ jsx12(SizableText11, { size: "$9", fontWeight: "700", textAlign: "center", children: step?.title }),
672
+ /* @__PURE__ */ jsx12(SizableText11, { size: "$4", color: "$color10", textAlign: "center", maxWidth: 300, children: step?.description })
673
+ ] })
674
+ ] }),
675
+ /* @__PURE__ */ jsxs9(YStack9, { gap: "$4", paddingBottom: "$6", children: [
676
+ /* @__PURE__ */ jsx12(XStack6, { justifyContent: "center", gap: "$2", children: steps.map((_, i) => /* @__PURE__ */ jsx12(
677
+ Circle3,
678
+ {
679
+ size: 8,
680
+ backgroundColor: i === current ? "$color9" : "$color4",
681
+ animation: "quick"
682
+ },
683
+ i
684
+ )) }),
685
+ /* @__PURE__ */ jsx12(
686
+ Button4,
687
+ {
688
+ size: "$5",
689
+ backgroundColor: "$color9",
690
+ color: "$color1",
691
+ borderRadius: "$5",
692
+ hoverStyle: { backgroundColor: "$color10" },
693
+ pressStyle: { backgroundColor: "$color8" },
694
+ onPress: () => isLast ? onComplete?.() : setCurrent((c) => c + 1),
695
+ children: isLast ? completeLabel : nextLabel
696
+ }
697
+ )
698
+ ] })
699
+ ] });
700
+ }
701
+
702
+ // src/patterns/ChatBubble.tsx
703
+ import { SizableText as SizableText12, XStack as XStack7, YStack as YStack10, Circle as Circle4, Image as Image3 } from "tamagui";
704
+ import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
705
+ function ChatBubble({ message, showAvatar = true }) {
706
+ const isUser = message.sender === "user";
707
+ return /* @__PURE__ */ jsxs10(
708
+ XStack7,
709
+ {
710
+ alignSelf: isUser ? "flex-end" : "flex-start",
711
+ maxWidth: "80%",
712
+ gap: "$2",
713
+ flexDirection: isUser ? "row-reverse" : "row",
714
+ children: [
715
+ showAvatar && !isUser && /* @__PURE__ */ jsx13(Circle4, { size: 32, backgroundColor: "$color4", overflow: "hidden", children: message.avatar ? /* @__PURE__ */ jsx13(Image3, { source: { uri: message.avatar }, width: 32, height: 32, objectFit: "cover" }) : /* @__PURE__ */ jsx13(SizableText12, { size: "$2", fontWeight: "600", color: "$color11", children: message.senderName?.[0]?.toUpperCase() ?? "?" }) }),
716
+ /* @__PURE__ */ jsxs10(
717
+ YStack10,
718
+ {
719
+ backgroundColor: isUser ? "$color9" : "$color3",
720
+ paddingHorizontal: "$3",
721
+ paddingVertical: "$2.5",
722
+ borderRadius: "$5",
723
+ borderBottomRightRadius: isUser ? "$2" : "$5",
724
+ borderBottomLeftRadius: isUser ? "$5" : "$2",
725
+ gap: "$1",
726
+ children: [
727
+ /* @__PURE__ */ jsx13(SizableText12, { size: "$4", color: isUser ? "$color1" : "$color12", children: message.text }),
728
+ message.timestamp && /* @__PURE__ */ jsx13(SizableText12, { size: "$1", color: isUser ? "$color3" : "$color9", alignSelf: "flex-end", children: message.timestamp })
729
+ ]
730
+ }
731
+ )
732
+ ]
733
+ }
734
+ );
735
+ }
736
+
737
+ // src/patterns/SettingsScreen.tsx
738
+ import { Separator as Separator4, SizableText as SizableText13, Switch, XStack as XStack8, YStack as YStack11 } from "tamagui";
739
+ import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
740
+ function SettingsItemRow({ item }) {
741
+ return /* @__PURE__ */ jsxs11(
742
+ XStack8,
743
+ {
744
+ alignItems: "center",
745
+ gap: "$3",
746
+ paddingVertical: "$3",
747
+ paddingHorizontal: "$4",
748
+ hoverStyle: item.onPress ? { backgroundColor: "$color2" } : void 0,
749
+ pressStyle: item.onPress ? { backgroundColor: "$color3" } : void 0,
750
+ onPress: item.onPress,
751
+ cursor: item.onPress ? "pointer" : void 0,
752
+ children: [
753
+ item.icon && /* @__PURE__ */ jsx14(YStack11, { width: 24, alignItems: "center", children: item.icon }),
754
+ /* @__PURE__ */ jsxs11(YStack11, { flex: 1, gap: "$1", children: [
755
+ /* @__PURE__ */ jsx14(SizableText13, { size: "$4", fontWeight: "500", children: item.title }),
756
+ item.subtitle && /* @__PURE__ */ jsx14(SizableText13, { size: "$2", color: "$color9", children: item.subtitle })
757
+ ] }),
758
+ item.type === "toggle" ? /* @__PURE__ */ jsx14(Switch, { size: "$3", checked: item.value, onCheckedChange: item.onValueChange, children: /* @__PURE__ */ jsx14(Switch.Thumb, { animation: "quick" }) }) : item.right ? item.right : item.onPress && /* @__PURE__ */ jsx14(SizableText13, { size: "$5", color: "$color8", children: "\u203A" })
759
+ ]
760
+ }
761
+ );
762
+ }
763
+ function SettingsScreen({ sections, header }) {
764
+ return /* @__PURE__ */ jsxs11(YStack11, { flex: 1, backgroundColor: "$background", children: [
765
+ header,
766
+ /* @__PURE__ */ jsx14(YStack11, { gap: "$4", paddingVertical: "$2", children: sections.map((section, si) => /* @__PURE__ */ jsxs11(YStack11, { children: [
767
+ section.title && /* @__PURE__ */ jsx14(
768
+ SizableText13,
769
+ {
770
+ size: "$2",
771
+ fontWeight: "600",
772
+ color: "$color9",
773
+ paddingHorizontal: "$4",
774
+ paddingBottom: "$2",
775
+ textTransform: "uppercase",
776
+ children: section.title
777
+ }
778
+ ),
779
+ /* @__PURE__ */ jsx14(YStack11, { backgroundColor: "$color1", borderRadius: "$4", marginHorizontal: "$3", overflow: "hidden", children: section.items.map((item, ii) => /* @__PURE__ */ jsxs11(YStack11, { children: [
780
+ /* @__PURE__ */ jsx14(SettingsItemRow, { item }),
781
+ ii < section.items.length - 1 && /* @__PURE__ */ jsx14(Separator4, { borderColor: "$color3", marginLeft: "$12" })
782
+ ] }, item.id)) })
783
+ ] }, si)) })
784
+ ] });
785
+ }
786
+
787
+ // src/patterns/EmptyState.tsx
788
+ import { Button as Button5, SizableText as SizableText14, YStack as YStack12 } from "tamagui";
789
+ import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
790
+ function EmptyState({ icon, title, description, actionLabel, onAction }) {
791
+ return /* @__PURE__ */ jsxs12(YStack12, { flex: 1, alignItems: "center", justifyContent: "center", gap: "$4", padding: "$6", children: [
792
+ icon,
793
+ /* @__PURE__ */ jsxs12(YStack12, { gap: "$2", alignItems: "center", children: [
794
+ /* @__PURE__ */ jsx15(SizableText14, { size: "$6", fontWeight: "600", textAlign: "center", children: title }),
795
+ description && /* @__PURE__ */ jsx15(SizableText14, { size: "$4", color: "$color9", textAlign: "center", maxWidth: 280, children: description })
796
+ ] }),
797
+ actionLabel && onAction && /* @__PURE__ */ jsx15(
798
+ Button5,
799
+ {
800
+ size: "$4",
801
+ backgroundColor: "$color9",
802
+ color: "$color1",
803
+ borderRadius: "$4",
804
+ hoverStyle: { backgroundColor: "$color10" },
805
+ pressStyle: { backgroundColor: "$color8" },
806
+ onPress: onAction,
807
+ children: actionLabel
808
+ }
809
+ )
810
+ ] });
811
+ }
812
+
813
+ // src/patterns/ProfileHeader.tsx
814
+ import { Circle as Circle5, Image as Image4, SizableText as SizableText15, XStack as XStack9, YStack as YStack13 } from "tamagui";
815
+ import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
816
+ function ProfileHeader({ name, subtitle, avatar, stats, actions }) {
817
+ return /* @__PURE__ */ jsxs13(YStack13, { alignItems: "center", gap: "$4", paddingVertical: "$6", paddingHorizontal: "$4", children: [
818
+ /* @__PURE__ */ jsx16(Circle5, { size: 80, backgroundColor: "$color4", overflow: "hidden", children: avatar ? /* @__PURE__ */ jsx16(Image4, { source: { uri: avatar }, width: 80, height: 80, objectFit: "cover" }) : /* @__PURE__ */ jsx16(SizableText15, { size: "$9", fontWeight: "700", color: "$color11", children: name[0]?.toUpperCase() ?? "?" }) }),
819
+ /* @__PURE__ */ jsxs13(YStack13, { alignItems: "center", gap: "$1", children: [
820
+ /* @__PURE__ */ jsx16(SizableText15, { size: "$7", fontWeight: "700", children: name }),
821
+ subtitle && /* @__PURE__ */ jsx16(SizableText15, { size: "$4", color: "$color10", children: subtitle })
822
+ ] }),
823
+ stats && stats.length > 0 && /* @__PURE__ */ jsx16(XStack9, { gap: "$6", children: stats.map((stat, i) => /* @__PURE__ */ jsxs13(YStack13, { alignItems: "center", gap: "$1", children: [
824
+ /* @__PURE__ */ jsx16(SizableText15, { size: "$6", fontWeight: "700", children: stat.value }),
825
+ /* @__PURE__ */ jsx16(SizableText15, { size: "$2", color: "$color9", children: stat.label })
826
+ ] }, i)) }),
827
+ actions
828
+ ] });
544
829
  }
545
830
  export {
546
831
  Avatar,
832
+ Badge,
547
833
  BlinkText,
548
834
  Button,
549
835
  Card,
836
+ ChatBubble,
837
+ DialogProvider,
838
+ Divider,
839
+ EmptyState,
840
+ H1,
841
+ H2,
842
+ H3,
843
+ H4,
844
+ H5,
845
+ H6,
846
+ Image2 as Image,
550
847
  Input,
551
- blinkConfig
848
+ KeyboardStickyFooter,
849
+ ListItem,
850
+ OnboardingCarousel,
851
+ PageContainer,
852
+ PageMainContainer,
853
+ PaywallScreen,
854
+ Pressable,
855
+ ProfileHeader,
856
+ ScreenLayout,
857
+ Section,
858
+ SepHeading,
859
+ Separator2 as Separator,
860
+ SettingsScreen,
861
+ StepPageLayout,
862
+ SubHeading,
863
+ blinkConfig,
864
+ dialogConfirm,
865
+ showError
552
866
  };
553
867
  //# sourceMappingURL=index.mjs.map