@nofinite/nui 1.0.0 → 1.0.2

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 (348) hide show
  1. package/dist/components/accordion/Accordion.cjs +2 -0
  2. package/dist/components/accordion/Accordion.cjs.map +1 -0
  3. package/dist/components/accordion/Accordion.js +51 -0
  4. package/dist/components/accordion/Accordion.js.map +1 -0
  5. package/dist/components/alert/Alert.cjs +2 -0
  6. package/dist/components/alert/Alert.cjs.map +1 -0
  7. package/dist/components/alert/Alert.js +32 -0
  8. package/dist/components/alert/Alert.js.map +1 -0
  9. package/dist/components/avatar/Avatar.cjs +2 -0
  10. package/dist/components/avatar/Avatar.cjs.map +1 -0
  11. package/dist/components/avatar/Avatar.js +51 -0
  12. package/dist/components/avatar/Avatar.js.map +1 -0
  13. package/dist/components/avatar/AvatarGroup.cjs +2 -0
  14. package/dist/components/avatar/AvatarGroup.cjs.map +1 -0
  15. package/dist/components/avatar/AvatarGroup.js +32 -0
  16. package/dist/components/avatar/AvatarGroup.js.map +1 -0
  17. package/dist/components/badge/Badge.cjs +2 -0
  18. package/dist/components/badge/Badge.cjs.map +1 -0
  19. package/dist/components/badge/Badge.js +81 -0
  20. package/dist/components/badge/Badge.js.map +1 -0
  21. package/dist/components/badge/BadgeGroup.cjs +2 -0
  22. package/dist/components/badge/BadgeGroup.cjs.map +1 -0
  23. package/dist/components/badge/BadgeGroup.js +17 -0
  24. package/dist/components/badge/BadgeGroup.js.map +1 -0
  25. package/dist/components/breadcrumbs/Breadcrumbs.cjs +2 -0
  26. package/dist/components/breadcrumbs/Breadcrumbs.cjs.map +1 -0
  27. package/dist/components/breadcrumbs/Breadcrumbs.js +46 -0
  28. package/dist/components/breadcrumbs/Breadcrumbs.js.map +1 -0
  29. package/dist/components/button/Button.cjs +2 -0
  30. package/dist/components/button/Button.cjs.map +1 -0
  31. package/dist/components/button/Button.js +21 -0
  32. package/dist/components/button/Button.js.map +1 -0
  33. package/dist/components/card/Card.cjs +2 -0
  34. package/dist/components/card/Card.cjs.map +1 -0
  35. package/dist/components/card/Card.js +50 -0
  36. package/dist/components/card/Card.js.map +1 -0
  37. package/dist/components/checkbox/Checkbox.cjs +2 -0
  38. package/dist/components/checkbox/Checkbox.cjs.map +1 -0
  39. package/dist/components/checkbox/Checkbox.js +46 -0
  40. package/dist/components/checkbox/Checkbox.js.map +1 -0
  41. package/dist/components/chip/Chip.cjs +2 -0
  42. package/dist/components/chip/Chip.cjs.map +1 -0
  43. package/dist/components/chip/Chip.js +51 -0
  44. package/dist/components/chip/Chip.js.map +1 -0
  45. package/dist/components/combobox/Combobox.cjs +2 -0
  46. package/dist/components/combobox/Combobox.cjs.map +1 -0
  47. package/dist/components/combobox/Combobox.js +114 -0
  48. package/dist/components/combobox/Combobox.js.map +1 -0
  49. package/dist/components/commandpalette/CommandPalette.cjs +2 -0
  50. package/dist/components/commandpalette/CommandPalette.cjs.map +1 -0
  51. package/dist/components/commandpalette/CommandPalette.js +111 -0
  52. package/dist/components/commandpalette/CommandPalette.js.map +1 -0
  53. package/dist/components/contextmenu/ContextMenu.cjs +2 -0
  54. package/dist/components/contextmenu/ContextMenu.cjs.map +1 -0
  55. package/dist/components/contextmenu/ContextMenu.js +104 -0
  56. package/dist/components/contextmenu/ContextMenu.js.map +1 -0
  57. package/dist/components/datagrid/DataGrid.cjs +2 -0
  58. package/dist/components/datagrid/DataGrid.cjs.map +1 -0
  59. package/dist/components/datagrid/DataGrid.js +227 -0
  60. package/dist/components/datagrid/DataGrid.js.map +1 -0
  61. package/dist/components/datepicker/DatePicker.cjs +2 -0
  62. package/dist/components/datepicker/DatePicker.cjs.map +1 -0
  63. package/dist/components/datepicker/DatePicker.js +265 -0
  64. package/dist/components/datepicker/DatePicker.js.map +1 -0
  65. package/dist/components/daterangepicker/DateRangePicker.cjs +2 -0
  66. package/dist/components/daterangepicker/DateRangePicker.cjs.map +1 -0
  67. package/dist/components/daterangepicker/DateRangePicker.js +322 -0
  68. package/dist/components/daterangepicker/DateRangePicker.js.map +1 -0
  69. package/dist/components/drawer/Drawer.cjs +2 -0
  70. package/dist/components/drawer/Drawer.cjs.map +1 -0
  71. package/dist/components/drawer/Drawer.js +57 -0
  72. package/dist/components/drawer/Drawer.js.map +1 -0
  73. package/dist/components/dropdown/Dropdown.cjs +2 -0
  74. package/dist/components/dropdown/Dropdown.cjs.map +1 -0
  75. package/dist/components/dropdown/Dropdown.js +115 -0
  76. package/dist/components/dropdown/Dropdown.js.map +1 -0
  77. package/dist/components/fileuploader/FileUploader.cjs +2 -0
  78. package/dist/components/fileuploader/FileUploader.cjs.map +1 -0
  79. package/dist/components/fileuploader/FileUploader.js +83 -0
  80. package/dist/components/fileuploader/FileUploader.js.map +1 -0
  81. package/dist/components/hovercard/HoverCard.cjs +2 -0
  82. package/dist/components/hovercard/HoverCard.cjs.map +1 -0
  83. package/dist/components/hovercard/HoverCard.js +78 -0
  84. package/dist/components/hovercard/HoverCard.js.map +1 -0
  85. package/dist/components/input/Input.cjs +2 -0
  86. package/dist/components/input/Input.cjs.map +1 -0
  87. package/dist/components/input/Input.js +41 -0
  88. package/dist/components/input/Input.js.map +1 -0
  89. package/dist/components/layout/Container.cjs +2 -0
  90. package/dist/components/layout/Container.cjs.map +1 -0
  91. package/dist/components/layout/Container.js +33 -0
  92. package/dist/components/layout/Container.js.map +1 -0
  93. package/dist/components/layout/Flex.cjs +2 -0
  94. package/dist/components/layout/Flex.cjs.map +1 -0
  95. package/dist/components/layout/Flex.js +26 -0
  96. package/dist/components/layout/Flex.js.map +1 -0
  97. package/dist/components/layout/Grid.cjs +2 -0
  98. package/dist/components/layout/Grid.cjs.map +1 -0
  99. package/dist/components/layout/Grid.js +21 -0
  100. package/dist/components/layout/Grid.js.map +1 -0
  101. package/dist/components/layout/HStack.cjs +2 -0
  102. package/dist/components/layout/HStack.cjs.map +1 -0
  103. package/dist/components/layout/HStack.js +9 -0
  104. package/dist/components/layout/HStack.js.map +1 -0
  105. package/dist/components/layout/Stack.cjs +2 -0
  106. package/dist/components/layout/Stack.cjs.map +1 -0
  107. package/dist/components/layout/Stack.js +9 -0
  108. package/dist/components/layout/Stack.js.map +1 -0
  109. package/dist/components/megamenu/MegaMenu.cjs +2 -0
  110. package/dist/components/megamenu/MegaMenu.cjs.map +1 -0
  111. package/dist/components/megamenu/MegaMenu.js +43 -0
  112. package/dist/components/megamenu/MegaMenu.js.map +1 -0
  113. package/dist/components/modal/Modal.cjs +2 -0
  114. package/dist/components/modal/Modal.cjs.map +1 -0
  115. package/dist/components/modal/Modal.js +91 -0
  116. package/dist/components/modal/Modal.js.map +1 -0
  117. package/dist/components/pagination/Pagination.cjs +2 -0
  118. package/dist/components/pagination/Pagination.cjs.map +1 -0
  119. package/dist/components/pagination/Pagination.js +62 -0
  120. package/dist/components/pagination/Pagination.js.map +1 -0
  121. package/dist/components/popover/Popover.cjs +2 -0
  122. package/dist/components/popover/Popover.cjs.map +1 -0
  123. package/dist/components/popover/Popover.js +123 -0
  124. package/dist/components/popover/Popover.js.map +1 -0
  125. package/dist/components/progress/Progress.cjs +2 -0
  126. package/dist/components/progress/Progress.cjs.map +1 -0
  127. package/dist/components/progress/Progress.js +33 -0
  128. package/dist/components/progress/Progress.js.map +1 -0
  129. package/dist/components/radiogroup/RadioGroup.cjs +2 -0
  130. package/dist/components/radiogroup/RadioGroup.cjs.map +1 -0
  131. package/dist/components/radiogroup/RadioGroup.js +79 -0
  132. package/dist/components/radiogroup/RadioGroup.js.map +1 -0
  133. package/dist/components/rating/Rating.cjs +2 -0
  134. package/dist/components/rating/Rating.cjs.map +1 -0
  135. package/dist/components/rating/Rating.js +49 -0
  136. package/dist/components/rating/Rating.js.map +1 -0
  137. package/dist/components/skeleton/Skeleton.cjs +2 -0
  138. package/dist/components/skeleton/Skeleton.cjs.map +1 -0
  139. package/dist/components/skeleton/Skeleton.js +86 -0
  140. package/dist/components/skeleton/Skeleton.js.map +1 -0
  141. package/dist/components/slider/Slider.cjs +2 -0
  142. package/dist/components/slider/Slider.cjs.map +1 -0
  143. package/dist/components/slider/Slider.js +116 -0
  144. package/dist/components/slider/Slider.js.map +1 -0
  145. package/dist/components/spinner/Spinner.cjs +2 -0
  146. package/dist/components/spinner/Spinner.cjs.map +1 -0
  147. package/dist/components/spinner/Spinner.js +21 -0
  148. package/dist/components/spinner/Spinner.js.map +1 -0
  149. package/dist/components/stepper/Stepper.cjs +6 -0
  150. package/dist/components/stepper/Stepper.cjs.map +1 -0
  151. package/dist/components/stepper/Stepper.js +43 -0
  152. package/dist/components/stepper/Stepper.js.map +1 -0
  153. package/dist/components/switch/Switch.cjs +2 -0
  154. package/dist/components/switch/Switch.cjs.map +1 -0
  155. package/dist/components/switch/Switch.js +67 -0
  156. package/dist/components/switch/Switch.js.map +1 -0
  157. package/dist/components/table/Table.cjs +2 -0
  158. package/dist/components/table/Table.cjs.map +1 -0
  159. package/dist/components/table/Table.js +46 -0
  160. package/dist/components/table/Table.js.map +1 -0
  161. package/dist/components/tabs/Tabs.cjs +2 -0
  162. package/dist/components/tabs/Tabs.cjs.map +1 -0
  163. package/dist/components/tabs/Tabs.js +56 -0
  164. package/dist/components/tabs/Tabs.js.map +1 -0
  165. package/dist/components/textarea/Textarea.cjs +2 -0
  166. package/dist/components/textarea/Textarea.cjs.map +1 -0
  167. package/dist/components/textarea/Textarea.js +75 -0
  168. package/dist/components/textarea/Textarea.js.map +1 -0
  169. package/dist/components/toast/Toast.cjs +2 -0
  170. package/dist/components/toast/Toast.cjs.map +1 -0
  171. package/dist/components/toast/Toast.js +52 -0
  172. package/dist/components/toast/Toast.js.map +1 -0
  173. package/dist/components/tooltip/Tooltip.cjs +2 -0
  174. package/dist/components/tooltip/Tooltip.cjs.map +1 -0
  175. package/dist/components/tooltip/Tooltip.js +73 -0
  176. package/dist/components/tooltip/Tooltip.js.map +1 -0
  177. package/dist/components/treeview/TreeView.cjs +2 -0
  178. package/dist/components/treeview/TreeView.cjs.map +1 -0
  179. package/dist/components/treeview/TreeView.js +98 -0
  180. package/dist/components/treeview/TreeView.js.map +1 -0
  181. package/dist/components/virtuallist/VirtualList.cjs +2 -0
  182. package/dist/components/virtuallist/VirtualList.cjs.map +1 -0
  183. package/dist/components/virtuallist/VirtualList.js +58 -0
  184. package/dist/components/virtuallist/VirtualList.js.map +1 -0
  185. package/dist/index.cjs +2 -0
  186. package/dist/index.cjs.map +1 -0
  187. package/dist/index.js +109 -0
  188. package/dist/index.js.map +1 -0
  189. package/dist/styles/index.css +1 -0
  190. package/dist/theme/NUIProvider.cjs +2 -0
  191. package/dist/theme/NUIProvider.cjs.map +1 -0
  192. package/dist/theme/NUIProvider.js +34 -0
  193. package/dist/theme/NUIProvider.js.map +1 -0
  194. package/dist/theme/useTheme.cjs +2 -0
  195. package/dist/theme/useTheme.cjs.map +1 -0
  196. package/dist/theme/useTheme.js +9 -0
  197. package/dist/theme/useTheme.js.map +1 -0
  198. package/dist/types/components/accordion/Accordion.d.ts +18 -0
  199. package/dist/types/components/accordion/Accordion.d.ts.map +1 -0
  200. package/dist/types/components/alert/Alert.d.ts +13 -0
  201. package/dist/types/components/alert/Alert.d.ts.map +1 -0
  202. package/dist/types/components/avatar/Avatar.d.ts +18 -0
  203. package/dist/types/components/avatar/Avatar.d.ts.map +1 -0
  204. package/dist/types/components/avatar/AvatarGroup.d.ts +10 -0
  205. package/dist/types/components/avatar/AvatarGroup.d.ts.map +1 -0
  206. package/dist/types/components/badge/Badge.d.ts +22 -0
  207. package/dist/types/components/badge/Badge.d.ts.map +1 -0
  208. package/dist/types/components/badge/BadgeGroup.d.ts +9 -0
  209. package/dist/types/components/badge/BadgeGroup.d.ts.map +1 -0
  210. package/dist/types/components/breadcrumbs/Breadcrumbs.d.ts +15 -0
  211. package/dist/types/components/breadcrumbs/Breadcrumbs.d.ts.map +1 -0
  212. package/dist/types/components/button/Button.d.ts +15 -0
  213. package/dist/types/components/button/Button.d.ts.map +1 -0
  214. package/dist/types/components/card/Card.d.ts +27 -0
  215. package/dist/types/components/card/Card.d.ts.map +1 -0
  216. package/dist/types/components/checkbox/Checkbox.d.ts +15 -0
  217. package/dist/types/components/checkbox/Checkbox.d.ts.map +1 -0
  218. package/dist/types/components/chip/Chip.d.ts +21 -0
  219. package/dist/types/components/chip/Chip.d.ts.map +1 -0
  220. package/dist/types/components/combobox/Combobox.d.ts +24 -0
  221. package/dist/types/components/combobox/Combobox.d.ts.map +1 -0
  222. package/dist/types/components/commandpalette/CommandPalette.d.ts +21 -0
  223. package/dist/types/components/commandpalette/CommandPalette.d.ts.map +1 -0
  224. package/dist/types/components/contextmenu/ContextMenu.d.ts +17 -0
  225. package/dist/types/components/contextmenu/ContextMenu.d.ts.map +1 -0
  226. package/dist/types/components/datagrid/DataGrid.d.ts +28 -0
  227. package/dist/types/components/datagrid/DataGrid.d.ts.map +1 -0
  228. package/dist/types/components/datepicker/DatePicker.d.ts +14 -0
  229. package/dist/types/components/datepicker/DatePicker.d.ts.map +1 -0
  230. package/dist/types/components/daterangepicker/DateRangePicker.d.ts +19 -0
  231. package/dist/types/components/daterangepicker/DateRangePicker.d.ts.map +1 -0
  232. package/dist/types/components/drawer/Drawer.d.ts +12 -0
  233. package/dist/types/components/drawer/Drawer.d.ts.map +1 -0
  234. package/dist/types/components/dropdown/Dropdown.d.ts +18 -0
  235. package/dist/types/components/dropdown/Dropdown.d.ts.map +1 -0
  236. package/dist/types/components/fileuploader/FileUploader.d.ts +9 -0
  237. package/dist/types/components/fileuploader/FileUploader.d.ts.map +1 -0
  238. package/dist/types/components/hovercard/HoverCard.d.ts +10 -0
  239. package/dist/types/components/hovercard/HoverCard.d.ts.map +1 -0
  240. package/dist/types/components/input/Input.d.ts +15 -0
  241. package/dist/types/components/input/Input.d.ts.map +1 -0
  242. package/dist/types/components/layout/Container.d.ts +8 -0
  243. package/dist/types/components/layout/Container.d.ts.map +1 -0
  244. package/dist/types/components/layout/Flex.d.ts +14 -0
  245. package/dist/types/components/layout/Flex.d.ts.map +1 -0
  246. package/dist/types/components/layout/Grid.d.ts +10 -0
  247. package/dist/types/components/layout/Grid.d.ts.map +1 -0
  248. package/dist/types/components/layout/HStack.d.ts +8 -0
  249. package/dist/types/components/layout/HStack.d.ts.map +1 -0
  250. package/dist/types/components/layout/Stack.d.ts +8 -0
  251. package/dist/types/components/layout/Stack.d.ts.map +1 -0
  252. package/dist/types/components/megamenu/MegaMenu.d.ts +12 -0
  253. package/dist/types/components/megamenu/MegaMenu.d.ts.map +1 -0
  254. package/dist/types/components/modal/Modal.d.ts +16 -0
  255. package/dist/types/components/modal/Modal.d.ts.map +1 -0
  256. package/dist/types/components/pagination/Pagination.d.ts +9 -0
  257. package/dist/types/components/pagination/Pagination.d.ts.map +1 -0
  258. package/dist/types/components/popover/Popover.d.ts +21 -0
  259. package/dist/types/components/popover/Popover.d.ts.map +1 -0
  260. package/dist/types/components/progress/Progress.d.ts +13 -0
  261. package/dist/types/components/progress/Progress.d.ts.map +1 -0
  262. package/dist/types/components/radiogroup/RadioGroup.d.ts +18 -0
  263. package/dist/types/components/radiogroup/RadioGroup.d.ts.map +1 -0
  264. package/dist/types/components/rating/Rating.d.ts +19 -0
  265. package/dist/types/components/rating/Rating.d.ts.map +1 -0
  266. package/dist/types/components/select/Select.d.ts +20 -0
  267. package/dist/types/components/select/Select.d.ts.map +1 -0
  268. package/dist/types/components/skeleton/Skeleton.d.ts +44 -0
  269. package/dist/types/components/skeleton/Skeleton.d.ts.map +1 -0
  270. package/dist/types/components/slider/Slider.d.ts +13 -0
  271. package/dist/types/components/slider/Slider.d.ts.map +1 -0
  272. package/dist/types/components/spinner/Spinner.d.ts +7 -0
  273. package/dist/types/components/spinner/Spinner.d.ts.map +1 -0
  274. package/dist/types/components/stepper/Stepper.d.ts +12 -0
  275. package/dist/types/components/stepper/Stepper.d.ts.map +1 -0
  276. package/dist/types/components/switch/Switch.d.ts +15 -0
  277. package/dist/types/components/switch/Switch.d.ts.map +1 -0
  278. package/dist/types/components/table/Table.d.ts +14 -0
  279. package/dist/types/components/table/Table.d.ts.map +1 -0
  280. package/dist/types/components/tabs/Tabs.d.ts +14 -0
  281. package/dist/types/components/tabs/Tabs.d.ts.map +1 -0
  282. package/dist/types/components/textarea/Textarea.d.ts +14 -0
  283. package/dist/types/components/textarea/Textarea.d.ts.map +1 -0
  284. package/dist/types/components/toast/Toast.d.ts +16 -0
  285. package/dist/types/components/toast/Toast.d.ts.map +1 -0
  286. package/dist/types/components/tooltip/Tooltip.d.ts +10 -0
  287. package/dist/types/components/tooltip/Tooltip.d.ts.map +1 -0
  288. package/dist/types/components/treeview/TreeView.d.ts +16 -0
  289. package/dist/types/components/treeview/TreeView.d.ts.map +1 -0
  290. package/dist/types/components/virtuallist/VirtualList.d.ts +23 -0
  291. package/dist/types/components/virtuallist/VirtualList.d.ts.map +1 -0
  292. package/dist/types/index.d.ts +50 -0
  293. package/dist/types/index.d.ts.map +1 -0
  294. package/dist/types/theme/NUIProvider.d.ts +14 -0
  295. package/dist/types/theme/NUIProvider.d.ts.map +1 -0
  296. package/dist/types/theme/useTheme.d.ts +11 -0
  297. package/dist/types/theme/useTheme.d.ts.map +1 -0
  298. package/dist/types/utils/generateid/generateId.d.ts +2 -0
  299. package/dist/types/utils/generateid/generateId.d.ts.map +1 -0
  300. package/dist/types/utils/index.d.ts +9 -0
  301. package/dist/types/utils/index.d.ts.map +1 -0
  302. package/dist/types/utils/inertmanager/inertManager.d.ts +13 -0
  303. package/dist/types/utils/inertmanager/inertManager.d.ts.map +1 -0
  304. package/dist/types/utils/keyboardnav/keyboardNav.d.ts +11 -0
  305. package/dist/types/utils/keyboardnav/keyboardNav.d.ts.map +1 -0
  306. package/dist/types/utils/onclickoutside/onClickOutside.d.ts +3 -0
  307. package/dist/types/utils/onclickoutside/onClickOutside.d.ts.map +1 -0
  308. package/dist/types/utils/portal/portal.d.ts +4 -0
  309. package/dist/types/utils/portal/portal.d.ts.map +1 -0
  310. package/dist/types/utils/restorefocus/restoreFocus.d.ts +8 -0
  311. package/dist/types/utils/restorefocus/restoreFocus.d.ts.map +1 -0
  312. package/dist/types/utils/scrolllock/scrollLock.d.ts +11 -0
  313. package/dist/types/utils/scrolllock/scrollLock.d.ts.map +1 -0
  314. package/dist/types/utils/trapfocus/trapFocus.d.ts +8 -0
  315. package/dist/types/utils/trapfocus/trapFocus.d.ts.map +1 -0
  316. package/dist/utils/generateid/generateId.cjs +2 -0
  317. package/dist/utils/generateid/generateId.cjs.map +1 -0
  318. package/dist/utils/generateid/generateId.js +7 -0
  319. package/dist/utils/generateid/generateId.js.map +1 -0
  320. package/dist/utils/inertmanager/inertManager.cjs +2 -0
  321. package/dist/utils/inertmanager/inertManager.cjs.map +1 -0
  322. package/dist/utils/inertmanager/inertManager.js +18 -0
  323. package/dist/utils/inertmanager/inertManager.js.map +1 -0
  324. package/dist/utils/keyboardnav/keyboardNav.cjs +2 -0
  325. package/dist/utils/keyboardnav/keyboardNav.cjs.map +1 -0
  326. package/dist/utils/keyboardnav/keyboardNav.js +10 -0
  327. package/dist/utils/keyboardnav/keyboardNav.js.map +1 -0
  328. package/dist/utils/onclickoutside/onClickOutside.cjs +2 -0
  329. package/dist/utils/onclickoutside/onClickOutside.cjs.map +1 -0
  330. package/dist/utils/onclickoutside/onClickOutside.js +11 -0
  331. package/dist/utils/onclickoutside/onClickOutside.js.map +1 -0
  332. package/dist/utils/portal/portal.cjs +2 -0
  333. package/dist/utils/portal/portal.cjs.map +1 -0
  334. package/dist/utils/portal/portal.js +8 -0
  335. package/dist/utils/portal/portal.js.map +1 -0
  336. package/dist/utils/restorefocus/restoreFocus.cjs +2 -0
  337. package/dist/utils/restorefocus/restoreFocus.cjs.map +1 -0
  338. package/dist/utils/restorefocus/restoreFocus.js +7 -0
  339. package/dist/utils/restorefocus/restoreFocus.js.map +1 -0
  340. package/dist/utils/scrolllock/scrollLock.cjs +2 -0
  341. package/dist/utils/scrolllock/scrollLock.cjs.map +1 -0
  342. package/dist/utils/scrolllock/scrollLock.js +12 -0
  343. package/dist/utils/scrolllock/scrollLock.js.map +1 -0
  344. package/dist/utils/trapfocus/trapFocus.cjs +3 -0
  345. package/dist/utils/trapfocus/trapFocus.cjs.map +1 -0
  346. package/dist/utils/trapfocus/trapFocus.js +14 -0
  347. package/dist/utils/trapfocus/trapFocus.js.map +1 -0
  348. package/package.json +3 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Modal.cjs","sources":["../../../../src/components/modal/Modal.tsx"],"sourcesContent":["/**\r\n * Modal.tsx\r\n * ----------\r\n * Fully accessible, WCAG-compliant modal/dialog component.\r\n *\r\n * Features:\r\n * - Role-based WAI-ARIA dialog semantics\r\n * - aria-modal, aria-labelledby, aria-describedby\r\n * - Portal rendering into <body>\r\n * - ESC-to-close (optional)\r\n * - Click-outside-to-close (optional)\r\n * - Focus trap (Tab / Shift+Tab)\r\n * - Focus restore on close\r\n * - Scroll locking on open\r\n * - INERT background content (full compliance)\r\n * - prefers-reduced-motion support\r\n * - initial focus element support\r\n *\r\n * Zero dependencies — all logic is pure React.\r\n */\r\n\r\n/**\r\n * Modal.tsx (Lint Clean Version)\r\n * ------------------------------\r\n * All ESLint issues fixed:\r\n * - No missing dependencies\r\n * - No inline re-created functions\r\n * - No non-null assertions\r\n * - No unused values\r\n */\r\n\r\nimport React, { useEffect, useRef, useCallback } from 'react';\r\nimport './Modal.css';\r\n\r\nimport { trapFocus, onClickOutside, restoreFocus, scrollLock, Portal, applyInertToSiblings,\r\n removeInertFromSiblings } from '../../utils/index';\r\n\r\nexport interface ModalProps {\r\n open: boolean;\r\n onClose: () => void;\r\n\r\n title?: string;\r\n description?: string;\r\n\r\n labelledById?: string;\r\n describedById?: string;\r\n\r\n disableClickOutside?: boolean;\r\n disableEsc?: boolean;\r\n\r\n initialFocusRef?: React.RefObject<HTMLElement>;\r\n\r\n className?: string;\r\n children?: React.ReactNode;\r\n}\r\n\r\nlet idCounter = 0;\r\nconst nextId = (prefix: string) => {\r\n idCounter += 1;\r\n return `${prefix}-${idCounter}`;\r\n};\r\n\r\nexport function Modal({\r\n open,\r\n onClose,\r\n title,\r\n description,\r\n labelledById,\r\n describedById,\r\n disableClickOutside = false,\r\n disableEsc = false,\r\n initialFocusRef,\r\n className = '',\r\n children,\r\n}: ModalProps) {\r\n const overlayRef = useRef<HTMLDivElement | null>(null);\r\n const dialogRef = useRef<HTMLDivElement | null>(null);\r\n\r\n const previouslyFocusedElementRef = useRef<HTMLElement | null>(null);\r\n\r\n // Stable IDs (do NOT regenerate each render)\r\n const internalTitleId = useRef(\r\n labelledById || (title ? nextId('modal-title') : undefined)\r\n );\r\n\r\n const internalDescId = useRef(\r\n describedById || (description ? nextId('modal-desc') : undefined)\r\n );\r\n\r\n const titleId = internalTitleId.current;\r\n const descId = internalDescId.current;\r\n\r\n /**\r\n * Make onClose stable using useCallback\r\n */\r\n const handleClose = useCallback(() => {\r\n onClose();\r\n }, [onClose]);\r\n\r\n /**\r\n * ESC close handling\r\n */\r\n useEffect(() => {\r\n if (!open || disableEsc) return;\r\n\r\n const onKey = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') {\r\n e.preventDefault();\r\n handleClose();\r\n }\r\n };\r\n\r\n document.addEventListener('keydown', onKey);\r\n return () => document.removeEventListener('keydown', onKey);\r\n }, [open, disableEsc, handleClose]);\r\n\r\n /**\r\n * Main open/close lifecycle\r\n */\r\n useEffect(() => {\r\n if (!open) return;\r\n\r\n // Save previously focused element\r\n previouslyFocusedElementRef.current = document.activeElement as HTMLElement;\r\n\r\n // Lock scroll\r\n scrollLock.lock();\r\n\r\n // Make background inert\r\n const inertTargets = overlayRef.current\r\n ? applyInertToSiblings(overlayRef.current)\r\n : [];\r\n\r\n // Initial focus\r\n if (\r\n initialFocusRef?.current &&\r\n dialogRef.current?.contains(initialFocusRef.current)\r\n ) {\r\n initialFocusRef.current.focus();\r\n }\r\n\r\n // Focus trap\r\n const trapCleanup = dialogRef.current\r\n ? trapFocus(dialogRef.current)\r\n : undefined;\r\n\r\n // Click outside\r\n let clickOutsideCleanup: (() => void) | undefined;\r\n if (!disableClickOutside && dialogRef.current) {\r\n clickOutsideCleanup = onClickOutside(dialogRef, handleClose);\r\n }\r\n\r\n return () => {\r\n clickOutsideCleanup?.();\r\n trapCleanup?.();\r\n scrollLock.unlock();\r\n removeInertFromSiblings(inertTargets);\r\n restoreFocus(previouslyFocusedElementRef.current);\r\n };\r\n }, [open, disableClickOutside, handleClose, initialFocusRef]);\r\n\r\n if (!open) return null;\r\n\r\n return (\r\n <Portal>\r\n <div ref={overlayRef} className=\"ui-modal-overlay\" aria-hidden=\"false\">\r\n <div\r\n ref={dialogRef}\r\n className={`ui-modal-container ${className}`}\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n aria-labelledby={titleId}\r\n aria-describedby={descId}\r\n tabIndex={-1}\r\n onClick={(e) => e.stopPropagation()}\r\n >\r\n {title && (\r\n <div id={titleId} className=\"ui-modal-title\">\r\n {title}\r\n </div>\r\n )}\r\n\r\n {description && (\r\n <div id={descId} className=\"ui-modal-description\">\r\n {description}\r\n </div>\r\n )}\r\n\r\n <div className=\"ui-modal-content\">{children}</div>\r\n\r\n <button\r\n type=\"button\"\r\n aria-label=\"Close dialog\"\r\n className=\"ui-modal-close\"\r\n onClick={handleClose}\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n {!disableClickOutside && (\r\n <button\r\n aria-hidden=\"true\"\r\n className=\"ui-modal-overlay-catcher\"\r\n onClick={handleClose}\r\n tabIndex={-1}\r\n />\r\n )}\r\n </div>\r\n </Portal>\r\n );\r\n}\r\n"],"names":["idCounter","nextId","prefix","Modal","open","onClose","title","description","labelledById","describedById","disableClickOutside","disableEsc","initialFocusRef","className","children","overlayRef","useRef","dialogRef","previouslyFocusedElementRef","internalTitleId","internalDescId","titleId","descId","handleClose","useCallback","useEffect","onKey","e","scrollLock","inertTargets","applyInertToSiblings","trapCleanup","trapFocus","clickOutsideCleanup","onClickOutside","removeInertFromSiblings","restoreFocus","jsx","Portal","jsxs"],"mappings":"ieAwDA,IAAIA,EAAY,EAChB,MAAMC,EAAUC,IACdF,GAAa,EACN,GAAGE,CAAM,IAAIF,CAAS,IAGxB,SAASG,EAAM,CACpB,KAAAC,EACA,QAAAC,EACA,MAAAC,EACA,YAAAC,EACA,aAAAC,EACA,cAAAC,EACA,oBAAAC,EAAsB,GACtB,WAAAC,EAAa,GACb,gBAAAC,EACA,UAAAC,EAAY,GACZ,SAAAC,CACF,EAAe,CACb,MAAMC,EAAaC,EAAAA,OAA8B,IAAI,EAC/CC,EAAYD,EAAAA,OAA8B,IAAI,EAE9CE,EAA8BF,EAAAA,OAA2B,IAAI,EAG7DG,EAAkBH,EAAAA,OACtBR,IAAiBF,EAAQL,EAAO,aAAa,EAAI,OAAA,EAG7CmB,EAAiBJ,EAAAA,OACrBP,IAAkBF,EAAcN,EAAO,YAAY,EAAI,OAAA,EAGnDoB,EAAUF,EAAgB,QAC1BG,EAASF,EAAe,QAKxBG,EAAcC,EAAAA,YAAY,IAAM,CACpCnB,EAAA,CACF,EAAG,CAACA,CAAO,CAAC,EAgEZ,OA3DAoB,EAAAA,UAAU,IAAM,CACd,GAAI,CAACrB,GAAQO,EAAY,OAEzB,MAAMe,EAASC,GAAqB,CAC9BA,EAAE,MAAQ,WACZA,EAAE,eAAA,EACFJ,EAAA,EAEJ,EAEA,gBAAS,iBAAiB,UAAWG,CAAK,EACnC,IAAM,SAAS,oBAAoB,UAAWA,CAAK,CAC5D,EAAG,CAACtB,EAAMO,EAAYY,CAAW,CAAC,EAKlCE,EAAAA,UAAU,IAAM,CACd,GAAI,CAACrB,EAAM,OAGXc,EAA4B,QAAU,SAAS,cAG/CU,EAAAA,WAAW,KAAA,EAGX,MAAMC,EAAed,EAAW,QAC5Be,EAAAA,qBAAqBf,EAAW,OAAO,EACvC,CAAA,EAIFH,GAAiB,SACjBK,EAAU,SAAS,SAASL,EAAgB,OAAO,GAEnDA,EAAgB,QAAQ,MAAA,EAI1B,MAAMmB,EAAcd,EAAU,QAC1Be,EAAAA,UAAUf,EAAU,OAAO,EAC3B,OAGJ,IAAIgB,EACJ,MAAI,CAACvB,GAAuBO,EAAU,UACpCgB,EAAsBC,EAAAA,eAAejB,EAAWM,CAAW,GAGtD,IAAM,CACXU,IAAA,EACAF,IAAA,EACAH,EAAAA,WAAW,OAAA,EACXO,EAAAA,wBAAwBN,CAAY,EACpCO,EAAAA,aAAalB,EAA4B,OAAO,CAClD,CACF,EAAG,CAACd,EAAMM,EAAqBa,EAAaX,CAAe,CAAC,EAEvDR,EAGHiC,EAAAA,IAACC,EAAAA,QACC,SAAAC,EAAAA,KAAC,MAAA,CAAI,IAAKxB,EAAY,UAAU,mBAAmB,cAAY,QAC7D,SAAA,CAAAwB,EAAAA,KAAC,MAAA,CACC,IAAKtB,EACL,UAAW,sBAAsBJ,CAAS,GAC1C,KAAK,SACL,aAAW,OACX,kBAAiBQ,EACjB,mBAAkBC,EAClB,SAAU,GACV,QAAUK,GAAMA,EAAE,gBAAA,EAEjB,SAAA,CAAArB,SACE,MAAA,CAAI,GAAIe,EAAS,UAAU,iBACzB,SAAAf,EACH,EAGDC,GACC8B,EAAAA,IAAC,MAAA,CAAI,GAAIf,EAAQ,UAAU,uBACxB,SAAAf,EACH,EAGF8B,EAAAA,IAAC,MAAA,CAAI,UAAU,mBAAoB,SAAAvB,CAAA,CAAS,EAE5CuB,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,aAAW,eACX,UAAU,iBACV,QAASd,EACV,SAAA,GAAA,CAAA,CAED,CAAA,CAAA,EAGD,CAACb,GACA2B,EAAAA,IAAC,SAAA,CACC,cAAY,OACZ,UAAU,2BACV,QAASd,EACT,SAAU,EAAA,CAAA,CACZ,CAAA,CAEJ,CAAA,CACF,EAhDgB,IAkDpB"}
@@ -0,0 +1,91 @@
1
+ import { jsx as o, jsxs as h } from "react/jsx-runtime";
2
+ import { useRef as l, useCallback as j, useEffect as k } from "react";
3
+ /* empty css */
4
+ import { scrollLock as I } from "../../utils/scrolllock/scrollLock.js";
5
+ import { applyInertToSiblings as w, removeInertFromSiblings as D } from "../../utils/inertmanager/inertManager.js";
6
+ import { trapFocus as P } from "../../utils/trapfocus/trapFocus.js";
7
+ import { onClickOutside as S } from "../../utils/onclickoutside/onClickOutside.js";
8
+ import { restoreFocus as F } from "../../utils/restorefocus/restoreFocus.js";
9
+ import { Portal as K } from "../../utils/portal/portal.js";
10
+ let g = 0;
11
+ const C = (e) => (g += 1, `${e}-${g}`);
12
+ function O({
13
+ open: e,
14
+ onClose: m,
15
+ title: i,
16
+ description: d,
17
+ labelledById: N,
18
+ describedById: x,
19
+ disableClickOutside: u = !1,
20
+ disableEsc: f = !1,
21
+ initialFocusRef: a,
22
+ className: E = "",
23
+ children: L
24
+ }) {
25
+ const s = l(null), r = l(null), v = l(null), T = l(
26
+ N || (i ? C("modal-title") : void 0)
27
+ ), $ = l(
28
+ x || (d ? C("modal-desc") : void 0)
29
+ ), p = T.current, y = $.current, t = j(() => {
30
+ m();
31
+ }, [m]);
32
+ return k(() => {
33
+ if (!e || f) return;
34
+ const n = (c) => {
35
+ c.key === "Escape" && (c.preventDefault(), t());
36
+ };
37
+ return document.addEventListener("keydown", n), () => document.removeEventListener("keydown", n);
38
+ }, [e, f, t]), k(() => {
39
+ if (!e) return;
40
+ v.current = document.activeElement, I.lock();
41
+ const n = s.current ? w(s.current) : [];
42
+ a?.current && r.current?.contains(a.current) && a.current.focus();
43
+ const c = r.current ? P(r.current) : void 0;
44
+ let b;
45
+ return !u && r.current && (b = S(r, t)), () => {
46
+ b?.(), c?.(), I.unlock(), D(n), F(v.current);
47
+ };
48
+ }, [e, u, t, a]), e ? /* @__PURE__ */ o(K, { children: /* @__PURE__ */ h("div", { ref: s, className: "ui-modal-overlay", "aria-hidden": "false", children: [
49
+ /* @__PURE__ */ h(
50
+ "div",
51
+ {
52
+ ref: r,
53
+ className: `ui-modal-container ${E}`,
54
+ role: "dialog",
55
+ "aria-modal": "true",
56
+ "aria-labelledby": p,
57
+ "aria-describedby": y,
58
+ tabIndex: -1,
59
+ onClick: (n) => n.stopPropagation(),
60
+ children: [
61
+ i && /* @__PURE__ */ o("div", { id: p, className: "ui-modal-title", children: i }),
62
+ d && /* @__PURE__ */ o("div", { id: y, className: "ui-modal-description", children: d }),
63
+ /* @__PURE__ */ o("div", { className: "ui-modal-content", children: L }),
64
+ /* @__PURE__ */ o(
65
+ "button",
66
+ {
67
+ type: "button",
68
+ "aria-label": "Close dialog",
69
+ className: "ui-modal-close",
70
+ onClick: t,
71
+ children: "×"
72
+ }
73
+ )
74
+ ]
75
+ }
76
+ ),
77
+ !u && /* @__PURE__ */ o(
78
+ "button",
79
+ {
80
+ "aria-hidden": "true",
81
+ className: "ui-modal-overlay-catcher",
82
+ onClick: t,
83
+ tabIndex: -1
84
+ }
85
+ )
86
+ ] }) }) : null;
87
+ }
88
+ export {
89
+ O as Modal
90
+ };
91
+ //# sourceMappingURL=Modal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Modal.js","sources":["../../../../src/components/modal/Modal.tsx"],"sourcesContent":["/**\r\n * Modal.tsx\r\n * ----------\r\n * Fully accessible, WCAG-compliant modal/dialog component.\r\n *\r\n * Features:\r\n * - Role-based WAI-ARIA dialog semantics\r\n * - aria-modal, aria-labelledby, aria-describedby\r\n * - Portal rendering into <body>\r\n * - ESC-to-close (optional)\r\n * - Click-outside-to-close (optional)\r\n * - Focus trap (Tab / Shift+Tab)\r\n * - Focus restore on close\r\n * - Scroll locking on open\r\n * - INERT background content (full compliance)\r\n * - prefers-reduced-motion support\r\n * - initial focus element support\r\n *\r\n * Zero dependencies — all logic is pure React.\r\n */\r\n\r\n/**\r\n * Modal.tsx (Lint Clean Version)\r\n * ------------------------------\r\n * All ESLint issues fixed:\r\n * - No missing dependencies\r\n * - No inline re-created functions\r\n * - No non-null assertions\r\n * - No unused values\r\n */\r\n\r\nimport React, { useEffect, useRef, useCallback } from 'react';\r\nimport './Modal.css';\r\n\r\nimport { trapFocus, onClickOutside, restoreFocus, scrollLock, Portal, applyInertToSiblings,\r\n removeInertFromSiblings } from '../../utils/index';\r\n\r\nexport interface ModalProps {\r\n open: boolean;\r\n onClose: () => void;\r\n\r\n title?: string;\r\n description?: string;\r\n\r\n labelledById?: string;\r\n describedById?: string;\r\n\r\n disableClickOutside?: boolean;\r\n disableEsc?: boolean;\r\n\r\n initialFocusRef?: React.RefObject<HTMLElement>;\r\n\r\n className?: string;\r\n children?: React.ReactNode;\r\n}\r\n\r\nlet idCounter = 0;\r\nconst nextId = (prefix: string) => {\r\n idCounter += 1;\r\n return `${prefix}-${idCounter}`;\r\n};\r\n\r\nexport function Modal({\r\n open,\r\n onClose,\r\n title,\r\n description,\r\n labelledById,\r\n describedById,\r\n disableClickOutside = false,\r\n disableEsc = false,\r\n initialFocusRef,\r\n className = '',\r\n children,\r\n}: ModalProps) {\r\n const overlayRef = useRef<HTMLDivElement | null>(null);\r\n const dialogRef = useRef<HTMLDivElement | null>(null);\r\n\r\n const previouslyFocusedElementRef = useRef<HTMLElement | null>(null);\r\n\r\n // Stable IDs (do NOT regenerate each render)\r\n const internalTitleId = useRef(\r\n labelledById || (title ? nextId('modal-title') : undefined)\r\n );\r\n\r\n const internalDescId = useRef(\r\n describedById || (description ? nextId('modal-desc') : undefined)\r\n );\r\n\r\n const titleId = internalTitleId.current;\r\n const descId = internalDescId.current;\r\n\r\n /**\r\n * Make onClose stable using useCallback\r\n */\r\n const handleClose = useCallback(() => {\r\n onClose();\r\n }, [onClose]);\r\n\r\n /**\r\n * ESC close handling\r\n */\r\n useEffect(() => {\r\n if (!open || disableEsc) return;\r\n\r\n const onKey = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') {\r\n e.preventDefault();\r\n handleClose();\r\n }\r\n };\r\n\r\n document.addEventListener('keydown', onKey);\r\n return () => document.removeEventListener('keydown', onKey);\r\n }, [open, disableEsc, handleClose]);\r\n\r\n /**\r\n * Main open/close lifecycle\r\n */\r\n useEffect(() => {\r\n if (!open) return;\r\n\r\n // Save previously focused element\r\n previouslyFocusedElementRef.current = document.activeElement as HTMLElement;\r\n\r\n // Lock scroll\r\n scrollLock.lock();\r\n\r\n // Make background inert\r\n const inertTargets = overlayRef.current\r\n ? applyInertToSiblings(overlayRef.current)\r\n : [];\r\n\r\n // Initial focus\r\n if (\r\n initialFocusRef?.current &&\r\n dialogRef.current?.contains(initialFocusRef.current)\r\n ) {\r\n initialFocusRef.current.focus();\r\n }\r\n\r\n // Focus trap\r\n const trapCleanup = dialogRef.current\r\n ? trapFocus(dialogRef.current)\r\n : undefined;\r\n\r\n // Click outside\r\n let clickOutsideCleanup: (() => void) | undefined;\r\n if (!disableClickOutside && dialogRef.current) {\r\n clickOutsideCleanup = onClickOutside(dialogRef, handleClose);\r\n }\r\n\r\n return () => {\r\n clickOutsideCleanup?.();\r\n trapCleanup?.();\r\n scrollLock.unlock();\r\n removeInertFromSiblings(inertTargets);\r\n restoreFocus(previouslyFocusedElementRef.current);\r\n };\r\n }, [open, disableClickOutside, handleClose, initialFocusRef]);\r\n\r\n if (!open) return null;\r\n\r\n return (\r\n <Portal>\r\n <div ref={overlayRef} className=\"ui-modal-overlay\" aria-hidden=\"false\">\r\n <div\r\n ref={dialogRef}\r\n className={`ui-modal-container ${className}`}\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n aria-labelledby={titleId}\r\n aria-describedby={descId}\r\n tabIndex={-1}\r\n onClick={(e) => e.stopPropagation()}\r\n >\r\n {title && (\r\n <div id={titleId} className=\"ui-modal-title\">\r\n {title}\r\n </div>\r\n )}\r\n\r\n {description && (\r\n <div id={descId} className=\"ui-modal-description\">\r\n {description}\r\n </div>\r\n )}\r\n\r\n <div className=\"ui-modal-content\">{children}</div>\r\n\r\n <button\r\n type=\"button\"\r\n aria-label=\"Close dialog\"\r\n className=\"ui-modal-close\"\r\n onClick={handleClose}\r\n >\r\n ×\r\n </button>\r\n </div>\r\n\r\n {!disableClickOutside && (\r\n <button\r\n aria-hidden=\"true\"\r\n className=\"ui-modal-overlay-catcher\"\r\n onClick={handleClose}\r\n tabIndex={-1}\r\n />\r\n )}\r\n </div>\r\n </Portal>\r\n );\r\n}\r\n"],"names":["idCounter","nextId","prefix","Modal","open","onClose","title","description","labelledById","describedById","disableClickOutside","disableEsc","initialFocusRef","className","children","overlayRef","useRef","dialogRef","previouslyFocusedElementRef","internalTitleId","internalDescId","titleId","descId","handleClose","useCallback","useEffect","onKey","e","scrollLock","inertTargets","applyInertToSiblings","trapCleanup","trapFocus","clickOutsideCleanup","onClickOutside","removeInertFromSiblings","restoreFocus","jsx","Portal","jsxs"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime");;/* empty css */function f({page:n,total:a,onChange:u,siblings:r=1,className:c=""}){if(a<=1)return null;const t=i=>{i<1||i>a||u(i)},e=[],l=n-r>2,o=n+r<a-1,h=Math.max(1,n-r),d=Math.min(a,n+r);e.push(1),l&&e.push("...");for(let i=h;i<=d;i++)i!==1&&i!==a&&e.push(i);return o&&e.push("..."),a>1&&e.push(a),s.jsxs("nav",{className:`ui-pagination ${c}`,"aria-label":"Pagination Navigation",children:[s.jsx("button",{className:"ui-page-btn",onClick:()=>t(n-1),disabled:n===1,"aria-label":"Previous Page",children:"←"}),e.map((i,b)=>i==="..."?s.jsx("span",{className:"ui-page-ellipsis",children:"…"},`ellipsis-${b}`):s.jsx("button",{className:`ui-page-btn ${i===n?"active":""}`,"aria-current":i===n?"page":void 0,onClick:()=>t(i),children:i},`page-${i}`)),s.jsx("button",{className:"ui-page-btn",onClick:()=>t(n+1),disabled:n===a,"aria-label":"Next Page",children:"→"})]})}exports.Pagination=f;
2
+ //# sourceMappingURL=Pagination.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pagination.cjs","sources":["../../../../src/components/pagination/Pagination.tsx"],"sourcesContent":["/**\r\n * Pagination.tsx\r\n * -----------------\r\n * WAI-ARIA compliant pagination component.\r\n *\r\n * Features:\r\n * - First / Prev / Next / Last controls\r\n * - Arrow key navigation\r\n * - Controlled + fully typed\r\n * - Accessible roles & labels\r\n * - Works with screen readers\r\n * - Theme-aware classes only (no inline styles)\r\n */\r\n\r\n/**\r\n * Pagination.tsx — FINAL VERSION\r\n * --------------------------------\r\n * - No duplicate keys\r\n * - GitHub-style gap rendering\r\n * - Clean, predictable page logic\r\n * - Fully accessible\r\n * - No external dependencies\r\n */\r\n\r\nimport './Pagination.css';\r\n\r\nexport interface PaginationProps {\r\n page: number; // current page (1-based)\r\n total: number; // total pages\r\n onChange: (p: number) => void;\r\n siblings?: number; // how many pages to show around active page\r\n className?: string;\r\n}\r\n\r\nexport function Pagination({\r\n page,\r\n total,\r\n onChange,\r\n siblings = 1,\r\n className = '',\r\n}: PaginationProps) {\r\n if (total <= 1) return null;\r\n\r\n const goTo = (p: number) => {\r\n if (p < 1 || p > total) return;\r\n onChange(p);\r\n };\r\n\r\n /* -------------------------------------------------------\r\n * Page calculation (no duplicates, GitHub-style)\r\n * ------------------------------------------------------*/\r\n\r\n const pages: (number | '...')[] = [];\r\n\r\n const hasLeftGap = page - siblings > 2;\r\n const hasRightGap = page + siblings < total - 1;\r\n\r\n const start = Math.max(1, page - siblings);\r\n const end = Math.min(total, page + siblings);\r\n\r\n // Always add first page\r\n pages.push(1);\r\n\r\n // Left gap …\r\n if (hasLeftGap) pages.push('...');\r\n\r\n // Middle pages\r\n for (let i = start; i <= end; i++) {\r\n if (i !== 1 && i !== total) {\r\n pages.push(i);\r\n }\r\n }\r\n\r\n // Right gap …\r\n if (hasRightGap) pages.push('...');\r\n\r\n // Always add last page\r\n if (total > 1) pages.push(total);\r\n\r\n return (\r\n <nav\r\n className={`ui-pagination ${className}`}\r\n aria-label=\"Pagination Navigation\"\r\n >\r\n {/* Previous */}\r\n <button\r\n className=\"ui-page-btn\"\r\n onClick={() => goTo(page - 1)}\r\n disabled={page === 1}\r\n aria-label=\"Previous Page\"\r\n >\r\n ←\r\n </button>\r\n\r\n {/* Pages */}\r\n {pages.map((p, i) =>\r\n p === '...' ? (\r\n <span key={`ellipsis-${i}`} className=\"ui-page-ellipsis\">\r\n …\r\n </span>\r\n ) : (\r\n <button\r\n key={`page-${p}`}\r\n className={`ui-page-btn ${p === page ? 'active' : ''}`}\r\n aria-current={p === page ? 'page' : undefined}\r\n onClick={() => goTo(p)}\r\n >\r\n {p}\r\n </button>\r\n )\r\n )}\r\n\r\n {/* Next */}\r\n <button\r\n className=\"ui-page-btn\"\r\n onClick={() => goTo(page + 1)}\r\n disabled={page === total}\r\n aria-label=\"Next Page\"\r\n >\r\n →\r\n </button>\r\n </nav>\r\n );\r\n}\r\n"],"names":["Pagination","page","total","onChange","siblings","className","goTo","p","pages","hasLeftGap","hasRightGap","start","end","jsxs","jsx","i"],"mappings":"qJAkCO,SAASA,EAAW,CACzB,KAAAC,EACA,MAAAC,EACA,SAAAC,EACA,SAAAC,EAAW,EACX,UAAAC,EAAY,EACd,EAAoB,CAClB,GAAIH,GAAS,EAAG,OAAO,KAEvB,MAAMI,EAAQC,GAAc,CACtBA,EAAI,GAAKA,EAAIL,GACjBC,EAASI,CAAC,CACZ,EAMMC,EAA4B,CAAA,EAE5BC,EAAaR,EAAOG,EAAW,EAC/BM,EAAcT,EAAOG,EAAWF,EAAQ,EAExCS,EAAQ,KAAK,IAAI,EAAGV,EAAOG,CAAQ,EACnCQ,EAAM,KAAK,IAAIV,EAAOD,EAAOG,CAAQ,EAG3CI,EAAM,KAAK,CAAC,EAGRC,GAAYD,EAAM,KAAK,KAAK,EAGhC,QAAS,EAAIG,EAAO,GAAKC,EAAK,IACxB,IAAM,GAAK,IAAMV,GACnBM,EAAM,KAAK,CAAC,EAKhB,OAAIE,GAAaF,EAAM,KAAK,KAAK,EAG7BN,EAAQ,GAAGM,EAAM,KAAKN,CAAK,EAG7BW,EAAAA,KAAC,MAAA,CACC,UAAW,iBAAiBR,CAAS,GACrC,aAAW,wBAGX,SAAA,CAAAS,EAAAA,IAAC,SAAA,CACC,UAAU,cACV,QAAS,IAAMR,EAAKL,EAAO,CAAC,EAC5B,SAAUA,IAAS,EACnB,aAAW,gBACZ,SAAA,GAAA,CAAA,EAKAO,EAAM,IAAI,CAACD,EAAGQ,IACbR,IAAM,MACJO,EAAAA,IAAC,OAAA,CAA2B,UAAU,mBAAmB,SAAA,KAA9C,YAAYC,CAAC,EAExB,EAEAD,EAAAA,IAAC,SAAA,CAEC,UAAW,eAAeP,IAAMN,EAAO,SAAW,EAAE,GACpD,eAAcM,IAAMN,EAAO,OAAS,OACpC,QAAS,IAAMK,EAAKC,CAAC,EAEpB,SAAAA,CAAA,EALI,QAAQA,CAAC,EAAA,CAMhB,EAKJO,EAAAA,IAAC,SAAA,CACC,UAAU,cACV,QAAS,IAAMR,EAAKL,EAAO,CAAC,EAC5B,SAAUA,IAASC,EACnB,aAAW,YACZ,SAAA,GAAA,CAAA,CAED,CAAA,CAAA,CAGN"}
@@ -0,0 +1,62 @@
1
+ import { jsxs as f, jsx as r } from "react/jsx-runtime";
2
+ /* empty css */
3
+ function p({
4
+ page: a,
5
+ total: n,
6
+ onChange: t,
7
+ siblings: e = 1,
8
+ className: u = ""
9
+ }) {
10
+ if (n <= 1) return null;
11
+ const c = (i) => {
12
+ i < 1 || i > n || t(i);
13
+ }, s = [], o = a - e > 2, l = a + e < n - 1, h = Math.max(1, a - e), d = Math.min(n, a + e);
14
+ s.push(1), o && s.push("...");
15
+ for (let i = h; i <= d; i++)
16
+ i !== 1 && i !== n && s.push(i);
17
+ return l && s.push("..."), n > 1 && s.push(n), /* @__PURE__ */ f(
18
+ "nav",
19
+ {
20
+ className: `ui-pagination ${u}`,
21
+ "aria-label": "Pagination Navigation",
22
+ children: [
23
+ /* @__PURE__ */ r(
24
+ "button",
25
+ {
26
+ className: "ui-page-btn",
27
+ onClick: () => c(a - 1),
28
+ disabled: a === 1,
29
+ "aria-label": "Previous Page",
30
+ children: "←"
31
+ }
32
+ ),
33
+ s.map(
34
+ (i, m) => i === "..." ? /* @__PURE__ */ r("span", { className: "ui-page-ellipsis", children: "…" }, `ellipsis-${m}`) : /* @__PURE__ */ r(
35
+ "button",
36
+ {
37
+ className: `ui-page-btn ${i === a ? "active" : ""}`,
38
+ "aria-current": i === a ? "page" : void 0,
39
+ onClick: () => c(i),
40
+ children: i
41
+ },
42
+ `page-${i}`
43
+ )
44
+ ),
45
+ /* @__PURE__ */ r(
46
+ "button",
47
+ {
48
+ className: "ui-page-btn",
49
+ onClick: () => c(a + 1),
50
+ disabled: a === n,
51
+ "aria-label": "Next Page",
52
+ children: "→"
53
+ }
54
+ )
55
+ ]
56
+ }
57
+ );
58
+ }
59
+ export {
60
+ p as Pagination
61
+ };
62
+ //# sourceMappingURL=Pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pagination.js","sources":["../../../../src/components/pagination/Pagination.tsx"],"sourcesContent":["/**\r\n * Pagination.tsx\r\n * -----------------\r\n * WAI-ARIA compliant pagination component.\r\n *\r\n * Features:\r\n * - First / Prev / Next / Last controls\r\n * - Arrow key navigation\r\n * - Controlled + fully typed\r\n * - Accessible roles & labels\r\n * - Works with screen readers\r\n * - Theme-aware classes only (no inline styles)\r\n */\r\n\r\n/**\r\n * Pagination.tsx — FINAL VERSION\r\n * --------------------------------\r\n * - No duplicate keys\r\n * - GitHub-style gap rendering\r\n * - Clean, predictable page logic\r\n * - Fully accessible\r\n * - No external dependencies\r\n */\r\n\r\nimport './Pagination.css';\r\n\r\nexport interface PaginationProps {\r\n page: number; // current page (1-based)\r\n total: number; // total pages\r\n onChange: (p: number) => void;\r\n siblings?: number; // how many pages to show around active page\r\n className?: string;\r\n}\r\n\r\nexport function Pagination({\r\n page,\r\n total,\r\n onChange,\r\n siblings = 1,\r\n className = '',\r\n}: PaginationProps) {\r\n if (total <= 1) return null;\r\n\r\n const goTo = (p: number) => {\r\n if (p < 1 || p > total) return;\r\n onChange(p);\r\n };\r\n\r\n /* -------------------------------------------------------\r\n * Page calculation (no duplicates, GitHub-style)\r\n * ------------------------------------------------------*/\r\n\r\n const pages: (number | '...')[] = [];\r\n\r\n const hasLeftGap = page - siblings > 2;\r\n const hasRightGap = page + siblings < total - 1;\r\n\r\n const start = Math.max(1, page - siblings);\r\n const end = Math.min(total, page + siblings);\r\n\r\n // Always add first page\r\n pages.push(1);\r\n\r\n // Left gap …\r\n if (hasLeftGap) pages.push('...');\r\n\r\n // Middle pages\r\n for (let i = start; i <= end; i++) {\r\n if (i !== 1 && i !== total) {\r\n pages.push(i);\r\n }\r\n }\r\n\r\n // Right gap …\r\n if (hasRightGap) pages.push('...');\r\n\r\n // Always add last page\r\n if (total > 1) pages.push(total);\r\n\r\n return (\r\n <nav\r\n className={`ui-pagination ${className}`}\r\n aria-label=\"Pagination Navigation\"\r\n >\r\n {/* Previous */}\r\n <button\r\n className=\"ui-page-btn\"\r\n onClick={() => goTo(page - 1)}\r\n disabled={page === 1}\r\n aria-label=\"Previous Page\"\r\n >\r\n ←\r\n </button>\r\n\r\n {/* Pages */}\r\n {pages.map((p, i) =>\r\n p === '...' ? (\r\n <span key={`ellipsis-${i}`} className=\"ui-page-ellipsis\">\r\n …\r\n </span>\r\n ) : (\r\n <button\r\n key={`page-${p}`}\r\n className={`ui-page-btn ${p === page ? 'active' : ''}`}\r\n aria-current={p === page ? 'page' : undefined}\r\n onClick={() => goTo(p)}\r\n >\r\n {p}\r\n </button>\r\n )\r\n )}\r\n\r\n {/* Next */}\r\n <button\r\n className=\"ui-page-btn\"\r\n onClick={() => goTo(page + 1)}\r\n disabled={page === total}\r\n aria-label=\"Next Page\"\r\n >\r\n →\r\n </button>\r\n </nav>\r\n );\r\n}\r\n"],"names":["Pagination","page","total","onChange","siblings","className","goTo","p","pages","hasLeftGap","hasRightGap","start","end","jsxs","jsx","i"],"mappings":";;AAkCO,SAASA,EAAW;AAAA,EACzB,MAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,WAAAC,IAAY;AACd,GAAoB;AAClB,MAAIH,KAAS,EAAG,QAAO;AAEvB,QAAMI,IAAO,CAACC,MAAc;AAC1B,IAAIA,IAAI,KAAKA,IAAIL,KACjBC,EAASI,CAAC;AAAA,EACZ,GAMMC,IAA4B,CAAA,GAE5BC,IAAaR,IAAOG,IAAW,GAC/BM,IAAcT,IAAOG,IAAWF,IAAQ,GAExCS,IAAQ,KAAK,IAAI,GAAGV,IAAOG,CAAQ,GACnCQ,IAAM,KAAK,IAAIV,GAAOD,IAAOG,CAAQ;AAG3C,EAAAI,EAAM,KAAK,CAAC,GAGRC,KAAYD,EAAM,KAAK,KAAK;AAGhC,WAAS,IAAIG,GAAO,KAAKC,GAAK;AAC5B,IAAI,MAAM,KAAK,MAAMV,KACnBM,EAAM,KAAK,CAAC;AAKhB,SAAIE,KAAaF,EAAM,KAAK,KAAK,GAG7BN,IAAQ,KAAGM,EAAM,KAAKN,CAAK,GAG7B,gBAAAW;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,iBAAiBR,CAAS;AAAA,MACrC,cAAW;AAAA,MAGX,UAAA;AAAA,QAAA,gBAAAS;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,SAAS,MAAMR,EAAKL,IAAO,CAAC;AAAA,YAC5B,UAAUA,MAAS;AAAA,YACnB,cAAW;AAAA,YACZ,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAKAO,EAAM;AAAA,UAAI,CAACD,GAAGQ,MACbR,MAAM,QACJ,gBAAAO,EAAC,QAAA,EAA2B,WAAU,oBAAmB,UAAA,OAA9C,YAAYC,CAAC,EAExB,IAEA,gBAAAD;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,WAAW,eAAeP,MAAMN,IAAO,WAAW,EAAE;AAAA,cACpD,gBAAcM,MAAMN,IAAO,SAAS;AAAA,cACpC,SAAS,MAAMK,EAAKC,CAAC;AAAA,cAEpB,UAAAA;AAAA,YAAA;AAAA,YALI,QAAQA,CAAC;AAAA,UAAA;AAAA,QAMhB;AAAA,QAKJ,gBAAAO;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,SAAS,MAAMR,EAAKL,IAAO,CAAC;AAAA,YAC5B,UAAUA,MAASC;AAAA,YACnB,cAAW;AAAA,YACZ,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAED;AAAA,IAAA;AAAA,EAAA;AAGN;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),o=require("react");;/* empty css */const m=require("../../utils/restorefocus/restoreFocus.cjs"),k=require("../../utils/trapfocus/trapFocus.cjs"),w=require("../../utils/onclickoutside/onClickOutside.cjs"),x=require("../../utils/portal/portal.cjs"),b=o.createContext(null);function g(){const s=o.useContext(b);if(!s)throw new Error("Popover components must be inside <Popover>");return s}function y({children:s}){const[c,r]=o.useState(!1),n=o.useRef(null),t=o.useRef(null),i=`popover-${o.useId()}`;return o.useEffect(()=>{c||m.restoreFocus(n.current)},[c]),a.jsx(b.Provider,{value:{open:c,setOpen:r,triggerRef:n,contentRef:t,contentId:i},children:a.jsx("div",{className:"ui-popover-root",children:s})})}function E({children:s,className:c=""}){const{open:r,setOpen:n,triggerRef:t,contentId:i}=g();return a.jsx("button",{ref:t,type:"button",className:`ui-popover-trigger ${c}`,"aria-haspopup":"dialog","aria-expanded":r,"aria-controls":r?i:void 0,onClick:u=>{u.stopPropagation(),n(l=>!l)},onKeyDown:u=>{u.key==="Escape"&&r&&(u.stopPropagation(),n(!1))},children:s})}function R({children:s,className:c="",placement:r="bottom",offset:n=8}){const{open:t,setOpen:i,triggerRef:u,contentRef:l,contentId:h}=g(),[P,C]=o.useState(null);return o.useEffect(()=>{if(t&&l.current)return k.trapFocus(l.current)},[t,l]),o.useEffect(()=>t?w.onClickOutside(l,()=>i(!1)):void 0,[t,i,l,u]),o.useEffect(()=>{if(!t)return;const e=p=>{p.key==="Escape"&&(p.stopPropagation(),i(!1))};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[t,i]),o.useLayoutEffect(()=>{if(!t||!u.current)return;const e=u.current.getBoundingClientRect(),p=window.scrollX,v=window.scrollY;let f=0,d=0;switch(r){case"bottom":f=e.bottom+n+v,d=e.left+e.width/2+p;break;case"top":f=e.top-n+v,d=e.left+e.width/2+p;break;case"left":f=e.top+e.height/2+v,d=e.left-n+p;break;case"right":f=e.top+e.height/2+v,d=e.right+n+p;break}C({top:f,left:d})},[t,r,n,u]),t?a.jsx(x.Portal,{children:a.jsx("div",{id:h,ref:l,role:"dialog","aria-modal":"true",className:`ui-popover-content ui-popover-${r} ${c}`,style:{position:"absolute",top:P?.top??0,left:P?.left??0},children:s})}):null}function j({children:s="Close",className:c=""}){const{setOpen:r}=g();return a.jsx("button",{type:"button",onClick:()=>r(!1),className:`ui-popover-close ${c}`,children:s})}exports.Popover=y;exports.PopoverClose=j;exports.PopoverContent=R;exports.PopoverTrigger=E;
2
+ //# sourceMappingURL=Popover.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Popover.cjs","sources":["../../../../src/components/popover/Popover.tsx"],"sourcesContent":["import React, {\r\n createContext,\r\n useContext,\r\n useRef,\r\n useEffect,\r\n useState,\r\n useLayoutEffect,\r\n useId,\r\n} from 'react';\r\n\r\nimport './Popover.css';\r\n\r\n// Import your existing utilities\r\n// Ensure these paths match your folder structure exactly!\r\nimport { Portal, onClickOutside, restoreFocus, trapFocus } from '../../utils/index'; \r\n\r\ntype Placement = 'top' | 'bottom' | 'left' | 'right';\r\n\r\nconst PopoverContext = createContext<{\r\n open: boolean;\r\n setOpen: React.Dispatch<React.SetStateAction<boolean>>;\r\n triggerRef: React.RefObject<HTMLElement | null>;\r\n contentRef: React.RefObject<HTMLDivElement | null>;\r\n contentId: string;\r\n} | null>(null);\r\n\r\nfunction usePopover() {\r\n const ctx = useContext(PopoverContext);\r\n if (!ctx) throw new Error('Popover components must be inside <Popover>');\r\n return ctx;\r\n}\r\n\r\n/* -------------------------------------------------------\r\n * Root\r\n * ------------------------------------------------------*/\r\nexport function Popover({ children }: { children: React.ReactNode }) {\r\n const [open, setOpen] = useState(false);\r\n const triggerRef = useRef<HTMLElement | null>(null);\r\n const contentRef = useRef<HTMLDivElement | null>(null);\r\n const contentId = `popover-${useId()}`;\r\n\r\n // Restore focus to trigger on close\r\n useEffect(() => {\r\n if (!open) {\r\n restoreFocus(triggerRef.current);\r\n }\r\n }, [open]);\r\n\r\n return (\r\n <PopoverContext.Provider\r\n value={{ open, setOpen, triggerRef, contentRef, contentId }}\r\n >\r\n {/* Wrapper ensures trigger stays in document flow */}\r\n <div className=\"ui-popover-root\">{children}</div>\r\n </PopoverContext.Provider>\r\n );\r\n}\r\n\r\n/* -------------------------------------------------------\r\n * Trigger\r\n * ------------------------------------------------------*/\r\nexport function PopoverTrigger({\r\n children,\r\n className = '',\r\n}: {\r\n children: React.ReactNode;\r\n className?: string;\r\n}) {\r\n const { open, setOpen, triggerRef, contentId } = usePopover();\r\n\r\n return (\r\n <button\r\n ref={triggerRef as React.RefObject<HTMLButtonElement>}\r\n type=\"button\"\r\n className={`ui-popover-trigger ${className}`}\r\n aria-haspopup=\"dialog\"\r\n aria-expanded={open}\r\n aria-controls={open ? contentId : undefined}\r\n onClick={(e) => {\r\n // Stop propagation to prevent immediate close by external listeners\r\n e.stopPropagation();\r\n setOpen((s) => !s);\r\n }}\r\n onKeyDown={(e) => {\r\n if (e.key === 'Escape' && open) {\r\n e.stopPropagation();\r\n setOpen(false);\r\n }\r\n }}\r\n >\r\n {children}\r\n </button>\r\n );\r\n}\r\n\r\n/* -------------------------------------------------------\r\n * Content (Portaled & Positioned)\r\n * ------------------------------------------------------*/\r\nexport function PopoverContent({\r\n children,\r\n className = '',\r\n placement = 'bottom',\r\n offset = 8,\r\n}: {\r\n children: React.ReactNode;\r\n className?: string;\r\n placement?: Placement;\r\n offset?: number;\r\n}) {\r\n const { open, setOpen, triggerRef, contentRef, contentId } = usePopover();\r\n const [coords, setCoords] = useState<{ top: number; left: number } | null>(null);\r\n\r\n // 1. Trap Focus when open (FIXED RETURN TYPE)\r\n useEffect(() => {\r\n if (open && contentRef.current) {\r\n // Return the cleanup function from trapFocus\r\n return trapFocus(contentRef.current);\r\n }\r\n // Explicitly return undefined so TS knows we handled the \"else\" case\r\n return undefined;\r\n }, [open, contentRef]);\r\n\r\n // 2. Click Outside Logic\r\n useEffect(() => {\r\n if (!open) return;\r\n\r\n const cleanup = onClickOutside(contentRef, () => setOpen(false));\r\n return cleanup;\r\n }, [open, setOpen, contentRef, triggerRef]);\r\n\r\n // 3. Global Escape Key\r\n useEffect(() => {\r\n if (!open) return;\r\n const handler = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') {\r\n e.stopPropagation();\r\n setOpen(false);\r\n }\r\n };\r\n document.addEventListener('keydown', handler);\r\n return () => document.removeEventListener('keydown', handler);\r\n }, [open, setOpen]);\r\n\r\n // 4. Calculate Position\r\n useLayoutEffect(() => {\r\n if (!open || !triggerRef.current) return;\r\n\r\n const rect = triggerRef.current.getBoundingClientRect();\r\n const scrollX = window.scrollX;\r\n const scrollY = window.scrollY;\r\n\r\n let top = 0;\r\n let left = 0;\r\n\r\n switch (placement) {\r\n case 'bottom':\r\n top = rect.bottom + offset + scrollY;\r\n left = rect.left + (rect.width / 2) + scrollX;\r\n break;\r\n case 'top':\r\n top = rect.top - offset + scrollY;\r\n left = rect.left + (rect.width / 2) + scrollX;\r\n break;\r\n case 'left':\r\n top = rect.top + (rect.height / 2) + scrollY;\r\n left = rect.left - offset + scrollX;\r\n break;\r\n case 'right':\r\n top = rect.top + (rect.height / 2) + scrollY;\r\n left = rect.right + offset + scrollX;\r\n break;\r\n }\r\n\r\n setCoords({ top, left });\r\n }, [open, placement, offset, triggerRef]);\r\n\r\n if (!open) return null;\r\n\r\n return (\r\n <Portal>\r\n <div\r\n id={contentId}\r\n ref={contentRef}\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n className={`ui-popover-content ui-popover-${placement} ${className}`}\r\n style={{\r\n position: 'absolute',\r\n top: coords?.top ?? 0,\r\n left: coords?.left ?? 0,\r\n }}\r\n >\r\n {children}\r\n </div>\r\n </Portal>\r\n );\r\n}\r\n\r\n/* -------------------------------------------------------\r\n * Close Button\r\n * ------------------------------------------------------*/\r\nexport function PopoverClose({\r\n children = 'Close',\r\n className = '',\r\n}: {\r\n children?: React.ReactNode;\r\n className?: string;\r\n}) {\r\n const { setOpen } = usePopover();\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={() => setOpen(false)}\r\n className={`ui-popover-close ${className}`}\r\n >\r\n {children}\r\n </button>\r\n );\r\n}"],"names":["PopoverContext","createContext","usePopover","ctx","useContext","Popover","children","open","setOpen","useState","triggerRef","useRef","contentRef","contentId","useId","useEffect","restoreFocus","jsx","PopoverTrigger","className","e","s","PopoverContent","placement","offset","coords","setCoords","trapFocus","onClickOutside","handler","useLayoutEffect","rect","scrollX","scrollY","top","left","Portal","PopoverClose"],"mappings":"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"}
@@ -0,0 +1,123 @@
1
+ import { jsx as l } from "react/jsx-runtime";
2
+ import { useState as b, useRef as h, useId as C, useEffect as m, createContext as y, useLayoutEffect as x, useContext as E } from "react";
3
+ /* empty css */
4
+ import { restoreFocus as R } from "../../utils/restorefocus/restoreFocus.js";
5
+ import { trapFocus as O } from "../../utils/trapfocus/trapFocus.js";
6
+ import { onClickOutside as $ } from "../../utils/onclickoutside/onClickOutside.js";
7
+ import { Portal as I } from "../../utils/portal/portal.js";
8
+ const P = y(null);
9
+ function v() {
10
+ const n = E(P);
11
+ if (!n) throw new Error("Popover components must be inside <Popover>");
12
+ return n;
13
+ }
14
+ function D({ children: n }) {
15
+ const [s, t] = b(!1), r = h(null), e = h(null), c = `popover-${C()}`;
16
+ return m(() => {
17
+ s || R(r.current);
18
+ }, [s]), /* @__PURE__ */ l(
19
+ P.Provider,
20
+ {
21
+ value: { open: s, setOpen: t, triggerRef: r, contentRef: e, contentId: c },
22
+ children: /* @__PURE__ */ l("div", { className: "ui-popover-root", children: n })
23
+ }
24
+ );
25
+ }
26
+ function K({
27
+ children: n,
28
+ className: s = ""
29
+ }) {
30
+ const { open: t, setOpen: r, triggerRef: e, contentId: c } = v();
31
+ return /* @__PURE__ */ l(
32
+ "button",
33
+ {
34
+ ref: e,
35
+ type: "button",
36
+ className: `ui-popover-trigger ${s}`,
37
+ "aria-haspopup": "dialog",
38
+ "aria-expanded": t,
39
+ "aria-controls": t ? c : void 0,
40
+ onClick: (i) => {
41
+ i.stopPropagation(), r((p) => !p);
42
+ },
43
+ onKeyDown: (i) => {
44
+ i.key === "Escape" && t && (i.stopPropagation(), r(!1));
45
+ },
46
+ children: n
47
+ }
48
+ );
49
+ }
50
+ function S({
51
+ children: n,
52
+ className: s = "",
53
+ placement: t = "bottom",
54
+ offset: r = 8
55
+ }) {
56
+ const { open: e, setOpen: c, triggerRef: i, contentRef: p, contentId: w } = v(), [g, k] = b(null);
57
+ return m(() => {
58
+ if (e && p.current)
59
+ return O(p.current);
60
+ }, [e, p]), m(() => e ? $(p, () => c(!1)) : void 0, [e, c, p, i]), m(() => {
61
+ if (!e) return;
62
+ const o = (u) => {
63
+ u.key === "Escape" && (u.stopPropagation(), c(!1));
64
+ };
65
+ return document.addEventListener("keydown", o), () => document.removeEventListener("keydown", o);
66
+ }, [e, c]), x(() => {
67
+ if (!e || !i.current) return;
68
+ const o = i.current.getBoundingClientRect(), u = window.scrollX, d = window.scrollY;
69
+ let a = 0, f = 0;
70
+ switch (t) {
71
+ case "bottom":
72
+ a = o.bottom + r + d, f = o.left + o.width / 2 + u;
73
+ break;
74
+ case "top":
75
+ a = o.top - r + d, f = o.left + o.width / 2 + u;
76
+ break;
77
+ case "left":
78
+ a = o.top + o.height / 2 + d, f = o.left - r + u;
79
+ break;
80
+ case "right":
81
+ a = o.top + o.height / 2 + d, f = o.right + r + u;
82
+ break;
83
+ }
84
+ k({ top: a, left: f });
85
+ }, [e, t, r, i]), e ? /* @__PURE__ */ l(I, { children: /* @__PURE__ */ l(
86
+ "div",
87
+ {
88
+ id: w,
89
+ ref: p,
90
+ role: "dialog",
91
+ "aria-modal": "true",
92
+ className: `ui-popover-content ui-popover-${t} ${s}`,
93
+ style: {
94
+ position: "absolute",
95
+ top: g?.top ?? 0,
96
+ left: g?.left ?? 0
97
+ },
98
+ children: n
99
+ }
100
+ ) }) : null;
101
+ }
102
+ function T({
103
+ children: n = "Close",
104
+ className: s = ""
105
+ }) {
106
+ const { setOpen: t } = v();
107
+ return /* @__PURE__ */ l(
108
+ "button",
109
+ {
110
+ type: "button",
111
+ onClick: () => t(!1),
112
+ className: `ui-popover-close ${s}`,
113
+ children: n
114
+ }
115
+ );
116
+ }
117
+ export {
118
+ D as Popover,
119
+ T as PopoverClose,
120
+ S as PopoverContent,
121
+ K as PopoverTrigger
122
+ };
123
+ //# sourceMappingURL=Popover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Popover.js","sources":["../../../../src/components/popover/Popover.tsx"],"sourcesContent":["import React, {\r\n createContext,\r\n useContext,\r\n useRef,\r\n useEffect,\r\n useState,\r\n useLayoutEffect,\r\n useId,\r\n} from 'react';\r\n\r\nimport './Popover.css';\r\n\r\n// Import your existing utilities\r\n// Ensure these paths match your folder structure exactly!\r\nimport { Portal, onClickOutside, restoreFocus, trapFocus } from '../../utils/index'; \r\n\r\ntype Placement = 'top' | 'bottom' | 'left' | 'right';\r\n\r\nconst PopoverContext = createContext<{\r\n open: boolean;\r\n setOpen: React.Dispatch<React.SetStateAction<boolean>>;\r\n triggerRef: React.RefObject<HTMLElement | null>;\r\n contentRef: React.RefObject<HTMLDivElement | null>;\r\n contentId: string;\r\n} | null>(null);\r\n\r\nfunction usePopover() {\r\n const ctx = useContext(PopoverContext);\r\n if (!ctx) throw new Error('Popover components must be inside <Popover>');\r\n return ctx;\r\n}\r\n\r\n/* -------------------------------------------------------\r\n * Root\r\n * ------------------------------------------------------*/\r\nexport function Popover({ children }: { children: React.ReactNode }) {\r\n const [open, setOpen] = useState(false);\r\n const triggerRef = useRef<HTMLElement | null>(null);\r\n const contentRef = useRef<HTMLDivElement | null>(null);\r\n const contentId = `popover-${useId()}`;\r\n\r\n // Restore focus to trigger on close\r\n useEffect(() => {\r\n if (!open) {\r\n restoreFocus(triggerRef.current);\r\n }\r\n }, [open]);\r\n\r\n return (\r\n <PopoverContext.Provider\r\n value={{ open, setOpen, triggerRef, contentRef, contentId }}\r\n >\r\n {/* Wrapper ensures trigger stays in document flow */}\r\n <div className=\"ui-popover-root\">{children}</div>\r\n </PopoverContext.Provider>\r\n );\r\n}\r\n\r\n/* -------------------------------------------------------\r\n * Trigger\r\n * ------------------------------------------------------*/\r\nexport function PopoverTrigger({\r\n children,\r\n className = '',\r\n}: {\r\n children: React.ReactNode;\r\n className?: string;\r\n}) {\r\n const { open, setOpen, triggerRef, contentId } = usePopover();\r\n\r\n return (\r\n <button\r\n ref={triggerRef as React.RefObject<HTMLButtonElement>}\r\n type=\"button\"\r\n className={`ui-popover-trigger ${className}`}\r\n aria-haspopup=\"dialog\"\r\n aria-expanded={open}\r\n aria-controls={open ? contentId : undefined}\r\n onClick={(e) => {\r\n // Stop propagation to prevent immediate close by external listeners\r\n e.stopPropagation();\r\n setOpen((s) => !s);\r\n }}\r\n onKeyDown={(e) => {\r\n if (e.key === 'Escape' && open) {\r\n e.stopPropagation();\r\n setOpen(false);\r\n }\r\n }}\r\n >\r\n {children}\r\n </button>\r\n );\r\n}\r\n\r\n/* -------------------------------------------------------\r\n * Content (Portaled & Positioned)\r\n * ------------------------------------------------------*/\r\nexport function PopoverContent({\r\n children,\r\n className = '',\r\n placement = 'bottom',\r\n offset = 8,\r\n}: {\r\n children: React.ReactNode;\r\n className?: string;\r\n placement?: Placement;\r\n offset?: number;\r\n}) {\r\n const { open, setOpen, triggerRef, contentRef, contentId } = usePopover();\r\n const [coords, setCoords] = useState<{ top: number; left: number } | null>(null);\r\n\r\n // 1. Trap Focus when open (FIXED RETURN TYPE)\r\n useEffect(() => {\r\n if (open && contentRef.current) {\r\n // Return the cleanup function from trapFocus\r\n return trapFocus(contentRef.current);\r\n }\r\n // Explicitly return undefined so TS knows we handled the \"else\" case\r\n return undefined;\r\n }, [open, contentRef]);\r\n\r\n // 2. Click Outside Logic\r\n useEffect(() => {\r\n if (!open) return;\r\n\r\n const cleanup = onClickOutside(contentRef, () => setOpen(false));\r\n return cleanup;\r\n }, [open, setOpen, contentRef, triggerRef]);\r\n\r\n // 3. Global Escape Key\r\n useEffect(() => {\r\n if (!open) return;\r\n const handler = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') {\r\n e.stopPropagation();\r\n setOpen(false);\r\n }\r\n };\r\n document.addEventListener('keydown', handler);\r\n return () => document.removeEventListener('keydown', handler);\r\n }, [open, setOpen]);\r\n\r\n // 4. Calculate Position\r\n useLayoutEffect(() => {\r\n if (!open || !triggerRef.current) return;\r\n\r\n const rect = triggerRef.current.getBoundingClientRect();\r\n const scrollX = window.scrollX;\r\n const scrollY = window.scrollY;\r\n\r\n let top = 0;\r\n let left = 0;\r\n\r\n switch (placement) {\r\n case 'bottom':\r\n top = rect.bottom + offset + scrollY;\r\n left = rect.left + (rect.width / 2) + scrollX;\r\n break;\r\n case 'top':\r\n top = rect.top - offset + scrollY;\r\n left = rect.left + (rect.width / 2) + scrollX;\r\n break;\r\n case 'left':\r\n top = rect.top + (rect.height / 2) + scrollY;\r\n left = rect.left - offset + scrollX;\r\n break;\r\n case 'right':\r\n top = rect.top + (rect.height / 2) + scrollY;\r\n left = rect.right + offset + scrollX;\r\n break;\r\n }\r\n\r\n setCoords({ top, left });\r\n }, [open, placement, offset, triggerRef]);\r\n\r\n if (!open) return null;\r\n\r\n return (\r\n <Portal>\r\n <div\r\n id={contentId}\r\n ref={contentRef}\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n className={`ui-popover-content ui-popover-${placement} ${className}`}\r\n style={{\r\n position: 'absolute',\r\n top: coords?.top ?? 0,\r\n left: coords?.left ?? 0,\r\n }}\r\n >\r\n {children}\r\n </div>\r\n </Portal>\r\n );\r\n}\r\n\r\n/* -------------------------------------------------------\r\n * Close Button\r\n * ------------------------------------------------------*/\r\nexport function PopoverClose({\r\n children = 'Close',\r\n className = '',\r\n}: {\r\n children?: React.ReactNode;\r\n className?: string;\r\n}) {\r\n const { setOpen } = usePopover();\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={() => setOpen(false)}\r\n className={`ui-popover-close ${className}`}\r\n >\r\n {children}\r\n </button>\r\n );\r\n}"],"names":["PopoverContext","createContext","usePopover","ctx","useContext","Popover","children","open","setOpen","useState","triggerRef","useRef","contentRef","contentId","useId","useEffect","restoreFocus","jsx","PopoverTrigger","className","e","s","PopoverContent","placement","offset","coords","setCoords","trapFocus","onClickOutside","handler","useLayoutEffect","rect","scrollX","scrollY","top","left","Portal","PopoverClose"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime");;/* empty css */function d({value:r,max:i=100,indeterminate:a=!1,label:o="Progress",className:t=""}){const e=a||r===void 0,n=Math.min(Math.max((r??0)/i,0),1)*100;return s.jsx("div",{className:`ui-progress ${t}`,role:"progressbar","aria-valuemin":e?void 0:0,"aria-valuemax":e?void 0:i,"aria-valuenow":e?void 0:r,"aria-label":o,children:s.jsx("div",{className:`ui-progress-bar ${e?"indeterminate":""}`,style:e?void 0:{width:`${n}%`}})})}exports.Progress=d;
2
+ //# sourceMappingURL=Progress.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Progress.cjs","sources":["../../../../src/components/progress/Progress.tsx"],"sourcesContent":["/**\r\n * Progress.tsx — FINAL VERSION\r\n * --------------------------------\r\n * Features:\r\n * - Determinate mode (value/max)\r\n * - Indeterminate mode\r\n * - Smooth animation\r\n * - ARIA compliant\r\n * - Pure TSX + CSS (no inline styles except width)\r\n */\r\n\r\nimport './Progress.css';\r\n\r\nexport interface ProgressProps {\r\n /** Current value (determinate mode). */\r\n value?: number;\r\n\r\n /** Maximum value (default: 100). */\r\n max?: number;\r\n\r\n /** Indeterminate mode when value is undefined. */\r\n indeterminate?: boolean;\r\n\r\n /** Optional label for screen readers. */\r\n label?: string;\r\n\r\n className?: string;\r\n}\r\n\r\nexport function Progress({\r\n value,\r\n max = 100,\r\n indeterminate = false,\r\n label = 'Progress',\r\n className = '',\r\n}: ProgressProps) {\r\n const isIndeterminate = indeterminate || value === undefined;\r\n\r\n const percentage = Math.min(Math.max((value ?? 0) / max, 0), 1) * 100;\r\n\r\n return (\r\n <div\r\n className={`ui-progress ${className}`}\r\n role=\"progressbar\"\r\n aria-valuemin={isIndeterminate ? undefined : 0}\r\n aria-valuemax={isIndeterminate ? undefined : max}\r\n aria-valuenow={isIndeterminate ? undefined : value}\r\n aria-label={label}\r\n >\r\n <div\r\n className={`ui-progress-bar ${isIndeterminate ? 'indeterminate' : ''}`}\r\n style={!isIndeterminate ? { width: `${percentage}%` } : undefined}\r\n />\r\n </div>\r\n );\r\n}\r\n"],"names":["Progress","value","max","indeterminate","label","className","isIndeterminate","percentage","jsx"],"mappings":"mJA6BO,SAASA,EAAS,CACvB,MAAAC,EACA,IAAAC,EAAM,IACN,cAAAC,EAAgB,GAChB,MAAAC,EAAQ,WACR,UAAAC,EAAY,EACd,EAAkB,CAChB,MAAMC,EAAkBH,GAAiBF,IAAU,OAE7CM,EAAa,KAAK,IAAI,KAAK,KAAKN,GAAS,GAAKC,EAAK,CAAC,EAAG,CAAC,EAAI,IAElE,OACEM,EAAAA,IAAC,MAAA,CACC,UAAW,eAAeH,CAAS,GACnC,KAAK,cACL,gBAAeC,EAAkB,OAAY,EAC7C,gBAAeA,EAAkB,OAAYJ,EAC7C,gBAAeI,EAAkB,OAAYL,EAC7C,aAAYG,EAEZ,SAAAI,EAAAA,IAAC,MAAA,CACC,UAAW,mBAAmBF,EAAkB,gBAAkB,EAAE,GACpE,MAAQA,EAAgD,OAA9B,CAAE,MAAO,GAAGC,CAAU,IAAQ,CAAA,CAC1D,CAAA,CAGN"}
@@ -0,0 +1,33 @@
1
+ import { jsx as a } from "react/jsx-runtime";
2
+ /* empty css */
3
+ function l({
4
+ value: e,
5
+ max: i = 100,
6
+ indeterminate: s = !1,
7
+ label: o = "Progress",
8
+ className: t = ""
9
+ }) {
10
+ const r = s || e === void 0, n = Math.min(Math.max((e ?? 0) / i, 0), 1) * 100;
11
+ return /* @__PURE__ */ a(
12
+ "div",
13
+ {
14
+ className: `ui-progress ${t}`,
15
+ role: "progressbar",
16
+ "aria-valuemin": r ? void 0 : 0,
17
+ "aria-valuemax": r ? void 0 : i,
18
+ "aria-valuenow": r ? void 0 : e,
19
+ "aria-label": o,
20
+ children: /* @__PURE__ */ a(
21
+ "div",
22
+ {
23
+ className: `ui-progress-bar ${r ? "indeterminate" : ""}`,
24
+ style: r ? void 0 : { width: `${n}%` }
25
+ }
26
+ )
27
+ }
28
+ );
29
+ }
30
+ export {
31
+ l as Progress
32
+ };
33
+ //# sourceMappingURL=Progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Progress.js","sources":["../../../../src/components/progress/Progress.tsx"],"sourcesContent":["/**\r\n * Progress.tsx — FINAL VERSION\r\n * --------------------------------\r\n * Features:\r\n * - Determinate mode (value/max)\r\n * - Indeterminate mode\r\n * - Smooth animation\r\n * - ARIA compliant\r\n * - Pure TSX + CSS (no inline styles except width)\r\n */\r\n\r\nimport './Progress.css';\r\n\r\nexport interface ProgressProps {\r\n /** Current value (determinate mode). */\r\n value?: number;\r\n\r\n /** Maximum value (default: 100). */\r\n max?: number;\r\n\r\n /** Indeterminate mode when value is undefined. */\r\n indeterminate?: boolean;\r\n\r\n /** Optional label for screen readers. */\r\n label?: string;\r\n\r\n className?: string;\r\n}\r\n\r\nexport function Progress({\r\n value,\r\n max = 100,\r\n indeterminate = false,\r\n label = 'Progress',\r\n className = '',\r\n}: ProgressProps) {\r\n const isIndeterminate = indeterminate || value === undefined;\r\n\r\n const percentage = Math.min(Math.max((value ?? 0) / max, 0), 1) * 100;\r\n\r\n return (\r\n <div\r\n className={`ui-progress ${className}`}\r\n role=\"progressbar\"\r\n aria-valuemin={isIndeterminate ? undefined : 0}\r\n aria-valuemax={isIndeterminate ? undefined : max}\r\n aria-valuenow={isIndeterminate ? undefined : value}\r\n aria-label={label}\r\n >\r\n <div\r\n className={`ui-progress-bar ${isIndeterminate ? 'indeterminate' : ''}`}\r\n style={!isIndeterminate ? { width: `${percentage}%` } : undefined}\r\n />\r\n </div>\r\n );\r\n}\r\n"],"names":["Progress","value","max","indeterminate","label","className","isIndeterminate","percentage","jsx"],"mappings":";;AA6BO,SAASA,EAAS;AAAA,EACvB,OAAAC;AAAA,EACA,KAAAC,IAAM;AAAA,EACN,eAAAC,IAAgB;AAAA,EAChB,OAAAC,IAAQ;AAAA,EACR,WAAAC,IAAY;AACd,GAAkB;AAChB,QAAMC,IAAkBH,KAAiBF,MAAU,QAE7CM,IAAa,KAAK,IAAI,KAAK,KAAKN,KAAS,KAAKC,GAAK,CAAC,GAAG,CAAC,IAAI;AAElE,SACE,gBAAAM;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,eAAeH,CAAS;AAAA,MACnC,MAAK;AAAA,MACL,iBAAeC,IAAkB,SAAY;AAAA,MAC7C,iBAAeA,IAAkB,SAAYJ;AAAA,MAC7C,iBAAeI,IAAkB,SAAYL;AAAA,MAC7C,cAAYG;AAAA,MAEZ,UAAA,gBAAAI;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAW,mBAAmBF,IAAkB,kBAAkB,EAAE;AAAA,UACpE,OAAQA,IAAgD,SAA9B,EAAE,OAAO,GAAGC,CAAU;QAAQ;AAAA,MAAA;AAAA,IAC1D;AAAA,EAAA;AAGN;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),u=require("react");;/* empty css */function p({options:l,value:d,defaultValue:m,onChange:o,name:k,disabled:b=!1,className:x=""}){const c=d!==void 0,[v,w]=u.useState(m),R=c?d:v,f=u.useRef([]),h=u.useCallback(e=>{c||w(e),o?.(e)},[c,o]),j=(e,n)=>{const a=l.map((i,y)=>i.disabled?null:y).filter(i=>i!==null),r=a.indexOf(n);if(r===-1)return;let t=r;switch(e.key){case"ArrowDown":case"ArrowRight":t=(r+1)%a.length;break;case"ArrowUp":case"ArrowLeft":t=(r-1+a.length)%a.length;break;case"Home":t=0;break;case"End":t=a.length-1;break;default:return}e.preventDefault();const g=a[t];f.current[g]?.focus(),h(l[g].value)};return s.jsx("div",{className:`ui-radio-group ${x}`,role:"radiogroup",children:l.map((e,n)=>{const a=R===e.value;return s.jsxs("label",{className:"ui-radio-item","aria-disabled":b||e.disabled,children:[s.jsx("input",{ref:r=>{f.current[n]=r},type:"radio",className:"ui-radio-input",name:k,value:e.value,disabled:b||e.disabled,checked:a,onChange:()=>h(e.value),onKeyDown:r=>j(r,n),"data-state":a?"checked":"unchecked"}),s.jsx("span",{className:"ui-radio-label",children:e.label})]},e.value)})})}exports.RadioGroup=p;
2
+ //# sourceMappingURL=RadioGroup.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RadioGroup.cjs","sources":["../../../../src/components/radiogroup/RadioGroup.tsx"],"sourcesContent":["/**\r\n * RadioGroup.tsx\r\n * ----------------\r\n * Fully accessible WAI-ARIA radio group.\r\n * - Arrow key navigation\r\n * - Home/End keys\r\n * - Controlled & uncontrolled\r\n * - Disabled support\r\n */\r\n\r\nimport React, { useState, useCallback, useRef } from 'react';\r\nimport './RadioGroup.css';\r\n\r\nexport interface RadioOption {\r\n label: React.ReactNode;\r\n value: string;\r\n disabled?: boolean;\r\n}\r\n\r\ninterface RadioGroupProps {\r\n options: RadioOption[];\r\n value?: string; // controlled\r\n defaultValue?: string; // uncontrolled\r\n onChange?: (value: string) => void;\r\n name?: string; // form support\r\n disabled?: boolean;\r\n className?: string;\r\n}\r\n\r\nexport function RadioGroup({\r\n options,\r\n value,\r\n defaultValue,\r\n onChange,\r\n name,\r\n disabled = false,\r\n className = '',\r\n}: RadioGroupProps) {\r\n const isControlled = value !== undefined;\r\n\r\n const [internalValue, setInternalValue] = useState(defaultValue);\r\n const selected = isControlled ? value : internalValue;\r\n\r\n const itemRefs = useRef<Array<HTMLInputElement | null>>([]);\r\n\r\n const select = useCallback(\r\n (val: string) => {\r\n if (!isControlled) setInternalValue(val);\r\n onChange?.(val);\r\n },\r\n [isControlled, onChange]\r\n );\r\n\r\n const onKeyDown = (e: React.KeyboardEvent, index: number) => {\r\n const enabledIndices = options\r\n .map((o, i) => (!o.disabled ? i : null))\r\n .filter((i) => i !== null) as number[];\r\n\r\n const currentIndex = enabledIndices.indexOf(index);\r\n if (currentIndex === -1) return;\r\n\r\n let nextIndex = currentIndex;\r\n\r\n switch (e.key) {\r\n case 'ArrowDown':\r\n case 'ArrowRight':\r\n nextIndex = (currentIndex + 1) % enabledIndices.length;\r\n break;\r\n\r\n case 'ArrowUp':\r\n case 'ArrowLeft':\r\n nextIndex =\r\n (currentIndex - 1 + enabledIndices.length) % enabledIndices.length;\r\n break;\r\n\r\n case 'Home':\r\n nextIndex = 0;\r\n break;\r\n\r\n case 'End':\r\n nextIndex = enabledIndices.length - 1;\r\n break;\r\n\r\n default:\r\n return;\r\n }\r\n\r\n e.preventDefault();\r\n const targetIndex = enabledIndices[nextIndex];\r\n const target = itemRefs.current[targetIndex];\r\n target?.focus();\r\n select(options[targetIndex].value);\r\n };\r\n\r\n return (\r\n <div className={`ui-radio-group ${className}`} role=\"radiogroup\">\r\n {options.map((opt, i) => {\r\n const isChecked = selected === opt.value;\r\n\r\n return (\r\n <label\r\n key={opt.value}\r\n className=\"ui-radio-item\"\r\n aria-disabled={disabled || opt.disabled}\r\n >\r\n <input\r\n ref={(el) => {\r\n itemRefs.current[i] = el;\r\n }}\r\n type=\"radio\"\r\n className=\"ui-radio-input\"\r\n name={name}\r\n value={opt.value}\r\n disabled={disabled || opt.disabled}\r\n checked={isChecked}\r\n onChange={() => select(opt.value)}\r\n onKeyDown={(e) => onKeyDown(e, i)}\r\n data-state={isChecked ? 'checked' : 'unchecked'}\r\n />\r\n\r\n <span className=\"ui-radio-label\">{opt.label}</span>\r\n </label>\r\n );\r\n })}\r\n </div>\r\n );\r\n}\r\n"],"names":["RadioGroup","options","value","defaultValue","onChange","name","disabled","className","isControlled","internalValue","setInternalValue","useState","selected","itemRefs","useRef","select","useCallback","val","onKeyDown","index","enabledIndices","o","i","currentIndex","nextIndex","targetIndex","jsx","opt","isChecked","jsxs","el","e"],"mappings":"wKA6BO,SAASA,EAAW,CACzB,QAAAC,EACA,MAAAC,EACA,aAAAC,EACA,SAAAC,EACA,KAAAC,EACA,SAAAC,EAAW,GACX,UAAAC,EAAY,EACd,EAAoB,CAClB,MAAMC,EAAeN,IAAU,OAEzB,CAACO,EAAeC,CAAgB,EAAIC,EAAAA,SAASR,CAAY,EACzDS,EAAWJ,EAAeN,EAAQO,EAElCI,EAAWC,EAAAA,OAAuC,EAAE,EAEpDC,EAASC,EAAAA,YACZC,GAAgB,CACVT,GAAcE,EAAiBO,CAAG,EACvCb,IAAWa,CAAG,CAChB,EACA,CAACT,EAAcJ,CAAQ,CAAA,EAGnBc,EAAY,CAAC,EAAwBC,IAAkB,CAC3D,MAAMC,EAAiBnB,EACpB,IAAI,CAACoB,EAAGC,IAAQD,EAAE,SAAe,KAAJC,CAAS,EACtC,OAAQ,GAAM,IAAM,IAAI,EAErBC,EAAeH,EAAe,QAAQD,CAAK,EACjD,GAAII,IAAiB,GAAI,OAEzB,IAAIC,EAAYD,EAEhB,OAAQ,EAAE,IAAA,CACR,IAAK,YACL,IAAK,aACHC,GAAaD,EAAe,GAAKH,EAAe,OAChD,MAEF,IAAK,UACL,IAAK,YACHI,GACGD,EAAe,EAAIH,EAAe,QAAUA,EAAe,OAC9D,MAEF,IAAK,OACHI,EAAY,EACZ,MAEF,IAAK,MACHA,EAAYJ,EAAe,OAAS,EACpC,MAEF,QACE,MAAA,CAGJ,EAAE,eAAA,EACF,MAAMK,EAAcL,EAAeI,CAAS,EAC7BX,EAAS,QAAQY,CAAW,GACnC,MAAA,EACRV,EAAOd,EAAQwB,CAAW,EAAE,KAAK,CACnC,EAEA,OACEC,EAAAA,IAAC,MAAA,CAAI,UAAW,kBAAkBnB,CAAS,GAAI,KAAK,aACjD,SAAAN,EAAQ,IAAI,CAAC0B,EAAKL,IAAM,CACvB,MAAMM,EAAYhB,IAAae,EAAI,MAEnC,OACEE,EAAAA,KAAC,QAAA,CAEC,UAAU,gBACV,gBAAevB,GAAYqB,EAAI,SAE/B,SAAA,CAAAD,EAAAA,IAAC,QAAA,CACC,IAAMI,GAAO,CACXjB,EAAS,QAAQS,CAAC,EAAIQ,CACxB,EACA,KAAK,QACL,UAAU,iBACV,KAAAzB,EACA,MAAOsB,EAAI,MACX,SAAUrB,GAAYqB,EAAI,SAC1B,QAASC,EACT,SAAU,IAAMb,EAAOY,EAAI,KAAK,EAChC,UAAYI,GAAMb,EAAUa,EAAGT,CAAC,EAChC,aAAYM,EAAY,UAAY,WAAA,CAAA,EAGtCF,EAAAA,IAAC,OAAA,CAAK,UAAU,iBAAkB,WAAI,KAAA,CAAM,CAAA,CAAA,EAnBvCC,EAAI,KAAA,CAsBf,CAAC,CAAA,CACH,CAEJ"}
@@ -0,0 +1,79 @@
1
+ import { jsx as i, jsxs as y } from "react/jsx-runtime";
2
+ import { useState as A, useRef as D, useCallback as N } from "react";
3
+ /* empty css */
4
+ function V({
5
+ options: l,
6
+ value: d,
7
+ defaultValue: h,
8
+ onChange: o,
9
+ name: g,
10
+ disabled: u = !1,
11
+ className: k = ""
12
+ }) {
13
+ const s = d !== void 0, [w, x] = A(h), p = s ? d : w, f = D([]), m = N(
14
+ (e) => {
15
+ s || x(e), o?.(e);
16
+ },
17
+ [s, o]
18
+ ), v = (e, t) => {
19
+ const a = l.map((c, I) => c.disabled ? null : I).filter((c) => c !== null), r = a.indexOf(t);
20
+ if (r === -1) return;
21
+ let n = r;
22
+ switch (e.key) {
23
+ case "ArrowDown":
24
+ case "ArrowRight":
25
+ n = (r + 1) % a.length;
26
+ break;
27
+ case "ArrowUp":
28
+ case "ArrowLeft":
29
+ n = (r - 1 + a.length) % a.length;
30
+ break;
31
+ case "Home":
32
+ n = 0;
33
+ break;
34
+ case "End":
35
+ n = a.length - 1;
36
+ break;
37
+ default:
38
+ return;
39
+ }
40
+ e.preventDefault();
41
+ const b = a[n];
42
+ f.current[b]?.focus(), m(l[b].value);
43
+ };
44
+ return /* @__PURE__ */ i("div", { className: `ui-radio-group ${k}`, role: "radiogroup", children: l.map((e, t) => {
45
+ const a = p === e.value;
46
+ return /* @__PURE__ */ y(
47
+ "label",
48
+ {
49
+ className: "ui-radio-item",
50
+ "aria-disabled": u || e.disabled,
51
+ children: [
52
+ /* @__PURE__ */ i(
53
+ "input",
54
+ {
55
+ ref: (r) => {
56
+ f.current[t] = r;
57
+ },
58
+ type: "radio",
59
+ className: "ui-radio-input",
60
+ name: g,
61
+ value: e.value,
62
+ disabled: u || e.disabled,
63
+ checked: a,
64
+ onChange: () => m(e.value),
65
+ onKeyDown: (r) => v(r, t),
66
+ "data-state": a ? "checked" : "unchecked"
67
+ }
68
+ ),
69
+ /* @__PURE__ */ i("span", { className: "ui-radio-label", children: e.label })
70
+ ]
71
+ },
72
+ e.value
73
+ );
74
+ }) });
75
+ }
76
+ export {
77
+ V as RadioGroup
78
+ };
79
+ //# sourceMappingURL=RadioGroup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RadioGroup.js","sources":["../../../../src/components/radiogroup/RadioGroup.tsx"],"sourcesContent":["/**\r\n * RadioGroup.tsx\r\n * ----------------\r\n * Fully accessible WAI-ARIA radio group.\r\n * - Arrow key navigation\r\n * - Home/End keys\r\n * - Controlled & uncontrolled\r\n * - Disabled support\r\n */\r\n\r\nimport React, { useState, useCallback, useRef } from 'react';\r\nimport './RadioGroup.css';\r\n\r\nexport interface RadioOption {\r\n label: React.ReactNode;\r\n value: string;\r\n disabled?: boolean;\r\n}\r\n\r\ninterface RadioGroupProps {\r\n options: RadioOption[];\r\n value?: string; // controlled\r\n defaultValue?: string; // uncontrolled\r\n onChange?: (value: string) => void;\r\n name?: string; // form support\r\n disabled?: boolean;\r\n className?: string;\r\n}\r\n\r\nexport function RadioGroup({\r\n options,\r\n value,\r\n defaultValue,\r\n onChange,\r\n name,\r\n disabled = false,\r\n className = '',\r\n}: RadioGroupProps) {\r\n const isControlled = value !== undefined;\r\n\r\n const [internalValue, setInternalValue] = useState(defaultValue);\r\n const selected = isControlled ? value : internalValue;\r\n\r\n const itemRefs = useRef<Array<HTMLInputElement | null>>([]);\r\n\r\n const select = useCallback(\r\n (val: string) => {\r\n if (!isControlled) setInternalValue(val);\r\n onChange?.(val);\r\n },\r\n [isControlled, onChange]\r\n );\r\n\r\n const onKeyDown = (e: React.KeyboardEvent, index: number) => {\r\n const enabledIndices = options\r\n .map((o, i) => (!o.disabled ? i : null))\r\n .filter((i) => i !== null) as number[];\r\n\r\n const currentIndex = enabledIndices.indexOf(index);\r\n if (currentIndex === -1) return;\r\n\r\n let nextIndex = currentIndex;\r\n\r\n switch (e.key) {\r\n case 'ArrowDown':\r\n case 'ArrowRight':\r\n nextIndex = (currentIndex + 1) % enabledIndices.length;\r\n break;\r\n\r\n case 'ArrowUp':\r\n case 'ArrowLeft':\r\n nextIndex =\r\n (currentIndex - 1 + enabledIndices.length) % enabledIndices.length;\r\n break;\r\n\r\n case 'Home':\r\n nextIndex = 0;\r\n break;\r\n\r\n case 'End':\r\n nextIndex = enabledIndices.length - 1;\r\n break;\r\n\r\n default:\r\n return;\r\n }\r\n\r\n e.preventDefault();\r\n const targetIndex = enabledIndices[nextIndex];\r\n const target = itemRefs.current[targetIndex];\r\n target?.focus();\r\n select(options[targetIndex].value);\r\n };\r\n\r\n return (\r\n <div className={`ui-radio-group ${className}`} role=\"radiogroup\">\r\n {options.map((opt, i) => {\r\n const isChecked = selected === opt.value;\r\n\r\n return (\r\n <label\r\n key={opt.value}\r\n className=\"ui-radio-item\"\r\n aria-disabled={disabled || opt.disabled}\r\n >\r\n <input\r\n ref={(el) => {\r\n itemRefs.current[i] = el;\r\n }}\r\n type=\"radio\"\r\n className=\"ui-radio-input\"\r\n name={name}\r\n value={opt.value}\r\n disabled={disabled || opt.disabled}\r\n checked={isChecked}\r\n onChange={() => select(opt.value)}\r\n onKeyDown={(e) => onKeyDown(e, i)}\r\n data-state={isChecked ? 'checked' : 'unchecked'}\r\n />\r\n\r\n <span className=\"ui-radio-label\">{opt.label}</span>\r\n </label>\r\n );\r\n })}\r\n </div>\r\n );\r\n}\r\n"],"names":["RadioGroup","options","value","defaultValue","onChange","name","disabled","className","isControlled","internalValue","setInternalValue","useState","selected","itemRefs","useRef","select","useCallback","val","onKeyDown","index","enabledIndices","o","i","currentIndex","nextIndex","targetIndex","jsx","opt","isChecked","jsxs","el","e"],"mappings":";;;AA6BO,SAASA,EAAW;AAAA,EACzB,SAAAC;AAAA,EACA,OAAAC;AAAA,EACA,cAAAC;AAAA,EACA,UAAAC;AAAA,EACA,MAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,WAAAC,IAAY;AACd,GAAoB;AAClB,QAAMC,IAAeN,MAAU,QAEzB,CAACO,GAAeC,CAAgB,IAAIC,EAASR,CAAY,GACzDS,IAAWJ,IAAeN,IAAQO,GAElCI,IAAWC,EAAuC,EAAE,GAEpDC,IAASC;AAAA,IACb,CAACC,MAAgB;AACf,MAAKT,KAAcE,EAAiBO,CAAG,GACvCb,IAAWa,CAAG;AAAA,IAChB;AAAA,IACA,CAACT,GAAcJ,CAAQ;AAAA,EAAA,GAGnBc,IAAY,CAAC,GAAwBC,MAAkB;AAC3D,UAAMC,IAAiBnB,EACpB,IAAI,CAACoB,GAAGC,MAAQD,EAAE,WAAe,OAAJC,CAAS,EACtC,OAAO,CAACA,MAAMA,MAAM,IAAI,GAErBC,IAAeH,EAAe,QAAQD,CAAK;AACjD,QAAII,MAAiB,GAAI;AAEzB,QAAIC,IAAYD;AAEhB,YAAQ,EAAE,KAAA;AAAA,MACR,KAAK;AAAA,MACL,KAAK;AACH,QAAAC,KAAaD,IAAe,KAAKH,EAAe;AAChD;AAAA,MAEF,KAAK;AAAA,MACL,KAAK;AACH,QAAAI,KACGD,IAAe,IAAIH,EAAe,UAAUA,EAAe;AAC9D;AAAA,MAEF,KAAK;AACH,QAAAI,IAAY;AACZ;AAAA,MAEF,KAAK;AACH,QAAAA,IAAYJ,EAAe,SAAS;AACpC;AAAA,MAEF;AACE;AAAA,IAAA;AAGJ,MAAE,eAAA;AACF,UAAMK,IAAcL,EAAeI,CAAS;AAE5C,IADeX,EAAS,QAAQY,CAAW,GACnC,MAAA,GACRV,EAAOd,EAAQwB,CAAW,EAAE,KAAK;AAAA,EACnC;AAEA,SACE,gBAAAC,EAAC,OAAA,EAAI,WAAW,kBAAkBnB,CAAS,IAAI,MAAK,cACjD,UAAAN,EAAQ,IAAI,CAAC0B,GAAKL,MAAM;AACvB,UAAMM,IAAYhB,MAAae,EAAI;AAEnC,WACE,gBAAAE;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,WAAU;AAAA,QACV,iBAAevB,KAAYqB,EAAI;AAAA,QAE/B,UAAA;AAAA,UAAA,gBAAAD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,KAAK,CAACI,MAAO;AACX,gBAAAjB,EAAS,QAAQS,CAAC,IAAIQ;AAAA,cACxB;AAAA,cACA,MAAK;AAAA,cACL,WAAU;AAAA,cACV,MAAAzB;AAAA,cACA,OAAOsB,EAAI;AAAA,cACX,UAAUrB,KAAYqB,EAAI;AAAA,cAC1B,SAASC;AAAA,cACT,UAAU,MAAMb,EAAOY,EAAI,KAAK;AAAA,cAChC,WAAW,CAACI,MAAMb,EAAUa,GAAGT,CAAC;AAAA,cAChC,cAAYM,IAAY,YAAY;AAAA,YAAA;AAAA,UAAA;AAAA,UAGtC,gBAAAF,EAAC,QAAA,EAAK,WAAU,kBAAkB,YAAI,MAAA,CAAM;AAAA,QAAA;AAAA,MAAA;AAAA,MAnBvCC,EAAI;AAAA,IAAA;AAAA,EAsBf,CAAC,EAAA,CACH;AAEJ;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),c=require("react");;/* empty css */function S({value:i,max:a=5,onChange:u,icon:d="☆",iconFilled:g="★",size:f="md",className:h=""}){const[m,y]=c.useState(0),t=i??m,[x,o]=c.useState(null),R=x??t,r=e=>{i===void 0&&y(e),u?.(e)},b=e=>{e.key==="ArrowRight"&&r(Math.min((t??0)+1,a)),e.key==="ArrowLeft"&&r(Math.max((t??0)-1,1))};return s.jsx("div",{className:`ui-rating ui-rating--${f} ${h}`,role:"radiogroup",tabIndex:0,onKeyDown:b,"aria-label":"Rating",children:Array.from({length:a},(e,M)=>{const n=M+1,l=n<=R;return s.jsx("span",{role:"radio","aria-checked":t===n,tabIndex:-1,className:`ui-rating-item ${l?"filled":""}`,onMouseEnter:()=>o(n),onMouseLeave:()=>o(null),onClick:()=>r(n),children:l?g:d},n)})})}exports.Rating=S;
2
+ //# sourceMappingURL=Rating.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Rating.cjs","sources":["../../../../src/components/rating/Rating.tsx"],"sourcesContent":["/**\r\n * Rating.tsx — FINAL VERSION\r\n * ---------------------------\r\n * Features:\r\n * - Click to select\r\n * - Hover preview\r\n * - Keyboard navigation\r\n * - Theme-aware\r\n * - Accessible\r\n */\r\n\r\nimport React, { useState } from 'react';\r\nimport './Rating.css';\r\n\r\nexport interface RatingProps {\r\n /** Current value (1–max). If undefined → uncontrolled mode */\r\n value?: number;\r\n\r\n /** Max number of stars */\r\n max?: number;\r\n\r\n /** Change handler */\r\n onChange?: (value: number) => void;\r\n\r\n /** Custom icon */\r\n icon?: React.ReactNode;\r\n\r\n /** Custom filled icon */\r\n iconFilled?: React.ReactNode;\r\n\r\n /** Size */\r\n size?: 'sm' | 'md' | 'lg';\r\n\r\n /** Optional class */\r\n className?: string;\r\n}\r\n\r\nexport function Rating({\r\n value,\r\n max = 5,\r\n onChange,\r\n icon = '☆',\r\n iconFilled = '★',\r\n size = 'md',\r\n className = '',\r\n}: RatingProps) {\r\n // uncontrolled internal value\r\n const [internal, setInternal] = useState(0);\r\n const current = value ?? internal;\r\n\r\n const [hover, setHover] = useState<number | null>(null);\r\n\r\n const finalValue = hover ?? current;\r\n\r\n const handleSelect = (v: number) => {\r\n if (value === undefined) setInternal(v);\r\n onChange?.(v);\r\n };\r\n\r\n const handleKey = (e: React.KeyboardEvent<HTMLDivElement>) => {\r\n if (e.key === 'ArrowRight') handleSelect(Math.min((current ?? 0) + 1, max));\r\n if (e.key === 'ArrowLeft') handleSelect(Math.max((current ?? 0) - 1, 1));\r\n };\r\n\r\n return (\r\n <div\r\n className={`ui-rating ui-rating--${size} ${className}`}\r\n role=\"radiogroup\"\r\n tabIndex={0}\r\n onKeyDown={handleKey}\r\n aria-label=\"Rating\"\r\n >\r\n {Array.from({ length: max }, (_, i) => {\r\n const index = i + 1;\r\n const filled = index <= finalValue;\r\n\r\n return (\r\n <span\r\n key={index}\r\n role=\"radio\"\r\n aria-checked={current === index}\r\n tabIndex={-1}\r\n className={`ui-rating-item ${filled ? 'filled' : ''}`}\r\n onMouseEnter={() => setHover(index)}\r\n onMouseLeave={() => setHover(null)}\r\n onClick={() => handleSelect(index)}\r\n >\r\n {filled ? iconFilled : icon}\r\n </span>\r\n );\r\n })}\r\n </div>\r\n );\r\n}\r\n"],"names":["Rating","value","max","onChange","icon","iconFilled","size","className","internal","setInternal","useState","current","hover","setHover","finalValue","handleSelect","v","handleKey","jsx","_","i","index","filled"],"mappings":"oKAqCO,SAASA,EAAO,CACrB,MAAAC,EACA,IAAAC,EAAM,EACN,SAAAC,EACA,KAAAC,EAAO,IACP,WAAAC,EAAa,IACb,KAAAC,EAAO,KACP,UAAAC,EAAY,EACd,EAAgB,CAEd,KAAM,CAACC,EAAUC,CAAW,EAAIC,EAAAA,SAAS,CAAC,EACpCC,EAAUV,GAASO,EAEnB,CAACI,EAAOC,CAAQ,EAAIH,EAAAA,SAAwB,IAAI,EAEhDI,EAAaF,GAASD,EAEtBI,EAAgBC,GAAc,CAC9Bf,IAAU,QAAWQ,EAAYO,CAAC,EACtCb,IAAWa,CAAC,CACd,EAEMC,EAAa,GAA2C,CACxD,EAAE,MAAQ,cAAcF,EAAa,KAAK,KAAKJ,GAAW,GAAK,EAAGT,CAAG,CAAC,EACtE,EAAE,MAAQ,aAAaa,EAAa,KAAK,KAAKJ,GAAW,GAAK,EAAG,CAAC,CAAC,CACzE,EAEA,OACEO,EAAAA,IAAC,MAAA,CACC,UAAW,wBAAwBZ,CAAI,IAAIC,CAAS,GACpD,KAAK,aACL,SAAU,EACV,UAAWU,EACX,aAAW,SAEV,SAAA,MAAM,KAAK,CAAE,OAAQf,GAAO,CAACiB,EAAGC,IAAM,CACrC,MAAMC,EAAQD,EAAI,EACZE,EAASD,GAASP,EAExB,OACEI,EAAAA,IAAC,OAAA,CAEC,KAAK,QACL,eAAcP,IAAYU,EAC1B,SAAU,GACV,UAAW,kBAAkBC,EAAS,SAAW,EAAE,GACnD,aAAc,IAAMT,EAASQ,CAAK,EAClC,aAAc,IAAMR,EAAS,IAAI,EACjC,QAAS,IAAME,EAAaM,CAAK,EAEhC,WAAShB,EAAaD,CAAA,EATlBiB,CAAA,CAYX,CAAC,CAAA,CAAA,CAGP"}