@vellira-ui/react-native 2.31.0 → 2.32.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 +11 -10
  2. package/dist/index.js +1949 -527
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -60,9 +60,9 @@ function useTheme() {
60
60
 
61
61
  // src/theme/useThemeStyles.ts
62
62
  import { useMemo as useMemo2 } from "react";
63
- function useThemeStyles(createStyles25) {
63
+ function useThemeStyles(createStyles23) {
64
64
  const { theme } = useTheme();
65
- return useMemo2(() => createStyles25(theme), [createStyles25, theme]);
65
+ return useMemo2(() => createStyles23(theme), [createStyles23, theme]);
66
66
  }
67
67
 
68
68
  // src/components/Dropdown/Content/DropdownContent.styles.ts
@@ -1055,6 +1055,8 @@ function FormField({
1055
1055
  labelId,
1056
1056
  descriptionId,
1057
1057
  errorId,
1058
+ description,
1059
+ error,
1058
1060
  required,
1059
1061
  disabled,
1060
1062
  invalid: isInvalid,
@@ -1286,184 +1288,1523 @@ var RadioGroup = forwardRef(
1286
1288
  );
1287
1289
  RadioGroup.displayName = "RadioGroup";
1288
1290
 
1289
- // src/components/Select/Select.tsx
1290
- import { useEffect as useEffect2, useState as useState2 } from "react";
1291
- import { Picker } from "@react-native-picker/picker";
1292
- import { useSelect } from "@vellira-ui/core";
1293
- import { Modal as Modal3, Pressable as Pressable7, Text as Text8, View as View13 } from "react-native";
1291
+ // 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";
1294
1294
 
1295
- // src/components/Select/SelectTrigger/SelectTrigger.tsx
1296
- import { ChevronDown as ChevronDown2 } from "@vellira-ui/icons";
1297
- import { Pressable as Pressable6, Text as Text7, View as View12 } from "react-native";
1295
+ // src/components/Select/Group/SelectGroup.tsx
1296
+ import { Pressable as Pressable6, Text as Text7 } from "react-native";
1297
+
1298
+ // src/components/Select/internal/SelectCollection.ts
1299
+ import { Children as Children2, isValidElement as isValidElement4 } from "react";
1300
+
1301
+ // src/components/Select/internal/types.ts
1302
+ var selectSlotName = /* @__PURE__ */ Symbol("VelliraNativeSelectSlot");
1303
+
1304
+ // src/components/Select/internal/SelectCollection.ts
1305
+ var createSelectSlot = (name, displayName) => {
1306
+ const Slot = (_props) => null;
1307
+ Slot[selectSlotName] = name;
1308
+ Slot.displayName = displayName;
1309
+ return Slot;
1310
+ };
1311
+ var getSelectSlot = (type) => type?.[selectSlotName];
1312
+ var defaultSelectFilter = (option, query) => option.label.toLowerCase().includes(query.trim().toLowerCase());
1313
+ var getTextFromNode = (node) => {
1314
+ if (typeof node === "string" || typeof node === "number") {
1315
+ return String(node);
1316
+ }
1317
+ return void 0;
1318
+ };
1319
+ var getGroupLabel = (props) => {
1320
+ if (props.label) return props.label;
1321
+ let label;
1322
+ Children2.forEach(props.children, (child) => {
1323
+ if (label || !isValidElement4(child)) return;
1324
+ if (getSelectSlot(child.type) === "label") {
1325
+ label = getTextFromNode(child.props.children);
1326
+ }
1327
+ });
1328
+ return label;
1329
+ };
1330
+ var getGroupItemValues = (children) => {
1331
+ const values = [];
1332
+ const visit = (node) => {
1333
+ Children2.forEach(node, (child) => {
1334
+ if (!isValidElement4(child)) return;
1335
+ const slot = getSelectSlot(child.type);
1336
+ if (slot === "content") {
1337
+ visit(child.props.children);
1338
+ return;
1339
+ }
1340
+ if (slot === "group") {
1341
+ visit(child.props.children);
1342
+ return;
1343
+ }
1344
+ if (slot === "item") {
1345
+ values.push(child.props.value);
1346
+ }
1347
+ });
1348
+ };
1349
+ visit(children);
1350
+ return values;
1351
+ };
1352
+ var parseSelectChildren = (children) => {
1353
+ const options = [];
1354
+ const rows = [];
1355
+ let searchable = false;
1356
+ let searchPlaceholder;
1357
+ let empty;
1358
+ let loading;
1359
+ const visit = (node, group) => {
1360
+ Children2.forEach(node, (child) => {
1361
+ if (!isValidElement4(child)) return;
1362
+ const slot = getSelectSlot(child.type);
1363
+ if (slot === "content") {
1364
+ visit(child.props.children, group);
1365
+ return;
1366
+ }
1367
+ if (slot === "search") {
1368
+ searchable = true;
1369
+ searchPlaceholder = child.props.placeholder;
1370
+ return;
1371
+ }
1372
+ if (slot === "empty") {
1373
+ empty = child.props.children;
1374
+ return;
1375
+ }
1376
+ if (slot === "loading") {
1377
+ loading = child.props.children;
1378
+ return;
1379
+ }
1380
+ if (slot === "group") {
1381
+ const props = child.props;
1382
+ const groupLabel = getGroupLabel(props);
1383
+ if (groupLabel) {
1384
+ rows.push({
1385
+ type: "group",
1386
+ key: `group-${groupLabel}-${rows.length}`,
1387
+ label: groupLabel,
1388
+ selectable: props.selectable,
1389
+ selectLabel: props.selectLabel,
1390
+ itemValues: getGroupItemValues(props.children)
1391
+ });
1392
+ }
1393
+ visit(props.children, groupLabel);
1394
+ return;
1395
+ }
1396
+ if (slot === "label") {
1397
+ return;
1398
+ }
1399
+ if (slot === "separator") {
1400
+ rows.push({ type: "separator", key: `separator-${rows.length}` });
1401
+ return;
1402
+ }
1403
+ if (slot === "item") {
1404
+ const props = child.props;
1405
+ const option = {
1406
+ value: props.value,
1407
+ label: props.label,
1408
+ disabled: props.disabled,
1409
+ description: props.description,
1410
+ icon: props.icon,
1411
+ badge: props.badge,
1412
+ color: props.color,
1413
+ accessibilityLabel: props.accessibilityLabel,
1414
+ accessibilityHint: props.accessibilityHint ?? group
1415
+ };
1416
+ options.push(option);
1417
+ rows.push({
1418
+ type: "item",
1419
+ key: `item-${props.value}`,
1420
+ option
1421
+ });
1422
+ }
1423
+ });
1424
+ };
1425
+ visit(children);
1426
+ return { options, rows, searchable, searchPlaceholder, empty, loading };
1427
+ };
1298
1428
 
1299
- // src/components/Select/SelectTrigger/SelectTrigger.styles.ts
1429
+ // src/components/Select/Group/SelectGroup.styles.ts
1300
1430
  import { StyleSheet as StyleSheet14 } from "react-native";
1301
- var createStyles14 = (theme) => StyleSheet14.create({
1302
- trigger: {
1303
- width: "100%",
1304
- minWidth: 0,
1431
+ var createGroupStyles = (theme) => StyleSheet14.create({
1432
+ groupLabel: {
1433
+ paddingHorizontal: theme.tokens.spacing[3],
1434
+ paddingTop: theme.tokens.spacing[4],
1435
+ paddingBottom: theme.tokens.spacing[1],
1436
+ color: theme.components.select.dropdown.groupLabel.fg,
1437
+ fontFamily: theme.tokens.typography.family.medium,
1438
+ fontSize: theme.tokens.typography.size.xs,
1439
+ letterSpacing: 0.6,
1440
+ textTransform: "uppercase"
1441
+ },
1442
+ groupAction: {
1443
+ minHeight: 36,
1444
+ flexDirection: "row",
1305
1445
  alignItems: "center",
1306
1446
  justifyContent: "space-between",
1447
+ gap: theme.tokens.spacing[2],
1448
+ paddingHorizontal: theme.tokens.spacing[3],
1449
+ paddingTop: theme.tokens.spacing[4],
1450
+ paddingBottom: theme.tokens.spacing[1]
1451
+ },
1452
+ groupActionText: {
1453
+ color: theme.components.select.dropdown.groupLabel.fg,
1454
+ fontFamily: theme.tokens.typography.family.medium,
1455
+ fontSize: theme.tokens.typography.size.xs,
1456
+ letterSpacing: 0.6,
1457
+ textTransform: "uppercase"
1458
+ },
1459
+ groupActionMeta: {
1460
+ color: theme.components.select.option.default.fg,
1461
+ fontFamily: theme.tokens.typography.family.medium,
1462
+ fontSize: theme.tokens.typography.size.xs
1463
+ },
1464
+ separator: {
1465
+ height: 1,
1466
+ marginHorizontal: theme.tokens.spacing[3],
1467
+ marginVertical: theme.tokens.spacing[2],
1468
+ backgroundColor: theme.components.select.dropdown.separator.bg
1469
+ }
1470
+ });
1471
+
1472
+ // src/components/Select/Group/SelectGroup.tsx
1473
+ import { jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
1474
+ var SelectGroup = createSelectSlot(
1475
+ "group",
1476
+ "Select.Group"
1477
+ );
1478
+ var SelectGroupLabelRow = ({ label }) => {
1479
+ const styles = useThemeStyles(createGroupStyles);
1480
+ return /* @__PURE__ */ jsx16(Text7, { style: styles.groupLabel, children: label });
1481
+ };
1482
+ var SelectGroupActionRow = ({
1483
+ label,
1484
+ selectLabel,
1485
+ selectedCount,
1486
+ itemCount,
1487
+ onPress
1488
+ }) => {
1489
+ const styles = useThemeStyles(createGroupStyles);
1490
+ const isSelected = itemCount > 0 && selectedCount === itemCount;
1491
+ const isMixed = selectedCount > 0 && selectedCount < itemCount;
1492
+ const resolvedLabel = selectLabel ?? label;
1493
+ return /* @__PURE__ */ jsxs8(
1494
+ Pressable6,
1495
+ {
1496
+ accessibilityRole: "button",
1497
+ accessibilityLabel: resolvedLabel,
1498
+ accessibilityHint: `Selects all options in ${label}`,
1499
+ accessibilityState: {
1500
+ selected: isSelected,
1501
+ checked: isMixed ? "mixed" : isSelected,
1502
+ disabled: itemCount === 0
1503
+ },
1504
+ disabled: itemCount === 0,
1505
+ onPress,
1506
+ style: styles.groupAction,
1507
+ children: [
1508
+ /* @__PURE__ */ jsx16(Text7, { style: styles.groupActionText, children: resolvedLabel }),
1509
+ /* @__PURE__ */ jsxs8(Text7, { style: styles.groupActionMeta, children: [
1510
+ selectedCount,
1511
+ "/",
1512
+ itemCount
1513
+ ] })
1514
+ ]
1515
+ }
1516
+ );
1517
+ };
1518
+ SelectGroupLabelRow.displayName = "Select.GroupLabelRow";
1519
+ SelectGroupActionRow.displayName = "Select.GroupActionRow";
1520
+
1521
+ // src/components/Select/Group/SelectLabel.tsx
1522
+ var SelectLabel = createSelectSlot(
1523
+ "label",
1524
+ "Select.Label"
1525
+ );
1526
+
1527
+ // src/components/Select/Group/SelectSeparator.tsx
1528
+ import { View as View12 } from "react-native";
1529
+ import { jsx as jsx17 } from "react/jsx-runtime";
1530
+ var SelectSeparator = createSelectSlot(
1531
+ "separator",
1532
+ "Select.Separator"
1533
+ );
1534
+ var SelectSeparatorRow = () => {
1535
+ const styles = useThemeStyles(createGroupStyles);
1536
+ return /* @__PURE__ */ jsx17(View12, { style: styles.separator });
1537
+ };
1538
+ SelectSeparatorRow.displayName = "Select.SeparatorRow";
1539
+
1540
+ // src/components/Select/internal/SelectContext.tsx
1541
+ import { createContext as createContext5, useContext as useContext5 } from "react";
1542
+ var SelectContext = createContext5(null);
1543
+ var useSelectContext = () => {
1544
+ const context = useContext5(SelectContext);
1545
+ if (!context) {
1546
+ throw new Error("Select compound components must be used inside Select");
1547
+ }
1548
+ return context;
1549
+ };
1550
+
1551
+ // src/components/Select/Item/SelectItem.tsx
1552
+ import { cloneElement as cloneElement4, isValidElement as isValidElement5 } from "react";
1553
+ import { Check } from "@vellira-ui/icons";
1554
+ import { Pressable as Pressable7, Text as Text8, View as View13 } from "react-native";
1555
+
1556
+ // src/components/Select/Item/SelectItem.styles.ts
1557
+ import { StyleSheet as StyleSheet15 } from "react-native";
1558
+ var createItemStyles = (theme) => StyleSheet15.create({
1559
+ option: {
1560
+ minHeight: 44,
1307
1561
  flexDirection: "row",
1308
- paddingHorizontal: theme.tokens.spacing[4],
1309
- paddingVertical: theme.tokens.spacing[3],
1310
- backgroundColor: theme.components.select.trigger.default.bg,
1311
- borderColor: theme.components.select.trigger.default.border,
1562
+ alignItems: "center",
1563
+ gap: theme.tokens.spacing[3],
1564
+ paddingHorizontal: theme.tokens.spacing[3],
1565
+ paddingVertical: theme.tokens.spacing[2],
1566
+ marginBottom: 2,
1312
1567
  borderRadius: theme.tokens.radius.md,
1313
- borderWidth: 1
1568
+ borderWidth: 1,
1569
+ borderColor: "transparent"
1314
1570
  },
1315
- sm: {
1316
- minHeight: 36,
1317
- paddingHorizontal: theme.tokens.spacing[3],
1318
- paddingVertical: theme.tokens.spacing[2]
1571
+ optionDisabled: {
1572
+ opacity: 0.55
1319
1573
  },
1320
- md: {
1321
- minHeight: 44,
1322
- paddingHorizontal: theme.tokens.spacing[4],
1323
- paddingVertical: theme.tokens.spacing[3]
1574
+ optionIcon: {
1575
+ width: 22,
1576
+ minWidth: 22,
1577
+ alignItems: "center",
1578
+ justifyContent: "center"
1324
1579
  },
1325
- lg: {
1326
- minHeight: 52,
1327
- paddingHorizontal: theme.tokens.spacing[5],
1328
- paddingVertical: theme.tokens.spacing[4]
1580
+ optionTextWrap: {
1581
+ flex: 1,
1582
+ minWidth: 0,
1583
+ gap: 2
1329
1584
  },
1330
- textSm: {
1585
+ optionLabel: {
1586
+ fontFamily: theme.tokens.typography.family.medium,
1587
+ fontSize: theme.tokens.typography.size.md,
1588
+ lineHeight: theme.tokens.typography.lineHeight.md
1589
+ },
1590
+ optionDescription: {
1591
+ color: theme.components.select.option.description.fg,
1592
+ fontFamily: theme.tokens.typography.family.regular,
1331
1593
  fontSize: theme.tokens.typography.size.sm,
1332
1594
  lineHeight: theme.tokens.typography.lineHeight.sm
1333
1595
  },
1334
- textMd: {
1335
- fontSize: theme.tokens.typography.size.md,
1336
- lineHeight: theme.tokens.typography.lineHeight.md
1596
+ badge: {
1597
+ paddingHorizontal: theme.tokens.spacing[2],
1598
+ paddingVertical: 2,
1599
+ borderRadius: 999,
1600
+ borderWidth: 1
1337
1601
  },
1338
- textLg: {
1339
- fontSize: theme.tokens.typography.size.lg,
1340
- lineHeight: theme.tokens.typography.lineHeight.lg
1602
+ badgeText: {
1603
+ fontFamily: theme.tokens.typography.family.medium,
1604
+ fontSize: theme.tokens.typography.size.xs,
1605
+ lineHeight: theme.tokens.typography.lineHeight.xs
1341
1606
  },
1342
- triggerOpen: {
1343
- backgroundColor: theme.components.select.trigger.focus.bg,
1344
- borderColor: theme.components.select.trigger.focus.border,
1345
- borderWidth: 2
1607
+ check: {
1608
+ width: 20,
1609
+ height: 20,
1610
+ alignItems: "center",
1611
+ justifyContent: "center"
1612
+ }
1613
+ });
1614
+
1615
+ // src/components/Select/Item/SelectItem.tsx
1616
+ import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs9 } from "react/jsx-runtime";
1617
+ var renderNodeOrText = (node, textStyle, fallback) => {
1618
+ if (typeof node === "string" || typeof node === "number") {
1619
+ return /* @__PURE__ */ jsx18(Text8, { style: textStyle, children: node });
1620
+ }
1621
+ if (isValidElement5(node) && node.type === Text8) {
1622
+ return cloneElement4(node, {
1623
+ style: [textStyle, node.props.style]
1624
+ });
1625
+ }
1626
+ return node ?? (fallback ? /* @__PURE__ */ jsx18(Text8, { style: textStyle, children: fallback }) : null);
1627
+ };
1628
+ var SelectItem = createSelectSlot(
1629
+ "item",
1630
+ "Select.Item"
1631
+ );
1632
+ var SelectItemRow = ({
1633
+ option,
1634
+ isSelected,
1635
+ isDisabled,
1636
+ optionStyle,
1637
+ onSelect
1638
+ }) => {
1639
+ const { theme } = useTheme();
1640
+ const styles = useThemeStyles(createItemStyles);
1641
+ const { color, variant, renderOption } = useSelectContext();
1642
+ 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;
1645
+ return /* @__PURE__ */ jsx18(
1646
+ Pressable7,
1647
+ {
1648
+ disabled: isDisabled,
1649
+ accessibilityRole: "button",
1650
+ accessibilityLabel: option.accessibilityLabel ?? option.label,
1651
+ accessibilityHint: option.accessibilityHint,
1652
+ accessibilityState: {
1653
+ selected: isSelected,
1654
+ disabled: isDisabled
1655
+ },
1656
+ 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,
1675
+ {
1676
+ color: optionFg,
1677
+ size: 18
1678
+ }
1679
+ ) : option.icon }),
1680
+ /* @__PURE__ */ jsxs9(View13, { style: styles.optionTextWrap, children: [
1681
+ /* @__PURE__ */ jsx18(
1682
+ Text8,
1683
+ {
1684
+ numberOfLines: 1,
1685
+ style: [styles.optionLabel, { color: optionFg }],
1686
+ children: option.label
1687
+ }
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,
1696
+ {
1697
+ backgroundColor: optionPalette.badge.bg,
1698
+ borderColor: optionPalette.badge.border
1699
+ }
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
+ ] })
1709
+ }
1710
+ );
1711
+ };
1712
+ SelectItemRow.displayName = "Select.ItemRow";
1713
+
1714
+ // src/components/Select/Item/SelectItemBadge.tsx
1715
+ var SelectItemBadge = createSelectSlot(
1716
+ "itemBadge",
1717
+ "Select.ItemBadge"
1718
+ );
1719
+
1720
+ // src/components/Select/Item/SelectItemDescription.tsx
1721
+ var SelectItemDescription = createSelectSlot(
1722
+ "itemDescription",
1723
+ "Select.ItemDescription"
1724
+ );
1725
+
1726
+ // src/components/Select/Item/SelectItemIcon.tsx
1727
+ var SelectItemIcon = createSelectSlot(
1728
+ "itemIcon",
1729
+ "Select.ItemIcon"
1730
+ );
1731
+
1732
+ // src/components/Select/Presentation/SelectBackdrop.tsx
1733
+ import { Pressable as Pressable8 } from "react-native";
1734
+
1735
+ // src/components/Select/Presentation/SelectPresentation.styles.ts
1736
+ import { StyleSheet as StyleSheet16 } from "react-native";
1737
+ var createPresentationStyles = (theme) => StyleSheet16.create({
1738
+ modalRoot: {
1739
+ flex: 1
1346
1740
  },
1347
- triggerError: {
1348
- borderColor: theme.components.select.trigger.error.border
1741
+ sheetRoot: {
1742
+ justifyContent: "flex-end"
1349
1743
  },
1350
- triggerErrorOpen: {
1351
- borderColor: theme.components.select.trigger.error.border,
1352
- shadowColor: theme.components.select.trigger.error.ring,
1353
- shadowOffset: {
1354
- width: 0,
1355
- height: 0
1356
- },
1357
- shadowOpacity: 0.2,
1358
- shadowRadius: 6,
1359
- elevation: 1
1744
+ modalPresentationRoot: {
1745
+ alignItems: "center",
1746
+ justifyContent: "center",
1747
+ padding: theme.tokens.spacing[4]
1360
1748
  },
1361
- textOpen: {
1362
- color: theme.components.select.trigger.focus.fg
1749
+ popoverRoot: {
1750
+ padding: theme.tokens.spacing[4]
1363
1751
  },
1364
- triggerDisabled: {
1365
- backgroundColor: theme.components.select.trigger.disabled.bg,
1366
- borderColor: theme.components.select.trigger.disabled.border
1752
+ popoverRootTop: {
1753
+ justifyContent: "flex-start"
1367
1754
  },
1368
- text: {
1369
- flex: 1,
1370
- minWidth: 0,
1371
- color: theme.components.select.trigger.default.fg,
1372
- fontFamily: theme.tokens.typography.family.regular
1755
+ popoverRootBottom: {
1756
+ justifyContent: "flex-end"
1373
1757
  },
1374
- textDisabled: {
1375
- color: theme.components.select.trigger.disabled.fg
1758
+ backdrop: {
1759
+ ...StyleSheet16.absoluteFill,
1760
+ backgroundColor: theme.semantic.overlay.backdrop
1376
1761
  },
1377
- placeholder: {
1378
- color: theme.components.select.trigger.placeholder.fg
1762
+ content: {
1763
+ overflow: "hidden",
1764
+ backgroundColor: theme.components.select.dropdown.bg,
1765
+ borderColor: theme.components.select.dropdown.border,
1766
+ borderWidth: 1
1379
1767
  },
1380
- icon: {
1381
- width: 16,
1382
- height: 16,
1383
- marginLeft: theme.tokens.spacing[2],
1768
+ sheet: {
1769
+ maxHeight: "74%",
1770
+ borderTopLeftRadius: theme.tokens.radius.lg,
1771
+ borderTopRightRadius: theme.tokens.radius.lg,
1772
+ borderBottomWidth: 0
1773
+ },
1774
+ modalPresentation: {
1775
+ width: "100%",
1776
+ maxWidth: 420,
1777
+ maxHeight: "74%",
1778
+ borderRadius: theme.tokens.radius.lg
1779
+ },
1780
+ popover: {
1781
+ width: "100%",
1782
+ maxWidth: 420,
1783
+ maxHeight: "60%",
1784
+ alignSelf: "center",
1785
+ borderRadius: theme.tokens.radius.lg
1786
+ },
1787
+ popoverTop: {
1788
+ marginBottom: theme.tokens.spacing[8],
1789
+ alignSelf: "center"
1790
+ },
1791
+ popoverBottom: {
1792
+ marginTop: theme.tokens.spacing[8],
1793
+ alignSelf: "center"
1794
+ },
1795
+ handleWrap: {
1384
1796
  alignItems: "center",
1385
- justifyContent: "center"
1797
+ paddingTop: theme.tokens.spacing[3]
1386
1798
  },
1387
- iconOpen: {
1388
- transform: [{ rotate: "180deg" }]
1799
+ handle: {
1800
+ width: 44,
1801
+ height: 4,
1802
+ borderRadius: 999,
1803
+ backgroundColor: theme.semantic.border.muted
1389
1804
  }
1390
1805
  });
1391
1806
 
1392
- // src/components/Select/SelectTrigger/SelectTrigger.tsx
1393
- import { jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
1394
- function SelectTrigger({
1395
- displayText,
1396
- isPlaceholder,
1397
- isOpen,
1398
- size = "md",
1399
- disabled = false,
1400
- required = false,
1401
- hasError = false,
1402
- accessibilityLabel,
1403
- accessibilityHint,
1404
- triggerStyle,
1405
- textStyle,
1406
- onPress
1407
- }) {
1408
- const { theme } = useTheme();
1409
- const styles = useThemeStyles(createStyles14);
1807
+ // src/components/Select/Presentation/SelectBackdrop.tsx
1808
+ import { jsx as jsx19 } from "react/jsx-runtime";
1809
+ var SelectBackdrop = ({
1810
+ onClose,
1811
+ dismissOnBackdropPress
1812
+ }) => {
1813
+ const styles = useThemeStyles(createPresentationStyles);
1814
+ return /* @__PURE__ */ jsx19(
1815
+ Pressable8,
1816
+ {
1817
+ style: styles.backdrop,
1818
+ onPress: dismissOnBackdropPress ? onClose : void 0,
1819
+ accessibilityRole: "button",
1820
+ accessibilityLabel: "Dismiss select"
1821
+ }
1822
+ );
1823
+ };
1824
+ SelectBackdrop.displayName = "Select.Backdrop";
1825
+
1826
+ // src/components/Select/Presentation/SelectHandle.tsx
1827
+ import { View as View14 } from "react-native";
1828
+ import { jsx as jsx20 } from "react/jsx-runtime";
1829
+ var SelectHandle = () => {
1830
+ const styles = useThemeStyles(createPresentationStyles);
1831
+ return /* @__PURE__ */ jsx20(View14, { style: styles.handleWrap, accessible: false, children: /* @__PURE__ */ jsx20(View14, { style: styles.handle }) });
1832
+ };
1833
+ SelectHandle.displayName = "Select.Handle";
1834
+
1835
+ // src/components/Select/Presentation/SelectModal.tsx
1836
+ import { Modal as Modal3, View as View15 } from "react-native";
1837
+ import { jsx as jsx21, jsxs as jsxs10 } from "react/jsx-runtime";
1838
+ var SelectModal = ({
1839
+ visible,
1840
+ onClose,
1841
+ dismissOnBackdropPress,
1842
+ contentStyle,
1843
+ children
1844
+ }) => {
1845
+ const styles = useThemeStyles(createPresentationStyles);
1846
+ return /* @__PURE__ */ jsx21(
1847
+ Modal3,
1848
+ {
1849
+ transparent: true,
1850
+ visible,
1851
+ animationType: "slide",
1852
+ onRequestClose: onClose,
1853
+ children: /* @__PURE__ */ jsxs10(
1854
+ View15,
1855
+ {
1856
+ style: [styles.modalRoot, styles.modalPresentationRoot],
1857
+ testID: "select-content-root",
1858
+ children: [
1859
+ /* @__PURE__ */ jsx21(
1860
+ SelectBackdrop,
1861
+ {
1862
+ onClose,
1863
+ dismissOnBackdropPress
1864
+ }
1865
+ ),
1866
+ /* @__PURE__ */ jsx21(
1867
+ View15,
1868
+ {
1869
+ style: [styles.content, styles.modalPresentation, contentStyle],
1870
+ testID: "select-modal",
1871
+ children
1872
+ }
1873
+ )
1874
+ ]
1875
+ }
1876
+ )
1877
+ }
1878
+ );
1879
+ };
1880
+ SelectModal.displayName = "Select.Modal";
1881
+
1882
+ // src/components/Select/Presentation/SelectPopover.tsx
1883
+ import { Modal as Modal4, View as View16 } from "react-native";
1884
+ import { jsx as jsx22, jsxs as jsxs11 } from "react/jsx-runtime";
1885
+ var SelectPopover = ({
1886
+ visible,
1887
+ onClose,
1888
+ dismissOnBackdropPress,
1889
+ placement,
1890
+ matchTriggerWidth,
1891
+ triggerWidth,
1892
+ contentStyle,
1893
+ children
1894
+ }) => {
1895
+ const styles = useThemeStyles(createPresentationStyles);
1896
+ return /* @__PURE__ */ jsx22(
1897
+ Modal4,
1898
+ {
1899
+ transparent: true,
1900
+ visible,
1901
+ animationType: "fade",
1902
+ onRequestClose: onClose,
1903
+ children: /* @__PURE__ */ jsxs11(
1904
+ View16,
1905
+ {
1906
+ style: [
1907
+ styles.modalRoot,
1908
+ styles.popoverRoot,
1909
+ placement === "top" ? styles.popoverRootTop : styles.popoverRootBottom
1910
+ ],
1911
+ testID: "select-content-root",
1912
+ children: [
1913
+ /* @__PURE__ */ jsx22(
1914
+ SelectBackdrop,
1915
+ {
1916
+ onClose,
1917
+ dismissOnBackdropPress
1918
+ }
1919
+ ),
1920
+ /* @__PURE__ */ jsx22(
1921
+ View16,
1922
+ {
1923
+ style: [
1924
+ styles.content,
1925
+ styles.popover,
1926
+ placement === "top" ? styles.popoverTop : styles.popoverBottom,
1927
+ matchTriggerWidth && triggerWidth ? { width: triggerWidth } : null,
1928
+ contentStyle
1929
+ ],
1930
+ testID: "select-popover",
1931
+ children
1932
+ }
1933
+ )
1934
+ ]
1935
+ }
1936
+ )
1937
+ }
1938
+ );
1939
+ };
1940
+ SelectPopover.displayName = "Select.Popover";
1941
+
1942
+ // src/components/Select/Presentation/SelectSheet.tsx
1943
+ import { Modal as Modal5, View as View17 } from "react-native";
1944
+ import { jsx as jsx23, jsxs as jsxs12 } from "react/jsx-runtime";
1945
+ var SelectSheet = ({
1946
+ visible,
1947
+ onClose,
1948
+ dismissOnBackdropPress,
1949
+ contentStyle,
1950
+ children
1951
+ }) => {
1952
+ const styles = useThemeStyles(createPresentationStyles);
1953
+ return /* @__PURE__ */ jsx23(
1954
+ Modal5,
1955
+ {
1956
+ transparent: true,
1957
+ visible,
1958
+ animationType: "slide",
1959
+ onRequestClose: onClose,
1960
+ children: /* @__PURE__ */ jsxs12(
1961
+ View17,
1962
+ {
1963
+ style: [styles.modalRoot, styles.sheetRoot],
1964
+ testID: "select-content-root",
1965
+ children: [
1966
+ /* @__PURE__ */ jsx23(
1967
+ SelectBackdrop,
1968
+ {
1969
+ onClose,
1970
+ dismissOnBackdropPress
1971
+ }
1972
+ ),
1973
+ /* @__PURE__ */ jsxs12(
1974
+ View17,
1975
+ {
1976
+ style: [styles.content, styles.sheet, contentStyle],
1977
+ testID: "select-sheet",
1978
+ children: [
1979
+ /* @__PURE__ */ jsx23(SelectHandle, {}),
1980
+ children
1981
+ ]
1982
+ }
1983
+ )
1984
+ ]
1985
+ }
1986
+ )
1987
+ }
1988
+ );
1989
+ };
1990
+ SelectSheet.displayName = "Select.Sheet";
1991
+
1992
+ // src/components/Select/Content/SelectContent.styles.ts
1993
+ import { StyleSheet as StyleSheet17 } from "react-native";
1994
+ var createContentStyles = (theme) => StyleSheet17.create({
1995
+ toolbar: {
1996
+ minHeight: 52,
1997
+ flexDirection: "row",
1998
+ alignItems: "center",
1999
+ justifyContent: "space-between",
2000
+ paddingHorizontal: theme.tokens.spacing[4],
2001
+ borderBottomColor: theme.components.select.dropdown.separator.bg,
2002
+ borderBottomWidth: 1
2003
+ },
2004
+ title: {
2005
+ flex: 1,
2006
+ marginHorizontal: theme.tokens.spacing[3],
2007
+ color: theme.components.select.dropdown.fg,
2008
+ fontFamily: theme.tokens.typography.family.medium,
2009
+ fontSize: theme.tokens.typography.size.md,
2010
+ lineHeight: theme.tokens.typography.lineHeight.md,
2011
+ textAlign: "center"
2012
+ },
2013
+ toolbarAction: {
2014
+ minWidth: 64,
2015
+ minHeight: 44,
2016
+ alignItems: "center",
2017
+ justifyContent: "center"
2018
+ },
2019
+ cancelText: {
2020
+ color: theme.components.select.trigger.placeholder.fg,
2021
+ fontFamily: theme.tokens.typography.family.medium,
2022
+ fontSize: theme.tokens.typography.size.md,
2023
+ lineHeight: theme.tokens.typography.lineHeight.md
2024
+ },
2025
+ doneText: {
2026
+ color: theme.semantic.text.interactive,
2027
+ fontFamily: theme.tokens.typography.family.medium,
2028
+ fontSize: theme.tokens.typography.size.md,
2029
+ lineHeight: theme.tokens.typography.lineHeight.md
2030
+ },
2031
+ list: {
2032
+ maxHeight: 420
2033
+ },
2034
+ listContent: {
2035
+ paddingHorizontal: theme.tokens.spacing[2],
2036
+ paddingVertical: theme.tokens.spacing[2]
2037
+ },
2038
+ empty: {
2039
+ minHeight: 72,
2040
+ alignItems: "center",
2041
+ justifyContent: "center",
2042
+ padding: theme.tokens.spacing[4]
2043
+ },
2044
+ emptyText: {
2045
+ color: theme.components.select.dropdown.empty.fg,
2046
+ fontFamily: theme.tokens.typography.family.regular,
2047
+ fontSize: theme.tokens.typography.size.md,
2048
+ lineHeight: theme.tokens.typography.lineHeight.md,
2049
+ textAlign: "center"
2050
+ },
2051
+ loading: {
2052
+ minHeight: 72,
2053
+ flexDirection: "row",
2054
+ alignItems: "center",
2055
+ justifyContent: "center",
2056
+ gap: theme.tokens.spacing[2],
2057
+ padding: theme.tokens.spacing[4]
2058
+ },
2059
+ loadingText: {
2060
+ color: theme.components.select.dropdown.fg,
2061
+ fontFamily: theme.tokens.typography.family.regular,
2062
+ fontSize: theme.tokens.typography.size.md,
2063
+ lineHeight: theme.tokens.typography.lineHeight.md
2064
+ }
2065
+ });
2066
+
2067
+ // src/components/Select/Content/SelectEmpty.tsx
2068
+ import { Text as Text9, View as View18 } from "react-native";
2069
+ import { jsx as jsx24 } from "react/jsx-runtime";
2070
+ var renderText = (node, style) => {
2071
+ if (typeof node === "string" || typeof node === "number") {
2072
+ return /* @__PURE__ */ jsx24(Text9, { style, children: node });
2073
+ }
2074
+ return node;
2075
+ };
2076
+ var SelectEmpty = createSelectSlot(
2077
+ "empty",
2078
+ "Select.Empty"
2079
+ );
2080
+ var SelectEmptyState = () => {
2081
+ const styles = useThemeStyles(createContentStyles);
2082
+ const { empty } = useSelectContext();
2083
+ return /* @__PURE__ */ jsx24(View18, { style: styles.empty, children: renderText(empty, styles.emptyText) });
2084
+ };
2085
+ SelectEmptyState.displayName = "Select.EmptyState";
2086
+
2087
+ // src/components/Select/Content/SelectLoading.tsx
2088
+ import { ActivityIndicator, Text as Text10, View as View19 } from "react-native";
2089
+ import { jsx as jsx25, jsxs as jsxs13 } from "react/jsx-runtime";
2090
+ var renderText2 = (node, style) => {
2091
+ if (typeof node === "string" || typeof node === "number") {
2092
+ return /* @__PURE__ */ jsx25(Text10, { style, children: node });
2093
+ }
2094
+ return node;
2095
+ };
2096
+ var SelectLoading = createSelectSlot(
2097
+ "loading",
2098
+ "Select.Loading"
2099
+ );
2100
+ var SelectLoadingState = () => {
2101
+ const { theme } = useTheme();
2102
+ const styles = useThemeStyles(createContentStyles);
2103
+ const { loadingContent } = useSelectContext();
2104
+ return /* @__PURE__ */ jsxs13(View19, { style: styles.loading, children: [
2105
+ /* @__PURE__ */ jsx25(
2106
+ ActivityIndicator,
2107
+ {
2108
+ testID: "select-content-loading-indicator",
2109
+ size: "small",
2110
+ color: theme.components.select.dropdown.fg
2111
+ }
2112
+ ),
2113
+ renderText2(loadingContent, styles.loadingText)
2114
+ ] });
2115
+ };
2116
+ SelectLoadingState.displayName = "Select.LoadingState";
2117
+
2118
+ // src/components/Select/Content/SelectSearch.tsx
2119
+ import { useEffect as useEffect2 } from "react";
2120
+ import { Close as Close2, Search } from "@vellira-ui/icons";
2121
+ import { Pressable as Pressable9, TextInput, View as View20 } from "react-native";
2122
+
2123
+ // src/components/Select/Content/SelectSearch.styles.ts
2124
+ import { StyleSheet as StyleSheet18 } from "react-native";
2125
+ var createSearchStyles = (theme) => StyleSheet18.create({
2126
+ searchWrap: {
2127
+ flexDirection: "row",
2128
+ alignItems: "center",
2129
+ marginHorizontal: theme.tokens.spacing[4],
2130
+ marginTop: theme.tokens.spacing[3],
2131
+ marginBottom: theme.tokens.spacing[2],
2132
+ paddingHorizontal: theme.tokens.spacing[3],
2133
+ minHeight: 44,
2134
+ borderWidth: 1,
2135
+ borderRadius: theme.tokens.radius.md,
2136
+ borderColor: theme.components.select.dropdown.search.border,
2137
+ backgroundColor: theme.components.select.dropdown.search.bg
2138
+ },
2139
+ searchInput: {
2140
+ flex: 1,
2141
+ minWidth: 0,
2142
+ color: theme.components.select.dropdown.search.fg,
2143
+ fontFamily: theme.tokens.typography.family.regular,
2144
+ fontSize: theme.tokens.typography.size.md,
2145
+ lineHeight: theme.tokens.typography.lineHeight.md,
2146
+ paddingVertical: 0
2147
+ },
2148
+ searchIcon: {
2149
+ width: 18,
2150
+ height: 18,
2151
+ marginRight: theme.tokens.spacing[2],
2152
+ alignItems: "center",
2153
+ justifyContent: "center"
2154
+ },
2155
+ searchClearButton: {
2156
+ width: 28,
2157
+ height: 28,
2158
+ marginLeft: theme.tokens.spacing[2],
2159
+ alignItems: "center",
2160
+ justifyContent: "center",
2161
+ borderRadius: 999,
2162
+ backgroundColor: theme.semantic.status.error.bg
2163
+ }
2164
+ });
2165
+
2166
+ // src/components/Select/Content/SelectSearch.tsx
2167
+ import { jsx as jsx26, jsxs as jsxs14 } from "react/jsx-runtime";
2168
+ var SelectSearch = createSelectSlot(
2169
+ "search",
2170
+ "Select.Search"
2171
+ );
2172
+ var SelectSearchField = () => {
2173
+ const { theme } = useTheme();
2174
+ const styles = useThemeStyles(createSearchStyles);
2175
+ const {
2176
+ query,
2177
+ setQuery,
2178
+ searchPlaceholder,
2179
+ searchInputRef,
2180
+ searchStyle,
2181
+ selectedRowIndex,
2182
+ virtual
2183
+ } = useSelectContext();
2184
+ const shouldAutoFocus = !virtual || selectedRowIndex === 0;
2185
+ useEffect2(() => {
2186
+ if (!shouldAutoFocus) return;
2187
+ const focusTimer = setTimeout(() => {
2188
+ searchInputRef.current?.focus();
2189
+ }, 0);
2190
+ return () => clearTimeout(focusTimer);
2191
+ }, [searchInputRef, shouldAutoFocus]);
2192
+ return /* @__PURE__ */ jsxs14(View20, { style: styles.searchWrap, children: [
2193
+ /* @__PURE__ */ jsx26(
2194
+ View20,
2195
+ {
2196
+ style: styles.searchIcon,
2197
+ accessibilityElementsHidden: true,
2198
+ importantForAccessibility: "no",
2199
+ children: /* @__PURE__ */ jsx26(
2200
+ Search,
2201
+ {
2202
+ width: 16,
2203
+ height: 16,
2204
+ color: theme.components.select.dropdown.search.placeholder
2205
+ }
2206
+ )
2207
+ }
2208
+ ),
2209
+ /* @__PURE__ */ jsx26(
2210
+ TextInput,
2211
+ {
2212
+ ref: searchInputRef,
2213
+ value: query,
2214
+ onChangeText: setQuery,
2215
+ placeholder: searchPlaceholder,
2216
+ autoFocus: shouldAutoFocus,
2217
+ returnKeyType: "search",
2218
+ placeholderTextColor: theme.components.select.dropdown.search.placeholder,
2219
+ accessibilityLabel: searchPlaceholder,
2220
+ style: [styles.searchInput, searchStyle]
2221
+ }
2222
+ ),
2223
+ query && /* @__PURE__ */ jsx26(
2224
+ Pressable9,
2225
+ {
2226
+ accessibilityRole: "button",
2227
+ accessibilityLabel: "Clear search",
2228
+ hitSlop: 8,
2229
+ onPress: () => setQuery(""),
2230
+ style: styles.searchClearButton,
2231
+ children: /* @__PURE__ */ jsx26(
2232
+ Close2,
2233
+ {
2234
+ width: 14,
2235
+ height: 14,
2236
+ color: theme.semantic.status.error.fg
2237
+ }
2238
+ )
2239
+ }
2240
+ )
2241
+ ] });
2242
+ };
2243
+ SelectSearchField.displayName = "Select.SearchField";
2244
+
2245
+ // src/components/Select/Content/SelectContent.tsx
2246
+ import { Fragment as Fragment3, jsx as jsx27, jsxs as jsxs15 } from "react/jsx-runtime";
2247
+ var SelectContent = createSelectSlot(
2248
+ "content",
2249
+ "Select.Content"
2250
+ );
2251
+ var SelectContentSurface = () => {
2252
+ const styles = useThemeStyles(createContentStyles);
2253
+ const wasOpenRef = useRef2(false);
2254
+ const [openCycle, setOpenCycle] = useState2(0);
2255
+ const context = useSelectContext();
2256
+ const {
2257
+ isOpen,
2258
+ resolvedPresentation,
2259
+ placement,
2260
+ dismissOnBackdropPress,
2261
+ contentStyle,
2262
+ matchTriggerWidth,
2263
+ triggerWidth,
2264
+ resolvedLabel,
2265
+ closeContent,
2266
+ searchable,
2267
+ loading,
2268
+ filteredRows,
2269
+ selectedValues,
2270
+ selectedOptions,
2271
+ maxSelected,
2272
+ optionStyle,
2273
+ selectOption,
2274
+ selectGroup,
2275
+ itemHeight,
2276
+ selectedRowIndex,
2277
+ query
2278
+ } = context;
2279
+ const shouldSeedSelectedPosition = Boolean(context.virtual) && selectedRowIndex > 0 && query === "";
2280
+ const initialScrollIndex = shouldSeedSelectedPosition ? selectedRowIndex : void 0;
2281
+ useEffect3(() => {
2282
+ if (isOpen && !wasOpenRef.current) {
2283
+ setOpenCycle((cycle) => cycle + 1);
2284
+ }
2285
+ wasOpenRef.current = isOpen;
2286
+ }, [isOpen]);
2287
+ const renderRow = ({ item }) => {
2288
+ if (item.type === "group") {
2289
+ if (item.selectable && context.multiple) {
2290
+ const enabledGroupValues = item.itemValues.filter(
2291
+ (value) => context.optionsByValue.get(value)
2292
+ );
2293
+ const selectedGroupCount = selectedOptions.filter(
2294
+ (option) => enabledGroupValues.includes(option.value)
2295
+ ).length;
2296
+ return /* @__PURE__ */ jsx27(
2297
+ SelectGroupActionRow,
2298
+ {
2299
+ label: item.label,
2300
+ selectLabel: item.selectLabel,
2301
+ selectedCount: selectedGroupCount,
2302
+ itemCount: enabledGroupValues.length,
2303
+ onPress: () => selectGroup(enabledGroupValues)
2304
+ }
2305
+ );
2306
+ }
2307
+ return /* @__PURE__ */ jsx27(SelectGroupLabelRow, { label: item.label });
2308
+ }
2309
+ if (item.type === "separator") {
2310
+ return /* @__PURE__ */ jsx27(SelectSeparatorRow, {});
2311
+ }
2312
+ const isSelected = selectedValues.includes(item.option.value);
2313
+ const maxReached = !isSelected && typeof maxSelected === "number" && selectedValues.length >= maxSelected;
2314
+ return /* @__PURE__ */ jsx27(
2315
+ SelectItemRow,
2316
+ {
2317
+ option: item.option,
2318
+ isSelected,
2319
+ isDisabled: Boolean(item.option.disabled || maxReached),
2320
+ optionStyle,
2321
+ onSelect: selectOption
2322
+ }
2323
+ );
2324
+ };
2325
+ const body = /* @__PURE__ */ jsxs15(Fragment3, { children: [
2326
+ /* @__PURE__ */ jsxs15(
2327
+ View21,
2328
+ {
2329
+ style: styles.toolbar,
2330
+ accessible: true,
2331
+ accessibilityRole: "toolbar",
2332
+ accessibilityLabel: `${resolvedLabel} selection actions`,
2333
+ children: [
2334
+ /* @__PURE__ */ jsx27(
2335
+ Pressable10,
2336
+ {
2337
+ onPress: closeContent,
2338
+ hitSlop: 8,
2339
+ style: styles.toolbarAction,
2340
+ accessibilityRole: "button",
2341
+ accessibilityLabel: "Close selection",
2342
+ children: /* @__PURE__ */ jsx27(Text11, { style: styles.cancelText, children: "Cancel" })
2343
+ }
2344
+ ),
2345
+ /* @__PURE__ */ jsx27(Text11, { style: styles.title, numberOfLines: 1, accessibilityRole: "header", children: resolvedLabel }),
2346
+ /* @__PURE__ */ jsx27(
2347
+ Pressable10,
2348
+ {
2349
+ onPress: closeContent,
2350
+ hitSlop: 8,
2351
+ style: styles.toolbarAction,
2352
+ accessibilityRole: "button",
2353
+ accessibilityLabel: "Done",
2354
+ children: /* @__PURE__ */ jsx27(Text11, { style: styles.doneText, children: "Done" })
2355
+ }
2356
+ )
2357
+ ]
2358
+ }
2359
+ ),
2360
+ searchable && /* @__PURE__ */ jsx27(SelectSearchField, {}),
2361
+ loading && filteredRows.length === 0 ? /* @__PURE__ */ jsx27(SelectLoadingState, {}) : filteredRows.length === 0 ? /* @__PURE__ */ jsx27(SelectEmptyState, {}) : /* @__PURE__ */ jsx27(
2362
+ FlatList,
2363
+ {
2364
+ data: filteredRows,
2365
+ keyExtractor: (item) => item.key,
2366
+ renderItem: renderRow,
2367
+ style: styles.list,
2368
+ contentContainerStyle: styles.listContent,
2369
+ keyboardShouldPersistTaps: "handled",
2370
+ initialScrollIndex,
2371
+ initialNumToRender: typeof context.virtual === "object" ? context.virtual.initialNumToRender : 12,
2372
+ windowSize: typeof context.virtual === "object" ? context.virtual.windowSize : 7,
2373
+ getItemLayout: (_data, index) => ({
2374
+ length: itemHeight,
2375
+ offset: itemHeight * index,
2376
+ index
2377
+ })
2378
+ },
2379
+ `select-list-${openCycle}`
2380
+ )
2381
+ ] });
2382
+ if (resolvedPresentation === "sheet") {
2383
+ return /* @__PURE__ */ jsx27(
2384
+ SelectSheet,
2385
+ {
2386
+ visible: isOpen,
2387
+ onClose: closeContent,
2388
+ dismissOnBackdropPress,
2389
+ contentStyle,
2390
+ children: body
2391
+ }
2392
+ );
2393
+ }
2394
+ if (resolvedPresentation === "popover") {
2395
+ return /* @__PURE__ */ jsx27(
2396
+ SelectPopover,
2397
+ {
2398
+ visible: isOpen,
2399
+ onClose: closeContent,
2400
+ dismissOnBackdropPress,
2401
+ placement,
2402
+ matchTriggerWidth,
2403
+ triggerWidth,
2404
+ contentStyle,
2405
+ children: body
2406
+ }
2407
+ );
2408
+ }
2409
+ return /* @__PURE__ */ jsx27(
2410
+ SelectModal,
2411
+ {
2412
+ visible: isOpen,
2413
+ onClose: closeContent,
2414
+ dismissOnBackdropPress,
2415
+ contentStyle,
2416
+ children: body
2417
+ }
2418
+ );
2419
+ };
2420
+ SelectContentSurface.displayName = "Select.ContentSurface";
2421
+
2422
+ // src/components/Select/Root/SelectRoot.tsx
2423
+ import { useMemo as useMemo6, useRef as useRef3, useState as useState4 } from "react";
2424
+ import { useSelect } from "@vellira-ui/core";
2425
+ import { View as View23 } from "react-native";
2426
+
2427
+ // src/components/Select/internal/useSelectAccessibility.ts
2428
+ import { AccessibilityInfo } from "react-native";
2429
+ var useSelectAccessibility = ({
2430
+ accessibilityLabel,
2431
+ accessibilityHint,
2432
+ label,
2433
+ description,
2434
+ error,
2435
+ invalid,
2436
+ placeholder,
2437
+ selectedLabel,
2438
+ hasFieldContext,
2439
+ fieldDescribedBy
2440
+ }) => {
2441
+ const descriptionText = typeof description === "string" || typeof description === "number" ? String(description) : void 0;
2442
+ const errorText = typeof error === "string" || typeof error === "number" ? String(error) : void 0;
2443
+ const resolvedLabel = accessibilityLabel ?? label ?? selectedLabel ?? placeholder ?? "Select";
2444
+ const resolvedHint = accessibilityHint ?? (invalid && errorText ? errorText : descriptionText ? descriptionText : hasFieldContext && fieldDescribedBy ? "Opens a list of options" : void 0);
2445
+ return {
2446
+ resolvedLabel,
2447
+ resolvedHint,
2448
+ announce: (message) => {
2449
+ AccessibilityInfo.announceForAccessibility?.(message);
2450
+ }
2451
+ };
2452
+ };
2453
+
2454
+ // src/components/Select/internal/useSelectCollection.ts
2455
+ import { useMemo as useMemo4 } from "react";
2456
+ var useSelectCollection = (children, optionsProp) => {
2457
+ const parsedChildren = useMemo4(
2458
+ () => parseSelectChildren(children),
2459
+ [children]
2460
+ );
2461
+ const options = useMemo4(
2462
+ () => [...optionsProp ?? [], ...parsedChildren.options],
2463
+ [optionsProp, parsedChildren.options]
2464
+ );
2465
+ const rows = useMemo4(() => {
2466
+ if (parsedChildren.rows.length > 0) {
2467
+ return parsedChildren.rows;
2468
+ }
2469
+ return options.map((option) => ({
2470
+ type: "item",
2471
+ key: `item-${option.value}`,
2472
+ option
2473
+ }));
2474
+ }, [options, parsedChildren.rows]);
2475
+ return {
2476
+ options,
2477
+ rows,
2478
+ searchableFromChildren: parsedChildren.searchable,
2479
+ searchPlaceholderFromChildren: parsedChildren.searchPlaceholder,
2480
+ emptyFromChildren: parsedChildren.empty,
2481
+ loadingFromChildren: parsedChildren.loading
2482
+ };
2483
+ };
2484
+
2485
+ // src/components/Select/internal/useSelectPresentation.ts
2486
+ import { useWindowDimensions } from "react-native";
2487
+ var useSelectPresentation = (presentation = "auto") => {
2488
+ const { width } = useWindowDimensions();
2489
+ if (presentation === "auto") {
2490
+ return width >= 768 ? "popover" : "sheet";
2491
+ }
2492
+ return presentation;
2493
+ };
2494
+
2495
+ // src/components/Select/internal/useSelectSearch.ts
2496
+ import { useEffect as useEffect4, useMemo as useMemo5, useState as useState3 } from "react";
2497
+ var useSelectSearch = ({
2498
+ rows,
2499
+ isOpen,
2500
+ searchable,
2501
+ searchableFromChildren,
2502
+ onSearch,
2503
+ filterOptions,
2504
+ filter = defaultSelectFilter
2505
+ }) => {
2506
+ const [query, setQuery] = useState3("");
2507
+ const shouldSearch = searchable ?? searchableFromChildren ?? Boolean(onSearch);
2508
+ const shouldFilter = filterOptions ?? !onSearch;
2509
+ const filteredRows = useMemo5(() => {
2510
+ if (!query || !shouldFilter) return rows;
2511
+ const visibleRows = [];
2512
+ let pendingGroup;
2513
+ rows.forEach((row) => {
2514
+ if (row.type === "group") {
2515
+ pendingGroup = row;
2516
+ return;
2517
+ }
2518
+ if (row.type === "separator") {
2519
+ if (visibleRows.length > 0 && visibleRows[visibleRows.length - 1]?.type !== "separator") {
2520
+ visibleRows.push(row);
2521
+ }
2522
+ return;
2523
+ }
2524
+ if (!filter(row.option, query)) return;
2525
+ if (pendingGroup) {
2526
+ visibleRows.push(pendingGroup);
2527
+ pendingGroup = void 0;
2528
+ }
2529
+ visibleRows.push(row);
2530
+ });
2531
+ return visibleRows.filter((row, index, collection) => {
2532
+ if (row.type !== "separator") return true;
2533
+ return index > 0 && index < collection.length - 1 && collection[index - 1]?.type !== "separator";
2534
+ });
2535
+ }, [filter, query, rows, shouldFilter]);
2536
+ useEffect4(() => {
2537
+ if (!isOpen) {
2538
+ setQuery("");
2539
+ return;
2540
+ }
2541
+ if (shouldSearch) {
2542
+ onSearch?.(query);
2543
+ }
2544
+ }, [isOpen, onSearch, query, shouldSearch]);
2545
+ return {
2546
+ query,
2547
+ setQuery,
2548
+ shouldSearch,
2549
+ filteredRows
2550
+ };
2551
+ };
2552
+
2553
+ // src/components/Select/Trigger/SelectIcon.tsx
2554
+ var SelectIcon = createSelectSlot(
2555
+ "icon",
2556
+ "Select.Icon"
2557
+ );
2558
+
2559
+ // src/components/Select/Trigger/SelectTrigger.tsx
2560
+ import { cloneElement as cloneElement5, isValidElement as isValidElement6 } from "react";
2561
+ 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";
2563
+
2564
+ // src/components/Select/Trigger/SelectTrigger.styles.ts
2565
+ import { StyleSheet as StyleSheet19 } from "react-native";
2566
+ var createTriggerStyles = (theme) => StyleSheet19.create({
2567
+ trigger: {
2568
+ width: "100%",
2569
+ minWidth: 0,
2570
+ minHeight: 44,
2571
+ alignItems: "center",
2572
+ flexDirection: "row",
2573
+ borderRadius: theme.tokens.radius.md,
2574
+ borderWidth: 1
2575
+ },
2576
+ sm: {
2577
+ minHeight: 44,
2578
+ paddingHorizontal: theme.tokens.spacing[3],
2579
+ paddingVertical: theme.tokens.spacing[2]
2580
+ },
2581
+ md: {
2582
+ minHeight: 46,
2583
+ paddingHorizontal: theme.tokens.spacing[4],
2584
+ paddingVertical: theme.tokens.spacing[3]
2585
+ },
2586
+ lg: {
2587
+ minHeight: 52,
2588
+ paddingHorizontal: theme.tokens.spacing[5],
2589
+ paddingVertical: theme.tokens.spacing[4]
2590
+ },
2591
+ value: {
2592
+ flex: 1,
2593
+ minWidth: 0
2594
+ },
2595
+ text: {
2596
+ fontFamily: theme.tokens.typography.family.regular
2597
+ },
2598
+ textSm: {
2599
+ fontSize: theme.tokens.typography.size.sm,
2600
+ lineHeight: theme.tokens.typography.lineHeight.sm
2601
+ },
2602
+ textMd: {
2603
+ fontSize: theme.tokens.typography.size.md,
2604
+ lineHeight: theme.tokens.typography.lineHeight.md
2605
+ },
2606
+ textLg: {
2607
+ fontSize: theme.tokens.typography.size.lg,
2608
+ lineHeight: theme.tokens.typography.lineHeight.lg
2609
+ },
2610
+ affix: {
2611
+ flexShrink: 0,
2612
+ color: theme.semantic.text.secondary,
2613
+ fontFamily: theme.tokens.typography.family.regular,
2614
+ fontSize: theme.tokens.typography.size.md,
2615
+ lineHeight: theme.tokens.typography.lineHeight.md
2616
+ },
2617
+ startIcon: {
2618
+ width: 18,
2619
+ height: 18,
2620
+ marginRight: theme.tokens.spacing[2],
2621
+ alignItems: "center",
2622
+ justifyContent: "center"
2623
+ },
2624
+ endIcon: {
2625
+ width: 18,
2626
+ height: 18,
2627
+ marginLeft: theme.tokens.spacing[2],
2628
+ alignItems: "center",
2629
+ justifyContent: "center"
2630
+ },
2631
+ iconOpen: {
2632
+ transform: [{ rotate: "180deg" }]
2633
+ },
2634
+ clearButton: {
2635
+ width: 28,
2636
+ height: 28,
2637
+ marginLeft: theme.tokens.spacing[2],
2638
+ alignItems: "center",
2639
+ justifyContent: "center",
2640
+ borderRadius: 999,
2641
+ backgroundColor: theme.semantic.status.error.bg
2642
+ }
2643
+ });
2644
+
2645
+ // src/components/Select/Trigger/SelectTrigger.tsx
2646
+ import { jsx as jsx28, jsxs as jsxs16 } from "react/jsx-runtime";
2647
+ var SelectTriggerSlot = createSelectSlot(
2648
+ "trigger",
2649
+ "Select.Trigger"
2650
+ );
2651
+ function SelectTrigger({
2652
+ displayText,
2653
+ isPlaceholder,
2654
+ isOpen,
2655
+ size = "md",
2656
+ color = "primary",
2657
+ variant = "outline",
2658
+ disabled = false,
2659
+ required = false,
2660
+ hasError = false,
2661
+ hasValue = false,
2662
+ loading = false,
2663
+ clearable = false,
2664
+ startIcon,
2665
+ endIcon,
2666
+ prefix,
2667
+ suffix,
2668
+ accessibilityLabel,
2669
+ accessibilityHint,
2670
+ nativeID,
2671
+ accessibilityLabelledBy,
2672
+ ariaDescribedBy,
2673
+ triggerStyle,
2674
+ textStyle,
2675
+ onPress,
2676
+ onClear
2677
+ }) {
2678
+ const { theme } = useTheme();
2679
+ const styles = useThemeStyles(createTriggerStyles);
2680
+ const palette = theme.components.select[color][variant];
2681
+ const triggerState = isOpen ? palette.focus : palette.default;
2682
+ const resolvedIconSize = size === "lg" ? 18 : 16;
1410
2683
  const textSizeStyle = {
1411
2684
  sm: styles.textSm,
1412
2685
  md: styles.textMd,
1413
2686
  lg: styles.textLg
1414
2687
  };
1415
- const resolvedAccessibilityHint = accessibilityHint ?? (hasError ? "Invalid selection. Opens a picker" : required ? "Required. Opens a picker" : "Opens a picker");
1416
- return /* @__PURE__ */ jsxs8(
1417
- Pressable6,
2688
+ const resolvedAccessibilityHint = accessibilityHint ?? (hasError ? "Invalid selection. Opens a list of options" : required ? "Required. Opens a list of options" : "Opens a list of options");
2689
+ const iconColor = disabled ? theme.components.select.trigger.disabled.icon : triggerState.icon;
2690
+ const renderIcon = (icon) => isValidElement6(icon) ? cloneElement5(icon, { color: iconColor, size: resolvedIconSize }) : null;
2691
+ const renderValue = () => {
2692
+ const valueStyle = [
2693
+ styles.text,
2694
+ textSizeStyle[size],
2695
+ { color: triggerState.fg },
2696
+ isPlaceholder && { color: triggerState.placeholder },
2697
+ disabled && {
2698
+ color: theme.components.select.trigger.disabled.fg
2699
+ },
2700
+ textStyle
2701
+ ];
2702
+ if (typeof displayText === "string" || typeof displayText === "number") {
2703
+ return /* @__PURE__ */ jsx28(Text12, { numberOfLines: 1, style: valueStyle, children: displayText });
2704
+ }
2705
+ if (isValidElement6(displayText) && displayText.type === Text12) {
2706
+ return cloneElement5(displayText, {
2707
+ numberOfLines: displayText.props.numberOfLines ?? 1,
2708
+ style: [valueStyle, displayText.props.style]
2709
+ });
2710
+ }
2711
+ return displayText;
2712
+ };
2713
+ return /* @__PURE__ */ jsxs16(
2714
+ Pressable11,
1418
2715
  {
2716
+ nativeID,
1419
2717
  disabled,
1420
2718
  accessibilityRole: "button",
1421
2719
  accessibilityLabel,
1422
2720
  accessibilityHint: resolvedAccessibilityHint,
2721
+ accessibilityLabelledBy,
2722
+ "aria-describedby": ariaDescribedBy,
1423
2723
  accessibilityState: {
1424
2724
  expanded: isOpen,
1425
- disabled
2725
+ disabled,
2726
+ selected: hasValue,
2727
+ busy: loading
1426
2728
  },
1427
2729
  onPress,
1428
2730
  style: [
1429
2731
  styles.trigger,
2732
+ {
2733
+ backgroundColor: triggerState.bg,
2734
+ borderColor: triggerState.border
2735
+ },
1430
2736
  styles[size],
1431
- isOpen && styles.triggerOpen,
1432
- hasError && styles.triggerError,
1433
- disabled && styles.triggerDisabled,
2737
+ isOpen && {
2738
+ shadowColor: theme.components.select[color].ring,
2739
+ shadowOffset: { width: 0, height: 0 },
2740
+ shadowOpacity: 0.16,
2741
+ shadowRadius: 6,
2742
+ elevation: 1
2743
+ },
2744
+ hasError && {
2745
+ borderColor: theme.components.select.trigger.error.border
2746
+ },
2747
+ disabled && {
2748
+ backgroundColor: theme.components.select.trigger.disabled.bg,
2749
+ borderColor: theme.components.select.trigger.disabled.border
2750
+ },
1434
2751
  triggerStyle
1435
2752
  ],
1436
2753
  children: [
1437
- /* @__PURE__ */ jsx16(
1438
- Text7,
2754
+ startIcon && /* @__PURE__ */ jsx28(
2755
+ View22,
1439
2756
  {
1440
- numberOfLines: 1,
1441
- style: [
1442
- styles.text,
1443
- textSizeStyle[size],
1444
- isPlaceholder && styles.placeholder,
1445
- isOpen && styles.textOpen,
1446
- disabled && styles.textDisabled,
1447
- textStyle
1448
- ],
1449
- children: displayText
2757
+ pointerEvents: "none",
2758
+ style: styles.startIcon,
2759
+ accessibilityElementsHidden: true,
2760
+ importantForAccessibility: "no",
2761
+ children: renderIcon(startIcon)
1450
2762
  }
1451
2763
  ),
1452
- /* @__PURE__ */ jsx16(
1453
- View12,
2764
+ prefix && /* @__PURE__ */ jsx28(Text12, { style: styles.affix, children: prefix }),
2765
+ /* @__PURE__ */ jsx28(View22, { style: styles.value, children: renderValue() }),
2766
+ suffix && /* @__PURE__ */ jsx28(Text12, { style: styles.affix, children: suffix }),
2767
+ loading ? /* @__PURE__ */ jsx28(
2768
+ ActivityIndicator2,
1454
2769
  {
1455
- style: [styles.icon, isOpen && styles.iconOpen],
1456
- accessibilityElementsHidden: true,
1457
- importantForAccessibility: "no",
1458
- children: /* @__PURE__ */ jsx16(
1459
- ChevronDown2,
2770
+ testID: "select-loading-indicator",
2771
+ size: "small",
2772
+ color: iconColor
2773
+ }
2774
+ ) : clearable && hasValue && !disabled ? /* @__PURE__ */ jsx28(
2775
+ Pressable11,
2776
+ {
2777
+ accessibilityRole: "button",
2778
+ accessibilityLabel: "Clear selection",
2779
+ hitSlop: 8,
2780
+ onPress: onClear,
2781
+ style: styles.clearButton,
2782
+ children: /* @__PURE__ */ jsx28(
2783
+ Close3,
1460
2784
  {
1461
- width: 16,
1462
- height: 16,
1463
- color: disabled ? theme.components.select.trigger.disabled.fg : theme.components.select.trigger.placeholder.fg
2785
+ width: 14,
2786
+ height: 14,
2787
+ color: theme.semantic.status.error.fg
1464
2788
  }
1465
2789
  )
1466
2790
  }
2791
+ ) : endIcon ? /* @__PURE__ */ jsx28(
2792
+ View22,
2793
+ {
2794
+ pointerEvents: "none",
2795
+ style: styles.endIcon,
2796
+ accessibilityElementsHidden: true,
2797
+ importantForAccessibility: "no",
2798
+ children: renderIcon(endIcon)
2799
+ }
2800
+ ) : /* @__PURE__ */ jsx28(
2801
+ View22,
2802
+ {
2803
+ style: [styles.endIcon, isOpen && styles.iconOpen],
2804
+ accessibilityElementsHidden: true,
2805
+ importantForAccessibility: "no",
2806
+ children: /* @__PURE__ */ jsx28(ChevronDown2, { width: 16, height: 16, color: iconColor })
2807
+ }
1467
2808
  )
1468
2809
  ]
1469
2810
  }
@@ -1471,290 +2812,371 @@ function SelectTrigger({
1471
2812
  }
1472
2813
  SelectTrigger.displayName = "SelectTrigger";
1473
2814
 
1474
- // src/components/Select/Select.styles.ts
1475
- import { StyleSheet as StyleSheet15 } from "react-native";
1476
- var createStyles15 = (theme) => StyleSheet15.create({
1477
- modalRoot: {
1478
- flex: 1,
1479
- justifyContent: "flex-end"
1480
- },
1481
- backdrop: {
1482
- ...StyleSheet15.absoluteFill,
1483
- backgroundColor: theme.semantic.overlay.backdrop
1484
- },
1485
- sheet: {
1486
- maxHeight: "50%",
1487
- overflow: "hidden",
1488
- backgroundColor: theme.components.select.dropdown.bg,
1489
- borderColor: theme.components.select.dropdown.border,
1490
- borderTopLeftRadius: theme.tokens.radius.lg,
1491
- borderTopRightRadius: theme.tokens.radius.lg,
1492
- borderWidth: 1,
1493
- borderBottomWidth: 0,
1494
- shadowColor: theme.tokens.shadows.lg.color,
1495
- shadowOffset: {
1496
- width: theme.tokens.shadows.lg.x,
1497
- height: -theme.tokens.shadows.lg.y
1498
- },
1499
- shadowOpacity: theme.tokens.shadows.lg.opacity,
1500
- shadowRadius: theme.tokens.shadows.lg.blur,
1501
- elevation: theme.tokens.shadows.lg.elevation
1502
- },
1503
- toolbar: {
1504
- minHeight: 48,
1505
- flexDirection: "row",
1506
- alignItems: "center",
1507
- justifyContent: "space-between",
1508
- paddingHorizontal: theme.tokens.spacing[4],
1509
- borderBottomColor: theme.components.select.dropdown.border,
1510
- borderBottomWidth: 1
1511
- },
1512
- title: {
1513
- flex: 1,
1514
- marginHorizontal: theme.tokens.spacing[3],
1515
- color: theme.components.select.dropdown.fg,
1516
- fontFamily: theme.tokens.typography.family.medium,
1517
- fontSize: theme.tokens.typography.size.md,
1518
- lineHeight: theme.tokens.typography.lineHeight.md,
1519
- textAlign: "center"
1520
- },
1521
- toolbarAction: {
1522
- minWidth: 64,
1523
- minHeight: 44,
1524
- alignItems: "center",
1525
- justifyContent: "center"
1526
- },
1527
- cancelText: {
1528
- color: theme.components.select.trigger.placeholder.fg,
1529
- fontFamily: theme.tokens.typography.family.medium,
1530
- fontSize: theme.tokens.typography.size.md,
1531
- lineHeight: theme.tokens.typography.lineHeight.md
1532
- },
1533
- doneText: {
1534
- color: theme.semantic.text.interactive,
1535
- fontFamily: theme.tokens.typography.family.medium,
1536
- fontSize: theme.tokens.typography.size.md,
1537
- lineHeight: theme.tokens.typography.lineHeight.md
1538
- },
1539
- picker: {
1540
- width: "100%"
1541
- }
1542
- });
2815
+ // src/components/Select/Trigger/SelectValue.tsx
2816
+ var SelectValue = createSelectSlot(
2817
+ "value",
2818
+ "Select.Value"
2819
+ );
1543
2820
 
1544
- // src/components/Select/Select.tsx
1545
- import { jsx as jsx17, jsxs as jsxs9 } from "react/jsx-runtime";
1546
- function Select({
1547
- label,
1548
- description,
1549
- value,
1550
- defaultValue,
1551
- onValueChange,
1552
- options: optionsProp,
1553
- multiple = false,
1554
- maxSelected,
1555
- closeOnSelect,
1556
- placeholder = "Select...",
1557
- size = "md",
1558
- required = false,
1559
- disabled = false,
1560
- error,
1561
- style,
1562
- triggerStyle,
1563
- textStyle,
1564
- pickerStyle,
1565
- accessibilityLabel,
1566
- accessibilityHint
1567
- }) {
1568
- const { theme } = useTheme();
1569
- const styles = useThemeStyles(createStyles15);
1570
- const options = optionsProp ?? [];
2821
+ // src/components/Select/Root/SelectRoot.tsx
2822
+ import { jsx as jsx29, jsxs as jsxs17 } from "react/jsx-runtime";
2823
+ function SelectRoot(props) {
2824
+ const {
2825
+ label,
2826
+ description,
2827
+ error,
2828
+ invalid = false,
2829
+ required = false,
2830
+ disabled = false,
2831
+ placeholder = "Select...",
2832
+ color = "primary",
2833
+ variant = "outline",
2834
+ size,
2835
+ open,
2836
+ defaultOpen,
2837
+ onOpenChange,
2838
+ clearable = false,
2839
+ searchable: searchableProp,
2840
+ searchPlaceholder,
2841
+ loading = false,
2842
+ loadingText = "Loading...",
2843
+ onSearch,
2844
+ filterOptions,
2845
+ filter,
2846
+ empty,
2847
+ startIcon,
2848
+ endIcon,
2849
+ prefix,
2850
+ suffix,
2851
+ renderValue,
2852
+ renderOption,
2853
+ closeOnSelect,
2854
+ maxSelected,
2855
+ presentation = "auto",
2856
+ placement = "bottom",
2857
+ matchTriggerWidth = false,
2858
+ dismissOnBackdropPress = true,
2859
+ virtual,
2860
+ options: optionsProp,
2861
+ children,
2862
+ style,
2863
+ triggerStyle,
2864
+ textStyle,
2865
+ contentStyle,
2866
+ optionStyle,
2867
+ searchStyle,
2868
+ accessibilityLabel,
2869
+ accessibilityHint,
2870
+ testID
2871
+ } = props;
2872
+ const field = useFormFieldContext();
2873
+ const hasOwnField = Boolean(label || description || error);
2874
+ const [triggerWidth, setTriggerWidth] = useState4();
2875
+ const searchInputRef = useRef3(null);
2876
+ const selectedFocusValueRef = useRef3(void 0);
2877
+ const resolvedPresentation = useSelectPresentation(presentation);
2878
+ const {
2879
+ options,
2880
+ rows,
2881
+ searchableFromChildren,
2882
+ searchPlaceholderFromChildren,
2883
+ emptyFromChildren,
2884
+ loadingFromChildren
2885
+ } = useSelectCollection(children, optionsProp);
2886
+ const resolvedSize = size ?? field?.size ?? "md";
2887
+ const isInvalid = invalid || Boolean(error) || !hasOwnField && Boolean(field?.invalid);
2888
+ const isDisabled = disabled || !hasOwnField && Boolean(field?.disabled);
2889
+ const isRequired = required || !hasOwnField && Boolean(field?.required);
2890
+ const controlledValue = props.multiple ? props.value : props.value === null ? "" : props.value;
2891
+ const controlledDefaultValue = props.multiple ? props.defaultValue : props.defaultValue === null ? "" : props.defaultValue;
1571
2892
  const {
1572
2893
  selectedValue,
1573
- selectedValues,
1574
- selectedOption,
1575
- selectedOptions,
2894
+ setSelectedValue,
1576
2895
  isOpen,
1577
- setIsOpen,
2896
+ openDropdown,
2897
+ closeDropdown,
1578
2898
  selectValue
1579
2899
  } = useSelect({
1580
- value,
1581
- defaultValue,
1582
- onValueChange,
2900
+ value: controlledValue,
2901
+ defaultValue: controlledDefaultValue,
2902
+ onValueChange: (nextValue) => {
2903
+ if (props.multiple) {
2904
+ props.onValueChange?.(
2905
+ nextValue
2906
+ );
2907
+ return;
2908
+ }
2909
+ props.onValueChange?.(
2910
+ nextValue === "" ? null : nextValue
2911
+ );
2912
+ },
1583
2913
  options,
1584
- multiple,
2914
+ multiple: props.multiple,
1585
2915
  maxSelected,
1586
2916
  closeOnSelect,
1587
- disabled
2917
+ disabled: isDisabled,
2918
+ open,
2919
+ defaultOpen,
2920
+ onOpenChange
1588
2921
  });
1589
- const resolvedSelectedValues = selectedValues ?? [];
1590
- const resolvedSelectedOptions = selectedOptions ?? [];
1591
- const selectedValueText = Array.isArray(selectedValue) ? selectedValue[0] ?? "" : selectedValue ?? "";
1592
- const [draftValue, setDraftValue] = useState2(selectedValueText);
1593
- const hasError = !!error;
1594
- useEffect2(() => {
1595
- if (isOpen) {
1596
- setDraftValue(selectedValueText);
2922
+ const selectedValues = Array.isArray(selectedValue) ? selectedValue : selectedValue ? [selectedValue] : [];
2923
+ const selectedOption = options.find(
2924
+ (option) => selectedValues.includes(option.value)
2925
+ );
2926
+ const selectedOptions = options.filter(
2927
+ (option) => selectedValues.includes(option.value)
2928
+ );
2929
+ const optionsByValue = useMemo6(
2930
+ () => new Map(
2931
+ options.filter((option) => !option.disabled).map((option) => [option.value, option])
2932
+ ),
2933
+ [options]
2934
+ );
2935
+ const { query, setQuery, shouldSearch, filteredRows } = useSelectSearch({
2936
+ rows,
2937
+ isOpen,
2938
+ searchable: searchableProp,
2939
+ searchableFromChildren,
2940
+ onSearch,
2941
+ filterOptions,
2942
+ filter
2943
+ });
2944
+ const selectedFocusValue = selectedValues.includes(
2945
+ selectedFocusValueRef.current ?? ""
2946
+ ) ? selectedFocusValueRef.current : selectedValues[0];
2947
+ const selectedRowIndex = Math.max(
2948
+ 0,
2949
+ filteredRows.findIndex(
2950
+ (row) => row.type === "item" && row.option.value === selectedFocusValue
2951
+ )
2952
+ );
2953
+ const itemHeight = typeof virtual === "object" ? virtual.estimatedItemSize ?? 46 : 46;
2954
+ const displayValue = useMemo6(() => {
2955
+ if (renderValue) {
2956
+ return renderValue(
2957
+ props.multiple ? selectedOptions : selectedOption ?? null,
2958
+ { placeholder, multiple: Boolean(props.multiple) }
2959
+ );
1597
2960
  }
1598
- }, [isOpen, selectedValueText]);
1599
- const resolvedLabel = accessibilityLabel ?? label ?? selectedOption?.label ?? placeholder ?? "Select";
1600
- const openPicker = () => {
1601
- if (disabled) return;
1602
- setDraftValue(selectedValueText);
1603
- setIsOpen(true);
2961
+ if (props.multiple && selectedOptions.length > 0) {
2962
+ const visibleLabels = selectedOptions.slice(0, 2).map((option) => option.label);
2963
+ return selectedOptions.length > 2 ? `${visibleLabels.join(", ")} +${selectedOptions.length - 2}` : visibleLabels.join(", ");
2964
+ }
2965
+ return selectedOption?.label ?? placeholder;
2966
+ }, [
2967
+ placeholder,
2968
+ props.multiple,
2969
+ renderValue,
2970
+ selectedOption,
2971
+ selectedOptions
2972
+ ]);
2973
+ const { resolvedLabel, resolvedHint, announce } = useSelectAccessibility({
2974
+ accessibilityLabel,
2975
+ accessibilityHint,
2976
+ label: !hasOwnField ? void 0 : label,
2977
+ description: !hasOwnField ? field?.description : description,
2978
+ error: !hasOwnField ? field?.error : error,
2979
+ invalid: isInvalid,
2980
+ placeholder,
2981
+ selectedLabel: selectedOption?.label,
2982
+ hasFieldContext: !hasOwnField && Boolean(field),
2983
+ fieldDescribedBy: field?.ariaDescribedBy
2984
+ });
2985
+ const hasValue = selectedValues.length > 0;
2986
+ const clearValue = () => {
2987
+ selectedFocusValueRef.current = void 0;
2988
+ selectValue("");
2989
+ announce("Selection cleared");
1604
2990
  };
1605
- const closePicker = () => {
1606
- setIsOpen(false);
2991
+ const selectOption = (option) => {
2992
+ if (option.disabled) return;
2993
+ const selectedBefore = selectedValues.includes(option.value);
2994
+ const maxReached = Boolean(props.multiple) && !selectedBefore && typeof maxSelected === "number" && selectedValues.length >= maxSelected;
2995
+ if (maxReached) return;
2996
+ selectedFocusValueRef.current = option.value;
2997
+ selectValue(option.value);
2998
+ announce(`${option.label} selected`);
1607
2999
  };
1608
- const handleValueChange = (nextValue) => {
1609
- const nextOption = options.find((option) => option.value === nextValue);
1610
- if (!nextOption || nextOption.disabled) {
3000
+ const selectGroup = (values) => {
3001
+ if (!props.multiple || values.length === 0) return;
3002
+ const enabledValues = values.filter((value) => optionsByValue.has(value));
3003
+ const selectedGroupValues = enabledValues.filter(
3004
+ (value) => selectedValues.includes(value)
3005
+ );
3006
+ const outsideSelectedCount = selectedValues.filter(
3007
+ (value) => !enabledValues.includes(value)
3008
+ ).length;
3009
+ const maxSelectableGroupCount = typeof maxSelected === "number" ? Math.max(
3010
+ 0,
3011
+ Math.min(enabledValues.length, maxSelected - outsideSelectedCount)
3012
+ ) : enabledValues.length;
3013
+ const shouldClearGroup = selectedGroupValues.length > 0 && selectedGroupValues.length >= maxSelectableGroupCount;
3014
+ if (shouldClearGroup) {
3015
+ selectedFocusValueRef.current = void 0;
3016
+ setSelectedValue(
3017
+ selectedValues.filter((value) => !enabledValues.includes(value))
3018
+ );
3019
+ announce("Group selection cleared");
1611
3020
  return;
1612
3021
  }
1613
- setDraftValue(nextValue);
1614
- };
1615
- const confirmPicker = () => {
1616
- const nextOption = options.find((option) => option.value === draftValue);
1617
- if (!nextOption || nextOption.disabled) {
1618
- setIsOpen(false);
1619
- return;
3022
+ const nextValues = [...selectedValues];
3023
+ for (const value of enabledValues) {
3024
+ if (nextValues.includes(value)) continue;
3025
+ if (typeof maxSelected === "number" && nextValues.length >= maxSelected) {
3026
+ break;
3027
+ }
3028
+ nextValues.push(value);
3029
+ }
3030
+ setSelectedValue(nextValues);
3031
+ selectedFocusValueRef.current = nextValues.at(-1);
3032
+ announce("Group selected");
3033
+ if (closeOnSelect) {
3034
+ closeDropdown();
1620
3035
  }
1621
- selectValue(draftValue);
1622
- setIsOpen(false);
1623
3036
  };
1624
- const displayText = multiple && resolvedSelectedOptions.length ? resolvedSelectedOptions.map((option) => option.label).join(", ") : selectedOption?.label ?? placeholder;
1625
- return /* @__PURE__ */ jsxs9(
1626
- FormField,
3037
+ const contextValue = {
3038
+ label,
3039
+ description,
3040
+ error,
3041
+ placeholder,
3042
+ color,
3043
+ variant,
3044
+ size: resolvedSize,
3045
+ isOpen,
3046
+ hasValue,
3047
+ loading,
3048
+ clearable,
3049
+ searchable: shouldSearch,
3050
+ multiple: Boolean(props.multiple),
3051
+ maxSelected,
3052
+ virtual,
3053
+ resolvedLabel,
3054
+ resolvedHint,
3055
+ resolvedPresentation,
3056
+ placement,
3057
+ dismissOnBackdropPress,
3058
+ matchTriggerWidth,
3059
+ triggerWidth,
3060
+ selectedValues,
3061
+ selectedOptions,
3062
+ optionsByValue,
3063
+ rows,
3064
+ filteredRows,
3065
+ selectedRowIndex,
3066
+ itemHeight,
3067
+ query,
3068
+ searchPlaceholder: searchPlaceholder ?? searchPlaceholderFromChildren ?? "Search...",
3069
+ searchInputRef,
3070
+ empty: empty ?? emptyFromChildren ?? "Nothing found",
3071
+ loadingContent: loadingFromChildren ?? loadingText,
3072
+ closeContent: closeDropdown,
3073
+ openContent: openDropdown,
3074
+ clearValue,
3075
+ selectOption,
3076
+ selectGroup,
3077
+ setQuery,
3078
+ renderValue,
3079
+ renderOption,
3080
+ startIcon,
3081
+ endIcon,
3082
+ prefix,
3083
+ suffix,
3084
+ triggerStyle,
3085
+ textStyle,
3086
+ contentStyle,
3087
+ optionStyle,
3088
+ searchStyle,
3089
+ fieldControlId: !hasOwnField ? field?.controlId : void 0,
3090
+ fieldLabelId: !hasOwnField ? field?.labelId : void 0,
3091
+ fieldDescribedBy: !hasOwnField ? field?.ariaDescribedBy : void 0
3092
+ };
3093
+ const control = /* @__PURE__ */ jsx29(SelectContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs17(
3094
+ View23,
1627
3095
  {
1628
- label,
1629
- description,
1630
- error,
1631
- required,
1632
- disabled,
1633
- style,
3096
+ testID,
3097
+ onLayout: (event) => setTriggerWidth(event.nativeEvent.layout.width),
1634
3098
  children: [
1635
- /* @__PURE__ */ jsx17(
3099
+ /* @__PURE__ */ jsx29(
1636
3100
  SelectTrigger,
1637
3101
  {
1638
- displayText,
1639
- isPlaceholder: resolvedSelectedValues.length === 0,
3102
+ displayText: displayValue,
3103
+ isPlaceholder: !hasValue,
1640
3104
  isOpen,
1641
- size,
1642
- disabled,
1643
- required,
1644
- hasError,
3105
+ hasValue,
3106
+ size: resolvedSize,
3107
+ color,
3108
+ variant,
3109
+ disabled: isDisabled,
3110
+ required: isRequired,
3111
+ hasError: isInvalid,
3112
+ loading,
3113
+ clearable,
3114
+ startIcon,
3115
+ endIcon,
3116
+ prefix,
3117
+ suffix,
3118
+ nativeID: !hasOwnField ? field?.controlId : void 0,
1645
3119
  accessibilityLabel: resolvedLabel,
1646
- accessibilityHint,
3120
+ accessibilityHint: resolvedHint,
3121
+ accessibilityLabelledBy: !hasOwnField ? field?.labelId : void 0,
3122
+ ariaDescribedBy: !hasOwnField ? field?.ariaDescribedBy : void 0,
1647
3123
  triggerStyle,
1648
3124
  textStyle,
1649
- onPress: openPicker
3125
+ onPress: openDropdown,
3126
+ onClear: clearValue
1650
3127
  }
1651
3128
  ),
1652
- /* @__PURE__ */ jsx17(
1653
- Modal3,
1654
- {
1655
- transparent: true,
1656
- visible: isOpen,
1657
- animationType: "slide",
1658
- onRequestClose: closePicker,
1659
- children: /* @__PURE__ */ jsxs9(View13, { style: styles.modalRoot, children: [
1660
- /* @__PURE__ */ jsx17(Pressable7, { style: styles.backdrop, onPress: closePicker }),
1661
- /* @__PURE__ */ jsxs9(View13, { style: styles.sheet, children: [
1662
- /* @__PURE__ */ jsxs9(
1663
- View13,
1664
- {
1665
- style: styles.toolbar,
1666
- accessible: true,
1667
- accessibilityRole: "toolbar",
1668
- accessibilityLabel: `${resolvedLabel} picker actions`,
1669
- children: [
1670
- /* @__PURE__ */ jsx17(
1671
- Pressable7,
1672
- {
1673
- onPress: closePicker,
1674
- hitSlop: 8,
1675
- style: styles.toolbarAction,
1676
- accessibilityRole: "button",
1677
- accessibilityLabel: "Cancel selection",
1678
- accessibilityHint: "Closes the picker without changing the selected value",
1679
- children: /* @__PURE__ */ jsx17(Text8, { style: styles.cancelText, children: "Cancel" })
1680
- }
1681
- ),
1682
- /* @__PURE__ */ jsx17(
1683
- Text8,
1684
- {
1685
- style: styles.title,
1686
- numberOfLines: 1,
1687
- accessibilityRole: "header",
1688
- children: resolvedLabel
1689
- }
1690
- ),
1691
- /* @__PURE__ */ jsx17(
1692
- Pressable7,
1693
- {
1694
- onPress: confirmPicker,
1695
- hitSlop: 8,
1696
- style: styles.toolbarAction,
1697
- accessibilityRole: "button",
1698
- accessibilityLabel: "Confirm selection",
1699
- accessibilityHint: "Applies the highlighted picker value",
1700
- children: /* @__PURE__ */ jsx17(Text8, { style: styles.doneText, children: "Done" })
1701
- }
1702
- )
1703
- ]
1704
- }
1705
- ),
1706
- /* @__PURE__ */ jsxs9(
1707
- Picker,
1708
- {
1709
- selectedValue: draftValue,
1710
- onValueChange: handleValueChange,
1711
- enabled: !disabled,
1712
- style: [styles.picker, pickerStyle],
1713
- itemStyle: {
1714
- color: theme.components.select.option.default.fg
1715
- },
1716
- children: [
1717
- /* @__PURE__ */ jsx17(
1718
- Picker.Item,
1719
- {
1720
- label: placeholder,
1721
- value: "",
1722
- enabled: false,
1723
- color: theme.components.select.option.disabled.fg
1724
- }
1725
- ),
1726
- options.map((option) => /* @__PURE__ */ jsx17(
1727
- Picker.Item,
1728
- {
1729
- label: option.disabled ? `${option.label} - unavailable` : option.label,
1730
- value: option.value,
1731
- enabled: !option.disabled,
1732
- color: option.disabled ? theme.components.select.option.disabled.fg : theme.components.select.option.default.fg
1733
- },
1734
- option.value
1735
- ))
1736
- ]
1737
- }
1738
- )
1739
- ] })
1740
- ] })
1741
- }
1742
- )
3129
+ /* @__PURE__ */ jsx29(SelectContentSurface, {})
1743
3130
  ]
1744
3131
  }
3132
+ ) });
3133
+ if (!hasOwnField && field) {
3134
+ return control;
3135
+ }
3136
+ return /* @__PURE__ */ jsx29(
3137
+ FormField,
3138
+ {
3139
+ label,
3140
+ description,
3141
+ error,
3142
+ required: isRequired,
3143
+ disabled: isDisabled,
3144
+ invalid: isInvalid,
3145
+ size: resolvedSize,
3146
+ style,
3147
+ children: control
3148
+ }
1745
3149
  );
1746
3150
  }
1747
- Select.displayName = "Select";
3151
+ SelectRoot.displayName = "Select";
3152
+
3153
+ // src/components/Select/Select.tsx
3154
+ var Select = Object.assign(SelectRoot, {
3155
+ Trigger: SelectTriggerSlot,
3156
+ Value: SelectValue,
3157
+ Icon: SelectIcon,
3158
+ Content: SelectContent,
3159
+ Search: SelectSearch,
3160
+ Group: SelectGroup,
3161
+ Label: SelectLabel,
3162
+ Item: SelectItem,
3163
+ ItemIcon: SelectItemIcon,
3164
+ ItemDescription: SelectItemDescription,
3165
+ ItemBadge: SelectItemBadge,
3166
+ Separator: SelectSeparator,
3167
+ Empty: SelectEmpty,
3168
+ Loading: SelectLoading
3169
+ });
1748
3170
 
1749
3171
  // src/components/Tabs/List/TabsList.tsx
1750
- import { View as View14 } from "react-native";
3172
+ import { View as View24 } from "react-native";
1751
3173
 
1752
3174
  // src/components/Tabs/TabsContext.tsx
1753
- import { createContext as createContext5, useContext as useContext5 } from "react";
1754
- var TabsContext = createContext5(null);
3175
+ import { createContext as createContext6, useContext as useContext6 } from "react";
3176
+ var TabsContext = createContext6(null);
1755
3177
  var TabsProvider = TabsContext.Provider;
1756
3178
  var useTabs = () => {
1757
- const context = useContext5(TabsContext);
3179
+ const context = useContext6(TabsContext);
1758
3180
  if (!context) {
1759
3181
  throw new Error("Tabs components must be used inside <Tabs>.");
1760
3182
  }
@@ -1763,8 +3185,8 @@ var useTabs = () => {
1763
3185
  TabsContext.displayName = "TabsContext";
1764
3186
 
1765
3187
  // src/components/Tabs/List/TabsList.styles.ts
1766
- import { StyleSheet as StyleSheet16 } from "react-native";
1767
- var createStyles16 = (theme) => StyleSheet16.create({
3188
+ import { StyleSheet as StyleSheet20 } from "react-native";
3189
+ var createStyles14 = (theme) => StyleSheet20.create({
1768
3190
  list: {
1769
3191
  flexDirection: "row",
1770
3192
  alignSelf: "stretch",
@@ -1790,12 +3212,12 @@ var createStyles16 = (theme) => StyleSheet16.create({
1790
3212
  });
1791
3213
 
1792
3214
  // src/components/Tabs/List/TabsList.tsx
1793
- import { jsx as jsx18 } from "react/jsx-runtime";
3215
+ import { jsx as jsx30 } from "react/jsx-runtime";
1794
3216
  var TabsList = ({ children, style }) => {
1795
- const styles = useThemeStyles(createStyles16);
3217
+ const styles = useThemeStyles(createStyles14);
1796
3218
  const { orientation, appearance } = useTabs();
1797
- return /* @__PURE__ */ jsx18(
1798
- View14,
3219
+ return /* @__PURE__ */ jsx30(
3220
+ View24,
1799
3221
  {
1800
3222
  accessibilityRole: "tablist",
1801
3223
  style: [
@@ -1811,11 +3233,11 @@ var TabsList = ({ children, style }) => {
1811
3233
  TabsList.displayName = "TabsList";
1812
3234
 
1813
3235
  // src/components/Tabs/Panel/TabsPanel.tsx
1814
- import { View as View15 } from "react-native";
3236
+ import { View as View25 } from "react-native";
1815
3237
 
1816
3238
  // src/components/Tabs/Panel/TabsPanel.styles.ts
1817
- import { StyleSheet as StyleSheet17 } from "react-native";
1818
- var createStyles17 = (theme) => StyleSheet17.create({
3239
+ import { StyleSheet as StyleSheet21 } from "react-native";
3240
+ var createStyles15 = (theme) => StyleSheet21.create({
1819
3241
  panel: {
1820
3242
  width: "100%",
1821
3243
  minWidth: 0,
@@ -1842,13 +3264,13 @@ var createStyles17 = (theme) => StyleSheet17.create({
1842
3264
  });
1843
3265
 
1844
3266
  // src/components/Tabs/Panel/TabsPanel.tsx
1845
- import { jsx as jsx19 } from "react/jsx-runtime";
3267
+ import { jsx as jsx31 } from "react/jsx-runtime";
1846
3268
  var TabsPanel = ({ index, children, style }) => {
1847
- const styles = useThemeStyles(createStyles17);
3269
+ const styles = useThemeStyles(createStyles15);
1848
3270
  const { activeIndex, orientation } = useTabs();
1849
3271
  if (activeIndex !== index) return null;
1850
- return /* @__PURE__ */ jsx19(
1851
- View15,
3272
+ return /* @__PURE__ */ jsx31(
3273
+ View25,
1852
3274
  {
1853
3275
  style: [
1854
3276
  styles.panel,
@@ -1862,13 +3284,13 @@ var TabsPanel = ({ index, children, style }) => {
1862
3284
  TabsPanel.displayName = "TabsPanel";
1863
3285
 
1864
3286
  // src/components/Tabs/Tab/Tab.tsx
1865
- import { cloneElement as cloneElement4, isValidElement as isValidElement4 } from "react";
1866
- import { Pressable as Pressable8, Text as Text9, View as View16 } from "react-native";
3287
+ import { cloneElement as cloneElement6, isValidElement as isValidElement7 } from "react";
3288
+ import { Pressable as Pressable12, Text as Text13, View as View26 } from "react-native";
1867
3289
 
1868
3290
  // src/components/Tabs/Tab/Tab.styles.ts
1869
- import { StyleSheet as StyleSheet18 } from "react-native";
3291
+ import { StyleSheet as StyleSheet22 } from "react-native";
1870
3292
  var fontWeight2 = (value) => value;
1871
- var createStyles18 = (theme) => StyleSheet18.create({
3293
+ var createStyles16 = (theme) => StyleSheet22.create({
1872
3294
  tab: {
1873
3295
  minHeight: 40,
1874
3296
  alignItems: "center",
@@ -1986,7 +3408,7 @@ var createStyles18 = (theme) => StyleSheet18.create({
1986
3408
  });
1987
3409
 
1988
3410
  // src/components/Tabs/Tab/Tab.tsx
1989
- import { Fragment as Fragment2, jsx as jsx20, jsxs as jsxs10 } from "react/jsx-runtime";
3411
+ import { Fragment as Fragment4, jsx as jsx32, jsxs as jsxs18 } from "react/jsx-runtime";
1990
3412
  var Tab = ({
1991
3413
  index,
1992
3414
  children,
@@ -1996,7 +3418,7 @@ var Tab = ({
1996
3418
  textStyle
1997
3419
  }) => {
1998
3420
  const { theme } = useTheme();
1999
- const styles = useThemeStyles(createStyles18);
3421
+ const styles = useThemeStyles(createStyles16);
2000
3422
  const { activeIndex, appearance, orientation, setActiveIndex } = useTabs();
2001
3423
  const isActive = activeIndex === index;
2002
3424
  const isPills = appearance === "pills";
@@ -2004,11 +3426,11 @@ var Tab = ({
2004
3426
  const isDefault = appearance === "default";
2005
3427
  const isVertical = orientation === "vertical";
2006
3428
  const iconColor = isPills && isActive ? theme.components.tabs.pills.active.fg : isActive ? theme.components.tabs.trigger.active.fg : theme.components.tabs.trigger.default.fg;
2007
- const renderedIcon = isValidElement4(icon) ? cloneElement4(icon, {
3429
+ const renderedIcon = isValidElement7(icon) ? cloneElement6(icon, {
2008
3430
  color: iconColor
2009
3431
  }) : icon;
2010
- return /* @__PURE__ */ jsx20(
2011
- Pressable8,
3432
+ return /* @__PURE__ */ jsx32(
3433
+ Pressable12,
2012
3434
  {
2013
3435
  disabled,
2014
3436
  accessibilityRole: "tab",
@@ -2028,9 +3450,9 @@ var Tab = ({
2028
3450
  disabled && styles.tabDisabled,
2029
3451
  style
2030
3452
  ],
2031
- children: ({ pressed }) => /* @__PURE__ */ jsxs10(Fragment2, { children: [
2032
- isUnderline && !isVertical && /* @__PURE__ */ jsx20(
2033
- View16,
3453
+ children: ({ pressed }) => /* @__PURE__ */ jsxs18(Fragment4, { children: [
3454
+ isUnderline && !isVertical && /* @__PURE__ */ jsx32(
3455
+ View26,
2034
3456
  {
2035
3457
  pointerEvents: "none",
2036
3458
  style: [
@@ -2039,8 +3461,8 @@ var Tab = ({
2039
3461
  ]
2040
3462
  }
2041
3463
  ),
2042
- isUnderline && isVertical && /* @__PURE__ */ jsx20(
2043
- View16,
3464
+ isUnderline && isVertical && /* @__PURE__ */ jsx32(
3465
+ View26,
2044
3466
  {
2045
3467
  pointerEvents: "none",
2046
3468
  style: [
@@ -2050,9 +3472,9 @@ var Tab = ({
2050
3472
  ]
2051
3473
  }
2052
3474
  ),
2053
- icon != null && /* @__PURE__ */ jsx20(View16, { style: styles.tabIcon, children: renderedIcon }),
2054
- children != null && /* @__PURE__ */ jsx20(
2055
- Text9,
3475
+ icon != null && /* @__PURE__ */ jsx32(View26, { style: styles.tabIcon, children: renderedIcon }),
3476
+ children != null && /* @__PURE__ */ jsx32(
3477
+ Text13,
2056
3478
  {
2057
3479
  numberOfLines: 2,
2058
3480
  ellipsizeMode: "tail",
@@ -2073,13 +3495,13 @@ var Tab = ({
2073
3495
  Tab.displayName = "Tab";
2074
3496
 
2075
3497
  // src/components/Tabs/Tabs.tsx
2076
- import { useMemo as useMemo4 } from "react";
3498
+ import { useMemo as useMemo7 } from "react";
2077
3499
  import { useTabs as useTabs2 } from "@vellira-ui/core";
2078
- import { View as View17 } from "react-native";
3500
+ import { View as View27 } from "react-native";
2079
3501
 
2080
3502
  // src/components/Tabs/Tabs.styles.ts
2081
- import { StyleSheet as StyleSheet19 } from "react-native";
2082
- var createStyles19 = (theme) => StyleSheet19.create({
3503
+ import { StyleSheet as StyleSheet23 } from "react-native";
3504
+ var createStyles17 = (theme) => StyleSheet23.create({
2083
3505
  root: {
2084
3506
  width: "100%",
2085
3507
  minWidth: 0
@@ -2094,7 +3516,7 @@ var createStyles19 = (theme) => StyleSheet19.create({
2094
3516
  });
2095
3517
 
2096
3518
  // src/components/Tabs/Tabs.tsx
2097
- import { jsx as jsx21 } from "react/jsx-runtime";
3519
+ import { jsx as jsx33 } from "react/jsx-runtime";
2098
3520
  var TabsRoot = ({
2099
3521
  children,
2100
3522
  activeIndex: controlledActiveIndex,
@@ -2104,19 +3526,19 @@ var TabsRoot = ({
2104
3526
  appearance = "pills",
2105
3527
  style
2106
3528
  }) => {
2107
- const styles = useThemeStyles(createStyles19);
3529
+ const styles = useThemeStyles(createStyles17);
2108
3530
  const { activeIndex, setActiveIndex } = useTabs2({
2109
3531
  activeIndex: controlledActiveIndex,
2110
3532
  defaultActiveIndex,
2111
3533
  onChange,
2112
3534
  orientation
2113
3535
  });
2114
- const value = useMemo4(
3536
+ const value = useMemo7(
2115
3537
  () => ({ activeIndex, appearance, orientation, setActiveIndex }),
2116
3538
  [activeIndex, appearance, orientation, setActiveIndex]
2117
3539
  );
2118
- return /* @__PURE__ */ jsx21(TabsProvider, { value, children: /* @__PURE__ */ jsx21(
2119
- View17,
3540
+ return /* @__PURE__ */ jsx33(TabsProvider, { value, children: /* @__PURE__ */ jsx33(
3541
+ View27,
2120
3542
  {
2121
3543
  style: [
2122
3544
  styles.root,
@@ -2137,20 +3559,20 @@ var Tabs = Object.assign(TabsRoot, {
2137
3559
  });
2138
3560
 
2139
3561
  // src/components/Tooltip/Tooltip.tsx
2140
- import { useEffect as useEffect3, useRef as useRef3, useState as useState4 } from "react";
2141
- import { Modal as Modal4, Pressable as Pressable9, Text as Text10, View as View18 } from "react-native";
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";
2142
3564
 
2143
3565
  // src/hooks/useNativeFloatingPosition.ts
2144
- import { useCallback as useCallback2, useRef as useRef2, useState as useState3 } from "react";
3566
+ import { useCallback as useCallback2, useRef as useRef4, useState as useState5 } from "react";
2145
3567
  import { Dimensions } from "react-native";
2146
3568
  var safePadding = 12;
2147
3569
  function useNativeFloatingPosition(placement = "top", offset = 8) {
2148
- const [position, setPosition] = useState3({ top: 0, left: 0 });
2149
- const floatingSizeRef = useRef2({
3570
+ const [position, setPosition] = useState5({ top: 0, left: 0 });
3571
+ const floatingSizeRef = useRef4({
2150
3572
  width: 0,
2151
3573
  height: 0
2152
3574
  });
2153
- const lastTriggerRef = useRef2(null);
3575
+ const lastTriggerRef = useRef4(null);
2154
3576
  const clamp = useCallback2((value, min, max) => {
2155
3577
  return Math.min(Math.max(value, min), Math.max(min, max));
2156
3578
  }, []);
@@ -2207,13 +3629,13 @@ function useNativeFloatingPosition(placement = "top", offset = 8) {
2207
3629
  }
2208
3630
 
2209
3631
  // src/components/Tooltip/Tooltip.styles.ts
2210
- import { StyleSheet as StyleSheet20 } from "react-native";
2211
- var createStyles20 = (theme) => StyleSheet20.create({
3632
+ import { StyleSheet as StyleSheet24 } from "react-native";
3633
+ var createStyles18 = (theme) => StyleSheet24.create({
2212
3634
  root: {
2213
3635
  alignSelf: "flex-start"
2214
3636
  },
2215
3637
  overlay: {
2216
- ...StyleSheet20.absoluteFill
3638
+ ...StyleSheet24.absoluteFill
2217
3639
  },
2218
3640
  bubble: {
2219
3641
  position: "absolute",
@@ -2245,7 +3667,7 @@ var createStyles20 = (theme) => StyleSheet20.create({
2245
3667
  });
2246
3668
 
2247
3669
  // src/components/Tooltip/Tooltip.tsx
2248
- import { jsx as jsx22, jsxs as jsxs11 } from "react/jsx-runtime";
3670
+ import { jsx as jsx34, jsxs as jsxs19 } from "react/jsx-runtime";
2249
3671
  function Tooltip({
2250
3672
  children,
2251
3673
  content,
@@ -2257,10 +3679,10 @@ function Tooltip({
2257
3679
  contentStyle,
2258
3680
  textStyle
2259
3681
  }) {
2260
- const styles = useThemeStyles(createStyles20);
2261
- const [visible, setVisible] = useState4(false);
2262
- const triggerRef = useRef3(null);
2263
- const closeTimerRef = useRef3(null);
3682
+ const styles = useThemeStyles(createStyles18);
3683
+ const [visible, setVisible] = useState6(false);
3684
+ const triggerRef = useRef5(null);
3685
+ const closeTimerRef = useRef5(null);
2264
3686
  const { position, updatePosition, onFloatingLayout } = useNativeFloatingPosition(placement, 8);
2265
3687
  const hideDelay = delay?.close ?? 2500;
2266
3688
  const clearCloseTimer = () => {
@@ -2279,21 +3701,21 @@ function Tooltip({
2279
3701
  closeTimerRef.current = null;
2280
3702
  }, hideDelay);
2281
3703
  };
2282
- useEffect3(() => {
3704
+ useEffect5(() => {
2283
3705
  return clearCloseTimer;
2284
3706
  }, []);
2285
- return /* @__PURE__ */ jsxs11(View18, { style: [styles.root, style], children: [
2286
- /* @__PURE__ */ jsx22(Pressable9, { ref: triggerRef, onLongPress: showTooltip, children }),
2287
- /* @__PURE__ */ jsx22(Modal4, { visible: visible && !disabled, transparent: true, animationType: "fade", children: /* @__PURE__ */ jsx22(
2288
- Pressable9,
3707
+ return /* @__PURE__ */ jsxs19(View28, { style: [styles.root, style], children: [
3708
+ /* @__PURE__ */ jsx34(Pressable13, { ref: triggerRef, onLongPress: showTooltip, children }),
3709
+ /* @__PURE__ */ jsx34(Modal6, { visible: visible && !disabled, transparent: true, animationType: "fade", children: /* @__PURE__ */ jsx34(
3710
+ Pressable13,
2289
3711
  {
2290
3712
  style: styles.overlay,
2291
3713
  onPress: () => {
2292
3714
  clearCloseTimer();
2293
3715
  setVisible(false);
2294
3716
  },
2295
- children: /* @__PURE__ */ jsx22(
2296
- View18,
3717
+ children: /* @__PURE__ */ jsx34(
3718
+ View28,
2297
3719
  {
2298
3720
  pointerEvents: "none",
2299
3721
  style: [
@@ -2306,7 +3728,7 @@ function Tooltip({
2306
3728
  contentStyle
2307
3729
  ],
2308
3730
  onLayout: onFloatingLayout,
2309
- children: typeof content === "string" ? /* @__PURE__ */ jsx22(Text10, { style: [styles.text, textStyle], children: content }) : content
3731
+ children: typeof content === "string" ? /* @__PURE__ */ jsx34(Text14, { style: [styles.text, textStyle], children: content }) : content
2310
3732
  }
2311
3733
  )
2312
3734
  }
@@ -2316,8 +3738,8 @@ function Tooltip({
2316
3738
  Tooltip.displayName = "Tooltip";
2317
3739
 
2318
3740
  // src/primitives/Button/Button.tsx
2319
- import { cloneElement as cloneElement5, useState as useState5 } from "react";
2320
- import { ActivityIndicator, Pressable as Pressable10, Text as Text11, View as View19 } from "react-native";
3741
+ 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";
2321
3743
 
2322
3744
  // src/utils/devWarning.ts
2323
3745
  var devWarning = (condition, message) => {
@@ -2327,9 +3749,9 @@ var devWarning = (condition, message) => {
2327
3749
  };
2328
3750
 
2329
3751
  // src/primitives/Button/Button.styles.ts
2330
- import { StyleSheet as StyleSheet21 } from "react-native";
3752
+ import { StyleSheet as StyleSheet25 } from "react-native";
2331
3753
  var fontWeight3 = (value) => value;
2332
- var createStyles21 = (theme) => StyleSheet21.create({
3754
+ var createStyles19 = (theme) => StyleSheet25.create({
2333
3755
  button: {
2334
3756
  flexDirection: "row",
2335
3757
  alignItems: "center",
@@ -2394,7 +3816,7 @@ var createStyles21 = (theme) => StyleSheet21.create({
2394
3816
  });
2395
3817
 
2396
3818
  // src/primitives/Button/Button.tsx
2397
- import { Fragment as Fragment3, jsx as jsx23, jsxs as jsxs12 } from "react/jsx-runtime";
3819
+ import { Fragment as Fragment5, jsx as jsx35, jsxs as jsxs20 } from "react/jsx-runtime";
2398
3820
  var sizeMap = {
2399
3821
  sm: {
2400
3822
  px: 12,
@@ -2446,13 +3868,13 @@ function Button({
2446
3868
  ...props
2447
3869
  }) {
2448
3870
  const { theme } = useTheme();
2449
- const styles = useThemeStyles(createStyles21);
3871
+ const styles = useThemeStyles(createStyles19);
2450
3872
  const config = sizeMap[size];
2451
3873
  const radius = shape === "square" ? theme.tokens.radius.sm : shape === "rounded" ? theme.tokens.radius.md : theme.tokens.radius.full;
2452
3874
  const appearanceTheme = theme.components.button[color][appearance];
2453
- const [isHovered, setIsHovered] = useState5(false);
2454
- const [isFocused, setIsFocused] = useState5(false);
2455
- const [labelWidth, setLabelWidth] = useState5(0);
3875
+ const [isHovered, setIsHovered] = useState7(false);
3876
+ const [isFocused, setIsFocused] = useState7(false);
3877
+ const [labelWidth, setLabelWidth] = useState7(0);
2456
3878
  const isDisabled = disabled || loading;
2457
3879
  const iconOnly = iconOnlyProp || !children && Boolean(iconStart || iconEnd);
2458
3880
  const content = loading && loadingText ? loadingText : children;
@@ -2478,7 +3900,7 @@ function Button({
2478
3900
  setIsHovered(false);
2479
3901
  onHoverOut?.(event);
2480
3902
  };
2481
- const renderIcon = (icon, iconColor) => cloneElement5(icon, {
3903
+ const renderIcon = (icon, iconColor) => cloneElement7(icon, {
2482
3904
  color: iconColor,
2483
3905
  size: resolvedIconSize
2484
3906
  });
@@ -2489,8 +3911,8 @@ function Button({
2489
3911
  );
2490
3912
  };
2491
3913
  const getInteractionTheme = (pressed) => isDisabled ? theme.components.button.disabled : pressed ? appearanceTheme.pressed : isHovered ? appearanceTheme.hover : appearanceTheme.default;
2492
- return /* @__PURE__ */ jsx23(
2493
- Pressable10,
3914
+ return /* @__PURE__ */ jsx35(
3915
+ Pressable14,
2494
3916
  {
2495
3917
  ...props,
2496
3918
  testID,
@@ -2526,12 +3948,12 @@ function Button({
2526
3948
  children: ({ pressed }) => {
2527
3949
  const interactionTheme = getInteractionTheme(pressed);
2528
3950
  const contentColor = interactionTheme.fg;
2529
- return /* @__PURE__ */ jsxs12(Fragment3, { children: [
2530
- loading && /* @__PURE__ */ jsx23(ActivityIndicator, { size: "small", color: contentColor }),
3951
+ return /* @__PURE__ */ jsxs20(Fragment5, { children: [
3952
+ loading && /* @__PURE__ */ jsx35(ActivityIndicator3, { size: "small", color: contentColor }),
2531
3953
  !loading && iconStart && renderIcon(iconStart, contentColor),
2532
- content && !iconOnly && /* @__PURE__ */ jsxs12(View19, { style: styles.labelSlot, children: [
2533
- /* @__PURE__ */ jsx23(
2534
- Text11,
3954
+ content && !iconOnly && /* @__PURE__ */ jsxs20(View29, { style: styles.labelSlot, children: [
3955
+ /* @__PURE__ */ jsx35(
3956
+ Text15,
2535
3957
  {
2536
3958
  onLayout: handleLabelLayout,
2537
3959
  style: [
@@ -2546,8 +3968,8 @@ function Button({
2546
3968
  children: content
2547
3969
  }
2548
3970
  ),
2549
- measureLabel && /* @__PURE__ */ jsx23(
2550
- Text11,
3971
+ measureLabel && /* @__PURE__ */ jsx35(
3972
+ Text15,
2551
3973
  {
2552
3974
  accessibilityElementsHidden: true,
2553
3975
  importantForAccessibility: "no-hide-descendants",
@@ -2564,8 +3986,8 @@ function Button({
2564
3986
  }
2565
3987
  )
2566
3988
  ] }),
2567
- badge && !iconOnly && /* @__PURE__ */ jsx23(
2568
- Text11,
3989
+ badge && !iconOnly && /* @__PURE__ */ jsx35(
3990
+ Text15,
2569
3991
  {
2570
3992
  style: [
2571
3993
  styles.badge,
@@ -2577,8 +3999,8 @@ function Button({
2577
3999
  children: badge
2578
4000
  }
2579
4001
  ),
2580
- shortcut && !iconOnly && /* @__PURE__ */ jsx23(
2581
- Text11,
4002
+ shortcut && !iconOnly && /* @__PURE__ */ jsx35(
4003
+ Text15,
2582
4004
  {
2583
4005
  style: [
2584
4006
  styles.shortcut,
@@ -2597,14 +4019,14 @@ function Button({
2597
4019
  }
2598
4020
 
2599
4021
  // src/primitives/Checkbox/Checkbox.tsx
2600
- import { forwardRef as forwardRef2, useEffect as useEffect4 } from "react";
4022
+ import { forwardRef as forwardRef2, useEffect as useEffect6 } from "react";
2601
4023
  import { useControllableState as useControllableState3 } from "@vellira-ui/core";
2602
- import { Check } from "@vellira-ui/icons";
2603
- import { Pressable as Pressable11, Text as Text12, View as View20 } from "react-native";
4024
+ import { Check as Check2 } from "@vellira-ui/icons";
4025
+ import { Pressable as Pressable15, Text as Text16, View as View30 } from "react-native";
2604
4026
 
2605
4027
  // src/primitives/Checkbox/Checkbox.styles.ts
2606
- import { StyleSheet as StyleSheet22 } from "react-native";
2607
- var createStyles22 = (theme) => StyleSheet22.create({
4028
+ import { StyleSheet as StyleSheet26 } from "react-native";
4029
+ var createStyles20 = (theme) => StyleSheet26.create({
2608
4030
  container: {
2609
4031
  gap: theme.tokens.spacing[2]
2610
4032
  },
@@ -2747,7 +4169,7 @@ var createStyles22 = (theme) => StyleSheet22.create({
2747
4169
  });
2748
4170
 
2749
4171
  // src/primitives/Checkbox/Checkbox.tsx
2750
- import { Fragment as Fragment4, jsx as jsx24, jsxs as jsxs13 } from "react/jsx-runtime";
4172
+ import { Fragment as Fragment6, jsx as jsx36, jsxs as jsxs21 } from "react/jsx-runtime";
2751
4173
  var iconSizeBySize = {
2752
4174
  sm: 10,
2753
4175
  md: 12,
@@ -2775,7 +4197,7 @@ var Checkbox = forwardRef2(
2775
4197
  ...PressableProps
2776
4198
  }, ref) => {
2777
4199
  const { theme } = useTheme();
2778
- const styles = useThemeStyles(createStyles22);
4200
+ const styles = useThemeStyles(createStyles20);
2779
4201
  const checkboxColor = theme.components.checkbox[color];
2780
4202
  const boxSizeStyle = {
2781
4203
  sm: styles.boxSm,
@@ -2805,15 +4227,15 @@ var Checkbox = forwardRef2(
2805
4227
  const resolvedAccessibilityLabel = accessibilityLabel ?? label;
2806
4228
  const resolvedAccessibilityHint = [accessibilityHint, description, error].filter(Boolean).join(" ");
2807
4229
  const accessibilityChecked = indeterminate ? "mixed" : isChecked;
2808
- useEffect4(() => {
4230
+ useEffect6(() => {
2809
4231
  devWarning(
2810
4232
  Boolean(resolvedAccessibilityLabel),
2811
4233
  "Checkbox: an accessible label must be provided through label or accessibilityLabel."
2812
4234
  );
2813
4235
  }, [resolvedAccessibilityLabel]);
2814
- return /* @__PURE__ */ jsxs13(View20, { style: styles.container, children: [
2815
- /* @__PURE__ */ jsx24(
2816
- Pressable11,
4236
+ return /* @__PURE__ */ jsxs21(View30, { style: styles.container, children: [
4237
+ /* @__PURE__ */ jsx36(
4238
+ Pressable15,
2817
4239
  {
2818
4240
  ...PressableProps,
2819
4241
  ref,
@@ -2836,9 +4258,9 @@ var Checkbox = forwardRef2(
2836
4258
  children: ({ pressed }) => {
2837
4259
  const isSelected = isChecked || indeterminate;
2838
4260
  const checkColor = disabled ? theme.components.checkbox.disabled.fg : pressed && isSelected ? checkboxColor.pressed.fg : checkboxColor.default.fg;
2839
- return /* @__PURE__ */ jsxs13(Fragment4, { children: [
2840
- /* @__PURE__ */ jsx24(
2841
- View20,
4261
+ return /* @__PURE__ */ jsxs21(Fragment6, { children: [
4262
+ /* @__PURE__ */ jsx36(
4263
+ View30,
2842
4264
  {
2843
4265
  style: [
2844
4266
  styles.box,
@@ -2855,8 +4277,8 @@ var Checkbox = forwardRef2(
2855
4277
  hasError && styles.boxError,
2856
4278
  disabled && styles.boxDisabled
2857
4279
  ],
2858
- children: indeterminate ? indeterminateIcon ?? /* @__PURE__ */ jsx24(
2859
- View20,
4280
+ children: indeterminate ? indeterminateIcon ?? /* @__PURE__ */ jsx36(
4281
+ View30,
2860
4282
  {
2861
4283
  style: [
2862
4284
  styles.indeterminateMark,
@@ -2865,11 +4287,11 @@ var Checkbox = forwardRef2(
2865
4287
  }
2866
4288
  ]
2867
4289
  }
2868
- ) : isChecked && (icon ?? /* @__PURE__ */ jsx24(Check, { size: iconSizeBySize[size], color: checkColor }))
4290
+ ) : isChecked && (icon ?? /* @__PURE__ */ jsx36(Check2, { size: iconSizeBySize[size], color: checkColor }))
2869
4291
  }
2870
4292
  ),
2871
- label && /* @__PURE__ */ jsxs13(
2872
- Text12,
4293
+ label && /* @__PURE__ */ jsxs21(
4294
+ Text16,
2873
4295
  {
2874
4296
  style: [
2875
4297
  styles.label,
@@ -2882,7 +4304,7 @@ var Checkbox = forwardRef2(
2882
4304
  ],
2883
4305
  children: [
2884
4306
  label,
2885
- required && /* @__PURE__ */ jsx24(Text12, { style: styles.requiredMark, children: " *" })
4307
+ required && /* @__PURE__ */ jsx36(Text16, { style: styles.requiredMark, children: " *" })
2886
4308
  ]
2887
4309
  }
2888
4310
  )
@@ -2890,8 +4312,8 @@ var Checkbox = forwardRef2(
2890
4312
  }
2891
4313
  }
2892
4314
  ),
2893
- description && /* @__PURE__ */ jsx24(
2894
- Text12,
4315
+ description && /* @__PURE__ */ jsx36(
4316
+ Text16,
2895
4317
  {
2896
4318
  style: [
2897
4319
  styles.descriptionText,
@@ -2901,21 +4323,21 @@ var Checkbox = forwardRef2(
2901
4323
  children: description
2902
4324
  }
2903
4325
  ),
2904
- hasError && /* @__PURE__ */ jsx24(Text12, { style: [styles.errorText, helperTextSizeStyle[size]], children: error })
4326
+ hasError && /* @__PURE__ */ jsx36(Text16, { style: [styles.errorText, helperTextSizeStyle[size]], children: error })
2905
4327
  ] });
2906
4328
  }
2907
4329
  );
2908
4330
  Checkbox.displayName = "Checkbox";
2909
4331
 
2910
4332
  // src/primitives/Input/Input.tsx
2911
- import { cloneElement as cloneElement6, forwardRef as forwardRef3, useState as useState6 } from "react";
2912
- import { Pressable as Pressable12, Text as Text13, TextInput, View as View21 } from "react-native";
4333
+ 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";
2913
4335
 
2914
4336
  // src/primitives/Input/Input.styles.ts
2915
- import { StyleSheet as StyleSheet23 } from "react-native";
4337
+ import { StyleSheet as StyleSheet27 } from "react-native";
2916
4338
  var getDisabledPlaceholderTextColor = (theme) => theme.components.input.disabled.placeholder;
2917
4339
  var resolveRingColor = (ring) => typeof ring === "string" ? ring : ring.color;
2918
- var createStyles23 = (theme) => StyleSheet23.create({
4340
+ var createStyles21 = (theme) => StyleSheet27.create({
2919
4341
  inputWrapper: {
2920
4342
  position: "relative",
2921
4343
  width: "100%",
@@ -3059,7 +4481,7 @@ var createStyles23 = (theme) => StyleSheet23.create({
3059
4481
  });
3060
4482
 
3061
4483
  // src/primitives/Input/Input.tsx
3062
- import { jsx as jsx25, jsxs as jsxs14 } from "react/jsx-runtime";
4484
+ import { jsx as jsx37, jsxs as jsxs22 } from "react/jsx-runtime";
3063
4485
  var keyboardTypeByInputType = {
3064
4486
  text: "default",
3065
4487
  email: "email-address",
@@ -3157,11 +4579,11 @@ var Input = forwardRef3(
3157
4579
  ...props
3158
4580
  }, ref) => {
3159
4581
  const { theme } = useTheme();
3160
- const styles = useThemeStyles(createStyles23);
4582
+ const styles = useThemeStyles(createStyles21);
3161
4583
  const field = useFormFieldContext();
3162
4584
  const hasOwnField = Boolean(label || description || error);
3163
- const [isFocused, setIsFocused] = useState6(false);
3164
- const [uncontrolledValue, setUncontrolledValue] = useState6(
4585
+ const [isFocused, setIsFocused] = useState8(false);
4586
+ const [uncontrolledValue, setUncontrolledValue] = useState8(
3165
4587
  defaultValue ?? ""
3166
4588
  );
3167
4589
  const isControlled = value !== void 0;
@@ -3178,7 +4600,7 @@ var Input = forwardRef3(
3178
4600
  const isReadOnly = readOnly || loading;
3179
4601
  const placeholderTextColor = isDisabled ? getDisabledPlaceholderTextColor(theme) : readOnly ? theme.components.input.readOnly.placeholder : inputState.placeholder;
3180
4602
  const isPassword = type === "password";
3181
- const [isPasswordRevealed, setIsPasswordRevealed] = useState6(false);
4603
+ const [isPasswordRevealed, setIsPasswordRevealed] = useState8(false);
3182
4604
  const resolvedIconSize = iconSize ?? 16;
3183
4605
  const handleFocus = (event) => {
3184
4606
  setIsFocused(true);
@@ -3209,22 +4631,22 @@ var Input = forwardRef3(
3209
4631
  const startIconColor = isDisabled ? theme.components.input.disabled.icon : theme.components.input.icon[startIconTone];
3210
4632
  const endIconColor = isDisabled ? theme.components.input.disabled.icon : theme.components.input.icon[endIconTone];
3211
4633
  const clearIconColor = isDisabled ? theme.components.input.disabled.icon : theme.components.input.icon[clearIconTone];
3212
- const control = /* @__PURE__ */ jsxs14(View21, { style: styles.inputWrapper, children: [
3213
- startIcon && /* @__PURE__ */ jsx25(
3214
- View21,
4634
+ const control = /* @__PURE__ */ jsxs22(View31, { style: styles.inputWrapper, children: [
4635
+ startIcon && /* @__PURE__ */ jsx37(
4636
+ View31,
3215
4637
  {
3216
4638
  pointerEvents: "none",
3217
4639
  style: styles.leftIcon,
3218
4640
  accessibilityElementsHidden: true,
3219
4641
  importantForAccessibility: "no",
3220
- children: cloneElement6(startIcon, {
4642
+ children: cloneElement8(startIcon, {
3221
4643
  color: startIconColor,
3222
4644
  size: resolvedIconSize
3223
4645
  })
3224
4646
  }
3225
4647
  ),
3226
- /* @__PURE__ */ jsx25(
3227
- TextInput,
4648
+ /* @__PURE__ */ jsx37(
4649
+ TextInput2,
3228
4650
  {
3229
4651
  ...props,
3230
4652
  ref,
@@ -3279,37 +4701,37 @@ var Input = forwardRef3(
3279
4701
  ]
3280
4702
  }
3281
4703
  ),
3282
- showClearButton ? /* @__PURE__ */ jsx25(
3283
- Pressable12,
4704
+ showClearButton ? /* @__PURE__ */ jsx37(
4705
+ Pressable16,
3284
4706
  {
3285
4707
  accessibilityRole: "button",
3286
4708
  accessibilityLabel: "Clear input",
3287
4709
  hitSlop: 8,
3288
4710
  onPress: handleClear,
3289
4711
  style: styles.clearButton,
3290
- children: clearIcon ? cloneElement6(clearIcon, {
4712
+ children: clearIcon ? cloneElement8(clearIcon, {
3291
4713
  color: clearIconColor,
3292
4714
  size: resolvedIconSize
3293
- }) : /* @__PURE__ */ jsx25(Text13, { style: [styles.clearButtonText, { color: clearIconColor }], children: "\xD7" })
4715
+ }) : /* @__PURE__ */ jsx37(Text17, { style: [styles.clearButtonText, { color: clearIconColor }], children: "\xD7" })
3294
4716
  }
3295
- ) : showRevealButton ? /* @__PURE__ */ jsx25(
3296
- Pressable12,
4717
+ ) : showRevealButton ? /* @__PURE__ */ jsx37(
4718
+ Pressable16,
3297
4719
  {
3298
4720
  accessibilityRole: "button",
3299
4721
  accessibilityLabel: isPasswordRevealed ? "Hide password" : "Show password",
3300
4722
  hitSlop: 8,
3301
4723
  onPress: () => setIsPasswordRevealed((revealed) => !revealed),
3302
4724
  style: styles.revealButton,
3303
- children: /* @__PURE__ */ jsx25(Text13, { style: styles.revealButtonText, children: isPasswordRevealed ? "Hide" : "Show" })
4725
+ children: /* @__PURE__ */ jsx37(Text17, { style: styles.revealButtonText, children: isPasswordRevealed ? "Hide" : "Show" })
3304
4726
  }
3305
- ) : showRightIcon && endIcon && /* @__PURE__ */ jsx25(
3306
- View21,
4727
+ ) : showRightIcon && endIcon && /* @__PURE__ */ jsx37(
4728
+ View31,
3307
4729
  {
3308
4730
  pointerEvents: "none",
3309
4731
  style: styles.rightIcon,
3310
4732
  accessibilityElementsHidden: true,
3311
4733
  importantForAccessibility: "no",
3312
- children: cloneElement6(endIcon, {
4734
+ children: cloneElement8(endIcon, {
3313
4735
  color: endIconColor,
3314
4736
  size: resolvedIconSize
3315
4737
  })
@@ -3319,7 +4741,7 @@ var Input = forwardRef3(
3319
4741
  if (!hasOwnField && field) {
3320
4742
  return control;
3321
4743
  }
3322
- return /* @__PURE__ */ jsx25(
4744
+ return /* @__PURE__ */ jsx37(
3323
4745
  FormField,
3324
4746
  {
3325
4747
  label,
@@ -3338,17 +4760,17 @@ var Input = forwardRef3(
3338
4760
  Input.displayName = "Input";
3339
4761
 
3340
4762
  // src/primitives/Radio/Radio.tsx
3341
- import { forwardRef as forwardRef4, useEffect as useEffect5 } from "react";
4763
+ import { forwardRef as forwardRef4, useEffect as useEffect7 } from "react";
3342
4764
  import { useControllableState as useControllableState4 } from "@vellira-ui/core";
3343
4765
  import {
3344
- Pressable as Pressable13,
3345
- Text as Text14,
3346
- View as View22
4766
+ Pressable as Pressable17,
4767
+ Text as Text18,
4768
+ View as View32
3347
4769
  } from "react-native";
3348
4770
 
3349
4771
  // src/primitives/Radio/Radio.styles.ts
3350
- import { StyleSheet as StyleSheet24 } from "react-native";
3351
- var createStyles24 = (theme) => StyleSheet24.create({
4772
+ import { StyleSheet as StyleSheet28 } from "react-native";
4773
+ var createStyles22 = (theme) => StyleSheet28.create({
3352
4774
  root: {
3353
4775
  alignSelf: "flex-start"
3354
4776
  },
@@ -3433,7 +4855,7 @@ var createStyles24 = (theme) => StyleSheet24.create({
3433
4855
  });
3434
4856
 
3435
4857
  // src/primitives/Radio/Radio.tsx
3436
- import { Fragment as Fragment5, jsx as jsx26, jsxs as jsxs15 } from "react/jsx-runtime";
4858
+ import { Fragment as Fragment7, jsx as jsx38, jsxs as jsxs23 } from "react/jsx-runtime";
3437
4859
  var controlSizeBySize = {
3438
4860
  sm: 14,
3439
4861
  md: 16,
@@ -3468,7 +4890,7 @@ var Radio = forwardRef4(
3468
4890
  ...rest
3469
4891
  }, ref) => {
3470
4892
  const { theme } = useTheme();
3471
- const styles = createStyles24(theme);
4893
+ const styles = createStyles22(theme);
3472
4894
  const group = useRadioGroupContext();
3473
4895
  const isInsideGroup = group !== null;
3474
4896
  const [standaloneChecked, setStandaloneChecked] = useControllableState4({
@@ -3507,7 +4929,7 @@ var Radio = forwardRef4(
3507
4929
  };
3508
4930
  const typographySize = typographySizeByRadioSize[resolvedSize];
3509
4931
  const controlMarginTop = (typographySize.labelLineHeight - controlSize) / 2;
3510
- useEffect5(() => {
4932
+ useEffect7(() => {
3511
4933
  if (typeof __DEV__ !== "undefined" && __DEV__ && !label && !accessibilityLabel) {
3512
4934
  console.warn(
3513
4935
  "Radio requires either a visible label or accessibilityLabel."
@@ -3536,9 +4958,9 @@ var Radio = forwardRef4(
3536
4958
  state.pressed && !resolvedDisabled && styles.pressablePressed,
3537
4959
  typeof style === "function" ? style(state) : style
3538
4960
  ];
3539
- return /* @__PURE__ */ jsxs15(View22, { style: [styles.root, containerStyle], children: [
3540
- /* @__PURE__ */ jsx26(
3541
- Pressable13,
4961
+ return /* @__PURE__ */ jsxs23(View32, { style: [styles.root, containerStyle], children: [
4962
+ /* @__PURE__ */ jsx38(
4963
+ Pressable17,
3542
4964
  {
3543
4965
  ...rest,
3544
4966
  ref,
@@ -3552,9 +4974,9 @@ var Radio = forwardRef4(
3552
4974
  disabled: resolvedDisabled,
3553
4975
  onPress: handlePress,
3554
4976
  style: resolvePressableStyle,
3555
- children: (state) => /* @__PURE__ */ jsxs15(Fragment5, { children: [
3556
- /* @__PURE__ */ jsx26(
3557
- View22,
4977
+ children: (state) => /* @__PURE__ */ jsxs23(Fragment7, { children: [
4978
+ /* @__PURE__ */ jsx38(
4979
+ View32,
3558
4980
  {
3559
4981
  pointerEvents: "none",
3560
4982
  style: [
@@ -3577,8 +4999,8 @@ var Radio = forwardRef4(
3577
4999
  resolvedDisabled && styles.controlDisabled,
3578
5000
  resolvedChecked && resolvedDisabled && styles.controlCheckedDisabled
3579
5001
  ],
3580
- children: resolvedChecked && (icon ?? /* @__PURE__ */ jsx26(
3581
- View22,
5002
+ children: resolvedChecked && (icon ?? /* @__PURE__ */ jsx38(
5003
+ View32,
3582
5004
  {
3583
5005
  style: [
3584
5006
  styles.indicator,
@@ -3593,9 +5015,9 @@ var Radio = forwardRef4(
3593
5015
  ))
3594
5016
  }
3595
5017
  ),
3596
- (label || description) && /* @__PURE__ */ jsxs15(View22, { pointerEvents: "none", style: styles.content, children: [
3597
- label && (typeof label === "string" ? /* @__PURE__ */ jsx26(
3598
- Text14,
5018
+ (label || description) && /* @__PURE__ */ jsxs23(View32, { pointerEvents: "none", style: styles.content, children: [
5019
+ label && (typeof label === "string" ? /* @__PURE__ */ jsx38(
5020
+ Text18,
3599
5021
  {
3600
5022
  style: [
3601
5023
  styles.label,
@@ -3616,8 +5038,8 @@ var Radio = forwardRef4(
3616
5038
  children: label
3617
5039
  }
3618
5040
  ) : label),
3619
- description && (typeof description === "string" ? /* @__PURE__ */ jsx26(
3620
- Text14,
5041
+ description && (typeof description === "string" ? /* @__PURE__ */ jsx38(
5042
+ Text18,
3621
5043
  {
3622
5044
  style: [
3623
5045
  styles.description,
@@ -3635,8 +5057,8 @@ var Radio = forwardRef4(
3635
5057
  ] })
3636
5058
  }
3637
5059
  ),
3638
- error && /* @__PURE__ */ jsx26(
3639
- Text14,
5060
+ error && /* @__PURE__ */ jsx38(
5061
+ Text18,
3640
5062
  {
3641
5063
  accessibilityLiveRegion: "polite",
3642
5064
  style: [