@fabio.caffarello/react-design-system 1.7.0 → 1.8.0

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 (460) hide show
  1. package/README.md +48 -3
  2. package/dist/docs/components/ComponentStatusTable.d.ts +11 -0
  3. package/dist/ui/atoms/Accordion/Accordion.d.ts +34 -0
  4. package/dist/ui/atoms/Accordion/Accordion.stories.d.ts +11 -0
  5. package/dist/ui/atoms/Accordion/Accordion.test.d.ts +1 -0
  6. package/dist/ui/atoms/Accordion/index.d.ts +2 -0
  7. package/dist/ui/atoms/Avatar/Avatar.d.ts +30 -0
  8. package/dist/ui/atoms/Avatar/Avatar.stories.d.ts +13 -0
  9. package/dist/ui/atoms/Avatar/Avatar.test.d.ts +1 -0
  10. package/dist/ui/atoms/Avatar/AvatarGroup.d.ts +26 -0
  11. package/dist/ui/atoms/Avatar/index.d.ts +9 -0
  12. package/dist/ui/atoms/Badge/Badge.d.ts +14 -6
  13. package/dist/ui/atoms/Badge/Badge.stories.d.ts +8 -9
  14. package/dist/ui/atoms/BoxWrapper/BoxWrapper.d.ts +3 -3
  15. package/dist/ui/atoms/BoxWrapper/BoxWrapper.test.d.ts +1 -0
  16. package/dist/ui/atoms/Button/Button.d.ts +32 -10
  17. package/dist/ui/atoms/Button/Button.stories.d.ts +7 -0
  18. package/dist/ui/atoms/Button/Button.test.d.ts +1 -0
  19. package/dist/ui/atoms/Checkbox/Checkbox.d.ts +2 -1
  20. package/dist/ui/atoms/Collapsible/Collapsible.stories.d.ts +2 -0
  21. package/dist/ui/atoms/Info/Info.d.ts +2 -3
  22. package/dist/ui/atoms/Info/Info.test.d.ts +1 -0
  23. package/dist/ui/atoms/Input/Input.d.ts +14 -4
  24. package/dist/ui/atoms/Input/Input.stories.d.ts +6 -0
  25. package/dist/ui/atoms/Popover/Popover.d.ts +35 -0
  26. package/dist/ui/atoms/Popover/Popover.stories.d.ts +11 -0
  27. package/dist/ui/atoms/Popover/Popover.test.d.ts +1 -0
  28. package/dist/ui/atoms/Popover/index.d.ts +2 -0
  29. package/dist/ui/atoms/Progress/Progress.d.ts +33 -0
  30. package/dist/ui/atoms/Progress/Progress.stories.d.ts +12 -0
  31. package/dist/ui/atoms/Progress/Progress.test.d.ts +1 -0
  32. package/dist/ui/atoms/Select/Select.d.ts +18 -6
  33. package/dist/ui/atoms/Select/Select.stories.d.ts +11 -8
  34. package/dist/ui/atoms/Separator/Separator.d.ts +23 -0
  35. package/dist/ui/atoms/Separator/Separator.stories.d.ts +10 -0
  36. package/dist/ui/atoms/Separator/Separator.test.d.ts +1 -0
  37. package/dist/ui/atoms/Separator/index.d.ts +2 -0
  38. package/dist/ui/atoms/Skeleton/Skeleton.d.ts +1 -1
  39. package/dist/ui/atoms/Skeleton/Skeleton.stories.d.ts +24 -0
  40. package/dist/ui/atoms/Slider/Slider.d.ts +45 -0
  41. package/dist/ui/atoms/Slider/Slider.stories.d.ts +13 -0
  42. package/dist/ui/atoms/Slider/Slider.test.d.ts +1 -0
  43. package/dist/ui/atoms/Slider/index.d.ts +2 -0
  44. package/dist/ui/atoms/Spinner/Spinner.d.ts +22 -0
  45. package/dist/ui/atoms/Spinner/Spinner.stories.d.ts +9 -0
  46. package/dist/ui/atoms/Spinner/Spinner.test.d.ts +1 -0
  47. package/dist/ui/atoms/Switch/Switch.d.ts +28 -0
  48. package/dist/ui/atoms/Switch/Switch.stories.d.ts +11 -0
  49. package/dist/ui/atoms/Switch/Switch.test.d.ts +1 -0
  50. package/dist/ui/atoms/Switch/index.d.ts +2 -0
  51. package/dist/ui/atoms/Tooltip/Tooltip.d.ts +2 -1
  52. package/dist/ui/atoms/Tooltip/Tooltip.stories.d.ts +17 -0
  53. package/dist/ui/atoms/index.d.ts +20 -3
  54. package/dist/ui/index.d.ts +6 -1
  55. package/dist/ui/molecules/Card/Card.d.ts +6 -2
  56. package/dist/ui/molecules/Card/Card.stories.d.ts +2 -0
  57. package/dist/ui/molecules/ColorPicker/ColorPicker.d.ts +28 -0
  58. package/dist/ui/molecules/ColorPicker/ColorPicker.stories.d.ts +12 -0
  59. package/dist/ui/molecules/ColorPicker/ColorPicker.test.d.ts +1 -0
  60. package/dist/ui/molecules/ColorPicker/index.d.ts +2 -0
  61. package/dist/ui/molecules/DatePicker/DatePicker.d.ts +74 -0
  62. package/dist/ui/molecules/DatePicker/DatePicker.stories.d.ts +12 -0
  63. package/dist/ui/molecules/DatePicker/DatePicker.test.d.ts +1 -0
  64. package/dist/ui/molecules/DatePicker/DatePickerCalendar.d.ts +6 -0
  65. package/dist/ui/molecules/DatePicker/DatePickerContext.d.ts +28 -0
  66. package/dist/ui/molecules/DatePicker/DatePickerInput.d.ts +9 -0
  67. package/dist/ui/molecules/DatePicker/DatePickerProvider.d.ts +23 -0
  68. package/dist/ui/molecules/DatePicker/index.d.ts +14 -0
  69. package/dist/ui/molecules/Dropdown/Dropdown.d.ts +2 -1
  70. package/dist/ui/molecules/Dropdown/Dropdown.stories.d.ts +13 -0
  71. package/dist/ui/molecules/EmptyState/EmptyState.stories.d.ts +22 -0
  72. package/dist/ui/molecules/FileUpload/FileUpload.d.ts +37 -0
  73. package/dist/ui/molecules/FileUpload/FileUpload.stories.d.ts +12 -0
  74. package/dist/ui/molecules/FileUpload/FileUpload.test.d.ts +1 -0
  75. package/dist/ui/molecules/FileUpload/index.d.ts +2 -0
  76. package/dist/ui/molecules/Form/Form.d.ts +29 -4
  77. package/dist/ui/molecules/Form/Form.stories.d.ts +2 -0
  78. package/dist/ui/molecules/Form/FormContext.d.ts +17 -0
  79. package/dist/ui/molecules/Form/FormField.d.ts +36 -0
  80. package/dist/ui/molecules/Form/FormProvider.d.ts +14 -0
  81. package/dist/ui/molecules/Form/index.d.ts +13 -0
  82. package/dist/ui/molecules/Form/useFormFieldArray.d.ts +28 -0
  83. package/dist/ui/molecules/InputWithLabel/InputWithLabel.test.d.ts +1 -0
  84. package/dist/ui/molecules/Rating/Rating.d.ts +33 -0
  85. package/dist/ui/molecules/Rating/Rating.stories.d.ts +13 -0
  86. package/dist/ui/molecules/Rating/Rating.test.d.ts +1 -0
  87. package/dist/ui/molecules/Rating/index.d.ts +2 -0
  88. package/dist/ui/molecules/SearchInput/SearchInput.d.ts +24 -0
  89. package/dist/ui/molecules/SearchInput/SearchInput.stories.d.ts +10 -0
  90. package/dist/ui/molecules/SearchInput/SearchInput.test.d.ts +1 -0
  91. package/dist/ui/molecules/SearchInput/index.d.ts +2 -0
  92. package/dist/ui/molecules/SidebarHeader/SidebarHeader.test.d.ts +1 -0
  93. package/dist/ui/molecules/TableActions/TableActions.d.ts +31 -0
  94. package/dist/ui/molecules/TableActions/TableActions.stories.d.ts +7 -0
  95. package/dist/ui/molecules/TableActions/TableActions.test.d.ts +1 -0
  96. package/dist/ui/molecules/TableFilters/TableFilters.d.ts +37 -0
  97. package/dist/ui/molecules/TableFilters/TableFilters.stories.d.ts +7 -0
  98. package/dist/ui/molecules/TableFilters/TableFilters.test.d.ts +1 -0
  99. package/dist/ui/molecules/TablePagination/TablePagination.d.ts +29 -0
  100. package/dist/ui/molecules/TablePagination/TablePagination.stories.d.ts +8 -0
  101. package/dist/ui/molecules/TablePagination/TablePagination.test.d.ts +1 -0
  102. package/dist/ui/molecules/Tabs/Tabs.d.ts +15 -0
  103. package/dist/ui/molecules/Tabs/Tabs.stories.d.ts +10 -0
  104. package/dist/ui/molecules/Tabs/Tabs.test.d.ts +1 -0
  105. package/dist/ui/molecules/Tabs/TabsContent.d.ts +14 -0
  106. package/dist/ui/molecules/Tabs/TabsContext.d.ts +18 -0
  107. package/dist/ui/molecules/Tabs/TabsList.d.ts +12 -0
  108. package/dist/ui/molecules/Tabs/TabsProvider.d.ts +16 -0
  109. package/dist/ui/molecules/Tabs/TabsTrigger.d.ts +13 -0
  110. package/dist/ui/molecules/Tabs/index.d.ts +17 -0
  111. package/dist/ui/molecules/TimePicker/TimePicker.d.ts +29 -0
  112. package/dist/ui/molecules/TimePicker/TimePicker.stories.d.ts +12 -0
  113. package/dist/ui/molecules/TimePicker/TimePicker.test.d.ts +1 -0
  114. package/dist/ui/molecules/TimePicker/index.d.ts +2 -0
  115. package/dist/ui/molecules/index.d.ts +13 -5
  116. package/dist/ui/organisms/CommandPalette/CommandPalette.d.ts +37 -0
  117. package/dist/ui/organisms/CommandPalette/CommandPalette.stories.d.ts +11 -0
  118. package/dist/ui/organisms/CommandPalette/CommandPalette.test.d.ts +1 -0
  119. package/dist/ui/organisms/CommandPalette/index.d.ts +2 -0
  120. package/dist/ui/organisms/DataGrid/DataGrid.d.ts +84 -0
  121. package/dist/ui/organisms/DataGrid/DataGrid.stories.d.ts +14 -0
  122. package/dist/ui/organisms/DataGrid/DataGrid.test.d.ts +1 -0
  123. package/dist/ui/organisms/DataGrid/index.d.ts +2 -0
  124. package/dist/ui/organisms/Dialog/AlertDialog.d.ts +34 -0
  125. package/dist/ui/organisms/Dialog/Dialog.d.ts +58 -0
  126. package/dist/ui/organisms/Dialog/Dialog.stories.d.ts +13 -0
  127. package/dist/ui/organisms/Dialog/Dialog.test.d.ts +1 -0
  128. package/dist/ui/organisms/Dialog/DialogClose.d.ts +8 -0
  129. package/dist/ui/organisms/Dialog/DialogContent.d.ts +8 -0
  130. package/dist/ui/organisms/Dialog/DialogContext.d.ts +10 -0
  131. package/dist/ui/organisms/Dialog/DialogDescription.d.ts +4 -0
  132. package/dist/ui/organisms/Dialog/DialogFooter.d.ts +5 -0
  133. package/dist/ui/organisms/Dialog/DialogHeader.d.ts +5 -0
  134. package/dist/ui/organisms/Dialog/DialogProvider.d.ts +10 -0
  135. package/dist/ui/organisms/Dialog/DialogTitle.d.ts +5 -0
  136. package/dist/ui/organisms/Dialog/DialogTrigger.d.ts +6 -0
  137. package/dist/ui/organisms/Dialog/index.d.ts +22 -0
  138. package/dist/ui/organisms/Sidebar/Sidebar.d.ts +7 -4
  139. package/dist/ui/organisms/Sidebar/SidebarGroup/SidebarGroup.d.ts +27 -0
  140. package/dist/ui/organisms/Sidebar/SidebarGroup/SidebarGroup.stories.d.ts +11 -0
  141. package/dist/ui/organisms/Sidebar/SidebarGroup/SidebarGroup.test.d.ts +1 -0
  142. package/dist/ui/organisms/Sidebar/SidebarHeader/SidebarHeader.d.ts +19 -0
  143. package/dist/ui/organisms/Sidebar/SidebarHeader/SidebarHeader.test.d.ts +1 -0
  144. package/dist/ui/organisms/Sidebar/SidebarItem/SidebarItem.d.ts +23 -0
  145. package/dist/ui/organisms/Sidebar/SidebarItem/SidebarItem.stories.d.ts +10 -0
  146. package/dist/ui/organisms/Sidebar/SidebarItem/SidebarItem.test.d.ts +1 -0
  147. package/dist/ui/organisms/Sidebar/index.d.ts +8 -0
  148. package/dist/ui/organisms/Stepper/Stepper.d.ts +40 -0
  149. package/dist/ui/organisms/Stepper/Stepper.stories.d.ts +12 -0
  150. package/dist/ui/organisms/Stepper/Stepper.test.d.ts +1 -0
  151. package/dist/ui/organisms/Stepper/index.d.ts +2 -0
  152. package/dist/ui/organisms/Table/Table.d.ts +84 -16
  153. package/dist/ui/organisms/Table/Table.stories.d.ts +15 -0
  154. package/dist/ui/organisms/Table/TableActions/TableActions.d.ts +31 -0
  155. package/dist/ui/organisms/Table/TableActions/TableActions.stories.d.ts +7 -0
  156. package/dist/ui/organisms/Table/TableActions/TableActions.test.d.ts +1 -0
  157. package/dist/ui/organisms/Table/TableActions.d.ts +13 -0
  158. package/dist/ui/organisms/Table/TableBody.d.ts +12 -0
  159. package/dist/ui/organisms/Table/TableCell.d.ts +14 -0
  160. package/dist/ui/organisms/Table/TableContext.d.ts +75 -0
  161. package/dist/ui/organisms/Table/TableEmptyState.d.ts +11 -0
  162. package/dist/ui/organisms/Table/TableFilters/TableFilters.d.ts +37 -0
  163. package/dist/ui/organisms/Table/TableFilters/TableFilters.stories.d.ts +7 -0
  164. package/dist/ui/organisms/Table/TableFilters/TableFilters.test.d.ts +1 -0
  165. package/dist/ui/organisms/Table/TableFilters.d.ts +12 -0
  166. package/dist/ui/organisms/Table/TableHeader.d.ts +10 -0
  167. package/dist/ui/organisms/Table/TableHeaderCell.d.ts +18 -0
  168. package/dist/ui/organisms/Table/TableHeaderRow.d.ts +10 -0
  169. package/dist/ui/organisms/Table/TablePagination/TablePagination.d.ts +29 -0
  170. package/dist/ui/organisms/Table/TablePagination/TablePagination.stories.d.ts +8 -0
  171. package/dist/ui/organisms/Table/TablePagination/TablePagination.test.d.ts +1 -0
  172. package/dist/ui/organisms/Table/TablePagination.d.ts +14 -0
  173. package/dist/ui/organisms/Table/TableProvider.d.ts +55 -0
  174. package/dist/ui/organisms/Table/TableRow.d.ts +14 -0
  175. package/dist/ui/organisms/Table/TableTypes.d.ts +8 -0
  176. package/dist/ui/organisms/Table/index.d.ts +30 -0
  177. package/dist/ui/organisms/Table/useColumnResizing.d.ts +39 -0
  178. package/dist/ui/organisms/Table/useVirtualScrolling.d.ts +35 -0
  179. package/dist/ui/organisms/Timeline/Timeline.d.ts +34 -0
  180. package/dist/ui/organisms/Timeline/Timeline.stories.d.ts +12 -0
  181. package/dist/ui/organisms/Timeline/Timeline.test.d.ts +1 -0
  182. package/dist/ui/organisms/Timeline/index.d.ts +2 -0
  183. package/dist/ui/organisms/Toast/Toast.d.ts +8 -0
  184. package/dist/ui/organisms/Toast/Toast.stories.d.ts +14 -0
  185. package/dist/ui/organisms/Toast/Toast.test.d.ts +1 -0
  186. package/dist/ui/organisms/Toast/ToastContainer.d.ts +5 -0
  187. package/dist/ui/organisms/Toast/ToastContext.d.ts +21 -0
  188. package/dist/ui/organisms/Toast/ToastProvider.d.ts +7 -0
  189. package/dist/ui/organisms/Toast/index.d.ts +15 -0
  190. package/dist/ui/organisms/Toast/useToast.d.ts +35 -0
  191. package/dist/ui/organisms/index.d.ts +12 -2
  192. package/dist/ui/providers/AdvancedThemeProvider.d.ts +52 -0
  193. package/dist/ui/providers/index.d.ts +9 -0
  194. package/dist/ui/themes/ThemeBuilder.d.ts +28 -0
  195. package/dist/ui/themes/ThemeRegistry.d.ts +55 -0
  196. package/dist/ui/themes/index.d.ts +9 -0
  197. package/dist/ui/themes/types.d.ts +48 -0
  198. package/dist/ui/themes/utils.d.ts +21 -0
  199. package/dist/ui/tokens/TokenVisualizations.d.ts +41 -0
  200. package/dist/ui/tokens/animations.d.ts +65 -0
  201. package/dist/ui/tokens/borders.d.ts +61 -0
  202. package/dist/ui/tokens/gradients.d.ts +55 -0
  203. package/dist/ui/tokens/index.d.ts +31 -0
  204. package/dist/ui/tokens/opacity.d.ts +51 -0
  205. package/dist/ui/tokens/radius.d.ts +45 -0
  206. package/dist/ui/tokens/shadows.d.ts +42 -0
  207. package/dist/ui/tokens/themes/dark.d.ts +26 -26
  208. package/dist/ui/tokens/themes/light.d.ts +26 -26
  209. package/dist/ui/tokens/tokens.factory.d.ts +42 -0
  210. package/dist/ui/tokens/z-index.d.ts +44 -0
  211. package/dist/ui/utils/index.d.ts +6 -0
  212. package/package.json +50 -6
  213. package/src/docs/Accessibility.mdx +402 -0
  214. package/src/docs/BestPractices.mdx +315 -0
  215. package/src/docs/ComponentComposition.mdx +381 -0
  216. package/src/docs/ComponentStatus.mdx +177 -0
  217. package/src/docs/DesignSystem.mdx +121 -0
  218. package/src/docs/GettingStarted.mdx +284 -0
  219. package/src/docs/MigrationGuide.mdx +297 -0
  220. package/src/docs/Performance.mdx +206 -0
  221. package/src/docs/components/ComponentStatusTable.tsx +184 -0
  222. package/src/setupTests.ts +32 -0
  223. package/src/ui/atoms/Accordion/Accordion.stories.tsx +147 -0
  224. package/src/ui/atoms/Accordion/Accordion.test.tsx +86 -0
  225. package/src/ui/atoms/Accordion/Accordion.tsx +147 -0
  226. package/src/ui/atoms/Accordion/index.ts +2 -0
  227. package/src/ui/atoms/Avatar/Avatar.stories.tsx +226 -0
  228. package/src/ui/atoms/Avatar/Avatar.test.tsx +233 -0
  229. package/src/ui/atoms/Avatar/Avatar.tsx +128 -0
  230. package/src/ui/atoms/Avatar/AvatarGroup.tsx +96 -0
  231. package/src/ui/atoms/Avatar/index.ts +11 -0
  232. package/src/ui/atoms/Badge/Badge.stories.tsx +65 -56
  233. package/src/ui/atoms/Badge/Badge.test.tsx +27 -50
  234. package/src/ui/atoms/Badge/Badge.tsx +70 -27
  235. package/src/ui/atoms/BoxWrapper/BoxWrapper.stories.tsx +1 -1
  236. package/src/ui/atoms/BoxWrapper/BoxWrapper.test.tsx +27 -0
  237. package/src/ui/atoms/BoxWrapper/BoxWrapper.tsx +5 -2
  238. package/src/ui/atoms/Button/Button.stories.tsx +130 -1
  239. package/src/ui/atoms/Button/Button.test.tsx +233 -0
  240. package/src/ui/atoms/Button/Button.tsx +160 -53
  241. package/src/ui/atoms/Checkbox/Checkbox.tsx +14 -1
  242. package/src/ui/atoms/Collapsible/Collapsible.stories.tsx +47 -1
  243. package/src/ui/atoms/Collapsible/Collapsible.test.tsx +36 -24
  244. package/src/ui/atoms/Collapsible/Collapsible.tsx +9 -1
  245. package/src/ui/atoms/ErrorMessage/ErrorMessage.stories.tsx +1 -1
  246. package/src/ui/atoms/Info/Info.stories.tsx +1 -1
  247. package/src/ui/atoms/Info/Info.test.tsx +45 -0
  248. package/src/ui/atoms/Info/Info.tsx +2 -2
  249. package/src/ui/atoms/Input/Input.stories.tsx +80 -0
  250. package/src/ui/atoms/Input/Input.test.tsx +190 -36
  251. package/src/ui/atoms/Input/Input.tsx +144 -25
  252. package/src/ui/atoms/Label/Label.stories.tsx +1 -1
  253. package/src/ui/atoms/NavLink/NavLink.stories.tsx +1 -1
  254. package/src/ui/atoms/Popover/Popover.stories.tsx +157 -0
  255. package/src/ui/atoms/Popover/Popover.test.tsx +80 -0
  256. package/src/ui/atoms/Popover/Popover.tsx +256 -0
  257. package/src/ui/atoms/Popover/index.ts +2 -0
  258. package/src/ui/atoms/Progress/Progress.css +17 -0
  259. package/src/ui/atoms/Progress/Progress.stories.tsx +170 -0
  260. package/src/ui/atoms/Progress/Progress.test.tsx +134 -0
  261. package/src/ui/atoms/Progress/Progress.tsx +138 -0
  262. package/src/ui/atoms/Radio/Radio.tsx +1 -1
  263. package/src/ui/atoms/Select/Select.stories.tsx +93 -58
  264. package/src/ui/atoms/Select/Select.test.tsx +162 -46
  265. package/src/ui/atoms/Select/Select.tsx +142 -44
  266. package/src/ui/atoms/Separator/Separator.stories.tsx +88 -0
  267. package/src/ui/atoms/Separator/Separator.test.tsx +34 -0
  268. package/src/ui/atoms/Separator/Separator.tsx +81 -0
  269. package/src/ui/atoms/Separator/index.ts +2 -0
  270. package/src/ui/atoms/Skeleton/Skeleton.stories.tsx +62 -0
  271. package/src/ui/atoms/Skeleton/Skeleton.tsx +19 -2
  272. package/src/ui/atoms/Slider/Slider.stories.tsx +205 -0
  273. package/src/ui/atoms/Slider/Slider.test.tsx +53 -0
  274. package/src/ui/atoms/Slider/Slider.tsx +307 -0
  275. package/src/ui/atoms/Slider/index.ts +2 -0
  276. package/src/ui/atoms/Spinner/Spinner.stories.tsx +56 -0
  277. package/src/ui/atoms/Spinner/Spinner.test.tsx +35 -0
  278. package/src/ui/atoms/Spinner/Spinner.tsx +88 -0
  279. package/src/ui/atoms/Switch/Switch.stories.tsx +182 -0
  280. package/src/ui/atoms/Switch/Switch.test.tsx +90 -0
  281. package/src/ui/atoms/Switch/Switch.tsx +181 -0
  282. package/src/ui/atoms/Switch/index.ts +2 -0
  283. package/src/ui/atoms/Text/Text.stories.tsx +1 -1
  284. package/src/ui/atoms/Text/Text.test.tsx +48 -32
  285. package/src/ui/atoms/Textarea/Textarea.stories.tsx +1 -1
  286. package/src/ui/atoms/Tooltip/Tooltip.stories.tsx +44 -0
  287. package/src/ui/atoms/Tooltip/Tooltip.tsx +94 -6
  288. package/src/ui/atoms/index.ts +27 -4
  289. package/src/ui/index.ts +6 -1
  290. package/src/ui/molecules/Breadcrumb/Breadcrumb.stories.tsx +1 -1
  291. package/src/ui/molecules/Breadcrumb/Breadcrumb.tsx +1 -1
  292. package/src/ui/molecules/Card/Card.stories.tsx +49 -1
  293. package/src/ui/molecules/Card/Card.tsx +40 -5
  294. package/src/ui/molecules/ColorPicker/ColorPicker.stories.tsx +156 -0
  295. package/src/ui/molecules/ColorPicker/ColorPicker.test.tsx +47 -0
  296. package/src/ui/molecules/ColorPicker/ColorPicker.tsx +271 -0
  297. package/src/ui/molecules/ColorPicker/index.ts +2 -0
  298. package/src/ui/molecules/DatePicker/DatePicker.mdx +150 -0
  299. package/src/ui/molecules/DatePicker/DatePicker.stories.tsx +188 -0
  300. package/src/ui/molecules/DatePicker/DatePicker.test.tsx +381 -0
  301. package/src/ui/molecules/DatePicker/DatePicker.tsx +231 -0
  302. package/src/ui/molecules/DatePicker/DatePickerCalendar.tsx +277 -0
  303. package/src/ui/molecules/DatePicker/DatePickerContext.tsx +39 -0
  304. package/src/ui/molecules/DatePicker/DatePickerInput.tsx +147 -0
  305. package/src/ui/molecules/DatePicker/DatePickerProvider.tsx +100 -0
  306. package/src/ui/molecules/DatePicker/index.ts +16 -0
  307. package/src/ui/molecules/Dropdown/Dropdown.stories.tsx +50 -8
  308. package/src/ui/molecules/Dropdown/Dropdown.test.tsx +272 -12
  309. package/src/ui/molecules/Dropdown/Dropdown.tsx +176 -10
  310. package/src/ui/molecules/EmptyState/EmptyState.stories.tsx +24 -2
  311. package/src/ui/molecules/EmptyState/EmptyState.tsx +9 -3
  312. package/src/ui/molecules/FileUpload/FileUpload.stories.tsx +177 -0
  313. package/src/ui/molecules/FileUpload/FileUpload.test.tsx +114 -0
  314. package/src/ui/molecules/FileUpload/FileUpload.tsx +312 -0
  315. package/src/ui/molecules/FileUpload/index.ts +2 -0
  316. package/src/ui/molecules/Form/Form.mdx +145 -0
  317. package/src/ui/molecules/Form/Form.stories.tsx +121 -1
  318. package/src/ui/molecules/Form/Form.test.tsx +1 -3
  319. package/src/ui/molecules/Form/Form.tsx +95 -15
  320. package/src/ui/molecules/Form/FormContext.tsx +35 -0
  321. package/src/ui/molecules/Form/FormField.tsx +83 -0
  322. package/src/ui/molecules/Form/FormProvider.tsx +34 -0
  323. package/src/ui/molecules/Form/index.ts +21 -0
  324. package/src/ui/molecules/Form/useFormFieldArray.ts +46 -0
  325. package/src/ui/molecules/InputWithLabel/InputWithLabel.stories.tsx +1 -1
  326. package/src/ui/molecules/InputWithLabel/InputWithLabel.test.tsx +44 -0
  327. package/src/ui/molecules/InputWithLabel/InputWithLabel.tsx +3 -1
  328. package/src/ui/molecules/NavbarGroup/NavbarGroup.stories.tsx +1 -1
  329. package/src/ui/molecules/Pagination/Pagination.stories.tsx +1 -1
  330. package/src/ui/molecules/Rating/Rating.stories.tsx +206 -0
  331. package/src/ui/molecules/Rating/Rating.test.tsx +60 -0
  332. package/src/ui/molecules/Rating/Rating.tsx +173 -0
  333. package/src/ui/molecules/Rating/index.ts +2 -0
  334. package/src/ui/molecules/SearchInput/SearchInput.stories.tsx +146 -0
  335. package/src/ui/molecules/SearchInput/SearchInput.test.tsx +82 -0
  336. package/src/ui/molecules/SearchInput/SearchInput.tsx +133 -0
  337. package/src/ui/molecules/SearchInput/index.ts +2 -0
  338. package/src/ui/molecules/Tabs/Tabs.stories.tsx +229 -0
  339. package/src/ui/molecules/Tabs/Tabs.test.tsx +497 -0
  340. package/src/ui/molecules/Tabs/Tabs.tsx +58 -0
  341. package/src/ui/molecules/Tabs/TabsContent.tsx +50 -0
  342. package/src/ui/molecules/Tabs/TabsContext.tsx +36 -0
  343. package/src/ui/molecules/Tabs/TabsList.tsx +98 -0
  344. package/src/ui/molecules/Tabs/TabsProvider.tsx +53 -0
  345. package/src/ui/molecules/Tabs/TabsTrigger.tsx +111 -0
  346. package/src/ui/molecules/Tabs/index.ts +23 -0
  347. package/src/ui/molecules/TimePicker/TimePicker.stories.tsx +145 -0
  348. package/src/ui/molecules/TimePicker/TimePicker.test.tsx +41 -0
  349. package/src/ui/molecules/TimePicker/TimePicker.tsx +264 -0
  350. package/src/ui/molecules/TimePicker/index.ts +2 -0
  351. package/src/ui/molecules/index.ts +20 -7
  352. package/src/ui/organisms/CommandPalette/CommandPalette.stories.tsx +218 -0
  353. package/src/ui/organisms/CommandPalette/CommandPalette.test.tsx +85 -0
  354. package/src/ui/organisms/CommandPalette/CommandPalette.tsx +333 -0
  355. package/src/ui/organisms/CommandPalette/index.ts +2 -0
  356. package/src/ui/organisms/DataGrid/DataGrid.stories.tsx +196 -0
  357. package/src/ui/organisms/DataGrid/DataGrid.test.tsx +53 -0
  358. package/src/ui/organisms/DataGrid/DataGrid.tsx +294 -0
  359. package/src/ui/organisms/DataGrid/index.ts +2 -0
  360. package/src/ui/organisms/Dialog/AlertDialog.tsx +92 -0
  361. package/src/ui/organisms/Dialog/Dialog.mdx +200 -0
  362. package/src/ui/organisms/Dialog/Dialog.stories.tsx +226 -0
  363. package/src/ui/organisms/Dialog/Dialog.test.tsx +435 -0
  364. package/src/ui/organisms/Dialog/Dialog.tsx +79 -0
  365. package/src/ui/organisms/Dialog/DialogClose.tsx +45 -0
  366. package/src/ui/organisms/Dialog/DialogContent.tsx +149 -0
  367. package/src/ui/organisms/Dialog/DialogContext.tsx +25 -0
  368. package/src/ui/organisms/Dialog/DialogDescription.tsx +28 -0
  369. package/src/ui/organisms/Dialog/DialogFooter.tsx +18 -0
  370. package/src/ui/organisms/Dialog/DialogHeader.tsx +18 -0
  371. package/src/ui/organisms/Dialog/DialogProvider.tsx +73 -0
  372. package/src/ui/organisms/Dialog/DialogTitle.tsx +31 -0
  373. package/src/ui/organisms/Dialog/DialogTrigger.tsx +34 -0
  374. package/src/ui/organisms/Dialog/index.ts +24 -0
  375. package/src/ui/organisms/LoginBox/LoginBox.stories.tsx +1 -1
  376. package/src/ui/organisms/Modal/Modal.stories.tsx +2 -2
  377. package/src/ui/organisms/Modal/Modal.test.tsx +1 -1
  378. package/src/ui/organisms/Sidebar/Sidebar.stories.tsx +1 -1
  379. package/src/ui/organisms/Sidebar/Sidebar.test.tsx +5 -3
  380. package/src/ui/organisms/Sidebar/Sidebar.tsx +21 -6
  381. package/src/ui/{molecules → organisms/Sidebar}/SidebarGroup/SidebarGroup.stories.tsx +2 -2
  382. package/src/ui/{molecules → organisms/Sidebar}/SidebarGroup/SidebarGroup.test.tsx +32 -9
  383. package/src/ui/{molecules → organisms/Sidebar}/SidebarGroup/SidebarGroup.tsx +7 -7
  384. package/src/ui/organisms/Sidebar/SidebarHeader/SidebarHeader.test.tsx +66 -0
  385. package/src/ui/{molecules → organisms/Sidebar}/SidebarHeader/SidebarHeader.tsx +1 -2
  386. package/src/ui/{atoms → organisms/Sidebar}/SidebarItem/SidebarItem.stories.tsx +1 -1
  387. package/src/ui/{atoms → organisms/Sidebar}/SidebarItem/SidebarItem.test.tsx +9 -8
  388. package/src/ui/{atoms → organisms/Sidebar}/SidebarItem/SidebarItem.tsx +9 -3
  389. package/src/ui/organisms/Sidebar/index.ts +13 -0
  390. package/src/ui/organisms/Stepper/Stepper.stories.tsx +253 -0
  391. package/src/ui/organisms/Stepper/Stepper.test.tsx +76 -0
  392. package/src/ui/organisms/Stepper/Stepper.tsx +323 -0
  393. package/src/ui/organisms/Stepper/index.ts +2 -0
  394. package/src/ui/organisms/Table/Table.mdx +154 -0
  395. package/src/ui/organisms/Table/Table.stories.tsx +614 -4
  396. package/src/ui/organisms/Table/Table.test.tsx +86 -4
  397. package/src/ui/organisms/Table/Table.tsx +215 -99
  398. package/src/ui/organisms/Table/TableActions/TableActions.stories.tsx +88 -0
  399. package/src/ui/organisms/Table/TableActions/TableActions.test.tsx +64 -0
  400. package/src/ui/organisms/Table/TableActions/TableActions.tsx +71 -0
  401. package/src/ui/organisms/Table/TableActions.tsx +46 -0
  402. package/src/ui/organisms/Table/TableBody.tsx +137 -0
  403. package/src/ui/organisms/Table/TableCell.tsx +36 -0
  404. package/src/ui/organisms/Table/TableContext.tsx +111 -0
  405. package/src/ui/organisms/Table/TableEmptyState.tsx +51 -0
  406. package/src/ui/organisms/Table/TableFilters/TableFilters.stories.tsx +111 -0
  407. package/src/ui/organisms/Table/TableFilters/TableFilters.test.tsx +104 -0
  408. package/src/ui/organisms/Table/TableFilters/TableFilters.tsx +191 -0
  409. package/src/ui/organisms/Table/TableFilters.tsx +39 -0
  410. package/src/ui/organisms/Table/TableHeader.tsx +29 -0
  411. package/src/ui/organisms/Table/TableHeaderCell.tsx +142 -0
  412. package/src/ui/organisms/Table/TableHeaderRow.tsx +72 -0
  413. package/src/ui/organisms/Table/TablePagination/TablePagination.stories.tsx +87 -0
  414. package/src/ui/organisms/Table/TablePagination/TablePagination.test.tsx +90 -0
  415. package/src/ui/organisms/Table/TablePagination/TablePagination.tsx +207 -0
  416. package/src/ui/organisms/Table/TablePagination.tsx +48 -0
  417. package/src/ui/organisms/Table/TableProvider.tsx +429 -0
  418. package/src/ui/organisms/Table/TableRow.tsx +85 -0
  419. package/src/ui/organisms/Table/TableTypes.ts +11 -0
  420. package/src/ui/organisms/Table/index.ts +55 -0
  421. package/src/ui/organisms/Table/useColumnResizing.ts +134 -0
  422. package/src/ui/organisms/Table/useVirtualScrolling.ts +116 -0
  423. package/src/ui/organisms/Timeline/Timeline.stories.tsx +230 -0
  424. package/src/ui/organisms/Timeline/Timeline.test.tsx +47 -0
  425. package/src/ui/organisms/Timeline/Timeline.tsx +179 -0
  426. package/src/ui/organisms/Timeline/index.ts +2 -0
  427. package/src/ui/organisms/Toast/Toast.stories.tsx +169 -0
  428. package/src/ui/organisms/Toast/Toast.test.tsx +537 -0
  429. package/src/ui/organisms/Toast/Toast.tsx +144 -0
  430. package/src/ui/organisms/Toast/ToastContainer.tsx +54 -0
  431. package/src/ui/organisms/Toast/ToastContext.tsx +38 -0
  432. package/src/ui/organisms/Toast/ToastProvider.tsx +56 -0
  433. package/src/ui/organisms/Toast/index.ts +17 -0
  434. package/src/ui/organisms/Toast/useToast.ts +70 -0
  435. package/src/ui/organisms/index.ts +17 -2
  436. package/src/ui/providers/AdvancedThemeProvider.tsx +229 -0
  437. package/src/ui/providers/index.ts +14 -0
  438. package/src/ui/themes/README.md +281 -0
  439. package/src/ui/themes/ThemeBuilder.ts +149 -0
  440. package/src/ui/themes/ThemeRegistry.ts +187 -0
  441. package/src/ui/themes/index.ts +20 -0
  442. package/src/ui/themes/types.ts +53 -0
  443. package/src/ui/themes/utils.ts +70 -0
  444. package/src/ui/tokens/README.md +212 -0
  445. package/src/ui/tokens/TokenVisualizations.tsx +273 -0
  446. package/src/ui/tokens/Tokens.mdx +348 -0
  447. package/src/ui/tokens/animations.ts +157 -0
  448. package/src/ui/tokens/borders.ts +121 -0
  449. package/src/ui/tokens/gradients.ts +154 -0
  450. package/src/ui/tokens/index.ts +57 -0
  451. package/src/ui/tokens/opacity.ts +107 -0
  452. package/src/ui/tokens/radius.ts +107 -0
  453. package/src/ui/tokens/shadows.ts +92 -0
  454. package/src/ui/tokens/tokens.factory.ts +124 -0
  455. package/src/ui/tokens/z-index.ts +113 -0
  456. package/src/ui/utils/index.ts +10 -0
  457. package/src/App.css +0 -42
  458. package/src/App.tsx +0 -35
  459. package/src/index.css +0 -68
  460. package/src/main.tsx +0 -15
