@vellira-ui/react-native 2.41.0 → 2.43.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.
Files changed (3) hide show
  1. package/README.md +17 -13
  2. package/dist/index.js +619 -300
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,8 +1,133 @@
1
1
  import { Children, cloneElement, createContext, forwardRef, isValidElement, useCallback, useContext, useEffect, useId, useMemo, useRef, useState } from "react";
2
2
  import { Check, ChevronDown, Close, Search } from "@vellira-ui/icons";
3
- import { AccessibilityInfo, ActivityIndicator, Animated, Dimensions, FlatList, Modal as Modal$1, Pressable, ScrollView, StyleSheet, Text, TextInput, View, findNodeHandle, useWindowDimensions } from "react-native";
3
+ import { AccessibilityInfo, ActivityIndicator, Animated, Dimensions, Easing, FlatList, Modal as Modal$1, Platform, Pressable, ScrollView, StyleSheet, Text, TextInput, View, findNodeHandle, useWindowDimensions } from "react-native";
4
4
  import { darkTheme, highContrastTheme, lightTheme } from "@vellira-ui/tokens";
5
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ //#region src/managers/FloatingManager/useNativeFloatingPosition.ts
7
+ const safePadding = 12;
8
+ function useNativeFloatingPosition(placement = "top", offset = 8) {
9
+ const [position, setPosition] = useState({
10
+ top: 0,
11
+ left: 0
12
+ });
13
+ const floatingSizeRef = useRef({
14
+ width: 0,
15
+ height: 0
16
+ });
17
+ const lastTriggerRef = useRef(null);
18
+ const clamp = useCallback((value, min, max) => {
19
+ return Math.min(Math.max(value, min), Math.max(min, max));
20
+ }, []);
21
+ const calculatePosition = useCallback((triggerRect, size) => {
22
+ const { width: screenWidth, height: screenHeight } = Dimensions.get("window");
23
+ const [side, align = "center"] = placement.split("-");
24
+ const horizontalTop = side === "bottom" ? triggerRect.y + triggerRect.height + offset : triggerRect.y - size.height - offset;
25
+ const verticalTop = align === "start" ? triggerRect.y : align === "end" ? triggerRect.y + triggerRect.height - size.height : triggerRect.y + triggerRect.height / 2 - size.height / 2;
26
+ const horizontalLeft = align === "start" ? triggerRect.x : align === "end" ? triggerRect.x + triggerRect.width - size.width : triggerRect.x + triggerRect.width / 2 - size.width / 2;
27
+ const verticalLeft = side === "right" ? triggerRect.x + triggerRect.width + offset : triggerRect.x - size.width - offset;
28
+ const rawPosition = side === "left" || side === "right" ? {
29
+ top: verticalTop,
30
+ left: verticalLeft
31
+ } : {
32
+ top: horizontalTop,
33
+ left: horizontalLeft
34
+ };
35
+ return {
36
+ top: clamp(rawPosition.top, safePadding, screenHeight - size.height - safePadding),
37
+ left: clamp(rawPosition.left, safePadding, screenWidth - size.width - safePadding)
38
+ };
39
+ }, [
40
+ placement,
41
+ offset,
42
+ clamp
43
+ ]);
44
+ const updatePosition = useCallback((triggerRef, measuredSize = floatingSizeRef.current) => {
45
+ lastTriggerRef.current = triggerRef;
46
+ const node = triggerRef.current;
47
+ if (!node || typeof node.measureInWindow !== "function") {
48
+ setPosition({
49
+ top: 0,
50
+ left: 0
51
+ });
52
+ return;
53
+ }
54
+ node.measureInWindow((x, y, width, height) => {
55
+ setPosition(calculatePosition({
56
+ x,
57
+ y,
58
+ width,
59
+ height
60
+ }, measuredSize));
61
+ });
62
+ }, [calculatePosition]);
63
+ return {
64
+ position,
65
+ updatePosition,
66
+ onFloatingLayout: useCallback((event) => {
67
+ const { width, height } = event.nativeEvent.layout;
68
+ const nextSize = {
69
+ width,
70
+ height
71
+ };
72
+ floatingSizeRef.current = nextSize;
73
+ if (lastTriggerRef.current) updatePosition(lastTriggerRef.current, nextSize);
74
+ }, [updatePosition])
75
+ };
76
+ }
77
+ //#endregion
78
+ //#region src/managers/OverlayStack/NativeOverlayStack.ts
79
+ let stack = [];
80
+ const nativeOverlayStackStore = {
81
+ add(id) {
82
+ stack = stack.filter((item) => item !== id);
83
+ stack.push(id);
84
+ },
85
+ remove(id) {
86
+ stack = stack.filter((item) => item !== id);
87
+ },
88
+ isTop(id) {
89
+ return stack[stack.length - 1] === id;
90
+ }
91
+ };
92
+ //#endregion
93
+ //#region src/managers/OverlayStack/useNativeOverlayStack.ts
94
+ const useNativeOverlayStack = ({ id, visible }) => {
95
+ useEffect(() => {
96
+ if (!visible) return;
97
+ nativeOverlayStackStore.add(id);
98
+ return () => {
99
+ nativeOverlayStackStore.remove(id);
100
+ };
101
+ }, [id, visible]);
102
+ return { isTopOverlay: useCallback(() => nativeOverlayStackStore.isTop(id), [id]) };
103
+ };
104
+ //#endregion
105
+ //#region src/hooks/behavior/overlay/useOverlayStack.ts
106
+ const useOverlayStack = ({ active, id }) => useNativeOverlayStack({
107
+ id,
108
+ visible: active
109
+ });
110
+ //#endregion
111
+ //#region src/hooks/behavior/overlay/useOverlayDismiss.ts
112
+ const useOverlayDismiss = ({ active, closeOnOutsidePress = true, id, requestClose }) => {
113
+ const { isTopOverlay } = useOverlayStack({
114
+ active,
115
+ id
116
+ });
117
+ const requestTopClose = useCallback(() => {
118
+ if (!isTopOverlay()) return;
119
+ requestClose();
120
+ }, [isTopOverlay, requestClose]);
121
+ return {
122
+ isTopOverlay,
123
+ requestClose: requestTopClose,
124
+ requestOutsideClose: useCallback(() => {
125
+ if (!closeOnOutsidePress) return;
126
+ requestTopClose();
127
+ }, [closeOnOutsidePress, requestTopClose])
128
+ };
129
+ };
130
+ //#endregion
6
131
  //#region src/hooks/useControllableState.ts
