@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
@@ -0,0 +1,134 @@
1
+ import { jsx as m } from "react/jsx-runtime";
2
+ import { forwardRef as P, useRef as D, useCallback as S, useLayoutEffect as B, createContext as L, useContext as G } from "react";
3
+ /* empty css */
4
+ import { cn as k } from "../../utils/cn/cn.js";
5
+ const H = L(null);
6
+ function K() {
7
+ const i = G(H);
8
+ if (!i) throw new Error("Resizable components must be used within <Resizable>");
9
+ return i;
10
+ }
11
+ const M = P(({
12
+ direction: i = "horizontal",
13
+ onLayout: u,
14
+ className: y,
15
+ children: b,
16
+ ...d
17
+ }, f) => {
18
+ const s = D(null), z = D([]), A = S((e, o) => {
19
+ const l = s.current;
20
+ if (!l) return !1;
21
+ const a = Array.from(l.querySelectorAll("[data-resizable-panel]")), c = Array.from(l.querySelectorAll("[data-resizable-handle]")), t = a[e], r = a[e + 1];
22
+ if (!t || !r) return !1;
23
+ const n = z.current, R = parseFloat(t.dataset.minSize || "0"), g = parseFloat(t.dataset.maxSize || "100"), w = parseFloat(r.dataset.minSize || "0"), x = parseFloat(r.dataset.maxSize || "100"), h = Math.min(g - n[e], n[e + 1] - w), p = Math.max(R - n[e], n[e + 1] - x), v = Math.max(p, Math.min(h, o));
24
+ return v !== 0 ? (n[e] += v, n[e + 1] -= v, t.style.flexGrow = n[e].toString(), r.style.flexGrow = n[e + 1].toString(), c[e]?.setAttribute("aria-valuenow", n[e].toFixed(0)), !0) : !1;
25
+ }, []), q = S((e, o) => {
26
+ o.preventDefault(), e.focus();
27
+ const l = s.current;
28
+ if (!l) return;
29
+ const a = Array.from(l.querySelectorAll("[data-resizable-handle]")), c = a.indexOf(e);
30
+ if (c === -1) return;
31
+ const t = i === "horizontal", r = t ? l.clientWidth : l.clientHeight, n = a.reduce((h, p) => h + (t ? p.offsetWidth : p.offsetHeight), 0), R = r - n;
32
+ let g = t ? o.clientX : o.clientY;
33
+ const w = (h) => {
34
+ const p = t ? h.clientX : h.clientY, E = (p - g) / R * 100;
35
+ A(c, E), g = p;
36
+ }, x = () => {
37
+ document.removeEventListener("pointermove", w), document.removeEventListener("pointerup", x), document.body.style.cursor = "", document.body.style.userSelect = "", e.removeAttribute("data-dragging"), u && u([...z.current]);
38
+ };
39
+ document.addEventListener("pointermove", w), document.addEventListener("pointerup", x), document.body.style.cursor = t ? "col-resize" : "row-resize", document.body.style.userSelect = "none", e.setAttribute("data-dragging", "true");
40
+ }, [i, u, A]), C = S((e, o) => {
41
+ const l = s.current;
42
+ if (!l) return;
43
+ const c = Array.from(l.querySelectorAll("[data-resizable-handle]")).indexOf(e);
44
+ if (c === -1) return;
45
+ let t = 0;
46
+ const r = o.shiftKey ? 10 : 2;
47
+ i === "horizontal" ? (o.key === "ArrowRight" && (t = r), o.key === "ArrowLeft" && (t = -r)) : (o.key === "ArrowDown" && (t = r), o.key === "ArrowUp" && (t = -r)), o.key === "Home" && (t = -100), o.key === "End" && (t = 100), t !== 0 && (A(c, t), u && u([...z.current]));
48
+ }, [i, u, A]);
49
+ return B(() => {
50
+ const e = s.current;
51
+ if (!e) return;
52
+ const o = Array.from(e.querySelectorAll("[data-resizable-panel]")), l = Array.from(e.querySelectorAll("[data-resizable-handle]"));
53
+ if (z.current.length !== o.length) {
54
+ const a = o.map((r) => parseFloat(r.dataset.defaultSize || "0")), c = a.reduce((r, n) => r + n, 0), t = a.filter((r) => r === 0).length;
55
+ if (t > 0) {
56
+ const r = Math.max(0, 100 - c) / t;
57
+ for (let n = 0; n < a.length; n++)
58
+ a[n] === 0 && (a[n] = r);
59
+ }
60
+ z.current = a;
61
+ }
62
+ o.forEach((a, c) => {
63
+ a.style.flexGrow = z.current[c].toString(), a.style.flexBasis = "0px";
64
+ }), l.forEach((a, c) => {
65
+ a.setAttribute("aria-valuenow", z.current[c].toFixed(0));
66
+ });
67
+ }, [b]), /* @__PURE__ */ m(H.Provider, { value: { direction: i, startDrag: q, keyboardResize: C }, children: /* @__PURE__ */ m(
68
+ "div",
69
+ {
70
+ ref: (e) => {
71
+ s.current = e, typeof f == "function" ? f(e) : f && (f.current = e);
72
+ },
73
+ "data-direction": i,
74
+ className: k("nui-resizable-group", y),
75
+ ...d,
76
+ children: b
77
+ }
78
+ ) });
79
+ });
80
+ M.displayName = "Resizable";
81
+ const F = P(({
82
+ defaultSize: i,
83
+ minSize: u = 0,
84
+ maxSize: y = 100,
85
+ className: b,
86
+ children: d,
87
+ ...f
88
+ }, s) => /* @__PURE__ */ m(
89
+ "div",
90
+ {
91
+ ref: s,
92
+ "data-resizable-panel": !0,
93
+ "data-default-size": i,
94
+ "data-min-size": u,
95
+ "data-max-size": y,
96
+ className: k("nui-resizable-panel", b),
97
+ ...f,
98
+ children: d
99
+ }
100
+ ));
101
+ F.displayName = "Resizable.Panel";
102
+ const N = P(({
103
+ withIcon: i = !1,
104
+ className: u,
105
+ ...y
106
+ }, b) => {
107
+ const d = K(), f = (s) => {
108
+ ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "Home", "End"].includes(s.key) && (s.preventDefault(), d.keyboardResize(s.currentTarget, s));
109
+ };
110
+ return /* @__PURE__ */ m(
111
+ "div",
112
+ {
113
+ ref: b,
114
+ "data-resizable-handle": !0,
115
+ role: "separator",
116
+ "aria-orientation": d.direction,
117
+ tabIndex: 0,
118
+ onPointerDown: (s) => d.startDrag(s.currentTarget, s),
119
+ onKeyDown: f,
120
+ className: k("nui-resizable-handle", u),
121
+ ...y,
122
+ children: i && /* @__PURE__ */ m("div", { className: "nui-resizable-handle-icon", "aria-hidden": "true", children: /* @__PURE__ */ m("svg", { width: "15", height: "15", viewBox: "0 0 15 15", fill: "none", stroke: "currentColor", children: d.direction === "horizontal" ? /* @__PURE__ */ m("path", { d: "M5.5 4.5V10.5M9.5 4.5V10.5", strokeLinecap: "round" }) : /* @__PURE__ */ m("path", { d: "M4.5 5.5H10.5M4.5 9.5H10.5", strokeLinecap: "round" }) }) })
123
+ }
124
+ );
125
+ });
126
+ N.displayName = "Resizable.Handle";
127
+ const V = Object.assign(M, {
128
+ Panel: F,
129
+ Handle: N
130
+ });
131
+ export {
132
+ V as Resizable
133
+ };
134
+ //# sourceMappingURL=Resizable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Resizable.js","sources":["../../../src/components/resizable/Resizable.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { createContext, useContext, useRef, useCallback, useLayoutEffect, forwardRef } from 'react';\nimport { cn } from '../../utils';\nimport './Resizable.css';\n\n/* ============================================================\n * Context\n * ============================================================ */\n\ninterface ResizableContextValue {\n direction: 'horizontal' | 'vertical';\n startDrag: (handleElement: HTMLElement, e: React.PointerEvent) => void;\n keyboardResize: (handleElement: HTMLElement, e: React.KeyboardEvent) => void;\n}\n\nconst ResizableContext = createContext<ResizableContextValue | null>(null);\n\nfunction useResizable() {\n const ctx = useContext(ResizableContext);\n if (!ctx) throw new Error('Resizable components must be used within <Resizable>');\n return ctx;\n}\n\n/* ============================================================\n * 1. Resizable Group (Root)\n * ============================================================ */\n\nexport interface ResizableProps extends React.HTMLAttributes<HTMLDivElement> {\n /** The flex layout direction. Defaults to 'horizontal'. */\n direction?: 'horizontal' | 'vertical';\n /** Callback fired when the user completes a resize action, providing an array of panel sizes (percentages) */\n onLayout?: (sizes: number[]) => void;\n}\n\n/**\n * Resizable Component (Root)\n * * A Compound Component wrapper that manages the complex math and event delegation \n * required to dynamically resize panels via pointer or keyboard.\n */\nconst ResizableRoot = forwardRef<HTMLDivElement, ResizableProps>(({\n direction = 'horizontal',\n onLayout,\n className,\n children,\n ...props\n}, ref) => {\n const containerRef = useRef<HTMLDivElement>(null);\n \n // We store current sizes in a ref rather than state to avoid constant React re-renders during dragging (60fps performance!)\n const currentSizes = useRef<number[]>([]);\n\n /* ----------------------------------------------------\n Core Math Engine\n ---------------------------------------------------- */\n const resizePanels = useCallback((handleIndex: number, deltaPct: number) => {\n const container = containerRef.current;\n if (!container) return false;\n\n const panels = Array.from(container.querySelectorAll('[data-resizable-panel]')) as HTMLElement[];\n const handles = Array.from(container.querySelectorAll('[data-resizable-handle]')) as HTMLElement[];\n\n const panelA = panels[handleIndex];\n const panelB = panels[handleIndex + 1];\n if (!panelA || !panelB) return false;\n\n const startSizes = currentSizes.current;\n \n // Read constraints from DOM attributes\n const minA = parseFloat(panelA.dataset.minSize || '0');\n const maxA = parseFloat(panelA.dataset.maxSize || '100');\n const minB = parseFloat(panelB.dataset.minSize || '0');\n const maxB = parseFloat(panelB.dataset.maxSize || '100');\n\n // Calculate maximum allowable movement based on panel constraints\n const maxDeltaRight = Math.min(maxA - startSizes[handleIndex], startSizes[handleIndex + 1] - minB);\n const maxDeltaLeft = Math.max(minA - startSizes[handleIndex], startSizes[handleIndex + 1] - maxB);\n\n // Clamp the requested delta to the allowed range\n const allowedDelta = Math.max(maxDeltaLeft, Math.min(maxDeltaRight, deltaPct));\n\n if (allowedDelta !== 0) {\n startSizes[handleIndex] += allowedDelta;\n startSizes[handleIndex + 1] -= allowedDelta;\n\n // Apply sizes directly to DOM for performance\n panelA.style.flexGrow = startSizes[handleIndex].toString();\n panelB.style.flexGrow = startSizes[handleIndex + 1].toString();\n \n // Update WAI-ARIA states\n handles[handleIndex]?.setAttribute('aria-valuenow', startSizes[handleIndex].toFixed(0));\n return true;\n }\n return false;\n }, []);\n\n /* ----------------------------------------------------\n Pointer Event Listeners\n ---------------------------------------------------- */\n const startDrag = useCallback((handleElement: HTMLElement, e: React.PointerEvent) => {\n e.preventDefault();\n \n // Because preventDefault() stops the browser from naturally focusing the element,\n // we MUST manually force focus so the user's arrow keys start working immediately!\n handleElement.focus(); \n \n const container = containerRef.current;\n if (!container) return;\n\n const handles = Array.from(container.querySelectorAll('[data-resizable-handle]')) as HTMLElement[];\n const handleIndex = handles.indexOf(handleElement);\n if (handleIndex === -1) return;\n\n const isHorizontal = direction === 'horizontal';\n const availablePx = isHorizontal ? container.clientWidth : container.clientHeight;\n \n // We must subtract the size of the handles themselves so the math calculates percentage of *free* space\n const totalHandlePx = handles.reduce((acc, h) => acc + (isHorizontal ? h.offsetWidth : h.offsetHeight), 0);\n const flexAvailable = availablePx - totalHandlePx;\n\n let lastPos = isHorizontal ? e.clientX : e.clientY;\n\n const handlePointerMove = (moveEvent: PointerEvent) => {\n const currentPos = isHorizontal ? moveEvent.clientX : moveEvent.clientY;\n const deltaPx = currentPos - lastPos;\n \n // Convert physical pixel delta to a percentage of the flex container\n const deltaPct = (deltaPx / flexAvailable) * 100;\n\n resizePanels(handleIndex, deltaPct);\n lastPos = currentPos;\n };\n\n const handlePointerUp = () => {\n document.removeEventListener('pointermove', handlePointerMove);\n document.removeEventListener('pointerup', handlePointerUp);\n \n // Restore default cursor interactions\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n handleElement.removeAttribute('data-dragging');\n \n if (onLayout) onLayout([...currentSizes.current]);\n };\n\n // Attach listeners to document so drag continues even if mouse leaves the handle hitbox\n document.addEventListener('pointermove', handlePointerMove);\n document.addEventListener('pointerup', handlePointerUp);\n \n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n document.body.style.userSelect = 'none';\n handleElement.setAttribute('data-dragging', 'true');\n }, [direction, onLayout, resizePanels]);\n\n /* ----------------------------------------------------\n Keyboard Navigation Engine (WAI-ARIA)\n ---------------------------------------------------- */\n const keyboardResize = useCallback((handleElement: HTMLElement, e: React.KeyboardEvent) => {\n const container = containerRef.current;\n if (!container) return;\n \n const handles = Array.from(container.querySelectorAll('[data-resizable-handle]')) as HTMLElement[];\n const handleIndex = handles.indexOf(handleElement);\n if (handleIndex === -1) return;\n\n let deltaPct = 0;\n const step = e.shiftKey ? 10 : 2; // Modern UX: Shift + Arrow jumps by 10%\n\n // 1. Directional locking\n if (direction === 'horizontal') {\n if (e.key === 'ArrowRight') deltaPct = step;\n if (e.key === 'ArrowLeft') deltaPct = -step;\n } else {\n if (e.key === 'ArrowDown') deltaPct = step;\n if (e.key === 'ArrowUp') deltaPct = -step;\n }\n\n // 2. Absolute limits (Home/End)\n if (e.key === 'Home') deltaPct = -100; // Will be mathematically clamped by resizePanels\n if (e.key === 'End') deltaPct = 100;\n\n if (deltaPct !== 0) {\n resizePanels(handleIndex, deltaPct);\n if (onLayout) onLayout([...currentSizes.current]);\n }\n }, [direction, onLayout, resizePanels]);\n\n /* ----------------------------------------------------\n Initialization\n ---------------------------------------------------- */\n useLayoutEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const panels = Array.from(container.querySelectorAll('[data-resizable-panel]')) as HTMLElement[];\n const handles = Array.from(container.querySelectorAll('[data-resizable-handle]')) as HTMLElement[];\n\n // Only initialize if we haven't already (or if the number of panels changes)\n if (currentSizes.current.length !== panels.length) {\n const initial = panels.map(p => parseFloat(p.dataset.defaultSize || '0'));\n const total = initial.reduce((a, b) => a + b, 0);\n const unassignedCount = initial.filter(s => s === 0).length;\n\n // Distribute remaining space evenly among panels without a defaultSize\n if (unassignedCount > 0) {\n const share = Math.max(0, 100 - total) / unassignedCount;\n for (let i = 0; i < initial.length; i++) {\n if (initial[i] === 0) initial[i] = share;\n }\n }\n currentSizes.current = initial;\n }\n\n // Apply initialized sizes\n panels.forEach((p, i) => {\n p.style.flexGrow = currentSizes.current[i].toString();\n p.style.flexBasis = '0px'; \n });\n\n handles.forEach((h, i) => {\n h.setAttribute('aria-valuenow', currentSizes.current[i].toFixed(0));\n });\n }, [children]);\n\n return (\n <ResizableContext.Provider value={{ direction, startDrag, keyboardResize }}>\n <div\n ref={(el) => {\n containerRef.current = el;\n if (typeof ref === 'function') ref(el);\n else if (ref) ref.current = el;\n }}\n data-direction={direction}\n className={cn(\"nui-resizable-group\", className)}\n {...props}\n >\n {children}\n </div>\n </ResizableContext.Provider>\n );\n});\nResizableRoot.displayName = 'Resizable';\n\n/* ============================================================\n * 2. Resizable Panel\n * ============================================================ */\n\nexport interface ResizablePanelProps extends React.HTMLAttributes<HTMLDivElement> {\n /** The initial size of the panel as a percentage of the available space (0-100) */\n defaultSize?: number; \n /** The absolute minimum size the panel can shrink to */\n minSize?: number; \n /** The absolute maximum size the panel can grow to */\n maxSize?: number; \n}\n\nconst ResizablePanel = forwardRef<HTMLDivElement, ResizablePanelProps>(({\n defaultSize,\n minSize = 0,\n maxSize = 100,\n className,\n children,\n ...props\n}, ref) => {\n return (\n <div\n ref={ref}\n data-resizable-panel\n data-default-size={defaultSize}\n data-min-size={minSize}\n data-max-size={maxSize}\n className={cn(\"nui-resizable-panel\", className)}\n {...props}\n >\n {children}\n </div>\n );\n});\nResizablePanel.displayName = 'Resizable.Panel';\n\n/* ============================================================\n * 3. Resizable Handle\n * ============================================================ */\n\nexport interface ResizableHandleProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Renders a visual grip icon in the center of the handle */\n withIcon?: boolean; \n}\n\nconst ResizableHandle = forwardRef<HTMLDivElement, ResizableHandleProps>(({\n withIcon = false,\n className,\n ...props\n}, ref) => {\n const ctx = useResizable();\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n // Intercept standard split-view control keys\n if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End'].includes(e.key)) {\n e.preventDefault();\n ctx.keyboardResize(e.currentTarget, e); // Pass the full event for e.shiftKey\n }\n };\n\n return (\n <div\n ref={ref}\n data-resizable-handle\n role=\"separator\"\n aria-orientation={ctx.direction}\n tabIndex={0}\n onPointerDown={(e) => ctx.startDrag(e.currentTarget, e)}\n onKeyDown={handleKeyDown}\n className={cn(\"nui-resizable-handle\", className)}\n {...props}\n >\n {withIcon && (\n <div className=\"nui-resizable-handle-icon\" aria-hidden=\"true\">\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 15 15\" fill=\"none\" stroke=\"currentColor\">\n {ctx.direction === 'horizontal' ? (\n <path d=\"M5.5 4.5V10.5M9.5 4.5V10.5\" strokeLinecap=\"round\" />\n ) : (\n <path d=\"M4.5 5.5H10.5M4.5 9.5H10.5\" strokeLinecap=\"round\" />\n )}\n </svg>\n </div>\n )}\n </div>\n );\n});\nResizableHandle.displayName = 'Resizable.Handle';\n\n/* ============================================================\n * Export\n * ============================================================ */\n\nexport const Resizable = Object.assign(ResizableRoot, {\n Panel: ResizablePanel,\n Handle: ResizableHandle,\n});"],"names":["ResizableContext","createContext","useResizable","ctx","useContext","ResizableRoot","forwardRef","direction","onLayout","className","children","props","ref","containerRef","useRef","currentSizes","resizePanels","useCallback","handleIndex","deltaPct","container","panels","handles","panelA","panelB","startSizes","minA","maxA","minB","maxB","maxDeltaRight","maxDeltaLeft","allowedDelta","startDrag","handleElement","e","isHorizontal","availablePx","totalHandlePx","acc","h","flexAvailable","lastPos","handlePointerMove","moveEvent","currentPos","handlePointerUp","keyboardResize","step","useLayoutEffect","initial","p","total","a","b","unassignedCount","s","share","i","jsx","el","cn","ResizablePanel","defaultSize","minSize","maxSize","ResizableHandle","withIcon","handleKeyDown","Resizable"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react/jsx-runtime"),l=require("react");;/* empty css */const z=require("../../utils/restorefocus/restoreFocus.cjs"),G=require("../../utils/onclickoutside/onClickOutside.cjs"),J=require("../../utils/portal/portal.cjs");function L(s,h,g){const o=s.length;let d=h;for(let r=0;r<o;r++)if(d=(d+g+o)%o,!s[d].disabled)return d;return-1}function Q({options:s,value:h,defaultValue:g,onChange:o,placeholder:d="Select...",disabled:r=!1,name:C,id:O,className:T=""}){const I=h!==void 0,[$,K]=l.useState(g),b=I?h:$,S=s.find(e=>e.value===b)??null,[i,x]=l.useState(!1),[a,f]=l.useState(()=>s.findIndex(e=>!e.disabled)),v=l.useRef({buffer:"",lastTime:0}),p=l.useRef(null),m=l.useRef(null),P=l.useId(),R=O??P,y=`${R}-listbox`,E=`${R}-label`,V=l.useCallback(()=>{r||x(!0)},[r]),F=l.useCallback(()=>{x(!1),z.restoreFocus(p.current)},[]),M=l.useCallback(()=>{r||x(e=>!e)},[r]);l.useEffect(()=>{if(i)return G.onClickOutside(m,()=>x(!1))},[i]),l.useEffect(()=>{if(!i)return;const e=s.findIndex(n=>n.value===b&&!n.disabled),t=e>=0?e:s.findIndex(n=>!n.disabled);f(t>=0?t:-1),setTimeout(()=>{m.current?.focus()},0)},[i,s,b]);const N=l.useCallback(e=>{if(e<0||e>=s.length)return;const t=s[e];t.disabled||(I||K(t.value),o?.(t.value),x(!1),p.current?.focus())},[I,s,o]),U=e=>{r||["ArrowDown","ArrowUp"," ","Enter"].includes(e.key)&&(e.preventDefault(),V())},B=e=>{const t=e.key;if(t==="ArrowDown"){e.preventDefault();const n=L(s,a,1);n>=0&&f(n)}else if(t==="ArrowUp"){e.preventDefault();const n=L(s,a,-1);n>=0&&f(n)}else if(t==="Home"){e.preventDefault();const n=s.findIndex(u=>!u.disabled);n>=0&&f(n)}else if(t==="End"){e.preventDefault();const n=s.length-1-[...s].reverse().findIndex(u=>!u.disabled);n>=0&&f(n)}else if(t==="Enter"||t===" ")e.preventDefault(),a>=0&&N(a);else if(t==="Escape")e.preventDefault(),F();else if(t.length===1&&t.match(/\S/)){const n=Date.now();n-v.current.lastTime>700&&(v.current.buffer=""),v.current.buffer+=t.toLowerCase(),v.current.lastTime=n;const u=v.current.buffer,w=a>=0?a+1:0,A=s.length;for(let k=0;k<A;k++){const j=(w+k)%A,W=String(s[j].label).toLowerCase();if(!s[j].disabled&&W.startsWith(u)){f(j);break}}}},H=e=>{N(e)},[D,q]=l.useState(null);return l.useEffect(()=>{if(!i||!p.current){q(null);return}const e=p.current.getBoundingClientRect(),t=e.bottom+6,n=e.left;q({top:t,left:n})},[i]),c.jsxs("div",{className:`ui-select ${T}`,children:[C&&c.jsx("input",{type:"hidden",name:C,value:b??""}),c.jsxs("button",{ref:p,id:E,type:"button",className:"ui-select-trigger","aria-haspopup":"listbox","aria-expanded":i,"aria-controls":i?y:void 0,"aria-disabled":r||void 0,onClick:()=>M(),onKeyDown:U,disabled:r,children:[c.jsx("span",{children:S?c.jsx("span",{children:S.label}):c.jsx("span",{className:"ui-select-placeholder",children:d})}),c.jsx("span",{className:"ui-select-chevron","aria-hidden":!0,children:""})]}),i&&D&&c.jsx(J.Portal,{children:c.jsx("div",{id:y,ref:m,className:"ui-select-listbox",role:"listbox","aria-labelledby":E,tabIndex:0,style:{top:D.top,left:D.left},onKeyDown:B,children:s.map((e,t)=>{const n=b===e.value,u=a===t;return c.jsx("div",{id:`${y}-option-${t}`,role:"option","aria-selected":n,"aria-disabled":e.disabled||void 0,className:"ui-select-option",tabIndex:-1,onMouseDown:w=>w.preventDefault(),onClick:()=>!e.disabled&&H(t),style:{outline:u?"2px solid var(--color-primary)":void 0},children:e.label},e.value)})})})]})}exports.Select=Q;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("react/jsx-runtime"),r=require("react");;/* empty css */const Q=require("../../utils/restorefocus/restoreFocus.cjs"),Z=require("../../utils/onclickoutside/onClickOutside.cjs"),S=require("../../utils/cn/cn.cjs"),_=require("../../utils/portal/portal.cjs");function B(s,I,D){const b=s.length;let h=I;for(let u=0;u<b;u++)if(h=(h+D+b)%b,!s[h].disabled)return h;return-1}const K=r.forwardRef(({options:s,value:I,defaultValue:D,onChange:b,placeholder:h="Select...",disabled:u=!1,error:V=!1,name:N,id:$,className:M,...P},x)=>{const R=I!==void 0,[W,z]=r.useState(D),p=R?I:W,T=s.find(e=>e.value===p)??null,[c,g]=r.useState(!1),[o,d]=r.useState(()=>s.findIndex(e=>!e.disabled)),m=r.useRef({buffer:"",lastTime:0}),v=r.useRef(null),k=r.useRef(null),C=r.useRef(null),F=r.useId(),q=$??F,E=`${q}-listbox`,A=`${q}-label`,H=r.useCallback(e=>{v.current=e,typeof x=="function"?x(e):x&&(x.current=e)},[x]),[L,U]=r.useState({top:-9999,left:-9999,width:0}),w=r.useCallback(()=>{if(!v.current||!k.current)return;const e=v.current.getBoundingClientRect(),t=k.current.getBoundingClientRect(),n=window.scrollY,l=window.scrollX;let a=e.bottom+n+4;const j=e.left+l,y=e.width,f=16;e.bottom+t.height+4>document.documentElement.clientHeight-f&&(a=e.top+n-t.height-4,a<f+n&&(a=f+n)),U({top:a,left:j,width:y})},[]);r.useLayoutEffect(()=>{if(c)return w(),window.addEventListener("resize",w),window.addEventListener("scroll",w,!0),()=>{window.removeEventListener("resize",w),window.removeEventListener("scroll",w,!0)}},[c,w]);const X=r.useCallback(()=>{g(!1),Q.restoreFocus(v.current)},[]);r.useEffect(()=>c?Z.onClickOutside([k,v],()=>g(!1)):void 0,[c]),r.useEffect(()=>{if(!c)return;const e=s.findIndex(l=>l.value===p&&!l.disabled),t=e>=0?e:s.findIndex(l=>!l.disabled);d(t>=0?t:-1);const n=setTimeout(()=>k.current?.focus(),10);return()=>clearTimeout(n)},[c,s,p]),r.useEffect(()=>{c&&C.current&&C.current.scrollIntoView({block:"nearest"})},[o,c]);const O=r.useCallback(e=>{if(e<0||e>=s.length)return;const t=s[e];t.disabled||(R||z(t.value),b?.(t.value),g(!1),v.current?.focus())},[R,s,b]),Y=e=>{u||["ArrowDown","ArrowUp"," ","Enter"].includes(e.key)&&(e.preventDefault(),g(!0))},G=e=>{const t=e.key;if(t==="ArrowDown"){e.preventDefault();const n=B(s,o,1);n>=0&&d(n)}else if(t==="ArrowUp"){e.preventDefault();const n=B(s,o,-1);n>=0&&d(n)}else if(t==="Home"){e.preventDefault();const n=s.findIndex(l=>!l.disabled);n>=0&&d(n)}else if(t==="End"){e.preventDefault();const n=s.length-1-[...s].reverse().findIndex(l=>!l.disabled);n>=0&&d(n)}else if(t==="Enter"||t===" ")e.preventDefault(),o>=0&&O(o);else if(t==="Escape")e.preventDefault(),X();else if(t.length===1&&t.match(/\S/)){const n=Date.now();n-m.current.lastTime>700&&(m.current.buffer=""),m.current.buffer+=t.toLowerCase(),m.current.lastTime=n;const l=m.current.buffer,a=o>=0?o+1:0,j=s.length;for(let y=0;y<j;y++){const f=(a+y)%j,J=String(s[f].label).toLowerCase();if(!s[f].disabled&&J.startsWith(l)){d(f);break}}}};return i.jsxs("div",{className:S.cn("nui-select-root",M),children:[N&&i.jsx("input",{type:"hidden",name:N,value:p??""}),i.jsxs("button",{ref:H,id:A,type:"button",className:S.cn("nui-select-trigger",V&&"error"),"aria-haspopup":"listbox","aria-expanded":c,"aria-controls":c?E:void 0,"aria-disabled":u||void 0,onClick:()=>!u&&g(e=>!e),onKeyDown:Y,disabled:u,...P,children:[i.jsx("span",{className:"nui-select-value",children:T?T.label:i.jsx("span",{className:"nui-select-placeholder",children:h})}),i.jsx("svg",{className:"nui-select-chevron",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:i.jsx("polyline",{points:"6 9 12 15 18 9"})})]}),c&&i.jsx(_.Portal,{children:i.jsx("div",{id:E,ref:k,className:"nui-select-listbox",role:"listbox","aria-labelledby":A,tabIndex:0,style:{top:L.top,left:L.left,width:L.width},onKeyDown:G,children:s.map((e,t)=>{const n=p===e.value,l=o===t;return i.jsxs("div",{ref:l?C:null,id:`${E}-option-${t}`,role:"option","aria-selected":n,"aria-disabled":e.disabled||void 0,className:S.cn("nui-select-option",l&&"active",n&&"selected",e.disabled&&"disabled"),tabIndex:-1,onMouseDown:a=>a.preventDefault(),onClick:()=>!e.disabled&&O(t),onMouseEnter:()=>!e.disabled&&d(t),children:[i.jsx("span",{className:"nui-select-option-label",children:e.label}),n&&i.jsx("svg",{className:"nui-select-check",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"3",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:i.jsx("polyline",{points:"20 6 9 17 4 12"})})]},e.value)})})})]})});K.displayName="Select";exports.Select=K;
2
2
  //# sourceMappingURL=Select.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Select.cjs","sources":["../../../src/components/select/Select.tsx"],"sourcesContent":["/**\r\n * Select.tsx\r\n * ----------\r\n * Accessible single-select (listbox) component.\r\n *\r\n * Features:\r\n * - WAI-ARIA listbox pattern\r\n * - Keyboard navigation (ArrowUp/ArrowDown, Home, End, Enter, Space, Esc)\r\n * - Typeahead support\r\n * - Controlled + uncontrolled modes\r\n * - Portal rendering for the listbox\r\n * - Click outside to close\r\n * - Proper ARIA attributes and relationships\r\n * - Hidden input for form compatibility (optional name prop)\r\n *\r\n * Usage:\r\n * <Select\r\n * options={[{ value: 'a', label: 'Apple' }, { value: 'b', label: 'Banana' }]}\r\n * value={value} // optional controlled value\r\n * onChange={(v) => setValue(v)} // required if controlled\r\n * placeholder=\"Select fruit\"\r\n * name=\"fruit\" // optional, adds hidden input\r\n * />\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useRef,\r\n useEffect,\r\n useCallback,\r\n KeyboardEvent,\r\n} from 'react';\r\nimport './Select.css';\r\nimport { Portal, onClickOutside, restoreFocus } from '../../utils/index';\r\n\r\ntype Option = {\r\n value: string;\r\n label: React.ReactNode;\r\n disabled?: boolean;\r\n};\r\n\r\ninterface SelectProps {\r\n options: Option[];\r\n value?: string; // controlled value\r\n defaultValue?: string; // uncontrolled initial\r\n onChange?: (value: string) => void;\r\n placeholder?: string;\r\n disabled?: boolean;\r\n name?: string; // if provided, render hidden input for forms\r\n id?: string;\r\n className?: string;\r\n}\r\n\r\n/* Helper: find next enabled index given direction */\r\nfunction findNextEnabled(options: Option[], start: number, direction: 1 | -1) {\r\n const len = options.length;\r\n let i = start;\r\n for (let step = 0; step < len; step++) {\r\n i = (i + direction + len) % len;\r\n if (!options[i].disabled) return i;\r\n }\r\n return -1;\r\n}\r\n\r\nexport function Select({\r\n options,\r\n value,\r\n defaultValue,\r\n onChange,\r\n placeholder = 'Select...',\r\n disabled = false,\r\n name,\r\n id,\r\n className = '',\r\n}: SelectProps) {\r\n // Controlled vs uncontrolled\r\n const isControlled = value !== undefined;\r\n const [internalValue, setInternalValue] = useState<string | undefined>(\r\n defaultValue\r\n );\r\n const selectedValue = isControlled ? value : internalValue;\r\n\r\n const selectedOption = options.find((o) => o.value === selectedValue) ?? null;\r\n\r\n const [open, setOpen] = useState(false);\r\n const [activeIndex, setActiveIndex] = useState<number>(() =>\r\n options.findIndex((o) => !o.disabled)\r\n );\r\n\r\n // Typeahead buffer\r\n const typeaheadRef = useRef({ buffer: '', lastTime: 0 });\r\n\r\n // Refs\r\n const triggerRef = useRef<HTMLButtonElement | null>(null);\r\n const listRef = useRef<HTMLDivElement | null>(null);\r\n\r\n // Unique ids\r\n const reactId = React.useId();\r\n const baseId = id ?? reactId;\r\n const listboxId = `${baseId}-listbox`;\r\n const labelId = `${baseId}-label`;\r\n\r\n // Open/close helpers\r\n const openList = useCallback(() => {\r\n if (disabled) return;\r\n setOpen(true);\r\n }, [disabled]);\r\n\r\n const closeList = useCallback(() => {\r\n setOpen(false);\r\n // restore focus to trigger\r\n restoreFocus(triggerRef.current);\r\n }, []);\r\n\r\n // Toggle\r\n const toggleList = useCallback(() => {\r\n if (disabled) return;\r\n setOpen((s) => !s);\r\n }, [disabled]);\r\n\r\n // Click outside to close\r\n useEffect(() => {\r\n if (!open) return;\r\n return onClickOutside(listRef, () => setOpen(false));\r\n }, [open]);\r\n\r\n // Ensure that when opening, activeIndex is valid and focus moves to listbox\r\n useEffect(() => {\r\n if (!open) return;\r\n // set active to selected or first enabled\r\n const selIndex = options.findIndex(\r\n (o) => o.value === selectedValue && !o.disabled\r\n );\r\n const idx =\r\n selIndex >= 0 ? selIndex : options.findIndex((o) => !o.disabled);\r\n setActiveIndex(idx >= 0 ? idx : -1);\r\n\r\n // focus the list container so keyboard events are captured\r\n setTimeout(() => {\r\n listRef.current?.focus();\r\n }, 0);\r\n }, [open, options, selectedValue]);\r\n\r\n // Selection handler\r\n const selectIndex = useCallback(\r\n (i: number) => {\r\n if (i < 0 || i >= options.length) return;\r\n const opt = options[i];\r\n if (opt.disabled) return;\r\n if (!isControlled) setInternalValue(opt.value);\r\n onChange?.(opt.value);\r\n setOpen(false);\r\n // restore focus\r\n triggerRef.current?.focus();\r\n },\r\n [isControlled, options, onChange]\r\n );\r\n\r\n // Keyboard handling when trigger has focus\r\n const onTriggerKeyDown = (e: KeyboardEvent<HTMLButtonElement>) => {\r\n if (disabled) return;\r\n if (['ArrowDown', 'ArrowUp', ' ', 'Enter'].includes(e.key)) {\r\n e.preventDefault();\r\n openList();\r\n }\r\n };\r\n\r\n // Keyboard handling when listbox has focus\r\n const onListKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\r\n const key = e.key;\r\n if (key === 'ArrowDown') {\r\n e.preventDefault();\r\n const next = findNextEnabled(options, activeIndex, 1);\r\n if (next >= 0) setActiveIndex(next);\r\n } else if (key === 'ArrowUp') {\r\n e.preventDefault();\r\n const prev = findNextEnabled(options, activeIndex, -1);\r\n if (prev >= 0) setActiveIndex(prev);\r\n } else if (key === 'Home') {\r\n e.preventDefault();\r\n const first = options.findIndex((o) => !o.disabled);\r\n if (first >= 0) setActiveIndex(first);\r\n } else if (key === 'End') {\r\n e.preventDefault();\r\n const last =\r\n options.length -\r\n 1 -\r\n [...options].reverse().findIndex((o) => !o.disabled);\r\n if (last >= 0) setActiveIndex(last);\r\n } else if (key === 'Enter' || key === ' ') {\r\n e.preventDefault();\r\n if (activeIndex >= 0) selectIndex(activeIndex);\r\n } else if (key === 'Escape') {\r\n e.preventDefault();\r\n closeList();\r\n } else if (key.length === 1 && key.match(/\\S/)) {\r\n // typeahead: accumulate buffer of characters\r\n const now = Date.now();\r\n if (now - typeaheadRef.current.lastTime > 700) {\r\n typeaheadRef.current.buffer = '';\r\n }\r\n typeaheadRef.current.buffer += key.toLowerCase();\r\n typeaheadRef.current.lastTime = now;\r\n\r\n const buf = typeaheadRef.current.buffer;\r\n const start = activeIndex >= 0 ? activeIndex + 1 : 0;\r\n const len = options.length;\r\n // search forward from next item, wrapping\r\n for (let i = 0; i < len; i++) {\r\n const idx = (start + i) % len;\r\n const lab = String(options[idx].label).toLowerCase();\r\n if (!options[idx].disabled && lab.startsWith(buf)) {\r\n setActiveIndex(idx);\r\n break;\r\n }\r\n }\r\n }\r\n };\r\n\r\n // Click on option\r\n const onOptionClick = (i: number) => {\r\n selectIndex(i);\r\n };\r\n\r\n // compute listbox position based on trigger\r\n const [pos, setPos] = useState<{ top: number; left: number } | null>(null);\r\n useEffect(() => {\r\n if (!open || !triggerRef.current) {\r\n setPos(null);\r\n return;\r\n }\r\n const rect = triggerRef.current.getBoundingClientRect();\r\n const top = rect.bottom + 6;\r\n const left = rect.left;\r\n setPos({ top, left });\r\n }, [open]);\r\n\r\n // render\r\n return (\r\n <div className={`ui-select ${className}`}>\r\n {/* Hidden input for form compatibility */}\r\n {name && <input type=\"hidden\" name={name} value={selectedValue ?? ''} />}\r\n\r\n <button\r\n ref={triggerRef}\r\n id={labelId}\r\n type=\"button\"\r\n className=\"ui-select-trigger\"\r\n aria-haspopup=\"listbox\"\r\n aria-expanded={open}\r\n aria-controls={open ? listboxId : undefined}\r\n aria-disabled={disabled || undefined}\r\n onClick={() => toggleList()}\r\n onKeyDown={onTriggerKeyDown}\r\n disabled={disabled}\r\n >\r\n <span>\r\n {selectedOption ? (\r\n <span>{selectedOption.label}</span>\r\n ) : (\r\n <span className=\"ui-select-placeholder\">{placeholder}</span>\r\n )}\r\n </span>\r\n <span className=\"ui-select-chevron\" aria-hidden>\r\n ▾\r\n </span>\r\n </button>\r\n\r\n {open && pos && (\r\n <Portal>\r\n <div\r\n id={listboxId}\r\n ref={listRef}\r\n className=\"ui-select-listbox\"\r\n role=\"listbox\"\r\n aria-labelledby={labelId}\r\n tabIndex={0}\r\n style={{\r\n top: pos.top,\r\n left: pos.left,\r\n }}\r\n onKeyDown={onListKeyDown}\r\n >\r\n {options.map((opt, i) => {\r\n const isSelected = selectedValue === opt.value;\r\n const isActive = activeIndex === i;\r\n return (\r\n <div\r\n key={opt.value}\r\n id={`${listboxId}-option-${i}`}\r\n role=\"option\"\r\n aria-selected={isSelected}\r\n aria-disabled={opt.disabled || undefined}\r\n className=\"ui-select-option\"\r\n tabIndex={-1}\r\n onMouseDown={(e) => e.preventDefault()} /* prevent blur */\r\n onClick={() => !opt.disabled && onOptionClick(i)}\r\n // Visual focus when active (not moving DOM focus)\r\n style={{\r\n outline: isActive\r\n ? '2px solid var(--color-primary)'\r\n : undefined,\r\n }}\r\n >\r\n {opt.label}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </Portal>\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"names":["findNextEnabled","options","start","direction","len","i","step","Select","value","defaultValue","onChange","placeholder","disabled","name","id","className","isControlled","internalValue","setInternalValue","useState","selectedValue","selectedOption","o","open","setOpen","activeIndex","setActiveIndex","typeaheadRef","useRef","triggerRef","listRef","reactId","React","baseId","listboxId","labelId","openList","useCallback","closeList","restoreFocus","toggleList","s","useEffect","onClickOutside","selIndex","idx","selectIndex","opt","onTriggerKeyDown","onListKeyDown","key","next","prev","first","last","now","buf","lab","onOptionClick","pos","setPos","rect","top","left","jsxs","jsx","Portal","isSelected","isActive","e"],"mappings":"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"}
