@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":"Pagination.js","sources":["../../../src/components/pagination/Pagination.tsx"],"sourcesContent":["/**\r\n * Pagination.tsx\r\n * -----------------\r\n * WAI-ARIA compliant pagination component.\r\n *\r\n * Features:\r\n * - First / Prev / Next / Last controls\r\n * - Arrow key navigation\r\n * - Controlled + fully typed\r\n * - Accessible roles & labels\r\n * - Works with screen readers\r\n * - Theme-aware classes only (no inline styles)\r\n */\r\n\r\n/**\r\n * Pagination.tsx — FINAL VERSION\r\n * --------------------------------\r\n * - No duplicate keys\r\n * - GitHub-style gap rendering\r\n * - Clean, predictable page logic\r\n * - Fully accessible\r\n * - No external dependencies\r\n */\r\n\r\nimport './Pagination.css';\r\n\r\nexport interface PaginationProps {\r\n page: number; // current page (1-based)\r\n total: number; // total pages\r\n onChange: (p: number) => void;\r\n siblings?: number; // how many pages to show around active page\r\n className?: string;\r\n}\r\n\r\nexport function Pagination({\r\n page,\r\n total,\r\n onChange,\r\n siblings = 1,\r\n className = '',\r\n}: PaginationProps) {\r\n if (total <= 1) return null;\r\n\r\n const goTo = (p: number) => {\r\n if (p < 1 || p > total) return;\r\n onChange(p);\r\n };\r\n\r\n /* -------------------------------------------------------\r\n * Page calculation (no duplicates, GitHub-style)\r\n * ------------------------------------------------------*/\r\n\r\n const pages: (number | '...')[] = [];\r\n\r\n const hasLeftGap = page - siblings > 2;\r\n const hasRightGap = page + siblings < total - 1;\r\n\r\n const start = Math.max(1, page - siblings);\r\n const end = Math.min(total, page + siblings);\r\n\r\n // Always add first page\r\n pages.push(1);\r\n\r\n // Left gap …\r\n if (hasLeftGap) pages.push('...');\r\n\r\n // Middle pages\r\n for (let i = start; i <= end; i++) {\r\n if (i !== 1 && i !== total) {\r\n pages.push(i);\r\n }\r\n }\r\n\r\n // Right gap …\r\n if (hasRightGap) pages.push('...');\r\n\r\n // Always add last page\r\n if (total > 1) pages.push(total);\r\n\r\n return (\r\n <nav\r\n className={`ui-pagination ${className}`}\r\n aria-label=\"Pagination Navigation\"\r\n >\r\n {/* Previous */}\r\n <button\r\n className=\"ui-page-btn\"\r\n onClick={() => goTo(page - 1)}\r\n disabled={page === 1}\r\n aria-label=\"Previous Page\"\r\n >\r\n ←\r\n </button>\r\n\r\n {/* Pages */}\r\n {pages.map((p, i) =>\r\n p === '...' ? (\r\n <span key={`ellipsis-${i}`} className=\"ui-page-ellipsis\">\r\n …\r\n </span>\r\n ) : (\r\n <button\r\n key={`page-${p}`}\r\n className={`ui-page-btn ${p === page ? 'active' : ''}`}\r\n aria-current={p === page ? 'page' : undefined}\r\n onClick={() => goTo(p)}\r\n >\r\n {p}\r\n </button>\r\n )\r\n )}\r\n\r\n {/* Next */}\r\n <button\r\n className=\"ui-page-btn\"\r\n onClick={() => goTo(page + 1)}\r\n disabled={page === total}\r\n aria-label=\"Next Page\"\r\n >\r\n →\r\n </button>\r\n </nav>\r\n );\r\n}\r\n"],"names":["Pagination","page","total","onChange","siblings","className","goTo","p","pages","hasLeftGap","hasRightGap","start","end","jsxs","jsx","i"],"mappings":";;AAkCO,SAASA,EAAW;AAAA,EACzB,MAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,WAAAC,IAAY;AACd,GAAoB;AAClB,MAAIH,KAAS,EAAG,QAAO;AAEvB,QAAMI,IAAO,CAACC,MAAc;AAC1B,IAAIA,IAAI,KAAKA,IAAIL,KACjBC,EAASI,CAAC;AAAA,EACZ,GAMMC,IAA4B,CAAA,GAE5BC,IAAaR,IAAOG,IAAW,GAC/BM,IAAcT,IAAOG,IAAWF,IAAQ,GAExCS,IAAQ,KAAK,IAAI,GAAGV,IAAOG,CAAQ,GACnCQ,IAAM,KAAK,IAAIV,GAAOD,IAAOG,CAAQ;AAG3C,EAAAI,EAAM,KAAK,CAAC,GAGRC,KAAYD,EAAM,KAAK,KAAK;AAGhC,WAAS,IAAIG,GAAO,KAAKC,GAAK;AAC5B,IAAI,MAAM,KAAK,MAAMV,KACnBM,EAAM,KAAK,CAAC;AAKhB,SAAIE,KAAaF,EAAM,KAAK,KAAK,GAG7BN,IAAQ,KAAGM,EAAM,KAAKN,CAAK,GAG7B,gBAAAW;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,iBAAiBR,CAAS;AAAA,MACrC,cAAW;AAAA,MAGX,UAAA;AAAA,QAAA,gBAAAS;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,SAAS,MAAMR,EAAKL,IAAO,CAAC;AAAA,YAC5B,UAAUA,MAAS;AAAA,YACnB,cAAW;AAAA,YACZ,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAKAO,EAAM;AAAA,UAAI,CAACD,GAAGQ,MACbR,MAAM,QACJ,gBAAAO,EAAC,QAAA,EAA2B,WAAU,oBAAmB,UAAA,OAA9C,YAAYC,CAAC,EAExB,IAEA,gBAAAD;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,WAAW,eAAeP,MAAMN,IAAO,WAAW,EAAE;AAAA,cACpD,gBAAcM,MAAMN,IAAO,SAAS;AAAA,cACpC,SAAS,MAAMK,EAAKC,CAAC;AAAA,cAEpB,UAAAA;AAAA,YAAA;AAAA,YALI,QAAQA,CAAC;AAAA,UAAA;AAAA,QAMhB;AAAA,QAKJ,gBAAAO;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,SAAS,MAAMR,EAAKL,IAAO,CAAC;AAAA,YAC5B,UAAUA,MAASC;AAAA,YACnB,cAAW;AAAA,YACZ,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAED;AAAA,IAAA;AAAA,EAAA;AAGN;"}
1
+ {"version":3,"file":"Pagination.js","sources":["../../../src/components/pagination/Pagination.tsx"],"sourcesContent":["import React, { useMemo } from 'react';\nimport { cn } from '../../utils';\nimport './Pagination.css';\n\n/* ============================================================\n * Types\n * ============================================================ */\n\nexport interface PaginationProps extends Omit<React.HTMLAttributes<HTMLElement>, 'onChange'> {\n /** The current active page number (1-indexed) */\n page: number;\n /** The total number of pages available */\n total: number;\n /** Callback fired when a new page is selected */\n onChange: (page: number) => void;\n /** Number of page links to show on each side of the current page. Defaults to 1. */\n siblings?: number;\n /** Custom class name applied to the root navigation element */\n className?: string;\n /** Disables all interaction with the pagination controls */\n disabled?: boolean;\n}\n\ntype PaginationItem = number | 'left-ellipsis' | 'right-ellipsis';\n\n/* ============================================================\n * Component\n * ============================================================ */\n\n/**\n * Pagination Component\n * * A navigation structure for splitting large lists across multiple pages.\n * * Automatically calculates when to collapse page ranges into ellipses based on siblings.\n * * Uses standard <nav> and <ul> elements for WAI-ARIA compliance.\n */\nexport function Pagination({\n page,\n total,\n onChange,\n siblings = 1,\n className,\n disabled = false,\n ...props\n}: PaginationProps) {\n \n // Guard against invalid ranges supplied by the developer\n const currentPage = Math.max(1, Math.min(page, total));\n\n const goTo = (p: number) => {\n if (disabled || p < 1 || p > total || p === currentPage) return;\n onChange(p);\n };\n\n /* ----------------------------------------------------\n Mathematically Perfect Page Generation\n ---------------------------------------------------- */\n const pages = useMemo<PaginationItem[]>(() => {\n // Math: 1 (first) + 1 (last) + 2 (siblings) + 1 (current) + 2 (ellipses)\n const totalPageNumbersToShow = 5 + siblings * 2;\n\n // 1. If we don't have enough pages to warrant an ellipsis, show them all\n if (total <= totalPageNumbersToShow) {\n return Array.from({ length: total }, (_, i) => i + 1);\n }\n\n const leftSiblingIndex = Math.max(currentPage - siblings, 1);\n const rightSiblingIndex = Math.min(currentPage + siblings, total);\n\n // 2. We only show an ellipsis if there are MORE than 2 pages hidden\n const showLeftDots = leftSiblingIndex > 2;\n const showRightDots = rightSiblingIndex < total - 2;\n\n const firstPageIndex = 1;\n const lastPageIndex = total;\n\n // Case 1: Show right dots only (e.g., [1] 2 3 4 5 ... 10)\n if (!showLeftDots && showRightDots) {\n const leftItemCount = 3 + 2 * siblings;\n const leftRange = Array.from({ length: leftItemCount }, (_, i) => i + 1);\n return [...leftRange, 'right-ellipsis', lastPageIndex];\n }\n\n // Case 2: Show left dots only (e.g., 1 ... 6 7 8 9 [10])\n if (showLeftDots && !showRightDots) {\n const rightItemCount = 3 + 2 * siblings;\n const rightRange = Array.from({ length: rightItemCount }, (_, i) => total - rightItemCount + 1 + i);\n return [firstPageIndex, 'left-ellipsis', ...rightRange];\n }\n\n // Case 3: Show both dots (e.g., 1 ... 4 [5] 6 ... 10)\n if (showLeftDots && showRightDots) {\n const middleRange = Array.from(\n { length: rightSiblingIndex - leftSiblingIndex + 1 },\n (_, i) => leftSiblingIndex + i\n );\n return [firstPageIndex, 'left-ellipsis', ...middleRange, 'right-ellipsis', lastPageIndex];\n }\n\n return [];\n }, [total, currentPage, siblings]);\n\n if (total <= 1) return null;\n\n /* ----------------------------------------------------\n Render\n ---------------------------------------------------- */\n return (\n <nav\n className={cn(\"nui-pagination\", className)}\n aria-label=\"Pagination Navigation\"\n {...props}\n >\n <ul className=\"nui-pagination-list\">\n \n {/* Previous Button */}\n <li>\n <button\n className=\"nui-pagination-btn nui-pagination-btn--nav\"\n onClick={() => goTo(currentPage - 1)}\n disabled={disabled || currentPage === 1}\n aria-label=\"Previous Page\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <polyline points=\"15 18 9 12 15 6\"></polyline>\n </svg>\n </button>\n </li>\n\n {/* Page Numbers & Ellipses */}\n {pages.map((p) => {\n if (p === 'left-ellipsis' || p === 'right-ellipsis') {\n return (\n <li key={p} className=\"nui-pagination-ellipsis\" aria-hidden=\"true\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"1\"></circle>\n <circle cx=\"19\" cy=\"12\" r=\"1\"></circle>\n <circle cx=\"5\" cy=\"12\" r=\"1\"></circle>\n </svg>\n </li>\n );\n }\n\n const isCurrent = p === currentPage;\n\n return (\n <li key={`page-${p}`}>\n <button\n className={cn(\n \"nui-pagination-btn\",\n isCurrent && \"nui-pagination-btn--active\"\n )}\n aria-current={isCurrent ? 'page' : undefined}\n aria-label={isCurrent ? `Page ${p}` : `Go to page ${p}`}\n disabled={disabled}\n onClick={() => goTo(p)}\n >\n {p}\n </button>\n </li>\n );\n })}\n\n {/* Next Button */}\n <li>\n <button\n className=\"nui-pagination-btn nui-pagination-btn--nav\"\n onClick={() => goTo(currentPage + 1)}\n disabled={disabled || currentPage === total}\n aria-label=\"Next Page\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <polyline points=\"9 18 15 12 9 6\"></polyline>\n </svg>\n </button>\n </li>\n </ul>\n </nav>\n );\n}"],"names":["Pagination","page","total","onChange","siblings","className","disabled","props","currentPage","goTo","p","pages","useMemo","totalPageNumbersToShow","_","i","leftSiblingIndex","rightSiblingIndex","showLeftDots","showRightDots","firstPageIndex","lastPageIndex","leftItemCount","rightItemCount","rightRange","middleRange","jsx","cn","jsxs","isCurrent"],"mappings":";;;;AAmCO,SAASA,EAAW;AAAA,EACzB,MAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,WAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,GAAGC;AACL,GAAoB;AAGlB,QAAMC,IAAc,KAAK,IAAI,GAAG,KAAK,IAAIP,GAAMC,CAAK,CAAC,GAE/CO,IAAO,CAACC,MAAc;AAC1B,IAAIJ,KAAYI,IAAI,KAAKA,IAAIR,KAASQ,MAAMF,KAC5CL,EAASO,CAAC;AAAA,EACZ,GAKMC,IAAQC,EAA0B,MAAM;AAE5C,UAAMC,IAAyB,IAAIT,IAAW;AAG9C,QAAIF,KAASW;AACX,aAAO,MAAM,KAAK,EAAE,QAAQX,KAAS,CAACY,GAAGC,MAAMA,IAAI,CAAC;AAGtD,UAAMC,IAAmB,KAAK,IAAIR,IAAcJ,GAAU,CAAC,GACrDa,IAAoB,KAAK,IAAIT,IAAcJ,GAAUF,CAAK,GAG1DgB,IAAeF,IAAmB,GAClCG,IAAgBF,IAAoBf,IAAQ,GAE5CkB,IAAiB,GACjBC,IAAgBnB;AAGtB,QAAI,CAACgB,KAAgBC,GAAe;AAClC,YAAMG,IAAgB,IAAI,IAAIlB;AAE9B,aAAO,CAAC,GADU,MAAM,KAAK,EAAE,QAAQkB,EAAA,GAAiB,CAACR,GAAGC,MAAMA,IAAI,CAAC,GACjD,kBAAkBM,CAAa;AAAA,IACvD;AAGA,QAAIH,KAAgB,CAACC,GAAe;AAClC,YAAMI,IAAiB,IAAI,IAAInB,GACzBoB,IAAa,MAAM,KAAK,EAAE,QAAQD,EAAA,GAAkB,CAACT,GAAGC,MAAMb,IAAQqB,IAAiB,IAAIR,CAAC;AAClG,aAAO,CAACK,GAAgB,iBAAiB,GAAGI,CAAU;AAAA,IACxD;AAGA,QAAIN,KAAgBC,GAAe;AACjC,YAAMM,IAAc,MAAM;AAAA,QACxB,EAAE,QAAQR,IAAoBD,IAAmB,EAAA;AAAA,QACjD,CAACF,GAAGC,MAAMC,IAAmBD;AAAA,MAAA;AAE/B,aAAO,CAACK,GAAgB,iBAAiB,GAAGK,GAAa,kBAAkBJ,CAAa;AAAA,IAC1F;AAEA,WAAO,CAAA;AAAA,EACT,GAAG,CAACnB,GAAOM,GAAaJ,CAAQ,CAAC;AAEjC,SAAIF,KAAS,IAAU,OAMrB,gBAAAwB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,EAAG,kBAAkBtB,CAAS;AAAA,MACzC,cAAW;AAAA,MACV,GAAGE;AAAA,MAEJ,UAAA,gBAAAqB,EAAC,MAAA,EAAG,WAAU,uBAGZ,UAAA;AAAA,QAAA,gBAAAF,EAAC,MAAA,EACC,UAAA,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,SAAS,MAAMjB,EAAKD,IAAc,CAAC;AAAA,YACnC,UAAUF,KAAYE,MAAgB;AAAA,YACtC,cAAW;AAAA,YAEX,UAAA,gBAAAkB,EAAC,OAAA,EAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SAAQ,eAAY,QACzJ,UAAA,gBAAAA,EAAC,YAAA,EAAS,QAAO,kBAAA,CAAkB,EAAA,CACrC;AAAA,UAAA;AAAA,QAAA,GAEJ;AAAA,QAGCf,EAAM,IAAI,CAACD,MAAM;AAChB,cAAIA,MAAM,mBAAmBA,MAAM;AACjC,mBACE,gBAAAgB,EAAC,QAAW,WAAU,2BAA0B,eAAY,QAC1D,UAAA,gBAAAE,EAAC,OAAA,EAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACrI,UAAA;AAAA,cAAA,gBAAAF,EAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,KAAI;AAAA,gCAC7B,UAAA,EAAO,IAAG,MAAK,IAAG,MAAK,GAAE,KAAI;AAAA,gCAC7B,UAAA,EAAO,IAAG,KAAI,IAAG,MAAK,GAAE,IAAA,CAAI;AAAA,YAAA,EAAA,CAC/B,KALOhB,CAMT;AAIJ,gBAAMmB,IAAYnB,MAAMF;AAExB,mCACG,MAAA,EACC,UAAA,gBAAAkB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAWC;AAAA,gBACT;AAAA,gBACAE,KAAa;AAAA,cAAA;AAAA,cAEf,gBAAcA,IAAY,SAAS;AAAA,cACnC,cAAYA,IAAY,QAAQnB,CAAC,KAAK,cAAcA,CAAC;AAAA,cACrD,UAAAJ;AAAA,cACA,SAAS,MAAMG,EAAKC,CAAC;AAAA,cAEpB,UAAAA;AAAA,YAAA;AAAA,UAAA,EACH,GAZO,QAAQA,CAAC,EAalB;AAAA,QAEJ,CAAC;AAAA,0BAGA,MAAA,EACC,UAAA,gBAAAgB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,SAAS,MAAMjB,EAAKD,IAAc,CAAC;AAAA,YACnC,UAAUF,KAAYE,MAAgBN;AAAA,YACtC,cAAW;AAAA,YAEX,UAAA,gBAAAwB,EAAC,OAAA,EAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SAAQ,eAAY,QACzJ,UAAA,gBAAAA,EAAC,YAAA,EAAS,QAAO,iBAAA,CAAiB,EAAA,CACpC;AAAA,UAAA;AAAA,QAAA,EACF,CACF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAGN;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),o=require("react");;/* empty css */const m=require("../../utils/restorefocus/restoreFocus.cjs"),k=require("../../utils/trapfocus/trapFocus.cjs"),w=require("../../utils/onclickoutside/onClickOutside.cjs"),x=require("../../utils/portal/portal.cjs"),b=o.createContext(null);function g(){const s=o.useContext(b);if(!s)throw new Error("Popover components must be inside <Popover>");return s}function y({children:s}){const[c,r]=o.useState(!1),n=o.useRef(null),t=o.useRef(null),i=`popover-${o.useId()}`;return o.useEffect(()=>{c||m.restoreFocus(n.current)},[c]),a.jsx(b.Provider,{value:{open:c,setOpen:r,triggerRef:n,contentRef:t,contentId:i},children:a.jsx("div",{className:"ui-popover-root",children:s})})}function E({children:s,className:c=""}){const{open:r,setOpen:n,triggerRef:t,contentId:i}=g();return a.jsx("button",{ref:t,type:"button",className:`ui-popover-trigger ${c}`,"aria-haspopup":"dialog","aria-expanded":r,"aria-controls":r?i:void 0,onClick:u=>{u.stopPropagation(),n(l=>!l)},onKeyDown:u=>{u.key==="Escape"&&r&&(u.stopPropagation(),n(!1))},children:s})}function R({children:s,className:c="",placement:r="bottom",offset:n=8}){const{open:t,setOpen:i,triggerRef:u,contentRef:l,contentId:h}=g(),[P,C]=o.useState(null);return o.useEffect(()=>{if(t&&l.current)return k.trapFocus(l.current)},[t,l]),o.useEffect(()=>t?w.onClickOutside(l,()=>i(!1)):void 0,[t,i,l,u]),o.useEffect(()=>{if(!t)return;const e=p=>{p.key==="Escape"&&(p.stopPropagation(),i(!1))};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[t,i]),o.useLayoutEffect(()=>{if(!t||!u.current)return;const e=u.current.getBoundingClientRect(),p=window.scrollX,v=window.scrollY;let f=0,d=0;switch(r){case"bottom":f=e.bottom+n+v,d=e.left+e.width/2+p;break;case"top":f=e.top-n+v,d=e.left+e.width/2+p;break;case"left":f=e.top+e.height/2+v,d=e.left-n+p;break;case"right":f=e.top+e.height/2+v,d=e.right+n+p;break}C({top:f,left:d})},[t,r,n,u]),t?a.jsx(x.Portal,{children:a.jsx("div",{id:h,ref:l,role:"dialog","aria-modal":"true",className:`ui-popover-content ui-popover-${r} ${c}`,style:{position:"absolute",top:P?.top??0,left:P?.left??0},children:s})}):null}function j({children:s="Close",className:c=""}){const{setOpen:r}=g();return a.jsx("button",{type:"button",onClick:()=>r(!1),className:`ui-popover-close ${c}`,children:s})}exports.Popover=y;exports.PopoverClose=j;exports.PopoverContent=R;exports.PopoverTrigger=E;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const k=require("react/jsx-runtime"),t=require("react");;/* empty css */const D=require("../../utils/restorefocus/restoreFocus.cjs"),$=require("../../utils/trapfocus/trapFocus.cjs"),z=require("../../utils/onclickoutside/onClickOutside.cjs"),B=require("../../utils/portal/portal.cjs"),K=require("../../utils/cn/cn.cjs"),S=t.createContext(null);function L(){const a=t.useContext(S);if(!a)throw new Error("Popover components must be inside <Popover>");return a}function q({children:a,defaultOpen:p=!1}){const[o,i]=t.useState(p),d=t.useRef(null),r=t.useRef(null),c=`popover-${t.useId()}`;return t.useEffect(()=>{!o&&d.current&&D.restoreFocus(d.current)},[o]),k.jsx(S.Provider,{value:{open:o,setOpen:i,triggerRef:d,contentRef:r,contentId:c},children:a})}q.displayName="Popover";function O({children:a}){const{open:p,setOpen:o,triggerRef:i,contentId:d}=L(),r=t.Children.only(a),c=r.props.ref??r.ref,f={ref:e=>{i.current=e,typeof c=="function"?c(e):c&&typeof c=="object"&&"current"in c&&(c.current=e)},"aria-haspopup":"dialog","aria-expanded":p,"aria-controls":p?d:void 0,onClick:e=>{e.preventDefault(),o(y=>!y),r.props.onClick?.(e)},onKeyDown:e=>{e.key==="Escape"&&p&&(e.stopPropagation(),o(!1)),r.props.onKeyDown?.(e)}};return t.cloneElement(r,f)}O.displayName="Popover.Trigger";function j({children:a,className:p,placement:o="bottom",offset:i=8,...d}){const{open:r,setOpen:c,triggerRef:f,contentRef:e,contentId:y}=L(),[P,X]=t.useState({top:-9999,left:-9999,arrowX:50,arrowY:50}),[F,I]=t.useState(o);t.useEffect(()=>{if(r&&e.current)return $.trapFocus(e.current)},[r,e]),t.useEffect(()=>r?z.onClickOutside([e,f],()=>{c(!1)}):void 0,[r,c,e,f]),t.useEffect(()=>{if(!r)return;const n=s=>{s.key==="Escape"&&(s.stopPropagation(),c(!1))};return document.addEventListener("keydown",n),()=>document.removeEventListener("keydown",n)},[r,c]);const h=t.useCallback(()=>{if(!f.current||!e.current)return;const n=f.current.getBoundingClientRect(),s=e.current.getBoundingClientRect(),g=window.scrollX,v=window.scrollY;let l=0,u=0,Y=50,N=50,w=o;const C=12,E=C,R=document.documentElement.clientWidth-s.width-C,x=C,b=document.documentElement.clientHeight-s.height-C;if(o==="top"||o==="bottom"){const m=n.left+g+n.width/2;u=m-s.width/2,u<E&&(u=E),u>R&&(u=R),Y=m-u,o==="bottom"?(l=n.bottom+v+i,l+s.height>b+v&&(l=n.top+v-s.height-i,w="top")):(l=n.top+v-s.height-i,l<x+v&&(l=n.bottom+v+i,w="bottom"))}else{const m=n.top+v+n.height/2;l=m-s.height/2,l<x&&(l=x),l>b&&(l=b),N=m-l,o==="right"?(u=n.right+g+i,u+s.width>R+g&&(u=n.left+g-s.width-i,w="left")):(u=n.left+g-s.width-i,u<E+g&&(u=n.right+g+i,w="right"))}I(w),X({top:l,left:u,arrowX:Y,arrowY:N})},[o,i,f,e]);return t.useLayoutEffect(()=>{if(r)return h(),window.addEventListener("resize",h),window.addEventListener("scroll",h,!0),()=>{window.removeEventListener("resize",h),window.removeEventListener("scroll",h,!0)}},[r,h]),r?k.jsx(B.Portal,{children:k.jsx("div",{id:y,ref:e,role:"dialog","aria-modal":"true","data-placement":F,className:K.cn("nui-popover-content",p),style:{position:"absolute",top:P.top,left:P.left,"--nui-popover-arrow-x":`${P.arrowX}px`,"--nui-popover-arrow-y":`${P.arrowY}px`},...d,children:a})}):null}j.displayName="Popover.Content";function T({children:a}){const{setOpen:p}=L(),o=t.Children.only(a);return t.cloneElement(o,{onClick:i=>{p(!1),o.props.onClick?.(i)}})}T.displayName="Popover.Close";const A=Object.assign(q,{Trigger:O,Content:j,Close:T});exports.Popover=A;exports.PopoverClose=T;exports.PopoverContent=j;exports.PopoverRoot=q;exports.PopoverTrigger=O;
2
2
  //# sourceMappingURL=Popover.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.cjs","sources":["../../../src/components/popover/Popover.tsx"],"sourcesContent":["import React, {\r\n createContext,\r\n useContext,\r\n useRef,\r\n useEffect,\r\n useState,\r\n useLayoutEffect,\r\n useId,\r\n} from 'react';\r\n\r\nimport './Popover.css';\r\n\r\n// Import your existing utilities\r\n// Ensure these paths match your folder structure exactly!\r\nimport { Portal, onClickOutside, restoreFocus, trapFocus } from '../../utils/index'; \r\n\r\ntype Placement = 'top' | 'bottom' | 'left' | 'right';\r\n\r\nconst PopoverContext = createContext<{\r\n open: boolean;\r\n setOpen: React.Dispatch<React.SetStateAction<boolean>>;\r\n triggerRef: React.RefObject<HTMLElement | null>;\r\n contentRef: React.RefObject<HTMLDivElement | null>;\r\n contentId: string;\r\n} | null>(null);\r\n\r\nfunction usePopover() {\r\n const ctx = useContext(PopoverContext);\r\n if (!ctx) throw new Error('Popover components must be inside <Popover>');\r\n return ctx;\r\n}\r\n\r\n/* -------------------------------------------------------\r\n * Root\r\n * ------------------------------------------------------*/\r\nexport function Popover({ children }: { children: React.ReactNode }) {\r\n const [open, setOpen] = useState(false);\r\n const triggerRef = useRef<HTMLElement | null>(null);\r\n const contentRef = useRef<HTMLDivElement | null>(null);\r\n const contentId = `popover-${useId()}`;\r\n\r\n // Restore focus to trigger on close\r\n useEffect(() => {\r\n if (!open) {\r\n restoreFocus(triggerRef.current);\r\n }\r\n }, [open]);\r\n\r\n return (\r\n <PopoverContext.Provider\r\n value={{ open, setOpen, triggerRef, contentRef, contentId }}\r\n >\r\n {/* Wrapper ensures trigger stays in document flow */}\r\n <div className=\"ui-popover-root\">{children}</div>\r\n </PopoverContext.Provider>\r\n );\r\n}\r\n\r\n/* -------------------------------------------------------\r\n * Trigger\r\n * ------------------------------------------------------*/\r\nexport function PopoverTrigger({\r\n children,\r\n className = '',\r\n}: {\r\n children: React.ReactNode;\r\n className?: string;\r\n}) {\r\n const { open, setOpen, triggerRef, contentId } = usePopover();\r\n\r\n return (\r\n <button\r\n ref={triggerRef as React.RefObject<HTMLButtonElement>}\r\n type=\"button\"\r\n className={`ui-popover-trigger ${className}`}\r\n aria-haspopup=\"dialog\"\r\n aria-expanded={open}\r\n aria-controls={open ? contentId : undefined}\r\n onClick={(e) => {\r\n // Stop propagation to prevent immediate close by external listeners\r\n e.stopPropagation();\r\n setOpen((s) => !s);\r\n }}\r\n onKeyDown={(e) => {\r\n if (e.key === 'Escape' && open) {\r\n e.stopPropagation();\r\n setOpen(false);\r\n }\r\n }}\r\n >\r\n {children}\r\n </button>\r\n );\r\n}\r\n\r\n/* -------------------------------------------------------\r\n * Content (Portaled & Positioned)\r\n * ------------------------------------------------------*/\r\nexport function PopoverContent({\r\n children,\r\n className = '',\r\n placement = 'bottom',\r\n offset = 8,\r\n}: {\r\n children: React.ReactNode;\r\n className?: string;\r\n placement?: Placement;\r\n offset?: number;\r\n}) {\r\n const { open, setOpen, triggerRef, contentRef, contentId } = usePopover();\r\n const [coords, setCoords] = useState<{ top: number; left: number } | null>(null);\r\n\r\n // 1. Trap Focus when open (FIXED RETURN TYPE)\r\n useEffect(() => {\r\n if (open && contentRef.current) {\r\n // Return the cleanup function from trapFocus\r\n return trapFocus(contentRef.current);\r\n }\r\n // Explicitly return undefined so TS knows we handled the \"else\" case\r\n return undefined;\r\n }, [open, contentRef]);\r\n\r\n // 2. Click Outside Logic\r\n useEffect(() => {\r\n if (!open) return;\r\n\r\n const cleanup = onClickOutside(contentRef, () => setOpen(false));\r\n return cleanup;\r\n }, [open, setOpen, contentRef, triggerRef]);\r\n\r\n // 3. Global Escape Key\r\n useEffect(() => {\r\n if (!open) return;\r\n const handler = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') {\r\n e.stopPropagation();\r\n setOpen(false);\r\n }\r\n };\r\n document.addEventListener('keydown', handler);\r\n return () => document.removeEventListener('keydown', handler);\r\n }, [open, setOpen]);\r\n\r\n // 4. Calculate Position\r\n useLayoutEffect(() => {\r\n if (!open || !triggerRef.current) return;\r\n\r\n const rect = triggerRef.current.getBoundingClientRect();\r\n const scrollX = window.scrollX;\r\n const scrollY = window.scrollY;\r\n\r\n let top = 0;\r\n let left = 0;\r\n\r\n switch (placement) {\r\n case 'bottom':\r\n top = rect.bottom + offset + scrollY;\r\n left = rect.left + (rect.width / 2) + scrollX;\r\n break;\r\n case 'top':\r\n top = rect.top - offset + scrollY;\r\n left = rect.left + (rect.width / 2) + scrollX;\r\n break;\r\n case 'left':\r\n top = rect.top + (rect.height / 2) + scrollY;\r\n left = rect.left - offset + scrollX;\r\n break;\r\n case 'right':\r\n top = rect.top + (rect.height / 2) + scrollY;\r\n left = rect.right + offset + scrollX;\r\n break;\r\n }\r\n\r\n setCoords({ top, left });\r\n }, [open, placement, offset, triggerRef]);\r\n\r\n if (!open) return null;\r\n\r\n return (\r\n <Portal>\r\n <div\r\n id={contentId}\r\n ref={contentRef}\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n className={`ui-popover-content ui-popover-${placement} ${className}`}\r\n style={{\r\n position: 'absolute',\r\n top: coords?.top ?? 0,\r\n left: coords?.left ?? 0,\r\n }}\r\n >\r\n {children}\r\n </div>\r\n </Portal>\r\n );\r\n}\r\n\r\n/* -------------------------------------------------------\r\n * Close Button\r\n * ------------------------------------------------------*/\r\nexport function PopoverClose({\r\n children = 'Close',\r\n className = '',\r\n}: {\r\n children?: React.ReactNode;\r\n className?: string;\r\n}) {\r\n const { setOpen } = usePopover();\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={() => setOpen(false)}\r\n className={`ui-popover-close ${className}`}\r\n >\r\n {children}\r\n </button>\r\n );\r\n}"],"names":["PopoverContext","createContext","usePopover","ctx","useContext","Popover","children","open","setOpen","useState","triggerRef","useRef","contentRef","contentId","useId","useEffect","restoreFocus","jsx","PopoverTrigger","className","e","s","PopoverContent","placement","offset","coords","setCoords","trapFocus","onClickOutside","handler","useLayoutEffect","rect","scrollX","scrollY","top","left","Portal","PopoverClose"],"mappings":"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"}
1
+ {"version":3,"file":"Popover.cjs","sources":["../../../src/components/popover/Popover.tsx"],"sourcesContent":["\"use client\";\n\nimport React, {\n createContext,\n useContext,\n useRef,\n useEffect,\n useState,\n useLayoutEffect,\n useId,\n useCallback,\n} from 'react';\nimport { cn } from '../../utils';\nimport { Portal, restoreFocus, trapFocus, onClickOutside } from '../../utils';\nimport './Popover.css';\n\nexport type PopoverPlacement = 'top' | 'bottom' | 'left' | 'right';\n\n/* -------------------------------------------------------\n * Context\n * ------------------------------------------------------*/\ninterface PopoverContextValue {\n open: boolean;\n setOpen: React.Dispatch<React.SetStateAction<boolean>>;\n triggerRef: React.RefObject<HTMLElement | null>;\n contentRef: React.RefObject<HTMLDivElement | null>;\n contentId: string;\n}\n\nconst PopoverContext = createContext<PopoverContextValue | null>(null);\n\nfunction usePopover() {\n const ctx = useContext(PopoverContext);\n if (!ctx) throw new Error('Popover components must be inside <Popover>');\n return ctx;\n}\n\n/* -------------------------------------------------------\n * 1. Root\n * ------------------------------------------------------*/\n\nexport interface PopoverRootProps {\n children: React.ReactNode; \n defaultOpen?: boolean;\n}\n\n/**\n * Popover Component (Root)\n * * A non-modal dialog that floats around a trigger element.\n * * Uses Compound Component Architecture.\n */\nexport function PopoverRoot({ children, defaultOpen = false }: PopoverRootProps) {\n const [open, setOpen] = useState(defaultOpen);\n const triggerRef = useRef<HTMLElement | null>(null);\n const contentRef = useRef<HTMLDivElement | null>(null);\n const contentId = `popover-${useId()}`;\n\n // WAI-ARIA Standard: Restore focus to trigger on close\n useEffect(() => {\n if (!open && triggerRef.current) {\n restoreFocus(triggerRef.current);\n }\n }, [open]);\n\n return (\n <PopoverContext.Provider value={{ open, setOpen, triggerRef, contentRef, contentId }}>\n {children}\n </PopoverContext.Provider>\n );\n}\nPopoverRoot.displayName = 'Popover';\n\n/* -------------------------------------------------------\n * 2. Trigger\n * ------------------------------------------------------*/\n\nexport interface PopoverTriggerProps {\n children: React.ReactElement;\n}\n\n/**\n * Popover Trigger\n * * Automatically clones the child element and injects necessary event listeners and ARIA attributes.\n */\nexport function PopoverTrigger({ children }: PopoverTriggerProps) {\n const { open, setOpen, triggerRef, contentId } = usePopover();\n\n // Safely extract the child and ref\n const child = React.Children.only(children) as React.ReactElement<React.HTMLProps<HTMLElement>>;\n const childRef = child.props.ref ?? (child as unknown as { ref?: React.Ref<HTMLElement> }).ref;\n\n const triggerProps: React.HTMLProps<HTMLElement> = {\n ref: (node: HTMLElement | null) => {\n triggerRef.current = node;\n if (typeof childRef === 'function') {\n childRef(node);\n } else if (childRef && typeof childRef === 'object' && 'current' in childRef) {\n (childRef as { current: HTMLElement | null }).current = node;\n }\n },\n 'aria-haspopup': 'dialog',\n 'aria-expanded': open,\n 'aria-controls': open ? contentId : undefined,\n onClick: (e: React.MouseEvent<HTMLElement>) => {\n e.preventDefault();\n setOpen((prev) => !prev);\n child.props.onClick?.(e);\n },\n onKeyDown: (e: React.KeyboardEvent<HTMLElement>) => {\n if (e.key === 'Escape' && open) {\n e.stopPropagation();\n setOpen(false);\n }\n child.props.onKeyDown?.(e);\n },\n };\n\n return React.cloneElement(child, triggerProps);\n}\nPopoverTrigger.displayName = 'Popover.Trigger';\n\n/* -------------------------------------------------------\n * 3. Content\n * ------------------------------------------------------*/\nexport interface PopoverContentProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n /** Preferred placement of the popover relative to the trigger. Defaults to 'bottom' */\n placement?: PopoverPlacement;\n /** Gap in pixels between the trigger and the popover. Defaults to 8px. */\n offset?: number;\n}\n\n/**\n * Popover Content\n * * Renders inside a Portal and implements smart collision detection to stay in the viewport.\n * * Automatically traps focus when open.\n */\nexport function PopoverContent({\n children,\n className,\n placement = 'bottom',\n offset = 8,\n ...props\n}: PopoverContentProps) {\n const { open, setOpen, triggerRef, contentRef, contentId } = usePopover();\n const [coords, setCoords] = useState({ top: -9999, left: -9999, arrowX: 50, arrowY: 50 });\n const [actualPlacement, setActualPlacement] = useState<PopoverPlacement>(placement);\n\n // Focus Trapping\n useEffect(() => {\n if (open && contentRef.current) {\n return trapFocus(contentRef.current);\n }\n return undefined;\n }, [open, contentRef]);\n\n // Click Outside Handler\n useEffect(() => {\n if (!open) return;\n const cleanup = onClickOutside([contentRef, triggerRef], () => {\n setOpen(false);\n });\n return cleanup;\n }, [open, setOpen, contentRef, triggerRef]);\n\n // Escape Key Handler\n useEffect(() => {\n if (!open) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.stopPropagation();\n setOpen(false);\n }\n };\n document.addEventListener('keydown', handler);\n return () => document.removeEventListener('keydown', handler);\n }, [open, setOpen]);\n\n // Positioning Math (Includes Boundary Collision)\n const updatePosition = useCallback(() => {\n if (!triggerRef.current || !contentRef.current) return;\n\n const triggerRect = triggerRef.current.getBoundingClientRect();\n const contentRect = contentRef.current.getBoundingClientRect();\n\n const scrollX = window.scrollX;\n const scrollY = window.scrollY;\n\n let top = 0;\n let left = 0;\n let arrowX = 50;\n let arrowY = 50;\n let nextPlacement = placement;\n\n // Viewport boundaries with safety padding\n const padding = 12;\n const minLeft = padding;\n const maxLeft = document.documentElement.clientWidth - contentRect.width - padding;\n const minTop = padding;\n const maxTop = document.documentElement.clientHeight - contentRect.height - padding;\n\n if (placement === 'top' || placement === 'bottom') {\n const actualCenter = triggerRect.left + scrollX + triggerRect.width / 2;\n left = actualCenter - contentRect.width / 2;\n\n // Clamp X\n if (left < minLeft) left = minLeft;\n if (left > maxLeft) left = maxLeft;\n\n // Calculate Arrow X\n arrowX = actualCenter - left;\n\n if (placement === 'bottom') {\n top = triggerRect.bottom + scrollY + offset;\n // Collision Detection: Flip if clipping bottom\n if (top + contentRect.height > maxTop + scrollY) {\n top = triggerRect.top + scrollY - contentRect.height - offset;\n nextPlacement = 'top';\n }\n } else {\n top = triggerRect.top + scrollY - contentRect.height - offset;\n // Collision Detection: Flip if clipping top\n if (top < minTop + scrollY) {\n top = triggerRect.bottom + scrollY + offset;\n nextPlacement = 'bottom';\n }\n }\n } else {\n const actualCenterY = triggerRect.top + scrollY + triggerRect.height / 2;\n top = actualCenterY - contentRect.height / 2;\n\n // Clamp Y\n if (top < minTop) top = minTop;\n if (top > maxTop) top = maxTop;\n\n // Calculate Arrow Y\n arrowY = actualCenterY - top;\n\n if (placement === 'right') {\n left = triggerRect.right + scrollX + offset;\n // Collision Detection: Flip to left if clipping right\n if (left + contentRect.width > maxLeft + scrollX) {\n left = triggerRect.left + scrollX - contentRect.width - offset;\n nextPlacement = 'left';\n }\n } else {\n left = triggerRect.left + scrollX - contentRect.width - offset;\n // Collision Detection: Flip to right if clipping left\n if (left < minLeft + scrollX) {\n left = triggerRect.right + scrollX + offset;\n nextPlacement = 'right';\n }\n }\n }\n\n setActualPlacement(nextPlacement);\n setCoords({ top, left, arrowX, arrowY });\n }, [placement, offset, triggerRef, contentRef]);\n\n useLayoutEffect(() => {\n if (!open) return;\n updatePosition();\n window.addEventListener('resize', updatePosition);\n window.addEventListener('scroll', updatePosition, true);\n return () => {\n window.removeEventListener('resize', updatePosition);\n window.removeEventListener('scroll', updatePosition, true);\n };\n }, [open, updatePosition]);\n\n if (!open) return null;\n\n return (\n <Portal>\n <div\n id={contentId}\n ref={contentRef}\n role=\"dialog\"\n aria-modal=\"true\"\n data-placement={actualPlacement}\n className={cn('nui-popover-content', className)}\n style={{\n position: 'absolute',\n top: coords.top,\n left: coords.left,\n '--nui-popover-arrow-x': `${coords.arrowX}px`,\n '--nui-popover-arrow-y': `${coords.arrowY}px`,\n } as React.CSSProperties}\n {...props}\n >\n {children}\n </div>\n </Portal>\n );\n}\nPopoverContent.displayName = 'Popover.Content';\n\n/* -------------------------------------------------------\n * 4. Close Button\n * ------------------------------------------------------*/\n\nexport interface PopoverCloseProps {\n children: React.ReactElement;\n}\n\n/**\n * Popover Close\n * * Optional headless wrapper that injects a close action into a child button.\n */\nexport function PopoverClose({ children }: PopoverCloseProps) {\n const { setOpen } = usePopover();\n \n const child = React.Children.only(children) as React.ReactElement<React.HTMLProps<HTMLElement>>;\n \n return React.cloneElement(child, {\n onClick: (e: React.MouseEvent<HTMLElement>) => {\n setOpen(false);\n child.props.onClick?.(e);\n },\n });\n}\nPopoverClose.displayName = 'Popover.Close';\n\n/* -------------------------------------------------------\n * Export\n * ------------------------------------------------------*/\nexport const Popover = Object.assign(PopoverRoot, {\n Trigger: PopoverTrigger,\n Content: PopoverContent,\n Close: PopoverClose,\n});"],"names":["PopoverContext","createContext","usePopover","ctx","useContext","PopoverRoot","children","defaultOpen","open","setOpen","useState","triggerRef","useRef","contentRef","contentId","useId","useEffect","restoreFocus","jsx","PopoverTrigger","child","React","childRef","triggerProps","node","prev","PopoverContent","className","placement","offset","props","coords","setCoords","actualPlacement","setActualPlacement","trapFocus","onClickOutside","handler","e","updatePosition","useCallback","triggerRect","contentRect","scrollX","scrollY","top","left","arrowX","arrowY","nextPlacement","padding","minLeft","maxLeft","minTop","maxTop","actualCenter","actualCenterY","useLayoutEffect","Portal","cn","PopoverClose","Popover"],"mappings":"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"}
@@ -1,123 +1,122 @@
1
- import { jsx as l } from "react/jsx-runtime";
2
- import { useState as b, useRef as h, useId as C, useEffect as m, createContext as y, useLayoutEffect as x, useContext as E } from "react";
1
+ import { jsx as L } from "react/jsx-runtime";
2
+ import y, { useState as O, useRef as X, useId as A, useEffect as P, createContext as H, useCallback as S, useLayoutEffect as W, useContext as q } from "react";
3
3
  /* empty css */
4
- import { restoreFocus as R } from "../../utils/restorefocus/restoreFocus.js";
5
- import { trapFocus as O } from "../../utils/trapfocus/trapFocus.js";
6
- import { onClickOutside as $ } from "../../utils/onclickoutside/onClickOutside.js";
7
- import { Portal as I } from "../../utils/portal/portal.js";
8
- const P = y(null);
9
- function v() {
10
- const n = E(P);
11
- if (!n) throw new Error("Popover components must be inside <Popover>");
12
- return n;
4
+ import { restoreFocus as G } from "../../utils/restorefocus/restoreFocus.js";
5
+ import { trapFocus as J } from "../../utils/trapfocus/trapFocus.js";
6
+ import { onClickOutside as M } from "../../utils/onclickoutside/onClickOutside.js";
7
+ import { Portal as Q } from "../../utils/portal/portal.js";
8
+ import { cn as U } from "../../utils/cn/cn.js";
9
+ const I = H(null);
10
+ function Y() {
11
+ const p = q(I);
12
+ if (!p) throw new Error("Popover components must be inside <Popover>");
13
+ return p;
13
14
  }
14
- function D({ children: n }) {
15
- const [s, t] = b(!1), r = h(null), e = h(null), c = `popover-${C()}`;
16
- return m(() => {
17
- s || R(r.current);
18
- }, [s]), /* @__PURE__ */ l(
19
- P.Provider,
20
- {
21
- value: { open: s, setOpen: t, triggerRef: r, contentRef: e, contentId: c },
22
- children: /* @__PURE__ */ l("div", { className: "ui-popover-root", children: n })
23
- }
24
- );
15
+ function j({ children: p, defaultOpen: u = !1 }) {
16
+ const [e, r] = O(u), a = X(null), o = X(null), i = `popover-${A()}`;
17
+ return P(() => {
18
+ !e && a.current && G(a.current);
19
+ }, [e]), /* @__PURE__ */ L(I.Provider, { value: { open: e, setOpen: r, triggerRef: a, contentRef: o, contentId: i }, children: p });
25
20
  }
26
- function K({
27
- children: n,
28
- className: s = ""
29
- }) {
30
- const { open: t, setOpen: r, triggerRef: e, contentId: c } = v();
31
- return /* @__PURE__ */ l(
32
- "button",
33
- {
34
- ref: e,
35
- type: "button",
36
- className: `ui-popover-trigger ${s}`,
37
- "aria-haspopup": "dialog",
38
- "aria-expanded": t,
39
- "aria-controls": t ? c : void 0,
40
- onClick: (i) => {
41
- i.stopPropagation(), r((p) => !p);
42
- },
43
- onKeyDown: (i) => {
44
- i.key === "Escape" && t && (i.stopPropagation(), r(!1));
45
- },
46
- children: n
21
+ j.displayName = "Popover";
22
+ function D({ children: p }) {
23
+ const { open: u, setOpen: e, triggerRef: r, contentId: a } = Y(), o = y.Children.only(p), i = o.props.ref ?? o.ref, d = {
24
+ ref: (t) => {
25
+ r.current = t, typeof i == "function" ? i(t) : i && typeof i == "object" && "current" in i && (i.current = t);
26
+ },
27
+ "aria-haspopup": "dialog",
28
+ "aria-expanded": u,
29
+ "aria-controls": u ? a : void 0,
30
+ onClick: (t) => {
31
+ t.preventDefault(), e((E) => !E), o.props.onClick?.(t);
32
+ },
33
+ onKeyDown: (t) => {
34
+ t.key === "Escape" && u && (t.stopPropagation(), e(!1)), o.props.onKeyDown?.(t);
47
35
  }
48
- );
36
+ };
37
+ return y.cloneElement(o, d);
49
38
  }
50
- function S({
51
- children: n,
52
- className: s = "",
53
- placement: t = "bottom",
54
- offset: r = 8
39
+ D.displayName = "Popover.Trigger";
40
+ function $({
41
+ children: p,
42
+ className: u,
43
+ placement: e = "bottom",
44
+ offset: r = 8,
45
+ ...a
55
46
  }) {
56
- const { open: e, setOpen: c, triggerRef: i, contentRef: p, contentId: w } = v(), [g, k] = b(null);
57
- return m(() => {
58
- if (e && p.current)
59
- return O(p.current);
60
- }, [e, p]), m(() => e ? $(p, () => c(!1)) : void 0, [e, c, p, i]), m(() => {
61
- if (!e) return;
62
- const o = (u) => {
63
- u.key === "Escape" && (u.stopPropagation(), c(!1));
47
+ const { open: o, setOpen: i, triggerRef: d, contentRef: t, contentId: E } = Y(), [w, B] = O({ top: -9999, left: -9999, arrowX: 50, arrowY: 50 }), [F, K] = O(e);
48
+ P(() => {
49
+ if (o && t.current)
50
+ return J(t.current);
51
+ }, [o, t]), P(() => o ? M([t, d], () => {
52
+ i(!1);
53
+ }) : void 0, [o, i, t, d]), P(() => {
54
+ if (!o) return;
55
+ const n = (c) => {
56
+ c.key === "Escape" && (c.stopPropagation(), i(!1));
64
57
  };
65
- return document.addEventListener("keydown", o), () => document.removeEventListener("keydown", o);
66
- }, [e, c]), x(() => {
67
- if (!e || !i.current) return;
68
- const o = i.current.getBoundingClientRect(), u = window.scrollX, d = window.scrollY;
69
- let a = 0, f = 0;
70
- switch (t) {
71
- case "bottom":
72
- a = o.bottom + r + d, f = o.left + o.width / 2 + u;
73
- break;
74
- case "top":
75
- a = o.top - r + d, f = o.left + o.width / 2 + u;
76
- break;
77
- case "left":
78
- a = o.top + o.height / 2 + d, f = o.left - r + u;
79
- break;
80
- case "right":
81
- a = o.top + o.height / 2 + d, f = o.right + r + u;
82
- break;
58
+ return document.addEventListener("keydown", n), () => document.removeEventListener("keydown", n);
59
+ }, [o, i]);
60
+ const g = S(() => {
61
+ if (!d.current || !t.current) return;
62
+ const n = d.current.getBoundingClientRect(), c = t.current.getBoundingClientRect(), f = window.scrollX, m = window.scrollY;
63
+ let s = 0, l = 0, N = 50, T = 50, h = e;
64
+ const C = 12, x = C, R = document.documentElement.clientWidth - c.width - C, b = C, k = document.documentElement.clientHeight - c.height - C;
65
+ if (e === "top" || e === "bottom") {
66
+ const v = n.left + f + n.width / 2;
67
+ l = v - c.width / 2, l < x && (l = x), l > R && (l = R), N = v - l, e === "bottom" ? (s = n.bottom + m + r, s + c.height > k + m && (s = n.top + m - c.height - r, h = "top")) : (s = n.top + m - c.height - r, s < b + m && (s = n.bottom + m + r, h = "bottom"));
68
+ } else {
69
+ const v = n.top + m + n.height / 2;
70
+ s = v - c.height / 2, s < b && (s = b), s > k && (s = k), T = v - s, e === "right" ? (l = n.right + f + r, l + c.width > R + f && (l = n.left + f - c.width - r, h = "left")) : (l = n.left + f - c.width - r, l < x + f && (l = n.right + f + r, h = "right"));
83
71
  }
84
- k({ top: a, left: f });
85
- }, [e, t, r, i]), e ? /* @__PURE__ */ l(I, { children: /* @__PURE__ */ l(
72
+ K(h), B({ top: s, left: l, arrowX: N, arrowY: T });
73
+ }, [e, r, d, t]);
74
+ return W(() => {
75
+ if (o)
76
+ return g(), window.addEventListener("resize", g), window.addEventListener("scroll", g, !0), () => {
77
+ window.removeEventListener("resize", g), window.removeEventListener("scroll", g, !0);
78
+ };
79
+ }, [o, g]), o ? /* @__PURE__ */ L(Q, { children: /* @__PURE__ */ L(
86
80
  "div",
87
81
  {
88
- id: w,
89
- ref: p,
82
+ id: E,
83
+ ref: t,
90
84
  role: "dialog",
91
85
  "aria-modal": "true",
92
- className: `ui-popover-content ui-popover-${t} ${s}`,
86
+ "data-placement": F,
87
+ className: U("nui-popover-content", u),
93
88
  style: {
94
89
  position: "absolute",
95
- top: g?.top ?? 0,
96
- left: g?.left ?? 0
90
+ top: w.top,
91
+ left: w.left,
92
+ "--nui-popover-arrow-x": `${w.arrowX}px`,
93
+ "--nui-popover-arrow-y": `${w.arrowY}px`
97
94
  },
98
- children: n
95
+ ...a,
96
+ children: p
99
97
  }
100
98
  ) }) : null;
101
99
  }
102
- function T({
103
- children: n = "Close",
104
- className: s = ""
105
- }) {
106
- const { setOpen: t } = v();
107
- return /* @__PURE__ */ l(
108
- "button",
109
- {
110
- type: "button",
111
- onClick: () => t(!1),
112
- className: `ui-popover-close ${s}`,
113
- children: n
100
+ $.displayName = "Popover.Content";
101
+ function z({ children: p }) {
102
+ const { setOpen: u } = Y(), e = y.Children.only(p);
103
+ return y.cloneElement(e, {
104
+ onClick: (r) => {
105
+ u(!1), e.props.onClick?.(r);
114
106
  }
115
- );
107
+ });
116
108
  }
109
+ z.displayName = "Popover.Close";
110
+ const it = Object.assign(j, {
111
+ Trigger: D,
112
+ Content: $,
113
+ Close: z
114
+ });
117
115
  export {
118
- D as Popover,
119
- T as PopoverClose,
120
- S as PopoverContent,
121
- K as PopoverTrigger
116
+ it as Popover,
117
+ z as PopoverClose,
118
+ $ as PopoverContent,
119
+ j as PopoverRoot,
120
+ D as PopoverTrigger
122
121
  };
123
122
  //# sourceMappingURL=Popover.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.js","sources":["../../../src/components/popover/Popover.tsx"],"sourcesContent":["import React, {\r\n createContext,\r\n useContext,\r\n useRef,\r\n useEffect,\r\n useState,\r\n useLayoutEffect,\r\n useId,\r\n} from 'react';\r\n\r\nimport './Popover.css';\r\n\r\n// Import your existing utilities\r\n// Ensure these paths match your folder structure exactly!\r\nimport { Portal, onClickOutside, restoreFocus, trapFocus } from '../../utils/index'; \r\n\r\ntype Placement = 'top' | 'bottom' | 'left' | 'right';\r\n\r\nconst PopoverContext = createContext<{\r\n open: boolean;\r\n setOpen: React.Dispatch<React.SetStateAction<boolean>>;\r\n triggerRef: React.RefObject<HTMLElement | null>;\r\n contentRef: React.RefObject<HTMLDivElement | null>;\r\n contentId: string;\r\n} | null>(null);\r\n\r\nfunction usePopover() {\r\n const ctx = useContext(PopoverContext);\r\n if (!ctx) throw new Error('Popover components must be inside <Popover>');\r\n return ctx;\r\n}\r\n\r\n/* -------------------------------------------------------\r\n * Root\r\n * ------------------------------------------------------*/\r\nexport function Popover({ children }: { children: React.ReactNode }) {\r\n const [open, setOpen] = useState(false);\r\n const triggerRef = useRef<HTMLElement | null>(null);\r\n const contentRef = useRef<HTMLDivElement | null>(null);\r\n const contentId = `popover-${useId()}`;\r\n\r\n // Restore focus to trigger on close\r\n useEffect(() => {\r\n if (!open) {\r\n restoreFocus(triggerRef.current);\r\n }\r\n }, [open]);\r\n\r\n return (\r\n <PopoverContext.Provider\r\n value={{ open, setOpen, triggerRef, contentRef, contentId }}\r\n >\r\n {/* Wrapper ensures trigger stays in document flow */}\r\n <div className=\"ui-popover-root\">{children}</div>\r\n </PopoverContext.Provider>\r\n );\r\n}\r\n\r\n/* -------------------------------------------------------\r\n * Trigger\r\n * ------------------------------------------------------*/\r\nexport function PopoverTrigger({\r\n children,\r\n className = '',\r\n}: {\r\n children: React.ReactNode;\r\n className?: string;\r\n}) {\r\n const { open, setOpen, triggerRef, contentId } = usePopover();\r\n\r\n return (\r\n <button\r\n ref={triggerRef as React.RefObject<HTMLButtonElement>}\r\n type=\"button\"\r\n className={`ui-popover-trigger ${className}`}\r\n aria-haspopup=\"dialog\"\r\n aria-expanded={open}\r\n aria-controls={open ? contentId : undefined}\r\n onClick={(e) => {\r\n // Stop propagation to prevent immediate close by external listeners\r\n e.stopPropagation();\r\n setOpen((s) => !s);\r\n }}\r\n onKeyDown={(e) => {\r\n if (e.key === 'Escape' && open) {\r\n e.stopPropagation();\r\n setOpen(false);\r\n }\r\n }}\r\n >\r\n {children}\r\n </button>\r\n );\r\n}\r\n\r\n/* -------------------------------------------------------\r\n * Content (Portaled & Positioned)\r\n * ------------------------------------------------------*/\r\nexport function PopoverContent({\r\n children,\r\n className = '',\r\n placement = 'bottom',\r\n offset = 8,\r\n}: {\r\n children: React.ReactNode;\r\n className?: string;\r\n placement?: Placement;\r\n offset?: number;\r\n}) {\r\n const { open, setOpen, triggerRef, contentRef, contentId } = usePopover();\r\n const [coords, setCoords] = useState<{ top: number; left: number } | null>(null);\r\n\r\n // 1. Trap Focus when open (FIXED RETURN TYPE)\r\n useEffect(() => {\r\n if (open && contentRef.current) {\r\n // Return the cleanup function from trapFocus\r\n return trapFocus(contentRef.current);\r\n }\r\n // Explicitly return undefined so TS knows we handled the \"else\" case\r\n return undefined;\r\n }, [open, contentRef]);\r\n\r\n // 2. Click Outside Logic\r\n useEffect(() => {\r\n if (!open) return;\r\n\r\n const cleanup = onClickOutside(contentRef, () => setOpen(false));\r\n return cleanup;\r\n }, [open, setOpen, contentRef, triggerRef]);\r\n\r\n // 3. Global Escape Key\r\n useEffect(() => {\r\n if (!open) return;\r\n const handler = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') {\r\n e.stopPropagation();\r\n setOpen(false);\r\n }\r\n };\r\n document.addEventListener('keydown', handler);\r\n return () => document.removeEventListener('keydown', handler);\r\n }, [open, setOpen]);\r\n\r\n // 4. Calculate Position\r\n useLayoutEffect(() => {\r\n if (!open || !triggerRef.current) return;\r\n\r\n const rect = triggerRef.current.getBoundingClientRect();\r\n const scrollX = window.scrollX;\r\n const scrollY = window.scrollY;\r\n\r\n let top = 0;\r\n let left = 0;\r\n\r\n switch (placement) {\r\n case 'bottom':\r\n top = rect.bottom + offset + scrollY;\r\n left = rect.left + (rect.width / 2) + scrollX;\r\n break;\r\n case 'top':\r\n top = rect.top - offset + scrollY;\r\n left = rect.left + (rect.width / 2) + scrollX;\r\n break;\r\n case 'left':\r\n top = rect.top + (rect.height / 2) + scrollY;\r\n left = rect.left - offset + scrollX;\r\n break;\r\n case 'right':\r\n top = rect.top + (rect.height / 2) + scrollY;\r\n left = rect.right + offset + scrollX;\r\n break;\r\n }\r\n\r\n setCoords({ top, left });\r\n }, [open, placement, offset, triggerRef]);\r\n\r\n if (!open) return null;\r\n\r\n return (\r\n <Portal>\r\n <div\r\n id={contentId}\r\n ref={contentRef}\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n className={`ui-popover-content ui-popover-${placement} ${className}`}\r\n style={{\r\n position: 'absolute',\r\n top: coords?.top ?? 0,\r\n left: coords?.left ?? 0,\r\n }}\r\n >\r\n {children}\r\n </div>\r\n </Portal>\r\n );\r\n}\r\n\r\n/* -------------------------------------------------------\r\n * Close Button\r\n * ------------------------------------------------------*/\r\nexport function PopoverClose({\r\n children = 'Close',\r\n className = '',\r\n}: {\r\n children?: React.ReactNode;\r\n className?: string;\r\n}) {\r\n const { setOpen } = usePopover();\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={() => setOpen(false)}\r\n className={`ui-popover-close ${className}`}\r\n >\r\n {children}\r\n </button>\r\n );\r\n}"],"names":["PopoverContext","createContext","usePopover","ctx","useContext","Popover","children","open","setOpen","useState","triggerRef","useRef","contentRef","contentId","useId","useEffect","restoreFocus","jsx","PopoverTrigger","className","e","s","PopoverContent","placement","offset","coords","setCoords","trapFocus","onClickOutside","handler","useLayoutEffect","rect","scrollX","scrollY","top","left","Portal","PopoverClose"],"mappings":"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"}
1
+ {"version":3,"file":"Popover.js","sources":["../../../src/components/popover/Popover.tsx"],"sourcesContent":["\"use client\";\n\nimport React, {\n createContext,\n useContext,\n useRef,\n useEffect,\n useState,\n useLayoutEffect,\n useId,\n useCallback,\n} from 'react';\nimport { cn } from '../../utils';\nimport { Portal, restoreFocus, trapFocus, onClickOutside } from '../../utils';\nimport './Popover.css';\n\nexport type PopoverPlacement = 'top' | 'bottom' | 'left' | 'right';\n\n/* -------------------------------------------------------\n * Context\n * ------------------------------------------------------*/\ninterface PopoverContextValue {\n open: boolean;\n setOpen: React.Dispatch<React.SetStateAction<boolean>>;\n triggerRef: React.RefObject<HTMLElement | null>;\n contentRef: React.RefObject<HTMLDivElement | null>;\n contentId: string;\n}\n\nconst PopoverContext = createContext<PopoverContextValue | null>(null);\n\nfunction usePopover() {\n const ctx = useContext(PopoverContext);\n if (!ctx) throw new Error('Popover components must be inside <Popover>');\n return ctx;\n}\n\n/* -------------------------------------------------------\n * 1. Root\n * ------------------------------------------------------*/\n\nexport interface PopoverRootProps {\n children: React.ReactNode; \n defaultOpen?: boolean;\n}\n\n/**\n * Popover Component (Root)\n * * A non-modal dialog that floats around a trigger element.\n * * Uses Compound Component Architecture.\n */\nexport function PopoverRoot({ children, defaultOpen = false }: PopoverRootProps) {\n const [open, setOpen] = useState(defaultOpen);\n const triggerRef = useRef<HTMLElement | null>(null);\n const contentRef = useRef<HTMLDivElement | null>(null);\n const contentId = `popover-${useId()}`;\n\n // WAI-ARIA Standard: Restore focus to trigger on close\n useEffect(() => {\n if (!open && triggerRef.current) {\n restoreFocus(triggerRef.current);\n }\n }, [open]);\n\n return (\n <PopoverContext.Provider value={{ open, setOpen, triggerRef, contentRef, contentId }}>\n {children}\n </PopoverContext.Provider>\n );\n}\nPopoverRoot.displayName = 'Popover';\n\n/* -------------------------------------------------------\n * 2. Trigger\n * ------------------------------------------------------*/\n\nexport interface PopoverTriggerProps {\n children: React.ReactElement;\n}\n\n/**\n * Popover Trigger\n * * Automatically clones the child element and injects necessary event listeners and ARIA attributes.\n */\nexport function PopoverTrigger({ children }: PopoverTriggerProps) {\n const { open, setOpen, triggerRef, contentId } = usePopover();\n\n // Safely extract the child and ref\n const child = React.Children.only(children) as React.ReactElement<React.HTMLProps<HTMLElement>>;\n const childRef = child.props.ref ?? (child as unknown as { ref?: React.Ref<HTMLElement> }).ref;\n\n const triggerProps: React.HTMLProps<HTMLElement> = {\n ref: (node: HTMLElement | null) => {\n triggerRef.current = node;\n if (typeof childRef === 'function') {\n childRef(node);\n } else if (childRef && typeof childRef === 'object' && 'current' in childRef) {\n (childRef as { current: HTMLElement | null }).current = node;\n }\n },\n 'aria-haspopup': 'dialog',\n 'aria-expanded': open,\n 'aria-controls': open ? contentId : undefined,\n onClick: (e: React.MouseEvent<HTMLElement>) => {\n e.preventDefault();\n setOpen((prev) => !prev);\n child.props.onClick?.(e);\n },\n onKeyDown: (e: React.KeyboardEvent<HTMLElement>) => {\n if (e.key === 'Escape' && open) {\n e.stopPropagation();\n setOpen(false);\n }\n child.props.onKeyDown?.(e);\n },\n };\n\n return React.cloneElement(child, triggerProps);\n}\nPopoverTrigger.displayName = 'Popover.Trigger';\n\n/* -------------------------------------------------------\n * 3. Content\n * ------------------------------------------------------*/\nexport interface PopoverContentProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n /** Preferred placement of the popover relative to the trigger. Defaults to 'bottom' */\n placement?: PopoverPlacement;\n /** Gap in pixels between the trigger and the popover. Defaults to 8px. */\n offset?: number;\n}\n\n/**\n * Popover Content\n * * Renders inside a Portal and implements smart collision detection to stay in the viewport.\n * * Automatically traps focus when open.\n */\nexport function PopoverContent({\n children,\n className,\n placement = 'bottom',\n offset = 8,\n ...props\n}: PopoverContentProps) {\n const { open, setOpen, triggerRef, contentRef, contentId } = usePopover();\n const [coords, setCoords] = useState({ top: -9999, left: -9999, arrowX: 50, arrowY: 50 });\n const [actualPlacement, setActualPlacement] = useState<PopoverPlacement>(placement);\n\n // Focus Trapping\n useEffect(() => {\n if (open && contentRef.current) {\n return trapFocus(contentRef.current);\n }\n return undefined;\n }, [open, contentRef]);\n\n // Click Outside Handler\n useEffect(() => {\n if (!open) return;\n const cleanup = onClickOutside([contentRef, triggerRef], () => {\n setOpen(false);\n });\n return cleanup;\n }, [open, setOpen, contentRef, triggerRef]);\n\n // Escape Key Handler\n useEffect(() => {\n if (!open) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.stopPropagation();\n setOpen(false);\n }\n };\n document.addEventListener('keydown', handler);\n return () => document.removeEventListener('keydown', handler);\n }, [open, setOpen]);\n\n // Positioning Math (Includes Boundary Collision)\n const updatePosition = useCallback(() => {\n if (!triggerRef.current || !contentRef.current) return;\n\n const triggerRect = triggerRef.current.getBoundingClientRect();\n const contentRect = contentRef.current.getBoundingClientRect();\n\n const scrollX = window.scrollX;\n const scrollY = window.scrollY;\n\n let top = 0;\n let left = 0;\n let arrowX = 50;\n let arrowY = 50;\n let nextPlacement = placement;\n\n // Viewport boundaries with safety padding\n const padding = 12;\n const minLeft = padding;\n const maxLeft = document.documentElement.clientWidth - contentRect.width - padding;\n const minTop = padding;\n const maxTop = document.documentElement.clientHeight - contentRect.height - padding;\n\n if (placement === 'top' || placement === 'bottom') {\n const actualCenter = triggerRect.left + scrollX + triggerRect.width / 2;\n left = actualCenter - contentRect.width / 2;\n\n // Clamp X\n if (left < minLeft) left = minLeft;\n if (left > maxLeft) left = maxLeft;\n\n // Calculate Arrow X\n arrowX = actualCenter - left;\n\n if (placement === 'bottom') {\n top = triggerRect.bottom + scrollY + offset;\n // Collision Detection: Flip if clipping bottom\n if (top + contentRect.height > maxTop + scrollY) {\n top = triggerRect.top + scrollY - contentRect.height - offset;\n nextPlacement = 'top';\n }\n } else {\n top = triggerRect.top + scrollY - contentRect.height - offset;\n // Collision Detection: Flip if clipping top\n if (top < minTop + scrollY) {\n top = triggerRect.bottom + scrollY + offset;\n nextPlacement = 'bottom';\n }\n }\n } else {\n const actualCenterY = triggerRect.top + scrollY + triggerRect.height / 2;\n top = actualCenterY - contentRect.height / 2;\n\n // Clamp Y\n if (top < minTop) top = minTop;\n if (top > maxTop) top = maxTop;\n\n // Calculate Arrow Y\n arrowY = actualCenterY - top;\n\n if (placement === 'right') {\n left = triggerRect.right + scrollX + offset;\n // Collision Detection: Flip to left if clipping right\n if (left + contentRect.width > maxLeft + scrollX) {\n left = triggerRect.left + scrollX - contentRect.width - offset;\n nextPlacement = 'left';\n }\n } else {\n left = triggerRect.left + scrollX - contentRect.width - offset;\n // Collision Detection: Flip to right if clipping left\n if (left < minLeft + scrollX) {\n left = triggerRect.right + scrollX + offset;\n nextPlacement = 'right';\n }\n }\n }\n\n setActualPlacement(nextPlacement);\n setCoords({ top, left, arrowX, arrowY });\n }, [placement, offset, triggerRef, contentRef]);\n\n useLayoutEffect(() => {\n if (!open) return;\n updatePosition();\n window.addEventListener('resize', updatePosition);\n window.addEventListener('scroll', updatePosition, true);\n return () => {\n window.removeEventListener('resize', updatePosition);\n window.removeEventListener('scroll', updatePosition, true);\n };\n }, [open, updatePosition]);\n\n if (!open) return null;\n\n return (\n <Portal>\n <div\n id={contentId}\n ref={contentRef}\n role=\"dialog\"\n aria-modal=\"true\"\n data-placement={actualPlacement}\n className={cn('nui-popover-content', className)}\n style={{\n position: 'absolute',\n top: coords.top,\n left: coords.left,\n '--nui-popover-arrow-x': `${coords.arrowX}px`,\n '--nui-popover-arrow-y': `${coords.arrowY}px`,\n } as React.CSSProperties}\n {...props}\n >\n {children}\n </div>\n </Portal>\n );\n}\nPopoverContent.displayName = 'Popover.Content';\n\n/* -------------------------------------------------------\n * 4. Close Button\n * ------------------------------------------------------*/\n\nexport interface PopoverCloseProps {\n children: React.ReactElement;\n}\n\n/**\n * Popover Close\n * * Optional headless wrapper that injects a close action into a child button.\n */\nexport function PopoverClose({ children }: PopoverCloseProps) {\n const { setOpen } = usePopover();\n \n const child = React.Children.only(children) as React.ReactElement<React.HTMLProps<HTMLElement>>;\n \n return React.cloneElement(child, {\n onClick: (e: React.MouseEvent<HTMLElement>) => {\n setOpen(false);\n child.props.onClick?.(e);\n },\n });\n}\nPopoverClose.displayName = 'Popover.Close';\n\n/* -------------------------------------------------------\n * Export\n * ------------------------------------------------------*/\nexport const Popover = Object.assign(PopoverRoot, {\n Trigger: PopoverTrigger,\n Content: PopoverContent,\n Close: PopoverClose,\n});"],"names":["PopoverContext","createContext","usePopover","ctx","useContext","PopoverRoot","children","defaultOpen","open","setOpen","useState","triggerRef","useRef","contentRef","contentId","useId","useEffect","restoreFocus","jsx","PopoverTrigger","child","React","childRef","triggerProps","node","e","prev","PopoverContent","className","placement","offset","props","coords","setCoords","actualPlacement","setActualPlacement","trapFocus","onClickOutside","handler","updatePosition","useCallback","triggerRect","contentRect","scrollX","scrollY","top","left","arrowX","arrowY","nextPlacement","padding","minLeft","maxLeft","minTop","maxTop","actualCenter","actualCenterY","useLayoutEffect","Portal","cn","PopoverClose","Popover"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime");;/* empty css */function d({value:r,max:i=100,indeterminate:a=!1,label:o="Progress",className:t=""}){const e=a||r===void 0,n=Math.min(Math.max((r??0)/i,0),1)*100;return s.jsx("div",{className:`ui-progress ${t}`,role:"progressbar","aria-valuemin":e?void 0:0,"aria-valuemax":e?void 0:i,"aria-valuenow":e?void 0:r,"aria-label":o,children:s.jsx("div",{className:`ui-progress-bar ${e?"indeterminate":""}`,style:e?void 0:{width:`${n}%`}})})}exports.Progress=d;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),p=require("react");;/* empty css */const v=require("../../utils/cn/cn.cjs"),n=p.forwardRef(({value:s,max:e=100,indeterminate:o=!1,size:t="md",variant:c="default",label:u="Progress",className:l,...d},g)=>{const a=o||s===void 0,i=Math.min(Math.max(s??0,0),e),m=i/e*100;return r.jsx("div",{ref:g,role:"progressbar","aria-valuemin":0,"aria-valuemax":e,"aria-valuenow":a?void 0:i,"aria-label":u,className:v.cn("nui-progress",`nui-progress--${t}`,`nui-progress--${c}`,l),...d,children:a?r.jsx("div",{className:"nui-progress-indicator nui-progress-indicator--indeterminate"}):r.jsx("div",{className:"nui-progress-indicator",style:{transform:`translateX(-${100-m}%)`}})})});n.displayName="Progress";exports.Progress=n;
2
2
  //# sourceMappingURL=Progress.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Progress.cjs","sources":["../../../src/components/progress/Progress.tsx"],"sourcesContent":["/**\r\n * Progress.tsx FINAL VERSION\r\n * --------------------------------\r\n * Features:\r\n * - Determinate mode (value/max)\r\n * - Indeterminate mode\r\n * - Smooth animation\r\n * - ARIA compliant\r\n * - Pure TSX + CSS (no inline styles except width)\r\n */\r\n\r\nimport './Progress.css';\r\n\r\nexport interface ProgressProps {\r\n /** Current value (determinate mode). */\r\n value?: number;\r\n\r\n /** Maximum value (default: 100). */\r\n max?: number;\r\n\r\n /** Indeterminate mode when value is undefined. */\r\n indeterminate?: boolean;\r\n\r\n /** Optional label for screen readers. */\r\n label?: string;\r\n\r\n className?: string;\r\n}\r\n\r\nexport function Progress({\r\n value,\r\n max = 100,\r\n indeterminate = false,\r\n label = 'Progress',\r\n className = '',\r\n}: ProgressProps) {\r\n const isIndeterminate = indeterminate || value === undefined;\r\n\r\n const percentage = Math.min(Math.max((value ?? 0) / max, 0), 1) * 100;\r\n\r\n return (\r\n <div\r\n className={`ui-progress ${className}`}\r\n role=\"progressbar\"\r\n aria-valuemin={isIndeterminate ? undefined : 0}\r\n aria-valuemax={isIndeterminate ? undefined : max}\r\n aria-valuenow={isIndeterminate ? undefined : value}\r\n aria-label={label}\r\n >\r\n <div\r\n className={`ui-progress-bar ${isIndeterminate ? 'indeterminate' : ''}`}\r\n style={!isIndeterminate ? { width: `${percentage}%` } : undefined}\r\n />\r\n </div>\r\n );\r\n}\r\n"],"names":["Progress","value","max","indeterminate","label","className","isIndeterminate","percentage","jsx"],"mappings":"mJA6BO,SAASA,EAAS,CACvB,MAAAC,EACA,IAAAC,EAAM,IACN,cAAAC,EAAgB,GAChB,MAAAC,EAAQ,WACR,UAAAC,EAAY,EACd,EAAkB,CAChB,MAAMC,EAAkBH,GAAiBF,IAAU,OAE7CM,EAAa,KAAK,IAAI,KAAK,KAAKN,GAAS,GAAKC,EAAK,CAAC,EAAG,CAAC,EAAI,IAElE,OACEM,EAAAA,IAAC,MAAA,CACC,UAAW,eAAeH,CAAS,GACnC,KAAK,cACL,gBAAeC,EAAkB,OAAY,EAC7C,gBAAeA,EAAkB,OAAYJ,EAC7C,gBAAeI,EAAkB,OAAYL,EAC7C,aAAYG,EAEZ,SAAAI,EAAAA,IAAC,MAAA,CACC,UAAW,mBAAmBF,EAAkB,gBAAkB,EAAE,GACpE,MAAQA,EAAgD,OAA9B,CAAE,MAAO,GAAGC,CAAU,IAAQ,CAAA,CAC1D,CAAA,CAGN"}
1
+ {"version":3,"file":"Progress.cjs","sources":["../../../src/components/progress/Progress.tsx"],"sourcesContent":["import React, { forwardRef } from 'react';\nimport { cn } from '../../utils';\nimport './Progress.css';\n\n/* ============================================================\n * Types\n * ============================================================ */\n\nexport interface ProgressProps extends React.HTMLAttributes<HTMLDivElement> {\n /** The current progress value */\n value?: number;\n /** The maximum possible value. Defaults to 100. */\n max?: number;\n /** Forces the progress bar into an animated indeterminate state */\n indeterminate?: boolean;\n /** The visual height of the progress bar. Defaults to 'md'. */\n size?: 'sm' | 'md' | 'lg';\n /** The semantic color variant. Defaults to 'default'. */\n variant?: 'default' | 'success' | 'warning' | 'danger';\n /** WAI-ARIA hidden label for screen readers. Defaults to 'Progress'. */\n label?: string; \n}\n\n/* ============================================================\n * Component\n * ============================================================ */\n\n/**\n * Progress Component\n * * A WAI-ARIA compliant progress bar indicating the completion status of a task.\n * * Architecture Note: Uses CSS `transform: translateX` instead of `width` for \n * hardware-accelerated (GPU) 60fps rendering to prevent layout thrashing on the main thread.\n */\nexport const Progress = forwardRef<HTMLDivElement, ProgressProps>(({\n value,\n max = 100,\n indeterminate = false,\n size = 'md',\n variant = 'default',\n label = 'Progress',\n className,\n ...props\n}, ref) => {\n // If no value is provided, safely fall back to indeterminate mode\n const isIndeterminate = indeterminate || value === undefined;\n\n // Safely clamp the percentage between 0 and 100 to prevent layout breakage\n const safeValue = Math.min(Math.max(value ?? 0, 0), max);\n const percentage = (safeValue / max) * 100;\n\n return (\n <div\n ref={ref}\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={max}\n aria-valuenow={isIndeterminate ? undefined : safeValue}\n aria-label={label}\n className={cn(\n \"nui-progress\",\n `nui-progress--${size}`,\n `nui-progress--${variant}`,\n className\n )}\n {...props}\n >\n {isIndeterminate ? (\n /* Hardware-Accelerated Indeterminate Bar */\n <div className=\"nui-progress-indicator nui-progress-indicator--indeterminate\" />\n ) : (\n /* Hardware-Accelerated Determinate Bar */\n <div\n className=\"nui-progress-indicator\"\n style={{\n // We use translateX instead of width for buttery smooth 60fps rendering\n transform: `translateX(-${100 - percentage}%)`,\n }}\n />\n )}\n </div>\n );\n});\n\nProgress.displayName = 'Progress';"],"names":["Progress","forwardRef","value","max","indeterminate","size","variant","label","className","props","ref","isIndeterminate","safeValue","percentage","jsx","cn"],"mappings":"+MAiCaA,EAAWC,EAAAA,WAA0C,CAAC,CACjE,MAAAC,EACA,IAAAC,EAAM,IACN,cAAAC,EAAgB,GAChB,KAAAC,EAAO,KACP,QAAAC,EAAU,UACV,MAAAC,EAAQ,WACR,UAAAC,EACA,GAAGC,CACL,EAAGC,IAAQ,CAET,MAAMC,EAAkBP,GAAiBF,IAAU,OAG7CU,EAAY,KAAK,IAAI,KAAK,IAAIV,GAAS,EAAG,CAAC,EAAGC,CAAG,EACjDU,EAAcD,EAAYT,EAAO,IAEvC,OACEW,EAAAA,IAAC,MAAA,CACC,IAAAJ,EACA,KAAK,cACL,gBAAe,EACf,gBAAeP,EACf,gBAAeQ,EAAkB,OAAYC,EAC7C,aAAYL,EACZ,UAAWQ,EAAAA,GACT,eACA,iBAAiBV,CAAI,GACrB,iBAAiBC,CAAO,GACxBE,CAAA,EAED,GAAGC,EAEH,SAAAE,EAECG,EAAAA,IAAC,MAAA,CAAI,UAAU,8DAAA,CAA+D,EAG9EA,EAAAA,IAAC,MAAA,CACC,UAAU,yBACV,MAAO,CAEL,UAAW,eAAe,IAAMD,CAAU,IAAA,CAC5C,CAAA,CACF,CAAA,CAIR,CAAC,EAEDb,EAAS,YAAc"}
@@ -1,33 +1,55 @@
1
- import { jsx as a } from "react/jsx-runtime";
1
+ import { jsx as s } from "react/jsx-runtime";
2
+ import { forwardRef as g } from "react";
2
3
  /* empty css */
3
- function l({
4
+ import { cn as u } from "../../utils/cn/cn.js";
5
+ const f = g(({
4
6
  value: e,
5
- max: i = 100,
6
- indeterminate: s = !1,
7
- label: o = "Progress",
8
- className: t = ""
9
- }) {
10
- const r = s || e === void 0, n = Math.min(Math.max((e ?? 0) / i, 0), 1) * 100;
11
- return /* @__PURE__ */ a(
7
+ max: r = 100,
8
+ indeterminate: o = !1,
9
+ size: n = "md",
10
+ variant: t = "default",
11
+ label: m = "Progress",
12
+ className: d,
13
+ ...l
14
+ }, p) => {
15
+ const a = o || e === void 0, i = Math.min(Math.max(e ?? 0, 0), r), c = i / r * 100;
16
+ return /* @__PURE__ */ s(
12
17
  "div",
13
18
  {
14
- className: `ui-progress ${t}`,
19
+ ref: p,
15
20
  role: "progressbar",
16
- "aria-valuemin": r ? void 0 : 0,
17
- "aria-valuemax": r ? void 0 : i,
18
- "aria-valuenow": r ? void 0 : e,
19
- "aria-label": o,
20
- children: /* @__PURE__ */ a(
21
- "div",
22
- {
23
- className: `ui-progress-bar ${r ? "indeterminate" : ""}`,
24
- style: r ? void 0 : { width: `${n}%` }
25
- }
21
+ "aria-valuemin": 0,
22
+ "aria-valuemax": r,
23
+ "aria-valuenow": a ? void 0 : i,
24
+ "aria-label": m,
25
+ className: u(
26
+ "nui-progress",
27
+ `nui-progress--${n}`,
28
+ `nui-progress--${t}`,
29
+ d
30
+ ),
31
+ ...l,
32
+ children: a ? (
33
+ /* Hardware-Accelerated Indeterminate Bar */
34
+ /* @__PURE__ */ s("div", { className: "nui-progress-indicator nui-progress-indicator--indeterminate" })
35
+ ) : (
36
+ /* Hardware-Accelerated Determinate Bar */
37
+ /* @__PURE__ */ s(
38
+ "div",
39
+ {
40
+ className: "nui-progress-indicator",
41
+ style: {
42
+ // We use translateX instead of width for buttery smooth 60fps rendering
43
+ transform: `translateX(-${100 - c}%)`
44
+ }
45
+ }
46
+ )
26
47
  )
27
48
  }
28
49
  );
29
- }
50
+ });
51
+ f.displayName = "Progress";
30
52
  export {
31
- l as Progress
53
+ f as Progress
32
54
  };
33
55
  //# sourceMappingURL=Progress.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Progress.js","sources":["../../../src/components/progress/Progress.tsx"],"sourcesContent":["/**\r\n * Progress.tsx FINAL VERSION\r\n * --------------------------------\r\n * Features:\r\n * - Determinate mode (value/max)\r\n * - Indeterminate mode\r\n * - Smooth animation\r\n * - ARIA compliant\r\n * - Pure TSX + CSS (no inline styles except width)\r\n */\r\n\r\nimport './Progress.css';\r\n\r\nexport interface ProgressProps {\r\n /** Current value (determinate mode). */\r\n value?: number;\r\n\r\n /** Maximum value (default: 100). */\r\n max?: number;\r\n\r\n /** Indeterminate mode when value is undefined. */\r\n indeterminate?: boolean;\r\n\r\n /** Optional label for screen readers. */\r\n label?: string;\r\n\r\n className?: string;\r\n}\r\n\r\nexport function Progress({\r\n value,\r\n max = 100,\r\n indeterminate = false,\r\n label = 'Progress',\r\n className = '',\r\n}: ProgressProps) {\r\n const isIndeterminate = indeterminate || value === undefined;\r\n\r\n const percentage = Math.min(Math.max((value ?? 0) / max, 0), 1) * 100;\r\n\r\n return (\r\n <div\r\n className={`ui-progress ${className}`}\r\n role=\"progressbar\"\r\n aria-valuemin={isIndeterminate ? undefined : 0}\r\n aria-valuemax={isIndeterminate ? undefined : max}\r\n aria-valuenow={isIndeterminate ? undefined : value}\r\n aria-label={label}\r\n >\r\n <div\r\n className={`ui-progress-bar ${isIndeterminate ? 'indeterminate' : ''}`}\r\n style={!isIndeterminate ? { width: `${percentage}%` } : undefined}\r\n />\r\n </div>\r\n );\r\n}\r\n"],"names":["Progress","value","max","indeterminate","label","className","isIndeterminate","percentage","jsx"],"mappings":";;AA6BO,SAASA,EAAS;AAAA,EACvB,OAAAC;AAAA,EACA,KAAAC,IAAM;AAAA,EACN,eAAAC,IAAgB;AAAA,EAChB,OAAAC,IAAQ;AAAA,EACR,WAAAC,IAAY;AACd,GAAkB;AAChB,QAAMC,IAAkBH,KAAiBF,MAAU,QAE7CM,IAAa,KAAK,IAAI,KAAK,KAAKN,KAAS,KAAKC,GAAK,CAAC,GAAG,CAAC,IAAI;AAElE,SACE,gBAAAM;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,eAAeH,CAAS;AAAA,MACnC,MAAK;AAAA,MACL,iBAAeC,IAAkB,SAAY;AAAA,MAC7C,iBAAeA,IAAkB,SAAYJ;AAAA,MAC7C,iBAAeI,IAAkB,SAAYL;AAAA,MAC7C,cAAYG;AAAA,MAEZ,UAAA,gBAAAI;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAW,mBAAmBF,IAAkB,kBAAkB,EAAE;AAAA,UACpE,OAAQA,IAAgD,SAA9B,EAAE,OAAO,GAAGC,CAAU;QAAQ;AAAA,MAAA;AAAA,IAC1D;AAAA,EAAA;AAGN;"}
1
+ {"version":3,"file":"Progress.js","sources":["../../../src/components/progress/Progress.tsx"],"sourcesContent":["import React, { forwardRef } from 'react';\nimport { cn } from '../../utils';\nimport './Progress.css';\n\n/* ============================================================\n * Types\n * ============================================================ */\n\nexport interface ProgressProps extends React.HTMLAttributes<HTMLDivElement> {\n /** The current progress value */\n value?: number;\n /** The maximum possible value. Defaults to 100. */\n max?: number;\n /** Forces the progress bar into an animated indeterminate state */\n indeterminate?: boolean;\n /** The visual height of the progress bar. Defaults to 'md'. */\n size?: 'sm' | 'md' | 'lg';\n /** The semantic color variant. Defaults to 'default'. */\n variant?: 'default' | 'success' | 'warning' | 'danger';\n /** WAI-ARIA hidden label for screen readers. Defaults to 'Progress'. */\n label?: string; \n}\n\n/* ============================================================\n * Component\n * ============================================================ */\n\n/**\n * Progress Component\n * * A WAI-ARIA compliant progress bar indicating the completion status of a task.\n * * Architecture Note: Uses CSS `transform: translateX` instead of `width` for \n * hardware-accelerated (GPU) 60fps rendering to prevent layout thrashing on the main thread.\n */\nexport const Progress = forwardRef<HTMLDivElement, ProgressProps>(({\n value,\n max = 100,\n indeterminate = false,\n size = 'md',\n variant = 'default',\n label = 'Progress',\n className,\n ...props\n}, ref) => {\n // If no value is provided, safely fall back to indeterminate mode\n const isIndeterminate = indeterminate || value === undefined;\n\n // Safely clamp the percentage between 0 and 100 to prevent layout breakage\n const safeValue = Math.min(Math.max(value ?? 0, 0), max);\n const percentage = (safeValue / max) * 100;\n\n return (\n <div\n ref={ref}\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={max}\n aria-valuenow={isIndeterminate ? undefined : safeValue}\n aria-label={label}\n className={cn(\n \"nui-progress\",\n `nui-progress--${size}`,\n `nui-progress--${variant}`,\n className\n )}\n {...props}\n >\n {isIndeterminate ? (\n /* Hardware-Accelerated Indeterminate Bar */\n <div className=\"nui-progress-indicator nui-progress-indicator--indeterminate\" />\n ) : (\n /* Hardware-Accelerated Determinate Bar */\n <div\n className=\"nui-progress-indicator\"\n style={{\n // We use translateX instead of width for buttery smooth 60fps rendering\n transform: `translateX(-${100 - percentage}%)`,\n }}\n />\n )}\n </div>\n );\n});\n\nProgress.displayName = 'Progress';"],"names":["Progress","forwardRef","value","max","indeterminate","size","variant","label","className","props","ref","isIndeterminate","safeValue","percentage","jsx","cn"],"mappings":";;;;AAiCO,MAAMA,IAAWC,EAA0C,CAAC;AAAA,EACjE,OAAAC;AAAA,EACA,KAAAC,IAAM;AAAA,EACN,eAAAC,IAAgB;AAAA,EAChB,MAAAC,IAAO;AAAA,EACP,SAAAC,IAAU;AAAA,EACV,OAAAC,IAAQ;AAAA,EACR,WAAAC;AAAA,EACA,GAAGC;AACL,GAAGC,MAAQ;AAET,QAAMC,IAAkBP,KAAiBF,MAAU,QAG7CU,IAAY,KAAK,IAAI,KAAK,IAAIV,KAAS,GAAG,CAAC,GAAGC,CAAG,GACjDU,IAAcD,IAAYT,IAAO;AAEvC,SACE,gBAAAW;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAJ;AAAA,MACA,MAAK;AAAA,MACL,iBAAe;AAAA,MACf,iBAAeP;AAAA,MACf,iBAAeQ,IAAkB,SAAYC;AAAA,MAC7C,cAAYL;AAAA,MACZ,WAAWQ;AAAA,QACT;AAAA,QACA,iBAAiBV,CAAI;AAAA,QACrB,iBAAiBC,CAAO;AAAA,QACxBE;AAAA,MAAA;AAAA,MAED,GAAGC;AAAA,MAEH,UAAAE;AAAA;AAAA,QAEC,gBAAAG,EAAC,OAAA,EAAI,WAAU,+DAAA,CAA+D;AAAA;AAAA;AAAA,QAG9E,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA;AAAA,cAEL,WAAW,eAAe,MAAMD,CAAU;AAAA,YAAA;AAAA,UAC5C;AAAA,QAAA;AAAA;AAAA,IACF;AAAA,EAAA;AAIR,CAAC;AAEDb,EAAS,cAAc;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),u=require("react");;/* empty css */function p({options:l,value:d,defaultValue:m,onChange:o,name:k,disabled:b=!1,className:x=""}){const c=d!==void 0,[v,w]=u.useState(m),R=c?d:v,f=u.useRef([]),h=u.useCallback(e=>{c||w(e),o?.(e)},[c,o]),j=(e,n)=>{const a=l.map((i,y)=>i.disabled?null:y).filter(i=>i!==null),r=a.indexOf(n);if(r===-1)return;let t=r;switch(e.key){case"ArrowDown":case"ArrowRight":t=(r+1)%a.length;break;case"ArrowUp":case"ArrowLeft":t=(r-1+a.length)%a.length;break;case"Home":t=0;break;case"End":t=a.length-1;break;default:return}e.preventDefault();const g=a[t];f.current[g]?.focus(),h(l[g].value)};return s.jsx("div",{className:`ui-radio-group ${x}`,role:"radiogroup",children:l.map((e,n)=>{const a=R===e.value;return s.jsxs("label",{className:"ui-radio-item","aria-disabled":b||e.disabled,children:[s.jsx("input",{ref:r=>{f.current[n]=r},type:"radio",className:"ui-radio-input",name:k,value:e.value,disabled:b||e.disabled,checked:a,onChange:()=>h(e.value),onKeyDown:r=>j(r,n),"data-state":a?"checked":"unchecked"}),s.jsx("span",{className:"ui-radio-label",children:e.label})]},e.value)})})}exports.RadioGroup=p;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("react/jsx-runtime"),o=require("react");;/* empty css */const g=require("../../utils/cn/cn.cjs"),h=o.createContext(null);function v(){const e=o.useContext(h);if(!e)throw new Error("RadioGroup.Item must be used within a <RadioGroup>");return e}const G=o.forwardRef(({value:e,defaultValue:u,onChange:r,name:s,disabled:d=!1,orientation:n="vertical",className:t,children:c,...i},l)=>{const a=e!==void 0,[p,b]=o.useState(u),f=a?e:p,x=o.useId(),C=s||`nui-radiogroup-${x}`,j=o.useCallback(R=>{a||b(R),r?.(R)},[a,r]);return m.jsx(h.Provider,{value:{value:f,onChange:j,name:C,disabled:d},children:m.jsx("div",{ref:l,role:"radiogroup","aria-orientation":n,className:g.cn("nui-radio-group",n==="horizontal"&&"nui-radio-group--horizontal",t),...i,children:c})})});G.displayName="RadioGroup";const I=o.forwardRef(({value:e,disabled:u,className:r,id:s,...d},n)=>{const t=v(),c=t.disabled||u,i=t.value===e,l=o.useId(),a=s||`nui-radio-${l}`;return m.jsx("input",{ref:n,id:a,type:"radio",name:t.name,value:e,checked:i,disabled:c,"aria-checked":i,onChange:p=>t.onChange(p.target.value),className:g.cn("nui-radio-input",r),...d})});I.displayName="RadioGroup.Item";const w=Object.assign(G,{Item:I});exports.RadioGroup=w;
2
2
  //# sourceMappingURL=RadioGroup.cjs.map