@pattern-stack/frontend-patterns 1.0.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 (400) hide show
  1. package/README.md +310 -0
  2. package/dist/atoms/composed/Accordion/Accordion.d.ts +20 -0
  3. package/dist/atoms/composed/Accordion/Accordion.d.ts.map +1 -0
  4. package/dist/atoms/composed/Accordion/index.d.ts +2 -0
  5. package/dist/atoms/composed/Accordion/index.d.ts.map +1 -0
  6. package/dist/atoms/composed/Alert/Alert.d.ts +25 -0
  7. package/dist/atoms/composed/Alert/Alert.d.ts.map +1 -0
  8. package/dist/atoms/composed/Alert/index.d.ts +2 -0
  9. package/dist/atoms/composed/Alert/index.d.ts.map +1 -0
  10. package/dist/atoms/composed/Breadcrumb/Breadcrumb.d.ts +17 -0
  11. package/dist/atoms/composed/Breadcrumb/Breadcrumb.d.ts.map +1 -0
  12. package/dist/atoms/composed/Breadcrumb/index.d.ts +2 -0
  13. package/dist/atoms/composed/Breadcrumb/index.d.ts.map +1 -0
  14. package/dist/atoms/composed/Chart/Chart.d.ts +37 -0
  15. package/dist/atoms/composed/Chart/Chart.d.ts.map +1 -0
  16. package/dist/atoms/composed/Chart/index.d.ts +3 -0
  17. package/dist/atoms/composed/Chart/index.d.ts.map +1 -0
  18. package/dist/atoms/composed/ColorSwatch/ColorSwatch.d.ts +19 -0
  19. package/dist/atoms/composed/ColorSwatch/ColorSwatch.d.ts.map +1 -0
  20. package/dist/atoms/composed/ColorSwatch/index.d.ts +2 -0
  21. package/dist/atoms/composed/ColorSwatch/index.d.ts.map +1 -0
  22. package/dist/atoms/composed/DarkModeToggle.d.ts +4 -0
  23. package/dist/atoms/composed/DarkModeToggle.d.ts.map +1 -0
  24. package/dist/atoms/composed/DataBadge/DataBadge.d.ts +13 -0
  25. package/dist/atoms/composed/DataBadge/DataBadge.d.ts.map +1 -0
  26. package/dist/atoms/composed/DataBadge/index.d.ts +2 -0
  27. package/dist/atoms/composed/DataBadge/index.d.ts.map +1 -0
  28. package/dist/atoms/composed/DataTable/DataTable.d.ts +28 -0
  29. package/dist/atoms/composed/DataTable/DataTable.d.ts.map +1 -0
  30. package/dist/atoms/composed/DataTable/TableCellWithTooltip.d.ts +10 -0
  31. package/dist/atoms/composed/DataTable/TableCellWithTooltip.d.ts.map +1 -0
  32. package/dist/atoms/composed/DataTable/index.d.ts +3 -0
  33. package/dist/atoms/composed/DataTable/index.d.ts.map +1 -0
  34. package/dist/atoms/composed/DateTimePicker/DateTimePicker.d.ts +45 -0
  35. package/dist/atoms/composed/DateTimePicker/DateTimePicker.d.ts.map +1 -0
  36. package/dist/atoms/composed/DateTimePicker/index.d.ts +3 -0
  37. package/dist/atoms/composed/DateTimePicker/index.d.ts.map +1 -0
  38. package/dist/atoms/composed/DetailedCard/DetailedCard.d.ts +30 -0
  39. package/dist/atoms/composed/DetailedCard/DetailedCard.d.ts.map +1 -0
  40. package/dist/atoms/composed/DetailedCard/index.d.ts +3 -0
  41. package/dist/atoms/composed/DetailedCard/index.d.ts.map +1 -0
  42. package/dist/atoms/composed/EmptyState/EmptyState.d.ts +18 -0
  43. package/dist/atoms/composed/EmptyState/EmptyState.d.ts.map +1 -0
  44. package/dist/atoms/composed/EmptyState/index.d.ts +2 -0
  45. package/dist/atoms/composed/EmptyState/index.d.ts.map +1 -0
  46. package/dist/atoms/composed/FileUpload/FileUpload.d.ts +46 -0
  47. package/dist/atoms/composed/FileUpload/FileUpload.d.ts.map +1 -0
  48. package/dist/atoms/composed/FileUpload/index.d.ts +3 -0
  49. package/dist/atoms/composed/FileUpload/index.d.ts.map +1 -0
  50. package/dist/atoms/composed/FormField/FormField.d.ts +23 -0
  51. package/dist/atoms/composed/FormField/FormField.d.ts.map +1 -0
  52. package/dist/atoms/composed/FormField/index.d.ts +2 -0
  53. package/dist/atoms/composed/FormField/index.d.ts.map +1 -0
  54. package/dist/atoms/composed/GlobalSearch/GlobalSearch.d.ts +8 -0
  55. package/dist/atoms/composed/GlobalSearch/GlobalSearch.d.ts.map +1 -0
  56. package/dist/atoms/composed/GlobalSearch/index.d.ts +2 -0
  57. package/dist/atoms/composed/GlobalSearch/index.d.ts.map +1 -0
  58. package/dist/atoms/composed/IconBadge/IconBadge.d.ts +16 -0
  59. package/dist/atoms/composed/IconBadge/IconBadge.d.ts.map +1 -0
  60. package/dist/atoms/composed/IconBadge/index.d.ts +3 -0
  61. package/dist/atoms/composed/IconBadge/index.d.ts.map +1 -0
  62. package/dist/atoms/composed/Modal/Modal.d.ts +18 -0
  63. package/dist/atoms/composed/Modal/Modal.d.ts.map +1 -0
  64. package/dist/atoms/composed/Modal/index.d.ts +3 -0
  65. package/dist/atoms/composed/Modal/index.d.ts.map +1 -0
  66. package/dist/atoms/composed/PaletteSwitcher.d.ts +7 -0
  67. package/dist/atoms/composed/PaletteSwitcher.d.ts.map +1 -0
  68. package/dist/atoms/composed/ProgressBar/ProgressBar.d.ts +25 -0
  69. package/dist/atoms/composed/ProgressBar/ProgressBar.d.ts.map +1 -0
  70. package/dist/atoms/composed/ProgressBar/index.d.ts +2 -0
  71. package/dist/atoms/composed/ProgressBar/index.d.ts.map +1 -0
  72. package/dist/atoms/composed/StatCard/StatCard.d.ts +21 -0
  73. package/dist/atoms/composed/StatCard/StatCard.d.ts.map +1 -0
  74. package/dist/atoms/composed/StatCard/index.d.ts +2 -0
  75. package/dist/atoms/composed/StatCard/index.d.ts.map +1 -0
  76. package/dist/atoms/composed/StyleGuide.d.ts +3 -0
  77. package/dist/atoms/composed/StyleGuide.d.ts.map +1 -0
  78. package/dist/atoms/composed/Toast/Toast.d.ts +40 -0
  79. package/dist/atoms/composed/Toast/Toast.d.ts.map +1 -0
  80. package/dist/atoms/composed/Toast/index.d.ts +2 -0
  81. package/dist/atoms/composed/Toast/index.d.ts.map +1 -0
  82. package/dist/atoms/composed/Tooltip/Tooltip.d.ts +16 -0
  83. package/dist/atoms/composed/Tooltip/Tooltip.d.ts.map +1 -0
  84. package/dist/atoms/composed/Tooltip/index.d.ts +2 -0
  85. package/dist/atoms/composed/Tooltip/index.d.ts.map +1 -0
  86. package/dist/atoms/composed/UserAvatar/UserAvatar.d.ts +8 -0
  87. package/dist/atoms/composed/UserAvatar/UserAvatar.d.ts.map +1 -0
  88. package/dist/atoms/composed/UserAvatar/index.d.ts +2 -0
  89. package/dist/atoms/composed/UserAvatar/index.d.ts.map +1 -0
  90. package/dist/atoms/composed/UserMenu/UserMenu.d.ts +8 -0
  91. package/dist/atoms/composed/UserMenu/UserMenu.d.ts.map +1 -0
  92. package/dist/atoms/composed/UserMenu/index.d.ts +2 -0
  93. package/dist/atoms/composed/UserMenu/index.d.ts.map +1 -0
  94. package/dist/atoms/composed/index.d.ts +25 -0
  95. package/dist/atoms/composed/index.d.ts.map +1 -0
  96. package/dist/atoms/hooks/useApi.d.ts +25 -0
  97. package/dist/atoms/hooks/useApi.d.ts.map +1 -0
  98. package/dist/atoms/hooks/useHealth.d.ts +19 -0
  99. package/dist/atoms/hooks/useHealth.d.ts.map +1 -0
  100. package/dist/atoms/index.d.ts +9 -0
  101. package/dist/atoms/index.d.ts.map +1 -0
  102. package/dist/atoms/services/api/client.d.ts +20 -0
  103. package/dist/atoms/services/api/client.d.ts.map +1 -0
  104. package/dist/atoms/services/auth-service.d.ts +24 -0
  105. package/dist/atoms/services/auth-service.d.ts.map +1 -0
  106. package/dist/atoms/services/health.d.ts +7 -0
  107. package/dist/atoms/services/health.d.ts.map +1 -0
  108. package/dist/atoms/services/index.d.ts +4 -0
  109. package/dist/atoms/services/index.d.ts.map +1 -0
  110. package/dist/atoms/shared/config/constants.d.ts +15 -0
  111. package/dist/atoms/shared/config/constants.d.ts.map +1 -0
  112. package/dist/atoms/shared/config/dashboard-sizes.d.ts +83 -0
  113. package/dist/atoms/shared/config/dashboard-sizes.d.ts.map +1 -0
  114. package/dist/atoms/shared/config/environment.d.ts +10 -0
  115. package/dist/atoms/shared/config/environment.d.ts.map +1 -0
  116. package/dist/atoms/shared/index.d.ts +4 -0
  117. package/dist/atoms/shared/index.d.ts.map +1 -0
  118. package/dist/atoms/types/auth.d.ts +56 -0
  119. package/dist/atoms/types/auth.d.ts.map +1 -0
  120. package/dist/atoms/types/generated.d.ts +1469 -0
  121. package/dist/atoms/types/generated.d.ts.map +1 -0
  122. package/dist/atoms/types/index.d.ts +4 -0
  123. package/dist/atoms/types/index.d.ts.map +1 -0
  124. package/dist/atoms/types/loading.d.ts +26 -0
  125. package/dist/atoms/types/loading.d.ts.map +1 -0
  126. package/dist/atoms/ui/Badge.d.ts +10 -0
  127. package/dist/atoms/ui/Badge.d.ts.map +1 -0
  128. package/dist/atoms/ui/ErrorBoundary.d.ts +18 -0
  129. package/dist/atoms/ui/ErrorBoundary.d.ts.map +1 -0
  130. package/dist/atoms/ui/Select.d.ts +28 -0
  131. package/dist/atoms/ui/Select.d.ts.map +1 -0
  132. package/dist/atoms/ui/Switch.d.ts +9 -0
  133. package/dist/atoms/ui/Switch.d.ts.map +1 -0
  134. package/dist/atoms/ui/Tabs.d.ts +30 -0
  135. package/dist/atoms/ui/Tabs.d.ts.map +1 -0
  136. package/dist/atoms/ui/avatar.d.ts +7 -0
  137. package/dist/atoms/ui/avatar.d.ts.map +1 -0
  138. package/dist/atoms/ui/button.d.ts +14 -0
  139. package/dist/atoms/ui/button.d.ts.map +1 -0
  140. package/dist/atoms/ui/card.d.ts +12 -0
  141. package/dist/atoms/ui/card.d.ts.map +1 -0
  142. package/dist/atoms/ui/dropdown-menu.d.ts +28 -0
  143. package/dist/atoms/ui/dropdown-menu.d.ts.map +1 -0
  144. package/dist/atoms/ui/index.d.ts +15 -0
  145. package/dist/atoms/ui/index.d.ts.map +1 -0
  146. package/dist/atoms/ui/input.d.ts +5 -0
  147. package/dist/atoms/ui/input.d.ts.map +1 -0
  148. package/dist/atoms/ui/label.d.ts +6 -0
  149. package/dist/atoms/ui/label.d.ts.map +1 -0
  150. package/dist/atoms/ui/skeleton.d.ts +3 -0
  151. package/dist/atoms/ui/skeleton.d.ts.map +1 -0
  152. package/dist/atoms/ui/spinner.d.ts +14 -0
  153. package/dist/atoms/ui/spinner.d.ts.map +1 -0
  154. package/dist/atoms/ui/table.d.ts +11 -0
  155. package/dist/atoms/ui/table.d.ts.map +1 -0
  156. package/dist/atoms/utils/animations.d.ts +65 -0
  157. package/dist/atoms/utils/animations.d.ts.map +1 -0
  158. package/dist/atoms/utils/tooltip-helpers.d.ts +71 -0
  159. package/dist/atoms/utils/tooltip-helpers.d.ts.map +1 -0
  160. package/dist/atoms/utils/utils.d.ts +4 -0
  161. package/dist/atoms/utils/utils.d.ts.map +1 -0
  162. package/dist/features/auth/components/LoginForm.d.ts +2 -0
  163. package/dist/features/auth/components/LoginForm.d.ts.map +1 -0
  164. package/dist/features/auth/components/LogoutButton.d.ts +2 -0
  165. package/dist/features/auth/components/LogoutButton.d.ts.map +1 -0
  166. package/dist/features/auth/components/ProtectedRoute.d.ts +10 -0
  167. package/dist/features/auth/components/ProtectedRoute.d.ts.map +1 -0
  168. package/dist/features/auth/components/index.d.ts +4 -0
  169. package/dist/features/auth/components/index.d.ts.map +1 -0
  170. package/dist/features/auth/hooks/index.d.ts +3 -0
  171. package/dist/features/auth/hooks/index.d.ts.map +1 -0
  172. package/dist/features/auth/hooks/useAuth.d.ts +10 -0
  173. package/dist/features/auth/hooks/useAuth.d.ts.map +1 -0
  174. package/dist/features/auth/hooks/usePermissions.d.ts +13 -0
  175. package/dist/features/auth/hooks/usePermissions.d.ts.map +1 -0
  176. package/dist/features/auth/index.d.ts +3 -0
  177. package/dist/features/auth/index.d.ts.map +1 -0
  178. package/dist/features/index.d.ts +2 -0
  179. package/dist/features/index.d.ts.map +1 -0
  180. package/dist/frontend-patterns.css +567 -0
  181. package/dist/index.d.ts +10 -0
  182. package/dist/index.d.ts.map +1 -0
  183. package/dist/index.es.js +10152 -0
  184. package/dist/index.es.js.map +1 -0
  185. package/dist/index.js +10170 -0
  186. package/dist/index.js.map +1 -0
  187. package/dist/molecules/forms/FormGroup.d.ts +17 -0
  188. package/dist/molecules/forms/FormGroup.d.ts.map +1 -0
  189. package/dist/molecules/forms/SearchInput.d.ts +36 -0
  190. package/dist/molecules/forms/SearchInput.d.ts.map +1 -0
  191. package/dist/molecules/forms/index.d.ts +3 -0
  192. package/dist/molecules/forms/index.d.ts.map +1 -0
  193. package/dist/molecules/index.d.ts +4 -0
  194. package/dist/molecules/index.d.ts.map +1 -0
  195. package/dist/molecules/layout/AppHeader/AppHeader.d.ts +7 -0
  196. package/dist/molecules/layout/AppHeader/AppHeader.d.ts.map +1 -0
  197. package/dist/molecules/layout/AppHeader/index.d.ts +2 -0
  198. package/dist/molecules/layout/AppHeader/index.d.ts.map +1 -0
  199. package/dist/molecules/layout/AppLayout.d.ts +2 -0
  200. package/dist/molecules/layout/AppLayout.d.ts.map +1 -0
  201. package/dist/molecules/layout/PageTemplate.d.ts +19 -0
  202. package/dist/molecules/layout/PageTemplate.d.ts.map +1 -0
  203. package/dist/molecules/layout/SectionHeader/SectionHeader.d.ts +24 -0
  204. package/dist/molecules/layout/SectionHeader/SectionHeader.d.ts.map +1 -0
  205. package/dist/molecules/layout/SectionHeader/index.d.ts +2 -0
  206. package/dist/molecules/layout/SectionHeader/index.d.ts.map +1 -0
  207. package/dist/molecules/layout/ShowcaseSection.d.ts +22 -0
  208. package/dist/molecules/layout/ShowcaseSection.d.ts.map +1 -0
  209. package/dist/molecules/layout/Sidebar.d.ts +6 -0
  210. package/dist/molecules/layout/Sidebar.d.ts.map +1 -0
  211. package/dist/molecules/layout/SidebarButton/SidebarButton.d.ts +13 -0
  212. package/dist/molecules/layout/SidebarButton/SidebarButton.d.ts.map +1 -0
  213. package/dist/molecules/layout/SidebarButton/index.d.ts +2 -0
  214. package/dist/molecules/layout/SidebarButton/index.d.ts.map +1 -0
  215. package/dist/molecules/layout/SidebarContext.d.ts +12 -0
  216. package/dist/molecules/layout/SidebarContext.d.ts.map +1 -0
  217. package/dist/molecules/layout/index.d.ts +8 -0
  218. package/dist/molecules/layout/index.d.ts.map +1 -0
  219. package/dist/molecules/navigation/NavMenu.d.ts +20 -0
  220. package/dist/molecules/navigation/NavMenu.d.ts.map +1 -0
  221. package/dist/molecules/navigation/Pagination.d.ts +14 -0
  222. package/dist/molecules/navigation/Pagination.d.ts.map +1 -0
  223. package/dist/molecules/navigation/index.d.ts +3 -0
  224. package/dist/molecules/navigation/index.d.ts.map +1 -0
  225. package/dist/organisms/index.d.ts +2 -0
  226. package/dist/organisms/index.d.ts.map +1 -0
  227. package/dist/organisms/showcase/ComponentShowcasePage.d.ts +3 -0
  228. package/dist/organisms/showcase/ComponentShowcasePage.d.ts.map +1 -0
  229. package/dist/templates/AuthTemplate.d.ts +68 -0
  230. package/dist/templates/AuthTemplate.d.ts.map +1 -0
  231. package/dist/templates/ComponentShowcaseTemplate.d.ts +53 -0
  232. package/dist/templates/ComponentShowcaseTemplate.d.ts.map +1 -0
  233. package/dist/templates/DashboardTemplate.d.ts +62 -0
  234. package/dist/templates/DashboardTemplate.d.ts.map +1 -0
  235. package/dist/templates/DataTemplate.d.ts +78 -0
  236. package/dist/templates/DataTemplate.d.ts.map +1 -0
  237. package/dist/templates/admin/AdminCRUDTemplate.d.ts +105 -0
  238. package/dist/templates/admin/AdminCRUDTemplate.d.ts.map +1 -0
  239. package/dist/templates/admin/AdminDashboardTemplate.d.ts +89 -0
  240. package/dist/templates/admin/AdminDashboardTemplate.d.ts.map +1 -0
  241. package/dist/templates/admin/AdminDetailTemplate.d.ts +132 -0
  242. package/dist/templates/admin/AdminDetailTemplate.d.ts.map +1 -0
  243. package/dist/templates/admin/index.d.ts +4 -0
  244. package/dist/templates/admin/index.d.ts.map +1 -0
  245. package/dist/templates/factory.d.ts +28 -0
  246. package/dist/templates/factory.d.ts.map +1 -0
  247. package/dist/templates/index.d.ts +7 -0
  248. package/dist/templates/index.d.ts.map +1 -0
  249. package/package.json +118 -0
  250. package/src/App.css +42 -0
  251. package/src/App.tsx +54 -0
  252. package/src/__tests__/README.md +221 -0
  253. package/src/__tests__/atoms/hooks/simple-hooks.test.ts +44 -0
  254. package/src/__tests__/atoms/ui/button.test.tsx +68 -0
  255. package/src/__tests__/atoms/utils/simple.test.ts +18 -0
  256. package/src/__tests__/atoms/utils/utils.test.ts +77 -0
  257. package/src/__tests__/features/auth/simple-auth.test.tsx +40 -0
  258. package/src/__tests__/molecules/layout/simple-layout.test.tsx +81 -0
  259. package/src/__tests__/organisms/showcase/simple-showcase.test.tsx +167 -0
  260. package/src/__tests__/setup.ts +51 -0
  261. package/src/__tests__/utils.tsx +123 -0
  262. package/src/atoms/composed/Accordion/Accordion.tsx +271 -0
  263. package/src/atoms/composed/Accordion/index.ts +1 -0
  264. package/src/atoms/composed/Alert/Alert.tsx +132 -0
  265. package/src/atoms/composed/Alert/index.ts +1 -0
  266. package/src/atoms/composed/Breadcrumb/Breadcrumb.tsx +83 -0
  267. package/src/atoms/composed/Breadcrumb/index.ts +1 -0
  268. package/src/atoms/composed/Chart/Chart.tsx +425 -0
  269. package/src/atoms/composed/Chart/index.ts +2 -0
  270. package/src/atoms/composed/ColorSwatch/ColorSwatch.tsx +72 -0
  271. package/src/atoms/composed/ColorSwatch/index.ts +1 -0
  272. package/src/atoms/composed/DarkModeToggle.tsx +66 -0
  273. package/src/atoms/composed/DataBadge/DataBadge.tsx +81 -0
  274. package/src/atoms/composed/DataBadge/index.ts +1 -0
  275. package/src/atoms/composed/DataTable/DataTable.tsx +394 -0
  276. package/src/atoms/composed/DataTable/TableCellWithTooltip.tsx +41 -0
  277. package/src/atoms/composed/DataTable/index.ts +2 -0
  278. package/src/atoms/composed/DateTimePicker/DateTimePicker.tsx +611 -0
  279. package/src/atoms/composed/DateTimePicker/index.ts +2 -0
  280. package/src/atoms/composed/DetailedCard/DetailedCard.tsx +181 -0
  281. package/src/atoms/composed/DetailedCard/index.ts +2 -0
  282. package/src/atoms/composed/EmptyState/EmptyState.tsx +90 -0
  283. package/src/atoms/composed/EmptyState/index.ts +1 -0
  284. package/src/atoms/composed/FileUpload/FileUpload.tsx +477 -0
  285. package/src/atoms/composed/FileUpload/index.ts +2 -0
  286. package/src/atoms/composed/FormField/FormField.tsx +92 -0
  287. package/src/atoms/composed/FormField/index.ts +1 -0
  288. package/src/atoms/composed/GlobalSearch/GlobalSearch.tsx +37 -0
  289. package/src/atoms/composed/GlobalSearch/index.ts +1 -0
  290. package/src/atoms/composed/IconBadge/IconBadge.tsx +95 -0
  291. package/src/atoms/composed/IconBadge/index.ts +2 -0
  292. package/src/atoms/composed/Modal/Modal.tsx +223 -0
  293. package/src/atoms/composed/Modal/index.ts +2 -0
  294. package/src/atoms/composed/PaletteSwitcher.tsx +386 -0
  295. package/src/atoms/composed/ProgressBar/ProgressBar.tsx +116 -0
  296. package/src/atoms/composed/ProgressBar/index.ts +1 -0
  297. package/src/atoms/composed/StatCard/StatCard.tsx +219 -0
  298. package/src/atoms/composed/StatCard/index.ts +1 -0
  299. package/src/atoms/composed/StyleGuide.tsx +717 -0
  300. package/src/atoms/composed/Toast/Toast.tsx +219 -0
  301. package/src/atoms/composed/Toast/index.ts +1 -0
  302. package/src/atoms/composed/Tooltip/Tooltip.tsx +213 -0
  303. package/src/atoms/composed/Tooltip/index.ts +1 -0
  304. package/src/atoms/composed/UserAvatar/UserAvatar.tsx +139 -0
  305. package/src/atoms/composed/UserAvatar/index.ts +1 -0
  306. package/src/atoms/composed/UserMenu/UserMenu.tsx +16 -0
  307. package/src/atoms/composed/UserMenu/index.ts +1 -0
  308. package/src/atoms/composed/index.ts +29 -0
  309. package/src/atoms/hooks/useApi.ts +80 -0
  310. package/src/atoms/hooks/useHealth.ts +17 -0
  311. package/src/atoms/index.ts +13 -0
  312. package/src/atoms/services/api/client.ts +134 -0
  313. package/src/atoms/services/auth-service.ts +248 -0
  314. package/src/atoms/services/health.ts +15 -0
  315. package/src/atoms/services/index.ts +3 -0
  316. package/src/atoms/shared/config/constants.ts +17 -0
  317. package/src/atoms/shared/config/dashboard-sizes.ts +111 -0
  318. package/src/atoms/shared/config/environment.ts +10 -0
  319. package/src/atoms/shared/index.ts +4 -0
  320. package/src/atoms/shared/styles/color-palettes.css +566 -0
  321. package/src/atoms/types/auth.ts +62 -0
  322. package/src/atoms/types/generated.ts +1469 -0
  323. package/src/atoms/types/index.ts +4 -0
  324. package/src/atoms/types/loading.ts +28 -0
  325. package/src/atoms/ui/Badge.tsx +30 -0
  326. package/src/atoms/ui/ErrorBoundary.tsx +59 -0
  327. package/src/atoms/ui/Select.tsx +53 -0
  328. package/src/atoms/ui/Switch.tsx +42 -0
  329. package/src/atoms/ui/Tabs.tsx +118 -0
  330. package/src/atoms/ui/avatar.tsx +48 -0
  331. package/src/atoms/ui/button.tsx +70 -0
  332. package/src/atoms/ui/card.tsx +76 -0
  333. package/src/atoms/ui/dropdown-menu.tsx +199 -0
  334. package/src/atoms/ui/index.ts +39 -0
  335. package/src/atoms/ui/input.tsx +23 -0
  336. package/src/atoms/ui/label.tsx +23 -0
  337. package/src/atoms/ui/skeleton.tsx +13 -0
  338. package/src/atoms/ui/spinner.tsx +49 -0
  339. package/src/atoms/ui/table.tsx +116 -0
  340. package/src/atoms/utils/animations.ts +135 -0
  341. package/src/atoms/utils/tooltip-helpers.ts +140 -0
  342. package/src/atoms/utils/utils.ts +9 -0
  343. package/src/features/auth/components/LoginForm.tsx +168 -0
  344. package/src/features/auth/components/LogoutButton.tsx +19 -0
  345. package/src/features/auth/components/ProtectedRoute.tsx +60 -0
  346. package/src/features/auth/components/index.ts +4 -0
  347. package/src/features/auth/hooks/index.ts +2 -0
  348. package/src/features/auth/hooks/useAuth.tsx +205 -0
  349. package/src/features/auth/hooks/usePermissions.ts +35 -0
  350. package/src/features/auth/index.ts +2 -0
  351. package/src/features/index.ts +2 -0
  352. package/src/index.css +704 -0
  353. package/src/index.ts +13 -0
  354. package/src/main.tsx +48 -0
  355. package/src/molecules/.gitkeep +0 -0
  356. package/src/molecules/forms/FormGroup.tsx +75 -0
  357. package/src/molecules/forms/SearchInput.tsx +259 -0
  358. package/src/molecules/forms/index.ts +4 -0
  359. package/src/molecules/index.ts +4 -0
  360. package/src/molecules/layout/AppHeader/AppHeader.tsx +42 -0
  361. package/src/molecules/layout/AppHeader/index.ts +1 -0
  362. package/src/molecules/layout/AppLayout.tsx +29 -0
  363. package/src/molecules/layout/PageTemplate.tsx +87 -0
  364. package/src/molecules/layout/SectionHeader/SectionHeader.tsx +87 -0
  365. package/src/molecules/layout/SectionHeader/index.ts +1 -0
  366. package/src/molecules/layout/ShowcaseSection.tsx +57 -0
  367. package/src/molecules/layout/Sidebar.tsx +144 -0
  368. package/src/molecules/layout/SidebarButton/SidebarButton.tsx +99 -0
  369. package/src/molecules/layout/SidebarButton/index.ts +1 -0
  370. package/src/molecules/layout/SidebarContext.tsx +31 -0
  371. package/src/molecules/layout/index.ts +7 -0
  372. package/src/molecules/navigation/NavMenu.tsx +188 -0
  373. package/src/molecules/navigation/Pagination.tsx +172 -0
  374. package/src/molecules/navigation/index.ts +4 -0
  375. package/src/organisms/index.ts +5 -0
  376. package/src/organisms/showcase/ComponentShowcasePage.tsx +2496 -0
  377. package/src/organisms/showcase/index.ts +1 -0
  378. package/src/pages/AdminShowcase/AdminCRUDShowcase.tsx +242 -0
  379. package/src/pages/AdminShowcase/AdminDashboardShowcase.tsx +171 -0
  380. package/src/pages/AdminShowcase/AdminDetailShowcase.tsx +385 -0
  381. package/src/pages/AdminShowcase/index.tsx +3 -0
  382. package/src/pages/ComponentShowcase/BadgesShowcase.tsx +188 -0
  383. package/src/pages/ComponentShowcase/CardsShowcase.tsx +392 -0
  384. package/src/pages/ComponentShowcase/PalettesShowcase.tsx +207 -0
  385. package/src/pages/ComponentShowcase/StatesShowcase.tsx +485 -0
  386. package/src/pages/ComponentShowcase/TablesShowcase.tsx +134 -0
  387. package/src/pages/ComponentShowcase/TypographyShowcase.tsx +255 -0
  388. package/src/pages/ComponentShowcase/index.tsx +188 -0
  389. package/src/pages/index.ts +2 -0
  390. package/src/templates/AuthTemplate.tsx +216 -0
  391. package/src/templates/ComponentShowcaseTemplate.tsx +173 -0
  392. package/src/templates/DashboardTemplate.tsx +232 -0
  393. package/src/templates/DataTemplate.tsx +319 -0
  394. package/src/templates/admin/AdminCRUDTemplate.tsx +630 -0
  395. package/src/templates/admin/AdminDashboardTemplate.tsx +351 -0
  396. package/src/templates/admin/AdminDetailTemplate.tsx +563 -0
  397. package/src/templates/admin/index.ts +29 -0
  398. package/src/templates/factory.tsx +169 -0
  399. package/src/templates/index.ts +37 -0
  400. package/src/vite-env.d.ts +1 -0
