@boostdev/design-system-react-native 0.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/dist/index.cjs ADDED
@@ -0,0 +1,4337 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ Accordion: () => Accordion,
34
+ Alert: () => Alert,
35
+ Avatar: () => Avatar,
36
+ Badge: () => Badge,
37
+ Breadcrumb: () => Breadcrumb,
38
+ Button: () => Button,
39
+ ButtonContainer: () => ButtonContainer,
40
+ ButtonGroup: () => ButtonGroup,
41
+ Calendar: () => Calendar,
42
+ Card: () => Card,
43
+ Carousel: () => Carousel,
44
+ Checkbox: () => Checkbox,
45
+ CheckboxGroup: () => CheckboxGroup,
46
+ Collapsible: () => Collapsible,
47
+ Combobox: () => Combobox,
48
+ DescriptionList: () => DescriptionList,
49
+ Dialog: () => Dialog,
50
+ Drawer: () => Drawer,
51
+ DropdownMenu: () => DropdownMenu,
52
+ FileInput: () => FileInput,
53
+ FormInput: () => FormInput,
54
+ IconWrapper: () => IconWrapper,
55
+ Label: () => Label,
56
+ Link: () => Link,
57
+ Loading: () => Loading,
58
+ Message: () => Message,
59
+ NotificationBanner: () => NotificationBanner,
60
+ NumberInput: () => NumberInput,
61
+ Pagination: () => Pagination,
62
+ Popover: () => Popover,
63
+ Progress: () => Progress,
64
+ ProgressCircle: () => ProgressCircle,
65
+ Radio: () => Radio,
66
+ RadioGroup: () => RadioGroup,
67
+ Rating: () => Rating,
68
+ SectionHeader: () => SectionHeader,
69
+ SegmentedControl: () => SegmentedControl,
70
+ Select: () => Select,
71
+ Separator: () => Separator,
72
+ Skeleton: () => Skeleton,
73
+ Slider: () => Slider,
74
+ Switch: () => Switch,
75
+ Table: () => Table,
76
+ Tabs: () => Tabs,
77
+ Textarea: () => Textarea,
78
+ ThemeProvider: () => ThemeProvider,
79
+ ToastProvider: () => ToastProvider,
80
+ Tooltip: () => Tooltip,
81
+ Typography: () => Typography,
82
+ animation: () => import_native.animation,
83
+ border: () => import_native.border,
84
+ colors: () => import_native.colors,
85
+ font: () => import_native.font,
86
+ lineHeight: () => lineHeight,
87
+ spacing: () => import_native.spacing,
88
+ useTheme: () => useTheme,
89
+ useToast: () => useToast,
90
+ zIndex: () => import_native.zIndex
91
+ });
92
+ module.exports = __toCommonJS(index_exports);
93
+
94
+ // src/native/ThemeContext.tsx
95
+ var import_react = require("react");
96
+ var import_react_native = require("react-native");
97
+
98
+ // src/native/tokens.ts
99
+ var import_native = require("@boostdev/design-system-foundation/native");
100
+ var lineHeight = {
101
+ display: Math.round(import_native.font.size.display * import_native.font.lineHeight.display),
102
+ heading1: Math.round(import_native.font.size.heading1 * import_native.font.lineHeight.heading),
103
+ heading2: Math.round(import_native.font.size.heading2 * import_native.font.lineHeight.heading),
104
+ heading3: Math.round(import_native.font.size.heading3 * import_native.font.lineHeight.heading),
105
+ body: Math.round(import_native.font.size.body * import_native.font.lineHeight.body),
106
+ bodyS: Math.round(import_native.font.size.bodyS * import_native.font.lineHeight.body)
107
+ };
108
+
109
+ // src/native/ThemeContext.tsx
110
+ var import_jsx_runtime = require("react/jsx-runtime");
111
+ var ThemeContext = (0, import_react.createContext)(null);
112
+ function ThemeProvider({ children, colorScheme }) {
113
+ const systemScheme = (0, import_react_native.useColorScheme)();
114
+ const isDark = (colorScheme ?? systemScheme) === "dark";
115
+ const value = (0, import_react.useMemo)(
116
+ () => ({ colors: isDark ? import_native.colors.dark : import_native.colors.light, isDark }),
117
+ [isDark]
118
+ );
119
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeContext.Provider, { value, children });
120
+ }
121
+ function useTheme() {
122
+ const ctx = (0, import_react.useContext)(ThemeContext);
123
+ if (!ctx) throw new Error("useTheme must be used within ThemeProvider");
124
+ return ctx;
125
+ }
126
+
127
+ // src/components/ui/Typography/Typography.native.tsx
128
+ var import_react_native2 = require("react-native");
129
+ var import_jsx_runtime2 = require("react/jsx-runtime");
130
+ var styles = import_react_native2.StyleSheet.create({
131
+ base: {
132
+ fontFamily: import_native.font.family.body,
133
+ fontWeight: import_native.font.weight.body
134
+ },
135
+ h1: {
136
+ fontSize: import_native.font.size.heading1,
137
+ fontFamily: import_native.font.family.heading,
138
+ fontWeight: import_native.font.weight.heading,
139
+ lineHeight: lineHeight.heading1
140
+ },
141
+ h2: {
142
+ fontSize: import_native.font.size.heading2,
143
+ fontFamily: import_native.font.family.heading,
144
+ fontWeight: import_native.font.weight.heading,
145
+ lineHeight: lineHeight.heading2
146
+ },
147
+ h3: {
148
+ fontSize: import_native.font.size.heading3,
149
+ fontFamily: import_native.font.family.heading,
150
+ fontWeight: import_native.font.weight.heading,
151
+ lineHeight: lineHeight.heading3
152
+ },
153
+ body: {
154
+ fontSize: import_native.font.size.body,
155
+ lineHeight: lineHeight.body
156
+ },
157
+ body_s: {
158
+ fontSize: import_native.font.size.bodyS,
159
+ lineHeight: lineHeight.bodyS
160
+ }
161
+ });
162
+ var accessibilityRoles = {
163
+ h1: "header",
164
+ h2: "header",
165
+ h3: "header",
166
+ body: "text",
167
+ body_s: "text"
168
+ };
169
+ function Typography({ variant = "body", children, style }) {
170
+ const { colors: colors2 } = useTheme();
171
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
172
+ import_react_native2.Text,
173
+ {
174
+ accessibilityRole: accessibilityRoles[variant],
175
+ style: [styles.base, styles[variant], { color: colors2.colorOnBg }, style],
176
+ children
177
+ }
178
+ );
179
+ }
180
+
181
+ // src/components/ui/Badge/Badge.native.tsx
182
+ var import_react_native3 = require("react-native");
183
+ var import_jsx_runtime3 = require("react/jsx-runtime");
184
+ var styles2 = import_react_native3.StyleSheet.create({
185
+ badge: {
186
+ alignSelf: "flex-start",
187
+ flexDirection: "row",
188
+ alignItems: "center",
189
+ justifyContent: "center",
190
+ paddingVertical: import_native.spacing.xxs,
191
+ paddingHorizontal: import_native.spacing.xs,
192
+ borderRadius: import_native.border.radius.full
193
+ },
194
+ text: {
195
+ fontSize: import_native.font.size.bodyS,
196
+ fontFamily: import_native.font.family.body,
197
+ fontWeight: import_native.font.weight.semibold,
198
+ lineHeight: import_native.font.size.bodyS
199
+ }
200
+ });
201
+ function Badge({ children, variant = "primary", style }) {
202
+ const { colors: colors2 } = useTheme();
203
+ const variantColors = {
204
+ primary: { bg: colors2.colorInteractive, text: colors2.colorOnInteractive },
205
+ secondary: { bg: colors2.colorBgSubtle, text: colors2.colorOnBgSubtle },
206
+ success: { bg: colors2.colorSuccess, text: colors2.colorOnSuccess },
207
+ error: { bg: colors2.colorError, text: colors2.colorOnError },
208
+ warning: { bg: colors2.colorWarning, text: colors2.colorOnWarning }
209
+ };
210
+ const { bg, text } = variantColors[variant];
211
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.View, { style: [styles2.badge, { backgroundColor: bg }, style], children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { style: [styles2.text, { color: text }], children }) });
212
+ }
213
+
214
+ // src/components/ui/Avatar/Avatar.native.tsx
215
+ var import_react_native4 = require("react-native");
216
+ var import_jsx_runtime4 = require("react/jsx-runtime");
217
+ var sizeMap = {
218
+ small: { container: 32, fontSize: import_native.font.size.bodyS },
219
+ medium: { container: 48, fontSize: import_native.font.size.body },
220
+ large: { container: 72, fontSize: import_native.font.size.heading3 }
221
+ };
222
+ function getInitials(name) {
223
+ return name.split(" ").filter(Boolean).slice(0, 2).map((word) => word[0].toUpperCase()).join("");
224
+ }
225
+ var styles3 = import_react_native4.StyleSheet.create({
226
+ container: {
227
+ borderRadius: import_native.border.radius.full,
228
+ overflow: "hidden",
229
+ alignItems: "center",
230
+ justifyContent: "center"
231
+ },
232
+ image: {
233
+ width: "100%",
234
+ height: "100%"
235
+ },
236
+ initials: {
237
+ fontFamily: import_native.font.family.body,
238
+ fontWeight: import_native.font.weight.semibold
239
+ }
240
+ });
241
+ function Avatar({ src, alt, name, size = "medium", style }) {
242
+ const { colors: colors2 } = useTheme();
243
+ const { container, fontSize } = sizeMap[size];
244
+ const label = alt ?? name ?? "User avatar";
245
+ if (src) {
246
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
247
+ import_react_native4.View,
248
+ {
249
+ style: [styles3.container, { width: container, height: container }, style],
250
+ accessibilityLabel: label,
251
+ accessibilityRole: "image",
252
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Image, { source: { uri: src }, style: styles3.image })
253
+ }
254
+ );
255
+ }
256
+ const initials = name ? getInitials(name) : "";
257
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
258
+ import_react_native4.View,
259
+ {
260
+ style: [
261
+ styles3.container,
262
+ { width: container, height: container, backgroundColor: colors2.colorBlue },
263
+ style
264
+ ],
265
+ accessibilityLabel: label,
266
+ accessibilityRole: "image",
267
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
268
+ import_react_native4.Text,
269
+ {
270
+ style: [styles3.initials, { fontSize, color: colors2.colorOnBlue }],
271
+ importantForAccessibility: "no",
272
+ accessibilityElementsHidden: true,
273
+ children: initials
274
+ }
275
+ )
276
+ }
277
+ );
278
+ }
279
+
280
+ // src/components/ui/Separator/Separator.native.tsx
281
+ var import_react_native5 = require("react-native");
282
+ var import_jsx_runtime5 = require("react/jsx-runtime");
283
+ var styles4 = import_react_native5.StyleSheet.create({
284
+ horizontal: {
285
+ height: import_react_native5.StyleSheet.hairlineWidth,
286
+ width: "100%"
287
+ },
288
+ vertical: {
289
+ width: import_react_native5.StyleSheet.hairlineWidth,
290
+ alignSelf: "stretch"
291
+ }
292
+ });
293
+ function Separator({ orientation = "horizontal", style }) {
294
+ const { colors: colors2 } = useTheme();
295
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
296
+ import_react_native5.View,
297
+ {
298
+ accessibilityRole: "none",
299
+ style: [
300
+ orientation === "vertical" ? styles4.vertical : styles4.horizontal,
301
+ { backgroundColor: colors2.colorBgSubtle },
302
+ style
303
+ ]
304
+ }
305
+ );
306
+ }
307
+
308
+ // src/components/ui/Loading/Loading.native.tsx
309
+ var import_react_native6 = require("react-native");
310
+ var import_jsx_runtime6 = require("react/jsx-runtime");
311
+ var rnSize = {
312
+ small: "small",
313
+ medium: "large",
314
+ large: "large"
315
+ };
316
+ function Loading({ size = "medium", accessibilityLabel = "Loading", style }) {
317
+ const { colors: colors2 } = useTheme();
318
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
319
+ import_react_native6.ActivityIndicator,
320
+ {
321
+ size: rnSize[size],
322
+ color: colors2.colorInteractive,
323
+ style,
324
+ accessibilityRole: "progressbar",
325
+ accessibilityLabel
326
+ }
327
+ );
328
+ }
329
+
330
+ // src/components/ui/Progress/Progress.native.tsx
331
+ var import_react_native7 = require("react-native");
332
+ var import_jsx_runtime7 = require("react/jsx-runtime");
333
+ var trackHeight = {
334
+ small: 4,
335
+ medium: 8,
336
+ large: 12
337
+ };
338
+ var styles5 = import_react_native7.StyleSheet.create({
339
+ container: {
340
+ width: "100%"
341
+ },
342
+ labelRow: {
343
+ flexDirection: "row",
344
+ justifyContent: "space-between",
345
+ marginBottom: import_native.spacing.xxs
346
+ },
347
+ labelText: {
348
+ fontSize: import_native.font.size.bodyS,
349
+ fontFamily: import_native.font.family.body,
350
+ lineHeight: lineHeight.bodyS
351
+ },
352
+ track: {
353
+ width: "100%",
354
+ borderRadius: import_native.border.radius.full,
355
+ overflow: "hidden"
356
+ },
357
+ fill: {
358
+ height: "100%",
359
+ borderRadius: import_native.border.radius.full
360
+ }
361
+ });
362
+ function Progress({
363
+ value,
364
+ max = 100,
365
+ label,
366
+ showLabel = false,
367
+ size = "medium",
368
+ style
369
+ }) {
370
+ const { colors: colors2 } = useTheme();
371
+ const percentage = Math.min(100, Math.max(0, value / max * 100));
372
+ const height = trackHeight[size];
373
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native7.View, { style: [styles5.container, style], children: [
374
+ showLabel && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native7.View, { style: styles5.labelRow, children: [
375
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native7.Text, { style: [styles5.labelText, { color: colors2.colorOnBg }], children: label }),
376
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native7.Text, { style: [styles5.labelText, { color: colors2.colorOnBgSubtle }], children: [
377
+ Math.round(percentage),
378
+ "%"
379
+ ] })
380
+ ] }),
381
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
382
+ import_react_native7.View,
383
+ {
384
+ style: [styles5.track, { height, backgroundColor: colors2.colorBgSubtle }],
385
+ accessibilityRole: "progressbar",
386
+ accessibilityLabel: label,
387
+ accessibilityValue: { min: 0, max, now: value },
388
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
389
+ import_react_native7.View,
390
+ {
391
+ style: [
392
+ styles5.fill,
393
+ { width: `${percentage}%`, backgroundColor: colors2.colorInteractive }
394
+ ]
395
+ }
396
+ )
397
+ }
398
+ )
399
+ ] });
400
+ }
401
+
402
+ // src/components/ui/Skeleton/Skeleton.native.tsx
403
+ var import_react2 = require("react");
404
+ var import_react_native8 = require("react-native");
405
+ var import_jsx_runtime8 = require("react/jsx-runtime");
406
+ var styles6 = import_react_native8.StyleSheet.create({
407
+ skeleton: {
408
+ borderRadius: import_native.border.radius.xs,
409
+ overflow: "hidden"
410
+ }
411
+ });
412
+ function Skeleton({ style }) {
413
+ const { colors: colors2 } = useTheme();
414
+ const opacity = (0, import_react2.useRef)(new import_react_native8.Animated.Value(1)).current;
415
+ (0, import_react2.useEffect)(() => {
416
+ const anim = import_react_native8.Animated.loop(
417
+ import_react_native8.Animated.sequence([
418
+ import_react_native8.Animated.timing(opacity, { toValue: 0.4, duration: 700, useNativeDriver: true }),
419
+ import_react_native8.Animated.timing(opacity, { toValue: 1, duration: 700, useNativeDriver: true })
420
+ ])
421
+ );
422
+ anim.start();
423
+ return () => anim.stop();
424
+ }, [opacity]);
425
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
426
+ import_react_native8.Animated.View,
427
+ {
428
+ importantForAccessibility: "no-hide-descendants",
429
+ style: [
430
+ styles6.skeleton,
431
+ { backgroundColor: colors2.colorBgSubtle, opacity },
432
+ style
433
+ ]
434
+ }
435
+ );
436
+ }
437
+
438
+ // src/components/ui/Alert/Alert.native.tsx
439
+ var import_react_native9 = require("react-native");
440
+ var import_jsx_runtime9 = require("react/jsx-runtime");
441
+ var styles7 = import_react_native9.StyleSheet.create({
442
+ alert: {
443
+ flexDirection: "row",
444
+ alignItems: "flex-start",
445
+ padding: import_native.spacing.m,
446
+ borderRadius: import_native.border.radius.s,
447
+ gap: import_native.spacing.xs
448
+ },
449
+ icon: {
450
+ flexShrink: 0,
451
+ marginTop: 2
452
+ },
453
+ content: {
454
+ flex: 1,
455
+ gap: import_native.spacing.xxs
456
+ },
457
+ title: {
458
+ fontSize: import_native.font.size.body,
459
+ fontFamily: import_native.font.family.body,
460
+ fontWeight: import_native.font.weight.semibold,
461
+ lineHeight: lineHeight.body
462
+ },
463
+ body: {
464
+ fontSize: import_native.font.size.bodyS,
465
+ fontFamily: import_native.font.family.body,
466
+ lineHeight: lineHeight.bodyS
467
+ },
468
+ dismiss: {
469
+ padding: import_native.spacing.xxs,
470
+ flexShrink: 0
471
+ }
472
+ });
473
+ function Alert({
474
+ variant = "info",
475
+ icon,
476
+ title,
477
+ children,
478
+ onDismiss,
479
+ style
480
+ }) {
481
+ const { colors: colors2 } = useTheme();
482
+ const isUrgent = variant === "error" || variant === "warning";
483
+ const variantColors = {
484
+ info: { bg: colors2.colorBlueSubtle, text: colors2.colorOnBlueSubtle, border: colors2.colorBlue },
485
+ success: { bg: colors2.colorSuccessSubtle, text: colors2.colorOnSuccessSubtle, border: colors2.colorSuccess },
486
+ warning: { bg: colors2.colorOrangeSubtle, text: colors2.colorOnOrangeSubtle, border: colors2.colorWarning },
487
+ error: { bg: colors2.colorRedSubtle, text: colors2.colorOnBg, border: colors2.colorError }
488
+ };
489
+ const { bg, text, border: borderColor } = variantColors[variant];
490
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
491
+ import_react_native9.View,
492
+ {
493
+ accessibilityRole: isUrgent ? "alert" : "none",
494
+ accessibilityLiveRegion: isUrgent ? "assertive" : "polite",
495
+ style: [styles7.alert, { backgroundColor: bg, borderStartWidth: import_native.spacing.s, borderStartColor: borderColor }, style],
496
+ children: [
497
+ icon && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native9.View, { style: styles7.icon, children: icon }),
498
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native9.View, { style: styles7.content, children: [
499
+ title && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native9.Text, { style: [styles7.title, { color: text }], children: title }),
500
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native9.Text, { style: [styles7.body, { color: text }], children })
501
+ ] }),
502
+ onDismiss && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
503
+ import_react_native9.Pressable,
504
+ {
505
+ onPress: onDismiss,
506
+ style: styles7.dismiss,
507
+ accessibilityLabel: "Dismiss alert",
508
+ accessibilityRole: "button",
509
+ hitSlop: 8,
510
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native9.Text, { style: { color: text, fontSize: 16 }, children: "\u2715" })
511
+ }
512
+ )
513
+ ]
514
+ }
515
+ );
516
+ }
517
+
518
+ // src/components/ui/NotificationBanner/NotificationBanner.native.tsx
519
+ var import_react_native10 = require("react-native");
520
+ var import_jsx_runtime10 = require("react/jsx-runtime");
521
+ var styles8 = import_react_native10.StyleSheet.create({
522
+ banner: {
523
+ flexDirection: "row",
524
+ alignItems: "center",
525
+ paddingVertical: import_native.spacing.s,
526
+ paddingHorizontal: import_native.spacing.m,
527
+ gap: import_native.spacing.xs
528
+ },
529
+ content: {
530
+ flex: 1,
531
+ fontSize: import_native.font.size.bodyS,
532
+ fontFamily: import_native.font.family.body,
533
+ lineHeight: lineHeight.bodyS
534
+ },
535
+ dismiss: {
536
+ padding: import_native.spacing.xxs,
537
+ flexShrink: 0
538
+ }
539
+ });
540
+ function NotificationBanner({
541
+ variant = "info",
542
+ children,
543
+ action,
544
+ onDismiss,
545
+ style
546
+ }) {
547
+ const { colors: colors2 } = useTheme();
548
+ const isUrgent = variant === "error" || variant === "warning";
549
+ const variantColors = {
550
+ info: { bg: colors2.colorBlueSubtle, text: colors2.colorOnBlueSubtle, border: colors2.colorBlue },
551
+ success: { bg: colors2.colorSuccessSubtle, text: colors2.colorOnSuccessSubtle, border: colors2.colorSuccess },
552
+ warning: { bg: colors2.colorOrangeSubtle, text: colors2.colorOnOrangeSubtle, border: colors2.colorWarning },
553
+ error: { bg: colors2.colorRedSubtle, text: colors2.colorOnBg, border: colors2.colorError }
554
+ };
555
+ const { bg, text, border: borderColor } = variantColors[variant];
556
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
557
+ import_react_native10.View,
558
+ {
559
+ accessibilityRole: isUrgent ? "alert" : "none",
560
+ accessibilityLiveRegion: isUrgent ? "assertive" : "polite",
561
+ style: [styles8.banner, { backgroundColor: bg, borderBottomWidth: 3, borderBottomColor: borderColor }, style],
562
+ children: [
563
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native10.Text, { style: [styles8.content, { color: text }], children }),
564
+ action,
565
+ onDismiss && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
566
+ import_react_native10.Pressable,
567
+ {
568
+ onPress: onDismiss,
569
+ style: styles8.dismiss,
570
+ accessibilityLabel: "Dismiss notification",
571
+ accessibilityRole: "button",
572
+ hitSlop: 8,
573
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native10.Text, { style: { color: text, fontSize: 16 }, children: "\u2715" })
574
+ }
575
+ )
576
+ ]
577
+ }
578
+ );
579
+ }
580
+
581
+ // src/components/ui/Link/Link.native.tsx
582
+ var import_react_native11 = require("react-native");
583
+ var import_jsx_runtime11 = require("react/jsx-runtime");
584
+ var styles9 = import_react_native11.StyleSheet.create({
585
+ text: {
586
+ fontSize: import_native.font.size.body,
587
+ fontFamily: import_native.font.family.body,
588
+ textDecorationLine: "underline"
589
+ },
590
+ pressed: {
591
+ opacity: 0.75
592
+ }
593
+ });
594
+ function Link({ href, children, accessibilityLabel, style, onPress }) {
595
+ const { colors: colors2 } = useTheme();
596
+ const handlePress = () => {
597
+ if (onPress) {
598
+ onPress();
599
+ } else if (href) {
600
+ import_react_native11.Linking.openURL(href);
601
+ }
602
+ };
603
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
604
+ import_react_native11.Pressable,
605
+ {
606
+ onPress: handlePress,
607
+ accessibilityRole: "link",
608
+ accessibilityLabel,
609
+ style: ({ pressed }) => pressed && styles9.pressed,
610
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native11.Text, { style: [styles9.text, { color: colors2.colorInteractiveOnBg }, style], children })
611
+ }
612
+ );
613
+ }
614
+
615
+ // src/components/ui/DescriptionList/DescriptionList.native.tsx
616
+ var import_react_native12 = require("react-native");
617
+ var import_jsx_runtime12 = require("react/jsx-runtime");
618
+ var styles10 = import_react_native12.StyleSheet.create({
619
+ list: {
620
+ gap: import_native.spacing.m
621
+ },
622
+ group: {
623
+ gap: import_native.spacing.xxs
624
+ },
625
+ term: {
626
+ fontSize: import_native.font.size.bodyS,
627
+ fontFamily: import_native.font.family.body,
628
+ fontWeight: import_native.font.weight.semibold,
629
+ lineHeight: lineHeight.bodyS
630
+ },
631
+ description: {
632
+ fontSize: import_native.font.size.body,
633
+ fontFamily: import_native.font.family.body,
634
+ fontWeight: import_native.font.weight.body,
635
+ lineHeight: lineHeight.body
636
+ }
637
+ });
638
+ function DescriptionList({ items, style }) {
639
+ const { colors: colors2 } = useTheme();
640
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native12.View, { style: [styles10.list, style], accessibilityRole: "list", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native12.View, { style: styles10.group, accessibilityRole: "listitem", children: [
641
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native12.Text, { style: [styles10.term, { color: colors2.colorOnBgSubtle }], children: item.term }),
642
+ typeof item.description === "string" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native12.Text, { style: [styles10.description, { color: colors2.colorOnBg }], children: item.description }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native12.View, { children: item.description })
643
+ ] }, i)) });
644
+ }
645
+
646
+ // src/components/ui/Breadcrumb/Breadcrumb.native.tsx
647
+ var import_react_native13 = require("react-native");
648
+ var import_jsx_runtime13 = require("react/jsx-runtime");
649
+ var styles11 = import_react_native13.StyleSheet.create({
650
+ container: {
651
+ flexDirection: "row",
652
+ flexWrap: "wrap",
653
+ alignItems: "center"
654
+ },
655
+ separator: {
656
+ marginHorizontal: import_native.spacing.xs,
657
+ fontSize: import_native.font.size.body,
658
+ fontFamily: import_native.font.family.body,
659
+ lineHeight: lineHeight.body
660
+ },
661
+ itemText: {
662
+ fontSize: import_native.font.size.body,
663
+ fontFamily: import_native.font.family.body,
664
+ lineHeight: lineHeight.body
665
+ },
666
+ pressed: {
667
+ opacity: 0.75
668
+ }
669
+ });
670
+ function Breadcrumb({ items, style }) {
671
+ const { colors: colors2 } = useTheme();
672
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
673
+ import_react_native13.View,
674
+ {
675
+ style: [styles11.container, style],
676
+ accessibilityRole: "navigation",
677
+ accessibilityLabel: "Breadcrumb",
678
+ children: items.map((item, index) => {
679
+ const isLast = index === items.length - 1;
680
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native13.View, { style: { flexDirection: "row", alignItems: "center", minHeight: 44 }, children: isLast ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
681
+ import_react_native13.Text,
682
+ {
683
+ style: [styles11.itemText, { color: colors2.colorOnBg }],
684
+ accessibilityRole: "text",
685
+ children: item.label
686
+ }
687
+ ) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
688
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
689
+ import_react_native13.Pressable,
690
+ {
691
+ onPress: item.onPress,
692
+ accessibilityRole: "link",
693
+ style: ({ pressed }) => pressed && styles11.pressed,
694
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native13.Text, { style: [styles11.itemText, { color: colors2.colorInteractiveOnBg }], children: item.label })
695
+ }
696
+ ),
697
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
698
+ import_react_native13.Text,
699
+ {
700
+ style: [styles11.separator, { color: colors2.colorOnBgSubtle }],
701
+ importantForAccessibility: "no",
702
+ accessibilityElementsHidden: true,
703
+ children: "/"
704
+ }
705
+ )
706
+ ] }) }, index);
707
+ })
708
+ }
709
+ );
710
+ }
711
+
712
+ // src/components/ui/ProgressCircle/ProgressCircle.native.tsx
713
+ var import_react_native14 = require("react-native");
714
+ var import_jsx_runtime14 = require("react/jsx-runtime");
715
+ var SIZE_PX = {
716
+ small: 40,
717
+ medium: 64,
718
+ large: 96
719
+ };
720
+ var STROKE_WIDTH = {
721
+ small: 3,
722
+ medium: 4,
723
+ large: 5
724
+ };
725
+ var FONT_SIZE = {
726
+ small: import_native.font.size.bodyS - 2,
727
+ medium: import_native.font.size.bodyS,
728
+ large: import_native.font.size.body
729
+ };
730
+ var styles12 = import_react_native14.StyleSheet.create({
731
+ wrapper: {
732
+ alignItems: "center",
733
+ justifyContent: "center"
734
+ },
735
+ valueText: {
736
+ position: "absolute",
737
+ fontFamily: import_native.font.family.body,
738
+ fontWeight: import_native.font.weight.semibold
739
+ }
740
+ });
741
+ function HalfCircle({
742
+ size,
743
+ stroke,
744
+ color,
745
+ rotation
746
+ }) {
747
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
748
+ import_react_native14.View,
749
+ {
750
+ style: {
751
+ width: size / 2,
752
+ height: size,
753
+ overflow: "hidden"
754
+ },
755
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
756
+ import_react_native14.View,
757
+ {
758
+ style: {
759
+ width: size,
760
+ height: size,
761
+ borderRadius: size / 2,
762
+ borderWidth: stroke,
763
+ borderColor: color,
764
+ transform: [{ rotate: `${rotation}deg` }]
765
+ }
766
+ }
767
+ )
768
+ }
769
+ );
770
+ }
771
+ function ProgressCircle({
772
+ value,
773
+ max = 100,
774
+ size = "medium",
775
+ label,
776
+ showValue = false,
777
+ style
778
+ }) {
779
+ const { colors: colors2 } = useTheme();
780
+ const percentage = Math.min(100, Math.max(0, value / max * 100));
781
+ const px = SIZE_PX[size];
782
+ const stroke = STROKE_WIDTH[size];
783
+ const fillColor = colors2.colorInteractive;
784
+ const trackColor = colors2.colorBgSubtle;
785
+ const degrees = percentage / 100 * 360;
786
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
787
+ import_react_native14.View,
788
+ {
789
+ style: [
790
+ styles12.wrapper,
791
+ { width: px, height: px },
792
+ style
793
+ ],
794
+ accessibilityRole: "progressbar",
795
+ accessibilityLabel: label,
796
+ accessibilityValue: { min: 0, max, now: value },
797
+ children: [
798
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
799
+ import_react_native14.View,
800
+ {
801
+ style: {
802
+ position: "absolute",
803
+ width: px,
804
+ height: px,
805
+ borderRadius: px / 2,
806
+ borderWidth: stroke,
807
+ borderColor: trackColor
808
+ }
809
+ }
810
+ ),
811
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
812
+ import_react_native14.View,
813
+ {
814
+ style: {
815
+ position: "absolute",
816
+ width: px / 2,
817
+ height: px,
818
+ start: px / 2,
819
+ overflow: "hidden"
820
+ },
821
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
822
+ HalfCircle,
823
+ {
824
+ size: px,
825
+ stroke,
826
+ color: percentage > 0 ? fillColor : "transparent",
827
+ rotation: Math.min(degrees, 180) - 180
828
+ }
829
+ )
830
+ }
831
+ ),
832
+ degrees > 180 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
833
+ import_react_native14.View,
834
+ {
835
+ style: {
836
+ position: "absolute",
837
+ width: px / 2,
838
+ height: px,
839
+ start: 0,
840
+ overflow: "hidden"
841
+ },
842
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
843
+ import_react_native14.View,
844
+ {
845
+ style: {
846
+ position: "absolute",
847
+ end: 0
848
+ },
849
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
850
+ HalfCircle,
851
+ {
852
+ size: px,
853
+ stroke,
854
+ color: fillColor,
855
+ rotation: Math.min(degrees - 180, 180)
856
+ }
857
+ )
858
+ }
859
+ )
860
+ }
861
+ ),
862
+ showValue && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
863
+ import_react_native14.Text,
864
+ {
865
+ style: [styles12.valueText, { fontSize: FONT_SIZE[size], color: colors2.colorOnBg }],
866
+ importantForAccessibility: "no",
867
+ accessibilityElementsHidden: true,
868
+ children: [
869
+ Math.round(percentage),
870
+ "%"
871
+ ]
872
+ }
873
+ )
874
+ ]
875
+ }
876
+ );
877
+ }
878
+
879
+ // src/components/ui/Tooltip/Tooltip.native.tsx
880
+ var import_react3 = require("react");
881
+ var import_react_native15 = require("react-native");
882
+ var import_jsx_runtime15 = require("react/jsx-runtime");
883
+ var styles13 = import_react_native15.StyleSheet.create({
884
+ wrapper: {
885
+ position: "relative"
886
+ },
887
+ tooltip: {
888
+ position: "absolute",
889
+ bottom: "100%",
890
+ start: 0,
891
+ marginBottom: import_native.spacing.xxs,
892
+ paddingVertical: import_native.spacing.xxs,
893
+ paddingHorizontal: import_native.spacing.xs,
894
+ borderRadius: import_native.border.radius.full,
895
+ zIndex: 10,
896
+ alignSelf: "flex-start"
897
+ },
898
+ text: {
899
+ fontSize: import_native.font.size.bodyS,
900
+ fontFamily: import_native.font.family.body
901
+ }
902
+ });
903
+ function Tooltip({ content, children, style }) {
904
+ const { colors: colors2 } = useTheme();
905
+ const [visible, setVisible] = (0, import_react3.useState)(false);
906
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native15.View, { style: [styles13.wrapper, style], children: [
907
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
908
+ import_react_native15.Pressable,
909
+ {
910
+ onLongPress: () => setVisible(true),
911
+ onPressOut: () => setVisible(false),
912
+ accessibilityHint: content,
913
+ children
914
+ }
915
+ ),
916
+ visible && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
917
+ import_react_native15.View,
918
+ {
919
+ style: [styles13.tooltip, { backgroundColor: colors2.colorOnBg }],
920
+ accessibilityRole: "text",
921
+ accessibilityLabel: content,
922
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native15.Text, { style: [styles13.text, { color: colors2.colorBg }], children: content })
923
+ }
924
+ )
925
+ ] });
926
+ }
927
+
928
+ // src/components/ui/Pagination/Pagination.native.tsx
929
+ var import_react_native16 = require("react-native");
930
+ var import_jsx_runtime16 = require("react/jsx-runtime");
931
+ function getPageRange(current, total) {
932
+ const delta = 1;
933
+ const range = [];
934
+ for (let i = 1; i <= total; i++) {
935
+ if (i === 1 || i === total || i >= current - delta && i <= current + delta) {
936
+ range.push(i);
937
+ } else if (range[range.length - 1] !== "...") {
938
+ range.push("...");
939
+ }
940
+ }
941
+ return range;
942
+ }
943
+ var styles14 = import_react_native16.StyleSheet.create({
944
+ container: {
945
+ flexDirection: "row",
946
+ alignItems: "center",
947
+ gap: import_native.spacing.xxs
948
+ },
949
+ button: {
950
+ minWidth: 44,
951
+ minHeight: 44,
952
+ alignItems: "center",
953
+ justifyContent: "center",
954
+ borderRadius: import_native.border.radius.full,
955
+ paddingHorizontal: import_native.spacing.xs,
956
+ paddingVertical: import_native.spacing.xxs
957
+ },
958
+ buttonText: {
959
+ fontSize: import_native.font.size.body,
960
+ fontFamily: import_native.font.family.body,
961
+ lineHeight: lineHeight.body,
962
+ fontWeight: import_native.font.weight.body
963
+ },
964
+ navText: {
965
+ fontSize: import_native.font.size.body,
966
+ fontFamily: import_native.font.family.body,
967
+ lineHeight: lineHeight.body,
968
+ fontWeight: import_native.font.weight.semibold
969
+ },
970
+ ellipsis: {
971
+ fontSize: import_native.font.size.body,
972
+ fontFamily: import_native.font.family.body,
973
+ lineHeight: lineHeight.body,
974
+ minWidth: 44,
975
+ minHeight: 44,
976
+ textAlign: "center",
977
+ textAlignVertical: "center"
978
+ },
979
+ pressed: {
980
+ opacity: 0.75
981
+ },
982
+ disabled: {
983
+ opacity: 0.4
984
+ }
985
+ });
986
+ function Pagination({
987
+ currentPage,
988
+ totalPages,
989
+ onPageChange,
990
+ style
991
+ }) {
992
+ const { colors: colors2 } = useTheme();
993
+ const pages = getPageRange(currentPage, totalPages);
994
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
995
+ import_react_native16.View,
996
+ {
997
+ style: [styles14.container, style],
998
+ accessibilityRole: "navigation",
999
+ accessibilityLabel: "Pagination",
1000
+ children: [
1001
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1002
+ import_react_native16.Pressable,
1003
+ {
1004
+ onPress: () => onPageChange(currentPage - 1),
1005
+ disabled: currentPage <= 1,
1006
+ accessibilityRole: "button",
1007
+ accessibilityLabel: "Previous page",
1008
+ accessibilityState: { disabled: currentPage <= 1 },
1009
+ style: ({ pressed }) => [
1010
+ styles14.button,
1011
+ currentPage <= 1 && styles14.disabled,
1012
+ pressed && !currentPage && styles14.pressed
1013
+ ],
1014
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native16.Text, { style: [styles14.navText, { color: colors2.colorOnBg }], children: "\u2039" })
1015
+ }
1016
+ ),
1017
+ pages.map(
1018
+ (page, index) => page === "..." ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1019
+ import_react_native16.Text,
1020
+ {
1021
+ style: [styles14.ellipsis, { color: colors2.colorOnBgSubtle }],
1022
+ importantForAccessibility: "no",
1023
+ accessibilityElementsHidden: true,
1024
+ children: "..."
1025
+ },
1026
+ `ellipsis-${index}`
1027
+ ) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1028
+ import_react_native16.Pressable,
1029
+ {
1030
+ onPress: () => onPageChange(page),
1031
+ accessibilityRole: "button",
1032
+ accessibilityLabel: `Page ${page}`,
1033
+ accessibilityState: { selected: currentPage === page },
1034
+ style: ({ pressed }) => [
1035
+ styles14.button,
1036
+ currentPage === page && { backgroundColor: colors2.colorInteractive },
1037
+ pressed && styles14.pressed
1038
+ ],
1039
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1040
+ import_react_native16.Text,
1041
+ {
1042
+ style: [
1043
+ styles14.buttonText,
1044
+ {
1045
+ color: currentPage === page ? colors2.colorOnInteractive : colors2.colorOnBg
1046
+ },
1047
+ currentPage === page && { fontWeight: import_native.font.weight.semibold }
1048
+ ],
1049
+ children: page
1050
+ }
1051
+ )
1052
+ },
1053
+ page
1054
+ )
1055
+ ),
1056
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1057
+ import_react_native16.Pressable,
1058
+ {
1059
+ onPress: () => onPageChange(currentPage + 1),
1060
+ disabled: currentPage >= totalPages,
1061
+ accessibilityRole: "button",
1062
+ accessibilityLabel: "Next page",
1063
+ accessibilityState: { disabled: currentPage >= totalPages },
1064
+ style: ({ pressed }) => [
1065
+ styles14.button,
1066
+ currentPage >= totalPages && styles14.disabled,
1067
+ pressed && styles14.pressed
1068
+ ],
1069
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native16.Text, { style: [styles14.navText, { color: colors2.colorOnBg }], children: "\u203A" })
1070
+ }
1071
+ )
1072
+ ]
1073
+ }
1074
+ );
1075
+ }
1076
+
1077
+ // src/components/ui/Collapsible/Collapsible.native.tsx
1078
+ var import_react4 = require("react");
1079
+ var import_react_native17 = require("react-native");
1080
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1081
+ if (import_react_native17.Platform.OS === "android" && import_react_native17.UIManager.setLayoutAnimationEnabledExperimental) {
1082
+ import_react_native17.UIManager.setLayoutAnimationEnabledExperimental(true);
1083
+ }
1084
+ var styles15 = import_react_native17.StyleSheet.create({
1085
+ container: {
1086
+ borderRadius: import_native.border.radius.m,
1087
+ overflow: "hidden"
1088
+ },
1089
+ header: {
1090
+ flexDirection: "row",
1091
+ alignItems: "center",
1092
+ justifyContent: "space-between",
1093
+ minHeight: 44,
1094
+ paddingVertical: import_native.spacing.s,
1095
+ paddingHorizontal: import_native.spacing.m
1096
+ },
1097
+ summaryText: {
1098
+ flex: 1,
1099
+ fontSize: import_native.font.size.body,
1100
+ fontFamily: import_native.font.family.body,
1101
+ fontWeight: import_native.font.weight.semibold,
1102
+ lineHeight: lineHeight.body
1103
+ },
1104
+ chevron: {
1105
+ fontSize: import_native.font.size.body,
1106
+ marginStart: import_native.spacing.xs
1107
+ },
1108
+ content: {
1109
+ paddingHorizontal: import_native.spacing.m,
1110
+ paddingBottom: import_native.spacing.m
1111
+ },
1112
+ pressed: {
1113
+ opacity: 0.75
1114
+ }
1115
+ });
1116
+ function Collapsible({
1117
+ summary,
1118
+ children,
1119
+ open: controlledOpen,
1120
+ defaultOpen = false,
1121
+ onToggle,
1122
+ name: _name,
1123
+ // eslint-disable-line @typescript-eslint/no-unused-vars
1124
+ style
1125
+ }) {
1126
+ const { colors: colors2 } = useTheme();
1127
+ const [internalOpen, setInternalOpen] = (0, import_react4.useState)(defaultOpen);
1128
+ const isControlled = controlledOpen !== void 0;
1129
+ const isOpen = isControlled ? controlledOpen : internalOpen;
1130
+ const rotation = (0, import_react4.useRef)(new import_react_native17.Animated.Value(isOpen ? 1 : 0)).current;
1131
+ const toggle = (0, import_react4.useCallback)(() => {
1132
+ const next = !isOpen;
1133
+ import_react_native17.LayoutAnimation.configureNext(import_react_native17.LayoutAnimation.Presets.easeInEaseOut);
1134
+ import_react_native17.Animated.timing(rotation, {
1135
+ toValue: next ? 1 : 0,
1136
+ duration: 200,
1137
+ useNativeDriver: true
1138
+ }).start();
1139
+ if (!isControlled) {
1140
+ setInternalOpen(next);
1141
+ }
1142
+ onToggle?.(next);
1143
+ }, [isOpen, isControlled, onToggle, rotation]);
1144
+ const rotateZ = rotation.interpolate({
1145
+ inputRange: [0, 1],
1146
+ outputRange: ["0deg", "90deg"]
1147
+ });
1148
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1149
+ import_react_native17.View,
1150
+ {
1151
+ style: [styles15.container, { borderBottomWidth: 1, borderBottomColor: colors2.colorBgSubtle }, style],
1152
+ accessibilityRole: "summary",
1153
+ children: [
1154
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1155
+ import_react_native17.Pressable,
1156
+ {
1157
+ onPress: toggle,
1158
+ accessibilityRole: "button",
1159
+ accessibilityLabel: summary,
1160
+ accessibilityState: { expanded: isOpen },
1161
+ style: ({ pressed }) => [styles15.header, pressed && styles15.pressed],
1162
+ children: [
1163
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native17.Text, { style: [styles15.summaryText, { color: colors2.colorOnBg }], children: summary }),
1164
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1165
+ import_react_native17.Animated.Text,
1166
+ {
1167
+ style: [styles15.chevron, { color: colors2.colorOnBgSubtle, transform: [{ rotateZ }] }],
1168
+ importantForAccessibility: "no",
1169
+ accessibilityElementsHidden: true,
1170
+ children: "\u25B8"
1171
+ }
1172
+ )
1173
+ ]
1174
+ }
1175
+ ),
1176
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native17.View, { style: styles15.content, children })
1177
+ ]
1178
+ }
1179
+ );
1180
+ }
1181
+
1182
+ // src/components/ui/Accordion/Accordion.native.tsx
1183
+ var import_react5 = require("react");
1184
+ var import_react_native18 = require("react-native");
1185
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1186
+ if (import_react_native18.Platform.OS === "android" && import_react_native18.UIManager.setLayoutAnimationEnabledExperimental) {
1187
+ import_react_native18.UIManager.setLayoutAnimationEnabledExperimental(true);
1188
+ }
1189
+ var styles16 = import_react_native18.StyleSheet.create({
1190
+ container: {
1191
+ overflow: "hidden",
1192
+ borderRadius: import_native.border.radius.s
1193
+ },
1194
+ item: {
1195
+ borderBottomWidth: 1
1196
+ },
1197
+ header: {
1198
+ flexDirection: "row",
1199
+ alignItems: "center",
1200
+ justifyContent: "space-between",
1201
+ minHeight: 44,
1202
+ paddingVertical: import_native.spacing.s,
1203
+ paddingHorizontal: import_native.spacing.m
1204
+ },
1205
+ titleText: {
1206
+ flex: 1,
1207
+ fontSize: import_native.font.size.body,
1208
+ fontFamily: import_native.font.family.body,
1209
+ fontWeight: import_native.font.weight.semibold,
1210
+ lineHeight: lineHeight.body
1211
+ },
1212
+ chevron: {
1213
+ fontSize: import_native.font.size.bodyS,
1214
+ marginStart: import_native.spacing.xs
1215
+ },
1216
+ panel: {
1217
+ paddingHorizontal: import_native.spacing.m,
1218
+ paddingBottom: import_native.spacing.m
1219
+ },
1220
+ pressed: {
1221
+ opacity: 0.75
1222
+ },
1223
+ disabled: {
1224
+ opacity: 0.4
1225
+ }
1226
+ });
1227
+ function Accordion({
1228
+ items,
1229
+ allowMultiple = false,
1230
+ defaultOpen = [],
1231
+ style
1232
+ }) {
1233
+ const { colors: colors2 } = useTheme();
1234
+ const [openIds, setOpenIds] = (0, import_react5.useState)(defaultOpen);
1235
+ const toggle = (id) => {
1236
+ import_react_native18.LayoutAnimation.configureNext(import_react_native18.LayoutAnimation.Presets.easeInEaseOut);
1237
+ setOpenIds((prev) => {
1238
+ const isOpen = prev.includes(id);
1239
+ if (isOpen) return prev.filter((i) => i !== id);
1240
+ return allowMultiple ? [...prev, id] : [id];
1241
+ });
1242
+ };
1243
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native18.View, { style: [styles16.container, style], children: items.map((item, index) => {
1244
+ const isOpen = openIds.includes(item.id);
1245
+ const isLast = index === items.length - 1;
1246
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1247
+ import_react_native18.View,
1248
+ {
1249
+ style: [
1250
+ styles16.item,
1251
+ { borderBottomColor: colors2.colorBgSubtle },
1252
+ isLast && { borderBottomWidth: 0 }
1253
+ ],
1254
+ children: [
1255
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1256
+ import_react_native18.Pressable,
1257
+ {
1258
+ onPress: () => toggle(item.id),
1259
+ disabled: item.disabled,
1260
+ accessibilityRole: "button",
1261
+ accessibilityState: { expanded: isOpen, disabled: item.disabled },
1262
+ style: ({ pressed }) => [
1263
+ styles16.header,
1264
+ item.disabled && styles16.disabled,
1265
+ pressed && !item.disabled && styles16.pressed
1266
+ ],
1267
+ children: [
1268
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native18.Text, { style: [styles16.titleText, { color: colors2.colorOnBg }], children: typeof item.title === "string" ? item.title : item.title }),
1269
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1270
+ import_react_native18.Text,
1271
+ {
1272
+ style: [styles16.chevron, { color: colors2.colorOnBgSubtle }],
1273
+ importantForAccessibility: "no",
1274
+ accessibilityElementsHidden: true,
1275
+ children: isOpen ? "\u25BE" : "\u25B8"
1276
+ }
1277
+ )
1278
+ ]
1279
+ }
1280
+ ),
1281
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native18.View, { style: styles16.panel, accessibilityRole: "summary", children: item.content })
1282
+ ]
1283
+ },
1284
+ item.id
1285
+ );
1286
+ }) });
1287
+ }
1288
+
1289
+ // src/components/ui/Tabs/Tabs.native.tsx
1290
+ var import_react6 = require("react");
1291
+ var import_react_native19 = require("react-native");
1292
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1293
+ var styles17 = import_react_native19.StyleSheet.create({
1294
+ container: {
1295
+ overflow: "hidden"
1296
+ },
1297
+ tabList: {
1298
+ flexDirection: "row",
1299
+ borderBottomWidth: 2
1300
+ },
1301
+ tabButton: {
1302
+ minHeight: 44,
1303
+ paddingHorizontal: import_native.spacing.m,
1304
+ paddingVertical: import_native.spacing.s,
1305
+ alignItems: "center",
1306
+ justifyContent: "center",
1307
+ borderBottomWidth: 2,
1308
+ marginBottom: -2
1309
+ },
1310
+ tabLabel: {
1311
+ fontSize: import_native.font.size.body,
1312
+ fontFamily: import_native.font.family.body,
1313
+ lineHeight: lineHeight.body
1314
+ },
1315
+ panel: {
1316
+ paddingVertical: import_native.spacing.m
1317
+ },
1318
+ pressed: {
1319
+ opacity: 0.75
1320
+ },
1321
+ disabled: {
1322
+ opacity: 0.4
1323
+ }
1324
+ });
1325
+ function Tabs({
1326
+ tabs,
1327
+ defaultTab,
1328
+ style
1329
+ }) {
1330
+ const { colors: colors2 } = useTheme();
1331
+ const [activeTab, setActiveTab] = (0, import_react6.useState)(defaultTab ?? tabs[0]?.id);
1332
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_react_native19.View, { style: [styles17.container, style], children: [
1333
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1334
+ import_react_native19.ScrollView,
1335
+ {
1336
+ horizontal: true,
1337
+ showsHorizontalScrollIndicator: false,
1338
+ contentContainerStyle: [styles17.tabList, { borderBottomColor: colors2.colorBgSubtle }],
1339
+ accessibilityRole: "tabbar",
1340
+ children: tabs.map((tab) => {
1341
+ const isActive = activeTab === tab.id;
1342
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1343
+ import_react_native19.Pressable,
1344
+ {
1345
+ onPress: () => setActiveTab(tab.id),
1346
+ disabled: tab.disabled,
1347
+ accessibilityRole: "tab",
1348
+ accessibilityState: {
1349
+ selected: isActive,
1350
+ disabled: tab.disabled
1351
+ },
1352
+ accessibilityLabel: typeof tab.label === "string" ? tab.label : void 0,
1353
+ style: ({ pressed }) => [
1354
+ styles17.tabButton,
1355
+ {
1356
+ borderBottomColor: isActive ? colors2.colorInteractive : "transparent"
1357
+ },
1358
+ tab.disabled && styles17.disabled,
1359
+ pressed && !tab.disabled && styles17.pressed
1360
+ ],
1361
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1362
+ import_react_native19.Text,
1363
+ {
1364
+ style: [
1365
+ styles17.tabLabel,
1366
+ {
1367
+ color: isActive ? colors2.colorInteractive : colors2.colorOnBgSubtle,
1368
+ fontWeight: isActive ? import_native.font.weight.semibold : import_native.font.weight.body
1369
+ }
1370
+ ],
1371
+ children: tab.label
1372
+ }
1373
+ )
1374
+ },
1375
+ tab.id
1376
+ );
1377
+ })
1378
+ }
1379
+ ),
1380
+ tabs.map((tab) => {
1381
+ const isActive = activeTab === tab.id;
1382
+ if (!isActive) return null;
1383
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native19.View, { style: styles17.panel, accessibilityRole: "tabpanel", children: tab.content }, tab.id);
1384
+ })
1385
+ ] });
1386
+ }
1387
+
1388
+ // src/components/ui/Table/Table.native.tsx
1389
+ var import_react_native20 = require("react-native");
1390
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1391
+ var styles18 = import_react_native20.StyleSheet.create({
1392
+ wrapper: {
1393
+ borderRadius: import_native.border.radius.s,
1394
+ overflow: "hidden"
1395
+ },
1396
+ caption: {
1397
+ fontSize: import_native.font.size.bodyS,
1398
+ fontFamily: import_native.font.family.body,
1399
+ fontWeight: import_native.font.weight.semibold,
1400
+ lineHeight: lineHeight.bodyS,
1401
+ paddingVertical: import_native.spacing.xs,
1402
+ paddingHorizontal: import_native.spacing.m
1403
+ },
1404
+ headerRow: {
1405
+ flexDirection: "row"
1406
+ },
1407
+ headerCell: {
1408
+ flex: 1,
1409
+ minWidth: 100,
1410
+ paddingVertical: import_native.spacing.s,
1411
+ paddingHorizontal: import_native.spacing.m,
1412
+ flexDirection: "row",
1413
+ alignItems: "center",
1414
+ gap: import_native.spacing.xxs
1415
+ },
1416
+ headerText: {
1417
+ fontSize: import_native.font.size.bodyS,
1418
+ fontFamily: import_native.font.family.body,
1419
+ fontWeight: import_native.font.weight.semibold,
1420
+ lineHeight: lineHeight.bodyS
1421
+ },
1422
+ sortIndicator: {
1423
+ fontSize: import_native.font.size.bodyS
1424
+ },
1425
+ row: {
1426
+ flexDirection: "row",
1427
+ borderTopWidth: 1,
1428
+ minHeight: 44
1429
+ },
1430
+ cell: {
1431
+ flex: 1,
1432
+ minWidth: 100,
1433
+ paddingVertical: import_native.spacing.s,
1434
+ paddingHorizontal: import_native.spacing.m,
1435
+ justifyContent: "center"
1436
+ },
1437
+ cellText: {
1438
+ fontSize: import_native.font.size.body,
1439
+ fontFamily: import_native.font.family.body,
1440
+ fontWeight: import_native.font.weight.body,
1441
+ lineHeight: lineHeight.body
1442
+ },
1443
+ pressed: {
1444
+ opacity: 0.75
1445
+ }
1446
+ });
1447
+ function Table({
1448
+ columns,
1449
+ rows,
1450
+ caption,
1451
+ sortKey,
1452
+ sortDirection,
1453
+ onSort,
1454
+ style
1455
+ }) {
1456
+ const { colors: colors2 } = useTheme();
1457
+ const handleSort = (key) => {
1458
+ if (!onSort) return;
1459
+ const nextDirection = sortKey === key && sortDirection === "asc" ? "desc" : "asc";
1460
+ onSort(key, nextDirection);
1461
+ };
1462
+ const getSortLabel = (col) => {
1463
+ const base = `Sort by ${String(col.header)}`;
1464
+ if (sortKey !== col.key) return base;
1465
+ return `${base}, currently ${sortDirection === "asc" ? "ascending" : "descending"}`;
1466
+ };
1467
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1468
+ import_react_native20.ScrollView,
1469
+ {
1470
+ horizontal: true,
1471
+ showsHorizontalScrollIndicator: true,
1472
+ style: [styles18.wrapper, { backgroundColor: colors2.colorBg }, style],
1473
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_react_native20.View, { children: [
1474
+ caption && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native20.Text, { style: [styles18.caption, { color: colors2.colorOnBgSubtle }], children: caption }),
1475
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native20.View, { style: [styles18.headerRow, { backgroundColor: colors2.colorBgSubtle }], children: columns.map(
1476
+ (col) => col.sortable ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1477
+ import_react_native20.Pressable,
1478
+ {
1479
+ onPress: () => handleSort(col.key),
1480
+ accessibilityRole: "button",
1481
+ accessibilityLabel: getSortLabel(col),
1482
+ style: ({ pressed }) => [styles18.headerCell, pressed && styles18.pressed],
1483
+ children: [
1484
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native20.Text, { style: [styles18.headerText, { color: colors2.colorOnBg }], children: col.header }),
1485
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1486
+ import_react_native20.Text,
1487
+ {
1488
+ style: [
1489
+ styles18.sortIndicator,
1490
+ {
1491
+ color: sortKey === col.key ? colors2.colorInteractive : colors2.colorOnBgSubtle
1492
+ }
1493
+ ],
1494
+ importantForAccessibility: "no",
1495
+ accessibilityElementsHidden: true,
1496
+ children: sortKey === col.key ? sortDirection === "asc" ? "\u25B2" : "\u25BC" : "\u25BD"
1497
+ }
1498
+ )
1499
+ ]
1500
+ },
1501
+ col.key
1502
+ ) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native20.View, { style: styles18.headerCell, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native20.Text, { style: [styles18.headerText, { color: colors2.colorOnBg }], children: col.header }) }, col.key)
1503
+ ) }),
1504
+ rows.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1505
+ import_react_native20.View,
1506
+ {
1507
+ style: [
1508
+ styles18.row,
1509
+ { borderTopColor: colors2.colorBgSubtle },
1510
+ rowIndex % 2 === 1 && { backgroundColor: colors2.colorBgSubtle }
1511
+ ],
1512
+ accessibilityRole: "none",
1513
+ children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native20.View, { style: styles18.cell, children: col.render ? typeof col.render(row) === "string" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native20.Text, { style: [styles18.cellText, { color: colors2.colorOnBg }], children: col.render(row) }) : col.render(row) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native20.Text, { style: [styles18.cellText, { color: colors2.colorOnBg }], children: String(row[col.key] ?? "") }) }, col.key))
1514
+ },
1515
+ rowIndex
1516
+ ))
1517
+ ] })
1518
+ }
1519
+ );
1520
+ }
1521
+
1522
+ // src/components/ui/Calendar/Calendar.native.tsx
1523
+ var import_react7 = require("react");
1524
+ var import_react_native21 = require("react-native");
1525
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1526
+ var DAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
1527
+ var DAY_LABELS = {
1528
+ Su: "Sunday",
1529
+ Mo: "Monday",
1530
+ Tu: "Tuesday",
1531
+ We: "Wednesday",
1532
+ Th: "Thursday",
1533
+ Fr: "Friday",
1534
+ Sa: "Saturday"
1535
+ };
1536
+ var MONTHS = [
1537
+ "January",
1538
+ "February",
1539
+ "March",
1540
+ "April",
1541
+ "May",
1542
+ "June",
1543
+ "July",
1544
+ "August",
1545
+ "September",
1546
+ "October",
1547
+ "November",
1548
+ "December"
1549
+ ];
1550
+ function isSameDay(a, b) {
1551
+ return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
1552
+ }
1553
+ function toMidnight(date) {
1554
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate());
1555
+ }
1556
+ function isOutOfRange(date, min, max) {
1557
+ const d = toMidnight(date);
1558
+ if (min && d < toMidnight(min)) return true;
1559
+ return !!(max && d > toMidnight(max));
1560
+ }
1561
+ function getDaysInMonth(year, month) {
1562
+ return new Date(year, month + 1, 0).getDate();
1563
+ }
1564
+ function getFirstDayOfMonth(year, month) {
1565
+ return new Date(year, month, 1).getDay();
1566
+ }
1567
+ var DAY_SIZE = 44;
1568
+ var styles19 = import_react_native21.StyleSheet.create({
1569
+ container: {
1570
+ alignSelf: "flex-start"
1571
+ },
1572
+ header: {
1573
+ flexDirection: "row",
1574
+ alignItems: "center",
1575
+ justifyContent: "space-between",
1576
+ paddingVertical: import_native.spacing.xs,
1577
+ paddingHorizontal: import_native.spacing.xxs
1578
+ },
1579
+ navButton: {
1580
+ minWidth: DAY_SIZE,
1581
+ minHeight: DAY_SIZE,
1582
+ alignItems: "center",
1583
+ justifyContent: "center",
1584
+ borderRadius: import_native.border.radius.full
1585
+ },
1586
+ navText: {
1587
+ fontSize: import_native.font.size.heading3,
1588
+ fontWeight: import_native.font.weight.semibold
1589
+ },
1590
+ monthYear: {
1591
+ fontSize: import_native.font.size.body,
1592
+ fontFamily: import_native.font.family.body,
1593
+ fontWeight: import_native.font.weight.semibold,
1594
+ lineHeight: lineHeight.body
1595
+ },
1596
+ weekRow: {
1597
+ flexDirection: "row"
1598
+ },
1599
+ weekday: {
1600
+ width: DAY_SIZE,
1601
+ height: DAY_SIZE,
1602
+ alignItems: "center",
1603
+ justifyContent: "center"
1604
+ },
1605
+ weekdayText: {
1606
+ fontSize: import_native.font.size.bodyS,
1607
+ fontFamily: import_native.font.family.body,
1608
+ fontWeight: import_native.font.weight.semibold,
1609
+ lineHeight: lineHeight.bodyS
1610
+ },
1611
+ grid: {
1612
+ gap: import_native.spacing.xxxs
1613
+ },
1614
+ dayRow: {
1615
+ flexDirection: "row"
1616
+ },
1617
+ dayCell: {
1618
+ width: DAY_SIZE,
1619
+ height: DAY_SIZE,
1620
+ alignItems: "center",
1621
+ justifyContent: "center",
1622
+ borderRadius: import_native.border.radius.full
1623
+ },
1624
+ dayText: {
1625
+ fontSize: import_native.font.size.body,
1626
+ fontFamily: import_native.font.family.body,
1627
+ lineHeight: lineHeight.body
1628
+ },
1629
+ today: {
1630
+ borderWidth: 1
1631
+ },
1632
+ pressed: {
1633
+ opacity: 0.75
1634
+ },
1635
+ disabled: {
1636
+ opacity: 0.4
1637
+ }
1638
+ });
1639
+ function Calendar({
1640
+ value,
1641
+ defaultValue,
1642
+ min,
1643
+ max,
1644
+ onChange,
1645
+ style
1646
+ }) {
1647
+ const { colors: colors2 } = useTheme();
1648
+ const today = /* @__PURE__ */ new Date();
1649
+ const controlled = value !== void 0;
1650
+ const [internal, setInternal] = (0, import_react7.useState)(defaultValue);
1651
+ const selected = controlled ? value : internal;
1652
+ const [viewYear, setViewYear] = (0, import_react7.useState)(
1653
+ selected?.getFullYear() ?? today.getFullYear()
1654
+ );
1655
+ const [viewMonth, setViewMonth] = (0, import_react7.useState)(
1656
+ selected?.getMonth() ?? today.getMonth()
1657
+ );
1658
+ const daysInMonth = getDaysInMonth(viewYear, viewMonth);
1659
+ const firstDay = getFirstDayOfMonth(viewYear, viewMonth);
1660
+ const navigate = (delta) => {
1661
+ const d = new Date(viewYear, viewMonth + delta, 1);
1662
+ setViewYear(d.getFullYear());
1663
+ setViewMonth(d.getMonth());
1664
+ };
1665
+ const selectDay = (day) => {
1666
+ const date = new Date(viewYear, viewMonth, day);
1667
+ if (isOutOfRange(date, min, max)) return;
1668
+ if (!controlled) setInternal(date);
1669
+ onChange?.(date);
1670
+ };
1671
+ const cells = [
1672
+ ...Array.from({ length: firstDay }, () => null),
1673
+ ...Array.from({ length: daysInMonth }, (_, i) => ({ day: i + 1 }))
1674
+ ];
1675
+ while (cells.length % 7 !== 0) cells.push(null);
1676
+ const rows = Array.from(
1677
+ { length: cells.length / 7 },
1678
+ (_, i) => cells.slice(i * 7, i * 7 + 7)
1679
+ );
1680
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
1681
+ import_react_native21.View,
1682
+ {
1683
+ style: [styles19.container, style],
1684
+ accessibilityRole: "none",
1685
+ accessibilityLabel: `${MONTHS[viewMonth]} ${viewYear} calendar`,
1686
+ children: [
1687
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_react_native21.View, { style: styles19.header, children: [
1688
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1689
+ import_react_native21.Pressable,
1690
+ {
1691
+ onPress: () => navigate(-1),
1692
+ accessibilityRole: "button",
1693
+ accessibilityLabel: "Previous month",
1694
+ style: ({ pressed }) => [styles19.navButton, pressed && styles19.pressed],
1695
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native21.Text, { style: [styles19.navText, { color: colors2.colorOnBg }], children: "\u2039" })
1696
+ }
1697
+ ),
1698
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
1699
+ import_react_native21.Text,
1700
+ {
1701
+ style: [styles19.monthYear, { color: colors2.colorOnBg }],
1702
+ accessibilityRole: "text",
1703
+ accessibilityLiveRegion: "polite",
1704
+ children: [
1705
+ MONTHS[viewMonth],
1706
+ " ",
1707
+ viewYear
1708
+ ]
1709
+ }
1710
+ ),
1711
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1712
+ import_react_native21.Pressable,
1713
+ {
1714
+ onPress: () => navigate(1),
1715
+ accessibilityRole: "button",
1716
+ accessibilityLabel: "Next month",
1717
+ style: ({ pressed }) => [styles19.navButton, pressed && styles19.pressed],
1718
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native21.Text, { style: [styles19.navText, { color: colors2.colorOnBg }], children: "\u203A" })
1719
+ }
1720
+ )
1721
+ ] }),
1722
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native21.View, { style: styles19.weekRow, children: DAYS.map((d) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native21.View, { style: styles19.weekday, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1723
+ import_react_native21.Text,
1724
+ {
1725
+ style: [styles19.weekdayText, { color: colors2.colorOnBgSubtle }],
1726
+ accessibilityLabel: DAY_LABELS[d],
1727
+ children: d
1728
+ }
1729
+ ) }, d)) }),
1730
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native21.View, { style: styles19.grid, children: rows.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native21.View, { style: styles19.dayRow, children: row.map((cell, colIndex) => {
1731
+ if (!cell) {
1732
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native21.View, { style: styles19.dayCell }, colIndex);
1733
+ }
1734
+ const date = new Date(viewYear, viewMonth, cell.day);
1735
+ const isSelected = selected ? isSameDay(date, selected) : false;
1736
+ const isToday = isSameDay(date, today);
1737
+ const disabled = isOutOfRange(date, min, max);
1738
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1739
+ import_react_native21.Pressable,
1740
+ {
1741
+ onPress: () => selectDay(cell.day),
1742
+ disabled,
1743
+ accessibilityRole: "button",
1744
+ accessibilityLabel: date.toLocaleDateString("en", {
1745
+ month: "long",
1746
+ day: "numeric",
1747
+ year: "numeric"
1748
+ }),
1749
+ accessibilityState: {
1750
+ selected: isSelected,
1751
+ disabled
1752
+ },
1753
+ style: ({ pressed }) => [
1754
+ styles19.dayCell,
1755
+ isSelected && {
1756
+ backgroundColor: colors2.colorInteractive
1757
+ },
1758
+ isToday && !isSelected && [
1759
+ styles19.today,
1760
+ { borderColor: colors2.colorInteractive }
1761
+ ],
1762
+ disabled && styles19.disabled,
1763
+ pressed && !disabled && styles19.pressed
1764
+ ],
1765
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1766
+ import_react_native21.Text,
1767
+ {
1768
+ style: [
1769
+ styles19.dayText,
1770
+ {
1771
+ color: isSelected ? colors2.colorOnInteractive : colors2.colorOnBg,
1772
+ fontWeight: isToday ? import_native.font.weight.semibold : import_native.font.weight.body
1773
+ }
1774
+ ],
1775
+ children: cell.day
1776
+ }
1777
+ )
1778
+ },
1779
+ colIndex
1780
+ );
1781
+ }) }, rowIndex)) })
1782
+ ]
1783
+ }
1784
+ );
1785
+ }
1786
+
1787
+ // src/components/ui/Carousel/Carousel.native.tsx
1788
+ var import_react8 = require("react");
1789
+ var import_react_native22 = require("react-native");
1790
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1791
+ var DOT_SIZE = 8;
1792
+ var DOT_HIT_SIZE = 44;
1793
+ var styles20 = import_react_native22.StyleSheet.create({
1794
+ container: {
1795
+ width: "100%"
1796
+ },
1797
+ scrollView: {
1798
+ flexGrow: 0
1799
+ },
1800
+ slide: {
1801
+ justifyContent: "center",
1802
+ alignItems: "center"
1803
+ },
1804
+ nav: {
1805
+ flexDirection: "row",
1806
+ alignItems: "center",
1807
+ justifyContent: "center",
1808
+ gap: import_native.spacing.xs,
1809
+ paddingVertical: import_native.spacing.s
1810
+ },
1811
+ navButton: {
1812
+ minWidth: 44,
1813
+ minHeight: 44,
1814
+ alignItems: "center",
1815
+ justifyContent: "center",
1816
+ borderRadius: import_native.border.radius.s
1817
+ },
1818
+ navText: {
1819
+ fontSize: 20,
1820
+ fontWeight: "600"
1821
+ },
1822
+ dots: {
1823
+ flexDirection: "row",
1824
+ alignItems: "center",
1825
+ gap: import_native.spacing.xs
1826
+ },
1827
+ dotWrapper: {
1828
+ minWidth: DOT_HIT_SIZE,
1829
+ minHeight: DOT_HIT_SIZE,
1830
+ alignItems: "center",
1831
+ justifyContent: "center"
1832
+ },
1833
+ dot: {
1834
+ width: DOT_SIZE,
1835
+ height: DOT_SIZE,
1836
+ borderRadius: DOT_SIZE / 2
1837
+ },
1838
+ pressed: {
1839
+ opacity: 0.75
1840
+ }
1841
+ });
1842
+ function Carousel({
1843
+ items,
1844
+ label,
1845
+ style
1846
+ }) {
1847
+ const { colors: colors2 } = useTheme();
1848
+ const scrollRef = (0, import_react8.useRef)(null);
1849
+ const [activeIndex, setActiveIndex] = (0, import_react8.useState)(0);
1850
+ const [slideWidth, setSlideWidth] = (0, import_react8.useState)(import_react_native22.Dimensions.get("window").width);
1851
+ const handleScroll = (0, import_react8.useCallback)(
1852
+ (e) => {
1853
+ const offset = e.nativeEvent.contentOffset.x;
1854
+ const width = e.nativeEvent.layoutMeasurement.width;
1855
+ if (width > 0) {
1856
+ const index = Math.round(offset / width);
1857
+ setActiveIndex(index);
1858
+ }
1859
+ },
1860
+ []
1861
+ );
1862
+ const scrollTo = (index) => {
1863
+ const clamped = Math.max(0, Math.min(index, items.length - 1));
1864
+ scrollRef.current?.scrollTo({ x: clamped * slideWidth, animated: true });
1865
+ };
1866
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
1867
+ import_react_native22.View,
1868
+ {
1869
+ style: [styles20.container, style],
1870
+ accessibilityRole: "none",
1871
+ accessibilityLabel: label,
1872
+ children: [
1873
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1874
+ import_react_native22.ScrollView,
1875
+ {
1876
+ ref: scrollRef,
1877
+ horizontal: true,
1878
+ pagingEnabled: true,
1879
+ showsHorizontalScrollIndicator: false,
1880
+ onScroll: handleScroll,
1881
+ scrollEventThrottle: 16,
1882
+ onLayout: (e) => setSlideWidth(e.nativeEvent.layout.width),
1883
+ style: styles20.scrollView,
1884
+ children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native22.View, { style: [styles20.slide, { width: slideWidth }], children: item }, index))
1885
+ }
1886
+ ),
1887
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_native22.View, { style: styles20.nav, children: [
1888
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1889
+ import_react_native22.Pressable,
1890
+ {
1891
+ onPress: () => scrollTo(activeIndex - 1),
1892
+ disabled: activeIndex <= 0,
1893
+ accessibilityRole: "button",
1894
+ accessibilityLabel: "Previous",
1895
+ accessibilityState: { disabled: activeIndex <= 0 },
1896
+ style: ({ pressed }) => [
1897
+ styles20.navButton,
1898
+ activeIndex <= 0 && { opacity: 0.4 },
1899
+ pressed && styles20.pressed
1900
+ ],
1901
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native22.Text, { style: [styles20.navText, { color: colors2.colorOnBg }], children: "\u2039" })
1902
+ }
1903
+ ),
1904
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native22.View, { style: styles20.dots, children: items.map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1905
+ import_react_native22.Pressable,
1906
+ {
1907
+ onPress: () => scrollTo(index),
1908
+ accessibilityRole: "button",
1909
+ accessibilityLabel: `Go to slide ${index + 1}`,
1910
+ accessibilityState: { selected: activeIndex === index },
1911
+ style: styles20.dotWrapper,
1912
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1913
+ import_react_native22.View,
1914
+ {
1915
+ style: [
1916
+ styles20.dot,
1917
+ {
1918
+ backgroundColor: activeIndex === index ? colors2.colorInteractive : colors2.colorBgSubtle
1919
+ }
1920
+ ]
1921
+ }
1922
+ )
1923
+ },
1924
+ index
1925
+ )) }),
1926
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1927
+ import_react_native22.Pressable,
1928
+ {
1929
+ onPress: () => scrollTo(activeIndex + 1),
1930
+ disabled: activeIndex >= items.length - 1,
1931
+ accessibilityRole: "button",
1932
+ accessibilityLabel: "Next",
1933
+ accessibilityState: { disabled: activeIndex >= items.length - 1 },
1934
+ style: ({ pressed }) => [
1935
+ styles20.navButton,
1936
+ activeIndex >= items.length - 1 && { opacity: 0.4 },
1937
+ pressed && styles20.pressed
1938
+ ],
1939
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native22.Text, { style: [styles20.navText, { color: colors2.colorOnBg }], children: "\u203A" })
1940
+ }
1941
+ )
1942
+ ] })
1943
+ ]
1944
+ }
1945
+ );
1946
+ }
1947
+
1948
+ // src/components/layout/Card/Card.native.tsx
1949
+ var import_react_native23 = require("react-native");
1950
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1951
+ var paddingMap = {
1952
+ none: 0,
1953
+ small: import_native.spacing.s,
1954
+ medium: import_native.spacing.m,
1955
+ large: import_native.spacing.xxl
1956
+ };
1957
+ var alignMap = {
1958
+ start: "flex-start",
1959
+ center: "center",
1960
+ end: "flex-end"
1961
+ };
1962
+ var styles21 = import_react_native23.StyleSheet.create({
1963
+ card: {
1964
+ borderRadius: import_native.border.radius.m,
1965
+ overflow: "hidden"
1966
+ }
1967
+ });
1968
+ function Card({
1969
+ children,
1970
+ variant = "default",
1971
+ padding = "medium",
1972
+ textAlign = "start",
1973
+ style,
1974
+ onPress,
1975
+ accessibilityLabel
1976
+ }) {
1977
+ const { colors: colors2 } = useTheme();
1978
+ const variantStyle = {
1979
+ backgroundColor: colors2.colorBg,
1980
+ ...variant === "elevated" && {
1981
+ shadowColor: "#000",
1982
+ shadowOffset: { width: 0, height: 2 },
1983
+ shadowOpacity: 0.1,
1984
+ shadowRadius: 8,
1985
+ elevation: 4
1986
+ },
1987
+ ...variant === "outlined" && {
1988
+ borderWidth: 1,
1989
+ borderColor: colors2.colorBgSubtle
1990
+ }
1991
+ };
1992
+ const inner = {
1993
+ padding: paddingMap[padding],
1994
+ alignItems: alignMap[textAlign]
1995
+ };
1996
+ if (onPress) {
1997
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1998
+ import_react_native23.Pressable,
1999
+ {
2000
+ onPress,
2001
+ accessibilityRole: "button",
2002
+ accessibilityLabel,
2003
+ style: ({ pressed }) => [styles21.card, variantStyle, inner, pressed && { opacity: 0.8 }, style],
2004
+ children
2005
+ }
2006
+ );
2007
+ }
2008
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native23.View, { style: [styles21.card, variantStyle, inner, style], children });
2009
+ }
2010
+
2011
+ // src/components/layout/SectionHeader/SectionHeader.native.tsx
2012
+ var import_react_native24 = require("react-native");
2013
+ var import_jsx_runtime24 = require("react/jsx-runtime");
2014
+ var alignMap2 = {
2015
+ start: "flex-start",
2016
+ center: "center",
2017
+ end: "flex-end"
2018
+ };
2019
+ var titleStyles = import_react_native24.StyleSheet.create({
2020
+ small: {
2021
+ fontSize: import_native.font.size.heading3,
2022
+ fontFamily: import_native.font.family.heading,
2023
+ fontWeight: import_native.font.weight.heading,
2024
+ lineHeight: lineHeight.heading3
2025
+ },
2026
+ medium: {
2027
+ fontSize: import_native.font.size.heading2,
2028
+ fontFamily: import_native.font.family.heading,
2029
+ fontWeight: import_native.font.weight.heading,
2030
+ lineHeight: lineHeight.heading2
2031
+ },
2032
+ large: {
2033
+ fontSize: import_native.font.size.heading1,
2034
+ fontFamily: import_native.font.family.heading,
2035
+ fontWeight: import_native.font.weight.heading,
2036
+ lineHeight: lineHeight.heading1
2037
+ }
2038
+ });
2039
+ var styles22 = import_react_native24.StyleSheet.create({
2040
+ container: {
2041
+ gap: import_native.spacing.xxs
2042
+ },
2043
+ subtitle: {
2044
+ fontSize: import_native.font.size.bodyS,
2045
+ fontFamily: import_native.font.family.body,
2046
+ lineHeight: lineHeight.bodyS
2047
+ }
2048
+ });
2049
+ function SectionHeader({
2050
+ title,
2051
+ subtitle,
2052
+ alignment = "start",
2053
+ size = "medium",
2054
+ style
2055
+ }) {
2056
+ const { colors: colors2 } = useTheme();
2057
+ const align = alignMap2[alignment];
2058
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native24.View, { style: [styles22.container, { alignItems: align }, style], children: [
2059
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2060
+ import_react_native24.Text,
2061
+ {
2062
+ accessibilityRole: "header",
2063
+ style: [titleStyles[size], { color: colors2.colorOnBg }],
2064
+ children: title
2065
+ }
2066
+ ),
2067
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_native24.Text, { style: [styles22.subtitle, { color: colors2.colorOnBgSubtle }], children: subtitle })
2068
+ ] });
2069
+ }
2070
+
2071
+ // src/components/layout/IconWrapper/IconWrapper.native.tsx
2072
+ var import_react_native25 = require("react-native");
2073
+ var import_jsx_runtime25 = require("react/jsx-runtime");
2074
+ function IconWrapper({ children, style, accessibilityElementsHidden }) {
2075
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2076
+ import_react_native25.View,
2077
+ {
2078
+ style: [{ alignItems: "center", justifyContent: "center" }, style],
2079
+ importantForAccessibility: accessibilityElementsHidden ? "no-hide-descendants" : "auto",
2080
+ accessibilityElementsHidden,
2081
+ children
2082
+ }
2083
+ );
2084
+ }
2085
+
2086
+ // src/components/layout/ButtonGroup/ButtonGroup.native.tsx
2087
+ var import_react_native26 = require("react-native");
2088
+ var import_jsx_runtime26 = require("react/jsx-runtime");
2089
+ var styles23 = import_react_native26.StyleSheet.create({
2090
+ group: {
2091
+ flexDirection: "row",
2092
+ flexWrap: "wrap",
2093
+ gap: import_native.spacing.xs
2094
+ },
2095
+ column: {
2096
+ flexDirection: "column",
2097
+ gap: import_native.spacing.xs
2098
+ }
2099
+ });
2100
+ function ButtonContainer({ children, variant, accessibilityLabel, style }) {
2101
+ const isColumn = variant === "card" || variant === "modal";
2102
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2103
+ import_react_native26.View,
2104
+ {
2105
+ accessibilityLabel,
2106
+ style: [isColumn ? styles23.column : styles23.group, style],
2107
+ children
2108
+ }
2109
+ );
2110
+ }
2111
+ var ButtonGroup = ButtonContainer;
2112
+
2113
+ // src/components/interaction/Button/Button.native.tsx
2114
+ var import_react_native27 = require("react-native");
2115
+ var import_jsx_runtime27 = require("react/jsx-runtime");
2116
+ var sizeTokens = {
2117
+ small: { height: 36, px: import_native.spacing.m, fontSize: import_native.font.size.bodyS, radius: import_native.border.radius.full },
2118
+ medium: { height: 48, px: import_native.spacing.m, fontSize: import_native.font.size.body, radius: import_native.border.radius.full },
2119
+ large: { height: 56, px: import_native.spacing.xxl, fontSize: import_native.font.size.heading3, radius: import_native.border.radius.full }
2120
+ };
2121
+ var styles24 = import_react_native27.StyleSheet.create({
2122
+ pressable: {
2123
+ flexDirection: "row",
2124
+ alignItems: "center",
2125
+ justifyContent: "center",
2126
+ gap: import_native.spacing.xs,
2127
+ alignSelf: "flex-start"
2128
+ },
2129
+ label: {
2130
+ fontFamily: import_native.font.family.body,
2131
+ fontWeight: import_native.font.weight.semibold,
2132
+ includeFontPadding: false
2133
+ }
2134
+ });
2135
+ function Button({
2136
+ children,
2137
+ variant = "default",
2138
+ size = "medium",
2139
+ iconStart,
2140
+ iconEnd,
2141
+ disabled = false,
2142
+ isIconOnly = false,
2143
+ onPress,
2144
+ accessibilityLabel,
2145
+ style
2146
+ }) {
2147
+ const { colors: colors2 } = useTheme();
2148
+ const { height, px, fontSize, radius } = sizeTokens[size];
2149
+ const primaryColor = colors2.colorInteractive;
2150
+ const onPrimaryColor = colors2.colorOnInteractive;
2151
+ const outlineTextColor = colors2.colorInteractiveOnBg;
2152
+ const isOutline = variant === "outline" || variant === "ghost";
2153
+ const containerStyle = {
2154
+ height,
2155
+ paddingHorizontal: isIconOnly ? import_native.spacing.xs : px,
2156
+ borderRadius: radius,
2157
+ opacity: disabled ? 0.4 : 1,
2158
+ // Icon-only: square with equal xs padding on both axes.
2159
+ ...isIconOnly && { aspectRatio: 1, paddingVertical: import_native.spacing.xs },
2160
+ ...variant === "default" && { backgroundColor: primaryColor },
2161
+ ...isOutline && {
2162
+ backgroundColor: "transparent",
2163
+ borderWidth: 1,
2164
+ borderColor: outlineTextColor
2165
+ }
2166
+ };
2167
+ const textColor = variant === "default" ? onPrimaryColor : outlineTextColor;
2168
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
2169
+ import_react_native27.Pressable,
2170
+ {
2171
+ onPress,
2172
+ disabled,
2173
+ accessibilityRole: "button",
2174
+ accessibilityLabel,
2175
+ accessibilityState: { disabled },
2176
+ style: ({ pressed }) => [styles24.pressable, containerStyle, pressed && { opacity: 0.75 }, style],
2177
+ children: [
2178
+ iconStart && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_native27.View, { importantForAccessibility: "no-hide-descendants", accessibilityElementsHidden: true, children: iconStart }),
2179
+ children && (isIconOnly ? children : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_native27.Text, { style: [styles24.label, { fontSize, color: textColor }], children })),
2180
+ iconEnd && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_native27.View, { importantForAccessibility: "no-hide-descendants", children: iconEnd })
2181
+ ]
2182
+ }
2183
+ );
2184
+ }
2185
+
2186
+ // src/components/interaction/Rating/Rating.native.tsx
2187
+ var import_react_native28 = require("react-native");
2188
+ var import_jsx_runtime28 = require("react/jsx-runtime");
2189
+ var STAR_SIZE = 24;
2190
+ var styles25 = import_react_native28.StyleSheet.create({
2191
+ container: {
2192
+ flexDirection: "row",
2193
+ alignItems: "center"
2194
+ },
2195
+ star: {
2196
+ fontSize: STAR_SIZE,
2197
+ fontFamily: import_native.font.family.body
2198
+ }
2199
+ });
2200
+ function Rating({ value, max = 5, style, accessibilityLabel }) {
2201
+ const { colors: colors2 } = useTheme();
2202
+ const label = accessibilityLabel ?? `${value} out of ${max} stars`;
2203
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2204
+ import_react_native28.View,
2205
+ {
2206
+ style: [styles25.container, style],
2207
+ accessibilityRole: "image",
2208
+ accessibilityLabel: label,
2209
+ children: Array.from({ length: max }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2210
+ import_react_native28.Text,
2211
+ {
2212
+ style: [
2213
+ styles25.star,
2214
+ { color: i < value ? colors2.colorWarning : colors2.colorBgSubtle }
2215
+ ],
2216
+ importantForAccessibility: "no",
2217
+ accessibilityElementsHidden: true,
2218
+ children: "\u2605"
2219
+ },
2220
+ i
2221
+ ))
2222
+ }
2223
+ );
2224
+ }
2225
+
2226
+ // src/components/interaction/form/Switch/Switch.native.tsx
2227
+ var import_react_native31 = require("react-native");
2228
+
2229
+ // src/components/interaction/form/atoms/Label.native.tsx
2230
+ var import_react_native29 = require("react-native");
2231
+ var import_jsx_runtime29 = require("react/jsx-runtime");
2232
+ function Label({ label, style }) {
2233
+ const { colors: colors2 } = useTheme();
2234
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
2235
+ import_react_native29.Text,
2236
+ {
2237
+ style: [
2238
+ {
2239
+ fontFamily: import_native.font.family.body,
2240
+ fontSize: import_native.font.size.body,
2241
+ lineHeight: lineHeight.body,
2242
+ fontWeight: import_native.font.weight.semibold,
2243
+ color: colors2.colorOnBg
2244
+ },
2245
+ style
2246
+ ],
2247
+ children: label
2248
+ }
2249
+ );
2250
+ }
2251
+
2252
+ // src/components/interaction/form/atoms/Message.native.tsx
2253
+ var import_react_native30 = require("react-native");
2254
+ var import_jsx_runtime30 = require("react/jsx-runtime");
2255
+ var styles26 = import_react_native30.StyleSheet.create({
2256
+ base: {
2257
+ fontFamily: import_native.font.family.body,
2258
+ fontSize: import_native.font.size.bodyS,
2259
+ lineHeight: lineHeight.bodyS
2260
+ }
2261
+ });
2262
+ function Message({ message, type, style }) {
2263
+ const { colors: colors2 } = useTheme();
2264
+ if (!message) return null;
2265
+ const color = type === "error" ? colors2.colorError : colors2.colorOnBgSubtle;
2266
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
2267
+ import_react_native30.Text,
2268
+ {
2269
+ accessibilityRole: type === "error" ? "alert" : "none",
2270
+ accessibilityLiveRegion: type === "error" ? "assertive" : "polite",
2271
+ style: [styles26.base, { color }, style],
2272
+ children: message
2273
+ }
2274
+ );
2275
+ }
2276
+
2277
+ // src/components/interaction/form/Switch/Switch.native.tsx
2278
+ var import_jsx_runtime31 = require("react/jsx-runtime");
2279
+ var styles27 = import_react_native31.StyleSheet.create({
2280
+ container: {
2281
+ gap: import_native.spacing.xxs
2282
+ },
2283
+ row: {
2284
+ flexDirection: "row",
2285
+ alignItems: "center",
2286
+ gap: import_native.spacing.xs
2287
+ }
2288
+ });
2289
+ function Switch({
2290
+ label,
2291
+ value = false,
2292
+ onChange,
2293
+ disabled = false,
2294
+ error,
2295
+ hint,
2296
+ style
2297
+ }) {
2298
+ const { colors: colors2 } = useTheme();
2299
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_react_native31.View, { style: [styles27.container, style], children: [
2300
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_react_native31.View, { style: styles27.row, children: [
2301
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2302
+ import_react_native31.Switch,
2303
+ {
2304
+ value,
2305
+ onValueChange: onChange,
2306
+ disabled,
2307
+ accessibilityLabel: label,
2308
+ accessibilityRole: "switch",
2309
+ accessibilityState: { checked: value, disabled },
2310
+ thumbColor: colors2.colorInteractive,
2311
+ trackColor: { false: colors2.colorBgSubtle, true: colors2.colorBlueSubtle }
2312
+ }
2313
+ ),
2314
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Label, { label })
2315
+ ] }),
2316
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Message, { type: "error", message: error }),
2317
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Message, { type: "hint", message: hint })
2318
+ ] });
2319
+ }
2320
+
2321
+ // src/components/interaction/form/Checkbox/Checkbox.native.tsx
2322
+ var import_react_native32 = require("react-native");
2323
+ var import_jsx_runtime32 = require("react/jsx-runtime");
2324
+ var BOX = 22;
2325
+ var styles28 = import_react_native32.StyleSheet.create({
2326
+ container: {
2327
+ gap: import_native.spacing.xxs
2328
+ },
2329
+ row: {
2330
+ flexDirection: "row",
2331
+ alignItems: "center",
2332
+ gap: import_native.spacing.xs,
2333
+ minHeight: 44
2334
+ },
2335
+ box: {
2336
+ width: BOX,
2337
+ height: BOX,
2338
+ borderRadius: import_native.border.radius.xs,
2339
+ borderWidth: 2,
2340
+ alignItems: "center",
2341
+ justifyContent: "center"
2342
+ },
2343
+ checkmark: {
2344
+ fontSize: 14,
2345
+ fontWeight: "700",
2346
+ lineHeight: 16
2347
+ }
2348
+ });
2349
+ function Checkbox({
2350
+ label,
2351
+ name,
2352
+ checked = false,
2353
+ onChange,
2354
+ disabled = false,
2355
+ error,
2356
+ hint,
2357
+ style
2358
+ }) {
2359
+ const { colors: colors2 } = useTheme();
2360
+ const borderColor = error ? colors2.colorError : checked ? colors2.colorInteractive : colors2.colorOnBg;
2361
+ const bgColor = checked ? colors2.colorInteractive : "transparent";
2362
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react_native32.View, { style: [styles28.container, style], children: [
2363
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
2364
+ import_react_native32.Pressable,
2365
+ {
2366
+ onPress: () => !disabled && onChange?.(!checked),
2367
+ accessibilityRole: "checkbox",
2368
+ accessibilityLabel: typeof label === "string" ? label : name,
2369
+ accessibilityState: { checked, disabled },
2370
+ disabled,
2371
+ style: ({ pressed }) => [styles28.row, pressed && { opacity: 0.7 }, disabled && { opacity: 0.4 }],
2372
+ children: [
2373
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_react_native32.View, { style: [styles28.box, { borderColor, backgroundColor: bgColor }], children: checked && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Label, { label: "\u2713", style: [styles28.checkmark, { color: colors2.colorOnInteractive }] }) }),
2374
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Label, { label })
2375
+ ]
2376
+ }
2377
+ ),
2378
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Message, { type: "error", message: error }),
2379
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Message, { type: "hint", message: hint })
2380
+ ] });
2381
+ }
2382
+
2383
+ // src/components/interaction/form/CheckboxGroup/CheckboxGroup.native.tsx
2384
+ var import_react_native33 = require("react-native");
2385
+ var import_jsx_runtime33 = require("react/jsx-runtime");
2386
+ var styles29 = import_react_native33.StyleSheet.create({
2387
+ container: {
2388
+ gap: import_native.spacing.xs
2389
+ },
2390
+ legend: {
2391
+ fontFamily: import_native.font.family.body,
2392
+ fontSize: import_native.font.size.body,
2393
+ lineHeight: lineHeight.body,
2394
+ fontWeight: import_native.font.weight.semibold
2395
+ },
2396
+ required: {
2397
+ fontWeight: import_native.font.weight.body
2398
+ },
2399
+ items: {
2400
+ gap: import_native.spacing.xxs
2401
+ }
2402
+ });
2403
+ function CheckboxGroup({
2404
+ legend,
2405
+ children,
2406
+ error,
2407
+ hint,
2408
+ required,
2409
+ disabled = false,
2410
+ style
2411
+ }) {
2412
+ const { colors: colors2 } = useTheme();
2413
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
2414
+ import_react_native33.View,
2415
+ {
2416
+ style: [styles29.container, disabled && { opacity: 0.4 }, style],
2417
+ accessibilityRole: "none",
2418
+ accessibilityLabel: legend,
2419
+ children: [
2420
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_react_native33.Text, { style: [styles29.legend, { color: colors2.colorOnBg }], children: [
2421
+ legend,
2422
+ required && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_react_native33.Text, { style: [styles29.required, { color: colors2.colorOnBgSubtle }], children: " *" })
2423
+ ] }),
2424
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_react_native33.View, { style: styles29.items, children }),
2425
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Message, { type: "error", message: error }),
2426
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Message, { type: "hint", message: hint })
2427
+ ]
2428
+ }
2429
+ );
2430
+ }
2431
+
2432
+ // src/components/interaction/form/Radio/Radio.native.tsx
2433
+ var import_react_native34 = require("react-native");
2434
+ var import_jsx_runtime34 = require("react/jsx-runtime");
2435
+ var DOT = 22;
2436
+ var INNER = 10;
2437
+ var styles30 = import_react_native34.StyleSheet.create({
2438
+ container: {
2439
+ gap: import_native.spacing.xxs
2440
+ },
2441
+ row: {
2442
+ flexDirection: "row",
2443
+ alignItems: "center",
2444
+ gap: import_native.spacing.xs,
2445
+ minHeight: 44
2446
+ },
2447
+ outer: {
2448
+ width: DOT,
2449
+ height: DOT,
2450
+ borderRadius: DOT / 2,
2451
+ borderWidth: 2,
2452
+ alignItems: "center",
2453
+ justifyContent: "center"
2454
+ },
2455
+ inner: {
2456
+ width: INNER,
2457
+ height: INNER,
2458
+ borderRadius: INNER / 2
2459
+ }
2460
+ });
2461
+ function Radio({
2462
+ label,
2463
+ name,
2464
+ checked = false,
2465
+ onChange,
2466
+ disabled = false,
2467
+ error,
2468
+ hint,
2469
+ style
2470
+ }) {
2471
+ const { colors: colors2 } = useTheme();
2472
+ const borderColor = error ? colors2.colorError : checked ? colors2.colorInteractive : colors2.colorOnBg;
2473
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react_native34.View, { style: [styles30.container, style], children: [
2474
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
2475
+ import_react_native34.Pressable,
2476
+ {
2477
+ onPress: () => !disabled && onChange?.(),
2478
+ accessibilityRole: "radio",
2479
+ accessibilityLabel: typeof label === "string" ? label : name,
2480
+ accessibilityState: { checked, disabled },
2481
+ disabled,
2482
+ style: ({ pressed }) => [styles30.row, pressed && { opacity: 0.7 }, disabled && { opacity: 0.4 }],
2483
+ children: [
2484
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react_native34.View, { style: [styles30.outer, { borderColor }], children: checked && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react_native34.View, { style: [styles30.inner, { backgroundColor: colors2.colorInteractive }] }) }),
2485
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Label, { label })
2486
+ ]
2487
+ }
2488
+ ),
2489
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Message, { type: "error", message: error }),
2490
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Message, { type: "hint", message: hint })
2491
+ ] });
2492
+ }
2493
+
2494
+ // src/components/interaction/form/RadioGroup/RadioGroup.native.tsx
2495
+ var import_react_native35 = require("react-native");
2496
+ var import_jsx_runtime35 = require("react/jsx-runtime");
2497
+ var styles31 = import_react_native35.StyleSheet.create({
2498
+ container: {
2499
+ gap: import_native.spacing.xs
2500
+ },
2501
+ legend: {
2502
+ fontFamily: import_native.font.family.body,
2503
+ fontSize: import_native.font.size.body,
2504
+ lineHeight: lineHeight.body,
2505
+ fontWeight: import_native.font.weight.semibold
2506
+ },
2507
+ required: {
2508
+ fontWeight: import_native.font.weight.body
2509
+ },
2510
+ items: {
2511
+ gap: import_native.spacing.xxs
2512
+ }
2513
+ });
2514
+ function RadioGroup({
2515
+ legend,
2516
+ children,
2517
+ error,
2518
+ hint,
2519
+ required,
2520
+ disabled = false,
2521
+ style
2522
+ }) {
2523
+ const { colors: colors2 } = useTheme();
2524
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
2525
+ import_react_native35.View,
2526
+ {
2527
+ style: [styles31.container, disabled && { opacity: 0.4 }, style],
2528
+ accessibilityRole: "radiogroup",
2529
+ accessibilityLabel: legend,
2530
+ children: [
2531
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_react_native35.Text, { style: [styles31.legend, { color: colors2.colorOnBg }], children: [
2532
+ legend,
2533
+ required && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react_native35.Text, { style: [styles31.required, { color: colors2.colorOnBgSubtle }], children: " *" })
2534
+ ] }),
2535
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react_native35.View, { style: styles31.items, children }),
2536
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Message, { type: "error", message: error }),
2537
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Message, { type: "hint", message: hint })
2538
+ ]
2539
+ }
2540
+ );
2541
+ }
2542
+
2543
+ // src/components/interaction/form/FileInput/FileInput.native.tsx
2544
+ var import_react_native36 = require("react-native");
2545
+ var import_jsx_runtime36 = require("react/jsx-runtime");
2546
+ var styles32 = import_react_native36.StyleSheet.create({
2547
+ container: {
2548
+ gap: import_native.spacing.xxs
2549
+ },
2550
+ dropZone: {
2551
+ alignItems: "center",
2552
+ justifyContent: "center",
2553
+ gap: import_native.spacing.xs,
2554
+ paddingVertical: import_native.spacing.xl,
2555
+ paddingHorizontal: import_native.spacing.m,
2556
+ borderWidth: 2,
2557
+ borderStyle: "dashed",
2558
+ borderRadius: import_native.border.radius.s,
2559
+ minHeight: 120
2560
+ },
2561
+ icon: {
2562
+ fontSize: 28,
2563
+ lineHeight: 32
2564
+ },
2565
+ prompt: {
2566
+ fontFamily: import_native.font.family.body,
2567
+ fontSize: import_native.font.size.body,
2568
+ lineHeight: lineHeight.body,
2569
+ textAlign: "center"
2570
+ },
2571
+ acceptHint: {
2572
+ fontFamily: import_native.font.family.body,
2573
+ fontSize: import_native.font.size.bodyS,
2574
+ lineHeight: lineHeight.bodyS,
2575
+ textAlign: "center"
2576
+ },
2577
+ fileList: {
2578
+ gap: import_native.spacing.xxs,
2579
+ alignItems: "center"
2580
+ },
2581
+ fileName: {
2582
+ fontFamily: import_native.font.family.body,
2583
+ fontSize: import_native.font.size.bodyS,
2584
+ lineHeight: lineHeight.bodyS
2585
+ }
2586
+ });
2587
+ function FileInput({
2588
+ label,
2589
+ name,
2590
+ accept,
2591
+ disabled = false,
2592
+ required,
2593
+ error,
2594
+ hint,
2595
+ onSelect,
2596
+ fileNames = [],
2597
+ style
2598
+ }) {
2599
+ const { colors: colors2 } = useTheme();
2600
+ const borderColor = error ? colors2.colorError : colors2.colorBgSubtle;
2601
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react_native36.View, { style: [styles32.container, style], testID: name, children: [
2602
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
2603
+ Label,
2604
+ {
2605
+ label: required ? `${label} *` : label
2606
+ }
2607
+ ),
2608
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
2609
+ import_react_native36.Pressable,
2610
+ {
2611
+ onPress: () => !disabled && onSelect?.(),
2612
+ disabled,
2613
+ accessibilityRole: "button",
2614
+ accessibilityLabel: `${label}, tap to select file`,
2615
+ accessibilityState: { disabled },
2616
+ style: ({ pressed }) => [
2617
+ styles32.dropZone,
2618
+ {
2619
+ borderColor,
2620
+ backgroundColor: "transparent"
2621
+ },
2622
+ pressed && { opacity: 0.7 },
2623
+ disabled && { opacity: 0.4 }
2624
+ ],
2625
+ children: [
2626
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_native36.Text, { style: [styles32.icon, { color: colors2.colorInteractive }], children: "\u2191" }),
2627
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_native36.Text, { style: [styles32.prompt, { color: colors2.colorOnBgSubtle }], children: fileNames.length > 0 ? "Selected files:" : "Tap to select file" }),
2628
+ fileNames.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_native36.View, { style: styles32.fileList, children: fileNames.map((fileName) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_native36.Text, { style: [styles32.fileName, { color: colors2.colorOnBg }], children: fileName }, fileName)) }),
2629
+ accept && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_native36.Text, { style: [styles32.acceptHint, { color: colors2.colorOnBgSubtle }], children: accept })
2630
+ ]
2631
+ }
2632
+ ),
2633
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Message, { type: "error", message: error }),
2634
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Message, { type: "hint", message: hint })
2635
+ ] });
2636
+ }
2637
+
2638
+ // src/components/interaction/form/Combobox/Combobox.native.tsx
2639
+ var import_react9 = require("react");
2640
+ var import_react_native37 = require("react-native");
2641
+ var import_jsx_runtime37 = require("react/jsx-runtime");
2642
+ var MAX_DROPDOWN_HEIGHT = 200;
2643
+ var styles33 = import_react_native37.StyleSheet.create({
2644
+ container: {
2645
+ gap: import_native.spacing.xxs
2646
+ },
2647
+ inputWrapper: {
2648
+ position: "relative"
2649
+ },
2650
+ input: {
2651
+ fontFamily: import_native.font.family.body,
2652
+ fontSize: import_native.font.size.body,
2653
+ lineHeight: lineHeight.body,
2654
+ paddingVertical: import_native.spacing.xs,
2655
+ paddingHorizontal: import_native.spacing.s,
2656
+ borderWidth: 1,
2657
+ borderRadius: import_native.border.radius.full,
2658
+ minHeight: 44
2659
+ },
2660
+ dropdown: {
2661
+ position: "absolute",
2662
+ top: "100%",
2663
+ start: 0,
2664
+ end: 0,
2665
+ maxHeight: MAX_DROPDOWN_HEIGHT,
2666
+ borderWidth: 1,
2667
+ borderTopWidth: 0,
2668
+ borderBottomStartRadius: import_native.border.radius.xs,
2669
+ borderBottomEndRadius: import_native.border.radius.xs,
2670
+ zIndex: 10
2671
+ },
2672
+ option: {
2673
+ paddingVertical: import_native.spacing.xs,
2674
+ paddingHorizontal: import_native.spacing.s,
2675
+ minHeight: 44,
2676
+ justifyContent: "center"
2677
+ },
2678
+ optionText: {
2679
+ fontFamily: import_native.font.family.body,
2680
+ fontSize: import_native.font.size.body,
2681
+ lineHeight: lineHeight.body
2682
+ }
2683
+ });
2684
+ function Combobox({
2685
+ label,
2686
+ name,
2687
+ options,
2688
+ placeholder,
2689
+ value,
2690
+ onChange,
2691
+ disabled = false,
2692
+ error,
2693
+ hint,
2694
+ style
2695
+ }) {
2696
+ const { colors: colors2 } = useTheme();
2697
+ const selectedOption = (0, import_react9.useMemo)(
2698
+ () => options.find((o) => o.value === value),
2699
+ [options, value]
2700
+ );
2701
+ const [inputValue, setInputValue] = (0, import_react9.useState)(selectedOption?.label ?? "");
2702
+ const [isOpen, setIsOpen] = (0, import_react9.useState)(false);
2703
+ const filtered = (0, import_react9.useMemo)(
2704
+ () => options.filter(
2705
+ (o) => o.label.toLowerCase().includes(inputValue.toLowerCase())
2706
+ ),
2707
+ [options, inputValue]
2708
+ );
2709
+ const selectOption = (option) => {
2710
+ setInputValue(option.label);
2711
+ setIsOpen(false);
2712
+ onChange?.(option.value);
2713
+ };
2714
+ const handleChangeText = (text) => {
2715
+ setInputValue(text);
2716
+ setIsOpen(true);
2717
+ };
2718
+ const handleFocus = () => {
2719
+ setIsOpen(true);
2720
+ };
2721
+ const handleBlur = () => {
2722
+ setTimeout(() => setIsOpen(false), 150);
2723
+ };
2724
+ const borderColor = error ? colors2.colorError : colors2.colorOnBg;
2725
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_react_native37.View, { style: [styles33.container, style], children: [
2726
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Label, { label }),
2727
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_react_native37.View, { style: styles33.inputWrapper, children: [
2728
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2729
+ import_react_native37.TextInput,
2730
+ {
2731
+ value: inputValue,
2732
+ onChangeText: handleChangeText,
2733
+ onFocus: handleFocus,
2734
+ onBlur: handleBlur,
2735
+ placeholder,
2736
+ placeholderTextColor: colors2.colorOnBgSubtle,
2737
+ editable: !disabled,
2738
+ accessibilityRole: "combobox",
2739
+ accessibilityLabel: typeof label === "string" ? label : name,
2740
+ accessibilityState: { disabled, expanded: isOpen },
2741
+ style: [
2742
+ styles33.input,
2743
+ {
2744
+ borderColor,
2745
+ color: colors2.colorOnBg,
2746
+ backgroundColor: colors2.colorBg
2747
+ },
2748
+ disabled && { opacity: 0.4 }
2749
+ ]
2750
+ }
2751
+ ),
2752
+ isOpen && filtered.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2753
+ import_react_native37.ScrollView,
2754
+ {
2755
+ style: [
2756
+ styles33.dropdown,
2757
+ {
2758
+ borderColor: colors2.colorBgSubtle,
2759
+ backgroundColor: colors2.colorBg
2760
+ }
2761
+ ],
2762
+ keyboardShouldPersistTaps: "handled",
2763
+ nestedScrollEnabled: true,
2764
+ children: filtered.map((option) => {
2765
+ const isSelected = option.value === value;
2766
+ const isDisabled = option.disabled;
2767
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2768
+ import_react_native37.Pressable,
2769
+ {
2770
+ onPress: () => !isDisabled && selectOption(option),
2771
+ disabled: isDisabled,
2772
+ accessibilityRole: "menuitem",
2773
+ accessibilityLabel: option.label,
2774
+ accessibilityState: { selected: isSelected, disabled: isDisabled },
2775
+ style: ({ pressed }) => [
2776
+ styles33.option,
2777
+ isSelected && { backgroundColor: colors2.colorBlueSubtle },
2778
+ pressed && !isDisabled && { backgroundColor: colors2.colorBgSubtle },
2779
+ isDisabled && { opacity: 0.4 }
2780
+ ],
2781
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2782
+ import_react_native37.Text,
2783
+ {
2784
+ style: [
2785
+ styles33.optionText,
2786
+ {
2787
+ color: isSelected ? colors2.colorInteractive : colors2.colorOnBg
2788
+ },
2789
+ isSelected && { fontWeight: import_native.font.weight.semibold }
2790
+ ],
2791
+ children: option.label
2792
+ }
2793
+ )
2794
+ },
2795
+ option.value
2796
+ );
2797
+ })
2798
+ }
2799
+ )
2800
+ ] }),
2801
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Message, { type: "error", message: error }),
2802
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Message, { type: "hint", message: hint })
2803
+ ] });
2804
+ }
2805
+
2806
+ // src/components/interaction/form/SegmentedControl/SegmentedControl.native.tsx
2807
+ var import_react10 = require("react");
2808
+ var import_react_native38 = require("react-native");
2809
+ var import_jsx_runtime38 = require("react/jsx-runtime");
2810
+ var sizeTokens2 = {
2811
+ small: { height: 32, fontSize: import_native.font.size.bodyS, px: import_native.spacing.s },
2812
+ medium: { height: 40, fontSize: import_native.font.size.body, px: import_native.spacing.m },
2813
+ large: { height: 48, fontSize: import_native.font.size.body, px: import_native.spacing.l }
2814
+ };
2815
+ var styles34 = import_react_native38.StyleSheet.create({
2816
+ track: {
2817
+ flexDirection: "row",
2818
+ borderRadius: import_native.border.radius.full,
2819
+ overflow: "hidden"
2820
+ },
2821
+ item: {
2822
+ flex: 1,
2823
+ alignItems: "center",
2824
+ justifyContent: "center",
2825
+ minHeight: 44
2826
+ },
2827
+ label: {
2828
+ fontFamily: import_native.font.family.body,
2829
+ fontWeight: import_native.font.weight.semibold,
2830
+ textAlign: "center"
2831
+ }
2832
+ });
2833
+ function SegmentedControl({
2834
+ selectedIndex = 0,
2835
+ disabled = false,
2836
+ size = "medium",
2837
+ variant = "outline",
2838
+ children,
2839
+ accessibilityLabel,
2840
+ onValueChange,
2841
+ style
2842
+ }) {
2843
+ const { colors: colors2 } = useTheme();
2844
+ const { height, fontSize, px } = sizeTokens2[size];
2845
+ const items = import_react10.Children.toArray(children);
2846
+ const trackStyle = variant === "filled" ? { backgroundColor: colors2.colorBgSubtle } : { backgroundColor: "transparent", borderWidth: 1, borderColor: colors2.colorBgSubtle };
2847
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2848
+ import_react_native38.View,
2849
+ {
2850
+ style: [styles34.track, trackStyle, { borderRadius: import_native.border.radius.full }, style],
2851
+ accessibilityRole: "tablist",
2852
+ accessibilityLabel,
2853
+ children: items.map((child, index) => {
2854
+ const isActive = index === selectedIndex;
2855
+ const activeStyle = variant === "filled" ? { backgroundColor: colors2.colorInteractive } : { borderWidth: 2, borderColor: colors2.colorInteractive };
2856
+ const inactiveStyle = variant === "filled" ? {} : {};
2857
+ const textColor = variant === "filled" && isActive ? colors2.colorOnInteractive : isActive ? colors2.colorInteractive : colors2.colorOnBgSubtle;
2858
+ const label = typeof child === "string" || typeof child === "number" ? String(child) : null;
2859
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2860
+ import_react_native38.Pressable,
2861
+ {
2862
+ onPress: () => !disabled && onValueChange?.(index),
2863
+ disabled,
2864
+ accessibilityRole: "tab",
2865
+ accessibilityLabel: label ?? void 0,
2866
+ accessibilityState: { selected: isActive, disabled },
2867
+ style: ({ pressed }) => [
2868
+ styles34.item,
2869
+ { height, paddingHorizontal: px },
2870
+ isActive ? activeStyle : inactiveStyle,
2871
+ variant === "filled" && isActive && { borderRadius: import_native.border.radius.full },
2872
+ pressed && !disabled && { opacity: 0.7 },
2873
+ disabled && { opacity: 0.4 }
2874
+ ],
2875
+ children: label !== null ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_native38.Text, { style: [styles34.label, { fontSize, color: textColor }], children: label }) : child
2876
+ },
2877
+ index
2878
+ );
2879
+ })
2880
+ }
2881
+ );
2882
+ }
2883
+
2884
+ // src/components/interaction/form/FormInput/FormInput.native.tsx
2885
+ var import_react11 = require("react");
2886
+ var import_react_native39 = require("react-native");
2887
+ var import_jsx_runtime39 = require("react/jsx-runtime");
2888
+ var keyboardTypeMap = {
2889
+ text: "default",
2890
+ email: "email-address",
2891
+ password: "default",
2892
+ tel: "phone-pad",
2893
+ url: "url",
2894
+ number: "numeric",
2895
+ search: "default"
2896
+ };
2897
+ var styles35 = import_react_native39.StyleSheet.create({
2898
+ container: {
2899
+ gap: import_native.spacing.xxs
2900
+ },
2901
+ input: {
2902
+ fontFamily: import_native.font.family.body,
2903
+ fontSize: import_native.font.size.body,
2904
+ lineHeight: lineHeight.body,
2905
+ paddingHorizontal: import_native.spacing.s,
2906
+ paddingVertical: import_native.spacing.xs,
2907
+ borderWidth: 1,
2908
+ borderRadius: import_native.border.radius.full,
2909
+ minHeight: 44
2910
+ }
2911
+ });
2912
+ function FormInput({
2913
+ label,
2914
+ name,
2915
+ type = "text",
2916
+ value,
2917
+ defaultValue,
2918
+ placeholder,
2919
+ error,
2920
+ hint,
2921
+ disabled = false,
2922
+ onChange,
2923
+ onBlur,
2924
+ onFocus,
2925
+ style
2926
+ }) {
2927
+ const { colors: colors2 } = useTheme();
2928
+ const [focused, setFocused] = (0, import_react11.useState)(false);
2929
+ const borderColor = error ? colors2.colorError : focused ? colors2.colorInteractive : colors2.colorOnBg;
2930
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_react_native39.View, { style: [styles35.container, style], children: [
2931
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Label, { label }),
2932
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2933
+ import_react_native39.TextInput,
2934
+ {
2935
+ accessibilityLabel: typeof label === "string" ? label : name,
2936
+ accessibilityState: { disabled },
2937
+ accessibilityHint: hint,
2938
+ value,
2939
+ defaultValue,
2940
+ placeholder,
2941
+ placeholderTextColor: colors2.colorOnBgSubtle,
2942
+ keyboardType: keyboardTypeMap[type],
2943
+ secureTextEntry: type === "password",
2944
+ autoCapitalize: type === "email" || type === "url" ? "none" : "sentences",
2945
+ autoComplete: type === "email" ? "email" : type === "tel" ? "tel" : void 0,
2946
+ editable: !disabled,
2947
+ onChangeText: onChange,
2948
+ onFocus: () => {
2949
+ setFocused(true);
2950
+ onFocus?.();
2951
+ },
2952
+ onBlur: () => {
2953
+ setFocused(false);
2954
+ onBlur?.();
2955
+ },
2956
+ style: [
2957
+ styles35.input,
2958
+ {
2959
+ borderColor,
2960
+ color: colors2.colorOnBg,
2961
+ backgroundColor: colors2.colorBg
2962
+ },
2963
+ disabled && { opacity: 0.4 }
2964
+ ]
2965
+ }
2966
+ ),
2967
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Message, { type: "error", message: error }),
2968
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Message, { type: "hint", message: hint })
2969
+ ] });
2970
+ }
2971
+
2972
+ // src/components/interaction/form/Textarea/Textarea.native.tsx
2973
+ var import_react12 = require("react");
2974
+ var import_react_native40 = require("react-native");
2975
+ var import_jsx_runtime40 = require("react/jsx-runtime");
2976
+ var styles36 = import_react_native40.StyleSheet.create({
2977
+ container: {
2978
+ gap: import_native.spacing.xxs
2979
+ },
2980
+ textarea: {
2981
+ fontFamily: import_native.font.family.body,
2982
+ fontSize: import_native.font.size.body,
2983
+ lineHeight: lineHeight.body,
2984
+ paddingHorizontal: import_native.spacing.s,
2985
+ paddingVertical: import_native.spacing.xs,
2986
+ borderWidth: 1,
2987
+ borderRadius: import_native.border.radius.xs,
2988
+ minHeight: 100,
2989
+ textAlignVertical: "top"
2990
+ }
2991
+ });
2992
+ function Textarea({
2993
+ label,
2994
+ name,
2995
+ value,
2996
+ defaultValue,
2997
+ placeholder,
2998
+ error,
2999
+ hint,
3000
+ disabled = false,
3001
+ numberOfLines = 4,
3002
+ onChange,
3003
+ onBlur,
3004
+ onFocus,
3005
+ style
3006
+ }) {
3007
+ const { colors: colors2 } = useTheme();
3008
+ const [focused, setFocused] = (0, import_react12.useState)(false);
3009
+ const borderColor = error ? colors2.colorError : focused ? colors2.colorInteractive : colors2.colorOnBg;
3010
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native40.View, { style: [styles36.container, style], children: [
3011
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Label, { label }),
3012
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
3013
+ import_react_native40.TextInput,
3014
+ {
3015
+ accessibilityLabel: typeof label === "string" ? label : name,
3016
+ accessibilityState: { disabled },
3017
+ accessibilityHint: hint,
3018
+ multiline: true,
3019
+ numberOfLines,
3020
+ value,
3021
+ defaultValue,
3022
+ placeholder,
3023
+ placeholderTextColor: colors2.colorOnBgSubtle,
3024
+ editable: !disabled,
3025
+ onChangeText: onChange,
3026
+ onFocus: () => {
3027
+ setFocused(true);
3028
+ onFocus?.();
3029
+ },
3030
+ onBlur: () => {
3031
+ setFocused(false);
3032
+ onBlur?.();
3033
+ },
3034
+ style: [
3035
+ styles36.textarea,
3036
+ {
3037
+ borderColor,
3038
+ color: colors2.colorOnBg,
3039
+ backgroundColor: colors2.colorBg
3040
+ },
3041
+ disabled && { opacity: 0.4 }
3042
+ ]
3043
+ }
3044
+ ),
3045
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Message, { type: "error", message: error }),
3046
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Message, { type: "hint", message: hint })
3047
+ ] });
3048
+ }
3049
+
3050
+ // src/components/interaction/form/Select/Select.native.tsx
3051
+ var import_react13 = require("react");
3052
+ var import_react_native41 = require("react-native");
3053
+ var import_jsx_runtime41 = require("react/jsx-runtime");
3054
+ var styles37 = import_react_native41.StyleSheet.create({
3055
+ container: {
3056
+ gap: import_native.spacing.xxs
3057
+ },
3058
+ trigger: {
3059
+ flexDirection: "row",
3060
+ alignItems: "center",
3061
+ justifyContent: "space-between",
3062
+ paddingHorizontal: import_native.spacing.s,
3063
+ paddingVertical: import_native.spacing.xs,
3064
+ borderWidth: 1,
3065
+ borderRadius: import_native.border.radius.full,
3066
+ minHeight: 44
3067
+ },
3068
+ triggerText: {
3069
+ fontFamily: import_native.font.family.body,
3070
+ fontSize: import_native.font.size.body,
3071
+ lineHeight: lineHeight.body,
3072
+ flex: 1
3073
+ },
3074
+ chevron: {
3075
+ fontFamily: import_native.font.family.body,
3076
+ fontSize: import_native.font.size.body,
3077
+ marginStart: import_native.spacing.xs
3078
+ },
3079
+ overlay: {
3080
+ flex: 1,
3081
+ justifyContent: "flex-end",
3082
+ backgroundColor: "rgba(0, 0, 0, 0.5)"
3083
+ },
3084
+ sheet: {
3085
+ maxHeight: "60%",
3086
+ borderTopStartRadius: import_native.border.radius.m,
3087
+ borderTopEndRadius: import_native.border.radius.m,
3088
+ paddingTop: import_native.spacing.m,
3089
+ paddingBottom: import_native.spacing.xxxl
3090
+ },
3091
+ sheetHeader: {
3092
+ flexDirection: "row",
3093
+ justifyContent: "space-between",
3094
+ alignItems: "center",
3095
+ paddingHorizontal: import_native.spacing.m,
3096
+ paddingBottom: import_native.spacing.s
3097
+ },
3098
+ sheetTitle: {
3099
+ fontFamily: import_native.font.family.body,
3100
+ fontSize: import_native.font.size.heading3,
3101
+ fontWeight: import_native.font.weight.semibold
3102
+ },
3103
+ closeText: {
3104
+ fontFamily: import_native.font.family.body,
3105
+ fontSize: import_native.font.size.body,
3106
+ fontWeight: import_native.font.weight.semibold
3107
+ },
3108
+ optionItem: {
3109
+ paddingHorizontal: import_native.spacing.m,
3110
+ paddingVertical: import_native.spacing.s,
3111
+ minHeight: 44,
3112
+ justifyContent: "center"
3113
+ },
3114
+ optionText: {
3115
+ fontFamily: import_native.font.family.body,
3116
+ fontSize: import_native.font.size.body,
3117
+ lineHeight: lineHeight.body
3118
+ }
3119
+ });
3120
+ function Select({
3121
+ label,
3122
+ name,
3123
+ options,
3124
+ placeholder = "Select an option",
3125
+ value,
3126
+ error,
3127
+ hint,
3128
+ disabled = false,
3129
+ onChange,
3130
+ style
3131
+ }) {
3132
+ const { colors: colors2 } = useTheme();
3133
+ const [open, setOpen] = (0, import_react13.useState)(false);
3134
+ const selectedOption = options.find((o) => o.value === value);
3135
+ const displayText = selectedOption?.label ?? placeholder;
3136
+ const isPlaceholder = !selectedOption;
3137
+ const borderColor = error ? colors2.colorError : open ? colors2.colorInteractive : colors2.colorOnBg;
3138
+ const handleSelect = (optionValue) => {
3139
+ onChange?.(optionValue);
3140
+ setOpen(false);
3141
+ };
3142
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react_native41.View, { style: [styles37.container, style], children: [
3143
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Label, { label }),
3144
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
3145
+ import_react_native41.Pressable,
3146
+ {
3147
+ accessibilityRole: "button",
3148
+ accessibilityLabel: typeof label === "string" ? `${label}, ${displayText}` : name,
3149
+ accessibilityState: { disabled, expanded: open },
3150
+ accessibilityHint: "Double tap to open options",
3151
+ disabled,
3152
+ onPress: () => setOpen(true),
3153
+ style: [
3154
+ styles37.trigger,
3155
+ {
3156
+ borderColor,
3157
+ backgroundColor: colors2.colorBg
3158
+ },
3159
+ disabled && { opacity: 0.4 }
3160
+ ],
3161
+ children: [
3162
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
3163
+ import_react_native41.Text,
3164
+ {
3165
+ style: [
3166
+ styles37.triggerText,
3167
+ {
3168
+ color: isPlaceholder ? colors2.colorOnBgSubtle : colors2.colorOnBg
3169
+ }
3170
+ ],
3171
+ children: displayText
3172
+ }
3173
+ ),
3174
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native41.Text, { style: [styles37.chevron, { color: colors2.colorOnBgSubtle }], "aria-hidden": true, children: "\u25BE" })
3175
+ ]
3176
+ }
3177
+ ),
3178
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
3179
+ import_react_native41.Modal,
3180
+ {
3181
+ visible: open,
3182
+ transparent: true,
3183
+ animationType: "slide",
3184
+ onRequestClose: () => setOpen(false),
3185
+ children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
3186
+ import_react_native41.Pressable,
3187
+ {
3188
+ style: styles37.overlay,
3189
+ onPress: () => setOpen(false),
3190
+ accessibilityRole: "button",
3191
+ accessibilityLabel: "Close options",
3192
+ children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
3193
+ import_react_native41.Pressable,
3194
+ {
3195
+ style: [styles37.sheet, { backgroundColor: colors2.colorBg }],
3196
+ onPress: () => {
3197
+ },
3198
+ children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react_native41.SafeAreaView, { children: [
3199
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react_native41.View, { style: styles37.sheetHeader, children: [
3200
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native41.Text, { style: [styles37.sheetTitle, { color: colors2.colorOnBg }], children: typeof label === "string" ? label : "Select" }),
3201
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
3202
+ import_react_native41.Pressable,
3203
+ {
3204
+ accessibilityRole: "button",
3205
+ accessibilityLabel: "Close",
3206
+ onPress: () => setOpen(false),
3207
+ hitSlop: 8,
3208
+ children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native41.Text, { style: [styles37.closeText, { color: colors2.colorInteractive }], children: "Done" })
3209
+ }
3210
+ )
3211
+ ] }),
3212
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
3213
+ import_react_native41.FlatList,
3214
+ {
3215
+ data: options,
3216
+ keyExtractor: (item) => item.value,
3217
+ renderItem: ({ item }) => {
3218
+ const isSelected = item.value === value;
3219
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
3220
+ import_react_native41.Pressable,
3221
+ {
3222
+ accessibilityRole: "button",
3223
+ accessibilityLabel: item.label,
3224
+ accessibilityState: {
3225
+ selected: isSelected,
3226
+ disabled: item.disabled
3227
+ },
3228
+ disabled: item.disabled,
3229
+ onPress: () => handleSelect(item.value),
3230
+ style: ({ pressed }) => [
3231
+ styles37.optionItem,
3232
+ isSelected && { backgroundColor: colors2.colorBgSubtle },
3233
+ pressed && { opacity: 0.7 },
3234
+ item.disabled && { opacity: 0.4 }
3235
+ ],
3236
+ children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
3237
+ import_react_native41.Text,
3238
+ {
3239
+ style: [
3240
+ styles37.optionText,
3241
+ {
3242
+ color: isSelected ? colors2.colorInteractive : colors2.colorOnBg,
3243
+ fontWeight: isSelected ? import_native.font.weight.semibold : import_native.font.weight.body
3244
+ }
3245
+ ],
3246
+ children: item.label
3247
+ }
3248
+ )
3249
+ }
3250
+ );
3251
+ }
3252
+ }
3253
+ )
3254
+ ] })
3255
+ }
3256
+ )
3257
+ }
3258
+ )
3259
+ }
3260
+ ),
3261
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Message, { type: "error", message: error }),
3262
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Message, { type: "hint", message: hint })
3263
+ ] });
3264
+ }
3265
+
3266
+ // src/components/interaction/form/Slider/Slider.native.tsx
3267
+ var import_react14 = require("react");
3268
+ var import_react_native42 = require("react-native");
3269
+ var import_jsx_runtime42 = require("react/jsx-runtime");
3270
+ var TRACK_HEIGHT = 6;
3271
+ var THUMB_SIZE = 24;
3272
+ var styles38 = import_react_native42.StyleSheet.create({
3273
+ container: {
3274
+ gap: import_native.spacing.xxs
3275
+ },
3276
+ labelRow: {
3277
+ flexDirection: "row",
3278
+ justifyContent: "space-between",
3279
+ alignItems: "center"
3280
+ },
3281
+ valueText: {
3282
+ fontFamily: import_native.font.family.body,
3283
+ fontSize: import_native.font.size.bodyS,
3284
+ lineHeight: lineHeight.bodyS,
3285
+ fontWeight: import_native.font.weight.semibold
3286
+ },
3287
+ trackContainer: {
3288
+ height: THUMB_SIZE + import_native.spacing.xs * 2,
3289
+ justifyContent: "center",
3290
+ paddingHorizontal: THUMB_SIZE / 2
3291
+ },
3292
+ track: {
3293
+ height: TRACK_HEIGHT,
3294
+ borderRadius: TRACK_HEIGHT / 2,
3295
+ overflow: "hidden"
3296
+ },
3297
+ fill: {
3298
+ height: TRACK_HEIGHT,
3299
+ borderRadius: TRACK_HEIGHT / 2
3300
+ },
3301
+ thumb: {
3302
+ position: "absolute",
3303
+ width: THUMB_SIZE,
3304
+ height: THUMB_SIZE,
3305
+ borderRadius: THUMB_SIZE / 2,
3306
+ top: "50%",
3307
+ marginTop: -(THUMB_SIZE / 2),
3308
+ borderWidth: 2
3309
+ }
3310
+ });
3311
+ function clampValue(v, min, max) {
3312
+ return Math.min(max, Math.max(min, v));
3313
+ }
3314
+ function snapToStep(v, min, step) {
3315
+ return Math.round((v - min) / step) * step + min;
3316
+ }
3317
+ function Slider({
3318
+ label,
3319
+ name: _name,
3320
+ // eslint-disable-line @typescript-eslint/no-unused-vars
3321
+ value,
3322
+ defaultValue,
3323
+ min = 0,
3324
+ max = 100,
3325
+ step = 1,
3326
+ showValue = false,
3327
+ disabled = false,
3328
+ error,
3329
+ hint,
3330
+ onChange,
3331
+ style
3332
+ }) {
3333
+ const { colors: colors2 } = useTheme();
3334
+ const isControlled = value !== void 0;
3335
+ const [internalValue, setInternalValue] = (0, import_react14.useState)(defaultValue ?? min);
3336
+ const [trackWidth, setTrackWidth] = (0, import_react14.useState)(0);
3337
+ const currentValue = isControlled ? value : internalValue;
3338
+ const fillPct = max > min ? (currentValue - min) / (max - min) * 100 : 0;
3339
+ const updateValue = (v) => {
3340
+ const clamped = clampValue(v, min, max);
3341
+ const snapped = snapToStep(clamped, min, step);
3342
+ if (!isControlled) setInternalValue(snapped);
3343
+ onChange?.(snapped);
3344
+ };
3345
+ const handleTrackLayout = (e) => {
3346
+ setTrackWidth(e.nativeEvent.layout.width);
3347
+ };
3348
+ const valueFromTouch = (pageX, layoutX) => {
3349
+ const x = pageX - layoutX;
3350
+ const pct = clampValue(x / trackWidth, 0, 1);
3351
+ return pct * (max - min) + min;
3352
+ };
3353
+ const handleStartShouldSetResponder = () => !disabled;
3354
+ const handleResponderGrant = (e) => {
3355
+ const target = e.currentTarget;
3356
+ target.measure((_x, _y, _w, _h, pageX) => {
3357
+ updateValue(valueFromTouch(e.nativeEvent.pageX, pageX));
3358
+ });
3359
+ };
3360
+ const handleResponderMove = (e) => {
3361
+ const target = e.currentTarget;
3362
+ target.measure((_x, _y, _w, _h, pageX) => {
3363
+ updateValue(valueFromTouch(e.nativeEvent.pageX, pageX));
3364
+ });
3365
+ };
3366
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
3367
+ import_react_native42.View,
3368
+ {
3369
+ style: [styles38.container, style],
3370
+ accessibilityRole: "adjustable",
3371
+ accessibilityLabel: label,
3372
+ accessibilityValue: { min, max, now: currentValue, text: String(currentValue) },
3373
+ accessibilityState: { disabled },
3374
+ children: [
3375
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native42.View, { style: styles38.labelRow, children: [
3376
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Label, { label }),
3377
+ showValue && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_native42.Text, { style: [styles38.valueText, { color: colors2.colorOnBg }], children: currentValue })
3378
+ ] }),
3379
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
3380
+ import_react_native42.View,
3381
+ {
3382
+ style: [styles38.trackContainer, disabled && { opacity: 0.4 }],
3383
+ onLayout: handleTrackLayout,
3384
+ onStartShouldSetResponder: handleStartShouldSetResponder,
3385
+ onMoveShouldSetResponder: handleStartShouldSetResponder,
3386
+ onResponderGrant: handleResponderGrant,
3387
+ onResponderMove: handleResponderMove,
3388
+ children: [
3389
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_native42.View, { style: [styles38.track, { backgroundColor: colors2.colorBgSubtle }], children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
3390
+ import_react_native42.View,
3391
+ {
3392
+ style: [
3393
+ styles38.fill,
3394
+ {
3395
+ width: `${fillPct}%`,
3396
+ backgroundColor: error ? colors2.colorError : colors2.colorInteractive
3397
+ }
3398
+ ]
3399
+ }
3400
+ ) }),
3401
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
3402
+ import_react_native42.View,
3403
+ {
3404
+ style: [
3405
+ styles38.thumb,
3406
+ {
3407
+ start: `${fillPct}%`,
3408
+ marginStart: -(THUMB_SIZE / 2),
3409
+ backgroundColor: colors2.colorBg,
3410
+ borderColor: error ? colors2.colorError : colors2.colorInteractive
3411
+ }
3412
+ ]
3413
+ }
3414
+ )
3415
+ ]
3416
+ }
3417
+ ),
3418
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Message, { type: "error", message: error }),
3419
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Message, { type: "hint", message: hint })
3420
+ ]
3421
+ }
3422
+ );
3423
+ }
3424
+
3425
+ // src/components/interaction/form/NumberInput/NumberInput.native.tsx
3426
+ var import_react15 = require("react");
3427
+ var import_react_native43 = require("react-native");
3428
+ var import_jsx_runtime43 = require("react/jsx-runtime");
3429
+ var STEPPER_SIZE = 44;
3430
+ var styles39 = import_react_native43.StyleSheet.create({
3431
+ container: {
3432
+ gap: import_native.spacing.xxs
3433
+ },
3434
+ inputRow: {
3435
+ flexDirection: "row",
3436
+ alignItems: "center"
3437
+ },
3438
+ stepper: {
3439
+ width: STEPPER_SIZE,
3440
+ height: STEPPER_SIZE,
3441
+ alignItems: "center",
3442
+ justifyContent: "center",
3443
+ borderWidth: 1
3444
+ },
3445
+ stepperStart: {
3446
+ borderTopStartRadius: import_native.border.radius.full,
3447
+ borderBottomStartRadius: import_native.border.radius.full,
3448
+ borderEndWidth: 0
3449
+ },
3450
+ stepperEnd: {
3451
+ borderTopEndRadius: import_native.border.radius.full,
3452
+ borderBottomEndRadius: import_native.border.radius.full,
3453
+ borderStartWidth: 0
3454
+ },
3455
+ stepperText: {
3456
+ fontSize: 20,
3457
+ fontWeight: import_native.font.weight.semibold,
3458
+ lineHeight: 24
3459
+ },
3460
+ input: {
3461
+ flex: 1,
3462
+ fontFamily: import_native.font.family.body,
3463
+ fontSize: import_native.font.size.body,
3464
+ lineHeight: lineHeight.body,
3465
+ textAlign: "center",
3466
+ paddingHorizontal: import_native.spacing.xs,
3467
+ paddingVertical: import_native.spacing.xs,
3468
+ borderTopWidth: 1,
3469
+ borderBottomWidth: 1,
3470
+ minHeight: STEPPER_SIZE
3471
+ }
3472
+ });
3473
+ function NumberInput({
3474
+ label,
3475
+ name: _name,
3476
+ // eslint-disable-line @typescript-eslint/no-unused-vars
3477
+ value,
3478
+ defaultValue,
3479
+ min,
3480
+ max,
3481
+ step = 1,
3482
+ disabled = false,
3483
+ error,
3484
+ hint,
3485
+ onChange,
3486
+ style
3487
+ }) {
3488
+ const { colors: colors2 } = useTheme();
3489
+ const isControlled = value !== void 0;
3490
+ const [internalValue, setInternalValue] = (0, import_react15.useState)(defaultValue ?? 0);
3491
+ const currentValue = isControlled ? value : internalValue;
3492
+ const clamp = (v) => {
3493
+ const withMin = min !== void 0 ? Math.max(min, v) : v;
3494
+ return max !== void 0 ? Math.min(max, withMin) : withMin;
3495
+ };
3496
+ const update = (next) => {
3497
+ const clamped = clamp(next);
3498
+ if (!isControlled) setInternalValue(clamped);
3499
+ onChange?.(clamped);
3500
+ };
3501
+ const canDecrease = min === void 0 || currentValue > min;
3502
+ const canIncrease = max === void 0 || currentValue < max;
3503
+ const borderColor = error ? colors2.colorError : colors2.colorOnBg;
3504
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native43.View, { style: [styles39.container, style], children: [
3505
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Label, { label }),
3506
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native43.View, { style: [styles39.inputRow, disabled && { opacity: 0.4 }], children: [
3507
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3508
+ import_react_native43.Pressable,
3509
+ {
3510
+ accessibilityRole: "button",
3511
+ accessibilityLabel: "Decrease",
3512
+ accessibilityState: { disabled: disabled || !canDecrease },
3513
+ disabled: disabled || !canDecrease,
3514
+ onPress: () => update(currentValue - step),
3515
+ style: ({ pressed }) => [
3516
+ styles39.stepper,
3517
+ styles39.stepperStart,
3518
+ {
3519
+ borderColor,
3520
+ backgroundColor: colors2.colorBgSubtle
3521
+ },
3522
+ pressed && { opacity: 0.7 },
3523
+ (disabled || !canDecrease) && { opacity: 0.4 }
3524
+ ],
3525
+ children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3526
+ import_react_native43.Text,
3527
+ {
3528
+ style: [styles39.stepperText, { color: colors2.colorOnBg }],
3529
+ "aria-hidden": true,
3530
+ children: "\u2212"
3531
+ }
3532
+ )
3533
+ }
3534
+ ),
3535
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3536
+ import_react_native43.TextInput,
3537
+ {
3538
+ accessibilityLabel: label,
3539
+ accessibilityState: { disabled },
3540
+ accessibilityValue: {
3541
+ min,
3542
+ max,
3543
+ now: currentValue,
3544
+ text: String(currentValue)
3545
+ },
3546
+ keyboardType: "numeric",
3547
+ value: String(currentValue),
3548
+ editable: !disabled,
3549
+ onChangeText: (text) => {
3550
+ const parsed = parseFloat(text);
3551
+ const safe = isNaN(parsed) ? 0 : parsed;
3552
+ update(safe);
3553
+ },
3554
+ style: [
3555
+ styles39.input,
3556
+ {
3557
+ borderColor,
3558
+ color: colors2.colorOnBg,
3559
+ backgroundColor: colors2.colorBg
3560
+ }
3561
+ ]
3562
+ }
3563
+ ),
3564
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3565
+ import_react_native43.Pressable,
3566
+ {
3567
+ accessibilityRole: "button",
3568
+ accessibilityLabel: "Increase",
3569
+ accessibilityState: { disabled: disabled || !canIncrease },
3570
+ disabled: disabled || !canIncrease,
3571
+ onPress: () => update(currentValue + step),
3572
+ style: ({ pressed }) => [
3573
+ styles39.stepper,
3574
+ styles39.stepperEnd,
3575
+ {
3576
+ borderColor,
3577
+ backgroundColor: colors2.colorBgSubtle
3578
+ },
3579
+ pressed && { opacity: 0.7 },
3580
+ (disabled || !canIncrease) && { opacity: 0.4 }
3581
+ ],
3582
+ children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3583
+ import_react_native43.Text,
3584
+ {
3585
+ style: [styles39.stepperText, { color: colors2.colorOnBg }],
3586
+ "aria-hidden": true,
3587
+ children: "+"
3588
+ }
3589
+ )
3590
+ }
3591
+ )
3592
+ ] }),
3593
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Message, { type: "error", message: error }),
3594
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Message, { type: "hint", message: hint })
3595
+ ] });
3596
+ }
3597
+
3598
+ // src/components/interaction/Dialog/Dialog.native.tsx
3599
+ var import_react_native44 = require("react-native");
3600
+ var import_jsx_runtime44 = require("react/jsx-runtime");
3601
+ var styles40 = import_react_native44.StyleSheet.create({
3602
+ overlay: {
3603
+ flex: 1,
3604
+ justifyContent: "center",
3605
+ alignItems: "center",
3606
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
3607
+ padding: import_native.spacing.m
3608
+ },
3609
+ panel: {
3610
+ width: "100%",
3611
+ maxWidth: 480,
3612
+ borderRadius: import_native.border.radius.m,
3613
+ padding: import_native.spacing.l,
3614
+ paddingTop: import_native.spacing.xl,
3615
+ shadowColor: "#000",
3616
+ shadowOffset: { width: 0, height: 4 },
3617
+ shadowOpacity: 0.15,
3618
+ shadowRadius: 12,
3619
+ elevation: 8
3620
+ },
3621
+ header: {
3622
+ flexDirection: "row",
3623
+ justifyContent: "space-between",
3624
+ alignItems: "center",
3625
+ marginBottom: import_native.spacing.m
3626
+ },
3627
+ title: {
3628
+ fontFamily: import_native.font.family.body,
3629
+ fontSize: import_native.font.size.heading3,
3630
+ fontWeight: import_native.font.weight.semibold,
3631
+ flex: 1
3632
+ },
3633
+ closeButton: {
3634
+ position: "absolute",
3635
+ top: import_native.spacing.s,
3636
+ end: import_native.spacing.s,
3637
+ width: 44,
3638
+ height: 44,
3639
+ alignItems: "center",
3640
+ justifyContent: "center",
3641
+ zIndex: 1
3642
+ },
3643
+ closeText: {
3644
+ fontFamily: import_native.font.family.body,
3645
+ fontSize: 20,
3646
+ lineHeight: 24
3647
+ }
3648
+ });
3649
+ function Dialog({
3650
+ isOpen = false,
3651
+ onClose,
3652
+ title,
3653
+ children,
3654
+ style
3655
+ }) {
3656
+ const { colors: colors2 } = useTheme();
3657
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3658
+ import_react_native44.Modal,
3659
+ {
3660
+ visible: isOpen,
3661
+ transparent: true,
3662
+ animationType: "fade",
3663
+ onRequestClose: onClose,
3664
+ children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3665
+ import_react_native44.Pressable,
3666
+ {
3667
+ style: styles40.overlay,
3668
+ onPress: onClose,
3669
+ accessibilityRole: "button",
3670
+ accessibilityLabel: "Close dialog",
3671
+ children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
3672
+ import_react_native44.Pressable,
3673
+ {
3674
+ style: [styles40.panel, { backgroundColor: colors2.colorGreySubtle }, style],
3675
+ onPress: () => {
3676
+ },
3677
+ accessibilityRole: "none",
3678
+ children: [
3679
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3680
+ import_react_native44.Pressable,
3681
+ {
3682
+ style: styles40.closeButton,
3683
+ onPress: onClose,
3684
+ accessibilityRole: "button",
3685
+ accessibilityLabel: "Close dialog",
3686
+ hitSlop: 8,
3687
+ children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3688
+ import_react_native44.Text,
3689
+ {
3690
+ style: [styles40.closeText, { color: colors2.colorOnBgSubtle }],
3691
+ "aria-hidden": true,
3692
+ children: "\u2715"
3693
+ }
3694
+ )
3695
+ }
3696
+ ),
3697
+ !!title && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native44.View, { style: styles40.header, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native44.Text, { style: [styles40.title, { color: colors2.colorOnGreySubtle }], children: title }) }),
3698
+ children
3699
+ ]
3700
+ }
3701
+ )
3702
+ }
3703
+ )
3704
+ }
3705
+ );
3706
+ }
3707
+
3708
+ // src/components/interaction/Drawer/Drawer.native.tsx
3709
+ var import_react16 = require("react");
3710
+ var import_react_native45 = require("react-native");
3711
+ var import_jsx_runtime45 = require("react/jsx-runtime");
3712
+ var styles41 = import_react_native45.StyleSheet.create({
3713
+ overlay: {
3714
+ flex: 1,
3715
+ justifyContent: "flex-end"
3716
+ },
3717
+ panel: {
3718
+ maxHeight: "90%",
3719
+ borderTopStartRadius: import_native.border.radius.m,
3720
+ borderTopEndRadius: import_native.border.radius.m,
3721
+ paddingTop: import_native.spacing.m,
3722
+ paddingHorizontal: import_native.spacing.m,
3723
+ paddingBottom: import_native.spacing.m,
3724
+ shadowColor: "#000",
3725
+ shadowOffset: { width: 0, height: -4 },
3726
+ shadowOpacity: 0.15,
3727
+ shadowRadius: 16,
3728
+ elevation: 16
3729
+ },
3730
+ header: {
3731
+ flexDirection: "row",
3732
+ justifyContent: "space-between",
3733
+ alignItems: "center",
3734
+ paddingBottom: import_native.spacing.m,
3735
+ borderBottomWidth: 1,
3736
+ marginBottom: import_native.spacing.m
3737
+ },
3738
+ title: {
3739
+ fontFamily: import_native.font.family.body,
3740
+ fontSize: import_native.font.size.heading3,
3741
+ fontWeight: import_native.font.weight.semibold,
3742
+ flex: 1
3743
+ },
3744
+ closeButton: {
3745
+ width: 44,
3746
+ height: 44,
3747
+ alignItems: "center",
3748
+ justifyContent: "center"
3749
+ },
3750
+ closeText: {
3751
+ fontFamily: import_native.font.family.body,
3752
+ fontSize: 20,
3753
+ lineHeight: 24
3754
+ },
3755
+ body: {
3756
+ flex: 1
3757
+ }
3758
+ });
3759
+ function Drawer({
3760
+ isOpen,
3761
+ onClose,
3762
+ title,
3763
+ children,
3764
+ style
3765
+ }) {
3766
+ const { colors: colors2 } = useTheme();
3767
+ const screenHeight = import_react_native45.Dimensions.get("window").height;
3768
+ const slideAnim = (0, import_react16.useRef)(new import_react_native45.Animated.Value(screenHeight)).current;
3769
+ const backdropAnim = (0, import_react16.useRef)(new import_react_native45.Animated.Value(0)).current;
3770
+ (0, import_react16.useEffect)(() => {
3771
+ if (isOpen) {
3772
+ import_react_native45.Animated.parallel([
3773
+ import_react_native45.Animated.timing(slideAnim, {
3774
+ toValue: 0,
3775
+ duration: 250,
3776
+ useNativeDriver: true
3777
+ }),
3778
+ import_react_native45.Animated.timing(backdropAnim, {
3779
+ toValue: 1,
3780
+ duration: 250,
3781
+ useNativeDriver: true
3782
+ })
3783
+ ]).start();
3784
+ } else {
3785
+ import_react_native45.Animated.parallel([
3786
+ import_react_native45.Animated.timing(slideAnim, {
3787
+ toValue: screenHeight,
3788
+ duration: 200,
3789
+ useNativeDriver: true
3790
+ }),
3791
+ import_react_native45.Animated.timing(backdropAnim, {
3792
+ toValue: 0,
3793
+ duration: 200,
3794
+ useNativeDriver: true
3795
+ })
3796
+ ]).start();
3797
+ }
3798
+ }, [isOpen, slideAnim, backdropAnim, screenHeight]);
3799
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3800
+ import_react_native45.Modal,
3801
+ {
3802
+ visible: isOpen,
3803
+ transparent: true,
3804
+ animationType: "none",
3805
+ onRequestClose: onClose,
3806
+ children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_react_native45.View, { style: styles41.overlay, children: [
3807
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3808
+ import_react_native45.Animated.View,
3809
+ {
3810
+ style: [
3811
+ import_react_native45.StyleSheet.absoluteFill,
3812
+ { backgroundColor: "rgba(0, 0, 0, 0.5)", opacity: backdropAnim }
3813
+ ],
3814
+ children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3815
+ import_react_native45.Pressable,
3816
+ {
3817
+ style: import_react_native45.StyleSheet.absoluteFill,
3818
+ onPress: onClose,
3819
+ accessibilityRole: "button",
3820
+ accessibilityLabel: "Close drawer"
3821
+ }
3822
+ )
3823
+ }
3824
+ ),
3825
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
3826
+ import_react_native45.Animated.View,
3827
+ {
3828
+ style: [
3829
+ styles41.panel,
3830
+ {
3831
+ backgroundColor: colors2.colorBg,
3832
+ transform: [{ translateY: slideAnim }]
3833
+ },
3834
+ style
3835
+ ],
3836
+ accessibilityRole: "none",
3837
+ children: [
3838
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
3839
+ import_react_native45.View,
3840
+ {
3841
+ style: [styles41.header, { borderBottomColor: colors2.colorBgSubtle }],
3842
+ children: [
3843
+ !!title && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react_native45.Text, { style: [styles41.title, { color: colors2.colorOnBg }], children: title }),
3844
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3845
+ import_react_native45.Pressable,
3846
+ {
3847
+ style: styles41.closeButton,
3848
+ onPress: onClose,
3849
+ accessibilityRole: "button",
3850
+ accessibilityLabel: "Close drawer",
3851
+ hitSlop: 8,
3852
+ children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3853
+ import_react_native45.Text,
3854
+ {
3855
+ style: [styles41.closeText, { color: colors2.colorOnBgSubtle }],
3856
+ "aria-hidden": true,
3857
+ children: "\u2715"
3858
+ }
3859
+ )
3860
+ }
3861
+ )
3862
+ ]
3863
+ }
3864
+ ),
3865
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react_native45.View, { style: styles41.body, children })
3866
+ ]
3867
+ }
3868
+ )
3869
+ ] })
3870
+ }
3871
+ );
3872
+ }
3873
+
3874
+ // src/components/interaction/Toast/Toast.native.tsx
3875
+ var import_react17 = require("react");
3876
+ var import_react_native46 = require("react-native");
3877
+ var import_jsx_runtime46 = require("react/jsx-runtime");
3878
+ var ToastContext = (0, import_react17.createContext)(void 0);
3879
+ var styles42 = import_react_native46.StyleSheet.create({
3880
+ container: {
3881
+ position: "absolute",
3882
+ top: 0,
3883
+ start: 0,
3884
+ end: 0,
3885
+ paddingTop: import_native.spacing.xxxl,
3886
+ paddingHorizontal: import_native.spacing.m,
3887
+ zIndex: 9999,
3888
+ pointerEvents: "box-none"
3889
+ },
3890
+ toast: {
3891
+ flexDirection: "row",
3892
+ alignItems: "center",
3893
+ justifyContent: "space-between",
3894
+ paddingVertical: import_native.spacing.s,
3895
+ paddingHorizontal: import_native.spacing.m,
3896
+ borderRadius: import_native.border.radius.s,
3897
+ marginBottom: import_native.spacing.xs,
3898
+ minHeight: 48
3899
+ },
3900
+ message: {
3901
+ fontFamily: import_native.font.family.body,
3902
+ fontSize: import_native.font.size.body,
3903
+ fontWeight: import_native.font.weight.semibold,
3904
+ flex: 1
3905
+ },
3906
+ closeButton: {
3907
+ width: 44,
3908
+ height: 44,
3909
+ alignItems: "center",
3910
+ justifyContent: "center",
3911
+ marginStart: import_native.spacing.xs
3912
+ },
3913
+ closeText: {
3914
+ fontFamily: import_native.font.family.body,
3915
+ fontSize: 16,
3916
+ lineHeight: 20
3917
+ }
3918
+ });
3919
+ function ToastItem({
3920
+ toast,
3921
+ onRemove
3922
+ }) {
3923
+ const { colors: colors2 } = useTheme();
3924
+ const slideAnim = (0, import_react17.useRef)(new import_react_native46.Animated.Value(-100)).current;
3925
+ const opacityAnim = (0, import_react17.useRef)(new import_react_native46.Animated.Value(0)).current;
3926
+ const variantColors = (0, import_react17.useMemo)(
3927
+ () => ({
3928
+ success: { bg: colors2.colorSuccess, text: colors2.colorOnSuccess },
3929
+ error: { bg: colors2.colorError, text: colors2.colorOnError },
3930
+ info: { bg: colors2.colorBgSubtle, text: colors2.colorOnBgSubtle }
3931
+ }),
3932
+ [colors2]
3933
+ );
3934
+ (0, import_react17.useEffect)(() => {
3935
+ import_react_native46.Animated.parallel([
3936
+ import_react_native46.Animated.timing(slideAnim, {
3937
+ toValue: 0,
3938
+ duration: 200,
3939
+ useNativeDriver: true
3940
+ }),
3941
+ import_react_native46.Animated.timing(opacityAnim, {
3942
+ toValue: 1,
3943
+ duration: 200,
3944
+ useNativeDriver: true
3945
+ })
3946
+ ]).start();
3947
+ }, [slideAnim, opacityAnim]);
3948
+ (0, import_react17.useEffect)(() => {
3949
+ const timer = setTimeout(onRemove, 5e3);
3950
+ return () => clearTimeout(timer);
3951
+ }, [onRemove]);
3952
+ const { bg, text } = variantColors[toast.variant];
3953
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
3954
+ import_react_native46.Animated.View,
3955
+ {
3956
+ style: [
3957
+ styles42.toast,
3958
+ {
3959
+ backgroundColor: bg,
3960
+ transform: [{ translateY: slideAnim }],
3961
+ opacity: opacityAnim
3962
+ }
3963
+ ],
3964
+ accessibilityRole: "alert",
3965
+ accessibilityLiveRegion: "polite",
3966
+ children: [
3967
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native46.Text, { style: [styles42.message, { color: text }], children: toast.message }),
3968
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3969
+ import_react_native46.Pressable,
3970
+ {
3971
+ style: styles42.closeButton,
3972
+ onPress: onRemove,
3973
+ accessibilityRole: "button",
3974
+ accessibilityLabel: "Dismiss",
3975
+ hitSlop: 8,
3976
+ children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native46.Text, { style: [styles42.closeText, { color: text }], "aria-hidden": true, children: "\u2715" })
3977
+ }
3978
+ )
3979
+ ]
3980
+ }
3981
+ );
3982
+ }
3983
+ function ToastProvider({
3984
+ children,
3985
+ style
3986
+ }) {
3987
+ const [toasts, setToasts] = (0, import_react17.useState)([]);
3988
+ const showToast = (0, import_react17.useCallback)((message, variant) => {
3989
+ const id = Math.random().toString(36).substring(2, 9);
3990
+ setToasts((prev) => [...prev, { id, message, variant }]);
3991
+ }, []);
3992
+ const removeToast = (0, import_react17.useCallback)((id) => {
3993
+ setToasts((prev) => prev.filter((t) => t.id !== id));
3994
+ }, []);
3995
+ const value = (0, import_react17.useMemo)(() => ({ showToast }), [showToast]);
3996
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ToastContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_react_native46.View, { style: [{ flex: 1 }, style], children: [
3997
+ children,
3998
+ toasts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3999
+ import_react_native46.View,
4000
+ {
4001
+ style: styles42.container,
4002
+ accessibilityRole: "summary",
4003
+ accessibilityLabel: "Notifications",
4004
+ children: toasts.map((toast) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
4005
+ ToastItem,
4006
+ {
4007
+ toast,
4008
+ onRemove: () => removeToast(toast.id)
4009
+ },
4010
+ toast.id
4011
+ ))
4012
+ }
4013
+ )
4014
+ ] }) });
4015
+ }
4016
+ function useToast() {
4017
+ const context = (0, import_react17.useContext)(ToastContext);
4018
+ if (!context) {
4019
+ throw new Error("useToast must be used within a ToastProvider");
4020
+ }
4021
+ return context;
4022
+ }
4023
+
4024
+ // src/components/interaction/DropdownMenu/DropdownMenu.native.tsx
4025
+ var import_react18 = __toESM(require("react"), 1);
4026
+ var import_react_native47 = require("react-native");
4027
+ var import_jsx_runtime47 = require("react/jsx-runtime");
4028
+ var styles43 = import_react_native47.StyleSheet.create({
4029
+ overlay: {
4030
+ flex: 1,
4031
+ justifyContent: "flex-end"
4032
+ },
4033
+ sheet: {
4034
+ maxHeight: "60%",
4035
+ borderTopStartRadius: import_native.border.radius.m,
4036
+ borderTopEndRadius: import_native.border.radius.m,
4037
+ paddingTop: import_native.spacing.m,
4038
+ paddingBottom: import_native.spacing.xxxl
4039
+ },
4040
+ sheetHeader: {
4041
+ flexDirection: "row",
4042
+ justifyContent: "space-between",
4043
+ alignItems: "center",
4044
+ paddingHorizontal: import_native.spacing.m,
4045
+ paddingBottom: import_native.spacing.s,
4046
+ borderBottomWidth: 1,
4047
+ marginBottom: import_native.spacing.xxs
4048
+ },
4049
+ sheetTitle: {
4050
+ fontFamily: import_native.font.family.body,
4051
+ fontSize: import_native.font.size.heading3,
4052
+ fontWeight: import_native.font.weight.semibold
4053
+ },
4054
+ closeText: {
4055
+ fontFamily: import_native.font.family.body,
4056
+ fontSize: import_native.font.size.body,
4057
+ fontWeight: import_native.font.weight.semibold
4058
+ },
4059
+ separator: {
4060
+ height: 1,
4061
+ marginHorizontal: import_native.spacing.m,
4062
+ marginVertical: import_native.spacing.xxs
4063
+ },
4064
+ item: {
4065
+ flexDirection: "row",
4066
+ alignItems: "center",
4067
+ paddingHorizontal: import_native.spacing.m,
4068
+ paddingVertical: import_native.spacing.s,
4069
+ minHeight: 48,
4070
+ gap: import_native.spacing.s
4071
+ },
4072
+ itemText: {
4073
+ fontFamily: import_native.font.family.body,
4074
+ fontSize: import_native.font.size.body,
4075
+ lineHeight: lineHeight.body
4076
+ }
4077
+ });
4078
+ function DropdownMenu({
4079
+ trigger,
4080
+ items,
4081
+ title = "Menu",
4082
+ style
4083
+ }) {
4084
+ const { colors: colors2 } = useTheme();
4085
+ const [open, setOpen] = (0, import_react18.useState)(false);
4086
+ const screenHeight = import_react_native47.Dimensions.get("window").height;
4087
+ const slideAnim = (0, import_react18.useRef)(new import_react_native47.Animated.Value(screenHeight)).current;
4088
+ const backdropAnim = (0, import_react18.useRef)(new import_react_native47.Animated.Value(0)).current;
4089
+ (0, import_react18.useEffect)(() => {
4090
+ if (open) {
4091
+ import_react_native47.Animated.parallel([
4092
+ import_react_native47.Animated.timing(slideAnim, {
4093
+ toValue: 0,
4094
+ duration: 250,
4095
+ useNativeDriver: true
4096
+ }),
4097
+ import_react_native47.Animated.timing(backdropAnim, {
4098
+ toValue: 1,
4099
+ duration: 250,
4100
+ useNativeDriver: true
4101
+ })
4102
+ ]).start();
4103
+ } else {
4104
+ import_react_native47.Animated.parallel([
4105
+ import_react_native47.Animated.timing(slideAnim, {
4106
+ toValue: screenHeight,
4107
+ duration: 200,
4108
+ useNativeDriver: true
4109
+ }),
4110
+ import_react_native47.Animated.timing(backdropAnim, {
4111
+ toValue: 0,
4112
+ duration: 200,
4113
+ useNativeDriver: true
4114
+ })
4115
+ ]).start();
4116
+ }
4117
+ }, [open, slideAnim, backdropAnim, screenHeight]);
4118
+ const handleItemPress = (item) => {
4119
+ item.onPress?.();
4120
+ setOpen(false);
4121
+ };
4122
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_react_native47.View, { style, children: [
4123
+ import_react18.default.cloneElement(trigger, {
4124
+ onPress: () => setOpen(true),
4125
+ accessibilityRole: "button",
4126
+ accessibilityLabel: title
4127
+ }),
4128
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
4129
+ import_react_native47.Modal,
4130
+ {
4131
+ visible: open,
4132
+ transparent: true,
4133
+ animationType: "none",
4134
+ onRequestClose: () => setOpen(false),
4135
+ children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_react_native47.View, { style: styles43.overlay, children: [
4136
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
4137
+ import_react_native47.Animated.View,
4138
+ {
4139
+ style: [
4140
+ import_react_native47.StyleSheet.absoluteFill,
4141
+ { backgroundColor: "rgba(0, 0, 0, 0.5)", opacity: backdropAnim }
4142
+ ],
4143
+ children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
4144
+ import_react_native47.Pressable,
4145
+ {
4146
+ style: import_react_native47.StyleSheet.absoluteFill,
4147
+ onPress: () => setOpen(false),
4148
+ accessibilityRole: "button",
4149
+ accessibilityLabel: "Close menu"
4150
+ }
4151
+ )
4152
+ }
4153
+ ),
4154
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
4155
+ import_react_native47.Animated.View,
4156
+ {
4157
+ style: [
4158
+ styles43.sheet,
4159
+ {
4160
+ backgroundColor: colors2.colorBg,
4161
+ transform: [{ translateY: slideAnim }]
4162
+ }
4163
+ ],
4164
+ children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
4165
+ import_react_native47.Pressable,
4166
+ {
4167
+ onPress: () => {
4168
+ },
4169
+ children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_react_native47.SafeAreaView, { children: [
4170
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
4171
+ import_react_native47.View,
4172
+ {
4173
+ style: [
4174
+ styles43.sheetHeader,
4175
+ { borderBottomColor: colors2.colorBgSubtle }
4176
+ ],
4177
+ children: [
4178
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native47.Text, { style: [styles43.sheetTitle, { color: colors2.colorOnBg }], children: title }),
4179
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
4180
+ import_react_native47.Pressable,
4181
+ {
4182
+ accessibilityRole: "button",
4183
+ accessibilityLabel: "Close",
4184
+ onPress: () => setOpen(false),
4185
+ hitSlop: 8,
4186
+ children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
4187
+ import_react_native47.Text,
4188
+ {
4189
+ style: [
4190
+ styles43.closeText,
4191
+ { color: colors2.colorInteractive }
4192
+ ],
4193
+ children: "Done"
4194
+ }
4195
+ )
4196
+ }
4197
+ )
4198
+ ]
4199
+ }
4200
+ ),
4201
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
4202
+ import_react_native47.FlatList,
4203
+ {
4204
+ data: items,
4205
+ keyExtractor: (item) => item.id,
4206
+ renderItem: ({ item }) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
4207
+ item.separator && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
4208
+ import_react_native47.View,
4209
+ {
4210
+ style: [
4211
+ styles43.separator,
4212
+ { backgroundColor: colors2.colorBgSubtle }
4213
+ ],
4214
+ accessibilityRole: "none"
4215
+ }
4216
+ ),
4217
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
4218
+ import_react_native47.Pressable,
4219
+ {
4220
+ accessibilityRole: "menuitem",
4221
+ accessibilityLabel: item.label,
4222
+ accessibilityState: { disabled: item.disabled },
4223
+ disabled: item.disabled,
4224
+ onPress: () => handleItemPress(item),
4225
+ style: ({ pressed }) => [
4226
+ styles43.item,
4227
+ pressed && { backgroundColor: colors2.colorBgSubtle },
4228
+ item.disabled && { opacity: 0.4 }
4229
+ ],
4230
+ children: [
4231
+ !!item.icon && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
4232
+ import_react_native47.View,
4233
+ {
4234
+ importantForAccessibility: "no-hide-descendants",
4235
+ accessibilityElementsHidden: true,
4236
+ children: item.icon
4237
+ }
4238
+ ),
4239
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
4240
+ import_react_native47.Text,
4241
+ {
4242
+ style: [
4243
+ styles43.itemText,
4244
+ { color: colors2.colorOnBg }
4245
+ ],
4246
+ children: item.label
4247
+ }
4248
+ )
4249
+ ]
4250
+ }
4251
+ )
4252
+ ] })
4253
+ }
4254
+ )
4255
+ ] })
4256
+ }
4257
+ )
4258
+ }
4259
+ )
4260
+ ] })
4261
+ }
4262
+ )
4263
+ ] });
4264
+ }
4265
+
4266
+ // src/components/interaction/Popover/Popover.native.tsx
4267
+ var import_react19 = __toESM(require("react"), 1);
4268
+ var import_react_native48 = require("react-native");
4269
+ var import_jsx_runtime48 = require("react/jsx-runtime");
4270
+ var styles44 = import_react_native48.StyleSheet.create({
4271
+ wrapper: {
4272
+ alignSelf: "flex-start"
4273
+ },
4274
+ overlay: {
4275
+ flex: 1,
4276
+ justifyContent: "center",
4277
+ alignItems: "center",
4278
+ backgroundColor: "rgba(0, 0, 0, 0.25)",
4279
+ padding: import_native.spacing.m
4280
+ },
4281
+ panel: {
4282
+ width: "100%",
4283
+ maxWidth: 360,
4284
+ borderRadius: import_native.border.radius.s,
4285
+ padding: import_native.spacing.m,
4286
+ shadowColor: "#000",
4287
+ shadowOffset: { width: 0, height: 2 },
4288
+ shadowOpacity: 0.15,
4289
+ shadowRadius: 8,
4290
+ elevation: 4
4291
+ }
4292
+ });
4293
+ function Popover({
4294
+ children,
4295
+ content,
4296
+ accessibilityLabel,
4297
+ style
4298
+ }) {
4299
+ const { colors: colors2 } = useTheme();
4300
+ const [isOpen, setIsOpen] = (0, import_react19.useState)(false);
4301
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_react_native48.View, { style: [styles44.wrapper, style], children: [
4302
+ import_react19.default.cloneElement(children, {
4303
+ onPress: () => setIsOpen(true),
4304
+ accessibilityRole: "button",
4305
+ accessibilityLabel: accessibilityLabel ?? "Open popover"
4306
+ }),
4307
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
4308
+ import_react_native48.Modal,
4309
+ {
4310
+ visible: isOpen,
4311
+ transparent: true,
4312
+ animationType: "fade",
4313
+ onRequestClose: () => setIsOpen(false),
4314
+ children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
4315
+ import_react_native48.Pressable,
4316
+ {
4317
+ style: styles44.overlay,
4318
+ onPress: () => setIsOpen(false),
4319
+ accessibilityRole: "button",
4320
+ accessibilityLabel: "Close popover",
4321
+ children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
4322
+ import_react_native48.Pressable,
4323
+ {
4324
+ style: [styles44.panel, { backgroundColor: colors2.colorBg }],
4325
+ onPress: () => {
4326
+ },
4327
+ accessibilityRole: "none",
4328
+ accessibilityLabel,
4329
+ children: content
4330
+ }
4331
+ )
4332
+ }
4333
+ )
4334
+ }
4335
+ )
4336
+ ] });
4337
+ }