@entropix/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.js ADDED
@@ -0,0 +1,1212 @@
1
+ import { createContext, useMemo, useContext, useCallback, useRef, useEffect, useState } from 'react';
2
+ import { tokens } from '@entropix/tokens/native';
3
+ import { tokens as tokens$1 } from '@entropix/tokens/native/light';
4
+ import { tokens as tokens$2 } from '@entropix/tokens/native/dark';
5
+ import { jsx, jsxs } from 'react/jsx-runtime';
6
+ import { Pressable, Text, Animated, Modal, View, StyleSheet, Dimensions } from 'react-native';
7
+ import { useButton, useToggle, useDialog, useTabs, useAccordion, useMenu } from '@entropix/core';
8
+
9
+ // src/theme/theme-context.tsx
10
+ var ThemeContext = createContext({
11
+ mode: "light",
12
+ tokens: tokens$1,
13
+ baseTokens: tokens
14
+ });
15
+ function EntropixProvider({
16
+ mode = "light",
17
+ children
18
+ }) {
19
+ const value = useMemo(
20
+ () => ({
21
+ mode,
22
+ tokens: mode === "dark" ? tokens$2 : tokens$1,
23
+ baseTokens: tokens
24
+ }),
25
+ [mode]
26
+ );
27
+ return /* @__PURE__ */ jsx(ThemeContext.Provider, { value, children });
28
+ }
29
+ function useTheme() {
30
+ return useContext(ThemeContext);
31
+ }
32
+
33
+ // src/utils/map-accessibility-to-rn.ts
34
+ var RN_ROLE_MAP = {
35
+ button: "button",
36
+ checkbox: "checkbox",
37
+ switch: "switch",
38
+ dialog: "none",
39
+ // Modal component handles dialog semantics
40
+ alertdialog: "alert",
41
+ link: "link",
42
+ tab: "tab",
43
+ tablist: "tablist",
44
+ menu: "menu",
45
+ menuitem: "menuitem",
46
+ radio: "radio",
47
+ radiogroup: "radiogroup",
48
+ slider: "adjustable",
49
+ spinbutton: "spinbutton",
50
+ textbox: "text",
51
+ combobox: "combobox",
52
+ progressbar: "progressbar",
53
+ alert: "alert",
54
+ status: "text",
55
+ tooltip: "text",
56
+ none: "none",
57
+ presentation: "none"
58
+ };
59
+ function mapAccessibilityToRN(props) {
60
+ const result = { accessible: true };
61
+ if (props.role) {
62
+ result.accessibilityRole = RN_ROLE_MAP[props.role] ?? props.role;
63
+ }
64
+ if (props.label) {
65
+ result.accessibilityLabel = props.label;
66
+ }
67
+ if (props.describedBy) {
68
+ result.accessibilityHint = props.describedBy;
69
+ }
70
+ if (props.labelledBy) {
71
+ result.accessibilityLabelledBy = props.labelledBy;
72
+ }
73
+ const state = {};
74
+ let hasState = false;
75
+ if (props.disabled !== void 0) {
76
+ state.disabled = props.disabled;
77
+ hasState = true;
78
+ }
79
+ if (props.expanded !== void 0) {
80
+ state.expanded = props.expanded;
81
+ hasState = true;
82
+ }
83
+ if (props.selected !== void 0) {
84
+ state.selected = props.selected;
85
+ hasState = true;
86
+ }
87
+ if (props.checked !== void 0) {
88
+ state.checked = props.checked;
89
+ hasState = true;
90
+ }
91
+ if (props.busy !== void 0) {
92
+ state.busy = props.busy;
93
+ hasState = true;
94
+ }
95
+ if (hasState) {
96
+ result.accessibilityState = state;
97
+ }
98
+ if (props.valueNow !== void 0 || props.valueMin !== void 0 || props.valueMax !== void 0 || props.valueText !== void 0) {
99
+ result.accessibilityValue = {};
100
+ if (props.valueNow !== void 0)
101
+ result.accessibilityValue.now = props.valueNow;
102
+ if (props.valueMin !== void 0)
103
+ result.accessibilityValue.min = props.valueMin;
104
+ if (props.valueMax !== void 0)
105
+ result.accessibilityValue.max = props.valueMax;
106
+ if (props.valueText !== void 0)
107
+ result.accessibilityValue.text = props.valueText;
108
+ }
109
+ if (props.live) {
110
+ result.accessibilityLiveRegion = props.live === "off" ? "none" : props.live;
111
+ }
112
+ if (props.hidden) {
113
+ result.accessibilityElementsHidden = true;
114
+ result.importantForAccessibility = "no-hide-descendants";
115
+ }
116
+ return result;
117
+ }
118
+ function Button({
119
+ onPress,
120
+ disabled,
121
+ loading,
122
+ variant = "primary",
123
+ size = "md",
124
+ style,
125
+ textStyle,
126
+ children,
127
+ ...rest
128
+ }) {
129
+ const { tokens: t, baseTokens: bt } = useTheme();
130
+ const { isDisabled, isLoading, getButtonProps } = useButton({
131
+ disabled,
132
+ loading,
133
+ onPress,
134
+ elementType: "div"
135
+ });
136
+ const propGetterReturn = getButtonProps();
137
+ const rnAccessibility = mapAccessibilityToRN(propGetterReturn.accessibility);
138
+ const handlePress = useCallback(() => {
139
+ propGetterReturn.onAction?.();
140
+ }, [propGetterReturn.onAction]);
141
+ const sizeStyles = getSizeStyle(size, bt);
142
+ const variantStyles = getVariantStyle(variant, t);
143
+ const labelColor = getVariantTextColor(variant, t);
144
+ const isInactive = isDisabled || isLoading;
145
+ return /* @__PURE__ */ jsx(
146
+ Pressable,
147
+ {
148
+ ...rnAccessibility,
149
+ ...rest,
150
+ disabled: isInactive,
151
+ onPress: isInactive ? void 0 : handlePress,
152
+ style: [
153
+ baseStyle,
154
+ sizeStyles.container,
155
+ variantStyles,
156
+ isInactive && { opacity: 0.5 },
157
+ style
158
+ ],
159
+ children: typeof children === "string" ? /* @__PURE__ */ jsx(
160
+ Text,
161
+ {
162
+ style: [
163
+ { color: labelColor, fontSize: sizeStyles.fontSize, fontWeight: "500" },
164
+ textStyle
165
+ ],
166
+ children
167
+ }
168
+ ) : children
169
+ }
170
+ );
171
+ }
172
+ var baseStyle = {
173
+ flexDirection: "row",
174
+ alignItems: "center",
175
+ justifyContent: "center"
176
+ };
177
+ function getSizeStyle(size, bt) {
178
+ switch (size) {
179
+ case "sm":
180
+ return {
181
+ container: {
182
+ paddingVertical: bt.entropixSpacing1,
183
+ paddingHorizontal: bt.entropixSpacing3,
184
+ borderRadius: bt.entropixRadiusSm,
185
+ gap: bt.entropixButtonGap
186
+ },
187
+ fontSize: bt.entropixFontSizeXs
188
+ };
189
+ case "lg":
190
+ return {
191
+ container: {
192
+ paddingVertical: bt.entropixSpacing3,
193
+ paddingHorizontal: bt.entropixSpacing6,
194
+ borderRadius: bt.entropixRadiusLg,
195
+ gap: bt.entropixButtonGap
196
+ },
197
+ fontSize: bt.entropixFontSizeBase
198
+ };
199
+ default:
200
+ return {
201
+ container: {
202
+ paddingVertical: bt.entropixButtonPaddingY,
203
+ paddingHorizontal: bt.entropixButtonPaddingX,
204
+ borderRadius: bt.entropixButtonBorderRadius,
205
+ gap: bt.entropixButtonGap
206
+ },
207
+ fontSize: bt.entropixButtonFontSize
208
+ };
209
+ }
210
+ }
211
+ function getVariantStyle(variant, t) {
212
+ switch (variant) {
213
+ case "primary":
214
+ return { backgroundColor: t.entropixButtonPrimaryBg, borderWidth: 1, borderColor: t.entropixButtonPrimaryBorder };
215
+ case "secondary":
216
+ return { backgroundColor: t.entropixButtonSecondaryBg, borderWidth: 1, borderColor: t.entropixButtonSecondaryBorder };
217
+ case "outline":
218
+ return { backgroundColor: "transparent", borderWidth: 1, borderColor: t.entropixColorBorderDefault };
219
+ case "ghost":
220
+ return { backgroundColor: "transparent", borderWidth: 1, borderColor: "transparent" };
221
+ case "danger":
222
+ return { backgroundColor: t.entropixButtonDangerBg, borderWidth: 1, borderColor: t.entropixButtonDangerBorder };
223
+ }
224
+ }
225
+ function getVariantTextColor(variant, t) {
226
+ switch (variant) {
227
+ case "primary":
228
+ return t.entropixButtonPrimaryText;
229
+ case "secondary":
230
+ return t.entropixButtonSecondaryText;
231
+ case "outline":
232
+ case "ghost":
233
+ return t.entropixColorTextPrimary;
234
+ case "danger":
235
+ return t.entropixButtonDangerText;
236
+ }
237
+ }
238
+ function Toggle(props) {
239
+ return /* @__PURE__ */ jsx(ToggleInner, { ...props, role: "checkbox" });
240
+ }
241
+ function ToggleInner({
242
+ checked,
243
+ defaultChecked,
244
+ onChange,
245
+ disabled,
246
+ label,
247
+ role = "checkbox",
248
+ style,
249
+ textStyle,
250
+ children,
251
+ ...rest
252
+ }) {
253
+ const { tokens: t, baseTokens: bt } = useTheme();
254
+ const { isDisabled, getToggleProps } = useToggle({
255
+ checked,
256
+ defaultChecked,
257
+ onChange,
258
+ disabled,
259
+ role
260
+ });
261
+ const propGetterReturn = getToggleProps();
262
+ const rnAccessibility = mapAccessibilityToRN(propGetterReturn.accessibility);
263
+ const isChecked = propGetterReturn.accessibility.checked === true;
264
+ if (label) {
265
+ rnAccessibility.accessibilityLabel = label;
266
+ }
267
+ const handlePress = useCallback(() => {
268
+ propGetterReturn.onAction?.();
269
+ }, [propGetterReturn.onAction]);
270
+ return /* @__PURE__ */ jsx(
271
+ Pressable,
272
+ {
273
+ ...rnAccessibility,
274
+ ...rest,
275
+ disabled: isDisabled,
276
+ onPress: isDisabled ? void 0 : handlePress,
277
+ style: [
278
+ {
279
+ flexDirection: "row",
280
+ alignItems: "center",
281
+ justifyContent: "center",
282
+ paddingVertical: bt.entropixSpacing2,
283
+ paddingHorizontal: bt.entropixSpacing3,
284
+ borderWidth: 1,
285
+ borderColor: isChecked ? "transparent" : t.entropixColorBorderDefault,
286
+ borderRadius: bt.entropixRadiusMd,
287
+ backgroundColor: isChecked ? t.entropixColorActionPrimaryDefault : t.entropixColorBgPrimary
288
+ },
289
+ isDisabled && { opacity: 0.5 },
290
+ style
291
+ ],
292
+ children: typeof children === "string" ? /* @__PURE__ */ jsx(
293
+ Text,
294
+ {
295
+ style: [
296
+ {
297
+ fontSize: bt.entropixFontSizeSm,
298
+ fontWeight: "500",
299
+ color: isChecked ? t.entropixColorTextInverse : t.entropixColorTextPrimary
300
+ },
301
+ textStyle
302
+ ],
303
+ children
304
+ }
305
+ ) : children != null ? children : /* @__PURE__ */ jsx(
306
+ Text,
307
+ {
308
+ style: {
309
+ fontSize: bt.entropixFontSizeSm,
310
+ fontWeight: "500",
311
+ color: isChecked ? t.entropixColorTextInverse : t.entropixColorTextPrimary
312
+ },
313
+ children: isChecked ? "On" : "Off"
314
+ }
315
+ )
316
+ }
317
+ );
318
+ }
319
+ var TRACK_WIDTH = 44;
320
+ var TRACK_HEIGHT = 24;
321
+ var TRACK_PADDING = 2;
322
+ var THUMB_SIZE = TRACK_HEIGHT - TRACK_PADDING * 2;
323
+ var THUMB_TRAVEL = TRACK_WIDTH - TRACK_PADDING * 2 - THUMB_SIZE;
324
+ function Switch({
325
+ checked,
326
+ defaultChecked,
327
+ onChange,
328
+ disabled,
329
+ label,
330
+ style,
331
+ ...rest
332
+ }) {
333
+ const { tokens: t, baseTokens: bt } = useTheme();
334
+ const { isDisabled, getToggleProps } = useToggle({
335
+ checked,
336
+ defaultChecked,
337
+ onChange,
338
+ disabled,
339
+ role: "switch"
340
+ });
341
+ const propGetterReturn = getToggleProps();
342
+ const rnAccessibility = mapAccessibilityToRN(propGetterReturn.accessibility);
343
+ const isChecked = propGetterReturn.accessibility.checked === true;
344
+ if (label) {
345
+ rnAccessibility.accessibilityLabel = label;
346
+ }
347
+ const handlePress = useCallback(() => {
348
+ propGetterReturn.onAction?.();
349
+ }, [propGetterReturn.onAction]);
350
+ const thumbAnim = useRef(
351
+ new Animated.Value(defaultChecked || checked ? THUMB_TRAVEL : 0)
352
+ ).current;
353
+ useEffect(() => {
354
+ Animated.timing(thumbAnim, {
355
+ toValue: isChecked ? THUMB_TRAVEL : 0,
356
+ duration: 150,
357
+ useNativeDriver: false
358
+ }).start();
359
+ }, [isChecked, thumbAnim]);
360
+ return /* @__PURE__ */ jsx(
361
+ Pressable,
362
+ {
363
+ ...rnAccessibility,
364
+ ...rest,
365
+ disabled: isDisabled,
366
+ onPress: isDisabled ? void 0 : handlePress,
367
+ style: [
368
+ {
369
+ width: TRACK_WIDTH,
370
+ height: TRACK_HEIGHT,
371
+ borderRadius: bt.entropixRadiusFull,
372
+ backgroundColor: isChecked ? t.entropixColorActionPrimaryDefault : t.entropixColorGray300,
373
+ padding: TRACK_PADDING,
374
+ justifyContent: "center"
375
+ },
376
+ isDisabled && { opacity: 0.5 },
377
+ style
378
+ ],
379
+ children: /* @__PURE__ */ jsx(
380
+ Animated.View,
381
+ {
382
+ style: {
383
+ width: THUMB_SIZE,
384
+ height: THUMB_SIZE,
385
+ borderRadius: bt.entropixRadiusFull,
386
+ backgroundColor: t.entropixColorWhite,
387
+ transform: [{ translateX: thumbAnim }]
388
+ }
389
+ }
390
+ )
391
+ }
392
+ );
393
+ }
394
+ var DialogContext = createContext(null);
395
+ function useDialogContext() {
396
+ const context = useContext(DialogContext);
397
+ if (!context) {
398
+ throw new Error(
399
+ "Dialog compound components must be used within a <Dialog> provider."
400
+ );
401
+ }
402
+ return context;
403
+ }
404
+ function Dialog({
405
+ children,
406
+ isOpen,
407
+ defaultOpen,
408
+ onOpenChange,
409
+ closeOnOverlayPress,
410
+ closeOnEscape,
411
+ modal,
412
+ role
413
+ }) {
414
+ const dialog = useDialog({
415
+ isOpen,
416
+ defaultOpen,
417
+ onOpenChange,
418
+ closeOnOverlayPress,
419
+ closeOnEscape,
420
+ modal,
421
+ role
422
+ });
423
+ return /* @__PURE__ */ jsx(DialogContext.Provider, { value: dialog, children });
424
+ }
425
+ function DialogTrigger({
426
+ children,
427
+ style,
428
+ ...rest
429
+ }) {
430
+ const { getTriggerProps } = useDialogContext();
431
+ const propGetterReturn = getTriggerProps();
432
+ const rnAccessibility = mapAccessibilityToRN(propGetterReturn.accessibility);
433
+ const handlePress = useCallback(() => {
434
+ propGetterReturn.onAction?.();
435
+ }, [propGetterReturn.onAction]);
436
+ return /* @__PURE__ */ jsx(
437
+ Pressable,
438
+ {
439
+ ...rnAccessibility,
440
+ ...rest,
441
+ onPress: handlePress,
442
+ style,
443
+ children
444
+ }
445
+ );
446
+ }
447
+ function DialogContent({
448
+ children,
449
+ style,
450
+ cardStyle,
451
+ animationType = "fade",
452
+ transparent = true,
453
+ ...rest
454
+ }) {
455
+ const { tokens: t, baseTokens: bt } = useTheme();
456
+ const { isOpen, close, ids, getContentProps } = useDialogContext();
457
+ const propGetterReturn = getContentProps();
458
+ const rnAccessibility = mapAccessibilityToRN(propGetterReturn.accessibility);
459
+ return /* @__PURE__ */ jsx(
460
+ Modal,
461
+ {
462
+ visible: isOpen,
463
+ transparent,
464
+ animationType,
465
+ onRequestClose: close,
466
+ supportedOrientations: ["portrait", "landscape"],
467
+ children: /* @__PURE__ */ jsx(
468
+ View,
469
+ {
470
+ ...rest,
471
+ style: [
472
+ {
473
+ flex: 1,
474
+ justifyContent: "center",
475
+ alignItems: "center",
476
+ backgroundColor: "rgba(0, 0, 0, 0.5)"
477
+ },
478
+ style
479
+ ],
480
+ children: /* @__PURE__ */ jsx(
481
+ View,
482
+ {
483
+ ...rnAccessibility,
484
+ nativeID: ids.content,
485
+ style: [
486
+ {
487
+ backgroundColor: t.entropixColorBgPrimary,
488
+ borderRadius: bt.entropixRadiusLg,
489
+ padding: bt.entropixSpacing6,
490
+ width: "90%",
491
+ maxWidth: 480,
492
+ shadowColor: "#000",
493
+ shadowOffset: { width: 0, height: 4 },
494
+ shadowOpacity: 0.15,
495
+ shadowRadius: 12,
496
+ elevation: 8
497
+ },
498
+ cardStyle
499
+ ],
500
+ children
501
+ }
502
+ )
503
+ }
504
+ )
505
+ }
506
+ );
507
+ }
508
+ function DialogTitle({ children, style, ...rest }) {
509
+ const { tokens: t, baseTokens: bt } = useTheme();
510
+ const { ids } = useDialogContext();
511
+ return /* @__PURE__ */ jsx(
512
+ Text,
513
+ {
514
+ ...rest,
515
+ nativeID: ids.title,
516
+ style: [
517
+ {
518
+ fontSize: 18,
519
+ fontWeight: "600",
520
+ color: t.entropixColorTextPrimary,
521
+ marginBottom: bt.entropixSpacing2
522
+ },
523
+ style
524
+ ],
525
+ accessibilityRole: "header",
526
+ children
527
+ }
528
+ );
529
+ }
530
+ function DialogDescription({
531
+ children,
532
+ style,
533
+ ...rest
534
+ }) {
535
+ const { tokens: t, baseTokens: bt } = useTheme();
536
+ const { ids } = useDialogContext();
537
+ return /* @__PURE__ */ jsx(
538
+ Text,
539
+ {
540
+ ...rest,
541
+ nativeID: ids.description,
542
+ style: [
543
+ {
544
+ fontSize: bt.entropixFontSizeSm,
545
+ color: t.entropixColorTextSecondary,
546
+ lineHeight: 20,
547
+ marginBottom: bt.entropixSpacing4
548
+ },
549
+ style
550
+ ],
551
+ children
552
+ }
553
+ );
554
+ }
555
+ function DialogClose({ children, style, ...rest }) {
556
+ const { tokens: t, baseTokens: bt } = useTheme();
557
+ const { getCloseProps } = useDialogContext();
558
+ const propGetterReturn = getCloseProps();
559
+ const rnAccessibility = mapAccessibilityToRN(propGetterReturn.accessibility);
560
+ const handlePress = useCallback(() => {
561
+ propGetterReturn.onAction?.();
562
+ }, [propGetterReturn.onAction]);
563
+ return /* @__PURE__ */ jsx(
564
+ Pressable,
565
+ {
566
+ ...rnAccessibility,
567
+ ...rest,
568
+ onPress: handlePress,
569
+ style: [
570
+ {
571
+ position: "absolute",
572
+ top: bt.entropixSpacing3,
573
+ right: bt.entropixSpacing3,
574
+ width: 32,
575
+ height: 32,
576
+ alignItems: "center",
577
+ justifyContent: "center",
578
+ borderRadius: bt.entropixRadiusSm
579
+ },
580
+ style
581
+ ],
582
+ accessibilityRole: "button",
583
+ children: children ?? /* @__PURE__ */ jsx(
584
+ Text,
585
+ {
586
+ style: {
587
+ fontSize: 16,
588
+ color: t.entropixColorTextSecondary
589
+ },
590
+ children: "\u2715"
591
+ }
592
+ )
593
+ }
594
+ );
595
+ }
596
+ function DialogOverlay({ style, testID }) {
597
+ const { isOpen, getOverlayProps } = useDialogContext();
598
+ const propGetterReturn = getOverlayProps();
599
+ const handlePress = useCallback(() => {
600
+ propGetterReturn.onAction?.();
601
+ }, [propGetterReturn.onAction]);
602
+ if (!isOpen) return null;
603
+ return /* @__PURE__ */ jsx(
604
+ Pressable,
605
+ {
606
+ testID,
607
+ accessible: false,
608
+ importantForAccessibility: "no",
609
+ onPress: propGetterReturn.onAction ? handlePress : void 0,
610
+ style: [
611
+ {
612
+ ...StyleSheet.absoluteFillObject,
613
+ backgroundColor: "rgba(0, 0, 0, 0.5)"
614
+ },
615
+ style
616
+ ]
617
+ }
618
+ );
619
+ }
620
+ var TabsContext = createContext(null);
621
+ function useTabsContext() {
622
+ const context = useContext(TabsContext);
623
+ if (!context) {
624
+ throw new Error(
625
+ "Tabs compound components must be used within a <Tabs> provider."
626
+ );
627
+ }
628
+ return context;
629
+ }
630
+ function Tabs({ children, style, ...options }) {
631
+ const tabs = useTabs(options);
632
+ return /* @__PURE__ */ jsx(TabsContext.Provider, { value: tabs, children: /* @__PURE__ */ jsx(View, { style, children }) });
633
+ }
634
+ function TabList({ children, style }) {
635
+ const { tokens: t, baseTokens: bt } = useTheme();
636
+ const { getTabListProps } = useTabsContext();
637
+ const propGetterReturn = getTabListProps();
638
+ const rnAccessibility = mapAccessibilityToRN(propGetterReturn.accessibility);
639
+ return /* @__PURE__ */ jsx(
640
+ View,
641
+ {
642
+ ...rnAccessibility,
643
+ style: [
644
+ {
645
+ flexDirection: "row",
646
+ gap: bt.entropixSpacing1,
647
+ borderBottomWidth: 1,
648
+ borderBottomColor: t.entropixColorBorderDefault
649
+ },
650
+ style
651
+ ],
652
+ children
653
+ }
654
+ );
655
+ }
656
+ function Tab({ value, children, style, textStyle, ...rest }) {
657
+ const { tokens: t, baseTokens: bt } = useTheme();
658
+ const { getTabProps, selectedKey } = useTabsContext();
659
+ const propGetterReturn = getTabProps(value);
660
+ const rnAccessibility = mapAccessibilityToRN(propGetterReturn.accessibility);
661
+ const isActive = selectedKey === value;
662
+ const isDisabled = propGetterReturn.accessibility.disabled === true;
663
+ const handlePress = useCallback(() => {
664
+ propGetterReturn.onAction?.();
665
+ }, [propGetterReturn.onAction]);
666
+ return /* @__PURE__ */ jsx(
667
+ Pressable,
668
+ {
669
+ ...rnAccessibility,
670
+ ...rest,
671
+ onPress: propGetterReturn.onAction ? handlePress : void 0,
672
+ style: [
673
+ {
674
+ paddingVertical: bt.entropixSpacing2,
675
+ paddingHorizontal: bt.entropixSpacing4,
676
+ borderBottomWidth: 2,
677
+ borderBottomColor: isActive ? t.entropixColorActionPrimaryDefault : "transparent"
678
+ },
679
+ isDisabled && { opacity: 0.5 },
680
+ style
681
+ ],
682
+ children: typeof children === "string" ? /* @__PURE__ */ jsx(
683
+ Text,
684
+ {
685
+ style: [
686
+ {
687
+ fontSize: bt.entropixFontSizeSm,
688
+ fontWeight: "500",
689
+ color: isActive ? t.entropixColorActionPrimaryDefault : t.entropixColorTextSecondary
690
+ },
691
+ textStyle
692
+ ],
693
+ children
694
+ }
695
+ ) : children
696
+ }
697
+ );
698
+ }
699
+ function TabPanel({ value, children, style }) {
700
+ const { baseTokens: bt } = useTheme();
701
+ const { getTabPanelProps, selectedKey } = useTabsContext();
702
+ const propGetterReturn = getTabPanelProps(value);
703
+ const rnAccessibility = mapAccessibilityToRN(propGetterReturn.accessibility);
704
+ if (selectedKey !== value) return null;
705
+ return /* @__PURE__ */ jsx(
706
+ View,
707
+ {
708
+ ...rnAccessibility,
709
+ style: [{ padding: bt.entropixSpacing4 }, style],
710
+ children
711
+ }
712
+ );
713
+ }
714
+ var AccordionContext = createContext(null);
715
+ function useAccordionContext() {
716
+ const context = useContext(AccordionContext);
717
+ if (!context) {
718
+ throw new Error(
719
+ "Accordion compound components must be used within an <Accordion> provider."
720
+ );
721
+ }
722
+ return context;
723
+ }
724
+ var AccordionItemContext = createContext(null);
725
+ function useAccordionItemContext() {
726
+ const context = useContext(AccordionItemContext);
727
+ if (context === null) {
728
+ throw new Error(
729
+ "AccordionTrigger and AccordionPanel must be used within an <AccordionItem>."
730
+ );
731
+ }
732
+ return context;
733
+ }
734
+ function Accordion({ children, style, ...options }) {
735
+ const { tokens: t, baseTokens: bt } = useTheme();
736
+ const accordion = useAccordion(options);
737
+ return /* @__PURE__ */ jsx(AccordionContext.Provider, { value: accordion, children: /* @__PURE__ */ jsx(
738
+ View,
739
+ {
740
+ style: [
741
+ {
742
+ borderWidth: 1,
743
+ borderColor: t.entropixColorBorderDefault,
744
+ borderRadius: bt.entropixRadiusLg,
745
+ overflow: "hidden"
746
+ },
747
+ style
748
+ ],
749
+ children
750
+ }
751
+ ) });
752
+ }
753
+ function AccordionItem({
754
+ value,
755
+ isLast = false,
756
+ children,
757
+ style
758
+ }) {
759
+ const { tokens: t } = useTheme();
760
+ return /* @__PURE__ */ jsx(AccordionItemContext.Provider, { value, children: /* @__PURE__ */ jsx(
761
+ View,
762
+ {
763
+ style: [
764
+ {
765
+ borderBottomWidth: isLast ? 0 : 1,
766
+ borderBottomColor: t.entropixColorBorderDefault
767
+ },
768
+ style
769
+ ],
770
+ children
771
+ }
772
+ ) });
773
+ }
774
+ function AccordionTrigger({
775
+ children,
776
+ style,
777
+ textStyle,
778
+ ...rest
779
+ }) {
780
+ const { tokens: t, baseTokens: bt } = useTheme();
781
+ const itemKey = useAccordionItemContext();
782
+ const { getItemTriggerProps, isExpanded } = useAccordionContext();
783
+ const propGetterReturn = getItemTriggerProps(itemKey);
784
+ const rnAccessibility = mapAccessibilityToRN(propGetterReturn.accessibility);
785
+ const expanded = isExpanded(itemKey);
786
+ const handlePress = useCallback(() => {
787
+ propGetterReturn.onAction?.();
788
+ }, [propGetterReturn.onAction]);
789
+ return /* @__PURE__ */ jsxs(
790
+ Pressable,
791
+ {
792
+ ...rnAccessibility,
793
+ ...rest,
794
+ onPress: propGetterReturn.onAction ? handlePress : void 0,
795
+ style: [
796
+ {
797
+ flexDirection: "row",
798
+ alignItems: "center",
799
+ justifyContent: "space-between",
800
+ paddingVertical: bt.entropixSpacing4,
801
+ paddingHorizontal: bt.entropixSpacing4
802
+ },
803
+ style
804
+ ],
805
+ children: [
806
+ typeof children === "string" ? /* @__PURE__ */ jsx(
807
+ Text,
808
+ {
809
+ style: [
810
+ {
811
+ fontSize: bt.entropixFontSizeSm,
812
+ fontWeight: "500",
813
+ color: t.entropixColorTextPrimary,
814
+ flex: 1
815
+ },
816
+ textStyle
817
+ ],
818
+ children
819
+ }
820
+ ) : children,
821
+ /* @__PURE__ */ jsx(
822
+ Text,
823
+ {
824
+ style: {
825
+ fontSize: 12,
826
+ color: t.entropixColorTextSecondary,
827
+ marginLeft: bt.entropixSpacing2
828
+ },
829
+ children: expanded ? "\u2212" : "+"
830
+ }
831
+ )
832
+ ]
833
+ }
834
+ );
835
+ }
836
+ function AccordionPanel({ children, style }) {
837
+ const { baseTokens: bt } = useTheme();
838
+ const itemKey = useAccordionItemContext();
839
+ const { getItemPanelProps, isExpanded } = useAccordionContext();
840
+ const propGetterReturn = getItemPanelProps(itemKey);
841
+ const rnAccessibility = mapAccessibilityToRN(propGetterReturn.accessibility);
842
+ if (!isExpanded(itemKey)) return null;
843
+ return /* @__PURE__ */ jsx(
844
+ View,
845
+ {
846
+ ...rnAccessibility,
847
+ style: [
848
+ {
849
+ paddingHorizontal: bt.entropixSpacing4,
850
+ paddingBottom: bt.entropixSpacing4
851
+ },
852
+ style
853
+ ],
854
+ children
855
+ }
856
+ );
857
+ }
858
+ var MenuContext = createContext(null);
859
+ function useMenuContext() {
860
+ const context = useContext(MenuContext);
861
+ if (!context) {
862
+ throw new Error(
863
+ "Menu compound components must be used within a <Menu> provider."
864
+ );
865
+ }
866
+ return context;
867
+ }
868
+ function Menu({ children, ...options }) {
869
+ const menu = useMenu(options);
870
+ return /* @__PURE__ */ jsx(MenuContext.Provider, { value: menu, children });
871
+ }
872
+ function MenuTrigger({ children, style, ...rest }) {
873
+ const { getTriggerProps } = useMenuContext();
874
+ const propGetterReturn = getTriggerProps();
875
+ const rnAccessibility = mapAccessibilityToRN(propGetterReturn.accessibility);
876
+ const handlePress = useCallback(() => {
877
+ propGetterReturn.onAction?.();
878
+ }, [propGetterReturn.onAction]);
879
+ return /* @__PURE__ */ jsx(
880
+ Pressable,
881
+ {
882
+ ...rnAccessibility,
883
+ ...rest,
884
+ onPress: handlePress,
885
+ style,
886
+ children
887
+ }
888
+ );
889
+ }
890
+ function MenuContent({ children, style, testID }) {
891
+ const { tokens: t, baseTokens: bt } = useTheme();
892
+ const { isOpen, getMenuProps } = useMenuContext();
893
+ const propGetterReturn = getMenuProps();
894
+ const rnAccessibility = mapAccessibilityToRN(propGetterReturn.accessibility);
895
+ if (!isOpen) return null;
896
+ return /* @__PURE__ */ jsx(
897
+ View,
898
+ {
899
+ ...rnAccessibility,
900
+ testID,
901
+ style: [
902
+ {
903
+ minWidth: 160,
904
+ padding: bt.entropixSpacing1,
905
+ backgroundColor: t.entropixColorBgPrimary,
906
+ borderWidth: 1,
907
+ borderColor: t.entropixColorBorderDefault,
908
+ borderRadius: bt.entropixRadiusMd,
909
+ shadowColor: "#000",
910
+ shadowOffset: { width: 0, height: 2 },
911
+ shadowOpacity: 0.1,
912
+ shadowRadius: 8,
913
+ elevation: 4
914
+ },
915
+ style
916
+ ],
917
+ children
918
+ }
919
+ );
920
+ }
921
+ function wrapStringChildren(children, style) {
922
+ if (typeof children === "string" || typeof children === "number") {
923
+ return /* @__PURE__ */ jsx(Text, { style, children });
924
+ }
925
+ return children;
926
+ }
927
+ function MenuItem({
928
+ index,
929
+ onSelect,
930
+ disabled,
931
+ children,
932
+ style,
933
+ textStyle,
934
+ ...rest
935
+ }) {
936
+ const { tokens: t, baseTokens: bt } = useTheme();
937
+ const { getItemProps } = useMenuContext();
938
+ const propGetterReturn = getItemProps(index, { onSelect, disabled });
939
+ const rnAccessibility = mapAccessibilityToRN(propGetterReturn.accessibility);
940
+ const handlePress = useCallback(() => {
941
+ propGetterReturn.onAction?.();
942
+ }, [propGetterReturn.onAction]);
943
+ return /* @__PURE__ */ jsx(
944
+ Pressable,
945
+ {
946
+ ...rnAccessibility,
947
+ ...rest,
948
+ disabled,
949
+ onPress: propGetterReturn.onAction ? handlePress : void 0,
950
+ style: [
951
+ {
952
+ flexDirection: "row",
953
+ alignItems: "center",
954
+ paddingVertical: bt.entropixSpacing2,
955
+ paddingHorizontal: bt.entropixSpacing3,
956
+ borderRadius: bt.entropixRadiusSm,
957
+ opacity: disabled ? 0.5 : 1
958
+ },
959
+ style
960
+ ],
961
+ children: wrapStringChildren(children, {
962
+ fontSize: bt.entropixFontSizeSm,
963
+ color: t.entropixColorTextPrimary,
964
+ ...textStyle
965
+ })
966
+ }
967
+ );
968
+ }
969
+ var BREAKPOINTS = {
970
+ sm: 640,
971
+ md: 768,
972
+ lg: 1024,
973
+ xl: 1280,
974
+ "2xl": 1536
975
+ };
976
+ var BREAKPOINT_ORDER = ["base", "sm", "md", "lg", "xl", "2xl"];
977
+ function useBreakpoint() {
978
+ const getBreakpoint = useCallback(() => {
979
+ const { width } = Dimensions.get("window");
980
+ if (width >= BREAKPOINTS["2xl"]) return "2xl";
981
+ if (width >= BREAKPOINTS.xl) return "xl";
982
+ if (width >= BREAKPOINTS.lg) return "lg";
983
+ if (width >= BREAKPOINTS.md) return "md";
984
+ if (width >= BREAKPOINTS.sm) return "sm";
985
+ return "base";
986
+ }, []);
987
+ const [breakpoint, setBreakpoint] = useState(getBreakpoint);
988
+ useEffect(() => {
989
+ const subscription = Dimensions.addEventListener("change", ({ window }) => {
990
+ const width = window.width;
991
+ let next = "base";
992
+ if (width >= BREAKPOINTS["2xl"]) next = "2xl";
993
+ else if (width >= BREAKPOINTS.xl) next = "xl";
994
+ else if (width >= BREAKPOINTS.lg) next = "lg";
995
+ else if (width >= BREAKPOINTS.md) next = "md";
996
+ else if (width >= BREAKPOINTS.sm) next = "sm";
997
+ setBreakpoint((prev) => prev !== next ? next : prev);
998
+ });
999
+ return () => subscription.remove();
1000
+ }, []);
1001
+ return breakpoint;
1002
+ }
1003
+ function useBreakpointValue(breakpoint) {
1004
+ const current = useBreakpoint();
1005
+ const currentIndex = BREAKPOINT_ORDER.indexOf(current);
1006
+ const targetIndex = BREAKPOINT_ORDER.indexOf(breakpoint);
1007
+ return currentIndex >= targetIndex;
1008
+ }
1009
+ function useScreenDimensions() {
1010
+ const [dimensions, setDimensions] = useState(() => Dimensions.get("window"));
1011
+ useEffect(() => {
1012
+ const subscription = Dimensions.addEventListener("change", ({ window }) => {
1013
+ setDimensions(window);
1014
+ });
1015
+ return () => subscription.remove();
1016
+ }, []);
1017
+ return { width: dimensions.width, height: dimensions.height };
1018
+ }
1019
+ function Stack({
1020
+ gap,
1021
+ align,
1022
+ fullWidth,
1023
+ style,
1024
+ children,
1025
+ ...rest
1026
+ }) {
1027
+ const { baseTokens: bt } = useTheme();
1028
+ const gapValue = getGapValue(gap, bt);
1029
+ const alignMap = {
1030
+ start: "flex-start",
1031
+ center: "center",
1032
+ end: "flex-end",
1033
+ stretch: "stretch"
1034
+ };
1035
+ return /* @__PURE__ */ jsx(
1036
+ View,
1037
+ {
1038
+ style: [
1039
+ { flexDirection: "column" },
1040
+ gapValue !== void 0 && { gap: gapValue },
1041
+ gapValue === void 0 && { gap: bt.entropixSpaceLayoutStack },
1042
+ align && { alignItems: alignMap[align] },
1043
+ fullWidth && { width: "100%" },
1044
+ style
1045
+ ],
1046
+ ...rest,
1047
+ children
1048
+ }
1049
+ );
1050
+ }
1051
+ function getGapValue(gap, bt) {
1052
+ if (!gap) return void 0;
1053
+ switch (gap) {
1054
+ case "none":
1055
+ return 0;
1056
+ case "xs":
1057
+ return bt.entropixSpacing1;
1058
+ case "sm":
1059
+ return bt.entropixSpacing2;
1060
+ case "md":
1061
+ return bt.entropixSpacing4;
1062
+ case "lg":
1063
+ return bt.entropixSpacing6;
1064
+ case "xl":
1065
+ return bt.entropixSpacing8;
1066
+ case "2xl":
1067
+ return bt.entropixSpacing12;
1068
+ }
1069
+ }
1070
+ function Inline({
1071
+ gap,
1072
+ align,
1073
+ justify,
1074
+ wrap,
1075
+ style,
1076
+ children,
1077
+ ...rest
1078
+ }) {
1079
+ const { baseTokens: bt } = useTheme();
1080
+ const gapValue = getGapValue2(gap, bt);
1081
+ const alignMap = {
1082
+ start: "flex-start",
1083
+ center: "center",
1084
+ end: "flex-end",
1085
+ stretch: "stretch",
1086
+ baseline: "baseline"
1087
+ };
1088
+ const justifyMap = {
1089
+ start: "flex-start",
1090
+ center: "center",
1091
+ end: "flex-end",
1092
+ between: "space-between",
1093
+ around: "space-around"
1094
+ };
1095
+ return /* @__PURE__ */ jsx(
1096
+ View,
1097
+ {
1098
+ style: [
1099
+ {
1100
+ flexDirection: "row",
1101
+ alignItems: "center"
1102
+ },
1103
+ gapValue !== void 0 && { gap: gapValue },
1104
+ gapValue === void 0 && { gap: bt.entropixSpaceLayoutInline },
1105
+ align && { alignItems: alignMap[align] },
1106
+ justify && { justifyContent: justifyMap[justify] },
1107
+ wrap && { flexWrap: "wrap" },
1108
+ style
1109
+ ],
1110
+ ...rest,
1111
+ children
1112
+ }
1113
+ );
1114
+ }
1115
+ function getGapValue2(gap, bt) {
1116
+ if (!gap) return void 0;
1117
+ switch (gap) {
1118
+ case "none":
1119
+ return 0;
1120
+ case "xs":
1121
+ return bt.entropixSpacing1;
1122
+ case "sm":
1123
+ return bt.entropixSpacing2;
1124
+ case "md":
1125
+ return bt.entropixSpacing4;
1126
+ case "lg":
1127
+ return bt.entropixSpacing6;
1128
+ case "xl":
1129
+ return bt.entropixSpacing8;
1130
+ case "2xl":
1131
+ return bt.entropixSpacing12;
1132
+ }
1133
+ }
1134
+ var maxWidthMap = {
1135
+ xs: 480,
1136
+ sm: 640,
1137
+ md: 768,
1138
+ lg: 1024,
1139
+ xl: 1280,
1140
+ full: void 0
1141
+ };
1142
+ function Container({
1143
+ maxWidth = "lg",
1144
+ center,
1145
+ style,
1146
+ children,
1147
+ ...rest
1148
+ }) {
1149
+ const { baseTokens: bt } = useTheme();
1150
+ const breakpoint = useBreakpoint();
1151
+ const maxW = maxWidthMap[maxWidth];
1152
+ let pageMargin = bt.entropixSpaceLayoutPageMargin;
1153
+ if (breakpoint === "lg" || breakpoint === "xl" || breakpoint === "2xl") {
1154
+ pageMargin = bt.entropixSpaceLayoutPageMarginLg;
1155
+ } else if (breakpoint === "md") {
1156
+ pageMargin = bt.entropixSpaceLayoutPageMarginMd;
1157
+ }
1158
+ return /* @__PURE__ */ jsx(
1159
+ View,
1160
+ {
1161
+ style: [
1162
+ {
1163
+ width: "100%",
1164
+ paddingHorizontal: pageMargin
1165
+ },
1166
+ maxW !== void 0 && { maxWidth: maxW, alignSelf: "center" },
1167
+ center && { alignItems: "center" },
1168
+ style
1169
+ ],
1170
+ ...rest,
1171
+ children
1172
+ }
1173
+ );
1174
+ }
1175
+ function Divider({
1176
+ orientation = "horizontal",
1177
+ spacing,
1178
+ style,
1179
+ ...rest
1180
+ }) {
1181
+ const { tokens: t, baseTokens: bt } = useTheme();
1182
+ const spacingMap = {
1183
+ sm: bt.entropixSpacing2,
1184
+ md: bt.entropixSpacing4,
1185
+ lg: bt.entropixSpacing6
1186
+ };
1187
+ const spacingValue = spacing ? spacingMap[spacing] : 0;
1188
+ const isVertical = orientation === "vertical";
1189
+ const dividerStyle = isVertical ? {
1190
+ width: 1,
1191
+ alignSelf: "stretch",
1192
+ backgroundColor: t.entropixColorBorderDefault,
1193
+ marginHorizontal: spacingValue
1194
+ } : {
1195
+ height: 1,
1196
+ width: "100%",
1197
+ backgroundColor: t.entropixColorBorderDefault,
1198
+ marginVertical: spacingValue
1199
+ };
1200
+ return /* @__PURE__ */ jsx(
1201
+ View,
1202
+ {
1203
+ accessibilityRole: isVertical ? "none" : void 0,
1204
+ style: [dividerStyle, style],
1205
+ ...rest
1206
+ }
1207
+ );
1208
+ }
1209
+
1210
+ export { Accordion, AccordionItem, AccordionPanel, AccordionTrigger, BREAKPOINTS, Button, Container, Dialog, DialogClose, DialogContent, DialogDescription, DialogOverlay, DialogTitle, DialogTrigger, Divider, EntropixProvider, Inline, Menu, MenuContent, MenuItem, MenuTrigger, Stack, Switch, Tab, TabList, TabPanel, Tabs, Toggle, mapAccessibilityToRN, useBreakpoint, useBreakpointValue, useScreenDimensions, useTheme };
1211
+ //# sourceMappingURL=index.js.map
1212
+ //# sourceMappingURL=index.js.map