@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/client.cjs CHANGED
@@ -1805,6 +1805,24 @@ var AlertDialog = Object.assign(AlertDialogRoot, {
1805
1805
  Action: AlertDialogAction,
1806
1806
  Cancel: AlertDialogCancel
1807
1807
  });
1808
+ var BASE_STYLE = {
1809
+ overflow: "hidden"
1810
+ };
1811
+ var AspectRatio = /* @__PURE__ */ __name(({ ratio, children, className, testID }) => {
1812
+ const containerStyle = {
1813
+ ...BASE_STYLE,
1814
+ aspectRatio: ratio
1815
+ };
1816
+ return /* @__PURE__ */ jsxRuntime.jsx(
1817
+ reactNative.View,
1818
+ {
1819
+ ...testID !== void 0 ? { testID } : {},
1820
+ className: cn("overflow-hidden", className),
1821
+ style: containerStyle,
1822
+ children
1823
+ }
1824
+ );
1825
+ }, "AspectRatio");
1808
1826
  var SIZE_PX = {
1809
1827
  sm: 32,
1810
1828
  md: 40,
@@ -3530,7 +3548,7 @@ var SIZE_KEYS = {
3530
3548
  md: { padX: "4", font: "md" },
3531
3549
  lg: { padX: "5", font: "lg" }
3532
3550
  };
3533
- var BASE_STYLE = {
3551
+ var BASE_STYLE2 = {
3534
3552
  flexDirection: "row",
3535
3553
  alignItems: "center",
3536
3554
  justifyContent: "center"
@@ -3621,7 +3639,7 @@ var Button = /* @__PURE__ */ __name(({
3621
3639
  };
3622
3640
  const sizeFontSize = px(colors.fontSize[sizeKeys.font]);
3623
3641
  const inlineBase = [
3624
- BASE_STYLE,
3642
+ BASE_STYLE2,
3625
3643
  { backgroundColor: stateBg },
3626
3644
  sizeContainer,
3627
3645
  { opacity: isInoperative ? 0.6 : stateInteractionOpacity }
@@ -3701,6 +3719,39 @@ var Button = /* @__PURE__ */ __name(({
3701
3719
  }
3702
3720
  );
3703
3721
  }, "Button");
3722
+ var ButtonGroup = /* @__PURE__ */ __name(({ children, orientation = "horizontal", size, className, testID }) => {
3723
+ const isHorizontal = orientation === "horizontal";
3724
+ const containerStyle = {
3725
+ flexDirection: isHorizontal ? "row" : "column",
3726
+ // gap: 0 so buttons touch; shared-border effect comes from CSS on web
3727
+ // and from touching edges on native.
3728
+ gap: 0,
3729
+ alignSelf: "flex-start",
3730
+ overflow: "hidden"
3731
+ };
3732
+ const childArray = React.Children.toArray(children).filter(React.isValidElement);
3733
+ const total = childArray.length;
3734
+ const clonedChildren = childArray.map((child, index) => {
3735
+ const position = index === 0 ? "first" : index === total - 1 ? "last" : "middle";
3736
+ const extraProps = {
3737
+ "data-position": position,
3738
+ "data-group-orientation": orientation
3739
+ };
3740
+ if (size !== void 0) {
3741
+ extraProps["data-group-size"] = size;
3742
+ }
3743
+ return React.cloneElement(child, extraProps);
3744
+ });
3745
+ return /* @__PURE__ */ jsxRuntime.jsx(
3746
+ reactNative.View,
3747
+ {
3748
+ ...testID !== void 0 ? { testID } : {},
3749
+ className: cn(isHorizontal ? "flex-row" : "flex-col", "self-start overflow-hidden", className),
3750
+ style: containerStyle,
3751
+ children: clonedChildren
3752
+ }
3753
+ );
3754
+ }, "ButtonGroup");
3704
3755
 
3705
3756
  // src/components/Calendar/scroll/ScrollBody.tsx
3706
3757
  var ScrollBody = /* @__PURE__ */ __name((_props) => {
@@ -6468,6 +6519,254 @@ var Card = Object.assign(CardRoot, {
6468
6519
  Content: CardContent,
6469
6520
  Footer: CardFooter
6470
6521
  });
6522
+ var CarouselContext = React.createContext(null);
6523
+ function useCarouselContext(caller) {
6524
+ const ctx = React.useContext(CarouselContext);
6525
+ if (!ctx) {
6526
+ throw new Error(`<${caller}> must be rendered inside <Carousel>.`);
6527
+ }
6528
+ return ctx;
6529
+ }
6530
+ __name(useCarouselContext, "useCarouselContext");
6531
+ var CarouselRoot = /* @__PURE__ */ __name(({
6532
+ index: controlledIndex,
6533
+ defaultIndex = 0,
6534
+ onIndexChange,
6535
+ loop = false,
6536
+ orientation = "horizontal",
6537
+ children,
6538
+ className,
6539
+ testID
6540
+ }) => {
6541
+ const [inner, setInner] = React.useState(defaultIndex);
6542
+ const isControlled = controlledIndex !== void 0;
6543
+ const index = isControlled ? controlledIndex : inner;
6544
+ const [count, setCount] = React.useState(0);
6545
+ const listRef = React.useRef(null);
6546
+ const id = React.useId();
6547
+ const setIndex = React.useCallback(
6548
+ (next2) => {
6549
+ if (!isControlled) {
6550
+ setInner(next2);
6551
+ }
6552
+ onIndexChange?.(next2);
6553
+ },
6554
+ [isControlled, onIndexChange]
6555
+ );
6556
+ const scrollTo = React.useCallback(
6557
+ (idx) => {
6558
+ const list = listRef.current;
6559
+ if (!list) {
6560
+ return;
6561
+ }
6562
+ const item = list.children[idx];
6563
+ if (!item) {
6564
+ return;
6565
+ }
6566
+ item.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "nearest" });
6567
+ setIndex(idx);
6568
+ },
6569
+ [setIndex]
6570
+ );
6571
+ const next = React.useCallback(() => {
6572
+ if (count === 0) {
6573
+ return;
6574
+ }
6575
+ if (index < count - 1) {
6576
+ scrollTo(index + 1);
6577
+ } else if (loop) {
6578
+ scrollTo(0);
6579
+ }
6580
+ }, [index, count, loop, scrollTo]);
6581
+ const prev = React.useCallback(() => {
6582
+ if (count === 0) {
6583
+ return;
6584
+ }
6585
+ if (index > 0) {
6586
+ scrollTo(index - 1);
6587
+ } else if (loop) {
6588
+ scrollTo(count - 1);
6589
+ }
6590
+ }, [index, count, loop, scrollTo]);
6591
+ React.useEffect(() => {
6592
+ const list = listRef.current;
6593
+ if (!list) {
6594
+ return;
6595
+ }
6596
+ const handleScroll = /* @__PURE__ */ __name(() => {
6597
+ const { scrollLeft, scrollTop, offsetWidth, offsetHeight } = list;
6598
+ const pos = orientation === "horizontal" ? scrollLeft : scrollTop;
6599
+ const size = orientation === "horizontal" ? offsetWidth : offsetHeight;
6600
+ if (size === 0) {
6601
+ return;
6602
+ }
6603
+ const newIdx = Math.round(pos / size);
6604
+ if (newIdx !== index) {
6605
+ setIndex(newIdx);
6606
+ }
6607
+ }, "handleScroll");
6608
+ list.addEventListener("scroll", handleScroll, { passive: true });
6609
+ return () => list.removeEventListener("scroll", handleScroll);
6610
+ }, [orientation, index, setIndex]);
6611
+ return /* @__PURE__ */ jsxRuntime.jsx(
6612
+ CarouselContext.Provider,
6613
+ {
6614
+ value: { index, count, loop, orientation, scrollTo, next, prev, listRef, setCount, id },
6615
+ children: /* @__PURE__ */ jsxRuntime.jsx(
6616
+ "section",
6617
+ {
6618
+ "aria-label": testID ?? "Carousel",
6619
+ className: cn("relative overflow-hidden", className),
6620
+ "data-testid": testID,
6621
+ children
6622
+ }
6623
+ )
6624
+ }
6625
+ );
6626
+ }, "CarouselRoot");
6627
+ var CarouselContent = /* @__PURE__ */ __name(({ children, className, testID }) => {
6628
+ const ctx = useCarouselContext("Carousel.Content");
6629
+ const childCount = React.Children.count(children);
6630
+ React.useEffect(() => {
6631
+ ctx.setCount(childCount);
6632
+ }, [childCount, ctx.setCount]);
6633
+ const isHorizontal = ctx.orientation === "horizontal";
6634
+ return /* @__PURE__ */ jsxRuntime.jsx(
6635
+ "div",
6636
+ {
6637
+ ref: ctx.listRef,
6638
+ "data-testid": testID,
6639
+ className: cn(
6640
+ "flex",
6641
+ isHorizontal ? "flex-row overflow-x-auto overflow-y-hidden" : "flex-col overflow-y-auto overflow-x-hidden",
6642
+ className
6643
+ ),
6644
+ style: {
6645
+ scrollSnapType: isHorizontal ? "x mandatory" : "y mandatory",
6646
+ scrollBehavior: "smooth",
6647
+ WebkitOverflowScrolling: "touch",
6648
+ // Hide scrollbar
6649
+ scrollbarWidth: "none",
6650
+ msOverflowStyle: "none"
6651
+ },
6652
+ children
6653
+ }
6654
+ );
6655
+ }, "CarouselContent");
6656
+ var CarouselItem = /* @__PURE__ */ __name(({ children, className, testID }) => {
6657
+ const ctx = useCarouselContext("Carousel.Item");
6658
+ const isHorizontal = ctx.orientation === "horizontal";
6659
+ return /* @__PURE__ */ jsxRuntime.jsx(
6660
+ "div",
6661
+ {
6662
+ "data-testid": testID,
6663
+ className: cn("shrink-0", isHorizontal ? "w-full" : "h-full", className),
6664
+ style: {
6665
+ scrollSnapAlign: "start",
6666
+ minWidth: isHorizontal ? "100%" : void 0,
6667
+ minHeight: !isHorizontal ? "100%" : void 0
6668
+ },
6669
+ children
6670
+ }
6671
+ );
6672
+ }, "CarouselItem");
6673
+ var CarouselPrevious = /* @__PURE__ */ __name(({ className, testID, children }) => {
6674
+ const ctx = useCarouselContext("Carousel.Previous");
6675
+ const disabled = !ctx.loop && ctx.index === 0;
6676
+ return /* @__PURE__ */ jsxRuntime.jsx(
6677
+ "button",
6678
+ {
6679
+ type: "button",
6680
+ "aria-label": "Previous slide",
6681
+ disabled,
6682
+ "data-testid": testID,
6683
+ onClick: ctx.prev,
6684
+ className: cn(
6685
+ "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",
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: "M15 18l-6-6 6-6", strokeLinecap: "round", strokeLinejoin: "round" })
6698
+ }
6699
+ )
6700
+ }
6701
+ );
6702
+ }, "CarouselPrevious");
6703
+ var CarouselNext = /* @__PURE__ */ __name(({ className, testID, children }) => {
6704
+ const ctx = useCarouselContext("Carousel.Next");
6705
+ const disabled = !ctx.loop && ctx.index >= ctx.count - 1;
6706
+ return /* @__PURE__ */ jsxRuntime.jsx(
6707
+ "button",
6708
+ {
6709
+ type: "button",
6710
+ "aria-label": "Next slide",
6711
+ disabled,
6712
+ "data-testid": testID,
6713
+ onClick: ctx.next,
6714
+ className: cn(
6715
+ "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",
6716
+ className
6717
+ ),
6718
+ children: children ?? /* @__PURE__ */ jsxRuntime.jsx(
6719
+ "svg",
6720
+ {
6721
+ viewBox: "0 0 24 24",
6722
+ fill: "none",
6723
+ stroke: "currentColor",
6724
+ strokeWidth: 2,
6725
+ className: "h-4 w-4",
6726
+ "aria-hidden": "true",
6727
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 18l6-6-6-6", strokeLinecap: "round", strokeLinejoin: "round" })
6728
+ }
6729
+ )
6730
+ }
6731
+ );
6732
+ }, "CarouselNext");
6733
+ var CarouselDots = /* @__PURE__ */ __name(({ className, testID }) => {
6734
+ const ctx = useCarouselContext("Carousel.Dots");
6735
+ if (ctx.count === 0) {
6736
+ return null;
6737
+ }
6738
+ return /* @__PURE__ */ jsxRuntime.jsx(
6739
+ "div",
6740
+ {
6741
+ role: "tablist",
6742
+ "aria-label": "Slide navigation",
6743
+ "data-testid": testID,
6744
+ className: cn("absolute bottom-3 left-0 right-0 flex items-center justify-center gap-1.5", className),
6745
+ children: Array.from({ length: ctx.count }, (_, i) => /* @__PURE__ */ jsxRuntime.jsx(
6746
+ "button",
6747
+ {
6748
+ type: "button",
6749
+ role: "tab",
6750
+ "aria-selected": i === ctx.index,
6751
+ "aria-label": `Go to slide ${i + 1}`,
6752
+ onClick: () => ctx.scrollTo(i),
6753
+ className: cn(
6754
+ "h-1.5 w-1.5 rounded-full transition-all",
6755
+ i === ctx.index ? "w-3 bg-white" : "bg-white/50 hover:bg-white/75"
6756
+ )
6757
+ },
6758
+ i
6759
+ ))
6760
+ }
6761
+ );
6762
+ }, "CarouselDots");
6763
+ var Carousel = Object.assign(CarouselRoot, {
6764
+ Content: CarouselContent,
6765
+ Item: CarouselItem,
6766
+ Previous: CarouselPrevious,
6767
+ Next: CarouselNext,
6768
+ Dots: CarouselDots
6769
+ });
6471
6770
  var ROW_LAYOUT_BASE = { flexDirection: "row", alignItems: "center" };
6472
6771
  var BOX_LAYOUT_BASE = {
6473
6772
  // 20×20 box — component-density literal — not from theme
@@ -6613,6 +6912,182 @@ var Checkbox = /* @__PURE__ */ __name(({
6613
6912
  }
6614
6913
  );
6615
6914
  }, "Checkbox");
6915
+ var CollapsibleContext = React.createContext(null);
6916
+ var useCollapsibleContext = /* @__PURE__ */ __name((label) => {
6917
+ const ctx = React.useContext(CollapsibleContext);
6918
+ if (!ctx) {
6919
+ throw new Error(`<${label}> must be rendered inside a <Collapsible>.`);
6920
+ }
6921
+ return ctx;
6922
+ }, "useCollapsibleContext");
6923
+ var CollapsibleRoot = /* @__PURE__ */ __name(({
6924
+ open: controlledOpen,
6925
+ defaultOpen = false,
6926
+ onOpenChange,
6927
+ children,
6928
+ className,
6929
+ testID
6930
+ }) => {
6931
+ const baseId = React.useId();
6932
+ const [innerOpen, setInnerOpen] = React.useState(defaultOpen);
6933
+ const isControlled = controlledOpen !== void 0;
6934
+ const open = isControlled ? controlledOpen : innerOpen;
6935
+ const toggle = React.useCallback(() => {
6936
+ const next = !open;
6937
+ if (!isControlled) {
6938
+ setInnerOpen(next);
6939
+ }
6940
+ onOpenChange?.(next);
6941
+ }, [open, isControlled, onOpenChange]);
6942
+ const ctx = React.useMemo(
6943
+ () => ({
6944
+ open,
6945
+ toggle,
6946
+ contentId: `${baseId}-content`,
6947
+ triggerId: `${baseId}-trigger`
6948
+ }),
6949
+ [open, toggle, baseId]
6950
+ );
6951
+ return /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContext.Provider, { value: ctx, children: /* @__PURE__ */ jsxRuntime.jsx(
6952
+ reactNative.View,
6953
+ {
6954
+ ...testID !== void 0 ? { testID } : {},
6955
+ className: cn("flex-col", className),
6956
+ style: { flexDirection: "column" },
6957
+ children
6958
+ }
6959
+ ) });
6960
+ }, "CollapsibleRoot");
6961
+ var CollapsibleTrigger = /* @__PURE__ */ __name(({ children, className, testID }) => {
6962
+ const { open, toggle, contentId, triggerId } = useCollapsibleContext("Collapsible.Trigger");
6963
+ const colors = useThemeColors();
6964
+ const triggerStyle = {
6965
+ flexDirection: "row",
6966
+ alignItems: "center",
6967
+ paddingVertical: px(colors.spacing["2"]),
6968
+ paddingHorizontal: px(colors.spacing["1"])
6969
+ };
6970
+ return /* @__PURE__ */ jsxRuntime.jsx(
6971
+ reactNative.Pressable,
6972
+ {
6973
+ id: triggerId,
6974
+ ...testID !== void 0 ? { testID } : {},
6975
+ role: "button",
6976
+ accessibilityRole: "button",
6977
+ "aria-expanded": open,
6978
+ "aria-controls": contentId,
6979
+ onPress: toggle,
6980
+ className: cn("flex-row items-center py-2 px-1", className),
6981
+ style: triggerStyle,
6982
+ children: typeof children === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
6983
+ reactNative.Text,
6984
+ {
6985
+ style: {
6986
+ color: colors.semantic.text.default,
6987
+ fontFamily: colors.fontFamily.body,
6988
+ fontSize: px(colors.fontSize.sm),
6989
+ fontWeight: colors.fontWeight.medium
6990
+ },
6991
+ children
6992
+ }
6993
+ ) : children
6994
+ }
6995
+ );
6996
+ }, "CollapsibleTrigger");
6997
+ var CollapsibleContent = /* @__PURE__ */ __name(({ children, className, testID }) => {
6998
+ const { open, contentId, triggerId } = useCollapsibleContext("Collapsible.Content");
6999
+ const wrapperRef = React.useRef(null);
7000
+ const innerRef = React.useRef(null);
7001
+ React.useEffect(() => {
7002
+ if (reactNative.Platform.OS !== "web") {
7003
+ return;
7004
+ }
7005
+ const wrapper = wrapperRef.current;
7006
+ const inner = innerRef.current;
7007
+ if (!wrapper || !inner) {
7008
+ return;
7009
+ }
7010
+ const isFirstPaint = wrapper.dataset.noriPainted !== "1";
7011
+ wrapper.dataset.noriPainted = "1";
7012
+ wrapper.style.overflow = "hidden";
7013
+ wrapper.style.transitionProperty = "max-height, opacity";
7014
+ wrapper.style.transitionDuration = "200ms";
7015
+ wrapper.style.transitionTimingFunction = "cubic-bezier(0.16, 1, 0.3, 1)";
7016
+ if (open) {
7017
+ const target = inner.scrollHeight;
7018
+ if (isFirstPaint) {
7019
+ wrapper.style.maxHeight = `${target}px`;
7020
+ wrapper.style.opacity = "1";
7021
+ return;
7022
+ }
7023
+ wrapper.style.maxHeight = "0px";
7024
+ wrapper.style.opacity = "0";
7025
+ void wrapper.offsetHeight;
7026
+ requestAnimationFrame(() => {
7027
+ wrapper.style.maxHeight = `${target}px`;
7028
+ wrapper.style.opacity = "1";
7029
+ });
7030
+ } else {
7031
+ if (isFirstPaint) {
7032
+ wrapper.style.maxHeight = "0px";
7033
+ wrapper.style.opacity = "0";
7034
+ return;
7035
+ }
7036
+ const current = inner.scrollHeight;
7037
+ wrapper.style.maxHeight = `${current}px`;
7038
+ wrapper.style.opacity = "1";
7039
+ void wrapper.offsetHeight;
7040
+ requestAnimationFrame(() => {
7041
+ wrapper.style.maxHeight = "0px";
7042
+ wrapper.style.opacity = "0";
7043
+ });
7044
+ }
7045
+ }, [open]);
7046
+ if (reactNative.Platform.OS !== "web") {
7047
+ if (!open) {
7048
+ return null;
7049
+ }
7050
+ return /* @__PURE__ */ jsxRuntime.jsx(
7051
+ reactNative.View,
7052
+ {
7053
+ ...testID !== void 0 ? { testID } : {},
7054
+ id: contentId,
7055
+ "aria-labelledby": triggerId,
7056
+ className: cn("flex-col", className),
7057
+ style: { flexDirection: "column" },
7058
+ children
7059
+ }
7060
+ );
7061
+ }
7062
+ return /* @__PURE__ */ jsxRuntime.jsx(
7063
+ reactNative.View,
7064
+ {
7065
+ ref: (node) => {
7066
+ wrapperRef.current = node;
7067
+ },
7068
+ ...testID !== void 0 ? { testID } : {},
7069
+ id: contentId,
7070
+ "aria-labelledby": triggerId,
7071
+ "aria-hidden": !open,
7072
+ className: cn("overflow-hidden", className),
7073
+ children: /* @__PURE__ */ jsxRuntime.jsx(
7074
+ reactNative.View,
7075
+ {
7076
+ ref: (node) => {
7077
+ innerRef.current = node;
7078
+ },
7079
+ className: "flex-col",
7080
+ style: { flexDirection: "column" },
7081
+ children
7082
+ }
7083
+ )
7084
+ }
7085
+ );
7086
+ }, "CollapsibleContent");
7087
+ var Collapsible = Object.assign(CollapsibleRoot, {
7088
+ Trigger: CollapsibleTrigger,
7089
+ Content: CollapsibleContent
7090
+ });
6616
7091
  var Combobox = /* @__PURE__ */ __name((props) => {
6617
7092
  return /* @__PURE__ */ jsxRuntime.jsx(Select, { searchable: true, ...props });
6618
7093
  }, "Combobox");