@@ -1,30 +1,62 @@
1
1
  'use client';
2
2
 
3
3
  import type { FormHTMLAttributes, ReactNode } from "react";
4
+ import { FormProvider } from './FormProvider';
5
+ import type { FieldValues, UseFormReturn } from 'react-hook-form';
4
6
 
5
- interface Props extends FormHTMLAttributes<HTMLFormElement> {
7
+ // Simple Form Props (backward compatible)
8
+ interface SimpleFormProps extends FormHTMLAttributes<HTMLFormElement> {
6
9
  children: ReactNode;
7
10
  onSubmit?: (e: React.FormEvent<HTMLFormElement>) => void;
8
11
  loading?: boolean;
9
12
  error?: string | null;
10
13
  success?: string | null;
14
+ form?: never; // Cannot use form prop in simple mode
11
15
  }
12
16
 
17
+ // React Hook Form Props
18
+ interface ReactHookFormProps<TFieldValues extends FieldValues = FieldValues> extends Omit<FormHTMLAttributes<HTMLFormElement>, 'onSubmit'> {
19
+ children: ReactNode;
20
+ form: UseFormReturn<TFieldValues>;
21
+ onSubmit: (data: TFieldValues) => void | Promise<void>;
22
+ loading?: boolean;
23
+ error?: string | null;
24
+ success?: string | null;
25
+ onSubmitError?: (errors: unknown) => void;
26
+ }
27
+
28
+ type FormProps<TFieldValues extends FieldValues = FieldValues> =
29
+ | SimpleFormProps
30
+ | ReactHookFormProps<TFieldValues>;
31
+
13
32
  /**
14
33
  * Form Component
15
34
  *
16
- * A wrapper component for forms with validation states and layout.
17
- * Follows Atomic Design principles as a Molecule component.
35
+ * A flexible form component that supports both simple forms and react-hook-form integration.
18
36
  *
19
37
  * @example
20
38
  * ```tsx
39
+ * // Simple form (backward compatible)
21
40
  * <Form onSubmit={handleSubmit} loading={isSubmitting}>
22
41
  * <Input name="email" />
23
42
  * <Button type="submit">Submit</Button>
24
43
  * </Form>
44
+ *
45
+ * // With react-hook-form
46
+ * const form = useForm({ resolver: zodResolver(schema) });
47
+ * <Form form={form} onSubmit={handleSubmit}>
48
+ * <FormField name="email">
49
+ * {({ register, error }) => (
50
+ * <>
51
+ * <Input {...register('email')} />
52
+ * {error && <ErrorMessage>{error}</ErrorMessage>}
53
+ * </>
54
+ * )}
55
+ * </FormField>
56
+ * </Form>
25
57
  * ```
26
58
  */
27
- export default function Form({
59
+ export default function Form<TFieldValues extends FieldValues = FieldValues>({
28
60
  children,
29
61
  onSubmit,
30
62
  loading = false,
@@ -32,20 +64,68 @@ export default function Form({
32
64
  success = null,
33
65
  className = "",
34
66
  ...props
35
- }: Props) {
36
- const baseClasses = [
37
- "space-y-4",
38
- ];
67
+ }: FormProps<TFieldValues>) {
68
+ const baseClasses = ["space-y-4"];
69
+ const classes = [...baseClasses, className].filter(Boolean).join(" ");
70
+
71
+ // Check if using react-hook-form
72
+ const isReactHookForm = 'form' in props && props.form !== undefined;
73
+
74
+ if (isReactHookForm) {
75
+ const { form, onSubmit: onSubmitData, onSubmitError, ...formProps } = props as ReactHookFormProps<TFieldValues>;
76
+
77
+ const handleSubmit = form.handleSubmit(
78
+ async (data) => {
79
+ try {
80
+ await onSubmitData(data);
81
+ } catch (err) {
82
+ onSubmitError?.(err);
83
+ }
84
+ },
85
+ (errors) => {
86
+ onSubmitError?.(errors);
87
+ }
88
+ );
89
+
90
+ return (
91
+ <FormProvider form={form} loading={loading}>
92
+ <form
93
+ className={classes}
94
+ onSubmit={handleSubmit}
95
+ noValidate
96
+ {...formProps}
97
+ >
98
+ {children}
99
+ {error && (
100
+ <div
101
+ role="alert"
102
+ className="p-3 text-sm text-red-800 bg-red-50 border border-red-200 rounded"
103
+ >
104
+ {error}
105
+ </div>
106
+ )}
107
+ {success && (
108
+ <div
109
+ role="alert"
110
+ className="p-3 text-sm text-green-800 bg-green-50 border border-green-200 rounded"
111
+ >
112
+ {success}
113
+ </div>
114
+ )}
115
+ </form>
116
+ </FormProvider>
117
+ );
118
+ }
39
119
 
40
- const classes = [
41
- ...baseClasses,
42
- className,
43
- ].filter(Boolean).join(" ");
120
+ // Simple form mode (backward compatible)
121
+ // Use onSubmit from props or from direct prop
122
+ const onSubmitSimple = (props as SimpleFormProps).onSubmit || onSubmit;
123
+ const { onSubmit: _, ...simpleProps } = props as SimpleFormProps;
44
124
 
45
125
  const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
46
126
  e.preventDefault();
47
- if (onSubmit && !loading) {
48
- onSubmit(e);
127
+ if (onSubmitSimple && !loading) {
128
+ onSubmitSimple(e);
49
129
  }
50
130
  };
51
131
 
@@ -54,7 +134,7 @@ export default function Form({
54
134
  className={classes}
55
135
  onSubmit={handleSubmit}
56
136
  noValidate
57
- {...props}
137
+ {...simpleProps}
58
138
  >
59
139
  {children}
60
140
  {error && (
@@ -0,0 +1,35 @@
1
+ 'use client';
2
+
3
+ import { createContext, useContext } from 'react';
4
+ import type { FieldValues, UseFormReturn } from 'react-hook-form';
5
+
6
+ export interface FormContextValue<TFieldValues extends FieldValues = FieldValues> {
7
+ form?: UseFormReturn<TFieldValues>;
8
+ loading?: boolean;
9
+ }
10
+
11
+ const FormContext = createContext<FormContextValue<FieldValues> | undefined>(undefined);
12
+
13
+ /**
14
+ * Hook to access Form context
15
+ *
16
+ * @throws Error if used outside of Form component with react-hook-form
17
+ */
18
+ export function useFormContext<TFieldValues extends FieldValues = FieldValues>(): FormContextValue<TFieldValues> {
19
+ const context = useContext(FormContext);
20
+
21
+ if (context === undefined) {
22
+ throw new Error('useFormContext must be used within a Form component with react-hook-form integration');
23
+ }
24
+
25
+ return context as FormContextValue<TFieldValues>;
26
+ }
27
+
28
+ /**
29
+ * Hook to access Form context (optional, returns undefined if not in Form)
30
+ */
31
+ export function useFormContextOptional<TFieldValues extends FieldValues = FieldValues>(): FormContextValue<TFieldValues> | undefined {
32
+ return useContext(FormContext) as FormContextValue<TFieldValues> | undefined;
33
+ }
34
+
35
+ export { FormContext };
@@ -0,0 +1,83 @@
1
+ 'use client';
2
+
3
+ import { useFormContext } from './FormContext';
4
+ import { ErrorMessage } from '../../atoms';
5
+ import type { FieldValues, Path, RegisterOptions } from 'react-hook-form';
6
+ import type { ReactNode } from 'react';
7
+
8
+ export interface FormFieldProps<TFieldValues extends FieldValues = FieldValues> {
9
+ name: Path<TFieldValues>;
10
+ label?: string;
11
+ children: (props: {
12
+ name: string;
13
+ register: ReturnType<ReturnType<UseFormReturn<TFieldValues>['register']>>;
14
+ error?: string;
15
+ value?: unknown;
16
+ onChange?: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => void;
17
+ onBlur?: () => void;
18
+ }) => ReactNode;
19
+ rules?: RegisterOptions<TFieldValues>;
20
+ className?: string;
21
+ }
22
+
23
+ /**
24
+ * FormField Component
25
+ *
26
+ * A wrapper component for form fields that integrates with react-hook-form.
27
+ * Provides register, error, and validation state to children.
28
+ *
29
+ * @example
30
+ * ```tsx
31
+ * <FormField name="email" label="Email">
32
+ * {({ register, error }) => (
33
+ * <>
34
+ * <Label htmlFor="email">Email</Label>
35
+ * <Input id="email" {...register('email')} />
36
+ * {error && <ErrorMessage>{error}</ErrorMessage>}
37
+ * </>
38
+ * )}
39
+ * </FormField>
40
+ * ```
41
+ */
42
+ export function FormField<TFieldValues extends FieldValues = FieldValues>({
43
+ name,
44
+ label,
45
+ children,
46
+ rules,
47
+ className = '',
48
+ }: FormFieldProps<TFieldValues>) {
49
+ const { form } = useFormContext<TFieldValues>();
50
+
51
+ if (!form) {
52
+ throw new Error('FormField must be used within a Form component with react-hook-form integration');
53
+ }
54
+
55
+ const {
56
+ register,
57
+ formState: { errors },
58
+ watch,
59
+ } = form;
60
+
61
+ const fieldRegister = register(name, rules);
62
+ const error = errors[name]?.message as string | undefined;
63
+ const value = watch(name);
64
+
65
+ return (
66
+ <div className={`space-y-2 ${className}`}>
67
+ {label && (
68
+ <label htmlFor={name} className="block text-sm font-medium text-gray-700">
69
+ {label}
70
+ </label>
71
+ )}
72
+ {children({
73
+ name,
74
+ register: fieldRegister,
75
+ error,
76
+ value,
77
+ onChange: fieldRegister.onChange,
78
+ onBlur: fieldRegister.onBlur,
79
+ })}
80
+ {error && <ErrorMessage>{error}</ErrorMessage>}
81
+ </div>
82
+ );
83
+ }
@@ -0,0 +1,34 @@
1
+ 'use client';
2
+
3
+ import { FormContext, type FormContextValue } from './FormContext';
4
+ import type { ReactNode } from 'react';
5
+ import type { FieldValues, UseFormReturn } from 'react-hook-form';
6
+
7
+ export interface FormProviderProps<TFieldValues extends FieldValues = FieldValues> {
8
+ form?: UseFormReturn<TFieldValues>;
9
+ loading?: boolean;
10
+ children: ReactNode;
11
+ }
12
+
13
+ /**
14
+ * FormProvider Component
15
+ *
16
+ * Provides react-hook-form context to form children.
17
+ * Used internally by Form component when react-hook-form is integrated.
18
+ */
19
+ export function FormProvider<TFieldValues extends FieldValues = FieldValues>({
20
+ form,
21
+ loading = false,
22
+ children,
23
+ }: FormProviderProps<TFieldValues>) {
24
+ const contextValue: FormContextValue<TFieldValues> = {
25
+ form,
26
+ loading,
27
+ };
28
+
29
+ return (
30
+ <FormContext.Provider value={contextValue}>
31
+ {children}
32
+ </FormContext.Provider>
33
+ );
34
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Form Components
3
+ *
4
+ * Form components with optional react-hook-form and Zod integration.
5
+ */
6
+
7
+ // Main Form component
8
+ export { default as Form } from './Form';
9
+
10
+ // Context and Provider
11
+ export { FormContext, useFormContext, useFormContextOptional } from './FormContext';
12
+ export type { FormContextValue } from './FormContext';
13
+ export { FormProvider } from './FormProvider';
14
+ export type { FormProviderProps } from './FormProvider';
15
+
16
+ // FormField for react-hook-form integration
17
+ export { FormField } from './FormField';
18
+ export type { FormFieldProps } from './FormField';
19
+
20
+ // Hooks
21
+ export { useFormFieldArray } from './useFormFieldArray';
@@ -0,0 +1,46 @@
1
+ 'use client';
2
+
3
+ import { useFormContext } from './FormContext';
4
+ import { useFieldArray } from 'react-hook-form';
5
+ import type { FieldValues, Path, UseFieldArrayProps } from 'react-hook-form';
6
+
7
+ /**
8
+ * Hook for managing field arrays in forms
9
+ *
10
+ * Wrapper around react-hook-form's useFieldArray that integrates with Form context.
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * const { fields, append, remove } = useFormFieldArray({
15
+ * name: 'items',
16
+ * });
17
+ *
18
+ * return (
19
+ * <>
20
+ * {fields.map((field, index) => (
21
+ * <div key={field.id}>
22
+ * <FormField name={`items.${index}.name`}>
23
+ * {({ register }) => <Input {...register(`items.${index}.name`)} />}
24
+ * </FormField>
25
+ * <Button onClick={() => remove(index)}>Remove</Button>
26
+ * </div>
27
+ * ))}
28
+ * <Button onClick={() => append({ name: '' })}>Add Item</Button>
29
+ * </>
30
+ * );
31
+ * ```
32
+ */
33
+ export function useFormFieldArray<TFieldValues extends FieldValues = FieldValues, TFieldArrayName extends Path<TFieldValues> = Path<TFieldValues>>(
34
+ props: Omit<UseFieldArrayProps<TFieldValues, TFieldArrayName>, 'control'>
35
+ ) {
36
+ const { form } = useFormContext<TFieldValues>();
37
+
38
+ if (!form) {
39
+ throw new Error('useFormFieldArray must be used within a Form component with react-hook-form integration');
40
+ }
41
+
42
+ return useFieldArray<TFieldValues, TFieldArrayName>({
43
+ ...props,
44
+ control: form.control,
45
+ });
46
+ }
@@ -2,7 +2,7 @@ import type { Meta, StoryObj } from "@storybook/react";
2
2
  import InputWithLabel from "./InputWithLabel";
3
3
 
4
4
  const meta: Meta<typeof InputWithLabel> = {
5
- title: "UI/Molecules/InputWithLabel",
5
+ title: "Molecules/InputWithLabel",
6
6
  component: InputWithLabel,
7
7
  };
8
8
 
@@ -0,0 +1,44 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { render, screen } from '@testing-library/react';
3
+ import InputWithLabel from './InputWithLabel';
4
+
5
+ describe('InputWithLabel', () => {
6
+ it('renders label and input', () => {
7
+ render(<InputWithLabel id="test-input" label="Test Label" />);
8
+ expect(screen.getByText('Test Label')).toBeInTheDocument();
9
+ expect(screen.getByLabelText('Test Label')).toBeInTheDocument();
10
+ });
11
+
12
+ it('associates label with input via htmlFor', () => {
13
+ render(<InputWithLabel id="test-input" label="Test Label" />);
14
+ const label = screen.getByText('Test Label');
15
+ const input = screen.getByLabelText('Test Label');
16
+ expect(label).toHaveAttribute('for', 'test-input');
17
+ expect(input).toHaveAttribute('id', 'test-input');
18
+ });
19
+
20
+ it('passes through input props', () => {
21
+ render(
22
+ <InputWithLabel
23
+ id="test-input"
24
+ label="Test Label"
25
+ type="email"
26
+ placeholder="Enter email"
27
+ required
28
+ />
29
+ );
30
+ const input = screen.getByLabelText('Test Label');
31
+ expect(input).toHaveAttribute('type', 'email');
32
+ expect(input).toHaveAttribute('placeholder', 'Enter email');
33
+ expect(input).toBeRequired();
34
+ });
35
+
36
+ it('applies size prop to input', () => {
37
+ const { container } = render(
38
+ <InputWithLabel id="test-input" label="Test Label" size="sm" />
39
+ );
40
+ const input = container.querySelector('input');
41
+ // Input component should receive size prop
42
+ expect(input).toBeInTheDocument();
43
+ });
44
+ });
@@ -7,7 +7,9 @@ interface Props extends Omit<HTMLProps<HTMLInputElement>, 'size'> {
7
7
  }
8
8
 
9
9
  export default function InputWithLabel({ label, size, ...props }: Props) {
10
- if (!props.id) {
10
+
11
+ if (!props.id && process.env.NODE_ENV === 'development') {
12
+
11
13
  console.error("InputWithLabel component requires an id prop");
12
14
  }
13
15
 
@@ -2,7 +2,7 @@ import type { Meta, StoryObj } from "@storybook/react";
2
2
  import NavbarGroup from "./NavbarGroup";
3
3
 
4
4
  const meta: Meta<typeof NavbarGroup> = {
5
- title: "UI/Molecules/NavbarGroup",
5
+ title: "Molecules/NavbarGroup",
6
6
  component: NavbarGroup,
7
7
  parameters: {
8
8
  docs: {
@@ -3,7 +3,7 @@ import { useState } from "react";
3
3
  import Pagination from "./Pagination";
4
4
 
5
5
  const meta: Meta<typeof Pagination> = {
6
- title: "UI/Molecules/Pagination",
6
+ title: "Molecules/Pagination",
7
7
  component: Pagination,
8
8
  parameters: {
9
9
  docs: {
@@ -0,0 +1,206 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { useState } from 'react';
3
+ import Rating from './Rating';
4
+
5
+ const meta: Meta<typeof Rating> = {
6
+ title: 'Molecules/Rating',
7
+ component: Rating,
8
+ tags: ['autodocs'],
9
+ parameters: {
10
+ layout: 'centered',
11
+ },
12
+ argTypes: {
13
+ size: {
14
+ control: 'select',
15
+ options: ['sm', 'md', 'lg'],
16
+ },
17
+ variant: {
18
+ control: 'select',
19
+ options: ['filled', 'outlined'],
20
+ },
21
+ max: {
22
+ control: 'number',
23
+ },
24
+ },
25
+ };
26
+
27
+ export default meta;
28
+ type Story = StoryObj<typeof Rating>;
29
+
30
+ export const Default: Story = {
31
+ render: (args) => {
32
+ const [value, setValue] = useState(args.defaultValue || 0);
33
+ return (
34
+ <Rating
35
+ {...args}
36
+ value={value}
37
+ onChange={setValue}
38
+ />
39
+ );
40
+ },
41
+ args: {
42
+ max: 5,
43
+ defaultValue: 0,
44
+ },
45
+ };
46
+
47
+ export const WithValue: Story = {
48
+ render: (args) => {
49
+ const [value, setValue] = useState(args.defaultValue || 3);
50
+ return (
51
+ <Rating
52
+ {...args}
53
+ value={value}
54
+ onChange={setValue}
55
+ showValue
56
+ />
57
+ );
58
+ },
59
+ args: {
60
+ max: 5,
61
+ defaultValue: 3,
62
+ },
63
+ };
64
+
65
+ export const ReadOnly: Story = {
66
+ render: () => (
67
+ <div className="space-y-4">
68
+ <div>
69
+ <p className="text-sm text-gray-600 mb-2">Read-only rating (3 stars)</p>
70
+ <Rating value={3} readOnly showValue />
71
+ </div>
72
+ <div>
73
+ <p className="text-sm text-gray-600 mb-2">Read-only rating (4.5 stars)</p>
74
+ <Rating value={4.5} readOnly showValue allowHalf />
75
+ </div>
76
+ </div>
77
+ ),
78
+ };
79
+
80
+ export const HalfRatings: Story = {
81
+ render: (args) => {
82
+ const [value, setValue] = useState(args.defaultValue || 2.5);
83
+ return (
84
+ <div className="space-y-4">
85
+ <Rating
86
+ {...args}
87
+ value={value}
88
+ onChange={setValue}
89
+ allowHalf
90
+ showValue
91
+ />
92
+ <p className="text-sm text-gray-600">Current value: {value}</p>
93
+ </div>
94
+ );
95
+ },
96
+ args: {
97
+ max: 5,
98
+ defaultValue: 2.5,
99
+ },
100
+ };
101
+
102
+ export const Sizes: Story = {
103
+ render: () => {
104
+ const [smValue, setSmValue] = useState(3);
105
+ const [mdValue, setMdValue] = useState(3);
106
+ const [lgValue, setLgValue] = useState(3);
107
+
108
+ return (
109
+ <div className="space-y-6">
110
+ <div>
111
+ <p className="text-sm text-gray-600 mb-2">Small</p>
112
+ <Rating size="sm" value={smValue} onChange={setSmValue} showValue />
113
+ </div>
114
+ <div>
115
+ <p className="text-sm text-gray-600 mb-2">Medium</p>
116
+ <Rating size="md" value={mdValue} onChange={setMdValue} showValue />
117
+ </div>
118
+ <div>
119
+ <p className="text-sm text-gray-600 mb-2">Large</p>
120
+ <Rating size="lg" value={lgValue} onChange={setLgValue} showValue />
121
+ </div>
122
+ </div>
123
+ );
124
+ },
125
+ };
126
+
127
+ export const CustomMax: Story = {
128
+ render: () => {
129
+ const [value, setValue] = useState(7);
130
+ return (
131
+ <div className="space-y-4">
132
+ <Rating
133
+ max={10}
134
+ value={value}
135
+ onChange={setValue}
136
+ showValue
137
+ />
138
+ <p className="text-sm text-gray-600">Rating out of 10</p>
139
+ </div>
140
+ );
141
+ },
142
+ };
143
+
144
+ export const Variants: Story = {
145
+ render: () => {
146
+ const [filledValue, setFilledValue] = useState(3);
147
+ const [outlinedValue, setOutlinedValue] = useState(3);
148
+
149
+ return (
150
+ <div className="space-y-6">
151
+ <div>
152
+ <p className="text-sm text-gray-600 mb-2">Filled</p>
153
+ <Rating variant="filled" value={filledValue} onChange={setFilledValue} showValue />
154
+ </div>
155
+ <div>
156
+ <p className="text-sm text-gray-600 mb-2">Outlined</p>
157
+ <Rating variant="outlined" value={outlinedValue} onChange={setOutlinedValue} showValue />
158
+ </div>
159
+ </div>
160
+ );
161
+ },
162
+ };
163
+
164
+ export const InContext: Story = {
165
+ render: () => {
166
+ const [productRating, setProductRating] = useState(4.5);
167
+ const [serviceRating, setServiceRating] = useState(5);
168
+
169
+ return (
170
+ <div className="w-96 space-y-6 p-4 border border-gray-200 rounded-lg">
171
+ <h3 className="text-lg font-semibold">Rate Your Experience</h3>
172
+
173
+ <div className="space-y-2">
174
+ <div className="flex items-center justify-between">
175
+ <span className="text-sm font-medium">Product Quality</span>
176
+ <Rating
177
+ value={productRating}
178
+ onChange={setProductRating}
179
+ allowHalf
180
+ showValue
181
+ size="sm"
182
+ />
183
+ </div>
184
+ </div>
185
+
186
+ <div className="space-y-2">
187
+ <div className="flex items-center justify-between">
188
+ <span className="text-sm font-medium">Customer Service</span>
189
+ <Rating
190
+ value={serviceRating}
191
+ onChange={setServiceRating}
192
+ showValue
193
+ size="sm"
194
+ />
195
+ </div>
196
+ </div>
197
+
198
+ <div className="pt-4 border-t border-gray-200">
199
+ <p className="text-xs text-gray-500">
200
+ Average: {((productRating + serviceRating) / 2).toFixed(1)}/5
201
+ </p>
202
+ </div>
203
+ </div>
204
+ );
205
+ },
206
+ };