@vellira-ui/react-native 2.32.0 → 2.33.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 CHANGED
@@ -69,9 +69,21 @@ function useThemeStyles(createStyles23) {
69
69
  import { StyleSheet } from "react-native";
70
70
  var createStyles = (theme) => StyleSheet.create({
71
71
  modalRoot: {
72
- flex: 1,
72
+ flex: 1
73
+ },
74
+ sheet: {
73
75
  justifyContent: "flex-end"
74
76
  },
77
+ modal: {
78
+ alignItems: "center",
79
+ justifyContent: "center",
80
+ padding: theme.tokens.spacing[4]
81
+ },
82
+ popover: {
83
+ alignItems: "center",
84
+ justifyContent: "center",
85
+ padding: theme.tokens.spacing[4]
86
+ },
75
87
  backdrop: {
76
88
  ...StyleSheet.absoluteFill,
77
89
  backgroundColor: theme.semantic.overlay.backdrop
@@ -93,6 +105,24 @@ var createStyles = (theme) => StyleSheet.create({
93
105
  shadowOpacity: 0.24,
94
106
  shadowRadius: 16,
95
107
  elevation: 12
108
+ },
109
+ sheetMenu: {
110
+ width: "100%",
111
+ maxHeight: "70%",
112
+ borderTopLeftRadius: theme.tokens.radius.lg,
113
+ borderTopRightRadius: theme.tokens.radius.lg
114
+ },
115
+ modalMenu: {
116
+ width: "100%",
117
+ maxWidth: 420,
118
+ maxHeight: "70%",
119
+ borderRadius: theme.tokens.radius.lg
120
+ },
121
+ popoverMenu: {
122
+ width: "100%",
123
+ maxWidth: 360,
124
+ maxHeight: "60%",
125
+ borderRadius: theme.tokens.radius.md
96
126
  }
97
127
  });
98
128
 
@@ -103,17 +133,19 @@ function DropdownContent({
103
133
  children,
104
134
  onClose,
105
135
  contentStyle,
106
- accessibilityLabel
136
+ accessibilityLabel,
137
+ presentation
107
138
  }) {
108
139
  const styles = useThemeStyles(createStyles);
140
+ const isSheet = presentation === "sheet";
109
141
  return /* @__PURE__ */ jsx2(
110
142
  Modal,
111
143
  {
112
144
  transparent: true,
113
145
  visible: isOpen,
114
- animationType: "slide",
146
+ animationType: isSheet ? "slide" : "fade",
115
147
  onRequestClose: onClose,
116
- children: /* @__PURE__ */ jsxs(View, { style: styles.modalRoot, children: [
148
+ children: /* @__PURE__ */ jsxs(View, { style: [styles.modalRoot, styles[presentation]], children: [
117
149
  /* @__PURE__ */ jsx2(
118
150
  Pressable,
119
151
  {
@@ -128,7 +160,7 @@ function DropdownContent({
128
160
  {
129
161
  accessibilityRole: "menu",
130
162
  accessibilityLabel,
131
- style: [styles.menu, contentStyle],
163
+ style: [styles.menu, styles[`${presentation}Menu`], contentStyle],
132
164
  children
133
165
  }
134
166
  )
@@ -139,9 +171,16 @@ function DropdownContent({
139
171
  DropdownContent.displayName = "DropdownContent";
140
172
 
141
173
  // src/components/Dropdown/Dropdown.tsx
142
- import { useCallback, useMemo as useMemo3 } from "react";
174
+ import { useCallback, useEffect as useEffect2, useMemo as useMemo3, useRef as useRef2 } from "react";
143
175
  import { useDropdown } from "@vellira-ui/core";
144
- import { View as View4 } from "react-native";
176
+ import {
177
+ AccessibilityInfo,
178
+ findNodeHandle,
179
+ FlatList,
180
+ Text as Text4,
181
+ useWindowDimensions,
182
+ View as View4
183
+ } from "react-native";
145
184
 
146
185
  // src/components/Dropdown/Group/DropdownGroup.tsx
147
186
  import { Text } from "react-native";
@@ -168,8 +207,100 @@ function DropdownGroup({ label }) {
168
207
  }
169
208
  DropdownGroup.displayName = "DropdownGroup";
170
209
 
210
+ // src/components/Dropdown/internal/DropdownCollection.ts
211
+ import { Children, isValidElement } from "react";
212
+ function createDropdownSlot(name, displayName) {
213
+ const Slot = () => null;
214
+ Slot.__velliraDropdownPart = name;
215
+ Slot.displayName = displayName;
216
+ return Slot;
217
+ }
218
+ function parseDropdownChildren(children) {
219
+ let generatedId = 0;
220
+ let trigger;
221
+ let triggerProps;
222
+ let contentProps;
223
+ const entries = [];
224
+ const items = [];
225
+ const nextId = (prefix) => `${prefix}-${generatedId++}`;
226
+ function pushItem(props) {
227
+ const entry = {
228
+ type: "item",
229
+ id: nextId("item"),
230
+ props,
231
+ label: getItemLabel(props.children) || props.value || "",
232
+ disabled: props.disabled
233
+ };
234
+ items.push(entry);
235
+ entries.push(entry);
236
+ }
237
+ function visit(node) {
238
+ Children.forEach(node, (child) => {
239
+ if (!isValidElement(child)) return;
240
+ const type = child.type;
241
+ switch (type.__velliraDropdownPart) {
242
+ case "trigger":
243
+ triggerProps = child.props;
244
+ trigger = triggerProps.children;
245
+ return;
246
+ case "content":
247
+ contentProps = child.props;
248
+ visit(contentProps.children);
249
+ return;
250
+ case "group":
251
+ visit(child.props.children);
252
+ return;
253
+ case "label":
254
+ entries.push({
255
+ type: "label",
256
+ id: nextId("label"),
257
+ props: child.props
258
+ });
259
+ return;
260
+ case "separator":
261
+ entries.push({
262
+ type: "separator",
263
+ id: nextId("separator"),
264
+ props: child.props
265
+ });
266
+ return;
267
+ case "empty":
268
+ entries.push({
269
+ type: "empty",
270
+ id: nextId("empty"),
271
+ props: child.props
272
+ });
273
+ return;
274
+ case "loading":
275
+ entries.push({
276
+ type: "loading",
277
+ id: nextId("loading"),
278
+ props: child.props
279
+ });
280
+ return;
281
+ case "item":
282
+ pushItem(child.props);
283
+ return;
284
+ default:
285
+ visit(child.props.children);
286
+ }
287
+ });
288
+ }
289
+ visit(children);
290
+ return { contentProps, entries, items, trigger, triggerProps };
291
+ }
292
+ function getItemLabel(children) {
293
+ const labelParts = [];
294
+ Children.forEach(children, (child) => {
295
+ if (typeof child === "string" || typeof child === "number") {
296
+ labelParts.push(String(child));
297
+ }
298
+ });
299
+ return labelParts.join("").trim();
300
+ }
301
+
171
302
  // src/components/Dropdown/Item/DropdownItem.tsx
172
- import { cloneElement, isValidElement } from "react";
303
+ import { cloneElement, isValidElement as isValidElement2 } from "react";
173
304
  import { Pressable as Pressable2, Text as Text2 } from "react-native";
174
305
 
175
306
  // src/components/Dropdown/Item/DropdownItem.styles.ts
@@ -177,6 +308,7 @@ import { StyleSheet as StyleSheet3 } from "react-native";
177
308
  var createStyles3 = (theme) => StyleSheet3.create({
178
309
  item: {
179
310
  minWidth: 0,
311
+ minHeight: 44,
180
312
  alignItems: "center",
181
313
  flexDirection: "row",
182
314
  gap: theme.tokens.spacing[4],
@@ -235,7 +367,7 @@ function DropdownItem({
235
367
  const { theme } = useTheme();
236
368
  const styles = useThemeStyles(createStyles3);
237
369
  const renderColoredNode = (node, color) => {
238
- if (!isValidElement(node)) return node;
370
+ if (!isValidElement2(node)) return node;
239
371
  return cloneElement(node, { color });
240
372
  };
241
373
  const getContentColor = (pressed) => {
@@ -320,7 +452,7 @@ DropdownSeparator.displayName = "DropdownSeparator";
320
452
  // src/components/Dropdown/Trigger/DropdownTrigger.tsx
321
453
  import {
322
454
  cloneElement as cloneElement2,
323
- isValidElement as isValidElement2,
455
+ isValidElement as isValidElement3,
324
456
  useEffect,
325
457
  useRef,
326
458
  useState
@@ -431,6 +563,7 @@ import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
431
563
  function DropdownTrigger({
432
564
  label,
433
565
  trigger,
566
+ children,
434
567
  icon,
435
568
  arrowIcon,
436
569
  showArrow = true,
@@ -438,6 +571,7 @@ function DropdownTrigger({
438
571
  disabled = false,
439
572
  isOpen,
440
573
  triggerStyle,
574
+ triggerRef,
441
575
  accessibilityLabel,
442
576
  accessibilityHint,
443
577
  onPress
@@ -485,15 +619,34 @@ function DropdownTrigger({
485
619
  }
486
620
  );
487
621
  }
488
- if (!isValidElement2(node)) return node;
622
+ if (!isValidElement3(node)) return node;
489
623
  return cloneElement2(node, { color });
490
624
  };
491
625
  const contentColor = disabled ? theme.components.dropdown.trigger.disabled.fg : isPressed ? theme.components.dropdown.trigger.hover.fg : theme.components.dropdown.trigger.default.fg;
492
626
  const arrow = arrowIcon ? renderColoredNode(arrowIcon, contentColor) : /* @__PURE__ */ jsx6(ChevronDown, { width: 16, height: 16, color: contentColor });
493
627
  const renderedIcon = icon ? renderColoredNode(icon, contentColor) : null;
628
+ const triggerContent = trigger ?? children;
629
+ if (isValidElement3(triggerContent)) {
630
+ const child = triggerContent;
631
+ const isChildDisabled = disabled || child.props.disabled;
632
+ return cloneElement2(child, {
633
+ ref: triggerRef,
634
+ disabled: isChildDisabled,
635
+ accessibilityLabel: accessibilityLabel ?? (typeof label === "string" ? label : void 0),
636
+ accessibilityHint,
637
+ accessibilityState: { expanded: isOpen, disabled: isChildDisabled },
638
+ onPress: () => {
639
+ child.props.onPress?.();
640
+ if (!isChildDisabled) {
641
+ onPress();
642
+ }
643
+ }
644
+ });
645
+ }
494
646
  return /* @__PURE__ */ jsxs3(
495
647
  Pressable3,
496
648
  {
649
+ ref: triggerRef,
497
650
  disabled,
498
651
  accessibilityRole: "button",
499
652
  accessibilityLabel: accessibilityLabel ?? (typeof label === "string" ? label : void 0),
@@ -513,7 +666,7 @@ function DropdownTrigger({
513
666
  ],
514
667
  children: [
515
668
  hasIcon && /* @__PURE__ */ jsx6(View3, { style: styles.icon, children: renderedIcon }),
516
- !isIconOnly && (trigger ? renderColoredNode(trigger, contentColor) : /* @__PURE__ */ jsx6(
669
+ !isIconOnly && (triggerContent ? renderColoredNode(triggerContent, contentColor) : /* @__PURE__ */ jsx6(
517
670
  Text3,
518
671
  {
519
672
  numberOfLines: 1,
@@ -541,31 +694,38 @@ DropdownTrigger.displayName = "DropdownTrigger";
541
694
 
542
695
  // src/components/Dropdown/Dropdown.styles.ts
543
696
  import { StyleSheet as StyleSheet6 } from "react-native";
544
- var createStyles6 = () => StyleSheet6.create({
697
+ var createStyles6 = (theme) => StyleSheet6.create({
545
698
  root: {
546
699
  alignSelf: "flex-start"
700
+ },
701
+ emptyText: {
702
+ minHeight: 44,
703
+ paddingHorizontal: theme.tokens.spacing[3],
704
+ paddingVertical: theme.tokens.spacing[3],
705
+ color: theme.components.dropdown.item.disabled.fg,
706
+ fontFamily: theme.tokens.typography.family.regular,
707
+ fontSize: theme.tokens.typography.size.md,
708
+ lineHeight: theme.tokens.typography.lineHeight.md
547
709
  }
548
710
  });
549
711
 
550
- // src/components/Dropdown/types.ts
551
- var isMenuItem = (item) => item.type === void 0 || item.type === "item";
552
- var isGroup = (item) => item.type === "group";
553
- var isSeparator = (item) => item.type === "separator";
554
-
555
712
  // src/components/Dropdown/Dropdown.tsx
556
713
  import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
557
- function Dropdown({
714
+ function DropdownRoot({
715
+ children,
558
716
  label = "Menu",
559
717
  trigger,
560
718
  icon,
561
719
  arrowIcon,
562
720
  showArrow = true,
563
- items,
564
- onSelect,
565
721
  open,
566
722
  defaultOpen = false,
567
723
  onOpenChange,
724
+ presentation = "auto",
725
+ closeOnSelect = true,
568
726
  disabled = false,
727
+ loading = false,
728
+ loadingText = "Loading actions...",
569
729
  size = "md",
570
730
  style,
571
731
  triggerStyle,
@@ -576,13 +736,21 @@ function Dropdown({
576
736
  accessibilityHint
577
737
  }) {
578
738
  const styles = useThemeStyles(createStyles6);
739
+ const { width } = useWindowDimensions();
740
+ const triggerRef = useRef2(null);
741
+ const parsed = useMemo3(() => parseDropdownChildren(children), [children]);
742
+ const resolvedPresentation = presentation === "auto" ? width < 768 ? "sheet" : "popover" : presentation;
579
743
  const menuAccessibilityLabel = useMemo3(() => {
580
744
  if (accessibilityLabel) return accessibilityLabel;
581
745
  return typeof label === "string" ? label : "Menu";
582
746
  }, [accessibilityLabel, label]);
583
747
  const navigableItems = useMemo3(
584
- () => items.filter((item) => isMenuItem(item)),
585
- [items]
748
+ () => parsed.items.map((item) => ({
749
+ disabled: item.disabled,
750
+ label: item.label,
751
+ value: item.id
752
+ })),
753
+ [parsed.items]
586
754
  );
587
755
  const { isOpen, closeDropdown, toggleDropdown } = useDropdown({
588
756
  items: navigableItems,
@@ -590,32 +758,96 @@ function Dropdown({
590
758
  defaultOpen,
591
759
  disabled,
592
760
  onOpenChange,
593
- onSelect,
594
761
  getItemValue: (item) => item.value,
595
762
  getItemText: (item) => typeof item.label === "string" ? item.label : item.value
596
763
  });
764
+ useEffect2(() => {
765
+ if (!isOpen) return;
766
+ AccessibilityInfo.announceForAccessibility(
767
+ `${menuAccessibilityLabel} opened`
768
+ );
769
+ }, [isOpen, menuAccessibilityLabel]);
770
+ const focusTrigger = useCallback(() => {
771
+ if (typeof findNodeHandle !== "function") return;
772
+ const handle = findNodeHandle(triggerRef.current);
773
+ if (handle && AccessibilityInfo.setAccessibilityFocus) {
774
+ AccessibilityInfo.setAccessibilityFocus(handle);
775
+ }
776
+ }, []);
777
+ const closeAndFocusTrigger = useCallback(() => {
778
+ closeDropdown();
779
+ requestAnimationFrame(focusTrigger);
780
+ }, [closeDropdown, focusTrigger]);
597
781
  const handleSelect = useCallback(
598
- (value) => {
599
- onSelect?.(value);
600
- closeDropdown();
782
+ (entry) => {
783
+ if (entry.disabled || loading) return;
784
+ const event = createDropdownSelectEvent();
785
+ entry.props.onSelect?.(event);
786
+ const shouldClose = entry.props.closeOnSelect ?? closeOnSelect;
787
+ if (!event.defaultPrevented && shouldClose) {
788
+ closeAndFocusTrigger();
789
+ }
601
790
  },
602
- [closeDropdown, onSelect]
791
+ [closeAndFocusTrigger, closeOnSelect, loading]
603
792
  );
604
793
  const handleTriggerPress = useCallback(() => {
605
794
  toggleDropdown();
606
795
  }, [toggleDropdown]);
796
+ const renderEntry = useCallback(
797
+ ({ item }) => {
798
+ if (item.type === "label") {
799
+ return /* @__PURE__ */ jsx7(DropdownGroup, { label: item.props.children });
800
+ }
801
+ if (item.type === "separator") {
802
+ return /* @__PURE__ */ jsx7(DropdownSeparator, {});
803
+ }
804
+ if (item.type === "empty") {
805
+ return /* @__PURE__ */ jsx7(Text4, { style: styles.emptyText, children: item.props.children });
806
+ }
807
+ if (item.type === "loading") {
808
+ return /* @__PURE__ */ jsx7(Text4, { style: styles.emptyText, children: item.props.children });
809
+ }
810
+ return /* @__PURE__ */ jsx7(
811
+ DropdownItem,
812
+ {
813
+ label: item.props.children,
814
+ value: item.props.value ?? item.id,
815
+ icon: item.props.icon,
816
+ danger: item.props.danger,
817
+ disabled: item.props.disabled,
818
+ textWrap: item.props.textWrap,
819
+ itemStyle,
820
+ textStyle,
821
+ onSelect: () => handleSelect(item)
822
+ }
823
+ );
824
+ },
825
+ [handleSelect, itemStyle, styles.emptyText, textStyle]
826
+ );
827
+ const data = loading ? [
828
+ {
829
+ type: "loading",
830
+ id: "loading",
831
+ props: { children: loadingText }
832
+ }
833
+ ] : parsed.entries;
834
+ const contentStyleFromSlot = parsed.contentProps?.style;
835
+ const presentationFromSlot = parsed.contentProps?.presentation === "auto" ? void 0 : parsed.contentProps?.presentation;
607
836
  return /* @__PURE__ */ jsxs4(View4, { style: [styles.root, style], children: [
608
837
  /* @__PURE__ */ jsx7(
609
838
  DropdownTrigger,
610
839
  {
611
840
  label,
612
- trigger,
841
+ trigger: trigger ?? parsed.trigger,
613
842
  icon,
614
843
  arrowIcon,
615
844
  showArrow,
616
- disabled,
845
+ disabled: disabled || parsed.triggerProps?.disabled,
617
846
  isOpen,
618
847
  size,
848
+ triggerRef: (node) => {
849
+ triggerRef.current = node;
850
+ },
619
851
  triggerStyle,
620
852
  accessibilityLabel,
621
853
  accessibilityHint,
@@ -626,50 +858,82 @@ function Dropdown({
626
858
  DropdownContent,
627
859
  {
628
860
  isOpen,
629
- onClose: closeDropdown,
630
- contentStyle,
861
+ onClose: closeAndFocusTrigger,
862
+ contentStyle: [contentStyle, contentStyleFromSlot],
631
863
  accessibilityLabel: menuAccessibilityLabel,
632
- children: items.map((item, index) => {
633
- if (isGroup(item)) {
634
- return /* @__PURE__ */ jsx7(
635
- DropdownGroup,
636
- {
637
- label: item.label
638
- },
639
- `group-${item.label}-${index}`
640
- );
641
- }
642
- if (isSeparator(item)) {
643
- return /* @__PURE__ */ jsx7(DropdownSeparator, {}, `separator-${index}`);
644
- }
645
- if (!isMenuItem(item)) {
646
- return null;
864
+ presentation: presentationFromSlot ?? resolvedPresentation,
865
+ children: /* @__PURE__ */ jsx7(
866
+ FlatList,
867
+ {
868
+ data,
869
+ keyExtractor: (item) => item.id,
870
+ renderItem: renderEntry,
871
+ keyboardShouldPersistTaps: "handled",
872
+ removeClippedSubviews: data.length > 24
647
873
  }
648
- return /* @__PURE__ */ jsx7(
649
- DropdownItem,
650
- {
651
- label: item.label,
652
- value: item.value,
653
- icon: item.icon,
654
- danger: item.danger,
655
- disabled: item.disabled,
656
- textWrap: item.textWrap,
657
- itemStyle,
658
- textStyle,
659
- onSelect: handleSelect
660
- },
661
- `${item.value}-${index}`
662
- );
663
- })
874
+ )
664
875
  }
665
876
  )
666
877
  ] });
667
878
  }
668
- Dropdown.displayName = "Dropdown";
879
+ DropdownRoot.displayName = "Dropdown";
880
+ function createDropdownSelectEvent() {
881
+ let defaultPrevented = false;
882
+ return {
883
+ preventDefault: () => {
884
+ defaultPrevented = true;
885
+ },
886
+ get defaultPrevented() {
887
+ return defaultPrevented;
888
+ }
889
+ };
890
+ }
891
+ var DropdownTriggerSlot = createDropdownSlot(
892
+ "trigger",
893
+ "Dropdown.Trigger"
894
+ );
895
+ var DropdownContentSlot = createDropdownSlot(
896
+ "content",
897
+ "Dropdown.Content"
898
+ );
899
+ var DropdownItemSlot = createDropdownSlot(
900
+ "item",
901
+ "Dropdown.Item"
902
+ );
903
+ var DropdownGroupSlot = createDropdownSlot(
904
+ "group",
905
+ "Dropdown.Group"
906
+ );
907
+ var DropdownLabelSlot = createDropdownSlot(
908
+ "label",
909
+ "Dropdown.Label"
910
+ );
911
+ var DropdownSeparatorSlot = createDropdownSlot(
912
+ "separator",
913
+ "Dropdown.Separator"
914
+ );
915
+ var DropdownEmptySlot = createDropdownSlot(
916
+ "empty",
917
+ "Dropdown.Empty"
918
+ );
919
+ var DropdownLoadingSlot = createDropdownSlot(
920
+ "loading",
921
+ "Dropdown.Loading"
922
+ );
923
+ var Dropdown = Object.assign(DropdownRoot, {
924
+ Trigger: DropdownTriggerSlot,
925
+ Content: DropdownContentSlot,
926
+ Item: DropdownItemSlot,
927
+ Group: DropdownGroupSlot,
928
+ Label: DropdownLabelSlot,
929
+ Separator: DropdownSeparatorSlot,
930
+ Empty: DropdownEmptySlot,
931
+ Loading: DropdownLoadingSlot
932
+ });
669
933
 
670
934
  // src/components/Modal/Body/ModalBody.tsx
671
- import { Children, cloneElement as cloneElement3, isValidElement as isValidElement3 } from "react";
672
- import { Text as Text4, View as View5 } from "react-native";
935
+ import { Children as Children2, cloneElement as cloneElement3, isValidElement as isValidElement4 } from "react";
936
+ import { Text as Text5, View as View5 } from "react-native";
673
937
 
674
938
  // src/components/Modal/Body/ModalBody.styles.ts
675
939
  import { StyleSheet as StyleSheet7 } from "react-native";
@@ -693,10 +957,10 @@ var createStyles7 = (theme) => StyleSheet7.create({
693
957
 
694
958
  // src/components/Modal/Body/ModalBody.tsx
695
959
  import { jsx as jsx8 } from "react/jsx-runtime";
696
- var isTextElement = (child) => isValidElement3(child) && child.type === Text4;
697
- var renderBodyChildren = (children, textStyle) => Children.map(children, (child) => {
960
+ var isTextElement = (child) => isValidElement4(child) && child.type === Text5;
961
+ var renderBodyChildren = (children, textStyle) => Children2.map(children, (child) => {
698
962
  if (typeof child === "string" || typeof child === "number") {
699
- return /* @__PURE__ */ jsx8(Text4, { style: textStyle, children: child });
963
+ return /* @__PURE__ */ jsx8(Text5, { style: textStyle, children: child });
700
964
  }
701
965
  if (!isTextElement(child)) {
702
966
  return child;
@@ -770,7 +1034,7 @@ ModalFooter.displayName = "ModalFooter";
770
1034
 
771
1035
  // src/components/Modal/Header/ModalHeader.tsx
772
1036
  import { Close } from "@vellira-ui/icons";
773
- import { Pressable as Pressable4, Text as Text5, View as View8 } from "react-native";
1037
+ import { Pressable as Pressable4, Text as Text6, View as View8 } from "react-native";
774
1038
 
775
1039
  // src/components/Modal/ModalContext.tsx
776
1040
  import { createContext as createContext2, useContext as useContext2 } from "react";
@@ -829,7 +1093,7 @@ var ModalHeader = ({
829
1093
  const styles = useThemeStyles(createStyles10);
830
1094
  const { onClose } = useModalContext();
831
1095
  return /* @__PURE__ */ jsxs5(View8, { style: [styles.header, style], children: [
832
- /* @__PURE__ */ jsx11(Text5, { style: [styles.title, textStyle], children }),
1096
+ /* @__PURE__ */ jsx11(Text6, { style: [styles.title, textStyle], children }),
833
1097
  onClose && /* @__PURE__ */ jsx11(
834
1098
  Pressable4,
835
1099
  {
@@ -945,7 +1209,7 @@ import { View as View11 } from "react-native";
945
1209
 
946
1210
  // src/patterns/FormField/FormField.tsx
947
1211
  import { useId } from "react";
948
- import { Text as Text6, View as View10 } from "react-native";
1212
+ import { Text as Text7, View as View10 } from "react-native";
949
1213
 
950
1214
  // src/patterns/FormField/FormField.styles.ts
951
1215
  import { StyleSheet as StyleSheet12 } from "react-native";
@@ -1072,7 +1336,7 @@ function FormField({
1072
1336
  style: [styles.root, { gap: sizeTokens.gap }, style],
1073
1337
  children: [
1074
1338
  label && (typeof label === "string" || typeof label === "number" ? /* @__PURE__ */ jsxs7(
1075
- Text6,
1339
+ Text7,
1076
1340
  {
1077
1341
  style: [
1078
1342
  styles.label,
@@ -1086,7 +1350,7 @@ function FormField({
1086
1350
  children: [
1087
1351
  label,
1088
1352
  required && /* @__PURE__ */ jsx14(
1089
- Text6,
1353
+ Text7,
1090
1354
  {
1091
1355
  style: styles.required,
1092
1356
  accessible: false,
@@ -1095,7 +1359,7 @@ function FormField({
1095
1359
  }
1096
1360
  ),
1097
1361
  !required && optionalText && /* @__PURE__ */ jsx14(
1098
- Text6,
1362
+ Text7,
1099
1363
  {
1100
1364
  style: [
1101
1365
  styles.optional,
@@ -1108,7 +1372,7 @@ function FormField({
1108
1372
  }
1109
1373
  ),
1110
1374
  labelInfo && /* @__PURE__ */ jsx14(
1111
- Text6,
1375
+ Text7,
1112
1376
  {
1113
1377
  style: [
1114
1378
  styles.labelInfo,
@@ -1125,7 +1389,7 @@ function FormField({
1125
1389
  ) : /* @__PURE__ */ jsxs7(View10, { style: styles.customLabel, children: [
1126
1390
  label,
1127
1391
  required && /* @__PURE__ */ jsx14(
1128
- Text6,
1392
+ Text7,
1129
1393
  {
1130
1394
  style: styles.required,
1131
1395
  accessible: false,
@@ -1137,7 +1401,7 @@ function FormField({
1137
1401
  labelInfo
1138
1402
  ] })),
1139
1403
  description && (typeof description === "string" || typeof description === "number" ? /* @__PURE__ */ jsx14(
1140
- Text6,
1404
+ Text7,
1141
1405
  {
1142
1406
  style: [
1143
1407
  styles.description,
@@ -1153,7 +1417,7 @@ function FormField({
1153
1417
  ) : description),
1154
1418
  /* @__PURE__ */ jsx14(FormFieldContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx14(View10, { style: [styles.control, { gap: sizeTokens.gap }, controlStyle], children }) }),
1155
1419
  error && (typeof error === "string" || typeof error === "number" ? /* @__PURE__ */ jsx14(
1156
- Text6,
1420
+ Text7,
1157
1421
  {
1158
1422
  accessibilityLiveRegion: "polite",
1159
1423
  style: [
@@ -1289,14 +1553,14 @@ var RadioGroup = forwardRef(
1289
1553
  RadioGroup.displayName = "RadioGroup";
1290
1554
 
1291
1555
  // src/components/Select/Content/SelectContent.tsx
1292
- import { useEffect as useEffect3, useRef as useRef2, useState as useState2 } from "react";
1293
- import { FlatList, Pressable as Pressable10, Text as Text11, View as View21 } from "react-native";
1556
+ import { useEffect as useEffect4, useRef as useRef3, useState as useState2 } from "react";
1557
+ import { FlatList as FlatList2, Pressable as Pressable10, Text as Text12, View as View21 } from "react-native";
1294
1558
 
1295
1559
  // src/components/Select/Group/SelectGroup.tsx
1296
- import { Pressable as Pressable6, Text as Text7 } from "react-native";
1560
+ import { Pressable as Pressable6, Text as Text8 } from "react-native";
1297
1561
 
1298
1562
  // src/components/Select/internal/SelectCollection.ts
1299
- import { Children as Children2, isValidElement as isValidElement4 } from "react";
1563
+ import { Children as Children3, isValidElement as isValidElement5 } from "react";
1300
1564
 
1301
1565
  // src/components/Select/internal/types.ts
1302
1566
  var selectSlotName = /* @__PURE__ */ Symbol("VelliraNativeSelectSlot");
@@ -1319,8 +1583,8 @@ var getTextFromNode = (node) => {
1319
1583
  var getGroupLabel = (props) => {
1320
1584
  if (props.label) return props.label;
1321
1585
  let label;
1322
- Children2.forEach(props.children, (child) => {
1323
- if (label || !isValidElement4(child)) return;
1586
+ Children3.forEach(props.children, (child) => {
1587
+ if (label || !isValidElement5(child)) return;
1324
1588
  if (getSelectSlot(child.type) === "label") {
1325
1589
  label = getTextFromNode(child.props.children);
1326
1590
  }
@@ -1330,8 +1594,8 @@ var getGroupLabel = (props) => {
1330
1594
  var getGroupItemValues = (children) => {
1331
1595
  const values = [];
1332
1596
  const visit = (node) => {
1333
- Children2.forEach(node, (child) => {
1334
- if (!isValidElement4(child)) return;
1597
+ Children3.forEach(node, (child) => {
1598
+ if (!isValidElement5(child)) return;
1335
1599
  const slot = getSelectSlot(child.type);
1336
1600
  if (slot === "content") {
1337
1601
  visit(child.props.children);
@@ -1357,8 +1621,8 @@ var parseSelectChildren = (children) => {
1357
1621
  let empty;
1358
1622
  let loading;
1359
1623
  const visit = (node, group) => {
1360
- Children2.forEach(node, (child) => {
1361
- if (!isValidElement4(child)) return;
1624
+ Children3.forEach(node, (child) => {
1625
+ if (!isValidElement5(child)) return;
1362
1626
  const slot = getSelectSlot(child.type);
1363
1627
  if (slot === "content") {
1364
1628
  visit(child.props.children, group);
@@ -1477,7 +1741,7 @@ var SelectGroup = createSelectSlot(
1477
1741
  );
1478
1742
  var SelectGroupLabelRow = ({ label }) => {
1479
1743
  const styles = useThemeStyles(createGroupStyles);
1480
- return /* @__PURE__ */ jsx16(Text7, { style: styles.groupLabel, children: label });
1744
+ return /* @__PURE__ */ jsx16(Text8, { style: styles.groupLabel, children: label });
1481
1745
  };
1482
1746
  var SelectGroupActionRow = ({
1483
1747
  label,
@@ -1505,8 +1769,8 @@ var SelectGroupActionRow = ({
1505
1769
  onPress,
1506
1770
  style: styles.groupAction,
1507
1771
  children: [
1508
- /* @__PURE__ */ jsx16(Text7, { style: styles.groupActionText, children: resolvedLabel }),
1509
- /* @__PURE__ */ jsxs8(Text7, { style: styles.groupActionMeta, children: [
1772
+ /* @__PURE__ */ jsx16(Text8, { style: styles.groupActionText, children: resolvedLabel }),
1773
+ /* @__PURE__ */ jsxs8(Text8, { style: styles.groupActionMeta, children: [
1510
1774
  selectedCount,
1511
1775
  "/",
1512
1776
  itemCount
@@ -1549,9 +1813,9 @@ var useSelectContext = () => {
1549
1813
  };
1550
1814
 
1551
1815
  // src/components/Select/Item/SelectItem.tsx
1552
- import { cloneElement as cloneElement4, isValidElement as isValidElement5 } from "react";
1816
+ import { cloneElement as cloneElement4, isValidElement as isValidElement6 } from "react";
1553
1817
  import { Check } from "@vellira-ui/icons";
1554
- import { Pressable as Pressable7, Text as Text8, View as View13 } from "react-native";
1818
+ import { Pressable as Pressable7, Text as Text9, View as View13 } from "react-native";
1555
1819
 
1556
1820
  // src/components/Select/Item/SelectItem.styles.ts
1557
1821
  import { StyleSheet as StyleSheet15 } from "react-native";
@@ -1616,14 +1880,14 @@ var createItemStyles = (theme) => StyleSheet15.create({
1616
1880
  import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs9 } from "react/jsx-runtime";
1617
1881
  var renderNodeOrText = (node, textStyle, fallback) => {
1618
1882
  if (typeof node === "string" || typeof node === "number") {
1619
- return /* @__PURE__ */ jsx18(Text8, { style: textStyle, children: node });
1883
+ return /* @__PURE__ */ jsx18(Text9, { style: textStyle, children: node });
1620
1884
  }
1621
- if (isValidElement5(node) && node.type === Text8) {
1885
+ if (isValidElement6(node) && node.type === Text9) {
1622
1886
  return cloneElement4(node, {
1623
1887
  style: [textStyle, node.props.style]
1624
1888
  });
1625
1889
  }
1626
- return node ?? (fallback ? /* @__PURE__ */ jsx18(Text8, { style: textStyle, children: fallback }) : null);
1890
+ return node ?? (fallback ? /* @__PURE__ */ jsx18(Text9, { style: textStyle, children: fallback }) : null);
1627
1891
  };
1628
1892
  var SelectItem = createSelectSlot(
1629
1893
  "item",
@@ -1640,8 +1904,13 @@ var SelectItemRow = ({
1640
1904
  const styles = useThemeStyles(createItemStyles);
1641
1905
  const { color, variant, renderOption } = useSelectContext();
1642
1906
  const optionPalette = theme.components.select[option.color ?? color][variant].option;
1643
- const optionState = isSelected ? theme.components.select.option.selected : optionPalette.hover;
1644
- const optionFg = isDisabled ? theme.components.select.option.disabled.fg : isSelected ? optionState.fg : theme.components.select.option.default.fg;
1907
+ const getOptionState = (pressed) => {
1908
+ if (isDisabled) return theme.components.select.option.disabled;
1909
+ if (isSelected) {
1910
+ return pressed ? optionPalette.selectedPressed : optionPalette.selected;
1911
+ }
1912
+ return pressed ? optionPalette.pressed : theme.components.select.option.default;
1913
+ };
1645
1914
  return /* @__PURE__ */ jsx18(
1646
1915
  Pressable7,
1647
1916
  {
@@ -1654,58 +1923,73 @@ var SelectItemRow = ({
1654
1923
  disabled: isDisabled
1655
1924
  },
1656
1925
  onPress: () => onSelect(option),
1657
- style: [
1658
- styles.option,
1659
- {
1660
- backgroundColor: isSelected ? optionState.bg : theme.components.select.option.default.bg,
1661
- borderColor: isSelected ? optionState.border : "transparent"
1662
- },
1663
- isDisabled && styles.optionDisabled,
1664
- optionStyle
1665
- ],
1666
- children: renderOption ? renderNodeOrText(
1667
- renderOption(option, {
1668
- selected: isSelected,
1669
- disabled: isDisabled
1670
- }),
1671
- [styles.optionLabel, { color: optionFg }]
1672
- ) : /* @__PURE__ */ jsxs9(Fragment2, { children: [
1673
- option.icon && /* @__PURE__ */ jsx18(View13, { style: styles.optionIcon, children: isValidElement5(option.icon) ? cloneElement4(
1674
- option.icon,
1926
+ style: ({ pressed }) => {
1927
+ const optionState = getOptionState(pressed);
1928
+ return [
1929
+ styles.option,
1675
1930
  {
1676
- color: optionFg,
1677
- size: 18
1678
- }
1679
- ) : option.icon }),
1680
- /* @__PURE__ */ jsxs9(View13, { style: styles.optionTextWrap, children: [
1681
- /* @__PURE__ */ jsx18(
1682
- Text8,
1931
+ backgroundColor: optionState.bg,
1932
+ borderColor: optionState.border
1933
+ },
1934
+ isDisabled && styles.optionDisabled,
1935
+ optionStyle
1936
+ ];
1937
+ },
1938
+ children: ({ pressed }) => {
1939
+ const optionState = getOptionState(pressed);
1940
+ const optionFg = optionState.fg;
1941
+ const descriptionFg = isSelected || pressed ? optionFg : theme.components.select.option.description.fg;
1942
+ return renderOption ? renderNodeOrText(
1943
+ renderOption(option, {
1944
+ selected: isSelected,
1945
+ disabled: isDisabled
1946
+ }),
1947
+ [styles.optionLabel, { color: optionFg }]
1948
+ ) : /* @__PURE__ */ jsxs9(Fragment2, { children: [
1949
+ option.icon && /* @__PURE__ */ jsx18(View13, { style: styles.optionIcon, children: isValidElement6(option.icon) ? cloneElement4(
1950
+ option.icon,
1683
1951
  {
1684
- numberOfLines: 1,
1685
- style: [styles.optionLabel, { color: optionFg }],
1686
- children: option.label
1952
+ color: optionFg,
1953
+ size: 18
1687
1954
  }
1688
- ),
1689
- option.description && /* @__PURE__ */ jsx18(Text8, { numberOfLines: 2, style: styles.optionDescription, children: option.description })
1690
- ] }),
1691
- option.badge && /* @__PURE__ */ jsx18(
1692
- View13,
1693
- {
1694
- style: [
1695
- styles.badge,
1955
+ ) : option.icon }),
1956
+ /* @__PURE__ */ jsxs9(View13, { style: styles.optionTextWrap, children: [
1957
+ /* @__PURE__ */ jsx18(
1958
+ Text9,
1696
1959
  {
1697
- backgroundColor: optionPalette.badge.bg,
1698
- borderColor: optionPalette.badge.border
1960
+ numberOfLines: 1,
1961
+ style: [styles.optionLabel, { color: optionFg }],
1962
+ children: option.label
1699
1963
  }
1700
- ],
1701
- children: renderNodeOrText(option.badge, [
1702
- styles.badgeText,
1703
- { color: optionPalette.badge.fg }
1704
- ])
1705
- }
1706
- ),
1707
- isSelected && /* @__PURE__ */ jsx18(View13, { style: styles.check, children: /* @__PURE__ */ jsx18(Check, { width: 16, height: 16, color: optionFg }) })
1708
- ] })
1964
+ ),
1965
+ option.description && /* @__PURE__ */ jsx18(
1966
+ Text9,
1967
+ {
1968
+ numberOfLines: 2,
1969
+ style: [styles.optionDescription, { color: descriptionFg }],
1970
+ children: option.description
1971
+ }
1972
+ )
1973
+ ] }),
1974
+ option.badge && /* @__PURE__ */ jsx18(
1975
+ View13,
1976
+ {
1977
+ style: [
1978
+ styles.badge,
1979
+ {
1980
+ backgroundColor: optionPalette.badge.bg,
1981
+ borderColor: optionPalette.badge.border
1982
+ }
1983
+ ],
1984
+ children: renderNodeOrText(option.badge, [
1985
+ styles.badgeText,
1986
+ { color: optionPalette.badge.fg }
1987
+ ])
1988
+ }
1989
+ ),
1990
+ isSelected && /* @__PURE__ */ jsx18(View13, { style: styles.check, children: /* @__PURE__ */ jsx18(Check, { width: 16, height: 16, color: optionFg }) })
1991
+ ] });
1992
+ }
1709
1993
  }
1710
1994
  );
1711
1995
  };
@@ -2065,11 +2349,11 @@ var createContentStyles = (theme) => StyleSheet17.create({
2065
2349
  });
2066
2350
 
2067
2351
  // src/components/Select/Content/SelectEmpty.tsx
2068
- import { Text as Text9, View as View18 } from "react-native";
2352
+ import { Text as Text10, View as View18 } from "react-native";
2069
2353
  import { jsx as jsx24 } from "react/jsx-runtime";
2070
2354
  var renderText = (node, style) => {
2071
2355
  if (typeof node === "string" || typeof node === "number") {
2072
- return /* @__PURE__ */ jsx24(Text9, { style, children: node });
2356
+ return /* @__PURE__ */ jsx24(Text10, { style, children: node });
2073
2357
  }
2074
2358
  return node;
2075
2359
  };
@@ -2085,11 +2369,11 @@ var SelectEmptyState = () => {
2085
2369
  SelectEmptyState.displayName = "Select.EmptyState";
2086
2370
 
2087
2371
  // src/components/Select/Content/SelectLoading.tsx
2088
- import { ActivityIndicator, Text as Text10, View as View19 } from "react-native";
2372
+ import { ActivityIndicator, Text as Text11, View as View19 } from "react-native";
2089
2373
  import { jsx as jsx25, jsxs as jsxs13 } from "react/jsx-runtime";
2090
2374
  var renderText2 = (node, style) => {
2091
2375
  if (typeof node === "string" || typeof node === "number") {
2092
- return /* @__PURE__ */ jsx25(Text10, { style, children: node });
2376
+ return /* @__PURE__ */ jsx25(Text11, { style, children: node });
2093
2377
  }
2094
2378
  return node;
2095
2379
  };
@@ -2116,7 +2400,7 @@ var SelectLoadingState = () => {
2116
2400
  SelectLoadingState.displayName = "Select.LoadingState";
2117
2401
 
2118
2402
  // src/components/Select/Content/SelectSearch.tsx
2119
- import { useEffect as useEffect2 } from "react";
2403
+ import { useEffect as useEffect3 } from "react";
2120
2404
  import { Close as Close2, Search } from "@vellira-ui/icons";
2121
2405
  import { Pressable as Pressable9, TextInput, View as View20 } from "react-native";
2122
2406
 
@@ -2159,7 +2443,7 @@ var createSearchStyles = (theme) => StyleSheet18.create({
2159
2443
  alignItems: "center",
2160
2444
  justifyContent: "center",
2161
2445
  borderRadius: 999,
2162
- backgroundColor: theme.semantic.status.error.bg
2446
+ backgroundColor: theme.components.select.clearButton.hoverBg
2163
2447
  }
2164
2448
  });
2165
2449
 
@@ -2182,7 +2466,7 @@ var SelectSearchField = () => {
2182
2466
  virtual
2183
2467
  } = useSelectContext();
2184
2468
  const shouldAutoFocus = !virtual || selectedRowIndex === 0;
2185
- useEffect2(() => {
2469
+ useEffect3(() => {
2186
2470
  if (!shouldAutoFocus) return;
2187
2471
  const focusTimer = setTimeout(() => {
2188
2472
  searchInputRef.current?.focus();
@@ -2233,7 +2517,7 @@ var SelectSearchField = () => {
2233
2517
  {
2234
2518
  width: 14,
2235
2519
  height: 14,
2236
- color: theme.semantic.status.error.fg
2520
+ color: theme.components.select.clearButton.hoverFg
2237
2521
  }
2238
2522
  )
2239
2523
  }
@@ -2250,7 +2534,7 @@ var SelectContent = createSelectSlot(
2250
2534
  );
2251
2535
  var SelectContentSurface = () => {
2252
2536
  const styles = useThemeStyles(createContentStyles);
2253
- const wasOpenRef = useRef2(false);
2537
+ const wasOpenRef = useRef3(false);
2254
2538
  const [openCycle, setOpenCycle] = useState2(0);
2255
2539
  const context = useSelectContext();
2256
2540
  const {
@@ -2278,7 +2562,7 @@ var SelectContentSurface = () => {
2278
2562
  } = context;
2279
2563
  const shouldSeedSelectedPosition = Boolean(context.virtual) && selectedRowIndex > 0 && query === "";
2280
2564
  const initialScrollIndex = shouldSeedSelectedPosition ? selectedRowIndex : void 0;
2281
- useEffect3(() => {
2565
+ useEffect4(() => {
2282
2566
  if (isOpen && !wasOpenRef.current) {
2283
2567
  setOpenCycle((cycle) => cycle + 1);
2284
2568
  }
@@ -2339,10 +2623,10 @@ var SelectContentSurface = () => {
2339
2623
  style: styles.toolbarAction,
2340
2624
  accessibilityRole: "button",
2341
2625
  accessibilityLabel: "Close selection",
2342
- children: /* @__PURE__ */ jsx27(Text11, { style: styles.cancelText, children: "Cancel" })
2626
+ children: /* @__PURE__ */ jsx27(Text12, { style: styles.cancelText, children: "Cancel" })
2343
2627
  }
2344
2628
  ),
2345
- /* @__PURE__ */ jsx27(Text11, { style: styles.title, numberOfLines: 1, accessibilityRole: "header", children: resolvedLabel }),
2629
+ /* @__PURE__ */ jsx27(Text12, { style: styles.title, numberOfLines: 1, accessibilityRole: "header", children: resolvedLabel }),
2346
2630
  /* @__PURE__ */ jsx27(
2347
2631
  Pressable10,
2348
2632
  {
@@ -2351,7 +2635,7 @@ var SelectContentSurface = () => {
2351
2635
  style: styles.toolbarAction,
2352
2636
  accessibilityRole: "button",
2353
2637
  accessibilityLabel: "Done",
2354
- children: /* @__PURE__ */ jsx27(Text11, { style: styles.doneText, children: "Done" })
2638
+ children: /* @__PURE__ */ jsx27(Text12, { style: styles.doneText, children: "Done" })
2355
2639
  }
2356
2640
  )
2357
2641
  ]
@@ -2359,7 +2643,7 @@ var SelectContentSurface = () => {
2359
2643
  ),
2360
2644
  searchable && /* @__PURE__ */ jsx27(SelectSearchField, {}),
2361
2645
  loading && filteredRows.length === 0 ? /* @__PURE__ */ jsx27(SelectLoadingState, {}) : filteredRows.length === 0 ? /* @__PURE__ */ jsx27(SelectEmptyState, {}) : /* @__PURE__ */ jsx27(
2362
- FlatList,
2646
+ FlatList2,
2363
2647
  {
2364
2648
  data: filteredRows,
2365
2649
  keyExtractor: (item) => item.key,
@@ -2420,12 +2704,12 @@ var SelectContentSurface = () => {
2420
2704
  SelectContentSurface.displayName = "Select.ContentSurface";
2421
2705
 
2422
2706
  // src/components/Select/Root/SelectRoot.tsx
2423
- import { useMemo as useMemo6, useRef as useRef3, useState as useState4 } from "react";
2707
+ import { useMemo as useMemo6, useRef as useRef4, useState as useState4 } from "react";
2424
2708
  import { useSelect } from "@vellira-ui/core";
2425
2709
  import { View as View23 } from "react-native";
2426
2710
 
2427
2711
  // src/components/Select/internal/useSelectAccessibility.ts
2428
- import { AccessibilityInfo } from "react-native";
2712
+ import { AccessibilityInfo as AccessibilityInfo2 } from "react-native";
2429
2713
  var useSelectAccessibility = ({
2430
2714
  accessibilityLabel,
2431
2715
  accessibilityHint,
@@ -2446,7 +2730,7 @@ var useSelectAccessibility = ({
2446
2730
  resolvedLabel,
2447
2731
  resolvedHint,
2448
2732
  announce: (message) => {
2449
- AccessibilityInfo.announceForAccessibility?.(message);
2733
+ AccessibilityInfo2.announceForAccessibility?.(message);
2450
2734
  }
2451
2735
  };
2452
2736
  };
@@ -2483,9 +2767,9 @@ var useSelectCollection = (children, optionsProp) => {
2483
2767
  };
2484
2768
 
2485
2769
  // src/components/Select/internal/useSelectPresentation.ts
2486
- import { useWindowDimensions } from "react-native";
2770
+ import { useWindowDimensions as useWindowDimensions2 } from "react-native";
2487
2771
  var useSelectPresentation = (presentation = "auto") => {
2488
- const { width } = useWindowDimensions();
2772
+ const { width } = useWindowDimensions2();
2489
2773
  if (presentation === "auto") {
2490
2774
  return width >= 768 ? "popover" : "sheet";
2491
2775
  }
@@ -2493,7 +2777,7 @@ var useSelectPresentation = (presentation = "auto") => {
2493
2777
  };
2494
2778
 
2495
2779
  // src/components/Select/internal/useSelectSearch.ts
2496
- import { useEffect as useEffect4, useMemo as useMemo5, useState as useState3 } from "react";
2780
+ import { useEffect as useEffect5, useMemo as useMemo5, useState as useState3 } from "react";
2497
2781
  var useSelectSearch = ({
2498
2782
  rows,
2499
2783
  isOpen,
@@ -2533,7 +2817,7 @@ var useSelectSearch = ({
2533
2817
  return index > 0 && index < collection.length - 1 && collection[index - 1]?.type !== "separator";
2534
2818
  });
2535
2819
  }, [filter, query, rows, shouldFilter]);
2536
- useEffect4(() => {
2820
+ useEffect5(() => {
2537
2821
  if (!isOpen) {
2538
2822
  setQuery("");
2539
2823
  return;
@@ -2557,9 +2841,9 @@ var SelectIcon = createSelectSlot(
2557
2841
  );
2558
2842
 
2559
2843
  // src/components/Select/Trigger/SelectTrigger.tsx
2560
- import { cloneElement as cloneElement5, isValidElement as isValidElement6 } from "react";
2844
+ import { cloneElement as cloneElement5, isValidElement as isValidElement7 } from "react";
2561
2845
  import { ChevronDown as ChevronDown2, Close as Close3 } from "@vellira-ui/icons";
2562
- import { ActivityIndicator as ActivityIndicator2, Pressable as Pressable11, Text as Text12, View as View22 } from "react-native";
2846
+ import { ActivityIndicator as ActivityIndicator2, Pressable as Pressable11, Text as Text13, View as View22 } from "react-native";
2563
2847
 
2564
2848
  // src/components/Select/Trigger/SelectTrigger.styles.ts
2565
2849
  import { StyleSheet as StyleSheet19 } from "react-native";
@@ -2638,7 +2922,7 @@ var createTriggerStyles = (theme) => StyleSheet19.create({
2638
2922
  alignItems: "center",
2639
2923
  justifyContent: "center",
2640
2924
  borderRadius: 999,
2641
- backgroundColor: theme.semantic.status.error.bg
2925
+ backgroundColor: theme.components.select.clearButton.hoverBg
2642
2926
  }
2643
2927
  });
2644
2928
 
@@ -2687,7 +2971,7 @@ function SelectTrigger({
2687
2971
  };
2688
2972
  const resolvedAccessibilityHint = accessibilityHint ?? (hasError ? "Invalid selection. Opens a list of options" : required ? "Required. Opens a list of options" : "Opens a list of options");
2689
2973
  const iconColor = disabled ? theme.components.select.trigger.disabled.icon : triggerState.icon;
2690
- const renderIcon = (icon) => isValidElement6(icon) ? cloneElement5(icon, { color: iconColor, size: resolvedIconSize }) : null;
2974
+ const renderIcon = (icon) => isValidElement7(icon) ? cloneElement5(icon, { color: iconColor, size: resolvedIconSize }) : null;
2691
2975
  const renderValue = () => {
2692
2976
  const valueStyle = [
2693
2977
  styles.text,
@@ -2700,9 +2984,9 @@ function SelectTrigger({
2700
2984
  textStyle
2701
2985
  ];
2702
2986
  if (typeof displayText === "string" || typeof displayText === "number") {
2703
- return /* @__PURE__ */ jsx28(Text12, { numberOfLines: 1, style: valueStyle, children: displayText });
2987
+ return /* @__PURE__ */ jsx28(Text13, { numberOfLines: 1, style: valueStyle, children: displayText });
2704
2988
  }
2705
- if (isValidElement6(displayText) && displayText.type === Text12) {
2989
+ if (isValidElement7(displayText) && displayText.type === Text13) {
2706
2990
  return cloneElement5(displayText, {
2707
2991
  numberOfLines: displayText.props.numberOfLines ?? 1,
2708
2992
  style: [valueStyle, displayText.props.style]
@@ -2761,9 +3045,9 @@ function SelectTrigger({
2761
3045
  children: renderIcon(startIcon)
2762
3046
  }
2763
3047
  ),
2764
- prefix && /* @__PURE__ */ jsx28(Text12, { style: styles.affix, children: prefix }),
3048
+ prefix && /* @__PURE__ */ jsx28(Text13, { style: styles.affix, children: prefix }),
2765
3049
  /* @__PURE__ */ jsx28(View22, { style: styles.value, children: renderValue() }),
2766
- suffix && /* @__PURE__ */ jsx28(Text12, { style: styles.affix, children: suffix }),
3050
+ suffix && /* @__PURE__ */ jsx28(Text13, { style: styles.affix, children: suffix }),
2767
3051
  loading ? /* @__PURE__ */ jsx28(
2768
3052
  ActivityIndicator2,
2769
3053
  {
@@ -2784,7 +3068,7 @@ function SelectTrigger({
2784
3068
  {
2785
3069
  width: 14,
2786
3070
  height: 14,
2787
- color: theme.semantic.status.error.fg
3071
+ color: theme.components.select.clearButton.hoverFg
2788
3072
  }
2789
3073
  )
2790
3074
  }
@@ -2872,8 +3156,8 @@ function SelectRoot(props) {
2872
3156
  const field = useFormFieldContext();
2873
3157
  const hasOwnField = Boolean(label || description || error);
2874
3158
  const [triggerWidth, setTriggerWidth] = useState4();
2875
- const searchInputRef = useRef3(null);
2876
- const selectedFocusValueRef = useRef3(void 0);
3159
+ const searchInputRef = useRef4(null);
3160
+ const selectedFocusValueRef = useRef4(void 0);
2877
3161
  const resolvedPresentation = useSelectPresentation(presentation);
2878
3162
  const {
2879
3163
  options,
@@ -3284,8 +3568,8 @@ var TabsPanel = ({ index, children, style }) => {
3284
3568
  TabsPanel.displayName = "TabsPanel";
3285
3569
 
3286
3570
  // src/components/Tabs/Tab/Tab.tsx
3287
- import { cloneElement as cloneElement6, isValidElement as isValidElement7 } from "react";
3288
- import { Pressable as Pressable12, Text as Text13, View as View26 } from "react-native";
3571
+ import { cloneElement as cloneElement6, isValidElement as isValidElement8 } from "react";
3572
+ import { Pressable as Pressable12, Text as Text14, View as View26 } from "react-native";
3289
3573
 
3290
3574
  // src/components/Tabs/Tab/Tab.styles.ts
3291
3575
  import { StyleSheet as StyleSheet22 } from "react-native";
@@ -3426,7 +3710,7 @@ var Tab = ({
3426
3710
  const isDefault = appearance === "default";
3427
3711
  const isVertical = orientation === "vertical";
3428
3712
  const iconColor = isPills && isActive ? theme.components.tabs.pills.active.fg : isActive ? theme.components.tabs.trigger.active.fg : theme.components.tabs.trigger.default.fg;
3429
- const renderedIcon = isValidElement7(icon) ? cloneElement6(icon, {
3713
+ const renderedIcon = isValidElement8(icon) ? cloneElement6(icon, {
3430
3714
  color: iconColor
3431
3715
  }) : icon;
3432
3716
  return /* @__PURE__ */ jsx32(
@@ -3474,7 +3758,7 @@ var Tab = ({
3474
3758
  ),
3475
3759
  icon != null && /* @__PURE__ */ jsx32(View26, { style: styles.tabIcon, children: renderedIcon }),
3476
3760
  children != null && /* @__PURE__ */ jsx32(
3477
- Text13,
3761
+ Text14,
3478
3762
  {
3479
3763
  numberOfLines: 2,
3480
3764
  ellipsizeMode: "tail",
@@ -3559,20 +3843,20 @@ var Tabs = Object.assign(TabsRoot, {
3559
3843
  });
3560
3844
 
3561
3845
  // src/components/Tooltip/Tooltip.tsx
3562
- import { useEffect as useEffect5, useRef as useRef5, useState as useState6 } from "react";
3563
- import { Modal as Modal6, Pressable as Pressable13, Text as Text14, View as View28 } from "react-native";
3846
+ import { useEffect as useEffect6, useRef as useRef6, useState as useState6 } from "react";
3847
+ import { Modal as Modal6, Pressable as Pressable13, Text as Text15, View as View28 } from "react-native";
3564
3848
 
3565
3849
  // src/hooks/useNativeFloatingPosition.ts
3566
- import { useCallback as useCallback2, useRef as useRef4, useState as useState5 } from "react";
3850
+ import { useCallback as useCallback2, useRef as useRef5, useState as useState5 } from "react";
3567
3851
  import { Dimensions } from "react-native";
3568
3852
  var safePadding = 12;
3569
3853
  function useNativeFloatingPosition(placement = "top", offset = 8) {
3570
3854
  const [position, setPosition] = useState5({ top: 0, left: 0 });
3571
- const floatingSizeRef = useRef4({
3855
+ const floatingSizeRef = useRef5({
3572
3856
  width: 0,
3573
3857
  height: 0
3574
3858
  });
3575
- const lastTriggerRef = useRef4(null);
3859
+ const lastTriggerRef = useRef5(null);
3576
3860
  const clamp = useCallback2((value, min, max) => {
3577
3861
  return Math.min(Math.max(value, min), Math.max(min, max));
3578
3862
  }, []);
@@ -3681,8 +3965,8 @@ function Tooltip({
3681
3965
  }) {
3682
3966
  const styles = useThemeStyles(createStyles18);
3683
3967
  const [visible, setVisible] = useState6(false);
3684
- const triggerRef = useRef5(null);
3685
- const closeTimerRef = useRef5(null);
3968
+ const triggerRef = useRef6(null);
3969
+ const closeTimerRef = useRef6(null);
3686
3970
  const { position, updatePosition, onFloatingLayout } = useNativeFloatingPosition(placement, 8);
3687
3971
  const hideDelay = delay?.close ?? 2500;
3688
3972
  const clearCloseTimer = () => {
@@ -3701,7 +3985,7 @@ function Tooltip({
3701
3985
  closeTimerRef.current = null;
3702
3986
  }, hideDelay);
3703
3987
  };
3704
- useEffect5(() => {
3988
+ useEffect6(() => {
3705
3989
  return clearCloseTimer;
3706
3990
  }, []);
3707
3991
  return /* @__PURE__ */ jsxs19(View28, { style: [styles.root, style], children: [
@@ -3728,7 +4012,7 @@ function Tooltip({
3728
4012
  contentStyle
3729
4013
  ],
3730
4014
  onLayout: onFloatingLayout,
3731
- children: typeof content === "string" ? /* @__PURE__ */ jsx34(Text14, { style: [styles.text, textStyle], children: content }) : content
4015
+ children: typeof content === "string" ? /* @__PURE__ */ jsx34(Text15, { style: [styles.text, textStyle], children: content }) : content
3732
4016
  }
3733
4017
  )
3734
4018
  }
@@ -3739,7 +4023,7 @@ Tooltip.displayName = "Tooltip";
3739
4023
 
3740
4024
  // src/primitives/Button/Button.tsx
3741
4025
  import { cloneElement as cloneElement7, useState as useState7 } from "react";
3742
- import { ActivityIndicator as ActivityIndicator3, Pressable as Pressable14, Text as Text15, View as View29 } from "react-native";
4026
+ import { ActivityIndicator as ActivityIndicator3, Pressable as Pressable14, Text as Text16, View as View29 } from "react-native";
3743
4027
 
3744
4028
  // src/utils/devWarning.ts
3745
4029
  var devWarning = (condition, message) => {
@@ -3953,7 +4237,7 @@ function Button({
3953
4237
  !loading && iconStart && renderIcon(iconStart, contentColor),
3954
4238
  content && !iconOnly && /* @__PURE__ */ jsxs20(View29, { style: styles.labelSlot, children: [
3955
4239
  /* @__PURE__ */ jsx35(
3956
- Text15,
4240
+ Text16,
3957
4241
  {
3958
4242
  onLayout: handleLabelLayout,
3959
4243
  style: [
@@ -3969,7 +4253,7 @@ function Button({
3969
4253
  }
3970
4254
  ),
3971
4255
  measureLabel && /* @__PURE__ */ jsx35(
3972
- Text15,
4256
+ Text16,
3973
4257
  {
3974
4258
  accessibilityElementsHidden: true,
3975
4259
  importantForAccessibility: "no-hide-descendants",
@@ -3987,7 +4271,7 @@ function Button({
3987
4271
  )
3988
4272
  ] }),
3989
4273
  badge && !iconOnly && /* @__PURE__ */ jsx35(
3990
- Text15,
4274
+ Text16,
3991
4275
  {
3992
4276
  style: [
3993
4277
  styles.badge,
@@ -4000,7 +4284,7 @@ function Button({
4000
4284
  }
4001
4285
  ),
4002
4286
  shortcut && !iconOnly && /* @__PURE__ */ jsx35(
4003
- Text15,
4287
+ Text16,
4004
4288
  {
4005
4289
  style: [
4006
4290
  styles.shortcut,
@@ -4019,10 +4303,10 @@ function Button({
4019
4303
  }
4020
4304
 
4021
4305
  // src/primitives/Checkbox/Checkbox.tsx
4022
- import { forwardRef as forwardRef2, useEffect as useEffect6 } from "react";
4306
+ import { forwardRef as forwardRef2, useEffect as useEffect7 } from "react";
4023
4307
  import { useControllableState as useControllableState3 } from "@vellira-ui/core";
4024
4308
  import { Check as Check2 } from "@vellira-ui/icons";
4025
- import { Pressable as Pressable15, Text as Text16, View as View30 } from "react-native";
4309
+ import { Pressable as Pressable15, Text as Text17, View as View30 } from "react-native";
4026
4310
 
4027
4311
  // src/primitives/Checkbox/Checkbox.styles.ts
4028
4312
  import { StyleSheet as StyleSheet26 } from "react-native";
@@ -4227,7 +4511,7 @@ var Checkbox = forwardRef2(
4227
4511
  const resolvedAccessibilityLabel = accessibilityLabel ?? label;
4228
4512
  const resolvedAccessibilityHint = [accessibilityHint, description, error].filter(Boolean).join(" ");
4229
4513
  const accessibilityChecked = indeterminate ? "mixed" : isChecked;
4230
- useEffect6(() => {
4514
+ useEffect7(() => {
4231
4515
  devWarning(
4232
4516
  Boolean(resolvedAccessibilityLabel),
4233
4517
  "Checkbox: an accessible label must be provided through label or accessibilityLabel."
@@ -4291,7 +4575,7 @@ var Checkbox = forwardRef2(
4291
4575
  }
4292
4576
  ),
4293
4577
  label && /* @__PURE__ */ jsxs21(
4294
- Text16,
4578
+ Text17,
4295
4579
  {
4296
4580
  style: [
4297
4581
  styles.label,
@@ -4304,7 +4588,7 @@ var Checkbox = forwardRef2(
4304
4588
  ],
4305
4589
  children: [
4306
4590
  label,
4307
- required && /* @__PURE__ */ jsx36(Text16, { style: styles.requiredMark, children: " *" })
4591
+ required && /* @__PURE__ */ jsx36(Text17, { style: styles.requiredMark, children: " *" })
4308
4592
  ]
4309
4593
  }
4310
4594
  )
@@ -4313,7 +4597,7 @@ var Checkbox = forwardRef2(
4313
4597
  }
4314
4598
  ),
4315
4599
  description && /* @__PURE__ */ jsx36(
4316
- Text16,
4600
+ Text17,
4317
4601
  {
4318
4602
  style: [
4319
4603
  styles.descriptionText,
@@ -4323,7 +4607,7 @@ var Checkbox = forwardRef2(
4323
4607
  children: description
4324
4608
  }
4325
4609
  ),
4326
- hasError && /* @__PURE__ */ jsx36(Text16, { style: [styles.errorText, helperTextSizeStyle[size]], children: error })
4610
+ hasError && /* @__PURE__ */ jsx36(Text17, { style: [styles.errorText, helperTextSizeStyle[size]], children: error })
4327
4611
  ] });
4328
4612
  }
4329
4613
  );
@@ -4331,7 +4615,7 @@ Checkbox.displayName = "Checkbox";
4331
4615
 
4332
4616
  // src/primitives/Input/Input.tsx
4333
4617
  import { cloneElement as cloneElement8, forwardRef as forwardRef3, useState as useState8 } from "react";
4334
- import { Pressable as Pressable16, Text as Text17, TextInput as TextInput2, View as View31 } from "react-native";
4618
+ import { Pressable as Pressable16, Text as Text18, TextInput as TextInput2, View as View31 } from "react-native";
4335
4619
 
4336
4620
  // src/primitives/Input/Input.styles.ts
4337
4621
  import { StyleSheet as StyleSheet27 } from "react-native";
@@ -4712,7 +4996,7 @@ var Input = forwardRef3(
4712
4996
  children: clearIcon ? cloneElement8(clearIcon, {
4713
4997
  color: clearIconColor,
4714
4998
  size: resolvedIconSize
4715
- }) : /* @__PURE__ */ jsx37(Text17, { style: [styles.clearButtonText, { color: clearIconColor }], children: "\xD7" })
4999
+ }) : /* @__PURE__ */ jsx37(Text18, { style: [styles.clearButtonText, { color: clearIconColor }], children: "\xD7" })
4716
5000
  }
4717
5001
  ) : showRevealButton ? /* @__PURE__ */ jsx37(
4718
5002
  Pressable16,
@@ -4722,7 +5006,7 @@ var Input = forwardRef3(
4722
5006
  hitSlop: 8,
4723
5007
  onPress: () => setIsPasswordRevealed((revealed) => !revealed),
4724
5008
  style: styles.revealButton,
4725
- children: /* @__PURE__ */ jsx37(Text17, { style: styles.revealButtonText, children: isPasswordRevealed ? "Hide" : "Show" })
5009
+ children: /* @__PURE__ */ jsx37(Text18, { style: styles.revealButtonText, children: isPasswordRevealed ? "Hide" : "Show" })
4726
5010
  }
4727
5011
  ) : showRightIcon && endIcon && /* @__PURE__ */ jsx37(
4728
5012
  View31,
@@ -4760,11 +5044,11 @@ var Input = forwardRef3(
4760
5044
  Input.displayName = "Input";
4761
5045
 
4762
5046
  // src/primitives/Radio/Radio.tsx
4763
- import { forwardRef as forwardRef4, useEffect as useEffect7 } from "react";
5047
+ import { forwardRef as forwardRef4, useEffect as useEffect8 } from "react";
4764
5048
  import { useControllableState as useControllableState4 } from "@vellira-ui/core";
4765
5049
  import {
4766
5050
  Pressable as Pressable17,
4767
- Text as Text18,
5051
+ Text as Text19,
4768
5052
  View as View32
4769
5053
  } from "react-native";
4770
5054
 
@@ -4929,7 +5213,7 @@ var Radio = forwardRef4(
4929
5213
  };
4930
5214
  const typographySize = typographySizeByRadioSize[resolvedSize];
4931
5215
  const controlMarginTop = (typographySize.labelLineHeight - controlSize) / 2;
4932
- useEffect7(() => {
5216
+ useEffect8(() => {
4933
5217
  if (typeof __DEV__ !== "undefined" && __DEV__ && !label && !accessibilityLabel) {
4934
5218
  console.warn(
4935
5219
  "Radio requires either a visible label or accessibilityLabel."
@@ -5017,7 +5301,7 @@ var Radio = forwardRef4(
5017
5301
  ),
5018
5302
  (label || description) && /* @__PURE__ */ jsxs23(View32, { pointerEvents: "none", style: styles.content, children: [
5019
5303
  label && (typeof label === "string" ? /* @__PURE__ */ jsx38(
5020
- Text18,
5304
+ Text19,
5021
5305
  {
5022
5306
  style: [
5023
5307
  styles.label,
@@ -5039,7 +5323,7 @@ var Radio = forwardRef4(
5039
5323
  }
5040
5324
  ) : label),
5041
5325
  description && (typeof description === "string" ? /* @__PURE__ */ jsx38(
5042
- Text18,
5326
+ Text19,
5043
5327
  {
5044
5328
  style: [
5045
5329
  styles.description,
@@ -5058,7 +5342,7 @@ var Radio = forwardRef4(
5058
5342
  }
5059
5343
  ),
5060
5344
  error && /* @__PURE__ */ jsx38(
5061
- Text18,
5345
+ Text19,
5062
5346
  {
5063
5347
  accessibilityLiveRegion: "polite",
5064
5348
  style: [