@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
@@ -0,0 +1,312 @@
1
+ 'use client';
2
+
3
+ import { useState, useRef, type DragEvent, type ChangeEvent } from 'react';
4
+ import { Upload, X, File, CheckCircle2, AlertCircle } from 'lucide-react';
5
+ import { getColorClass } from '../../tokens/colors';
6
+ import { getSpacingClass } from '../../tokens/spacing';
7
+ import { getRadiusClass } from '../../tokens/radius';
8
+ import { getAnimationClass } from '../../tokens/animations';
9
+ import Button from '../../atoms/Button/Button';
10
+ import Progress from '../../atoms/Progress/Progress';
11
+
12
+ export interface FileUploadFile {
13
+ file: File;
14
+ id: string;
15
+ preview?: string;
16
+ progress?: number;
17
+ error?: string;
18
+ }
19
+
20
+ export interface FileUploadProps {
21
+ accept?: string;
22
+ multiple?: boolean;
23
+ maxSize?: number; // in bytes
24
+ maxFiles?: number;
25
+ onFilesChange?: (files: FileUploadFile[]) => void;
26
+ onFileRemove?: (fileId: string) => void;
27
+ showPreview?: boolean;
28
+ showProgress?: boolean;
29
+ disabled?: boolean;
30
+ className?: string;
31
+ label?: string;
32
+ description?: string;
33
+ }
34
+
35
+ /**
36
+ * FileUpload Component
37
+ *
38
+ * A file upload component with drag and drop, preview, validation, and progress.
39
+ * Follows Atomic Design principles as a Molecule component.
40
+ *
41
+ * @example
42
+ * ```tsx
43
+ * <FileUpload
44
+ * accept="image/*"
45
+ * maxSize={5 * 1024 * 1024} // 5MB
46
+ * onFilesChange={(files) => console.log(files)}
47
+ * />
48
+ * ```
49
+ */
50
+ export default function FileUpload({
51
+ accept,
52
+ multiple = false,
53
+ maxSize,
54
+ maxFiles,
55
+ onFilesChange,
56
+ onFileRemove,
57
+ showPreview = true,
58
+ showProgress = false,
59
+ disabled = false,
60
+ className = '',
61
+ label,
62
+ description,
63
+ }: FileUploadProps) {
64
+ const [files, setFiles] = useState<FileUploadFile[]>([]);
65
+ const [isDragging, setIsDragging] = useState(false);
66
+ const fileInputRef = useRef<HTMLInputElement>(null);
67
+
68
+ const formatFileSize = (bytes: number): string => {
69
+ if (bytes === 0) return '0 Bytes';
70
+ const k = 1024;
71
+ const sizes = ['Bytes', 'KB', 'MB', 'GB'];
72
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
73
+ return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];
74
+ };
75
+
76
+ const validateFile = (file: File): string | null => {
77
+ if (maxSize && file.size > maxSize) {
78
+ return `File size exceeds ${formatFileSize(maxSize)}`;
79
+ }
80
+ return null;
81
+ };
82
+
83
+ const processFiles = (fileList: FileList | File[]): FileUploadFile[] => {
84
+ const fileArray = Array.from(fileList);
85
+ const newFiles: FileUploadFile[] = [];
86
+
87
+ fileArray.forEach((file) => {
88
+ const error = validateFile(file);
89
+ const fileId = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
90
+
91
+ const fileUpload: FileUploadFile = {
92
+ file,
93
+ id: fileId,
94
+ error,
95
+ progress: showProgress ? 0 : undefined,
96
+ };
97
+
98
+ // Generate preview for images
99
+ if (showPreview && file.type.startsWith('image/')) {
100
+ const reader = new FileReader();
101
+ reader.onload = (e) => {
102
+ setFiles((prev) =>
103
+ prev.map((f) =>
104
+ f.id === fileId ? { ...f, preview: e.target?.result as string } : f
105
+ )
106
+ );
107
+ };
108
+ reader.readAsDataURL(file);
109
+ }
110
+
111
+ newFiles.push(fileUpload);
112
+ });
113
+
114
+ return newFiles;
115
+ };
116
+
117
+ const handleFiles = (newFiles: FileUploadFile[]) => {
118
+ const updatedFiles = multiple ? [...files, ...newFiles] : newFiles;
119
+ const limitedFiles = maxFiles ? updatedFiles.slice(0, maxFiles) : updatedFiles;
120
+
121
+ setFiles(limitedFiles);
122
+ onFilesChange?.(limitedFiles);
123
+ };
124
+
125
+ const handleDrop = (e: DragEvent<HTMLDivElement>) => {
126
+ e.preventDefault();
127
+ setIsDragging(false);
128
+
129
+ if (disabled) return;
130
+
131
+ const droppedFiles = e.dataTransfer.files;
132
+ if (droppedFiles.length > 0) {
133
+ const processedFiles = processFiles(droppedFiles);
134
+ handleFiles(processedFiles);
135
+ }
136
+ };
137
+
138
+ const handleDragOver = (e: DragEvent<HTMLDivElement>) => {
139
+ e.preventDefault();
140
+ if (!disabled) {
141
+ setIsDragging(true);
142
+ }
143
+ };
144
+
145
+ const handleDragLeave = (e: DragEvent<HTMLDivElement>) => {
146
+ e.preventDefault();
147
+ setIsDragging(false);
148
+ };
149
+
150
+ const handleFileInput = (e: ChangeEvent<HTMLInputElement>) => {
151
+ if (e.target.files && e.target.files.length > 0) {
152
+ const processedFiles = processFiles(e.target.files);
153
+ handleFiles(processedFiles);
154
+ }
155
+ // Reset input
156
+ if (fileInputRef.current) {
157
+ fileInputRef.current.value = '';
158
+ }
159
+ };
160
+
161
+ const handleRemove = (fileId: string) => {
162
+ const updatedFiles = files.filter((f) => f.id !== fileId);
163
+ setFiles(updatedFiles);
164
+ onFilesChange?.(updatedFiles);
165
+ onFileRemove?.(fileId);
166
+ };
167
+
168
+ const handleClick = () => {
169
+ if (!disabled) {
170
+ fileInputRef.current?.click();
171
+ }
172
+ };
173
+
174
+ return (
175
+ <div className={`space-y-4 ${className}`}>
176
+ {(label || description) && (
177
+ <div>
178
+ {label && (
179
+ <label className="block text-sm font-medium text-gray-700 mb-1">
180
+ {label}
181
+ </label>
182
+ )}
183
+ {description && (
184
+ <p className="text-sm text-gray-500">{description}</p>
185
+ )}
186
+ </div>
187
+ )}
188
+
189
+ <div
190
+ onDrop={handleDrop}
191
+ onDragOver={handleDragOver}
192
+ onDragLeave={handleDragLeave}
193
+ onClick={handleClick}
194
+ className={`
195
+ relative
196
+ border-2
197
+ border-dashed
198
+ ${isDragging ? getColorClass('primary', 'DEFAULT', 'border') : 'border-gray-300'}
199
+ ${getRadiusClass('lg')}
200
+ ${getSpacingClass('lg', 'p')}
201
+ text-center
202
+ cursor-pointer
203
+ ${getAnimationClass('base')}
204
+ ${disabled ? 'opacity-50 cursor-not-allowed' : 'hover:border-gray-400'}
205
+ `}
206
+ >
207
+ <input
208
+ ref={fileInputRef}
209
+ type="file"
210
+ accept={accept}
211
+ multiple={multiple}
212
+ onChange={handleFileInput}
213
+ disabled={disabled}
214
+ className="hidden"
215
+ />
216
+
217
+ <div className="flex flex-col items-center gap-2">
218
+ <Upload
219
+ className={`
220
+ ${isDragging ? getColorClass('primary', 'DEFAULT', 'text') : 'text-gray-400'}
221
+ h-8 w-8
222
+ `}
223
+ />
224
+ <div>
225
+ <span className="text-sm font-medium text-gray-700">
226
+ {isDragging ? 'Drop files here' : 'Click to upload or drag and drop'}
227
+ </span>
228
+ {accept && (
229
+ <p className="text-xs text-gray-500 mt-1">
230
+ Accepted: {accept}
231
+ </p>
232
+ )}
233
+ {maxSize && (
234
+ <p className="text-xs text-gray-500">
235
+ Max size: {formatFileSize(maxSize)}
236
+ </p>
237
+ )}
238
+ </div>
239
+ </div>
240
+ </div>
241
+
242
+ {files.length > 0 && (
243
+ <div className="space-y-2">
244
+ {files.map((fileUpload) => (
245
+ <div
246
+ key={fileUpload.id}
247
+ className={`
248
+ flex
249
+ items-center
250
+ gap-3
251
+ ${getSpacingClass('base', 'p')}
252
+ border
253
+ border-gray-200
254
+ ${getRadiusClass('md')}
255
+ ${fileUpload.error ? getColorClass('error', 'light', 'bg') : 'bg-gray-50'}
256
+ `}
257
+ >
258
+ {showPreview && fileUpload.preview ? (
259
+ <img
260
+ src={fileUpload.preview}
261
+ alt={fileUpload.file.name}
262
+ className={`w-12 h-12 object-cover ${getRadiusClass('md')}`}
263
+ />
264
+ ) : (
265
+ <File className="h-8 w-8 text-gray-400" />
266
+ )}
267
+
268
+ <div className="flex-1 min-w-0">
269
+ <p className="text-sm font-medium text-gray-900 truncate">
270
+ {fileUpload.file.name}
271
+ </p>
272
+ <p className="text-xs text-gray-500">
273
+ {formatFileSize(fileUpload.file.size)}
274
+ </p>
275
+ {fileUpload.error && (
276
+ <div className="flex items-center gap-1 mt-1">
277
+ <AlertCircle className={`h-3 w-3 ${getColorClass('error', 'DEFAULT', 'text')}`} />
278
+ <span className={`text-xs ${getColorClass('error', 'DEFAULT', 'text')}`}>
279
+ {fileUpload.error}
280
+ </span>
281
+ </div>
282
+ )}
283
+ {showProgress && fileUpload.progress !== undefined && (
284
+ <div className="mt-2">
285
+ <Progress value={fileUpload.progress} size="sm" />
286
+ </div>
287
+ )}
288
+ </div>
289
+
290
+ {!fileUpload.error && !showProgress && (
291
+ <CheckCircle2 className={`h-5 w-5 ${getColorClass('success', 'DEFAULT', 'text')}`} />
292
+ )}
293
+
294
+ <Button
295
+ variant="ghost"
296
+ size="sm"
297
+ onClick={(e) => {
298
+ e.stopPropagation();
299
+ handleRemove(fileUpload.id);
300
+ }}
301
+ className="h-auto p-1"
302
+ aria-label={`Remove ${fileUpload.file.name}`}
303
+ >
304
+ <X className="h-4 w-4" />
305
+ </Button>
306
+ </div>
307
+ ))}
308
+ </div>
309
+ )}
310
+ </div>
311
+ );
312
+ }
@@ -0,0 +1,2 @@
1
+ export { default } from './FileUpload';
2
+ export type { FileUploadProps, FileUploadFile } from './FileUpload';
@@ -0,0 +1,145 @@
1
+ import { Meta } from '@storybook/addon-docs/blocks';
2
+
3
+ <Meta title="Molecules/Form" />
4
+
5
+ # Form
6
+
7
+ A comprehensive form wrapper component that provides validation states, error handling, success messages, and consistent layout.
8
+
9
+ ## Features
10
+
11
+ - **Validation States**: Visual feedback for error, success, and loading states
12
+ - **Error Handling**: Global and field-level error messages
13
+ - **Accessibility**: Full ARIA support and keyboard navigation
14
+ - **Layout**: Consistent spacing and structure
15
+ - **Loading States**: Built-in loading indicator support
16
+
17
+ ## Basic Usage
18
+
19
+ ```tsx
20
+ import { Form, Input, Label, Button } from '@fabio.caffarello/react-design-system';
21
+
22
+ <Form onSubmit={handleSubmit}>
23
+ <div className="space-y-2">
24
+ <Label htmlFor="email" variant="required">Email</Label>
25
+ <Input id="email" name="email" type="email" required />
26
+ </div>
27
+ <Button type="submit">Submit</Button>
28
+ </Form>
29
+ ```
30
+
31
+ ## Validation States
32
+
33
+ ### Error State
34
+
35
+ Display global or field-level errors:
36
+
37
+ ```tsx
38
+ <Form error="Please fix the errors below">
39
+ {/* Form fields */}
40
+ </Form>
41
+ ```
42
+
43
+ ### Success State
44
+
45
+ Show success messages:
46
+
47
+ ```tsx
48
+ <Form success="Form submitted successfully!">
49
+ {/* Form fields */}
50
+ </Form>
51
+ ```
52
+
53
+ ### Loading State
54
+
55
+ Indicate form submission in progress:
56
+
57
+ ```tsx
58
+ <Form loading={isSubmitting}>
59
+ <Button type="submit" disabled={isSubmitting}>
60
+ {isSubmitting ? 'Submitting...' : 'Submit'}
61
+ </Button>
62
+ </Form>
63
+ ```
64
+
65
+ ## Field-Level Validation
66
+
67
+ Use individual field components with error states:
68
+
69
+ ```tsx
70
+ import { Input, ErrorMessage } from '@fabio.caffarello/react-design-system';
71
+
72
+ <div className="space-y-2">
73
+ <Label htmlFor="email">Email</Label>
74
+ <Input
75
+ id="email"
76
+ error={!!errors.email}
77
+ helperText={errors.email}
78
+ />
79
+ {errors.email && (
80
+ <ErrorMessage>{errors.email}</ErrorMessage>
81
+ )}
82
+ </div>
83
+ ```
84
+
85
+ ## Form Layout
86
+
87
+ The Form component provides consistent spacing:
88
+
89
+ ```tsx
90
+ <Form className="max-w-md space-y-4">
91
+ <div className="space-y-2">
92
+ <Label htmlFor="name">Name</Label>
93
+ <Input id="name" />
94
+ </div>
95
+ <div className="space-y-2">
96
+ <Label htmlFor="email">Email</Label>
97
+ <Input id="email" type="email" />
98
+ </div>
99
+ <Button type="submit">Submit</Button>
100
+ </Form>
101
+ ```
102
+
103
+ ## Integration with React Hook Form
104
+
105
+ ```tsx
106
+ import { useForm } from 'react-hook-form';
107
+ import { Form, Input, Label, Button } from '@fabio.caffarello/react-design-system';
108
+
109
+ function MyForm() {
110
+ const { register, handleSubmit, formState: { errors } } = useForm();
111
+
112
+ return (
113
+ <Form onSubmit={handleSubmit(onSubmit)}>
114
+ <div className="space-y-2">
115
+ <Label htmlFor="email">Email</Label>
116
+ <Input
117
+ id="email"
118
+ {...register('email', { required: 'Email is required' })}
119
+ error={!!errors.email}
120
+ helperText={errors.email?.message}
121
+ />
122
+ </div>
123
+ <Button type="submit">Submit</Button>
124
+ </Form>
125
+ );
126
+ }
127
+ ```
128
+
129
+ ## Accessibility
130
+
131
+ The Form component ensures accessibility:
132
+
133
+ - Proper form structure with `role="form"`
134
+ - ARIA labels and descriptions
135
+ - Error messages associated with fields via `aria-describedby`
136
+ - Keyboard navigation support
137
+ - Focus management
138
+
139
+ ### Best Practices
140
+
141
+ 1. **Labels**: Always provide labels for form fields
142
+ 2. **Error Messages**: Associate error messages with fields
143
+ 3. **Required Fields**: Clearly indicate required fields
144
+ 4. **Loading States**: Provide feedback during submission
145
+ 5. **Validation**: Validate on both client and server side
@@ -3,7 +3,7 @@ import Form from "./Form";
3
3
  import { Input, Label, Button, Textarea, Select, ErrorMessage } from "../../atoms";