@@ -8211,11 +8686,60 @@ var Dialog = Object.assign(DialogRoot, {
8211
8686
  Footer: DialogFooter,
8212
8687
  Close: DialogClose
8213
8688
  });
8214
- var FieldContext = React.createContext(null);
8215
- var useFieldContextStrict = /* @__PURE__ */ __name((caller) => {
8216
- const ctx = React.useContext(FieldContext);
8217
- if (!ctx) {
8218
- throw new Error(`[Field] ${caller} must be used inside <Field> or <Field.Group>.`);
8689
+ var Empty = /* @__PURE__ */ __name(({ icon, title, description, action, className, testID }) => {
8690
+ const colors = useThemeColors();
8691
+ const containerStyle = {
8692
+ flexDirection: "column",
8693
+ alignItems: "center",
8694
+ justifyContent: "center",
8695
+ gap: px(colors.spacing["3"]),
8696
+ paddingVertical: px(colors.spacing["8"]),
8697
+ paddingHorizontal: px(colors.spacing["4"])
8698
+ };
8699
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8700
+ reactNative.View,
8701
+ {
8702
+ ...testID !== void 0 ? { testID } : {},
8703
+ className: cn("flex-col items-center justify-center gap-3 py-8 px-4", className),
8704
+ style: containerStyle,
8705
+ children: [
8706
+ icon != null ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { marginBottom: px(colors.spacing["1"]) }, children: icon }) : null,
8707
+ /* @__PURE__ */ jsxRuntime.jsx(
8708
+ reactNative.Text,
8709
+ {
8710
+ style: {
8711
+ color: colors.semantic.text.default,
8712
+ fontFamily: colors.fontFamily.body,
8713
+ fontSize: px(colors.fontSize.md),
8714
+ fontWeight: colors.fontWeight.semibold,
8715
+ textAlign: "center"
8716
+ },
8717
+ children: title
8718
+ }
8719
+ ),
8720
+ description != null ? /* @__PURE__ */ jsxRuntime.jsx(
8721
+ reactNative.Text,
8722
+ {
8723
+ style: {
8724
+ color: colors.semantic.text.muted,
8725
+ fontFamily: colors.fontFamily.body,
8726
+ fontSize: px(colors.fontSize.sm),
8727
+ lineHeight: px(colors.fontSize.sm) * Number(colors.lineHeight.normal),
8728
+ textAlign: "center"
8729
+ },
8730
+ children: description
8731
+ }
8732
+ ) : null,
8733
+ action != null ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { marginTop: px(colors.spacing["1"]) }, children: action }) : null
8734
+ ]
8735
+ }
8736
+ );
8737
+ }, "Empty");
8738
+ var FieldContext = React.createContext(null);
8739
+ var useFieldContextStrict = /* @__PURE__ */ __name((caller) => {
8740
+ const ctx = React.useContext(FieldContext);
8741
+ if (!ctx) {
8742
+ throw new Error(`[Field] ${caller} must be used inside <Field> or <Field.Group>.`);
8219
8743
  }
8220
8744
  return ctx;
8221
8745
  }, "useFieldContextStrict");