1
+ {"version":3,"file":"Select.cjs","sources":["../../../src/components/select/Select.tsx"],"sourcesContent":["\"use client\";\n\nimport React, {\n useState,\n useRef,\n useEffect,\n useCallback,\n useLayoutEffect,\n KeyboardEvent,\n forwardRef,\n} from 'react';\nimport { Portal, onClickOutside, restoreFocus, cn } from '../../utils';\nimport './Select.css';\n\n/* ============================================================\n * Types\n * ============================================================ */\n\nexport type SelectOption = {\n value: string;\n label: React.ReactNode;\n disabled?: boolean;\n};\n\nexport interface SelectProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'value' | 'defaultValue' | 'onChange'> {\n /** Array of available options */\n options: SelectOption[];\n /** Controlled state value */\n value?: string; \n /** Uncontrolled initial value */\n defaultValue?: string; \n /** Callback fired when an option is selected */\n onChange?: (value: string) => void;\n /** Text displayed when no option is selected */\n placeholder?: string;\n /** Name attribute applied to the hidden input for native form submission */\n name?: string; \n /** Applies error styling to the trigger button */\n error?: boolean; \n}\n\n/* Helper: find next enabled index given direction */\nfunction findNextEnabled(options: SelectOption[], start: number, direction: 1 | -1) {\n const len = options.length;\n let i = start;\n for (let step = 0; step < len; step++) {\n i = (i + direction + len) % len;\n if (!options[i].disabled) return i;\n }\n return -1;\n}\n\n/* ============================================================\n * Component\n * ============================================================ */\n\n/**\n * Select Component\n * * A highly accessible dropdown select menu.\n * * Automatically manages focus, keyboard typeahead navigation, and viewport collision detection.\n */\nexport const Select = forwardRef<HTMLButtonElement, SelectProps>(({\n options,\n value,\n defaultValue,\n onChange,\n placeholder = 'Select...',\n disabled = false,\n error = false,\n name,\n id,\n className,\n ...props\n}, ref) => {\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState<string | undefined>(defaultValue);\n const selectedValue = isControlled ? value : internalValue;\n const selectedOption = options.find((o) => o.value === selectedValue) ?? null;\n\n const [open, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState<number>(() => options.findIndex((o) => !o.disabled));\n\n // Used for WAI-ARIA keyboard typeahead navigation\n const typeaheadRef = useRef({ buffer: '', lastTime: 0 });\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n const listRef = useRef<HTMLDivElement | null>(null);\n const activeOptionRef = useRef<HTMLDivElement | null>(null);\n\n const reactId = React.useId();\n const baseId = id ?? reactId;\n const listboxId = `${baseId}-listbox`;\n const labelId = `${baseId}-label`;\n\n /* ----------------------------------------------------\n Ref Merging\n ---------------------------------------------------- */\n const setTriggerRef = useCallback((node: HTMLButtonElement | null) => {\n triggerRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n }, [ref]);\n\n /* ----------------------------------------------------\n Smart Position & Width Sync\n ---------------------------------------------------- */\n const [coords, setCoords] = useState({ top: -9999, left: -9999, width: 0 });\n\n const updatePosition = useCallback(() => {\n if (!triggerRef.current || !listRef.current) return;\n\n const triggerRect = triggerRef.current.getBoundingClientRect();\n const listRect = listRef.current.getBoundingClientRect();\n const scrollY = window.scrollY;\n const scrollX = window.scrollX;\n\n let top = triggerRect.bottom + scrollY + 4;\n const left = triggerRect.left + scrollX;\n const width = triggerRect.width; // Sync Portal width to trigger width\n\n // Viewport Bottom Collision\n const padding = 16;\n if (triggerRect.bottom + listRect.height + 4 > document.documentElement.clientHeight - padding) {\n top = triggerRect.top + scrollY - listRect.height - 4; // Flip above\n if (top < padding + scrollY) top = padding + scrollY; // Hard top clamp\n }\n\n setCoords({ top, left, width });\n }, []);\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 /* ----------------------------------------------------\n Focus & Scroll Management\n ---------------------------------------------------- */\n const closeList = useCallback(() => {\n setOpen(false);\n restoreFocus(triggerRef.current);\n }, []);\n\n useEffect(() => {\n if (!open) return;\n const cleanup = onClickOutside([listRef, triggerRef], () => setOpen(false));\n return cleanup;\n }, [open]);\n\n useEffect(() => {\n if (!open) return;\n // Set active index to the currently selected item, or the first available option\n const selIndex = options.findIndex((o) => o.value === selectedValue && !o.disabled);\n const idx = selIndex >= 0 ? selIndex : options.findIndex((o) => !o.disabled);\n setActiveIndex(idx >= 0 ? idx : -1);\n\n // Defer focus to ensure Portal is rendered\n const timeoutId = setTimeout(() => listRef.current?.focus(), 10);\n return () => clearTimeout(timeoutId);\n }, [open, options, selectedValue]);\n\n // Auto-scroll to active item when navigating via keyboard\n useEffect(() => {\n if (open && activeOptionRef.current) {\n activeOptionRef.current.scrollIntoView({ block: 'nearest' });\n }\n }, [activeIndex, open]);\n\n /* ----------------------------------------------------\n Event Handlers\n ---------------------------------------------------- */\n const selectIndex = useCallback((i: number) => {\n if (i < 0 || i >= options.length) return;\n const opt = options[i];\n if (opt.disabled) return;\n if (!isControlled) setInternalValue(opt.value);\n onChange?.(opt.value);\n setOpen(false);\n triggerRef.current?.focus();\n }, [isControlled, options, onChange]);\n\n const onTriggerKeyDown = (e: KeyboardEvent<HTMLButtonElement>) => {\n if (disabled) return;\n if (['ArrowDown', 'ArrowUp', ' ', 'Enter'].includes(e.key)) {\n e.preventDefault();\n setOpen(true);\n }\n };\n\n const onListKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n const key = e.key;\n if (key === 'ArrowDown') {\n e.preventDefault();\n const next = findNextEnabled(options, activeIndex, 1);\n if (next >= 0) setActiveIndex(next);\n } else if (key === 'ArrowUp') {\n e.preventDefault();\n const prev = findNextEnabled(options, activeIndex, -1);\n if (prev >= 0) setActiveIndex(prev);\n } else if (key === 'Home') {\n e.preventDefault();\n const first = options.findIndex((o) => !o.disabled);\n if (first >= 0) setActiveIndex(first);\n } else if (key === 'End') {\n e.preventDefault();\n const last = options.length - 1 - [...options].reverse().findIndex((o) => !o.disabled);\n if (last >= 0) setActiveIndex(last);\n } else if (key === 'Enter' || key === ' ') {\n e.preventDefault();\n if (activeIndex >= 0) selectIndex(activeIndex);\n } else if (key === 'Escape') {\n e.preventDefault();\n closeList();\n } else if (key.length === 1 && key.match(/\\S/)) {\n // Typeahead logic\n const now = Date.now();\n if (now - typeaheadRef.current.lastTime > 700) typeaheadRef.current.buffer = '';\n typeaheadRef.current.buffer += key.toLowerCase();\n typeaheadRef.current.lastTime = now;\n\n const buf = typeaheadRef.current.buffer;\n const start = activeIndex >= 0 ? activeIndex + 1 : 0;\n const len = options.length;\n for (let i = 0; i < len; i++) {\n const idx = (start + i) % len;\n const lab = String(options[idx].label).toLowerCase();\n if (!options[idx].disabled && lab.startsWith(buf)) {\n setActiveIndex(idx);\n break;\n }\n }\n }\n };\n\n /* ----------------------------------------------------\n Render\n ---------------------------------------------------- */\n return (\n <div className={cn(\"nui-select-root\", className)}>\n {/* Hidden input for native form submission */}\n {name && <input type=\"hidden\" name={name} value={selectedValue ?? ''} />}\n\n <button\n ref={setTriggerRef}\n id={labelId}\n type=\"button\"\n className={cn(\"nui-select-trigger\", error && \"error\")}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={open ? listboxId : undefined}\n aria-disabled={disabled || undefined}\n onClick={() => !disabled && setOpen((s) => !s)}\n onKeyDown={onTriggerKeyDown}\n disabled={disabled}\n {...props}\n >\n <span className=\"nui-select-value\">\n {selectedOption ? (\n selectedOption.label\n ) : (\n <span className=\"nui-select-placeholder\">{placeholder}</span>\n )}\n </span>\n <svg className=\"nui-select-chevron\" 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=\"6 9 12 15 18 9\"></polyline>\n </svg>\n </button>\n\n {open && (\n <Portal>\n <div\n id={listboxId}\n ref={listRef}\n className=\"nui-select-listbox\"\n role=\"listbox\"\n aria-labelledby={labelId}\n tabIndex={0}\n style={{ top: coords.top, left: coords.left, width: coords.width }}\n onKeyDown={onListKeyDown}\n >\n {options.map((opt, i) => {\n const isSelected = selectedValue === opt.value;\n const isActive = activeIndex === i;\n return (\n <div\n key={opt.value}\n ref={isActive ? activeOptionRef : null}\n id={`${listboxId}-option-${i}`}\n role=\"option\"\n aria-selected={isSelected}\n aria-disabled={opt.disabled || undefined}\n className={cn(\n \"nui-select-option\",\n isActive && \"active\",\n isSelected && \"selected\",\n opt.disabled && \"disabled\"\n )}\n tabIndex={-1}\n onMouseDown={(e) => e.preventDefault()} \n onClick={() => !opt.disabled && selectIndex(i)}\n onMouseEnter={() => !opt.disabled && setActiveIndex(i)}\n >\n <span className=\"nui-select-option-label\">{opt.label}</span>\n {isSelected && (\n <svg className=\"nui-select-check\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <polyline points=\"20 6 9 17 4 12\"></polyline>\n </svg>\n )}\n </div>\n );\n })}\n </div>\n </Portal>\n )}\n </div>\n );\n});\nSelect.displayName = 'Select';"],"names":["findNextEnabled","options","start","direction","len","i","step","Select","forwardRef","value","defaultValue","onChange","placeholder","disabled","error","name","id","className","props","ref","isControlled","internalValue","setInternalValue","useState","selectedValue","selectedOption","o","open","setOpen","activeIndex","setActiveIndex","typeaheadRef","useRef","triggerRef","listRef","activeOptionRef","reactId","React","baseId","listboxId","labelId","setTriggerRef","useCallback","node","coords","setCoords","updatePosition","triggerRect","listRect","scrollY","scrollX","top","left","width","padding","useLayoutEffect","closeList","restoreFocus","useEffect","onClickOutside","selIndex","idx","timeoutId","selectIndex","opt","onTriggerKeyDown","onListKeyDown","key","next","prev","first","last","now","buf","lab","cn","jsxs","s","jsx","Portal","isSelected","isActive","e"],"mappings":"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"}
@@ -1,156 +1,156 @@
1
- import { jsxs as V, jsx as i } from "react/jsx-runtime";
2
- import X, { useState as x, useRef as A, useCallback as h, useEffect as E } from "react";
1
+ import { jsxs as A, jsx as i } from "react/jsx-runtime";
2
+ import ee, { forwardRef as te, useState as D, useRef as E, useCallback as L, useLayoutEffect as ne, useEffect as j } from "react";
3
3
  /* empty css */
