@nofinite/nui 1.1.2 → 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":"Select.js","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.js","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,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const r=require("react/jsx-runtime");;/* empty css */function c(e){if(e!==void 0)return typeof e=="number"?`${e}px`:e}function t({size:e="md",width:n,animated:a=!0,circle:o=!1,ariaHidden:i=!0,className:u="",style:d}){const l=["ui-skeleton",`ui-skeleton--${e}`,a&&"ui-skeleton--animated",o&&"ui-skeleton--circle",u].filter(Boolean).join(" ");return r.jsx("span",{className:l,style:{width:c(n),display:n?"block":void 0,...d},"aria-hidden":i,role:"presentation"})}function m({width:e="100%",size:n="md"}){return r.jsx(t,{width:e,size:n})}function s({lines:e=3,size:n="md"}){const a=Array.from({length:e});return r.jsx("div",{"aria-hidden":"true",children:a.map((o,i)=>r.jsx("div",{style:{marginBlockEnd:"8px"},children:r.jsx(t,{width:i===e-1?"75%":"100%",size:n})},i))})}function f({size:e=40}){return r.jsx(t,{circle:!0,width:e,animated:!0})}function x({width:e=100,height:n=36}){return r.jsx(t,{width:e,size:"md",animated:!0,style:{height:n,borderRadius:"var(--radius-md)"}})}function h(){return r.jsxs("div",{"aria-hidden":"true",children:[r.jsx(t,{width:"60%",size:"lg",style:{marginBottom:12}}),r.jsx(s,{lines:3}),r.jsx(t,{width:"40%",size:"md",style:{marginTop:16}})]})}t.Text=m;t.Paragraph=s;t.Avatar=f;t.Button=x;t.Card=h;exports.Skeleton=t;exports.default=t;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("react/jsx-runtime"),h=require("react");;/* empty css */const o=require("../../utils/cn/cn.cjs");function l(e){if(e!==void 0)return typeof e=="number"?`${e}px`:e}const i=h.forwardRef(({size:e="md",width:t,height:r,animated:s=!0,circle:d=!1,ariaHidden:a=!0,className:x,style:p,...f},m)=>n.jsx("span",{ref:m,"aria-hidden":a,role:"presentation",className:o.cn("nui-skeleton",`nui-skeleton--${e}`,s&&"nui-skeleton--animated",d&&"nui-skeleton--circle",x),style:{width:l(t),height:l(r),...p},...f}));i.displayName="Skeleton";function j({width:e="100%",size:t="md",className:r,...s}){return n.jsx(i,{width:e,size:t,className:r,...s})}function u({lines:e=3,size:t="md",className:r,...s}){return n.jsx("div",{"aria-hidden":"true",className:o.cn("nui-skeleton-paragraph",r),style:{display:"flex",flexDirection:"column",gap:"8px"},...s,children:Array.from({length:e}).map((d,a)=>n.jsx(i,{width:a===e-1?"75%":"100%",size:t},a))})}function c({size:e=40,className:t,...r}){return n.jsx(i,{circle:!0,width:e,className:t,...r})}function y({width:e=100,height:t=40,className:r,...s}){return n.jsx(i,{width:e,height:t,className:o.cn("nui-skeleton-button",r),style:{borderRadius:"6px"},...s})}function g({className:e,style:t,...r}){return n.jsxs("div",{"aria-hidden":"true",className:o.cn("nui-skeleton-card",e),style:{padding:"16px",border:"1px solid var(--nui-border-default, #e2e8f0)",borderRadius:"12px",...t},...r,children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"12px",marginBottom:"16px"},children:[n.jsx(c,{size:48}),n.jsxs("div",{style:{flex:1,display:"flex",flexDirection:"column",gap:"8px"},children:[n.jsx(i,{width:"40%",size:"md"}),n.jsx(i,{width:"20%",size:"sm"})]})]}),n.jsx(u,{lines:3})]})}const k=Object.assign(i,{Text:j,Paragraph:u,Avatar:c,Button:y,Card:g});exports.Skeleton=k;
2
2
  //# sourceMappingURL=Skeleton.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Skeleton.cjs","sources":["../../../src/components/skeleton/Skeleton.tsx"],"sourcesContent":["/**\r\n * Skeleton.tsx\r\n * Lightweight, accessible skeleton (placeholder) component.\r\n *\r\n * Props:\r\n * - size: visual thickness (xs, sm, md, lg, xl)\r\n * - width: number | string (e.g. 200, \"50%\", \"100px\")\r\n * - animated: whether to show shimmer (respects prefers-reduced-motion)\r\n * - circle: renders as a circle (useful for avatars)\r\n * - className: pass-through for custom styling\r\n *\r\n * Accessibility:\r\n * - role=\"status\" with aria-busy on parent usage is recommended by developer.\r\n * - For individual skeletons that should be ignored by assistive tech set aria-hidden=true.\r\n */\r\n/**\r\n * Skeleton.tsx + Helper Components\r\n * --------------------------------\r\n * Adds:\r\n * - Skeleton.Text\r\n * - Skeleton.Paragraph\r\n * - Skeleton.Avatar\r\n * - Skeleton.Button\r\n * - Skeleton.Card\r\n */\r\n\r\nimport React from 'react';\r\nimport './Skeleton.css';\r\n\r\ntype Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\r\n\r\ninterface SkeletonProps {\r\n size?: Size;\r\n width?: number | string;\r\n animated?: boolean;\r\n circle?: boolean;\r\n ariaHidden?: boolean;\r\n className?: string;\r\n style?: React.CSSProperties;\r\n}\r\n\r\nfunction formatWidth(w?: number | string): string | undefined {\r\n if (w === undefined) return undefined;\r\n if (typeof w === 'number') return `${w}px`;\r\n return w;\r\n}\r\n\r\nexport function Skeleton({\r\n size = 'md',\r\n width,\r\n animated = true,\r\n circle = false,\r\n ariaHidden = true,\r\n className = '',\r\n style,\r\n}: SkeletonProps) {\r\n const classes = [\r\n 'ui-skeleton',\r\n `ui-skeleton--${size}`,\r\n animated && 'ui-skeleton--animated',\r\n circle && 'ui-skeleton--circle',\r\n className,\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n return (\r\n <span\r\n className={classes}\r\n style={{\r\n width: formatWidth(width),\r\n display: width ? 'block' : undefined,\r\n ...style,\r\n }}\r\n aria-hidden={ariaHidden}\r\n role=\"presentation\"\r\n />\r\n );\r\n}\r\n\r\n/* -------------------------------------------------------\r\n * Helper Components\r\n * ------------------------------------------------------*/\r\n\r\n/**\r\n * Simple text line.\r\n * Default width: 100%\r\n */\r\nfunction Text({\r\n width = '100%',\r\n size = 'md',\r\n}: {\r\n width?: number | string;\r\n size?: Size;\r\n}) {\r\n return <Skeleton width={width} size={size} />;\r\n}\r\n\r\n/**\r\n * Paragraph: multiple lines of text skeleton\r\n * lines default = 3\r\n */\r\nfunction Paragraph({\r\n lines = 3,\r\n size = 'md',\r\n}: {\r\n lines?: number;\r\n size?: Size;\r\n}) {\r\n const arr = Array.from({ length: lines });\r\n\r\n return (\r\n <div aria-hidden=\"true\">\r\n {arr.map((_, i) => (\r\n <div key={i} style={{ marginBlockEnd: '8px' }}>\r\n <Skeleton width={i === lines - 1 ? '75%' : '100%'} size={size} />\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\n/**\r\n * Avatar placeholder, circle with dynamic size\r\n */\r\nfunction AvatarSkeleton({ size = 40 }: { size?: number }) {\r\n return <Skeleton circle width={size} animated />;\r\n}\r\n\r\n/**\r\n * Button skeleton (pill-like shape)\r\n */\r\nfunction ButtonSkeleton({\r\n width = 100,\r\n height = 36,\r\n}: {\r\n width?: number;\r\n height?: number;\r\n}) {\r\n return (\r\n <Skeleton\r\n width={width}\r\n size=\"md\"\r\n animated\r\n style={{\r\n height,\r\n borderRadius: 'var(--radius-md)',\r\n }}\r\n />\r\n );\r\n}\r\n\r\n/**\r\n * Card Skeleton: header + lines + footer bar\r\n */\r\nfunction CardSkeleton() {\r\n return (\r\n <div aria-hidden=\"true\">\r\n <Skeleton width=\"60%\" size=\"lg\" style={{ marginBottom: 12 }} />\r\n <Paragraph lines={3} />\r\n <Skeleton width=\"40%\" size=\"md\" style={{ marginTop: 16 }} />\r\n </div>\r\n );\r\n}\r\n\r\n/* Attach helpers */\r\nSkeleton.Text = Text;\r\nSkeleton.Paragraph = Paragraph;\r\nSkeleton.Avatar = AvatarSkeleton;\r\nSkeleton.Button = ButtonSkeleton;\r\nSkeleton.Card = CardSkeleton;\r\n\r\nexport default Skeleton;\r\n"],"names":["formatWidth","w","Skeleton","size","width","animated","circle","ariaHidden","className","style","classes","jsx","Text","Paragraph","lines","arr","_","AvatarSkeleton","ButtonSkeleton","height","CardSkeleton","jsxs"],"mappings":"+KAyCA,SAASA,EAAYC,EAAyC,CAC5D,GAAIA,IAAM,OACV,OAAI,OAAOA,GAAM,SAAiB,GAAGA,CAAC,KAC/BA,CACT,CAEO,SAASC,EAAS,CACvB,KAAAC,EAAO,KACP,MAAAC,EACA,SAAAC,EAAW,GACX,OAAAC,EAAS,GACT,WAAAC,EAAa,GACb,UAAAC,EAAY,GACZ,MAAAC,CACF,EAAkB,CAChB,MAAMC,EAAU,CACd,cACA,gBAAgBP,CAAI,GACpBE,GAAY,wBACZC,GAAU,sBACVE,CAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG,EAEX,OACEG,EAAAA,IAAC,OAAA,CACC,UAAWD,EACX,MAAO,CACL,MAAOV,EAAYI,CAAK,EACxB,QAASA,EAAQ,QAAU,OAC3B,GAAGK,CAAA,EAEL,cAAaF,EACb,KAAK,cAAA,CAAA,CAGX,CAUA,SAASK,EAAK,CACZ,MAAAR,EAAQ,OACR,KAAAD,EAAO,IACT,EAGG,CACD,OAAOQ,EAAAA,IAACT,EAAA,CAAS,MAAAE,EAAc,KAAAD,CAAA,CAAY,CAC7C,CAMA,SAASU,EAAU,CACjB,MAAAC,EAAQ,EACR,KAAAX,EAAO,IACT,EAGG,CACD,MAAMY,EAAM,MAAM,KAAK,CAAE,OAAQD,EAAO,EAExC,OACEH,EAAAA,IAAC,MAAA,CAAI,cAAY,OACd,SAAAI,EAAI,IAAI,CAACC,EAAG,IACXL,EAAAA,IAAC,MAAA,CAAY,MAAO,CAAE,eAAgB,KAAA,EACpC,SAAAA,EAAAA,IAACT,EAAA,CAAS,MAAO,IAAMY,EAAQ,EAAI,MAAQ,OAAQ,KAAAX,CAAA,CAAY,CAAA,EADvD,CAEV,CACD,EACH,CAEJ,CAKA,SAASc,EAAe,CAAE,KAAAd,EAAO,IAAyB,CACxD,aAAQD,EAAA,CAAS,OAAM,GAAC,MAAOC,EAAM,SAAQ,GAAC,CAChD,CAKA,SAASe,EAAe,CACtB,MAAAd,EAAQ,IACR,OAAAe,EAAS,EACX,EAGG,CACD,OACER,EAAAA,IAACT,EAAA,CACC,MAAAE,EACA,KAAK,KACL,SAAQ,GACR,MAAO,CACL,OAAAe,EACA,aAAc,kBAAA,CAChB,CAAA,CAGN,CAKA,SAASC,GAAe,CACtB,OACEC,EAAAA,KAAC,MAAA,CAAI,cAAY,OACf,SAAA,CAAAV,EAAAA,IAACT,EAAA,CAAS,MAAM,MAAM,KAAK,KAAK,MAAO,CAAE,aAAc,EAAA,CAAG,CAAG,EAC7DS,EAAAA,IAACE,EAAA,CAAU,MAAO,CAAA,CAAG,EACrBF,EAAAA,IAACT,EAAA,CAAS,MAAM,MAAM,KAAK,KAAK,MAAO,CAAE,UAAW,GAAG,CAAG,CAAA,EAC5D,CAEJ,CAGAA,EAAS,KAAOU,EAChBV,EAAS,UAAYW,EACrBX,EAAS,OAASe,EAClBf,EAAS,OAASgB,EAClBhB,EAAS,KAAOkB"}
