@boxcustodia/library 2.0.0-alpha.10 → 2.0.0-alpha.12

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 (352) hide show
  1. package/dist/index.cjs.js +70 -70
  2. package/dist/index.css +2 -0
  3. package/dist/index.d.ts +420 -272
  4. package/dist/index.es.js +34448 -27816
  5. package/dist/theme.css +1 -1
  6. package/package.json +11 -6
  7. package/src/__doc__/Changelog.mdx +6 -0
  8. package/src/__doc__/Components.mdx +73 -0
  9. package/src/__doc__/Examples.tsx +69 -0
  10. package/src/__doc__/Icons.mdx +41 -0
  11. package/src/__doc__/Intro.mdx +138 -0
  12. package/src/__doc__/MCP.mdx +71 -0
  13. package/src/__doc__/Migration.mdx +475 -0
  14. package/src/__doc__/Theme.mdx +132 -0
  15. package/src/__doc__/Types.mdx +252 -0
  16. package/src/components/alert/alert.stories.tsx +142 -0
  17. package/src/components/alert/alert.tsx +109 -0
  18. package/src/components/alert/index.ts +7 -0
  19. package/src/components/alert-dialog/alert-dialog.stories.tsx +173 -0
  20. package/src/components/alert-dialog/alert-dialog.test.tsx +49 -0
  21. package/src/components/alert-dialog/alert-dialog.tsx +265 -0
  22. package/src/components/alert-dialog/index.ts +1 -0
  23. package/src/components/auto-complete/auto-complete-primitives.tsx +155 -0
  24. package/src/components/auto-complete/auto-complete.stories.tsx +241 -0
  25. package/src/components/auto-complete/auto-complete.tsx +82 -0
  26. package/src/components/auto-complete/index.ts +2 -0
  27. package/src/components/avatar/avatar.stories.tsx +84 -0
  28. package/src/components/avatar/avatar.test.tsx +61 -0
  29. package/src/components/avatar/avatar.tsx +104 -0
  30. package/src/components/avatar/index.ts +1 -0
  31. package/src/components/background-image/background-image.stories.tsx +21 -0
  32. package/src/components/background-image/background-image.test.tsx +29 -0
  33. package/src/components/background-image/background-image.tsx +23 -0
  34. package/src/components/background-image/index.ts +1 -0
  35. package/src/components/button/button.stories.tsx +396 -0
  36. package/src/components/button/button.test.tsx +58 -0
  37. package/src/components/button/button.tsx +31 -0
  38. package/src/components/button/button.variants.ts +44 -0
  39. package/src/components/button/components/base-button.tsx +86 -0
  40. package/src/components/button/components/loader-overlay.tsx +21 -0
  41. package/src/components/button/components/loading-icon.tsx +47 -0
  42. package/src/components/button/index.ts +3 -0
  43. package/src/components/calendar/calendar.model.ts +86 -0
  44. package/src/components/calendar/calendar.stories.tsx +155 -0
  45. package/src/components/calendar/calendar.test.tsx +12 -0
  46. package/src/components/calendar/calendar.tsx +185 -0
  47. package/src/components/calendar/components/calendar-navigation.tsx +141 -0
  48. package/src/components/calendar/components/day.tsx +61 -0
  49. package/src/components/calendar/components/decade-view.tsx +45 -0
  50. package/src/components/calendar/components/index.ts +6 -0
  51. package/src/components/calendar/components/month-view.tsx +58 -0
  52. package/src/components/calendar/components/week-days.tsx +27 -0
  53. package/src/components/calendar/components/year-view.tsx +29 -0
  54. package/src/components/calendar/hooks/index.ts +4 -0
  55. package/src/components/calendar/hooks/use-calendar-navigation.ts +79 -0
  56. package/src/components/calendar/hooks/use-calendar.ts +90 -0
  57. package/src/components/calendar/hooks/use-multiple-calendar.ts +34 -0
  58. package/src/components/calendar/hooks/use-range-calendar.ts +91 -0
  59. package/src/components/calendar/hooks/use-single-calendar.ts +18 -0
  60. package/src/components/calendar/index.ts +1 -0
  61. package/src/components/calendar/utils/typeguards.ts +7 -0
  62. package/src/components/card/card.stories.tsx +116 -0
  63. package/src/components/card/card.tsx +74 -0
  64. package/src/components/card/index.ts +1 -0
  65. package/src/components/center/center.stories.tsx +81 -0
  66. package/src/components/center/center.tsx +24 -0
  67. package/src/components/center/index.ts +1 -0
  68. package/src/components/checkbox/checkbox.stories.tsx +307 -0
  69. package/src/components/checkbox/checkbox.tsx +273 -0
  70. package/src/components/checkbox/index.ts +1 -0
  71. package/src/components/checkbox-group/checkbox-group.stories.tsx +104 -0
  72. package/src/components/checkbox-group/checkbox-group.tsx +16 -0
  73. package/src/components/checkbox-group/index.ts +1 -0
  74. package/src/components/combobox/combobox.stories.tsx +339 -0
  75. package/src/components/combobox/combobox.tsx +892 -0
  76. package/src/components/combobox/index.ts +1 -0
  77. package/src/components/date-picker/date-input.stories.tsx +158 -0
  78. package/src/components/date-picker/date-input.tsx +163 -0
  79. package/src/components/date-picker/date-picker.model.ts +90 -0
  80. package/src/components/date-picker/date-picker.stories.tsx +200 -0
  81. package/src/components/date-picker/date-picker.test.tsx +23 -0
  82. package/src/components/date-picker/date-picker.tsx +298 -0
  83. package/src/components/date-picker/date-picker.utils.ts +260 -0
  84. package/src/components/date-picker/index.ts +3 -0
  85. package/src/components/date-picker/use-date-input-popover.ts +48 -0
  86. package/src/components/date-picker/use-date-input.ts +125 -0
  87. package/src/components/dialog/dialog.stories.tsx +171 -0
  88. package/src/components/dialog/dialog.test.tsx +68 -0
  89. package/src/components/dialog/dialog.tsx +277 -0
  90. package/src/components/dialog/index.ts +1 -0
  91. package/src/components/divider/divider.stories.tsx +70 -0
  92. package/src/components/divider/divider.test.tsx +22 -0
  93. package/src/components/divider/divider.tsx +23 -0
  94. package/src/components/divider/index.ts +1 -0
  95. package/src/components/dropzone/dropzone.stories.tsx +210 -0
  96. package/src/components/dropzone/dropzone.tsx +154 -0
  97. package/src/components/dropzone/file-types.ts +64 -0
  98. package/src/components/dropzone/index.ts +3 -0
  99. package/src/components/dropzone/upload-primitives.tsx +310 -0
  100. package/src/components/dropzone/use-dropzone.ts +122 -0
  101. package/src/components/empty-state/empty-state.stories.tsx +56 -0
  102. package/src/components/empty-state/empty-state.tsx +39 -0
  103. package/src/components/empty-state/index.ts +1 -0
  104. package/src/components/field/field.stories.tsx +223 -0
  105. package/src/components/field/field.tsx +229 -0
  106. package/src/components/field/index.ts +1 -0
  107. package/src/components/form/form.stories.tsx +594 -0
  108. package/src/components/form/form.tsx +30 -0
  109. package/src/components/form/index.ts +1 -0
  110. package/src/components/heading/heading.stories.tsx +74 -0
  111. package/src/components/heading/heading.tsx +28 -0
  112. package/src/components/heading/heading.variants.ts +27 -0
  113. package/src/components/heading/index.ts +1 -0
  114. package/src/components/index.ts +46 -0
  115. package/src/components/input/index.ts +1 -0
  116. package/src/components/input/input.stories.tsx +104 -0
  117. package/src/components/input/input.tsx +75 -0
  118. package/src/components/kbd/index.ts +1 -0
  119. package/src/components/kbd/kbd.stories.tsx +40 -0
  120. package/src/components/kbd/kbd.tsx +31 -0
  121. package/src/components/kbd/kbd.variants.ts +26 -0
  122. package/src/components/label/index.ts +1 -0
  123. package/src/components/label/label.stories.tsx +68 -0
  124. package/src/components/label/label.test.tsx +61 -0
  125. package/src/components/label/label.tsx +62 -0
  126. package/src/components/loader/index.ts +1 -0
  127. package/src/components/loader/loader.stories.tsx +60 -0
  128. package/src/components/loader/loader.test.tsx +26 -0
  129. package/src/components/loader/loader.tsx +60 -0
  130. package/src/components/menu/index.ts +2 -0
  131. package/src/components/menu/menu-primitives.tsx +248 -0
  132. package/src/components/menu/menu.stories.tsx +203 -0
  133. package/src/components/menu/menu.tsx +100 -0
  134. package/src/components/menu/util/render-menu-item.tsx +54 -0
  135. package/src/components/multi-select/hooks/use-multi-select.ts +66 -0
  136. package/src/components/multi-select/index.ts +1 -0
  137. package/src/components/multi-select/multi-select.stories.tsx +294 -0
  138. package/src/components/multi-select/multi-select.tsx +300 -0
  139. package/src/components/multi-select/multi-select.variants.ts +22 -0
  140. package/src/components/number-input/index.ts +1 -0
  141. package/src/components/number-input/number-input.stories.tsx +209 -0
  142. package/src/components/number-input/number-input.test.tsx +87 -0
  143. package/src/components/number-input/number-input.tsx +230 -0
  144. package/src/components/pagination/components/pagination-option.tsx +27 -0
  145. package/src/components/pagination/index.ts +1 -0
  146. package/src/components/pagination/pagination.stories.tsx +80 -0
  147. package/src/components/pagination/pagination.test.tsx +76 -0
  148. package/src/components/pagination/pagination.tsx +102 -0
  149. package/src/components/password/index.ts +1 -0
  150. package/src/components/password/password.stories.tsx +104 -0
  151. package/src/components/password/password.tsx +71 -0
  152. package/src/components/popover/index.ts +1 -0
  153. package/src/components/popover/popover.stories.tsx +213 -0
  154. package/src/components/popover/popover.tsx +203 -0
  155. package/src/components/progress/index.ts +1 -0
  156. package/src/components/progress/progress.stories.tsx +124 -0
  157. package/src/components/progress/progress.test.tsx +25 -0
  158. package/src/components/progress/progress.tsx +124 -0
  159. package/src/components/scroll-area/index.ts +1 -0
  160. package/src/components/scroll-area/scroll-area.stories.tsx +166 -0
  161. package/src/components/scroll-area/scroll-area.tsx +64 -0
  162. package/src/components/select/index.ts +1 -0
  163. package/src/components/select/select.stories.tsx +253 -0
  164. package/src/components/select/select.tsx +430 -0
  165. package/src/components/show/index.ts +1 -0
  166. package/src/components/show/show.stories.tsx +197 -0
  167. package/src/components/show/show.test.tsx +41 -0
  168. package/src/components/show/show.tsx +16 -0
  169. package/src/components/skeleton/index.ts +1 -0
  170. package/src/components/skeleton/skeleton.stories.tsx +36 -0
  171. package/src/components/skeleton/skeleton.test.tsx +14 -0
  172. package/src/components/skeleton/skeleton.tsx +15 -0
  173. package/src/components/stack/index.ts +1 -0
  174. package/src/components/stack/stack.stories.tsx +194 -0
  175. package/src/components/stack/stack.tsx +52 -0
  176. package/src/components/stepper/Stepper.tsx +190 -0
  177. package/src/components/stepper/context/stepper-context.tsx +11 -0
  178. package/src/components/stepper/index.ts +1 -0
  179. package/src/components/stepper/stepper.stories.tsx +130 -0
  180. package/src/components/stepper/stepper.test.tsx +91 -0
  181. package/src/components/switch/index.ts +1 -0
  182. package/src/components/switch/switch.stories.tsx +122 -0
  183. package/src/components/switch/switch.test.tsx +30 -0
  184. package/src/components/switch/switch.tsx +86 -0
  185. package/src/components/table/index.ts +3 -0
  186. package/src/components/table/table-primitives.tsx +122 -0
  187. package/src/components/table/table.model.ts +20 -0
  188. package/src/components/table/table.stories.tsx +169 -0
  189. package/src/components/table/table.test.tsx +91 -0
  190. package/src/components/table/table.tsx +109 -0
  191. package/src/components/table-pagination/index.ts +2 -0
  192. package/src/components/table-pagination/table-pagination.model.ts +2 -0
  193. package/src/components/table-pagination/table-pagination.stories.tsx +23 -0
  194. package/src/components/table-pagination/table-pagination.test.tsx +32 -0
  195. package/src/components/table-pagination/table-pagination.tsx +108 -0
  196. package/src/components/tabs/context/tabs-context.tsx +14 -0
  197. package/src/components/tabs/index.ts +1 -0
  198. package/src/components/tabs/tabs.stories.tsx +182 -0
  199. package/src/components/tabs/tabs.test.tsx +61 -0
  200. package/src/components/tabs/tabs.tsx +175 -0
  201. package/src/components/tag/index.ts +2 -0
  202. package/src/components/tag/tag.stories.tsx +170 -0
  203. package/src/components/tag/tag.test.tsx +18 -0
  204. package/src/components/tag/tag.tsx +99 -0
  205. package/src/components/tag/tag.variants.ts +31 -0
  206. package/src/components/textarea/index.ts +1 -0
  207. package/src/components/textarea/textarea.stories.tsx +73 -0
  208. package/src/components/textarea/textarea.tsx +105 -0
  209. package/src/components/timeline/index.ts +1 -0
  210. package/src/components/timeline/timeline-status.ts +5 -0
  211. package/src/components/timeline/timeline.stories.tsx +84 -0
  212. package/src/components/timeline/timeline.tsx +147 -0
  213. package/src/components/toast/index.ts +1 -0
  214. package/src/components/toast/toast.stories.tsx +392 -0
  215. package/src/components/toast/toast.test.tsx +50 -0
  216. package/src/components/toast/toast.tsx +411 -0
  217. package/src/components/tooltip/index.ts +1 -0
  218. package/src/components/tooltip/tooltip.stories.tsx +226 -0
  219. package/src/components/tooltip/tooltip.test.tsx +46 -0
  220. package/src/components/tooltip/tooltip.tsx +171 -0
  221. package/src/components/tree/hooks/use-controllable-tree-state.ts +80 -0
  222. package/src/components/tree/index.ts +2 -0
  223. package/src/components/tree/tree-primitives.tsx +126 -0
  224. package/src/components/tree/tree.stories.tsx +468 -0
  225. package/src/components/tree/tree.tsx +42 -0
  226. package/src/hooks/index.ts +26 -0
  227. package/src/hooks/useArray/__doc__/useArray.stories.tsx +100 -0
  228. package/src/hooks/useArray/__test__/useArray.test.tsx +88 -0
  229. package/src/hooks/useArray/index.ts +1 -0
  230. package/src/hooks/useArray/useArray.ts +76 -0
  231. package/src/hooks/useAsync/__doc__/useAsync.stories.tsx +149 -0
  232. package/src/hooks/useAsync/__test__/useAsync.test.tsx +68 -0
  233. package/src/hooks/useAsync/index.ts +1 -0
  234. package/src/hooks/useAsync/useAsync.ts +58 -0
  235. package/src/hooks/useClickOutside/__doc__/useClickOutside.stories.tsx +40 -0
  236. package/src/hooks/useClickOutside/__test__/useClickOutside.test.tsx +33 -0
  237. package/src/hooks/useClickOutside/index.ts +1 -0
  238. package/src/hooks/useClickOutside/useClickOutside.ts +26 -0
  239. package/src/hooks/useClipboard/__doc__/useClipboard.stories.tsx +45 -0
  240. package/src/hooks/useClipboard/__test__/useClipboard.test.tsx +19 -0
  241. package/src/hooks/useClipboard/index.ts +1 -0
  242. package/src/hooks/useClipboard/useClipboard.tsx +28 -0
  243. package/src/hooks/useDebounceCallback/__doc__/useDebouncedCallback.stories.tsx +84 -0
  244. package/src/hooks/useDebounceCallback/index.ts +1 -0
  245. package/src/hooks/useDebounceCallback/useDebouncedCallback.ts +23 -0
  246. package/src/hooks/useDebounceValue/__doc__/useDebouncedValue.stories.tsx +75 -0
  247. package/src/hooks/useDebounceValue/index.ts +1 -0
  248. package/src/hooks/useDebounceValue/useDebouncedValue.ts +17 -0
  249. package/src/hooks/useDisclosure/__doc__/useDisclosure.stories.tsx +39 -0
  250. package/src/hooks/useDisclosure/__test__/useDisclosure.test.ts +43 -0
  251. package/src/hooks/useDisclosure/index.ts +1 -0
  252. package/src/hooks/useDisclosure/useDisclosure.ts +37 -0
  253. package/src/hooks/useDocumentTitle/__doc__/useDocumentTitle.stories.tsx +26 -0
  254. package/src/hooks/useDocumentTitle/index.ts +1 -0
  255. package/src/hooks/useDocumentTitle/useDocumentTitle.tsx +11 -0
  256. package/src/hooks/useEventListener/__doc__/useEventListener.stories.tsx +28 -0
  257. package/src/hooks/useEventListener/__test__/useEventListener.test.tsx +26 -0
  258. package/src/hooks/useEventListener/index.ts +1 -0
  259. package/src/hooks/useEventListener/useEventListener.ts +25 -0
  260. package/src/hooks/useFocusTrap/__doc__/useFocusTrap.stories.tsx +37 -0
  261. package/src/hooks/useFocusTrap/index.ts +1 -0
  262. package/src/hooks/useFocusTrap/scopeTab.ts +38 -0
  263. package/src/hooks/useFocusTrap/tabbable.ts +70 -0
  264. package/src/hooks/useFocusTrap/useFocusTrap.ts +78 -0
  265. package/src/hooks/useHotkey/__docs__/useHotkey.stories.tsx +116 -0
  266. package/src/hooks/useHotkey/__test__/useHotkey.test.tsx +105 -0
  267. package/src/hooks/useHotkey/__utils__/create-hotkey-listener.ts +25 -0
  268. package/src/hooks/useHotkey/__utils__/index.ts +3 -0
  269. package/src/hooks/useHotkey/__utils__/is-input-field.ts +14 -0
  270. package/src/hooks/useHotkey/__utils__/match-key-modifiers.ts +25 -0
  271. package/src/hooks/useHotkey/index.ts +1 -0
  272. package/src/hooks/useHotkey/useHotkey.ts +34 -0
  273. package/src/hooks/useHover/__doc__/useHover.stories.tsx +41 -0
  274. package/src/hooks/useHover/__test__/useHover.test.tsx +45 -0
  275. package/src/hooks/useHover/index.ts +1 -0
  276. package/src/hooks/useHover/useHover.tsx +40 -0
  277. package/src/hooks/useIsVisible/__doc__/useIsVisible.stories.tsx +60 -0
  278. package/src/hooks/useIsVisible/index.ts +1 -0
  279. package/src/hooks/useIsVisible/useIsVisible.tsx +50 -0
  280. package/src/hooks/useLocalStorage/__doc__/useLocalStorage.stories.tsx +86 -0
  281. package/src/hooks/useLocalStorage/__test__/useLocalStorage.test.ts +85 -0
  282. package/src/hooks/useLocalStorage/index.ts +1 -0
  283. package/src/hooks/useLocalStorage/useLocalStorage.ts +57 -0
  284. package/src/hooks/useMediaQuery/__doc__/useMediaQuery.stories.tsx +39 -0
  285. package/src/hooks/useMediaQuery/index.ts +1 -0
  286. package/src/hooks/useMediaQuery/useMediaQuery.ts +22 -0
  287. package/src/hooks/useMemoizedFn/index.ts +1 -0
  288. package/src/hooks/useMemoizedFn/useMemoizedFn.ts +32 -0
  289. package/src/hooks/useMutation/__doc__/useMutation.stories.tsx +111 -0
  290. package/src/hooks/useMutation/__test__/useMutation.test.tsx +83 -0
  291. package/src/hooks/useMutation/index.ts +1 -0
  292. package/src/hooks/useMutation/useMutation.tsx +60 -0
  293. package/src/hooks/useObject/__doc__/useObject.stories.tsx +119 -0
  294. package/src/hooks/useObject/__test__/useObject.test.tsx +87 -0
  295. package/src/hooks/useObject/index.ts +1 -0
  296. package/src/hooks/useObject/useObject.tsx +48 -0
  297. package/src/hooks/usePagination/__doc__/usePagination.stories.tsx +72 -0
  298. package/src/hooks/usePagination/__test__/usePagination.test.tsx +98 -0
  299. package/src/hooks/usePagination/index.ts +2 -0
  300. package/src/hooks/usePagination/usePagination.tsx +74 -0
  301. package/src/hooks/usePortal/__doc__/usePortal.stories.tsx +19 -0
  302. package/src/hooks/usePortal/__test__/usePortal.test.tsx +20 -0
  303. package/src/hooks/usePortal/index.ts +1 -0
  304. package/src/hooks/usePortal/usePortal.ts +40 -0
  305. package/src/hooks/usePreventCloseWindow/__doc__/usePreventCloseWindow.stories.tsx +32 -0
  306. package/src/hooks/usePreventCloseWindow/index.ts +1 -0
  307. package/src/hooks/usePreventCloseWindow/usePreventCloseWindow.ts +33 -0
  308. package/src/hooks/useRangePagination/__test__/useRangePagination.test.tsx +63 -0
  309. package/src/hooks/useRangePagination/index.ts +2 -0
  310. package/src/hooks/useRangePagination/useRangePagination.tsx +72 -0
  311. package/src/hooks/useSelection/__doc__/useSelection.stories.tsx +140 -0
  312. package/src/hooks/useSelection/__test__/useSelection.test.tsx +57 -0
  313. package/src/hooks/useSelection/index.ts +1 -0
  314. package/src/hooks/useSelection/useSelection.ts +121 -0
  315. package/src/hooks/useStep/__doc__/useStep.stories.tsx +98 -0
  316. package/src/hooks/useStep/__test__/useStep.test.ts +51 -0
  317. package/src/hooks/useStep/index.ts +1 -0
  318. package/src/hooks/useStep/useStep.ts +57 -0
  319. package/src/hooks/useToggle/__doc__/useToggle.stories.tsx +25 -0
  320. package/src/hooks/useToggle/__test__/useToggle.test.tsx +43 -0
  321. package/src/hooks/useToggle/index.ts +1 -0
  322. package/src/hooks/useToggle/useToggle.ts +16 -0
  323. package/src/index.ts +6 -0
  324. package/src/lib/cn.ts +8 -0
  325. package/src/lib/index.ts +1 -0
  326. package/src/models/Generic.model.ts +67 -0
  327. package/src/models/index.ts +1 -0
  328. package/src/providers/index.ts +2 -0
  329. package/src/providers/library-provider.tsx +44 -0
  330. package/src/providers/theme/ThemeProvider.tsx +25 -0
  331. package/src/providers/theme/index.ts +3 -0
  332. package/src/providers/theme/types.ts +11 -0
  333. package/src/providers/theme/useThemeProps.ts +25 -0
  334. package/src/stores/theme.store.ts +31 -0
  335. package/src/styles/components.css +4 -0
  336. package/src/styles/index.css +2 -0
  337. package/src/styles/library.css +2 -0
  338. package/src/styles/theme.css +232 -0
  339. package/src/utils/dates/parseDateRange.utility.ts +39 -0
  340. package/src/utils/form.tsx +91 -0
  341. package/src/utils/functions/createSafeContext.ts +17 -0
  342. package/src/utils/functions/ensureReactElement.tsx +30 -0
  343. package/src/utils/functions/getFormData.ts +19 -0
  344. package/src/utils/functions/index.ts +4 -0
  345. package/src/utils/functions/mergeRefs.ts +18 -0
  346. package/src/utils/index.ts +3 -0
  347. package/src/utils/strings/extractInitials.utility.ts +10 -0
  348. package/src/utils/strings/index.ts +1 -0
  349. package/src/utils/tests/click.ts +3 -0
  350. package/src/utils/tests/index.ts +2 -0
  351. package/src/utils/tests/keyboard.ts +21 -0
  352. package/src/utils/tests/type.ts +6 -0
