xertica-ui 2.1.8 → 2.1.10

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 (830) hide show
  1. package/CHANGELOG.md +469 -454
  2. package/README.md +299 -285
  3. package/bin/cli.ts +548 -473
  4. package/bin/generate-tokens.ts +262 -260
  5. package/components/assets/xertica-orbe-animation.ts +1162 -804
  6. package/components/assistant/code-block/CodeBlock.tsx +266 -263
  7. package/components/assistant/code-block/code-block.stories.tsx +57 -57
  8. package/components/assistant/code-block/code-block.test.tsx +44 -44
  9. package/components/assistant/code-block/index.ts +1 -1
  10. package/components/assistant/formatted-document/FormattedDocument.tsx +145 -118
  11. package/components/assistant/formatted-document/formatted-document.stories.tsx +51 -51
  12. package/components/assistant/formatted-document/formatted-document.test.tsx +42 -42
  13. package/components/assistant/formatted-document/index.ts +1 -1
  14. package/components/assistant/markdown-message/MarkdownMessage.tsx +152 -116
  15. package/components/assistant/markdown-message/index.ts +1 -1
  16. package/components/assistant/markdown-message/markdown-message.stories.tsx +50 -50
  17. package/components/assistant/markdown-message/markdown-message.test.tsx +33 -33
  18. package/components/assistant/modern-chat-input/ModernChatInput.tsx +549 -560
  19. package/components/assistant/modern-chat-input/index.ts +1 -1
  20. package/components/assistant/modern-chat-input/modern-chat-input.stories.tsx +131 -131
  21. package/components/assistant/modern-chat-input/modern-chat-input.test.tsx +79 -72
  22. package/components/assistant/xertica-assistant/index.ts +3 -3
  23. package/components/assistant/xertica-assistant/parts/AssistantCollapsedView.tsx +97 -97
  24. package/components/assistant/xertica-assistant/parts/AssistantConversationList.tsx +104 -104
  25. package/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.tsx +79 -81
  26. package/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.tsx +74 -86
  27. package/components/assistant/xertica-assistant/parts/AssistantHeader.tsx +73 -77
  28. package/components/assistant/xertica-assistant/parts/AssistantMessageBubble.tsx +558 -573
  29. package/components/assistant/xertica-assistant/parts/AssistantTabBar.tsx +65 -65
  30. package/components/assistant/xertica-assistant/parts/AssistantTypingIndicator.tsx +41 -41
  31. package/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.tsx +101 -98
  32. package/components/assistant/xertica-assistant/parts/index.ts +16 -16
  33. package/components/assistant/xertica-assistant/types.ts +134 -139
  34. package/components/assistant/xertica-assistant/use-assistant.ts +546 -232
  35. package/components/assistant/xertica-assistant/xertica-assistant.stories.tsx +407 -401
  36. package/components/assistant/xertica-assistant/xertica-assistant.test.tsx +65 -65
  37. package/components/assistant/xertica-assistant/xertica-assistant.tsx +609 -593
  38. package/components/blocks/card-patterns/ActivityCard.tsx +41 -32
  39. package/components/blocks/card-patterns/FeatureCard.tsx +54 -45
  40. package/components/blocks/card-patterns/NotificationCard.tsx +59 -49
  41. package/components/blocks/card-patterns/ProfileCard.tsx +45 -29
  42. package/components/blocks/card-patterns/ProjectCard.tsx +59 -38
  43. package/components/blocks/card-patterns/QuickActionCard.tsx +31 -25
  44. package/components/blocks/card-patterns/card-patterns.stories.tsx +162 -92
  45. package/components/blocks/card-patterns/index.ts +12 -12
  46. package/components/blocks/index.ts +1 -1
  47. package/components/brand/branding/branding.stories.tsx +57 -55
  48. package/components/brand/language-selector/LanguageSelector.tsx +67 -61
  49. package/components/brand/language-selector/index.ts +1 -1
  50. package/components/brand/language-selector/language-selector.stories.tsx +64 -28
  51. package/components/brand/language-selector/language-selector.test.tsx +45 -27
  52. package/components/brand/theme-toggle/ThemeToggle.tsx +68 -66
  53. package/components/brand/theme-toggle/index.ts +1 -1
  54. package/components/brand/theme-toggle/theme-toggle.stories.tsx +34 -34
  55. package/components/brand/theme-toggle/theme-toggle.test.tsx +34 -34
  56. package/components/brand/xertica-logo/XerticaLogo.stories.tsx +82 -82
  57. package/components/brand/xertica-logo/XerticaLogo.tsx +104 -87
  58. package/components/brand/xertica-logo/index.ts +1 -1
  59. package/components/brand/xertica-logo/xertica-logo.test.tsx +26 -26
  60. package/components/brand/xertica-orbe/XerticaOrbe.tsx +1927 -1357
  61. package/components/brand/xertica-orbe/index.ts +1 -1
  62. package/components/brand/xertica-orbe/xertica-orbe.stories.tsx +40 -40
  63. package/components/brand/xertica-orbe/xertica-orbe.test.tsx +19 -19
  64. package/components/brand/xertica-provider/XerticaProvider.tsx +63 -63
  65. package/components/brand/xertica-provider/index.ts +1 -1
  66. package/components/brand/xertica-provider/xertica-provider.test.tsx +22 -22
  67. package/components/brand/xertica-xlogo/XerticaXLogo.stories.tsx +79 -79
  68. package/components/brand/xertica-xlogo/XerticaXLogo.tsx +65 -69
  69. package/components/brand/xertica-xlogo/index.ts +1 -1
  70. package/components/brand/xertica-xlogo/xertica-xlogo.test.tsx +16 -16
  71. package/components/examples/ApiKeyMapExample.tsx +71 -72
  72. package/components/examples/DrawingMapExample.tsx +565 -539
  73. package/components/examples/FilterableMapExample.tsx +393 -385
  74. package/components/examples/LocationPickerExample.tsx +348 -328
  75. package/components/examples/MapExamples.tsx +61 -75
  76. package/components/examples/MapGmpExample.tsx +169 -154
  77. package/components/examples/MapShowcase.tsx +471 -471
  78. package/components/examples/RouteMapExamples.tsx +329 -329
  79. package/components/examples/SidebarLogoExample.tsx +65 -65
  80. package/components/examples/SimpleFilterableMap.tsx +40 -13
  81. package/components/examples/index.ts +9 -16
  82. package/components/figma/ImageWithFallback.tsx +7 -7
  83. package/components/hooks/index.ts +13 -22
  84. package/components/hooks/use-layout-shortcuts.ts +43 -46
  85. package/components/index.ts +72 -72
  86. package/components/layout/header/header.stories.tsx +204 -193
  87. package/components/layout/header/header.test.tsx +67 -68
  88. package/components/layout/header/header.tsx +347 -334
  89. package/components/layout/header/index.ts +1 -1
  90. package/components/layout/sidebar/index.ts +3 -3
  91. package/components/layout/sidebar/sidebar.stories.tsx +586 -510
  92. package/components/layout/sidebar/sidebar.test.tsx +65 -62
  93. package/components/layout/sidebar/sidebar.tsx +1068 -1073
  94. package/components/layout/sidebar/use-sidebar.ts +104 -104
  95. package/components/media/FloatingMediaWrapper.tsx +365 -313
  96. package/components/media/audio-player/AudioPlayer.stories.tsx +124 -120
  97. package/components/media/audio-player/AudioPlayer.test.tsx +106 -106
  98. package/components/media/audio-player/AudioPlayer.tsx +763 -587
  99. package/components/media/audio-player/index.ts +1 -1
  100. package/components/media/audio-player/use-audio-player.ts +312 -308
  101. package/components/media/video-player/VideoPlayer.stories.tsx +98 -94
  102. package/components/media/video-player/VideoPlayer.test.tsx +73 -73
  103. package/components/media/video-player/VideoPlayer.tsx +308 -297
  104. package/components/media/video-player/index.ts +1 -1
  105. package/components/pages/forgot-password-page/ForgotPasswordPage.stories.tsx +24 -24
  106. package/components/pages/forgot-password-page/ForgotPasswordPage.tsx +188 -180
  107. package/components/pages/forgot-password-page/forgot-password-page.test.tsx +45 -42
  108. package/components/pages/forgot-password-page/index.ts +1 -1
  109. package/components/pages/home-content/HomeContent.stories.tsx +43 -39
  110. package/components/pages/home-content/HomeContent.tsx +120 -122
  111. package/components/pages/home-content/index.ts +1 -1
  112. package/components/pages/home-page/HomePage.stories.tsx +1 -1
  113. package/components/pages/home-page/HomePage.tsx +75 -94
  114. package/components/pages/home-page/home-page.test.tsx +53 -42
  115. package/components/pages/home-page/index.ts +1 -1
  116. package/components/pages/login-page/LoginPage.stories.tsx +39 -39
  117. package/components/pages/login-page/LoginPage.tsx +216 -216
  118. package/components/pages/login-page/index.ts +1 -1
  119. package/components/pages/login-page/login-page.test.tsx +63 -60
  120. package/components/pages/reset-password-page/ResetPasswordPage.stories.tsx +24 -24
  121. package/components/pages/reset-password-page/ResetPasswordPage.tsx +237 -246
  122. package/components/pages/reset-password-page/index.ts +1 -1
  123. package/components/pages/template-content/TemplateContent.stories.tsx +43 -39
  124. package/components/pages/template-content/TemplateContent.tsx +1237 -1030
  125. package/components/pages/template-content/index.ts +1 -1
  126. package/components/pages/template-page/TemplatePage.stories.tsx +1 -1
  127. package/components/pages/template-page/TemplatePage.tsx +62 -73
  128. package/components/pages/template-page/index.ts +1 -1
  129. package/components/pages/template-page/template-page.test.tsx +52 -39
  130. package/components/pages/verify-email-page/VerifyEmailPage.stories.tsx +41 -41
  131. package/components/pages/verify-email-page/VerifyEmailPage.tsx +206 -198
  132. package/components/pages/verify-email-page/index.ts +1 -1
  133. package/components/shared/CustomTooltipContent.tsx +48 -52
  134. package/components/shared/assistant-utils.test.ts +16 -18
  135. package/components/shared/assistant-utils.ts +208 -171
  136. package/components/shared/error-boundary.stories.tsx +132 -0
  137. package/components/shared/error-boundary.tsx +154 -0
  138. package/components/shared/error-fallbacks.tsx +226 -0
  139. package/components/shared/layout-constants.ts +8 -8
  140. package/components/shared/navigation.ts +35 -0
  141. package/components/shared/use-mobile.test.ts +16 -16
  142. package/components/shared/use-mobile.ts +36 -38
  143. package/components/shared/utils.test.ts +14 -14
  144. package/components/shared/utils.ts +6 -6
  145. package/components/ui/accordion/accordion.stories.tsx +60 -71
  146. package/components/ui/accordion/accordion.test.tsx +59 -64
  147. package/components/ui/accordion/accordion.tsx +77 -79
  148. package/components/ui/accordion/index.ts +1 -1
  149. package/components/ui/alert/alert.stories.tsx +86 -90
  150. package/components/ui/alert/alert.test.tsx +53 -55
  151. package/components/ui/alert/alert.tsx +93 -116
  152. package/components/ui/alert/index.ts +1 -1
  153. package/components/ui/alert-dialog/alert-dialog.stories.tsx +84 -84
  154. package/components/ui/alert-dialog/alert-dialog.test.tsx +70 -68
  155. package/components/ui/alert-dialog/alert-dialog.tsx +149 -171
  156. package/components/ui/alert-dialog/index.ts +1 -1
  157. package/components/ui/aspect-ratio/aspect-ratio.stories.tsx +46 -46
  158. package/components/ui/aspect-ratio/aspect-ratio.test.tsx +28 -28
  159. package/components/ui/aspect-ratio/aspect-ratio.tsx +20 -22
  160. package/components/ui/aspect-ratio/index.ts +1 -1
  161. package/components/ui/assistant-chart/AssistantChart.tsx +64 -64
  162. package/components/ui/assistant-chart/assistant-chart.stories.tsx +44 -44
  163. package/components/ui/assistant-chart/assistant-chart.test.tsx +46 -42
  164. package/components/ui/assistant-chart/index.ts +1 -1
  165. package/components/ui/avatar/avatar.stories.tsx +86 -86
  166. package/components/ui/avatar/avatar.test.tsx +55 -55
  167. package/components/ui/avatar/avatar.tsx +71 -77
  168. package/components/ui/avatar/index.ts +1 -1
  169. package/components/ui/badge/badge.stories.tsx +72 -72
  170. package/components/ui/badge/badge.test.tsx +40 -40
  171. package/components/ui/badge/badge.tsx +57 -67
  172. package/components/ui/badge/index.ts +1 -1
  173. package/components/ui/breadcrumb/breadcrumb.stories.tsx +123 -118
  174. package/components/ui/breadcrumb/breadcrumb.test.tsx +70 -70
  175. package/components/ui/breadcrumb/breadcrumb.tsx +114 -121
  176. package/components/ui/breadcrumb/index.ts +1 -1
  177. package/components/ui/button/button.stories.tsx +183 -161
  178. package/components/ui/button/button.test.tsx +64 -64
  179. package/components/ui/button/button.tsx +98 -109
  180. package/components/ui/button/index.ts +1 -1
  181. package/components/ui/calendar/calendar.stories.tsx +108 -108
  182. package/components/ui/calendar/calendar.test.tsx +53 -53
  183. package/components/ui/calendar/calendar.tsx +75 -103
  184. package/components/ui/calendar/index.ts +1 -1
  185. package/components/ui/card/card.stories.tsx +80 -24
  186. package/components/ui/card/card.test.tsx +55 -55
  187. package/components/ui/card/card.tsx +83 -104
  188. package/components/ui/card/index.ts +1 -1
  189. package/components/ui/carousel/carousel.stories.tsx +80 -80
  190. package/components/ui/carousel/carousel.test.tsx +75 -74
  191. package/components/ui/carousel/carousel.tsx +242 -253
  192. package/components/ui/carousel/index.ts +1 -1
  193. package/components/ui/chart/chart.stories.tsx +175 -150
  194. package/components/ui/chart/chart.test.tsx +93 -269
  195. package/components/ui/chart/chart.tsx +2211 -58
  196. package/components/ui/chart/index.ts +1 -1
  197. package/components/ui/checkbox/checkbox.stories.tsx +89 -83
  198. package/components/ui/checkbox/checkbox.test.tsx +49 -49
  199. package/components/ui/checkbox/checkbox.tsx +68 -68
  200. package/components/ui/checkbox/index.ts +1 -1
  201. package/components/ui/collapsible/collapsible.stories.tsx +45 -60
  202. package/components/ui/collapsible/collapsible.test.tsx +51 -51
  203. package/components/ui/collapsible/collapsible.tsx +32 -44
  204. package/components/ui/collapsible/index.ts +1 -1
  205. package/components/ui/command/command.stories.tsx +134 -141
  206. package/components/ui/command/command.test.tsx +48 -48
  207. package/components/ui/command/command.tsx +163 -192
  208. package/components/ui/command/index.ts +1 -1
  209. package/components/ui/context-menu/context-menu.stories.tsx +76 -78
  210. package/components/ui/context-menu/context-menu.test.tsx +61 -59
  211. package/components/ui/context-menu/context-menu.tsx +236 -264
  212. package/components/ui/context-menu/index.ts +1 -1
  213. package/components/ui/dialog/dialog.stories.tsx +174 -174
  214. package/components/ui/dialog/dialog.test.tsx +78 -76
  215. package/components/ui/dialog/dialog.tsx +189 -201
  216. package/components/ui/dialog/index.ts +1 -1
  217. package/components/ui/drawer/drawer.stories.tsx +71 -75
  218. package/components/ui/drawer/drawer.test.tsx +67 -65
  219. package/components/ui/drawer/drawer.tsx +146 -158
  220. package/components/ui/drawer/index.ts +1 -1
  221. package/components/ui/dropdown-menu/dropdown-menu.stories.tsx +156 -156
  222. package/components/ui/dropdown-menu/dropdown-menu.test.tsx +62 -60
  223. package/components/ui/dropdown-menu/dropdown-menu.tsx +240 -269
  224. package/components/ui/dropdown-menu/index.ts +1 -1
  225. package/components/ui/empty/empty.stories.tsx +85 -92
  226. package/components/ui/empty/empty.test.tsx +31 -37
  227. package/components/ui/empty/empty.tsx +88 -104
  228. package/components/ui/empty/index.ts +1 -1
  229. package/components/ui/file-upload/file-upload.stories.tsx +144 -153
  230. package/components/ui/file-upload/file-upload.test.tsx +65 -69
  231. package/components/ui/file-upload/file-upload.tsx +142 -149
  232. package/components/ui/file-upload/index.ts +2 -2
  233. package/components/ui/file-upload/use-file-upload.ts +177 -232
  234. package/components/ui/form/form.stories.tsx +85 -87
  235. package/components/ui/form/form.test.tsx +75 -80
  236. package/components/ui/form/form.tsx +163 -208
  237. package/components/ui/form/index.ts +1 -1
  238. package/components/ui/google-maps-loader/google-maps-loader.test.tsx +35 -35
  239. package/components/ui/google-maps-loader/google-maps-loader.tsx +463 -443
  240. package/components/ui/google-maps-loader/index.ts +1 -1
  241. package/components/ui/hover-card/hover-card.stories.tsx +61 -67
  242. package/components/ui/hover-card/hover-card.test.tsx +48 -50
  243. package/components/ui/hover-card/hover-card.tsx +50 -56
  244. package/components/ui/hover-card/index.ts +1 -1
  245. package/components/ui/index.ts +400 -313
  246. package/components/ui/input/index.ts +1 -1
  247. package/components/ui/input/input.stories.tsx +153 -143
  248. package/components/ui/input/input.test.tsx +47 -47
  249. package/components/ui/input/input.tsx +57 -57
  250. package/components/ui/input-otp/index.ts +1 -1
  251. package/components/ui/input-otp/input-otp.stories.tsx +117 -118
  252. package/components/ui/input-otp/input-otp.test.tsx +74 -79
  253. package/components/ui/input-otp/input-otp.tsx +101 -104
  254. package/components/ui/label/index.ts +1 -1
  255. package/components/ui/label/label.stories.tsx +74 -74
  256. package/components/ui/label/label.test.tsx +45 -45
  257. package/components/ui/label/label.tsx +53 -53
  258. package/components/ui/map/index.ts +1 -1
  259. package/components/ui/map/map.stories.tsx +39 -39
  260. package/components/ui/map/map.test.tsx +82 -74
  261. package/components/ui/map/map.tsx +505 -470
  262. package/components/ui/map/mock.test.tsx +13 -13
  263. package/components/ui/map-config/index.ts +1 -1
  264. package/components/ui/map-config/map-config.ts +18 -12
  265. package/components/ui/map-layers/index.ts +1 -1
  266. package/components/ui/map-layers/map-layers.test.tsx +48 -44
  267. package/components/ui/map-layers/map-layers.tsx +126 -129
  268. package/components/ui/map.exports/index.ts +1 -1
  269. package/components/ui/map.exports/map.exports.ts +31 -31
  270. package/components/ui/menubar/index.ts +1 -1
  271. package/components/ui/menubar/menubar.stories.tsx +130 -130
  272. package/components/ui/menubar/menubar.test.tsx +53 -51
  273. package/components/ui/menubar/menubar.tsx +265 -289
  274. package/components/ui/navigation-menu/index.ts +1 -1
  275. package/components/ui/navigation-menu/navigation-menu.stories.tsx +126 -128
  276. package/components/ui/navigation-menu/navigation-menu.test.tsx +47 -47
  277. package/components/ui/navigation-menu/navigation-menu.tsx +165 -174
  278. package/components/ui/notification-badge/index.ts +1 -1
  279. package/components/ui/notification-badge/notification-badge.stories.tsx +66 -75
  280. package/components/ui/notification-badge/notification-badge.test.tsx +61 -61
  281. package/components/ui/notification-badge/notification-badge.tsx +91 -88
  282. package/components/ui/page-header/index.ts +1 -1
  283. package/components/ui/page-header/page-header.stories.tsx +69 -69
  284. package/components/ui/page-header/page-header.test.tsx +37 -42
  285. package/components/ui/page-header/page-header.tsx +124 -131
  286. package/components/ui/pagination/index.ts +3 -3
  287. package/components/ui/pagination/pagination.stories.tsx +210 -200
  288. package/components/ui/pagination/pagination.test.tsx +63 -61
  289. package/components/ui/pagination/pagination.tsx +140 -156
  290. package/components/ui/pagination/use-pagination.ts +173 -211
  291. package/components/ui/popover/index.ts +1 -1
  292. package/components/ui/popover/popover.stories.tsx +73 -75
  293. package/components/ui/popover/popover.test.tsx +48 -50
  294. package/components/ui/popover/popover.tsx +54 -60
  295. package/components/ui/progress/index.ts +1 -1
  296. package/components/ui/progress/progress.stories.tsx +55 -55
  297. package/components/ui/progress/progress.test.tsx +23 -23
  298. package/components/ui/progress/progress.tsx +68 -68
  299. package/components/ui/radio-group/index.ts +1 -1
  300. package/components/ui/radio-group/radio-group.stories.tsx +114 -106
  301. package/components/ui/radio-group/radio-group.test.tsx +78 -78
  302. package/components/ui/radio-group/radio-group.tsx +93 -92
  303. package/components/ui/rating/index.ts +1 -1
  304. package/components/ui/rating/rating.stories.tsx +50 -50
  305. package/components/ui/rating/rating.test.tsx +48 -48
  306. package/components/ui/rating/rating.tsx +145 -145
  307. package/components/ui/resizable/index.ts +1 -1
  308. package/components/ui/resizable/resizable.stories.tsx +88 -101
  309. package/components/ui/resizable/resizable.test.tsx +61 -58
  310. package/components/ui/resizable/resizable.tsx +452 -417
  311. package/components/ui/rich-text-editor/index.ts +7 -3
  312. package/components/ui/rich-text-editor/rich-text-editor.stories.tsx +290 -262
  313. package/components/ui/rich-text-editor/rich-text-editor.test.tsx +86 -84
  314. package/components/ui/rich-text-editor/rich-text-editor.tsx +634 -450
  315. package/components/ui/rich-text-editor/use-rich-text-editor.ts +453 -466
  316. package/components/ui/route-map/index.ts +1 -1
  317. package/components/ui/route-map/route-map.stories.tsx +48 -54
  318. package/components/ui/route-map/route-map.test.tsx +108 -95
  319. package/components/ui/route-map/route-map.tsx +348 -300
  320. package/components/ui/scroll-area/index.ts +1 -1
  321. package/components/ui/scroll-area/scroll-area.stories.tsx +31 -35
  322. package/components/ui/scroll-area/scroll-area.test.tsx +27 -27
  323. package/components/ui/scroll-area/scroll-area.tsx +70 -72
  324. package/components/ui/search/index.ts +1 -1
  325. package/components/ui/search/search.stories.tsx +107 -108
  326. package/components/ui/search/search.test.tsx +67 -67
  327. package/components/ui/search/search.tsx +141 -135
  328. package/components/ui/select/index.ts +1 -1
  329. package/components/ui/select/select.stories.tsx +157 -151
  330. package/components/ui/select/select.test.tsx +99 -103
  331. package/components/ui/select/select.tsx +195 -203
  332. package/components/ui/separator/index.ts +1 -1
  333. package/components/ui/separator/separator.stories.tsx +55 -57
  334. package/components/ui/separator/separator.test.tsx +23 -23
  335. package/components/ui/separator/separator.tsx +39 -39
  336. package/components/ui/sheet/index.ts +1 -1
  337. package/components/ui/sheet/sheet.stories.tsx +93 -95
  338. package/components/ui/sheet/sheet.test.tsx +62 -60
  339. package/components/ui/sheet/sheet.tsx +149 -162
  340. package/components/ui/simple-map/index.ts +1 -1
  341. package/components/ui/simple-map/simple-map.stories.tsx +44 -48
  342. package/components/ui/simple-map/simple-map.test.tsx +36 -47
  343. package/components/ui/simple-map/simple-map.tsx +92 -98
  344. package/components/ui/skeleton/index.ts +1 -1
  345. package/components/ui/skeleton/skeleton.stories.tsx +36 -36
  346. package/components/ui/skeleton/skeleton.test.tsx +19 -19
  347. package/components/ui/skeleton/skeleton.tsx +25 -25
  348. package/components/ui/slider/index.ts +1 -1
  349. package/components/ui/slider/slider.stories.tsx +44 -44
  350. package/components/ui/slider/slider.test.tsx +25 -25
  351. package/components/ui/slider/slider.tsx +66 -71
  352. package/components/ui/sonner/index.ts +1 -1
  353. package/components/ui/sonner/sonner.stories.tsx +41 -47
  354. package/components/ui/sonner/sonner.test.tsx +24 -24
  355. package/components/ui/sonner/sonner.tsx +74 -69
  356. package/components/ui/stats-card/index.ts +1 -1
  357. package/components/ui/stats-card/stats-card.stories.tsx +77 -77
  358. package/components/ui/stats-card/stats-card.test.tsx +34 -38
  359. package/components/ui/stats-card/stats-card.tsx +93 -99
  360. package/components/ui/stepper/index.ts +3 -3
  361. package/components/ui/stepper/stepper.stories.tsx +171 -174
  362. package/components/ui/stepper/stepper.test.tsx +47 -47
  363. package/components/ui/stepper/stepper.tsx +190 -168
  364. package/components/ui/stepper/use-stepper.ts +139 -140
  365. package/components/ui/switch/index.ts +1 -1
  366. package/components/ui/switch/switch.stories.tsx +73 -67
  367. package/components/ui/switch/switch.test.tsx +44 -44
  368. package/components/ui/switch/switch.tsx +70 -70
  369. package/components/ui/table/index.ts +1 -1
  370. package/components/ui/table/table.stories.tsx +114 -109
  371. package/components/ui/table/table.test.tsx +43 -50
  372. package/components/ui/table/table.tsx +104 -128
  373. package/components/ui/tabs/index.ts +1 -1
  374. package/components/ui/tabs/tabs.stories.tsx +117 -111
  375. package/components/ui/tabs/tabs.test.tsx +50 -50
  376. package/components/ui/tabs/tabs.tsx +66 -78
  377. package/components/ui/textarea/index.ts +1 -1
  378. package/components/ui/textarea/textarea.stories.tsx +69 -67
  379. package/components/ui/textarea/textarea.test.tsx +41 -41
  380. package/components/ui/textarea/textarea.tsx +61 -61
  381. package/components/ui/timeline/index.ts +1 -1
  382. package/components/ui/timeline/timeline.stories.tsx +97 -87
  383. package/components/ui/timeline/timeline.test.tsx +53 -53
  384. package/components/ui/timeline/timeline.tsx +124 -156
  385. package/components/ui/toggle/index.ts +1 -1
  386. package/components/ui/toggle/toggle.stories.tsx +56 -56
  387. package/components/ui/toggle/toggle.test.tsx +32 -32
  388. package/components/ui/toggle/toggle.tsx +55 -57
  389. package/components/ui/toggle-group/index.ts +1 -1
  390. package/components/ui/toggle-group/toggle-group.stories.tsx +66 -66
  391. package/components/ui/toggle-group/toggle-group.test.tsx +47 -47
  392. package/components/ui/toggle-group/toggle-group.tsx +79 -83
  393. package/components/ui/tooltip/index.ts +1 -1
  394. package/components/ui/tooltip/tooltip.stories.tsx +83 -82
  395. package/components/ui/tooltip/tooltip.test.tsx +39 -37
  396. package/components/ui/tooltip/tooltip.tsx +69 -73
  397. package/components/ui/tree-view/index.ts +4 -4
  398. package/components/ui/tree-view/tree-view.stories.tsx +154 -166
  399. package/components/ui/tree-view/tree-view.test.tsx +58 -58
  400. package/components/ui/tree-view/tree-view.tsx +171 -165
  401. package/components/ui/tree-view/use-tree-view.ts +237 -248
  402. package/components.json +161 -781
  403. package/contexts/ApiKeyContext.test.tsx +26 -26
  404. package/contexts/ApiKeyContext.tsx +125 -121
  405. package/contexts/AssistenteContext.test.tsx +17 -17
  406. package/contexts/AssistenteContext.tsx +113 -107
  407. package/contexts/AuthContext.tsx +118 -0
  408. package/contexts/BrandColorsContext.test.tsx +21 -21
  409. package/contexts/BrandColorsContext.tsx +251 -236
  410. package/contexts/LanguageContext.test.tsx +29 -29
  411. package/contexts/LanguageContext.tsx +60 -33
  412. package/contexts/LayoutContext.test.tsx +18 -18
  413. package/contexts/LayoutContext.tsx +140 -126
  414. package/contexts/ThemeContext.test.tsx +38 -36
  415. package/contexts/ThemeContext.tsx +86 -85
  416. package/contexts/index.ts +8 -7
  417. package/contexts/theme-data.ts +340 -340
  418. package/dist/AssistantChart-Bdd44uBn.cjs +3635 -0
  419. package/dist/AssistantChart-CFhDdGyU.js +3609 -0
  420. package/dist/AssistantChart-CeU2dIb6.js +3469 -0
  421. package/dist/AssistantChart-DO5UuX4J.cjs +3495 -0
  422. package/dist/AudioPlayer-BJ2IuRQW.cjs +1275 -0
  423. package/dist/AudioPlayer-CFeV8t-5.cjs +936 -0
  424. package/dist/AudioPlayer-CySJIyvL.js +937 -0
  425. package/dist/AudioPlayer-Xxma6_-H.js +1276 -0
  426. package/dist/BrandColorsContext-DLVJgtmH.js +666 -0
  427. package/dist/BrandColorsContext-GUyFmkX0.cjs +665 -0
  428. package/dist/CodeBlock-C2ZUXt8V.js +219 -0
  429. package/dist/CodeBlock-C5oYnLQp.cjs +218 -0
  430. package/dist/CustomTooltipContent-BT6brkVJ.cjs +49 -0
  431. package/dist/CustomTooltipContent-CfOfikhq.js +33 -0
  432. package/dist/FeatureCard-9GhnlgL3.js +336 -0
  433. package/dist/FeatureCard-Dkp-xmzM.cjs +335 -0
  434. package/dist/LayoutContext-C4kKN9RV.cjs +93 -0
  435. package/dist/LayoutContext-CGEe1oPq.js +94 -0
  436. package/dist/ThemeContext-CGk3KK0k.cjs +180 -0
  437. package/dist/ThemeContext-CQSo4Iwc.js +181 -0
  438. package/dist/VerifyEmailPage--1Vurewl.cjs +3196 -0
  439. package/dist/VerifyEmailPage-1WwWczAn.js +2818 -0
  440. package/dist/VerifyEmailPage-BComraR7.cjs +2817 -0
  441. package/dist/VerifyEmailPage-CFLMls1p.cjs +2827 -0
  442. package/dist/VerifyEmailPage-COiyNl1y.js +2825 -0
  443. package/dist/VerifyEmailPage-CgMxRb4z.js +3197 -0
  444. package/dist/VerifyEmailPage-DjQKRlUS.cjs +2824 -0
  445. package/dist/VerifyEmailPage-MTD7AG1Z.js +2828 -0
  446. package/dist/XerticaOrbe-BCUVSPPB.cjs +1924 -0
  447. package/dist/XerticaOrbe-By8eEvR-.js +1925 -0
  448. package/dist/XerticaProvider-D-yNhF94.cjs +39 -0
  449. package/dist/XerticaProvider-DYq4JWtg.js +40 -0
  450. package/dist/XerticaXLogo-CQUUjXoH.cjs +242 -0
  451. package/dist/XerticaXLogo-Cmsp-Eey.js +243 -0
  452. package/dist/alert-dialog-B4M3vQKS.cjs +875 -0
  453. package/dist/alert-dialog-KpoabzJb.js +852 -0
  454. package/dist/assistant.cjs.js +18 -4
  455. package/dist/assistant.es.js +18 -4
  456. package/dist/avatar-CuYu2MKt.cjs +72 -0
  457. package/dist/avatar-Cxyofu1H.js +56 -0
  458. package/dist/blocks.cjs.js +1 -1
  459. package/dist/blocks.es.js +1 -1
  460. package/dist/brand.cjs.js +3 -3
  461. package/dist/brand.es.js +3 -3
  462. package/dist/breadcrumb-DIJ0X3Ot.js +96 -0
  463. package/dist/breadcrumb-DjSxkjlQ.cjs +95 -0
  464. package/dist/button-Bnv9SvYK.cjs +79 -0
  465. package/dist/button-C6uvh0rV.js +63 -0
  466. package/dist/card-B8-Gl5DL.js +73 -0
  467. package/dist/card-Bv_c57KU.cjs +72 -0
  468. package/dist/cli.js +98 -23
  469. package/dist/components/assistant/code-block/CodeBlock.d.ts +1 -1
  470. package/dist/components/assistant/formatted-document/FormattedDocument.d.ts +1 -1
  471. package/dist/components/assistant/xertica-assistant/use-assistant.d.ts +2 -1
  472. package/dist/components/assistant/xertica-assistant/xertica-assistant.d.ts +13 -5
  473. package/dist/components/blocks/card-patterns/ActivityCard.d.ts +2 -2
  474. package/dist/components/blocks/card-patterns/FeatureCard.d.ts +6 -6
  475. package/dist/components/blocks/card-patterns/NotificationCard.d.ts +2 -2
  476. package/dist/components/blocks/card-patterns/ProfileCard.d.ts +2 -2
  477. package/dist/components/blocks/card-patterns/ProjectCard.d.ts +2 -2
  478. package/dist/components/blocks/card-patterns/QuickActionCard.d.ts +5 -5
  479. package/dist/components/blocks/card-patterns/index.d.ts +12 -12
  480. package/dist/components/blocks/index.d.ts +1 -1
  481. package/dist/components/brand/language-selector/LanguageSelector.d.ts +13 -7
  482. package/dist/components/brand/theme-toggle/ThemeToggle.d.ts +1 -1
  483. package/dist/components/brand/xertica-logo/XerticaLogo.d.ts +1 -1
  484. package/dist/components/brand/xertica-xlogo/XerticaXLogo.d.ts +1 -1
  485. package/dist/components/hooks/index.d.ts +1 -11
  486. package/dist/components/index.d.ts +1 -1
  487. package/dist/components/layout/sidebar/sidebar.d.ts +6 -6
  488. package/dist/components/layout/sidebar/use-sidebar.d.ts +1 -1
  489. package/dist/components/media/video-player/VideoPlayer.d.ts +1 -1
  490. package/dist/components/pages/home-content/HomeContent.d.ts +6 -20
  491. package/dist/components/pages/home-page/HomePage.d.ts +7 -19
  492. package/dist/components/pages/template-content/TemplateContent.d.ts +1 -11
  493. package/dist/components/pages/template-page/TemplatePage.d.ts +2 -14
  494. package/dist/components/shared/error-boundary.d.ts +60 -0
  495. package/dist/components/shared/error-fallbacks.d.ts +16 -0
  496. package/dist/components/shared/navigation.d.ts +14 -0
  497. package/dist/components/shared/utils.d.ts +1 -1
  498. package/dist/components/ui/accordion/accordion.d.ts +2 -2
  499. package/dist/components/ui/alert/alert.d.ts +17 -17
  500. package/dist/components/ui/alert-dialog/alert-dialog.d.ts +4 -4
  501. package/dist/components/ui/aspect-ratio/aspect-ratio.d.ts +1 -1
  502. package/dist/components/ui/assistant-chart/AssistantChart.d.ts +1 -1
  503. package/dist/components/ui/avatar/avatar.d.ts +3 -3
  504. package/dist/components/ui/badge/badge.d.ts +3 -3
  505. package/dist/components/ui/breadcrumb/breadcrumb.d.ts +8 -8
  506. package/dist/components/ui/button/button.d.ts +4 -4
  507. package/dist/components/ui/calendar/calendar.d.ts +4 -4
  508. package/dist/components/ui/card/card.d.ts +9 -9
  509. package/dist/components/ui/carousel/carousel.d.ts +7 -7
  510. package/dist/components/ui/chart/chart.d.ts +324 -9
  511. package/dist/components/ui/checkbox/checkbox.d.ts +2 -2
  512. package/dist/components/ui/collapsible/collapsible.d.ts +1 -1
  513. package/dist/components/ui/command/command.d.ts +4 -4
  514. package/dist/components/ui/context-menu/context-menu.d.ts +4 -4
  515. package/dist/components/ui/dialog/dialog.d.ts +6 -6
  516. package/dist/components/ui/drawer/drawer.d.ts +5 -5
  517. package/dist/components/ui/dropdown-menu/dropdown-menu.d.ts +4 -4
  518. package/dist/components/ui/empty/empty.d.ts +2 -2
  519. package/dist/components/ui/file-upload/file-upload.d.ts +1 -1
  520. package/dist/components/ui/file-upload/use-file-upload.d.ts +15 -9
  521. package/dist/components/ui/form/form.d.ts +7 -7
  522. package/dist/components/ui/hover-card/hover-card.d.ts +2 -2
  523. package/dist/components/ui/index.d.ts +144 -144
  524. package/dist/components/ui/input/input.d.ts +3 -3
  525. package/dist/components/ui/input-otp/input-otp.d.ts +6 -6
  526. package/dist/components/ui/label/label.d.ts +3 -3
  527. package/dist/components/ui/map-config/map-config.d.ts +1 -1
  528. package/dist/components/ui/map.exports/map.exports.d.ts +1 -1
  529. package/dist/components/ui/menubar/menubar.d.ts +4 -4
  530. package/dist/components/ui/navigation-menu/navigation-menu.d.ts +2 -2
  531. package/dist/components/ui/notification-badge/notification-badge.d.ts +2 -2
  532. package/dist/components/ui/page-header/page-header.d.ts +1 -1
  533. package/dist/components/ui/pagination/pagination.d.ts +8 -9
  534. package/dist/components/ui/popover/popover.d.ts +2 -2
  535. package/dist/components/ui/progress/progress.d.ts +3 -3
  536. package/dist/components/ui/radio-group/radio-group.d.ts +2 -2
  537. package/dist/components/ui/rating/rating.d.ts +2 -2
  538. package/dist/components/ui/resizable/resizable.d.ts +1 -1
  539. package/dist/components/ui/rich-text-editor/index.d.ts +1 -1
  540. package/dist/components/ui/scroll-area/scroll-area.d.ts +2 -2
  541. package/dist/components/ui/search/search.d.ts +3 -3
  542. package/dist/components/ui/select/select.d.ts +2 -2
  543. package/dist/components/ui/separator/separator.d.ts +2 -2
  544. package/dist/components/ui/sheet/sheet.d.ts +6 -6
  545. package/dist/components/ui/skeleton/skeleton.d.ts +1 -1
  546. package/dist/components/ui/slider/slider.d.ts +2 -2
  547. package/dist/components/ui/sonner/sonner.d.ts +1 -1
  548. package/dist/components/ui/stats-card/stats-card.d.ts +1 -1
  549. package/dist/components/ui/stepper/stepper.d.ts +1 -1
  550. package/dist/components/ui/switch/switch.d.ts +2 -2
  551. package/dist/components/ui/table/table.d.ts +10 -10
  552. package/dist/components/ui/tabs/tabs.d.ts +2 -2
  553. package/dist/components/ui/textarea/textarea.d.ts +3 -3
  554. package/dist/components/ui/timeline/timeline.d.ts +1 -1
  555. package/dist/components/ui/toggle/toggle.d.ts +3 -3
  556. package/dist/components/ui/toggle-group/toggle-group.d.ts +3 -3
  557. package/dist/components/ui/tooltip/tooltip.d.ts +2 -2
  558. package/dist/components/ui/tree-view/tree-view.d.ts +4 -4
  559. package/dist/contexts/AuthContext.d.ts +47 -0
  560. package/dist/contexts/LanguageContext.d.ts +1 -0
  561. package/dist/contexts/ThemeContext.d.ts +1 -1
  562. package/dist/contexts/index.d.ts +1 -0
  563. package/dist/dropdown-menu-B_uEXNc4.cjs +220 -0
  564. package/dist/dropdown-menu-CFuCssWA.js +204 -0
  565. package/dist/features/assistant/data/mock.d.ts +12 -0
  566. package/dist/features/assistant/hooks/useAssistantConfig.d.ts +3 -0
  567. package/dist/features/assistant/index.d.ts +2 -0
  568. package/dist/features/home/data/mock.d.ts +28 -0
  569. package/dist/features/home/hooks/useDashboardStats.d.ts +3 -0
  570. package/dist/features/home/hooks/useFeatureCards.d.ts +3 -0
  571. package/dist/features/home/hooks/useTeamMembers.d.ts +3 -0
  572. package/dist/features/home/index.d.ts +5 -0
  573. package/dist/features/home/store/dashboardStore.d.ts +16 -0
  574. package/dist/google-maps-loader-BVoVhUwA.js +316 -0
  575. package/dist/google-maps-loader-DjJaYhV6.cjs +316 -0
  576. package/dist/hooks.cjs.js +13 -20
  577. package/dist/hooks.es.js +10 -17
  578. package/dist/i18n.d.ts +2 -0
  579. package/dist/index-B7A523O_.js +8 -0
  580. package/dist/index-DmHhnb7a.cjs +7 -0
  581. package/dist/index.cjs.js +53 -67
  582. package/dist/index.es.js +247 -261
  583. package/dist/input-CNFHVKvo.cjs +145 -0
  584. package/dist/input-wPYg0d0P.js +127 -0
  585. package/dist/layout.cjs.js +2 -2
  586. package/dist/layout.es.js +2 -2
  587. package/dist/media.cjs.js +1 -1
  588. package/dist/media.es.js +1 -1
  589. package/dist/pages.cjs.js +1 -1
  590. package/dist/pages.es.js +1 -1
  591. package/dist/progress-Cs9i4DPx.js +81 -0
  592. package/dist/progress-DDeuWPZw.cjs +97 -0
  593. package/dist/rich-text-editor-BM-LPpTh.js +2902 -0
  594. package/dist/rich-text-editor-Bp3zQqMC.js +2954 -0
  595. package/dist/rich-text-editor-CeucBdIv.cjs +2971 -0
  596. package/dist/rich-text-editor-DoCkKhzk.cjs +2919 -0
  597. package/dist/select-Cmb8zF7w.cjs +156 -0
  598. package/dist/select-CprSNX0z.js +139 -0
  599. package/dist/sidebar-BbVIQvlP.js +796 -0
  600. package/dist/sidebar-DQj1z3jG.cjs +758 -0
  601. package/dist/sidebar-Djn5syhi.cjs +786 -0
  602. package/dist/sidebar-LluMXfam.js +759 -0
  603. package/dist/sidebar-_rT7rBMk.js +787 -0
  604. package/dist/sidebar-q7P2Godd.cjs +795 -0
  605. package/dist/slider-DcJharR9.cjs +73 -0
  606. package/dist/slider-Pay3fka2.js +56 -0
  607. package/dist/tooltip-CwgSdy3h.cjs +67 -0
  608. package/dist/tooltip-D-OrYnKO.js +51 -0
  609. package/dist/ui.cjs.js +43 -57
  610. package/dist/ui.es.js +224 -238
  611. package/dist/use-audio-player-BJFV24XW.js +188 -0
  612. package/dist/use-audio-player-BkmEmj8Q.js +185 -0
  613. package/dist/use-audio-player-CLFTWFW1.cjs +184 -0
  614. package/dist/use-audio-player-DyVYlOnR.cjs +187 -0
  615. package/dist/use-mobile-BB4M_4Ru.cjs +47 -0
  616. package/dist/use-mobile-CLu9nqGL.js +31 -0
  617. package/dist/xertica-assistant-CfBCo21g.js +2148 -0
  618. package/dist/xertica-assistant-DrsRwla1.cjs +2147 -0
  619. package/dist/xertica-assistant-V_IdW4WF.cjs +2099 -0
  620. package/dist/xertica-assistant-ciJaWqm1.js +2100 -0
  621. package/dist/xertica-ui.css +1 -1
  622. package/docs/ai-usage.md +195 -192
  623. package/docs/architecture-improvements.md +476 -463
  624. package/docs/architecture.md +273 -139
  625. package/docs/components/accordion.md +109 -114
  626. package/docs/components/alert-dialog.md +127 -127
  627. package/docs/components/alert.md +106 -108
  628. package/docs/components/aspect-ratio.md +58 -58
  629. package/docs/components/assistant-chart.md +47 -46
  630. package/docs/components/assistant.md +426 -397
  631. package/docs/components/audio-player.md +167 -126
  632. package/docs/components/avatar.md +101 -103
  633. package/docs/components/badge.md +84 -84
  634. package/docs/components/branding.md +249 -251
  635. package/docs/components/breadcrumb.md +104 -104
  636. package/docs/components/button.md +156 -156
  637. package/docs/components/calendar.md +19 -32
  638. package/docs/components/card-patterns.md +114 -75
  639. package/docs/components/card.md +45 -35
  640. package/docs/components/carousel.md +100 -100
  641. package/docs/components/chart.md +638 -656
  642. package/docs/components/checkbox.md +88 -88
  643. package/docs/components/code-block.md +105 -108
  644. package/docs/components/collapsible.md +86 -91
  645. package/docs/components/command.md +113 -98
  646. package/docs/components/context-menu.md +81 -81
  647. package/docs/components/dialog.md +198 -180
  648. package/docs/components/drawer.md +105 -107
  649. package/docs/components/dropdown-menu.md +127 -131
  650. package/docs/components/empty.md +127 -136
  651. package/docs/components/error-boundary.md +191 -0
  652. package/docs/components/file-upload.md +189 -206
  653. package/docs/components/floating-media-wrapper.md +63 -63
  654. package/docs/components/form.md +177 -150
  655. package/docs/components/formatted-document.md +105 -113
  656. package/docs/components/google-maps-loader.md +44 -43
  657. package/docs/components/header.md +177 -175
  658. package/docs/components/hooks.md +425 -909
  659. package/docs/components/hover-card.md +86 -86
  660. package/docs/components/image-with-fallback.md +107 -106
  661. package/docs/components/input-otp.md +95 -104
  662. package/docs/components/input.md +130 -130
  663. package/docs/components/label.md +69 -69
  664. package/docs/components/language-selector.md +117 -76
  665. package/docs/components/map-layers.md +138 -140
  666. package/docs/components/map.md +12 -12
  667. package/docs/components/markdown-message.md +47 -48
  668. package/docs/components/menubar.md +89 -83
  669. package/docs/components/modern-chat-input.md +164 -163
  670. package/docs/components/navigation-menu.md +83 -83
  671. package/docs/components/notification-badge.md +78 -78
  672. package/docs/components/page-header.md +93 -95
  673. package/docs/components/pages.md +309 -351
  674. package/docs/components/pagination.md +334 -319
  675. package/docs/components/popover.md +116 -121
  676. package/docs/components/progress.md +103 -103
  677. package/docs/components/radio-group.md +133 -129
  678. package/docs/components/rating.md +77 -77
  679. package/docs/components/resizable.md +84 -88
  680. package/docs/components/rich-text-editor.md +255 -244
  681. package/docs/components/route-map.md +124 -124
  682. package/docs/components/scroll-area.md +58 -58
  683. package/docs/components/search.md +87 -87
  684. package/docs/components/select.md +144 -150
  685. package/docs/components/separator.md +58 -58
  686. package/docs/components/sheet.md +122 -124
  687. package/docs/components/sidebar.md +314 -328
  688. package/docs/components/simple-map.md +51 -49
  689. package/docs/components/skeleton.md +99 -92
  690. package/docs/components/slider.md +84 -90
  691. package/docs/components/sonner.md +115 -118
  692. package/docs/components/stats-card.md +120 -119
  693. package/docs/components/stepper.md +268 -268
  694. package/docs/components/switch.md +106 -113
  695. package/docs/components/table.md +138 -138
  696. package/docs/components/tabs.md +117 -117
  697. package/docs/components/textarea.md +86 -90
  698. package/docs/components/theme-toggle.md +73 -72
  699. package/docs/components/timeline.md +121 -117
  700. package/docs/components/toggle-group.md +68 -68
  701. package/docs/components/toggle.md +62 -66
  702. package/docs/components/tooltip.md +116 -116
  703. package/docs/components/tree-view.md +238 -237
  704. package/docs/components/use-mobile.md +96 -100
  705. package/docs/components/video-player.md +68 -68
  706. package/docs/components/xertica-logo.md +36 -35
  707. package/docs/components/xertica-orbe.md +35 -34
  708. package/docs/components/xertica-provider.md +50 -49
  709. package/docs/components/xertica-xlogo.md +35 -34
  710. package/docs/decision-tree.md +37 -31
  711. package/docs/doc-audit.md +224 -223
  712. package/docs/form-sizing.md +162 -154
  713. package/docs/getting-started.md +568 -415
  714. package/docs/guidelines.md +222 -209
  715. package/docs/i18n.md +195 -0
  716. package/docs/installation.md +267 -213
  717. package/docs/layout.md +143 -145
  718. package/docs/llms.md +295 -261
  719. package/docs/patterns/analytics.md +194 -208
  720. package/docs/patterns/crud.md +149 -158
  721. package/docs/patterns/dashboard.md +138 -148
  722. package/docs/patterns/detail-page.md +296 -276
  723. package/docs/patterns/form.md +241 -244
  724. package/docs/patterns/login.md +156 -167
  725. package/docs/patterns/settings.md +368 -346
  726. package/docs/patterns/wizard.md +213 -217
  727. package/docs/state-management.md +283 -0
  728. package/guidelines/Guidelines.md +21 -16
  729. package/hooks/useTheme.test.tsx +16 -16
  730. package/hooks/useTheme.ts +1 -1
  731. package/imports/Podcast.tsx +189 -38
  732. package/imports/XerticaAi.tsx +2 -2
  733. package/imports/XerticaX.tsx +3 -8
  734. package/imports/svg-aueiaqngck.ts +19 -10
  735. package/imports/svg-v9krss1ozd.ts +22 -15
  736. package/imports/svg-vhrdofe3qe.ts +5 -4
  737. package/llms-compact.txt +414 -376
  738. package/llms-full.txt +154 -33
  739. package/llms.txt +26 -0
  740. package/mcp/resources.json +22 -22
  741. package/mcp/tools.json +35 -35
  742. package/package.json +14 -4
  743. package/scripts/ai-validator.ts +91 -83
  744. package/scripts/cleanup-case-dupes.ts +62 -59
  745. package/scripts/generate-ai-manifests.ts +107 -96
  746. package/styles/globals.css +13 -13
  747. package/styles/xertica/app-overrides/chat.css +1 -1
  748. package/styles/xertica/base.css +71 -71
  749. package/styles/xertica/integrations/sonner.css +8 -8
  750. package/styles/xertica/theme-map.css +99 -99
  751. package/styles/xertica/tokens.css +236 -236
  752. package/templates/.prettierignore +4 -0
  753. package/templates/.prettierrc +10 -0
  754. package/templates/CLAUDE.md +34 -85
  755. package/templates/eslint.config.js +26 -29
  756. package/templates/guidelines/Guidelines.md +104 -329
  757. package/templates/package.json +69 -63
  758. package/templates/postcss.config.js +6 -6
  759. package/templates/src/app/App.tsx +46 -26
  760. package/templates/src/app/components/AppLayout.tsx +55 -46
  761. package/templates/src/app/components/AuthGuard.tsx +82 -108
  762. package/templates/src/app/context/AuthContext.tsx +108 -0
  763. package/templates/src/features/assistant/data/mock.ts +66 -0
  764. package/templates/src/features/assistant/hooks/useAssistantConfig.ts +19 -0
  765. package/templates/src/features/assistant/index.ts +5 -0
  766. package/templates/src/features/auth/ui/AuthPageShell.tsx +1 -3
  767. package/templates/src/features/auth/ui/ForgotPasswordContent.tsx +2 -0
  768. package/templates/src/features/auth/ui/LoginContent.tsx +3 -4
  769. package/templates/src/features/auth/ui/ResetPasswordContent.tsx +47 -22
  770. package/templates/src/features/auth/ui/SocialLoginButtons.tsx +19 -5
  771. package/templates/src/features/auth/ui/VerifyEmailContent.tsx +6 -4
  772. package/templates/src/features/home/data/mock.ts +35 -0
  773. package/templates/src/features/home/hooks/useFeatureCards.ts +19 -0
  774. package/templates/src/features/home/index.ts +10 -0
  775. package/templates/src/features/home/store/dashboardStore.ts +25 -0
  776. package/templates/src/features/home/ui/HomeContent.tsx +85 -83
  777. package/templates/src/features/template/ui/CrudTemplate.tsx +57 -225
  778. package/templates/src/features/template/ui/DashboardTemplate.tsx +59 -166
  779. package/templates/src/features/template/ui/FormTemplate.tsx +79 -189
  780. package/templates/src/features/template/ui/LoginTemplate.tsx +52 -50
  781. package/templates/src/features/template/ui/TemplateContent.tsx +1199 -921
  782. package/templates/src/i18n.ts +38 -0
  783. package/templates/src/locales/en.json +79 -0
  784. package/templates/src/locales/es.json +79 -0
  785. package/templates/src/locales/pt-BR.json +79 -0
  786. package/templates/src/main.tsx +11 -10
  787. package/templates/src/pages/AssistantPage.tsx +463 -334
  788. package/templates/src/pages/HomePage.tsx +19 -16
  789. package/templates/src/pages/TemplatePage.tsx +8 -28
  790. package/templates/src/shared/config/navigation.ts +6 -8
  791. package/templates/src/shared/error-boundary.tsx +154 -0
  792. package/templates/src/shared/error-fallbacks.tsx +226 -0
  793. package/templates/src/shared/lib/auth.ts +0 -11
  794. package/templates/src/shared/types/auth.ts +0 -6
  795. package/templates/src/styles/index.css +95 -95
  796. package/templates/src/styles/xertica/tokens.css +236 -236
  797. package/templates/tsconfig.json +24 -31
  798. package/templates/tsconfig.node.json +12 -12
  799. package/templates/vite-env.d.ts +1 -1
  800. package/templates/vite.config.ts +22 -22
  801. package/utils/color-utils.ts +72 -72
  802. package/utils/demo-responses.test.ts +10 -10
  803. package/utils/demo-responses.ts +151 -115
  804. package/utils/gemini.test.ts +25 -25
  805. package/utils/gemini.ts +29 -14
  806. package/components/assistant/xertica-assistant/hooks/index.ts +0 -8
  807. package/components/assistant/xertica-assistant/hooks/use-assistant-conversations.ts +0 -119
  808. package/components/assistant/xertica-assistant/hooks/use-assistant-messages.ts +0 -323
  809. package/components/assistant/xertica-assistant/hooks/use-assistant-suggestions.ts +0 -64
  810. package/components/blocks/card-patterns/card-patterns.test.tsx +0 -448
  811. package/components/ui/chart/parts/chart-dashboard.tsx +0 -1025
  812. package/components/ui/chart/parts/chart-metric.tsx +0 -622
  813. package/components/ui/chart/parts/chart-primitives.tsx +0 -432
  814. package/components/ui/chart/parts/chart-shared.tsx +0 -201
  815. package/components/ui/chart/parts/chart-utils.ts +0 -145
  816. package/components/ui/chart/parts/index.ts +0 -5
  817. package/components/ui/file-upload/use-file-upload.test.ts +0 -173
  818. package/components/ui/pagination/use-pagination.test.ts +0 -104
  819. package/components/ui/rich-text-editor/use-rich-text-editor.test.ts +0 -110
  820. package/components/ui/stepper/use-stepper.test.ts +0 -109
  821. package/components/ui/tree-view/use-tree-view.test.ts +0 -91
  822. package/templates/README.md +0 -152
  823. package/templates/src/features/settings/index.ts +0 -1
  824. package/templates/src/features/settings/ui/SettingsContent.tsx +0 -210
  825. package/templates/src/pages/NotFoundPage.tsx +0 -29
  826. package/templates/src/pages/SettingsPage.tsx +0 -21
  827. package/templates/src/shared/config/assistant.ts +0 -20
  828. package/templates/src/shared/lib/api.ts +0 -79
  829. package/templates/src/shared/ui/PageContent.tsx +0 -35
  830. package/templates/src/vite-env.d.ts +0 -12