package/src/main.tsx ADDED
@@ -0,0 +1,48 @@
1
+ import { StrictMode } from 'react'
2
+ import { createRoot } from 'react-dom/client'
3
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
4
+ import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
5
+ import { AuthProvider } from './features/auth'
6
+ import { SidebarProvider } from './molecules/layout'
7
+ import './index.css'
8
+ import App from './App.tsx'
9
+
10
+ // Suppress browser extension errors in development
11
+ if (import.meta.env.DEV) {
12
+ const originalError = console.error;
13
+ console.error = (...args) => {
14
+ const message = args[0];
15
+ if (
16
+ typeof message === 'string' &&
17
+ (message.includes('Deprecated API for given entry type') ||
18
+ message.includes('message channel closed before a response was received') ||
19
+ message.includes('Extension context invalidated'))
20
+ ) {
21
+ return; // Suppress extension-related errors
22
+ }
23
+ originalError(...args);
24
+ };
25
+ }
26
+
27
+ const queryClient = new QueryClient({
28
+ defaultOptions: {
29
+ queries: {
30
+ retry: 1,
31
+ refetchOnWindowFocus: false,
32
+ staleTime: 5 * 60 * 1000, // 5 minutes
33
+ },
34
+ },
35
+ })
36
+
37
+ createRoot(document.getElementById('root')!).render(
38
+ <StrictMode>
39
+ <QueryClientProvider client={queryClient}>
40
+ <AuthProvider>
41
+ <SidebarProvider>
42
+ <App />
43
+ </SidebarProvider>
44
+ </AuthProvider>
45
+ <ReactQueryDevtools initialIsOpen={false} />
46
+ </QueryClientProvider>
47
+ </StrictMode>,
48
+ )
File without changes
@@ -0,0 +1,75 @@
1
+ import React from 'react';
2
+ import { cn } from '../../atoms/utils/utils';
3
+
4
+ export interface FormGroupProps {
5
+ /** Group title */
6
+ title?: string;
7
+ /** Group description */
8
+ description?: string;
9
+ /** Group content */
10
+ children: React.ReactNode;
11
+ /** Visual variant */
12
+ variant?: 'default' | 'card' | 'section';
13
+ /** Additional CSS classes */
14
+ className?: string;
15
+ /** Category-based styling */
16
+ category?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
17
+ }
18
+
19
+ export const FormGroup: React.FC<FormGroupProps> = ({
20
+ title,
21
+ description,
22
+ children,
23
+ variant = 'default',
24
+ className,
25
+ category
26
+ }) => {
27
+ const variantClasses = {
28
+ default: 'space-y-4',
29
+ card: 'space-y-4 p-6 bg-card border border-border rounded-lg',
30
+ section: 'space-y-6 pb-6 border-b border-border last:border-b-0 last:pb-0'
31
+ };
32
+
33
+ const titleClasses = {
34
+ default: 'text-lg font-semibold text-foreground',
35
+ card: 'text-lg font-semibold text-foreground',
36
+ section: 'text-xl font-semibold text-foreground'
37
+ };
38
+
39
+ return (
40
+ <div
41
+ className={cn(
42
+ variantClasses[variant],
43
+ category && variant === 'card' && `border-category-${category}/20`,
44
+ className
45
+ )}
46
+ data-component-name="FormGroup"
47
+ >
48
+ {/* Header */}
49
+ {(title || description) && (
50
+ <div className="space-y-1">
51
+ {title && (
52
+ <h3
53
+ className={cn(
54
+ titleClasses[variant],
55
+ category && `text-category-${category}`
56
+ )}
57
+ >
58
+ {title}
59
+ </h3>
60
+ )}
61
+ {description && (
62
+ <p className="text-sm text-muted-foreground">
63
+ {description}
64
+ </p>
65
+ )}
66
+ </div>
67
+ )}
68
+
69
+ {/* Content */}
70
+ <div className="space-y-4">
71
+ {children}
72
+ </div>
73
+ </div>
74
+ );
75
+ };
@@ -0,0 +1,259 @@
1
+ import React, { useState, useRef, useEffect } from 'react';
2
+ import { Search, X, Loader2 } from 'lucide-react';
3
+ import { cn } from '../../atoms/utils/utils';
4
+ import { Input } from '../../atoms/ui/input';
5
+ import { Button } from '../../atoms/ui/button';
6
+ import { getAnimationClasses, animationPresets } from '../../atoms/utils/animations';
7
+
8
+ export interface SearchResult {
9
+ id: string;
10
+ label: string;
11
+ description?: string;
12
+ category?: string;
13
+ icon?: React.ReactNode;
14
+ }
15
+
16
+ export interface SearchInputProps {
17
+ /** Search placeholder text */
18
+ placeholder?: string;
19
+ /** Current search value */
20
+ value?: string;
21
+ /** Value change handler */
22
+ onChange?: (value: string) => void;
23
+ /** Search results */
24
+ results?: SearchResult[];
25
+ /** Loading state */
26
+ loading?: boolean;
27
+ /** Result selection handler */
28
+ onSelect?: (result: SearchResult) => void;
29
+ /** Search debounce delay in ms */
30
+ debounceMs?: number;
31
+ /** Whether to show clear button */
32
+ clearable?: boolean;
33
+ /** Additional CSS classes */
34
+ className?: string;
35
+ /** Category-based styling */
36
+ category?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
37
+ /** Maximum results to show */
38
+ maxResults?: number;
39
+ /** No results message */
40
+ noResultsText?: string;
41
+ }
42
+
43
+ export const SearchInput: React.FC<SearchInputProps> = ({
44
+ placeholder = 'Search...',
45
+ value = '',
46
+ onChange,
47
+ results = [],
48
+ loading = false,
49
+ onSelect,
50
+ debounceMs = 300,
51
+ clearable = true,
52
+ className,
53
+ category = 1,
54
+ maxResults = 10,
55
+ noResultsText = 'No results found'
56
+ }) => {
57
+ const [internalValue, setInternalValue] = useState(value);
58
+ const [isOpen, setIsOpen] = useState(false);
59
+ const [highlightedIndex, setHighlightedIndex] = useState(-1);
60
+
61
+ const inputRef = useRef<HTMLInputElement>(null);
62
+ const resultsRef = useRef<HTMLDivElement>(null);
63
+ const debounceRef = useRef<NodeJS.Timeout | undefined>(undefined);
64
+
65
+ const displayResults = results.slice(0, maxResults);
66
+ const showResults = isOpen && (displayResults.length > 0 || (internalValue && !loading));
67
+
68
+ // Debounced search
69
+ useEffect(() => {
70
+ if (debounceRef.current) {
71
+ clearTimeout(debounceRef.current);
72
+ }
73
+
74
+ debounceRef.current = setTimeout(() => {
75
+ if (onChange) onChange(internalValue);
76
+ }, debounceMs);
77
+
78
+ return () => {
79
+ if (debounceRef.current) {
80
+ clearTimeout(debounceRef.current);
81
+ }
82
+ };
83
+ }, [internalValue, onChange, debounceMs]);
84
+
85
+ // Sync external value
86
+ useEffect(() => {
87
+ setInternalValue(value);
88
+ }, [value]);
89
+
90
+ // Keyboard navigation
91
+ const handleKeyDown = (e: React.KeyboardEvent) => {
92
+ if (!showResults) return;
93
+
94
+ switch (e.key) {
95
+ case 'ArrowDown':
96
+ e.preventDefault();
97
+ setHighlightedIndex(prev =>
98
+ prev < displayResults.length - 1 ? prev + 1 : prev
99
+ );
100
+ break;
101
+ case 'ArrowUp':
102
+ e.preventDefault();
103
+ setHighlightedIndex(prev => prev > 0 ? prev - 1 : prev);
104
+ break;
105
+ case 'Enter':
106
+ e.preventDefault();
107
+ if (highlightedIndex >= 0 && displayResults[highlightedIndex]) {
108
+ handleSelect(displayResults[highlightedIndex]);
109
+ }
110
+ break;
111
+ case 'Escape':
112
+ setIsOpen(false);
113
+ setHighlightedIndex(-1);
114
+ inputRef.current?.blur();
115
+ break;
116
+ }
117
+ };
118
+
119
+ const handleSelect = (result: SearchResult) => {
120
+ onSelect?.(result);
121
+ setIsOpen(false);
122
+ setHighlightedIndex(-1);
123
+ inputRef.current?.blur();
124
+ };
125
+
126
+ const handleClear = () => {
127
+ setInternalValue('');
128
+ onChange?.('');
129
+ setIsOpen(false);
130
+ inputRef.current?.focus();
131
+ };
132
+
133
+ const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
134
+ const newValue = e.target.value;
135
+ setInternalValue(newValue);
136
+ setIsOpen(true);
137
+ setHighlightedIndex(-1);
138
+ };
139
+
140
+ const handleFocus = () => {
141
+ if (internalValue) {
142
+ setIsOpen(true);
143
+ }
144
+ };
145
+
146
+ const handleBlur = () => {
147
+ // Delay closing to allow for result clicks
148
+ setTimeout(() => {
149
+ if (!resultsRef.current?.contains(document.activeElement)) {
150
+ setIsOpen(false);
151
+ setHighlightedIndex(-1);
152
+ }
153
+ }, 150);
154
+ };
155
+
156
+ return (
157
+ <div className={cn('relative w-full', className)} data-component-name="SearchInput">
158
+ {/* Input container */}
159
+ <div className="relative">
160
+ <div className="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground">
161
+ {loading ? (
162
+ <Loader2 className="w-4 h-4 animate-spin" />
163
+ ) : (
164
+ <Search className="w-4 h-4" />
165
+ )}
166
+ </div>
167
+
168
+ <Input
169
+ ref={inputRef}
170
+ type="text"
171
+ value={internalValue}
172
+ onChange={handleInputChange}
173
+ onKeyDown={handleKeyDown}
174
+ onFocus={handleFocus}
175
+ onBlur={handleBlur}
176
+ placeholder={placeholder}
177
+ className={cn(
178
+ 'pl-10',
179
+ clearable && internalValue && 'pr-10',
180
+ showResults && `ring-2 ring-category-${category}/20`
181
+ )}
182
+ />
183
+
184
+ {clearable && internalValue && (
185
+ <Button
186
+ type="button"
187
+ variant="ghost"
188
+ size="sm"
189
+ onClick={handleClear}
190
+ className="absolute right-1 top-1/2 -translate-y-1/2 h-7 w-7 p-0 hover:bg-muted"
191
+ >
192
+ <X className="w-4 h-4" />
193
+ </Button>
194
+ )}
195
+ </div>
196
+
197
+ {/* Results dropdown */}
198
+ {showResults && (
199
+ <div
200
+ ref={resultsRef}
201
+ className={cn(
202
+ 'absolute top-full left-0 right-0 z-50 mt-1',
203
+ 'bg-popover border border-border rounded-md shadow-lg',
204
+ 'max-h-64 overflow-y-auto',
205
+ getAnimationClasses(animationPresets.card)
206
+ )}
207
+ >
208
+ {displayResults.length > 0 ? (
209
+ <div className="py-1">
210
+ {displayResults.map((result, index) => (
211
+ <button
212
+ key={result.id}
213
+ type="button"
214
+ onClick={() => handleSelect(result)}
215
+ className={cn(
216
+ 'w-full text-left px-3 py-2 text-sm',
217
+ 'hover:bg-muted/50 focus:bg-muted/50',
218
+ 'transition-colors duration-150',
219
+ index === highlightedIndex && [
220
+ `bg-category-${category}/10`,
221
+ `text-category-${category}`
222
+ ]
223
+ )}
224
+ >
225
+ <div className="flex items-center gap-2">
226
+ {result.icon && (
227
+ <span className="flex-shrink-0 text-muted-foreground">
228
+ {result.icon}
229
+ </span>
230
+ )}
231
+ <div className="flex-1 min-w-0">
232
+ <div className="font-medium truncate">
233
+ {result.label}
234
+ </div>
235
+ {result.description && (
236
+ <div className="text-xs text-muted-foreground truncate">
237
+ {result.description}
238
+ </div>
239
+ )}
240
+ </div>
241
+ {result.category && (
242
+ <span className="text-xs text-muted-foreground">
243
+ {result.category}
244
+ </span>
245
+ )}
246
+ </div>
247
+ </button>
248
+ ))}
249
+ </div>
250
+ ) : internalValue && !loading ? (
251
+ <div className="px-3 py-2 text-sm text-muted-foreground">
252
+ {noResultsText}
253
+ </div>
254
+ ) : null}
255
+ </div>
256
+ )}
257
+ </div>
258
+ );
259
+ };
@@ -0,0 +1,4 @@
1
+ // Form molecules - reusable form patterns and workflows
2
+ // Note: FormField moved to @/atoms/composed as it is a business UI component
3
+ export { FormGroup, type FormGroupProps } from './FormGroup';
4
+ export { SearchInput, type SearchInputProps, type SearchResult } from './SearchInput';
@@ -0,0 +1,4 @@
1
+ // Molecule layer exports - combinations of atoms and features
2
+ export * from './layout';
3
+ export * from './navigation';
4
+ export * from './forms';
@@ -0,0 +1,42 @@
1
+ import React from 'react';
2
+ import { GlobalSearch, UserMenu } from '../../../atoms/composed';
3
+ import { cn } from '../../../atoms/utils/utils';
4
+
5
+ interface AppHeaderProps {
6
+ className?: string;
7
+ }
8
+
9
+ export const AppHeader: React.FC<AppHeaderProps> = ({ className }) => {
10
+ return (
11
+ <header className={cn(
12
+ "fixed top-0 left-0 right-0 z-50",
13
+ "bg-card/95 backdrop-blur-sm border-b border-border",
14
+ "supports-[backdrop-filter]:bg-card/95",
15
+ className
16
+ )}>
17
+ <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
18
+ <div className="flex h-16 items-center justify-between">
19
+ {/* App Title */}
20
+ <div className="flex items-center">
21
+ <h1 className="text-xl font-bold text-foreground">
22
+ Data Trust Navigator
23
+ </h1>
24
+ </div>
25
+
26
+ {/* Centered Global Search */}
27
+ <div className="flex-1 max-w-2xl mx-8">
28
+ <GlobalSearch
29
+ className="w-full"
30
+ placeholder="Search models, tests, jobs, and components..."
31
+ />
32
+ </div>
33
+
34
+ {/* User Menu */}
35
+ <div className="flex items-center space-x-4">
36
+ <UserMenu category={8} />
37
+ </div>
38
+ </div>
39
+ </div>
40
+ </header>
41
+ );
42
+ };
@@ -0,0 +1 @@
1
+ export { AppHeader } from './AppHeader';
@@ -0,0 +1,29 @@
1
+ import { Outlet } from 'react-router-dom';
2
+ import { Sidebar } from './Sidebar';
3
+ import { AppHeader } from './AppHeader';
4
+ import { useSidebar } from './SidebarContext';
5
+ import { cn } from '../../atoms/utils/utils';
6
+
7
+ export const AppLayout = () => {
8
+ const { isExpanded } = useSidebar();
9
+
10
+ return (
11
+ <div className="min-h-screen bg-background">
12
+ {/* Header spans full width */}
13
+ <AppHeader />
14
+
15
+ {/* Sidebar positioned fixed */}
16
+ <Sidebar />
17
+
18
+ {/* Main content with proper spacing for fixed sidebar */}
19
+ <main
20
+ className={cn(
21
+ "pt-16 min-h-screen transition-all duration-300 ease-in-out",
22
+ isExpanded ? 'ml-64' : 'ml-16'
23
+ )}
24
+ >
25
+ <Outlet />
26
+ </main>
27
+ </div>
28
+ );
29
+ };
@@ -0,0 +1,87 @@
1
+ import React from 'react';
2
+ import { cn } from '../../atoms/utils/utils';
3
+ import { getAnimationClasses } from '../../atoms/utils/animations';
4
+
5
+ export interface PageTemplateProps {
6
+ /** Main page title */
7
+ title: string;
8
+ /** Optional subtitle/description */
9
+ subtitle?: string;
10
+ /** Optional icon element to display with title */
11
+ icon?: React.ReactNode;
12
+ /** Optional action buttons/controls for the header */
13
+ actions?: React.ReactNode;
14
+ /** Page content */
15
+ children: React.ReactNode;
16
+ /** Additional CSS classes for the container */
17
+ className?: string;
18
+ /** Whether to apply animation to the page content */
19
+ animated?: boolean;
20
+ }
21
+
22
+ export const PageTemplate: React.FC<PageTemplateProps> = ({
23
+ title,
24
+ subtitle,
25
+ icon,
26
+ actions,
27
+ children,
28
+ className,
29
+ animated = true
30
+ }) => {
31
+ return (
32
+ <div
33
+ className={cn(
34
+ 'min-h-screen bg-background',
35
+ animated && getAnimationClasses({ type: 'subtle', timing: 'slow' }),
36
+ className
37
+ )}
38
+ data-component-name="PageTemplate"
39
+ >
40
+ {/* Page Header */}
41
+ <header className="border-b border-border bg-card/50 backdrop-blur-sm sticky top-0 z-10">
42
+ <div className="container mx-auto px-4 sm:px-6 lg:px-8">
43
+ <div className="flex items-center justify-between py-6 sm:py-8">
44
+ <div className="flex items-center space-x-4 min-w-0 flex-1">
45
+ {icon && (
46
+ <div className="flex-shrink-0 w-8 h-8 sm:w-10 sm:h-10 flex items-center justify-center rounded bg-primary/10 text-primary">
47
+ {icon}
48
+ </div>
49
+ )}
50
+
51
+ <div className="min-w-0 flex-1">
52
+ <h1 className="text-2xl sm:text-3xl lg:text-4xl font-bold text-foreground tracking-tight">
53
+ {title}
54
+ </h1>
55
+ {subtitle && (
56
+ <p className="mt-2 text-base sm:text-lg text-muted-foreground max-w-3xl">
57
+ {subtitle}
58
+ </p>
59
+ )}
60
+ </div>
61
+ </div>
62
+
63
+ {actions && (
64
+ <div className="flex-shrink-0 ml-4">
65
+ <div className="flex items-center space-x-3">
66
+ {actions}
67
+ </div>
68
+ </div>
69
+ )}
70
+ </div>
71
+ </div>
72
+ </header>
73
+
74
+ {/* Page Content */}
75
+ <main className="container mx-auto px-4 sm:px-6 lg:px-8 py-6 sm:py-8 lg:py-12">
76
+ <div
77
+ className={cn(
78
+ 'space-y-8',
79
+ animated && 'animate-fade-in'
80
+ )}
81
+ >
82
+ {children}
83
+ </div>
84
+ </main>
85
+ </div>
86
+ );
87
+ };
@@ -0,0 +1,87 @@
1
+ import React from 'react';
2
+ import { cn } from '../../../atoms/utils/utils';
3
+ import { DataBadge } from '../../../atoms/composed/DataBadge';
4
+
5
+ export interface SectionHeaderProps {
6
+ /** Main heading text */
7
+ title: string;
8
+ /** Optional description text */
9
+ description?: string;
10
+ /** Optional subtitle text */
11
+ subtitle?: string;
12
+ /** Size variant */
13
+ size?: 'sm' | 'md' | 'lg';
14
+ /** Additional CSS classes */
15
+ className?: string;
16
+ /** Optional icon element */
17
+ icon?: React.ReactNode;
18
+ /** Optional badge configuration */
19
+ badge?: {
20
+ text: string;
21
+ variant?: 'category' | 'status';
22
+ category?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
23
+ status?: 'success' | 'warning' | 'error' | 'info' | 'neutral';
24
+ };
25
+ }
26
+
27
+ export const SectionHeader: React.FC<SectionHeaderProps> = ({
28
+ title,
29
+ description,
30
+ subtitle,
31
+ size = 'md',
32
+ className,
33
+ icon,
34
+ badge
35
+ }) => {
36
+ const titleSizes = {
37
+ sm: 'text-lg',
38
+ md: 'text-xl',
39
+ lg: 'text-2xl'
40
+ };
41
+
42
+ const spacingSizes = {
43
+ sm: 'space-y-1',
44
+ md: 'space-y-2',
45
+ lg: 'space-y-3'
46
+ };
47
+
48
+ return (
49
+ <div
50
+ className={cn(
51
+ 'text-center',
52
+ spacingSizes[size],
53
+ className
54
+ )}
55
+ data-component-name="SectionHeader"
56
+ >
57
+ <div className="flex items-center justify-center gap-3">
58
+ {icon}
59
+ <h3 className={cn('font-semibold text-foreground', titleSizes[size])}>
60
+ {title}
61
+ </h3>
62
+ {badge && (
63
+ <DataBadge
64
+ variant={badge.variant || 'status'}
65
+ status={badge.status}
66
+ category={badge.category}
67
+ size="sm"
68
+ >
69
+ {badge.text}
70
+ </DataBadge>
71
+ )}
72
+ </div>
73
+
74
+ {subtitle && (
75
+ <p className="text-muted-foreground text-sm font-medium">
76
+ {subtitle}
77
+ </p>
78
+ )}
79
+
80
+ {description && (
81
+ <p className="text-muted-foreground text-sm max-w-2xl mx-auto">
82
+ {description}
83
+ </p>
84
+ )}
85
+ </div>
86
+ );
87
+ };
@@ -0,0 +1 @@
1
+ export { SectionHeader, type SectionHeaderProps } from './SectionHeader';