@nofinite/nui 1.1.1 → 2.0.1

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 (405) hide show
  1. package/README.md +61 -48
  2. package/dist/components/accordion/Accordion.cjs +1 -1
  3. package/dist/components/accordion/Accordion.cjs.map +1 -1
  4. package/dist/components/accordion/Accordion.js +64 -43
  5. package/dist/components/accordion/Accordion.js.map +1 -1
  6. package/dist/components/alert/Alert.cjs +1 -1
  7. package/dist/components/alert/Alert.cjs.map +1 -1
  8. package/dist/components/alert/Alert.js +39 -25
  9. package/dist/components/alert/Alert.js.map +1 -1
  10. package/dist/components/avatar/Avatar.cjs +1 -1
  11. package/dist/components/avatar/Avatar.cjs.map +1 -1
  12. package/dist/components/avatar/Avatar.js +58 -44
  13. package/dist/components/avatar/Avatar.js.map +1 -1
  14. package/dist/components/avatar/AvatarGroup.cjs +1 -1
  15. package/dist/components/avatar/AvatarGroup.cjs.map +1 -1
  16. package/dist/components/avatar/AvatarGroup.js +34 -25
  17. package/dist/components/avatar/AvatarGroup.js.map +1 -1
  18. package/dist/components/badge/Badge.cjs +1 -1
  19. package/dist/components/badge/Badge.cjs.map +1 -1
  20. package/dist/components/badge/Badge.js +43 -68
  21. package/dist/components/badge/Badge.js.map +1 -1
  22. package/dist/components/badge/BadgeGroup.cjs +1 -1
  23. package/dist/components/badge/BadgeGroup.cjs.map +1 -1
  24. package/dist/components/badge/BadgeGroup.js +20 -10
  25. package/dist/components/badge/BadgeGroup.js.map +1 -1
  26. package/dist/components/breadcrumbs/Breadcrumbs.cjs +1 -1
  27. package/dist/components/breadcrumbs/Breadcrumbs.cjs.map +1 -1
  28. package/dist/components/breadcrumbs/Breadcrumbs.js +59 -39
  29. package/dist/components/breadcrumbs/Breadcrumbs.js.map +1 -1
  30. package/dist/components/button/Button.cjs +1 -1
  31. package/dist/components/button/Button.cjs.map +1 -1
  32. package/dist/components/button/Button.js +52 -17
  33. package/dist/components/button/Button.js.map +1 -1
  34. package/dist/components/card/Card.cjs +1 -1
  35. package/dist/components/card/Card.cjs.map +1 -1
  36. package/dist/components/card/Card.js +44 -41
  37. package/dist/components/card/Card.js.map +1 -1
  38. package/dist/components/checkbox/Checkbox.cjs +1 -1
  39. package/dist/components/checkbox/Checkbox.cjs.map +1 -1
  40. package/dist/components/checkbox/Checkbox.js +59 -40
  41. package/dist/components/checkbox/Checkbox.js.map +1 -1
  42. package/dist/components/chip/Chip.cjs +1 -1
  43. package/dist/components/chip/Chip.cjs.map +1 -1
  44. package/dist/components/chip/Chip.js +67 -47
  45. package/dist/components/chip/Chip.js.map +1 -1
  46. package/dist/components/combobox/Combobox.cjs +1 -1
  47. package/dist/components/combobox/Combobox.cjs.map +1 -1
  48. package/dist/components/combobox/Combobox.js +123 -108
  49. package/dist/components/combobox/Combobox.js.map +1 -1
  50. package/dist/components/commandpalette/CommandPalette.cjs +1 -1
  51. package/dist/components/commandpalette/CommandPalette.cjs.map +1 -1
  52. package/dist/components/commandpalette/CommandPalette.js +96 -73
  53. package/dist/components/commandpalette/CommandPalette.js.map +1 -1
  54. package/dist/components/contextmenu/ContextMenu.cjs +1 -1
  55. package/dist/components/contextmenu/ContextMenu.cjs.map +1 -1
  56. package/dist/components/contextmenu/ContextMenu.js +79 -58
  57. package/dist/components/contextmenu/ContextMenu.js.map +1 -1
  58. package/dist/components/datagrid/DataGrid.cjs +1 -1
  59. package/dist/components/datagrid/DataGrid.cjs.map +1 -1
  60. package/dist/components/datagrid/DataGrid.js +184 -202
  61. package/dist/components/datagrid/DataGrid.js.map +1 -1
  62. package/dist/components/datepicker/DatePicker.cjs +1 -1
  63. package/dist/components/datepicker/DatePicker.cjs.map +1 -1
  64. package/dist/components/datepicker/DatePicker.js +197 -164
  65. package/dist/components/datepicker/DatePicker.js.map +1 -1
  66. package/dist/components/daterangepicker/DateRangePicker.cjs +1 -1
  67. package/dist/components/daterangepicker/DateRangePicker.cjs.map +1 -1
  68. package/dist/components/daterangepicker/DateRangePicker.js +254 -213
  69. package/dist/components/daterangepicker/DateRangePicker.js.map +1 -1
  70. package/dist/components/dialog/DialogProvider.cjs +2 -0
  71. package/dist/components/dialog/DialogProvider.cjs.map +1 -0
  72. package/dist/components/dialog/DialogProvider.js +71 -0
  73. package/dist/components/dialog/DialogProvider.js.map +1 -0
  74. package/dist/components/dialog/dialogStore.cjs +2 -0
  75. package/dist/components/dialog/dialogStore.cjs.map +1 -0
  76. package/dist/components/dialog/dialogStore.js +60 -0
  77. package/dist/components/dialog/dialogStore.js.map +1 -0
  78. package/dist/components/drawer/Drawer.cjs +1 -1
  79. package/dist/components/drawer/Drawer.cjs.map +1 -1
  80. package/dist/components/drawer/Drawer.js +69 -47
  81. package/dist/components/drawer/Drawer.js.map +1 -1
  82. package/dist/components/dropdown/Dropdown.cjs +1 -1
  83. package/dist/components/dropdown/Dropdown.cjs.map +1 -1
  84. package/dist/components/dropdown/Dropdown.js +134 -108
  85. package/dist/components/dropdown/Dropdown.js.map +1 -1
  86. package/dist/components/fileuploader/FileUploader.cjs +1 -1
  87. package/dist/components/fileuploader/FileUploader.cjs.map +1 -1
  88. package/dist/components/fileuploader/FileUploader.js +96 -61
  89. package/dist/components/fileuploader/FileUploader.js.map +1 -1
  90. package/dist/components/hovercard/HoverCard.cjs +1 -1
  91. package/dist/components/hovercard/HoverCard.cjs.map +1 -1
  92. package/dist/components/hovercard/HoverCard.js +124 -69
  93. package/dist/components/hovercard/HoverCard.js.map +1 -1
  94. package/dist/components/input/Input.cjs +1 -1
  95. package/dist/components/input/Input.cjs.map +1 -1
  96. package/dist/components/input/Input.js +62 -37
  97. package/dist/components/input/Input.js.map +1 -1
  98. package/dist/components/layout/Container.cjs +1 -1
  99. package/dist/components/layout/Container.cjs.map +1 -1
  100. package/dist/components/layout/Container.js +21 -30
  101. package/dist/components/layout/Container.js.map +1 -1
  102. package/dist/components/layout/Flex.cjs +1 -1
  103. package/dist/components/layout/Flex.cjs.map +1 -1
  104. package/dist/components/layout/Flex.js +36 -19
  105. package/dist/components/layout/Flex.js.map +1 -1
  106. package/dist/components/layout/Grid.cjs +1 -1
  107. package/dist/components/layout/Grid.cjs.map +1 -1
  108. package/dist/components/layout/Grid.js +30 -18
  109. package/dist/components/layout/Grid.js.map +1 -1
  110. package/dist/components/link/Link.cjs +2 -0
  111. package/dist/components/link/Link.cjs.map +1 -0
  112. package/dist/components/link/Link.js +41 -0
  113. package/dist/components/link/Link.js.map +1 -0
  114. package/dist/components/megamenu/MegaMenu.cjs +1 -1
  115. package/dist/components/megamenu/MegaMenu.cjs.map +1 -1
  116. package/dist/components/megamenu/MegaMenu.js +107 -38
  117. package/dist/components/megamenu/MegaMenu.js.map +1 -1
  118. package/dist/components/modal/Modal.cjs +1 -1
  119. package/dist/components/modal/Modal.cjs.map +1 -1
  120. package/dist/components/modal/Modal.js +91 -83
  121. package/dist/components/modal/Modal.js.map +1 -1
  122. package/dist/components/multiselect/MultiSelect.cjs +2 -0
  123. package/dist/components/multiselect/MultiSelect.cjs.map +1 -0
  124. package/dist/components/multiselect/MultiSelect.js +176 -0
  125. package/dist/components/multiselect/MultiSelect.js.map +1 -0
  126. package/dist/components/nuiprovider/NUIProvider.cjs +2 -0
  127. package/dist/components/nuiprovider/NUIProvider.cjs.map +1 -0
  128. package/dist/components/nuiprovider/NUIProvider.js +36 -0
  129. package/dist/components/nuiprovider/NUIProvider.js.map +1 -0
  130. package/dist/components/pagination/Pagination.cjs +1 -1
  131. package/dist/components/pagination/Pagination.cjs.map +1 -1
  132. package/dist/components/pagination/Pagination.js +74 -41
  133. package/dist/components/pagination/Pagination.js.map +1 -1
  134. package/dist/components/popover/Popover.cjs +1 -1
  135. package/dist/components/popover/Popover.cjs.map +1 -1
  136. package/dist/components/popover/Popover.js +99 -100
  137. package/dist/components/popover/Popover.js.map +1 -1
  138. package/dist/components/progress/Progress.cjs +1 -1
  139. package/dist/components/progress/Progress.cjs.map +1 -1
  140. package/dist/components/progress/Progress.js +44 -22
  141. package/dist/components/progress/Progress.js.map +1 -1
  142. package/dist/components/radiogroup/RadioGroup.cjs +1 -1
  143. package/dist/components/radiogroup/RadioGroup.cjs.map +1 -1
  144. package/dist/components/radiogroup/RadioGroup.js +69 -74
  145. package/dist/components/radiogroup/RadioGroup.js.map +1 -1
  146. package/dist/components/rating/Rating.cjs +1 -1
  147. package/dist/components/rating/Rating.cjs.map +1 -1
  148. package/dist/components/rating/Rating.js +72 -33
  149. package/dist/components/rating/Rating.js.map +1 -1
  150. package/dist/components/resizable/Resizable.cjs +2 -0
  151. package/dist/components/resizable/Resizable.cjs.map +1 -0
  152. package/dist/components/resizable/Resizable.js +134 -0
  153. package/dist/components/resizable/Resizable.js.map +1 -0
  154. package/dist/components/select/Select.cjs +1 -1
  155. package/dist/components/select/Select.cjs.map +1 -1
  156. package/dist/components/select/Select.js +114 -113
  157. package/dist/components/select/Select.js.map +1 -1
  158. package/dist/components/skeleton/Skeleton.cjs +1 -1
  159. package/dist/components/skeleton/Skeleton.cjs.map +1 -1
  160. package/dist/components/skeleton/Skeleton.js +90 -67
  161. package/dist/components/skeleton/Skeleton.js.map +1 -1
  162. package/dist/components/slider/Slider.cjs +1 -1
  163. package/dist/components/slider/Slider.cjs.map +1 -1
  164. package/dist/components/slider/Slider.js +85 -82
  165. package/dist/components/slider/Slider.js.map +1 -1
  166. package/dist/components/spinner/Spinner.cjs +1 -1
  167. package/dist/components/spinner/Spinner.cjs.map +1 -1
  168. package/dist/components/spinner/Spinner.js +60 -17
  169. package/dist/components/spinner/Spinner.js.map +1 -1
  170. package/dist/components/stepper/Stepper.cjs +1 -5
  171. package/dist/components/stepper/Stepper.cjs.map +1 -1
  172. package/dist/components/stepper/Stepper.js +65 -39
  173. package/dist/components/stepper/Stepper.js.map +1 -1
  174. package/dist/components/switch/Switch.cjs +1 -1
  175. package/dist/components/switch/Switch.cjs.map +1 -1
  176. package/dist/components/switch/Switch.js +89 -62
  177. package/dist/components/switch/Switch.js.map +1 -1
  178. package/dist/components/table/Table.cjs +1 -1
  179. package/dist/components/table/Table.cjs.map +1 -1
  180. package/dist/components/table/Table.js +62 -35
  181. package/dist/components/table/Table.js.map +1 -1
  182. package/dist/components/tabs/Tabs.cjs +1 -1
  183. package/dist/components/tabs/Tabs.cjs.map +1 -1
  184. package/dist/components/tabs/Tabs.js +110 -50
  185. package/dist/components/tabs/Tabs.js.map +1 -1
  186. package/dist/components/textarea/Textarea.cjs +1 -1
  187. package/dist/components/textarea/Textarea.cjs.map +1 -1
  188. package/dist/components/textarea/Textarea.js +63 -58
  189. package/dist/components/textarea/Textarea.js.map +1 -1
  190. package/dist/components/timepicker/TimePicker.cjs +2 -0
  191. package/dist/components/timepicker/TimePicker.cjs.map +1 -0
  192. package/dist/components/timepicker/TimePicker.js +159 -0
  193. package/dist/components/timepicker/TimePicker.js.map +1 -0
  194. package/dist/components/timerangepicker/TimeRangePicker.cjs +2 -0
  195. package/dist/components/timerangepicker/TimeRangePicker.cjs.map +1 -0
  196. package/dist/components/timerangepicker/TimeRangePicker.js +208 -0
  197. package/dist/components/timerangepicker/TimeRangePicker.js.map +1 -0
  198. package/dist/components/toast/Toast.cjs +1 -1
  199. package/dist/components/toast/Toast.cjs.map +1 -1
  200. package/dist/components/toast/Toast.js +91 -38
  201. package/dist/components/toast/Toast.js.map +1 -1
  202. package/dist/components/tooltip/Tooltip.cjs +1 -1
  203. package/dist/components/tooltip/Tooltip.cjs.map +1 -1
  204. package/dist/components/tooltip/Tooltip.js +72 -56
  205. package/dist/components/tooltip/Tooltip.js.map +1 -1
  206. package/dist/components/treeview/TreeView.cjs +1 -1
  207. package/dist/components/treeview/TreeView.cjs.map +1 -1
  208. package/dist/components/treeview/TreeView.js +120 -90
  209. package/dist/components/treeview/TreeView.js.map +1 -1
  210. package/dist/components/virtuallist/VirtualList.cjs +1 -1
  211. package/dist/components/virtuallist/VirtualList.cjs.map +1 -1
  212. package/dist/components/virtuallist/VirtualList.js +52 -34
  213. package/dist/components/virtuallist/VirtualList.js.map +1 -1
  214. package/dist/index.cjs +1 -1
  215. package/dist/index.css +1 -0
  216. package/dist/index.js +118 -107
  217. package/dist/index.js.map +1 -1
  218. package/dist/package.json +49 -6
  219. package/dist/types/components/accordion/Accordion.d.ts +7 -3
  220. package/dist/types/components/accordion/Accordion.d.ts.map +1 -1
  221. package/dist/types/components/alert/Alert.d.ts +18 -5
  222. package/dist/types/components/alert/Alert.d.ts.map +1 -1
  223. package/dist/types/components/avatar/Avatar.d.ts +12 -8
  224. package/dist/types/components/avatar/Avatar.d.ts.map +1 -1
  225. package/dist/types/components/avatar/AvatarGroup.d.ts +11 -4
  226. package/dist/types/components/avatar/AvatarGroup.d.ts.map +1 -1
  227. package/dist/types/components/badge/Badge.d.ts +19 -11
  228. package/dist/types/components/badge/Badge.d.ts.map +1 -1
  229. package/dist/types/components/badge/BadgeGroup.d.ts +7 -4
  230. package/dist/types/components/badge/BadgeGroup.d.ts.map +1 -1
  231. package/dist/types/components/breadcrumbs/Breadcrumbs.d.ts +14 -6
  232. package/dist/types/components/breadcrumbs/Breadcrumbs.d.ts.map +1 -1
  233. package/dist/types/components/button/Button.d.ts +25 -10
  234. package/dist/types/components/button/Button.d.ts.map +1 -1
  235. package/dist/types/components/card/Card.d.ts +12 -21
  236. package/dist/types/components/card/Card.d.ts.map +1 -1
  237. package/dist/types/components/checkbox/Checkbox.d.ts +12 -7
  238. package/dist/types/components/checkbox/Checkbox.d.ts.map +1 -1
  239. package/dist/types/components/chip/Chip.d.ts +14 -11
  240. package/dist/types/components/chip/Chip.d.ts.map +1 -1
  241. package/dist/types/components/combobox/Combobox.d.ts +15 -4
  242. package/dist/types/components/combobox/Combobox.d.ts.map +1 -1
  243. package/dist/types/components/commandpalette/CommandPalette.d.ts +12 -3
  244. package/dist/types/components/commandpalette/CommandPalette.d.ts.map +1 -1
  245. package/dist/types/components/contextmenu/ContextMenu.d.ts +14 -6
  246. package/dist/types/components/contextmenu/ContextMenu.d.ts.map +1 -1
  247. package/dist/types/components/datagrid/DataGrid.d.ts +16 -4
  248. package/dist/types/components/datagrid/DataGrid.d.ts.map +1 -1
  249. package/dist/types/components/datepicker/DatePicker.d.ts +13 -1
  250. package/dist/types/components/datepicker/DatePicker.d.ts.map +1 -1
  251. package/dist/types/components/daterangepicker/DateRangePicker.d.ts +3 -1
  252. package/dist/types/components/daterangepicker/DateRangePicker.d.ts.map +1 -1
  253. package/dist/types/components/dialog/DialogProvider.d.ts +2 -0
  254. package/dist/types/components/dialog/DialogProvider.d.ts.map +1 -0
  255. package/dist/types/components/dialog/dialogStore.d.ts +42 -0
  256. package/dist/types/components/dialog/dialogStore.d.ts.map +1 -0
  257. package/dist/types/components/drawer/Drawer.d.ts +18 -4
  258. package/dist/types/components/drawer/Drawer.d.ts.map +1 -1
  259. package/dist/types/components/dropdown/Dropdown.d.ts +21 -16
  260. package/dist/types/components/dropdown/Dropdown.d.ts.map +1 -1
  261. package/dist/types/components/fileuploader/FileUploader.d.ts +22 -3
  262. package/dist/types/components/fileuploader/FileUploader.d.ts.map +1 -1
  263. package/dist/types/components/hovercard/HoverCard.d.ts +45 -5
  264. package/dist/types/components/hovercard/HoverCard.d.ts.map +1 -1
  265. package/dist/types/components/input/Input.d.ts +20 -10
  266. package/dist/types/components/input/Input.d.ts.map +1 -1
  267. package/dist/types/components/layout/Container.d.ts +8 -4
  268. package/dist/types/components/layout/Container.d.ts.map +1 -1
  269. package/dist/types/components/layout/Flex.d.ts +27 -10
  270. package/dist/types/components/layout/Flex.d.ts.map +1 -1
  271. package/dist/types/components/layout/Grid.d.ts +11 -5
  272. package/dist/types/components/layout/Grid.d.ts.map +1 -1
  273. package/dist/types/components/link/Link.d.ts +22 -0
  274. package/dist/types/components/link/Link.d.ts.map +1 -0
  275. package/dist/types/components/megamenu/MegaMenu.d.ts +8 -11
  276. package/dist/types/components/megamenu/MegaMenu.d.ts.map +1 -1
  277. package/dist/types/components/modal/Modal.d.ts +8 -7
  278. package/dist/types/components/modal/Modal.d.ts.map +1 -1
  279. package/dist/types/components/multiselect/MultiSelect.d.ts +33 -0
  280. package/dist/types/components/multiselect/MultiSelect.d.ts.map +1 -0
  281. package/dist/types/components/nuiprovider/NUIProvider.d.ts +29 -0
  282. package/dist/types/components/nuiprovider/NUIProvider.d.ts.map +1 -0
  283. package/dist/types/components/pagination/Pagination.d.ts +17 -3
  284. package/dist/types/components/pagination/Pagination.d.ts.map +1 -1
  285. package/dist/types/components/popover/Popover.d.ts +54 -16
  286. package/dist/types/components/popover/Popover.d.ts.map +1 -1
  287. package/dist/types/components/progress/Progress.d.ts +17 -7
  288. package/dist/types/components/progress/Progress.d.ts.map +1 -1
  289. package/dist/types/components/radiogroup/RadioGroup.d.ts +15 -10
  290. package/dist/types/components/radiogroup/RadioGroup.d.ts.map +1 -1
  291. package/dist/types/components/rating/Rating.d.ts +24 -10
  292. package/dist/types/components/rating/Rating.d.ts.map +1 -1
  293. package/dist/types/components/resizable/Resizable.d.ts +24 -0
  294. package/dist/types/components/resizable/Resizable.d.ts.map +1 -0
  295. package/dist/types/components/select/Select.d.ts +17 -8
  296. package/dist/types/components/select/Select.d.ts.map +1 -1
  297. package/dist/types/components/skeleton/Skeleton.d.ts +37 -36
  298. package/dist/types/components/skeleton/Skeleton.d.ts.map +1 -1
  299. package/dist/types/components/slider/Slider.d.ts +15 -4
  300. package/dist/types/components/slider/Slider.d.ts.map +1 -1
  301. package/dist/types/components/spinner/Spinner.d.ts +14 -4
  302. package/dist/types/components/spinner/Spinner.d.ts.map +1 -1
  303. package/dist/types/components/stepper/Stepper.d.ts +17 -3
  304. package/dist/types/components/stepper/Stepper.d.ts.map +1 -1
  305. package/dist/types/components/switch/Switch.d.ts +20 -5
  306. package/dist/types/components/switch/Switch.d.ts.map +1 -1
  307. package/dist/types/components/table/Table.d.ts +24 -4
  308. package/dist/types/components/table/Table.d.ts.map +1 -1
  309. package/dist/types/components/tabs/Tabs.d.ts +25 -12
  310. package/dist/types/components/tabs/Tabs.d.ts.map +1 -1
  311. package/dist/types/components/textarea/Textarea.d.ts +8 -5
  312. package/dist/types/components/textarea/Textarea.d.ts.map +1 -1
  313. package/dist/types/components/timepicker/TimePicker.d.ts +26 -0
  314. package/dist/types/components/timepicker/TimePicker.d.ts.map +1 -0
  315. package/dist/types/components/timerangepicker/TimeRangePicker.d.ts +32 -0
  316. package/dist/types/components/timerangepicker/TimeRangePicker.d.ts.map +1 -0
  317. package/dist/types/components/toast/Toast.d.ts +23 -7
  318. package/dist/types/components/toast/Toast.d.ts.map +1 -1
  319. package/dist/types/components/tooltip/Tooltip.d.ts +13 -2
  320. package/dist/types/components/tooltip/Tooltip.d.ts.map +1 -1
  321. package/dist/types/components/treeview/TreeView.d.ts +20 -6
  322. package/dist/types/components/treeview/TreeView.d.ts.map +1 -1
  323. package/dist/types/components/virtuallist/VirtualList.d.ts +12 -16
  324. package/dist/types/components/virtuallist/VirtualList.d.ts.map +1 -1
  325. package/dist/types/index.d.ts +8 -4
  326. package/dist/types/index.d.ts.map +1 -1
  327. package/dist/types/utils/cn/cn.d.ts +19 -0
  328. package/dist/types/utils/cn/cn.d.ts.map +1 -0
  329. package/dist/types/utils/generateid/generateId.d.ts +7 -0
  330. package/dist/types/utils/generateid/generateId.d.ts.map +1 -1
  331. package/dist/types/utils/index.d.ts +2 -0
  332. package/dist/types/utils/index.d.ts.map +1 -1
  333. package/dist/types/utils/inertmanager/inertManager.d.ts +13 -0
  334. package/dist/types/utils/inertmanager/inertManager.d.ts.map +1 -1
  335. package/dist/types/utils/keyboardnav/keyboardNav.d.ts +17 -6
  336. package/dist/types/utils/keyboardnav/keyboardNav.d.ts.map +1 -1
  337. package/dist/types/utils/onclickoutside/onClickOutside.d.ts +9 -1
  338. package/dist/types/utils/onclickoutside/onClickOutside.d.ts.map +1 -1
  339. package/dist/types/utils/portal/portal.d.ts +14 -1
  340. package/dist/types/utils/portal/portal.d.ts.map +1 -1
  341. package/dist/types/utils/restorefocus/restoreFocus.d.ts +8 -4
  342. package/dist/types/utils/restorefocus/restoreFocus.d.ts.map +1 -1
  343. package/dist/types/utils/scrolllock/scrollLock.d.ts +10 -2
  344. package/dist/types/utils/scrolllock/scrollLock.d.ts.map +1 -1
  345. package/dist/types/utils/slot/slot.d.ts +12 -0
  346. package/dist/types/utils/slot/slot.d.ts.map +1 -0
  347. package/dist/types/utils/trapfocus/trapFocus.d.ts +6 -2
  348. package/dist/types/utils/trapfocus/trapFocus.d.ts.map +1 -1
  349. package/dist/utils/cn/cn.cjs +2 -0
  350. package/dist/utils/cn/cn.cjs.map +1 -0
  351. package/dist/utils/cn/cn.js +21 -0
  352. package/dist/utils/cn/cn.js.map +1 -0
  353. package/dist/utils/inertmanager/inertManager.cjs.map +1 -1
  354. package/dist/utils/inertmanager/inertManager.js.map +1 -1
  355. package/dist/utils/onclickoutside/onClickOutside.cjs +1 -1
  356. package/dist/utils/onclickoutside/onClickOutside.cjs.map +1 -1
  357. package/dist/utils/onclickoutside/onClickOutside.js +10 -6
  358. package/dist/utils/onclickoutside/onClickOutside.js.map +1 -1
  359. package/dist/utils/portal/portal.cjs.map +1 -1
  360. package/dist/utils/portal/portal.js.map +1 -1
  361. package/dist/utils/restorefocus/restoreFocus.cjs.map +1 -1
  362. package/dist/utils/restorefocus/restoreFocus.js.map +1 -1
  363. package/dist/utils/scrolllock/scrollLock.cjs.map +1 -1
  364. package/dist/utils/scrolllock/scrollLock.js +7 -0
  365. package/dist/utils/scrolllock/scrollLock.js.map +1 -1
  366. package/dist/utils/slot/slot.cjs +2 -0
  367. package/dist/utils/slot/slot.cjs.map +1 -0
  368. package/dist/utils/slot/slot.js +57 -0
  369. package/dist/utils/slot/slot.js.map +1 -0
  370. package/dist/utils/trapfocus/trapFocus.cjs.map +1 -1
  371. package/dist/utils/trapfocus/trapFocus.js.map +1 -1
  372. package/package.json +49 -6
  373. package/dist/components/layout/HStack.cjs +0 -2
  374. package/dist/components/layout/HStack.cjs.map +0 -1
  375. package/dist/components/layout/HStack.js +0 -9
  376. package/dist/components/layout/HStack.js.map +0 -1
  377. package/dist/components/layout/Stack.cjs +0 -2
  378. package/dist/components/layout/Stack.cjs.map +0 -1
  379. package/dist/components/layout/Stack.js +0 -9
  380. package/dist/components/layout/Stack.js.map +0 -1
  381. package/dist/styles/nui.css +0 -1
  382. package/dist/theme/NUIProvider.cjs +0 -2
  383. package/dist/theme/NUIProvider.cjs.map +0 -1
  384. package/dist/theme/NUIProvider.js +0 -34
  385. package/dist/theme/NUIProvider.js.map +0 -1
  386. package/dist/theme/useTheme.cjs +0 -2
  387. package/dist/theme/useTheme.cjs.map +0 -1
  388. package/dist/theme/useTheme.js +0 -9
  389. package/dist/theme/useTheme.js.map +0 -1
  390. package/dist/types/components/layout/HStack.d.ts +0 -8
  391. package/dist/types/components/layout/HStack.d.ts.map +0 -1
  392. package/dist/types/components/layout/Stack.d.ts +0 -8
  393. package/dist/types/components/layout/Stack.d.ts.map +0 -1
  394. package/dist/types/theme/NUIProvider.d.ts +0 -14
  395. package/dist/types/theme/NUIProvider.d.ts.map +0 -1
  396. package/dist/types/theme/useTheme.d.ts +0 -11
  397. package/dist/types/theme/useTheme.d.ts.map +0 -1
  398. package/dist/utils/generateid/generateId.cjs +0 -2
  399. package/dist/utils/generateid/generateId.cjs.map +0 -1
  400. package/dist/utils/generateid/generateId.js +0 -7
  401. package/dist/utils/generateid/generateId.js.map +0 -1
  402. package/dist/utils/keyboardnav/keyboardNav.cjs +0 -2
  403. package/dist/utils/keyboardnav/keyboardNav.cjs.map +0 -1
  404. package/dist/utils/keyboardnav/keyboardNav.js +0 -10
  405. package/dist/utils/keyboardnav/keyboardNav.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Switch.cjs","sources":["../../../src/components/switch/Switch.tsx"],"sourcesContent":["/**\r\n * Switch.tsx\r\n * ----------\r\n * Accessible Toggle / Switch component.\r\n *\r\n * Features:\r\n * - role=\"switch\" semantics\r\n * - aria-checked driven\r\n * - keyboard (Space toggles)\r\n * - controlled + uncontrolled\r\n * - disabled support\r\n * - label support\r\n * - no external deps\r\n */\r\n/**\r\n * Switch.tsx (Lint-Clean Version)\r\n * Fully accessible toggle switch.\r\n */\r\n\r\nimport React, { useEffect, useRef } from 'react';\r\nimport './Switch.css';\r\n\r\ninterface SwitchProps {\r\n checked?: boolean;\r\n defaultChecked?: boolean;\r\n onChange?: (checked: boolean) => void;\r\n\r\n disabled?: boolean;\r\n label?: React.ReactNode;\r\n id?: string;\r\n name?: string;\r\n value?: string;\r\n className?: string;\r\n}\r\n\r\nexport function Switch({\r\n checked,\r\n defaultChecked,\r\n onChange,\r\n disabled = false,\r\n label,\r\n id,\r\n name,\r\n value,\r\n className = '',\r\n}: SwitchProps) {\r\n const isControlled = checked !== undefined;\r\n\r\n const [internal, setInternal] = React.useState(defaultChecked ?? false);\r\n const current = isControlled ? checked : internal;\r\n\r\n const controlRef = useRef<HTMLButtonElement | null>(null);\r\n\r\n /**\r\n * FIX → Always call useId at top level.\r\n */\r\n const internalId = React.useId();\r\n const finalId = id ?? internalId;\r\n\r\n /**\r\n * Spacebar toggling (keyboard)\r\n */\r\n useEffect(() => {\r\n const el = controlRef.current;\r\n if (!el) return;\r\n\r\n const handler = (e: KeyboardEvent) => {\r\n if (disabled) return;\r\n\r\n if (e.key === ' ' || e.key === 'Spacebar') {\r\n e.preventDefault();\r\n const next = !current;\r\n\r\n if (!isControlled) setInternal(next);\r\n onChange?.(next);\r\n }\r\n };\r\n\r\n el.addEventListener('keydown', handler);\r\n return () => {\r\n el.removeEventListener('keydown', handler);\r\n };\r\n }, [current, disabled, isControlled, onChange]);\r\n\r\n /**\r\n * Toggle function no non-null assertions.\r\n */\r\n const toggle = () => {\r\n if (disabled) return;\r\n const next = !current;\r\n\r\n if (!isControlled) setInternal(next);\r\n onChange?.(next);\r\n\r\n // Restore focus safely\r\n if (controlRef.current) {\r\n controlRef.current.focus();\r\n }\r\n };\r\n\r\n // Hidden input for form\r\n const hiddenValue = value ?? (current ? 'on' : 'off');\r\n\r\n return (\r\n <label\r\n className={`ui-switch-root ${className}`}\r\n htmlFor={finalId}\r\n aria-disabled={disabled || undefined}\r\n >\r\n {name && (\r\n <input type=\"hidden\" name={name} value={current ? hiddenValue : ''} />\r\n )}\r\n\r\n <button\r\n id={finalId}\r\n ref={controlRef}\r\n type=\"button\"\r\n role=\"switch\"\r\n aria-checked={current}\r\n aria-disabled={disabled || undefined}\r\n className=\"ui-switch-control\"\r\n data-state={current ? 'on' : 'off'}\r\n onClick={toggle}\r\n tabIndex={disabled ? -1 : 0}\r\n >\r\n <span className=\"ui-switch-thumb\" aria-hidden=\"true\" />\r\n </button>\r\n\r\n {label && <span className=\"ui-switch-label\">{label}</span>}\r\n </label>\r\n );\r\n}\r\n"],"names":["Switch","checked","defaultChecked","onChange","disabled","label","id","name","value","className","isControlled","internal","setInternal","React","current","controlRef","useRef","internalId","finalId","useEffect","el","handler","e","next","toggle","hiddenValue","jsxs","jsx"],"mappings":"oKAmCO,SAASA,EAAO,CACrB,QAAAC,EACA,eAAAC,EACA,SAAAC,EACA,SAAAC,EAAW,GACX,MAAAC,EACA,GAAAC,EACA,KAAAC,EACA,MAAAC,EACA,UAAAC,EAAY,EACd,EAAgB,CACd,MAAMC,EAAeT,IAAY,OAE3B,CAACU,EAAUC,CAAW,EAAIC,EAAM,SAASX,GAAkB,EAAK,EAChEY,EAAUJ,EAAeT,EAAUU,EAEnCI,EAAaC,EAAAA,OAAiC,IAAI,EAKlDC,EAAaJ,EAAM,MAAA,EACnBK,EAAUZ,GAAMW,EAKtBE,EAAAA,UAAU,IAAM,CACd,MAAMC,EAAKL,EAAW,QACtB,GAAI,CAACK,EAAI,OAET,MAAMC,EAAWC,GAAqB,CACpC,GAAI,CAAAlB,IAEAkB,EAAE,MAAQ,KAAOA,EAAE,MAAQ,YAAY,CACzCA,EAAE,eAAA,EACF,MAAMC,EAAO,CAACT,EAETJ,GAAcE,EAAYW,CAAI,EACnCpB,IAAWoB,CAAI,CACjB,CACF,EAEA,OAAAH,EAAG,iBAAiB,UAAWC,CAAO,EAC/B,IAAM,CACXD,EAAG,oBAAoB,UAAWC,CAAO,CAC3C,CACF,EAAG,CAACP,EAASV,EAAUM,EAAcP,CAAQ,CAAC,EAK9C,MAAMqB,EAAS,IAAM,CACnB,GAAIpB,EAAU,OACd,MAAMmB,EAAO,CAACT,EAETJ,GAAcE,EAAYW,CAAI,EACnCpB,IAAWoB,CAAI,EAGXR,EAAW,SACbA,EAAW,QAAQ,MAAA,CAEvB,EAGMU,EAAcjB,IAAUM,EAAU,KAAO,OAE/C,OACEY,EAAAA,KAAC,QAAA,CACC,UAAW,kBAAkBjB,CAAS,GACtC,QAASS,EACT,gBAAed,GAAY,OAE1B,SAAA,CAAAG,GACCoB,EAAAA,IAAC,SAAM,KAAK,SAAS,KAAApB,EAAY,MAAOO,EAAUW,EAAc,EAAA,CAAI,EAGtEE,EAAAA,IAAC,SAAA,CACC,GAAIT,EACJ,IAAKH,EACL,KAAK,SACL,KAAK,SACL,eAAcD,EACd,gBAAeV,GAAY,OAC3B,UAAU,oBACV,aAAYU,EAAU,KAAO,MAC7B,QAASU,EACT,SAAUpB,EAAW,GAAK,EAE1B,SAAAuB,EAAAA,IAAC,OAAA,CAAK,UAAU,kBAAkB,cAAY,MAAA,CAAO,CAAA,CAAA,EAGtDtB,GAASsB,EAAAA,IAAC,OAAA,CAAK,UAAU,kBAAmB,SAAAtB,CAAA,CAAM,CAAA,CAAA,CAAA,CAGzD"}
1
+ {"version":3,"file":"Switch.cjs","sources":["../../../src/components/switch/Switch.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { forwardRef, useId, useState } from 'react';\nimport { cn } from '../../utils';\nimport './Switch.css';\n\n/* ============================================================\n * Types\n * ============================================================ */\n\nexport interface SwitchProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onChange' | 'value'> {\n /** The controlled checked state of the switch */\n checked?: boolean;\n /** The uncontrolled default checked state */\n defaultChecked?: boolean;\n /** Callback fired when the state changes */\n onChange?: (checked: boolean) => void;\n \n /** Disables the switch, preventing interaction */\n disabled?: boolean;\n /** The primary text label for the switch */\n label?: React.ReactNode;\n /** Secondary descriptive text linked via WAI-ARIA */\n description?: React.ReactNode;\n \n /** Name attribute for native form submission */\n name?: string;\n /** Value submitted in a native form when checked. Defaults to \"on\". */\n value?: string;\n /** The visual size variant. Defaults to 'md'. */\n size?: 'sm' | 'md';\n \n /** Additional CSS classes for the outer wrapping div */\n wrapperClassName?: string;\n}\n\n/* ============================================================\n * Component\n * ============================================================ */\n\n/**\n * Switch Component\n * * A WAI-ARIA compliant toggle switch used to turn settings on or off.\n * * Automatically handles native form submission using a hidden input.\n */\nexport const Switch = forwardRef<HTMLButtonElement, SwitchProps>(\n (\n {\n checked,\n defaultChecked,\n onChange,\n disabled = false,\n label,\n description,\n id,\n name,\n value,\n size = 'md',\n className,\n wrapperClassName,\n ...props\n },\n ref\n ) => {\n // Unique ID generation for WCAG label and description linkage\n const reactId = useId();\n const switchId = id ?? `nui-switch-${reactId}`;\n const descriptionId = `${switchId}-description`;\n\n // State Management\n const isControlled = checked !== undefined;\n const [internalChecked, setInternalChecked] = useState(defaultChecked ?? false);\n const currentChecked = isControlled ? checked : internalChecked;\n\n const toggle = () => {\n if (disabled) return;\n const nextState = !currentChecked;\n if (!isControlled) setInternalChecked(nextState);\n onChange?.(nextState);\n };\n\n // Keyboard Accessibility (Space & Enter)\n const handleKeyDown = (e: React.KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault(); // Prevent page scroll on Spacebar\n toggle();\n }\n props.onKeyDown?.(e);\n };\n\n // Robust Label Click Handler\n // Standard <label> clicks only *focus* <button> elements in Safari/Firefox. \n // This handler ensures clicking the text always toggles the state.\n const handleLabelClick = (e: React.MouseEvent) => {\n if (disabled) return;\n e.preventDefault(); \n toggle();\n document.getElementById(switchId)?.focus();\n };\n\n // Hidden input value for standard HTML form submissions\n const hiddenValue = value ?? (currentChecked ? 'on' : 'off');\n\n return (\n <div \n className={cn(\n \"nui-switch-wrapper\", \n disabled && \"nui-switch-wrapper--disabled\", \n wrapperClassName\n )}\n >\n {/* Hidden Form Input */}\n {name && (\n <input type=\"hidden\" name={name} value={currentChecked ? hiddenValue : ''} />\n )}\n\n {/* The Actual Switch (Button) */}\n <button\n ref={ref}\n id={switchId}\n type=\"button\"\n role=\"switch\"\n aria-checked={currentChecked}\n aria-disabled={disabled}\n aria-describedby={description ? descriptionId : undefined}\n className={cn(\n \"nui-switch\",\n `nui-switch--${size}`,\n currentChecked && \"nui-switch--checked\",\n className\n )}\n onClick={toggle}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n {...props}\n >\n <span \n className={cn(\n \"nui-switch__thumb\", \n `nui-switch__thumb--${size}`, \n currentChecked && \"nui-switch__thumb--checked\"\n )} \n aria-hidden=\"true\" \n />\n </button>\n\n {/* Text Content */}\n {(label || description) && (\n <div className=\"nui-switch__text-container\">\n {label && (\n <label \n htmlFor={switchId} \n className=\"nui-switch__label\"\n onClick={handleLabelClick}\n >\n {label}\n </label>\n )}\n {description && (\n <div id={descriptionId} className=\"nui-switch__description\">\n {description}\n </div>\n )}\n </div>\n )}\n </div>\n );\n }\n);\n\nSwitch.displayName = 'Switch';"],"names":["Switch","forwardRef","checked","defaultChecked","onChange","disabled","label","description","id","name","value","size","className","wrapperClassName","props","ref","reactId","useId","switchId","descriptionId","isControlled","internalChecked","setInternalChecked","useState","currentChecked","toggle","nextState","handleKeyDown","handleLabelClick","hiddenValue","jsxs","cn","jsx"],"mappings":"6MA6CaA,EAASC,EAAAA,WACpB,CACE,CACE,QAAAC,EACA,eAAAC,EACA,SAAAC,EACA,SAAAC,EAAW,GACX,MAAAC,EACA,YAAAC,EACA,GAAAC,EACA,KAAAC,EACA,MAAAC,EACA,KAAAC,EAAO,KACP,UAAAC,EACA,iBAAAC,EACA,GAAGC,CAAA,EAELC,IACG,CAEH,MAAMC,EAAUC,EAAAA,MAAA,EACVC,EAAWV,GAAM,cAAcQ,CAAO,GACtCG,EAAgB,GAAGD,CAAQ,eAG3BE,EAAelB,IAAY,OAC3B,CAACmB,EAAiBC,CAAkB,EAAIC,EAAAA,SAASpB,GAAkB,EAAK,EACxEqB,EAAiBJ,EAAelB,EAAUmB,EAE1CI,EAAS,IAAM,CACnB,GAAIpB,EAAU,OACd,MAAMqB,EAAY,CAACF,EACdJ,GAAcE,EAAmBI,CAAS,EAC/CtB,IAAWsB,CAAS,CACtB,EAGMC,EAAiB,GAA8C,EAC/D,EAAE,MAAQ,KAAO,EAAE,MAAQ,WAC7B,EAAE,eAAA,EACFF,EAAA,GAEFX,EAAM,YAAY,CAAC,CACrB,EAKMc,EAAoB,GAAwB,CAC5CvB,IACJ,EAAE,eAAA,EACFoB,EAAA,EACA,SAAS,eAAeP,CAAQ,GAAG,MAAA,EACrC,EAGMW,EAAcnB,IAAUc,EAAiB,KAAO,OAEtD,OACEM,EAAAA,KAAC,MAAA,CACC,UAAWC,EAAAA,GACT,qBACA1B,GAAY,+BACZQ,CAAA,EAID,SAAA,CAAAJ,GACCuB,EAAAA,IAAC,SAAM,KAAK,SAAS,KAAAvB,EAAY,MAAOe,EAAiBK,EAAc,EAAA,CAAI,EAI7EG,EAAAA,IAAC,SAAA,CACC,IAAAjB,EACA,GAAIG,EACJ,KAAK,SACL,KAAK,SACL,eAAcM,EACd,gBAAenB,EACf,mBAAkBE,EAAcY,EAAgB,OAChD,UAAWY,EAAAA,GACT,aACA,eAAepB,CAAI,GACnBa,GAAkB,sBAClBZ,CAAA,EAEF,QAASa,EACT,UAAWE,EACX,SAAAtB,EACC,GAAGS,EAEJ,SAAAkB,EAAAA,IAAC,OAAA,CACC,UAAWD,EAAAA,GACT,oBACA,sBAAsBpB,CAAI,GAC1Ba,GAAkB,4BAAA,EAEpB,cAAY,MAAA,CAAA,CACd,CAAA,GAIAlB,GAASC,IACTuB,EAAAA,KAAC,MAAA,CAAI,UAAU,6BACZ,SAAA,CAAAxB,GACC0B,EAAAA,IAAC,QAAA,CACC,QAASd,EACT,UAAU,oBACV,QAASU,EAER,SAAAtB,CAAA,CAAA,EAGJC,GACCyB,EAAAA,IAAC,MAAA,CAAI,GAAIb,EAAe,UAAU,0BAC/B,SAAAZ,CAAA,CACH,CAAA,CAAA,CAEJ,CAAA,CAAA,CAAA,CAIR,CACF,EAEAP,EAAO,YAAc"}
@@ -1,67 +1,94 @@
1
- import { jsxs as E, jsx as i } from "react/jsx-runtime";
2
- import p, { useRef as R, useEffect as S } from "react";
1
+ import { jsxs as f, jsx as i } from "react/jsx-runtime";
2
+ import { forwardRef as g, useId as K, useState as j } from "react";
3
3
  /* empty css */
4
- function F({
5
- checked: a,
6
- defaultChecked: v,
7
- onChange: s,
8
- disabled: e = !1,
9
- label: u,
10
- id: w,
11
- name: l,
12
- value: x,
13
- className: y = ""
14
- }) {
15
- const r = a !== void 0, [k, f] = p.useState(v ?? !1), t = r ? a : k, o = R(null), I = p.useId(), d = w ?? I;
16
- S(() => {
17
- const n = o.current;
18
- if (!n) return;
19
- const h = (c) => {
20
- if (!e && (c.key === " " || c.key === "Spacebar")) {
21
- c.preventDefault();
22
- const m = !t;
23
- r || f(m), s?.(m);
24
- }
25
- };
26
- return n.addEventListener("keydown", h), () => {
27
- n.removeEventListener("keydown", h);
28
- };
29
- }, [t, e, r, s]);
30
- const N = () => {
31
- if (e) return;
32
- const n = !t;
33
- r || f(n), s?.(n), o.current && o.current.focus();
34
- }, b = x ?? (t ? "on" : "off");
35
- return /* @__PURE__ */ E(
36
- "label",
37
- {
38
- className: `ui-switch-root ${y}`,
39
- htmlFor: d,
40
- "aria-disabled": e || void 0,
41
- children: [
42
- l && /* @__PURE__ */ i("input", { type: "hidden", name: l, value: t ? b : "" }),
43
- /* @__PURE__ */ i(
44
- "button",
45
- {
46
- id: d,
47
- ref: o,
48
- type: "button",
49
- role: "switch",
50
- "aria-checked": t,
51
- "aria-disabled": e || void 0,
52
- className: "ui-switch-control",
53
- "data-state": t ? "on" : "off",
54
- onClick: N,
55
- tabIndex: e ? -1 : 0,
56
- children: /* @__PURE__ */ i("span", { className: "ui-switch-thumb", "aria-hidden": "true" })
57
- }
4
+ import { cn as a } from "../../utils/cn/cn.js";
5
+ const E = g(
6
+ ({
7
+ checked: h,
8
+ defaultChecked: p,
9
+ onChange: _,
10
+ disabled: n = !1,
11
+ label: r,
12
+ description: c,
13
+ id: k,
14
+ name: d,
15
+ value: y,
16
+ size: u = "md",
17
+ className: v,
18
+ wrapperClassName: C,
19
+ ...l
20
+ }, N) => {
21
+ const b = K(), s = k ?? `nui-switch-${b}`, w = `${s}-description`, m = h !== void 0, [I, x] = j(p ?? !1), e = m ? h : I, o = () => {
22
+ if (n) return;
23
+ const t = !e;
24
+ m || x(t), _?.(t);
25
+ }, D = (t) => {
26
+ (t.key === " " || t.key === "Enter") && (t.preventDefault(), o()), l.onKeyDown?.(t);
27
+ }, S = (t) => {
28
+ n || (t.preventDefault(), o(), document.getElementById(s)?.focus());
29
+ }, $ = y ?? (e ? "on" : "off");
30
+ return /* @__PURE__ */ f(
31
+ "div",
32
+ {
33
+ className: a(
34
+ "nui-switch-wrapper",
35
+ n && "nui-switch-wrapper--disabled",
36
+ C
58
37
  ),
59
- u && /* @__PURE__ */ i("span", { className: "ui-switch-label", children: u })
60
- ]
61
- }
62
- );
63
- }
38
+ children: [
39
+ d && /* @__PURE__ */ i("input", { type: "hidden", name: d, value: e ? $ : "" }),
40
+ /* @__PURE__ */ i(
41
+ "button",
42
+ {
43
+ ref: N,
44
+ id: s,
45
+ type: "button",
46
+ role: "switch",
47
+ "aria-checked": e,
48
+ "aria-disabled": n,
49
+ "aria-describedby": c ? w : void 0,
50
+ className: a(
51
+ "nui-switch",
52
+ `nui-switch--${u}`,
53
+ e && "nui-switch--checked",
54
+ v
55
+ ),
56
+ onClick: o,
57
+ onKeyDown: D,
58
+ disabled: n,
59
+ ...l,
60
+ children: /* @__PURE__ */ i(
61
+ "span",
62
+ {
63
+ className: a(
64
+ "nui-switch__thumb",
65
+ `nui-switch__thumb--${u}`,
66
+ e && "nui-switch__thumb--checked"
67
+ ),
68
+ "aria-hidden": "true"
69
+ }
70
+ )
71
+ }
72
+ ),
73
+ (r || c) && /* @__PURE__ */ f("div", { className: "nui-switch__text-container", children: [
74
+ r && /* @__PURE__ */ i(
75
+ "label",
76
+ {
77
+ htmlFor: s,
78
+ className: "nui-switch__label",
79
+ onClick: S,
80
+ children: r
81
+ }
82
+ ),
83
+ c && /* @__PURE__ */ i("div", { id: w, className: "nui-switch__description", children: c })
84
+ ] })
85
+ ]
86
+ }
87
+ );
88
+ }
89
+ );
90
+ E.displayName = "Switch";
64
91
  export {
65
- F as Switch
92
+ E as Switch
66
93
  };
67
94
  //# sourceMappingURL=Switch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Switch.js","sources":["../../../src/components/switch/Switch.tsx"],"sourcesContent":["/**\r\n * Switch.tsx\r\n * ----------\r\n * Accessible Toggle / Switch component.\r\n *\r\n * Features:\r\n * - role=\"switch\" semantics\r\n * - aria-checked driven\r\n * - keyboard (Space toggles)\r\n * - controlled + uncontrolled\r\n * - disabled support\r\n * - label support\r\n * - no external deps\r\n */\r\n/**\r\n * Switch.tsx (Lint-Clean Version)\r\n * Fully accessible toggle switch.\r\n */\r\n\r\nimport React, { useEffect, useRef } from 'react';\r\nimport './Switch.css';\r\n\r\ninterface SwitchProps {\r\n checked?: boolean;\r\n defaultChecked?: boolean;\r\n onChange?: (checked: boolean) => void;\r\n\r\n disabled?: boolean;\r\n label?: React.ReactNode;\r\n id?: string;\r\n name?: string;\r\n value?: string;\r\n className?: string;\r\n}\r\n\r\nexport function Switch({\r\n checked,\r\n defaultChecked,\r\n onChange,\r\n disabled = false,\r\n label,\r\n id,\r\n name,\r\n value,\r\n className = '',\r\n}: SwitchProps) {\r\n const isControlled = checked !== undefined;\r\n\r\n const [internal, setInternal] = React.useState(defaultChecked ?? false);\r\n const current = isControlled ? checked : internal;\r\n\r\n const controlRef = useRef<HTMLButtonElement | null>(null);\r\n\r\n /**\r\n * FIX → Always call useId at top level.\r\n */\r\n const internalId = React.useId();\r\n const finalId = id ?? internalId;\r\n\r\n /**\r\n * Spacebar toggling (keyboard)\r\n */\r\n useEffect(() => {\r\n const el = controlRef.current;\r\n if (!el) return;\r\n\r\n const handler = (e: KeyboardEvent) => {\r\n if (disabled) return;\r\n\r\n if (e.key === ' ' || e.key === 'Spacebar') {\r\n e.preventDefault();\r\n const next = !current;\r\n\r\n if (!isControlled) setInternal(next);\r\n onChange?.(next);\r\n }\r\n };\r\n\r\n el.addEventListener('keydown', handler);\r\n return () => {\r\n el.removeEventListener('keydown', handler);\r\n };\r\n }, [current, disabled, isControlled, onChange]);\r\n\r\n /**\r\n * Toggle function no non-null assertions.\r\n */\r\n const toggle = () => {\r\n if (disabled) return;\r\n const next = !current;\r\n\r\n if (!isControlled) setInternal(next);\r\n onChange?.(next);\r\n\r\n // Restore focus safely\r\n if (controlRef.current) {\r\n controlRef.current.focus();\r\n }\r\n };\r\n\r\n // Hidden input for form\r\n const hiddenValue = value ?? (current ? 'on' : 'off');\r\n\r\n return (\r\n <label\r\n className={`ui-switch-root ${className}`}\r\n htmlFor={finalId}\r\n aria-disabled={disabled || undefined}\r\n >\r\n {name && (\r\n <input type=\"hidden\" name={name} value={current ? hiddenValue : ''} />\r\n )}\r\n\r\n <button\r\n id={finalId}\r\n ref={controlRef}\r\n type=\"button\"\r\n role=\"switch\"\r\n aria-checked={current}\r\n aria-disabled={disabled || undefined}\r\n className=\"ui-switch-control\"\r\n data-state={current ? 'on' : 'off'}\r\n onClick={toggle}\r\n tabIndex={disabled ? -1 : 0}\r\n >\r\n <span className=\"ui-switch-thumb\" aria-hidden=\"true\" />\r\n </button>\r\n\r\n {label && <span className=\"ui-switch-label\">{label}</span>}\r\n </label>\r\n );\r\n}\r\n"],"names":["Switch","checked","defaultChecked","onChange","disabled","label","id","name","value","className","isControlled","internal","setInternal","React","current","controlRef","useRef","internalId","finalId","useEffect","el","handler","e","next","toggle","hiddenValue","jsxs","jsx"],"mappings":";;;AAmCO,SAASA,EAAO;AAAA,EACrB,SAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,UAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,OAAAC;AAAA,EACA,IAAAC;AAAA,EACA,MAAAC;AAAA,EACA,OAAAC;AAAA,EACA,WAAAC,IAAY;AACd,GAAgB;AACd,QAAMC,IAAeT,MAAY,QAE3B,CAACU,GAAUC,CAAW,IAAIC,EAAM,SAASX,KAAkB,EAAK,GAChEY,IAAUJ,IAAeT,IAAUU,GAEnCI,IAAaC,EAAiC,IAAI,GAKlDC,IAAaJ,EAAM,MAAA,GACnBK,IAAUZ,KAAMW;AAKtB,EAAAE,EAAU,MAAM;AACd,UAAMC,IAAKL,EAAW;AACtB,QAAI,CAACK,EAAI;AAET,UAAMC,IAAU,CAACC,MAAqB;AACpC,UAAI,CAAAlB,MAEAkB,EAAE,QAAQ,OAAOA,EAAE,QAAQ,aAAY;AACzC,QAAAA,EAAE,eAAA;AACF,cAAMC,IAAO,CAACT;AAEd,QAAKJ,KAAcE,EAAYW,CAAI,GACnCpB,IAAWoB,CAAI;AAAA,MACjB;AAAA,IACF;AAEA,WAAAH,EAAG,iBAAiB,WAAWC,CAAO,GAC/B,MAAM;AACX,MAAAD,EAAG,oBAAoB,WAAWC,CAAO;AAAA,IAC3C;AAAA,EACF,GAAG,CAACP,GAASV,GAAUM,GAAcP,CAAQ,CAAC;AAK9C,QAAMqB,IAAS,MAAM;AACnB,QAAIpB,EAAU;AACd,UAAMmB,IAAO,CAACT;AAEd,IAAKJ,KAAcE,EAAYW,CAAI,GACnCpB,IAAWoB,CAAI,GAGXR,EAAW,WACbA,EAAW,QAAQ,MAAA;AAAA,EAEvB,GAGMU,IAAcjB,MAAUM,IAAU,OAAO;AAE/C,SACE,gBAAAY;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,kBAAkBjB,CAAS;AAAA,MACtC,SAASS;AAAA,MACT,iBAAed,KAAY;AAAA,MAE1B,UAAA;AAAA,QAAAG,KACC,gBAAAoB,EAAC,WAAM,MAAK,UAAS,MAAApB,GAAY,OAAOO,IAAUW,IAAc,GAAA,CAAI;AAAA,QAGtE,gBAAAE;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,IAAIT;AAAA,YACJ,KAAKH;AAAA,YACL,MAAK;AAAA,YACL,MAAK;AAAA,YACL,gBAAcD;AAAA,YACd,iBAAeV,KAAY;AAAA,YAC3B,WAAU;AAAA,YACV,cAAYU,IAAU,OAAO;AAAA,YAC7B,SAASU;AAAA,YACT,UAAUpB,IAAW,KAAK;AAAA,YAE1B,UAAA,gBAAAuB,EAAC,QAAA,EAAK,WAAU,mBAAkB,eAAY,OAAA,CAAO;AAAA,UAAA;AAAA,QAAA;AAAA,QAGtDtB,KAAS,gBAAAsB,EAAC,QAAA,EAAK,WAAU,mBAAmB,UAAAtB,EAAA,CAAM;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGzD;"}
1
+ {"version":3,"file":"Switch.js","sources":["../../../src/components/switch/Switch.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { forwardRef, useId, useState } from 'react';\nimport { cn } from '../../utils';\nimport './Switch.css';\n\n/* ============================================================\n * Types\n * ============================================================ */\n\nexport interface SwitchProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onChange' | 'value'> {\n /** The controlled checked state of the switch */\n checked?: boolean;\n /** The uncontrolled default checked state */\n defaultChecked?: boolean;\n /** Callback fired when the state changes */\n onChange?: (checked: boolean) => void;\n \n /** Disables the switch, preventing interaction */\n disabled?: boolean;\n /** The primary text label for the switch */\n label?: React.ReactNode;\n /** Secondary descriptive text linked via WAI-ARIA */\n description?: React.ReactNode;\n \n /** Name attribute for native form submission */\n name?: string;\n /** Value submitted in a native form when checked. Defaults to \"on\". */\n value?: string;\n /** The visual size variant. Defaults to 'md'. */\n size?: 'sm' | 'md';\n \n /** Additional CSS classes for the outer wrapping div */\n wrapperClassName?: string;\n}\n\n/* ============================================================\n * Component\n * ============================================================ */\n\n/**\n * Switch Component\n * * A WAI-ARIA compliant toggle switch used to turn settings on or off.\n * * Automatically handles native form submission using a hidden input.\n */\nexport const Switch = forwardRef<HTMLButtonElement, SwitchProps>(\n (\n {\n checked,\n defaultChecked,\n onChange,\n disabled = false,\n label,\n description,\n id,\n name,\n value,\n size = 'md',\n className,\n wrapperClassName,\n ...props\n },\n ref\n ) => {\n // Unique ID generation for WCAG label and description linkage\n const reactId = useId();\n const switchId = id ?? `nui-switch-${reactId}`;\n const descriptionId = `${switchId}-description`;\n\n // State Management\n const isControlled = checked !== undefined;\n const [internalChecked, setInternalChecked] = useState(defaultChecked ?? false);\n const currentChecked = isControlled ? checked : internalChecked;\n\n const toggle = () => {\n if (disabled) return;\n const nextState = !currentChecked;\n if (!isControlled) setInternalChecked(nextState);\n onChange?.(nextState);\n };\n\n // Keyboard Accessibility (Space & Enter)\n const handleKeyDown = (e: React.KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault(); // Prevent page scroll on Spacebar\n toggle();\n }\n props.onKeyDown?.(e);\n };\n\n // Robust Label Click Handler\n // Standard <label> clicks only *focus* <button> elements in Safari/Firefox. \n // This handler ensures clicking the text always toggles the state.\n const handleLabelClick = (e: React.MouseEvent) => {\n if (disabled) return;\n e.preventDefault(); \n toggle();\n document.getElementById(switchId)?.focus();\n };\n\n // Hidden input value for standard HTML form submissions\n const hiddenValue = value ?? (currentChecked ? 'on' : 'off');\n\n return (\n <div \n className={cn(\n \"nui-switch-wrapper\", \n disabled && \"nui-switch-wrapper--disabled\", \n wrapperClassName\n )}\n >\n {/* Hidden Form Input */}\n {name && (\n <input type=\"hidden\" name={name} value={currentChecked ? hiddenValue : ''} />\n )}\n\n {/* The Actual Switch (Button) */}\n <button\n ref={ref}\n id={switchId}\n type=\"button\"\n role=\"switch\"\n aria-checked={currentChecked}\n aria-disabled={disabled}\n aria-describedby={description ? descriptionId : undefined}\n className={cn(\n \"nui-switch\",\n `nui-switch--${size}`,\n currentChecked && \"nui-switch--checked\",\n className\n )}\n onClick={toggle}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n {...props}\n >\n <span \n className={cn(\n \"nui-switch__thumb\", \n `nui-switch__thumb--${size}`, \n currentChecked && \"nui-switch__thumb--checked\"\n )} \n aria-hidden=\"true\" \n />\n </button>\n\n {/* Text Content */}\n {(label || description) && (\n <div className=\"nui-switch__text-container\">\n {label && (\n <label \n htmlFor={switchId} \n className=\"nui-switch__label\"\n onClick={handleLabelClick}\n >\n {label}\n </label>\n )}\n {description && (\n <div id={descriptionId} className=\"nui-switch__description\">\n {description}\n </div>\n )}\n </div>\n )}\n </div>\n );\n }\n);\n\nSwitch.displayName = 'Switch';"],"names":["Switch","forwardRef","checked","defaultChecked","onChange","disabled","label","description","id","name","value","size","className","wrapperClassName","props","ref","reactId","useId","switchId","descriptionId","isControlled","internalChecked","setInternalChecked","useState","currentChecked","toggle","nextState","handleKeyDown","e","handleLabelClick","hiddenValue","jsxs","cn","jsx"],"mappings":";;;;AA6CO,MAAMA,IAASC;AAAA,EACpB,CACE;AAAA,IACE,SAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,UAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,OAAAC;AAAA,IACA,aAAAC;AAAA,IACA,IAAAC;AAAA,IACA,MAAAC;AAAA,IACA,OAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,WAAAC;AAAA,IACA,kBAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAELC,MACG;AAEH,UAAMC,IAAUC,EAAA,GACVC,IAAWV,KAAM,cAAcQ,CAAO,IACtCG,IAAgB,GAAGD,CAAQ,gBAG3BE,IAAelB,MAAY,QAC3B,CAACmB,GAAiBC,CAAkB,IAAIC,EAASpB,KAAkB,EAAK,GACxEqB,IAAiBJ,IAAelB,IAAUmB,GAE1CI,IAAS,MAAM;AACnB,UAAIpB,EAAU;AACd,YAAMqB,IAAY,CAACF;AACnB,MAAKJ,KAAcE,EAAmBI,CAAS,GAC/CtB,IAAWsB,CAAS;AAAA,IACtB,GAGMC,IAAgB,CAACC,MAA8C;AACnE,OAAIA,EAAE,QAAQ,OAAOA,EAAE,QAAQ,aAC7BA,EAAE,eAAA,GACFH,EAAA,IAEFX,EAAM,YAAYc,CAAC;AAAA,IACrB,GAKMC,IAAmB,CAACD,MAAwB;AAChD,MAAIvB,MACJuB,EAAE,eAAA,GACFH,EAAA,GACA,SAAS,eAAeP,CAAQ,GAAG,MAAA;AAAA,IACrC,GAGMY,IAAcpB,MAAUc,IAAiB,OAAO;AAEtD,WACE,gBAAAO;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAWC;AAAA,UACT;AAAA,UACA3B,KAAY;AAAA,UACZQ;AAAA,QAAA;AAAA,QAID,UAAA;AAAA,UAAAJ,KACC,gBAAAwB,EAAC,WAAM,MAAK,UAAS,MAAAxB,GAAY,OAAOe,IAAiBM,IAAc,GAAA,CAAI;AAAA,UAI7E,gBAAAG;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,KAAAlB;AAAA,cACA,IAAIG;AAAA,cACJ,MAAK;AAAA,cACL,MAAK;AAAA,cACL,gBAAcM;AAAA,cACd,iBAAenB;AAAA,cACf,oBAAkBE,IAAcY,IAAgB;AAAA,cAChD,WAAWa;AAAA,gBACT;AAAA,gBACA,eAAerB,CAAI;AAAA,gBACnBa,KAAkB;AAAA,gBAClBZ;AAAA,cAAA;AAAA,cAEF,SAASa;AAAA,cACT,WAAWE;AAAA,cACX,UAAAtB;AAAA,cACC,GAAGS;AAAA,cAEJ,UAAA,gBAAAmB;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAWD;AAAA,oBACT;AAAA,oBACA,sBAAsBrB,CAAI;AAAA,oBAC1Ba,KAAkB;AAAA,kBAAA;AAAA,kBAEpB,eAAY;AAAA,gBAAA;AAAA,cAAA;AAAA,YACd;AAAA,UAAA;AAAA,WAIAlB,KAASC,MACT,gBAAAwB,EAAC,OAAA,EAAI,WAAU,8BACZ,UAAA;AAAA,YAAAzB,KACC,gBAAA2B;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAASf;AAAA,gBACT,WAAU;AAAA,gBACV,SAASW;AAAA,gBAER,UAAAvB;AAAA,cAAA;AAAA,YAAA;AAAA,YAGJC,KACC,gBAAA0B,EAAC,OAAA,EAAI,IAAId,GAAe,WAAU,2BAC/B,UAAAZ,EAAA,CACH;AAAA,UAAA,EAAA,CAEJ;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEAP,EAAO,cAAc;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),d=require("react");;/* empty css */function k({columns:i,data:a,emptyText:u="No data available",className:b=""}){const[n,y]=d.useState(null),c=d.useMemo(()=>n?[...a].sort((r,s)=>{const l=r[n.key],o=s[n.key];return l<o?n.direction==="asc"?-1:1:l>o?n.direction==="asc"?1:-1:0}):a,[a,n]),h=e=>{e.sortable&&y(r=>!r||r.key!==e.key?{key:e.key,direction:"asc"}:r.direction==="asc"?{key:e.key,direction:"desc"}:null)},j=e=>{if(!e.sortable)return null;const r=n?.key===e.key,s=n?.direction??"asc";return t.jsx("span",{className:`ui-table-sort-indicator ${r?"active":""}`,"aria-hidden":"true",children:r?s==="asc"?"":"":""})};return t.jsx("div",{className:"ui-table-container",children:t.jsxs("table",{className:`ui-table ${b}`,children:[t.jsx("thead",{children:t.jsx("tr",{children:i.map(e=>t.jsx("th",{scope:"col",children:e.sortable?t.jsxs("button",{type:"button",className:"ui-table-sort-button",onClick:()=>h(e),children:[e.label,j(e)]}):e.label},String(e.key)))})}),t.jsx("tbody",{children:c.length===0?t.jsx("tr",{children:t.jsx("td",{className:"ui-table-empty",colSpan:i.length,children:u})}):c.map((e,r)=>t.jsx("tr",{className:"ui-table-row",children:i.map(s=>t.jsx("td",{children:String(e[s.key])},String(s.key)))},r))})]})})}exports.Table=k;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),g=require("react");;/* empty css */const k=require("../../utils/cn/cn.cjs");function _({columns:o,data:c,rowKey:d,emptyText:f="No data available",className:j}){const[r,b]=g.useState(null),h=g.useMemo(()=>{if(!r)return c;const{key:e,direction:n}=r,a=o.find(l=>l.key===e);return[...c].sort((l,u)=>{if(a?.sortFn)return n==="asc"?a.sortFn(l,u):a.sortFn(u,l);const i=l[e],s=u[e];if(i===s)return 0;if(i==null)return n==="asc"?-1:1;if(s==null)return n==="asc"?1:-1;if(typeof i=="number"&&typeof s=="number")return n==="asc"?i-s:s-i;const S=String(i),v=String(s),x=S.localeCompare(v);return n==="asc"?x:-x})},[c,r,o]),y=e=>{e.sortable&&b(n=>!n||n.key!==e.key?{key:e.key,direction:"asc"}:n.direction==="asc"?{key:e.key,direction:"desc"}:null)},p=e=>typeof d=="function"?d(e):String(e[d]),m=e=>{if(!e.sortable)return null;const n=r?.key===e.key,a=r?.direction;return t.jsx("span",{className:k.cn("nui-table__sort-icon",n&&"active"),"aria-hidden":"true",children:n&&a==="asc"?t.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:t.jsx("path",{d:"m18 15-6-6-6 6"})}):n&&a==="desc"?t.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:t.jsx("path",{d:"m6 9 6 6 6-6"})}):t.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[t.jsx("path",{d:"m7 15 5 5 5-5"}),t.jsx("path",{d:"m7 9 5-5 5 5"})]})})};return t.jsx("div",{className:"nui-table-wrapper",children:t.jsxs("table",{className:k.cn("nui-table",j),children:[t.jsx("thead",{children:t.jsx("tr",{children:o.map(e=>t.jsx("th",{scope:"col",style:{textAlign:e.align||"left"},"aria-sort":r?.key===e.key?r.direction==="asc"?"ascending":"descending":"none",children:e.sortable?t.jsxs("button",{type:"button",className:"nui-table__sort-button",onClick:()=>y(e),style:{justifyContent:e.align==="right"?"flex-end":e.align==="center"?"center":"flex-start"},children:[e.label,m(e)]}):t.jsx("span",{className:"nui-table__header-label",children:e.label})},String(e.key)))})}),t.jsx("tbody",{children:h.length===0?t.jsx("tr",{children:t.jsx("td",{className:"nui-table__empty",colSpan:o.length,children:t.jsx("div",{className:"nui-table__empty-content",children:f})})}):h.map(e=>t.jsx("tr",{className:"nui-table__row",children:o.map(n=>t.jsx("td",{style:{textAlign:n.align||"left"},children:n.render?n.render(e):String(e[n.key]??"")},String(n.key)))},p(e)))})]})})}exports.Table=_;
2
2
  //# sourceMappingURL=Table.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Table.cjs","sources":["../../../src/components/table/Table.tsx"],"sourcesContent":["/**\r\n * Table.tsx\r\n * ----------\r\n * Accessible, sortable, theme-aware table.\r\n */\r\n\r\nimport { useState, useMemo } from 'react';\r\nimport './Table.css';\r\n\r\nexport interface TableColumn<T> {\r\n key: keyof T;\r\n label: string;\r\n sortable?: boolean;\r\n}\r\n\r\ninterface TableProps<T> {\r\n columns: TableColumn<T>[];\r\n data: T[];\r\n emptyText?: string;\r\n className?: string;\r\n}\r\n\r\ntype SortState<T> = {\r\n key: keyof T;\r\n direction: 'asc' | 'desc';\r\n} | null;\r\n\r\nexport function Table<T extends Record<string, any>>({\r\n columns,\r\n data,\r\n emptyText = 'No data available',\r\n className = '',\r\n}: TableProps<T>) {\r\n const [sort, setSort] = useState<SortState<T>>(null);\r\n\r\n const sortedData = useMemo(() => {\r\n if (!sort) return data;\r\n\r\n const sorted = [...data].sort((a, b) => {\r\n const aVal = a[sort.key];\r\n const bVal = b[sort.key];\r\n\r\n if (aVal < bVal) return sort.direction === 'asc' ? -1 : 1;\r\n if (aVal > bVal) return sort.direction === 'asc' ? 1 : -1;\r\n return 0;\r\n });\r\n\r\n return sorted;\r\n }, [data, sort]);\r\n\r\n const toggleSort = (col: TableColumn<T>) => {\r\n if (!col.sortable) return;\r\n\r\n setSort((prev) => {\r\n if (!prev || prev.key !== col.key) {\r\n return { key: col.key, direction: 'asc' };\r\n }\r\n if (prev.direction === 'asc') {\r\n return { key: col.key, direction: 'desc' };\r\n }\r\n return null; // reset\r\n });\r\n };\r\n\r\n const renderSortIcon = (col: TableColumn<T>) => {\r\n if (!col.sortable) return null;\r\n\r\n const isActive = sort?.key === col.key;\r\n const dir = sort?.direction ?? 'asc';\r\n\r\n return (\r\n <span\r\n className={`ui-table-sort-indicator ${isActive ? 'active' : ''}`}\r\n aria-hidden=\"true\"\r\n >\r\n {isActive ? (dir === 'asc' ? '▲' : '▼') : '↕'}\r\n </span>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"ui-table-container\">\r\n <table className={`ui-table ${className}`}>\r\n <thead>\r\n <tr>\r\n {columns.map((col) => (\r\n <th key={String(col.key)} scope=\"col\">\r\n {col.sortable ? (\r\n <button\r\n type=\"button\"\r\n className=\"ui-table-sort-button\"\r\n onClick={() => toggleSort(col)}\r\n >\r\n {col.label}\r\n {renderSortIcon(col)}\r\n </button>\r\n ) : (\r\n col.label\r\n )}\r\n </th>\r\n ))}\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n {sortedData.length === 0 ? (\r\n <tr>\r\n <td className=\"ui-table-empty\" colSpan={columns.length}>\r\n {emptyText}\r\n </td>\r\n </tr>\r\n ) : (\r\n sortedData.map((row, i) => (\r\n <tr key={i} className=\"ui-table-row\">\r\n {columns.map((col) => (\r\n <td key={String(col.key)}>{String(row[col.key])}</td>\r\n ))}\r\n </tr>\r\n ))\r\n )}\r\n </tbody>\r\n </table>\r\n </div>\r\n );\r\n}\r\n"],"names":["Table","columns","data","emptyText","className","sort","setSort","useState","sortedData","useMemo","a","b","aVal","bVal","toggleSort","col","prev","renderSortIcon","isActive","dir","jsx","jsxs","row","i"],"mappings":"mKA2BO,SAASA,EAAqC,CACnD,QAAAC,EACA,KAAAC,EACA,UAAAC,EAAY,oBACZ,UAAAC,EAAY,EACd,EAAkB,CAChB,KAAM,CAACC,EAAMC,CAAO,EAAIC,EAAAA,SAAuB,IAAI,EAE7CC,EAAaC,EAAAA,QAAQ,IACpBJ,EAEU,CAAC,GAAGH,CAAI,EAAE,KAAK,CAACQ,EAAGC,IAAM,CACtC,MAAMC,EAAOF,EAAEL,EAAK,GAAG,EACjBQ,EAAOF,EAAEN,EAAK,GAAG,EAEvB,OAAIO,EAAOC,EAAaR,EAAK,YAAc,MAAQ,GAAK,EACpDO,EAAOC,EAAaR,EAAK,YAAc,MAAQ,EAAI,GAChD,CACT,CAAC,EATiBH,EAYjB,CAACA,EAAMG,CAAI,CAAC,EAETS,EAAcC,GAAwB,CACrCA,EAAI,UAETT,EAASU,GACH,CAACA,GAAQA,EAAK,MAAQD,EAAI,IACrB,CAAE,IAAKA,EAAI,IAAK,UAAW,KAAA,EAEhCC,EAAK,YAAc,MACd,CAAE,IAAKD,EAAI,IAAK,UAAW,MAAA,EAE7B,IACR,CACH,EAEME,EAAkBF,GAAwB,CAC9C,GAAI,CAACA,EAAI,SAAU,OAAO,KAE1B,MAAMG,EAAWb,GAAM,MAAQU,EAAI,IAC7BI,EAAMd,GAAM,WAAa,MAE/B,OACEe,EAAAA,IAAC,OAAA,CACC,UAAW,2BAA2BF,EAAW,SAAW,EAAE,GAC9D,cAAY,OAEX,SAAAA,EAAYC,IAAQ,MAAQ,IAAM,IAAO,GAAA,CAAA,CAGhD,EAEA,OACEC,EAAAA,IAAC,OAAI,UAAU,qBACb,gBAAC,QAAA,CAAM,UAAW,YAAYhB,CAAS,GACrC,SAAA,CAAAgB,MAAC,QAAA,CACC,SAAAA,EAAAA,IAAC,KAAA,CACE,SAAAnB,EAAQ,IAAKc,GACZK,EAAAA,IAAC,KAAA,CAAyB,MAAM,MAC7B,SAAAL,EAAI,SACHM,EAAAA,KAAC,SAAA,CACC,KAAK,SACL,UAAU,uBACV,QAAS,IAAMP,EAAWC,CAAG,EAE5B,SAAA,CAAAA,EAAI,MACJE,EAAeF,CAAG,CAAA,CAAA,CAAA,EAGrBA,EAAI,KAAA,EAXC,OAAOA,EAAI,GAAG,CAavB,CACD,CAAA,CACH,EACF,EAEAK,EAAAA,IAAC,SACE,SAAAZ,EAAW,SAAW,EACrBY,EAAAA,IAAC,KAAA,CACC,eAAC,KAAA,CAAG,UAAU,iBAAiB,QAASnB,EAAQ,OAC7C,SAAAE,CAAA,CACH,EACF,EAEAK,EAAW,IAAI,CAACc,EAAKC,IACnBH,EAAAA,IAAC,MAAW,UAAU,eACnB,WAAQ,IAAKL,GACZK,EAAAA,IAAC,KAAA,CAA0B,gBAAOE,EAAIP,EAAI,GAAG,CAAC,CAAA,EAArC,OAAOA,EAAI,GAAG,CAAyB,CACjD,GAHMQ,CAIT,CACD,CAAA,CAEL,CAAA,CAAA,CACF,CAAA,CACF,CAEJ"}
1
+ {"version":3,"file":"Table.cjs","sources":["../../../src/components/table/Table.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { useState, useMemo } from 'react';\nimport { cn } from '../../utils';\nimport './Table.css';\n\n/* ============================================================\n * Types\n * ============================================================ */\n\nexport interface TableColumn<T> {\n /** The key from your data object that this column maps to */\n key: keyof T;\n /** The text displayed in the table header */\n label: string;\n /** Enables clicking the header to sort the table by this column */\n sortable?: boolean;\n /** Aligns the text in the column header and cells. Defaults to 'left' */\n align?: 'left' | 'center' | 'right';\n /** Custom render function for the cell. Useful for formatting (e.g., currency) or custom UI (e.g., status badges) */\n render?: (row: T) => React.ReactNode;\n /** Optional custom sorting function to override the default alphabetic/numeric sort */\n sortFn?: (a: T, b: T) => number;\n}\n\nexport interface TableProps<T> {\n /** Array of column configuration objects */\n columns: TableColumn<T>[];\n /** Array of data objects to render */\n data: T[];\n /** A unique identifier for each row (string/number key, or a function that returns a string) */\n rowKey: keyof T | ((row: T) => string);\n /** Text or React Node to display when the data array is empty */\n emptyText?: React.ReactNode;\n /** Custom class applied to the <table> element */\n className?: string;\n}\n\ntype SortState<T> = {\n key: keyof T;\n direction: 'asc' | 'desc';\n} | null;\n\n/* ============================================================\n * Component\n * ============================================================ */\n\n/**\n * Table Component\n * * A highly generic data table that supports automatic sorting and custom cell rendering.\n * * Uses strict TypeScript generics (`<T>`) so it can perfectly map to any data shape passed into it.\n */\nexport function Table<T>({\n columns,\n data,\n rowKey,\n emptyText = 'No data available',\n className,\n}: TableProps<T>) {\n const [sort, setSort] = useState<SortState<T>>(null);\n\n /* ----------------------------------------------------\n Sorting Logic\n ---------------------------------------------------- */\n const sortedData = useMemo(() => {\n if (!sort) return data;\n\n const { key, direction } = sort;\n const column = columns.find((c) => c.key === key);\n\n return [...data].sort((a, b) => {\n // 1. Fallback to custom sort function if provided\n if (column?.sortFn) {\n return direction === 'asc' ? column.sortFn(a, b) : column.sortFn(b, a);\n }\n\n const aVal = a[key];\n const bVal = b[key];\n\n if (aVal === bVal) return 0;\n if (aVal === null || aVal === undefined) return direction === 'asc' ? -1 : 1;\n if (bVal === null || bVal === undefined) return direction === 'asc' ? 1 : -1;\n\n // 2. Type-safe numeric sorting\n if (typeof aVal === 'number' && typeof bVal === 'number') {\n return direction === 'asc' ? aVal - bVal : bVal - aVal;\n }\n\n // 3. Type-safe string sorting (perfect for alphabetic ordering)\n const aStr = String(aVal);\n const bStr = String(bVal);\n const diff = aStr.localeCompare(bStr);\n \n return direction === 'asc' ? diff : -diff;\n });\n }, [data, sort, columns]);\n\n /* ----------------------------------------------------\n Event Handlers\n ---------------------------------------------------- */\n const toggleSort = (col: TableColumn<T>) => {\n if (!col.sortable) return;\n\n setSort((prev) => {\n // If clicking a new column, or clicking for the first time, sort ASC\n if (!prev || prev.key !== col.key) {\n return { key: col.key, direction: 'asc' };\n }\n // If currently ASC, flip to DESC\n if (prev.direction === 'asc') {\n return { key: col.key, direction: 'desc' };\n }\n // If currently DESC, clear the sort\n return null;\n });\n };\n\n const getRowId = (row: T): string => {\n return typeof rowKey === 'function' ? rowKey(row) : String(row[rowKey]);\n };\n\n /* ----------------------------------------------------\n Render Helpers\n ---------------------------------------------------- */\n const renderSortIcon = (col: TableColumn<T>) => {\n if (!col.sortable) return null;\n\n const isActive = sort?.key === col.key;\n const dir = sort?.direction;\n\n return (\n <span className={cn(\"nui-table__sort-icon\", isActive && \"active\")} aria-hidden=\"true\">\n {isActive && dir === 'asc' ? (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"m18 15-6-6-6 6\"/></svg>\n ) : isActive && dir === 'desc' ? (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"m6 9 6 6 6-6\"/></svg>\n ) : (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"m7 15 5 5 5-5\"/><path d=\"m7 9 5-5 5 5\"/></svg>\n )}\n </span>\n );\n };\n\n /* ----------------------------------------------------\n Render\n ---------------------------------------------------- */\n return (\n <div className=\"nui-table-wrapper\">\n <table className={cn(\"nui-table\", className)}>\n <thead>\n <tr>\n {columns.map((col) => (\n <th \n key={String(col.key)} \n scope=\"col\"\n style={{ textAlign: col.align || 'left' }}\n aria-sort={sort?.key === col.key ? (sort.direction === 'asc' ? 'ascending' : 'descending') : 'none'}\n >\n {col.sortable ? (\n <button\n type=\"button\"\n className=\"nui-table__sort-button\"\n onClick={() => toggleSort(col)}\n style={{ justifyContent: col.align === 'right' ? 'flex-end' : col.align === 'center' ? 'center' : 'flex-start' }}\n >\n {col.label}\n {renderSortIcon(col)}\n </button>\n ) : (\n <span className=\"nui-table__header-label\">{col.label}</span>\n )}\n </th>\n ))}\n </tr>\n </thead>\n\n <tbody>\n {sortedData.length === 0 ? (\n <tr>\n <td className=\"nui-table__empty\" colSpan={columns.length}>\n <div className=\"nui-table__empty-content\">\n {emptyText}\n </div>\n </td>\n </tr>\n ) : (\n sortedData.map((row) => (\n <tr key={getRowId(row)} className=\"nui-table__row\">\n {columns.map((col) => (\n <td \n key={String(col.key)}\n style={{ textAlign: col.align || 'left' }}\n >\n {col.render ? col.render(row) : String(row[col.key] ?? '')}\n </td>\n ))}\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n );\n}"],"names":["Table","columns","data","rowKey","emptyText","className","sort","setSort","useState","sortedData","useMemo","key","direction","column","c","a","b","aVal","bVal","aStr","bStr","diff","toggleSort","col","prev","getRowId","row","renderSortIcon","isActive","dir","cn","jsx","jsxs"],"mappings":"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"}
@@ -1,46 +1,73 @@
1
- import { jsx as r, jsxs as d } from "react/jsx-runtime";
2
- import { useState as m, useMemo as f } from "react";
1
+ import { jsx as n, jsxs as h } from "react/jsx-runtime";
2
+ import { useState as N, useMemo as j } from "react";
3
3
  /* empty css */
4
- function N({
4
+ import { cn as g } from "../../utils/cn/cn.js";
5
+ function B({
5
6
  columns: a,
6
- data: s,
7
- emptyText: u = "No data available",
8
- className: b = ""
7
+ data: d,
8
+ rowKey: c,
9
+ emptyText: p = "No data available",
10
+ className: m
9
11
  }) {
10
- const [n, h] = m(null), c = f(() => n ? [...s].sort((t, i) => {
11
- const o = t[n.key], l = i[n.key];
12
- return o < l ? n.direction === "asc" ? -1 : 1 : o > l ? n.direction === "asc" ? 1 : -1 : 0;
13
- }) : s, [s, n]), y = (e) => {
14
- e.sortable && h((t) => !t || t.key !== e.key ? { key: e.key, direction: "asc" } : t.direction === "asc" ? { key: e.key, direction: "desc" } : null);
15
- }, k = (e) => {
12
+ const [r, y] = N(null), f = j(() => {
13
+ if (!r) return d;
14
+ const { key: e, direction: t } = r, o = a.find((l) => l.key === e);
15
+ return [...d].sort((l, u) => {
16
+ if (o?.sortFn)
17
+ return t === "asc" ? o.sortFn(l, u) : o.sortFn(u, l);
18
+ const i = l[e], s = u[e];
19
+ if (i === s) return 0;
20
+ if (i == null) return t === "asc" ? -1 : 1;
21
+ if (s == null) return t === "asc" ? 1 : -1;
22
+ if (typeof i == "number" && typeof s == "number")
23
+ return t === "asc" ? i - s : s - i;
24
+ const v = String(i), x = String(s), k = v.localeCompare(x);
25
+ return t === "asc" ? k : -k;
26
+ });
27
+ }, [d, r, a]), b = (e) => {
28
+ e.sortable && y((t) => !t || t.key !== e.key ? { key: e.key, direction: "asc" } : t.direction === "asc" ? { key: e.key, direction: "desc" } : null);
29
+ }, S = (e) => typeof c == "function" ? c(e) : String(e[c]), _ = (e) => {
16
30
  if (!e.sortable) return null;
17
- const t = n?.key === e.key, i = n?.direction ?? "asc";
18
- return /* @__PURE__ */ r(
19
- "span",
20
- {
21
- className: `ui-table-sort-indicator ${t ? "active" : ""}`,
22
- "aria-hidden": "true",
23
- children: t ? i === "asc" ? "▲" : "▼" : "↕"
24
- }
25
- );
31
+ const t = r?.key === e.key, o = r?.direction;
32
+ return /* @__PURE__ */ n("span", { className: g("nui-table__sort-icon", t && "active"), "aria-hidden": "true", children: t && o === "asc" ? /* @__PURE__ */ n("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ n("path", { d: "m18 15-6-6-6 6" }) }) : t && o === "desc" ? /* @__PURE__ */ n("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ n("path", { d: "m6 9 6 6 6-6" }) }) : /* @__PURE__ */ h("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
33
+ /* @__PURE__ */ n("path", { d: "m7 15 5 5 5-5" }),
34
+ /* @__PURE__ */ n("path", { d: "m7 9 5-5 5 5" })
35
+ ] }) });
26
36
  };
27
- return /* @__PURE__ */ r("div", { className: "ui-table-container", children: /* @__PURE__ */ d("table", { className: `ui-table ${b}`, children: [
28
- /* @__PURE__ */ r("thead", { children: /* @__PURE__ */ r("tr", { children: a.map((e) => /* @__PURE__ */ r("th", { scope: "col", children: e.sortable ? /* @__PURE__ */ d(
29
- "button",
37
+ return /* @__PURE__ */ n("div", { className: "nui-table-wrapper", children: /* @__PURE__ */ h("table", { className: g("nui-table", m), children: [
38
+ /* @__PURE__ */ n("thead", { children: /* @__PURE__ */ n("tr", { children: a.map((e) => /* @__PURE__ */ n(
39
+ "th",
40
+ {
41
+ scope: "col",
42
+ style: { textAlign: e.align || "left" },
43
+ "aria-sort": r?.key === e.key ? r.direction === "asc" ? "ascending" : "descending" : "none",
44
+ children: e.sortable ? /* @__PURE__ */ h(
45
+ "button",
46
+ {
47
+ type: "button",
48
+ className: "nui-table__sort-button",
49
+ onClick: () => b(e),
50
+ style: { justifyContent: e.align === "right" ? "flex-end" : e.align === "center" ? "center" : "flex-start" },
51
+ children: [
52
+ e.label,
53
+ _(e)
54
+ ]
55
+ }
56
+ ) : /* @__PURE__ */ n("span", { className: "nui-table__header-label", children: e.label })
57
+ },
58
+ String(e.key)
59
+ )) }) }),
60
+ /* @__PURE__ */ n("tbody", { children: f.length === 0 ? /* @__PURE__ */ n("tr", { children: /* @__PURE__ */ n("td", { className: "nui-table__empty", colSpan: a.length, children: /* @__PURE__ */ n("div", { className: "nui-table__empty-content", children: p }) }) }) : f.map((e) => /* @__PURE__ */ n("tr", { className: "nui-table__row", children: a.map((t) => /* @__PURE__ */ n(
61
+ "td",
30
62
  {
31
- type: "button",
32
- className: "ui-table-sort-button",
33
- onClick: () => y(e),
34
- children: [
35
- e.label,
36
- k(e)
37
- ]
38
- }
39
- ) : e.label }, String(e.key))) }) }),
40
- /* @__PURE__ */ r("tbody", { children: c.length === 0 ? /* @__PURE__ */ r("tr", { children: /* @__PURE__ */ r("td", { className: "ui-table-empty", colSpan: a.length, children: u }) }) : c.map((e, t) => /* @__PURE__ */ r("tr", { className: "ui-table-row", children: a.map((i) => /* @__PURE__ */ r("td", { children: String(e[i.key]) }, String(i.key))) }, t)) })
63
+ style: { textAlign: t.align || "left" },
64
+ children: t.render ? t.render(e) : String(e[t.key] ?? "")
65
+ },
66
+ String(t.key)
67
+ )) }, S(e))) })
41
68
  ] }) });
42
69
  }
43
70
  export {
44
- N as Table
71
+ B as Table
45
72
  };
46
73
  //# sourceMappingURL=Table.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Table.js","sources":["../../../src/components/table/Table.tsx"],"sourcesContent":["/**\r\n * Table.tsx\r\n * ----------\r\n * Accessible, sortable, theme-aware table.\r\n */\r\n\r\nimport { useState, useMemo } from 'react';\r\nimport './Table.css';\r\n\r\nexport interface TableColumn<T> {\r\n key: keyof T;\r\n label: string;\r\n sortable?: boolean;\r\n}\r\n\r\ninterface TableProps<T> {\r\n columns: TableColumn<T>[];\r\n data: T[];\r\n emptyText?: string;\r\n className?: string;\r\n}\r\n\r\ntype SortState<T> = {\r\n key: keyof T;\r\n direction: 'asc' | 'desc';\r\n} | null;\r\n\r\nexport function Table<T extends Record<string, any>>({\r\n columns,\r\n data,\r\n emptyText = 'No data available',\r\n className = '',\r\n}: TableProps<T>) {\r\n const [sort, setSort] = useState<SortState<T>>(null);\r\n\r\n const sortedData = useMemo(() => {\r\n if (!sort) return data;\r\n\r\n const sorted = [...data].sort((a, b) => {\r\n const aVal = a[sort.key];\r\n const bVal = b[sort.key];\r\n\r\n if (aVal < bVal) return sort.direction === 'asc' ? -1 : 1;\r\n if (aVal > bVal) return sort.direction === 'asc' ? 1 : -1;\r\n return 0;\r\n });\r\n\r\n return sorted;\r\n }, [data, sort]);\r\n\r\n const toggleSort = (col: TableColumn<T>) => {\r\n if (!col.sortable) return;\r\n\r\n setSort((prev) => {\r\n if (!prev || prev.key !== col.key) {\r\n return { key: col.key, direction: 'asc' };\r\n }\r\n if (prev.direction === 'asc') {\r\n return { key: col.key, direction: 'desc' };\r\n }\r\n return null; // reset\r\n });\r\n };\r\n\r\n const renderSortIcon = (col: TableColumn<T>) => {\r\n if (!col.sortable) return null;\r\n\r\n const isActive = sort?.key === col.key;\r\n const dir = sort?.direction ?? 'asc';\r\n\r\n return (\r\n <span\r\n className={`ui-table-sort-indicator ${isActive ? 'active' : ''}`}\r\n aria-hidden=\"true\"\r\n >\r\n {isActive ? (dir === 'asc' ? '▲' : '▼') : '↕'}\r\n </span>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"ui-table-container\">\r\n <table className={`ui-table ${className}`}>\r\n <thead>\r\n <tr>\r\n {columns.map((col) => (\r\n <th key={String(col.key)} scope=\"col\">\r\n {col.sortable ? (\r\n <button\r\n type=\"button\"\r\n className=\"ui-table-sort-button\"\r\n onClick={() => toggleSort(col)}\r\n >\r\n {col.label}\r\n {renderSortIcon(col)}\r\n </button>\r\n ) : (\r\n col.label\r\n )}\r\n </th>\r\n ))}\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n {sortedData.length === 0 ? (\r\n <tr>\r\n <td className=\"ui-table-empty\" colSpan={columns.length}>\r\n {emptyText}\r\n </td>\r\n </tr>\r\n ) : (\r\n sortedData.map((row, i) => (\r\n <tr key={i} className=\"ui-table-row\">\r\n {columns.map((col) => (\r\n <td key={String(col.key)}>{String(row[col.key])}</td>\r\n ))}\r\n </tr>\r\n ))\r\n )}\r\n </tbody>\r\n </table>\r\n </div>\r\n );\r\n}\r\n"],"names":["Table","columns","data","emptyText","className","sort","setSort","useState","sortedData","useMemo","a","b","aVal","bVal","toggleSort","col","prev","renderSortIcon","isActive","dir","jsx","jsxs","row","i"],"mappings":";;;AA2BO,SAASA,EAAqC;AAAA,EACnD,SAAAC;AAAA,EACA,MAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,WAAAC,IAAY;AACd,GAAkB;AAChB,QAAM,CAACC,GAAMC,CAAO,IAAIC,EAAuB,IAAI,GAE7CC,IAAaC,EAAQ,MACpBJ,IAEU,CAAC,GAAGH,CAAI,EAAE,KAAK,CAACQ,GAAGC,MAAM;AACtC,UAAMC,IAAOF,EAAEL,EAAK,GAAG,GACjBQ,IAAOF,EAAEN,EAAK,GAAG;AAEvB,WAAIO,IAAOC,IAAaR,EAAK,cAAc,QAAQ,KAAK,IACpDO,IAAOC,IAAaR,EAAK,cAAc,QAAQ,IAAI,KAChD;AAAA,EACT,CAAC,IATiBH,GAYjB,CAACA,GAAMG,CAAI,CAAC,GAETS,IAAa,CAACC,MAAwB;AAC1C,IAAKA,EAAI,YAETT,EAAQ,CAACU,MACH,CAACA,KAAQA,EAAK,QAAQD,EAAI,MACrB,EAAE,KAAKA,EAAI,KAAK,WAAW,MAAA,IAEhCC,EAAK,cAAc,QACd,EAAE,KAAKD,EAAI,KAAK,WAAW,OAAA,IAE7B,IACR;AAAA,EACH,GAEME,IAAiB,CAACF,MAAwB;AAC9C,QAAI,CAACA,EAAI,SAAU,QAAO;AAE1B,UAAMG,IAAWb,GAAM,QAAQU,EAAI,KAC7BI,IAAMd,GAAM,aAAa;AAE/B,WACE,gBAAAe;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW,2BAA2BF,IAAW,WAAW,EAAE;AAAA,QAC9D,eAAY;AAAA,QAEX,UAAAA,IAAYC,MAAQ,QAAQ,MAAM,MAAO;AAAA,MAAA;AAAA,IAAA;AAAA,EAGhD;AAEA,SACE,gBAAAC,EAAC,SAAI,WAAU,sBACb,4BAAC,SAAA,EAAM,WAAW,YAAYhB,CAAS,IACrC,UAAA;AAAA,IAAA,gBAAAgB,EAAC,SAAA,EACC,UAAA,gBAAAA,EAAC,MAAA,EACE,UAAAnB,EAAQ,IAAI,CAACc,MACZ,gBAAAK,EAAC,MAAA,EAAyB,OAAM,OAC7B,UAAAL,EAAI,WACH,gBAAAM;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS,MAAMP,EAAWC,CAAG;AAAA,QAE5B,UAAA;AAAA,UAAAA,EAAI;AAAA,UACJE,EAAeF,CAAG;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA,IAGrBA,EAAI,MAAA,GAXC,OAAOA,EAAI,GAAG,CAavB,CACD,EAAA,CACH,GACF;AAAA,IAEA,gBAAAK,EAAC,WACE,UAAAZ,EAAW,WAAW,IACrB,gBAAAY,EAAC,MAAA,EACC,4BAAC,MAAA,EAAG,WAAU,kBAAiB,SAASnB,EAAQ,QAC7C,UAAAE,EAAA,CACH,GACF,IAEAK,EAAW,IAAI,CAACc,GAAKC,MACnB,gBAAAH,EAAC,QAAW,WAAU,gBACnB,YAAQ,IAAI,CAACL,MACZ,gBAAAK,EAAC,MAAA,EAA0B,iBAAOE,EAAIP,EAAI,GAAG,CAAC,EAAA,GAArC,OAAOA,EAAI,GAAG,CAAyB,CACjD,KAHMQ,CAIT,CACD,EAAA,CAEL;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;"}
1
+ {"version":3,"file":"Table.js","sources":["../../../src/components/table/Table.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { useState, useMemo } from 'react';\nimport { cn } from '../../utils';\nimport './Table.css';\n\n/* ============================================================\n * Types\n * ============================================================ */\n\nexport interface TableColumn<T> {\n /** The key from your data object that this column maps to */\n key: keyof T;\n /** The text displayed in the table header */\n label: string;\n /** Enables clicking the header to sort the table by this column */\n sortable?: boolean;\n /** Aligns the text in the column header and cells. Defaults to 'left' */\n align?: 'left' | 'center' | 'right';\n /** Custom render function for the cell. Useful for formatting (e.g., currency) or custom UI (e.g., status badges) */\n render?: (row: T) => React.ReactNode;\n /** Optional custom sorting function to override the default alphabetic/numeric sort */\n sortFn?: (a: T, b: T) => number;\n}\n\nexport interface TableProps<T> {\n /** Array of column configuration objects */\n columns: TableColumn<T>[];\n /** Array of data objects to render */\n data: T[];\n /** A unique identifier for each row (string/number key, or a function that returns a string) */\n rowKey: keyof T | ((row: T) => string);\n /** Text or React Node to display when the data array is empty */\n emptyText?: React.ReactNode;\n /** Custom class applied to the <table> element */\n className?: string;\n}\n\ntype SortState<T> = {\n key: keyof T;\n direction: 'asc' | 'desc';\n} | null;\n\n/* ============================================================\n * Component\n * ============================================================ */\n\n/**\n * Table Component\n * * A highly generic data table that supports automatic sorting and custom cell rendering.\n * * Uses strict TypeScript generics (`<T>`) so it can perfectly map to any data shape passed into it.\n */\nexport function Table<T>({\n columns,\n data,\n rowKey,\n emptyText = 'No data available',\n className,\n}: TableProps<T>) {\n const [sort, setSort] = useState<SortState<T>>(null);\n\n /* ----------------------------------------------------\n Sorting Logic\n ---------------------------------------------------- */\n const sortedData = useMemo(() => {\n if (!sort) return data;\n\n const { key, direction } = sort;\n const column = columns.find((c) => c.key === key);\n\n return [...data].sort((a, b) => {\n // 1. Fallback to custom sort function if provided\n if (column?.sortFn) {\n return direction === 'asc' ? column.sortFn(a, b) : column.sortFn(b, a);\n }\n\n const aVal = a[key];\n const bVal = b[key];\n\n if (aVal === bVal) return 0;\n if (aVal === null || aVal === undefined) return direction === 'asc' ? -1 : 1;\n if (bVal === null || bVal === undefined) return direction === 'asc' ? 1 : -1;\n\n // 2. Type-safe numeric sorting\n if (typeof aVal === 'number' && typeof bVal === 'number') {\n return direction === 'asc' ? aVal - bVal : bVal - aVal;\n }\n\n // 3. Type-safe string sorting (perfect for alphabetic ordering)\n const aStr = String(aVal);\n const bStr = String(bVal);\n const diff = aStr.localeCompare(bStr);\n \n return direction === 'asc' ? diff : -diff;\n });\n }, [data, sort, columns]);\n\n /* ----------------------------------------------------\n Event Handlers\n ---------------------------------------------------- */\n const toggleSort = (col: TableColumn<T>) => {\n if (!col.sortable) return;\n\n setSort((prev) => {\n // If clicking a new column, or clicking for the first time, sort ASC\n if (!prev || prev.key !== col.key) {\n return { key: col.key, direction: 'asc' };\n }\n // If currently ASC, flip to DESC\n if (prev.direction === 'asc') {\n return { key: col.key, direction: 'desc' };\n }\n // If currently DESC, clear the sort\n return null;\n });\n };\n\n const getRowId = (row: T): string => {\n return typeof rowKey === 'function' ? rowKey(row) : String(row[rowKey]);\n };\n\n /* ----------------------------------------------------\n Render Helpers\n ---------------------------------------------------- */\n const renderSortIcon = (col: TableColumn<T>) => {\n if (!col.sortable) return null;\n\n const isActive = sort?.key === col.key;\n const dir = sort?.direction;\n\n return (\n <span className={cn(\"nui-table__sort-icon\", isActive && \"active\")} aria-hidden=\"true\">\n {isActive && dir === 'asc' ? (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"m18 15-6-6-6 6\"/></svg>\n ) : isActive && dir === 'desc' ? (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"m6 9 6 6 6-6\"/></svg>\n ) : (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"m7 15 5 5 5-5\"/><path d=\"m7 9 5-5 5 5\"/></svg>\n )}\n </span>\n );\n };\n\n /* ----------------------------------------------------\n Render\n ---------------------------------------------------- */\n return (\n <div className=\"nui-table-wrapper\">\n <table className={cn(\"nui-table\", className)}>\n <thead>\n <tr>\n {columns.map((col) => (\n <th \n key={String(col.key)} \n scope=\"col\"\n style={{ textAlign: col.align || 'left' }}\n aria-sort={sort?.key === col.key ? (sort.direction === 'asc' ? 'ascending' : 'descending') : 'none'}\n >\n {col.sortable ? (\n <button\n type=\"button\"\n className=\"nui-table__sort-button\"\n onClick={() => toggleSort(col)}\n style={{ justifyContent: col.align === 'right' ? 'flex-end' : col.align === 'center' ? 'center' : 'flex-start' }}\n >\n {col.label}\n {renderSortIcon(col)}\n </button>\n ) : (\n <span className=\"nui-table__header-label\">{col.label}</span>\n )}\n </th>\n ))}\n </tr>\n </thead>\n\n <tbody>\n {sortedData.length === 0 ? (\n <tr>\n <td className=\"nui-table__empty\" colSpan={columns.length}>\n <div className=\"nui-table__empty-content\">\n {emptyText}\n </div>\n </td>\n </tr>\n ) : (\n sortedData.map((row) => (\n <tr key={getRowId(row)} className=\"nui-table__row\">\n {columns.map((col) => (\n <td \n key={String(col.key)}\n style={{ textAlign: col.align || 'left' }}\n >\n {col.render ? col.render(row) : String(row[col.key] ?? '')}\n </td>\n ))}\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n );\n}"],"names":["Table","columns","data","rowKey","emptyText","className","sort","setSort","useState","sortedData","useMemo","key","direction","column","c","a","b","aVal","bVal","aStr","bStr","diff","toggleSort","col","prev","getRowId","row","renderSortIcon","isActive","dir","cn","jsx","jsxs"],"mappings":";;;;AAoDO,SAASA,EAAS;AAAA,EACvB,SAAAC;AAAA,EACA,MAAAC;AAAA,EACA,QAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,WAAAC;AACF,GAAkB;AAChB,QAAM,CAACC,GAAMC,CAAO,IAAIC,EAAuB,IAAI,GAK7CC,IAAaC,EAAQ,MAAM;AAC/B,QAAI,CAACJ,EAAM,QAAOJ;AAElB,UAAM,EAAE,KAAAS,GAAK,WAAAC,EAAA,IAAcN,GACrBO,IAASZ,EAAQ,KAAK,CAACa,MAAMA,EAAE,QAAQH,CAAG;AAEhD,WAAO,CAAC,GAAGT,CAAI,EAAE,KAAK,CAACa,GAAGC,MAAM;AAE9B,UAAIH,GAAQ;AACV,eAAOD,MAAc,QAAQC,EAAO,OAAOE,GAAGC,CAAC,IAAIH,EAAO,OAAOG,GAAGD,CAAC;AAGvE,YAAME,IAAOF,EAAEJ,CAAG,GACZO,IAAOF,EAAEL,CAAG;AAElB,UAAIM,MAASC,EAAM,QAAO;AAC1B,UAAID,KAAS,KAA4B,QAAOL,MAAc,QAAQ,KAAK;AAC3E,UAAIM,KAAS,KAA4B,QAAON,MAAc,QAAQ,IAAI;AAG1E,UAAI,OAAOK,KAAS,YAAY,OAAOC,KAAS;AAC9C,eAAON,MAAc,QAAQK,IAAOC,IAAOA,IAAOD;AAIpD,YAAME,IAAO,OAAOF,CAAI,GAClBG,IAAO,OAAOF,CAAI,GAClBG,IAAOF,EAAK,cAAcC,CAAI;AAEpC,aAAOR,MAAc,QAAQS,IAAO,CAACA;AAAA,IACvC,CAAC;AAAA,EACH,GAAG,CAACnB,GAAMI,GAAML,CAAO,CAAC,GAKlBqB,IAAa,CAACC,MAAwB;AAC1C,IAAKA,EAAI,YAEThB,EAAQ,CAACiB,MAEH,CAACA,KAAQA,EAAK,QAAQD,EAAI,MACrB,EAAE,KAAKA,EAAI,KAAK,WAAW,MAAA,IAGhCC,EAAK,cAAc,QACd,EAAE,KAAKD,EAAI,KAAK,WAAW,OAAA,IAG7B,IACR;AAAA,EACH,GAEME,IAAW,CAACC,MACT,OAAOvB,KAAW,aAAaA,EAAOuB,CAAG,IAAI,OAAOA,EAAIvB,CAAM,CAAC,GAMlEwB,IAAiB,CAACJ,MAAwB;AAC9C,QAAI,CAACA,EAAI,SAAU,QAAO;AAE1B,UAAMK,IAAWtB,GAAM,QAAQiB,EAAI,KAC7BM,IAAMvB,GAAM;AAElB,6BACG,QAAA,EAAK,WAAWwB,EAAG,wBAAwBF,KAAY,QAAQ,GAAG,eAAY,QAC5E,eAAYC,MAAQ,0BAClB,OAAA,EAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SAAQ,4BAAC,QAAA,EAAK,GAAE,kBAAgB,EAAA,CAAE,IACvKD,KAAYC,MAAQ,SACtB,gBAAAE,EAAC,OAAA,EAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SAAQ,4BAAC,QAAA,EAAK,GAAE,eAAA,CAAc,EAAA,CAAE,IAEvK,gBAAAC,EAAC,OAAA,EAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SAAQ,UAAA;AAAA,MAAA,gBAAAD,EAAC,QAAA,EAAK,GAAE,gBAAA,CAAe;AAAA,MAAE,gBAAAA,EAAC,QAAA,EAAK,GAAE,eAAA,CAAc;AAAA,IAAA,EAAA,CAAE,EAAA,CAEpM;AAAA,EAEJ;AAKA,SACE,gBAAAA,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA,gBAAAC,EAAC,WAAM,WAAWF,EAAG,aAAazB,CAAS,GACzC,UAAA;AAAA,IAAA,gBAAA0B,EAAC,WACC,UAAA,gBAAAA,EAAC,MAAA,EACE,UAAA9B,EAAQ,IAAI,CAACsB,MACZ,gBAAAQ;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,OAAM;AAAA,QACN,OAAO,EAAE,WAAWR,EAAI,SAAS,OAAA;AAAA,QACjC,aAAWjB,GAAM,QAAQiB,EAAI,MAAOjB,EAAK,cAAc,QAAQ,cAAc,eAAgB;AAAA,QAE5F,YAAI,WACH,gBAAA0B;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,SAAS,MAAMV,EAAWC,CAAG;AAAA,YAC7B,OAAO,EAAE,gBAAgBA,EAAI,UAAU,UAAU,aAAaA,EAAI,UAAU,WAAW,WAAW,aAAA;AAAA,YAEjG,UAAA;AAAA,cAAAA,EAAI;AAAA,cACJI,EAAeJ,CAAG;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA,IAGrB,gBAAAQ,EAAC,QAAA,EAAK,WAAU,2BAA2B,YAAI,MAAA,CAAM;AAAA,MAAA;AAAA,MAhBlD,OAAOR,EAAI,GAAG;AAAA,IAAA,CAmBtB,GACH,EAAA,CACF;AAAA,IAEA,gBAAAQ,EAAC,SAAA,EACE,UAAAtB,EAAW,WAAW,IACrB,gBAAAsB,EAAC,MAAA,EACC,UAAA,gBAAAA,EAAC,MAAA,EAAG,WAAU,oBAAmB,SAAS9B,EAAQ,QAChD,UAAA,gBAAA8B,EAAC,OAAA,EAAI,WAAU,4BACZ,UAAA3B,EAAA,CACH,EAAA,CACF,EAAA,CACF,IAEAK,EAAW,IAAI,CAACiB,MACd,gBAAAK,EAAC,QAAuB,WAAU,kBAC/B,UAAA9B,EAAQ,IAAI,CAACsB,MACZ,gBAAAQ;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,OAAO,EAAE,WAAWR,EAAI,SAAS,OAAA;AAAA,QAEhC,UAAAA,EAAI,SAASA,EAAI,OAAOG,CAAG,IAAI,OAAOA,EAAIH,EAAI,GAAG,KAAK,EAAE;AAAA,MAAA;AAAA,MAHpD,OAAOA,EAAI,GAAG;AAAA,IAAA,CAKtB,KARME,EAASC,CAAG,CASrB,CACD,EAAA,CAEL;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("react/jsx-runtime"),c=require("react");;/* empty css */function h({tabs:i,defaultTab:u,className:a=""}){const[t,s]=c.useState(u||i[0]?.id),o=c.useRef([]);c.useEffect(()=>{const e=i.findIndex(n=>n.id===t);o.current[e]?.focus()},[t,i]);const f=(e,n)=>{if(!["ArrowRight","ArrowLeft","Home","End"].includes(e.key))return;e.preventDefault();let r=n;e.key==="ArrowRight"&&(r=(n+1)%i.length),e.key==="ArrowLeft"&&(r=(n-1+i.length)%i.length),e.key==="Home"&&(r=0),e.key==="End"&&(r=i.length-1),s(i[r].id)};return l.jsxs("div",{className:`ui-tabs ${a}`,children:[l.jsx("div",{role:"tablist",className:"ui-tabs-list",children:i.map((e,n)=>{const r=e.id===t;return l.jsx("button",{ref:d=>{o.current[n]=d},role:"tab",id:`tab-${e.id}`,"aria-selected":r,"aria-controls":`panel-${e.id}`,tabIndex:r?0:-1,className:"ui-tab",onClick:()=>s(e.id),onKeyDown:d=>f(d,n),children:e.label},e.id)})}),i.map(e=>e.id===t?l.jsx("div",{id:`panel-${e.id}`,role:"tabpanel","aria-labelledby":`tab-${e.id}`,className:"ui-tabs-panel",children:e.content},e.id):null)]})}exports.Tabs=h;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g=require("react/jsx-runtime"),o=require("react");;/* empty css */const x=require("../../utils/cn/cn.cjs"),y=o.createContext(null);function h(){const e=o.useContext(y);if(!e)throw new Error("Tabs components must be used within <Tabs>");return e}const m=o.forwardRef(({value:e,defaultValue:c,onChange:u,children:n,className:i,...b},t)=>{const l=e!==void 0,[d,s]=o.useState(c||""),a=o.useId(),r=l?e:d,f=T=>{l||s(T),u?.(T)};return g.jsx(y.Provider,{value:{value:r,onValueChange:f,idPrefix:a},children:g.jsx("div",{ref:t,className:x.cn("nui-tabs-root",i),...b,children:n})})});m.displayName="Tabs";const p=o.forwardRef(({children:e,className:c,...u},n)=>{const i=o.useRef(null),b=t=>{const l=t.target;if(l.getAttribute("role")!=="tab")return;const d=i.current;if(!d)return;const s=Array.from(d.querySelectorAll('[role="tab"]:not([disabled])')),a=s.indexOf(l);if(a===-1)return;let r=a;if(t.key==="ArrowRight")r=(a+1)%s.length;else if(t.key==="ArrowLeft")r=(a-1+s.length)%s.length;else if(t.key==="Home")r=0;else if(t.key==="End")r=s.length-1;else return;t.preventDefault(),s[r].focus()};return g.jsx("div",{ref:t=>{i.current=t,typeof n=="function"?n(t):n&&(n.current=t)},role:"tablist","aria-orientation":"horizontal",className:x.cn("nui-tabs-list",c),onKeyDown:b,...u,children:e})});p.displayName="Tabs.List";const C=o.forwardRef(({value:e,children:c,className:u,disabled:n,onClick:i,onFocus:b,...t},l)=>{const{value:d,onValueChange:s,idPrefix:a}=h(),r=d===e;return g.jsx("button",{ref:l,type:"button",role:"tab",id:`tab-${a}-${e}`,"aria-selected":r,"aria-controls":`panel-${a}-${e}`,tabIndex:r?0:-1,disabled:n,className:x.cn("nui-tabs-trigger",r&&"selected",n&&"disabled",u),onClick:f=>{n||s(e),i?.(f)},onFocus:f=>{n||s(e),b?.(f)},...t,children:c})});C.displayName="Tabs.Trigger";const w=o.forwardRef(({value:e,children:c,className:u,...n},i)=>{const{value:b,idPrefix:t}=h();return b===e?g.jsx("div",{ref:i,role:"tabpanel",id:`panel-${t}-${e}`,"aria-labelledby":`tab-${t}-${e}`,tabIndex:0,className:x.cn("nui-tabs-content",u),...n,children:c}):null});w.displayName="Tabs.Content";const R=Object.assign(m,{List:p,Trigger:C,Content:w});exports.Tabs=R;
2
2
  //# sourceMappingURL=Tabs.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tabs.cjs","sources":["../../../src/components/tabs/Tabs.tsx"],"sourcesContent":["/**\r\n * Tabs.tsx\r\n * ---------\r\n * Fully accessible WAI-ARIA Tabs Component.\r\n *\r\n * Features:\r\n * - roving tabindex\r\n * - ArrowLeft, ArrowRight, Home, End keyboard navigation\r\n * - aria-selected, aria-controls, role=\"tablist\"\r\n * - auto-focus on selected tab\r\n * - single-component API\r\n */\r\n\r\nimport React, { useState, useRef, useEffect } from 'react';\r\nimport './Tabs.css';\r\n\r\nexport interface TabItem {\r\n id: string;\r\n label: string;\r\n content: React.ReactNode;\r\n}\r\n\r\ninterface TabsProps {\r\n tabs: TabItem[];\r\n defaultTab?: string;\r\n className?: string;\r\n}\r\n\r\nexport function Tabs({ tabs, defaultTab, className = '' }: TabsProps) {\r\n const [active, setActive] = useState(defaultTab || tabs[0]?.id);\r\n\r\n const tabRefs = useRef<(HTMLButtonElement | null)[]>([]);\r\n\r\n // Focus active tab\r\n useEffect(() => {\r\n const index = tabs.findIndex((t) => t.id === active);\r\n tabRefs.current[index]?.focus();\r\n }, [active, tabs]);\r\n\r\n const handleKeyDown = (e: React.KeyboardEvent, index: number) => {\r\n if (!['ArrowRight', 'ArrowLeft', 'Home', 'End'].includes(e.key)) return;\r\n\r\n e.preventDefault();\r\n\r\n let newIndex = index;\r\n\r\n if (e.key === 'ArrowRight') newIndex = (index + 1) % tabs.length;\r\n if (e.key === 'ArrowLeft')\r\n newIndex = (index - 1 + tabs.length) % tabs.length;\r\n if (e.key === 'Home') newIndex = 0;\r\n if (e.key === 'End') newIndex = tabs.length - 1;\r\n\r\n setActive(tabs[newIndex].id);\r\n };\r\n\r\n return (\r\n <div className={`ui-tabs ${className}`}>\r\n <div role=\"tablist\" className=\"ui-tabs-list\">\r\n {tabs.map((tab, index) => {\r\n const isSelected = tab.id === active;\r\n\r\n return (\r\n <button\r\n key={tab.id}\r\n ref={(el) => {\r\n tabRefs.current[index] = el;\r\n }}\r\n role=\"tab\"\r\n id={`tab-${tab.id}`}\r\n aria-selected={isSelected}\r\n aria-controls={`panel-${tab.id}`}\r\n tabIndex={isSelected ? 0 : -1}\r\n className=\"ui-tab\"\r\n onClick={() => setActive(tab.id)}\r\n onKeyDown={(e) => handleKeyDown(e, index)}\r\n >\r\n {tab.label}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n\r\n {tabs.map((tab) =>\r\n tab.id === active ? (\r\n <div\r\n key={tab.id}\r\n id={`panel-${tab.id}`}\r\n role=\"tabpanel\"\r\n aria-labelledby={`tab-${tab.id}`}\r\n className=\"ui-tabs-panel\"\r\n >\r\n {tab.content}\r\n </div>\r\n ) : null\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"names":["Tabs","tabs","defaultTab","className","active","setActive","useState","tabRefs","useRef","useEffect","index","t","handleKeyDown","newIndex","jsxs","jsx","tab","isSelected","el","e"],"mappings":"kKA4BO,SAASA,EAAK,CAAE,KAAAC,EAAM,WAAAC,EAAY,UAAAC,EAAY,IAAiB,CACpE,KAAM,CAACC,EAAQC,CAAS,EAAIC,EAAAA,SAASJ,GAAcD,EAAK,CAAC,GAAG,EAAE,EAExDM,EAAUC,EAAAA,OAAqC,EAAE,EAGvDC,EAAAA,UAAU,IAAM,CACd,MAAMC,EAAQT,EAAK,UAAWU,GAAMA,EAAE,KAAOP,CAAM,EACnDG,EAAQ,QAAQG,CAAK,GAAG,MAAA,CAC1B,EAAG,CAACN,EAAQH,CAAI,CAAC,EAEjB,MAAMW,EAAgB,CAAC,EAAwBF,IAAkB,CAC/D,GAAI,CAAC,CAAC,aAAc,YAAa,OAAQ,KAAK,EAAE,SAAS,EAAE,GAAG,EAAG,OAEjE,EAAE,eAAA,EAEF,IAAIG,EAAWH,EAEX,EAAE,MAAQ,eAAcG,GAAYH,EAAQ,GAAKT,EAAK,QACtD,EAAE,MAAQ,cACZY,GAAYH,EAAQ,EAAIT,EAAK,QAAUA,EAAK,QAC1C,EAAE,MAAQ,SAAQY,EAAW,GAC7B,EAAE,MAAQ,QAAOA,EAAWZ,EAAK,OAAS,GAE9CI,EAAUJ,EAAKY,CAAQ,EAAE,EAAE,CAC7B,EAEA,OACEC,EAAAA,KAAC,MAAA,CAAI,UAAW,WAAWX,CAAS,GAClC,SAAA,CAAAY,EAAAA,IAAC,MAAA,CAAI,KAAK,UAAU,UAAU,eAC3B,SAAAd,EAAK,IAAI,CAACe,EAAKN,IAAU,CACxB,MAAMO,EAAaD,EAAI,KAAOZ,EAE9B,OACEW,EAAAA,IAAC,SAAA,CAEC,IAAMG,GAAO,CACXX,EAAQ,QAAQG,CAAK,EAAIQ,CAC3B,EACA,KAAK,MACL,GAAI,OAAOF,EAAI,EAAE,GACjB,gBAAeC,EACf,gBAAe,SAASD,EAAI,EAAE,GAC9B,SAAUC,EAAa,EAAI,GAC3B,UAAU,SACV,QAAS,IAAMZ,EAAUW,EAAI,EAAE,EAC/B,UAAYG,GAAMP,EAAcO,EAAGT,CAAK,EAEvC,SAAAM,EAAI,KAAA,EAbAA,EAAI,EAAA,CAgBf,CAAC,CAAA,CACH,EAECf,EAAK,IAAKe,GACTA,EAAI,KAAOZ,EACTW,EAAAA,IAAC,MAAA,CAEC,GAAI,SAASC,EAAI,EAAE,GACnB,KAAK,WACL,kBAAiB,OAAOA,EAAI,EAAE,GAC9B,UAAU,gBAET,SAAAA,EAAI,OAAA,EANAA,EAAI,EAAA,EAQT,IAAA,CACN,EACF,CAEJ"}
1
+ {"version":3,"file":"Tabs.cjs","sources":["../../../src/components/tabs/Tabs.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { createContext, useContext, useState, useRef, forwardRef, useId } from 'react';\nimport { cn } from '../../utils';\nimport './Tabs.css';\n\n/* ============================================================\n * Context\n * ============================================================ */\n\ninterface TabsContextValue {\n value: string;\n onValueChange: (value: string) => void;\n // A unique ID prefix to link triggers and panels for screen readers\n idPrefix: string; \n}\n\nconst TabsContext = createContext<TabsContextValue | null>(null);\n\nfunction useTabs() {\n const ctx = useContext(TabsContext);\n if (!ctx) throw new Error('Tabs components must be used within <Tabs>');\n return ctx;\n}\n\n/* ============================================================\n * 1. Tabs Root\n * ============================================================ */\n\nexport interface TabsProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n /** Controlled state value representing the active tab */\n value?: string;\n /** Uncontrolled initial value */\n defaultValue?: string;\n /** Callback fired when the active tab changes */\n onChange?: (value: string) => void;\n children: React.ReactNode;\n}\n\n/**\n * Tabs Component (Root)\n * * A Compound Component that manages the state and accessibility linking for a tabbed interface.\n */\nconst TabsRoot = forwardRef<HTMLDivElement, TabsProps>(\n ({ value, defaultValue, onChange, children, className, ...props }, ref) => {\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState(defaultValue || '');\n \n // Generate a stable, SSR-safe ID for ARIA linkage\n const idPrefix = useId();\n\n const currentValue = isControlled ? value : internalValue;\n\n const handleValueChange = (newValue: string) => {\n if (!isControlled) setInternalValue(newValue);\n onChange?.(newValue);\n };\n\n return (\n <TabsContext.Provider value={{ value: currentValue, onValueChange: handleValueChange, idPrefix }}>\n <div ref={ref} className={cn(\"nui-tabs-root\", className)} {...props}>\n {children}\n </div>\n </TabsContext.Provider>\n );\n }\n);\nTabsRoot.displayName = 'Tabs';\n\n/* ============================================================\n * 2. Tabs List\n * ============================================================ */\n\nexport interface TabsListProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n}\n\n/**\n * Tabs List\n * * Contains the tab triggers.\n * * Implements a \"Roving Tabindex\" to allow users to navigate tabs via arrow keys.\n */\nconst TabsList = forwardRef<HTMLDivElement, TabsListProps>(\n ({ children, className, ...props }, ref) => {\n const listRef = useRef<HTMLDivElement>(null);\n\n // Smart Roving Tabindex for Keyboard Navigation\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n const target = e.target as HTMLElement;\n if (target.getAttribute('role') !== 'tab') return;\n\n const list = listRef.current;\n if (!list) return;\n\n // Find all valid tab triggers\n const tabs = Array.from(\n list.querySelectorAll('[role=\"tab\"]:not([disabled])')\n ) as HTMLElement[];\n \n const currentIndex = tabs.indexOf(target);\n if (currentIndex === -1) return;\n\n let nextIndex = currentIndex;\n\n if (e.key === 'ArrowRight') nextIndex = (currentIndex + 1) % tabs.length;\n else if (e.key === 'ArrowLeft') nextIndex = (currentIndex - 1 + tabs.length) % tabs.length;\n else if (e.key === 'Home') nextIndex = 0;\n else if (e.key === 'End') nextIndex = tabs.length - 1;\n else return;\n\n e.preventDefault();\n tabs[nextIndex].focus();\n };\n\n return (\n <div\n ref={(node) => {\n listRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n }}\n role=\"tablist\"\n aria-orientation=\"horizontal\"\n className={cn(\"nui-tabs-list\", className)}\n onKeyDown={handleKeyDown}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\nTabsList.displayName = 'Tabs.List';\n\n/* ============================================================\n * 3. Tabs Trigger\n * ============================================================ */\n\nexport interface TabsTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** The unique identifier associated with this tab's content */\n value: string;\n}\n\n/**\n * Tabs Trigger\n * * The interactive button that activates a specific tab panel.\n * * Follows the WAI-ARIA \"Automatic Activation\" pattern (focusing the tab activates it).\n */\nconst TabsTrigger = forwardRef<HTMLButtonElement, TabsTriggerProps>(\n ({ value, children, className, disabled, onClick, onFocus, ...props }, ref) => {\n const { value: selectedValue, onValueChange, idPrefix } = useTabs();\n const isSelected = selectedValue === value;\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"tab\"\n id={`tab-${idPrefix}-${value}`}\n aria-selected={isSelected}\n aria-controls={`panel-${idPrefix}-${value}`}\n tabIndex={isSelected ? 0 : -1} // Only active tab is in the natural page tab sequence\n disabled={disabled}\n className={cn(\n \"nui-tabs-trigger\",\n isSelected && \"selected\",\n disabled && \"disabled\",\n className\n )}\n onClick={(e) => {\n if (!disabled) onValueChange(value);\n onClick?.(e);\n }}\n onFocus={(e) => {\n // Automatic Activation: Auto-select on keyboard focus\n if (!disabled) onValueChange(value);\n onFocus?.(e);\n }}\n {...props}\n >\n {children}\n </button>\n );\n }\n);\nTabsTrigger.displayName = 'Tabs.Trigger';\n\n/* ============================================================\n * 4. Tabs Content\n * ============================================================ */\n\nexport interface TabsContentProps extends React.HTMLAttributes<HTMLDivElement> {\n /** The unique identifier connecting this panel to its trigger */\n value: string;\n}\n\n/**\n * Tabs Content\n * * The panel that displays when its associated trigger is active.\n * * Only mounts to the DOM when active to keep the DOM clean.\n */\nconst TabsContent = forwardRef<HTMLDivElement, TabsContentProps>(\n ({ value, children, className, ...props }, ref) => {\n const { value: selectedValue, idPrefix } = useTabs();\n const isSelected = selectedValue === value;\n\n if (!isSelected) return null;\n\n return (\n <div\n ref={ref}\n role=\"tabpanel\"\n id={`panel-${idPrefix}-${value}`}\n aria-labelledby={`tab-${idPrefix}-${value}`}\n tabIndex={0} // Allows content area to be focused and read by screen readers\n className={cn(\"nui-tabs-content\", className)}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\nTabsContent.displayName = 'Tabs.Content';\n\n/* ============================================================\n * Export\n * ============================================================ */\n\nexport const Tabs = Object.assign(TabsRoot, {\n List: TabsList,\n Trigger: TabsTrigger,\n Content: TabsContent,\n});"],"names":["TabsContext","createContext","useTabs","ctx","useContext","TabsRoot","forwardRef","value","defaultValue","onChange","children","className","props","ref","isControlled","internalValue","setInternalValue","useState","idPrefix","useId","currentValue","handleValueChange","newValue","jsx","cn","TabsList","listRef","useRef","handleKeyDown","e","target","list","tabs","currentIndex","nextIndex","node","TabsTrigger","disabled","onClick","onFocus","selectedValue","onValueChange","isSelected","TabsContent","Tabs"],"mappings":"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"}