7
132
  const useControllableState = ({ value, defaultValue, onChange }) => {
8
133
  const [internalValue, setInternalValue] = useState(defaultValue);
@@ -461,14 +586,19 @@ const createStyles$21 = (theme) => StyleSheet.create({
461
586
  borderTopLeftRadius: theme.tokens.radius.lg,
462
587
  borderTopRightRadius: theme.tokens.radius.lg,
463
588
  borderWidth: 1,
464
- shadowColor: "#000000",
465
- shadowOffset: {
466
- width: 0,
467
- height: -4
468
- },
469
- shadowOpacity: .24,
470
- shadowRadius: 16,
471
- elevation: 12
589
+ ...Platform.select({
590
+ web: { boxShadow: "0 -4px 16px rgba(0, 0, 0, 0.24)" },
591
+ default: {
592
+ shadowColor: "#000000",
593
+ shadowOffset: {
594
+ width: 0,
595
+ height: -4
596
+ },
597
+ shadowOpacity: .24,
598
+ shadowRadius: 16,
599
+ elevation: 12
600
+ }
601
+ })
472
602
  },
473
603
  sheetMenu: {
474
604
  width: "100%",
@@ -515,9 +645,12 @@ const createStyles$21 = (theme) => StyleSheet.create({
515
645
  });
516
646
  //#endregion
517
647
  //#region src/components/Dropdown/Content/DropdownContent.tsx
518
- function DropdownContent({ isOpen, children, onClose, contentStyle, accessibilityLabel, presentation, searchable = false, searchValue = "", searchPlaceholder = "Search actions...", searchAccessibilityLabel, onSearchChange }) {
648
+ const nativePointerEventsBoxNone$1 = Platform.OS === "web" ? void 0 : { pointerEvents: "box-none" };
649
+ const webPointerEventsBoxNone$1 = Platform.OS === "web" ? { pointerEvents: "box-none" } : void 0;
650
+ function DropdownContent({ isOpen, children, onClose, color = "primary", contentStyle, accessibilityLabel, presentation, searchable = false, searchValue = "", searchPlaceholder = "Search actions...", searchAccessibilityLabel, onSearchChange }) {
519
651
  const { theme } = useTheme();
520
652
  const styles = useThemeStyles(createStyles$21);
653
+ const colorPalette = theme.components.dropdown[color];
521
654
  const isSheet = presentation === "sheet";
522
655
  const animation = useRef(new Animated.Value(isOpen ? 1 : 0)).current;
523
656
  const [reduceMotion, setReduceMotion] = useState(false);
@@ -541,7 +674,7 @@ function DropdownContent({ isOpen, children, onClose, contentStyle, accessibilit
541
674
  Animated.timing(animation, {
542
675
  toValue: 1,
543
676
  duration: isSheet ? 220 : 160,
544
- useNativeDriver: true
677
+ useNativeDriver: Platform.OS !== "web"
545
678
  }).start();
546
679
  }, [
547
680
  animation,
@@ -575,8 +708,12 @@ function DropdownContent({ isOpen, children, onClose, contentStyle, accessibilit
575
708
  children: /* @__PURE__ */ jsxs(View, {
576
709
  style: [styles.modalRoot, styles[presentation]],
577
710
  children: [/* @__PURE__ */ jsx(Animated.View, {
578
- pointerEvents: "box-none",
579
- style: [styles.backdrop, backdropAnimatedStyle],
711
+ ...nativePointerEventsBoxNone$1,
712
+ style: [
713
+ styles.backdrop,
714
+ backdropAnimatedStyle,
715
+ webPointerEventsBoxNone$1
716
+ ],
580
717
  children: /* @__PURE__ */ jsx(Pressable, {
581
718
  accessibilityRole: "button",
582
719
  accessibilityLabel: "Close menu",
@@ -589,6 +726,7 @@ function DropdownContent({ isOpen, children, onClose, contentStyle, accessibilit
589
726
  style: [
590
727
  styles.menu,
591
728
  styles[`${presentation}Menu`],
729
+ { borderColor: colorPalette.content.border },
592
730
  contentStyle,
593
731
  menuAnimatedStyle
594
732
  ],
@@ -619,125 +757,6 @@ function DropdownContent({ isOpen, children, onClose, contentStyle, accessibilit
619
757
  }
620
758
  DropdownContent.displayName = "DropdownContent";
621
759
  //#endregion
622
- //#region src/managers/FloatingManager/useNativeFloatingPosition.ts
623
- const safePadding = 12;
624
- function useNativeFloatingPosition(placement = "top", offset = 8) {
625
- const [position, setPosition] = useState({
626
- top: 0,
627
- left: 0
628
- });
629
- const floatingSizeRef = useRef({
630
- width: 0,
631
- height: 0
632
- });
633
- const lastTriggerRef = useRef(null);
634
- const clamp = useCallback((value, min, max) => {
635
- return Math.min(Math.max(value, min), Math.max(min, max));
636
- }, []);
637
- const calculatePosition = useCallback((triggerRect, size) => {
638
- const { width: screenWidth, height: screenHeight } = Dimensions.get("window");
639
- const [side, align = "center"] = placement.split("-");
640
- const horizontalTop = side === "bottom" ? triggerRect.y + triggerRect.height + offset : triggerRect.y - size.height - offset;
641
- const verticalTop = align === "start" ? triggerRect.y : align === "end" ? triggerRect.y + triggerRect.height - size.height : triggerRect.y + triggerRect.height / 2 - size.height / 2;
642
- const horizontalLeft = align === "start" ? triggerRect.x : align === "end" ? triggerRect.x + triggerRect.width - size.width : triggerRect.x + triggerRect.width / 2 - size.width / 2;
643
- const verticalLeft = side === "right" ? triggerRect.x + triggerRect.width + offset : triggerRect.x - size.width - offset;
644
- const rawPosition = side === "left" || side === "right" ? {
645
- top: verticalTop,
646
- left: verticalLeft
647
- } : {
648
- top: horizontalTop,
649
- left: horizontalLeft
650
- };
651
- return {
652
- top: clamp(rawPosition.top, safePadding, screenHeight - size.height - safePadding),
653
- left: clamp(rawPosition.left, safePadding, screenWidth - size.width - safePadding)
654
- };
655
- }, [
656
- placement,
657
- offset,
658
- clamp
659
- ]);
660
- const updatePosition = useCallback((triggerRef, measuredSize = floatingSizeRef.current) => {
661
- lastTriggerRef.current = triggerRef;
662
- const node = triggerRef.current;
663
- if (!node || typeof node.measureInWindow !== "function") {
664
- setPosition({
665
- top: 0,
666
- left: 0
667
- });
668
- return;
669
- }
670
- node.measureInWindow((x, y, width, height) => {
671
- setPosition(calculatePosition({
672
- x,
673
- y,
674
- width,
675
- height
676
- }, measuredSize));
677
- });
678
- }, [calculatePosition]);
679
- return {
680
- position,
681
- updatePosition,
682
- onFloatingLayout: useCallback((event) => {
683
- const { width, height } = event.nativeEvent.layout;
684
- const nextSize = {
685
- width,
686
- height
687
- };
688
- floatingSizeRef.current = nextSize;
689
- if (lastTriggerRef.current) updatePosition(lastTriggerRef.current, nextSize);
690
- }, [updatePosition])
691
- };
692
- }
693
- //#endregion
694
- //#region src/managers/OverlayStack/NativeOverlayStack.ts
695
- let stack = [];
696
- const nativeOverlayStackStore = {
697
- add(id) {
698
- stack = stack.filter((item) => item !== id);
699
- stack.push(id);
700
- },
701
- remove(id) {
702
- stack = stack.filter((item) => item !== id);
703
- },
704
- isTop(id) {
705
- return stack[stack.length - 1] === id;
706
- }
707
- };
708
- //#endregion
709
- //#region src/managers/OverlayStack/useNativeOverlayStack.ts
710
- const useNativeOverlayStack = ({ id, visible }) => {
711
- useEffect(() => {
712
- if (!visible) return;
713
- nativeOverlayStackStore.add(id);
714
- return () => {
715
- nativeOverlayStackStore.remove(id);
716
- };
717
- }, [id, visible]);
718
- return { isTopOverlay: useCallback(() => nativeOverlayStackStore.isTop(id), [id]) };
719
- };
720
- //#endregion
721
- //#region src/managers/OverlayStack/useNativeDismiss.ts
722
- const useNativeDismiss = ({ id, visible, closeOnOutsidePress = true, onClose }) => {
723
- const { isTopOverlay } = useNativeOverlayStack({
724
- id,
725
- visible
726
- });
727
- const requestClose = useCallback(() => {
728
- if (!isTopOverlay()) return;
729
- onClose();
730
- }, [isTopOverlay, onClose]);
731
- return {
732
- isTopOverlay,
733
- requestClose,
734
- requestOutsideClose: useCallback(() => {
735
- if (!closeOnOutsidePress) return;
736
- requestClose();
737
- }, [closeOnOutsidePress, requestClose])
738
- };
739
- };
740
- //#endregion
741
760
  //#region src/components/Dropdown/Group/DropdownGroup.styles.ts
742
761
  const createStyles$20 = (theme) => StyleSheet.create({ groupLabel: {
743
762
  paddingHorizontal: theme.tokens.spacing[4],
@@ -875,10 +894,6 @@ const createStyles$19 = (theme) => StyleSheet.create({
875
894
  backgroundColor: theme.components.dropdown.item.default.bg,
876
895
  borderRadius: theme.tokens.radius.sm
877
896
  },
878
- itemPressed: { backgroundColor: theme.components.dropdown.item.pressed.bg },
879
- itemDisabled: { backgroundColor: theme.components.dropdown.item.disabled.bg },
880
- itemDanger: { backgroundColor: theme.components.dropdown.item.danger.default.bg },
881
- itemDangerPressed: { backgroundColor: theme.components.dropdown.item.danger.active.bg },
882
897
  itemText: {
883
898
  flex: 1,
884
899
  minWidth: 0,
@@ -886,17 +901,14 @@ const createStyles$19 = (theme) => StyleSheet.create({
886
901
  fontFamily: theme.tokens.typography.family.regular,
887
902
  fontSize: theme.tokens.typography.size.md,
888
903
  lineHeight: theme.tokens.typography.lineHeight.md
889
- },
890
- itemTextPressed: { color: theme.components.dropdown.item.pressed.fg },
891
- itemTextDisabled: { color: theme.components.dropdown.item.disabled.fg },
892
- itemTextDanger: { color: theme.components.dropdown.item.danger.default.fg },
893
- itemTextDangerPressed: { color: theme.components.dropdown.item.danger.active.fg }
904
+ }
894
905
  });
895
906
  //#endregion
896
907
  //#region src/components/Dropdown/Item/DropdownItem.tsx
897
- function DropdownItem({ label, value, icon, danger = false, disabled = false, textWrap = "truncate", itemStyle, textStyle, onSelect }) {
908
+ function DropdownItem({ label, value, color = "primary", icon, danger = false, disabled = false, textWrap = "truncate", itemStyle, textStyle, onSelect }) {
898
909
  const { theme } = useTheme();
899
910
  const styles = useThemeStyles(createStyles$19);
911
+ const colorPalette = theme.components.dropdown[color];
900
912
  const renderColoredNode = (node, color) => {
901
913
  if (!isValidElement(node)) return node;
902
914
  return cloneElement(node, { color });
@@ -904,12 +916,12 @@ function DropdownItem({ label, value, icon, danger = false, disabled = false, te
904
916
  const getContentColor = (pressed) => {
905
917
  if (disabled) return theme.components.dropdown.item.disabled.fg;
906
918
  if (danger) return pressed ? theme.components.dropdown.item.danger.active.fg : theme.components.dropdown.item.danger.default.fg;
907
- return pressed ? theme.components.dropdown.item.pressed.fg : theme.components.dropdown.item.default.fg;
919
+ return pressed ? colorPalette.item.pressed.fg : theme.components.dropdown.item.default.fg;
908
920
  };
909
921
  const getBackgroundColor = (pressed) => {
910
922
  if (disabled) return theme.components.dropdown.item.disabled.bg;
911
923
  if (danger) return pressed ? theme.components.dropdown.item.danger.active.bg : theme.components.dropdown.item.danger.default.bg;
912
- return pressed ? theme.components.dropdown.item.pressed.bg : theme.components.dropdown.item.default.bg;
924
+ return pressed ? colorPalette.item.pressed.bg : theme.components.dropdown.item.default.bg;
913
925
  };
914
926
  const accessibilityLabel = typeof label === "string" ? label : value;
915
927
  const numberOfLines = textWrap === "wrap" ? void 0 : 1;
@@ -1009,10 +1021,6 @@ const createStyles$17 = (theme) => StyleSheet.create({
1009
1021
  minHeight: 52,
1010
1022
  padding: 0
1011
1023
  },
1012
- triggerPressed: {
1013
- backgroundColor: theme.components.dropdown.trigger.hover.bg,
1014
- borderColor: theme.components.dropdown.trigger.hover.border
1015
- },
1016
1024
  triggerDisabled: {
1017
1025
  backgroundColor: theme.components.dropdown.trigger.disabled.bg,
1018
1026
  borderColor: theme.components.dropdown.trigger.disabled.border,
@@ -1022,7 +1030,6 @@ const createStyles$17 = (theme) => StyleSheet.create({
1022
1030
  color: theme.components.dropdown.trigger.default.fg,
1023
1031
  fontFamily: theme.tokens.typography.family.regular
1024
1032
  },
1025
- triggerTextPressed: { color: theme.components.dropdown.trigger.hover.fg },
1026
1033
  triggerTextDisabled: { color: theme.components.dropdown.trigger.disabled.fg },
1027
1034
  textSm: {
1028
1035
  fontSize: theme.tokens.typography.size.sm,
@@ -1049,9 +1056,10 @@ const createStyles$17 = (theme) => StyleSheet.create({
1049
1056
  });
1050
1057
  //#endregion
1051
1058
  //#region src/components/Dropdown/Trigger/DropdownTrigger.tsx
1052
- function DropdownTrigger({ label, trigger, children, icon, arrowIcon, showArrow = true, size = "md", disabled = false, isOpen, triggerStyle, triggerRef, accessibilityLabel, accessibilityHint, onPress }) {
1059
+ function DropdownTrigger({ asChild = false, label, trigger, children, icon, arrowIcon, showArrow = true, color = "primary", size = "md", disabled = false, isOpen, triggerStyle, triggerRef, accessibilityLabel, accessibilityHint, onPress }) {
1053
1060
  const { theme } = useTheme();
1054
1061
  const styles = useThemeStyles(createStyles$17);
1062
+ const colorPalette = theme.components.dropdown[color];
1055
1063
  const textSizeStyle = {
1056
1064
  sm: styles.textSm,
1057
1065
  md: styles.textMd,
@@ -1070,7 +1078,7 @@ function DropdownTrigger({ label, trigger, children, icon, arrowIcon, showArrow
1070
1078
  Animated.timing(rotateAnim, {
1071
1079
  toValue: isOpen ? 1 : 0,
1072
1080
  duration: 180,
1073
- useNativeDriver: true
1081
+ useNativeDriver: Platform.OS !== "web"
1074
1082
  }).start();
1075
1083
  }, [isOpen, rotateAnim]);
1076
1084
  const arrowRotate = rotateAnim.interpolate({
@@ -1091,7 +1099,7 @@ function DropdownTrigger({ label, trigger, children, icon, arrowIcon, showArrow
1091
1099
  if (!isValidElement(node)) return node;
1092
1100
  return cloneElement(node, { color });
1093
1101
  };
1094
- const contentColor = disabled ? theme.components.dropdown.trigger.disabled.fg : isPressed ? theme.components.dropdown.trigger.hover.fg : theme.components.dropdown.trigger.default.fg;
1102
+ const contentColor = disabled ? theme.components.dropdown.trigger.disabled.fg : isPressed ? colorPalette.trigger.hover.fg : colorPalette.trigger.default.fg;
1095
1103
  const arrow = arrowIcon ? renderColoredNode(arrowIcon, contentColor) : /* @__PURE__ */ jsx(ChevronDown, {
1096
1104
  width: 16,
1097
1105
  height: 16,
@@ -1099,7 +1107,7 @@ function DropdownTrigger({ label, trigger, children, icon, arrowIcon, showArrow
1099
1107
  });
1100
1108
  const renderedIcon = icon ? renderColoredNode(icon, contentColor) : null;
1101
1109
  const triggerContent = trigger ?? children;
1102
- if (isValidElement(triggerContent)) {
1110
+ if (asChild && isValidElement(triggerContent)) {
1103
1111
  const child = triggerContent;
1104
1112
  const isChildDisabled = disabled || child.props.disabled;
1105
1113
  return cloneElement(child, {
@@ -1133,9 +1141,16 @@ function DropdownTrigger({ label, trigger, children, icon, arrowIcon, showArrow
1133
1141
  style: [
1134
1142
  styles.trigger,
1135
1143
  styles[size],
1144
+ {
1145
+ backgroundColor: colorPalette.trigger.default.bg,
1146
+ borderColor: colorPalette.trigger.default.border
1147
+ },
1136
1148
  isIconOnly && styles.iconOnly,
1137
1149
  isIconOnly && iconOnlySizeStyle,
1138
- isPressed && !disabled && styles.triggerPressed,
1150
+ isPressed && !disabled && {
1151
+ backgroundColor: colorPalette.trigger.hover.bg,
1152
+ borderColor: colorPalette.trigger.hover.border
1153
+ },
1139
1154
  disabled && styles.triggerDisabled,
1140
1155
  triggerStyle
1141
1156
  ],
@@ -1178,7 +1193,7 @@ const createStyles$16 = (theme) => StyleSheet.create({
1178
1193
  });
1179
1194
  //#endregion
1180
1195
  //#region src/components/Dropdown/Dropdown.tsx
1181
- function DropdownRoot({ children, label = "Menu", trigger, icon, arrowIcon, showArrow = true, open, defaultOpen = false, onOpenChange, presentation = "auto", closeOnSelect = true, disabled = false, loading = false, loadingText = "Loading actions...", searchable = false, command = false, searchValue, defaultSearchValue = "", searchPlaceholder, onSearch, empty, noOptionsText, size = "md", style, triggerStyle, contentStyle, itemStyle, textStyle, accessibilityLabel, accessibilityHint }) {
1196
+ function DropdownRoot({ children, label = "Menu", trigger, icon, arrowIcon, showArrow = true, open, defaultOpen = false, onOpenChange, presentation = "auto", closeOnSelect = true, color = "primary", disabled = false, loading = false, loadingText = "Loading actions...", searchable = false, command = false, searchValue, defaultSearchValue = "", searchPlaceholder, onSearch, empty, noOptionsText, size = "md", style, triggerStyle, contentStyle, itemStyle, textStyle, accessibilityLabel, accessibilityHint }) {
1182
1197
  const styles = useThemeStyles(createStyles$16);
1183
1198
  const overlayId = useId();
1184
1199
  const [uncontrolledSearchValue, setUncontrolledSearchValue] = useState(defaultSearchValue);
@@ -1220,6 +1235,11 @@ function DropdownRoot({ children, label = "Menu", trigger, icon, arrowIcon, show
1220
1235
  AccessibilityInfo.announceForAccessibility(`${menuAccessibilityLabel} opened`);
1221
1236
  }, [isOpen, menuAccessibilityLabel]);
1222
1237
  const focusTrigger = useCallback(() => {
1238
+ if (Platform.OS === "web") {
1239
+ const triggerNode = triggerRef.current;
1240
+ if (triggerNode && typeof triggerNode === "object" && "focus" in triggerNode && typeof triggerNode.focus === "function") triggerNode.focus();
1241
+ return;
1242
+ }
1223
1243
  if (typeof findNodeHandle !== "function") return;
1224
1244
  const handle = findNodeHandle(triggerRef.current);
1225
1245
  if (handle && AccessibilityInfo.setAccessibilityFocus) AccessibilityInfo.setAccessibilityFocus(handle);
@@ -1228,10 +1248,10 @@ function DropdownRoot({ children, label = "Menu", trigger, icon, arrowIcon, show
1228
1248
  closeDropdown();
1229
1249
  requestAnimationFrame(focusTrigger);
1230
1250
  }, [closeDropdown, focusTrigger]);
1231
- const dismiss = useNativeDismiss({
1251
+ const dismiss = useOverlayDismiss({
1232
1252
  id: overlayId,
1233
- visible: isOpen,
1234
- onClose: closeAndFocusTrigger
1253
+ active: isOpen,
1254
+ requestClose: closeAndFocusTrigger
1235
1255
  });
1236
1256
  const handleSelect = useCallback((entry) => {
1237
1257
  if (entry.disabled || loading) return;
@@ -1265,6 +1285,7 @@ function DropdownRoot({ children, label = "Menu", trigger, icon, arrowIcon, show
1265
1285
  return /* @__PURE__ */ jsx(DropdownItem, {
1266
1286
  label: item.props.children,
1267
1287
  value: item.props.value ?? item.id,
1288
+ color,
1268
1289
  icon: item.props.icon,
1269
1290
  danger: item.props.danger,
1270
1291
  disabled: item.props.disabled,
@@ -1274,6 +1295,7 @@ function DropdownRoot({ children, label = "Menu", trigger, icon, arrowIcon, show
1274
1295
  onSelect: () => handleSelect(item)
1275
1296
  });
1276
1297
  }, [
1298
+ color,
1277
1299
  handleSelect,
1278
1300
  itemStyle,
1279
1301
  styles.emptyText,
@@ -1293,11 +1315,13 @@ function DropdownRoot({ children, label = "Menu", trigger, icon, arrowIcon, show
1293
1315
  return /* @__PURE__ */ jsxs(View, {
1294
1316
  style: [styles.root, style],
1295
1317
  children: [/* @__PURE__ */ jsx(DropdownTrigger, {
1318
+ asChild: Boolean(parsed.trigger),
1296
1319
  label,
1297
1320
  trigger: trigger ?? parsed.trigger,
1298
1321
  icon,
1299
1322
  arrowIcon,
1300
1323
  showArrow,
1324
+ color,
1301
1325
  disabled: disabled || parsed.triggerProps?.disabled,
1302
1326
  isOpen,
1303
1327
  size,
@@ -1311,6 +1335,7 @@ function DropdownRoot({ children, label = "Menu", trigger, icon, arrowIcon, show
1311
1335
  }), /* @__PURE__ */ jsx(DropdownContent, {
1312
1336
  isOpen,
1313
1337
  onClose: dismiss.requestClose,
1338
+ color,
1314
1339
  contentStyle: [contentStyle, contentStyleFromSlot],
1315
1340
  accessibilityLabel: menuAccessibilityLabel,
1316
1341
  presentation: presentationFromSlot ?? resolvedPresentation,
@@ -1483,14 +1508,19 @@ const createStyles$13 = (theme) => StyleSheet.create({ content: {
1483
1508
  borderColor: theme.components.modal.content.border,
1484
1509
  borderRadius: theme.components.modal.content.radius,
1485
1510
  borderWidth: theme.components.modal.content.borderWidth,
1486
- shadowColor: theme.tokens.shadows.lg.color,
1487
- shadowOffset: {
1488
- width: theme.tokens.shadows.lg.x,
1489
- height: theme.tokens.shadows.lg.y
1490
- },
1491
- shadowOpacity: theme.tokens.shadows.lg.opacity,
1492
- shadowRadius: theme.tokens.shadows.lg.blur,
1493
- elevation: theme.tokens.shadows.lg.elevation
1511
+ ...Platform.select({
1512
+ web: { boxShadow: `${theme.tokens.shadows.lg.x}px ${theme.tokens.shadows.lg.y}px ${theme.tokens.shadows.lg.blur}px ${theme.tokens.shadows.lg.color}` },
1513
+ default: {
1514
+ shadowColor: theme.tokens.shadows.lg.color,
1515
+ shadowOffset: {
1516
+ width: theme.tokens.shadows.lg.x,
1517
+ height: theme.tokens.shadows.lg.y
1518
+ },
1519
+ shadowOpacity: theme.tokens.shadows.lg.opacity,
1520
+ shadowRadius: theme.tokens.shadows.lg.blur,
1521
+ elevation: theme.tokens.shadows.lg.elevation
1522
+ }
1523
+ })
1494
1524
  } });
1495
1525
  //#endregion
1496
1526
  //#region src/components/Modal/Content/ModalContent.tsx
@@ -1576,11 +1606,11 @@ const ModalRoot = ({ open, defaultOpen = false, onOpenChange, closeOnOutsidePres
1576
1606
  onOpenChange,
1577
1607
  closeOnOutsidePress
1578
1608
  });
1579
- const dismiss = useNativeDismiss({
1609
+ const dismiss = useOverlayDismiss({
1580
1610
  id: modal.contentId,
1581
- visible: modal.open,
1611
+ active: modal.open,
1582
1612
  closeOnOutsidePress: modal.closeOnOutsidePress,
1583
- onClose: modal.requestClose
1613
+ requestClose: modal.requestClose
1584
1614
  });
1585
1615
  return /* @__PURE__ */ jsx(ModalContext.Provider, {
1586
1616
  value: {
@@ -1727,6 +1757,8 @@ const indicatorSizeBySize = {
1727
1757
  md: 8,
1728
1758
  lg: 10
1729
1759
  };
1760
+ const nativePointerEventsNone$5 = Platform.OS === "web" ? void 0 : { pointerEvents: "none" };
1761
+ const webPointerEventsNone$5 = Platform.OS === "web" ? { pointerEvents: "none" } : void 0;
1730
1762
  const Radio = forwardRef(({ value, checked, defaultChecked = false, disabled: disabledProp = false, required: requiredProp = false, size: sizeProp, color: colorProp, onCheckedChange, label, description, icon, error, accessibilityLabel, accessibilityHint, containerStyle, labelStyle, descriptionStyle, errorStyle, style, ...rest }, ref) => {
1731
1763
  const { theme } = useTheme();
1732
1764
  const styles = createStyles$10(theme);
@@ -1806,9 +1838,10 @@ const Radio = forwardRef(({ value, checked, defaultChecked = false, disabled: di
1806
1838
  onPress: handlePress,
1807
1839
  style: resolvePressableStyle,
1808
1840
  children: (state) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(View, {
1809
- pointerEvents: "none",
1841
+ ...nativePointerEventsNone$5,
1810
1842
  style: [
1811
1843
  styles.control,
1844
+ webPointerEventsNone$5,
1812
1845
  {
1813
1846
  width: controlSize,
1814
1847
  height: controlSize,
@@ -1837,8 +1870,8 @@ const Radio = forwardRef(({ value, checked, defaultChecked = false, disabled: di
1837
1870
  resolvedDisabled && styles.indicatorDisabled
1838
1871
  ] }))
1839
1872
  }), (label || description) && /* @__PURE__ */ jsxs(View, {
1840
- pointerEvents: "none",
1841
- style: styles.content,
1873
+ ...nativePointerEventsNone$5,
1874
+ style: [styles.content, webPointerEventsNone$5],
1842
1875
  children: [label && (typeof label === "string" ? /* @__PURE__ */ jsx(Text, {
1843
1876
  style: [
1844
1877
  styles.label,
@@ -3241,6 +3274,10 @@ const createTriggerStyles = (theme) => StyleSheet.create({
3241
3274
  //#endregion
3242
3275
  //#region src/components/Select/Trigger/SelectTrigger.tsx
3243
3276
  const SelectTriggerSlot = createSelectSlot("trigger", "Select.Trigger");
3277
+ const nativePointerEventsNone$4 = Platform.OS === "web" ? void 0 : { pointerEvents: "none" };
3278
+ const nativePointerEventsBoxNone = Platform.OS === "web" ? void 0 : { pointerEvents: "box-none" };
3279
+ const webPointerEventsNone$4 = Platform.OS === "web" ? { pointerEvents: "none" } : void 0;
3280
+ const webPointerEventsBoxNone = Platform.OS === "web" ? { pointerEvents: "box-none" } : void 0;
3244
3281
  function SelectTrigger({ displayText, isPlaceholder, isOpen, size = "md", color = "primary", variant = "outline", disabled = false, required = false, hasError = false, hasValue = false, loading = false, clearable = false, startIcon, endIcon, prefix, suffix, accessibilityLabel, accessibilityHint, nativeID, accessibilityLabelledBy, ariaDescribedBy, triggerStyle, textStyle, onPress, onClear }) {
3245
3282
  const { theme } = useTheme();
3246
3283
  const styles = useThemeStyles(createTriggerStyles);
@@ -3248,6 +3285,16 @@ function SelectTrigger({ displayText, isPlaceholder, isOpen, size = "md", color
3248
3285
  const triggerState = isOpen ? palette.focus : palette.default;
3249
3286
  const resolvedIconSize = size === "lg" ? 18 : 16;
3250
3287
  const showClearButton = clearable && hasValue && !disabled && !loading;
3288
+ const openRingStyle = Platform.OS === "web" ? { boxShadow: `0 0 0 3px ${theme.components.select[color].ring}` } : {
3289
+ shadowColor: theme.components.select[color].ring,
3290
+ shadowOffset: {
3291
+ width: 0,
3292
+ height: 0
3293
+ },
3294
+ shadowOpacity: .16,
3295
+ shadowRadius: 6,
3296
+ elevation: 1
3297
+ };
3251
3298
  const triggerWithClearStyle = {
3252
3299
  sm: styles.triggerWithClearSm,
3253
3300
  md: styles.triggerWithClearMd,
@@ -3314,16 +3361,7 @@ function SelectTrigger({ displayText, isPlaceholder, isOpen, size = "md", color
3314
3361
  },
3315
3362
  styles[size],
3316
3363
  showClearButton && triggerWithClearStyle[size],
3317
- isOpen && {
3318
- shadowColor: theme.components.select[color].ring,
3319
- shadowOffset: {
3320
- width: 0,
3321
- height: 0
3322
- },
3323
- shadowOpacity: .16,
3324
- shadowRadius: 6,
3325
- elevation: 1
3326
- },
3364
+ isOpen && openRingStyle,
3327
3365
  hasError && { borderColor: theme.components.select.trigger.error.border },
3328
3366
  disabled && {
3329
3367
  backgroundColor: theme.components.select.trigger.disabled.bg,
@@ -3333,8 +3371,8 @@ function SelectTrigger({ displayText, isPlaceholder, isOpen, size = "md", color
3333
3371
  ],
3334
3372
  children: [
3335
3373
  startIcon && /* @__PURE__ */ jsx(View, {
3336
- pointerEvents: "none",
3337
- style: styles.startIcon,
3374
+ ...nativePointerEventsNone$4,
3375
+ style: [styles.startIcon, webPointerEventsNone$4],
3338
3376
  accessibilityElementsHidden: true,
3339
3377
  importantForAccessibility: "no",
3340
3378
  children: renderIcon(startIcon)
@@ -3356,8 +3394,8 @@ function SelectTrigger({ displayText, isPlaceholder, isOpen, size = "md", color
3356
3394
  size: "small",
3357
3395
  color: iconColor
3358
3396
  }) : showClearButton ? null : endIcon ? /* @__PURE__ */ jsx(View, {
3359
- pointerEvents: "none",
3360
- style: styles.endIcon,
3397
+ ...nativePointerEventsNone$4,
3398
+ style: [styles.endIcon, webPointerEventsNone$4],
3361
3399
  accessibilityElementsHidden: true,
3362
3400
  importantForAccessibility: "no",
3363
3401
  children: renderIcon(endIcon)
@@ -3373,8 +3411,12 @@ function SelectTrigger({ displayText, isPlaceholder, isOpen, size = "md", color
3373
3411
  })
3374
3412
  ]
3375
3413
  }), showClearButton && /* @__PURE__ */ jsx(View, {
3376
- pointerEvents: "box-none",
3377
- style: [styles.clearButtonContainer, clearButtonContainerStyle[size]],
3414
+ ...nativePointerEventsBoxNone,
3415
+ style: [
3416
+ styles.clearButtonContainer,
3417
+ clearButtonContainerStyle[size],
3418
+ webPointerEventsBoxNone
3419
+ ],
3378
3420
  children: /* @__PURE__ */ jsx(Pressable, {
3379
3421
  accessibilityRole: "button",
3380
3422
  accessibilityLabel: "Clear selection",
@@ -3475,11 +3517,11 @@ function SelectRoot(props) {
3475
3517
  fieldDescribedBy: field?.ariaDescribedBy
3476
3518
  });
3477
3519
  const hasValue = selectedValues.length > 0;
3478
- const dismiss = useNativeDismiss({
3520
+ const dismiss = useOverlayDismiss({
3479
3521
  id: overlayId,
3480
- visible: isOpen,
3522
+ active: isOpen,
3481
3523
  closeOnOutsidePress: dismissOnBackdropPress,
3482
- onClose: closeDropdown
3524
+ requestClose: closeDropdown
3483
3525
  });
3484
3526
  const clearValue = () => {
3485
3527
  selectedFocusValueRef.current = void 0;
@@ -3699,18 +3741,223 @@ const TabsContent = ({ value, children, forceMount = false, style }) => {
3699
3741
  TabsContent.displayName = "Tabs.Content";
3700
3742
  //#endregion
3701
3743
  //#region src/components/Tabs/List/TabsIndicator.tsx
3702
- const TabsIndicator = ({ children, style }) => /* @__PURE__ */ jsx(View, {
3703
- accessibilityElementsHidden: true,
3704
- importantForAccessibility: "no-hide-descendants",
3705
- pointerEvents: "none",
3706
- style,
3707
- children
3744
+ const COLLAPSED_SIZE = 8;
3745
+ const LINE_ANIMATION_DURATION = 360;
3746
+ const SURFACE_ANIMATION_DURATION = 220;
3747
+ const easing = Easing?.bezier?.(.22, 1, .36, 1) ?? ((value) => value);
3748
+ const nativePointerEventsNone$3 = Platform.OS === "web" ? void 0 : { pointerEvents: "none" };
3749
+ const webPointerEventsNone$3 = Platform.OS === "web" ? { pointerEvents: "none" } : void 0;
3750
+ const animateValue = (value, toValue, duration) => Animated.timing(value, {
3751
+ toValue,
3752
+ duration,
3753
+ easing,
3754
+ useNativeDriver: false
3708
3755
  });
3756
+ const TabsIndicator = ({ children, style }) => {
3757
+ const { theme } = useTheme();
3758
+ const { value, orientation, variant, color, size, indicatorVersion, getTriggerLayout } = useTabs();
3759
+ const translateX = useRef(new Animated.Value(0)).current;
3760
+ const translateY = useRef(new Animated.Value(0)).current;
3761
+ const width = useRef(new Animated.Value(0)).current;
3762
+ const height = useRef(new Animated.Value(0)).current;
3763
+ const previousLayoutRef = useRef(null);
3764
+ const previousValueRef = useRef(void 0);
3765
+ const previousOrientationRef = useRef(orientation);
3766
+ const animationRef = useRef(null);
3767
+ const [reduceMotion, setReduceMotion] = useState(false);
3768
+ const [visible, setVisible] = useState(false);
3769
+ const isVertical = orientation === "vertical";
3770
+ const palette = theme.components.tabs[color];
3771
+ useEffect(() => {
3772
+ AccessibilityInfo.isReduceMotionEnabled?.().then(setReduceMotion);
3773
+ const subscription = AccessibilityInfo.addEventListener?.("reduceMotionChanged", setReduceMotion);
3774
+ return () => {
3775
+ subscription?.remove();
3776
+ animationRef.current?.stop();
3777
+ };
3778
+ }, []);
3779
+ useEffect(() => {
3780
+ if (!value) {
3781
+ setVisible(false);
3782
+ return;
3783
+ }
3784
+ const nextLayout = getTriggerLayout(value);
3785
+ if (!nextLayout || nextLayout.width <= 0 || nextLayout.height <= 0) {
3786
+ setVisible(false);
3787
+ return;
3788
+ }
3789
+ setVisible(true);
3790
+ animationRef.current?.stop();
3791
+ const previousLayout = previousLayoutRef.current;
3792
+ if (!(!reduceMotion && previousLayout && previousValueRef.current !== value && previousOrientationRef.current === orientation)) {
3793
+ translateX.setValue(nextLayout.x);
3794
+ translateY.setValue(nextLayout.y);
3795
+ width.setValue(nextLayout.width);
3796
+ height.setValue(nextLayout.height);
3797
+ previousLayoutRef.current = nextLayout;
3798
+ previousValueRef.current = value;
3799
+ previousOrientationRef.current = orientation;
3800
+ return;
3801
+ }
3802
+ if (variant === "line" && isVertical) {
3803
+ const previousCenter = previousLayout.y + previousLayout.height / 2;
3804
+ const nextCenter = nextLayout.y + nextLayout.height / 2;
3805
+ const collapsedPreviousY = previousCenter - COLLAPSED_SIZE / 2;
3806
+ const collapsedNextY = nextCenter - COLLAPSED_SIZE / 2;
3807
+ translateY.setValue(previousLayout.y);
3808
+ height.setValue(previousLayout.height);
3809
+ animationRef.current = Animated.sequence([
3810
+ Animated.parallel([animateValue(height, COLLAPSED_SIZE, LINE_ANIMATION_DURATION * .28), animateValue(translateY, collapsedPreviousY, LINE_ANIMATION_DURATION * .28)]),
3811
+ animateValue(translateY, collapsedNextY, LINE_ANIMATION_DURATION * .36),
3812
+ Animated.parallel([animateValue(height, nextLayout.height, LINE_ANIMATION_DURATION * .36), animateValue(translateY, nextLayout.y, LINE_ANIMATION_DURATION * .36)])
3813
+ ]);
3814
+ } else if (variant === "line") {
3815
+ const previousCenter = previousLayout.x + previousLayout.width / 2;
3816
+ const nextCenter = nextLayout.x + nextLayout.width / 2;
3817
+ const collapsedPreviousX = previousCenter - COLLAPSED_SIZE / 2;
3818
+ const collapsedNextX = nextCenter - COLLAPSED_SIZE / 2;
3819
+ translateX.setValue(previousLayout.x);
3820
+ width.setValue(previousLayout.width);
3821
+ animationRef.current = Animated.sequence([
3822
+ Animated.parallel([animateValue(width, COLLAPSED_SIZE, LINE_ANIMATION_DURATION * .28), animateValue(translateX, collapsedPreviousX, LINE_ANIMATION_DURATION * .28)]),
3823
+ animateValue(translateX, collapsedNextX, LINE_ANIMATION_DURATION * .36),
3824
+ Animated.parallel([animateValue(width, nextLayout.width, LINE_ANIMATION_DURATION * .36), animateValue(translateX, nextLayout.x, LINE_ANIMATION_DURATION * .36)])
3825
+ ]);
3826
+ } else {
3827
+ translateX.setValue(previousLayout.x);
3828
+ translateY.setValue(previousLayout.y);
3829
+ width.setValue(previousLayout.width);
3830
+ height.setValue(previousLayout.height);
3831
+ animationRef.current = Animated.parallel([
3832
+ animateValue(translateX, nextLayout.x, SURFACE_ANIMATION_DURATION),
3833
+ animateValue(translateY, nextLayout.y, SURFACE_ANIMATION_DURATION),
3834
+ animateValue(width, nextLayout.width, SURFACE_ANIMATION_DURATION),
3835
+ animateValue(height, nextLayout.height, SURFACE_ANIMATION_DURATION)
3836
+ ]);
3837
+ }
3838
+ animationRef.current.start(() => {
3839
+ translateX.setValue(nextLayout.x);
3840
+ translateY.setValue(nextLayout.y);
3841
+ width.setValue(nextLayout.width);
3842
+ height.setValue(nextLayout.height);
3843
+ });
3844
+ previousLayoutRef.current = nextLayout;
3845
+ previousValueRef.current = value;
3846
+ previousOrientationRef.current = orientation;
3847
+ }, [
3848
+ getTriggerLayout,
3849
+ height,
3850
+ indicatorVersion,
3851
+ isVertical,
3852
+ orientation,
3853
+ reduceMotion,
3854
+ translateX,
3855
+ translateY,
3856
+ value,
3857
+ variant,
3858
+ width
3859
+ ]);
3860
+ const indicatorStyle = useMemo(() => {
3861
+ const baseStyle = {
3862
+ position: "absolute",
3863
+ opacity: visible ? 1 : 0,
3864
+ zIndex: 0
3865
+ };
3866
+ if (variant === "line") return [
3867
+ baseStyle,
3868
+ {
3869
+ backgroundColor: palette.indicator.bg,
3870
+ borderRadius: theme.tokens.radius.full
3871
+ },
3872
+ isVertical ? {
3873
+ top: 0,
3874
+ left: 0,
3875
+ width: 3,
3876
+ height,
3877
+ transform: [{ translateY }]
3878
+ } : {
3879
+ right: void 0,
3880
+ bottom: 0,
3881
+ left: 0,
3882
+ width,
3883
+ height: 3,
3884
+ transform: [{ translateX }]
3885
+ },
3886
+ style
3887
+ ];
3888
+ if (variant === "pills") return [
3889
+ baseStyle,
3890
+ {
3891
+ top: 0,
3892
+ left: 0,
3893
+ width,
3894
+ height,
3895
+ backgroundColor: palette.pills.active.bg,
3896
+ borderColor: palette.pills.active.border,
3897
+ borderRadius: theme.tokens.radius[size === "lg" ? "lg" : size === "sm" ? "sm" : "md"],
3898
+ borderWidth: 1,
3899
+ transform: [{ translateX }, { translateY }]
3900
+ },
3901
+ style
3902
+ ];
3903
+ return [
3904
+ baseStyle,
3905
+ {
3906
+ top: -1,
3907
+ left: -1,
3908
+ width,
3909
+ height,
3910
+ backgroundColor: palette.segmented.active.bg,
3911
+ borderColor: palette.segmented.active.border,
3912
+ borderRadius: theme.tokens.radius.lg,
3913
+ borderWidth: 1,
3914
+ ...Platform.select({
3915
+ web: { boxShadow: "0 1px 2px rgba(24, 21, 33, 0.06)" },
3916
+ default: {
3917
+ shadowColor: "#181521",
3918
+ shadowOffset: {
3919
+ width: 0,
3920
+ height: 1
3921
+ },
3922
+ shadowOpacity: .06,
3923
+ shadowRadius: 2
3924
+ }
3925
+ }),
3926
+ transform: [{ translateX }, { translateY }]
3927
+ },
3928
+ style
3929
+ ];
3930
+ }, [
3931
+ height,
3932
+ isVertical,
3933
+ palette.indicator.bg,
3934
+ palette.pills.active.bg,
3935
+ palette.pills.active.border,
3936
+ palette.segmented.active.bg,
3937
+ palette.segmented.active.border,
3938
+ size,
3939
+ style,
3940
+ theme.tokens.radius,
3941
+ translateX,
3942
+ translateY,
3943
+ variant,
3944
+ visible,
3945
+ width
3946
+ ]);
3947
+ return /* @__PURE__ */ jsx(Animated.View, {
3948
+ accessibilityElementsHidden: true,
3949
+ importantForAccessibility: "no-hide-descendants",
3950
+ ...nativePointerEventsNone$3,
3951
+ style: [indicatorStyle, webPointerEventsNone$3],
3952
+ children
3953
+ });
3954
+ };
3709
3955
  TabsIndicator.displayName = "Tabs.Indicator";
3710
3956
  //#endregion
3711
3957
  //#region src/components/Tabs/List/TabsList.styles.ts
3712
3958
  const createStyles$6 = (theme) => StyleSheet.create({
3713
3959
  list: {
3960
+ position: "relative",
3714
3961
  flexDirection: "row",
3715
3962
  alignSelf: "stretch",
3716
3963
  width: "100%",
@@ -3718,6 +3965,7 @@ const createStyles$6 = (theme) => StyleSheet.create({
3718
3965
  marginBottom: theme.tokens.spacing[6]
3719
3966
  },
3720
3967
  listSegmented: {
3968
+ gap: theme.tokens.spacing[1],
3721
3969
  padding: 2,
3722
3970
  backgroundColor: theme.components.tabs.list.segmentedBg,
3723
3971
  borderColor: theme.components.tabs.list.border,
@@ -3775,31 +4023,64 @@ const createStyles$5 = (theme) => StyleSheet.create({
3775
4023
  justifyContent: "center",
3776
4024
  paddingHorizontal: theme.tokens.spacing[4],
3777
4025
  paddingVertical: theme.tokens.spacing[2],
3778
- borderWidth: 1
4026
+ borderWidth: 1,
4027
+ zIndex: 1
4028
+ },
4029
+ tabIconOnly: {
4030
+ width: 44,
4031
+ minWidth: 44,
4032
+ paddingHorizontal: 0
3779
4033
  },
3780
4034
  tabSm: {
3781
4035
  minHeight: 36,
3782
4036
  paddingHorizontal: theme.tokens.spacing[3],
3783
4037
  paddingVertical: 6
3784
4038
  },
4039
+ tabIconOnlySm: {
4040
+ width: 36,
4041
+ minWidth: 36,
4042
+ paddingHorizontal: 0
4043
+ },
3785
4044
  tabLg: {
3786
4045
  minHeight: 52,
3787
4046
  paddingHorizontal: theme.tokens.spacing[5],
3788
4047
  paddingVertical: theme.tokens.spacing[3]
3789
4048
  },
4049
+ tabIconOnlyLg: {
4050
+ width: 52,
4051
+ minWidth: 52,
4052
+ paddingHorizontal: 0
4053
+ },
3790
4054
  tabSegmented: {
4055
+ flex: 1,
4056
+ minWidth: 0,
3791
4057
  minHeight: 32,
3792
4058
  paddingVertical: 5,
3793
4059
  borderRadius: theme.tokens.radius.lg
3794
4060
  },
4061
+ tabSegmentedIconOnly: {
4062
+ width: 32,
4063
+ minWidth: 32,
4064
+ paddingHorizontal: 0
4065
+ },
3795
4066
  tabSegmentedSm: {
3796
4067
  minHeight: 30,
3797
4068
  paddingVertical: 4
3798
4069
  },
4070
+ tabSegmentedIconOnlySm: {
4071
+ width: 30,
4072
+ minWidth: 30,
4073
+ paddingHorizontal: 0
4074
+ },
3799
4075
  tabSegmentedLg: {
3800
4076
  minHeight: 40,
3801
4077
  paddingVertical: 8
3802
4078
  },
4079
+ tabSegmentedIconOnlyLg: {
4080
+ width: 40,
4081
+ minWidth: 40,
4082
+ paddingHorizontal: 0
4083
+ },
3803
4084
  tabVertical: {
3804
4085
  position: "relative",
3805
4086
  width: "100%",
@@ -3808,25 +4089,6 @@ const createStyles$5 = (theme) => StyleSheet.create({
3808
4089
  flexShrink: 0,
3809
4090
  justifyContent: "flex-start"
3810
4091
  },
3811
- horizontalIndicator: {
3812
- position: "absolute",
3813
- right: 0,
3814
- bottom: 0,
3815
- left: 0,
3816
- height: 3,
3817
- backgroundColor: "transparent"
3818
- },
3819
- horizontalIndicatorActive: { backgroundColor: "transparent" },
3820
- verticalIndicator: {
3821
- position: "absolute",
3822
- top: 0,
3823
- bottom: 0,
3824
- left: 0,
3825
- width: 3,
3826
- backgroundColor: "transparent"
3827
- },
3828
- verticalIndicatorActive: { backgroundColor: "transparent" },
3829
- verticalIndicatorPressed: { backgroundColor: "transparent" },
3830
4092
  tabHovered: { backgroundColor: "transparent" },
3831
4093
  tabPressed: { backgroundColor: "transparent" },
3832
4094
  tabFocused: { borderColor: theme.semantic.focus.ring.color },
@@ -3860,6 +4122,11 @@ const createStyles$5 = (theme) => StyleSheet.create({
3860
4122
  paddingVertical: theme.tokens.spacing[1],
3861
4123
  borderRadius: theme.tokens.radius.md
3862
4124
  },
4125
+ tabPillsIconOnly: {
4126
+ width: 36,
4127
+ minWidth: 36,
4128
+ paddingHorizontal: 0
4129
+ },
3863
4130
  tabPillsActive: {
3864
4131
  backgroundColor: "transparent",
3865
4132
  borderRadius: theme.tokens.radius.md
@@ -3931,7 +4198,7 @@ TabsIcon.displayName = "Tabs.Icon";
3931
4198
  const TabsTrigger = ({ value, children, icon, badge, description, disabled, style, textStyle }) => {
3932
4199
  const { theme } = useTheme();
3933
4200
  const styles = useThemeStyles(createStyles$5);
3934
- const { value: selectedValue, variant, color, size, orientation, disabled: rootDisabled, setValue, registerTrigger } = useTabs();
4201
+ const { value: selectedValue, variant, color, size, orientation, disabled: rootDisabled, setValue, registerTrigger, registerTriggerLayout } = useTabs();
3935
4202
  const isDisabled = rootDisabled || disabled;
3936
4203
  const isActive = selectedValue === value;
3937
4204
  const isPills = variant === "pills";
@@ -3940,6 +4207,7 @@ const TabsTrigger = ({ value, children, icon, badge, description, disabled, styl
3940
4207
  const isVertical = orientation === "vertical";
3941
4208
  const isSm = size === "sm";
3942
4209
  const isLg = size === "lg";
4210
+ const isOnlyIcon = icon != null && children == null && badge == null;
3943
4211
  const palette = theme.components.tabs[color];
3944
4212
  const state = isDisabled ? theme.components.tabs.disabled : isPills ? isActive ? palette.pills.active : palette.pills.default : isActive ? palette.trigger.active : palette.trigger.default;
3945
4213
  const pressedState = isDisabled ? state : isPills ? isActive ? palette.pills.active : palette.pills.hover : isActive ? palette.trigger.active : palette.trigger.hover;
@@ -3947,12 +4215,17 @@ const TabsTrigger = ({ value, children, icon, badge, description, disabled, styl
3947
4215
  registerTrigger(value, Boolean(isDisabled), true);
3948
4216
  return () => {
3949
4217
  registerTrigger(value, Boolean(isDisabled), false);
4218
+ registerTriggerLayout(value, void 0);
3950
4219
  };
3951
4220
  }, [
3952
4221
  isDisabled,
3953
4222
  registerTrigger,
4223
+ registerTriggerLayout,
3954
4224
  value
3955
4225
  ]);
4226
+ const handleLayout = (event) => {
4227
+ registerTriggerLayout(value, event.nativeEvent.layout);
4228
+ };
3956
4229
  const iconColor = isPills && isActive ? palette.pills.active.fg : isActive ? palette.trigger.active.fg : state.fg;
3957
4230
  const renderedIcon = isValidElement(icon) ? cloneElement(icon, { color: iconColor }) : icon;
3958
4231
  return /* @__PURE__ */ jsx(Pressable, {
@@ -3965,43 +4238,39 @@ const TabsTrigger = ({ value, children, icon, badge, description, disabled, styl
3965
4238
  onPress: () => {
3966
4239
  if (!isDisabled && !isActive) setValue(value);
3967
4240
  },
4241
+ onLayout: handleLayout,
3968
4242
  style: ({ pressed }) => [
3969
4243
  styles.tab,
3970
4244
  isSm && styles.tabSm,
3971
4245
  isLg && styles.tabLg,
4246
+ isOnlyIcon && styles.tabIconOnly,
4247
+ isOnlyIcon && isSm && styles.tabIconOnlySm,
4248
+ isOnlyIcon && isLg && styles.tabIconOnlyLg,
3972
4249
  isVertical && styles.tabVertical,
3973
4250
  isPills && styles.tabPills,
4251
+ isPills && isOnlyIcon && styles.tabPillsIconOnly,
3974
4252
  isSegmented && styles.tabSegmented,
3975
4253
  isSegmented && isSm && styles.tabSegmentedSm,
3976
4254
  isSegmented && isLg && styles.tabSegmentedLg,
3977
- isPills && isActive && {
3978
- borderColor: palette.pills.active.border,
3979
- backgroundColor: palette.pills.active.bg
3980
- },
4255
+ isSegmented && isOnlyIcon && styles.tabSegmentedIconOnly,
4256
+ isSegmented && isOnlyIcon && isSm && styles.tabSegmentedIconOnlySm,
4257
+ isSegmented && isOnlyIcon && isLg && styles.tabSegmentedIconOnlyLg,
3981
4258
  {
3982
- borderColor: state.border,
4259
+ borderColor: isLine ? "transparent" : state.border,
3983
4260
  backgroundColor: pressed ? pressedState.bg : state.bg
3984
4261
  },
3985
4262
  isSegmented && isActive && {
3986
4263
  borderColor: palette.segmented.active.border,
3987
- backgroundColor: palette.segmented.active.bg
4264
+ backgroundColor: "transparent"
4265
+ },
4266
+ isPills && isActive && {
4267
+ borderColor: "transparent",
4268
+ backgroundColor: "transparent"
3988
4269
  },
3989
4270
  isDisabled && styles.tabDisabled,
3990
4271
  style
3991
4272
  ],
3992
- children: ({ pressed }) => /* @__PURE__ */ jsxs(Fragment, { children: [
3993
- isLine && !isVertical && /* @__PURE__ */ jsx(View, {
3994
- pointerEvents: "none",
3995
- style: [styles.horizontalIndicator, isActive && { backgroundColor: palette.indicator.bg }]
3996
- }),
3997
- isLine && isVertical && /* @__PURE__ */ jsx(View, {
3998
- pointerEvents: "none",
3999
- style: [
4000
- styles.verticalIndicator,
4001
- isActive && { backgroundColor: palette.indicator.bg },
4002
- pressed && !isActive && !isDisabled && { backgroundColor: palette.indicator.hoverBg }
4003
- ]
4004
- }),
4273
+ children: () => /* @__PURE__ */ jsxs(Fragment, { children: [
4005
4274
  icon != null && /* @__PURE__ */ jsx(View, {
4006
4275
  style: styles.tabIcon,
4007
4276
  children: renderedIcon
@@ -4066,7 +4335,9 @@ const TabsRoot = ({ children, value: controlledValue, defaultValue, onValueChang
4066
4335
  const styles = useThemeStyles(createStyles$4);
4067
4336
  const isControlled = controlledValue !== void 0;
4068
4337
  const [version, setVersion] = useState(0);
4338
+ const [indicatorVersion, setIndicatorVersion] = useState(0);
4069
4339
  const triggersRef = useRef([]);
4340
+ const triggerLayoutsRef = useRef(/* @__PURE__ */ new Map());
4070
4341
  const { value, setValue } = useTabs$1({
4071
4342
  value: controlledValue,
4072
4343
  defaultValue,
@@ -4089,6 +4360,14 @@ const TabsRoot = ({ children, value: controlledValue, defaultValue, onValueChang
4089
4360
  else triggersRef.current.push(nextTab);
4090
4361
  setVersion((current) => current + 1);
4091
4362
  }, []);
4363
+ const registerTriggerLayout = useCallback((triggerValue, layout) => {
4364
+ if (!layout) triggerLayoutsRef.current.delete(triggerValue);
4365
+ else triggerLayoutsRef.current.set(triggerValue, layout);
4366
+ setIndicatorVersion((current) => current + 1);
4367
+ }, []);
4368
+ const getTriggerLayout = useCallback((triggerValue) => {
4369
+ return triggerLayoutsRef.current.get(triggerValue);
4370
+ }, []);
4092
4371
  useEffect(() => {
4093
4372
  const enabledTabs = triggersRef.current.filter((tab) => !tab.disabled);
4094
4373
  const selectedExists = triggersRef.current.some((tab) => tab.value === value);
@@ -4118,7 +4397,10 @@ const TabsRoot = ({ children, value: controlledValue, defaultValue, onValueChang
4118
4397
  keepMounted,
4119
4398
  lazyMount,
4120
4399
  disabled,
4121
- registerTrigger
4400
+ registerTrigger,
4401
+ indicatorVersion,
4402
+ getTriggerLayout,
4403
+ registerTriggerLayout
4122
4404
  }), [
4123
4405
  activationMode,
4124
4406
  color,
@@ -4126,6 +4408,9 @@ const TabsRoot = ({ children, value: controlledValue, defaultValue, onValueChang
4126
4408
  keepMounted,
4127
4409
  lazyMount,
4128
4410
  orientation,
4411
+ getTriggerLayout,
4412
+ indicatorVersion,
4413
+ registerTriggerLayout,
4129
4414
  registerTrigger,
4130
4415
  setValue,
4131
4416
  size,
@@ -4166,6 +4451,8 @@ const useTooltipContext = () => {
4166
4451
  TooltipContext.displayName = "TooltipContext";
4167
4452
  //#endregion
4168
4453
  //#region src/components/Tooltip/Arrow/TooltipArrow.tsx
4454
+ const nativePointerEventsNone$2 = Platform.OS === "web" ? void 0 : { pointerEvents: "none" };
4455
+ const webPointerEventsNone$2 = Platform.OS === "web" ? { pointerEvents: "none" } : void 0;
4169
4456
  const TooltipArrow = ({ style }) => {
4170
4457
  const { theme } = useTheme();
4171
4458
  const tooltip = useTooltipContext();
@@ -4185,16 +4472,20 @@ const TooltipArrow = ({ style }) => {
4185
4472
  marginLeft: -size / 2
4186
4473
  };
4187
4474
  return /* @__PURE__ */ jsx(View, {
4188
- pointerEvents: "none",
4189
- style: [{
4190
- position: "absolute",
4191
- width: size,
4192
- height: size,
4193
- backgroundColor: theme.components.tooltip.arrow.bg,
4194
- transform: [{ rotate: "45deg" }],
4195
- [staticSide]: -size / 2,
4196
- ...crossAxisStyle
4197
- }, style]
4475
+ ...nativePointerEventsNone$2,
4476
+ style: [
4477
+ {
4478
+ position: "absolute",
4479
+ width: size,
4480
+ height: size,
4481
+ backgroundColor: theme.components.tooltip.arrow.bg,
4482
+ transform: [{ rotate: "45deg" }],
4483
+ [staticSide]: -size / 2,
4484
+ ...crossAxisStyle
4485
+ },
4486
+ webPointerEventsNone$2,
4487
+ style
4488
+ ]
4198
4489
  });
4199
4490
  };
4200
4491
  TooltipArrow.displayName = "Tooltip.Arrow";
@@ -4213,14 +4504,19 @@ const createStyles$3 = (theme) => StyleSheet.create({
4213
4504
  borderColor: theme.components.tooltip.content.border,
4214
4505
  borderRadius: theme.components.tooltip.content.radius,
4215
4506
  borderWidth: theme.components.tooltip.content.borderWidth,
4216
- shadowColor: theme.tokens.shadows.md.color,
4217
- shadowOffset: {
4218
- width: theme.tokens.shadows.md.x,
4219
- height: theme.tokens.shadows.md.y
4220
- },
4221
- shadowOpacity: theme.tokens.shadows.md.opacity,
4222
- shadowRadius: theme.tokens.shadows.md.blur,
4223
- elevation: theme.tokens.shadows.md.elevation
4507
+ ...Platform.select({
4508
+ web: { boxShadow: `${theme.tokens.shadows.md.x}px ${theme.tokens.shadows.md.y}px ${theme.tokens.shadows.md.blur}px ${theme.tokens.shadows.md.color}` },
4509
+ default: {
4510
+ shadowColor: theme.tokens.shadows.md.color,
4511
+ shadowOffset: {
4512
+ width: theme.tokens.shadows.md.x,
4513
+ height: theme.tokens.shadows.md.y
4514
+ },
4515
+ shadowOpacity: theme.tokens.shadows.md.opacity,
4516
+ shadowRadius: theme.tokens.shadows.md.blur,
4517
+ elevation: theme.tokens.shadows.md.elevation
4518
+ }
4519
+ })
4224
4520
  },
4225
4521
  text: {
4226
4522
  flexShrink: 1,
@@ -4233,16 +4529,19 @@ const createStyles$3 = (theme) => StyleSheet.create({
4233
4529
  });
4234
4530
  //#endregion
4235
4531
  //#region src/components/Tooltip/Content/TooltipContent.tsx
4236
- const TooltipContent = ({ children, forceMount = false, style, textStyle }) => {
4532
+ const nativePointerEventsNone$1 = Platform.OS === "web" ? void 0 : { pointerEvents: "none" };
4533
+ const webPointerEventsNone$1 = Platform.OS === "web" ? { pointerEvents: "none" } : void 0;
4534
+ const TooltipContent = ({ children, forceMount = false, withArrow = false, style, textStyle }) => {
4237
4535
  const styles = useThemeStyles(createStyles$3);
4238
4536
  const tooltip = useTooltipContext();
4239
4537
  const visible = tooltip.open && !tooltip.disabled;
4240
4538
  if (!forceMount && !visible) return null;
4241
- const bubble = /* @__PURE__ */ jsx(View, {
4539
+ const bubble = /* @__PURE__ */ jsxs(View, {
4242
4540
  nativeID: tooltip.contentId,
4243
- pointerEvents: "none",
4541
+ ...nativePointerEventsNone$1,
4244
4542
  style: [
4245
4543
  styles.bubble,
4544
+ webPointerEventsNone$1,
4246
4545
  {
4247
4546
  top: tooltip.position.top,
4248
4547
  left: tooltip.position.left
@@ -4251,10 +4550,10 @@ const TooltipContent = ({ children, forceMount = false, style, textStyle }) => {
4251
4550
  style
4252
4551
  ],
4253
4552
  onLayout: tooltip.onFloatingLayout,
4254
- children: Children.map(children, (child) => typeof child === "string" || typeof child === "number" ? /* @__PURE__ */ jsx(Text, {
4553
+ children: [Children.map(children, (child) => typeof child === "string" || typeof child === "number" ? /* @__PURE__ */ jsx(Text, {
4255
4554
  style: [styles.text, textStyle],
4256
4555
  children: child
4257
- }) : child)
4556
+ }) : child), withArrow && /* @__PURE__ */ jsx(TooltipArrow, {})]
4258
4557
  });
4259
4558
  if (!visible) return bubble;
4260
4559
  return /* @__PURE__ */ jsx(Modal$1, {
@@ -4332,11 +4631,11 @@ const TooltipRoot = ({ children, open: openProp, defaultOpen = false, onOpenChan
4332
4631
  setOpen,
4333
4632
  updatePosition
4334
4633
  ]);
4335
- const dismiss = useNativeDismiss({
4634
+ const dismiss = useOverlayDismiss({
4336
4635
  id: contentId,
4337
- visible: open && !disabled,
4636
+ active: open && !disabled,
4338
4637
  closeOnOutsidePress,
4339
- onClose: hide
4638
+ requestClose: hide
4340
4639
  });
4341
4640
  useEffect(() => {
4342
4641
  if (disabled && open) hide();
@@ -4466,14 +4765,19 @@ const createStyles$2 = (theme) => StyleSheet.create({
4466
4765
  disabled: { borderColor: theme.components.button.disabled.border },
4467
4766
  focused: {
4468
4767
  borderColor: theme.semantic.focus.ring.color,
4469
- shadowColor: theme.semantic.focus.ring.color,
4470
- shadowOffset: {
4471
- width: 0,
4472
- height: 0
4473
- },
4474
- shadowOpacity: .18,
4475
- shadowRadius: 8,
4476
- elevation: 2
4768
+ ...Platform.select({
4769
+ web: { boxShadow: `0 0 0 4px ${theme.semantic.focus.ring.color}` },
4770
+ default: {
4771
+ shadowColor: theme.semantic.focus.ring.color,
4772
+ shadowOffset: {
4773
+ width: 0,
4774
+ height: 0
4775
+ },
4776
+ shadowOpacity: .18,
4777
+ shadowRadius: 8,
4778
+ elevation: 2
4779
+ }
4780
+ })
4477
4781
  },
4478
4782
  pressed: { transform: [{ scale: .98 }] }
4479
4783
  });
@@ -4962,26 +5266,36 @@ const createStyles = (theme) => StyleSheet.create({
4962
5266
  color: theme.components.input.focus.fg,
4963
5267
  backgroundColor: theme.components.input.focus.bg,
4964
5268
  borderColor: theme.components.input.focus.border,
4965
- shadowColor: resolveRingColor(theme.components.input.focus.ring),
4966
- shadowOffset: {
4967
- width: 0,
4968
- height: 0
4969
- },
4970
- shadowOpacity: .18,
4971
- shadowRadius: 6,
4972
- elevation: 1
5269
+ ...Platform.select({
5270
+ web: { boxShadow: `0 0 0 3px ${resolveRingColor(theme.components.input.focus.ring)}` },
5271
+ default: {
5272
+ shadowColor: resolveRingColor(theme.components.input.focus.ring),
5273
+ shadowOffset: {
5274
+ width: 0,
5275
+ height: 0
5276
+ },
5277
+ shadowOpacity: .18,
5278
+ shadowRadius: 6,
5279
+ elevation: 1
5280
+ }
5281
+ })
4973
5282
  },
4974
5283
  error: { borderColor: theme.components.input.error.border },
4975
5284
  errorFocused: {
4976
5285
  borderColor: theme.components.input.error.border,
4977
- shadowColor: resolveRingColor(theme.components.input.error.ring),
4978
- shadowOffset: {
4979
- width: 0,
4980
- height: 0
4981
- },
4982
- shadowOpacity: .2,
4983
- shadowRadius: 6,
4984
- elevation: 1
5286
+ ...Platform.select({
5287
+ web: { boxShadow: `0 0 0 3px ${resolveRingColor(theme.components.input.error.ring)}` },
5288
+ default: {
5289
+ shadowColor: resolveRingColor(theme.components.input.error.ring),
5290
+ shadowOffset: {
5291
+ width: 0,
5292
+ height: 0
5293
+ },
5294
+ shadowOpacity: .2,
5295
+ shadowRadius: 6,
5296
+ elevation: 1
5297
+ }
5298
+ })
4985
5299
  },
4986
5300
  readOnly: {
4987
5301
  color: theme.components.input.readOnly.fg,
@@ -5044,6 +5358,8 @@ const applyMask = (value, mask) => {
5044
5358
  if (!mask) return value;
5045
5359
  return typeof mask === "function" ? mask(value) : applyPatternMask(value, mask);
5046
5360
  };
5361
+ const nativePointerEventsNone = Platform.OS === "web" ? void 0 : { pointerEvents: "none" };
5362
+ const webPointerEventsNone = Platform.OS === "web" ? { pointerEvents: "none" } : void 0;
5047
5363
  const Input = forwardRef(({ label, description, value, defaultValue, onValueChange, placeholder, size, error, invalid = false, disabled = false, required = false, loading = false, readOnly = false, type = "text", startIcon, endIcon, startIconTone = "default", endIconTone = "default", clearIcon, clearIconTone = "danger", iconSize, containerStyle, inputStyle, keyboardType, secureTextEntry, autoCapitalize, autoCorrect, onBlur, onFocus, accessibilityLabel, accessibilityHint, testID, autoFocus, maxLength, clearable, onClear, color = "primary", variant = "outline", revealPassword = false, showCounter: _showCounter, mask, format, parse, ...props }, ref) => {
5048
5364
  const { theme } = useTheme();
5049
5365
  const styles = useThemeStyles(createStyles);
@@ -5064,6 +5380,16 @@ const Input = forwardRef(({ label, description, value, defaultValue, onValueChan
5064
5380
  const isRequired = required || !hasOwnField && Boolean(field?.required);
5065
5381
  const isReadOnly = readOnly || loading;
5066
5382
  const placeholderTextColor = isDisabled ? getDisabledPlaceholderTextColor(theme) : readOnly ? theme.components.input.readOnly.placeholder : inputState.placeholder;
5383
+ const focusedRingStyle = Platform.OS === "web" ? { boxShadow: `0 0 0 3px ${inputColorPalette.ring}` } : {
5384
+ shadowColor: inputColorPalette.ring,
5385
+ shadowOffset: {
5386
+ width: 0,
5387
+ height: 0
5388
+ },
5389
+ shadowOpacity: .18,
5390
+ shadowRadius: 6,
5391
+ elevation: 1
5392
+ };
5067
5393
  const isPassword = type === "password";
5068
5394
  const [isPasswordRevealed, setIsPasswordRevealed] = useState(false);
5069
5395
  const resolvedIconSize = iconSize ?? 16;
@@ -5096,8 +5422,8 @@ const Input = forwardRef(({ label, description, value, defaultValue, onValueChan
5096
5422
  style: styles.inputWrapper,
5097
5423
  children: [
5098
5424
  startIcon && /* @__PURE__ */ jsx(View, {
5099
- pointerEvents: "none",
5100
- style: styles.leftIcon,
5425
+ ...nativePointerEventsNone,
5426
+ style: [styles.leftIcon, webPointerEventsNone],
5101
5427
  accessibilityElementsHidden: true,
5102
5428
  importantForAccessibility: "no",
5103
5429
  children: cloneElement(startIcon, {
@@ -5143,14 +5469,7 @@ const Input = forwardRef(({ label, description, value, defaultValue, onValueChan
5143
5469
  color: inputPalette.focus.fg,
5144
5470
  backgroundColor: inputPalette.focus.bg,
5145
5471
  borderColor: inputPalette.focus.border,
5146
- shadowColor: inputColorPalette.ring,
5147
- shadowOffset: {
5148
- width: 0,
5149
- height: 0
5150
- },
5151
- shadowOpacity: .18,
5152
- shadowRadius: 6,
5153
- elevation: 1
5472
+ ...focusedRingStyle
5154
5473
  },
5155
5474
  isInvalid && styles.error,
5156
5475
  isFocused && isInvalid && !isDisabled && !isReadOnly && styles.errorFocused,
@@ -5182,8 +5501,8 @@ const Input = forwardRef(({ label, description, value, defaultValue, onValueChan
5182
5501
  children: isPasswordRevealed ? "Hide" : "Show"
5183
5502
  })
5184
5503
  }) : showRightIcon && endIcon && /* @__PURE__ */ jsx(View, {
5185
- pointerEvents: "none",
5186
- style: styles.rightIcon,
5504
+ ...nativePointerEventsNone,
5505
+ style: [styles.rightIcon, webPointerEventsNone],
5187
5506
  accessibilityElementsHidden: true,
5188
5507
  importantForAccessibility: "no",
5189
5508
  children: cloneElement(endIcon, {