@@ -0,0 +1,2919 @@
1
+ "use strict";
2
+ const jsxRuntime = require("react/jsx-runtime");
3
+ const React = require("react");
4
+ const RechartsPrimitive = require("recharts");
5
+ const button = require("./button-Bnv9SvYK.cjs");
6
+ const classVarianceAuthority = require("class-variance-authority");
7
+ const lucideReact = require("lucide-react");
8
+ const card = require("./card-Bv_c57KU.cjs");
9
+ const select = require("./select-Cmb8zF7w.cjs");
10
+ const DialogPrimitive = require("@radix-ui/react-dialog");
11
+ const dropdownMenu = require("./dropdown-menu-B_uEXNc4.cjs");
12
+ const input = require("./input-CNFHVKvo.cjs");
13
+ function _interopNamespaceDefault(e) {
14
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
15
+ if (e) {
16
+ for (const k in e) {
17
+ if (k !== "default") {
18
+ const d = Object.getOwnPropertyDescriptor(e, k);
19
+ Object.defineProperty(n, k, d.get ? d : {
20
+ enumerable: true,
21
+ get: () => e[k]
22
+ });
23
+ }
24
+ }
25
+ }
26
+ n.default = e;
27
+ return Object.freeze(n);
28
+ }
29
+ const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
30
+ const RechartsPrimitive__namespace = /* @__PURE__ */ _interopNamespaceDefault(RechartsPrimitive);
31
+ const DialogPrimitive__namespace = /* @__PURE__ */ _interopNamespaceDefault(DialogPrimitive);
32
+ const alertVariants = classVarianceAuthority.cva(
33
+ "relative w-full rounded-[var(--radius)] border-l-4 px-4 py-3 grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-5 [&>svg]:translate-y-0.5 [&>svg]:text-current",
34
+ {
35
+ variants: {
36
+ variant: {
37
+ default: "bg-muted/50 border-l-border text-foreground [&>svg]:text-muted-foreground",
38
+ success: "bg-[color:var(--success)]/10 dark:bg-[color:var(--success)]/20 border-l-[color:var(--success)] text-foreground [&>svg]:text-[color:var(--success)]",
39
+ info: "bg-[color:var(--info)]/10 dark:bg-[color:var(--info)]/20 border-l-[color:var(--info)] text-foreground [&>svg]:text-[color:var(--info)]",
40
+ warning: "bg-[color:var(--warning)]/10 dark:bg-[color:var(--warning)]/20 border-l-[color:var(--warning)] text-foreground [&>svg]:text-[color:var(--warning)]",
41
+ destructive: "bg-[color:var(--destructive)]/10 dark:bg-[color:var(--destructive)]/20 border-l-[color:var(--destructive)] text-foreground [&>svg]:text-[color:var(--destructive)]"
42
+ }
43
+ },
44
+ defaultVariants: {
45
+ variant: "default"
46
+ }
47
+ }
48
+ );
49
+ const alertIcons = {
50
+ default: lucideReact.Info,
51
+ success: lucideReact.CheckCircle,
52
+ info: lucideReact.Info,
53
+ warning: lucideReact.AlertTriangle,
54
+ destructive: lucideReact.XCircle
55
+ };
56
+ function Alert({ className, variant, icon, children, ...props }) {
57
+ const alertVariant = variant && variant in alertIcons ? variant : "default";
58
+ const DefaultIcon = alertIcons[alertVariant];
59
+ return /* @__PURE__ */ jsxRuntime.jsxs(
60
+ "div",
61
+ {
62
+ "data-slot": "alert",
63
+ role: "alert",
64
+ className: button.cn(alertVariants({ variant }), className),
65
+ ...props,
66
+ children: [
67
+ icon !== void 0 ? icon : /* @__PURE__ */ jsxRuntime.jsx(DefaultIcon, { className: "flex-shrink-0" }),
68
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children })
69
+ ]
70
+ }
71
+ );
72
+ }
73
+ function AlertTitle({ className, ...props }) {
74
+ return /* @__PURE__ */ jsxRuntime.jsx(
75
+ "div",
76
+ {
77
+ "data-slot": "alert-title",
78
+ className: button.cn("font-medium mb-1 leading-tight", className),
79
+ ...props
80
+ }
81
+ );
82
+ }
83
+ function AlertDescription({ className, ...props }) {
84
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "alert-description", className: button.cn("leading-relaxed", className), ...props });
85
+ }
86
+ const Empty = React__namespace.forwardRef(
87
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
88
+ "div",
89
+ {
90
+ ref,
91
+ className: button.cn(
92
+ "flex min-h-[400px] flex-col items-center justify-center rounded-[var(--radius-card)] border border-dashed border-border p-8 text-center animate-in fade-in-50",
93
+ className
94
+ ),
95
+ ...props
96
+ }
97
+ )
98
+ );
99
+ Empty.displayName = "Empty";
100
+ const EmptyIcon = React__namespace.forwardRef(
101
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
102
+ "div",
103
+ {
104
+ ref,
105
+ className: button.cn(
106
+ "mx-auto flex h-20 w-20 items-center justify-center rounded-full bg-muted",
107
+ className
108
+ ),
109
+ ...props
110
+ }
111
+ )
112
+ );
113
+ EmptyIcon.displayName = "EmptyIcon";
114
+ const EmptyImage = React__namespace.forwardRef(
115
+ ({ className, alt, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
116
+ "img",
117
+ {
118
+ ref,
119
+ alt,
120
+ className: button.cn("mx-auto mb-4 h-48 w-48 object-contain opacity-50", className),
121
+ ...props
122
+ }
123
+ )
124
+ );
125
+ EmptyImage.displayName = "EmptyImage";
126
+ const EmptyTitle = React__namespace.forwardRef(
127
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("h3", { ref, className: button.cn("mt-4 font-semibold text-foreground", className), ...props })
128
+ );
129
+ EmptyTitle.displayName = "EmptyTitle";
130
+ const EmptyDescription = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
131
+ "p",
132
+ {
133
+ ref,
134
+ className: button.cn("mt-2 text-sm text-muted-foreground max-w-sm mx-auto", className),
135
+ ...props
136
+ }
137
+ ));
138
+ EmptyDescription.displayName = "EmptyDescription";
139
+ const EmptyAction = React__namespace.forwardRef(
140
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
141
+ "div",
142
+ {
143
+ ref,
144
+ className: button.cn("mt-6 flex flex-col gap-2 sm:flex-row sm:gap-4", className),
145
+ ...props
146
+ }
147
+ )
148
+ );
149
+ EmptyAction.displayName = "EmptyAction";
150
+ function Skeleton({ className, ...props }) {
151
+ return /* @__PURE__ */ jsxRuntime.jsx(
152
+ "div",
153
+ {
154
+ "data-slot": "skeleton",
155
+ className: button.cn("bg-accent animate-pulse rounded-md", className),
156
+ ...props
157
+ }
158
+ );
159
+ }
160
+ const THEMES = { light: "", dark: ".dark" };
161
+ const defaultPeriods = [
162
+ { value: "7d", label: "7 days" },
163
+ { value: "30d", label: "30 days" },
164
+ { value: "90d", label: "90 days" }
165
+ ];
166
+ const defaultChartColors = [
167
+ "var(--chart-1)",
168
+ "var(--chart-2)",
169
+ "var(--chart-3)",
170
+ "var(--chart-4)",
171
+ "var(--chart-5)",
172
+ "var(--chart-6)",
173
+ "var(--chart-7)",
174
+ "var(--chart-8)"
175
+ ];
176
+ const chartBarSizes = {
177
+ sm: 8,
178
+ md: 14,
179
+ lg: 22,
180
+ xl: 32
181
+ };
182
+ const ChartContext = React__namespace.createContext(null);
183
+ function useChart() {
184
+ const context = React__namespace.useContext(ChartContext);
185
+ if (!context) {
186
+ throw new Error("useChart must be used within a <ChartContainer />");
187
+ }
188
+ return context;
189
+ }
190
+ function ChartContainer({
191
+ id,
192
+ className,
193
+ children,
194
+ config,
195
+ ...props
196
+ }) {
197
+ const uniqueId = React__namespace.useId();
198
+ const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`;
199
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartContext.Provider, { value: { config }, children: /* @__PURE__ */ jsxRuntime.jsxs(
200
+ "div",
201
+ {
202
+ "data-slot": "chart",
203
+ "data-chart": chartId,
204
+ className: button.cn(
205
+ "[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border relative h-[300px] min-h-[200px] w-full min-w-0 overflow-hidden text-xs [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden",
206
+ className
207
+ ),
208
+ ...props,
209
+ children: [
210
+ /* @__PURE__ */ jsxRuntime.jsx(ChartStyle, { id: chartId, config }),
211
+ /* @__PURE__ */ jsxRuntime.jsx(RechartsPrimitive__namespace.ResponsiveContainer, { width: "100%", height: "100%", children })
212
+ ]
213
+ }
214
+ ) });
215
+ }
216
+ const ChartStyle = ({ id, config }) => {
217
+ const colorConfig = Object.entries(config).filter(([, config2]) => config2.theme || config2.color);
218
+ if (!colorConfig.length) {
219
+ return null;
220
+ }
221
+ return /* @__PURE__ */ jsxRuntime.jsx(
222
+ "style",
223
+ {
224
+ dangerouslySetInnerHTML: {
225
+ __html: Object.entries(THEMES).map(
226
+ ([theme, prefix]) => `
227
+ ${prefix} [data-chart=${id}] {
228
+ ${colorConfig.map(([key, itemConfig]) => {
229
+ var _a;
230
+ const color = ((_a = itemConfig.theme) == null ? void 0 : _a[theme]) || itemConfig.color;
231
+ return color ? ` --color-${key}: ${color};` : null;
232
+ }).join("\n")}
233
+ }
234
+ `
235
+ ).join("\n")
236
+ }
237
+ }
238
+ );
239
+ };
240
+ const ChartTooltip = RechartsPrimitive__namespace.Tooltip;
241
+ function ChartTooltipContent({
242
+ active,
243
+ payload,
244
+ className,
245
+ indicator = "dot",
246
+ hideLabel = false,
247
+ hideIndicator = false,
248
+ label,
249
+ labelFormatter,
250
+ labelClassName,
251
+ formatter,
252
+ color,
253
+ nameKey,
254
+ labelKey
255
+ }) {
256
+ const { config } = useChart();
257
+ const tooltipLabel = React__namespace.useMemo(() => {
258
+ var _a;
259
+ if (hideLabel || !(payload == null ? void 0 : payload.length)) {
260
+ return null;
261
+ }
262
+ const [item] = payload;
263
+ const key = `${labelKey || (item == null ? void 0 : item.dataKey) || (item == null ? void 0 : item.name) || "value"}`;
264
+ const itemConfig = getPayloadConfigFromPayload(config, item, key);
265
+ const value = !labelKey && typeof label === "string" ? ((_a = config[label]) == null ? void 0 : _a.label) || label : itemConfig == null ? void 0 : itemConfig.label;
266
+ if (labelFormatter) {
267
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: button.cn("font-medium", labelClassName), children: labelFormatter(value, payload) });
268
+ }
269
+ if (!value) {
270
+ return null;
271
+ }
272
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: button.cn("font-medium", labelClassName), children: value });
273
+ }, [label, labelFormatter, payload, hideLabel, labelClassName, config, labelKey]);
274
+ if (!active || !(payload == null ? void 0 : payload.length)) {
275
+ return null;
276
+ }
277
+ const nestLabel = payload.length === 1 && indicator !== "dot";
278
+ return /* @__PURE__ */ jsxRuntime.jsxs(
279
+ "div",
280
+ {
281
+ className: button.cn(
282
+ "border-border/50 bg-background/95 backdrop-blur-sm grid min-w-[8rem] items-start gap-1.5 rounded-xl border px-3 py-2 text-xs shadow-xl",
283
+ className
284
+ ),
285
+ children: [
286
+ !nestLabel ? tooltipLabel : null,
287
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-1.5", children: payload.map((item, index) => {
288
+ var _a;
289
+ const key = `${nameKey || item.name || item.dataKey || "value"}`;
290
+ const itemConfig = getPayloadConfigFromPayload(config, item, key);
291
+ const indicatorColor = color || ((_a = item.payload) == null ? void 0 : _a.fill) || item.color;
292
+ return /* @__PURE__ */ jsxRuntime.jsx(
293
+ "div",
294
+ {
295
+ className: button.cn(
296
+ "[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5",
297
+ indicator === "dot" && "items-center"
298
+ ),
299
+ children: formatter && (item == null ? void 0 : item.value) !== void 0 && item.name ? formatter(item.value, item.name, item, index, item.payload) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
300
+ (itemConfig == null ? void 0 : itemConfig.icon) ? /* @__PURE__ */ jsxRuntime.jsx(itemConfig.icon, {}) : !hideIndicator && /* @__PURE__ */ jsxRuntime.jsx(
301
+ "div",
302
+ {
303
+ className: button.cn(
304
+ "shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)",
305
+ {
306
+ "h-2.5 w-2.5": indicator === "dot",
307
+ "w-1": indicator === "line",
308
+ "w-0 border-[1.5px] border-dashed bg-transparent": indicator === "dashed",
309
+ "my-0.5": nestLabel && indicator === "dashed"
310
+ }
311
+ ),
312
+ style: {
313
+ "--color-bg": indicatorColor,
314
+ "--color-border": indicatorColor
315
+ }
316
+ }
317
+ ),
318
+ /* @__PURE__ */ jsxRuntime.jsxs(
319
+ "div",
320
+ {
321
+ className: button.cn(
322
+ "flex flex-1 justify-between leading-none",
323
+ nestLabel ? "items-end" : "items-center"
324
+ ),
325
+ children: [
326
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-1.5", children: [
327
+ nestLabel ? tooltipLabel : null,
328
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: (itemConfig == null ? void 0 : itemConfig.label) || item.name })
329
+ ] }),
330
+ item.value && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground font-mono font-semibold tabular-nums", children: item.value.toLocaleString() })
331
+ ]
332
+ }
333
+ )
334
+ ] })
335
+ },
336
+ item.dataKey
337
+ );
338
+ }) })
339
+ ]
340
+ }
341
+ );
342
+ }
343
+ const ChartLegend = RechartsPrimitive__namespace.Legend;
344
+ function ChartLegendContent({
345
+ className,
346
+ hideIcon = false,
347
+ payload,
348
+ verticalAlign = "bottom",
349
+ nameKey
350
+ }) {
351
+ const { config } = useChart();
352
+ if (!(payload == null ? void 0 : payload.length)) {
353
+ return null;
354
+ }
355
+ return /* @__PURE__ */ jsxRuntime.jsx(
356
+ "div",
357
+ {
358
+ className: button.cn(
359
+ "flex items-center justify-center gap-4",
360
+ verticalAlign === "top" ? "pb-3" : "pt-3",
361
+ className
362
+ ),
363
+ children: payload.map((item) => {
364
+ const key = `${nameKey ? item.value : item.dataKey || item.value || "value"}`;
365
+ const itemConfig = getPayloadConfigFromPayload(config, item, key);
366
+ return /* @__PURE__ */ jsxRuntime.jsxs(
367
+ "div",
368
+ {
369
+ className: button.cn(
370
+ "[&>svg]:text-muted-foreground flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3"
371
+ ),
372
+ children: [
373
+ (itemConfig == null ? void 0 : itemConfig.icon) && !hideIcon ? /* @__PURE__ */ jsxRuntime.jsx(itemConfig.icon, {}) : /* @__PURE__ */ jsxRuntime.jsx(
374
+ "div",
375
+ {
376
+ className: "h-2 w-2 shrink-0 rounded-full bg-(--color-bg)",
377
+ style: {
378
+ "--color-bg": item.color || `var(--color-${key})`
379
+ }
380
+ }
381
+ ),
382
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-xs", children: (itemConfig == null ? void 0 : itemConfig.label) || item.value })
383
+ ]
384
+ },
385
+ item.value
386
+ );
387
+ })
388
+ }
389
+ );
390
+ }
391
+ function getPayloadConfigFromPayload(config, payload, key) {
392
+ if (typeof payload !== "object" || payload === null) {
393
+ return void 0;
394
+ }
395
+ const payloadPayload = "payload" in payload && typeof payload.payload === "object" && payload.payload !== null ? payload.payload : void 0;
396
+ let configLabelKey = key;
397
+ if (key in payload && typeof payload[key] === "string") {
398
+ configLabelKey = payload[key];
399
+ } else if (payloadPayload && key in payloadPayload && typeof payloadPayload[key] === "string") {
400
+ configLabelKey = payloadPayload[key];
401
+ }
402
+ return configLabelKey in config ? config[configLabelKey] : config[key];
403
+ }
404
+ function getChartSeries(config, series) {
405
+ if (series == null ? void 0 : series.length) {
406
+ return series;
407
+ }
408
+ return Object.entries(config).map(([key, item]) => ({
409
+ key,
410
+ label: item.label
411
+ }));
412
+ }
413
+ function getSeriesColor(key, index, colors) {
414
+ if (Array.isArray(colors)) {
415
+ return colors[index] || defaultChartColors[index % defaultChartColors.length];
416
+ }
417
+ return (colors == null ? void 0 : colors[key]) || defaultChartColors[index % defaultChartColors.length];
418
+ }
419
+ function getChartConfigWithColors(config, keys, colors) {
420
+ return keys.reduce((nextConfig, key, index) => {
421
+ const item = config[key];
422
+ if ((item == null ? void 0 : item.theme) && !colors) {
423
+ nextConfig[key] = item;
424
+ return nextConfig;
425
+ }
426
+ nextConfig[key] = {
427
+ label: (item == null ? void 0 : item.label) || key,
428
+ icon: item == null ? void 0 : item.icon,
429
+ color: colors ? getSeriesColor(key, index, colors) : (item == null ? void 0 : item.color) || getSeriesColor(key, index)
430
+ };
431
+ return nextConfig;
432
+ }, {});
433
+ }
434
+ function buildChartConfig(keys, colors) {
435
+ return keys.reduce((cfg, key, index) => {
436
+ cfg[key] = {
437
+ label: key,
438
+ color: getSeriesColor(key, index, colors)
439
+ };
440
+ return cfg;
441
+ }, {});
442
+ }
443
+ function formatTick(value) {
444
+ if (typeof value !== "number") {
445
+ return value;
446
+ }
447
+ return Intl.NumberFormat("en", {
448
+ notation: "compact",
449
+ maximumFractionDigits: 1
450
+ }).format(value);
451
+ }
452
+ function defaultFilterData(data, period) {
453
+ const match = period.match(/^(\d+)/);
454
+ if (!match) {
455
+ return data;
456
+ }
457
+ const limit = Number(match[1]);
458
+ return data.slice(Math.max(data.length - limit, 0));
459
+ }
460
+ function getErrorDescription(error) {
461
+ if (typeof error === "string") {
462
+ return error;
463
+ }
464
+ if (error instanceof Error) {
465
+ return error.message;
466
+ }
467
+ return void 0;
468
+ }
469
+ function getBarSize(barSize = "md") {
470
+ return typeof barSize === "number" ? barSize : chartBarSizes[barSize];
471
+ }
472
+ function hasChartData(data, series) {
473
+ if (!data.length || !series.length) {
474
+ return false;
475
+ }
476
+ return data.some(
477
+ (item) => series.some((serie) => {
478
+ const value = item[serie.key];
479
+ return value !== null && value !== void 0 && value !== "";
480
+ })
481
+ );
482
+ }
483
+ function hasPieData(data, nameKey, valueKey) {
484
+ return data.some((item) => {
485
+ const name = item[nameKey];
486
+ const value = item[valueKey];
487
+ return name !== null && name !== void 0 && name !== "" && value !== null && value !== void 0 && value !== "";
488
+ });
489
+ }
490
+ function ChartState({
491
+ type,
492
+ className,
493
+ error,
494
+ onRetry,
495
+ retryLabel = "Try again",
496
+ emptyTitle = "No data available",
497
+ emptyDescription = "There is no data available for this chart yet.",
498
+ errorTitle = "Connection error",
499
+ errorDescription,
500
+ loadingLabel = "Loading chart data"
501
+ }) {
502
+ if (type === "loading") {
503
+ return /* @__PURE__ */ jsxRuntime.jsxs(
504
+ "div",
505
+ {
506
+ className: button.cn(
507
+ "flex min-h-[240px] flex-col justify-end gap-3 rounded-[var(--radius-card)] border border-border p-6",
508
+ className
509
+ ),
510
+ "aria-label": typeof loadingLabel === "string" ? loadingLabel : void 0,
511
+ children: [
512
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-8 w-2/5" }),
513
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-14 w-3/5" }),
514
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-24 w-4/5" }),
515
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-36 w-full" })
516
+ ]
517
+ }
518
+ );
519
+ }
520
+ if (type === "error") {
521
+ return /* @__PURE__ */ jsxRuntime.jsx(
522
+ "div",
523
+ {
524
+ className: button.cn(
525
+ "flex min-h-[240px] items-center justify-center rounded-[var(--radius-card)] border border-border p-6",
526
+ className
527
+ ),
528
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Alert, { variant: "destructive", className: "max-w-xl", children: [
529
+ /* @__PURE__ */ jsxRuntime.jsx(AlertTitle, { children: errorTitle }),
530
+ /* @__PURE__ */ jsxRuntime.jsx(AlertDescription, { children: errorDescription || getErrorDescription(error) || "Unable to load chart data. Check your connection and try again." }),
531
+ onRetry ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3", children: /* @__PURE__ */ jsxRuntime.jsxs(button.Button, { size: "sm", variant: "outline", onClick: onRetry, children: [
532
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "size-4" }),
533
+ retryLabel
534
+ ] }) }) : null
535
+ ] })
536
+ }
537
+ );
538
+ }
539
+ return /* @__PURE__ */ jsxRuntime.jsxs(Empty, { className: button.cn("min-h-[240px]", className), children: [
540
+ /* @__PURE__ */ jsxRuntime.jsx(EmptyIcon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BarChart3, { className: "size-10 text-muted-foreground" }) }),
541
+ /* @__PURE__ */ jsxRuntime.jsx(EmptyTitle, { children: emptyTitle }),
542
+ /* @__PURE__ */ jsxRuntime.jsx(EmptyDescription, { children: emptyDescription }),
543
+ onRetry ? /* @__PURE__ */ jsxRuntime.jsx(EmptyAction, { children: /* @__PURE__ */ jsxRuntime.jsxs(button.Button, { size: "sm", variant: "outline", onClick: onRetry, children: [
544
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.WifiOff, { className: "size-4" }),
545
+ retryLabel
546
+ ] }) }) : null
547
+ ] });
548
+ }
549
+ function getChartState(state, hasData, className) {
550
+ if (state.isLoading) {
551
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartState, { ...state, type: "loading", className });
552
+ }
553
+ if (state.error) {
554
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartState, { ...state, type: "error", className });
555
+ }
556
+ if (!hasData) {
557
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartState, { ...state, type: "empty", className });
558
+ }
559
+ return null;
560
+ }
561
+ function ChartCard({
562
+ title,
563
+ description,
564
+ action,
565
+ footer,
566
+ children,
567
+ className,
568
+ contentClassName,
569
+ ...props
570
+ }) {
571
+ return /* @__PURE__ */ jsxRuntime.jsxs(card.Card, { className: button.cn("w-full min-w-0 overflow-hidden", className), ...props, children: [
572
+ /* @__PURE__ */ jsxRuntime.jsxs(card.CardHeader, { children: [
573
+ /* @__PURE__ */ jsxRuntime.jsx(card.CardTitle, { children: title }),
574
+ description ? /* @__PURE__ */ jsxRuntime.jsx(card.CardDescription, { children: description }) : null,
575
+ action ? /* @__PURE__ */ jsxRuntime.jsx(card.CardAction, { children: action }) : null
576
+ ] }),
577
+ /* @__PURE__ */ jsxRuntime.jsx(card.CardContent, { className: contentClassName, children }),
578
+ footer ? /* @__PURE__ */ jsxRuntime.jsx(card.CardFooter, { children: footer }) : null
579
+ ] });
580
+ }
581
+ function AreaGradientDefs({
582
+ seriesKeys,
583
+ opacity = 0.3
584
+ }) {
585
+ return /* @__PURE__ */ jsxRuntime.jsx("defs", { children: seriesKeys.map((key) => /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: `gradient-${key}`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
586
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "5%", stopColor: `var(--color-${key})`, stopOpacity: opacity }),
587
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "95%", stopColor: `var(--color-${key})`, stopOpacity: 0 })
588
+ ] }, key)) });
589
+ }
590
+ function DashboardBarChart({
591
+ data,
592
+ config,
593
+ indexKey = "name",
594
+ series,
595
+ colors,
596
+ barSize = "md",
597
+ stacked = false,
598
+ showGrid = true,
599
+ showLegend = true,
600
+ valueFormatter = formatTick,
601
+ isLoading,
602
+ error,
603
+ onRetry,
604
+ retryLabel,
605
+ emptyTitle,
606
+ emptyDescription,
607
+ errorTitle,
608
+ errorDescription,
609
+ loadingLabel,
610
+ stateClassName,
611
+ className,
612
+ ...props
613
+ }) {
614
+ const chartSeries = getChartSeries(config, series);
615
+ const chartConfig = getChartConfigWithColors(
616
+ config,
617
+ chartSeries.map((item) => item.key),
618
+ colors
619
+ );
620
+ const chartState = getChartState(
621
+ {
622
+ isLoading,
623
+ error,
624
+ onRetry,
625
+ retryLabel,
626
+ emptyTitle,
627
+ emptyDescription,
628
+ errorTitle,
629
+ errorDescription,
630
+ loadingLabel
631
+ },
632
+ hasChartData(data, chartSeries),
633
+ button.cn("h-[320px] w-full", stateClassName)
634
+ );
635
+ const barElements = React__namespace.useMemo(() => {
636
+ const topOfStack = /* @__PURE__ */ new Set();
637
+ if (stacked) {
638
+ const lastByStack = /* @__PURE__ */ new Map();
639
+ chartSeries.forEach((s) => lastByStack.set(s.stackId || "total", s.key));
640
+ lastByStack.forEach((key) => topOfStack.add(key));
641
+ }
642
+ return chartSeries.map((item) => {
643
+ const isTop = !stacked || topOfStack.has(item.key);
644
+ return /* @__PURE__ */ jsxRuntime.jsx(
645
+ RechartsPrimitive__namespace.Bar,
646
+ {
647
+ dataKey: item.key,
648
+ fill: `var(--color-${item.key})`,
649
+ radius: isTop ? [4, 4, 0, 0] : [0, 0, 0, 0],
650
+ barSize: getBarSize(barSize),
651
+ stackId: stacked ? item.stackId || "total" : item.stackId,
652
+ isAnimationActive: true,
653
+ animationDuration: 600,
654
+ animationEasing: "ease-out"
655
+ },
656
+ item.key
657
+ );
658
+ });
659
+ }, [stacked, chartSeries]);
660
+ if (chartState) {
661
+ return chartState;
662
+ }
663
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartContainer, { config: chartConfig, className: button.cn("h-[320px] w-full", className), ...props, children: /* @__PURE__ */ jsxRuntime.jsxs(RechartsPrimitive__namespace.BarChart, { data, accessibilityLayer: true, barGap: 4, children: [
664
+ showGrid ? /* @__PURE__ */ jsxRuntime.jsx(
665
+ RechartsPrimitive__namespace.CartesianGrid,
666
+ {
667
+ vertical: false,
668
+ strokeDasharray: "3 3",
669
+ stroke: "var(--border)",
670
+ strokeOpacity: 0.5
671
+ }
672
+ ) : null,
673
+ /* @__PURE__ */ jsxRuntime.jsx(
674
+ RechartsPrimitive__namespace.XAxis,
675
+ {
676
+ dataKey: indexKey,
677
+ tickLine: false,
678
+ axisLine: false,
679
+ tickMargin: 8
680
+ }
681
+ ),
682
+ /* @__PURE__ */ jsxRuntime.jsx(
683
+ RechartsPrimitive__namespace.YAxis,
684
+ {
685
+ tickLine: false,
686
+ axisLine: false,
687
+ tickMargin: 8,
688
+ tickFormatter: valueFormatter
689
+ }
690
+ ),
691
+ /* @__PURE__ */ jsxRuntime.jsx(
692
+ ChartTooltip,
693
+ {
694
+ cursor: { fill: "var(--muted)", opacity: 0.4, radius: 4 },
695
+ content: /* @__PURE__ */ jsxRuntime.jsx(ChartTooltipContent, {})
696
+ }
697
+ ),
698
+ showLegend ? /* @__PURE__ */ jsxRuntime.jsx(ChartLegend, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartLegendContent, {}) }) : null,
699
+ barElements
700
+ ] }) });
701
+ }
702
+ function DashboardLineChart({
703
+ data,
704
+ config,
705
+ indexKey = "name",
706
+ series,
707
+ colors,
708
+ showDots = false,
709
+ showGrid = true,
710
+ showLegend = true,
711
+ curveType = "monotone",
712
+ strokeWidth = 2,
713
+ valueFormatter = formatTick,
714
+ isLoading,
715
+ error,
716
+ onRetry,
717
+ retryLabel,
718
+ emptyTitle,
719
+ emptyDescription,
720
+ errorTitle,
721
+ errorDescription,
722
+ loadingLabel,
723
+ stateClassName,
724
+ className,
725
+ ...props
726
+ }) {
727
+ const chartSeries = getChartSeries(config, series);
728
+ const chartConfig = getChartConfigWithColors(
729
+ config,
730
+ chartSeries.map((item) => item.key),
731
+ colors
732
+ );
733
+ const chartState = getChartState(
734
+ {
735
+ isLoading,
736
+ error,
737
+ onRetry,
738
+ retryLabel,
739
+ emptyTitle,
740
+ emptyDescription,
741
+ errorTitle,
742
+ errorDescription,
743
+ loadingLabel
744
+ },
745
+ hasChartData(data, chartSeries),
746
+ button.cn("h-[320px] w-full", stateClassName)
747
+ );
748
+ if (chartState) {
749
+ return chartState;
750
+ }
751
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartContainer, { config: chartConfig, className: button.cn("h-[320px] w-full", className), ...props, children: /* @__PURE__ */ jsxRuntime.jsxs(RechartsPrimitive__namespace.LineChart, { data, accessibilityLayer: true, children: [
752
+ showGrid ? /* @__PURE__ */ jsxRuntime.jsx(
753
+ RechartsPrimitive__namespace.CartesianGrid,
754
+ {
755
+ vertical: false,
756
+ strokeDasharray: "3 3",
757
+ stroke: "var(--border)",
758
+ strokeOpacity: 0.5
759
+ }
760
+ ) : null,
761
+ /* @__PURE__ */ jsxRuntime.jsx(
762
+ RechartsPrimitive__namespace.XAxis,
763
+ {
764
+ dataKey: indexKey,
765
+ tickLine: false,
766
+ axisLine: false,
767
+ tickMargin: 8
768
+ }
769
+ ),
770
+ /* @__PURE__ */ jsxRuntime.jsx(
771
+ RechartsPrimitive__namespace.YAxis,
772
+ {
773
+ tickLine: false,
774
+ axisLine: false,
775
+ tickMargin: 8,
776
+ tickFormatter: valueFormatter
777
+ }
778
+ ),
779
+ /* @__PURE__ */ jsxRuntime.jsx(ChartTooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartTooltipContent, { indicator: "line" }) }),
780
+ showLegend ? /* @__PURE__ */ jsxRuntime.jsx(ChartLegend, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartLegendContent, {}) }) : null,
781
+ chartSeries.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
782
+ RechartsPrimitive__namespace.Line,
783
+ {
784
+ type: curveType,
785
+ dataKey: item.key,
786
+ stroke: `var(--color-${item.key})`,
787
+ strokeWidth,
788
+ dot: showDots ? { r: 3, fill: `var(--color-${item.key})`, strokeWidth: 0 } : false,
789
+ activeDot: { r: 5, strokeWidth: 0 },
790
+ yAxisId: item.yAxisId,
791
+ isAnimationActive: true,
792
+ animationDuration: 600,
793
+ animationEasing: "ease-out"
794
+ },
795
+ item.key
796
+ ))
797
+ ] }) });
798
+ }
799
+ function HorizontalBarChart({
800
+ data,
801
+ config,
802
+ indexKey = "name",
803
+ series,
804
+ colors,
805
+ barSize = "md",
806
+ stacked = false,
807
+ categoryWidth = 96,
808
+ showGrid = true,
809
+ showLegend = true,
810
+ valueFormatter = formatTick,
811
+ isLoading,
812
+ error,
813
+ onRetry,
814
+ retryLabel,
815
+ emptyTitle,
816
+ emptyDescription,
817
+ errorTitle,
818
+ errorDescription,
819
+ loadingLabel,
820
+ stateClassName,
821
+ className,
822
+ ...props
823
+ }) {
824
+ const chartSeries = getChartSeries(config, series);
825
+ const chartConfig = getChartConfigWithColors(
826
+ config,
827
+ chartSeries.map((item) => item.key),
828
+ colors
829
+ );
830
+ const chartState = getChartState(
831
+ {
832
+ isLoading,
833
+ error,
834
+ onRetry,
835
+ retryLabel,
836
+ emptyTitle,
837
+ emptyDescription,
838
+ errorTitle,
839
+ errorDescription,
840
+ loadingLabel
841
+ },
842
+ hasChartData(data, chartSeries),
843
+ button.cn("h-[320px] w-full", stateClassName)
844
+ );
845
+ if (chartState) {
846
+ return chartState;
847
+ }
848
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartContainer, { config: chartConfig, className: button.cn("h-[320px] w-full", className), ...props, children: /* @__PURE__ */ jsxRuntime.jsxs(
849
+ RechartsPrimitive__namespace.BarChart,
850
+ {
851
+ data,
852
+ layout: "vertical",
853
+ accessibilityLayer: true,
854
+ margin: { left: 8, right: 16 },
855
+ children: [
856
+ showGrid ? /* @__PURE__ */ jsxRuntime.jsx(
857
+ RechartsPrimitive__namespace.CartesianGrid,
858
+ {
859
+ horizontal: false,
860
+ strokeDasharray: "3 3",
861
+ stroke: "var(--border)",
862
+ strokeOpacity: 0.5
863
+ }
864
+ ) : null,
865
+ /* @__PURE__ */ jsxRuntime.jsx(
866
+ RechartsPrimitive__namespace.XAxis,
867
+ {
868
+ type: "number",
869
+ tickLine: false,
870
+ axisLine: false,
871
+ tickMargin: 8,
872
+ tickFormatter: valueFormatter
873
+ }
874
+ ),
875
+ /* @__PURE__ */ jsxRuntime.jsx(
876
+ RechartsPrimitive__namespace.YAxis,
877
+ {
878
+ dataKey: indexKey,
879
+ type: "category",
880
+ tickLine: false,
881
+ axisLine: false,
882
+ tickMargin: 8,
883
+ width: categoryWidth
884
+ }
885
+ ),
886
+ /* @__PURE__ */ jsxRuntime.jsx(ChartTooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartTooltipContent, {}) }),
887
+ showLegend ? /* @__PURE__ */ jsxRuntime.jsx(ChartLegend, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartLegendContent, {}) }) : null,
888
+ chartSeries.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
889
+ RechartsPrimitive__namespace.Bar,
890
+ {
891
+ dataKey: item.key,
892
+ fill: `var(--color-${item.key})`,
893
+ radius: [0, 4, 4, 0],
894
+ barSize: getBarSize(barSize),
895
+ stackId: stacked ? item.stackId || "total" : item.stackId,
896
+ isAnimationActive: true,
897
+ animationDuration: 600,
898
+ animationEasing: "ease-out"
899
+ },
900
+ item.key
901
+ ))
902
+ ]
903
+ }
904
+ ) });
905
+ }
906
+ function InteractiveTimeSeriesChart({
907
+ data,
908
+ config,
909
+ indexKey = "date",
910
+ series,
911
+ colors,
912
+ periods = defaultPeriods,
913
+ defaultPeriod = ((_a) => (_a = periods[1]) == null ? void 0 : _a.value)() || ((_b) => (_b = periods[0]) == null ? void 0 : _b.value)() || "30d",
914
+ defaultSeries,
915
+ filterData = defaultFilterData,
916
+ showGrid = true,
917
+ showLegend = false,
918
+ showDots = false,
919
+ gradientFill = true,
920
+ curveType = "monotone",
921
+ strokeWidth = 2,
922
+ valueFormatter = formatTick,
923
+ isLoading,
924
+ error,
925
+ onRetry,
926
+ retryLabel,
927
+ emptyTitle,
928
+ emptyDescription,
929
+ errorTitle,
930
+ errorDescription,
931
+ loadingLabel,
932
+ stateClassName,
933
+ className,
934
+ ...props
935
+ }) {
936
+ var _a2;
937
+ const chartSeries = getChartSeries(config, series);
938
+ const chartConfig = getChartConfigWithColors(
939
+ config,
940
+ chartSeries.map((item) => item.key),
941
+ colors
942
+ );
943
+ const [period, setPeriod] = React__namespace.useState(defaultPeriod);
944
+ const [activeSeries, setActiveSeries] = React__namespace.useState(
945
+ defaultSeries || ((_a2 = chartSeries[0]) == null ? void 0 : _a2.key) || ""
946
+ );
947
+ const filteredData = React__namespace.useMemo(() => filterData(data, period), [data, filterData, period]);
948
+ const visibleSeries = chartSeries.length > 1 ? chartSeries.filter((item) => item.key === activeSeries) : chartSeries;
949
+ const chartState = getChartState(
950
+ {
951
+ isLoading,
952
+ error,
953
+ onRetry,
954
+ retryLabel,
955
+ emptyTitle,
956
+ emptyDescription,
957
+ errorTitle,
958
+ errorDescription,
959
+ loadingLabel
960
+ },
961
+ hasChartData(filteredData, visibleSeries),
962
+ button.cn("h-[320px] w-full", stateClassName)
963
+ );
964
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full space-y-4", children: [
965
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between", children: [
966
+ chartSeries.length > 1 ? /* @__PURE__ */ jsxRuntime.jsx(
967
+ "div",
968
+ {
969
+ className: "inline-flex h-10 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
970
+ role: "group",
971
+ "aria-label": "Selecionar metrica do grafico",
972
+ children: chartSeries.map((item) => {
973
+ var _a3;
974
+ const label = item.label || ((_a3 = config[item.key]) == null ? void 0 : _a3.label) || item.key;
975
+ return /* @__PURE__ */ jsxRuntime.jsx(
976
+ button.Button,
977
+ {
978
+ type: "button",
979
+ variant: "ghost",
980
+ size: "sm",
981
+ "aria-pressed": activeSeries === item.key,
982
+ onClick: () => setActiveSeries(item.key),
983
+ className: button.cn(
984
+ "h-8 px-3 text-sm font-medium transition-all",
985
+ activeSeries === item.key ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"
986
+ ),
987
+ children: label
988
+ },
989
+ item.key
990
+ );
991
+ })
992
+ }
993
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", {}),
994
+ /* @__PURE__ */ jsxRuntime.jsxs(select.Select, { value: period, onValueChange: setPeriod, children: [
995
+ /* @__PURE__ */ jsxRuntime.jsx(
996
+ select.SelectTrigger,
997
+ {
998
+ className: "w-full sm:w-[160px]",
999
+ size: "sm",
1000
+ "aria-label": "Selecionar periodo do grafico",
1001
+ children: /* @__PURE__ */ jsxRuntime.jsx(select.SelectValue, { placeholder: "Period" })
1002
+ }
1003
+ ),
1004
+ /* @__PURE__ */ jsxRuntime.jsx(select.SelectContent, { children: periods.map((item) => /* @__PURE__ */ jsxRuntime.jsx(select.SelectItem, { value: item.value, children: item.label }, item.value)) })
1005
+ ] })
1006
+ ] }),
1007
+ chartState || /* @__PURE__ */ jsxRuntime.jsx(
1008
+ ChartContainer,
1009
+ {
1010
+ config: chartConfig,
1011
+ className: button.cn("h-[320px] w-full", className),
1012
+ ...props,
1013
+ children: /* @__PURE__ */ jsxRuntime.jsxs(RechartsPrimitive__namespace.AreaChart, { data: filteredData, accessibilityLayer: true, children: [
1014
+ gradientFill && /* @__PURE__ */ jsxRuntime.jsx(AreaGradientDefs, { seriesKeys: visibleSeries.map((s) => s.key), opacity: 0.4 }),
1015
+ showGrid ? /* @__PURE__ */ jsxRuntime.jsx(
1016
+ RechartsPrimitive__namespace.CartesianGrid,
1017
+ {
1018
+ vertical: false,
1019
+ strokeDasharray: "3 3",
1020
+ stroke: "var(--border)",
1021
+ strokeOpacity: 0.5
1022
+ }
1023
+ ) : null,
1024
+ /* @__PURE__ */ jsxRuntime.jsx(
1025
+ RechartsPrimitive__namespace.XAxis,
1026
+ {
1027
+ dataKey: indexKey,
1028
+ tickLine: false,
1029
+ axisLine: false,
1030
+ tickMargin: 8
1031
+ }
1032
+ ),
1033
+ /* @__PURE__ */ jsxRuntime.jsx(
1034
+ RechartsPrimitive__namespace.YAxis,
1035
+ {
1036
+ tickLine: false,
1037
+ axisLine: false,
1038
+ tickMargin: 8,
1039
+ tickFormatter: valueFormatter
1040
+ }
1041
+ ),
1042
+ /* @__PURE__ */ jsxRuntime.jsx(ChartTooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartTooltipContent, { indicator: "line" }) }),
1043
+ showLegend ? /* @__PURE__ */ jsxRuntime.jsx(ChartLegend, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartLegendContent, {}) }) : null,
1044
+ visibleSeries.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
1045
+ RechartsPrimitive__namespace.Area,
1046
+ {
1047
+ type: curveType,
1048
+ dataKey: item.key,
1049
+ stroke: `var(--color-${item.key})`,
1050
+ fill: gradientFill ? `url(#gradient-${item.key})` : `var(--color-${item.key})`,
1051
+ fillOpacity: gradientFill ? 1 : 0.16,
1052
+ strokeWidth,
1053
+ dot: showDots ? { r: 3, fill: `var(--color-${item.key})`, strokeWidth: 0 } : false,
1054
+ activeDot: { r: 5, strokeWidth: 0 },
1055
+ isAnimationActive: true,
1056
+ animationDuration: 600,
1057
+ animationEasing: "ease-out"
1058
+ },
1059
+ item.key
1060
+ ))
1061
+ ] })
1062
+ }
1063
+ )
1064
+ ] });
1065
+ }
1066
+ function ComboMetricChart({
1067
+ data,
1068
+ config,
1069
+ indexKey = "name",
1070
+ series,
1071
+ colors,
1072
+ barSize = "md",
1073
+ showGrid = true,
1074
+ showLegend = true,
1075
+ gradientFill = false,
1076
+ curveType = "monotone",
1077
+ valueFormatter = formatTick,
1078
+ isLoading,
1079
+ error,
1080
+ onRetry,
1081
+ retryLabel,
1082
+ emptyTitle,
1083
+ emptyDescription,
1084
+ errorTitle,
1085
+ errorDescription,
1086
+ loadingLabel,
1087
+ stateClassName,
1088
+ className,
1089
+ ...props
1090
+ }) {
1091
+ const chartSeries = getChartSeries(config, series);
1092
+ const chartConfig = getChartConfigWithColors(
1093
+ config,
1094
+ chartSeries.map((item) => item.key),
1095
+ colors
1096
+ );
1097
+ const chartState = getChartState(
1098
+ {
1099
+ isLoading,
1100
+ error,
1101
+ onRetry,
1102
+ retryLabel,
1103
+ emptyTitle,
1104
+ emptyDescription,
1105
+ errorTitle,
1106
+ errorDescription,
1107
+ loadingLabel
1108
+ },
1109
+ hasChartData(data, chartSeries),
1110
+ button.cn("h-[340px] w-full", stateClassName)
1111
+ );
1112
+ if (chartState) {
1113
+ return chartState;
1114
+ }
1115
+ const areaSeries = gradientFill ? chartSeries.filter((s) => s.type === "area").map((s) => s.key) : [];
1116
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartContainer, { config: chartConfig, className: button.cn("h-[340px] w-full", className), ...props, children: /* @__PURE__ */ jsxRuntime.jsxs(RechartsPrimitive__namespace.ComposedChart, { data, accessibilityLayer: true, children: [
1117
+ gradientFill && areaSeries.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(AreaGradientDefs, { seriesKeys: areaSeries, opacity: 0.35 }),
1118
+ showGrid ? /* @__PURE__ */ jsxRuntime.jsx(
1119
+ RechartsPrimitive__namespace.CartesianGrid,
1120
+ {
1121
+ vertical: false,
1122
+ strokeDasharray: "3 3",
1123
+ stroke: "var(--border)",
1124
+ strokeOpacity: 0.5
1125
+ }
1126
+ ) : null,
1127
+ /* @__PURE__ */ jsxRuntime.jsx(
1128
+ RechartsPrimitive__namespace.XAxis,
1129
+ {
1130
+ dataKey: indexKey,
1131
+ tickLine: false,
1132
+ axisLine: false,
1133
+ tickMargin: 8
1134
+ }
1135
+ ),
1136
+ /* @__PURE__ */ jsxRuntime.jsx(
1137
+ RechartsPrimitive__namespace.YAxis,
1138
+ {
1139
+ tickLine: false,
1140
+ axisLine: false,
1141
+ tickMargin: 8,
1142
+ tickFormatter: valueFormatter
1143
+ }
1144
+ ),
1145
+ /* @__PURE__ */ jsxRuntime.jsx(ChartTooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartTooltipContent, {}) }),
1146
+ showLegend ? /* @__PURE__ */ jsxRuntime.jsx(ChartLegend, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartLegendContent, {}) }) : null,
1147
+ chartSeries.map(
1148
+ (item) => item.type === "line" ? /* @__PURE__ */ jsxRuntime.jsx(
1149
+ RechartsPrimitive__namespace.Line,
1150
+ {
1151
+ type: curveType,
1152
+ dataKey: item.key,
1153
+ stroke: `var(--color-${item.key})`,
1154
+ strokeWidth: 2,
1155
+ dot: false,
1156
+ activeDot: { r: 5, strokeWidth: 0 },
1157
+ yAxisId: item.yAxisId,
1158
+ isAnimationActive: true,
1159
+ animationDuration: 600,
1160
+ animationEasing: "ease-out"
1161
+ },
1162
+ item.key
1163
+ ) : item.type === "area" ? /* @__PURE__ */ jsxRuntime.jsx(
1164
+ RechartsPrimitive__namespace.Area,
1165
+ {
1166
+ type: curveType,
1167
+ dataKey: item.key,
1168
+ stroke: `var(--color-${item.key})`,
1169
+ fill: gradientFill ? `url(#gradient-${item.key})` : `var(--color-${item.key})`,
1170
+ fillOpacity: gradientFill ? 1 : 0.12,
1171
+ strokeWidth: 2,
1172
+ dot: false,
1173
+ activeDot: { r: 5, strokeWidth: 0 },
1174
+ yAxisId: item.yAxisId,
1175
+ isAnimationActive: true,
1176
+ animationDuration: 600,
1177
+ animationEasing: "ease-out"
1178
+ },
1179
+ item.key
1180
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1181
+ RechartsPrimitive__namespace.Bar,
1182
+ {
1183
+ dataKey: item.key,
1184
+ fill: `var(--color-${item.key})`,
1185
+ radius: [4, 4, 0, 0],
1186
+ barSize: getBarSize(barSize),
1187
+ yAxisId: item.yAxisId,
1188
+ isAnimationActive: true,
1189
+ animationDuration: 600,
1190
+ animationEasing: "ease-out"
1191
+ },
1192
+ item.key
1193
+ )
1194
+ )
1195
+ ] }) });
1196
+ }
1197
+ function DonutBreakdownChart({
1198
+ data,
1199
+ config,
1200
+ nameKey = "name",
1201
+ valueKey = "value",
1202
+ colors,
1203
+ centerLabel,
1204
+ centerValue,
1205
+ showLegend = true,
1206
+ innerRadius = "58%",
1207
+ outerRadius = "82%",
1208
+ isLoading,
1209
+ error,
1210
+ onRetry,
1211
+ retryLabel,
1212
+ emptyTitle,
1213
+ emptyDescription,
1214
+ errorTitle,
1215
+ errorDescription,
1216
+ loadingLabel,
1217
+ stateClassName,
1218
+ className,
1219
+ ...props
1220
+ }) {
1221
+ const [activeIndex, setActiveIndex] = React__namespace.useState(0);
1222
+ const chartKeys = data.map((entry, index) => String(entry[nameKey] || `segment-${index}`));
1223
+ const chartConfig = getChartConfigWithColors(config, chartKeys, colors);
1224
+ const chartState = getChartState(
1225
+ {
1226
+ isLoading,
1227
+ error,
1228
+ onRetry,
1229
+ retryLabel,
1230
+ emptyTitle,
1231
+ emptyDescription,
1232
+ errorTitle,
1233
+ errorDescription,
1234
+ loadingLabel
1235
+ },
1236
+ hasPieData(data, nameKey, valueKey),
1237
+ button.cn("h-[320px] w-full", stateClassName)
1238
+ );
1239
+ if (chartState) {
1240
+ return chartState;
1241
+ }
1242
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartContainer, { config: chartConfig, className: button.cn("h-[320px] w-full", className), ...props, children: /* @__PURE__ */ jsxRuntime.jsxs(RechartsPrimitive__namespace.PieChart, { accessibilityLayer: true, children: [
1243
+ /* @__PURE__ */ jsxRuntime.jsx(
1244
+ ChartTooltip,
1245
+ {
1246
+ cursor: false,
1247
+ content: /* @__PURE__ */ jsxRuntime.jsx(ChartTooltipContent, { hideLabel: true, nameKey })
1248
+ }
1249
+ ),
1250
+ showLegend ? /* @__PURE__ */ jsxRuntime.jsx(ChartLegend, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartLegendContent, { nameKey }), verticalAlign: "bottom" }) : null,
1251
+ /* @__PURE__ */ jsxRuntime.jsxs(
1252
+ RechartsPrimitive__namespace.Pie,
1253
+ {
1254
+ data,
1255
+ dataKey: valueKey,
1256
+ nameKey,
1257
+ innerRadius,
1258
+ outerRadius,
1259
+ paddingAngle: 3,
1260
+ activeIndex,
1261
+ onMouseEnter: (_, index) => setActiveIndex(index),
1262
+ isAnimationActive: true,
1263
+ animationDuration: 600,
1264
+ animationEasing: "ease-out",
1265
+ children: [
1266
+ data.map((entry, index) => {
1267
+ const key = String(entry[nameKey] || `segment-${index}`);
1268
+ return /* @__PURE__ */ jsxRuntime.jsx(
1269
+ RechartsPrimitive__namespace.Cell,
1270
+ {
1271
+ fill: `var(--color-${key})`,
1272
+ opacity: index === activeIndex ? 1 : 0.7,
1273
+ stroke: "transparent"
1274
+ },
1275
+ key
1276
+ );
1277
+ }),
1278
+ centerValue || centerLabel ? /* @__PURE__ */ jsxRuntime.jsx(
1279
+ RechartsPrimitive__namespace.Label,
1280
+ {
1281
+ position: "center",
1282
+ content: ({ viewBox }) => {
1283
+ if (!viewBox || !("cx" in viewBox) || !("cy" in viewBox)) {
1284
+ return null;
1285
+ }
1286
+ return /* @__PURE__ */ jsxRuntime.jsxs("text", { x: viewBox.cx, y: viewBox.cy, textAnchor: "middle", dominantBaseline: "middle", children: [
1287
+ centerValue ? /* @__PURE__ */ jsxRuntime.jsx(
1288
+ "tspan",
1289
+ {
1290
+ x: viewBox.cx,
1291
+ y: viewBox.cy,
1292
+ className: "fill-foreground text-2xl font-semibold",
1293
+ children: centerValue
1294
+ }
1295
+ ) : null,
1296
+ centerLabel ? /* @__PURE__ */ jsxRuntime.jsx(
1297
+ "tspan",
1298
+ {
1299
+ x: viewBox.cx,
1300
+ y: Number(viewBox.cy) + 22,
1301
+ className: "fill-muted-foreground text-xs",
1302
+ children: centerLabel
1303
+ }
1304
+ ) : null
1305
+ ] });
1306
+ }
1307
+ }
1308
+ ) : null
1309
+ ]
1310
+ }
1311
+ )
1312
+ ] }) });
1313
+ }
1314
+ function SparklineChart({
1315
+ data,
1316
+ dataKey,
1317
+ color = "var(--chart-1)",
1318
+ filled = true,
1319
+ showEndDot = true,
1320
+ curveType = "monotone",
1321
+ strokeWidth = 2,
1322
+ className
1323
+ }) {
1324
+ const sparkId = React__namespace.useId().replace(/:/g, "");
1325
+ const lastPoint = data[data.length - 1];
1326
+ const lastValue = lastPoint ? lastPoint[dataKey] : void 0;
1327
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: button.cn("relative h-12 w-full min-w-0", className), children: [
1328
+ /* @__PURE__ */ jsxRuntime.jsx(RechartsPrimitive__namespace.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(
1329
+ RechartsPrimitive__namespace.AreaChart,
1330
+ {
1331
+ data,
1332
+ margin: { top: 4, right: showEndDot ? 8 : 0, bottom: 0, left: 0 },
1333
+ children: [
1334
+ filled && /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: `spark-gradient-${sparkId}`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
1335
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "5%", stopColor: color, stopOpacity: 0.3 }),
1336
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "95%", stopColor: color, stopOpacity: 0 })
1337
+ ] }) }),
1338
+ /* @__PURE__ */ jsxRuntime.jsx(
1339
+ RechartsPrimitive__namespace.Area,
1340
+ {
1341
+ type: curveType,
1342
+ dataKey,
1343
+ stroke: color,
1344
+ strokeWidth,
1345
+ fill: filled ? `url(#spark-gradient-${sparkId})` : "none",
1346
+ fillOpacity: 1,
1347
+ dot: false,
1348
+ activeDot: false,
1349
+ isAnimationActive: true,
1350
+ animationDuration: 600,
1351
+ animationEasing: "ease-out"
1352
+ }
1353
+ )
1354
+ ]
1355
+ }
1356
+ ) }),
1357
+ showEndDot && lastValue !== void 0 && lastValue !== null && /* @__PURE__ */ jsxRuntime.jsx(
1358
+ "div",
1359
+ {
1360
+ className: "pointer-events-none absolute right-0 top-1/2 h-2.5 w-2.5 -translate-y-1/2 rounded-full ring-2 ring-background",
1361
+ style: { backgroundColor: color }
1362
+ }
1363
+ )
1364
+ ] });
1365
+ }
1366
+ function RadarMetricChart({
1367
+ data,
1368
+ labelKey,
1369
+ series,
1370
+ colors,
1371
+ filled = true,
1372
+ fillOpacity = 0.25,
1373
+ showDots = false,
1374
+ showGrid = true,
1375
+ showLegend,
1376
+ valueFormatter,
1377
+ isLoading,
1378
+ error,
1379
+ onRetry,
1380
+ retryLabel,
1381
+ emptyTitle,
1382
+ emptyDescription,
1383
+ errorTitle,
1384
+ errorDescription,
1385
+ loadingLabel,
1386
+ stateClassName,
1387
+ className
1388
+ }) {
1389
+ const chartConfig = React__namespace.useMemo(
1390
+ () => buildChartConfig(
1391
+ series.map((s) => s.key),
1392
+ colors
1393
+ ),
1394
+ [series, colors]
1395
+ );
1396
+ const hasData = data.length > 0 && series.length > 0;
1397
+ const chartState = getChartState(
1398
+ {
1399
+ isLoading,
1400
+ error,
1401
+ emptyTitle,
1402
+ emptyDescription,
1403
+ errorTitle,
1404
+ errorDescription,
1405
+ loadingLabel,
1406
+ stateClassName,
1407
+ onRetry,
1408
+ retryLabel
1409
+ },
1410
+ hasData
1411
+ );
1412
+ const displayLegend = showLegend ?? series.length > 1;
1413
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartContainer, { config: chartConfig, className: button.cn("h-[300px] w-full", className), children: chartState ?? /* @__PURE__ */ jsxRuntime.jsxs(RechartsPrimitive__namespace.RadarChart, { data, accessibilityLayer: true, children: [
1414
+ showGrid && /* @__PURE__ */ jsxRuntime.jsx(RechartsPrimitive__namespace.PolarGrid, { stroke: "var(--border)", strokeOpacity: 0.6 }),
1415
+ /* @__PURE__ */ jsxRuntime.jsx(
1416
+ RechartsPrimitive__namespace.PolarAngleAxis,
1417
+ {
1418
+ dataKey: labelKey,
1419
+ tick: { fill: "var(--muted-foreground)", fontSize: 12 }
1420
+ }
1421
+ ),
1422
+ /* @__PURE__ */ jsxRuntime.jsx(
1423
+ RechartsPrimitive__namespace.PolarRadiusAxis,
1424
+ {
1425
+ tick: false,
1426
+ axisLine: false,
1427
+ tickFormatter: valueFormatter
1428
+ }
1429
+ ),
1430
+ /* @__PURE__ */ jsxRuntime.jsx(
1431
+ ChartTooltip,
1432
+ {
1433
+ content: /* @__PURE__ */ jsxRuntime.jsx(
1434
+ ChartTooltipContent,
1435
+ {
1436
+ formatter: valueFormatter ? (v) => valueFormatter(v) : void 0
1437
+ }
1438
+ )
1439
+ }
1440
+ ),
1441
+ displayLegend && /* @__PURE__ */ jsxRuntime.jsx(ChartLegend, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartLegendContent, {}) }),
1442
+ series.map((s) => /* @__PURE__ */ jsxRuntime.jsx(
1443
+ RechartsPrimitive__namespace.Radar,
1444
+ {
1445
+ name: s.label ?? s.key,
1446
+ dataKey: s.key,
1447
+ stroke: `var(--color-${s.key})`,
1448
+ fill: filled ? `var(--color-${s.key})` : "none",
1449
+ fillOpacity: filled ? fillOpacity : 0,
1450
+ dot: showDots ? { r: 3, fill: `var(--color-${s.key})` } : false,
1451
+ isAnimationActive: true,
1452
+ animationDuration: 600,
1453
+ animationEasing: "ease-out"
1454
+ },
1455
+ s.key
1456
+ ))
1457
+ ] }) });
1458
+ }
1459
+ function PieMetricChart({
1460
+ data,
1461
+ nameKey,
1462
+ valueKey,
1463
+ colors,
1464
+ outerRadius = "80%",
1465
+ innerRadius = 0,
1466
+ showLabels = false,
1467
+ showLegend = true,
1468
+ explodeIndex,
1469
+ explodeOffset = 12,
1470
+ valueFormatter,
1471
+ isLoading,
1472
+ error,
1473
+ onRetry,
1474
+ retryLabel,
1475
+ emptyTitle,
1476
+ emptyDescription,
1477
+ errorTitle,
1478
+ errorDescription,
1479
+ loadingLabel,
1480
+ stateClassName,
1481
+ className
1482
+ }) {
1483
+ const names = React__namespace.useMemo(() => data.map((d) => String(d[nameKey] ?? "")), [data, nameKey]);
1484
+ const chartConfig = React__namespace.useMemo(() => buildChartConfig(names, colors), [names, colors]);
1485
+ const hasData = hasPieData(data, nameKey, valueKey);
1486
+ const chartState = getChartState(
1487
+ {
1488
+ isLoading,
1489
+ error,
1490
+ emptyTitle,
1491
+ emptyDescription,
1492
+ errorTitle,
1493
+ errorDescription,
1494
+ loadingLabel,
1495
+ stateClassName,
1496
+ onRetry,
1497
+ retryLabel
1498
+ },
1499
+ hasData
1500
+ );
1501
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartContainer, { config: chartConfig, className: button.cn("h-[300px] w-full", className), children: chartState ?? /* @__PURE__ */ jsxRuntime.jsxs(RechartsPrimitive__namespace.PieChart, { accessibilityLayer: true, children: [
1502
+ /* @__PURE__ */ jsxRuntime.jsx(
1503
+ ChartTooltip,
1504
+ {
1505
+ content: /* @__PURE__ */ jsxRuntime.jsx(
1506
+ ChartTooltipContent,
1507
+ {
1508
+ nameKey,
1509
+ formatter: valueFormatter ? (v) => valueFormatter(v) : void 0
1510
+ }
1511
+ )
1512
+ }
1513
+ ),
1514
+ showLegend && /* @__PURE__ */ jsxRuntime.jsx(ChartLegend, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartLegendContent, { nameKey }) }),
1515
+ /* @__PURE__ */ jsxRuntime.jsx(
1516
+ RechartsPrimitive__namespace.Pie,
1517
+ {
1518
+ data,
1519
+ dataKey: valueKey,
1520
+ nameKey,
1521
+ outerRadius,
1522
+ innerRadius,
1523
+ paddingAngle: 2,
1524
+ label: showLabels ? ({ cx, cy, midAngle, innerRadius: ir, outerRadius: or, percent }) => {
1525
+ const RADIAN = Math.PI / 180;
1526
+ const radius = Number(ir) + (Number(or) - Number(ir)) * 1.35;
1527
+ const x = Number(cx) + radius * Math.cos(-midAngle * RADIAN);
1528
+ const y = Number(cy) + radius * Math.sin(-midAngle * RADIAN);
1529
+ return percent > 0.04 ? /* @__PURE__ */ jsxRuntime.jsx(
1530
+ "text",
1531
+ {
1532
+ x,
1533
+ y,
1534
+ fill: "var(--foreground)",
1535
+ textAnchor: x > Number(cx) ? "start" : "end",
1536
+ dominantBaseline: "central",
1537
+ fontSize: 12,
1538
+ fontWeight: 500,
1539
+ children: `${(percent * 100).toFixed(0)}%`
1540
+ }
1541
+ ) : null;
1542
+ } : false,
1543
+ labelLine: false,
1544
+ isAnimationActive: true,
1545
+ animationDuration: 600,
1546
+ animationEasing: "ease-out",
1547
+ children: data.map((entry, index) => {
1548
+ var _a, _b;
1549
+ const name = String(entry[nameKey] ?? "");
1550
+ const isExploded = index === explodeIndex;
1551
+ return /* @__PURE__ */ jsxRuntime.jsx(
1552
+ RechartsPrimitive__namespace.Cell,
1553
+ {
1554
+ fill: ((_a = chartConfig[name]) == null ? void 0 : _a.color) ?? `var(--chart-${index % 8 + 1})`,
1555
+ stroke: "var(--background)",
1556
+ strokeWidth: 2,
1557
+ style: isExploded ? {
1558
+ filter: `drop-shadow(0 4px 8px color-mix(in srgb, ${((_b = chartConfig[name]) == null ? void 0 : _b.color) ?? "var(--chart-1)"} 40%, transparent))`
1559
+ } : void 0
1560
+ },
1561
+ `cell-${index}`
1562
+ );
1563
+ })
1564
+ }
1565
+ )
1566
+ ] }) });
1567
+ }
1568
+ function RadialBarMetricChart({
1569
+ data,
1570
+ dataKey = "value",
1571
+ nameKey = "name",
1572
+ colors,
1573
+ innerRadius = "30%",
1574
+ outerRadius = "100%",
1575
+ startAngle = 90,
1576
+ endAngle = -270,
1577
+ showBackground = true,
1578
+ showLegend = true,
1579
+ valueFormatter,
1580
+ isLoading,
1581
+ error,
1582
+ onRetry,
1583
+ retryLabel,
1584
+ emptyTitle,
1585
+ emptyDescription,
1586
+ errorTitle,
1587
+ errorDescription,
1588
+ loadingLabel,
1589
+ stateClassName,
1590
+ className
1591
+ }) {
1592
+ const names = React__namespace.useMemo(() => data.map((d) => String(d[nameKey] ?? "")), [data, nameKey]);
1593
+ const chartConfig = React__namespace.useMemo(() => buildChartConfig(names, colors), [names, colors]);
1594
+ const hasData = data.length > 0;
1595
+ const chartState = getChartState(
1596
+ {
1597
+ isLoading,
1598
+ error,
1599
+ emptyTitle,
1600
+ emptyDescription,
1601
+ errorTitle,
1602
+ errorDescription,
1603
+ loadingLabel,
1604
+ stateClassName,
1605
+ onRetry,
1606
+ retryLabel
1607
+ },
1608
+ hasData
1609
+ );
1610
+ const coloredData = React__namespace.useMemo(
1611
+ () => data.map((item, index) => {
1612
+ var _a;
1613
+ const name = String(item[nameKey] ?? "");
1614
+ return {
1615
+ ...item,
1616
+ fill: ((_a = chartConfig[name]) == null ? void 0 : _a.color) ?? `var(--chart-${index % 8 + 1})`
1617
+ };
1618
+ }),
1619
+ [data, nameKey, chartConfig]
1620
+ );
1621
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: button.cn("flex w-full flex-col gap-3", className), children: [
1622
+ /* @__PURE__ */ jsxRuntime.jsx(ChartContainer, { config: chartConfig, className: "h-[260px] w-full", children: chartState ?? /* @__PURE__ */ jsxRuntime.jsxs(
1623
+ RechartsPrimitive__namespace.RadialBarChart,
1624
+ {
1625
+ data: coloredData,
1626
+ innerRadius,
1627
+ outerRadius,
1628
+ startAngle,
1629
+ endAngle,
1630
+ accessibilityLayer: true,
1631
+ children: [
1632
+ /* @__PURE__ */ jsxRuntime.jsx(
1633
+ ChartTooltip,
1634
+ {
1635
+ cursor: false,
1636
+ content: /* @__PURE__ */ jsxRuntime.jsx(
1637
+ ChartTooltipContent,
1638
+ {
1639
+ nameKey,
1640
+ formatter: valueFormatter ? (v) => valueFormatter(v) : void 0
1641
+ }
1642
+ )
1643
+ }
1644
+ ),
1645
+ /* @__PURE__ */ jsxRuntime.jsx(
1646
+ RechartsPrimitive__namespace.RadialBar,
1647
+ {
1648
+ dataKey,
1649
+ background: showBackground ? { fill: "var(--muted)" } : false,
1650
+ cornerRadius: 6,
1651
+ isAnimationActive: true,
1652
+ animationDuration: 700,
1653
+ animationEasing: "ease-out"
1654
+ }
1655
+ )
1656
+ ]
1657
+ }
1658
+ ) }),
1659
+ showLegend && !chartState && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap justify-center gap-x-4 gap-y-1.5 px-2", children: coloredData.map((item, index) => {
1660
+ const d = item;
1661
+ const name = String(d[nameKey] ?? "");
1662
+ const fillColor = d.fill ?? `var(--chart-${index % 8 + 1})`;
1663
+ const val = d[dataKey];
1664
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
1665
+ /* @__PURE__ */ jsxRuntime.jsx(
1666
+ "span",
1667
+ {
1668
+ className: "inline-block h-2.5 w-2.5 shrink-0 rounded-full",
1669
+ style: { backgroundColor: fillColor }
1670
+ }
1671
+ ),
1672
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
1673
+ name,
1674
+ val !== void 0 && val !== null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 font-medium text-foreground", children: valueFormatter ? valueFormatter(val) : String(val) })
1675
+ ] })
1676
+ ] }, name);
1677
+ }) })
1678
+ ] });
1679
+ }
1680
+ function GaugeChart({
1681
+ value,
1682
+ min = 0,
1683
+ max = 100,
1684
+ thresholds,
1685
+ label,
1686
+ valueFormatter,
1687
+ showNeedle = true,
1688
+ className
1689
+ }) {
1690
+ const percent = Math.min(1, Math.max(0, (value - min) / (max - min)));
1691
+ const percentInt = Math.round(percent * 100);
1692
+ const activeColor = React__namespace.useMemo(() => {
1693
+ if (!thresholds || thresholds.length === 0) return "var(--chart-1)";
1694
+ for (const t of thresholds) {
1695
+ if (percentInt <= t.value) return t.color;
1696
+ }
1697
+ return thresholds[thresholds.length - 1].color;
1698
+ }, [thresholds, percentInt]);
1699
+ const displayText = valueFormatter ? valueFormatter(value, percentInt) : `${percentInt}%`;
1700
+ const cx = 100;
1701
+ const cy = 100;
1702
+ const R = 80;
1703
+ const r = 54;
1704
+ const polar = (angleDeg, radius) => {
1705
+ const rad = angleDeg * Math.PI / 180;
1706
+ return {
1707
+ x: cx + radius * Math.cos(rad),
1708
+ y: cy - radius * Math.sin(rad)
1709
+ };
1710
+ };
1711
+ const trackStart = polar(180, R);
1712
+ const trackEnd = polar(0, R);
1713
+ const trackStartI = polar(180, r);
1714
+ const trackEndI = polar(0, r);
1715
+ const trackPath = [
1716
+ `M ${trackStart.x} ${trackStart.y}`,
1717
+ `A ${R} ${R} 0 0 1 ${trackEnd.x} ${trackEnd.y}`,
1718
+ `L ${trackEndI.x} ${trackEndI.y}`,
1719
+ `A ${r} ${r} 0 0 0 ${trackStartI.x} ${trackStartI.y}`,
1720
+ "Z"
1721
+ ].join(" ");
1722
+ const valueAngle = 180 - percent * 180;
1723
+ const valueEnd = polar(valueAngle, R);
1724
+ const valueEndI = polar(valueAngle, r);
1725
+ const valuePath = percent <= 0 ? "" : percent >= 1 ? trackPath : [
1726
+ `M ${trackStart.x} ${trackStart.y}`,
1727
+ `A ${R} ${R} 0 0 1 ${valueEnd.x} ${valueEnd.y}`,
1728
+ `L ${valueEndI.x} ${valueEndI.y}`,
1729
+ `A ${r} ${r} 0 0 0 ${trackStartI.x} ${trackStartI.y}`,
1730
+ "Z"
1731
+ ].join(" ");
1732
+ const needleAngle = 180 - percent * 180;
1733
+ const needleTip = polar(needleAngle, r - 6);
1734
+ const needleBase1 = polar(needleAngle + 90, 5);
1735
+ const needleBase2 = polar(needleAngle - 90, 5);
1736
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: button.cn("flex flex-col items-center gap-2", className), children: [
1737
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative w-full max-w-[260px]", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 200 130", className: "w-full", "aria-label": `Gauge: ${displayText}`, children: [
1738
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: trackPath, fill: "var(--muted)" }),
1739
+ valuePath && /* @__PURE__ */ jsxRuntime.jsx("path", { d: valuePath, fill: activeColor }),
1740
+ showNeedle && /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
1741
+ /* @__PURE__ */ jsxRuntime.jsx(
1742
+ "polygon",
1743
+ {
1744
+ points: `${needleTip.x},${needleTip.y} ${needleBase1.x},${needleBase1.y} ${needleBase2.x},${needleBase2.y}`,
1745
+ fill: "var(--foreground)",
1746
+ opacity: 0.85
1747
+ }
1748
+ ),
1749
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx, cy, r: 5, fill: "var(--foreground)" })
1750
+ ] }),
1751
+ /* @__PURE__ */ jsxRuntime.jsx(
1752
+ "text",
1753
+ {
1754
+ x: cx,
1755
+ y: cy + 18,
1756
+ textAnchor: "middle",
1757
+ dominantBaseline: "middle",
1758
+ fontSize: 22,
1759
+ fontWeight: 700,
1760
+ fill: "currentColor",
1761
+ className: "fill-foreground",
1762
+ children: displayText
1763
+ }
1764
+ ),
1765
+ label && /* @__PURE__ */ jsxRuntime.jsx(
1766
+ "text",
1767
+ {
1768
+ x: cx,
1769
+ y: cy + 36,
1770
+ textAnchor: "middle",
1771
+ dominantBaseline: "middle",
1772
+ fontSize: 10,
1773
+ fill: "currentColor",
1774
+ className: "fill-muted-foreground",
1775
+ children: label
1776
+ }
1777
+ )
1778
+ ] }) }),
1779
+ thresholds && thresholds.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap justify-center gap-x-3 gap-y-1", children: thresholds.map((t, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
1780
+ /* @__PURE__ */ jsxRuntime.jsx(
1781
+ "span",
1782
+ {
1783
+ className: "inline-block h-2 w-2 shrink-0 rounded-full",
1784
+ style: { backgroundColor: t.color }
1785
+ }
1786
+ ),
1787
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: t.label })
1788
+ ] }, i)) })
1789
+ ] });
1790
+ }
1791
+ function Table({ className, ...props }) {
1792
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "table-container", className: "relative w-full overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
1793
+ "table",
1794
+ {
1795
+ "data-slot": "table",
1796
+ className: button.cn("w-full caption-bottom text-sm", className),
1797
+ ...props
1798
+ }
1799
+ ) });
1800
+ }
1801
+ function TableHeader({ className, ...props }) {
1802
+ return /* @__PURE__ */ jsxRuntime.jsx("thead", { "data-slot": "table-header", className: button.cn("[&_tr]:border-b", className), ...props });
1803
+ }
1804
+ function TableBody({ className, ...props }) {
1805
+ return /* @__PURE__ */ jsxRuntime.jsx(
1806
+ "tbody",
1807
+ {
1808
+ "data-slot": "table-body",
1809
+ className: button.cn("[&_tr:last-child]:border-0", className),
1810
+ ...props
1811
+ }
1812
+ );
1813
+ }
1814
+ function TableFooter({ className, ...props }) {
1815
+ return /* @__PURE__ */ jsxRuntime.jsx(
1816
+ "tfoot",
1817
+ {
1818
+ "data-slot": "table-footer",
1819
+ className: button.cn("bg-muted/50 border-t font-medium [&>tr]:last:border-b-0", className),
1820
+ ...props
1821
+ }
1822
+ );
1823
+ }
1824
+ function TableRow({ className, ...props }) {
1825
+ return /* @__PURE__ */ jsxRuntime.jsx(
1826
+ "tr",
1827
+ {
1828
+ "data-slot": "table-row",
1829
+ className: button.cn(
1830
+ "hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors",
1831
+ className
1832
+ ),
1833
+ ...props
1834
+ }
1835
+ );
1836
+ }
1837
+ function TableHead({ className, ...props }) {
1838
+ return /* @__PURE__ */ jsxRuntime.jsx(
1839
+ "th",
1840
+ {
1841
+ "data-slot": "table-head",
1842
+ className: button.cn(
1843
+ "text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
1844
+ className
1845
+ ),
1846
+ ...props
1847
+ }
1848
+ );
1849
+ }
1850
+ function TableCell({ className, ...props }) {
1851
+ return /* @__PURE__ */ jsxRuntime.jsx(
1852
+ "td",
1853
+ {
1854
+ "data-slot": "table-cell",
1855
+ className: button.cn(
1856
+ "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
1857
+ className
1858
+ ),
1859
+ ...props
1860
+ }
1861
+ );
1862
+ }
1863
+ function TableCaption({ className, ...props }) {
1864
+ return /* @__PURE__ */ jsxRuntime.jsx(
1865
+ "caption",
1866
+ {
1867
+ "data-slot": "table-caption",
1868
+ className: button.cn("text-muted-foreground mt-4 text-sm", className),
1869
+ ...props
1870
+ }
1871
+ );
1872
+ }
1873
+ const Textarea = React__namespace.forwardRef(
1874
+ ({ className, size = "md", ...props }, ref) => {
1875
+ const sizeClasses = {
1876
+ sm: "px-2 py-1 text-sm",
1877
+ md: "px-3 py-2 text-base",
1878
+ lg: "px-4 py-3 text-base"
1879
+ };
1880
+ return /* @__PURE__ */ jsxRuntime.jsx(
1881
+ "textarea",
1882
+ {
1883
+ "data-slot": "textarea",
1884
+ className: button.cn(
1885
+ "flex min-h-16 w-full bg-background rounded-[var(--radius)] border border-border transition-colors outline-none resize-none text-foreground",
1886
+ "placeholder:text-muted-foreground",
1887
+ "focus:ring-2 focus:ring-primary focus:border-transparent",
1888
+ "disabled:cursor-not-allowed disabled:opacity-50",
1889
+ sizeClasses[size],
1890
+ className
1891
+ ),
1892
+ ref,
1893
+ ...props
1894
+ }
1895
+ );
1896
+ }
1897
+ );
1898
+ Textarea.displayName = "Textarea";
1899
+ function Dialog({ ...props }) {
1900
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Root, { "data-slot": "dialog", ...props });
1901
+ }
1902
+ function DialogTrigger({ ...props }) {
1903
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Trigger, { "data-slot": "dialog-trigger", ...props });
1904
+ }
1905
+ function DialogPortal({ ...props }) {
1906
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Portal, { "data-slot": "dialog-portal", ...props });
1907
+ }
1908
+ function DialogClose({ ...props }) {
1909
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Close, { "data-slot": "dialog-close", ...props });
1910
+ }
1911
+ const DialogOverlay = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
1912
+ DialogPrimitive__namespace.Overlay,
1913
+ {
1914
+ ref,
1915
+ "data-slot": "dialog-overlay",
1916
+ className: button.cn(
1917
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/40 backdrop-blur-sm",
1918
+ className
1919
+ ),
1920
+ ...props
1921
+ }
1922
+ ));
1923
+ DialogOverlay.displayName = DialogPrimitive__namespace.Overlay.displayName;
1924
+ const dialogVariants = classVarianceAuthority.cva(
1925
+ "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 flex flex-col w-full translate-x-[-50%] translate-y-[-50%] border shadow-elevation-sm duration-200 rounded-[var(--radius-card)] overflow-hidden max-h-[calc(100dvh-2rem)]",
1926
+ {
1927
+ variants: {
1928
+ size: {
1929
+ sm: "max-w-sm",
1930
+ md: "max-w-md",
1931
+ lg: "max-w-lg",
1932
+ xl: "max-w-xl",
1933
+ "2xl": "max-w-2xl",
1934
+ "3xl": "max-w-3xl",
1935
+ "4xl": "max-w-4xl",
1936
+ "5xl": "max-w-5xl",
1937
+ full: "max-w-[calc(100vw-2rem)] h-[calc(100dvh-2rem)]"
1938
+ }
1939
+ },
1940
+ defaultVariants: {
1941
+ size: "lg"
1942
+ }
1943
+ }
1944
+ );
1945
+ const DialogContent = React__namespace.forwardRef(({ className, children, size, showClose = true, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { "data-slot": "dialog-portal", children: [
1946
+ /* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
1947
+ /* @__PURE__ */ jsxRuntime.jsxs(
1948
+ DialogPrimitive__namespace.Content,
1949
+ {
1950
+ ref,
1951
+ "data-slot": "dialog-content",
1952
+ className: button.cn(dialogVariants({ size }), className),
1953
+ ...props,
1954
+ children: [
1955
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4 p-6 overflow-y-auto flex-1 min-h-0", children }),
1956
+ showClose && /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { className: "absolute top-4 right-4 z-10 rounded-full p-2 opacity-70 transition-all hover:opacity-100 hover:bg-accent focus:ring-2 focus:ring-primary focus:ring-offset-2 focus:outline-none disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", children: [
1957
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, {}),
1958
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
1959
+ ] })
1960
+ ]
1961
+ }
1962
+ )
1963
+ ] }));
1964
+ DialogContent.displayName = DialogPrimitive__namespace.Content.displayName;
1965
+ function DialogHeader({ className, ...props }) {
1966
+ return /* @__PURE__ */ jsxRuntime.jsx(
1967
+ "div",
1968
+ {
1969
+ "data-slot": "dialog-header",
1970
+ className: button.cn("flex flex-col gap-2 text-left shrink-0", className),
1971
+ ...props
1972
+ }
1973
+ );
1974
+ }
1975
+ function DialogBody({ className, ...props }) {
1976
+ return /* @__PURE__ */ jsxRuntime.jsx(
1977
+ "div",
1978
+ {
1979
+ "data-slot": "dialog-body",
1980
+ className: button.cn("flex-1 overflow-y-auto min-h-0 -mx-6 px-6", className),
1981
+ ...props
1982
+ }
1983
+ );
1984
+ }
1985
+ function DialogFooter({ className, ...props }) {
1986
+ return /* @__PURE__ */ jsxRuntime.jsx(
1987
+ "div",
1988
+ {
1989
+ "data-slot": "dialog-footer",
1990
+ className: button.cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end shrink-0", className),
1991
+ ...props
1992
+ }
1993
+ );
1994
+ }
1995
+ function DialogTitle({ className, ...props }) {
1996
+ return /* @__PURE__ */ jsxRuntime.jsx(
1997
+ DialogPrimitive__namespace.Title,
1998
+ {
1999
+ "data-slot": "dialog-title",
2000
+ className: button.cn(
2001
+ "text-foreground font-semibold leading-tight text-[length:var(--text-h4)]",
2002
+ className
2003
+ ),
2004
+ ...props
2005
+ }
2006
+ );
2007
+ }
2008
+ function DialogDescription({
2009
+ className,
2010
+ ...props
2011
+ }) {
2012
+ return /* @__PURE__ */ jsxRuntime.jsx(
2013
+ DialogPrimitive__namespace.Description,
2014
+ {
2015
+ "data-slot": "dialog-description",
2016
+ className: button.cn("text-muted-foreground", className),
2017
+ ...props
2018
+ }
2019
+ );
2020
+ }
2021
+ function useRichTextEditor({
2022
+ value,
2023
+ onChange
2024
+ }) {
2025
+ const editorRef = React.useRef(null);
2026
+ const searchInputRef = React.useRef(null);
2027
+ const linkInputRef = React.useRef(null);
2028
+ const savedSelection = React.useRef(null);
2029
+ const [wordCount, setWordCount] = React.useState(0);
2030
+ const [characterCount, setCharacterCount] = React.useState(0);
2031
+ const [activeFormats, setActiveFormats] = React.useState({
2032
+ bold: false,
2033
+ italic: false,
2034
+ underline: false,
2035
+ justifyLeft: false,
2036
+ justifyCenter: false,
2037
+ justifyRight: false,
2038
+ insertUnorderedList: false,
2039
+ insertOrderedList: false,
2040
+ link: false,
2041
+ h1: false,
2042
+ h2: false,
2043
+ h3: false,
2044
+ p: true
2045
+ });
2046
+ const [isSearchOpen, setIsSearchOpen] = React.useState(false);
2047
+ const [searchQuery, setSearchQuery] = React.useState("");
2048
+ const [linkUrl, setLinkUrl] = React.useState("https://");
2049
+ const [isLinkOpen, setIsLinkOpen] = React.useState(false);
2050
+ const [hasSavedSelection, setHasSavedSelection] = React.useState(false);
2051
+ const findParentTag = React.useCallback((node, tagName) => {
2052
+ let current = node;
2053
+ while (current && current !== editorRef.current) {
2054
+ if (current.nodeName === tagName) return current;
2055
+ current = current.parentNode;
2056
+ }
2057
+ return null;
2058
+ }, []);
2059
+ const updateActiveFormats = React.useCallback(() => {
2060
+ let formatBlock = "";
2061
+ try {
2062
+ formatBlock = document.queryCommandValue("formatBlock");
2063
+ } catch (_e) {
2064
+ }
2065
+ const selection = window.getSelection();
2066
+ const anchorNode = selection == null ? void 0 : selection.anchorNode;
2067
+ const focusNode = selection == null ? void 0 : selection.focusNode;
2068
+ setActiveFormats({
2069
+ bold: document.queryCommandState("bold"),
2070
+ italic: document.queryCommandState("italic"),
2071
+ underline: document.queryCommandState("underline"),
2072
+ justifyLeft: document.queryCommandState("justifyLeft"),
2073
+ justifyCenter: document.queryCommandState("justifyCenter"),
2074
+ justifyRight: document.queryCommandState("justifyRight"),
2075
+ insertUnorderedList: document.queryCommandState("insertUnorderedList"),
2076
+ insertOrderedList: document.queryCommandState("insertOrderedList"),
2077
+ link: !!(findParentTag(anchorNode || null, "A") || findParentTag(focusNode || null, "A")),
2078
+ h1: formatBlock === "h1" || formatBlock === "H1",
2079
+ h2: formatBlock === "h2" || formatBlock === "H2",
2080
+ h3: formatBlock === "h3" || formatBlock === "H3",
2081
+ p: formatBlock === "p" || formatBlock === "P" || formatBlock === "div" || formatBlock === "DIV" || formatBlock === ""
2082
+ });
2083
+ }, [findParentTag]);
2084
+ const updateActiveFormatsRef = React.useRef(updateActiveFormats);
2085
+ React.useEffect(() => {
2086
+ updateActiveFormatsRef.current = updateActiveFormats;
2087
+ }, [updateActiveFormats]);
2088
+ React.useEffect(() => {
2089
+ if (editorRef.current && editorRef.current.innerHTML !== value) {
2090
+ editorRef.current.innerHTML = value;
2091
+ }
2092
+ const handleSelectionChange = () => {
2093
+ if (document.activeElement === editorRef.current) {
2094
+ updateActiveFormatsRef.current();
2095
+ }
2096
+ };
2097
+ document.addEventListener("selectionchange", handleSelectionChange);
2098
+ return () => document.removeEventListener("selectionchange", handleSelectionChange);
2099
+ }, []);
2100
+ React.useEffect(() => {
2101
+ var _a;
2102
+ const text = ((_a = editorRef.current) == null ? void 0 : _a.innerText) || "";
2103
+ setWordCount(text.trim() ? text.trim().split(/\s+/).length : 0);
2104
+ setCharacterCount(text.trim() ? text.length : 0);
2105
+ }, [value]);
2106
+ const handleInput = React.useCallback(() => {
2107
+ if (editorRef.current) {
2108
+ onChange == null ? void 0 : onChange(editorRef.current.innerHTML);
2109
+ updateActiveFormats();
2110
+ const text = editorRef.current.innerText || "";
2111
+ setWordCount(text.trim() ? text.trim().split(/\s+/).length : 0);
2112
+ setCharacterCount(text.trim() ? text.length : 0);
2113
+ }
2114
+ }, [onChange, updateActiveFormats]);
2115
+ const execCommand = React.useCallback(
2116
+ (command, val = "") => {
2117
+ var _a;
2118
+ document.execCommand(command, false, val);
2119
+ updateActiveFormats();
2120
+ (_a = editorRef.current) == null ? void 0 : _a.focus();
2121
+ if (editorRef.current) {
2122
+ onChange == null ? void 0 : onChange(editorRef.current.innerHTML);
2123
+ }
2124
+ },
2125
+ [onChange, updateActiveFormats]
2126
+ );
2127
+ const performSearch = React.useCallback((text, backward = false) => {
2128
+ var _a, _b;
2129
+ if (!text || !editorRef.current) return;
2130
+ const editor = editorRef.current;
2131
+ const selection = window.getSelection();
2132
+ if (!selection) return;
2133
+ const walker = document.createTreeWalker(editor, NodeFilter.SHOW_TEXT);
2134
+ const segments = [];
2135
+ let offset = 0;
2136
+ let node;
2137
+ while (node = walker.nextNode()) {
2138
+ segments.push({ node, start: offset });
2139
+ offset += node.length;
2140
+ }
2141
+ const fullText = segments.reduce((acc, s) => acc + (s.node.textContent ?? ""), "");
2142
+ let searchFrom = 0;
2143
+ if (selection.rangeCount > 0) {
2144
+ const range2 = selection.getRangeAt(0);
2145
+ if (editor.contains(range2.startContainer)) {
2146
+ const seg = segments.find((s) => s.node === range2.startContainer);
2147
+ if (seg) {
2148
+ searchFrom = backward ? seg.start + range2.startOffset - 1 : seg.start + range2.endOffset;
2149
+ }
2150
+ }
2151
+ }
2152
+ const lowerFull = fullText.toLowerCase();
2153
+ const lowerQuery = text.toLowerCase();
2154
+ let matchStart = -1;
2155
+ if (backward) {
2156
+ matchStart = lowerFull.lastIndexOf(lowerQuery, Math.max(0, searchFrom));
2157
+ if (matchStart === -1) matchStart = lowerFull.lastIndexOf(lowerQuery);
2158
+ } else {
2159
+ matchStart = lowerFull.indexOf(lowerQuery, searchFrom);
2160
+ if (matchStart === -1) matchStart = lowerFull.indexOf(lowerQuery);
2161
+ }
2162
+ if (matchStart === -1) return;
2163
+ const matchEnd = matchStart + text.length;
2164
+ const range = document.createRange();
2165
+ let startSet = false;
2166
+ let endSet = false;
2167
+ for (let i = 0; i < segments.length && !endSet; i++) {
2168
+ const seg = segments[i];
2169
+ const segEnd = seg.start + seg.node.length;
2170
+ if (!startSet && matchStart < segEnd && matchStart >= seg.start) {
2171
+ range.setStart(seg.node, matchStart - seg.start);
2172
+ startSet = true;
2173
+ }
2174
+ if (startSet && matchEnd <= segEnd) {
2175
+ range.setEnd(seg.node, matchEnd - seg.start);
2176
+ endSet = true;
2177
+ }
2178
+ }
2179
+ if (startSet && endSet) {
2180
+ selection.removeAllRanges();
2181
+ selection.addRange(range);
2182
+ (_b = (_a = range.startContainer.parentElement) == null ? void 0 : _a.scrollIntoView) == null ? void 0 : _b.call(_a, { block: "nearest" });
2183
+ }
2184
+ }, []);
2185
+ const handleCreateLink = React.useCallback(() => {
2186
+ if (savedSelection.current) {
2187
+ const selection2 = window.getSelection();
2188
+ selection2 == null ? void 0 : selection2.removeAllRanges();
2189
+ selection2 == null ? void 0 : selection2.addRange(savedSelection.current);
2190
+ }
2191
+ const selection = window.getSelection();
2192
+ const anchorNode = selection == null ? void 0 : selection.anchorNode;
2193
+ const existingLink = findParentTag(anchorNode || null, "A");
2194
+ if (existingLink) {
2195
+ if (linkUrl) {
2196
+ existingLink.setAttribute("href", linkUrl);
2197
+ existingLink.setAttribute("target", "_blank");
2198
+ existingLink.setAttribute("rel", "noopener noreferrer");
2199
+ existingLink.style.color = "hsl(var(--primary))";
2200
+ existingLink.style.textDecoration = "underline";
2201
+ existingLink.style.cursor = "pointer";
2202
+ }
2203
+ handleInput();
2204
+ setIsLinkOpen(false);
2205
+ savedSelection.current = null;
2206
+ return;
2207
+ }
2208
+ if (!selection || selection.rangeCount === 0 || selection.isCollapsed) {
2209
+ return;
2210
+ }
2211
+ if (linkUrl) {
2212
+ document.execCommand("createLink", false, linkUrl);
2213
+ setTimeout(() => {
2214
+ var _a;
2215
+ const anchor = findParentTag(((_a = window.getSelection()) == null ? void 0 : _a.anchorNode) || null, "A");
2216
+ if (anchor) {
2217
+ anchor.setAttribute("target", "_blank");
2218
+ anchor.setAttribute("rel", "noopener noreferrer");
2219
+ anchor.style.color = "hsl(var(--primary))";
2220
+ anchor.style.textDecoration = "underline";
2221
+ anchor.style.cursor = "pointer";
2222
+ }
2223
+ handleInput();
2224
+ }, 10);
2225
+ setIsLinkOpen(false);
2226
+ savedSelection.current = null;
2227
+ }
2228
+ }, [linkUrl, findParentTag, handleInput]);
2229
+ const handleUnlink = React.useCallback(() => {
2230
+ const selection = window.getSelection();
2231
+ const anchorNode = selection == null ? void 0 : selection.anchorNode;
2232
+ const existingLink = findParentTag(anchorNode || null, "A");
2233
+ if (existingLink) {
2234
+ const parent = existingLink.parentNode;
2235
+ while (existingLink.firstChild) {
2236
+ parent == null ? void 0 : parent.insertBefore(existingLink.firstChild, existingLink);
2237
+ }
2238
+ parent == null ? void 0 : parent.removeChild(existingLink);
2239
+ handleInput();
2240
+ } else {
2241
+ document.execCommand("unlink", false, "");
2242
+ }
2243
+ }, [findParentTag, handleInput]);
2244
+ const onLinkPopoverOpenChange = React.useCallback(
2245
+ (open) => {
2246
+ if (open) {
2247
+ const selection = window.getSelection();
2248
+ const anchorNode = selection == null ? void 0 : selection.anchorNode;
2249
+ const focusNode = selection == null ? void 0 : selection.focusNode;
2250
+ const existingLink = findParentTag(anchorNode || null, "A") || findParentTag(focusNode || null, "A");
2251
+ if (existingLink) {
2252
+ setLinkUrl(existingLink.getAttribute("href") || "https://");
2253
+ } else {
2254
+ setLinkUrl("https://");
2255
+ }
2256
+ if (selection && selection.rangeCount > 0 && (!selection.isCollapsed || existingLink)) {
2257
+ savedSelection.current = selection.getRangeAt(0).cloneRange();
2258
+ setHasSavedSelection(true);
2259
+ } else {
2260
+ savedSelection.current = null;
2261
+ setHasSavedSelection(false);
2262
+ }
2263
+ setTimeout(() => {
2264
+ var _a;
2265
+ return (_a = linkInputRef.current) == null ? void 0 : _a.focus();
2266
+ }, 100);
2267
+ } else {
2268
+ setHasSavedSelection(false);
2269
+ }
2270
+ setIsLinkOpen(open);
2271
+ },
2272
+ [findParentTag]
2273
+ );
2274
+ return {
2275
+ // Refs
2276
+ editorRef,
2277
+ searchInputRef,
2278
+ linkInputRef,
2279
+ // State
2280
+ activeFormats,
2281
+ isSearchOpen,
2282
+ setIsSearchOpen,
2283
+ searchQuery,
2284
+ setSearchQuery,
2285
+ linkUrl,
2286
+ setLinkUrl,
2287
+ isLinkOpen,
2288
+ hasSavedSelection,
2289
+ // Computed
2290
+ wordCount,
2291
+ characterCount,
2292
+ // Handlers
2293
+ updateActiveFormats,
2294
+ execCommand,
2295
+ handleInput,
2296
+ performSearch,
2297
+ handleCreateLink,
2298
+ handleUnlink,
2299
+ onLinkPopoverOpenChange
2300
+ };
2301
+ }
2302
+ function RichTextEditor({
2303
+ value,
2304
+ onChange,
2305
+ placeholder,
2306
+ className,
2307
+ actionButton,
2308
+ allowSearch = true,
2309
+ allowLinks = true,
2310
+ allowUndoRedo = true,
2311
+ allowHeadings = true,
2312
+ allowFormatting = true,
2313
+ allowAlignment = true,
2314
+ allowLists = true,
2315
+ showWordCount = true,
2316
+ showCharacterCount = true,
2317
+ disabled = false,
2318
+ readOnly = false,
2319
+ onFocus,
2320
+ onBlur,
2321
+ minHeight,
2322
+ maxHeight
2323
+ }) {
2324
+ const isEditable = !disabled && !readOnly;
2325
+ const showToolbar = isEditable;
2326
+ const {
2327
+ editorRef,
2328
+ searchInputRef,
2329
+ linkInputRef,
2330
+ activeFormats,
2331
+ isSearchOpen,
2332
+ setIsSearchOpen,
2333
+ searchQuery,
2334
+ setSearchQuery,
2335
+ linkUrl,
2336
+ setLinkUrl,
2337
+ isLinkOpen,
2338
+ hasSavedSelection,
2339
+ wordCount,
2340
+ characterCount,
2341
+ updateActiveFormats,
2342
+ execCommand,
2343
+ handleInput,
2344
+ performSearch,
2345
+ handleCreateLink,
2346
+ handleUnlink,
2347
+ onLinkPopoverOpenChange
2348
+ } = useRichTextEditor({ value, onChange });
2349
+ const getCurrentBlockLabel = () => {
2350
+ if (activeFormats.h1)
2351
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2352
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Heading1, { className: "w-4 h-4 mr-1 shrink-0" }),
2353
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: "Título 1" })
2354
+ ] });
2355
+ if (activeFormats.h2)
2356
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2357
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Heading2, { className: "w-4 h-4 mr-1 shrink-0" }),
2358
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: "Título 2" })
2359
+ ] });
2360
+ if (activeFormats.h3)
2361
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2362
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Heading3, { className: "w-4 h-4 mr-1 shrink-0" }),
2363
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: "Título 3" })
2364
+ ] });
2365
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2366
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Type, { className: "w-4 h-4 mr-1 shrink-0" }),
2367
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: "Parágrafo" })
2368
+ ] });
2369
+ };
2370
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2371
+ "div",
2372
+ {
2373
+ className: button.cn(
2374
+ "flex flex-col h-full w-full bg-background sm:border border-border sm:shadow-sm sm:rounded-lg overflow-hidden",
2375
+ disabled && "opacity-50 pointer-events-none",
2376
+ className
2377
+ ),
2378
+ children: [
2379
+ /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
2380
+ [contenteditable]:empty:before {
2381
+ content: attr(data-placeholder);
2382
+ color: hsl(var(--muted-foreground));
2383
+ pointer-events: none;
2384
+ display: block;
2385
+ }
2386
+ .prose-editor ul {
2387
+ list-style-type: disc !important;
2388
+ padding-left: 1.5rem !important;
2389
+ margin-top: 0.5rem !important;
2390
+ margin-bottom: 0.5rem !important;
2391
+ }
2392
+ .prose-editor ol {
2393
+ list-style-type: decimal !important;
2394
+ padding-left: 1.5rem !important;
2395
+ margin-top: 0.5rem !important;
2396
+ margin-bottom: 0.5rem !important;
2397
+ }
2398
+ .prose-editor b, .prose-editor strong {
2399
+ font-weight: 600 !important;
2400
+ }
2401
+ .prose-editor i, .prose-editor em {
2402
+ font-style: italic !important;
2403
+ }
2404
+ .prose-editor u {
2405
+ text-decoration: underline !important;
2406
+ }
2407
+ .prose-editor h1 {
2408
+ font-size: 2.25rem !important;
2409
+ font-weight: 700 !important;
2410
+ margin-bottom: 1.25rem !important;
2411
+ line-height: 1.2 !important;
2412
+ margin-top: 2rem !important;
2413
+ color: hsl(var(--foreground));
2414
+ }
2415
+ .prose-editor h2 {
2416
+ font-size: 1.75rem !important;
2417
+ font-weight: 600 !important;
2418
+ margin-bottom: 1rem !important;
2419
+ margin-top: 1.5rem !important;
2420
+ color: hsl(var(--foreground));
2421
+ }
2422
+ .prose-editor h3 {
2423
+ font-size: 1.35rem !important;
2424
+ font-weight: 600 !important;
2425
+ margin-bottom: 0.75rem !important;
2426
+ margin-top: 1.25rem !important;
2427
+ color: hsl(var(--foreground));
2428
+ }
2429
+ .prose-editor p {
2430
+ margin-bottom: 1rem !important;
2431
+ line-height: 1.6 !important;
2432
+ }
2433
+ .prose-editor a {
2434
+ color: var(--info) !important;
2435
+ text-decoration: underline !important;
2436
+ cursor: pointer !important;
2437
+ }
2438
+ .prose-editor h1:first-child, .prose-editor h2:first-child, .prose-editor h3:first-child, .prose-editor p:first-child {
2439
+ margin-top: 0 !important;
2440
+ }
2441
+ .prose-editor {
2442
+ outline: none !important;
2443
+ }
2444
+ ` }),
2445
+ showToolbar && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 py-2 border-b border-border bg-muted/30 flex items-center gap-1 flex-wrap shrink-0", children: [
2446
+ allowUndoRedo && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2447
+ /* @__PURE__ */ jsxRuntime.jsx(
2448
+ button.Button,
2449
+ {
2450
+ variant: "ghost",
2451
+ size: "icon",
2452
+ className: "h-8 w-8 text-muted-foreground",
2453
+ onClick: () => execCommand("undo"),
2454
+ title: "Desfazer",
2455
+ "aria-label": "Desfazer",
2456
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Undo, { className: "w-4 h-4" })
2457
+ }
2458
+ ),
2459
+ /* @__PURE__ */ jsxRuntime.jsx(
2460
+ button.Button,
2461
+ {
2462
+ variant: "ghost",
2463
+ size: "icon",
2464
+ className: "h-8 w-8 text-muted-foreground",
2465
+ onClick: () => execCommand("redo"),
2466
+ title: "Refazer",
2467
+ "aria-label": "Refazer",
2468
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Redo, { className: "w-4 h-4" })
2469
+ }
2470
+ ),
2471
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-6 bg-border mx-1 hidden sm:block" })
2472
+ ] }),
2473
+ allowHeadings && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2474
+ /* @__PURE__ */ jsxRuntime.jsxs(dropdownMenu.DropdownMenu, { modal: false, children: [
2475
+ /* @__PURE__ */ jsxRuntime.jsx(dropdownMenu.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
2476
+ button.Button,
2477
+ {
2478
+ variant: "ghost",
2479
+ size: "sm",
2480
+ className: "h-8 gap-0 text-muted-foreground w-[120px] justify-start px-2",
2481
+ children: [
2482
+ getCurrentBlockLabel(),
2483
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "w-3 h-3 ml-auto opacity-50 shrink-0" })
2484
+ ]
2485
+ }
2486
+ ) }),
2487
+ /* @__PURE__ */ jsxRuntime.jsxs(dropdownMenu.DropdownMenuContent, { align: "start", className: "w-[160px]", style: { zIndex: 9999 }, children: [
2488
+ /* @__PURE__ */ jsxRuntime.jsxs(
2489
+ dropdownMenu.DropdownMenuItem,
2490
+ {
2491
+ onPointerDown: (e) => e.preventDefault(),
2492
+ onClick: () => execCommand("formatBlock", "P"),
2493
+ className: "gap-2",
2494
+ children: [
2495
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Type, { className: "w-4 h-4 text-muted-foreground" }),
2496
+ " Parágrafo"
2497
+ ]
2498
+ }
2499
+ ),
2500
+ /* @__PURE__ */ jsxRuntime.jsxs(
2501
+ dropdownMenu.DropdownMenuItem,
2502
+ {
2503
+ onPointerDown: (e) => e.preventDefault(),
2504
+ onClick: () => execCommand("formatBlock", "H1"),
2505
+ className: "gap-2",
2506
+ children: [
2507
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Heading1, { className: "w-4 h-4 text-muted-foreground" }),
2508
+ " Título 1"
2509
+ ]
2510
+ }
2511
+ ),
2512
+ /* @__PURE__ */ jsxRuntime.jsxs(
2513
+ dropdownMenu.DropdownMenuItem,
2514
+ {
2515
+ onPointerDown: (e) => e.preventDefault(),
2516
+ onClick: () => execCommand("formatBlock", "H2"),
2517
+ className: "gap-2",
2518
+ children: [
2519
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Heading2, { className: "w-4 h-4 text-muted-foreground" }),
2520
+ " Título 2"
2521
+ ]
2522
+ }
2523
+ ),
2524
+ /* @__PURE__ */ jsxRuntime.jsxs(
2525
+ dropdownMenu.DropdownMenuItem,
2526
+ {
2527
+ onPointerDown: (e) => e.preventDefault(),
2528
+ onClick: () => execCommand("formatBlock", "H3"),
2529
+ className: "gap-2",
2530
+ children: [
2531
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Heading3, { className: "w-4 h-4 text-muted-foreground" }),
2532
+ " Título 3"
2533
+ ]
2534
+ }
2535
+ )
2536
+ ] })
2537
+ ] }),
2538
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-6 bg-border mx-1 hidden sm:block" })
2539
+ ] }),
2540
+ allowFormatting && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2541
+ /* @__PURE__ */ jsxRuntime.jsx(
2542
+ button.Button,
2543
+ {
2544
+ variant: "ghost",
2545
+ size: "icon",
2546
+ className: button.cn(
2547
+ "h-8 w-8 text-muted-foreground",
2548
+ activeFormats.bold && "bg-muted text-foreground"
2549
+ ),
2550
+ onClick: () => execCommand("bold"),
2551
+ title: "Negrito",
2552
+ "aria-label": "Negrito",
2553
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bold, { className: "w-4 h-4" })
2554
+ }
2555
+ ),
2556
+ /* @__PURE__ */ jsxRuntime.jsx(
2557
+ button.Button,
2558
+ {
2559
+ variant: "ghost",
2560
+ size: "icon",
2561
+ className: button.cn(
2562
+ "h-8 w-8 text-muted-foreground",
2563
+ activeFormats.italic && "bg-muted text-foreground"
2564
+ ),
2565
+ onClick: () => execCommand("italic"),
2566
+ title: "Itálico",
2567
+ "aria-label": "Itálico",
2568
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Italic, { className: "w-4 h-4" })
2569
+ }
2570
+ ),
2571
+ /* @__PURE__ */ jsxRuntime.jsx(
2572
+ button.Button,
2573
+ {
2574
+ variant: "ghost",
2575
+ size: "icon",
2576
+ className: button.cn(
2577
+ "h-8 w-8 text-muted-foreground",
2578
+ activeFormats.underline && "bg-muted text-foreground"
2579
+ ),
2580
+ onClick: () => execCommand("underline"),
2581
+ title: "Sublinhado",
2582
+ "aria-label": "Sublinhado",
2583
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Underline, { className: "w-4 h-4" })
2584
+ }
2585
+ ),
2586
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-6 bg-border mx-1 hidden sm:block" })
2587
+ ] }),
2588
+ allowAlignment && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2589
+ /* @__PURE__ */ jsxRuntime.jsx(
2590
+ button.Button,
2591
+ {
2592
+ variant: "ghost",
2593
+ size: "icon",
2594
+ className: button.cn(
2595
+ "h-8 w-8 text-muted-foreground",
2596
+ activeFormats.justifyLeft && "bg-muted text-foreground"
2597
+ ),
2598
+ onClick: () => execCommand("justifyLeft"),
2599
+ title: "Alinhar à esquerda",
2600
+ "aria-label": "Alinhar à esquerda",
2601
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlignLeft, { className: "w-4 h-4" })
2602
+ }
2603
+ ),
2604
+ /* @__PURE__ */ jsxRuntime.jsx(
2605
+ button.Button,
2606
+ {
2607
+ variant: "ghost",
2608
+ size: "icon",
2609
+ className: button.cn(
2610
+ "h-8 w-8 text-muted-foreground",
2611
+ activeFormats.justifyCenter && "bg-muted text-foreground"
2612
+ ),
2613
+ onClick: () => execCommand("justifyCenter"),
2614
+ title: "Centralizar",
2615
+ "aria-label": "Centralizar",
2616
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlignCenter, { className: "w-4 h-4" })
2617
+ }
2618
+ ),
2619
+ /* @__PURE__ */ jsxRuntime.jsx(
2620
+ button.Button,
2621
+ {
2622
+ variant: "ghost",
2623
+ size: "icon",
2624
+ className: button.cn(
2625
+ "h-8 w-8 text-muted-foreground",
2626
+ activeFormats.justifyRight && "bg-muted text-foreground"
2627
+ ),
2628
+ onClick: () => execCommand("justifyRight"),
2629
+ title: "Alinhar à direita",
2630
+ "aria-label": "Alinhar à direita",
2631
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlignRight, { className: "w-4 h-4" })
2632
+ }
2633
+ ),
2634
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-6 bg-border mx-1 hidden sm:block" })
2635
+ ] }),
2636
+ allowLists && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2637
+ /* @__PURE__ */ jsxRuntime.jsx(
2638
+ button.Button,
2639
+ {
2640
+ variant: "ghost",
2641
+ size: "icon",
2642
+ className: button.cn(
2643
+ "h-8 w-8 text-muted-foreground",
2644
+ activeFormats.insertUnorderedList && "bg-muted text-foreground"
2645
+ ),
2646
+ onClick: () => execCommand("insertUnorderedList"),
2647
+ title: "Lista com marcadores",
2648
+ "aria-label": "Lista com marcadores",
2649
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.List, { className: "w-4 h-4" })
2650
+ }
2651
+ ),
2652
+ /* @__PURE__ */ jsxRuntime.jsx(
2653
+ button.Button,
2654
+ {
2655
+ variant: "ghost",
2656
+ size: "icon",
2657
+ className: button.cn(
2658
+ "h-8 w-8 text-muted-foreground",
2659
+ activeFormats.insertOrderedList && "bg-muted text-foreground"
2660
+ ),
2661
+ onClick: () => execCommand("insertOrderedList"),
2662
+ title: "Lista numerada",
2663
+ "aria-label": "Lista numerada",
2664
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListOrdered, { className: "w-4 h-4" })
2665
+ }
2666
+ ),
2667
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-6 bg-border mx-1 hidden sm:block" })
2668
+ ] }),
2669
+ allowLinks && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2670
+ /* @__PURE__ */ jsxRuntime.jsxs(input.Popover, { open: isLinkOpen, onOpenChange: onLinkPopoverOpenChange, modal: false, children: [
2671
+ /* @__PURE__ */ jsxRuntime.jsx(input.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
2672
+ button.Button,
2673
+ {
2674
+ variant: "ghost",
2675
+ size: "icon",
2676
+ className: button.cn(
2677
+ "h-8 w-8 text-muted-foreground",
2678
+ (activeFormats.link || isLinkOpen) && "bg-muted text-foreground"
2679
+ ),
2680
+ title: "Inserir link",
2681
+ "aria-label": "Inserir link",
2682
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Link, { className: "w-4 h-4" })
2683
+ }
2684
+ ) }),
2685
+ /* @__PURE__ */ jsxRuntime.jsx(input.PopoverContent, { className: "w-80 p-3", align: "start", style: { zIndex: 9999 }, children: !activeFormats.link && !hasSavedSelection ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground py-1", children: "Selecione um texto para criar um link." }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
2686
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-medium", children: activeFormats.link ? "Editar Link" : "Inserir Link" }),
2687
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
2688
+ /* @__PURE__ */ jsxRuntime.jsx(
2689
+ input.Input,
2690
+ {
2691
+ ref: linkInputRef,
2692
+ placeholder: "https://...",
2693
+ value: linkUrl,
2694
+ onChange: (e) => setLinkUrl(e.target.value),
2695
+ onKeyDown: (e) => {
2696
+ if (e.key === "Enter") {
2697
+ e.preventDefault();
2698
+ e.stopPropagation();
2699
+ handleCreateLink();
2700
+ }
2701
+ },
2702
+ className: "h-8 text-xs"
2703
+ }
2704
+ ),
2705
+ /* @__PURE__ */ jsxRuntime.jsx(button.Button, { size: "sm", className: "h-8", onClick: handleCreateLink, children: "Aplicar" })
2706
+ ] })
2707
+ ] }) })
2708
+ ] }),
2709
+ /* @__PURE__ */ jsxRuntime.jsx(
2710
+ button.Button,
2711
+ {
2712
+ variant: "ghost",
2713
+ size: "icon",
2714
+ className: "h-8 w-8 text-muted-foreground",
2715
+ onClick: handleUnlink,
2716
+ title: "Remover link",
2717
+ "aria-label": "Remover link",
2718
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-4 h-4" })
2719
+ }
2720
+ ),
2721
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-6 bg-border mx-1 hidden sm:block" })
2722
+ ] }),
2723
+ (allowFormatting || allowHeadings || allowAlignment || allowLists || allowLinks) && /* @__PURE__ */ jsxRuntime.jsx(
2724
+ button.Button,
2725
+ {
2726
+ variant: "ghost",
2727
+ size: "icon",
2728
+ className: "h-8 w-8 text-muted-foreground",
2729
+ onClick: () => execCommand("removeFormat"),
2730
+ title: "Limpar formatação",
2731
+ "aria-label": "Limpar formatação",
2732
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Type, { className: "w-4 h-4" })
2733
+ }
2734
+ ),
2735
+ allowSearch && /* @__PURE__ */ jsxRuntime.jsx(
2736
+ button.Button,
2737
+ {
2738
+ variant: "ghost",
2739
+ size: "icon",
2740
+ className: button.cn(
2741
+ "h-8 w-8 text-muted-foreground",
2742
+ isSearchOpen && "bg-muted text-foreground"
2743
+ ),
2744
+ onClick: () => {
2745
+ setIsSearchOpen(!isSearchOpen);
2746
+ if (!isSearchOpen) setTimeout(() => {
2747
+ var _a;
2748
+ return (_a = searchInputRef.current) == null ? void 0 : _a.focus();
2749
+ }, 100);
2750
+ },
2751
+ title: "Buscar",
2752
+ "aria-label": "Buscar",
2753
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "w-4 h-4" })
2754
+ }
2755
+ ),
2756
+ actionButton && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2757
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1" }),
2758
+ actionButton
2759
+ ] })
2760
+ ] }),
2761
+ isSearchOpen && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 py-1.5 border-b border-border bg-muted/20 flex items-center gap-2", children: [
2762
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 max-w-sm", children: [
2763
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-muted-foreground" }),
2764
+ /* @__PURE__ */ jsxRuntime.jsx(
2765
+ input.Input,
2766
+ {
2767
+ ref: searchInputRef,
2768
+ placeholder: "Buscar no texto...",
2769
+ value: searchQuery,
2770
+ onChange: (e) => setSearchQuery(e.target.value),
2771
+ onKeyDown: (e) => {
2772
+ if (e.key === "Enter") {
2773
+ e.preventDefault();
2774
+ performSearch(searchQuery, e.shiftKey);
2775
+ }
2776
+ if (e.key === "Escape") {
2777
+ setIsSearchOpen(false);
2778
+ }
2779
+ },
2780
+ className: "h-8 pl-8 text-xs bg-background"
2781
+ }
2782
+ )
2783
+ ] }),
2784
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
2785
+ /* @__PURE__ */ jsxRuntime.jsx(
2786
+ button.Button,
2787
+ {
2788
+ variant: "ghost",
2789
+ size: "icon",
2790
+ className: "h-7 w-7",
2791
+ onMouseDown: (e) => e.preventDefault(),
2792
+ onClick: () => performSearch(searchQuery, true),
2793
+ title: "Anterior",
2794
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { className: "w-4 h-4" })
2795
+ }
2796
+ ),
2797
+ /* @__PURE__ */ jsxRuntime.jsx(
2798
+ button.Button,
2799
+ {
2800
+ variant: "ghost",
2801
+ size: "icon",
2802
+ className: "h-7 w-7",
2803
+ onMouseDown: (e) => e.preventDefault(),
2804
+ onClick: () => performSearch(searchQuery, false),
2805
+ title: "Próximo",
2806
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "w-4 h-4" })
2807
+ }
2808
+ ),
2809
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-4 bg-border mx-1" }),
2810
+ /* @__PURE__ */ jsxRuntime.jsx(
2811
+ button.Button,
2812
+ {
2813
+ variant: "ghost",
2814
+ size: "icon",
2815
+ className: "h-7 w-7 text-muted-foreground hover:text-foreground",
2816
+ onClick: () => setIsSearchOpen(false),
2817
+ title: "Fechar busca",
2818
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-4 h-4" })
2819
+ }
2820
+ )
2821
+ ] }),
2822
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden sm:block text-[10px] text-muted-foreground ml-auto uppercase tracking-wider font-medium", children: "Pressione Enter para buscar" })
2823
+ ] }),
2824
+ /* @__PURE__ */ jsxRuntime.jsx(
2825
+ "div",
2826
+ {
2827
+ className: "flex-1 overflow-y-auto p-4 sm:p-8 bg-background scrollbar-thin",
2828
+ style: { minHeight, maxHeight },
2829
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2830
+ "div",
2831
+ {
2832
+ ref: editorRef,
2833
+ contentEditable: isEditable,
2834
+ role: "textbox",
2835
+ "aria-multiline": "true",
2836
+ "aria-label": placeholder || "Editor de texto",
2837
+ "aria-readonly": readOnly,
2838
+ "aria-disabled": disabled,
2839
+ onInput: handleInput,
2840
+ onSelect: isEditable ? updateActiveFormats : void 0,
2841
+ onFocus: () => {
2842
+ updateActiveFormats();
2843
+ onFocus == null ? void 0 : onFocus();
2844
+ },
2845
+ onBlur,
2846
+ className: "prose-editor min-h-full max-w-none focus:outline-none",
2847
+ "data-placeholder": placeholder
2848
+ }
2849
+ )
2850
+ }
2851
+ ),
2852
+ (showWordCount || showCharacterCount) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-2 border-t border-border bg-muted/20 flex items-center justify-between", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[10px] sm:text-xs text-muted-foreground font-medium uppercase tracking-wider flex items-center gap-2", children: [
2853
+ showWordCount && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
2854
+ wordCount,
2855
+ " ",
2856
+ wordCount === 1 ? "palavra" : "palavras"
2857
+ ] }),
2858
+ showWordCount && showCharacterCount && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "•" }),
2859
+ showCharacterCount && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
2860
+ characterCount,
2861
+ " ",
2862
+ characterCount === 1 ? "caractere" : "caracteres"
2863
+ ] })
2864
+ ] }) })
2865
+ ]
2866
+ }
2867
+ );
2868
+ }
2869
+ exports.Alert = Alert;
2870
+ exports.AlertDescription = AlertDescription;
2871
+ exports.AlertTitle = AlertTitle;
2872
+ exports.ChartCard = ChartCard;
2873
+ exports.ChartContainer = ChartContainer;
2874
+ exports.ChartLegend = ChartLegend;
2875
+ exports.ChartLegendContent = ChartLegendContent;
2876
+ exports.ChartStyle = ChartStyle;
2877
+ exports.ChartTooltip = ChartTooltip;
2878
+ exports.ChartTooltipContent = ChartTooltipContent;
2879
+ exports.ComboMetricChart = ComboMetricChart;
2880
+ exports.DashboardBarChart = DashboardBarChart;
2881
+ exports.DashboardLineChart = DashboardLineChart;
2882
+ exports.Dialog = Dialog;
2883
+ exports.DialogBody = DialogBody;
2884
+ exports.DialogClose = DialogClose;
2885
+ exports.DialogContent = DialogContent;
2886
+ exports.DialogDescription = DialogDescription;
2887
+ exports.DialogFooter = DialogFooter;
2888
+ exports.DialogHeader = DialogHeader;
2889
+ exports.DialogOverlay = DialogOverlay;
2890
+ exports.DialogPortal = DialogPortal;
2891
+ exports.DialogTitle = DialogTitle;
2892
+ exports.DialogTrigger = DialogTrigger;
2893
+ exports.DonutBreakdownChart = DonutBreakdownChart;
2894
+ exports.Empty = Empty;
2895
+ exports.EmptyAction = EmptyAction;
2896
+ exports.EmptyDescription = EmptyDescription;
2897
+ exports.EmptyIcon = EmptyIcon;
2898
+ exports.EmptyImage = EmptyImage;
2899
+ exports.EmptyTitle = EmptyTitle;
2900
+ exports.GaugeChart = GaugeChart;
2901
+ exports.HorizontalBarChart = HorizontalBarChart;
2902
+ exports.InteractiveTimeSeriesChart = InteractiveTimeSeriesChart;
2903
+ exports.PieMetricChart = PieMetricChart;
2904
+ exports.RadarMetricChart = RadarMetricChart;
2905
+ exports.RadialBarMetricChart = RadialBarMetricChart;
2906
+ exports.RichTextEditor = RichTextEditor;
2907
+ exports.Skeleton = Skeleton;
2908
+ exports.SparklineChart = SparklineChart;
2909
+ exports.Table = Table;
2910
+ exports.TableBody = TableBody;
2911
+ exports.TableCaption = TableCaption;
2912
+ exports.TableCell = TableCell;
2913
+ exports.TableFooter = TableFooter;
2914
+ exports.TableHead = TableHead;
2915
+ exports.TableHeader = TableHeader;
2916
+ exports.TableRow = TableRow;
2917
+ exports.Textarea = Textarea;
2918
+ exports.useChart = useChart;
2919
+ exports.useRichTextEditor = useRichTextEditor;