xertica-ui 2.1.2 → 2.1.3

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 (402) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +1 -1
  3. package/assets/xertica-logo.svg +37 -37
  4. package/assets/xertica-x-logo.svg +20 -20
  5. package/bin/cli.ts +1 -1
  6. package/bin/generate-tokens.ts +13 -7
  7. package/components/assistant/index.ts +6 -6
  8. package/components/assistant/xertica-assistant/index.ts +2 -0
  9. package/components/assistant/xertica-assistant/use-assistant.ts +564 -0
  10. package/components/assistant/xertica-assistant/xertica-assistant.stories.tsx +200 -0
  11. package/components/assistant/xertica-assistant/xertica-assistant.tsx +183 -474
  12. package/components/blocks/card-patterns/ActivityCard.tsx +72 -72
  13. package/components/blocks/card-patterns/FeatureCard.tsx +100 -100
  14. package/components/blocks/card-patterns/NotificationCard.tsx +127 -127
  15. package/components/blocks/card-patterns/ProfileCard.tsx +84 -84
  16. package/components/blocks/card-patterns/ProjectCard.tsx +89 -89
  17. package/components/blocks/card-patterns/QuickActionCard.tsx +62 -62
  18. package/components/blocks/card-patterns/card-patterns.stories.tsx +445 -445
  19. package/components/blocks/card-patterns/index.ts +17 -17
  20. package/components/blocks/index.ts +1 -1
  21. package/components/brand/index.ts +6 -6
  22. package/components/brand/xertica-provider/XerticaProvider.tsx +48 -48
  23. package/components/brand/xertica-provider/xertica-provider.mdx +61 -61
  24. package/components/brand/xertica-provider/xertica-provider.test.tsx +52 -52
  25. package/components/examples/MapExamples.tsx +282 -282
  26. package/components/examples/SimpleFilterableMap.tsx +191 -191
  27. package/components/examples/index.ts +51 -51
  28. package/components/figma/ImageWithFallback.tsx +27 -27
  29. package/components/hooks/index.ts +7 -7
  30. package/components/index.ts +5 -5
  31. package/components/layout/header/header.test.tsx +8 -8
  32. package/components/layout/header/header.tsx +4 -4
  33. package/components/layout/index.ts +2 -2
  34. package/components/layout/sidebar/index.ts +2 -0
  35. package/components/layout/sidebar/sidebar.mdx +1 -1
  36. package/components/layout/sidebar/sidebar.stories.tsx +160 -8
  37. package/components/layout/sidebar/sidebar.test.tsx +11 -11
  38. package/components/layout/sidebar/sidebar.tsx +610 -471
  39. package/components/layout/sidebar/use-sidebar.ts +113 -0
  40. package/components/media/FloatingMediaWrapper.tsx +11 -11
  41. package/components/media/audio-player/AudioPlayer.tsx +22 -22
  42. package/components/media/index.ts +3 -3
  43. package/components/pages/home-content/HomeContent.tsx +7 -7
  44. package/components/pages/home-content/home-content.mdx +62 -62
  45. package/components/pages/home-page/HomePage.stories.tsx +39 -39
  46. package/components/pages/home-page/HomePage.tsx +1 -1
  47. package/components/pages/home-page/home-page.mdx +53 -53
  48. package/components/pages/index.ts +8 -8
  49. package/components/pages/template-content/TemplateContent.tsx +5 -5
  50. package/components/pages/template-content/template-content.mdx +61 -61
  51. package/components/pages/template-page/TemplatePage.stories.tsx +39 -39
  52. package/components/pages/template-page/TemplatePage.tsx +5 -5
  53. package/components/pages/template-page/template-page.mdx +53 -53
  54. package/components/public-api-smoke.test.tsx +52 -52
  55. package/components/shared/assistant-utils.ts +43 -43
  56. package/components/shared/layout-constants.ts +1 -1
  57. package/components/ui/accordion/accordion.mdx +8 -8
  58. package/components/ui/accordion/accordion.stories.tsx +53 -53
  59. package/components/ui/alert/alert.mdx +8 -8
  60. package/components/ui/alert-dialog/alert-dialog.mdx +8 -8
  61. package/components/ui/aspect-ratio/aspect-ratio.mdx +8 -8
  62. package/components/ui/assistant-chart/assistant-chart.mdx +8 -8
  63. package/components/ui/avatar/avatar.mdx +8 -8
  64. package/components/ui/badge/badge.mdx +8 -8
  65. package/components/ui/badge/badge.tsx +9 -9
  66. package/components/ui/breadcrumb/breadcrumb.mdx +8 -8
  67. package/components/ui/button/button.mdx +8 -8
  68. package/components/ui/calendar/calendar.mdx +8 -8
  69. package/components/ui/calendar/calendar.tsx +258 -258
  70. package/components/ui/card/card.mdx +8 -8
  71. package/components/ui/card/card.stories.tsx +245 -245
  72. package/components/ui/carousel/carousel.mdx +8 -8
  73. package/components/ui/chart/chart.mdx +8 -8
  74. package/components/ui/chart/chart.stories.tsx +1303 -344
  75. package/components/ui/chart/chart.test.tsx +154 -154
  76. package/components/ui/chart/chart.tsx +2367 -1494
  77. package/components/ui/checkbox/checkbox.mdx +8 -8
  78. package/components/ui/checkbox/checkbox.stories.tsx +20 -20
  79. package/components/ui/collapsible/collapsible.mdx +8 -8
  80. package/components/ui/command/command.mdx +8 -8
  81. package/components/ui/context-menu/context-menu.mdx +8 -8
  82. package/components/ui/dialog/dialog.mdx +8 -8
  83. package/components/ui/drawer/drawer.mdx +8 -8
  84. package/components/ui/dropdown-menu/dropdown-menu.mdx +8 -8
  85. package/components/ui/empty/empty.mdx +8 -8
  86. package/components/ui/file-upload/file-upload.mdx +8 -8
  87. package/components/ui/file-upload/file-upload.stories.tsx +100 -0
  88. package/components/ui/file-upload/file-upload.tsx +14 -74
  89. package/components/ui/file-upload/index.ts +1 -0
  90. package/components/ui/file-upload/use-file-upload.ts +181 -0
  91. package/components/ui/google-maps-loader/google-maps-loader.tsx +2 -2
  92. package/components/ui/hover-card/hover-card.mdx +8 -8
  93. package/components/ui/input/input.mdx +8 -8
  94. package/components/ui/input-otp/input-otp.mdx +8 -8
  95. package/components/ui/input-otp/input-otp.stories.tsx +6 -6
  96. package/components/ui/label/label.mdx +8 -8
  97. package/components/ui/map/map.mdx +8 -8
  98. package/components/ui/map/map.stories.tsx +51 -51
  99. package/components/ui/map/map.tsx +2 -2
  100. package/components/ui/menubar/menubar.mdx +8 -8
  101. package/components/ui/navigation-menu/navigation-menu.mdx +8 -8
  102. package/components/ui/notification-badge/notification-badge.mdx +8 -8
  103. package/components/ui/pagination/index.ts +2 -0
  104. package/components/ui/pagination/pagination.mdx +8 -8
  105. package/components/ui/pagination/pagination.stories.tsx +94 -0
  106. package/components/ui/pagination/use-pagination.ts +194 -0
  107. package/components/ui/popover/popover.mdx +8 -8
  108. package/components/ui/progress/progress.mdx +8 -8
  109. package/components/ui/progress/progress.tsx +68 -68
  110. package/components/ui/radio-group/radio-group.mdx +8 -8
  111. package/components/ui/rating/rating.mdx +8 -8
  112. package/components/ui/resizable/resizable.mdx +8 -8
  113. package/components/ui/rich-text-editor/index.ts +2 -0
  114. package/components/ui/rich-text-editor/rich-text-editor.stories.tsx +129 -1
  115. package/components/ui/rich-text-editor/rich-text-editor.tsx +86 -305
  116. package/components/ui/rich-text-editor/use-rich-text-editor.ts +439 -0
  117. package/components/ui/route-map/route-map.mdx +8 -8
  118. package/components/ui/route-map/route-map.stories.tsx +54 -54
  119. package/components/ui/route-map/route-map.tsx +2 -2
  120. package/components/ui/scroll-area/scroll-area.mdx +8 -8
  121. package/components/ui/search/search.mdx +8 -8
  122. package/components/ui/select/select.mdx +8 -8
  123. package/components/ui/select/select.stories.tsx +9 -9
  124. package/components/ui/separator/separator.mdx +8 -8
  125. package/components/ui/sheet/sheet.mdx +8 -8
  126. package/components/ui/sheet/sheet.stories.tsx +95 -95
  127. package/components/ui/simple-map/simple-map.mdx +8 -8
  128. package/components/ui/simple-map/simple-map.stories.tsx +48 -48
  129. package/components/ui/skeleton/skeleton.mdx +8 -8
  130. package/components/ui/slider/slider.mdx +8 -8
  131. package/components/ui/sonner/sonner.mdx +8 -8
  132. package/components/ui/stats-card/stats-card.mdx +8 -8
  133. package/components/ui/stepper/index.ts +3 -1
  134. package/components/ui/stepper/stepper.mdx +8 -8
  135. package/components/ui/stepper/stepper.stories.tsx +116 -0
  136. package/components/ui/stepper/stepper.tsx +4 -4
  137. package/components/ui/stepper/use-stepper.ts +137 -0
  138. package/components/ui/switch/switch.mdx +8 -8
  139. package/components/ui/switch/switch.stories.tsx +20 -20
  140. package/components/ui/table/table.mdx +8 -8
  141. package/components/ui/tabs/tabs.mdx +8 -8
  142. package/components/ui/tabs/tabs.stories.tsx +26 -26
  143. package/components/ui/textarea/textarea.mdx +8 -8
  144. package/components/ui/timeline/timeline.mdx +8 -8
  145. package/components/ui/toggle/toggle.mdx +8 -8
  146. package/components/ui/toggle-group/toggle-group.mdx +8 -8
  147. package/components/ui/tooltip/tooltip.mdx +8 -8
  148. package/components/ui/tree-view/index.ts +4 -1
  149. package/components/ui/tree-view/tree-view.mdx +8 -8
  150. package/components/ui/tree-view/tree-view.stories.tsx +110 -4
  151. package/components/ui/tree-view/tree-view.tsx +17 -125
  152. package/components/ui/tree-view/use-tree-view.ts +229 -0
  153. package/components.json +1512 -1512
  154. package/contexts/ApiKeyContext.tsx +72 -72
  155. package/contexts/BrandColorsContext.tsx +26 -26
  156. package/contexts/LanguageContext.tsx +13 -13
  157. package/contexts/LayoutContext.test.tsx +11 -11
  158. package/contexts/LayoutContext.tsx +29 -29
  159. package/contexts/ThemeContext.tsx +26 -26
  160. package/contexts/theme-data.ts +4 -4
  161. package/dist/{AssistantChart-CVzmmhx4.js → AssistantChart-C_hwFRRr.js} +4 -4
  162. package/dist/{AssistantChart-BAx9VQvb.cjs → AssistantChart-CldVCVDe.cjs} +311 -94
  163. package/dist/{AssistantChart-CVko2A1W.js → AssistantChart-Cu3m7RBo.js} +314 -97
  164. package/dist/{AssistantChart-9w31gdAb.cjs → AssistantChart-DoZCyS5r.cjs} +4 -4
  165. package/dist/AudioPlayer-B1lt5cPl.cjs +989 -0
  166. package/dist/AudioPlayer-BZ7bibzU.cjs +982 -0
  167. package/dist/AudioPlayer-C12BjQBV.cjs +997 -0
  168. package/dist/AudioPlayer-DMcG_c7L.js +990 -0
  169. package/dist/AudioPlayer-DcFKRJE_.js +998 -0
  170. package/dist/AudioPlayer-e8LfNoqO.js +983 -0
  171. package/dist/{xertica-assistant-Qp3ydksa.cjs → CodeBlock-7TTgmdGG.cjs} +263 -51
  172. package/dist/{xertica-assistant-gnCJdcZY.js → CodeBlock-BeSt1h5P.js} +219 -7
  173. package/dist/CodeBlock-BgfYL_rD.cjs +2094 -0
  174. package/dist/CodeBlock-BlcqlA9M.cjs +2094 -0
  175. package/dist/CodeBlock-Bnmeu5ez.cjs +2094 -0
  176. package/dist/CodeBlock-BtfPlbAI.js +2078 -0
  177. package/dist/CodeBlock-CIySIuYr.js +2078 -0
  178. package/dist/CodeBlock-CuPtUM-7.cjs +2094 -0
  179. package/dist/CodeBlock-D6ffWXgc.js +2078 -0
  180. package/dist/CodeBlock-D8dcwbit.cjs +2094 -0
  181. package/dist/CodeBlock-DMZrFnlw.cjs +2094 -0
  182. package/dist/CodeBlock-DlBehYN8.js +2078 -0
  183. package/dist/CodeBlock-DnYNI8rQ.js +2078 -0
  184. package/dist/CodeBlock-DvKWbSnE.cjs +2094 -0
  185. package/dist/CodeBlock-DwMCfkFY.js +2078 -0
  186. package/dist/CodeBlock-Dy6CNYyj.js +2078 -0
  187. package/dist/CodeBlock-U1pPOQI7.cjs +2094 -0
  188. package/dist/CodeBlock-f_GpNhEB.js +2078 -0
  189. package/dist/CodeBlock-oB6u8nI1.js +2078 -0
  190. package/dist/CodeBlock-tZC31B73.cjs +2094 -0
  191. package/dist/ImageWithFallback-CGtidP6B.cjs +4542 -0
  192. package/dist/ImageWithFallback-lsg3pdFg.js +4508 -0
  193. package/dist/LanguageSelector-B5YfbHra.js +231 -0
  194. package/dist/LanguageSelector-D6uacAIM.cjs +230 -0
  195. package/dist/LayoutContext-BAql6ZRY.js +97 -0
  196. package/dist/LayoutContext-BvK-ggDa.cjs +96 -0
  197. package/dist/ThemeContext-BoH4NLfN.js +734 -0
  198. package/dist/{ThemeContext-BbBNoFTG.js → ThemeContext-C2EwAPDt.js} +2 -2
  199. package/dist/ThemeContext-r69W20Xg.cjs +733 -0
  200. package/dist/{ThemeContext-Cmr8Ex8H.cjs → ThemeContext-vTjumZeM.cjs} +2 -2
  201. package/dist/{VerifyEmailPage-BE-L9mB7.js → VerifyEmailPage-C0c2e5n0.js} +7 -7
  202. package/dist/{VerifyEmailPage-DMBh4NM9.cjs → VerifyEmailPage-CYXtbKi3.cjs} +1 -1
  203. package/dist/{VerifyEmailPage-CR7kb5df.cjs → VerifyEmailPage-Cwi3kbol.cjs} +7 -7
  204. package/dist/{VerifyEmailPage-CdYPSJoO.js → VerifyEmailPage-DvMLZgFt.js} +1 -1
  205. package/dist/XerticaOrbe-KL1RBHzw.cjs +1354 -0
  206. package/dist/XerticaOrbe-zwS1p2a8.js +1355 -0
  207. package/dist/XerticaProvider-6btlAlzc.js +17 -0
  208. package/dist/XerticaProvider-BNoNOxQ5.cjs +16 -0
  209. package/dist/XerticaProvider-BlY2limY.cjs +38 -0
  210. package/dist/{XerticaProvider-BITjgC5p.js → XerticaProvider-CEoWMTxu.js} +2 -2
  211. package/dist/{XerticaProvider-By8q3Roe.cjs → XerticaProvider-CllrbMEJ.cjs} +2 -2
  212. package/dist/XerticaProvider-DDuiIcKo.js +39 -0
  213. package/dist/XerticaProvider-cI9hSs27.cjs +38 -0
  214. package/dist/XerticaProvider-hSwhNQex.js +39 -0
  215. package/dist/{alert-dialog-yckpaOpy.cjs → alert-dialog-DSKByiKZ.cjs} +3 -3
  216. package/dist/{alert-dialog-iDe5VE5o.js → alert-dialog-s-vmNkJ_.js} +3 -3
  217. package/dist/assistant.cjs.js +2 -1
  218. package/dist/assistant.es.js +3 -2
  219. package/dist/brand.cjs.js +1 -1
  220. package/dist/brand.es.js +1 -1
  221. package/dist/breadcrumb-CqJ7bHY5.js +161 -0
  222. package/dist/breadcrumb-m9Hb2_XN.cjs +177 -0
  223. package/dist/cli.js +14 -8
  224. package/dist/components/assistant/xertica-assistant/index.d.ts +2 -0
  225. package/dist/components/assistant/xertica-assistant/use-assistant.d.ts +126 -0
  226. package/dist/components/assistant/xertica-assistant/xertica-assistant.d.ts +7 -2
  227. package/dist/components/blocks/audio-player/AudioPlayer.d.ts +35 -0
  228. package/dist/components/blocks/audio-player/index.d.ts +1 -0
  229. package/dist/components/blocks/document-editor/DocumentEditor.d.ts +26 -0
  230. package/dist/components/blocks/document-editor/index.d.ts +1 -0
  231. package/dist/components/blocks/podcast-player/PodcastPlayer.d.ts +41 -0
  232. package/dist/components/blocks/podcast-player/index.d.ts +1 -0
  233. package/dist/components/layout/sidebar/index.d.ts +2 -0
  234. package/dist/components/layout/sidebar/sidebar.d.ts +80 -0
  235. package/dist/components/layout/sidebar/use-sidebar.d.ts +22 -0
  236. package/dist/components/shared/layout-constants.d.ts +1 -1
  237. package/dist/components/ui/button/button.d.ts +1 -1
  238. package/dist/components/ui/chart/chart.d.ts +162 -5
  239. package/dist/components/ui/file-upload/file-upload.d.ts +2 -0
  240. package/dist/components/ui/file-upload/index.d.ts +1 -0
  241. package/dist/components/ui/file-upload/use-file-upload.d.ts +49 -0
  242. package/dist/components/ui/pagination/index.d.ts +2 -0
  243. package/dist/components/ui/pagination/use-pagination.d.ts +78 -0
  244. package/dist/components/ui/rich-text-editor/index.d.ts +2 -0
  245. package/dist/components/ui/rich-text-editor/use-rich-text-editor.d.ts +107 -0
  246. package/dist/components/ui/stepper/index.d.ts +3 -1
  247. package/dist/components/ui/stepper/stepper.d.ts +2 -2
  248. package/dist/components/ui/stepper/use-stepper.d.ts +60 -0
  249. package/dist/components/ui/tree-view/index.d.ts +4 -1
  250. package/dist/components/ui/tree-view/tree-view.d.ts +4 -6
  251. package/dist/components/ui/tree-view/use-tree-view.d.ts +60 -0
  252. package/dist/dropdown-menu-BDB5CmQs.cjs +247 -0
  253. package/dist/dropdown-menu-DQidbKBD.js +231 -0
  254. package/dist/google-maps-loader-BFWp6VPd.js +287 -0
  255. package/dist/{google-maps-loader-t2IlYBzw.js → google-maps-loader-CTYySAun.js} +4 -0
  256. package/dist/{google-maps-loader-BqsYL48U.cjs → google-maps-loader-Y-QkD-Li.cjs} +5 -0
  257. package/dist/google-maps-loader-eS3uQ5TA.cjs +287 -0
  258. package/dist/header-Cgy6vYPk.cjs +731 -0
  259. package/dist/header-DRlT4jgI.js +715 -0
  260. package/dist/header-Dux00SI4.cjs +731 -0
  261. package/dist/header-EkGKXPsD.js +715 -0
  262. package/dist/header-WfEywpyc.cjs +731 -0
  263. package/dist/header-tifNQn2U.js +715 -0
  264. package/dist/hooks.cjs.js +1 -1
  265. package/dist/hooks.es.js +1 -1
  266. package/dist/index-BhapVLVj.js +8 -0
  267. package/dist/{index-D3RLKRAs.cjs → index-COtD8bRW.cjs} +1 -1
  268. package/dist/index-D6fxYEY8.cjs +7 -0
  269. package/dist/index-DW5tYe26.js +8 -0
  270. package/dist/index.cjs.js +19 -8
  271. package/dist/index.es.js +39 -28
  272. package/dist/index.umd.js +1043 -470
  273. package/dist/input-2R4loU86.js +127 -0
  274. package/dist/input-DWANSKGb.cjs +145 -0
  275. package/dist/layout.cjs.js +89 -1
  276. package/dist/layout.es.js +90 -2
  277. package/dist/pages.cjs.js +1 -1
  278. package/dist/pages.es.js +1 -1
  279. package/dist/rich-text-editor-0mraWT5y.cjs +2376 -0
  280. package/dist/rich-text-editor-B6jMRLzk.cjs +1939 -0
  281. package/dist/rich-text-editor-B8_oYcIR.js +1730 -0
  282. package/dist/rich-text-editor-B9UbSXNb.js +1203 -0
  283. package/dist/rich-text-editor-BYuRBNBU.js +2373 -0
  284. package/dist/rich-text-editor-Bb9pySTs.cjs +2374 -0
  285. package/dist/rich-text-editor-BcL6L3cm.cjs +2374 -0
  286. package/dist/rich-text-editor-BoVZYtTs.cjs +2391 -0
  287. package/dist/rich-text-editor-CPV1lEPH.cjs +1748 -0
  288. package/dist/rich-text-editor-CoKqbCtu.cjs +1799 -0
  289. package/dist/rich-text-editor-Cw56T_mB.js +2356 -0
  290. package/dist/rich-text-editor-Cyt8qs2b.js +1921 -0
  291. package/dist/rich-text-editor-D6H84OcX.cjs +1220 -0
  292. package/dist/rich-text-editor-D76gD-QI.js +2328 -0
  293. package/dist/rich-text-editor-DKkokOnA.js +1781 -0
  294. package/dist/rich-text-editor-DNsdpN64.cjs +2359 -0
  295. package/dist/rich-text-editor-DfG8bCyY.js +2358 -0
  296. package/dist/rich-text-editor-DgF8s7xW.js +2949 -0
  297. package/dist/rich-text-editor-Dxjw31Z4.js +2341 -0
  298. package/dist/rich-text-editor-DzP0Epmb.js +2356 -0
  299. package/dist/rich-text-editor-mWoaSCE4.cjs +2966 -0
  300. package/dist/rich-text-editor-skplNlBM.cjs +2345 -0
  301. package/dist/select-Bkbr0f-Z.cjs +162 -0
  302. package/dist/select-CvIVdX2n.js +145 -0
  303. package/dist/sidebar-CK_0ZQHj.cjs +803 -0
  304. package/dist/sidebar-CUuOvYhK.js +787 -0
  305. package/dist/slider-Bc5Hd0y1.js +56 -0
  306. package/dist/slider-N7hFFj6X.cjs +73 -0
  307. package/dist/tooltip-Ded96neP.cjs +137 -0
  308. package/dist/tooltip-HDOoD2-0.js +120 -0
  309. package/dist/ui.cjs.js +14 -4
  310. package/dist/ui.es.js +26 -16
  311. package/dist/use-mobile-B0hNy_Y6.cjs +4303 -0
  312. package/dist/use-mobile-BXuYROXM.js +4202 -0
  313. package/dist/use-mobile-Bbd51ASU.cjs +4392 -0
  314. package/dist/use-mobile-Bk6CX-TC.js +4359 -0
  315. package/dist/use-mobile-BvYdisLP.js +4202 -0
  316. package/dist/use-mobile-BzuxjzNX.cjs +4392 -0
  317. package/dist/use-mobile-CG2-SdXV.cjs +4235 -0
  318. package/dist/use-mobile-CKb5pqTs.js +4269 -0
  319. package/dist/use-mobile-CYuAuGDl.js +4202 -0
  320. package/dist/use-mobile-CaENcqm-.js +4508 -0
  321. package/dist/use-mobile-CbrYgJGJ.js +4203 -0
  322. package/dist/use-mobile-DMOvImGQ.cjs +4542 -0
  323. package/dist/use-mobile-DRB3BQgD.cjs +4235 -0
  324. package/dist/use-mobile-DZvv7QMR.js +4359 -0
  325. package/dist/use-mobile-DdI_TXam.cjs +4235 -0
  326. package/dist/use-mobile-DlceKf8a.js +4359 -0
  327. package/dist/use-mobile-DsOnow1o.cjs +4236 -0
  328. package/dist/use-mobile-Kcj6jSnK.cjs +4392 -0
  329. package/dist/use-mobile-bnKcua_i.js +4202 -0
  330. package/dist/use-mobile-ncXBeE2z.cjs +4235 -0
  331. package/dist/{xertica-assistant-B1IaHXnB.cjs → xertica-assistant-dyP7KHM5.cjs} +533 -392
  332. package/dist/{xertica-assistant-DPsESB6t.js → xertica-assistant-yX1CFBBo.js} +535 -394
  333. package/dist/xertica-ui.css +2 -2
  334. package/docs/ai-usage.md +28 -10
  335. package/docs/architecture.md +76 -0
  336. package/docs/components/assistant.md +159 -0
  337. package/docs/components/calendar.md +154 -154
  338. package/docs/components/card-patterns.md +337 -337
  339. package/docs/components/card.md +235 -235
  340. package/docs/components/chart.md +354 -39
  341. package/docs/components/file-upload.md +119 -2
  342. package/docs/components/map.md +84 -84
  343. package/docs/components/pagination.md +187 -0
  344. package/docs/components/rich-text-editor.md +164 -0
  345. package/docs/components/sidebar.md +153 -4
  346. package/docs/components/stepper.md +157 -12
  347. package/docs/components/tree-view.md +164 -6
  348. package/docs/components/xertica-provider.md +24 -24
  349. package/docs/decision-tree.md +287 -287
  350. package/docs/getting-started.md +1 -1
  351. package/docs/guidelines.md +14 -8
  352. package/docs/layout.md +2 -2
  353. package/docs/llms.md +4 -4
  354. package/guidelines/Guidelines.md +252 -250
  355. package/hooks/useTheme.ts +3 -3
  356. package/imports/Podcast.tsx +388 -388
  357. package/imports/XerticaAi.tsx +45 -45
  358. package/imports/XerticaX.tsx +19 -19
  359. package/imports/svg-aueiaqngck.ts +11 -11
  360. package/imports/svg-v9krss1ozd.ts +16 -16
  361. package/imports/svg-vhrdofe3qe.ts +5 -5
  362. package/llms-compact.txt +327 -327
  363. package/llms.txt +160 -160
  364. package/package.json +203 -203
  365. package/styles/xertica/app-overrides/chat.css +61 -61
  366. package/styles/xertica/app-overrides/scrollbar.css +33 -33
  367. package/styles/xertica/integrations/google-maps.css +76 -76
  368. package/styles/xertica/integrations/sonner.css +73 -73
  369. package/styles/xertica/tokens.css +41 -12
  370. package/templates/CLAUDE.md +182 -172
  371. package/templates/guidelines/Guidelines.md +325 -313
  372. package/templates/package.json +3 -3
  373. package/templates/src/features/auth/index.ts +4 -4
  374. package/templates/src/features/auth/ui/AuthPageShell.tsx +34 -34
  375. package/templates/src/features/auth/ui/ForgotPasswordContent.tsx +70 -70
  376. package/templates/src/features/auth/ui/LoginContent.tsx +90 -90
  377. package/templates/src/features/auth/ui/ResetPasswordContent.tsx +151 -151
  378. package/templates/src/features/auth/ui/SocialLoginButtons.tsx +59 -59
  379. package/templates/src/features/auth/ui/VerifyEmailContent.tsx +82 -82
  380. package/templates/src/features/home/index.ts +1 -1
  381. package/templates/src/features/home/ui/HomeContent.tsx +100 -100
  382. package/templates/src/features/template/index.ts +5 -5
  383. package/templates/src/features/template/ui/CrudTemplate.tsx +3 -3
  384. package/templates/src/features/template/ui/DashboardTemplate.tsx +3 -3
  385. package/templates/src/features/template/ui/FormTemplate.tsx +120 -120
  386. package/templates/src/features/template/ui/LoginTemplate.tsx +3 -3
  387. package/templates/src/pages/AssistantPage.tsx +328 -328
  388. package/templates/src/pages/ForgotPasswordPage.tsx +6 -6
  389. package/templates/src/pages/HomePage.tsx +57 -57
  390. package/templates/src/pages/LoginPage.tsx +10 -10
  391. package/templates/src/pages/ResetPasswordPage.tsx +6 -6
  392. package/templates/src/pages/TemplatePage.tsx +30 -30
  393. package/templates/src/pages/VerifyEmailPage.tsx +6 -6
  394. package/templates/src/shared/config/navigation.ts +20 -20
  395. package/templates/src/shared/lib/auth.ts +20 -20
  396. package/templates/src/shared/types/auth.ts +3 -3
  397. package/templates/src/styles/xertica/tokens.css +39 -10
  398. package/templates/tsconfig.json +5 -5
  399. package/utils/gemini.ts +140 -140
  400. package/dist/VerifyEmailPage-Bae2cBXT.cjs +0 -2827
  401. package/dist/VerifyEmailPage-CbgjOF0v.js +0 -2828
  402. package/dist/index-CkTUgOwX.js +0 -8
