@nori-ui/core 1.5.0 → 1.7.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 (228) hide show
  1. package/dist/Table.shared-BymRgTnY.d.cts +54 -0
  2. package/dist/Table.shared-BymRgTnY.d.ts +54 -0
  3. package/dist/{chunk-7UKRN73P.js → chunk-2XJCLPNH.js} +3 -3
  4. package/dist/{chunk-7UKRN73P.js.map → chunk-2XJCLPNH.js.map} +1 -1
  5. package/dist/{chunk-76FZF4GM.js → chunk-3B345SQU.js} +8 -125
  6. package/dist/chunk-3B345SQU.js.map +1 -0
  7. package/dist/{chunk-WOF67PKT.js → chunk-3CEJ5TB4.js} +3 -3
  8. package/dist/{chunk-WOF67PKT.js.map → chunk-3CEJ5TB4.js.map} +1 -1
  9. package/dist/{chunk-JSAG5YO7.js → chunk-3IIIHZHT.js} +3 -3
  10. package/dist/{chunk-JSAG5YO7.js.map → chunk-3IIIHZHT.js.map} +1 -1
  11. package/dist/{chunk-46OT4PA6.js → chunk-3W3XYULK.js} +3 -3
  12. package/dist/{chunk-46OT4PA6.js.map → chunk-3W3XYULK.js.map} +1 -1
  13. package/dist/{chunk-6PO2IWB3.js → chunk-4UFAZLSZ.js} +5 -3
  14. package/dist/chunk-4UFAZLSZ.js.map +1 -0
  15. package/dist/chunk-5YHT252H.js +145 -0
  16. package/dist/chunk-5YHT252H.js.map +1 -0
  17. package/dist/chunk-73CUV7MW.js +125 -0
  18. package/dist/chunk-73CUV7MW.js.map +1 -0
  19. package/dist/{chunk-ZMSIYLSI.js → chunk-7FSFJA33.js} +3 -3
  20. package/dist/{chunk-ZMSIYLSI.js.map → chunk-7FSFJA33.js.map} +1 -1
  21. package/dist/chunk-C32XGHWO.js +202 -0
  22. package/dist/chunk-C32XGHWO.js.map +1 -0
  23. package/dist/{chunk-UUXWRDWW.js → chunk-C5HQPXRI.js} +3 -3
  24. package/dist/{chunk-UUXWRDWW.js.map → chunk-C5HQPXRI.js.map} +1 -1
  25. package/dist/{chunk-2UXKXUX2.js → chunk-CPIKN4BX.js} +3 -3
  26. package/dist/{chunk-2UXKXUX2.js.map → chunk-CPIKN4BX.js.map} +1 -1
  27. package/dist/{chunk-GELLSU64.js → chunk-EN4CLDGZ.js} +3 -3
  28. package/dist/{chunk-GELLSU64.js.map → chunk-EN4CLDGZ.js.map} +1 -1
  29. package/dist/{chunk-WAKKQROH.js → chunk-F5UKI7XD.js} +3 -3
  30. package/dist/{chunk-WAKKQROH.js.map → chunk-F5UKI7XD.js.map} +1 -1
  31. package/dist/{chunk-MJ4AGXS7.js → chunk-GJMHNEQ3.js} +3 -3
  32. package/dist/{chunk-MJ4AGXS7.js.map → chunk-GJMHNEQ3.js.map} +1 -1
  33. package/dist/chunk-GTAXVTLF.js +43 -0
  34. package/dist/chunk-GTAXVTLF.js.map +1 -0
  35. package/dist/{chunk-WTNDPO2V.js → chunk-H2LHWJ52.js} +3 -3
  36. package/dist/{chunk-WTNDPO2V.js.map → chunk-H2LHWJ52.js.map} +1 -1
  37. package/dist/{chunk-L5X4SYJ4.js → chunk-HXCETKCC.js} +3 -3
  38. package/dist/{chunk-L5X4SYJ4.js.map → chunk-HXCETKCC.js.map} +1 -1
  39. package/dist/chunk-IGBXSBF7.js +71 -0
  40. package/dist/chunk-IGBXSBF7.js.map +1 -0
  41. package/dist/{chunk-O4NMS3KB.js → chunk-IIVTPN62.js} +3 -3
  42. package/dist/{chunk-O4NMS3KB.js.map → chunk-IIVTPN62.js.map} +1 -1
  43. package/dist/{chunk-RM5TSXVE.js → chunk-ISCJST4P.js} +3 -3
  44. package/dist/{chunk-RM5TSXVE.js.map → chunk-ISCJST4P.js.map} +1 -1
  45. package/dist/{chunk-UF5OENHV.js → chunk-IWM2XDXH.js} +3 -3
  46. package/dist/{chunk-UF5OENHV.js.map → chunk-IWM2XDXH.js.map} +1 -1
  47. package/dist/chunk-J5LK2XHE.js +118 -0
  48. package/dist/chunk-J5LK2XHE.js.map +1 -0
  49. package/dist/chunk-KFFGDET3.js +27 -0
  50. package/dist/chunk-KFFGDET3.js.map +1 -0
  51. package/dist/{chunk-AFQIK6JI.js → chunk-L6VYDM7S.js} +3 -3
  52. package/dist/{chunk-AFQIK6JI.js.map → chunk-L6VYDM7S.js.map} +1 -1
  53. package/dist/chunk-M4BI63P6.js +188 -0
  54. package/dist/chunk-M4BI63P6.js.map +1 -0
  55. package/dist/{chunk-H7MFAFV4.js → chunk-MK57AOTI.js} +4 -4
  56. package/dist/{chunk-H7MFAFV4.js.map → chunk-MK57AOTI.js.map} +1 -1
  57. package/dist/{chunk-FDBQOQMW.js → chunk-MOAIQHR7.js} +3 -3
  58. package/dist/{chunk-FDBQOQMW.js.map → chunk-MOAIQHR7.js.map} +1 -1
  59. package/dist/{chunk-LWQZ257T.js → chunk-MYBBBLYE.js} +3 -3
  60. package/dist/{chunk-LWQZ257T.js.map → chunk-MYBBBLYE.js.map} +1 -1
  61. package/dist/{chunk-F7G6R373.js → chunk-O6M3F7BZ.js} +5 -5
  62. package/dist/{chunk-F7G6R373.js.map → chunk-O6M3F7BZ.js.map} +1 -1
  63. package/dist/{chunk-XP55RZ3D.js → chunk-OELY6K44.js} +3 -3
  64. package/dist/{chunk-XP55RZ3D.js.map → chunk-OELY6K44.js.map} +1 -1
  65. package/dist/{chunk-GRDVE3IR.js → chunk-OIHX5B4R.js} +3 -3
  66. package/dist/{chunk-GRDVE3IR.js.map → chunk-OIHX5B4R.js.map} +1 -1
  67. package/dist/{chunk-4I37QSEM.js → chunk-PGYEIXCO.js} +5 -5
  68. package/dist/{chunk-4I37QSEM.js.map → chunk-PGYEIXCO.js.map} +1 -1
  69. package/dist/{chunk-UJ5KFRDE.js → chunk-PJTCO76H.js} +3 -3
  70. package/dist/{chunk-UJ5KFRDE.js.map → chunk-PJTCO76H.js.map} +1 -1
  71. package/dist/{chunk-6JVUVBZH.js → chunk-PJXVLE24.js} +5 -5
  72. package/dist/{chunk-6JVUVBZH.js.map → chunk-PJXVLE24.js.map} +1 -1
  73. package/dist/{chunk-IGLMPAWE.js → chunk-PLQPBMG2.js} +3 -3
  74. package/dist/{chunk-IGLMPAWE.js.map → chunk-PLQPBMG2.js.map} +1 -1
  75. package/dist/{chunk-HTF6FDB6.js → chunk-PQW5LKAI.js} +3 -3
  76. package/dist/{chunk-HTF6FDB6.js.map → chunk-PQW5LKAI.js.map} +1 -1
  77. package/dist/{chunk-VMAGFYHG.js → chunk-RI4Y2C5U.js} +3 -3
  78. package/dist/{chunk-VMAGFYHG.js.map → chunk-RI4Y2C5U.js.map} +1 -1
  79. package/dist/{chunk-BNDUQNG7.js → chunk-SF6WPUC5.js} +3 -3
  80. package/dist/{chunk-BNDUQNG7.js.map → chunk-SF6WPUC5.js.map} +1 -1
  81. package/dist/{chunk-SINLREQV.js → chunk-STX5UKYT.js} +3 -3
  82. package/dist/{chunk-SINLREQV.js.map → chunk-STX5UKYT.js.map} +1 -1
  83. package/dist/{chunk-KCLWPSV5.js → chunk-TSWPHJIU.js} +4 -4
  84. package/dist/{chunk-KCLWPSV5.js.map → chunk-TSWPHJIU.js.map} +1 -1
  85. package/dist/{chunk-5BM6H2CD.js → chunk-U2ZKY2CP.js} +3 -3
  86. package/dist/{chunk-5BM6H2CD.js.map → chunk-U2ZKY2CP.js.map} +1 -1
  87. package/dist/{chunk-C6TRLHMW.js → chunk-UKDDK42K.js} +3 -3
  88. package/dist/{chunk-C6TRLHMW.js.map → chunk-UKDDK42K.js.map} +1 -1
  89. package/dist/{chunk-UPVNZPFV.js → chunk-USFXANEU.js} +3 -3
  90. package/dist/{chunk-UPVNZPFV.js.map → chunk-USFXANEU.js.map} +1 -1
  91. package/dist/{chunk-Y4ZRSW35.js → chunk-V5QSMDZL.js} +3 -3
  92. package/dist/{chunk-Y4ZRSW35.js.map → chunk-V5QSMDZL.js.map} +1 -1
  93. package/dist/{chunk-EFK7726V.js → chunk-V75O7QQO.js} +3 -3
  94. package/dist/{chunk-EFK7726V.js.map → chunk-V75O7QQO.js.map} +1 -1
  95. package/dist/{chunk-CGQIVFCN.js → chunk-VL2WNGPF.js} +3 -3
  96. package/dist/{chunk-CGQIVFCN.js.map → chunk-VL2WNGPF.js.map} +1 -1
  97. package/dist/{chunk-VCJF75T2.js → chunk-VLZANXRZ.js} +3 -3
  98. package/dist/{chunk-VCJF75T2.js.map → chunk-VLZANXRZ.js.map} +1 -1
  99. package/dist/{chunk-ND7MRYW7.js → chunk-VOF3S5I4.js} +4 -4
  100. package/dist/{chunk-ND7MRYW7.js.map → chunk-VOF3S5I4.js.map} +1 -1
  101. package/dist/chunk-VP7DRJUZ.js +3 -0
  102. package/dist/chunk-VP7DRJUZ.js.map +1 -0
  103. package/dist/chunk-XQNVWHMN.js +60 -0
  104. package/dist/chunk-XQNVWHMN.js.map +1 -0
  105. package/dist/{chunk-W3HMOOON.js → chunk-ZGFXKYA5.js} +3 -3
  106. package/dist/{chunk-W3HMOOON.js.map → chunk-ZGFXKYA5.js.map} +1 -1
  107. package/dist/client.cjs +935 -156
  108. package/dist/client.cjs.map +1 -1
  109. package/dist/client.d.cts +9 -0
  110. package/dist/client.d.ts +9 -0
  111. package/dist/client.js +57 -47
  112. package/dist/client.js.map +1 -1
  113. package/dist/components/Accordion/index.js +2 -2
  114. package/dist/components/Alert/index.js +2 -2
  115. package/dist/components/AlertDialog/index.js +2 -2
  116. package/dist/components/AspectRatio/index.cjs +67 -0
  117. package/dist/components/AspectRatio/index.cjs.map +1 -0
  118. package/dist/components/AspectRatio/index.d.cts +30 -0
  119. package/dist/components/AspectRatio/index.d.ts +30 -0
  120. package/dist/components/AspectRatio/index.js +5 -0
  121. package/dist/components/AspectRatio/index.js.map +1 -0
  122. package/dist/components/Avatar/index.js +2 -2
  123. package/dist/components/Badge/index.js +2 -2
  124. package/dist/components/Box/index.js +4 -4
  125. package/dist/components/Breadcrumb/index.cjs +3 -1
  126. package/dist/components/Breadcrumb/index.cjs.map +1 -1
  127. package/dist/components/Breadcrumb/index.js +5 -5
  128. package/dist/components/Button/index.js +2 -2
  129. package/dist/components/ButtonGroup/index.cjs +83 -0
  130. package/dist/components/ButtonGroup/index.cjs.map +1 -0
  131. package/dist/components/ButtonGroup/index.d.cts +45 -0
  132. package/dist/components/ButtonGroup/index.d.ts +45 -0
  133. package/dist/components/ButtonGroup/index.js +5 -0
  134. package/dist/components/ButtonGroup/index.js.map +1 -0
  135. package/dist/components/Calendar/index.cjs +3 -1
  136. package/dist/components/Calendar/index.cjs.map +1 -1
  137. package/dist/components/Calendar/index.js +5 -5
  138. package/dist/components/Card/index.js +2 -2
  139. package/dist/components/Checkbox/index.js +2 -2
  140. package/dist/components/Collapsible/index.cjs +512 -0
  141. package/dist/components/Collapsible/index.cjs.map +1 -0
  142. package/dist/components/Collapsible/index.d.cts +50 -0
  143. package/dist/components/Collapsible/index.d.ts +50 -0
  144. package/dist/components/Collapsible/index.js +7 -0
  145. package/dist/components/Collapsible/index.js.map +1 -0
  146. package/dist/components/Combobox/index.js +3 -3
  147. package/dist/components/ContextMenu/index.js +4 -4
  148. package/dist/components/DataTable/index.cjs +770 -0
  149. package/dist/components/DataTable/index.cjs.map +1 -0
  150. package/dist/components/DataTable/index.d.cts +53 -0
  151. package/dist/components/DataTable/index.d.ts +53 -0
  152. package/dist/components/DataTable/index.js +8 -0
  153. package/dist/components/DataTable/index.js.map +1 -0
  154. package/dist/components/DatePicker/index.cjs +3 -1
  155. package/dist/components/DatePicker/index.cjs.map +1 -1
  156. package/dist/components/DatePicker/index.js +7 -7
  157. package/dist/components/Dialog/index.js +2 -2
  158. package/dist/components/DropdownMenu/index.js +3 -3
  159. package/dist/components/Empty/index.cjs +385 -0
  160. package/dist/components/Empty/index.cjs.map +1 -0
  161. package/dist/components/Empty/index.d.cts +32 -0
  162. package/dist/components/Empty/index.d.ts +32 -0
  163. package/dist/components/Empty/index.js +7 -0
  164. package/dist/components/Empty/index.js.map +1 -0
  165. package/dist/components/Field/index.cjs +3 -1
  166. package/dist/components/Field/index.cjs.map +1 -1
  167. package/dist/components/Field/index.d.cts +2 -2
  168. package/dist/components/Field/index.d.ts +2 -2
  169. package/dist/components/Field/index.js +3 -3
  170. package/dist/components/FloatButton/index.cjs +3 -1
  171. package/dist/components/FloatButton/index.cjs.map +1 -1
  172. package/dist/components/FloatButton/index.js +5 -5
  173. package/dist/components/HStack/index.js +4 -4
  174. package/dist/components/InputGroup/index.js +2 -2
  175. package/dist/components/Item/index.cjs +443 -0
  176. package/dist/components/Item/index.cjs.map +1 -0
  177. package/dist/components/Item/index.d.cts +40 -0
  178. package/dist/components/Item/index.d.ts +40 -0
  179. package/dist/components/Item/index.js +7 -0
  180. package/dist/components/Item/index.js.map +1 -0
  181. package/dist/components/Kbd/index.cjs +396 -0
  182. package/dist/components/Kbd/index.cjs.map +1 -0
  183. package/dist/components/Kbd/index.d.cts +22 -0
  184. package/dist/components/Kbd/index.d.ts +22 -0
  185. package/dist/components/Kbd/index.js +7 -0
  186. package/dist/components/Kbd/index.js.map +1 -0
  187. package/dist/components/Label/index.cjs +3 -1
  188. package/dist/components/Label/index.cjs.map +1 -1
  189. package/dist/components/Label/index.js +3 -3
  190. package/dist/components/Pagination/index.cjs +3 -1
  191. package/dist/components/Pagination/index.cjs.map +1 -1
  192. package/dist/components/Pagination/index.js +6 -5
  193. package/dist/components/Popover/index.js +2 -2
  194. package/dist/components/Progress/index.js +2 -2
  195. package/dist/components/Radio/index.js +2 -2
  196. package/dist/components/SegmentedControl/index.js +2 -2
  197. package/dist/components/Select/index.js +2 -2
  198. package/dist/components/Separator/index.js +2 -2
  199. package/dist/components/Sheet/index.js +2 -2
  200. package/dist/components/Skeleton/index.js +2 -2
  201. package/dist/components/Slider/index.js +2 -2
  202. package/dist/components/Switch/index.js +2 -2
  203. package/dist/components/Table/index.cjs +461 -0
  204. package/dist/components/Table/index.cjs.map +1 -0
  205. package/dist/components/Table/index.d.cts +16 -0
  206. package/dist/components/Table/index.d.ts +16 -0
  207. package/dist/components/Table/index.js +7 -0
  208. package/dist/components/Table/index.js.map +1 -0
  209. package/dist/components/Tabs/index.js +2 -2
  210. package/dist/components/Text/index.js +2 -2
  211. package/dist/components/TextArea/index.js +3 -3
  212. package/dist/components/TextInput/index.js +2 -2
  213. package/dist/components/Toggle/index.js +2 -2
  214. package/dist/components/Tooltip/index.js +2 -2
  215. package/dist/components/VStack/index.js +4 -4
  216. package/dist/i18n/index.cjs +3 -1
  217. package/dist/i18n/index.cjs.map +1 -1
  218. package/dist/i18n/index.js +1 -1
  219. package/dist/index.cjs +935 -156
  220. package/dist/index.cjs.map +1 -1
  221. package/dist/index.d.cts +9 -0
  222. package/dist/index.d.ts +9 -0
  223. package/dist/index.js +54 -44
  224. package/dist/slot/index.d.cts +2 -2
  225. package/dist/slot/index.d.ts +2 -2
  226. package/package.json +1 -1
  227. package/dist/chunk-6PO2IWB3.js.map +0 -1
  228. package/dist/chunk-76FZF4GM.js.map +0 -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,
