@nori-ui/core 1.6.0 → 1.8.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 (203) hide show
  1. package/dist/{chunk-7UKRN73P.js → chunk-2XJCLPNH.js} +3 -3
  2. package/dist/{chunk-7UKRN73P.js.map → chunk-2XJCLPNH.js.map} +1 -1
  3. package/dist/{chunk-5PSC5HT4.js → chunk-3B345SQU.js} +5 -5
  4. package/dist/{chunk-5PSC5HT4.js.map → chunk-3B345SQU.js.map} +1 -1
  5. package/dist/{chunk-JSAG5YO7.js → chunk-3IIIHZHT.js} +3 -3
  6. package/dist/{chunk-JSAG5YO7.js.map → chunk-3IIIHZHT.js.map} +1 -1
  7. package/dist/{chunk-DDGMLLS3.js → chunk-3W3XYULK.js} +3 -3
  8. package/dist/{chunk-DDGMLLS3.js.map → chunk-3W3XYULK.js.map} +1 -1
  9. package/dist/{chunk-WYPGQVDV.js → chunk-5YHT252H.js} +3 -3
  10. package/dist/{chunk-WYPGQVDV.js.map → chunk-5YHT252H.js.map} +1 -1
  11. package/dist/{chunk-ZMSIYLSI.js → chunk-7FSFJA33.js} +3 -3
  12. package/dist/{chunk-ZMSIYLSI.js.map → chunk-7FSFJA33.js.map} +1 -1
  13. package/dist/chunk-BOMPFNM4.js +165 -0
  14. package/dist/chunk-BOMPFNM4.js.map +1 -0
  15. package/dist/chunk-BVLOX4A3.js +256 -0
  16. package/dist/chunk-BVLOX4A3.js.map +1 -0
  17. package/dist/{chunk-YZ27OS2R.js → chunk-C32XGHWO.js} +3 -3
  18. package/dist/{chunk-YZ27OS2R.js.map → chunk-C32XGHWO.js.map} +1 -1
  19. package/dist/{chunk-UJWCEGQY.js → chunk-C5HQPXRI.js} +3 -3
  20. package/dist/{chunk-UJWCEGQY.js.map → chunk-C5HQPXRI.js.map} +1 -1
  21. package/dist/{chunk-XALU6LOT.js → chunk-EN4CLDGZ.js} +3 -3
  22. package/dist/{chunk-XALU6LOT.js.map → chunk-EN4CLDGZ.js.map} +1 -1
  23. package/dist/{chunk-6AD6KCVB.js → chunk-F5UKI7XD.js} +3 -3
  24. package/dist/{chunk-6AD6KCVB.js.map → chunk-F5UKI7XD.js.map} +1 -1
  25. package/dist/chunk-GTAXVTLF.js +43 -0
  26. package/dist/chunk-GTAXVTLF.js.map +1 -0
  27. package/dist/{chunk-NNFJKRXZ.js → chunk-H2LHWJ52.js} +3 -3
  28. package/dist/{chunk-NNFJKRXZ.js.map → chunk-H2LHWJ52.js.map} +1 -1
  29. package/dist/{chunk-PZS4A4VQ.js → chunk-HXCETKCC.js} +3 -3
  30. package/dist/{chunk-PZS4A4VQ.js.map → chunk-HXCETKCC.js.map} +1 -1
  31. package/dist/chunk-IGBXSBF7.js +71 -0
  32. package/dist/chunk-IGBXSBF7.js.map +1 -0
  33. package/dist/{chunk-JXLEMBDB.js → chunk-IIVTPN62.js} +3 -3
  34. package/dist/{chunk-JXLEMBDB.js.map → chunk-IIVTPN62.js.map} +1 -1
  35. package/dist/{chunk-PNP7L4TA.js → chunk-ISCJST4P.js} +3 -3
  36. package/dist/{chunk-PNP7L4TA.js.map → chunk-ISCJST4P.js.map} +1 -1
  37. package/dist/{chunk-TLS54G6Y.js → chunk-IWM2XDXH.js} +3 -3
  38. package/dist/{chunk-TLS54G6Y.js.map → chunk-IWM2XDXH.js.map} +1 -1
  39. package/dist/chunk-J5LK2XHE.js +118 -0
  40. package/dist/chunk-J5LK2XHE.js.map +1 -0
  41. package/dist/chunk-KFFGDET3.js +27 -0
  42. package/dist/chunk-KFFGDET3.js.map +1 -0
  43. package/dist/{chunk-MRJWPRCX.js → chunk-L6VYDM7S.js} +3 -3
  44. package/dist/{chunk-MRJWPRCX.js.map → chunk-L6VYDM7S.js.map} +1 -1
  45. package/dist/chunk-M4BI63P6.js +188 -0
  46. package/dist/chunk-M4BI63P6.js.map +1 -0
  47. package/dist/{chunk-RUWD35UI.js → chunk-MK57AOTI.js} +4 -4
  48. package/dist/{chunk-RUWD35UI.js.map → chunk-MK57AOTI.js.map} +1 -1
  49. package/dist/{chunk-3BDDPFCI.js → chunk-MOAIQHR7.js} +3 -3
  50. package/dist/{chunk-3BDDPFCI.js.map → chunk-MOAIQHR7.js.map} +1 -1
  51. package/dist/{chunk-5XEGZFG5.js → chunk-MYBBBLYE.js} +3 -3
  52. package/dist/{chunk-5XEGZFG5.js.map → chunk-MYBBBLYE.js.map} +1 -1
  53. package/dist/{chunk-WP2Z2ATO.js → chunk-O6M3F7BZ.js} +5 -5
  54. package/dist/{chunk-WP2Z2ATO.js.map → chunk-O6M3F7BZ.js.map} +1 -1
  55. package/dist/{chunk-FEPTH5RV.js → chunk-OELY6K44.js} +3 -3
  56. package/dist/{chunk-FEPTH5RV.js.map → chunk-OELY6K44.js.map} +1 -1
  57. package/dist/{chunk-BZLT6R62.js → chunk-OIHX5B4R.js} +3 -3
  58. package/dist/{chunk-BZLT6R62.js.map → chunk-OIHX5B4R.js.map} +1 -1
  59. package/dist/{chunk-QJVS2VXS.js → chunk-PGYEIXCO.js} +4 -4
  60. package/dist/{chunk-QJVS2VXS.js.map → chunk-PGYEIXCO.js.map} +1 -1
  61. package/dist/{chunk-UZD77M3J.js → chunk-PJTCO76H.js} +3 -3
  62. package/dist/{chunk-UZD77M3J.js.map → chunk-PJTCO76H.js.map} +1 -1
  63. package/dist/{chunk-4PUPKWEP.js → chunk-PJXVLE24.js} +4 -4
  64. package/dist/{chunk-4PUPKWEP.js.map → chunk-PJXVLE24.js.map} +1 -1
  65. package/dist/{chunk-WGT345SV.js → chunk-PLQPBMG2.js} +3 -3
  66. package/dist/{chunk-WGT345SV.js.map → chunk-PLQPBMG2.js.map} +1 -1
  67. package/dist/{chunk-OMU4R4Y5.js → chunk-PQW5LKAI.js} +3 -3
  68. package/dist/{chunk-OMU4R4Y5.js.map → chunk-PQW5LKAI.js.map} +1 -1
  69. package/dist/{chunk-Y5TJ7CAX.js → chunk-RI4Y2C5U.js} +3 -3
  70. package/dist/{chunk-Y5TJ7CAX.js.map → chunk-RI4Y2C5U.js.map} +1 -1
  71. package/dist/{chunk-3OIWAS2P.js → chunk-SF6WPUC5.js} +3 -3
  72. package/dist/{chunk-3OIWAS2P.js.map → chunk-SF6WPUC5.js.map} +1 -1
  73. package/dist/{chunk-MKSDYRWQ.js → chunk-STX5UKYT.js} +3 -3
  74. package/dist/{chunk-MKSDYRWQ.js.map → chunk-STX5UKYT.js.map} +1 -1
  75. package/dist/{chunk-2RL6WCFC.js → chunk-TSWPHJIU.js} +4 -4
  76. package/dist/{chunk-2RL6WCFC.js.map → chunk-TSWPHJIU.js.map} +1 -1
  77. package/dist/{chunk-SFNDR6DI.js → chunk-U2ZKY2CP.js} +3 -3
  78. package/dist/{chunk-SFNDR6DI.js.map → chunk-U2ZKY2CP.js.map} +1 -1
  79. package/dist/{chunk-PABG3IJ6.js → chunk-UKDDK42K.js} +3 -3
  80. package/dist/{chunk-PABG3IJ6.js.map → chunk-UKDDK42K.js.map} +1 -1
  81. package/dist/{chunk-VYRJ7OE5.js → chunk-USFXANEU.js} +3 -3
  82. package/dist/{chunk-VYRJ7OE5.js.map → chunk-USFXANEU.js.map} +1 -1
  83. package/dist/{chunk-CCUXO2HN.js → chunk-V5QSMDZL.js} +3 -3
  84. package/dist/{chunk-CCUXO2HN.js.map → chunk-V5QSMDZL.js.map} +1 -1
  85. package/dist/{chunk-NF7XG2FG.js → chunk-V75O7QQO.js} +3 -3
  86. package/dist/{chunk-NF7XG2FG.js.map → chunk-V75O7QQO.js.map} +1 -1
  87. package/dist/chunk-VFUV6XJR.js +257 -0
  88. package/dist/chunk-VFUV6XJR.js.map +1 -0
  89. package/dist/{chunk-NRYWNOG5.js → chunk-VL2WNGPF.js} +3 -3
  90. package/dist/{chunk-NRYWNOG5.js.map → chunk-VL2WNGPF.js.map} +1 -1
  91. package/dist/{chunk-JQQ3FBN7.js → chunk-VLZANXRZ.js} +3 -3
  92. package/dist/{chunk-JQQ3FBN7.js.map → chunk-VLZANXRZ.js.map} +1 -1
  93. package/dist/{chunk-2HMQDJ22.js → chunk-VOF3S5I4.js} +3 -3
  94. package/dist/{chunk-2HMQDJ22.js.map → chunk-VOF3S5I4.js.map} +1 -1
  95. package/dist/chunk-XQNVWHMN.js +60 -0
  96. package/dist/chunk-XQNVWHMN.js.map +1 -0
  97. package/dist/{chunk-JZ774T7U.js → chunk-ZGFXKYA5.js} +3 -3
  98. package/dist/{chunk-JZ774T7U.js.map → chunk-ZGFXKYA5.js.map} +1 -1
  99. package/dist/client.cjs +1106 -7
  100. package/dist/client.cjs.map +1 -1
  101. package/dist/client.d.cts +9 -0
  102. package/dist/client.d.ts +9 -0
  103. package/dist/client.js +56 -47
  104. package/dist/client.js.map +1 -1
  105. package/dist/components/Accordion/index.js +2 -2
  106. package/dist/components/Alert/index.js +2 -2
  107. package/dist/components/AlertDialog/index.js +2 -2
  108. package/dist/components/AspectRatio/index.cjs +67 -0
  109. package/dist/components/AspectRatio/index.cjs.map +1 -0
  110. package/dist/components/AspectRatio/index.d.cts +30 -0
  111. package/dist/components/AspectRatio/index.d.ts +30 -0
  112. package/dist/components/AspectRatio/index.js +5 -0
  113. package/dist/components/AspectRatio/index.js.map +1 -0
  114. package/dist/components/Avatar/index.js +2 -2
  115. package/dist/components/Badge/index.js +2 -2
  116. package/dist/components/Box/index.js +4 -4
  117. package/dist/components/Breadcrumb/index.js +3 -3
  118. package/dist/components/Button/index.js +2 -2
  119. package/dist/components/ButtonGroup/index.cjs +83 -0
  120. package/dist/components/ButtonGroup/index.cjs.map +1 -0
  121. package/dist/components/ButtonGroup/index.d.cts +45 -0
  122. package/dist/components/ButtonGroup/index.d.ts +45 -0
  123. package/dist/components/ButtonGroup/index.js +5 -0
  124. package/dist/components/ButtonGroup/index.js.map +1 -0
  125. package/dist/components/Calendar/index.js +3 -3
  126. package/dist/components/Card/index.js +2 -2
  127. package/dist/components/Carousel/index.cjs +297 -0
  128. package/dist/components/Carousel/index.cjs.map +1 -0
  129. package/dist/components/Carousel/index.d.cts +67 -0
  130. package/dist/components/Carousel/index.d.ts +67 -0
  131. package/dist/components/Carousel/index.js +5 -0
  132. package/dist/components/Carousel/index.js.map +1 -0
  133. package/dist/components/Checkbox/index.js +2 -2
  134. package/dist/components/Collapsible/index.cjs +512 -0
  135. package/dist/components/Collapsible/index.cjs.map +1 -0
  136. package/dist/components/Collapsible/index.d.cts +50 -0
  137. package/dist/components/Collapsible/index.d.ts +50 -0
  138. package/dist/components/Collapsible/index.js +7 -0
  139. package/dist/components/Collapsible/index.js.map +1 -0
  140. package/dist/components/Combobox/index.js +3 -3
  141. package/dist/components/ContextMenu/index.js +4 -4
  142. package/dist/components/DataTable/index.js +3 -3
  143. package/dist/components/DatePicker/index.js +5 -5
  144. package/dist/components/Dialog/index.js +2 -2
  145. package/dist/components/DropdownMenu/index.js +3 -3
  146. package/dist/components/Empty/index.cjs +385 -0
  147. package/dist/components/Empty/index.cjs.map +1 -0
  148. package/dist/components/Empty/index.d.cts +32 -0
  149. package/dist/components/Empty/index.d.ts +32 -0
  150. package/dist/components/Empty/index.js +7 -0
  151. package/dist/components/Empty/index.js.map +1 -0
  152. package/dist/components/FloatButton/index.js +3 -3
  153. package/dist/components/HStack/index.js +4 -4
  154. package/dist/components/HoverCard/index.cjs +894 -0
  155. package/dist/components/HoverCard/index.cjs.map +1 -0
  156. package/dist/components/HoverCard/index.d.cts +66 -0
  157. package/dist/components/HoverCard/index.d.ts +66 -0
  158. package/dist/components/HoverCard/index.js +9 -0
  159. package/dist/components/HoverCard/index.js.map +1 -0
  160. package/dist/components/InputGroup/index.js +2 -2
  161. package/dist/components/InputOTP/index.cjs +580 -0
  162. package/dist/components/InputOTP/index.cjs.map +1 -0
  163. package/dist/components/InputOTP/index.d.cts +49 -0
  164. package/dist/components/InputOTP/index.d.ts +49 -0
  165. package/dist/components/InputOTP/index.js +7 -0
  166. package/dist/components/InputOTP/index.js.map +1 -0
  167. package/dist/components/Item/index.cjs +443 -0
  168. package/dist/components/Item/index.cjs.map +1 -0
  169. package/dist/components/Item/index.d.cts +40 -0
  170. package/dist/components/Item/index.d.ts +40 -0
  171. package/dist/components/Item/index.js +7 -0
  172. package/dist/components/Item/index.js.map +1 -0
  173. package/dist/components/Kbd/index.cjs +396 -0
  174. package/dist/components/Kbd/index.cjs.map +1 -0
  175. package/dist/components/Kbd/index.d.cts +22 -0
  176. package/dist/components/Kbd/index.d.ts +22 -0
  177. package/dist/components/Kbd/index.js +7 -0
  178. package/dist/components/Kbd/index.js.map +1 -0
  179. package/dist/components/Pagination/index.js +4 -4
  180. package/dist/components/Popover/index.js +2 -2
  181. package/dist/components/Progress/index.js +2 -2
  182. package/dist/components/Radio/index.js +2 -2
  183. package/dist/components/SegmentedControl/index.js +2 -2
  184. package/dist/components/Select/index.js +2 -2
  185. package/dist/components/Separator/index.js +2 -2
  186. package/dist/components/Sheet/index.js +2 -2
  187. package/dist/components/Skeleton/index.js +2 -2
  188. package/dist/components/Slider/index.js +2 -2
  189. package/dist/components/Switch/index.js +2 -2
  190. package/dist/components/Table/index.js +2 -2
  191. package/dist/components/Tabs/index.js +2 -2
  192. package/dist/components/Text/index.js +2 -2
  193. package/dist/components/TextArea/index.js +3 -3
  194. package/dist/components/TextInput/index.js +2 -2
  195. package/dist/components/Toggle/index.js +2 -2
  196. package/dist/components/Tooltip/index.js +2 -2
  197. package/dist/components/VStack/index.js +4 -4
  198. package/dist/index.cjs +1106 -7
  199. package/dist/index.cjs.map +1 -1
  200. package/dist/index.d.cts +9 -0
  201. package/dist/index.d.ts +9 -0
  202. package/dist/index.js +54 -45
  203. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -1649,6 +1649,24 @@ var AlertDialog = Object.assign(AlertDialogRoot, {
1649
1649
  Action: AlertDialogAction,
1650
1650
  Cancel: AlertDialogCancel
1651
1651
  });