1
+ {"version":3,"file":"Skeleton.cjs","sources":["../../../src/components/skeleton/Skeleton.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../../utils';\nimport './Skeleton.css';\n\n/* ============================================================\n * Types\n * ============================================================ */\n\ntype SkeletonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\nexport interface SkeletonProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** The predefined height mapping for the skeleton */\n size?: SkeletonSize;\n /** Explicit width override (supports numbers as px, or strings like '100%') */\n width?: number | string;\n /** Explicit height override (supports numbers as px, or strings like '50px') */\n height?: number | string; \n /** Enables or disables the sweeping shimmer animation. Defaults to true. */\n animated?: boolean;\n /** Forces the skeleton into a perfect circle, ignoring the size height */\n circle?: boolean;\n /** Hides the element from screen readers. Defaults to true (recommended). */\n ariaHidden?: boolean;\n}\n\nfunction formatSize(val?: number | string): string | undefined {\n if (val === undefined) return undefined;\n return typeof val === 'number' ? `${val}px` : val;\n}\n\n/* ============================================================\n * 1. Root Component\n * ============================================================ */\n\n/**\n * Skeleton Component (Root)\n * * A visual placeholder used during asynchronous data fetching.\n * * WAI-ARIA Note: Skeletons are strictly visual and should remain hidden from \n * screen readers (`aria-hidden=\"true\"`) to prevent them from reading out \n * dozens of \"presentation\" or \"empty\" blocks while data loads.\n */\nconst SkeletonRoot = React.forwardRef<HTMLSpanElement, SkeletonProps>(({\n size = 'md',\n width,\n height,\n animated = true,\n circle = false,\n ariaHidden = true,\n className,\n style,\n ...props\n}, ref) => {\n return (\n <span\n ref={ref}\n aria-hidden={ariaHidden}\n role=\"presentation\"\n className={cn(\n 'nui-skeleton',\n `nui-skeleton--${size}`,\n animated && 'nui-skeleton--animated',\n circle && 'nui-skeleton--circle',\n className\n )}\n style={{\n width: formatSize(width),\n height: formatSize(height),\n ...style,\n }}\n {...props}\n />\n );\n});\nSkeletonRoot.displayName = 'Skeleton';\n\n/* ============================================================\n * Helper Components\n * ============================================================ */\n\nexport interface SkeletonTextProps extends React.HTMLAttributes<HTMLSpanElement> {\n width?: number | string;\n size?: SkeletonSize;\n}\n\nfunction Text({ width = '100%', size = 'md', className, ...props }: SkeletonTextProps) {\n return <SkeletonRoot width={width} size={size} className={className} {...props} />;\n}\n\nexport interface SkeletonParagraphProps extends React.HTMLAttributes<HTMLDivElement> {\n lines?: number;\n size?: SkeletonSize;\n}\n\nfunction Paragraph({ lines = 3, size = 'md', className, ...props }: SkeletonParagraphProps) {\n return (\n <div \n aria-hidden=\"true\" \n className={cn(\"nui-skeleton-paragraph\", className)} \n style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}\n {...props}\n >\n {Array.from({ length: lines }).map((_, i) => (\n <SkeletonRoot \n key={i} \n width={i === lines - 1 ? '75%' : '100%'} \n size={size} \n />\n ))}\n </div>\n );\n}\n\nexport interface SkeletonAvatarProps extends React.HTMLAttributes<HTMLSpanElement> {\n size?: number | string;\n}\n\nfunction Avatar({ size = 40, className, ...props }: SkeletonAvatarProps) {\n // width sets the size, the CSS aspect-ratio: 1/1 guarantees it stays a perfect circle!\n return <SkeletonRoot circle width={size} className={className} {...props} />;\n}\n\nexport interface SkeletonButtonProps extends React.HTMLAttributes<HTMLSpanElement> {\n width?: number | string;\n height?: number | string;\n}\n\nfunction Button({ width = 100, height = 40, className, ...props }: SkeletonButtonProps) {\n return (\n <SkeletonRoot\n width={width}\n height={height}\n className={cn(\"nui-skeleton-button\", className)}\n style={{ borderRadius: '6px' }}\n {...props}\n />\n );\n}\n\nfunction Card({ className, style, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div \n aria-hidden=\"true\" \n className={cn(\"nui-skeleton-card\", className)} \n style={{ padding: '16px', border: '1px solid var(--nui-border-default, #e2e8f0)', borderRadius: '12px', ...style }}\n {...props}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: '12px', marginBottom: '16px' }}>\n <Avatar size={48} />\n <div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <SkeletonRoot width=\"40%\" size=\"md\" />\n <SkeletonRoot width=\"20%\" size=\"sm\" />\n </div>\n </div>\n <Paragraph lines={3} />\n </div>\n );\n}\n\n/* ============================================================\n * Export\n * ============================================================ */\n\nexport const Skeleton = Object.assign(SkeletonRoot, {\n Text,\n Paragraph,\n Avatar,\n Button,\n Card,\n});"],"names":["formatSize","val","SkeletonRoot","React","size","width","height","animated","circle","ariaHidden","className","style","props","ref","jsx","cn","Text","Paragraph","lines","_","i","Avatar","Button","Card","jsxs","Skeleton"],"mappings":"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"}
@@ -1,86 +1,109 @@
1
- import { jsx as r, jsxs as m } from "react/jsx-runtime";
1
+ import { jsx as n, jsxs as s } from "react/jsx-runtime";
2
+ import y from "react";
2
3
  /* empty css */