@@ -1970,7 +1988,9 @@ var defaultDictionary = {
1970
1988
  "switch.off": "Off",
1971
1989
  // field
1972
1990
  "field.requiredIndicator": "*",
1973
- "field.requiredLabel": "required"
1991
+ "field.requiredLabel": "required",
1992
+ // table / dataTable
1993
+ "table.empty": "No data"
1974
1994
  };
1975
1995
 
1976
1996
  // src/i18n/resolve.ts
@@ -3485,7 +3505,7 @@ var SIZE_KEYS = {
3485
3505
  md: { padX: "4", font: "md" },
3486
3506
  lg: { padX: "5", font: "lg" }
3487
3507
  };
3488
- var BASE_STYLE = {
3508
+ var BASE_STYLE2 = {
3489
3509
  flexDirection: "row",
3490
3510
  alignItems: "center",
3491
3511
  justifyContent: "center"
@@ -3576,7 +3596,7 @@ var Button = /* @__PURE__ */ __name(({
3576
3596
  };
3577
3597
  const sizeFontSize = px(colors.fontSize[sizeKeys.font]);
3578
3598
  const inlineBase = [
3579
- BASE_STYLE,
3599
+ BASE_STYLE2,
3580
3600
  { backgroundColor: stateBg },
3581
3601
  sizeContainer,
3582
3602
  { opacity: isInoperative ? 0.6 : stateInteractionOpacity }
@@ -3656,6 +3676,39 @@ var Button = /* @__PURE__ */ __name(({
3656
3676
  }
3657
3677
  );
3658
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");
3659
3712
  var detectLocale = /* @__PURE__ */ __name(() => {
3660
3713
  try {
3661
3714
  return new Intl.DateTimeFormat().resolvedOptions().locale;
@@ -6590,6 +6643,182 @@ var Checkbox = /* @__PURE__ */ __name(({
6590
6643
  }
6591
6644
  );
6592
6645
  }, "Checkbox");
6646
+ var CollapsibleContext = React.createContext(null);
6647
+ var useCollapsibleContext = /* @__PURE__ */ __name((label) => {
6648
+ const ctx = React.useContext(CollapsibleContext);
6649
+ if (!ctx) {
6650
+ throw new Error(`<${label}> must be rendered inside a <Collapsible>.`);
6651
+ }
6652
+ return ctx;
6653
+ }, "useCollapsibleContext");
6654
+ var CollapsibleRoot = /* @__PURE__ */ __name(({
6655
+ open: controlledOpen,
6656
+ defaultOpen = false,
6657
+ onOpenChange,
6658
+ children,
6659
+ className,
6660
+ testID
6661
+ }) => {
6662
+ const baseId = React.useId();
6663
+ const [innerOpen, setInnerOpen] = React.useState(defaultOpen);
6664
+ const isControlled = controlledOpen !== void 0;
6665
+ const open = isControlled ? controlledOpen : innerOpen;
6666
+ const toggle = React.useCallback(() => {
6667
+ const next = !open;
6668
+ if (!isControlled) {
6669
+ setInnerOpen(next);
6670
+ }
6671
+ onOpenChange?.(next);
6672
+ }, [open, isControlled, onOpenChange]);
6673
+ const ctx = React.useMemo(
6674
+ () => ({
6675
+ open,
6676
+ toggle,
6677
+ contentId: `${baseId}-content`,
6678
+ triggerId: `${baseId}-trigger`
6679
+ }),
6680
+ [open, toggle, baseId]
6681
+ );
6682
+ return /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContext.Provider, { value: ctx, children: /* @__PURE__ */ jsxRuntime.jsx(
6683
+ reactNative.View,
6684
+ {
6685
+ ...testID !== void 0 ? { testID } : {},
6686
+ className: cn("flex-col", className),
6687
+ style: { flexDirection: "column" },
6688
+ children
6689
+ }
6690
+ ) });
6691
+ }, "CollapsibleRoot");
6692
+ var CollapsibleTrigger = /* @__PURE__ */ __name(({ children, className, testID }) => {
6693
+ const { open, toggle, contentId, triggerId } = useCollapsibleContext("Collapsible.Trigger");
6694
+ const colors = useThemeColors();
6695
+ const triggerStyle = {
6696
+ flexDirection: "row",
6697
+ alignItems: "center",
6698
+ paddingVertical: px(colors.spacing["2"]),
6699
+ paddingHorizontal: px(colors.spacing["1"])
6700
+ };
6701
+ return /* @__PURE__ */ jsxRuntime.jsx(
6702
+ reactNative.Pressable,
6703
+ {
6704
+ id: triggerId,
6705
+ ...testID !== void 0 ? { testID } : {},
6706
+ role: "button",
6707
+ accessibilityRole: "button",
6708
+ "aria-expanded": open,
6709
+ "aria-controls": contentId,
6710
+ onPress: toggle,
6711
+ className: cn("flex-row items-center py-2 px-1", className),
6712
+ style: triggerStyle,
6713
+ children: typeof children === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
6714
+ reactNative.Text,
6715
+ {
6716
+ style: {
6717
+ color: colors.semantic.text.default,
6718
+ fontFamily: colors.fontFamily.body,
6719
+ fontSize: px(colors.fontSize.sm),
6720
+ fontWeight: colors.fontWeight.medium
6721
+ },
6722
+ children
6723
+ }
6724
+ ) : children
6725
+ }
6726
+ );
6727
+ }, "CollapsibleTrigger");
6728
+ var CollapsibleContent = /* @__PURE__ */ __name(({ children, className, testID }) => {
6729
+ const { open, contentId, triggerId } = useCollapsibleContext("Collapsible.Content");
6730
+ const wrapperRef = React.useRef(null);
6731
+ const innerRef = React.useRef(null);
6732
+ React.useEffect(() => {
6733
+ if (reactNative.Platform.OS !== "web") {
6734
+ return;
6735
+ }
6736
+ const wrapper = wrapperRef.current;
6737
+ const inner = innerRef.current;
6738
+ if (!wrapper || !inner) {
6739
+ return;
6740
+ }
6741
+ const isFirstPaint = wrapper.dataset.noriPainted !== "1";
6742
+ wrapper.dataset.noriPainted = "1";
6743
+ wrapper.style.overflow = "hidden";
6744
+ wrapper.style.transitionProperty = "max-height, opacity";
6745
+ wrapper.style.transitionDuration = "200ms";
6746
+ wrapper.style.transitionTimingFunction = "cubic-bezier(0.16, 1, 0.3, 1)";
6747
+ if (open) {
6748
+ const target = inner.scrollHeight;
6749
+ if (isFirstPaint) {
6750
+ wrapper.style.maxHeight = `${target}px`;
6751
+ wrapper.style.opacity = "1";
6752
+ return;
6753
+ }
6754
+ wrapper.style.maxHeight = "0px";
6755
+ wrapper.style.opacity = "0";
6756
+ void wrapper.offsetHeight;
6757
+ requestAnimationFrame(() => {
6758
+ wrapper.style.maxHeight = `${target}px`;
6759
+ wrapper.style.opacity = "1";
6760
+ });
6761
+ } else {
6762
+ if (isFirstPaint) {
6763
+ wrapper.style.maxHeight = "0px";
6764
+ wrapper.style.opacity = "0";
6765
+ return;
6766
+ }
6767
+ const current = inner.scrollHeight;
6768
+ wrapper.style.maxHeight = `${current}px`;
6769
+ wrapper.style.opacity = "1";
6770
+ void wrapper.offsetHeight;
6771
+ requestAnimationFrame(() => {
6772
+ wrapper.style.maxHeight = "0px";
6773
+ wrapper.style.opacity = "0";
6774
+ });
6775
+ }
6776
+ }, [open]);
6777
+ if (reactNative.Platform.OS !== "web") {
6778
+ if (!open) {
6779
+ return null;
6780
+ }
6781
+ return /* @__PURE__ */ jsxRuntime.jsx(
6782
+ reactNative.View,
6783
+ {
6784
+ ...testID !== void 0 ? { testID } : {},
6785
+ id: contentId,
6786
+ "aria-labelledby": triggerId,
6787
+ className: cn("flex-col", className),
6788
+ style: { flexDirection: "column" },
6789
+ children
6790
+ }
6791
+ );
6792
+ }
6793
+ return /* @__PURE__ */ jsxRuntime.jsx(
6794
+ reactNative.View,
6795
+ {
6796
+ ref: (node) => {
6797
+ wrapperRef.current = node;
6798
+ },
6799
+ ...testID !== void 0 ? { testID } : {},
6800
+ id: contentId,
6801
+ "aria-labelledby": triggerId,
6802
+ "aria-hidden": !open,
6803
+ className: cn("overflow-hidden", className),
6804
+ children: /* @__PURE__ */ jsxRuntime.jsx(
6805
+ reactNative.View,
6806
+ {
6807
+ ref: (node) => {
6808
+ innerRef.current = node;
6809
+ },
6810
+ className: "flex-col",
6811
+ style: { flexDirection: "column" },
6812
+ children
6813
+ }
6814
+ )
6815
+ }
6816
+ );
6817
+ }, "CollapsibleContent");
6818
+ var Collapsible = Object.assign(CollapsibleRoot, {
6819
+ Trigger: CollapsibleTrigger,
6820
+ Content: CollapsibleContent
6821
+ });
6593
6822
  var Combobox = /* @__PURE__ */ __name((props) => {
6594
6823
  return /* @__PURE__ */ jsxRuntime.jsx(Select, { searchable: true, ...props });
6595
6824
  }, "Combobox");
@@ -7004,45 +7233,489 @@ var ContextMenu = Object.assign(ContextMenuRoot, {
7004
7233
  Separator: MenuSeparator,
7005
7234
  Label: MenuLabel
7006
7235
  });
7007
- function formatDate(date$1, locale) {
7008
- try {
7009
- return new Intl.DateTimeFormat(locale, { dateStyle: "medium" }).format(date$1.toDate(date.getLocalTimeZone()));
7010
- } catch {
7011
- return `${date$1.year}-${String(date$1.month).padStart(2, "0")}-${String(date$1.day).padStart(2, "0")}`;
7236
+ var range = /* @__PURE__ */ __name((from, to) => {
7237
+ if (to < from) {
7238
+ return [];
7012
7239
  }
7013
- }
7014
- __name(formatDate, "formatDate");
7015
- function CalendarIcon({ size = 16, color = "currentColor" }) {
7016
- const colors = useThemeColors();
7017
- if (reactNative.Platform.OS === "web") {
7018
- return /* @__PURE__ */ jsxRuntime.jsx(
7019
- "svg",
7020
- {
7021
- width: size,
7022
- height: size,
7023
- viewBox: "0 0 24 24",
7024
- fill: "none",
7025
- stroke: color,
7026
- strokeWidth: "2",
7027
- strokeLinecap: "round",
7028
- strokeLinejoin: "round",
7029
- "aria-hidden": "true",
7030
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 2v4M16 2v4M3 10h18M5 4h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z" })
7240
+ const out = new Array(to - from + 1);
7241
+ for (let i = 0; i < out.length; i += 1) {
7242
+ out[i] = from + i;
7243
+ }
7244
+ return out;
7245
+ }, "range");
7246
+ function usePagination(args) {
7247
+ const {
7248
+ page: controlledPage,
7249
+ defaultPage = 1,
7250
+ pageCount,
7251
+ siblingCount = 1,
7252
+ boundaryCount = 1,
7253
+ showFirstLast = false,
7254
+ showPrevNext = true,
7255
+ onPageChange
7256
+ } = args;
7257
+ const isControlled = controlledPage !== void 0;
7258
+ const [uncontrolledPage, setUncontrolledPage] = React.useState(defaultPage);
7259
+ const onChangeRef = React.useRef(onPageChange);
7260
+ onChangeRef.current = onPageChange;
7261
+ const safePageCount = Math.max(1, Math.floor(pageCount));
7262
+ const rawPage = isControlled ? controlledPage : uncontrolledPage;
7263
+ const currentPage = Math.min(Math.max(1, Math.floor(rawPage)), safePageCount);
7264
+ const goToPage = React.useCallback(
7265
+ (next2) => {
7266
+ const clamped = Math.min(Math.max(1, Math.floor(next2)), Math.max(1, Math.floor(pageCount)));
7267
+ if (!isControlled) {
7268
+ setUncontrolledPage(clamped);
7031
7269
  }
7270
+ onChangeRef.current?.(clamped);
7271
+ },
7272
+ [isControlled, pageCount]
7273
+ );
7274
+ const prev = React.useCallback(() => goToPage(currentPage - 1), [goToPage, currentPage]);
7275
+ const next = React.useCallback(() => goToPage(currentPage + 1), [goToPage, currentPage]);
7276
+ const first = React.useCallback(() => goToPage(1), [goToPage]);
7277
+ const last = React.useCallback(() => goToPage(safePageCount), [goToPage, safePageCount]);
7278
+ const pages = React.useMemo(() => {
7279
+ const items = [];
7280
+ const safeSibling = Math.max(0, Math.floor(siblingCount));
7281
+ const safeBoundary = Math.max(0, Math.floor(boundaryCount));
7282
+ if (showFirstLast) {
7283
+ items.push({ type: "first", disabled: currentPage <= 1 });
7284
+ }
7285
+ if (showPrevNext) {
7286
+ items.push({ type: "prev", disabled: currentPage <= 1 });
7287
+ }
7288
+ const startPages = range(1, Math.min(safeBoundary, safePageCount));
7289
+ const endPages = range(Math.max(safePageCount - safeBoundary + 1, safeBoundary + 1), safePageCount);
7290
+ const siblingsStart = Math.max(
7291
+ Math.min(currentPage - safeSibling, safePageCount - safeBoundary - safeSibling * 2 - 1),
7292
+ safeBoundary + 2
7032
7293
  );
7033
- }
7034
- const resolvedColor = color === "currentColor" ? colors.semantic.text.muted : color;
7035
- return /* @__PURE__ */ jsxRuntime.jsx(
7036
- reactNative.Text,
7037
- {
7038
- accessibilityElementsHidden: true,
7039
- importantForAccessibility: "no-hide-descendants",
7040
- style: { fontSize: size, lineHeight: size, color: resolvedColor },
7041
- children: "\u{1F4C5}"
7294
+ const siblingsEnd = Math.min(
7295
+ Math.max(currentPage + safeSibling, safeBoundary + safeSibling * 2 + 2),
7296
+ endPages.length > 0 ? endPages[0] - 2 : safePageCount - 1
7297
+ );
7298
+ const middle = [];
7299
+ if (siblingsStart > safeBoundary + 2) {
7300
+ middle.push("ellipsis");
7301
+ } else if (safeBoundary + 1 < safePageCount - safeBoundary) {
7302
+ middle.push(safeBoundary + 1);
7042
7303
  }
7043
- );
7044
- }
7045
- __name(CalendarIcon, "CalendarIcon");
7304
+ for (const p of range(siblingsStart, siblingsEnd)) {
7305
+ middle.push(p);
7306
+ }
7307
+ if (siblingsEnd < safePageCount - safeBoundary - 1) {
7308
+ middle.push("ellipsis");
7309
+ } else if (safePageCount - safeBoundary > safeBoundary) {
7310
+ middle.push(safePageCount - safeBoundary);
7311
+ }
7312
+ const seen = /* @__PURE__ */ new Set();
7313
+ const pushPage = /* @__PURE__ */ __name((n) => {
7314
+ if (n < 1 || n > safePageCount || seen.has(n)) {
7315
+ return;
7316
+ }
7317
+ seen.add(n);
7318
+ items.push({ type: "page", page: n, selected: n === currentPage });
7319
+ }, "pushPage");
7320
+ for (const n of startPages) {
7321
+ pushPage(n);
7322
+ }
7323
+ for (const m of middle) {
7324
+ if (m === "ellipsis") {
7325
+ items.push({ type: "ellipsis" });
7326
+ } else {
7327
+ pushPage(m);
7328
+ }
7329
+ }
7330
+ for (const n of endPages) {
7331
+ pushPage(n);
7332
+ }
7333
+ if (showPrevNext) {
7334
+ items.push({ type: "next", disabled: currentPage >= safePageCount });
7335
+ }
7336
+ if (showFirstLast) {
7337
+ items.push({ type: "last", disabled: currentPage >= safePageCount });
7338
+ }
7339
+ return items;
7340
+ }, [currentPage, safePageCount, siblingCount, boundaryCount, showFirstLast, showPrevNext]);
7341
+ return {
7342
+ page: currentPage,
7343
+ pages,
7344
+ canPrev: currentPage > 1,
7345
+ canNext: currentPage < safePageCount,
7346
+ goToPage,
7347
+ prev,
7348
+ next,
7349
+ first,
7350
+ last
7351
+ };
7352
+ }
7353
+ __name(usePagination, "usePagination");
7354
+ var TableContext = React.createContext({
7355
+ striped: false,
7356
+ compact: false,
7357
+ bordered: false,
7358
+ rowIndex: 0,
7359
+ setRowIndex: /* @__PURE__ */ __name(() => {
7360
+ }, "setRowIndex")
7361
+ });
7362
+ function buildTableCompound(parts) {
7363
+ return Object.assign(parts.Root, {
7364
+ Header: parts.Header,
7365
+ Body: parts.Body,
7366
+ Footer: parts.Footer,
7367
+ Row: parts.Row,
7368
+ HeaderCell: parts.HeaderCell,
7369
+ Cell: parts.Cell,
7370
+ Caption: parts.Caption
7371
+ });
7372
+ }
7373
+ __name(buildTableCompound, "buildTableCompound");
7374
+ var TableRoot = /* @__PURE__ */ __name(({ striped = false, compact = false, bordered = false, children, className, testID }) => {
7375
+ const [rowIndex, setRowIndex] = React.useState(0);
7376
+ const ctxValue = {
7377
+ striped,
7378
+ compact,
7379
+ bordered,
7380
+ rowIndex,
7381
+ setRowIndex
7382
+ };
7383
+ return /* @__PURE__ */ jsxRuntime.jsx(TableContext.Provider, { value: ctxValue, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("w-full overflow-auto", className), children: /* @__PURE__ */ jsxRuntime.jsx(
7384
+ "table",
7385
+ {
7386
+ className: cn(
7387
+ "w-full caption-bottom text-sm",
7388
+ bordered && "border border-semantic-border-default",
7389
+ className
7390
+ ),
7391
+ ...testID !== void 0 ? { "data-testid": testID } : {},
7392
+ children
7393
+ }
7394
+ ) }) });
7395
+ }, "TableRoot");
7396
+ var TableHeader = /* @__PURE__ */ __name(({ children, className, testID }) => /* @__PURE__ */ jsxRuntime.jsx(
7397
+ "thead",
7398
+ {
7399
+ className: cn("[&_tr]:border-b [&_tr]:border-semantic-border-default", className),
7400
+ ...testID !== void 0 ? { "data-testid": testID } : {},
7401
+ children
7402
+ }
7403
+ ), "TableHeader");
7404
+ var TableBody = /* @__PURE__ */ __name(({ children, className, testID }) => /* @__PURE__ */ jsxRuntime.jsx(
7405
+ "tbody",
7406
+ {
7407
+ className: cn("[&_tr:last-child]:border-0", className),
7408
+ ...testID !== void 0 ? { "data-testid": testID } : {},
7409
+ children
7410
+ }
7411
+ ), "TableBody");
7412
+ var TableFooter = /* @__PURE__ */ __name(({ children, className, testID }) => /* @__PURE__ */ jsxRuntime.jsx(
7413
+ "tfoot",
7414
+ {
7415
+ className: cn("border-t border-semantic-border-default font-medium", className),
7416
+ ...testID !== void 0 ? { "data-testid": testID } : {},
7417
+ children
7418
+ }
7419
+ ), "TableFooter");
7420
+ var TableRow = /* @__PURE__ */ __name(({ selected = false, onPress, children, className, testID }) => {
7421
+ const colors = useThemeColors();
7422
+ const handleClick = React.useCallback(() => {
7423
+ onPress?.();
7424
+ }, [onPress]);
7425
+ return /* @__PURE__ */ jsxRuntime.jsx(
7426
+ "tr",
7427
+ {
7428
+ className: cn(
7429
+ "border-b border-semantic-border-default transition-colors",
7430
+ onPress && "cursor-pointer hover:bg-semantic-background-subtle",
7431
+ selected && "bg-semantic-background-subtle",
7432
+ className
7433
+ ),
7434
+ style: selected ? { backgroundColor: colors.semantic.background.subtle } : void 0,
7435
+ onClick: onPress ? handleClick : void 0,
7436
+ ...testID !== void 0 ? { "data-testid": testID } : {},
7437
+ children
7438
+ }
7439
+ );
7440
+ }, "TableRow");
7441
+ var TableHeaderCell = /* @__PURE__ */ __name(({ align = "left", colSpan, children, className, testID }) => /* @__PURE__ */ jsxRuntime.jsx(
7442
+ "th",
7443
+ {
7444
+ className: cn(
7445
+ "h-10 px-4 font-medium text-semantic-text-secondary",
7446
+ align === "right" && "text-right",
7447
+ align === "center" && "text-center",
7448
+ align === "left" && "text-left",
7449
+ className
7450
+ ),
7451
+ colSpan,
7452
+ ...testID !== void 0 ? { "data-testid": testID } : {},
7453
+ children
7454
+ }
7455
+ ), "TableHeaderCell");
7456
+ var TableCell = /* @__PURE__ */ __name(({ align = "left", colSpan, children, className, testID }) => /* @__PURE__ */ jsxRuntime.jsx(
7457
+ "td",
7458
+ {
7459
+ className: cn(
7460
+ "p-4 align-middle",
7461
+ align === "right" && "text-right",
7462
+ align === "center" && "text-center",
7463
+ align === "left" && "text-left",
7464
+ className
7465
+ ),
7466
+ colSpan,
7467
+ ...testID !== void 0 ? { "data-testid": testID } : {},
7468
+ children
7469
+ }
7470
+ ), "TableCell");
7471
+ var TableCaption = /* @__PURE__ */ __name(({ children, className, testID }) => /* @__PURE__ */ jsxRuntime.jsx(
7472
+ "caption",
7473
+ {
7474
+ className: cn("mt-4 text-sm text-semantic-text-secondary", className),
7475
+ ...testID !== void 0 ? { "data-testid": testID } : {},
7476
+ children
7477
+ }
7478
+ ), "TableCaption");
7479
+ var Table = buildTableCompound({
7480
+ Root: TableRoot,
7481
+ Header: TableHeader,
7482
+ Body: TableBody,
7483
+ Footer: TableFooter,
7484
+ Row: TableRow,
7485
+ HeaderCell: TableHeaderCell,
7486
+ Cell: TableCell,
7487
+ Caption: TableCaption
7488
+ });
7489
+ function sortData(data, sort) {
7490
+ if (!sort) {
7491
+ return data;
7492
+ }
7493
+ const key = sort.id;
7494
+ return [...data].sort((a, b) => {
7495
+ const av = a[key];
7496
+ const bv = b[key];
7497
+ if (av == null && bv == null) {
7498
+ return 0;
7499
+ }
7500
+ if (av == null) {
7501
+ return 1;
7502
+ }
7503
+ if (bv == null) {
7504
+ return -1;
7505
+ }
7506
+ const cmp2 = av < bv ? -1 : av > bv ? 1 : 0;
7507
+ return sort.direction === "asc" ? cmp2 : -cmp2;
7508
+ });
7509
+ }
7510
+ __name(sortData, "sortData");
7511
+ function SortIndicator({ direction }) {
7512
+ if (direction === void 0) {
7513
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: 4, opacity: 0.3 }, children: "\u21C5" });
7514
+ }
7515
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: 4 }, children: direction === "asc" ? "\u2191" : "\u2193" });
7516
+ }
7517
+ __name(SortIndicator, "SortIndicator");
7518
+ function DataTable({
7519
+ data,
7520
+ columns,
7521
+ pageSize = 10,
7522
+ defaultSort,
7523
+ onRowPress,
7524
+ emptyState,
7525
+ striped,
7526
+ compact,
7527
+ bordered,
7528
+ testID,
7529
+ className
7530
+ }) {
7531
+ const [sort, setSort] = React.useState(defaultSort ?? null);
7532
+ const sorted = React.useMemo(() => sortData(data, sort), [data, sort]);
7533
+ const pageCount = Math.max(1, Math.ceil(sorted.length / pageSize));
7534
+ const { page, goToPage, canPrev, canNext } = usePagination({ pageCount, defaultPage: 1 });
7535
+ const pageSlice = React.useMemo(() => {
7536
+ const start = (page - 1) * pageSize;
7537
+ return sorted.slice(start, start + pageSize);
7538
+ }, [sorted, page, pageSize]);
7539
+ const handleSort = /* @__PURE__ */ __name((colId) => {
7540
+ setSort((prev) => {
7541
+ if (prev?.id !== colId) {
7542
+ goToPage(1);
7543
+ return { id: colId, direction: "asc" };
7544
+ }
7545
+ if (prev.direction === "asc") {
7546
+ return { id: colId, direction: "desc" };
7547
+ }
7548
+ goToPage(1);
7549
+ return null;
7550
+ });
7551
+ }, "handleSort");
7552
+ const tableProps = {};
7553
+ if (striped !== void 0) {
7554
+ tableProps.striped = striped;
7555
+ }
7556
+ if (compact !== void 0) {
7557
+ tableProps.compact = compact;
7558
+ }
7559
+ if (bordered !== void 0) {
7560
+ tableProps.bordered = bordered;
7561
+ }
7562
+ if (testID !== void 0) {
7563
+ tableProps.testID = testID;
7564
+ }
7565
+ if (className !== void 0) {
7566
+ tableProps.className = className;
7567
+ }
7568
+ return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: { width: "100%" }, children: [
7569
+ /* @__PURE__ */ jsxRuntime.jsxs(Table, { ...tableProps, children: [
7570
+ /* @__PURE__ */ jsxRuntime.jsx(Table.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(Table.Row, { children: columns.map((col) => {
7571
+ const align = col.align;
7572
+ return /* @__PURE__ */ jsxRuntime.jsx(Table.HeaderCell, { ...align !== void 0 ? { align } : {}, children: col.sortable ? /* @__PURE__ */ jsxRuntime.jsxs(
7573
+ reactNative.Pressable,
7574
+ {
7575
+ accessibilityRole: "button",
7576
+ accessibilityLabel: `Sort by ${col.id}`,
7577
+ "aria-label": `Sort by ${col.id}`,
7578
+ onPress: () => handleSort(col.id),
7579
+ style: { flexDirection: "row", alignItems: "center" },
7580
+ children: [
7581
+ typeof col.header === "string" ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { children: col.header }) : col.header,
7582
+ /* @__PURE__ */ jsxRuntime.jsx(
7583
+ SortIndicator,
7584
+ {
7585
+ ...sort?.id === col.id ? { direction: sort.direction } : {}
7586
+ }
7587
+ )
7588
+ ]
7589
+ }
7590
+ ) : col.header }, col.id);
7591
+ }) }) }),
7592
+ /* @__PURE__ */ jsxRuntime.jsx(Table.Body, { children: pageSlice.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(Table.Row, { children: /* @__PURE__ */ jsxRuntime.jsx(Table.Cell, { colSpan: columns.length, children: /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { children: emptyState ?? "No data" }) }) }) : pageSlice.map((row, i) => /* @__PURE__ */ jsxRuntime.jsx(
7593
+ Table.Row,
7594
+ {
7595
+ ...onRowPress !== void 0 ? { onPress: /* @__PURE__ */ __name(() => onRowPress(row), "onPress") } : {},
7596
+ children: columns.map((col) => {
7597
+ const colAlign = col.align;
7598
+ return /* @__PURE__ */ jsxRuntime.jsx(
7599
+ Table.Cell,
7600
+ {
7601
+ ...colAlign !== void 0 ? { align: colAlign } : {},
7602
+ children: col.cell(row)
7603
+ },
7604
+ col.id
7605
+ );
7606
+ })
7607
+ },
7608
+ i
7609
+ )) })
7610
+ ] }),
7611
+ pageCount > 1 && /* @__PURE__ */ jsxRuntime.jsx(
7612
+ PaginationControls,
7613
+ {
7614
+ page,
7615
+ pageCount,
7616
+ canPrev,
7617
+ canNext,
7618
+ goToPage
7619
+ }
7620
+ )
7621
+ ] });
7622
+ }
7623
+ __name(DataTable, "DataTable");
7624
+ function EmptyState({ children }) {
7625
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { paddingVertical: 32, alignItems: "center" }, children: typeof children === "string" ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: { color: "#888", fontSize: 14 }, children }) : children });
7626
+ }
7627
+ __name(EmptyState, "EmptyState");
7628
+ function PaginationControls({
7629
+ page,
7630
+ pageCount,
7631
+ canPrev,
7632
+ canNext,
7633
+ goToPage
7634
+ }) {
7635
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7636
+ reactNative.View,
7637
+ {
7638
+ style: {
7639
+ flexDirection: "row",
7640
+ justifyContent: "flex-end",
7641
+ alignItems: "center",
7642
+ paddingVertical: 8,
7643
+ gap: 8
7644
+ },
7645
+ children: [
7646
+ /* @__PURE__ */ jsxRuntime.jsx(
7647
+ reactNative.Pressable,
7648
+ {
7649
+ onPress: canPrev ? () => goToPage(page - 1) : void 0,
7650
+ accessibilityRole: "button",
7651
+ accessibilityLabel: "Previous page",
7652
+ "aria-label": "Previous page",
7653
+ "aria-disabled": !canPrev,
7654
+ style: { opacity: canPrev ? 1 : 0.4, paddingHorizontal: 8 },
7655
+ children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: { fontSize: 14 }, children: "\u2039 Prev" })
7656
+ }
7657
+ ),
7658
+ /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Text, { style: { fontSize: 14 }, "aria-live": "polite", children: [
7659
+ page,
7660
+ " / ",
7661
+ pageCount
7662
+ ] }),
7663
+ /* @__PURE__ */ jsxRuntime.jsx(
7664
+ reactNative.Pressable,
7665
+ {
7666
+ onPress: canNext ? () => goToPage(page + 1) : void 0,
7667
+ accessibilityRole: "button",
7668
+ accessibilityLabel: "Next page",
7669
+ "aria-label": "Next page",
7670
+ "aria-disabled": !canNext,
7671
+ style: { opacity: canNext ? 1 : 0.4, paddingHorizontal: 8 },
7672
+ children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: { fontSize: 14 }, children: "Next \u203A" })
7673
+ }
7674
+ )
7675
+ ]
7676
+ }
7677
+ );
7678
+ }
7679
+ __name(PaginationControls, "PaginationControls");
7680
+ function formatDate(date$1, locale) {
7681
+ try {
7682
+ return new Intl.DateTimeFormat(locale, { dateStyle: "medium" }).format(date$1.toDate(date.getLocalTimeZone()));
7683
+ } catch {
7684
+ return `${date$1.year}-${String(date$1.month).padStart(2, "0")}-${String(date$1.day).padStart(2, "0")}`;
7685
+ }
7686
+ }
7687
+ __name(formatDate, "formatDate");
7688
+ function CalendarIcon({ size = 16, color = "currentColor" }) {
7689
+ const colors = useThemeColors();
7690
+ if (reactNative.Platform.OS === "web") {
7691
+ return /* @__PURE__ */ jsxRuntime.jsx(
7692
+ "svg",
7693
+ {
7694
+ width: size,
7695
+ height: size,
7696
+ viewBox: "0 0 24 24",
7697
+ fill: "none",
7698
+ stroke: color,
7699
+ strokeWidth: "2",
7700
+ strokeLinecap: "round",
7701
+ strokeLinejoin: "round",
7702
+ "aria-hidden": "true",
7703
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 2v4M16 2v4M3 10h18M5 4h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z" })
7704
+ }
7705
+ );
7706
+ }
7707
+ const resolvedColor = color === "currentColor" ? colors.semantic.text.muted : color;
7708
+ return /* @__PURE__ */ jsxRuntime.jsx(
7709
+ reactNative.Text,
7710
+ {
7711
+ accessibilityElementsHidden: true,
7712
+ importantForAccessibility: "no-hide-descendants",
7713
+ style: { fontSize: size, lineHeight: size, color: resolvedColor },
7714
+ children: "\u{1F4C5}"
7715
+ }
7716
+ );
7717
+ }
7718
+ __name(CalendarIcon, "CalendarIcon");
7046
7719
  function buildCalendarOptional(minValue, maxValue, isDateUnavailable, firstDayOfWeek) {
7047
7720
  const out = {};
7048
7721
  if (minValue !== void 0) {
@@ -7744,6 +8417,55 @@ var Dialog = Object.assign(DialogRoot, {
7744
8417
  Footer: DialogFooter,
7745
8418
  Close: DialogClose
7746
8419
  });
8420
+ var Empty = /* @__PURE__ */ __name(({ icon, title, description, action, className, testID }) => {
8421
+ const colors = useThemeColors();
8422
+ const containerStyle = {
8423
+ flexDirection: "column",
8424
+ alignItems: "center",
8425
+ justifyContent: "center",
8426
+ gap: px(colors.spacing["3"]),
8427
+ paddingVertical: px(colors.spacing["8"]),
8428
+ paddingHorizontal: px(colors.spacing["4"])
8429
+ };
8430
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8431
+ reactNative.View,
8432
+ {
8433
+ ...testID !== void 0 ? { testID } : {},
8434
+ className: cn("flex-col items-center justify-center gap-3 py-8 px-4", className),
8435
+ style: containerStyle,
8436
+ children: [
8437
+ icon != null ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { marginBottom: px(colors.spacing["1"]) }, children: icon }) : null,
8438
+ /* @__PURE__ */ jsxRuntime.jsx(
8439
+ reactNative.Text,
8440
+ {
8441
+ style: {
8442
+ color: colors.semantic.text.default,
8443
+ fontFamily: colors.fontFamily.body,
8444
+ fontSize: px(colors.fontSize.md),
8445
+ fontWeight: colors.fontWeight.semibold,
8446
+ textAlign: "center"
8447
+ },
8448
+ children: title
8449
+ }
8450
+ ),
8451
+ description != null ? /* @__PURE__ */ jsxRuntime.jsx(
8452
+ reactNative.Text,
8453
+ {
8454
+ style: {
8455
+ color: colors.semantic.text.muted,
8456
+ fontFamily: colors.fontFamily.body,
8457
+ fontSize: px(colors.fontSize.sm),
8458
+ lineHeight: px(colors.fontSize.sm) * Number(colors.lineHeight.normal),
8459
+ textAlign: "center"
8460
+ },
8461
+ children: description
8462
+ }
8463
+ ) : null,
8464
+ action != null ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { marginTop: px(colors.spacing["1"]) }, children: action }) : null
8465
+ ]
8466
+ }
8467
+ );
8468
+ }, "Empty");
7747
8469
  var FieldContext = React.createContext(null);