4
4
 
5
5
  const meta: Meta<typeof Form> = {
6
- title: "UI/Molecules/Form",
6
+ title: "Molecules/Form",
7
7
  component: Form,
8
8
  parameters: {
9
9
  docs: {
@@ -192,4 +192,124 @@ export const CompleteForm: StoryObj<typeof Form> = {
192
192
  ),
193
193
  };
194
194
 
195
+ export const RegistrationForm: StoryObj<typeof Form> = {
196
+ args: {
197
+ onSubmit: (e) => {
198
+ e.preventDefault();
199
+ alert("Registration submitted!");
200
+ },
201
+ },
202
+ render: (args) => (
203
+ <Form {...args} className="max-w-lg space-y-4">
204
+ <div className="space-y-2">
205
+ <Label htmlFor="firstName" variant="required">
206
+ First Name
207
+ </Label>
208
+ <Input id="firstName" name="firstName" placeholder="John" required />
209
+ </div>
210
+ <div className="space-y-2">
211
+ <Label htmlFor="lastName" variant="required">
212
+ Last Name
213
+ </Label>
214
+ <Input id="lastName" name="lastName" placeholder="Doe" required />
215
+ </div>
216
+ <div className="space-y-2">
217
+ <Label htmlFor="email" variant="required">
218
+ Email
219
+ </Label>
220
+ <Input id="email" name="email" type="email" placeholder="john.doe@example.com" required />
221
+ </div>
222
+ <div className="space-y-2">
223
+ <Label htmlFor="password" variant="required">
224
+ Password
225
+ </Label>
226
+ <Input id="password" name="password" type="password" placeholder="Enter password" required />
227
+ </div>
228
+ <div className="space-y-2">
229
+ <Label htmlFor="country" variant="optional">
230
+ Country
231
+ </Label>
232
+ <Select
233
+ id="country"
234
+ name="country"
235
+ options={[
236
+ { value: "US", label: "United States" },
237
+ { value: "BR", label: "Brazil" },
238
+ { value: "UK", label: "United Kingdom" },
239
+ ]}
240
+ placeholder="Select country"
241
+ />
242
+ </div>
243
+ <div className="space-y-2">
244
+ <Label htmlFor="bio" variant="optional">
245
+ Bio
246
+ </Label>
247
+ <Textarea id="bio" name="bio" rows={4} placeholder="Tell us about yourself" />
248
+ </div>
249
+ <div className="flex gap-2">
250
+ <Button type="submit" variant="regular">
251
+ Register
252
+ </Button>
253
+ <Button type="button" variant="secondary">
254
+ Cancel
255
+ </Button>
256
+ </div>
257
+ </Form>
258
+ ),
259
+ parameters: {
260
+ docs: {
261
+ description: {
262
+ story: 'Complete registration form showing multiple form fields working together.',
263
+ },
264
+ },
265
+ },
266
+ };
267
+
268
+ export const ContactForm: StoryObj<typeof Form> = {
269
+ args: {
270
+ onSubmit: (e) => {
271
+ e.preventDefault();
272
+ alert("Message sent!");
273
+ },
274
+ },
275
+ render: (args) => (
276
+ <Form {...args} className="max-w-md space-y-4">
277
+ <div className="space-y-2">
278
+ <Label htmlFor="contactName" variant="required">
279
+ Name
280
+ </Label>
281
+ <Input id="contactName" name="name" placeholder="Your name" required />
282
+ </div>
283
+ <div className="space-y-2">
284
+ <Label htmlFor="contactEmail" variant="required">
285
+ Email
286
+ </Label>
287
+ <Input id="contactEmail" name="email" type="email" placeholder="your.email@example.com" required />
288
+ </div>
289
+ <div className="space-y-2">
290
+ <Label htmlFor="subject" variant="required">
291
+ Subject
292
+ </Label>
293
+ <Input id="subject" name="subject" placeholder="Message subject" required />
294
+ </div>
295
+ <div className="space-y-2">
296
+ <Label htmlFor="message" variant="required">
297
+ Message
298
+ </Label>
299
+ <Textarea id="message" name="message" rows={6} placeholder="Your message" required />
300
+ </div>
301
+ <Button type="submit" variant="regular" fullWidth>
302
+ Send Message
303
+ </Button>
304
+ </Form>
305
+ ),
306
+ parameters: {
307
+ docs: {
308
+ description: {
309
+ story: 'Contact form example showing a real-world use case.',
310
+ },
311
+ },
312
+ },
313
+ };
314
+
195
315
  export default meta;
@@ -16,9 +16,7 @@ describe("Form", () => {
16
16
  });
17
17
 
18
18
  it("calls onSubmit when form is submitted", () => {
19
- const handleSubmit = vi.fn((e) => {
20
- e.preventDefault();
21
- });
19
+ const handleSubmit = vi.fn();
22
20
  const { container } = render(
23
21
  <Form onSubmit={handleSubmit}>
24
22
  <Button type="submit">Submit</Button>