@@ -1,344 +1,1303 @@
1
- import type { Meta, StoryObj } from '@storybook/react';
2
- import {
3
- ChartContainer,
4
- ChartTooltip,
5
- ChartTooltipContent,
6
- ChartLegend,
7
- ChartLegendContent,
8
- ChartCard,
9
- DashboardBarChart,
10
- DashboardLineChart,
11
- HorizontalBarChart,
12
- InteractiveTimeSeriesChart,
13
- ComboMetricChart,
14
- DonutBreakdownChart,
15
- type ChartConfig,
16
- } from './chart';
17
- import {
18
- BarChart,
19
- Bar,
20
- XAxis,
21
- YAxis,
22
- CartesianGrid,
23
- LineChart,
24
- Line,
25
- } from 'recharts';
26
- import { Card, CardHeader, CardTitle, CardContent } from '../card';
27
- import React from 'react';
28
-
29
- const meta: Meta<typeof DashboardBarChart> = {
30
- title: 'UI/Chart',
31
- component: DashboardBarChart,
32
- render: (args) => <DashboardBarChart {...args} />,
33
- parameters: {
34
- layout: 'fullscreen',
35
- },
36
- decorators: [
37
- (Story) => (
38
- <div className="w-full min-w-0 p-8">
39
- <Story />
40
- </div>
41
- ),
42
- ],
43
- argTypes: {
44
- barSize: {
45
- control: 'select',
46
- options: ['sm', 'md', 'lg', 'xl'],
47
- description: 'Controls only the bar thickness.',
48
- },
49
- stacked: { control: 'boolean' },
50
- showGrid: { control: 'boolean' },
51
- showLegend: { control: 'boolean' },
52
- },
53
- };
54
-
55
- export default meta;
56
- type Story = StoryObj<typeof DashboardBarChart>;
57
-
58
- const data = [
59
- { month: 'Jan', revenue: 4000, expenses: 2400 },
60
- { month: 'Feb', revenue: 3000, expenses: 1398 },
61
- { month: 'Mar', revenue: 6000, expenses: 3200 },
62
- { month: 'Apr', revenue: 2780, expenses: 3908 },
63
- { month: 'May', revenue: 1890, expenses: 4800 },
64
- { month: 'Jun', revenue: 2390, expenses: 3800 },
65
- ];
66
-
67
- const chartConfig: ChartConfig = {
68
- revenue: { label: 'Revenue', color: 'var(--chart-1)' },
69
- expenses: { label: 'Expenses', color: 'var(--chart-5)' },
70
- };
71
-
72
- const richChartConfig: ChartConfig = {
73
- revenue: { label: 'Revenue', color: 'var(--chart-1)' },
74
- pipeline: { label: 'Pipeline', color: 'var(--chart-4)' },
75
- conversion: { label: 'Conversion', color: 'var(--chart-2)' },
76
- churn: { label: 'Churn', color: 'var(--chart-3)' },
77
- };
78
-
79
- const richData = [
80
- { date: 'Apr 01', revenue: 4200, pipeline: 2600, conversion: 32, churn: 8 },
81
- { date: 'Apr 08', revenue: 5200, pipeline: 3200, conversion: 38, churn: 7 },
82
- { date: 'Apr 15', revenue: 6100, pipeline: 3900, conversion: 42, churn: 6 },
83
- { date: 'Apr 22', revenue: 5600, pipeline: 4300, conversion: 41, churn: 9 },
84
- { date: 'Apr 29', revenue: 7200, pipeline: 4700, conversion: 48, churn: 5 },
85
- { date: 'May 06', revenue: 7900, pipeline: 5300, conversion: 52, churn: 4 },
86
- ];
87
-
88
- const breakdownConfig: ChartConfig = {
89
- enterprise: { label: 'Enterprise', color: 'var(--chart-1)' },
90
- midmarket: { label: 'Mid-market', color: 'var(--chart-4)' },
91
- startup: { label: 'Startup', color: 'var(--chart-2)' },
92
- };
93
-
94
- const breakdownData = [
95
- { name: 'enterprise', value: 52 },
96
- { name: 'midmarket', value: 31 },
97
- { name: 'startup', value: 17 },
98
- ];
99
-
100
- export const BarChartExample: Story = {
101
- render: () => (
102
- <Card className="w-full max-w-4xl">
103
- <CardHeader>
104
- <CardTitle>Monthly Performance</CardTitle>
105
- </CardHeader>
106
- <CardContent>
107
- <ChartContainer config={chartConfig} className="h-[300px] w-full">
108
- <BarChart data={data}>
109
- <CartesianGrid vertical={false} strokeDasharray="3 3" />
110
- <XAxis dataKey="month" tickLine={false} axisLine={false} />
111
- <ChartTooltip content={<ChartTooltipContent />} />
112
- <ChartLegend content={<ChartLegendContent />} />
113
- <Bar dataKey="revenue" fill="var(--color-revenue)" radius={[4, 4, 0, 0]} />
114
- <Bar dataKey="expenses" fill="var(--color-expenses)" radius={[4, 4, 0, 0]} />
115
- </BarChart>
116
- </ChartContainer>
117
- </CardContent>
118
- </Card>
119
- ),
120
- };
121
-
122
- export const LineChartExample: Story = {
123
- render: () => (
124
- <Card className="w-full max-w-4xl">
125
- <CardHeader>
126
- <CardTitle>Revenue Trends</CardTitle>
127
- </CardHeader>
128
- <CardContent>
129
- <ChartContainer config={chartConfig} className="h-[300px] w-full">
130
- <LineChart data={data}>
131
- <CartesianGrid vertical={false} />
132
- <XAxis dataKey="month" tickLine={false} axisLine={false} />
133
- <ChartTooltip content={<ChartTooltipContent />} />
134
- <Line
135
- type="monotone"
136
- dataKey="revenue"
137
- stroke="var(--color-revenue)"
138
- strokeWidth={3}
139
- dot={{ r: 4, fill: "var(--color-revenue)" }}
140
- activeDot={{ r: 6 }}
141
- />
142
- </LineChart>
143
- </ChartContainer>
144
- </CardContent>
145
- </Card>
146
- ),
147
- };
148
-
149
- export const DashboardBarChartExample: Story = {
150
- args: {
151
- data: richData,
152
- indexKey: 'date',
153
- config: richChartConfig,
154
- colors: {
155
- revenue: 'var(--chart-1)',
156
- pipeline: 'var(--chart-4)',
157
- },
158
- barSize: 'lg',
159
- series: [
160
- { key: 'revenue', stackId: 'money' },
161
- { key: 'pipeline', stackId: 'money' },
162
- ],
163
- stacked: true,
164
- },
165
- render: (args) => (
166
- <ChartCard
167
- title="Revenue by Week"
168
- description="Stacked dashboard-ready comparison"
169
- >
170
- <DashboardBarChart {...args} />
171
- </ChartCard>
172
- ),
173
- };
174
-
175
- export const DashboardLineChartExample: Story = {
176
- render: () => (
177
- <ChartCard
178
- title="Growth Trend"
179
- description="Multi-series line chart with color markers"
180
- >
181
- <DashboardLineChart
182
- data={richData}
183
- indexKey="date"
184
- config={richChartConfig}
185
- colors={{
186
- revenue: 'var(--chart-1)',
187
- pipeline: 'var(--chart-4)',
188
- conversion: 'var(--chart-2)',
189
- }}
190
- series={[
191
- { key: 'revenue', label: 'Revenue' },
192
- { key: 'pipeline', label: 'Pipeline' },
193
- { key: 'conversion', label: 'Conversion' },
194
- ]}
195
- />
196
- </ChartCard>
197
- ),
198
- };
199
-
200
- export const HorizontalBarChartExample: Story = {
201
- render: () => (
202
- <ChartCard
203
- title="Top Segments"
204
- description="Ranking chart for dashboard comparisons"
205
- >
206
- <HorizontalBarChart
207
- data={[
208
- { segment: 'Enterprise', revenue: 7600 },
209
- { segment: 'Mid-market', revenue: 5400 },
210
- { segment: 'Startup', revenue: 3100 },
211
- { segment: 'Partners', revenue: 2200 },
212
- ]}
213
- indexKey="segment"
214
- config={{ revenue: { label: 'Revenue', color: 'var(--chart-1)' } }}
215
- colors={{ revenue: 'var(--chart-1)' }}
216
- barSize="xl"
217
- categoryWidth={110}
218
- showLegend={false}
219
- />
220
- </ChartCard>
221
- ),
222
- };
223
-
224
- export const InteractiveTimeSeriesExample: Story = {
225
- render: () => (
226
- <ChartCard
227
- title="Executive Trend"
228
- description="Switch metric and period without leaving the card"
229
- >
230
- <InteractiveTimeSeriesChart
231
- data={richData}
232
- indexKey="date"
233
- config={richChartConfig}
234
- colors={['var(--chart-1)', 'var(--chart-4)', 'var(--chart-2)']}
235
- series={[
236
- { key: 'revenue', label: 'Revenue' },
237
- { key: 'pipeline', label: 'Pipeline' },
238
- { key: 'conversion', label: 'Conversion' },
239
- ]}
240
- />
241
- </ChartCard>
242
- ),
243
- };
244
-
245
- export const ComboMetricChartExample: Story = {
246
- render: () => (
247
- <ChartCard
248
- title="Pipeline Health"
249
- description="Bars for volume with a line for rate"
250
- >
251
- <ComboMetricChart
252
- data={richData}
253
- indexKey="date"
254
- config={richChartConfig}
255
- colors={{
256
- pipeline: 'var(--chart-4)',
257
- conversion: 'var(--chart-2)',
258
- }}
259
- barSize="lg"
260
- series={[
261
- { key: 'pipeline', type: 'bar' },
262
- { key: 'conversion', type: 'line' },
263
- ]}
264
- />
265
- </ChartCard>
266
- ),
267
- };
268
-
269
- export const DonutBreakdownExample: Story = {
270
- render: () => (
271
- <ChartCard
272
- title="Customer Mix"
273
- description="Interactive segment breakdown"
274
- >
275
- <DonutBreakdownChart
276
- data={breakdownData}
277
- config={breakdownConfig}
278
- colors={['var(--chart-1)', 'var(--chart-4)', 'var(--chart-2)']}
279
- centerValue="100%"
280
- centerLabel="Accounts"
281
- />
282
- </ChartCard>
283
- ),
284
- };
285
-
286
- export const EmptyStateExample: Story = {
287
- render: () => (
288
- <ChartCard
289
- title="Revenue by Week"
290
- description="The empty state is rendered by the chart wrapper"
291
- >
292
- <DashboardBarChart
293
- data={[]}
294
- indexKey="date"
295
- config={richChartConfig}
296
- emptyDescription="No revenue events were found for the selected period."
297
- />
298
- </ChartCard>
299
- ),
300
- };
301
-
302
- export const ConnectionErrorExample: Story = {
303
- render: () => (
304
- <ChartCard
305
- title="Pipeline Health"
306
- description="Connection errors stay inside the chart panel"
307
- >
308
- <ComboMetricChart
309
- data={richData}
310
- indexKey="date"
311
- config={richChartConfig}
312
- error="Unable to connect to the analytics service."
313
- onRetry={() => undefined}
314
- />
315
- </ChartCard>
316
- ),
317
- };
318
-
319
- export const BarSizeVariantsExample: Story = {
320
- render: () => (
321
- <div className="space-y-6">
322
- <ChartCard title="Thin Bars" description="barSize=&quot;sm&quot;">
323
- <DashboardBarChart
324
- data={richData}
325
- indexKey="date"
326
- config={richChartConfig}
327
- series={[{ key: 'revenue' }]}
328
- barSize="sm"
329
- showLegend={false}
330
- />
331
- </ChartCard>
332
- <ChartCard title="Wide Bars" description="barSize=&quot;xl&quot;">
333
- <DashboardBarChart
334
- data={richData}
335
- indexKey="date"
336
- config={richChartConfig}
337
- series={[{ key: 'revenue' }]}
338
- barSize="xl"
339
- showLegend={false}
340
- />
341
- </ChartCard>
342
- </div>
343
- ),
344
- };
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import {
3
+ ChartContainer,
4
+ ChartTooltip,
5
+ ChartTooltipContent,
6
+ ChartLegend,
7
+ ChartLegendContent,
8
+ ChartCard,
9
+ DashboardBarChart,
10
+ DashboardLineChart,
11
+ HorizontalBarChart,
12
+ InteractiveTimeSeriesChart,
13
+ ComboMetricChart,
14
+ DonutBreakdownChart,
15
+ SparklineChart,
16
+ RadarMetricChart,
17
+ PieMetricChart,
18
+ RadialBarMetricChart,
19
+ GaugeChart,
20
+ type ChartConfig,
21
+ type GaugeChartThreshold,
22
+ } from './chart';
23
+ import {
24
+ BarChart,
25
+ Bar,
26
+ XAxis,
27
+ YAxis,
28
+ CartesianGrid,
29
+ LineChart,
30
+ Line,
31
+ } from 'recharts';
32
+ import { Card, CardHeader, CardTitle, CardContent } from '../card';
33
+ import React from 'react';
34
+ import { TrendingUp, TrendingDown, Minus } from 'lucide-react';
35
+
36
+ const meta: Meta<typeof DashboardBarChart> = {
37
+ title: 'UI/Chart',
38
+ component: DashboardBarChart,
39
+ render: (args) => <DashboardBarChart {...args} />,
40
+ parameters: {
41
+ layout: 'fullscreen',
42
+ },
43
+ decorators: [
44
+ (Story) => (
45
+ <div className="w-full min-w-0 p-8">
46
+ <Story />
47
+ </div>
48
+ ),
49
+ ],
50
+ argTypes: {
51
+ barSize: {
52
+ control: 'select',
53
+ options: ['sm', 'md', 'lg', 'xl'],
54
+ description: 'Controls only the bar thickness.',
55
+ },
56
+ stacked: { control: 'boolean' },
57
+ showGrid: { control: 'boolean' },
58
+ showLegend: { control: 'boolean' },
59
+ },
60
+ };
61
+
62
+ export default meta;
63
+ type Story = StoryObj<typeof DashboardBarChart>;
64
+
65
+ // ─── Shared data ──────────────────────────────────────────────────────────────
66
+
67
+ const data = [
68
+ { month: 'Jan', revenue: 4000, expenses: 2400 },
69
+ { month: 'Feb', revenue: 3000, expenses: 1398 },
70
+ { month: 'Mar', revenue: 6000, expenses: 3200 },
71
+ { month: 'Apr', revenue: 2780, expenses: 3908 },
72
+ { month: 'May', revenue: 1890, expenses: 4800 },
73
+ { month: 'Jun', revenue: 2390, expenses: 3800 },
74
+ ];
75
+
76
+ const chartConfig: ChartConfig = {
77
+ revenue: { label: 'Revenue', color: 'var(--chart-1)' },
78
+ expenses: { label: 'Expenses', color: 'var(--chart-5)' },
79
+ };
80
+
81
+ const richChartConfig: ChartConfig = {
82
+ revenue: { label: 'Revenue', color: 'var(--chart-1)' },
83
+ pipeline: { label: 'Pipeline', color: 'var(--chart-4)' },
84
+ conversion: { label: 'Conversion', color: 'var(--chart-2)' },
85
+ churn: { label: 'Churn', color: 'var(--chart-5)' },
86
+ };
87
+
88
+ const richData = [
89
+ { date: 'Apr 01', revenue: 4200, pipeline: 2600, conversion: 32, churn: 8 },
90
+ { date: 'Apr 08', revenue: 5200, pipeline: 3200, conversion: 38, churn: 7 },
91
+ { date: 'Apr 15', revenue: 6100, pipeline: 3900, conversion: 42, churn: 6 },
92
+ { date: 'Apr 22', revenue: 5600, pipeline: 4300, conversion: 41, churn: 9 },
93
+ { date: 'Apr 29', revenue: 7200, pipeline: 4700, conversion: 48, churn: 5 },
94
+ { date: 'May 06', revenue: 7900, pipeline: 5300, conversion: 52, churn: 4 },
95
+ { date: 'May 13', revenue: 8400, pipeline: 5800, conversion: 55, churn: 3 },
96
+ { date: 'May 20', revenue: 9100, pipeline: 6200, conversion: 58, churn: 4 },
97
+ ];
98
+
99
+ const breakdownConfig: ChartConfig = {
100
+ enterprise: { label: 'Enterprise', color: 'var(--chart-1)' },
101
+ midmarket: { label: 'Mid-market', color: 'var(--chart-4)' },
102
+ startup: { label: 'Startup', color: 'var(--chart-2)' },
103
+ };
104
+
105
+ const breakdownData = [
106
+ { name: 'enterprise', value: 52 },
107
+ { name: 'midmarket', value: 31 },
108
+ { name: 'startup', value: 17 },
109
+ ];
110
+
111
+ // ─── Primitive stories ────────────────────────────────────────────────────────
112
+
113
+ export const BarChartExample: Story = {
114
+ name: 'Primitive / Bar Chart',
115
+ render: () => (
116
+ <Card className="w-full max-w-4xl">
117
+ <CardHeader>
118
+ <CardTitle>Monthly Performance</CardTitle>
119
+ </CardHeader>
120
+ <CardContent>
121
+ <ChartContainer config={chartConfig} className="h-[300px] w-full">
122
+ <BarChart data={data}>
123
+ <CartesianGrid vertical={false} strokeDasharray="3 3" />
124
+ <XAxis dataKey="month" tickLine={false} axisLine={false} />
125
+ <ChartTooltip content={<ChartTooltipContent />} />
126
+ <ChartLegend content={<ChartLegendContent />} />
127
+ <Bar dataKey="revenue" fill="var(--color-revenue)" radius={[4, 4, 0, 0]} />
128
+ <Bar dataKey="expenses" fill="var(--color-expenses)" radius={[4, 4, 0, 0]} />
129
+ </BarChart>
130
+ </ChartContainer>
131
+ </CardContent>
132
+ </Card>
133
+ ),
134
+ };
135
+
136
+ export const LineChartExample: Story = {
137
+ name: 'Primitive / Line Chart',
138
+ render: () => (
139
+ <Card className="w-full max-w-4xl">
140
+ <CardHeader>
141
+ <CardTitle>Revenue Trends</CardTitle>
142
+ </CardHeader>
143
+ <CardContent>
144
+ <ChartContainer config={chartConfig} className="h-[300px] w-full">
145
+ <LineChart data={data}>
146
+ <CartesianGrid vertical={false} strokeDasharray="3 3" />
147
+ <XAxis dataKey="month" tickLine={false} axisLine={false} />
148
+ <ChartTooltip content={<ChartTooltipContent />} />
149
+ <Line
150
+ type="monotone"
151
+ dataKey="revenue"
152
+ stroke="var(--color-revenue)"
153
+ strokeWidth={3}
154
+ dot={{ r: 4, fill: "var(--color-revenue)", strokeWidth: 0 }}
155
+ activeDot={{ r: 6, strokeWidth: 0 }}
156
+ />
157
+ </LineChart>
158
+ </ChartContainer>
159
+ </CardContent>
160
+ </Card>
161
+ ),
162
+ };
163
+
164
+ // ─── Dashboard chart stories ──────────────────────────────────────────────────
165
+
166
+ export const DashboardBarChartExample: Story = {
167
+ name: 'Bar Chart',
168
+ args: {
169
+ data: richData,
170
+ indexKey: 'date',
171
+ config: richChartConfig,
172
+ colors: {
173
+ revenue: 'var(--chart-1)',
174
+ pipeline: 'var(--chart-4)',
175
+ },
176
+ barSize: 'lg',
177
+ series: [
178
+ { key: 'revenue', stackId: 'money' },
179
+ { key: 'pipeline', stackId: 'money' },
180
+ ],
181
+ stacked: true,
182
+ },
183
+ render: (args) => (
184
+ <ChartCard
185
+ title="Revenue by Week"
186
+ description="Stacked dashboard-ready comparison"
187
+ >
188
+ <DashboardBarChart {...args} />
189
+ </ChartCard>
190
+ ),
191
+ };
192
+
193
+ export const DashboardLineChartExample: Story = {
194
+ name: 'Line Chart',
195
+ render: () => (
196
+ <ChartCard
197
+ title="Growth Trend"
198
+ description="Multi-series line chart with smooth curves"
199
+ >
200
+ <DashboardLineChart
201
+ data={richData}
202
+ indexKey="date"
203
+ config={richChartConfig}
204
+ colors={{
205
+ revenue: 'var(--chart-1)',
206
+ pipeline: 'var(--chart-4)',
207
+ conversion: 'var(--chart-2)',
208
+ }}
209
+ series={[
210
+ { key: 'revenue', label: 'Revenue' },
211
+ { key: 'pipeline', label: 'Pipeline' },
212
+ { key: 'conversion', label: 'Conversion' },
213
+ ]}
214
+ showDots
215
+ curveType="monotone"
216
+ strokeWidth={2.5}
217
+ />
218
+ </ChartCard>
219
+ ),
220
+ };
221
+
222
+ export const HorizontalBarChartExample: Story = {
223
+ name: 'Horizontal Bar Chart',
224
+ render: () => (
225
+ <ChartCard
226
+ title="Top Segments"
227
+ description="Ranking chart for dashboard comparisons"
228
+ >
229
+ <HorizontalBarChart
230
+ data={[
231
+ { segment: 'Enterprise', revenue: 7600 },
232
+ { segment: 'Mid-market', revenue: 5400 },
233
+ { segment: 'Startup', revenue: 3100 },
234
+ { segment: 'Partners', revenue: 2200 },
235
+ ]}
236
+ indexKey="segment"
237
+ config={{ revenue: { label: 'Revenue', color: 'var(--chart-1)' } }}
238
+ colors={{ revenue: 'var(--chart-1)' }}
239
+ barSize="xl"
240
+ categoryWidth={110}
241
+ showLegend={false}
242
+ />
243
+ </ChartCard>
244
+ ),
245
+ };
246
+
247
+ export const InteractiveTimeSeriesExample: Story = {
248
+ name: 'Interactive Time Series',
249
+ render: () => (
250
+ <ChartCard
251
+ title="Executive Trend"
252
+ description="Switch metric and period without leaving the card"
253
+ >
254
+ <InteractiveTimeSeriesChart
255
+ data={richData}
256
+ indexKey="date"
257
+ config={richChartConfig}
258
+ colors={['var(--chart-1)', 'var(--chart-4)', 'var(--chart-2)']}
259
+ series={[
260
+ { key: 'revenue', label: 'Revenue' },
261
+ { key: 'pipeline', label: 'Pipeline' },
262
+ { key: 'conversion', label: 'Conversion' },
263
+ ]}
264
+ gradientFill
265
+ />
266
+ </ChartCard>
267
+ ),
268
+ };
269
+
270
+ export const GradientAreaChartExample: Story = {
271
+ name: 'Gradient Area Chart',
272
+ render: () => (
273
+ <ChartCard
274
+ title="Revenue Over Time"
275
+ description="Area chart with gradient fill for a modern look"
276
+ >
277
+ <InteractiveTimeSeriesChart
278
+ data={richData}
279
+ indexKey="date"
280
+ config={{ revenue: { label: 'Revenue', color: 'var(--chart-1)' } }}
281
+ colors={['var(--chart-1)']}
282
+ series={[{ key: 'revenue', label: 'Revenue' }]}
283
+ gradientFill
284
+ showDots
285
+ periods={[
286
+ { value: '7d', label: '7 days' },
287
+ { value: '30d', label: '30 days' },
288
+ ]}
289
+ />
290
+ </ChartCard>
291
+ ),
292
+ };
293
+
294
+ export const ComboMetricChartExample: Story = {
295
+ name: 'Combo Metric Chart',
296
+ render: () => (
297
+ <ChartCard
298
+ title="Pipeline Health"
299
+ description="Bars for volume with a line for rate"
300
+ >
301
+ <ComboMetricChart
302
+ data={richData}
303
+ indexKey="date"
304
+ config={richChartConfig}
305
+ colors={{
306
+ pipeline: 'var(--chart-4)',
307
+ conversion: 'var(--chart-2)',
308
+ }}
309
+ barSize="lg"
310
+ series={[
311
+ { key: 'pipeline', type: 'bar' },
312
+ { key: 'conversion', type: 'line' },
313
+ ]}
314
+ />
315
+ </ChartCard>
316
+ ),
317
+ };
318
+
319
+ export const ComboWithGradientAreaExample: Story = {
320
+ name: 'Combo Chart with Gradient Area',
321
+ render: () => (
322
+ <ChartCard
323
+ title="Revenue & Pipeline"
324
+ description="Gradient area for revenue, line for conversion rate"
325
+ >
326
+ <ComboMetricChart
327
+ data={richData}
328
+ indexKey="date"
329
+ config={richChartConfig}
330
+ colors={{
331
+ revenue: 'var(--chart-1)',
332
+ conversion: 'var(--chart-2)',
333
+ }}
334
+ series={[
335
+ { key: 'revenue', type: 'area' },
336
+ { key: 'conversion', type: 'line' },
337
+ ]}
338
+ gradientFill
339
+ curveType="monotone"
340
+ />
341
+ </ChartCard>
342
+ ),
343
+ };
344
+
345
+ export const DonutBreakdownExample: Story = {
346
+ name: 'Donut Chart',
347
+ render: () => (
348
+ <ChartCard
349
+ title="Customer Mix"
350
+ description="Interactive segment breakdown"
351
+ >
352
+ <DonutBreakdownChart
353
+ data={breakdownData}
354
+ config={breakdownConfig}
355
+ colors={['var(--chart-1)', 'var(--chart-4)', 'var(--chart-2)']}
356
+ centerValue="100%"
357
+ centerLabel="Accounts"
358
+ />
359
+ </ChartCard>
360
+ ),
361
+ };
362
+
363
+ // ─── Sparkline stories ────────────────────────────────────────────────────────
364
+
365
+ const sparkData = [
366
+ { v: 12 }, { v: 18 }, { v: 14 }, { v: 22 }, { v: 19 },
367
+ { v: 28 }, { v: 24 }, { v: 31 }, { v: 27 }, { v: 35 },
368
+ ];
369
+
370
+ const sparkDataDown = [
371
+ { v: 35 }, { v: 30 }, { v: 28 }, { v: 22 }, { v: 25 },
372
+ { v: 18 }, { v: 20 }, { v: 14 }, { v: 12 }, { v: 8 },
373
+ ];
374
+
375
+ export const SparklineExample: Story = {
376
+ name: 'Sparkline Chart',
377
+ render: () => (
378
+ <div className="space-y-6 max-w-2xl">
379
+ <p className="text-sm text-muted-foreground">
380
+ Sparklines are minimal inline charts designed for stat cards and table cells.
381
+ </p>
382
+
383
+ {/* Stat cards with sparklines */}
384
+ <div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
385
+ <Card className="p-4">
386
+ <div className="flex items-start justify-between mb-3">
387
+ <div>
388
+ <p className="text-xs text-muted-foreground font-medium uppercase tracking-wide">Revenue</p>
389
+ <p className="text-2xl font-bold mt-0.5">$35.2K</p>
390
+ </div>
391
+ <span className="inline-flex items-center gap-1 text-xs font-medium text-emerald-600 bg-emerald-50 dark:bg-emerald-950 dark:text-emerald-400 px-2 py-0.5 rounded-full">
392
+ <TrendingUp className="size-3" />
393
+ +12%
394
+ </span>
395
+ </div>
396
+ <SparklineChart
397
+ data={sparkData}
398
+ dataKey="v"
399
+ color="var(--chart-2)"
400
+ filled
401
+ showEndDot
402
+ className="h-12"
403
+ />
404
+ </Card>
405
+
406
+ <Card className="p-4">
407
+ <div className="flex items-start justify-between mb-3">
408
+ <div>
409
+ <p className="text-xs text-muted-foreground font-medium uppercase tracking-wide">Churn</p>
410
+ <p className="text-2xl font-bold mt-0.5">8.4%</p>
411
+ </div>
412
+ <span className="inline-flex items-center gap-1 text-xs font-medium text-red-600 bg-red-50 dark:bg-red-950 dark:text-red-400 px-2 py-0.5 rounded-full">
413
+ <TrendingDown className="size-3" />
414
+ -3%
415
+ </span>
416
+ </div>
417
+ <SparklineChart
418
+ data={sparkDataDown}
419
+ dataKey="v"
420
+ color="var(--chart-5)"
421
+ filled
422
+ showEndDot
423
+ className="h-12"
424
+ />
425
+ </Card>
426
+
427
+ <Card className="p-4">
428
+ <div className="flex items-start justify-between mb-3">
429
+ <div>
430
+ <p className="text-xs text-muted-foreground font-medium uppercase tracking-wide">Pipeline</p>
431
+ <p className="text-2xl font-bold mt-0.5">$128K</p>
432
+ </div>
433
+ <span className="inline-flex items-center gap-1 text-xs font-medium text-muted-foreground bg-muted px-2 py-0.5 rounded-full">
434
+ <Minus className="size-3" />
435
+ 0%
436
+ </span>
437
+ </div>
438
+ <SparklineChart
439
+ data={[
440
+ { v: 20 }, { v: 22 }, { v: 19 }, { v: 23 }, { v: 21 },
441
+ { v: 24 }, { v: 22 }, { v: 25 }, { v: 23 }, { v: 24 },
442
+ ]}
443
+ dataKey="v"
444
+ color="var(--chart-4)"
445
+ filled
446
+ showEndDot
447
+ className="h-12"
448
+ />
449
+ </Card>
450
+ </div>
451
+
452
+ {/* Sparkline variants */}
453
+ <ChartCard title="Sparkline Variants" description="Line-only vs filled area">
454
+ <div className="space-y-4 py-2">
455
+ <div className="flex items-center gap-4">
456
+ <span className="text-xs text-muted-foreground w-24 shrink-0">Filled (default)</span>
457
+ <SparklineChart data={sparkData} dataKey="v" color="var(--chart-1)" filled className="h-10 flex-1" />
458
+ </div>
459
+ <div className="flex items-center gap-4">
460
+ <span className="text-xs text-muted-foreground w-24 shrink-0">Line only</span>
461
+ <SparklineChart data={sparkData} dataKey="v" color="var(--chart-3)" filled={false} showEndDot={false} className="h-10 flex-1" />
462
+ </div>
463
+ <div className="flex items-center gap-4">
464
+ <span className="text-xs text-muted-foreground w-24 shrink-0">Step curve</span>
465
+ <SparklineChart data={sparkData} dataKey="v" color="var(--chart-6)" filled curveType="step" className="h-10 flex-1" />
466
+ </div>
467
+ </div>
468
+ </ChartCard>
469
+ </div>
470
+ ),
471
+ };
472
+
473
+ // ─── Dashboard layout story ───────────────────────────────────────────────────
474
+
475
+ export const DashboardLayoutExample: Story = {
476
+ name: 'Dashboard Layout',
477
+ render: () => {
478
+ const kpiData = [
479
+ { label: 'Total Revenue', value: '$128.4K', trend: '+18%', up: true, sparkData: sparkData, color: 'var(--chart-1)' },
480
+ { label: 'Active Pipeline', value: '$62.1K', trend: '+9%', up: true, sparkData: sparkData.map(d => ({ v: d.v * 0.7 })), color: 'var(--chart-4)' },
481
+ { label: 'Conversion Rate', value: '58%', trend: '+4%', up: true, sparkData: sparkData.map(d => ({ v: d.v * 0.5 })), color: 'var(--chart-2)' },
482
+ { label: 'Churn Rate', value: '3.2%', trend: '-1%', up: false, sparkData: sparkDataDown, color: 'var(--chart-5)' },
483
+ ];
484
+
485
+ return (
486
+ <div className="space-y-6">
487
+ {/* KPI row */}
488
+ <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
489
+ {kpiData.map((kpi) => (
490
+ <Card key={kpi.label} className="p-4">
491
+ <div className="flex items-start justify-between mb-3">
492
+ <div>
493
+ <p className="text-xs text-muted-foreground font-medium">{kpi.label}</p>
494
+ <p className="text-xl font-bold mt-0.5">{kpi.value}</p>
495
+ </div>
496
+ <span className={`inline-flex items-center gap-1 text-xs font-medium px-2 py-0.5 rounded-full ${kpi.up
497
+ ? 'text-emerald-600 bg-emerald-50 dark:bg-emerald-950 dark:text-emerald-400'
498
+ : 'text-red-600 bg-red-50 dark:bg-red-950 dark:text-red-400'
499
+ }`}>
500
+ {kpi.up ? <TrendingUp className="size-3" /> : <TrendingDown className="size-3" />}
501
+ {kpi.trend}
502
+ </span>
503
+ </div>
504
+ <SparklineChart
505
+ data={kpi.sparkData}
506
+ dataKey="v"
507
+ color={kpi.color}
508
+ filled
509
+ showEndDot
510
+ className="h-10"
511
+ />
512
+ </Card>
513
+ ))}
514
+ </div>
515
+
516
+ {/* Main charts row */}
517
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
518
+ <div className="lg:col-span-2">
519
+ <ChartCard
520
+ title="Revenue & Pipeline"
521
+ description="Weekly performance overview"
522
+ >
523
+ <InteractiveTimeSeriesChart
524
+ data={richData}
525
+ indexKey="date"
526
+ config={richChartConfig}
527
+ colors={['var(--chart-1)', 'var(--chart-4)', 'var(--chart-2)']}
528
+ series={[
529
+ { key: 'revenue', label: 'Revenue' },
530
+ { key: 'pipeline', label: 'Pipeline' },
531
+ { key: 'conversion', label: 'Conversion' },
532
+ ]}
533
+ gradientFill
534
+ periods={[
535
+ { value: '7d', label: '7 days' },
536
+ { value: '30d', label: '30 days' },
537
+ ]}
538
+ />
539
+ </ChartCard>
540
+ </div>
541
+
542
+ <ChartCard
543
+ title="Customer Mix"
544
+ description="Segment breakdown"
545
+ >
546
+ <DonutBreakdownChart
547
+ data={breakdownData}
548
+ config={breakdownConfig}
549
+ colors={['var(--chart-1)', 'var(--chart-4)', 'var(--chart-2)']}
550
+ centerValue="100%"
551
+ centerLabel="Accounts"
552
+ />
553
+ </ChartCard>
554
+ </div>
555
+
556
+ {/* Bottom row */}
557
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
558
+ <ChartCard
559
+ title="Top Segments"
560
+ description="Revenue by customer segment"
561
+ >
562
+ <HorizontalBarChart
563
+ data={[
564
+ { segment: 'Enterprise', revenue: 7600 },
565
+ { segment: 'Mid-market', revenue: 5400 },
566
+ { segment: 'Startup', revenue: 3100 },
567
+ { segment: 'Partners', revenue: 2200 },
568
+ ]}
569
+ indexKey="segment"
570
+ config={{ revenue: { label: 'Revenue', color: 'var(--chart-1)' } }}
571
+ colors={{ revenue: 'var(--chart-1)' }}
572
+ barSize="xl"
573
+ categoryWidth={110}
574
+ showLegend={false}
575
+ />
576
+ </ChartCard>
577
+
578
+ <ChartCard
579
+ title="Pipeline Health"
580
+ description="Volume vs conversion rate"
581
+ >
582
+ <ComboMetricChart
583
+ data={richData}
584
+ indexKey="date"
585
+ config={richChartConfig}
586
+ colors={{
587
+ pipeline: 'var(--chart-4)',
588
+ conversion: 'var(--chart-2)',
589
+ }}
590
+ barSize="lg"
591
+ series={[
592
+ { key: 'pipeline', type: 'bar' },
593
+ { key: 'conversion', type: 'line' },
594
+ ]}
595
+ />
596
+ </ChartCard>
597
+ </div>
598
+ </div>
599
+ );
600
+ },
601
+ };
602
+
603
+ // ─── State stories ────────────────────────────────────────────────────────────
604
+
605
+ export const EmptyStateExample: Story = {
606
+ name: 'State / Empty',
607
+ render: () => (
608
+ <ChartCard
609
+ title="Revenue by Week"
610
+ description="The empty state is rendered by the chart wrapper"
611
+ >
612
+ <DashboardBarChart
613
+ data={[]}
614
+ indexKey="date"
615
+ config={richChartConfig}
616
+ emptyDescription="No revenue events were found for the selected period."
617
+ />
618
+ </ChartCard>
619
+ ),
620
+ };
621
+
622
+ export const ConnectionErrorExample: Story = {
623
+ name: 'State / Connection Error',
624
+ render: () => (
625
+ <ChartCard
626
+ title="Pipeline Health"
627
+ description="Connection errors stay inside the chart panel"
628
+ >
629
+ <ComboMetricChart
630
+ data={richData}
631
+ indexKey="date"
632
+ config={richChartConfig}
633
+ error="Unable to connect to the analytics service."
634
+ onRetry={() => undefined}
635
+ />
636
+ </ChartCard>
637
+ ),
638
+ };
639
+
640
+ export const LoadingStateExample: Story = {
641
+ name: 'State / Loading',
642
+ render: () => (
643
+ <ChartCard
644
+ title="Revenue by Week"
645
+ description="Loading skeleton while data is fetched"
646
+ >
647
+ <DashboardBarChart
648
+ data={[]}
649
+ indexKey="date"
650
+ config={richChartConfig}
651
+ isLoading
652
+ />
653
+ </ChartCard>
654
+ ),
655
+ };
656
+
657
+ // ─── Variant stories ──────────────────────────────────────────────────────────
658
+
659
+ export const BarSizeVariantsExample: Story = {
660
+ name: 'Variants / Bar Sizes',
661
+ render: () => (
662
+ <div className="space-y-6">
663
+ <ChartCard title="Thin Bars" description='barSize="sm"'>
664
+ <DashboardBarChart
665
+ data={richData}
666
+ indexKey="date"
667
+ config={richChartConfig}
668
+ series={[{ key: 'revenue' }]}
669
+ barSize="sm"
670
+ showLegend={false}
671
+ />
672
+ </ChartCard>
673
+ <ChartCard title="Wide Bars" description='barSize="xl"'>
674
+ <DashboardBarChart
675
+ data={richData}
676
+ indexKey="date"
677
+ config={richChartConfig}
678
+ series={[{ key: 'revenue' }]}
679
+ barSize="xl"
680
+ showLegend={false}
681
+ />
682
+ </ChartCard>
683
+ </div>
684
+ ),
685
+ };
686
+
687
+ export const CurveTypeVariantsExample: Story = {
688
+ name: 'Variants / Curve Types',
689
+ render: () => (
690
+ <div className="space-y-6">
691
+ {(['monotone', 'linear', 'step', 'natural', 'basis'] as const).map((curve) => (
692
+ <ChartCard key={curve} title={`curveType="${curve}"`} description="Line chart curve interpolation">
693
+ <DashboardLineChart
694
+ data={richData}
695
+ indexKey="date"
696
+ config={{ revenue: { label: 'Revenue', color: 'var(--chart-1)' } }}
697
+ series={[{ key: 'revenue' }]}
698
+ curveType={curve}
699
+ showLegend={false}
700
+ showDots={curve === 'linear'}
701
+ />
702
+ </ChartCard>
703
+ ))}
704
+ </div>
705
+ ),
706
+ };
707
+
708
+ export const ColorPaletteExample: Story = {
709
+ name: 'Variants / Color Palette',
710
+ render: () => {
711
+ const paletteConfig: ChartConfig = {
712
+ chart1: { label: 'chart-1 (indigo)', color: 'var(--chart-1)' },
713
+ chart2: { label: 'chart-2 (emerald)', color: 'var(--chart-2)' },
714
+ chart3: { label: 'chart-3 (amber)', color: 'var(--chart-3)' },
715
+ chart4: { label: 'chart-4 (blue)', color: 'var(--chart-4)' },
716
+ chart5: { label: 'chart-5 (red)', color: 'var(--chart-5)' },
717
+ chart6: { label: 'chart-6 (purple)', color: 'var(--chart-6)' },
718
+ chart7: { label: 'chart-7 (teal)', color: 'var(--chart-7)' },
719
+ chart8: { label: 'chart-8 (rose)', color: 'var(--chart-8)' },
720
+ };
721
+
722
+ const paletteData = [
723
+ { name: 'A', chart1: 80, chart2: 70, chart3: 60, chart4: 75, chart5: 55, chart6: 65, chart7: 72, chart8: 68 },
724
+ ];
725
+
726
+ return (
727
+ <ChartCard
728
+ title="Chart Color Palette"
729
+ description="All 8 chart tokens — vibrant, accessible, harmonious"
730
+ >
731
+ <DashboardBarChart
732
+ data={paletteData}
733
+ indexKey="name"
734
+ config={paletteConfig}
735
+ barSize="xl"
736
+ showGrid={false}
737
+ />
738
+ </ChartCard>
739
+ );
740
+ },
741
+ };
742
+
743
+ // ─── Radar Chart Stories ───────────────────────────────────────────────────────
744
+
745
+ const radarData = [
746
+ { skill: 'Performance', score: 88 },
747
+ { skill: 'Reliability', score: 72 },
748
+ { skill: 'Security', score: 95 },
749
+ { skill: 'Scalability', score: 65 },
750
+ { skill: 'Usability', score: 80 },
751
+ { skill: 'Maintainability', score: 58 },
752
+ ];
753
+
754
+ const radarMultiData = [
755
+ { skill: 'Performance', teamA: 88, teamB: 62 },
756
+ { skill: 'Reliability', teamA: 72, teamB: 85 },
757
+ { skill: 'Security', teamA: 95, teamB: 70 },
758
+ { skill: 'Scalability', teamA: 65, teamB: 90 },
759
+ { skill: 'Usability', teamA: 80, teamB: 55 },
760
+ { skill: 'Maintainability', teamA: 58, teamB: 78 },
761
+ ];
762
+
763
+ export const RadarChartFilled: Story = {
764
+ name: 'Radar Chart / Filled',
765
+ render: () => (
766
+ <ChartCard
767
+ title="System Health Score"
768
+ description="Filled radar — single series"
769
+ >
770
+ <RadarMetricChart
771
+ data={radarData}
772
+ labelKey="skill"
773
+ series={[{ key: 'score', label: 'Score' }]}
774
+ filled
775
+ showLegend={false}
776
+ />
777
+ </ChartCard>
778
+ ),
779
+ };
780
+
781
+ export const RadarChartOutline: Story = {
782
+ name: 'Radar Chart / Outline',
783
+ render: () => (
784
+ <ChartCard
785
+ title="System Health Score"
786
+ description="Outline only — no fill"
787
+ >
788
+ <RadarMetricChart
789
+ data={radarData}
790
+ labelKey="skill"
791
+ series={[{ key: 'score', label: 'Score' }]}
792
+ filled={false}
793
+ showDots
794
+ showLegend={false}
795
+ />
796
+ </ChartCard>
797
+ ),
798
+ };
799
+
800
+ export const RadarChartMultiSeries: Story = {
801
+ name: 'Radar Chart / Multi-Series',
802
+ render: () => (
803
+ <ChartCard
804
+ title="Team Comparison"
805
+ description="Two teams across 6 dimensions"
806
+ >
807
+ <RadarMetricChart
808
+ data={radarMultiData}
809
+ labelKey="skill"
810
+ series={[
811
+ { key: 'teamA', label: 'Team Alpha' },
812
+ { key: 'teamB', label: 'Team Beta' },
813
+ ]}
814
+ filled
815
+ fillOpacity={0.2}
816
+ showDots
817
+ />
818
+ </ChartCard>
819
+ ),
820
+ };
821
+
822
+ export const RadarChartVariants: Story = {
823
+ name: 'Radar Chart / All Variants',
824
+ render: () => (
825
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
826
+ <ChartCard title="Filled" description="Default filled area">
827
+ <RadarMetricChart
828
+ data={radarData}
829
+ labelKey="skill"
830
+ series={[{ key: 'score', label: 'Score' }]}
831
+ filled
832
+ showLegend={false}
833
+ />
834
+ </ChartCard>
835
+ <ChartCard title="Outline + Dots" description="No fill, with dots">
836
+ <RadarMetricChart
837
+ data={radarData}
838
+ labelKey="skill"
839
+ series={[{ key: 'score', label: 'Score' }]}
840
+ filled={false}
841
+ showDots
842
+ showLegend={false}
843
+ />
844
+ </ChartCard>
845
+ <ChartCard title="Multi-Series" description="Comparison overlay">
846
+ <RadarMetricChart
847
+ data={radarMultiData}
848
+ labelKey="skill"
849
+ series={[
850
+ { key: 'teamA', label: 'Team A' },
851
+ { key: 'teamB', label: 'Team B' },
852
+ ]}
853
+ filled
854
+ fillOpacity={0.18}
855
+ />
856
+ </ChartCard>
857
+ </div>
858
+ ),
859
+ };
860
+
861
+ // ─── Pie Chart Stories ────────────────────────────────────────────────────────
862
+
863
+ const pieData = [
864
+ { category: 'Infrastructure', spend: 42000 },
865
+ { category: 'Engineering', spend: 31000 },
866
+ { category: 'Marketing', spend: 18500 },
867
+ { category: 'Operations', spend: 12000 },
868
+ { category: 'Other', spend: 6500 },
869
+ ];
870
+
871
+ export const PieChartSimple: Story = {
872
+ name: 'Pie Chart / Simple',
873
+ render: () => (
874
+ <ChartCard
875
+ title="Budget Breakdown"
876
+ description="Simple pie — no labels"
877
+ >
878
+ <PieMetricChart
879
+ data={pieData}
880
+ nameKey="category"
881
+ valueKey="spend"
882
+ valueFormatter={(v) => `$${(v as number).toLocaleString()}`}
883
+ />
884
+ </ChartCard>
885
+ ),
886
+ };
887
+
888
+ export const PieChartWithLabels: Story = {
889
+ name: 'Pie Chart / With Labels',
890
+ render: () => (
891
+ <ChartCard
892
+ title="Budget Breakdown"
893
+ description="Pie with percentage labels"
894
+ >
895
+ <PieMetricChart
896
+ data={pieData}
897
+ nameKey="category"
898
+ valueKey="spend"
899
+ showLabels
900
+ valueFormatter={(v) => `$${(v as number).toLocaleString()}`}
901
+ />
902
+ </ChartCard>
903
+ ),
904
+ };
905
+
906
+ export const PieChartExploded: Story = {
907
+ name: 'Pie Chart / Exploded Slice',
908
+ render: () => (
909
+ <ChartCard
910
+ title="Budget Breakdown"
911
+ description="Largest slice highlighted with drop shadow"
912
+ >
913
+ <PieMetricChart
914
+ data={pieData}
915
+ nameKey="category"
916
+ valueKey="spend"
917
+ showLabels
918
+ explodeIndex={0}
919
+ valueFormatter={(v) => `$${(v as number).toLocaleString()}`}
920
+ />
921
+ </ChartCard>
922
+ ),
923
+ };
924
+
925
+ export const PieChartDonutVariant: Story = {
926
+ name: 'Pie Chart / Donut Variant',
927
+ render: () => (
928
+ <ChartCard
929
+ title="Budget Breakdown"
930
+ description="Pie with inner radius (donut style)"
931
+ >
932
+ <PieMetricChart
933
+ data={pieData}
934
+ nameKey="category"
935
+ valueKey="spend"
936
+ innerRadius="45%"
937
+ showLabels
938
+ valueFormatter={(v) => `$${(v as number).toLocaleString()}`}
939
+ />
940
+ </ChartCard>
941
+ ),
942
+ };
943
+
944
+ export const PieChartVariants: Story = {
945
+ name: 'Pie Chart / All Variants',
946
+ render: () => (
947
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
948
+ <ChartCard title="Simple" description="No labels">
949
+ <PieMetricChart data={pieData} nameKey="category" valueKey="spend" />
950
+ </ChartCard>
951
+ <ChartCard title="With Labels" description="Percentage labels">
952
+ <PieMetricChart data={pieData} nameKey="category" valueKey="spend" showLabels />
953
+ </ChartCard>
954
+ <ChartCard title="Exploded" description="First slice highlighted">
955
+ <PieMetricChart data={pieData} nameKey="category" valueKey="spend" showLabels explodeIndex={0} />
956
+ </ChartCard>
957
+ <ChartCard title="Donut" description="Inner radius 45%">
958
+ <PieMetricChart data={pieData} nameKey="category" valueKey="spend" innerRadius="45%" showLabels />
959
+ </ChartCard>
960
+ </div>
961
+ ),
962
+ };
963
+
964
+ // ─── Radial Bar Chart Stories ─────────────────────────────────────────────────
965
+
966
+ const radialData = [
967
+ { name: 'Infrastructure', value: 78 },
968
+ { name: 'Engineering', value: 62 },
969
+ { name: 'Marketing', value: 45 },
970
+ { name: 'Operations', value: 91 },
971
+ ];
972
+
973
+ export const RadialBarChartSingle: Story = {
974
+ name: 'Radial Bar / Single Bar',
975
+ render: () => (
976
+ <ChartCard
977
+ title="Deployment Success Rate"
978
+ description="Single radial bar — full circle"
979
+ >
980
+ <RadialBarMetricChart
981
+ data={[{ name: 'Success Rate', value: 87 }]}
982
+ dataKey="value"
983
+ nameKey="name"
984
+ showLegend={false}
985
+ innerRadius="60%"
986
+ outerRadius="90%"
987
+ valueFormatter={(v) => `${v}%`}
988
+ />
989
+ </ChartCard>
990
+ ),
991
+ };
992
+
993
+ export const RadialBarChartMulti: Story = {
994
+ name: 'Radial Bar / Multi-Bar',
995
+ render: () => (
996
+ <ChartCard
997
+ title="Department KPIs"
998
+ description="Multiple radial bars with background track"
999
+ >
1000
+ <RadialBarMetricChart
1001
+ data={radialData}
1002
+ dataKey="value"
1003
+ nameKey="name"
1004
+ innerRadius="20%"
1005
+ outerRadius="90%"
1006
+ valueFormatter={(v) => `${v}%`}
1007
+ />
1008
+ </ChartCard>
1009
+ ),
1010
+ };
1011
+
1012
+ export const RadialBarChartSemiCircle: Story = {
1013
+ name: 'Radial Bar / Semi-Circle',
1014
+ render: () => (
1015
+ <ChartCard
1016
+ title="Department KPIs"
1017
+ description="Semi-circle layout (startAngle=180, endAngle=0)"
1018
+ >
1019
+ <RadialBarMetricChart
1020
+ data={radialData}
1021
+ dataKey="value"
1022
+ nameKey="name"
1023
+ innerRadius="30%"
1024
+ outerRadius="90%"
1025
+ startAngle={180}
1026
+ endAngle={0}
1027
+ valueFormatter={(v) => `${v}%`}
1028
+ />
1029
+ </ChartCard>
1030
+ ),
1031
+ };
1032
+
1033
+ export const RadialBarChartVariants: Story = {
1034
+ name: 'Radial Bar / All Variants',
1035
+ render: () => (
1036
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
1037
+ <ChartCard title="Single Bar" description="Full circle">
1038
+ <RadialBarMetricChart
1039
+ data={[{ name: 'Success', value: 87 }]}
1040
+ dataKey="value"
1041
+ nameKey="name"
1042
+ showLegend={false}
1043
+ innerRadius="60%"
1044
+ outerRadius="90%"
1045
+ valueFormatter={(v) => `${v}%`}
1046
+ />
1047
+ </ChartCard>
1048
+ <ChartCard title="Multi-Bar" description="Stacked radial bars">
1049
+ <RadialBarMetricChart
1050
+ data={radialData}
1051
+ dataKey="value"
1052
+ nameKey="name"
1053
+ innerRadius="20%"
1054
+ outerRadius="90%"
1055
+ valueFormatter={(v) => `${v}%`}
1056
+ />
1057
+ </ChartCard>
1058
+ <ChartCard title="Semi-Circle" description="180° arc layout">
1059
+ <RadialBarMetricChart
1060
+ data={radialData}
1061
+ dataKey="value"
1062
+ nameKey="name"
1063
+ innerRadius="30%"
1064
+ outerRadius="90%"
1065
+ startAngle={180}
1066
+ endAngle={0}
1067
+ valueFormatter={(v) => `${v}%`}
1068
+ />
1069
+ </ChartCard>
1070
+ </div>
1071
+ ),
1072
+ };
1073
+
1074
+ // ─── Gauge Chart Stories ──────────────────────────────────────────────────────
1075
+
1076
+ const gaugeThresholds: GaugeChartThreshold[] = [
1077
+ { value: 33, color: 'var(--chart-5)', label: 'Critical' },
1078
+ { value: 66, color: 'var(--chart-3)', label: 'Warning' },
1079
+ { value: 100, color: 'var(--chart-2)', label: 'Healthy' },
1080
+ ];
1081
+
1082
+ export const GaugeChartSimple: Story = {
1083
+ name: 'Gauge Chart / Simple',
1084
+ render: () => (
1085
+ <ChartCard
1086
+ title="CPU Usage"
1087
+ description="Simple gauge — single color"
1088
+ className="max-w-sm mx-auto"
1089
+ >
1090
+ <div className="flex justify-center py-4">
1091
+ <GaugeChart value={67} label="CPU Usage" />
1092
+ </div>
1093
+ </ChartCard>
1094
+ ),
1095
+ };
1096
+
1097
+ export const GaugeChartWithThresholds: Story = {
1098
+ name: 'Gauge Chart / With Thresholds',
1099
+ render: () => (
1100
+ <ChartCard
1101
+ title="System Health"
1102
+ description="Color zones: critical / warning / healthy"
1103
+ className="max-w-sm mx-auto"
1104
+ >
1105
+ <div className="flex justify-center py-4">
1106
+ <GaugeChart
1107
+ value={72}
1108
+ label="Overall Health"
1109
+ thresholds={gaugeThresholds}
1110
+ />
1111
+ </div>
1112
+ </ChartCard>
1113
+ ),
1114
+ };
1115
+
1116
+ export const GaugeChartNoNeedle: Story = {
1117
+ name: 'Gauge Chart / No Needle',
1118
+ render: () => (
1119
+ <ChartCard
1120
+ title="Memory Usage"
1121
+ description="Arc only — no needle indicator"
1122
+ className="max-w-sm mx-auto"
1123
+ >
1124
+ <div className="flex justify-center py-4">
1125
+ <GaugeChart
1126
+ value={45}
1127
+ label="Memory"
1128
+ showNeedle={false}
1129
+ thresholds={gaugeThresholds}
1130
+ />
1131
+ </div>
1132
+ </ChartCard>
1133
+ ),
1134
+ };
1135
+
1136
+ export const GaugeChartVariants: Story = {
1137
+ name: 'Gauge Chart / All Variants',
1138
+ render: () => (
1139
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
1140
+ <ChartCard title="Low (22%)" description="Critical zone">
1141
+ <div className="flex justify-center py-2">
1142
+ <GaugeChart value={22} label="CPU" thresholds={gaugeThresholds} />
1143
+ </div>
1144
+ </ChartCard>
1145
+ <ChartCard title="Medium (55%)" description="Warning zone">
1146
+ <div className="flex justify-center py-2">
1147
+ <GaugeChart value={55} label="Memory" thresholds={gaugeThresholds} />
1148
+ </div>
1149
+ </ChartCard>
1150
+ <ChartCard title="High (88%)" description="Healthy zone">
1151
+ <div className="flex justify-center py-2">
1152
+ <GaugeChart value={88} label="Disk I/O" thresholds={gaugeThresholds} />
1153
+ </div>
1154
+ </ChartCard>
1155
+ </div>
1156
+ ),
1157
+ };
1158
+
1159
+ export const GaugeChartDashboard: Story = {
1160
+ name: 'Gauge Chart / Infrastructure Dashboard',
1161
+ render: () => {
1162
+ const metrics = [
1163
+ { label: 'CPU', value: 34, unit: '%' },
1164
+ { label: 'Memory', value: 71, unit: '%' },
1165
+ { label: 'Disk', value: 58, unit: '%' },
1166
+ { label: 'Network', value: 22, unit: '%' },
1167
+ ];
1168
+
1169
+ return (
1170
+ <div className="space-y-4">
1171
+ <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
1172
+ {metrics.map((m) => (
1173
+ <ChartCard key={m.label} title={m.label} description={`Current ${m.label} utilization`}>
1174
+ <div className="flex justify-center py-2">
1175
+ <GaugeChart
1176
+ value={m.value}
1177
+ label={m.label}
1178
+ thresholds={gaugeThresholds}
1179
+ valueFormatter={(v) => `${v}${m.unit}`}
1180
+ />
1181
+ </div>
1182
+ </ChartCard>
1183
+ ))}
1184
+ </div>
1185
+ </div>
1186
+ );
1187
+ },
1188
+ };
1189
+
1190
+ // ─── Complete Chart Library Overview ─────────────────────────────────────────
1191
+
1192
+ export const CompleteLibraryOverview: Story = {
1193
+ name: 'Complete Library / All Chart Types',
1194
+ render: () => (
1195
+ <div className="space-y-6">
1196
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
1197
+ {/* Bar */}
1198
+ <ChartCard title="Bar Chart" description="Categorical comparison">
1199
+ <DashboardBarChart
1200
+ data={[
1201
+ { month: 'Jan', revenue: 42000 },
1202
+ { month: 'Feb', revenue: 38000 },
1203
+ { month: 'Mar', revenue: 51000 },
1204
+ { month: 'Apr', revenue: 47000 },
1205
+ { month: 'May', revenue: 55000 },
1206
+ ]}
1207
+ indexKey="month"
1208
+ config={{ revenue: { label: 'Revenue', color: 'var(--chart-1)' } }}
1209
+ series={[{ key: 'revenue', label: 'Revenue' }]}
1210
+ showLegend={false}
1211
+ />
1212
+ </ChartCard>
1213
+
1214
+ {/* Line */}
1215
+ <ChartCard title="Line Chart" description="Trend over time">
1216
+ <DashboardLineChart
1217
+ data={[
1218
+ { month: 'Jan', users: 1200 },
1219
+ { month: 'Feb', users: 1450 },
1220
+ { month: 'Mar', users: 1380 },
1221
+ { month: 'Apr', users: 1620 },
1222
+ { month: 'May', users: 1890 },
1223
+ ]}
1224
+ indexKey="month"
1225
+ config={{ users: { label: 'Users', color: 'var(--chart-2)' } }}
1226
+ series={[{ key: 'users', label: 'Users' }]}
1227
+ showLegend={false}
1228
+ />
1229
+ </ChartCard>
1230
+
1231
+ {/* Donut */}
1232
+ <ChartCard title="Donut Chart" description="Part-to-whole">
1233
+ <DonutBreakdownChart
1234
+ data={[
1235
+ { name: 'Active', value: 68 },
1236
+ { name: 'Idle', value: 22 },
1237
+ { name: 'Offline', value: 10 },
1238
+ ]}
1239
+ nameKey="name"
1240
+ valueKey="value"
1241
+ config={{
1242
+ Active: { label: 'Active', color: 'var(--chart-2)' },
1243
+ Idle: { label: 'Idle', color: 'var(--chart-3)' },
1244
+ Offline: { label: 'Offline', color: 'var(--chart-5)' },
1245
+ }}
1246
+ centerValue="68%"
1247
+ centerLabel="Active"
1248
+ showLegend={false}
1249
+ />
1250
+ </ChartCard>
1251
+
1252
+ {/* Radar */}
1253
+ <ChartCard title="Radar Chart" description="Multi-dimensional">
1254
+ <RadarMetricChart
1255
+ data={radarData}
1256
+ labelKey="skill"
1257
+ series={[{ key: 'score', label: 'Score' }]}
1258
+ filled
1259
+ showLegend={false}
1260
+ />
1261
+ </ChartCard>
1262
+
1263
+ {/* Pie */}
1264
+ <ChartCard title="Pie Chart" description="Proportional slices">
1265
+ <PieMetricChart
1266
+ data={pieData}
1267
+ nameKey="category"
1268
+ valueKey="spend"
1269
+ showLabels
1270
+ showLegend={false}
1271
+ />
1272
+ </ChartCard>
1273
+
1274
+ {/* Radial Bar */}
1275
+ <ChartCard title="Radial Bar" description="Progress rings">
1276
+ <RadialBarMetricChart
1277
+ data={radialData}
1278
+ dataKey="value"
1279
+ nameKey="name"
1280
+ innerRadius="20%"
1281
+ outerRadius="90%"
1282
+ valueFormatter={(v) => `${v}%`}
1283
+ />
1284
+ </ChartCard>
1285
+ </div>
1286
+
1287
+ {/* Gauge row */}
1288
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
1289
+ {[
1290
+ { label: 'CPU', value: 34 },
1291
+ { label: 'Memory', value: 71 },
1292
+ { label: 'Disk', value: 58 },
1293
+ ].map((m) => (
1294
+ <ChartCard key={m.label} title={`Gauge — ${m.label}`} description="Semicircle gauge">
1295
+ <div className="flex justify-center py-2">
1296
+ <GaugeChart value={m.value} label={m.label} thresholds={gaugeThresholds} />
1297
+ </div>
1298
+ </ChartCard>
1299
+ ))}
1300
+ </div>
1301
+ </div>
1302
+ ),
1303
+ };