7748
8470
  var useFieldContextStrict = /* @__PURE__ */ __name((caller) => {
7749
8471
  const ctx = React.useContext(FieldContext);
@@ -9027,6 +9749,173 @@ var InputGroup = Object.assign(InputGroupRoot, {
9027
9749
  Addon: InputGroupAddon,
9028
9750
  Input: InputGroupInput
9029
9751
  });
9752
+ var Item = /* @__PURE__ */ __name(({
9753
+ leading,
9754
+ title,
9755
+ description,
9756
+ trailing,
9757
+ chevron = false,
9758
+ onPress,
9759
+ disabled = false,
9760
+ className,
9761
+ testID
9762
+ }) => {
9763
+ const colors = useThemeColors();
9764
+ const isTappable = onPress !== void 0;
9765
+ const rowStyle = {
9766
+ flexDirection: "row",
9767
+ alignItems: "center",
9768
+ gap: px(colors.spacing["3"]),
9769
+ paddingVertical: px(colors.spacing["3"]),
9770
+ paddingHorizontal: px(colors.spacing["4"]),
9771
+ minHeight: 52,
9772
+ opacity: disabled ? 0.5 : 1
9773
+ };
9774
+ const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9775
+ leading != null ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { flexShrink: 0 }, children: leading }) : null,
9776
+ /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: { flex: 1, flexDirection: "column", gap: 2 }, children: [
9777
+ typeof title === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
9778
+ reactNative.Text,
9779
+ {
9780
+ style: {
9781
+ color: colors.semantic.text.default,
9782
+ fontFamily: colors.fontFamily.body,
9783
+ fontSize: px(colors.fontSize.sm),
9784
+ fontWeight: colors.fontWeight.medium
9785
+ },
9786
+ numberOfLines: 1,
9787
+ children: title
9788
+ }
9789
+ ) : title,
9790
+ description != null ? typeof description === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
9791
+ reactNative.Text,
9792
+ {
9793
+ style: {
9794
+ color: colors.semantic.text.muted,
9795
+ fontFamily: colors.fontFamily.body,
9796
+ fontSize: px(colors.fontSize.xs)
9797
+ },
9798
+ numberOfLines: 1,
9799
+ children: description
9800
+ }
9801
+ ) : description : null
9802
+ ] }),
9803
+ trailing != null ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { flexShrink: 0 }, children: trailing }) : null,
9804
+ chevron ? /* @__PURE__ */ jsxRuntime.jsx(
9805
+ reactNative.View,
9806
+ {
9807
+ style: { flexShrink: 0 },
9808
+ "aria-hidden": true,
9809
+ testID: testID != null ? `${testID}-chevron` : void 0,
9810
+ children: /* @__PURE__ */ jsxRuntime.jsx(
9811
+ reactNative.Text,
9812
+ {
9813
+ accessibilityElementsHidden: true,
9814
+ importantForAccessibility: "no-hide-descendants",
9815
+ style: {
9816
+ fontSize: 14,
9817
+ lineHeight: 16,
9818
+ color: colors.semantic.text.muted,
9819
+ // On web rn-web passes style through — transform
9820
+ // with a rotate is the lightest-weight approach
9821
+ // that avoids importing the full SVG icon set.
9822
+ transform: [{ rotate: "-90deg" }]
9823
+ },
9824
+ children: "\u2304"
9825
+ }
9826
+ )
9827
+ }
9828
+ ) : null
9829
+ ] });
9830
+ if (isTappable) {
9831
+ return /* @__PURE__ */ jsxRuntime.jsx(
9832
+ reactNative.Pressable,
9833
+ {
9834
+ ...testID !== void 0 ? { testID } : {},
9835
+ role: "button",
9836
+ accessibilityRole: "button",
9837
+ disabled,
9838
+ onPress: disabled ? void 0 : onPress,
9839
+ className: cn(
9840
+ "flex-row items-center",
9841
+ disabled ? "opacity-50" : "hover:bg-semantic-background-subtle active:bg-semantic-border-default",
9842
+ className
9843
+ ),
9844
+ style: rowStyle,
9845
+ children: content
9846
+ }
9847
+ );
9848
+ }
9849
+ return /* @__PURE__ */ jsxRuntime.jsx(
9850
+ reactNative.View,
9851
+ {
9852
+ ...testID !== void 0 ? { testID } : {},
9853
+ className: cn("flex-row items-center", className),
9854
+ style: rowStyle,
9855
+ children: content
9856
+ }
9857
+ );
9858
+ }, "Item");
9859
+ var Kbd = /* @__PURE__ */ __name(({ children, className }) => {
9860
+ const colors = useThemeColors();
9861
+ const isDark = useColorScheme() === "dark";
9862
+ const bgColor = isDark ? colors.color.neutral["800"] : colors.color.neutral["100"];
9863
+ const borderColor = isDark ? colors.color.neutral["600"] : colors.color.neutral["300"];
9864
+ const textColor = isDark ? colors.color.neutral["200"] : colors.color.neutral["700"];
9865
+ const containerStyle = {
9866
+ display: "flex",
9867
+ flexDirection: "row",
9868
+ alignItems: "center",
9869
+ justifyContent: "center",
9870
+ alignSelf: "center",
9871
+ backgroundColor: bgColor,
9872
+ borderWidth: 1,
9873
+ borderColor,
9874
+ borderRadius: px(colors.radius.sm),
9875
+ paddingHorizontal: px(colors.spacing["1"]),
9876
+ paddingVertical: 2,
9877
+ // Subtle bottom shadow gives the classic key look.
9878
+ ...reactNative.Platform.OS === "web" ? {
9879
+ boxShadow: `0 1px 0 ${borderColor}`,
9880
+ display: "inline-flex"
9881
+ } : {}
9882
+ };
9883
+ const textStyle = {
9884
+ color: textColor,
9885
+ // Monospace font for key labels.
9886
+ fontFamily: colors.fontFamily.mono ?? "monospace",
9887
+ fontSize: px(colors.fontSize.xs),
9888
+ fontWeight: colors.fontWeight.medium,
9889
+ lineHeight: px(colors.fontSize.xs) * Number(colors.lineHeight.normal)
9890
+ };
9891
+ const extraWebProps = reactNative.Platform.OS === "web" ? {
9892
+ // rn-web: 'none' skips the role attribute so the outer
9893
+ // View is just a plain <div>; we rely on the inner
9894
+ // <span> with data-kbd for semantic annotation.
9895
+ accessibilityRole: "none"
9896
+ } : {};
9897
+ return /* @__PURE__ */ jsxRuntime.jsx(
9898
+ reactNative.View,
9899
+ {
9900
+ ...extraWebProps,
9901
+ className: cn(
9902
+ "inline-flex flex-row items-center rounded-sm border px-1 py-0.5",
9903
+ isDark ? "bg-neutral-800 border-neutral-600 text-neutral-200" : "bg-neutral-100 border-neutral-300 text-neutral-700",
9904
+ className
9905
+ ),
9906
+ style: containerStyle,
9907
+ children: /* @__PURE__ */ jsxRuntime.jsx(
9908
+ reactNative.Text,
9909
+ {
9910
+ ...reactNative.Platform.OS === "web" ? { "data-kbd": "" } : {},
9911
+ accessibilityRole: "none",
9912
+ style: textStyle,
9913
+ children
9914
+ }
9915
+ )
9916
+ }
9917
+ );
9918
+ }, "Kbd");
9030
9919
  var Label = /* @__PURE__ */ __name(({ htmlFor, required = false, disabled = false, children, className, testID }) => {
9031
9920
  const colors = useThemeColors();
9032
9921
  const { t } = useTranslation();
@@ -9076,124 +9965,6 @@ var Label = /* @__PURE__ */ __name(({ htmlFor, required = false, disabled = fals
9076
9965
  }
9077
9966
  );
9078
9967
  }, "Label");
9079
- var range = /* @__PURE__ */ __name((from, to) => {
9080
- if (to < from) {
9081
- return [];
9082
- }
9083
- const out = new Array(to - from + 1);
9084
- for (let i = 0; i < out.length; i += 1) {
9085
- out[i] = from + i;
9086
- }
9087
- return out;
9088
- }, "range");
9089
- function usePagination(args) {
9090
- const {
9091
- page: controlledPage,
9092
- defaultPage = 1,
9093
- pageCount,
9094
- siblingCount = 1,
9095
- boundaryCount = 1,
9096
- showFirstLast = false,
9097
- showPrevNext = true,
9098
- onPageChange
9099
- } = args;
9100
- const isControlled = controlledPage !== void 0;
9101
- const [uncontrolledPage, setUncontrolledPage] = React.useState(defaultPage);
9102
- const onChangeRef = React.useRef(onPageChange);
9103
- onChangeRef.current = onPageChange;
9104
- const safePageCount = Math.max(1, Math.floor(pageCount));
9105
- const rawPage = isControlled ? controlledPage : uncontrolledPage;
9106
- const currentPage = Math.min(Math.max(1, Math.floor(rawPage)), safePageCount);
9107
- const goToPage = React.useCallback(
9108
- (next2) => {
9109
- const clamped = Math.min(Math.max(1, Math.floor(next2)), Math.max(1, Math.floor(pageCount)));
9110
- if (!isControlled) {
9111
- setUncontrolledPage(clamped);
9112
- }
9113
- onChangeRef.current?.(clamped);
9114
- },
9115
- [isControlled, pageCount]
9116
- );
9117
- const prev = React.useCallback(() => goToPage(currentPage - 1), [goToPage, currentPage]);
9118
- const next = React.useCallback(() => goToPage(currentPage + 1), [goToPage, currentPage]);
9119
- const first = React.useCallback(() => goToPage(1), [goToPage]);
9120
- const last = React.useCallback(() => goToPage(safePageCount), [goToPage, safePageCount]);
9121
- const pages = React.useMemo(() => {
9122
- const items = [];
9123
- const safeSibling = Math.max(0, Math.floor(siblingCount));
9124
- const safeBoundary = Math.max(0, Math.floor(boundaryCount));
9125
- if (showFirstLast) {
9126
- items.push({ type: "first", disabled: currentPage <= 1 });
9127
- }
9128
- if (showPrevNext) {
9129
- items.push({ type: "prev", disabled: currentPage <= 1 });
9130
- }
9131
- const startPages = range(1, Math.min(safeBoundary, safePageCount));
9132
- const endPages = range(Math.max(safePageCount - safeBoundary + 1, safeBoundary + 1), safePageCount);
9133
- const siblingsStart = Math.max(
9134
- Math.min(currentPage - safeSibling, safePageCount - safeBoundary - safeSibling * 2 - 1),
9135
- safeBoundary + 2
9136
- );
9137
- const siblingsEnd = Math.min(
9138
- Math.max(currentPage + safeSibling, safeBoundary + safeSibling * 2 + 2),
9139
- endPages.length > 0 ? endPages[0] - 2 : safePageCount - 1
9140
- );
9141
- const middle = [];
9142
- if (siblingsStart > safeBoundary + 2) {
9143
- middle.push("ellipsis");
9144
- } else if (safeBoundary + 1 < safePageCount - safeBoundary) {
9145
- middle.push(safeBoundary + 1);
9146
- }
9147
- for (const p of range(siblingsStart, siblingsEnd)) {
9148
- middle.push(p);
9149
- }
9150
- if (siblingsEnd < safePageCount - safeBoundary - 1) {
9151
- middle.push("ellipsis");
9152
- } else if (safePageCount - safeBoundary > safeBoundary) {
9153
- middle.push(safePageCount - safeBoundary);
9154
- }
9155
- const seen = /* @__PURE__ */ new Set();
9156
- const pushPage = /* @__PURE__ */ __name((n) => {
9157
- if (n < 1 || n > safePageCount || seen.has(n)) {
9158
- return;
9159
- }
9160
- seen.add(n);
9161
- items.push({ type: "page", page: n, selected: n === currentPage });
9162
- }, "pushPage");
9163
- for (const n of startPages) {
9164
- pushPage(n);
9165
- }
9166
- for (const m of middle) {
9167
- if (m === "ellipsis") {
9168
- items.push({ type: "ellipsis" });
9169
- } else {
9170
- pushPage(m);
9171
- }
9172
- }
9173
- for (const n of endPages) {
9174
- pushPage(n);
9175
- }
9176
- if (showPrevNext) {
9177
- items.push({ type: "next", disabled: currentPage >= safePageCount });
9178
- }
9179
- if (showFirstLast) {
9180
- items.push({ type: "last", disabled: currentPage >= safePageCount });
9181
- }
9182
- return items;
9183
- }, [currentPage, safePageCount, siblingCount, boundaryCount, showFirstLast, showPrevNext]);
9184
- return {
9185
- page: currentPage,
9186
- pages,
9187
- canPrev: currentPage > 1,
9188
- canNext: currentPage < safePageCount,
9189
- goToPage,
9190
- prev,
9191
- next,
9192
- first,
9193
- last
9194
- };
9195
- }
9196
- __name(usePagination, "usePagination");
9197
9968
  var PAGINATION_COMPACT_BREAKPOINT = 480;
9198
9969
  var PaginationContext = React.createContext(null);
9199
9970
  var usePaginationContext = /* @__PURE__ */ __name((label) => {
@@ -13297,25 +14068,32 @@ __name(Icon, "Icon");
13297
14068
  exports.Accordion = Accordion;
13298
14069
  exports.Alert = Alert;
13299
14070
  exports.AlertDialog = AlertDialog;
14071
+ exports.AspectRatio = AspectRatio;
13300
14072
  exports.Avatar = Avatar;
13301
14073
  exports.Badge = Badge;
13302
14074
  exports.Box = Box;
13303
14075
  exports.Breadcrumb = Breadcrumb;
13304
14076
  exports.Button = Button;
14077
+ exports.ButtonGroup = ButtonGroup;
13305
14078
  exports.Calendar = Calendar;
13306
14079
  exports.Card = Card;
13307
14080
  exports.Checkbox = Checkbox;
14081
+ exports.Collapsible = Collapsible;
13308
14082
  exports.Combobox = Combobox;
13309
14083
  exports.ContextMenu = ContextMenu;
14084
+ exports.DataTable = DataTable;
13310
14085
  exports.DatePicker = DatePicker;
13311
14086
  exports.Dialog = Dialog;
13312
14087
  exports.Drawer = Drawer;
13313
14088
  exports.DropdownMenu = DropdownMenu;
14089
+ exports.Empty = Empty;
13314
14090
  exports.Field = Field;
13315
14091
  exports.FloatButton = FloatButton;
13316
14092
  exports.HStack = HStack;
13317
14093
  exports.Icon = Icon;
13318
14094
  exports.InputGroup = InputGroup;
14095
+ exports.Item = Item;
14096
+ exports.Kbd = Kbd;
13319
14097
  exports.Label = Label;
13320
14098
  exports.MenuContent = MenuContent;
13321
14099
  exports.MenuItem = MenuItem;
@@ -13344,6 +14122,7 @@ exports.SliderGestureProvider = SliderGestureProvider;
13344
14122
  exports.Slot = Slot;
13345
14123
  exports.Spinner = Spinner;
13346
14124
  exports.Switch = Switch;
14125
+ exports.Table = Table;
13347
14126
  exports.Tabs = Tabs;
13348
14127
  exports.Text = Text;
13349
14128
  exports.TextArea = TextArea;