@@ -9122,6 +9646,161 @@ function withAlpha(color, alpha) {
9122
9646
  return color;
9123
9647
  }
9124
9648
  __name(withAlpha, "withAlpha");
9649
+ var HoverCardContext = React.createContext(null);
9650
+ function useHoverCardContext(caller) {
9651
+ const ctx = React.useContext(HoverCardContext);
9652
+ if (!ctx) {
9653
+ throw new Error(`<${caller}> must be rendered inside <HoverCard>.`);
9654
+ }
9655
+ return ctx;
9656
+ }
9657
+ __name(useHoverCardContext, "useHoverCardContext");
9658
+ var DEFAULT_OPEN_DELAY = 300;
9659
+ var DEFAULT_CLOSE_DELAY = 200;
9660
+ var HoverCardRoot = /* @__PURE__ */ __name(({
9661
+ open: controlledOpen,
9662
+ defaultOpen = false,
9663
+ onOpenChange,
9664
+ openDelay = DEFAULT_OPEN_DELAY,
9665
+ closeDelay = DEFAULT_CLOSE_DELAY,
9666
+ children
9667
+ }) => {
9668
+ const [inner, setInner] = React.useState(defaultOpen);
9669
+ const isControlled = controlledOpen !== void 0;
9670
+ const open = isControlled ? controlledOpen : inner;
9671
+ const id = React.useId();
9672
+ const setOpen = React.useCallback(
9673
+ (next) => {
9674
+ if (!isControlled) {
9675
+ setInner(next);
9676
+ }
9677
+ onOpenChange?.(next);
9678
+ },
9679
+ [isControlled, onOpenChange]
9680
+ );
9681
+ const openTimer = React.useRef(null);
9682
+ const closeTimer = React.useRef(null);
9683
+ const cancelTimers = React.useCallback(() => {
9684
+ if (openTimer.current) {
9685
+ clearTimeout(openTimer.current);
9686
+ openTimer.current = null;
9687
+ }
9688
+ if (closeTimer.current) {
9689
+ clearTimeout(closeTimer.current);
9690
+ closeTimer.current = null;
9691
+ }
9692
+ }, []);
9693
+ const requestOpen = React.useCallback(() => {
9694
+ if (closeTimer.current) {
9695
+ clearTimeout(closeTimer.current);
9696
+ closeTimer.current = null;
9697
+ }
9698
+ if (openTimer.current) {
9699
+ return;
9700
+ }
9701
+ if (openDelay <= 0) {
9702
+ setOpen(true);
9703
+ return;
9704
+ }
9705
+ openTimer.current = setTimeout(() => {
9706
+ openTimer.current = null;
9707
+ setOpen(true);
9708
+ }, openDelay);
9709
+ }, [openDelay, setOpen]);
9710
+ const requestClose = React.useCallback(() => {
9711
+ if (openTimer.current) {
9712
+ clearTimeout(openTimer.current);
9713
+ openTimer.current = null;
9714
+ }
9715
+ if (closeTimer.current) {
9716
+ return;
9717
+ }
9718
+ if (closeDelay <= 0) {
9719
+ setOpen(false);
9720
+ return;
9721
+ }
9722
+ closeTimer.current = setTimeout(() => {
9723
+ closeTimer.current = null;
9724
+ setOpen(false);
9725
+ }, closeDelay);
9726
+ }, [closeDelay, setOpen]);
9727
+ React.useEffect(() => () => cancelTimers(), [cancelTimers]);
9728
+ return /* @__PURE__ */ jsxRuntime.jsx(
9729
+ HoverCardContext.Provider,
9730
+ {
9731
+ value: { open, requestOpen, requestClose, cancelTimers, contentId: `hc-content-${id}` },
9732
+ children: /* @__PURE__ */ jsxRuntime.jsx(Popover, { open, onOpenChange: setOpen, children })
9733
+ }
9734
+ );
9735
+ }, "HoverCardRoot");
9736
+ var HoverCardTrigger = /* @__PURE__ */ __name(({ asChild = true, children, className, testID }) => {
9737
+ const ctx = useHoverCardContext("HoverCard.Trigger");
9738
+ const handleMouseEnter = React.useCallback(() => {
9739
+ ctx.cancelTimers();
9740
+ ctx.requestOpen();
9741
+ }, [ctx]);
9742
+ const handleMouseLeave = React.useCallback(() => {
9743
+ ctx.requestClose();
9744
+ }, [ctx]);
9745
+ const handlers = {
9746
+ onMouseEnter: handleMouseEnter,
9747
+ onMouseLeave: handleMouseLeave,
9748
+ "aria-haspopup": "dialog",
9749
+ "aria-expanded": ctx.open
9750
+ };
9751
+ if (asChild && React.isValidElement(children)) {
9752
+ const child = children;
9753
+ const compose = /* @__PURE__ */ __name((existing, next) => (event) => {
9754
+ existing?.(event);
9755
+ next(event);
9756
+ }, "compose");
9757
+ return /* @__PURE__ */ jsxRuntime.jsx(
9758
+ Slot,
9759
+ {
9760
+ ...handlers,
9761
+ onMouseEnter: compose(child.props.onMouseEnter, handleMouseEnter),
9762
+ onMouseLeave: compose(child.props.onMouseLeave, handleMouseLeave),
9763
+ ...className !== void 0 ? { className } : {},
9764
+ ...testID !== void 0 ? { "data-testid": testID } : {},
9765
+ children: child
9766
+ }
9767
+ );
9768
+ }
9769
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { ...handlers, className, ...testID !== void 0 ? { "data-testid": testID } : {}, children });
9770
+ }, "HoverCardTrigger");
9771
+ var HoverCardContent = /* @__PURE__ */ __name(({ side = "bottom", align = "start", children, className, testID }) => {
9772
+ const ctx = useHoverCardContext("HoverCard.Content");
9773
+ const handleMouseEnter = React.useCallback(() => {
9774
+ ctx.cancelTimers();
9775
+ }, [ctx]);
9776
+ const handleMouseLeave = React.useCallback(() => {
9777
+ ctx.requestClose();
9778
+ }, [ctx]);
9779
+ return /* @__PURE__ */ jsxRuntime.jsx(
9780
+ Popover.Content,
9781
+ {
9782
+ side,
9783
+ align,
9784
+ ...className !== void 0 ? { className } : {},
9785
+ ...testID !== void 0 ? { testID } : {},
9786
+ children: /* @__PURE__ */ jsxRuntime.jsx(
9787
+ "div",
9788
+ {
9789
+ id: ctx.contentId,
9790
+ role: "dialog",
9791
+ "aria-label": "Hover card",
9792
+ onMouseEnter: handleMouseEnter,
9793
+ onMouseLeave: handleMouseLeave,
9794
+ children
9795
+ }
9796
+ )
9797
+ }
9798
+ );
9799
+ }, "HoverCardContent");
9800
+ var HoverCard = Object.assign(HoverCardRoot, {
9801
+ Trigger: HoverCardTrigger,
9802
+ Content: HoverCardContent
9803
+ });
9125
9804
  var ALIGN_CLASS = {
9126
9805
  start: "items-start",
9127
9806
  center: "items-center",
@@ -9494,6 +10173,417 @@ var InputGroup = Object.assign(InputGroupRoot, {
9494
10173
  Addon: InputGroupAddon,
9495
10174
  Input: InputGroupInput
9496
10175
  });
10176
+ function isAllowed(char, pattern) {
10177
+ if (pattern === "numeric") {
10178
+ return /^\d$/.test(char);
10179
+ }
10180
+ return /^[a-zA-Z0-9]$/.test(char);
10181
+ }
10182
+ __name(isAllowed, "isAllowed");
10183
+ function filterValue(value, pattern, length) {
10184
+ return value.split("").filter((c) => isAllowed(c, pattern)).slice(0, length).join("");
10185
+ }
10186
+ __name(filterValue, "filterValue");
10187
+ var InputOTP = /* @__PURE__ */ __name(({
10188
+ value = "",
10189
+ onChange,
10190
+ onComplete,
10191
+ length = 6,
10192
+ placeholder = "\xB7",
10193
+ pattern = "numeric",
10194
+ disabled = false,
10195
+ autoFocus = false,
10196
+ id,
10197
+ name,
10198
+ "aria-label": ariaLabel = "One-time code",
10199
+ "aria-labelledby": ariaLabelledBy,
10200
+ "aria-describedby": ariaDescribedBy,
10201
+ "aria-invalid": ariaInvalid,
10202
+ className,
10203
+ testID
10204
+ }) => {
10205
+ const colors = useThemeColors();
10206
+ const [cells, setCells] = React.useState(() => {
10207
+ const filtered = filterValue(value, pattern, length);
10208
+ return Array.from({ length }, (_, i) => filtered[i] ?? "");
10209
+ });
10210
+ const prevValue = React.useRef(value);
10211
+ React.useEffect(() => {
10212
+ if (value !== prevValue.current) {
10213
+ prevValue.current = value;
10214
+ const filtered = filterValue(value, pattern, length);
10215
+ setCells(Array.from({ length }, (_, i) => filtered[i] ?? ""));
10216
+ }
10217
+ }, [value, pattern, length]);
10218
+ const inputRefs = React.useRef([]);
10219
+ const focusCell = React.useCallback(
10220
+ (idx) => {
10221
+ if (idx >= 0 && idx < length) {
10222
+ inputRefs.current[idx]?.focus();
10223
+ }
10224
+ },
10225
+ [length]
10226
+ );
10227
+ const updateCells = React.useCallback(
10228
+ (next) => {
10229
+ setCells(next);
10230
+ const joined = next.join("");
10231
+ onChange?.(joined);
10232
+ if (joined.length === length && !next.includes("")) {
10233
+ onComplete?.(joined);
10234
+ }
10235
+ },
10236
+ [onChange, onComplete, length]
10237
+ );
10238
+ const onContainerPaste = React.useCallback(
10239
+ (e) => {
10240
+ e.preventDefault();
10241
+ const text = e.clipboardData.getData("text/plain") ?? "";
10242
+ const filtered = filterValue(text, pattern, length);
10243
+ const next = Array.from({ length }, (_, i) => filtered[i] ?? "");
10244
+ updateCells(next);
10245
+ const nextEmpty = next.indexOf("");
10246
+ focusCell(nextEmpty === -1 ? length - 1 : nextEmpty);
10247
+ },
10248
+ [pattern, length, updateCells, focusCell]
10249
+ );
10250
+ const handleChangeText = React.useCallback(
10251
+ (text, idx) => {
10252
+ if (text.length > 1) {
10253
+ const filtered = filterValue(text, pattern, length);
10254
+ const next2 = Array.from({ length }, (_, i) => filtered[i] ?? "");
10255
+ updateCells(next2);
10256
+ const nextEmpty = next2.indexOf("");
10257
+ focusCell(nextEmpty === -1 ? length - 1 : nextEmpty);
10258
+ return;
10259
+ }
10260
+ const char = text.slice(-1);
10261
+ if (char && !isAllowed(char, pattern)) {
10262
+ return;
10263
+ }
10264
+ const next = [...cells];
10265
+ next[idx] = char;
10266
+ updateCells(next);
10267
+ if (char) {
10268
+ focusCell(idx + 1);
10269
+ }
10270
+ },
10271
+ [cells, pattern, length, updateCells, focusCell]
10272
+ );
10273
+ const handleWebKeyDown = React.useCallback(
10274
+ (e, idx) => {
10275
+ if (e.key === "Backspace") {
10276
+ if (cells[idx] !== "") {
10277
+ const next = [...cells];
10278
+ next[idx] = "";
10279
+ updateCells(next);
10280
+ } else {
10281
+ focusCell(idx - 1);
10282
+ }
10283
+ e.preventDefault();
10284
+ } else if (e.key === "ArrowLeft") {
10285
+ focusCell(idx - 1);
10286
+ e.preventDefault();
10287
+ } else if (e.key === "ArrowRight") {
10288
+ focusCell(idx + 1);
10289
+ e.preventDefault();
10290
+ } else if (e.key.length === 1 && isAllowed(e.key, pattern)) {
10291
+ const next = [...cells];
10292
+ next[idx] = e.key;
10293
+ updateCells(next);
10294
+ focusCell(idx + 1);
10295
+ e.preventDefault();
10296
+ }
10297
+ },
10298
+ [cells, pattern, focusCell, updateCells]
10299
+ );
10300
+ const handleNativeKeyPress = React.useCallback(
10301
+ (e, idx) => {
10302
+ if (e.nativeEvent.key === "Backspace") {
10303
+ if (cells[idx] !== "") {
10304
+ const next = [...cells];
10305
+ next[idx] = "";
10306
+ updateCells(next);
10307
+ } else {
10308
+ focusCell(idx - 1);
10309
+ }
10310
+ }
10311
+ },
10312
+ [cells, focusCell, updateCells]
10313
+ );
10314
+ const cellStyle = [
10315
+ styles2.cell,
10316
+ {
10317
+ width: px(48),
10318
+ height: px(56),
10319
+ borderRadius: px(colors.radius.md),
10320
+ borderColor: colors.semantic.border.default,
10321
+ backgroundColor: colors.semantic.background.elevated,
10322
+ color: colors.semantic.text.default,
10323
+ fontSize: px(colors.fontSize.xl),
10324
+ fontFamily: colors.fontFamily.body
10325
+ },
10326
+ disabled ? styles2.disabled : null,
10327
+ ariaInvalid === true || ariaInvalid === "true" ? { borderColor: colors.color.danger } : null
10328
+ ];
10329
+ const isWeb3 = reactNative.Platform.OS === "web";
10330
+ const containerProps = isWeb3 ? {
10331
+ onPaste: onContainerPaste,
10332
+ role: "group",
10333
+ "aria-label": ariaLabel,
10334
+ "aria-labelledby": ariaLabelledBy,
10335
+ "aria-describedby": ariaDescribedBy
10336
+ } : {};
10337
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10338
+ reactNative.View,
10339
+ {
10340
+ testID,
10341
+ ...isWeb3 ? {} : { accessible: true, accessibilityLabel: ariaLabel },
10342
+ ...containerProps,
10343
+ className: cn("flex-row items-center gap-2", className),
10344
+ style: styles2.container,
10345
+ children: [
10346
+ Array.from({ length }, (_, idx) => {
10347
+ const cellValue = cells[idx] ?? "";
10348
+ const cellRef = /* @__PURE__ */ __name((el) => {
10349
+ inputRefs.current[idx] = el;
10350
+ }, "cellRef");
10351
+ const webProps = isWeb3 ? {
10352
+ onKeyDown: /* @__PURE__ */ __name((e) => handleWebKeyDown(e, idx), "onKeyDown"),
10353
+ // id only on the first cell
10354
+ ...idx === 0 && id ? { id, nativeID: id } : {},
10355
+ ...idx === 0 && name ? { name } : {},
10356
+ ...idx === 0 && ariaLabelledBy ? { "aria-labelledby": ariaLabelledBy } : {},
10357
+ ...idx === 0 && ariaDescribedBy ? { "aria-describedby": ariaDescribedBy } : {},
10358
+ ...idx === 0 && ariaInvalid !== void 0 ? { "aria-invalid": ariaInvalid } : {},
10359
+ inputMode: pattern === "numeric" ? "numeric" : "text"
10360
+ } : {};
10361
+ const nativeOnlyProps = isWeb3 ? {} : {
10362
+ keyboardType: pattern === "numeric" ? "number-pad" : "default",
10363
+ textAlign: "center",
10364
+ selectTextOnFocus: true,
10365
+ onKeyPress: /* @__PURE__ */ __name((e) => handleNativeKeyPress(e, idx), "onKeyPress")
10366
+ };
10367
+ return /* @__PURE__ */ jsxRuntime.jsx(
10368
+ reactNative.TextInput,
10369
+ {
10370
+ ref: cellRef,
10371
+ value: cellValue,
10372
+ placeholder: placeholder,
10373
+ maxLength: 1,
10374
+ editable: !disabled,
10375
+ autoFocus: autoFocus && idx === 0,
10376
+ testID: testID ? `${testID}-cell-${idx}` : void 0,
10377
+ onChangeText: (text) => handleChangeText(text, idx),
10378
+ accessibilityLabel: `Digit ${idx + 1} of ${length}`,
10379
+ ...nativeOnlyProps,
10380
+ ...webProps,
10381
+ style: cellStyle
10382
+ },
10383
+ idx
10384
+ );
10385
+ }),
10386
+ isWeb3 && name ? /* @__PURE__ */ jsxRuntime.jsx(
10387
+ reactNative.TextInput,
10388
+ {
10389
+ style: styles2.hidden,
10390
+ value: cells.join(""),
10391
+ "aria-hidden": true,
10392
+ tabIndex: -1,
10393
+ ...{ name }
10394
+ }
10395
+ ) : null
10396
+ ]
10397
+ }
10398
+ );
10399
+ }, "InputOTP");
10400
+ var styles2 = reactNative.StyleSheet.create({
10401
+ container: {
10402
+ flexDirection: "row",
10403
+ alignItems: "center",
10404
+ gap: 8
10405
+ },
10406
+ cell: {
10407
+ borderWidth: 1,
10408
+ textAlign: "center"
10409
+ },
10410
+ disabled: {
10411
+ opacity: 0.6
10412
+ },
10413
+ hidden: {
10414
+ position: "absolute",
10415
+ width: 0,
10416
+ height: 0,
10417
+ opacity: 0
10418
+ }
10419
+ });
10420
+ var Item = /* @__PURE__ */ __name(({
10421
+ leading,
10422
+ title,
10423
+ description,
10424
+ trailing,
10425
+ chevron = false,
10426
+ onPress,
10427
+ disabled = false,
10428
+ className,
10429
+ testID
10430
+ }) => {
10431
+ const colors = useThemeColors();
10432
+ const isTappable = onPress !== void 0;
10433
+ const rowStyle = {
10434
+ flexDirection: "row",
10435
+ alignItems: "center",
10436
+ gap: px(colors.spacing["3"]),
10437
+ paddingVertical: px(colors.spacing["3"]),
10438
+ paddingHorizontal: px(colors.spacing["4"]),
10439
+ minHeight: 52,
10440
+ opacity: disabled ? 0.5 : 1
10441
+ };
10442
+ const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10443
+ leading != null ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { flexShrink: 0 }, children: leading }) : null,
10444
+ /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: { flex: 1, flexDirection: "column", gap: 2 }, children: [
10445
+ typeof title === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
10446
+ reactNative.Text,
10447
+ {
10448
+ style: {
10449
+ color: colors.semantic.text.default,
10450
+ fontFamily: colors.fontFamily.body,
10451
+ fontSize: px(colors.fontSize.sm),
10452
+ fontWeight: colors.fontWeight.medium
10453
+ },
10454
+ numberOfLines: 1,
10455
+ children: title
10456
+ }
10457
+ ) : title,
10458
+ description != null ? typeof description === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
10459
+ reactNative.Text,
10460
+ {
10461
+ style: {
10462
+ color: colors.semantic.text.muted,
10463
+ fontFamily: colors.fontFamily.body,
10464
+ fontSize: px(colors.fontSize.xs)
10465
+ },
10466
+ numberOfLines: 1,
10467
+ children: description
10468
+ }
10469
+ ) : description : null
10470
+ ] }),
10471
+ trailing != null ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { flexShrink: 0 }, children: trailing }) : null,
10472
+ chevron ? /* @__PURE__ */ jsxRuntime.jsx(
10473
+ reactNative.View,
10474
+ {
10475
+ style: { flexShrink: 0 },
10476
+ "aria-hidden": true,
10477
+ testID: testID != null ? `${testID}-chevron` : void 0,
10478
+ children: /* @__PURE__ */ jsxRuntime.jsx(
10479
+ reactNative.Text,
10480
+ {
10481
+ accessibilityElementsHidden: true,
10482
+ importantForAccessibility: "no-hide-descendants",
10483
+ style: {
10484
+ fontSize: 14,
10485
+ lineHeight: 16,
10486
+ color: colors.semantic.text.muted,
10487
+ // On web rn-web passes style through — transform
10488
+ // with a rotate is the lightest-weight approach
10489
+ // that avoids importing the full SVG icon set.
10490
+ transform: [{ rotate: "-90deg" }]
10491
+ },
10492
+ children: "\u2304"
10493
+ }
10494
+ )
10495
+ }
10496
+ ) : null
10497
+ ] });
10498
+ if (isTappable) {
10499
+ return /* @__PURE__ */ jsxRuntime.jsx(
10500
+ reactNative.Pressable,
10501
+ {
10502
+ ...testID !== void 0 ? { testID } : {},
10503
+ role: "button",
10504
+ accessibilityRole: "button",
10505
+ disabled,
10506
+ onPress: disabled ? void 0 : onPress,
10507
+ className: cn(
10508
+ "flex-row items-center",
10509
+ disabled ? "opacity-50" : "hover:bg-semantic-background-subtle active:bg-semantic-border-default",
10510
+ className
10511
+ ),
10512
+ style: rowStyle,
10513
+ children: content
10514
+ }
10515
+ );
10516
+ }
10517
+ return /* @__PURE__ */ jsxRuntime.jsx(
10518
+ reactNative.View,
10519
+ {
10520
+ ...testID !== void 0 ? { testID } : {},
10521
+ className: cn("flex-row items-center", className),
10522
+ style: rowStyle,
10523
+ children: content
10524
+ }
10525
+ );
10526
+ }, "Item");
10527
+ var Kbd = /* @__PURE__ */ __name(({ children, className }) => {
10528
+ const colors = useThemeColors();
10529
+ const isDark = useColorScheme() === "dark";
10530
+ const bgColor = isDark ? colors.color.neutral["800"] : colors.color.neutral["100"];
10531
+ const borderColor = isDark ? colors.color.neutral["600"] : colors.color.neutral["300"];
10532
+ const textColor = isDark ? colors.color.neutral["200"] : colors.color.neutral["700"];
10533
+ const containerStyle = {
10534
+ display: "flex",
10535
+ flexDirection: "row",
10536
+ alignItems: "center",
10537
+ justifyContent: "center",
10538
+ alignSelf: "center",
10539
+ backgroundColor: bgColor,
10540
+ borderWidth: 1,
10541
+ borderColor,
10542
+ borderRadius: px(colors.radius.sm),
10543
+ paddingHorizontal: px(colors.spacing["1"]),
10544
+ paddingVertical: 2,
10545
+ // Subtle bottom shadow gives the classic key look.
10546
+ ...reactNative.Platform.OS === "web" ? {
10547
+ boxShadow: `0 1px 0 ${borderColor}`,
10548
+ display: "inline-flex"
10549
+ } : {}
10550
+ };
10551
+ const textStyle = {
10552
+ color: textColor,
10553
+ // Monospace font for key labels.
10554
+ fontFamily: colors.fontFamily.mono ?? "monospace",
10555
+ fontSize: px(colors.fontSize.xs),
10556
+ fontWeight: colors.fontWeight.medium,
10557
+ lineHeight: px(colors.fontSize.xs) * Number(colors.lineHeight.normal)
10558
+ };
10559
+ const extraWebProps = reactNative.Platform.OS === "web" ? {
10560
+ // rn-web: 'none' skips the role attribute so the outer
10561
+ // View is just a plain <div>; we rely on the inner
10562
+ // <span> with data-kbd for semantic annotation.
10563
+ accessibilityRole: "none"
10564
+ } : {};
10565
+ return /* @__PURE__ */ jsxRuntime.jsx(
10566
+ reactNative.View,
10567
+ {
10568
+ ...extraWebProps,
10569
+ className: cn(
10570
+ "inline-flex flex-row items-center rounded-sm border px-1 py-0.5",
10571
+ isDark ? "bg-neutral-800 border-neutral-600 text-neutral-200" : "bg-neutral-100 border-neutral-300 text-neutral-700",
10572
+ className
10573
+ ),
10574
+ style: containerStyle,
10575
+ children: /* @__PURE__ */ jsxRuntime.jsx(
10576
+ reactNative.Text,
10577
+ {
10578
+ ...reactNative.Platform.OS === "web" ? { "data-kbd": "" } : {},
10579
+ accessibilityRole: "none",
10580
+ style: textStyle,
10581
+ children
10582
+ }
10583
+ )
10584
+ }
10585
+ );
10586
+ }, "Kbd");
9497
10587
  var Label = /* @__PURE__ */ __name(({ htmlFor, required = false, disabled = false, children, className, testID }) => {
9498
10588
  const colors = useThemeColors();
9499
10589
  const { t } = useTranslation();
@@ -13783,14 +14873,18 @@ __name(NoriProvider, "NoriProvider");
13783
14873
  exports.Accordion = Accordion;
13784
14874
  exports.Alert = Alert;
13785
14875
  exports.AlertDialog = AlertDialog;
14876
+ exports.AspectRatio = AspectRatio;
13786
14877
  exports.Avatar = Avatar;
13787
14878
  exports.Badge = Badge;
13788
14879
  exports.Box = Box;
13789
14880
  exports.Breadcrumb = Breadcrumb;
13790
14881
  exports.Button = Button;
14882
+ exports.ButtonGroup = ButtonGroup;
13791
14883
  exports.Calendar = Calendar;
13792
14884
  exports.Card = Card;
14885
+ exports.Carousel = Carousel;
13793
14886
  exports.Checkbox = Checkbox;
14887
+ exports.Collapsible = Collapsible;
13794
14888
  exports.Combobox = Combobox;
13795
14889
  exports.ContextMenu = ContextMenu;
13796
14890
  exports.DataTable = DataTable;
@@ -13798,12 +14892,17 @@ exports.DatePicker = DatePicker;
13798
14892
  exports.Dialog = Dialog;
13799
14893
  exports.Drawer = Drawer;
13800
14894
  exports.DropdownMenu = DropdownMenu;
14895
+ exports.Empty = Empty;
13801
14896
  exports.Field = Field;
13802
14897
  exports.FloatButton = FloatButton;
13803
14898
  exports.HStack = HStack;
14899
+ exports.HoverCard = HoverCard;
13804
14900
  exports.I18nProvider = I18nProvider;
13805
14901
  exports.Icon = Icon;
13806
14902
  exports.InputGroup = InputGroup;
14903
+ exports.InputOTP = InputOTP;
14904
+ exports.Item = Item;
14905
+ exports.Kbd = Kbd;
13807
14906
  exports.Label = Label;
13808
14907
  exports.LocaleProvider = LocaleProvider;
13809
14908
  exports.MenuContent = MenuContent;