3
- function c(e) {
4
+ import { cn as d } from "../../utils/cn/cn.js";
5
+ function u(e) {
4
6
  if (e !== void 0)
5
7
  return typeof e == "number" ? `${e}px` : e;
6
8
  }
7
- function t({
9
+ const i = y.forwardRef(({
8
10
  size: e = "md",
9
- width: n,
10
- animated: a = !0,
11
- circle: o = !1,
12
- ariaHidden: i = !0,
13
- className: u = "",
14
- style: l
15
- }) {
16
- const s = [
17
- "ui-skeleton",
18
- `ui-skeleton--${e}`,
19
- a && "ui-skeleton--animated",
20
- o && "ui-skeleton--circle",
21
- u
22
- ].filter(Boolean).join(" ");
23
- return /* @__PURE__ */ r(
24
- "span",
11
+ width: t,
12
+ height: r,
13
+ animated: o = !0,
14
+ circle: l = !1,
15
+ ariaHidden: a = !0,
16
+ className: m,
17
+ style: f,
18
+ ...x
19
+ }, h) => /* @__PURE__ */ n(
20
+ "span",
21
+ {
22
+ ref: h,
23
+ "aria-hidden": a,
24
+ role: "presentation",
25
+ className: d(
26
+ "nui-skeleton",
27
+ `nui-skeleton--${e}`,
28
+ o && "nui-skeleton--animated",
29
+ l && "nui-skeleton--circle",
30
+ m
31
+ ),
32
+ style: {
33
+ width: u(t),
34
+ height: u(r),
35
+ ...f
36
+ },
37
+ ...x
38
+ }
39
+ ));
40
+ i.displayName = "Skeleton";
41
+ function g({ width: e = "100%", size: t = "md", className: r, ...o }) {
42
+ return /* @__PURE__ */ n(i, { width: e, size: t, className: r, ...o });
43
+ }
44
+ function c({ lines: e = 3, size: t = "md", className: r, ...o }) {
45
+ return /* @__PURE__ */ n(
46
+ "div",
25
47
  {
26
- className: s,
27
- style: {
28
- width: c(n),
29
- display: n ? "block" : void 0,
30
- ...l
31
- },
32
- "aria-hidden": i,
33
- role: "presentation"
48
+ "aria-hidden": "true",
49
+ className: d("nui-skeleton-paragraph", r),
50
+ style: { display: "flex", flexDirection: "column", gap: "8px" },
51
+ ...o,
52
+ children: Array.from({ length: e }).map((l, a) => /* @__PURE__ */ n(
53
+ i,
54
+ {
55
+ width: a === e - 1 ? "75%" : "100%",
56
+ size: t
57
+ },
58
+ a
59
+ ))
34
60
  }
35
61
  );
36
62
  }
37
- function f({
38
- width: e = "100%",
39
- size: n = "md"
40
- }) {
41
- return /* @__PURE__ */ r(t, { width: e, size: n });
42
- }
43
- function d({
44
- lines: e = 3,
45
- size: n = "md"
46
- }) {
47
- const a = Array.from({ length: e });
48
- return /* @__PURE__ */ r("div", { "aria-hidden": "true", children: a.map((o, i) => /* @__PURE__ */ r("div", { style: { marginBlockEnd: "8px" }, children: /* @__PURE__ */ r(t, { width: i === e - 1 ? "75%" : "100%", size: n }) }, i)) });
49
- }
50
- function h({ size: e = 40 }) {
51
- return /* @__PURE__ */ r(t, { circle: !0, width: e, animated: !0 });
63
+ function p({ size: e = 40, className: t, ...r }) {
64
+ return /* @__PURE__ */ n(i, { circle: !0, width: e, className: t, ...r });
52
65
  }
53
- function p({
54
- width: e = 100,
55
- height: n = 36
56
- }) {
57
- return /* @__PURE__ */ r(
58
- t,
66
+ function k({ width: e = 100, height: t = 40, className: r, ...o }) {
67
+ return /* @__PURE__ */ n(
68
+ i,
59
69
  {
60
70
  width: e,
61
- size: "md",
62
- animated: !0,
63
- style: {
64
- height: n,
65
- borderRadius: "var(--radius-md)"
66
- }
71
+ height: t,
72
+ className: d("nui-skeleton-button", r),
73
+ style: { borderRadius: "6px" },
74
+ ...o
67
75
  }
68
76
  );
69
77
  }
70
- function k() {
71
- return /* @__PURE__ */ m("div", { "aria-hidden": "true", children: [
72
- /* @__PURE__ */ r(t, { width: "60%", size: "lg", style: { marginBottom: 12 } }),
73
- /* @__PURE__ */ r(d, { lines: 3 }),
74
- /* @__PURE__ */ r(t, { width: "40%", size: "md", style: { marginTop: 16 } })
75
- ] });
78
+ function b({ className: e, style: t, ...r }) {
79
+ return /* @__PURE__ */ s(
80
+ "div",
81
+ {
82
+ "aria-hidden": "true",
83
+ className: d("nui-skeleton-card", e),
84
+ style: { padding: "16px", border: "1px solid var(--nui-border-default, #e2e8f0)", borderRadius: "12px", ...t },
85
+ ...r,
86
+ children: [
87
+ /* @__PURE__ */ s("div", { style: { display: "flex", alignItems: "center", gap: "12px", marginBottom: "16px" }, children: [
88
+ /* @__PURE__ */ n(p, { size: 48 }),
89
+ /* @__PURE__ */ s("div", { style: { flex: 1, display: "flex", flexDirection: "column", gap: "8px" }, children: [
90
+ /* @__PURE__ */ n(i, { width: "40%", size: "md" }),
91
+ /* @__PURE__ */ n(i, { width: "20%", size: "sm" })
92
+ ] })
93
+ ] }),
94
+ /* @__PURE__ */ n(c, { lines: 3 })
95
+ ]
96
+ }
97
+ );
76
98
  }
77
- t.Text = f;
78
- t.Paragraph = d;
79
- t.Avatar = h;
80
- t.Button = p;
81
- t.Card = k;
99
+ const z = Object.assign(i, {
100
+ Text: g,
101
+ Paragraph: c,
102
+ Avatar: p,
103
+ Button: k,
104
+ Card: b
105
+ });
82
106
  export {
83
- t as Skeleton,
84
- t as default
107
+ z as Skeleton
85
108
  };
86
109
  //# sourceMappingURL=Skeleton.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Skeleton.js","sources":["../../../src/components/skeleton/Skeleton.tsx"],"sourcesContent":["/**\r\n * Skeleton.tsx\r\n * Lightweight, accessible skeleton (placeholder) component.\r\n *\r\n * Props:\r\n * - size: visual thickness (xs, sm, md, lg, xl)\r\n * - width: number | string (e.g. 200, \"50%\", \"100px\")\r\n * - animated: whether to show shimmer (respects prefers-reduced-motion)\r\n * - circle: renders as a circle (useful for avatars)\r\n * - className: pass-through for custom styling\r\n *\r\n * Accessibility:\r\n * - role=\"status\" with aria-busy on parent usage is recommended by developer.\r\n * - For individual skeletons that should be ignored by assistive tech set aria-hidden=true.\r\n */\r\n/**\r\n * Skeleton.tsx + Helper Components\r\n * --------------------------------\r\n * Adds:\r\n * - Skeleton.Text\r\n * - Skeleton.Paragraph\r\n * - Skeleton.Avatar\r\n * - Skeleton.Button\r\n * - Skeleton.Card\r\n */\r\n\r\nimport React from 'react';\r\nimport './Skeleton.css';\r\n\r\ntype Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\r\n\r\ninterface SkeletonProps {\r\n size?: Size;\r\n width?: number | string;\r\n animated?: boolean;\r\n circle?: boolean;\r\n ariaHidden?: boolean;\r\n className?: string;\r\n style?: React.CSSProperties;\r\n}\r\n\r\nfunction formatWidth(w?: number | string): string | undefined {\r\n if (w === undefined) return undefined;\r\n if (typeof w === 'number') return `${w}px`;\r\n return w;\r\n}\r\n\r\nexport function Skeleton({\r\n size = 'md',\r\n width,\r\n animated = true,\r\n circle = false,\r\n ariaHidden = true,\r\n className = '',\r\n style,\r\n}: SkeletonProps) {\r\n const classes = [\r\n 'ui-skeleton',\r\n `ui-skeleton--${size}`,\r\n animated && 'ui-skeleton--animated',\r\n circle && 'ui-skeleton--circle',\r\n className,\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n return (\r\n <span\r\n className={classes}\r\n style={{\r\n width: formatWidth(width),\r\n display: width ? 'block' : undefined,\r\n ...style,\r\n }}\r\n aria-hidden={ariaHidden}\r\n role=\"presentation\"\r\n />\r\n );\r\n}\r\n\r\n/* -------------------------------------------------------\r\n * Helper Components\r\n * ------------------------------------------------------*/\r\n\r\n/**\r\n * Simple text line.\r\n * Default width: 100%\r\n */\r\nfunction Text({\r\n width = '100%',\r\n size = 'md',\r\n}: {\r\n width?: number | string;\r\n size?: Size;\r\n}) {\r\n return <Skeleton width={width} size={size} />;\r\n}\r\n\r\n/**\r\n * Paragraph: multiple lines of text skeleton\r\n * lines default = 3\r\n */\r\nfunction Paragraph({\r\n lines = 3,\r\n size = 'md',\r\n}: {\r\n lines?: number;\r\n size?: Size;\r\n}) {\r\n const arr = Array.from({ length: lines });\r\n\r\n return (\r\n <div aria-hidden=\"true\">\r\n {arr.map((_, i) => (\r\n <div key={i} style={{ marginBlockEnd: '8px' }}>\r\n <Skeleton width={i === lines - 1 ? '75%' : '100%'} size={size} />\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\n/**\r\n * Avatar placeholder, circle with dynamic size\r\n */\r\nfunction AvatarSkeleton({ size = 40 }: { size?: number }) {\r\n return <Skeleton circle width={size} animated />;\r\n}\r\n\r\n/**\r\n * Button skeleton (pill-like shape)\r\n */\r\nfunction ButtonSkeleton({\r\n width = 100,\r\n height = 36,\r\n}: {\r\n width?: number;\r\n height?: number;\r\n}) {\r\n return (\r\n <Skeleton\r\n width={width}\r\n size=\"md\"\r\n animated\r\n style={{\r\n height,\r\n borderRadius: 'var(--radius-md)',\r\n }}\r\n />\r\n );\r\n}\r\n\r\n/**\r\n * Card Skeleton: header + lines + footer bar\r\n */\r\nfunction CardSkeleton() {\r\n return (\r\n <div aria-hidden=\"true\">\r\n <Skeleton width=\"60%\" size=\"lg\" style={{ marginBottom: 12 }} />\r\n <Paragraph lines={3} />\r\n <Skeleton width=\"40%\" size=\"md\" style={{ marginTop: 16 }} />\r\n </div>\r\n );\r\n}\r\n\r\n/* Attach helpers */\r\nSkeleton.Text = Text;\r\nSkeleton.Paragraph = Paragraph;\r\nSkeleton.Avatar = AvatarSkeleton;\r\nSkeleton.Button = ButtonSkeleton;\r\nSkeleton.Card = CardSkeleton;\r\n\r\nexport default Skeleton;\r\n"],"names":["formatWidth","w","Skeleton","size","width","animated","circle","ariaHidden","className","style","classes","jsx","Text","Paragraph","lines","arr","_","AvatarSkeleton","ButtonSkeleton","height","CardSkeleton","jsxs"],"mappings":";;AAyCA,SAASA,EAAYC,GAAyC;AAC5D,MAAIA,MAAM;AACV,WAAI,OAAOA,KAAM,WAAiB,GAAGA,CAAC,OAC/BA;AACT;AAEO,SAASC,EAAS;AAAA,EACvB,MAAAC,IAAO;AAAA,EACP,OAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,QAAAC,IAAS;AAAA,EACT,YAAAC,IAAa;AAAA,EACb,WAAAC,IAAY;AAAA,EACZ,OAAAC;AACF,GAAkB;AAChB,QAAMC,IAAU;AAAA,IACd;AAAA,IACA,gBAAgBP,CAAI;AAAA,IACpBE,KAAY;AAAA,IACZC,KAAU;AAAA,IACVE;AAAA,EAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,SACE,gBAAAG;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWD;AAAA,MACX,OAAO;AAAA,QACL,OAAOV,EAAYI,CAAK;AAAA,QACxB,SAASA,IAAQ,UAAU;AAAA,QAC3B,GAAGK;AAAA,MAAA;AAAA,MAEL,eAAaF;AAAA,MACb,MAAK;AAAA,IAAA;AAAA,EAAA;AAGX;AAUA,SAASK,EAAK;AAAA,EACZ,OAAAR,IAAQ;AAAA,EACR,MAAAD,IAAO;AACT,GAGG;AACD,SAAO,gBAAAQ,EAACT,GAAA,EAAS,OAAAE,GAAc,MAAAD,EAAA,CAAY;AAC7C;AAMA,SAASU,EAAU;AAAA,EACjB,OAAAC,IAAQ;AAAA,EACR,MAAAX,IAAO;AACT,GAGG;AACD,QAAMY,IAAM,MAAM,KAAK,EAAE,QAAQD,GAAO;AAExC,SACE,gBAAAH,EAAC,OAAA,EAAI,eAAY,QACd,UAAAI,EAAI,IAAI,CAACC,GAAG,MACX,gBAAAL,EAAC,OAAA,EAAY,OAAO,EAAE,gBAAgB,MAAA,GACpC,UAAA,gBAAAA,EAACT,GAAA,EAAS,OAAO,MAAMY,IAAQ,IAAI,QAAQ,QAAQ,MAAAX,EAAA,CAAY,EAAA,GADvD,CAEV,CACD,GACH;AAEJ;AAKA,SAASc,EAAe,EAAE,MAAAd,IAAO,MAAyB;AACxD,2BAAQD,GAAA,EAAS,QAAM,IAAC,OAAOC,GAAM,UAAQ,IAAC;AAChD;AAKA,SAASe,EAAe;AAAA,EACtB,OAAAd,IAAQ;AAAA,EACR,QAAAe,IAAS;AACX,GAGG;AACD,SACE,gBAAAR;AAAA,IAACT;AAAA,IAAA;AAAA,MACC,OAAAE;AAAA,MACA,MAAK;AAAA,MACL,UAAQ;AAAA,MACR,OAAO;AAAA,QACL,QAAAe;AAAA,QACA,cAAc;AAAA,MAAA;AAAA,IAChB;AAAA,EAAA;AAGN;AAKA,SAASC,IAAe;AACtB,SACE,gBAAAC,EAAC,OAAA,EAAI,eAAY,QACf,UAAA;AAAA,IAAA,gBAAAV,EAACT,GAAA,EAAS,OAAM,OAAM,MAAK,MAAK,OAAO,EAAE,cAAc,GAAA,EAAG,CAAG;AAAA,IAC7D,gBAAAS,EAACE,GAAA,EAAU,OAAO,EAAA,CAAG;AAAA,IACrB,gBAAAF,EAACT,GAAA,EAAS,OAAM,OAAM,MAAK,MAAK,OAAO,EAAE,WAAW,KAAG,CAAG;AAAA,EAAA,GAC5D;AAEJ;AAGAA,EAAS,OAAOU;AAChBV,EAAS,YAAYW;AACrBX,EAAS,SAASe;AAClBf,EAAS,SAASgB;AAClBhB,EAAS,OAAOkB;"}
1
+ {"version":3,"file":"Skeleton.js","sources":["../../../src/components/skeleton/Skeleton.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../../utils';\nimport './Skeleton.css';\n\n/* ============================================================\n * Types\n * ============================================================ */\n\ntype SkeletonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\nexport interface SkeletonProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** The predefined height mapping for the skeleton */\n size?: SkeletonSize;\n /** Explicit width override (supports numbers as px, or strings like '100%') */\n width?: number | string;\n /** Explicit height override (supports numbers as px, or strings like '50px') */\n height?: number | string; \n /** Enables or disables the sweeping shimmer animation. Defaults to true. */\n animated?: boolean;\n /** Forces the skeleton into a perfect circle, ignoring the size height */\n circle?: boolean;\n /** Hides the element from screen readers. Defaults to true (recommended). */\n ariaHidden?: boolean;\n}\n\nfunction formatSize(val?: number | string): string | undefined {\n if (val === undefined) return undefined;\n return typeof val === 'number' ? `${val}px` : val;\n}\n\n/* ============================================================\n * 1. Root Component\n * ============================================================ */\n\n/**\n * Skeleton Component (Root)\n * * A visual placeholder used during asynchronous data fetching.\n * * WAI-ARIA Note: Skeletons are strictly visual and should remain hidden from \n * screen readers (`aria-hidden=\"true\"`) to prevent them from reading out \n * dozens of \"presentation\" or \"empty\" blocks while data loads.\n */\nconst SkeletonRoot = React.forwardRef<HTMLSpanElement, SkeletonProps>(({\n size = 'md',\n width,\n height,\n animated = true,\n circle = false,\n ariaHidden = true,\n className,\n style,\n ...props\n}, ref) => {\n return (\n <span\n ref={ref}\n aria-hidden={ariaHidden}\n role=\"presentation\"\n className={cn(\n 'nui-skeleton',\n `nui-skeleton--${size}`,\n animated && 'nui-skeleton--animated',\n circle && 'nui-skeleton--circle',\n className\n )}\n style={{\n width: formatSize(width),\n height: formatSize(height),\n ...style,\n }}\n {...props}\n />\n );\n});\nSkeletonRoot.displayName = 'Skeleton';\n\n/* ============================================================\n * Helper Components\n * ============================================================ */\n\nexport interface SkeletonTextProps extends React.HTMLAttributes<HTMLSpanElement> {\n width?: number | string;\n size?: SkeletonSize;\n}\n\nfunction Text({ width = '100%', size = 'md', className, ...props }: SkeletonTextProps) {\n return <SkeletonRoot width={width} size={size} className={className} {...props} />;\n}\n\nexport interface SkeletonParagraphProps extends React.HTMLAttributes<HTMLDivElement> {\n lines?: number;\n size?: SkeletonSize;\n}\n\nfunction Paragraph({ lines = 3, size = 'md', className, ...props }: SkeletonParagraphProps) {\n return (\n <div \n aria-hidden=\"true\" \n className={cn(\"nui-skeleton-paragraph\", className)} \n style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}\n {...props}\n >\n {Array.from({ length: lines }).map((_, i) => (\n <SkeletonRoot \n key={i} \n width={i === lines - 1 ? '75%' : '100%'} \n size={size} \n />\n ))}\n </div>\n );\n}\n\nexport interface SkeletonAvatarProps extends React.HTMLAttributes<HTMLSpanElement> {\n size?: number | string;\n}\n\nfunction Avatar({ size = 40, className, ...props }: SkeletonAvatarProps) {\n // width sets the size, the CSS aspect-ratio: 1/1 guarantees it stays a perfect circle!\n return <SkeletonRoot circle width={size} className={className} {...props} />;\n}\n\nexport interface SkeletonButtonProps extends React.HTMLAttributes<HTMLSpanElement> {\n width?: number | string;\n height?: number | string;\n}\n\nfunction Button({ width = 100, height = 40, className, ...props }: SkeletonButtonProps) {\n return (\n <SkeletonRoot\n width={width}\n height={height}\n className={cn(\"nui-skeleton-button\", className)}\n style={{ borderRadius: '6px' }}\n {...props}\n />\n );\n}\n\nfunction Card({ className, style, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div \n aria-hidden=\"true\" \n className={cn(\"nui-skeleton-card\", className)} \n style={{ padding: '16px', border: '1px solid var(--nui-border-default, #e2e8f0)', borderRadius: '12px', ...style }}\n {...props}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: '12px', marginBottom: '16px' }}>\n <Avatar size={48} />\n <div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <SkeletonRoot width=\"40%\" size=\"md\" />\n <SkeletonRoot width=\"20%\" size=\"sm\" />\n </div>\n </div>\n <Paragraph lines={3} />\n </div>\n );\n}\n\n/* ============================================================\n * Export\n * ============================================================ */\n\nexport const Skeleton = Object.assign(SkeletonRoot, {\n Text,\n Paragraph,\n Avatar,\n Button,\n Card,\n});"],"names":["formatSize","val","SkeletonRoot","React","size","width","height","animated","circle","ariaHidden","className","style","props","ref","jsx","cn","Text","Paragraph","lines","_","i","Avatar","Button","Card","jsxs","Skeleton"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("react/jsx-runtime"),o=require("react");;/* empty css */function R({min:n=0,max:a=100,step:c=1,value:g,defaultValue:m,onChange:b,disabled:s=!1,className:S=""}){const k=g!==void 0,[C,M]=o.useState(m??n),r=k?g:C,u=o.useCallback(t=>{const e=Math.min(a,Math.max(n,t)),d=Math.round(e/c)*c;k||M(d),b?.(d)},[k,a,n,c,b]),E=o.useRef(null),D=(r-n)/(a-n)*100,w=o.useCallback(t=>{const e=E.current;if(!e)return r;const d=e.getBoundingClientRect(),y=(t-d.left)/d.width;return n+y*(a-n)},[n,a,r]),[v,L]=o.useState(!1),f=o.useCallback(t=>{if(s)return;L(!0);const e="touches"in t?t.touches[0].clientX:t.clientX;u(w(e))},[s,w,u]),i=o.useCallback(t=>{if(!v||s)return;const e=t.touches?.[0]?.clientX??t.clientX;u(w(e))},[v,s,w,u]),l=o.useCallback(()=>{L(!1)},[]);o.useEffect(()=>{if(v)return window.addEventListener("mousemove",i),window.addEventListener("touchmove",i),window.addEventListener("mouseup",l),window.addEventListener("touchend",l),()=>{window.removeEventListener("mousemove",i),window.removeEventListener("touchmove",i),window.removeEventListener("mouseup",l),window.removeEventListener("touchend",l)}},[v,i,l]);const j=o.useCallback(t=>{if(s)return;let e=r;switch(t.key){case"ArrowRight":case"ArrowUp":e=r+c;break;case"ArrowLeft":case"ArrowDown":e=r-c;break;case"PageUp":e=r+c*10;break;case"PageDown":e=r-c*10;break;case"Home":e=n;break;case"End":e=a;break;default:return}t.preventDefault(),u(e)},[s,r,c,n,a,u]);return h.jsx("div",{className:`ui-slider ${s?"disabled":""} ${S}`,children:h.jsxs("div",{ref:E,className:"ui-slider-track",onMouseDown:f,onTouchStart:f,children:[h.jsx("div",{className:"ui-slider-fill",style:{width:`${D}%`}}),h.jsx("div",{className:"ui-slider-thumb",role:"slider",tabIndex:s?-1:0,"aria-valuemin":n,"aria-valuemax":a,"aria-valuenow":r,"aria-disabled":s||void 0,onKeyDown:j,onMouseDown:f,onTouchStart:f,style:{left:`${D}%`}})]})})}exports.Slider=R;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("react/jsx-runtime"),i=require("react");;/* empty css */const N=require("../../utils/cn/cn.cjs");function V({min:n=0,max:s=100,step:a=1,value:v,defaultValue:L,onChange:f,disabled:c=!1,className:D,...R}){const d=v!==void 0,[j,x]=i.useState(L??n),r=Math.min(s,Math.max(n,d?v:j)),h=i.useRef(null),k=i.useRef(null),[g,m]=i.useState(!1),u=i.useCallback(e=>{const t=Math.min(s,Math.max(n,e));let o=n+Math.round((t-n)/a)*a;o=Number(o.toFixed(5)),d||x(o),f?.(o)},[d,s,n,a,f]),w=i.useCallback(e=>{const t=h.current;if(!t)return r;const o=t.getBoundingClientRect(),y=Math.max(0,Math.min(e-o.left,o.width))/o.width;return n+y*(s-n)},[n,s,r]),b=e=>"touches"in e?e.touches[0].clientX:e.clientX,E=e=>{c||(k.current?.focus(),m(!0),u(w(b(e))))};i.useEffect(()=>{if(!g||c)return;const e=o=>{u(w(b(o)))},t=()=>{m(!1)};return window.addEventListener("mousemove",e),window.addEventListener("touchmove",e,{passive:!1}),window.addEventListener("mouseup",t),window.addEventListener("touchend",t),()=>{window.removeEventListener("mousemove",e),window.removeEventListener("touchmove",e),window.removeEventListener("mouseup",t),window.removeEventListener("touchend",t)}},[g,c,w,u]);const S=i.useCallback(e=>{if(c)return;let t=r;switch(e.key){case"ArrowRight":case"ArrowUp":t=r+a;break;case"ArrowLeft":case"ArrowDown":t=r-a;break;case"PageUp":t=r+a*10;break;case"PageDown":t=r-a*10;break;case"Home":t=n;break;case"End":t=s;break;default:return}e.preventDefault(),u(t)},[c,r,a,n,s,u]),M=(r-n)/(s-n)*100;return l.jsx("div",{className:N.cn("nui-slider-root",c&&"nui-slider--disabled",D),onMouseDown:E,onTouchStart:E,...R,children:l.jsx("div",{className:"nui-slider-track-container",children:l.jsxs("div",{ref:h,className:"nui-slider-track",children:[l.jsx("div",{className:"nui-slider-fill",style:{width:`${M}%`}}),l.jsx("div",{ref:k,className:"nui-slider-thumb",role:"slider",tabIndex:c?-1:0,"aria-valuemin":n,"aria-valuemax":s,"aria-valuenow":r,"aria-disabled":c||void 0,onKeyDown:S,style:{left:`${M}%`}})]})})})}exports.Slider=V;
2
2
  //# sourceMappingURL=Slider.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Slider.cjs","sources":["../../../src/components/slider/Slider.tsx"],"sourcesContent":["/**\r\n * Slider.tsx\r\n * -----------\r\n * Fully accessible single-thumb slider.\r\n * WAI-ARIA compliant, supports pointer, touch, keyboard.\r\n */\r\n\r\nimport React, { useRef, useEffect, useState, useCallback } from 'react';\r\nimport './Slider.css';\r\n\r\ninterface SliderProps {\r\n min?: number;\r\n max?: number;\r\n step?: number;\r\n value?: number;\r\n defaultValue?: number;\r\n onChange?: (value: number) => void;\r\n disabled?: boolean;\r\n className?: string;\r\n}\r\n\r\nexport function Slider({\r\n min = 0,\r\n max = 100,\r\n step = 1,\r\n value,\r\n defaultValue,\r\n onChange,\r\n disabled = false,\r\n className = '',\r\n}: SliderProps) {\r\n const isControlled = value !== undefined;\r\n\r\n const [internalValue, setInternalValue] = useState(defaultValue ?? min);\r\n\r\n const val = isControlled ? value : internalValue;\r\n\r\n /** Safe setter */\r\n const setVal = useCallback(\r\n (v: number) => {\r\n const clamped = Math.min(max, Math.max(min, v));\r\n const stepped = Math.round(clamped / step) * step;\r\n\r\n if (!isControlled) setInternalValue(stepped);\r\n onChange?.(stepped);\r\n },\r\n [isControlled, max, min, step, onChange]\r\n );\r\n\r\n const trackRef = useRef<HTMLDivElement | null>(null);\r\n\r\n /** Calculate percentage for UI */\r\n const percent = ((val - min) / (max - min)) * 100;\r\n\r\n /** Pixel → value conversion (FIXED: wrapped in useCallback) */\r\n const pixelToValue = useCallback(\r\n (clientX: number) => {\r\n const track = trackRef.current;\r\n if (!track) return val;\r\n\r\n const rect = track.getBoundingClientRect();\r\n const x = clientX - rect.left;\r\n const ratio = x / rect.width;\r\n const rawValue = min + ratio * (max - min);\r\n return rawValue;\r\n },\r\n [min, max, val]\r\n );\r\n\r\n /** Dragging state */\r\n const [dragging, setDragging] = useState(false);\r\n\r\n const startDrag = useCallback(\r\n (e: React.MouseEvent | React.TouchEvent) => {\r\n if (disabled) return;\r\n setDragging(true);\r\n\r\n const clientX = 'touches' in e ? e.touches[0].clientX : e.clientX;\r\n\r\n setVal(pixelToValue(clientX));\r\n },\r\n [disabled, pixelToValue, setVal]\r\n );\r\n\r\n const onMove = useCallback(\r\n (e: MouseEvent | TouchEvent) => {\r\n if (!dragging || disabled) return;\r\n\r\n const clientX =\r\n (e as TouchEvent).touches?.[0]?.clientX ?? (e as MouseEvent).clientX;\r\n\r\n setVal(pixelToValue(clientX));\r\n },\r\n [dragging, disabled, pixelToValue, setVal]\r\n );\r\n\r\n const endDrag = useCallback(() => {\r\n setDragging(false);\r\n }, []);\r\n\r\n /** Global listeners while dragging */\r\n useEffect(() => {\r\n if (!dragging) return;\r\n\r\n window.addEventListener('mousemove', onMove);\r\n window.addEventListener('touchmove', onMove);\r\n window.addEventListener('mouseup', endDrag);\r\n window.addEventListener('touchend', endDrag);\r\n\r\n return () => {\r\n window.removeEventListener('mousemove', onMove);\r\n window.removeEventListener('touchmove', onMove);\r\n window.removeEventListener('mouseup', endDrag);\r\n window.removeEventListener('touchend', endDrag);\r\n };\r\n }, [dragging, onMove, endDrag]);\r\n\r\n /** Keyboard handling */\r\n const onKeyDown = useCallback(\r\n (e: React.KeyboardEvent) => {\r\n if (disabled) return;\r\n\r\n let next = val;\r\n\r\n switch (e.key) {\r\n case 'ArrowRight':\r\n case 'ArrowUp':\r\n next = val + step;\r\n break;\r\n case 'ArrowLeft':\r\n case 'ArrowDown':\r\n next = val - step;\r\n break;\r\n case 'PageUp':\r\n next = val + step * 10;\r\n break;\r\n case 'PageDown':\r\n next = val - step * 10;\r\n break;\r\n case 'Home':\r\n next = min;\r\n break;\r\n case 'End':\r\n next = max;\r\n break;\r\n default:\r\n return;\r\n }\r\n\r\n e.preventDefault();\r\n setVal(next);\r\n },\r\n [disabled, val, step, min, max, setVal]\r\n );\r\n\r\n return (\r\n <div className={`ui-slider ${disabled ? 'disabled' : ''} ${className}`}>\r\n <div\r\n ref={trackRef}\r\n className=\"ui-slider-track\"\r\n onMouseDown={startDrag}\r\n onTouchStart={startDrag}\r\n >\r\n <div className=\"ui-slider-fill\" style={{ width: `${percent}%` }} />\r\n\r\n <div\r\n className=\"ui-slider-thumb\"\r\n role=\"slider\"\r\n tabIndex={disabled ? -1 : 0}\r\n aria-valuemin={min}\r\n aria-valuemax={max}\r\n aria-valuenow={val}\r\n aria-disabled={disabled || undefined}\r\n onKeyDown={onKeyDown}\r\n onMouseDown={startDrag}\r\n onTouchStart={startDrag}\r\n style={{ left: `${percent}%` }}\r\n />\r\n </div>\r\n </div>\r\n );\r\n}\r\n"],"names":["Slider","min","max","step","value","defaultValue","onChange","disabled","className","isControlled","internalValue","setInternalValue","useState","val","setVal","useCallback","v","clamped","stepped","trackRef","useRef","percent","pixelToValue","clientX","track","rect","ratio","dragging","setDragging","startDrag","e","onMove","endDrag","useEffect","onKeyDown","next","jsx","jsxs"],"mappings":"oKAqBO,SAASA,EAAO,CACrB,IAAAC,EAAM,EACN,IAAAC,EAAM,IACN,KAAAC,EAAO,EACP,MAAAC,EACA,aAAAC,EACA,SAAAC,EACA,SAAAC,EAAW,GACX,UAAAC,EAAY,EACd,EAAgB,CACd,MAAMC,EAAeL,IAAU,OAEzB,CAACM,EAAeC,CAAgB,EAAIC,EAAAA,SAASP,GAAgBJ,CAAG,EAEhEY,EAAMJ,EAAeL,EAAQM,EAG7BI,EAASC,EAAAA,YACZC,GAAc,CACb,MAAMC,EAAU,KAAK,IAAIf,EAAK,KAAK,IAAID,EAAKe,CAAC,CAAC,EACxCE,EAAU,KAAK,MAAMD,EAAUd,CAAI,EAAIA,EAExCM,GAAcE,EAAiBO,CAAO,EAC3CZ,IAAWY,CAAO,CACpB,EACA,CAACT,EAAcP,EAAKD,EAAKE,EAAMG,CAAQ,CAAA,EAGnCa,EAAWC,EAAAA,OAA8B,IAAI,EAG7CC,GAAYR,EAAMZ,IAAQC,EAAMD,GAAQ,IAGxCqB,EAAeP,EAAAA,YAClBQ,GAAoB,CACnB,MAAMC,EAAQL,EAAS,QACvB,GAAI,CAACK,EAAO,OAAOX,EAEnB,MAAMY,EAAOD,EAAM,sBAAA,EAEbE,GADIH,EAAUE,EAAK,MACPA,EAAK,MAEvB,OADiBxB,EAAMyB,GAASxB,EAAMD,EAExC,EACA,CAACA,EAAKC,EAAKW,CAAG,CAAA,EAIV,CAACc,EAAUC,CAAW,EAAIhB,EAAAA,SAAS,EAAK,EAExCiB,EAAYd,EAAAA,YACfe,GAA2C,CAC1C,GAAIvB,EAAU,OACdqB,EAAY,EAAI,EAEhB,MAAML,EAAU,YAAaO,EAAIA,EAAE,QAAQ,CAAC,EAAE,QAAUA,EAAE,QAE1DhB,EAAOQ,EAAaC,CAAO,CAAC,CAC9B,EACA,CAAChB,EAAUe,EAAcR,CAAM,CAAA,EAG3BiB,EAAShB,EAAAA,YACZe,GAA+B,CAC9B,GAAI,CAACH,GAAYpB,EAAU,OAE3B,MAAMgB,EACHO,EAAiB,UAAU,CAAC,GAAG,SAAYA,EAAiB,QAE/DhB,EAAOQ,EAAaC,CAAO,CAAC,CAC9B,EACA,CAACI,EAAUpB,EAAUe,EAAcR,CAAM,CAAA,EAGrCkB,EAAUjB,EAAAA,YAAY,IAAM,CAChCa,EAAY,EAAK,CACnB,EAAG,CAAA,CAAE,EAGLK,EAAAA,UAAU,IAAM,CACd,GAAKN,EAEL,cAAO,iBAAiB,YAAaI,CAAM,EAC3C,OAAO,iBAAiB,YAAaA,CAAM,EAC3C,OAAO,iBAAiB,UAAWC,CAAO,EAC1C,OAAO,iBAAiB,WAAYA,CAAO,EAEpC,IAAM,CACX,OAAO,oBAAoB,YAAaD,CAAM,EAC9C,OAAO,oBAAoB,YAAaA,CAAM,EAC9C,OAAO,oBAAoB,UAAWC,CAAO,EAC7C,OAAO,oBAAoB,WAAYA,CAAO,CAChD,CACF,EAAG,CAACL,EAAUI,EAAQC,CAAO,CAAC,EAG9B,MAAME,EAAYnB,EAAAA,YACfe,GAA2B,CAC1B,GAAIvB,EAAU,OAEd,IAAI4B,EAAOtB,EAEX,OAAQiB,EAAE,IAAA,CACR,IAAK,aACL,IAAK,UACHK,EAAOtB,EAAMV,EACb,MACF,IAAK,YACL,IAAK,YACHgC,EAAOtB,EAAMV,EACb,MACF,IAAK,SACHgC,EAAOtB,EAAMV,EAAO,GACpB,MACF,IAAK,WACHgC,EAAOtB,EAAMV,EAAO,GACpB,MACF,IAAK,OACHgC,EAAOlC,EACP,MACF,IAAK,MACHkC,EAAOjC,EACP,MACF,QACE,MAAA,CAGJ4B,EAAE,eAAA,EACFhB,EAAOqB,CAAI,CACb,EACA,CAAC5B,EAAUM,EAAKV,EAAMF,EAAKC,EAAKY,CAAM,CAAA,EAGxC,OACEsB,EAAAA,IAAC,OAAI,UAAW,aAAa7B,EAAW,WAAa,EAAE,IAAIC,CAAS,GAClE,SAAA6B,EAAAA,KAAC,MAAA,CACC,IAAKlB,EACL,UAAU,kBACV,YAAaU,EACb,aAAcA,EAEd,SAAA,CAAAO,EAAAA,IAAC,MAAA,CAAI,UAAU,iBAAiB,MAAO,CAAE,MAAO,GAAGf,CAAO,GAAA,CAAI,CAAG,EAEjEe,EAAAA,IAAC,MAAA,CACC,UAAU,kBACV,KAAK,SACL,SAAU7B,EAAW,GAAK,EAC1B,gBAAeN,EACf,gBAAeC,EACf,gBAAeW,EACf,gBAAeN,GAAY,OAC3B,UAAA2B,EACA,YAAaL,EACb,aAAcA,EACd,MAAO,CAAE,KAAM,GAAGR,CAAO,GAAA,CAAI,CAAA,CAC/B,CAAA,CAAA,EAEJ,CAEJ"}
1
+ {"version":3,"file":"Slider.cjs","sources":["../../../src/components/slider/Slider.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { useRef, useEffect, useState, useCallback } from 'react';\nimport { cn } from '../../utils';\nimport './Slider.css';\n\n/* ============================================================\n * Types\n * ============================================================ */\n\nexport interface SliderProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue'> {\n /** The minimum allowed value. Defaults to 0. */\n min?: number;\n /** The maximum allowed value. Defaults to 100. */\n max?: number;\n /** The interval between valid values. Defaults to 1. */\n step?: number;\n /** The controlled value of the slider. */\n value?: number;\n /** The initial uncontrolled value of the slider. */\n defaultValue?: number;\n /** Callback fired when the value changes. */\n onChange?: (value: number) => void;\n /** Disables the slider and prevents interaction. */\n disabled?: boolean;\n}\n\n/* ============================================================\n * Component\n * ============================================================ */\n\n/**\n * Slider Component\n * * A WAI-ARIA compliant input that allows users to select a value from a given range.\n * * Automatically handles global window pointer events for smooth dragging outside the hit area.\n */\nexport function Slider({\n min = 0,\n max = 100,\n step = 1,\n value,\n defaultValue,\n onChange,\n disabled = false,\n className,\n ...props // <-- Capture the rest of the HTML attributes (like style, id, etc.)\n}: SliderProps) {\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState(defaultValue ?? min);\n \n // Safely clamp the initial/current value to prevent out-of-bounds rendering\n const rawVal = isControlled ? value : internalValue;\n const val = Math.min(max, Math.max(min, rawVal as number));\n\n const trackRef = useRef<HTMLDivElement | null>(null);\n const thumbRef = useRef<HTMLDivElement | null>(null);\n const [isDragging, setIsDragging] = useState(false);\n\n /* ----------------------------------------------------\n Value Management\n ---------------------------------------------------- */\n const setVal = useCallback(\n (v: number) => {\n const clamped = Math.min(max, Math.max(min, v));\n // Ensures the stepped value correctly aligns with the minimum bound\n let stepped = min + Math.round((clamped - min) / step) * step;\n \n // Fixes JavaScript floating point math errors (e.g., 0.3000000000004)\n stepped = Number(stepped.toFixed(5));\n\n if (!isControlled) setInternalValue(stepped);\n onChange?.(stepped);\n },\n [isControlled, max, min, step, onChange]\n );\n\n const calculateValueFromPointer = useCallback(\n (clientX: number) => {\n const track = trackRef.current;\n if (!track) return val;\n\n const rect = track.getBoundingClientRect();\n const x = Math.max(0, Math.min(clientX - rect.left, rect.width));\n const ratio = x / rect.width;\n \n return min + ratio * (max - min);\n },\n [min, max, val]\n );\n\n /* ----------------------------------------------------\n Drag State Management\n ---------------------------------------------------- */\n const getClientX = (e: MouseEvent | TouchEvent | React.MouseEvent | React.TouchEvent) => {\n return 'touches' in e ? e.touches[0].clientX : (e as MouseEvent | React.MouseEvent).clientX;\n };\n\n const handlePointerDown = (e: React.MouseEvent | React.TouchEvent) => {\n if (disabled) return;\n \n // Instantly focus the thumb so Arrow Keys work immediately!\n thumbRef.current?.focus(); \n \n setIsDragging(true);\n setVal(calculateValueFromPointer(getClientX(e)));\n };\n\n // Syncs global drag listeners without memory leaks\n useEffect(() => {\n if (!isDragging || disabled) return;\n\n const handleMove = (e: MouseEvent | TouchEvent) => {\n setVal(calculateValueFromPointer(getClientX(e)));\n };\n\n const handleUp = () => {\n setIsDragging(false);\n };\n\n window.addEventListener('mousemove', handleMove);\n window.addEventListener('touchmove', handleMove, { passive: false });\n window.addEventListener('mouseup', handleUp);\n window.addEventListener('touchend', handleUp);\n\n return () => {\n window.removeEventListener('mousemove', handleMove);\n window.removeEventListener('touchmove', handleMove);\n window.removeEventListener('mouseup', handleUp);\n window.removeEventListener('touchend', handleUp);\n };\n }, [isDragging, disabled, calculateValueFromPointer, setVal]);\n\n /* ----------------------------------------------------\n Keyboard Navigation (WAI-ARIA)\n ---------------------------------------------------- */\n const onKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (disabled) return;\n\n let next = val;\n\n switch (e.key) {\n case 'ArrowRight':\n case 'ArrowUp':\n next = val + step;\n break;\n case 'ArrowLeft':\n case 'ArrowDown':\n next = val - step;\n break;\n case 'PageUp':\n next = val + step * 10;\n break;\n case 'PageDown':\n next = val - step * 10;\n break;\n case 'Home':\n next = min;\n break;\n case 'End':\n next = max;\n break;\n default:\n return; // Exit if it's not a recognized key\n }\n\n e.preventDefault(); // Prevent page scrolling ONLY when using valid arrow keys\n setVal(next);\n },\n [disabled, val, step, min, max, setVal]\n );\n\n /* ----------------------------------------------------\n Render\n ---------------------------------------------------- */\n const percent = ((val - min) / (max - min)) * 100;\n\n return (\n <div \n className={cn(\n \"nui-slider-root\", \n disabled && \"nui-slider--disabled\",\n className\n )}\n onMouseDown={handlePointerDown}\n onTouchStart={handlePointerDown}\n {...props} // <-- Spread the rest of the props (including style) to the root element\n >\n <div className=\"nui-slider-track-container\">\n <div ref={trackRef} className=\"nui-slider-track\">\n \n <div \n className=\"nui-slider-fill\" \n style={{ width: `${percent}%` }} \n />\n\n <div\n ref={thumbRef}\n className=\"nui-slider-thumb\"\n role=\"slider\"\n tabIndex={disabled ? -1 : 0}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuenow={val}\n aria-disabled={disabled || undefined}\n onKeyDown={onKeyDown}\n style={{ left: `${percent}%` }}\n />\n </div>\n </div>\n </div>\n );\n}"],"names":["Slider","min","max","step","value","defaultValue","onChange","disabled","className","props","isControlled","internalValue","setInternalValue","useState","val","trackRef","useRef","thumbRef","isDragging","setIsDragging","setVal","useCallback","v","clamped","stepped","calculateValueFromPointer","clientX","track","rect","ratio","getClientX","handlePointerDown","useEffect","handleMove","e","handleUp","onKeyDown","next","percent","jsx","cn"],"mappings":"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"}