1652
+ var BASE_STYLE = {
1653
+ overflow: "hidden"
1654
+ };
1655
+ var AspectRatio = /* @__PURE__ */ __name(({ ratio, children, className, testID }) => {
1656
+ const containerStyle = {
1657
+ ...BASE_STYLE,
1658
+ aspectRatio: ratio
1659
+ };
1660
+ return /* @__PURE__ */ jsxRuntime.jsx(
1661
+ reactNative.View,
1662
+ {
1663
+ ...testID !== void 0 ? { testID } : {},
1664
+ className: cn("overflow-hidden", className),
1665
+ style: containerStyle,
1666
+ children
1667
+ }
1668
+ );
1669
+ }, "AspectRatio");
1652
1670
  var SIZE_PX = {
1653
1671
  sm: 32,
1654
1672
  md: 40,
@@ -3487,7 +3505,7 @@ var SIZE_KEYS = {
3487
3505
  md: { padX: "4", font: "md" },
3488
3506
  lg: { padX: "5", font: "lg" }
3489
3507
  };
3490
- var BASE_STYLE = {
3508
+ var BASE_STYLE2 = {
3491
3509
  flexDirection: "row",
3492
3510
  alignItems: "center",
3493
3511
  justifyContent: "center"
@@ -3578,7 +3596,7 @@ var Button = /* @__PURE__ */ __name(({
3578
3596
  };
3579
3597
  const sizeFontSize = px(colors.fontSize[sizeKeys.font]);
3580
3598
  const inlineBase = [
3581
- BASE_STYLE,
3599
+ BASE_STYLE2,
3582
3600
  { backgroundColor: stateBg },
3583
3601
  sizeContainer,
3584
3602
  { opacity: isInoperative ? 0.6 : stateInteractionOpacity }
@@ -3658,6 +3676,39 @@ var Button = /* @__PURE__ */ __name(({
3658
3676
  }
3659
3677
  );
3660
3678
  }, "Button");
3679
+ var ButtonGroup = /* @__PURE__ */ __name(({ children, orientation = "horizontal", size, className, testID }) => {
3680
+ const isHorizontal = orientation === "horizontal";
3681
+ const containerStyle = {
3682
+ flexDirection: isHorizontal ? "row" : "column",
3683
+ // gap: 0 so buttons touch; shared-border effect comes from CSS on web
3684
+ // and from touching edges on native.
3685
+ gap: 0,
3686
+ alignSelf: "flex-start",
3687
+ overflow: "hidden"
3688
+ };
3689
+ const childArray = React.Children.toArray(children).filter(React.isValidElement);
3690
+ const total = childArray.length;
3691
+ const clonedChildren = childArray.map((child, index) => {
3692
+ const position = index === 0 ? "first" : index === total - 1 ? "last" : "middle";
3693
+ const extraProps = {
3694
+ "data-position": position,
3695
+ "data-group-orientation": orientation
3696
+ };
3697
+ if (size !== void 0) {
3698
+ extraProps["data-group-size"] = size;
3699
+ }
3700
+ return React.cloneElement(child, extraProps);
3701
+ });
3702
+ return /* @__PURE__ */ jsxRuntime.jsx(
3703
+ reactNative.View,
3704
+ {
3705
+ ...testID !== void 0 ? { testID } : {},
3706
+ className: cn(isHorizontal ? "flex-row" : "flex-col", "self-start overflow-hidden", className),
3707
+ style: containerStyle,
3708
+ children: clonedChildren
3709
+ }
3710
+ );
3711
+ }, "ButtonGroup");
3661
3712
  var detectLocale = /* @__PURE__ */ __name(() => {
3662
3713
  try {
3663
3714
  return new Intl.DateTimeFormat().resolvedOptions().locale;
@@ -6438,6 +6489,254 @@ var Card = Object.assign(CardRoot, {
6438
6489
  Content: CardContent,
6439
6490
  Footer: CardFooter
6440
6491
  });
6492
+ var CarouselContext = React.createContext(null);
6493
+ function useCarouselContext(caller) {
6494
+ const ctx = React.useContext(CarouselContext);
6495
+ if (!ctx) {
6496
+ throw new Error(`<${caller}> must be rendered inside <Carousel>.`);
6497
+ }
6498
+ return ctx;
6499
+ }
6500
+ __name(useCarouselContext, "useCarouselContext");
6501
+ var CarouselRoot = /* @__PURE__ */ __name(({
6502
+ index: controlledIndex,
6503
+ defaultIndex = 0,
6504
+ onIndexChange,
6505
+ loop = false,
6506
+ orientation = "horizontal",
6507
+ children,
6508
+ className,
6509
+ testID
6510
+ }) => {
6511
+ const [inner, setInner] = React.useState(defaultIndex);
6512
+ const isControlled = controlledIndex !== void 0;
6513
+ const index = isControlled ? controlledIndex : inner;
6514
+ const [count, setCount] = React.useState(0);
6515
+ const listRef = React.useRef(null);
6516
+ const id = React.useId();
6517
+ const setIndex = React.useCallback(
6518
+ (next2) => {
6519
+ if (!isControlled) {
6520
+ setInner(next2);
6521
+ }
6522
+ onIndexChange?.(next2);
6523
+ },
6524
+ [isControlled, onIndexChange]
6525
+ );
6526
+ const scrollTo = React.useCallback(
6527
+ (idx) => {
6528
+ const list = listRef.current;
6529
+ if (!list) {
6530
+ return;
6531
+ }
6532
+ const item = list.children[idx];
6533
+ if (!item) {
6534
+ return;
6535
+ }
6536
+ item.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "nearest" });
6537
+ setIndex(idx);
6538
+ },
6539
+ [setIndex]
6540
+ );
6541
+ const next = React.useCallback(() => {
6542
+ if (count === 0) {
6543
+ return;
6544
+ }
6545
+ if (index < count - 1) {
6546
+ scrollTo(index + 1);
6547
+ } else if (loop) {
6548
+ scrollTo(0);
6549
+ }
6550
+ }, [index, count, loop, scrollTo]);
6551
+ const prev = React.useCallback(() => {
6552
+ if (count === 0) {
6553
+ return;
6554
+ }
6555
+ if (index > 0) {
6556
+ scrollTo(index - 1);
6557
+ } else if (loop) {
6558
+ scrollTo(count - 1);
6559
+ }
6560
+ }, [index, count, loop, scrollTo]);
6561
+ React.useEffect(() => {
6562
+ const list = listRef.current;
6563
+ if (!list) {
6564
+ return;
6565
+ }
6566
+ const handleScroll = /* @__PURE__ */ __name(() => {
6567
+ const { scrollLeft, scrollTop, offsetWidth, offsetHeight } = list;
6568
+ const pos = orientation === "horizontal" ? scrollLeft : scrollTop;
6569
+ const size = orientation === "horizontal" ? offsetWidth : offsetHeight;
6570
+ if (size === 0) {
6571
+ return;
6572
+ }
6573
+ const newIdx = Math.round(pos / size);
6574
+ if (newIdx !== index) {
6575
+ setIndex(newIdx);
6576
+ }
6577
+ }, "handleScroll");
6578
+ list.addEventListener("scroll", handleScroll, { passive: true });
6579
+ return () => list.removeEventListener("scroll", handleScroll);
6580
+ }, [orientation, index, setIndex]);
6581
+ return /* @__PURE__ */ jsxRuntime.jsx(
6582
+ CarouselContext.Provider,
6583
+ {
6584
+ value: { index, count, loop, orientation, scrollTo, next, prev, listRef, setCount, id },
6585
+ children: /* @__PURE__ */ jsxRuntime.jsx(
6586
+ "section",
6587
+ {
6588
+ "aria-label": testID ?? "Carousel",
6589
+ className: cn("relative overflow-hidden", className),
6590
+ "data-testid": testID,
6591
+ children
6592
+ }
6593
+ )
6594
+ }
6595
+ );
6596
+ }, "CarouselRoot");
6597
+ var CarouselContent = /* @__PURE__ */ __name(({ children, className, testID }) => {
6598
+ const ctx = useCarouselContext("Carousel.Content");
6599
+ const childCount = React.Children.count(children);
6600
+ React.useEffect(() => {
6601
+ ctx.setCount(childCount);
6602
+ }, [childCount, ctx.setCount]);
6603
+ const isHorizontal = ctx.orientation === "horizontal";
6604
+ return /* @__PURE__ */ jsxRuntime.jsx(
6605
+ "div",
6606
+ {
6607
+ ref: ctx.listRef,
6608
+ "data-testid": testID,
6609
+ className: cn(
6610
+ "flex",
6611
+ isHorizontal ? "flex-row overflow-x-auto overflow-y-hidden" : "flex-col overflow-y-auto overflow-x-hidden",
6612
+ className
6613
+ ),
6614
+ style: {
6615
+ scrollSnapType: isHorizontal ? "x mandatory" : "y mandatory",
6616
+ scrollBehavior: "smooth",
6617
+ WebkitOverflowScrolling: "touch",
6618
+ // Hide scrollbar
6619
+ scrollbarWidth: "none",
6620
+ msOverflowStyle: "none"
6621
+ },
6622
+ children
6623
+ }
6624
+ );
6625
+ }, "CarouselContent");
6626
+ var CarouselItem = /* @__PURE__ */ __name(({ children, className, testID }) => {
6627
+ const ctx = useCarouselContext("Carousel.Item");
6628
+ const isHorizontal = ctx.orientation === "horizontal";
6629
+ return /* @__PURE__ */ jsxRuntime.jsx(
6630
+ "div",
6631
+ {
6632
+ "data-testid": testID,
6633
+ className: cn("shrink-0", isHorizontal ? "w-full" : "h-full", className),
6634
+ style: {
6635
+ scrollSnapAlign: "start",
6636
+ minWidth: isHorizontal ? "100%" : void 0,
6637
+ minHeight: !isHorizontal ? "100%" : void 0
6638
+ },
6639
+ children
6640
+ }
6641
+ );
6642
+ }, "CarouselItem");
6643
+ var CarouselPrevious = /* @__PURE__ */ __name(({ className, testID, children }) => {
6644
+ const ctx = useCarouselContext("Carousel.Previous");
6645
+ const disabled = !ctx.loop && ctx.index === 0;
6646
+ return /* @__PURE__ */ jsxRuntime.jsx(
6647
+ "button",
6648
+ {
6649
+ type: "button",
6650
+ "aria-label": "Previous slide",
6651
+ disabled,
6652
+ "data-testid": testID,
6653
+ onClick: ctx.prev,
6654
+ className: cn(
6655
+ "absolute left-2 top-1/2 z-10 flex h-8 w-8 -translate-y-1/2 items-center justify-center rounded-full bg-white/80 shadow hover:bg-white disabled:opacity-40",
6656
+ className
6657
+ ),
6658
+ children: children ?? /* @__PURE__ */ jsxRuntime.jsx(
6659
+ "svg",
6660
+ {
6661
+ viewBox: "0 0 24 24",
6662
+ fill: "none",
6663
+ stroke: "currentColor",
6664
+ strokeWidth: 2,
6665
+ className: "h-4 w-4",
6666
+ "aria-hidden": "true",
6667
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 18l-6-6 6-6", strokeLinecap: "round", strokeLinejoin: "round" })
6668
+ }
6669
+ )
6670
+ }
6671
+ );
6672
+ }, "CarouselPrevious");
6673
+ var CarouselNext = /* @__PURE__ */ __name(({ className, testID, children }) => {
6674
+ const ctx = useCarouselContext("Carousel.Next");
6675
+ const disabled = !ctx.loop && ctx.index >= ctx.count - 1;
6676
+ return /* @__PURE__ */ jsxRuntime.jsx(
6677
+ "button",
6678
+ {
6679
+ type: "button",
6680
+ "aria-label": "Next slide",
6681
+ disabled,
6682
+ "data-testid": testID,
6683
+ onClick: ctx.next,
6684
+ className: cn(
6685
+ "absolute right-2 top-1/2 z-10 flex h-8 w-8 -translate-y-1/2 items-center justify-center rounded-full bg-white/80 shadow hover:bg-white disabled:opacity-40",
6686
+ className
6687
+ ),
6688
+ children: children ?? /* @__PURE__ */ jsxRuntime.jsx(
6689
+ "svg",
6690
+ {
6691
+ viewBox: "0 0 24 24",
6692
+ fill: "none",
6693
+ stroke: "currentColor",
6694
+ strokeWidth: 2,
6695
+ className: "h-4 w-4",
6696
+ "aria-hidden": "true",
6697
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 18l6-6-6-6", strokeLinecap: "round", strokeLinejoin: "round" })
6698
+ }
6699
+ )
6700
+ }
6701
+ );
6702
+ }, "CarouselNext");
6703
+ var CarouselDots = /* @__PURE__ */ __name(({ className, testID }) => {
6704
+ const ctx = useCarouselContext("Carousel.Dots");
6705
+ if (ctx.count === 0) {
6706
+ return null;
6707
+ }
6708
+ return /* @__PURE__ */ jsxRuntime.jsx(
6709
+ "div",
6710
+ {
6711
+ role: "tablist",
6712
+ "aria-label": "Slide navigation",
6713
+ "data-testid": testID,
6714
+ className: cn("absolute bottom-3 left-0 right-0 flex items-center justify-center gap-1.5", className),
6715
+ children: Array.from({ length: ctx.count }, (_, i) => /* @__PURE__ */ jsxRuntime.jsx(
6716
+ "button",
6717
+ {
6718
+ type: "button",
6719
+ role: "tab",
6720
+ "aria-selected": i === ctx.index,
6721
+ "aria-label": `Go to slide ${i + 1}`,
6722
+ onClick: () => ctx.scrollTo(i),
6723
+ className: cn(
6724
+ "h-1.5 w-1.5 rounded-full transition-all",
6725
+ i === ctx.index ? "w-3 bg-white" : "bg-white/50 hover:bg-white/75"
6726
+ )
6727
+ },
6728
+ i
6729
+ ))
6730
+ }
6731
+ );
6732
+ }, "CarouselDots");
6733
+ var Carousel = Object.assign(CarouselRoot, {
6734
+ Content: CarouselContent,
6735
+ Item: CarouselItem,
6736
+ Previous: CarouselPrevious,
6737
+ Next: CarouselNext,
6738
+ Dots: CarouselDots
6739
+ });
6441
6740
  var SemanticIconsContext = React.createContext(defaultSemanticIcons);
6442
6741
  SemanticIconsContext.displayName = "SemanticIconsContext";
6443
6742
 
@@ -6592,6 +6891,182 @@ var Checkbox = /* @__PURE__ */ __name(({
6592
6891
  }
6593
6892
  );
6594
6893
  }, "Checkbox");
6894
+ var CollapsibleContext = React.createContext(null);
6895
+ var useCollapsibleContext = /* @__PURE__ */ __name((label) => {
6896
+ const ctx = React.useContext(CollapsibleContext);
6897
+ if (!ctx) {
6898
+ throw new Error(`<${label}> must be rendered inside a <Collapsible>.`);
6899
+ }
6900
+ return ctx;
6901
+ }, "useCollapsibleContext");
6902
+ var CollapsibleRoot = /* @__PURE__ */ __name(({
6903
+ open: controlledOpen,
6904
+ defaultOpen = false,
6905
+ onOpenChange,
6906
+ children,
6907
+ className,
6908
+ testID
6909
+ }) => {
6910
+ const baseId = React.useId();
6911
+ const [innerOpen, setInnerOpen] = React.useState(defaultOpen);
6912
+ const isControlled = controlledOpen !== void 0;
6913
+ const open = isControlled ? controlledOpen : innerOpen;
6914
+ const toggle = React.useCallback(() => {
6915
+ const next = !open;
6916
+ if (!isControlled) {
6917
+ setInnerOpen(next);
6918
+ }
6919
+ onOpenChange?.(next);
6920
+ }, [open, isControlled, onOpenChange]);
6921
+ const ctx = React.useMemo(
6922
+ () => ({
6923
+ open,
6924
+ toggle,
6925
+ contentId: `${baseId}-content`,
6926
+ triggerId: `${baseId}-trigger`
6927
+ }),
6928
+ [open, toggle, baseId]
6929
+ );
6930
+ return /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContext.Provider, { value: ctx, children: /* @__PURE__ */ jsxRuntime.jsx(
6931
+ reactNative.View,
6932
+ {
6933
+ ...testID !== void 0 ? { testID } : {},
6934
+ className: cn("flex-col", className),
6935
+ style: { flexDirection: "column" },
6936
+ children
6937
+ }
6938
+ ) });
6939
+ }, "CollapsibleRoot");
6940
+ var CollapsibleTrigger = /* @__PURE__ */ __name(({ children, className, testID }) => {
6941
+ const { open, toggle, contentId, triggerId } = useCollapsibleContext("Collapsible.Trigger");
6942
+ const colors = useThemeColors();
6943
+ const triggerStyle = {
6944
+ flexDirection: "row",
6945
+ alignItems: "center",
6946
+ paddingVertical: px(colors.spacing["2"]),
6947
+ paddingHorizontal: px(colors.spacing["1"])
6948
+ };
6949
+ return /* @__PURE__ */ jsxRuntime.jsx(
6950
+ reactNative.Pressable,
6951
+ {
6952
+ id: triggerId,
6953
+ ...testID !== void 0 ? { testID } : {},
6954
+ role: "button",
6955
+ accessibilityRole: "button",
6956
+ "aria-expanded": open,
6957
+ "aria-controls": contentId,
6958
+ onPress: toggle,
6959
+ className: cn("flex-row items-center py-2 px-1", className),
6960
+ style: triggerStyle,
6961
+ children: typeof children === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
6962
+ reactNative.Text,
6963
+ {
6964
+ style: {
6965
+ color: colors.semantic.text.default,
6966
+ fontFamily: colors.fontFamily.body,
6967
+ fontSize: px(colors.fontSize.sm),
6968
+ fontWeight: colors.fontWeight.medium
6969
+ },
6970
+ children
6971
+ }
6972
+ ) : children
6973
+ }
6974
+ );
6975
+ }, "CollapsibleTrigger");
6976
+ var CollapsibleContent = /* @__PURE__ */ __name(({ children, className, testID }) => {
6977
+ const { open, contentId, triggerId } = useCollapsibleContext("Collapsible.Content");
6978
+ const wrapperRef = React.useRef(null);
6979
+ const innerRef = React.useRef(null);
6980
+ React.useEffect(() => {
6981
+ if (reactNative.Platform.OS !== "web") {
6982
+ return;
6983
+ }
6984
+ const wrapper = wrapperRef.current;
6985
+ const inner = innerRef.current;
6986
+ if (!wrapper || !inner) {
6987
+ return;
6988
+ }
6989
+ const isFirstPaint = wrapper.dataset.noriPainted !== "1";
6990
+ wrapper.dataset.noriPainted = "1";
6991
+ wrapper.style.overflow = "hidden";
6992
+ wrapper.style.transitionProperty = "max-height, opacity";
6993
+ wrapper.style.transitionDuration = "200ms";
6994
+ wrapper.style.transitionTimingFunction = "cubic-bezier(0.16, 1, 0.3, 1)";
6995
+ if (open) {
6996
+ const target = inner.scrollHeight;
6997
+ if (isFirstPaint) {
6998
+ wrapper.style.maxHeight = `${target}px`;
6999
+ wrapper.style.opacity = "1";
7000
+ return;
7001
+ }
7002
+ wrapper.style.maxHeight = "0px";
7003
+ wrapper.style.opacity = "0";
7004
+ void wrapper.offsetHeight;
7005
+ requestAnimationFrame(() => {
7006
+ wrapper.style.maxHeight = `${target}px`;
7007
+ wrapper.style.opacity = "1";
7008
+ });
7009
+ } else {
7010
+ if (isFirstPaint) {
7011
+ wrapper.style.maxHeight = "0px";
7012
+ wrapper.style.opacity = "0";
7013
+ return;
7014
+ }
7015
+ const current = inner.scrollHeight;
7016
+ wrapper.style.maxHeight = `${current}px`;
7017
+ wrapper.style.opacity = "1";
7018
+ void wrapper.offsetHeight;
7019
+ requestAnimationFrame(() => {
7020
+ wrapper.style.maxHeight = "0px";
7021
+ wrapper.style.opacity = "0";
7022
+ });
7023
+ }
7024
+ }, [open]);
7025
+ if (reactNative.Platform.OS !== "web") {
7026
+ if (!open) {
7027
+ return null;
7028
+ }
7029
+ return /* @__PURE__ */ jsxRuntime.jsx(
7030
+ reactNative.View,
7031
+ {
7032
+ ...testID !== void 0 ? { testID } : {},
7033
+ id: contentId,
7034
+ "aria-labelledby": triggerId,
7035
+ className: cn("flex-col", className),
7036
+ style: { flexDirection: "column" },
7037
+ children
7038
+ }
7039
+ );
7040
+ }
7041
+ return /* @__PURE__ */ jsxRuntime.jsx(
7042
+ reactNative.View,
7043
+ {
7044
+ ref: (node) => {
7045
+ wrapperRef.current = node;
7046
+ },
7047
+ ...testID !== void 0 ? { testID } : {},
7048
+ id: contentId,
7049
+ "aria-labelledby": triggerId,
7050
+ "aria-hidden": !open,
7051
+ className: cn("overflow-hidden", className),
7052
+ children: /* @__PURE__ */ jsxRuntime.jsx(
7053
+ reactNative.View,
7054
+ {
7055
+ ref: (node) => {
7056
+ innerRef.current = node;
7057
+ },
7058
+ className: "flex-col",
7059
+ style: { flexDirection: "column" },
7060
+ children
7061
+ }
7062
+ )
7063
+ }
7064
+ );
7065
+ }, "CollapsibleContent");
7066
+ var Collapsible = Object.assign(CollapsibleRoot, {
7067
+ Trigger: CollapsibleTrigger,
7068
+ Content: CollapsibleContent
7069
+ });
6595
7070
  var Combobox = /* @__PURE__ */ __name((props) => {
6596
7071
  return /* @__PURE__ */ jsxRuntime.jsx(Select, { searchable: true, ...props });
6597
7072
  }, "Combobox");
@@ -8190,11 +8665,60 @@ var Dialog = Object.assign(DialogRoot, {
8190
8665
  Footer: DialogFooter,
8191
8666
  Close: DialogClose
8192
8667
  });
8193
- var FieldContext = React.createContext(null);
8194
- var useFieldContextStrict = /* @__PURE__ */ __name((caller) => {
8195
- const ctx = React.useContext(FieldContext);
8196
- if (!ctx) {
8197
- throw new Error(`[Field] ${caller} must be used inside <Field> or <Field.Group>.`);
8668
+ var Empty = /* @__PURE__ */ __name(({ icon, title, description, action, className, testID }) => {
8669
+ const colors = useThemeColors();
8670
+ const containerStyle = {
8671
+ flexDirection: "column",
8672
+ alignItems: "center",
8673
+ justifyContent: "center",
8674
+ gap: px(colors.spacing["3"]),
8675
+ paddingVertical: px(colors.spacing["8"]),
8676
+ paddingHorizontal: px(colors.spacing["4"])
8677
+ };
8678
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8679
+ reactNative.View,
8680
+ {
8681
+ ...testID !== void 0 ? { testID } : {},
8682
+ className: cn("flex-col items-center justify-center gap-3 py-8 px-4", className),
8683
+ style: containerStyle,
8684
+ children: [
8685
+ icon != null ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { marginBottom: px(colors.spacing["1"]) }, children: icon }) : null,
8686
+ /* @__PURE__ */ jsxRuntime.jsx(
8687
+ reactNative.Text,
8688
+ {
8689
+ style: {
8690
+ color: colors.semantic.text.default,
8691
+ fontFamily: colors.fontFamily.body,
8692
+ fontSize: px(colors.fontSize.md),
8693
+ fontWeight: colors.fontWeight.semibold,
8694
+ textAlign: "center"
8695
+ },
8696
+ children: title
8697
+ }
8698
+ ),
8699
+ description != null ? /* @__PURE__ */ jsxRuntime.jsx(
8700
+ reactNative.Text,
8701
+ {
8702
+ style: {
8703
+ color: colors.semantic.text.muted,
8704
+ fontFamily: colors.fontFamily.body,
8705
+ fontSize: px(colors.fontSize.sm),
8706
+ lineHeight: px(colors.fontSize.sm) * Number(colors.lineHeight.normal),
8707
+ textAlign: "center"
8708
+ },
8709
+ children: description
8710
+ }
8711
+ ) : null,
8712
+ action != null ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { marginTop: px(colors.spacing["1"]) }, children: action }) : null
8713
+ ]
8714
+ }
8715
+ );
8716
+ }, "Empty");
8717
+ var FieldContext = React.createContext(null);
8718
+ var useFieldContextStrict = /* @__PURE__ */ __name((caller) => {
8719
+ const ctx = React.useContext(FieldContext);
8720
+ if (!ctx) {
8721
+ throw new Error(`[Field] ${caller} must be used inside <Field> or <Field.Group>.`);
8198
8722
  }
8199
8723
  return ctx;
8200
8724
  }, "useFieldContextStrict");
@@ -9101,6 +9625,161 @@ function withAlpha(color, alpha) {
9101
9625
  return color;
9102
9626
  }
9103
9627
  __name(withAlpha, "withAlpha");
9628
+ var HoverCardContext = React.createContext(null);
9629
+ function useHoverCardContext(caller) {
9630
+ const ctx = React.useContext(HoverCardContext);
9631
+ if (!ctx) {
9632
+ throw new Error(`<${caller}> must be rendered inside <HoverCard>.`);
9633
+ }
9634
+ return ctx;
9635
+ }
9636
+ __name(useHoverCardContext, "useHoverCardContext");
9637
+ var DEFAULT_OPEN_DELAY = 300;
9638
+ var DEFAULT_CLOSE_DELAY = 200;
9639
+ var HoverCardRoot = /* @__PURE__ */ __name(({
9640
+ open: controlledOpen,
9641
+ defaultOpen = false,
9642
+ onOpenChange,
9643
+ openDelay = DEFAULT_OPEN_DELAY,
9644
+ closeDelay = DEFAULT_CLOSE_DELAY,
9645
+ children
9646
+ }) => {
9647
+ const [inner, setInner] = React.useState(defaultOpen);
9648
+ const isControlled = controlledOpen !== void 0;
9649
+ const open = isControlled ? controlledOpen : inner;
9650
+ const id = React.useId();
9651
+ const setOpen = React.useCallback(
9652
+ (next) => {
9653
+ if (!isControlled) {
9654
+ setInner(next);
9655
+ }
9656
+ onOpenChange?.(next);
9657
+ },
9658
+ [isControlled, onOpenChange]
9659
+ );
9660
+ const openTimer = React.useRef(null);
9661
+ const closeTimer = React.useRef(null);
9662
+ const cancelTimers = React.useCallback(() => {
9663
+ if (openTimer.current) {
9664
+ clearTimeout(openTimer.current);
9665
+ openTimer.current = null;
9666
+ }
9667
+ if (closeTimer.current) {
9668
+ clearTimeout(closeTimer.current);
9669
+ closeTimer.current = null;
9670
+ }
9671
+ }, []);
9672
+ const requestOpen = React.useCallback(() => {
9673
+ if (closeTimer.current) {
9674
+ clearTimeout(closeTimer.current);
9675
+ closeTimer.current = null;
9676
+ }
9677
+ if (openTimer.current) {
9678
+ return;
9679
+ }
9680
+ if (openDelay <= 0) {
9681
+ setOpen(true);
9682
+ return;
9683
+ }
9684
+ openTimer.current = setTimeout(() => {
9685
+ openTimer.current = null;
9686
+ setOpen(true);
9687
+ }, openDelay);
9688
+ }, [openDelay, setOpen]);
9689
+ const requestClose = React.useCallback(() => {
9690
+ if (openTimer.current) {
9691
+ clearTimeout(openTimer.current);
9692
+ openTimer.current = null;
9693
+ }
9694
+ if (closeTimer.current) {
9695
+ return;
9696
+ }
9697
+ if (closeDelay <= 0) {
9698
+ setOpen(false);
9699
+ return;
9700
+ }
9701
+ closeTimer.current = setTimeout(() => {
9702
+ closeTimer.current = null;
9703
+ setOpen(false);
9704
+ }, closeDelay);
9705
+ }, [closeDelay, setOpen]);
9706
+ React.useEffect(() => () => cancelTimers(), [cancelTimers]);
9707
+ return /* @__PURE__ */ jsxRuntime.jsx(
9708
+ HoverCardContext.Provider,
9709
+ {
9710
+ value: { open, requestOpen, requestClose, cancelTimers, contentId: `hc-content-${id}` },
9711
+ children: /* @__PURE__ */ jsxRuntime.jsx(Popover, { open, onOpenChange: setOpen, children })
9712
+ }
9713
+ );
9714
+ }, "HoverCardRoot");
9715
+ var HoverCardTrigger = /* @__PURE__ */ __name(({ asChild = true, children, className, testID }) => {
9716
+ const ctx = useHoverCardContext("HoverCard.Trigger");
9717
+ const handleMouseEnter = React.useCallback(() => {
9718
+ ctx.cancelTimers();
9719
+ ctx.requestOpen();
9720
+ }, [ctx]);
9721
+ const handleMouseLeave = React.useCallback(() => {
9722
+ ctx.requestClose();
9723
+ }, [ctx]);
9724
+ const handlers = {
9725
+ onMouseEnter: handleMouseEnter,
9726
+ onMouseLeave: handleMouseLeave,
9727
+ "aria-haspopup": "dialog",
9728
+ "aria-expanded": ctx.open
9729
+ };
9730
+ if (asChild && React.isValidElement(children)) {
9731
+ const child = children;
9732
+ const compose = /* @__PURE__ */ __name((existing, next) => (event) => {
9733
+ existing?.(event);
9734
+ next(event);
9735
+ }, "compose");
9736
+ return /* @__PURE__ */ jsxRuntime.jsx(
9737
+ Slot,
9738
+ {
9739
+ ...handlers,
9740
+ onMouseEnter: compose(child.props.onMouseEnter, handleMouseEnter),
9741
+ onMouseLeave: compose(child.props.onMouseLeave, handleMouseLeave),
9742
+ ...className !== void 0 ? { className } : {},
9743
+ ...testID !== void 0 ? { "data-testid": testID } : {},
9744
+ children: child
9745
+ }
9746
+ );
9747
+ }
9748
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { ...handlers, className, ...testID !== void 0 ? { "data-testid": testID } : {}, children });
9749
+ }, "HoverCardTrigger");
9750
+ var HoverCardContent = /* @__PURE__ */ __name(({ side = "bottom", align = "start", children, className, testID }) => {
9751
+ const ctx = useHoverCardContext("HoverCard.Content");
9752
+ const handleMouseEnter = React.useCallback(() => {
9753
+ ctx.cancelTimers();
9754
+ }, [ctx]);
9755
+ const handleMouseLeave = React.useCallback(() => {
9756
+ ctx.requestClose();
9757
+ }, [ctx]);
9758
+ return /* @__PURE__ */ jsxRuntime.jsx(
9759
+ Popover.Content,
9760
+ {
9761
+ side,
9762
+ align,
9763
+ ...className !== void 0 ? { className } : {},
9764
+ ...testID !== void 0 ? { testID } : {},
9765
+ children: /* @__PURE__ */ jsxRuntime.jsx(
9766
+ "div",
9767
+ {
9768
+ id: ctx.contentId,
9769
+ role: "dialog",
9770
+ "aria-label": "Hover card",
9771
+ onMouseEnter: handleMouseEnter,
9772
+ onMouseLeave: handleMouseLeave,
9773
+ children
9774
+ }
9775
+ )
9776
+ }
9777
+ );
9778
+ }, "HoverCardContent");
9779
+ var HoverCard = Object.assign(HoverCardRoot, {
9780
+ Trigger: HoverCardTrigger,
9781
+ Content: HoverCardContent
9782
+ });
9104
9783
  var ALIGN_CLASS = {
9105
9784
  start: "items-start",
9106
9785
  center: "items-center",
@@ -9473,6 +10152,417 @@ var InputGroup = Object.assign(InputGroupRoot, {
9473
10152
  Addon: InputGroupAddon,
9474
10153
  Input: InputGroupInput
9475
10154
  });
10155
+ function isAllowed(char, pattern) {
10156
+ if (pattern === "numeric") {
10157
+ return /^\d$/.test(char);
10158
+ }
10159
+ return /^[a-zA-Z0-9]$/.test(char);
10160
+ }
10161
+ __name(isAllowed, "isAllowed");
10162
+ function filterValue(value, pattern, length) {
10163
+ return value.split("").filter((c) => isAllowed(c, pattern)).slice(0, length).join("");
10164
+ }
10165
+ __name(filterValue, "filterValue");
10166
+ var InputOTP = /* @__PURE__ */ __name(({
10167
+ value = "",
10168
+ onChange,
10169
+ onComplete,
10170
+ length = 6,
10171
+ placeholder = "\xB7",
10172
+ pattern = "numeric",
10173
+ disabled = false,
10174
+ autoFocus = false,
10175
+ id,
10176
+ name,
10177
+ "aria-label": ariaLabel = "One-time code",
10178
+ "aria-labelledby": ariaLabelledBy,
10179
+ "aria-describedby": ariaDescribedBy,
10180
+ "aria-invalid": ariaInvalid,
10181
+ className,
10182
+ testID
10183
+ }) => {
10184
+ const colors = useThemeColors();
10185
+ const [cells, setCells] = React.useState(() => {
10186
+ const filtered = filterValue(value, pattern, length);
10187
+ return Array.from({ length }, (_, i) => filtered[i] ?? "");
10188
+ });
10189
+ const prevValue = React.useRef(value);
10190
+ React.useEffect(() => {
10191
+ if (value !== prevValue.current) {
10192
+ prevValue.current = value;
10193
+ const filtered = filterValue(value, pattern, length);
10194
+ setCells(Array.from({ length }, (_, i) => filtered[i] ?? ""));
10195
+ }
10196
+ }, [value, pattern, length]);
10197
+ const inputRefs = React.useRef([]);
10198
+ const focusCell = React.useCallback(
10199
+ (idx) => {
10200
+ if (idx >= 0 && idx < length) {
10201
+ inputRefs.current[idx]?.focus();
10202
+ }
10203
+ },
10204
+ [length]
10205
+ );
10206
+ const updateCells = React.useCallback(
10207
+ (next) => {
10208
+ setCells(next);
10209
+ const joined = next.join("");
10210
+ onChange?.(joined);
10211
+ if (joined.length === length && !next.includes("")) {
10212
+ onComplete?.(joined);
10213
+ }
10214
+ },
10215
+ [onChange, onComplete, length]
10216
+ );
10217
+ const onContainerPaste = React.useCallback(
10218
+ (e) => {
10219
+ e.preventDefault();
10220
+ const text = e.clipboardData.getData("text/plain") ?? "";
10221
+ const filtered = filterValue(text, pattern, length);
10222
+ const next = Array.from({ length }, (_, i) => filtered[i] ?? "");
10223
+ updateCells(next);
10224
+ const nextEmpty = next.indexOf("");
10225
+ focusCell(nextEmpty === -1 ? length - 1 : nextEmpty);
10226
+ },
10227
+ [pattern, length, updateCells, focusCell]
10228
+ );
10229
+ const handleChangeText = React.useCallback(
10230
+ (text, idx) => {
10231
+ if (text.length > 1) {
10232
+ const filtered = filterValue(text, pattern, length);
10233
+ const next2 = Array.from({ length }, (_, i) => filtered[i] ?? "");
10234
+ updateCells(next2);
10235
+ const nextEmpty = next2.indexOf("");
10236
+ focusCell(nextEmpty === -1 ? length - 1 : nextEmpty);
10237
+ return;
10238
+ }
10239
+ const char = text.slice(-1);
10240
+ if (char && !isAllowed(char, pattern)) {
10241
+ return;
10242
+ }
10243
+ const next = [...cells];
10244
+ next[idx] = char;
10245
+ updateCells(next);
10246
+ if (char) {
10247
+ focusCell(idx + 1);
10248
+ }
10249
+ },
10250
+ [cells, pattern, length, updateCells, focusCell]
10251
+ );
10252
+ const handleWebKeyDown = React.useCallback(
10253
+ (e, idx) => {
10254
+ if (e.key === "Backspace") {
10255
+ if (cells[idx] !== "") {
10256
+ const next = [...cells];
10257
+ next[idx] = "";
10258
+ updateCells(next);
10259
+ } else {
10260
+ focusCell(idx - 1);
10261
+ }
10262
+ e.preventDefault();
10263
+ } else if (e.key === "ArrowLeft") {
10264
+ focusCell(idx - 1);
10265
+ e.preventDefault();
10266
+ } else if (e.key === "ArrowRight") {
10267
+ focusCell(idx + 1);
10268
+ e.preventDefault();
10269
+ } else if (e.key.length === 1 && isAllowed(e.key, pattern)) {
10270
+ const next = [...cells];
10271
+ next[idx] = e.key;
10272
+ updateCells(next);
10273
+ focusCell(idx + 1);
10274
+ e.preventDefault();
10275
+ }
10276
+ },
10277
+ [cells, pattern, focusCell, updateCells]
10278
+ );
10279
+ const handleNativeKeyPress = React.useCallback(
10280
+ (e, idx) => {
10281
+ if (e.nativeEvent.key === "Backspace") {
10282
+ if (cells[idx] !== "") {
10283
+ const next = [...cells];
10284
+ next[idx] = "";
10285
+ updateCells(next);
10286
+ } else {
10287
+ focusCell(idx - 1);
10288
+ }
10289
+ }
10290
+ },
10291
+ [cells, focusCell, updateCells]
10292
+ );
10293
+ const cellStyle = [
10294
+ styles2.cell,
10295
+ {
10296
+ width: px(48),
10297
+ height: px(56),
10298
+ borderRadius: px(colors.radius.md),
10299
+ borderColor: colors.semantic.border.default,
10300
+ backgroundColor: colors.semantic.background.elevated,
10301
+ color: colors.semantic.text.default,
10302
+ fontSize: px(colors.fontSize.xl),
10303
+ fontFamily: colors.fontFamily.body
10304
+ },
10305
+ disabled ? styles2.disabled : null,
10306
+ ariaInvalid === true || ariaInvalid === "true" ? { borderColor: colors.color.danger } : null
10307
+ ];
10308
+ const isWeb3 = reactNative.Platform.OS === "web";
10309
+ const containerProps = isWeb3 ? {
10310
+ onPaste: onContainerPaste,
10311
+ role: "group",
10312
+ "aria-label": ariaLabel,
10313
+ "aria-labelledby": ariaLabelledBy,
10314
+ "aria-describedby": ariaDescribedBy
10315
+ } : {};
10316
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10317
+ reactNative.View,
10318
+ {
10319
+ testID,
10320
+ ...isWeb3 ? {} : { accessible: true, accessibilityLabel: ariaLabel },
10321
+ ...containerProps,
10322
+ className: cn("flex-row items-center gap-2", className),
10323
+ style: styles2.container,
10324
+ children: [
10325
+ Array.from({ length }, (_, idx) => {
10326
+ const cellValue = cells[idx] ?? "";
10327
+ const cellRef = /* @__PURE__ */ __name((el) => {
10328
+ inputRefs.current[idx] = el;
10329
+ }, "cellRef");
10330
+ const webProps = isWeb3 ? {
10331
+ onKeyDown: /* @__PURE__ */ __name((e) => handleWebKeyDown(e, idx), "onKeyDown"),
10332
+ // id only on the first cell
10333
+ ...idx === 0 && id ? { id, nativeID: id } : {},
10334
+ ...idx === 0 && name ? { name } : {},
10335
+ ...idx === 0 && ariaLabelledBy ? { "aria-labelledby": ariaLabelledBy } : {},
10336
+ ...idx === 0 && ariaDescribedBy ? { "aria-describedby": ariaDescribedBy } : {},
10337
+ ...idx === 0 && ariaInvalid !== void 0 ? { "aria-invalid": ariaInvalid } : {},
10338
+ inputMode: pattern === "numeric" ? "numeric" : "text"
10339
+ } : {};
10340
+ const nativeOnlyProps = isWeb3 ? {} : {
10341
+ keyboardType: pattern === "numeric" ? "number-pad" : "default",
10342
+ textAlign: "center",
10343
+ selectTextOnFocus: true,
10344
+ onKeyPress: /* @__PURE__ */ __name((e) => handleNativeKeyPress(e, idx), "onKeyPress")
10345
+ };
10346
+ return /* @__PURE__ */ jsxRuntime.jsx(
10347
+ reactNative.TextInput,
10348
+ {
10349
+ ref: cellRef,
10350
+ value: cellValue,
10351
+ placeholder: placeholder,
10352
+ maxLength: 1,
10353
+ editable: !disabled,
10354
+ autoFocus: autoFocus && idx === 0,
10355
+ testID: testID ? `${testID}-cell-${idx}` : void 0,
10356
+ onChangeText: (text) => handleChangeText(text, idx),
10357
+ accessibilityLabel: `Digit ${idx + 1} of ${length}`,
10358
+ ...nativeOnlyProps,
10359
+ ...webProps,
10360
+ style: cellStyle
10361
+ },
10362
+ idx
10363
+ );
10364
+ }),
10365
+ isWeb3 && name ? /* @__PURE__ */ jsxRuntime.jsx(
10366
+ reactNative.TextInput,
10367
+ {
10368
+ style: styles2.hidden,
10369
+ value: cells.join(""),
10370
+ "aria-hidden": true,
10371
+ tabIndex: -1,
10372
+ ...{ name }
10373
+ }
10374
+ ) : null
10375
+ ]
10376
+ }
10377
+ );
10378
+ }, "InputOTP");
10379
+ var styles2 = reactNative.StyleSheet.create({
10380
+ container: {
10381
+ flexDirection: "row",
10382
+ alignItems: "center",
10383
+ gap: 8
10384
+ },
10385
+ cell: {
10386
+ borderWidth: 1,
10387
+ textAlign: "center"
10388
+ },
10389
+ disabled: {
10390
+ opacity: 0.6
10391
+ },
10392
+ hidden: {
10393
+ position: "absolute",
10394
+ width: 0,
10395
+ height: 0,
10396
+ opacity: 0
10397
+ }
10398
+ });
10399
+ var Item = /* @__PURE__ */ __name(({
10400
+ leading,
10401
+ title,
10402
+ description,
10403
+ trailing,
10404
+ chevron = false,
10405
+ onPress,
10406
+ disabled = false,
10407
+ className,
10408
+ testID
10409
+ }) => {
10410
+ const colors = useThemeColors();
10411
+ const isTappable = onPress !== void 0;
10412
+ const rowStyle = {
10413
+ flexDirection: "row",
10414
+ alignItems: "center",
10415
+ gap: px(colors.spacing["3"]),
10416
+ paddingVertical: px(colors.spacing["3"]),
10417
+ paddingHorizontal: px(colors.spacing["4"]),
10418
+ minHeight: 52,
10419
+ opacity: disabled ? 0.5 : 1
10420
+ };
10421
+ const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10422
+ leading != null ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { flexShrink: 0 }, children: leading }) : null,
10423
+ /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: { flex: 1, flexDirection: "column", gap: 2 }, children: [
10424
+ typeof title === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
10425
+ reactNative.Text,
10426
+ {
10427
+ style: {
10428
+ color: colors.semantic.text.default,
10429
+ fontFamily: colors.fontFamily.body,
10430
+ fontSize: px(colors.fontSize.sm),
10431
+ fontWeight: colors.fontWeight.medium
10432
+ },
10433
+ numberOfLines: 1,
10434
+ children: title
10435
+ }
10436
+ ) : title,
10437
+ description != null ? typeof description === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
10438
+ reactNative.Text,
10439
+ {
10440
+ style: {
10441
+ color: colors.semantic.text.muted,
10442
+ fontFamily: colors.fontFamily.body,
10443
+ fontSize: px(colors.fontSize.xs)
10444
+ },
10445
+ numberOfLines: 1,
10446
+ children: description
10447
+ }
10448
+ ) : description : null
10449
+ ] }),
10450
+ trailing != null ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { flexShrink: 0 }, children: trailing }) : null,
10451
+ chevron ? /* @__PURE__ */ jsxRuntime.jsx(
10452
+ reactNative.View,
10453
+ {
10454
+ style: { flexShrink: 0 },
10455
+ "aria-hidden": true,
10456
+ testID: testID != null ? `${testID}-chevron` : void 0,
10457
+ children: /* @__PURE__ */ jsxRuntime.jsx(
10458
+ reactNative.Text,
10459
+ {
10460
+ accessibilityElementsHidden: true,
10461
+ importantForAccessibility: "no-hide-descendants",
10462
+ style: {
10463
+ fontSize: 14,
10464
+ lineHeight: 16,
10465
+ color: colors.semantic.text.muted,
10466
+ // On web rn-web passes style through — transform
10467
+ // with a rotate is the lightest-weight approach
10468
+ // that avoids importing the full SVG icon set.
10469
+ transform: [{ rotate: "-90deg" }]
10470
+ },
10471
+ children: "\u2304"
10472
+ }
10473
+ )
10474
+ }
10475
+ ) : null
10476
+ ] });
10477
+ if (isTappable) {
10478
+ return /* @__PURE__ */ jsxRuntime.jsx(
10479
+ reactNative.Pressable,
10480
+ {
10481
+ ...testID !== void 0 ? { testID } : {},
10482
+ role: "button",
10483
+ accessibilityRole: "button",
10484
+ disabled,
10485
+ onPress: disabled ? void 0 : onPress,
10486
+ className: cn(
10487
+ "flex-row items-center",
10488
+ disabled ? "opacity-50" : "hover:bg-semantic-background-subtle active:bg-semantic-border-default",
10489
+ className
10490
+ ),
10491
+ style: rowStyle,
10492
+ children: content
10493
+ }
10494
+ );
10495
+ }
10496
+ return /* @__PURE__ */ jsxRuntime.jsx(
10497
+ reactNative.View,
10498
+ {
10499
+ ...testID !== void 0 ? { testID } : {},
10500
+ className: cn("flex-row items-center", className),
10501
+ style: rowStyle,
10502
+ children: content
10503
+ }
10504
+ );
10505
+ }, "Item");
10506
+ var Kbd = /* @__PURE__ */ __name(({ children, className }) => {
10507
+ const colors = useThemeColors();
10508
+ const isDark = useColorScheme() === "dark";
10509
+ const bgColor = isDark ? colors.color.neutral["800"] : colors.color.neutral["100"];
10510
+ const borderColor = isDark ? colors.color.neutral["600"] : colors.color.neutral["300"];
10511
+ const textColor = isDark ? colors.color.neutral["200"] : colors.color.neutral["700"];
10512
+ const containerStyle = {
10513
+ display: "flex",
10514
+ flexDirection: "row",
10515
+ alignItems: "center",
10516
+ justifyContent: "center",
10517
+ alignSelf: "center",
10518
+ backgroundColor: bgColor,
10519
+ borderWidth: 1,
10520
+ borderColor,
10521
+ borderRadius: px(colors.radius.sm),
10522
+ paddingHorizontal: px(colors.spacing["1"]),
10523
+ paddingVertical: 2,
10524
+ // Subtle bottom shadow gives the classic key look.
10525
+ ...reactNative.Platform.OS === "web" ? {
10526
+ boxShadow: `0 1px 0 ${borderColor}`,
10527
+ display: "inline-flex"
10528
+ } : {}
10529
+ };
10530
+ const textStyle = {
10531
+ color: textColor,
10532
+ // Monospace font for key labels.
10533
+ fontFamily: colors.fontFamily.mono ?? "monospace",
10534
+ fontSize: px(colors.fontSize.xs),
10535
+ fontWeight: colors.fontWeight.medium,
10536
+ lineHeight: px(colors.fontSize.xs) * Number(colors.lineHeight.normal)
10537
+ };
10538
+ const extraWebProps = reactNative.Platform.OS === "web" ? {
10539
+ // rn-web: 'none' skips the role attribute so the outer
10540
+ // View is just a plain <div>; we rely on the inner
10541
+ // <span> with data-kbd for semantic annotation.
10542
+ accessibilityRole: "none"
10543
+ } : {};
10544
+ return /* @__PURE__ */ jsxRuntime.jsx(
10545
+ reactNative.View,
10546
+ {
10547
+ ...extraWebProps,
10548
+ className: cn(
10549
+ "inline-flex flex-row items-center rounded-sm border px-1 py-0.5",
10550
+ isDark ? "bg-neutral-800 border-neutral-600 text-neutral-200" : "bg-neutral-100 border-neutral-300 text-neutral-700",
10551
+ className
10552
+ ),
10553
+ style: containerStyle,
10554
+ children: /* @__PURE__ */ jsxRuntime.jsx(
10555
+ reactNative.Text,
10556
+ {
10557
+ ...reactNative.Platform.OS === "web" ? { "data-kbd": "" } : {},
10558
+ accessibilityRole: "none",
10559
+ style: textStyle,
10560
+ children
10561
+ }
10562
+ )
10563
+ }
10564
+ );
10565
+ }, "Kbd");
9476
10566
  var Label = /* @__PURE__ */ __name(({ htmlFor, required = false, disabled = false, children, className, testID }) => {
9477
10567
  const colors = useThemeColors();
9478
10568
  const { t } = useTranslation();
@@ -13625,14 +14715,18 @@ __name(Icon, "Icon");
13625
14715
  exports.Accordion = Accordion;
13626
14716
  exports.Alert = Alert;
13627
14717
  exports.AlertDialog = AlertDialog;
14718
+ exports.AspectRatio = AspectRatio;
13628
14719
  exports.Avatar = Avatar;
13629
14720
  exports.Badge = Badge;
13630
14721
  exports.Box = Box;
13631
14722
  exports.Breadcrumb = Breadcrumb;
13632
14723
  exports.Button = Button;
14724
+ exports.ButtonGroup = ButtonGroup;
13633
14725
  exports.Calendar = Calendar;
13634
14726
  exports.Card = Card;
14727
+ exports.Carousel = Carousel;
13635
14728
  exports.Checkbox = Checkbox;
14729
+ exports.Collapsible = Collapsible;
13636
14730
  exports.Combobox = Combobox;
13637
14731
  exports.ContextMenu = ContextMenu;
13638
14732
  exports.DataTable = DataTable;
@@ -13640,11 +14734,16 @@ exports.DatePicker = DatePicker;
13640
14734
  exports.Dialog = Dialog;
13641
14735
  exports.Drawer = Drawer;
13642
14736
  exports.DropdownMenu = DropdownMenu;
14737
+ exports.Empty = Empty;
13643
14738
  exports.Field = Field;
13644
14739
  exports.FloatButton = FloatButton;
13645
14740
  exports.HStack = HStack;
14741
+ exports.HoverCard = HoverCard;
13646
14742
  exports.Icon = Icon;
13647
14743
  exports.InputGroup = InputGroup;
14744
+ exports.InputOTP = InputOTP;
14745
+ exports.Item = Item;
14746
+ exports.Kbd = Kbd;
13648
14747
  exports.Label = Label;
13649
14748
  exports.MenuContent = MenuContent;
13650
14749
  exports.MenuItem = MenuItem;