4
- import { restoreFocus as Y } from "../../utils/restorefocus/restoreFocus.js";
5
- import { onClickOutside as Z } from "../../utils/onclickoutside/onClickOutside.js";
6
- import { Portal as _ } from "../../utils/portal/portal.js";
7
- function j(l, m, I) {
8
- const o = l.length;
9
- let f = m;
10
- for (let r = 0; r < o; r++)
11
- if (f = (f + I + o) % o, !l[f].disabled) return f;
4
+ import { restoreFocus as re } from "../../utils/restorefocus/restoreFocus.js";
5
+ import { onClickOutside as le } from "../../utils/onclickoutside/onClickOutside.js";
6
+ import { cn as B } from "../../utils/cn/cn.js";
7
+ import { Portal as se } from "../../utils/portal/portal.js";
8
+ function z(r, k, R) {
9
+ const f = r.length;
10
+ let b = k;
11
+ for (let a = 0; a < f; a++)
12
+ if (b = (b + R + f) % f, !r[b].disabled) return b;
12
13
  return -1;
13
14
  }
14
- function ie({
15
- options: l,
16
- value: m,
17
- defaultValue: I,
18
- onChange: o,
19
- placeholder: f = "Select...",
20
- disabled: r = !1,
21
- name: L,
22
- id: P,
23
- className: U = ""
24
- }) {
25
- const D = m !== void 0, [B, F] = x(
26
- I
27
- ), d = D ? m : B, R = l.find((e) => e.value === d) ?? null, [s, b] = x(!1), [c, u] = x(
28
- () => l.findIndex((e) => !e.disabled)
29
- ), v = A({ buffer: "", lastTime: 0 }), p = A(null), g = A(null), H = X.useId(), S = P ?? H, w = `${S}-listbox`, T = `${S}-label`, M = h(() => {
30
- r || b(!0);
31
- }, [r]), W = h(() => {
32
- b(!1), Y(p.current);
33
- }, []), q = h(() => {
34
- r || b((e) => !e);
35
- }, [r]);
36
- E(() => {
15
+ const ie = te(({
16
+ options: r,
17
+ value: k,
18
+ defaultValue: R,
19
+ onChange: f,
20
+ placeholder: b = "Select...",
21
+ disabled: a = !1,
22
+ error: H = !1,
23
+ name: K,
24
+ id: M,
25
+ className: P,
26
+ ...U
27
+ }, m) => {
28
+ const C = k !== void 0, [X, Y] = D(R), w = C ? k : X, O = r.find((e) => e.value === w) ?? null, [s, p] = D(!1), [o, d] = D(() => r.findIndex((e) => !e.disabled)), g = E({ buffer: "", lastTime: 0 }), h = E(null), x = E(null), N = E(null), F = ee.useId(), V = M ?? F, S = `${V}-listbox`, $ = `${V}-label`, q = L((e) => {
29
+ h.current = e, typeof m == "function" ? m(e) : m && (m.current = e);
30
+ }, [m]), [T, G] = D({ top: -9999, left: -9999, width: 0 }), v = L(() => {
31
+ if (!h.current || !x.current) return;
32
+ const e = h.current.getBoundingClientRect(), t = x.current.getBoundingClientRect(), n = window.scrollY, l = window.scrollX;
33
+ let c = e.bottom + n + 4;
34
+ const y = e.left + l, I = e.width, u = 16;
35
+ e.bottom + t.height + 4 > document.documentElement.clientHeight - u && (c = e.top + n - t.height - 4, c < u + n && (c = u + n)), G({ top: c, left: y, width: I });
36
+ }, []);
37
+ ne(() => {
37
38
  if (s)
38
- return Z(g, () => b(!1));
39
- }, [s]), E(() => {
39
+ return v(), window.addEventListener("resize", v), window.addEventListener("scroll", v, !0), () => {
40
+ window.removeEventListener("resize", v), window.removeEventListener("scroll", v, !0);
41
+ };
42
+ }, [s, v]);
43
+ const J = L(() => {
44
+ p(!1), re(h.current);
45
+ }, []);
46
+ j(() => s ? le([x, h], () => p(!1)) : void 0, [s]), j(() => {
40
47
  if (!s) return;
41
- const e = l.findIndex(
42
- (n) => n.value === d && !n.disabled
43
- ), t = e >= 0 ? e : l.findIndex((n) => !n.disabled);
44
- u(t >= 0 ? t : -1), setTimeout(() => {
45
- g.current?.focus();
46
- }, 0);
47
- }, [s, l, d]);
48
- const $ = h(
49
- (e) => {
50
- if (e < 0 || e >= l.length) return;
51
- const t = l[e];
52
- t.disabled || (D || F(t.value), o?.(t.value), b(!1), p.current?.focus());
53
- },
54
- [D, l, o]
55
- ), z = (e) => {
56
- r || ["ArrowDown", "ArrowUp", " ", "Enter"].includes(e.key) && (e.preventDefault(), M());
57
- }, G = (e) => {
48
+ const e = r.findIndex((l) => l.value === w && !l.disabled), t = e >= 0 ? e : r.findIndex((l) => !l.disabled);
49
+ d(t >= 0 ? t : -1);
50
+ const n = setTimeout(() => x.current?.focus(), 10);
51
+ return () => clearTimeout(n);
52
+ }, [s, r, w]), j(() => {
53
+ s && N.current && N.current.scrollIntoView({ block: "nearest" });
54
+ }, [o, s]);
55
+ const W = L((e) => {
56
+ if (e < 0 || e >= r.length) return;
57
+ const t = r[e];
58
+ t.disabled || (C || Y(t.value), f?.(t.value), p(!1), h.current?.focus());
59
+ }, [C, r, f]), Q = (e) => {
60
+ a || ["ArrowDown", "ArrowUp", " ", "Enter"].includes(e.key) && (e.preventDefault(), p(!0));
61
+ }, Z = (e) => {
58
62
  const t = e.key;
59
63
  if (t === "ArrowDown") {
60
64
  e.preventDefault();
61
- const n = j(l, c, 1);
62
- n >= 0 && u(n);
65
+ const n = z(r, o, 1);
66
+ n >= 0 && d(n);
63
67
  } else if (t === "ArrowUp") {
64
68
  e.preventDefault();
65
- const n = j(l, c, -1);
66
- n >= 0 && u(n);
69
+ const n = z(r, o, -1);
70
+ n >= 0 && d(n);
67
71
  } else if (t === "Home") {
68
72
  e.preventDefault();
69
- const n = l.findIndex((a) => !a.disabled);
70
- n >= 0 && u(n);
73
+ const n = r.findIndex((l) => !l.disabled);
74
+ n >= 0 && d(n);
71
75
  } else if (t === "End") {
72
76
  e.preventDefault();
73
- const n = l.length - 1 - [...l].reverse().findIndex((a) => !a.disabled);
74
- n >= 0 && u(n);
77
+ const n = r.length - 1 - [...r].reverse().findIndex((l) => !l.disabled);
78
+ n >= 0 && d(n);
75
79
  } else if (t === "Enter" || t === " ")
76
- e.preventDefault(), c >= 0 && $(c);
80
+ e.preventDefault(), o >= 0 && W(o);
77
81
  else if (t === "Escape")
78
- e.preventDefault(), W();
82
+ e.preventDefault(), J();
79
83
  else if (t.length === 1 && t.match(/\S/)) {
80
84
  const n = Date.now();
81
- n - v.current.lastTime > 700 && (v.current.buffer = ""), v.current.buffer += t.toLowerCase(), v.current.lastTime = n;
82
- const a = v.current.buffer, k = c >= 0 ? c + 1 : 0, O = l.length;
83
- for (let C = 0; C < O; C++) {
84
- const N = (k + C) % O, Q = String(l[N].label).toLowerCase();
85
- if (!l[N].disabled && Q.startsWith(a)) {
86
- u(N);
85
+ n - g.current.lastTime > 700 && (g.current.buffer = ""), g.current.buffer += t.toLowerCase(), g.current.lastTime = n;
86
+ const l = g.current.buffer, c = o >= 0 ? o + 1 : 0, y = r.length;
87
+ for (let I = 0; I < y; I++) {
88
+ const u = (c + I) % y, _ = String(r[u].label).toLowerCase();
89
+ if (!r[u].disabled && _.startsWith(l)) {
90
+ d(u);
87
91
  break;
88
92
  }
89
93
  }
90
94
  }
91
- }, J = (e) => {
92
- $(e);
93
- }, [y, K] = x(null);
94
- return E(() => {
95
- if (!s || !p.current) {
96
- K(null);
97
- return;
98
- }
99
- const e = p.current.getBoundingClientRect(), t = e.bottom + 6, n = e.left;
100
- K({ top: t, left: n });
101
- }, [s]), /* @__PURE__ */ V("div", { className: `ui-select ${U}`, children: [
102
- L && /* @__PURE__ */ i("input", { type: "hidden", name: L, value: d ?? "" }),
103
- /* @__PURE__ */ V(
95
+ };
96
+ return /* @__PURE__ */ A("div", { className: B("nui-select-root", P), children: [
97
+ K && /* @__PURE__ */ i("input", { type: "hidden", name: K, value: w ?? "" }),
98
+ /* @__PURE__ */ A(
104
99
  "button",
105
100
  {
106
- ref: p,
107
- id: T,
101
+ ref: q,
102
+ id: $,
108
103
  type: "button",
109
- className: "ui-select-trigger",
104
+ className: B("nui-select-trigger", H && "error"),
110
105
  "aria-haspopup": "listbox",
111
106
  "aria-expanded": s,
112
- "aria-controls": s ? w : void 0,
113
- "aria-disabled": r || void 0,
114
- onClick: () => q(),
115
- onKeyDown: z,
116
- disabled: r,
107
+ "aria-controls": s ? S : void 0,
108
+ "aria-disabled": a || void 0,
109
+ onClick: () => !a && p((e) => !e),
110
+ onKeyDown: Q,
111
+ disabled: a,
112
+ ...U,
117
113
  children: [
118
- /* @__PURE__ */ i("span", { children: R ? /* @__PURE__ */ i("span", { children: R.label }) : /* @__PURE__ */ i("span", { className: "ui-select-placeholder", children: f }) }),
119
- /* @__PURE__ */ i("span", { className: "ui-select-chevron", "aria-hidden": !0, children: "" })
114
+ /* @__PURE__ */ i("span", { className: "nui-select-value", children: O ? O.label : /* @__PURE__ */ i("span", { className: "nui-select-placeholder", children: b }) }),
115
+ /* @__PURE__ */ i("svg", { className: "nui-select-chevron", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ i("polyline", { points: "6 9 12 15 18 9" }) })
120
116
  ]
121
117
  }
122
118
  ),
123
- s && y && /* @__PURE__ */ i(_, { children: /* @__PURE__ */ i(
119
+ s && /* @__PURE__ */ i(se, { children: /* @__PURE__ */ i(
124
120
  "div",
125
121
  {
126
- id: w,
127
- ref: g,
128
- className: "ui-select-listbox",
122
+ id: S,
123
+ ref: x,
124
+ className: "nui-select-listbox",
129
125
  role: "listbox",
130
- "aria-labelledby": T,
126
+ "aria-labelledby": $,
131
127
  tabIndex: 0,
132
- style: {
133
- top: y.top,
134
- left: y.left
135
- },
136
- onKeyDown: G,
137
- children: l.map((e, t) => {
138
- const n = d === e.value, a = c === t;
139
- return /* @__PURE__ */ i(
128
+ style: { top: T.top, left: T.left, width: T.width },
129
+ onKeyDown: Z,
130
+ children: r.map((e, t) => {
131
+ const n = w === e.value, l = o === t;
132
+ return /* @__PURE__ */ A(
140
133
  "div",
141
134
  {
142
- id: `${w}-option-${t}`,
135
+ ref: l ? N : null,
136
+ id: `${S}-option-${t}`,
143
137
  role: "option",
144
138
  "aria-selected": n,
145
139
  "aria-disabled": e.disabled || void 0,
146
- className: "ui-select-option",
140
+ className: B(
141
+ "nui-select-option",
142
+ l && "active",
143
+ n && "selected",
144
+ e.disabled && "disabled"
145
+ ),
147
146
  tabIndex: -1,
148
- onMouseDown: (k) => k.preventDefault(),
149
- onClick: () => !e.disabled && J(t),
150
- style: {
151
- outline: a ? "2px solid var(--color-primary)" : void 0
152
- },
153
- children: e.label
147
+ onMouseDown: (c) => c.preventDefault(),
148
+ onClick: () => !e.disabled && W(t),
149
+ onMouseEnter: () => !e.disabled && d(t),
150
+ children: [
151
+ /* @__PURE__ */ i("span", { className: "nui-select-option-label", children: e.label }),
152
+ n && /* @__PURE__ */ i("svg", { className: "nui-select-check", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ i("polyline", { points: "20 6 9 17 4 12" }) })
153
+ ]
154
154
  },
155
155
  e.value
156
156
  );
@@ -158,7 +158,8 @@ function ie({
158
158
  }
159
159
  ) })
160
160
  ] });
161
- }
161
+ });
162
+ ie.displayName = "Select";
162
163
  export {
163
164
  ie as Select
164
165
  };