@@ -0,0 +1,468 @@
1
+ import { Meta, StoryObj } from "@storybook/react-vite";
2
+ import { ComponentType } from "react";
3
+ import { Collection } from "react-aria-components";
4
+ import { createToastManager, ToastProvider } from "../toast";
5
+
6
+ const toastManager = createToastManager();
7
+
8
+ import { Tree, TreeNode } from ".";
9
+ import {
10
+ TreeItem,
11
+ TreeItemContent,
12
+ TreeItemIndicator,
13
+ TreeItemLabel,
14
+ TreeRoot,
15
+ } from "./tree-primitives";
16
+
17
+ const files: TreeNode[] = [
18
+ {
19
+ id: "1",
20
+ title: "Work",
21
+ children: [
22
+ {
23
+ id: "1-1",
24
+ title: "Reports",
25
+ children: [
26
+ {
27
+ id: "1-1-1",
28
+ title: "2023",
29
+ children: [
30
+ {
31
+ id: "1-1-1-1",
32
+ title: "Q1 Report",
33
+ children: [
34
+ { id: "1-1-1-1-1", title: "Summary", children: [] },
35
+ { id: "1-1-1-1-2", title: "Details", children: [] },
36
+ ],
37
+ },
38
+ ],
39
+ },
40
+ ],
41
+ },
42
+ {
43
+ id: "1-2",
44
+ title: "Presentations",
45
+ children: [
46
+ {
47
+ id: "1-2-1",
48
+ title: "2023 Projects",
49
+ children: [
50
+ {
51
+ id: "1-2-1-1",
52
+ title: "Project A",
53
+ children: [
54
+ { id: "1-2-1-1-1", title: "Draft", children: [] },
55
+ { id: "1-2-1-1-2", title: "Final", children: [] },
56
+ ],
57
+ },
58
+ {
59
+ id: "1-2-1-2",
60
+ title: "Project B",
61
+ children: [
62
+ { id: "1-2-1-2-1", title: "Research", children: [] },
63
+ ],
64
+ },
65
+ ],
66
+ },
67
+ ],
68
+ },
69
+ ],
70
+ },
71
+ {
72
+ id: "2",
73
+ title: "Personal",
74
+ children: [
75
+ {
76
+ id: "2-1",
77
+ title: "Hobbies",
78
+ children: [
79
+ {
80
+ id: "2-1-1",
81
+ title: "Photography",
82
+ children: [
83
+ { id: "2-1-1-1", title: "Travel", children: [] },
84
+ { id: "2-1-1-2", title: "Portraits", children: [] },
85
+ ],
86
+ },
87
+ {
88
+ id: "2-1-2",
89
+ title: "Cooking",
90
+ children: [{ id: "2-1-2-1", title: "Recipes", children: [] }],
91
+ },
92
+ ],
93
+ },
94
+ ],
95
+ },
96
+ {
97
+ id: "3",
98
+ title: "Projects",
99
+ children: [
100
+ {
101
+ id: "3-1",
102
+ title: "Web Development",
103
+ children: [
104
+ {
105
+ id: "3-1-1",
106
+ title: "Portfolio",
107
+ children: [
108
+ { id: "3-1-1-1", title: "Images", children: [] },
109
+ { id: "3-1-1-2", title: "CSS", children: [] },
110
+ ],
111
+ },
112
+ { id: "3-1-2", title: "Landing Page", children: [] },
113
+ ],
114
+ },
115
+ {
116
+ id: "3-2",
117
+ title: "Mobile Apps",
118
+ children: [{ id: "3-2-1", title: "Weather App", children: [] }],
119
+ },
120
+ ],
121
+ },
122
+ {
123
+ id: "4",
124
+ title: "Finance",
125
+ children: [
126
+ {
127
+ id: "4-1",
128
+ title: "Budget",
129
+ children: [
130
+ {
131
+ id: "4-1-1",
132
+ title: "2023",
133
+ children: [
134
+ { id: "4-1-1-1", title: "January", children: [] },
135
+ { id: "4-1-1-2", title: "February", children: [] },
136
+ ],
137
+ },
138
+ ],
139
+ },
140
+ ],
141
+ },
142
+ {
143
+ id: "5",
144
+ title: "Health",
145
+ children: [
146
+ {
147
+ id: "5-1",
148
+ title: "Fitness",
149
+ children: [
150
+ { id: "5-1-1", title: "Workouts", children: [] },
151
+ { id: "5-1-2", title: "Nutrition", children: [] },
152
+ ],
153
+ },
154
+ { id: "5-2", title: "Wellness", children: [] },
155
+ ],
156
+ },
157
+ ];
158
+
159
+ /**
160
+ * El componente Tree proporciona una vista jerárquica de datos en forma de árbol.
161
+ * Está construido sobre [@react-aria](https://react-spectrum.adobe.com/react-aria/Tree.html#tree)
162
+ * y soporta selección, expansión, navegación por teclado y más.
163
+ *
164
+ * ## Nodo
165
+ * Los nodos del árbol deben tener las siguientes propiedades:
166
+ *
167
+ * ```tsx
168
+ * interface TreeNode {
169
+ * id: string | number;
170
+ * title: string;
171
+ * children: TreeNode[];
172
+ * }
173
+ * ```
174
+ */
175
+ const meta: Meta<typeof Tree> = {
176
+ title: "Data display/Tree",
177
+ component: Tree,
178
+ subcomponents: {
179
+ TreeRoot: TreeRoot as ComponentType<unknown>,
180
+ TreeItem: TreeItem as ComponentType<unknown>,
181
+ TreeItemContent: TreeItemContent as ComponentType<unknown>,
182
+ TreeItemIndicator: TreeItemIndicator as ComponentType<unknown>,
183
+ TreeItemLabel: TreeItemLabel as ComponentType<unknown>,
184
+ Collection: Collection as ComponentType<unknown>,
185
+ },
186
+ args: {
187
+ items: files,
188
+ selectionMode: "single",
189
+ },
190
+ argTypes: {
191
+ selectedKeys: {
192
+ description: "Las claves actualmente seleccionadas en la colección",
193
+ control: "object",
194
+ table: {
195
+ type: { summary: "'all' | Iterable<Key>" },
196
+ defaultValue: { summary: "—" },
197
+ },
198
+ },
199
+ defaultSelectedKeys: {
200
+ description: "Las claves inicialmente seleccionadas en la colección",
201
+ control: "object",
202
+ table: {
203
+ type: { summary: "'all' | Iterable<Key>" },
204
+ defaultValue: { summary: "—" },
205
+ },
206
+ },
207
+ expandedKeys: {
208
+ description: "Las claves actualmente expandidas en la colección",
209
+ control: "object",
210
+ table: {
211
+ type: { summary: "Iterable<Key>" },
212
+ defaultValue: { summary: "—" },
213
+ },
214
+ },
215
+ defaultExpandedKeys: {
216
+ description: "Las claves inicialmente expandidas en la colección",
217
+ control: "object",
218
+ table: {
219
+ type: { summary: "Iterable<Key>" },
220
+ defaultValue: { summary: "—" },
221
+ },
222
+ },
223
+ selectionMode: {
224
+ description: "El tipo de selección que está permitida en el árbol",
225
+ control: "select",
226
+ options: ["none", "single", "multiple"],
227
+ table: {
228
+ type: { summary: "'none' | 'single' | 'multiple'" },
229
+ defaultValue: { summary: "'none'" },
230
+ },
231
+ },
232
+ disabledKeys: {
233
+ description: "Las claves de los elementos que están deshabilitados",
234
+ control: "object",
235
+ table: {
236
+ type: { summary: "Iterable<Key>" },
237
+ defaultValue: { summary: "—" },
238
+ },
239
+ },
240
+ disallowEmptySelection: {
241
+ description:
242
+ "Si se debe permitir que no haya ningún elemento seleccionado",
243
+ control: "boolean",
244
+ table: {
245
+ type: { summary: "boolean" },
246
+ },
247
+ },
248
+ onSelectionChange: {
249
+ description: "Manejador llamado cuando cambia la selección",
250
+ table: {
251
+ type: { summary: "(keys: 'all' | Iterable<Key>) => void" },
252
+ defaultValue: { summary: "—" },
253
+ },
254
+ },
255
+ onExpandedChange: {
256
+ description: "Manejador llamado cuando cambian los elementos expandidos",
257
+ table: {
258
+ type: { summary: "(keys: Iterable<Key>) => void" },
259
+ defaultValue: { summary: "—" },
260
+ },
261
+ },
262
+ onAction: {
263
+ description:
264
+ "Manejador llamado cuando un usuario realiza una acción en un elemento. El evento exacto depende del prop selectionBehavior y la modalidad de interacción",
265
+ table: {
266
+ type: { summary: "(key: Key) => void" },
267
+ defaultValue: { summary: "—" },
268
+ },
269
+ },
270
+ onScroll: {
271
+ description: "Manejador llamado cuando un usuario hace scroll",
272
+ table: {
273
+ type: { summary: "(e: UIEvent<Element>) => void" },
274
+ defaultValue: { summary: "—" },
275
+ },
276
+ },
277
+ },
278
+ };
279
+
280
+ export default meta;
281
+ type Story = StoryObj<typeof Tree>;
282
+
283
+ /**
284
+ * Ejemplo básico del árbol con selección simple habilitada.
285
+ * Los usuarios pueden expandir/colapsar nodos y seleccionar un elemento a la vez.
286
+ */
287
+ export const Default: Story = {};
288
+
289
+ /**
290
+ * Configuración que permite seleccionar un solo elemento a la vez.
291
+ * Útil cuando necesitas que el usuario elija una única opción del árbol.
292
+ */
293
+ export const SingleSelection: Story = {
294
+ args: {
295
+ selectionMode: "single",
296
+ },
297
+ };
298
+
299
+ /**
300
+ * Permite seleccionar múltiples elementos simultáneamente.
301
+ * Los usuarios pueden usar `click` para selección individual
302
+ * o `shift + click` para selección en rango.
303
+ */
304
+ export const MultipleSelection: Story = {
305
+ args: {
306
+ selectionMode: "multiple",
307
+ },
308
+ };
309
+
310
+ /**
311
+ * Ejemplo de árbol con nodos deshabilitados completamente.
312
+ * Los elementos deshabilitados no pueden ser seleccionados ni expandidos.
313
+ *
314
+ * `disabledBehavior="all"` - Deshabilita todas las interacciones
315
+ *
316
+ * `disabledKeys` - Array de IDs de elementos a deshabilitar
317
+ */
318
+ export const Disabled: Story = {
319
+ args: {
320
+ disabledBehavior: "all",
321
+ disabledKeys: ["1", "2", "3"],
322
+ },
323
+ };
324
+
325
+ /**
326
+ * Ejemplo donde solo la selección está deshabilitada.
327
+ * Los elementos pueden expandirse pero no pueden ser seleccionados.
328
+ *
329
+ * `disabledBehavior="selection"` - Solo deshabilita la selección
330
+ *
331
+ * `disabledKeys` - Array de IDs de elementos a deshabilitar
332
+ */
333
+ export const DisabledSelection: Story = {
334
+ args: {
335
+ disabledBehavior: "selection",
336
+ disabledKeys: ["1", "2", "3"],
337
+ },
338
+ };
339
+
340
+ /**
341
+ * Árbol con nodos inicialmente expandidos.
342
+ * Útil para mostrar cierta estructura desde el inicio.
343
+ *
344
+ * `defaultExpandedKeys` - Array de IDs de elementos expandidos por defecto
345
+ */
346
+ export const DefaultExpanded: Story = {
347
+ args: {
348
+ defaultExpandedKeys: ["1", "1-1", "1-1-1", "1-1-1-1"],
349
+ },
350
+ };
351
+
352
+ /**
353
+ * Ejemplo de árbol con expansión controlada.
354
+ * El estado de expansión es manejado externamente.
355
+ *
356
+ * `expandedKeys` - Control explícito de los elementos expandidos
357
+ */
358
+ export const ControlledExpanded: Story = {
359
+ args: {
360
+ expandedKeys: ["1", "7"],
361
+ },
362
+ };
363
+
364
+ /**
365
+ * Árbol con selección inicial predeterminada.
366
+ *
367
+ * `defaultSelectedKeys` - Array de IDs de elementos seleccionados por defecto
368
+ */
369
+ export const DefaultSelected: Story = {
370
+ args: {
371
+ selectionMode: "single",
372
+ defaultSelectedKeys: ["4"],
373
+ },
374
+ };
375
+
376
+ /**
377
+ * Demostración de los eventos disponibles en el árbol.
378
+ * Muestra notificaciones toast para:
379
+ * - Cambios en expansión
380
+ * - Cambios en selección
381
+ * - Eventos de scroll
382
+ */
383
+ export const Events: Story = {
384
+ args: {
385
+ className: "h-96 overflow-y-auto border",
386
+ onExpandedChange: (keys: any) =>
387
+ toastManager.add({
388
+ variant: "success",
389
+ description: `Expanded: ${Array.from(keys)}`,
390
+ }),
391
+ onSelectionChange: (keys: any) =>
392
+ toastManager.add({
393
+ variant: "success",
394
+ description: `Selected: ${Array.from(keys)}`,
395
+ }),
396
+ onScroll: () =>
397
+ toastManager.add({ variant: "success", description: "Scroll" }),
398
+ },
399
+ decorators: [
400
+ (Story: any) => (
401
+ <ToastProvider toastManager={toastManager}>
402
+ <Story />
403
+ </ToastProvider>
404
+ ),
405
+ ],
406
+ };
407
+
408
+ /**
409
+ * ## Estructura con componentes primitivos
410
+ * ```tsx
411
+ * import { TreeRoot, TreeItem, Collection } from '../../components/tree'
412
+ *
413
+ * const Estructura = () => {
414
+ * return (
415
+ * <TreeRoot>
416
+ * <TreeItem>
417
+ * <TreeItemContent>
418
+ * <TreeItemIndicator />
419
+ * <TreeItemLabel>Item Label</TreeItemLabel>
420
+ * </TreeItemContent>
421
+ * <Collection>
422
+ * Child items
423
+ * </Collection>
424
+ * </TreeItem>
425
+ * </TreeRoot>
426
+ * )
427
+ * }
428
+ * ```
429
+ *
430
+ * Los componentes primitivos del Tree son:
431
+ *
432
+ * - `TreeRoot`: Contenedor principal que maneja la selección y expansión
433
+ * - `TreeItem`: Representa cada elemento del árbol
434
+ * - `TreeItemContent`: Contenedor del contenido del item
435
+ * - `TreeItemIndicator`: Indicador de expansión (chevron)
436
+ * - `TreeItemLabel`: Etiqueta del item
437
+ * - `Collection`: Contenedor de items hijos que permite manejo con teclado
438
+ */
439
+
440
+ export const Primitive: Story = {
441
+ render: () => {
442
+ const renderItem = (item: TreeNode) => {
443
+ return (
444
+ <TreeItem key={item.id} id={item.id} textValue={item.title}>
445
+ <TreeItemContent>
446
+ {item.children.length > 0 && <TreeItemIndicator />}
447
+ <TreeItemLabel>{item.title}</TreeItemLabel>
448
+ </TreeItemContent>
449
+ {item.children.length > 0 && (
450
+ <Collection>
451
+ {item.children.map((child: any) => renderItem(child))}
452
+ </Collection>
453
+ )}
454
+ </TreeItem>
455
+ );
456
+ };
457
+
458
+ return (
459
+ <TreeRoot
460
+ aria-label="Files"
461
+ selectionMode="multiple"
462
+ selectionBehavior="replace"
463
+ >
464
+ {files.map((item) => renderItem(item))}
465
+ </TreeRoot>
466
+ );
467
+ },
468
+ };
@@ -0,0 +1,42 @@
1
+ import * as React from "react";
2
+ import {
3
+ Collection,
4
+ TreeItem,
5
+ TreeItemContent,
6
+ TreeItemIndicator,
7
+ TreeItemLabel,
8
+ TreeRoot,
9
+ } from "./tree-primitives";
10
+
11
+ export interface TreeNode {
12
+ id: string | number;
13
+ title: string;
14
+ children: TreeNode[];
15
+ }
16
+
17
+ type TreeRootProps = React.ComponentProps<typeof TreeRoot>;
18
+ type Props<T extends TreeNode> = TreeRootProps & { items: T[] };
19
+
20
+ export function Tree<T extends TreeNode>({ items, ...props }: Props<T>) {
21
+ const renderItem = (item: T): React.ReactNode => {
22
+ return (
23
+ <TreeItem key={item.id} id={item.id} textValue={item.title}>
24
+ <TreeItemContent>
25
+ {item.children?.length ? <TreeItemIndicator /> : null}
26
+ <TreeItemLabel>{item.title}</TreeItemLabel>
27
+ </TreeItemContent>
28
+ {item.children?.length ? (
29
+ <Collection items={item.children as Iterable<T>}>
30
+ {renderItem}
31
+ </Collection>
32
+ ) : null}
33
+ </TreeItem>
34
+ );
35
+ };
36
+
37
+ return (
38
+ <TreeRoot items={items} {...props}>
39
+ {items.map((item) => renderItem(item))}
40
+ </TreeRoot>
41
+ );
42
+ }
@@ -0,0 +1,26 @@
1
+ export { useControllableState } from "@radix-ui/react-use-controllable-state";
2
+ export * from "./useArray";
3
+ export * from "./useAsync";
4
+ export * from "./useClickOutside";
5
+ export * from "./useClipboard";
6
+ export * from "./useDebounceCallback";
7
+ export * from "./useDebounceValue";
8
+ export * from "./useDisclosure";
9
+ export * from "./useDocumentTitle";
10
+ export * from "./useEventListener";
11
+ export * from "./useFocusTrap";
12
+ export * from "./useHotkey";
13
+ export * from "./useHover";
14
+ export * from "./useIsVisible";
15
+ export * from "./useLocalStorage";
16
+ export * from "./useMediaQuery";
17
+ export * from "./useMemoizedFn";
18
+ export * from "./useMutation";
19
+ export * from "./useObject";
20
+ export * from "./usePagination";
21
+ export * from "./usePortal";
22
+ export * from "./usePreventCloseWindow";
23
+ export * from "./useRangePagination";
24
+ export * from "./useSelection";
25
+ export * from "./useStep";
26
+ export * from "./useToggle";
@@ -0,0 +1,100 @@
1
+ import { Meta, StoryObj } from "@storybook/react-vite";
2
+ import { Trash } from "lucide-react";
3
+ import { Button } from "../../../components";
4
+ import useArray from "../useArray";
5
+
6
+ /**
7
+ * Hook que facilita el manejo de estado de una lista
8
+ * Se exponen los siguientes métodos:
9
+ *
10
+ * | Método | Descripción |
11
+ * | --- | --- |
12
+ * | `insertAt(index: number, item: T)` | Inserta un elemento en un índice específico en la lista. |
13
+ * | `removeAt(index: number)` | Elimina un elemento en un índice específico de la lista. |
14
+ * | `updateAt(index: number, newItem: T)` | Actualiza un elemento en un índice específico de la lista. |
15
+ * | `clear()` | Elimina todos los elementos de la lista. |
16
+ * | `reset()` | Restablece la lista a su valor por defecto o inicial. |
17
+ * | `push(item: T)` | Agrega un nuevo elemento al final de la lista. |
18
+ * | `pop()` | Elimina el último elemento de la lista. |
19
+ * | `set(newList: T[])` | Actualiza la lista con una nueva lista. |
20
+ * | `update(predicate: ListIterateeCustom<T, boolean>, newItem: T | (item: T) => T)` | Actualiza un elemento de la lista.
21
+ */
22
+ const meta: Meta = {
23
+ title: "hooks/useArray",
24
+ };
25
+
26
+ export default meta;
27
+
28
+ type Story = StoryObj<typeof meta>;
29
+
30
+ export const Default: Story = {
31
+ render: () => {
32
+ const [list, { insertAt, removeAt, clear, reset, pop, update }] =
33
+ useArray<string>(["First", "Second", "Third"]);
34
+
35
+ return (
36
+ <div className="space-y-2">
37
+ <div className="flex gap-2 flex-wrap">
38
+ <Button disabled={list.length < 1} onClick={() => insertAt(1, "woo")}>
39
+ Insertar despúes del primero
40
+ </Button>
41
+ <Button disabled={list.length < 2} onClick={() => removeAt(1)}>
42
+ Eliminar segundo item
43
+ </Button>
44
+ <Button disabled={list.length < 2} onClick={() => pop()}>
45
+ Eliminar el último item
46
+ </Button>
47
+ <Button
48
+ onClick={() => update((item: string) => item === "First", "🐙")}
49
+ >
50
+ Actualizar primer elemento por 🐙
51
+ </Button>
52
+ <Button onClick={reset}>Resetear</Button>
53
+ <Button onClick={clear}>Limpiar</Button>
54
+ </div>
55
+
56
+ <pre className="rounded-md bg-slate-950 p-4 text-white">
57
+ <code className="block">
58
+ List:{" "}
59
+ <span className="text-blue-300">
60
+ {JSON.stringify(list, null, 2)}
61
+ </span>
62
+ </code>
63
+ </pre>
64
+ </div>
65
+ );
66
+ },
67
+ };
68
+
69
+ export const DynamicList: Story = {
70
+ render: () => {
71
+ const [list, updateList] = useArray<string>([]);
72
+
73
+ const addItem = () => updateList.push(`Item ${list.length + 1}`);
74
+
75
+ return (
76
+ <div className="space-y-2">
77
+ <div className="flex items-center gap-2">
78
+ <Button onClick={addItem}>Add Item</Button>
79
+ <Button onClick={updateList.clear}>
80
+ <Trash /> Clear
81
+ </Button>
82
+ </div>
83
+ <ul>
84
+ {list.map((item, index) => (
85
+ <li key={index}>
86
+ {item}{" "}
87
+ <Button
88
+ size="icon"
89
+ variant="ghost"
90
+ onClick={() => updateList.removeAt(index)}
91
+ >
92
+ <Trash />
93
+ </Button>
94
+ </li>
95
+ ))}
96
+ </ul>
97
+ </div>
98
+ );
99
+ },
100
+ };