@vellira-ui/react-native 2.30.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 +1956 -515
  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,271 +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
- onChange,
1552
- options,
1553
- placeholder = "Select...",
1554
- size = "md",
1555
- required = false,
1556
- disabled = false,
1557
- error,
1558
- style,
1559
- triggerStyle,
1560
- textStyle,
1561
- pickerStyle,
1562
- accessibilityLabel,
1563
- accessibilityHint
1564
- }) {
1565
- const { theme } = useTheme();
1566
- const styles = useThemeStyles(createStyles15);
1567
- const { selectedValue, setSelectedValue, selectedOption, isOpen, setIsOpen } = useSelect({
1568
- value,
1569
- defaultValue,
1570
- onChange,
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;
2892
+ const {
2893
+ selectedValue,
2894
+ setSelectedValue,
2895
+ isOpen,
2896
+ openDropdown,
2897
+ closeDropdown,
2898
+ selectValue
2899
+ } = useSelect({
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
+ },
1571
2913
  options,
1572
- disabled
2914
+ multiple: props.multiple,
2915
+ maxSelected,
2916
+ closeOnSelect,
2917
+ disabled: isDisabled,
2918
+ open,
2919
+ defaultOpen,
2920
+ onOpenChange
1573
2921
  });
1574
- const [draftValue, setDraftValue] = useState2(selectedValue);
1575
- const hasError = !!error;
1576
- useEffect2(() => {
1577
- if (isOpen) {
1578
- setDraftValue(selectedValue);
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
+ );
1579
2960
  }
1580
- }, [isOpen, selectedValue]);
1581
- const resolvedLabel = accessibilityLabel ?? label ?? selectedOption?.label ?? placeholder ?? "Select";
1582
- const openPicker = () => {
1583
- if (disabled) return;
1584
- setDraftValue(selectedValue);
1585
- 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");
1586
2990
  };
1587
- const closePicker = () => {
1588
- 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`);
1589
2999
  };
1590
- const handleValueChange = (nextValue) => {
1591
- const nextOption = options.find((option) => option.value === nextValue);
1592
- 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");
1593
3020
  return;
1594
3021
  }
1595
- setDraftValue(nextValue);
1596
- };
1597
- const confirmPicker = () => {
1598
- const nextOption = options.find((option) => option.value === draftValue);
1599
- if (!nextOption || nextOption.disabled) {
1600
- setIsOpen(false);
1601
- 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();
1602
3035
  }
1603
- setSelectedValue(draftValue);
1604
- setIsOpen(false);
1605
3036
  };
1606
- return /* @__PURE__ */ jsxs9(
1607
- 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,
1608
3095
  {
1609
- label,
1610
- description,
1611
- error,
1612
- required,
1613
- disabled,
1614
- style,
3096
+ testID,
3097
+ onLayout: (event) => setTriggerWidth(event.nativeEvent.layout.width),
1615
3098
  children: [
1616
- /* @__PURE__ */ jsx17(
3099
+ /* @__PURE__ */ jsx29(
1617
3100
  SelectTrigger,
1618
3101
  {
1619
- displayText: selectedOption?.label ?? placeholder,
1620
- isPlaceholder: !selectedOption,
3102
+ displayText: displayValue,
3103
+ isPlaceholder: !hasValue,
1621
3104
  isOpen,
1622
- size,
1623
- disabled,
1624
- required,
1625
- 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,
1626
3119
  accessibilityLabel: resolvedLabel,
1627
- accessibilityHint,
3120
+ accessibilityHint: resolvedHint,
3121
+ accessibilityLabelledBy: !hasOwnField ? field?.labelId : void 0,
3122
+ ariaDescribedBy: !hasOwnField ? field?.ariaDescribedBy : void 0,
1628
3123
  triggerStyle,
1629
3124
  textStyle,
1630
- onPress: openPicker
3125
+ onPress: openDropdown,
3126
+ onClear: clearValue
1631
3127
  }
1632
3128
  ),
1633
- /* @__PURE__ */ jsx17(
1634
- Modal3,
1635
- {
1636
- transparent: true,
1637
- visible: isOpen,
1638
- animationType: "slide",
1639
- onRequestClose: closePicker,
1640
- children: /* @__PURE__ */ jsxs9(View13, { style: styles.modalRoot, children: [
1641
- /* @__PURE__ */ jsx17(Pressable7, { style: styles.backdrop, onPress: closePicker }),
1642
- /* @__PURE__ */ jsxs9(View13, { style: styles.sheet, children: [
1643
- /* @__PURE__ */ jsxs9(
1644
- View13,
1645
- {
1646
- style: styles.toolbar,
1647
- accessible: true,
1648
- accessibilityRole: "toolbar",
1649
- accessibilityLabel: `${resolvedLabel} picker actions`,
1650
- children: [
1651
- /* @__PURE__ */ jsx17(
1652
- Pressable7,
1653
- {
1654
- onPress: closePicker,
1655
- hitSlop: 8,
1656
- style: styles.toolbarAction,
1657
- accessibilityRole: "button",
1658
- accessibilityLabel: "Cancel selection",
1659
- accessibilityHint: "Closes the picker without changing the selected value",
1660
- children: /* @__PURE__ */ jsx17(Text8, { style: styles.cancelText, children: "Cancel" })
1661
- }
1662
- ),
1663
- /* @__PURE__ */ jsx17(
1664
- Text8,
1665
- {
1666
- style: styles.title,
1667
- numberOfLines: 1,
1668
- accessibilityRole: "header",
1669
- children: resolvedLabel
1670
- }
1671
- ),
1672
- /* @__PURE__ */ jsx17(
1673
- Pressable7,
1674
- {
1675
- onPress: confirmPicker,
1676
- hitSlop: 8,
1677
- style: styles.toolbarAction,
1678
- accessibilityRole: "button",
1679
- accessibilityLabel: "Confirm selection",
1680
- accessibilityHint: "Applies the highlighted picker value",
1681
- children: /* @__PURE__ */ jsx17(Text8, { style: styles.doneText, children: "Done" })
1682
- }
1683
- )
1684
- ]
1685
- }
1686
- ),
1687
- /* @__PURE__ */ jsxs9(
1688
- Picker,
1689
- {
1690
- selectedValue: draftValue,
1691
- onValueChange: handleValueChange,
1692
- enabled: !disabled,
1693
- style: [styles.picker, pickerStyle],
1694
- itemStyle: {
1695
- color: theme.components.select.option.default.fg
1696
- },
1697
- children: [
1698
- /* @__PURE__ */ jsx17(
1699
- Picker.Item,
1700
- {
1701
- label: placeholder,
1702
- value: "",
1703
- enabled: false,
1704
- color: theme.components.select.option.disabled.fg
1705
- }
1706
- ),
1707
- options.map((option) => /* @__PURE__ */ jsx17(
1708
- Picker.Item,
1709
- {
1710
- label: option.disabled ? `${option.label} - unavailable` : option.label,
1711
- value: option.value,
1712
- enabled: !option.disabled,
1713
- color: option.disabled ? theme.components.select.option.disabled.fg : theme.components.select.option.default.fg
1714
- },
1715
- option.value
1716
- ))
1717
- ]
1718
- }
1719
- )
1720
- ] })
1721
- ] })
1722
- }
1723
- )
3129
+ /* @__PURE__ */ jsx29(SelectContentSurface, {})
1724
3130
  ]
1725
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
+ }
1726
3149
  );
1727
3150
  }
1728
- 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
+ });
1729
3170
 
1730
3171
  // src/components/Tabs/List/TabsList.tsx
1731
- import { View as View14 } from "react-native";
3172
+ import { View as View24 } from "react-native";
1732
3173
 
1733
3174
  // src/components/Tabs/TabsContext.tsx
1734
- import { createContext as createContext5, useContext as useContext5 } from "react";
1735
- var TabsContext = createContext5(null);
3175
+ import { createContext as createContext6, useContext as useContext6 } from "react";
3176
+ var TabsContext = createContext6(null);
1736
3177
  var TabsProvider = TabsContext.Provider;
1737
3178
  var useTabs = () => {
1738
- const context = useContext5(TabsContext);
3179
+ const context = useContext6(TabsContext);
1739
3180
  if (!context) {
1740
3181
  throw new Error("Tabs components must be used inside <Tabs>.");
1741
3182
  }
@@ -1744,8 +3185,8 @@ var useTabs = () => {
1744
3185
  TabsContext.displayName = "TabsContext";
1745
3186
 
1746
3187
  // src/components/Tabs/List/TabsList.styles.ts
1747
- import { StyleSheet as StyleSheet16 } from "react-native";
1748
- var createStyles16 = (theme) => StyleSheet16.create({
3188
+ import { StyleSheet as StyleSheet20 } from "react-native";
3189
+ var createStyles14 = (theme) => StyleSheet20.create({
1749
3190
  list: {
1750
3191
  flexDirection: "row",
1751
3192
  alignSelf: "stretch",
@@ -1771,12 +3212,12 @@ var createStyles16 = (theme) => StyleSheet16.create({
1771
3212
  });
1772
3213
 
1773
3214
  // src/components/Tabs/List/TabsList.tsx
1774
- import { jsx as jsx18 } from "react/jsx-runtime";
3215
+ import { jsx as jsx30 } from "react/jsx-runtime";
1775
3216
  var TabsList = ({ children, style }) => {
1776
- const styles = useThemeStyles(createStyles16);
3217
+ const styles = useThemeStyles(createStyles14);
1777
3218
  const { orientation, appearance } = useTabs();
1778
- return /* @__PURE__ */ jsx18(
1779
- View14,
3219
+ return /* @__PURE__ */ jsx30(
3220
+ View24,
1780
3221
  {
1781
3222
  accessibilityRole: "tablist",
1782
3223
  style: [
@@ -1792,11 +3233,11 @@ var TabsList = ({ children, style }) => {
1792
3233
  TabsList.displayName = "TabsList";
1793
3234
 
1794
3235
  // src/components/Tabs/Panel/TabsPanel.tsx
1795
- import { View as View15 } from "react-native";
3236
+ import { View as View25 } from "react-native";
1796
3237
 
1797
3238
  // src/components/Tabs/Panel/TabsPanel.styles.ts
1798
- import { StyleSheet as StyleSheet17 } from "react-native";
1799
- var createStyles17 = (theme) => StyleSheet17.create({
3239
+ import { StyleSheet as StyleSheet21 } from "react-native";
3240
+ var createStyles15 = (theme) => StyleSheet21.create({
1800
3241
  panel: {
1801
3242
  width: "100%",
1802
3243
  minWidth: 0,
@@ -1823,13 +3264,13 @@ var createStyles17 = (theme) => StyleSheet17.create({
1823
3264
  });
1824
3265
 
1825
3266
  // src/components/Tabs/Panel/TabsPanel.tsx
1826
- import { jsx as jsx19 } from "react/jsx-runtime";
3267
+ import { jsx as jsx31 } from "react/jsx-runtime";
1827
3268
  var TabsPanel = ({ index, children, style }) => {
1828
- const styles = useThemeStyles(createStyles17);
3269
+ const styles = useThemeStyles(createStyles15);
1829
3270
  const { activeIndex, orientation } = useTabs();
1830
3271
  if (activeIndex !== index) return null;
1831
- return /* @__PURE__ */ jsx19(
1832
- View15,
3272
+ return /* @__PURE__ */ jsx31(
3273
+ View25,
1833
3274
  {
1834
3275
  style: [
1835
3276
  styles.panel,
@@ -1843,13 +3284,13 @@ var TabsPanel = ({ index, children, style }) => {
1843
3284
  TabsPanel.displayName = "TabsPanel";
1844
3285
 
1845
3286
  // src/components/Tabs/Tab/Tab.tsx
1846
- import { cloneElement as cloneElement4, isValidElement as isValidElement4 } from "react";
1847
- 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";
1848
3289
 
1849
3290
  // src/components/Tabs/Tab/Tab.styles.ts
1850
- import { StyleSheet as StyleSheet18 } from "react-native";
3291
+ import { StyleSheet as StyleSheet22 } from "react-native";
1851
3292
  var fontWeight2 = (value) => value;
1852
- var createStyles18 = (theme) => StyleSheet18.create({
3293
+ var createStyles16 = (theme) => StyleSheet22.create({
1853
3294
  tab: {
1854
3295
  minHeight: 40,
1855
3296
  alignItems: "center",
@@ -1967,7 +3408,7 @@ var createStyles18 = (theme) => StyleSheet18.create({
1967
3408
  });
1968
3409
 
1969
3410
  // src/components/Tabs/Tab/Tab.tsx
1970
- 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";
1971
3412
  var Tab = ({
1972
3413
  index,
1973
3414
  children,
@@ -1977,7 +3418,7 @@ var Tab = ({
1977
3418
  textStyle
1978
3419
  }) => {
1979
3420
  const { theme } = useTheme();
1980
- const styles = useThemeStyles(createStyles18);
3421
+ const styles = useThemeStyles(createStyles16);
1981
3422
  const { activeIndex, appearance, orientation, setActiveIndex } = useTabs();
1982
3423
  const isActive = activeIndex === index;
1983
3424
  const isPills = appearance === "pills";
@@ -1985,11 +3426,11 @@ var Tab = ({
1985
3426
  const isDefault = appearance === "default";
1986
3427
  const isVertical = orientation === "vertical";
1987
3428
  const iconColor = isPills && isActive ? theme.components.tabs.pills.active.fg : isActive ? theme.components.tabs.trigger.active.fg : theme.components.tabs.trigger.default.fg;
1988
- const renderedIcon = isValidElement4(icon) ? cloneElement4(icon, {
3429
+ const renderedIcon = isValidElement7(icon) ? cloneElement6(icon, {
1989
3430
  color: iconColor
1990
3431
  }) : icon;
1991
- return /* @__PURE__ */ jsx20(
1992
- Pressable8,
3432
+ return /* @__PURE__ */ jsx32(
3433
+ Pressable12,
1993
3434
  {
1994
3435
  disabled,
1995
3436
  accessibilityRole: "tab",
@@ -2009,9 +3450,9 @@ var Tab = ({
2009
3450
  disabled && styles.tabDisabled,
2010
3451
  style
2011
3452
  ],
2012
- children: ({ pressed }) => /* @__PURE__ */ jsxs10(Fragment2, { children: [
2013
- isUnderline && !isVertical && /* @__PURE__ */ jsx20(
2014
- View16,
3453
+ children: ({ pressed }) => /* @__PURE__ */ jsxs18(Fragment4, { children: [
3454
+ isUnderline && !isVertical && /* @__PURE__ */ jsx32(
3455
+ View26,
2015
3456
  {
2016
3457
  pointerEvents: "none",
2017
3458
  style: [
@@ -2020,8 +3461,8 @@ var Tab = ({
2020
3461
  ]
2021
3462
  }
2022
3463
  ),
2023
- isUnderline && isVertical && /* @__PURE__ */ jsx20(
2024
- View16,
3464
+ isUnderline && isVertical && /* @__PURE__ */ jsx32(
3465
+ View26,
2025
3466
  {
2026
3467
  pointerEvents: "none",
2027
3468
  style: [
@@ -2031,9 +3472,9 @@ var Tab = ({
2031
3472
  ]
2032
3473
  }
2033
3474
  ),
2034
- icon != null && /* @__PURE__ */ jsx20(View16, { style: styles.tabIcon, children: renderedIcon }),
2035
- children != null && /* @__PURE__ */ jsx20(
2036
- Text9,
3475
+ icon != null && /* @__PURE__ */ jsx32(View26, { style: styles.tabIcon, children: renderedIcon }),
3476
+ children != null && /* @__PURE__ */ jsx32(
3477
+ Text13,
2037
3478
  {
2038
3479
  numberOfLines: 2,
2039
3480
  ellipsizeMode: "tail",
@@ -2054,13 +3495,13 @@ var Tab = ({
2054
3495
  Tab.displayName = "Tab";
2055
3496
 
2056
3497
  // src/components/Tabs/Tabs.tsx
2057
- import { useMemo as useMemo4 } from "react";
3498
+ import { useMemo as useMemo7 } from "react";
2058
3499
  import { useTabs as useTabs2 } from "@vellira-ui/core";
2059
- import { View as View17 } from "react-native";
3500
+ import { View as View27 } from "react-native";
2060
3501
 
2061
3502
  // src/components/Tabs/Tabs.styles.ts
2062
- import { StyleSheet as StyleSheet19 } from "react-native";
2063
- var createStyles19 = (theme) => StyleSheet19.create({
3503
+ import { StyleSheet as StyleSheet23 } from "react-native";
3504
+ var createStyles17 = (theme) => StyleSheet23.create({
2064
3505
  root: {
2065
3506
  width: "100%",
2066
3507
  minWidth: 0
@@ -2075,7 +3516,7 @@ var createStyles19 = (theme) => StyleSheet19.create({
2075
3516
  });
2076
3517
 
2077
3518
  // src/components/Tabs/Tabs.tsx
2078
- import { jsx as jsx21 } from "react/jsx-runtime";
3519
+ import { jsx as jsx33 } from "react/jsx-runtime";
2079
3520
  var TabsRoot = ({
2080
3521
  children,
2081
3522
  activeIndex: controlledActiveIndex,
@@ -2085,19 +3526,19 @@ var TabsRoot = ({
2085
3526
  appearance = "pills",
2086
3527
  style
2087
3528
  }) => {
2088
- const styles = useThemeStyles(createStyles19);
3529
+ const styles = useThemeStyles(createStyles17);
2089
3530
  const { activeIndex, setActiveIndex } = useTabs2({
2090
3531
  activeIndex: controlledActiveIndex,
2091
3532
  defaultActiveIndex,
2092
3533
  onChange,
2093
3534
  orientation
2094
3535
  });
2095
- const value = useMemo4(
3536
+ const value = useMemo7(
2096
3537
  () => ({ activeIndex, appearance, orientation, setActiveIndex }),
2097
3538
  [activeIndex, appearance, orientation, setActiveIndex]
2098
3539
  );
2099
- return /* @__PURE__ */ jsx21(TabsProvider, { value, children: /* @__PURE__ */ jsx21(
2100
- View17,
3540
+ return /* @__PURE__ */ jsx33(TabsProvider, { value, children: /* @__PURE__ */ jsx33(
3541
+ View27,
2101
3542
  {
2102
3543
  style: [
2103
3544
  styles.root,
@@ -2118,20 +3559,20 @@ var Tabs = Object.assign(TabsRoot, {
2118
3559
  });
2119
3560
 
2120
3561
  // src/components/Tooltip/Tooltip.tsx
2121
- import { useEffect as useEffect3, useRef as useRef3, useState as useState4 } from "react";
2122
- 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";
2123
3564
 
2124
3565
  // src/hooks/useNativeFloatingPosition.ts
2125
- 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";
2126
3567
  import { Dimensions } from "react-native";
2127
3568
  var safePadding = 12;
2128
3569
  function useNativeFloatingPosition(placement = "top", offset = 8) {
2129
- const [position, setPosition] = useState3({ top: 0, left: 0 });
2130
- const floatingSizeRef = useRef2({
3570
+ const [position, setPosition] = useState5({ top: 0, left: 0 });
3571
+ const floatingSizeRef = useRef4({
2131
3572
  width: 0,
2132
3573
  height: 0
2133
3574
  });
2134
- const lastTriggerRef = useRef2(null);
3575
+ const lastTriggerRef = useRef4(null);
2135
3576
  const clamp = useCallback2((value, min, max) => {
2136
3577
  return Math.min(Math.max(value, min), Math.max(min, max));
2137
3578
  }, []);
@@ -2188,13 +3629,13 @@ function useNativeFloatingPosition(placement = "top", offset = 8) {
2188
3629
  }
2189
3630
 
2190
3631
  // src/components/Tooltip/Tooltip.styles.ts
2191
- import { StyleSheet as StyleSheet20 } from "react-native";
2192
- var createStyles20 = (theme) => StyleSheet20.create({
3632
+ import { StyleSheet as StyleSheet24 } from "react-native";
3633
+ var createStyles18 = (theme) => StyleSheet24.create({
2193
3634
  root: {
2194
3635
  alignSelf: "flex-start"
2195
3636
  },
2196
3637
  overlay: {
2197
- ...StyleSheet20.absoluteFill
3638
+ ...StyleSheet24.absoluteFill
2198
3639
  },
2199
3640
  bubble: {
2200
3641
  position: "absolute",
@@ -2226,7 +3667,7 @@ var createStyles20 = (theme) => StyleSheet20.create({
2226
3667
  });
2227
3668
 
2228
3669
  // src/components/Tooltip/Tooltip.tsx
2229
- import { jsx as jsx22, jsxs as jsxs11 } from "react/jsx-runtime";
3670
+ import { jsx as jsx34, jsxs as jsxs19 } from "react/jsx-runtime";
2230
3671
  function Tooltip({
2231
3672
  children,
2232
3673
  content,
@@ -2238,10 +3679,10 @@ function Tooltip({
2238
3679
  contentStyle,
2239
3680
  textStyle
2240
3681
  }) {
2241
- const styles = useThemeStyles(createStyles20);
2242
- const [visible, setVisible] = useState4(false);
2243
- const triggerRef = useRef3(null);
2244
- 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);
2245
3686
  const { position, updatePosition, onFloatingLayout } = useNativeFloatingPosition(placement, 8);
2246
3687
  const hideDelay = delay?.close ?? 2500;
2247
3688
  const clearCloseTimer = () => {
@@ -2260,21 +3701,21 @@ function Tooltip({
2260
3701
  closeTimerRef.current = null;
2261
3702
  }, hideDelay);
2262
3703
  };
2263
- useEffect3(() => {
3704
+ useEffect5(() => {
2264
3705
  return clearCloseTimer;
2265
3706
  }, []);
2266
- return /* @__PURE__ */ jsxs11(View18, { style: [styles.root, style], children: [
2267
- /* @__PURE__ */ jsx22(Pressable9, { ref: triggerRef, onLongPress: showTooltip, children }),
2268
- /* @__PURE__ */ jsx22(Modal4, { visible: visible && !disabled, transparent: true, animationType: "fade", children: /* @__PURE__ */ jsx22(
2269
- 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,
2270
3711
  {
2271
3712
  style: styles.overlay,
2272
3713
  onPress: () => {
2273
3714
  clearCloseTimer();
2274
3715
  setVisible(false);
2275
3716
  },
2276
- children: /* @__PURE__ */ jsx22(
2277
- View18,
3717
+ children: /* @__PURE__ */ jsx34(
3718
+ View28,
2278
3719
  {
2279
3720
  pointerEvents: "none",
2280
3721
  style: [
@@ -2287,7 +3728,7 @@ function Tooltip({
2287
3728
  contentStyle
2288
3729
  ],
2289
3730
  onLayout: onFloatingLayout,
2290
- 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
2291
3732
  }
2292
3733
  )
2293
3734
  }
@@ -2297,8 +3738,8 @@ function Tooltip({
2297
3738
  Tooltip.displayName = "Tooltip";
2298
3739
 
2299
3740
  // src/primitives/Button/Button.tsx
2300
- import { cloneElement as cloneElement5, useState as useState5 } from "react";
2301
- 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";
2302
3743
 
2303
3744
  // src/utils/devWarning.ts
2304
3745
  var devWarning = (condition, message) => {
@@ -2308,9 +3749,9 @@ var devWarning = (condition, message) => {
2308
3749
  };
2309
3750
 
2310
3751
  // src/primitives/Button/Button.styles.ts
2311
- import { StyleSheet as StyleSheet21 } from "react-native";
3752
+ import { StyleSheet as StyleSheet25 } from "react-native";
2312
3753
  var fontWeight3 = (value) => value;
2313
- var createStyles21 = (theme) => StyleSheet21.create({
3754
+ var createStyles19 = (theme) => StyleSheet25.create({
2314
3755
  button: {
2315
3756
  flexDirection: "row",
2316
3757
  alignItems: "center",
@@ -2375,7 +3816,7 @@ var createStyles21 = (theme) => StyleSheet21.create({
2375
3816
  });
2376
3817
 
2377
3818
  // src/primitives/Button/Button.tsx
2378
- 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";
2379
3820
  var sizeMap = {
2380
3821
  sm: {
2381
3822
  px: 12,
@@ -2427,13 +3868,13 @@ function Button({
2427
3868
  ...props
2428
3869
  }) {
2429
3870
  const { theme } = useTheme();
2430
- const styles = useThemeStyles(createStyles21);
3871
+ const styles = useThemeStyles(createStyles19);
2431
3872
  const config = sizeMap[size];
2432
3873
  const radius = shape === "square" ? theme.tokens.radius.sm : shape === "rounded" ? theme.tokens.radius.md : theme.tokens.radius.full;
2433
3874
  const appearanceTheme = theme.components.button[color][appearance];
2434
- const [isHovered, setIsHovered] = useState5(false);
2435
- const [isFocused, setIsFocused] = useState5(false);
2436
- const [labelWidth, setLabelWidth] = useState5(0);
3875
+ const [isHovered, setIsHovered] = useState7(false);
3876
+ const [isFocused, setIsFocused] = useState7(false);
3877
+ const [labelWidth, setLabelWidth] = useState7(0);
2437
3878
  const isDisabled = disabled || loading;
2438
3879
  const iconOnly = iconOnlyProp || !children && Boolean(iconStart || iconEnd);
2439
3880
  const content = loading && loadingText ? loadingText : children;
@@ -2459,7 +3900,7 @@ function Button({
2459
3900
  setIsHovered(false);
2460
3901
  onHoverOut?.(event);
2461
3902
  };
2462
- const renderIcon = (icon, iconColor) => cloneElement5(icon, {
3903
+ const renderIcon = (icon, iconColor) => cloneElement7(icon, {
2463
3904
  color: iconColor,
2464
3905
  size: resolvedIconSize
2465
3906
  });
@@ -2470,8 +3911,8 @@ function Button({
2470
3911
  );
2471
3912
  };
2472
3913
  const getInteractionTheme = (pressed) => isDisabled ? theme.components.button.disabled : pressed ? appearanceTheme.pressed : isHovered ? appearanceTheme.hover : appearanceTheme.default;
2473
- return /* @__PURE__ */ jsx23(
2474
- Pressable10,
3914
+ return /* @__PURE__ */ jsx35(
3915
+ Pressable14,
2475
3916
  {
2476
3917
  ...props,
2477
3918
  testID,
@@ -2507,12 +3948,12 @@ function Button({
2507
3948
  children: ({ pressed }) => {
2508
3949
  const interactionTheme = getInteractionTheme(pressed);
2509
3950
  const contentColor = interactionTheme.fg;
2510
- return /* @__PURE__ */ jsxs12(Fragment3, { children: [
2511
- loading && /* @__PURE__ */ jsx23(ActivityIndicator, { size: "small", color: contentColor }),
3951
+ return /* @__PURE__ */ jsxs20(Fragment5, { children: [
3952
+ loading && /* @__PURE__ */ jsx35(ActivityIndicator3, { size: "small", color: contentColor }),
2512
3953
  !loading && iconStart && renderIcon(iconStart, contentColor),
2513
- content && !iconOnly && /* @__PURE__ */ jsxs12(View19, { style: styles.labelSlot, children: [
2514
- /* @__PURE__ */ jsx23(
2515
- Text11,
3954
+ content && !iconOnly && /* @__PURE__ */ jsxs20(View29, { style: styles.labelSlot, children: [
3955
+ /* @__PURE__ */ jsx35(
3956
+ Text15,
2516
3957
  {
2517
3958
  onLayout: handleLabelLayout,
2518
3959
  style: [
@@ -2527,8 +3968,8 @@ function Button({
2527
3968
  children: content
2528
3969
  }
2529
3970
  ),
2530
- measureLabel && /* @__PURE__ */ jsx23(
2531
- Text11,
3971
+ measureLabel && /* @__PURE__ */ jsx35(
3972
+ Text15,
2532
3973
  {
2533
3974
  accessibilityElementsHidden: true,
2534
3975
  importantForAccessibility: "no-hide-descendants",
@@ -2545,8 +3986,8 @@ function Button({
2545
3986
  }
2546
3987
  )
2547
3988
  ] }),
2548
- badge && !iconOnly && /* @__PURE__ */ jsx23(
2549
- Text11,
3989
+ badge && !iconOnly && /* @__PURE__ */ jsx35(
3990
+ Text15,
2550
3991
  {
2551
3992
  style: [
2552
3993
  styles.badge,
@@ -2558,8 +3999,8 @@ function Button({
2558
3999
  children: badge
2559
4000
  }
2560
4001
  ),
2561
- shortcut && !iconOnly && /* @__PURE__ */ jsx23(
2562
- Text11,
4002
+ shortcut && !iconOnly && /* @__PURE__ */ jsx35(
4003
+ Text15,
2563
4004
  {
2564
4005
  style: [
2565
4006
  styles.shortcut,
@@ -2578,14 +4019,14 @@ function Button({
2578
4019
  }
2579
4020
 
2580
4021
  // src/primitives/Checkbox/Checkbox.tsx
2581
- import { forwardRef as forwardRef2, useEffect as useEffect4 } from "react";
4022
+ import { forwardRef as forwardRef2, useEffect as useEffect6 } from "react";
2582
4023
  import { useControllableState as useControllableState3 } from "@vellira-ui/core";
2583
- import { Check } from "@vellira-ui/icons";
2584
- 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";
2585
4026
 
2586
4027
  // src/primitives/Checkbox/Checkbox.styles.ts
2587
- import { StyleSheet as StyleSheet22 } from "react-native";
2588
- var createStyles22 = (theme) => StyleSheet22.create({
4028
+ import { StyleSheet as StyleSheet26 } from "react-native";
4029
+ var createStyles20 = (theme) => StyleSheet26.create({
2589
4030
  container: {
2590
4031
  gap: theme.tokens.spacing[2]
2591
4032
  },
@@ -2728,7 +4169,7 @@ var createStyles22 = (theme) => StyleSheet22.create({
2728
4169
  });
2729
4170
 
2730
4171
  // src/primitives/Checkbox/Checkbox.tsx
2731
- 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";
2732
4173
  var iconSizeBySize = {
2733
4174
  sm: 10,
2734
4175
  md: 12,
@@ -2756,7 +4197,7 @@ var Checkbox = forwardRef2(
2756
4197
  ...PressableProps
2757
4198
  }, ref) => {
2758
4199
  const { theme } = useTheme();
2759
- const styles = useThemeStyles(createStyles22);
4200
+ const styles = useThemeStyles(createStyles20);
2760
4201
  const checkboxColor = theme.components.checkbox[color];
2761
4202
  const boxSizeStyle = {
2762
4203
  sm: styles.boxSm,
@@ -2786,15 +4227,15 @@ var Checkbox = forwardRef2(
2786
4227
  const resolvedAccessibilityLabel = accessibilityLabel ?? label;
2787
4228
  const resolvedAccessibilityHint = [accessibilityHint, description, error].filter(Boolean).join(" ");
2788
4229
  const accessibilityChecked = indeterminate ? "mixed" : isChecked;
2789
- useEffect4(() => {
4230
+ useEffect6(() => {
2790
4231
  devWarning(
2791
4232
  Boolean(resolvedAccessibilityLabel),
2792
4233
  "Checkbox: an accessible label must be provided through label or accessibilityLabel."
2793
4234
  );
2794
4235
  }, [resolvedAccessibilityLabel]);
2795
- return /* @__PURE__ */ jsxs13(View20, { style: styles.container, children: [
2796
- /* @__PURE__ */ jsx24(
2797
- Pressable11,
4236
+ return /* @__PURE__ */ jsxs21(View30, { style: styles.container, children: [
4237
+ /* @__PURE__ */ jsx36(
4238
+ Pressable15,
2798
4239
  {
2799
4240
  ...PressableProps,
2800
4241
  ref,
@@ -2817,9 +4258,9 @@ var Checkbox = forwardRef2(
2817
4258
  children: ({ pressed }) => {
2818
4259
  const isSelected = isChecked || indeterminate;
2819
4260
  const checkColor = disabled ? theme.components.checkbox.disabled.fg : pressed && isSelected ? checkboxColor.pressed.fg : checkboxColor.default.fg;
2820
- return /* @__PURE__ */ jsxs13(Fragment4, { children: [
2821
- /* @__PURE__ */ jsx24(
2822
- View20,
4261
+ return /* @__PURE__ */ jsxs21(Fragment6, { children: [
4262
+ /* @__PURE__ */ jsx36(
4263
+ View30,
2823
4264
  {
2824
4265
  style: [
2825
4266
  styles.box,
@@ -2836,8 +4277,8 @@ var Checkbox = forwardRef2(
2836
4277
  hasError && styles.boxError,
2837
4278
  disabled && styles.boxDisabled
2838
4279
  ],
2839
- children: indeterminate ? indeterminateIcon ?? /* @__PURE__ */ jsx24(
2840
- View20,
4280
+ children: indeterminate ? indeterminateIcon ?? /* @__PURE__ */ jsx36(
4281
+ View30,
2841
4282
  {
2842
4283
  style: [
2843
4284
  styles.indeterminateMark,
@@ -2846,11 +4287,11 @@ var Checkbox = forwardRef2(
2846
4287
  }
2847
4288
  ]
2848
4289
  }
2849
- ) : isChecked && (icon ?? /* @__PURE__ */ jsx24(Check, { size: iconSizeBySize[size], color: checkColor }))
4290
+ ) : isChecked && (icon ?? /* @__PURE__ */ jsx36(Check2, { size: iconSizeBySize[size], color: checkColor }))
2850
4291
  }
2851
4292
  ),
2852
- label && /* @__PURE__ */ jsxs13(
2853
- Text12,
4293
+ label && /* @__PURE__ */ jsxs21(
4294
+ Text16,
2854
4295
  {
2855
4296
  style: [
2856
4297
  styles.label,
@@ -2863,7 +4304,7 @@ var Checkbox = forwardRef2(
2863
4304
  ],
2864
4305
  children: [
2865
4306
  label,
2866
- required && /* @__PURE__ */ jsx24(Text12, { style: styles.requiredMark, children: " *" })
4307
+ required && /* @__PURE__ */ jsx36(Text16, { style: styles.requiredMark, children: " *" })
2867
4308
  ]
2868
4309
  }
2869
4310
  )
@@ -2871,8 +4312,8 @@ var Checkbox = forwardRef2(
2871
4312
  }
2872
4313
  }
2873
4314
  ),
2874
- description && /* @__PURE__ */ jsx24(
2875
- Text12,
4315
+ description && /* @__PURE__ */ jsx36(
4316
+ Text16,
2876
4317
  {
2877
4318
  style: [
2878
4319
  styles.descriptionText,
@@ -2882,21 +4323,21 @@ var Checkbox = forwardRef2(
2882
4323
  children: description
2883
4324
  }
2884
4325
  ),
2885
- hasError && /* @__PURE__ */ jsx24(Text12, { style: [styles.errorText, helperTextSizeStyle[size]], children: error })
4326
+ hasError && /* @__PURE__ */ jsx36(Text16, { style: [styles.errorText, helperTextSizeStyle[size]], children: error })
2886
4327
  ] });
2887
4328
  }
2888
4329
  );
2889
4330
  Checkbox.displayName = "Checkbox";
2890
4331
 
2891
4332
  // src/primitives/Input/Input.tsx
2892
- import { cloneElement as cloneElement6, forwardRef as forwardRef3, useState as useState6 } from "react";
2893
- 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";
2894
4335
 
2895
4336
  // src/primitives/Input/Input.styles.ts
2896
- import { StyleSheet as StyleSheet23 } from "react-native";
4337
+ import { StyleSheet as StyleSheet27 } from "react-native";
2897
4338
  var getDisabledPlaceholderTextColor = (theme) => theme.components.input.disabled.placeholder;
2898
4339
  var resolveRingColor = (ring) => typeof ring === "string" ? ring : ring.color;
2899
- var createStyles23 = (theme) => StyleSheet23.create({
4340
+ var createStyles21 = (theme) => StyleSheet27.create({
2900
4341
  inputWrapper: {
2901
4342
  position: "relative",
2902
4343
  width: "100%",
@@ -3040,7 +4481,7 @@ var createStyles23 = (theme) => StyleSheet23.create({
3040
4481
  });
3041
4482
 
3042
4483
  // src/primitives/Input/Input.tsx
3043
- import { jsx as jsx25, jsxs as jsxs14 } from "react/jsx-runtime";
4484
+ import { jsx as jsx37, jsxs as jsxs22 } from "react/jsx-runtime";
3044
4485
  var keyboardTypeByInputType = {
3045
4486
  text: "default",
3046
4487
  email: "email-address",
@@ -3138,11 +4579,11 @@ var Input = forwardRef3(
3138
4579
  ...props
3139
4580
  }, ref) => {
3140
4581
  const { theme } = useTheme();
3141
- const styles = useThemeStyles(createStyles23);
4582
+ const styles = useThemeStyles(createStyles21);
3142
4583
  const field = useFormFieldContext();
3143
4584
  const hasOwnField = Boolean(label || description || error);
3144
- const [isFocused, setIsFocused] = useState6(false);
3145
- const [uncontrolledValue, setUncontrolledValue] = useState6(
4585
+ const [isFocused, setIsFocused] = useState8(false);
4586
+ const [uncontrolledValue, setUncontrolledValue] = useState8(
3146
4587
  defaultValue ?? ""
3147
4588
  );
3148
4589
  const isControlled = value !== void 0;
@@ -3159,7 +4600,7 @@ var Input = forwardRef3(
3159
4600
  const isReadOnly = readOnly || loading;
3160
4601
  const placeholderTextColor = isDisabled ? getDisabledPlaceholderTextColor(theme) : readOnly ? theme.components.input.readOnly.placeholder : inputState.placeholder;
3161
4602
  const isPassword = type === "password";
3162
- const [isPasswordRevealed, setIsPasswordRevealed] = useState6(false);
4603
+ const [isPasswordRevealed, setIsPasswordRevealed] = useState8(false);
3163
4604
  const resolvedIconSize = iconSize ?? 16;
3164
4605
  const handleFocus = (event) => {
3165
4606
  setIsFocused(true);
@@ -3190,22 +4631,22 @@ var Input = forwardRef3(
3190
4631
  const startIconColor = isDisabled ? theme.components.input.disabled.icon : theme.components.input.icon[startIconTone];
3191
4632
  const endIconColor = isDisabled ? theme.components.input.disabled.icon : theme.components.input.icon[endIconTone];
3192
4633
  const clearIconColor = isDisabled ? theme.components.input.disabled.icon : theme.components.input.icon[clearIconTone];
3193
- const control = /* @__PURE__ */ jsxs14(View21, { style: styles.inputWrapper, children: [
3194
- startIcon && /* @__PURE__ */ jsx25(
3195
- View21,
4634
+ const control = /* @__PURE__ */ jsxs22(View31, { style: styles.inputWrapper, children: [
4635
+ startIcon && /* @__PURE__ */ jsx37(
4636
+ View31,
3196
4637
  {
3197
4638
  pointerEvents: "none",
3198
4639
  style: styles.leftIcon,
3199
4640
  accessibilityElementsHidden: true,
3200
4641
  importantForAccessibility: "no",
3201
- children: cloneElement6(startIcon, {
4642
+ children: cloneElement8(startIcon, {
3202
4643
  color: startIconColor,
3203
4644
  size: resolvedIconSize
3204
4645
  })
3205
4646
  }
3206
4647
  ),
3207
- /* @__PURE__ */ jsx25(
3208
- TextInput,
4648
+ /* @__PURE__ */ jsx37(
4649
+ TextInput2,
3209
4650
  {
3210
4651
  ...props,
3211
4652
  ref,
@@ -3260,37 +4701,37 @@ var Input = forwardRef3(
3260
4701
  ]
3261
4702
  }
3262
4703
  ),
3263
- showClearButton ? /* @__PURE__ */ jsx25(
3264
- Pressable12,
4704
+ showClearButton ? /* @__PURE__ */ jsx37(
4705
+ Pressable16,
3265
4706
  {
3266
4707
  accessibilityRole: "button",
3267
4708
  accessibilityLabel: "Clear input",
3268
4709
  hitSlop: 8,
3269
4710
  onPress: handleClear,
3270
4711
  style: styles.clearButton,
3271
- children: clearIcon ? cloneElement6(clearIcon, {
4712
+ children: clearIcon ? cloneElement8(clearIcon, {
3272
4713
  color: clearIconColor,
3273
4714
  size: resolvedIconSize
3274
- }) : /* @__PURE__ */ jsx25(Text13, { style: [styles.clearButtonText, { color: clearIconColor }], children: "\xD7" })
4715
+ }) : /* @__PURE__ */ jsx37(Text17, { style: [styles.clearButtonText, { color: clearIconColor }], children: "\xD7" })
3275
4716
  }
3276
- ) : showRevealButton ? /* @__PURE__ */ jsx25(
3277
- Pressable12,
4717
+ ) : showRevealButton ? /* @__PURE__ */ jsx37(
4718
+ Pressable16,
3278
4719
  {
3279
4720
  accessibilityRole: "button",
3280
4721
  accessibilityLabel: isPasswordRevealed ? "Hide password" : "Show password",
3281
4722
  hitSlop: 8,
3282
4723
  onPress: () => setIsPasswordRevealed((revealed) => !revealed),
3283
4724
  style: styles.revealButton,
3284
- children: /* @__PURE__ */ jsx25(Text13, { style: styles.revealButtonText, children: isPasswordRevealed ? "Hide" : "Show" })
4725
+ children: /* @__PURE__ */ jsx37(Text17, { style: styles.revealButtonText, children: isPasswordRevealed ? "Hide" : "Show" })
3285
4726
  }
3286
- ) : showRightIcon && endIcon && /* @__PURE__ */ jsx25(
3287
- View21,
4727
+ ) : showRightIcon && endIcon && /* @__PURE__ */ jsx37(
4728
+ View31,
3288
4729
  {
3289
4730
  pointerEvents: "none",
3290
4731
  style: styles.rightIcon,
3291
4732
  accessibilityElementsHidden: true,
3292
4733
  importantForAccessibility: "no",
3293
- children: cloneElement6(endIcon, {
4734
+ children: cloneElement8(endIcon, {
3294
4735
  color: endIconColor,
3295
4736
  size: resolvedIconSize
3296
4737
  })
@@ -3300,7 +4741,7 @@ var Input = forwardRef3(
3300
4741
  if (!hasOwnField && field) {
3301
4742
  return control;
3302
4743
  }
3303
- return /* @__PURE__ */ jsx25(
4744
+ return /* @__PURE__ */ jsx37(
3304
4745
  FormField,
3305
4746
  {
3306
4747
  label,
@@ -3319,17 +4760,17 @@ var Input = forwardRef3(
3319
4760
  Input.displayName = "Input";
3320
4761
 
3321
4762
  // src/primitives/Radio/Radio.tsx
3322
- import { forwardRef as forwardRef4, useEffect as useEffect5 } from "react";
4763
+ import { forwardRef as forwardRef4, useEffect as useEffect7 } from "react";
3323
4764
  import { useControllableState as useControllableState4 } from "@vellira-ui/core";
3324
4765
  import {
3325
- Pressable as Pressable13,
3326
- Text as Text14,
3327
- View as View22
4766
+ Pressable as Pressable17,
4767
+ Text as Text18,
4768
+ View as View32
3328
4769
  } from "react-native";
3329
4770
 
3330
4771
  // src/primitives/Radio/Radio.styles.ts
3331
- import { StyleSheet as StyleSheet24 } from "react-native";
3332
- var createStyles24 = (theme) => StyleSheet24.create({
4772
+ import { StyleSheet as StyleSheet28 } from "react-native";
4773
+ var createStyles22 = (theme) => StyleSheet28.create({
3333
4774
  root: {
3334
4775
  alignSelf: "flex-start"
3335
4776
  },
@@ -3414,7 +4855,7 @@ var createStyles24 = (theme) => StyleSheet24.create({
3414
4855
  });
3415
4856
 
3416
4857
  // src/primitives/Radio/Radio.tsx
3417
- 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";
3418
4859
  var controlSizeBySize = {
3419
4860
  sm: 14,
3420
4861
  md: 16,
@@ -3449,7 +4890,7 @@ var Radio = forwardRef4(
3449
4890
  ...rest
3450
4891
  }, ref) => {
3451
4892
  const { theme } = useTheme();
3452
- const styles = createStyles24(theme);
4893
+ const styles = createStyles22(theme);
3453
4894
  const group = useRadioGroupContext();
3454
4895
  const isInsideGroup = group !== null;
3455
4896
  const [standaloneChecked, setStandaloneChecked] = useControllableState4({
@@ -3488,7 +4929,7 @@ var Radio = forwardRef4(
3488
4929
  };
3489
4930
  const typographySize = typographySizeByRadioSize[resolvedSize];
3490
4931
  const controlMarginTop = (typographySize.labelLineHeight - controlSize) / 2;
3491
- useEffect5(() => {
4932
+ useEffect7(() => {
3492
4933
  if (typeof __DEV__ !== "undefined" && __DEV__ && !label && !accessibilityLabel) {
3493
4934
  console.warn(
3494
4935
  "Radio requires either a visible label or accessibilityLabel."
@@ -3517,9 +4958,9 @@ var Radio = forwardRef4(
3517
4958
  state.pressed && !resolvedDisabled && styles.pressablePressed,
3518
4959
  typeof style === "function" ? style(state) : style
3519
4960
  ];
3520
- return /* @__PURE__ */ jsxs15(View22, { style: [styles.root, containerStyle], children: [
3521
- /* @__PURE__ */ jsx26(
3522
- Pressable13,
4961
+ return /* @__PURE__ */ jsxs23(View32, { style: [styles.root, containerStyle], children: [
4962
+ /* @__PURE__ */ jsx38(
4963
+ Pressable17,
3523
4964
  {
3524
4965
  ...rest,
3525
4966
  ref,
@@ -3533,9 +4974,9 @@ var Radio = forwardRef4(
3533
4974
  disabled: resolvedDisabled,
3534
4975
  onPress: handlePress,
3535
4976
  style: resolvePressableStyle,
3536
- children: (state) => /* @__PURE__ */ jsxs15(Fragment5, { children: [
3537
- /* @__PURE__ */ jsx26(
3538
- View22,
4977
+ children: (state) => /* @__PURE__ */ jsxs23(Fragment7, { children: [
4978
+ /* @__PURE__ */ jsx38(
4979
+ View32,
3539
4980
  {
3540
4981
  pointerEvents: "none",
3541
4982
  style: [
@@ -3558,8 +4999,8 @@ var Radio = forwardRef4(
3558
4999
  resolvedDisabled && styles.controlDisabled,
3559
5000
  resolvedChecked && resolvedDisabled && styles.controlCheckedDisabled
3560
5001
  ],
3561
- children: resolvedChecked && (icon ?? /* @__PURE__ */ jsx26(
3562
- View22,
5002
+ children: resolvedChecked && (icon ?? /* @__PURE__ */ jsx38(
5003
+ View32,
3563
5004
  {
3564
5005
  style: [
3565
5006
  styles.indicator,
@@ -3574,9 +5015,9 @@ var Radio = forwardRef4(
3574
5015
  ))
3575
5016
  }
3576
5017
  ),
3577
- (label || description) && /* @__PURE__ */ jsxs15(View22, { pointerEvents: "none", style: styles.content, children: [
3578
- label && (typeof label === "string" ? /* @__PURE__ */ jsx26(
3579
- Text14,
5018
+ (label || description) && /* @__PURE__ */ jsxs23(View32, { pointerEvents: "none", style: styles.content, children: [
5019
+ label && (typeof label === "string" ? /* @__PURE__ */ jsx38(
5020
+ Text18,
3580
5021
  {
3581
5022
  style: [
3582
5023
  styles.label,
@@ -3597,8 +5038,8 @@ var Radio = forwardRef4(
3597
5038
  children: label
3598
5039
  }
3599
5040
  ) : label),
3600
- description && (typeof description === "string" ? /* @__PURE__ */ jsx26(
3601
- Text14,
5041
+ description && (typeof description === "string" ? /* @__PURE__ */ jsx38(
5042
+ Text18,
3602
5043
  {
3603
5044
  style: [
3604
5045
  styles.description,
@@ -3616,8 +5057,8 @@ var Radio = forwardRef4(
3616
5057
  ] })
3617
5058
  }
3618
5059
  ),
3619
- error && /* @__PURE__ */ jsx26(
3620
- Text14,
5060
+ error && /* @__PURE__ */ jsx38(
5061
+ Text18,
3621
5062
  {
3622
5063
  accessibilityLiveRegion: "polite",
3623
5064
  style: [