xertica-ui 2.2.1 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/README.md +27 -3
- package/assets/xertica-logo.svg +37 -37
- package/assets/xertica-x-logo.svg +20 -20
- package/bin/cli.ts +477 -70
- package/bin/generate-tokens.ts +262 -262
- package/bin/language-config.ts +361 -361
- package/components/assets/xertica-orbe-animation.ts +1162 -1162
- package/components/assistant/code-block/code-block.stories.tsx +57 -57
- package/components/assistant/code-block/code-block.test.tsx +44 -44
- package/components/assistant/code-block/index.ts +1 -1
- package/components/assistant/formatted-document/formatted-document.stories.tsx +51 -51
- package/components/assistant/formatted-document/formatted-document.test.tsx +42 -42
- package/components/assistant/formatted-document/index.ts +1 -1
- package/components/assistant/index.ts +6 -6
- package/components/assistant/markdown-message/MarkdownMessage.tsx +152 -152
- package/components/assistant/markdown-message/index.ts +1 -1
- package/components/assistant/markdown-message/markdown-message.stories.tsx +50 -50
- package/components/assistant/markdown-message/markdown-message.test.tsx +33 -33
- package/components/assistant/modern-chat-input/ModernChatInput.tsx +554 -554
- package/components/assistant/modern-chat-input/index.ts +1 -1
- package/components/assistant/modern-chat-input/modern-chat-input.stories.tsx +131 -131
- package/components/assistant/modern-chat-input/modern-chat-input.test.tsx +79 -79
- package/components/assistant/xertica-assistant/index.ts +3 -3
- package/components/assistant/xertica-assistant/parts/AssistantTypingIndicator.tsx +41 -41
- package/components/assistant/xertica-assistant/parts/index.ts +16 -16
- package/components/assistant/xertica-assistant/types.ts +134 -134
- package/components/assistant/xertica-assistant/xertica-assistant.stories.tsx +407 -407
- package/components/assistant/xertica-assistant/xertica-assistant.test.tsx +65 -65
- package/components/blocks/card-patterns/ActivityCardSkeleton.tsx +56 -56
- package/components/blocks/card-patterns/FeatureCard.tsx +109 -109
- package/components/blocks/card-patterns/FeatureCardSkeleton.tsx +63 -63
- package/components/blocks/card-patterns/NotificationCardSkeleton.tsx +81 -81
- package/components/blocks/card-patterns/ProfileCardSkeleton.tsx +69 -69
- package/components/blocks/card-patterns/ProjectCardSkeleton.tsx +72 -72
- package/components/blocks/card-patterns/QuickActionCard.tsx +68 -68
- package/components/blocks/card-patterns/QuickActionCardSkeleton.tsx +44 -44
- package/components/blocks/card-patterns/card-patterns.mdx +123 -123
- package/components/blocks/index.ts +1 -1
- package/components/brand/branding/branding.stories.tsx +57 -57
- package/components/brand/index.ts +6 -6
- package/components/brand/language-selector/LanguageSelector.tsx +102 -102
- package/components/brand/language-selector/index.ts +1 -1
- package/components/brand/language-selector/language-selector.mdx +126 -126
- package/components/brand/language-selector/language-selector.stories.tsx +114 -114
- package/components/brand/language-selector/language-selector.test.tsx +101 -101
- package/components/brand/theme-toggle/index.ts +1 -1
- package/components/brand/theme-toggle/theme-toggle.stories.tsx +34 -34
- package/components/brand/theme-toggle/theme-toggle.test.tsx +34 -34
- package/components/brand/xertica-logo/XerticaLogo.stories.tsx +82 -82
- package/components/brand/xertica-logo/XerticaLogo.tsx +104 -104
- package/components/brand/xertica-logo/index.ts +1 -1
- package/components/brand/xertica-logo/xertica-logo.test.tsx +26 -26
- package/components/brand/xertica-orbe/XerticaOrbe.tsx +1927 -1927
- package/components/brand/xertica-orbe/index.ts +1 -1
- package/components/brand/xertica-orbe/xertica-orbe.stories.tsx +40 -40
- package/components/brand/xertica-orbe/xertica-orbe.test.tsx +19 -19
- package/components/brand/xertica-provider/XerticaProvider.tsx +112 -112
- package/components/brand/xertica-provider/index.ts +1 -1
- package/components/brand/xertica-provider/xertica-provider.mdx +61 -61
- package/components/brand/xertica-provider/xertica-provider.test.tsx +74 -74
- package/components/brand/xertica-xlogo/XerticaXLogo.stories.tsx +79 -79
- package/components/brand/xertica-xlogo/XerticaXLogo.tsx +65 -65
- package/components/brand/xertica-xlogo/index.ts +1 -1
- package/components/brand/xertica-xlogo/xertica-xlogo.test.tsx +16 -16
- package/components/examples/ApiKeyMapExample.tsx +71 -71
- package/components/examples/DrawingMapExample.tsx +565 -565
- package/components/examples/FilterableMapExample.tsx +393 -393
- package/components/examples/LocationPickerExample.tsx +348 -348
- package/components/examples/MapExamples.tsx +268 -268
- package/components/examples/MapGmpExample.tsx +169 -169
- package/components/examples/MapShowcase.tsx +471 -471
- package/components/examples/RouteMapExamples.tsx +329 -329
- package/components/examples/SidebarLogoExample.tsx +65 -65
- package/components/examples/SimpleFilterableMap.tsx +219 -219
- package/components/examples/index.ts +45 -45
- package/components/figma/ImageWithFallback.tsx +27 -27
- package/components/hooks/index.ts +13 -13
- package/components/hooks/use-layout-shortcuts.ts +43 -43
- package/components/layout/header/header.stories.tsx +204 -204
- package/components/layout/header/header.test.tsx +75 -75
- package/components/layout/header/header.tsx +349 -349
- package/components/layout/header/index.ts +1 -1
- package/components/layout/index.ts +2 -2
- package/components/layout/sidebar/index.ts +3 -3
- package/components/layout/sidebar/sidebar.mdx +1 -1
- package/components/layout/sidebar/sidebar.stories.tsx +586 -586
- package/components/layout/sidebar/sidebar.test.tsx +76 -76
- package/components/layout/sidebar/use-sidebar.ts +104 -104
- package/components/media/audio-player/AudioPlayer.stories.tsx +124 -124
- package/components/media/audio-player/AudioPlayer.test.tsx +106 -106
- package/components/media/audio-player/AudioPlayer.tsx +1 -1
- package/components/media/audio-player/index.ts +1 -1
- package/components/media/audio-player/use-audio-player.ts +312 -312
- package/components/media/index.ts +3 -3
- package/components/media/video-player/VideoPlayer.stories.tsx +98 -98
- package/components/media/video-player/VideoPlayer.test.tsx +73 -73
- package/components/media/video-player/index.ts +1 -1
- package/components/pages/forgot-password-page/ForgotPasswordPage.stories.tsx +24 -24
- package/components/pages/forgot-password-page/ForgotPasswordPage.tsx +188 -188
- package/components/pages/forgot-password-page/forgot-password-page.test.tsx +45 -45
- package/components/pages/forgot-password-page/index.ts +1 -1
- package/components/pages/home-content/HomeContent.stories.tsx +43 -43
- package/components/pages/home-content/HomeContent.tsx +1 -1
- package/components/pages/home-content/home-content.mdx +62 -62
- package/components/pages/home-content/index.ts +1 -1
- package/components/pages/home-page/HomePage.stories.tsx +39 -39
- package/components/pages/home-page/home-page.mdx +53 -53
- package/components/pages/home-page/home-page.test.tsx +53 -53
- package/components/pages/home-page/index.ts +1 -1
- package/components/pages/index.ts +8 -8
- package/components/pages/login-page/LoginPage.stories.tsx +39 -39
- package/components/pages/login-page/index.ts +1 -1
- package/components/pages/login-page/login-page.test.tsx +63 -63
- package/components/pages/reset-password-page/ResetPasswordPage.stories.tsx +24 -24
- package/components/pages/reset-password-page/index.ts +1 -1
- package/components/pages/template-content/TemplateContent.stories.tsx +43 -43
- package/components/pages/template-content/TemplateContent.tsx +1 -1
- package/components/pages/template-content/index.ts +1 -1
- package/components/pages/template-content/template-content.mdx +61 -61
- package/components/pages/template-page/TemplatePage.stories.tsx +39 -39
- package/components/pages/template-page/TemplatePage.tsx +62 -62
- package/components/pages/template-page/index.ts +1 -1
- package/components/pages/template-page/template-page.mdx +53 -53
- package/components/pages/template-page/template-page.test.tsx +52 -52
- package/components/pages/verify-email-page/VerifyEmailPage.stories.tsx +41 -41
- package/components/pages/verify-email-page/index.ts +1 -1
- package/components/public-api-smoke.test.tsx +52 -52
- package/components/shared/CustomTooltipContent.tsx +48 -48
- package/components/shared/assistant-utils.test.ts +16 -16
- package/components/shared/assistant-utils.ts +225 -225
- package/components/shared/error-boundary.stories.tsx +132 -132
- package/components/shared/error-boundary.tsx +154 -154
- package/components/shared/error-fallbacks.tsx +226 -226
- package/components/shared/layout-constants.ts +8 -8
- package/components/shared/navigation.ts +35 -35
- package/components/shared/use-mobile.test.ts +16 -16
- package/components/shared/use-mobile.ts +36 -36
- package/components/shared/utils.test.ts +14 -14
- package/components/shared/utils.ts +6 -6
- package/components/ui/accordion/accordion.mdx +8 -8
- package/components/ui/accordion/accordion.stories.tsx +105 -105
- package/components/ui/accordion/accordion.test.tsx +59 -59
- package/components/ui/accordion/accordion.tsx +77 -77
- package/components/ui/accordion/index.ts +1 -1
- package/components/ui/alert/alert.mdx +8 -8
- package/components/ui/alert/alert.stories.tsx +86 -86
- package/components/ui/alert/alert.test.tsx +53 -53
- package/components/ui/alert/alert.tsx +93 -93
- package/components/ui/alert/index.ts +1 -1
- package/components/ui/alert-dialog/alert-dialog.mdx +8 -8
- package/components/ui/alert-dialog/alert-dialog.stories.tsx +84 -84
- package/components/ui/alert-dialog/alert-dialog.test.tsx +70 -70
- package/components/ui/alert-dialog/alert-dialog.tsx +149 -149
- package/components/ui/alert-dialog/index.ts +1 -1
- package/components/ui/aspect-ratio/aspect-ratio.mdx +8 -8
- package/components/ui/aspect-ratio/aspect-ratio.stories.tsx +46 -46
- package/components/ui/aspect-ratio/aspect-ratio.test.tsx +28 -28
- package/components/ui/aspect-ratio/aspect-ratio.tsx +20 -20
- package/components/ui/aspect-ratio/index.ts +1 -1
- package/components/ui/assistant-chart/AssistantChart.tsx +64 -64
- package/components/ui/assistant-chart/assistant-chart.mdx +8 -8
- package/components/ui/assistant-chart/assistant-chart.stories.tsx +44 -44
- package/components/ui/assistant-chart/assistant-chart.test.tsx +46 -46
- package/components/ui/assistant-chart/index.ts +1 -1
- package/components/ui/avatar/avatar.mdx +8 -8
- package/components/ui/avatar/avatar.stories.tsx +86 -86
- package/components/ui/avatar/avatar.test.tsx +55 -55
- package/components/ui/avatar/avatar.tsx +71 -71
- package/components/ui/avatar/index.ts +1 -1
- package/components/ui/badge/badge.mdx +8 -8
- package/components/ui/badge/badge.stories.tsx +72 -72
- package/components/ui/badge/badge.test.tsx +40 -40
- package/components/ui/badge/badge.tsx +58 -58
- package/components/ui/badge/index.ts +1 -1
- package/components/ui/breadcrumb/breadcrumb.mdx +8 -8
- package/components/ui/breadcrumb/breadcrumb.stories.tsx +123 -123
- package/components/ui/breadcrumb/breadcrumb.test.tsx +70 -70
- package/components/ui/breadcrumb/breadcrumb.tsx +114 -114
- package/components/ui/breadcrumb/index.ts +1 -1
- package/components/ui/button/button.mdx +8 -8
- package/components/ui/button/button.stories.tsx +183 -183
- package/components/ui/button/button.test.tsx +64 -64
- package/components/ui/button/button.tsx +98 -98
- package/components/ui/button/index.ts +1 -1
- package/components/ui/calendar/calendar.mdx +8 -8
- package/components/ui/calendar/calendar.stories.tsx +108 -108
- package/components/ui/calendar/calendar.test.tsx +53 -53
- package/components/ui/calendar/calendar.tsx +230 -230
- package/components/ui/calendar/index.ts +1 -1
- package/components/ui/card/card.mdx +8 -8
- package/components/ui/card/card.stories.tsx +301 -301
- package/components/ui/card/card.test.tsx +55 -55
- package/components/ui/card/card.tsx +83 -83
- package/components/ui/card/index.ts +1 -1
- package/components/ui/carousel/carousel.mdx +8 -8
- package/components/ui/carousel/carousel.stories.tsx +80 -80
- package/components/ui/carousel/carousel.test.tsx +75 -75
- package/components/ui/carousel/carousel.tsx +242 -242
- package/components/ui/carousel/index.ts +1 -1
- package/components/ui/chart/chart.mdx +8 -8
- package/components/ui/chart/chart.stories.tsx +1328 -1328
- package/components/ui/chart/chart.test.tsx +178 -178
- package/components/ui/chart/chart.tsx +2232 -2232
- package/components/ui/chart/index.ts +1 -1
- package/components/ui/checkbox/checkbox.mdx +8 -8
- package/components/ui/checkbox/checkbox.stories.tsx +109 -109
- package/components/ui/checkbox/checkbox.test.tsx +49 -49
- package/components/ui/checkbox/checkbox.tsx +68 -68
- package/components/ui/checkbox/index.ts +1 -1
- package/components/ui/collapsible/collapsible.mdx +8 -8
- package/components/ui/collapsible/collapsible.stories.tsx +45 -45
- package/components/ui/collapsible/collapsible.test.tsx +51 -51
- package/components/ui/collapsible/collapsible.tsx +32 -32
- package/components/ui/collapsible/index.ts +1 -1
- package/components/ui/command/command.mdx +8 -8
- package/components/ui/command/command.stories.tsx +134 -134
- package/components/ui/command/command.test.tsx +48 -48
- package/components/ui/command/command.tsx +163 -163
- package/components/ui/command/index.ts +1 -1
- package/components/ui/context-menu/context-menu.mdx +8 -8
- package/components/ui/context-menu/context-menu.stories.tsx +76 -76
- package/components/ui/context-menu/context-menu.test.tsx +61 -61
- package/components/ui/context-menu/context-menu.tsx +236 -236
- package/components/ui/context-menu/index.ts +1 -1
- package/components/ui/dialog/dialog.mdx +8 -8
- package/components/ui/dialog/dialog.stories.tsx +174 -174
- package/components/ui/dialog/dialog.test.tsx +78 -78
- package/components/ui/dialog/dialog.tsx +189 -189
- package/components/ui/dialog/index.ts +1 -1
- package/components/ui/drawer/drawer.mdx +8 -8
- package/components/ui/drawer/drawer.stories.tsx +71 -71
- package/components/ui/drawer/drawer.test.tsx +67 -67
- package/components/ui/drawer/drawer.tsx +146 -146
- package/components/ui/drawer/index.ts +1 -1
- package/components/ui/dropdown-menu/dropdown-menu.mdx +8 -8
- package/components/ui/dropdown-menu/dropdown-menu.stories.tsx +156 -156
- package/components/ui/dropdown-menu/dropdown-menu.test.tsx +62 -62
- package/components/ui/dropdown-menu/dropdown-menu.tsx +240 -240
- package/components/ui/dropdown-menu/index.ts +1 -1
- package/components/ui/empty/empty.mdx +8 -8
- package/components/ui/empty/empty.stories.tsx +85 -85
- package/components/ui/empty/empty.test.tsx +31 -31
- package/components/ui/empty/empty.tsx +88 -88
- package/components/ui/empty/index.ts +1 -1
- package/components/ui/file-upload/file-upload.mdx +8 -8
- package/components/ui/file-upload/file-upload.stories.tsx +144 -144
- package/components/ui/file-upload/file-upload.test.tsx +65 -65
- package/components/ui/file-upload/file-upload.tsx +142 -142
- package/components/ui/file-upload/index.ts +2 -2
- package/components/ui/file-upload/use-file-upload.ts +177 -177
- package/components/ui/form/form.stories.tsx +85 -85
- package/components/ui/form/form.test.tsx +75 -75
- package/components/ui/form/form.tsx +163 -163
- package/components/ui/form/index.ts +1 -1
- package/components/ui/google-maps-loader/google-maps-loader.test.tsx +35 -35
- package/components/ui/google-maps-loader/google-maps-loader.tsx +465 -465
- package/components/ui/google-maps-loader/index.ts +1 -1
- package/components/ui/hover-card/hover-card.mdx +8 -8
- package/components/ui/hover-card/hover-card.stories.tsx +61 -61
- package/components/ui/hover-card/hover-card.test.tsx +48 -48
- package/components/ui/hover-card/hover-card.tsx +50 -50
- package/components/ui/hover-card/index.ts +1 -1
- package/components/ui/index.ts +400 -400
- package/components/ui/input/index.ts +1 -1
- package/components/ui/input/input.mdx +8 -8
- package/components/ui/input/input.stories.tsx +153 -153
- package/components/ui/input/input.test.tsx +47 -47
- package/components/ui/input/input.tsx +57 -57
- package/components/ui/input-otp/index.ts +1 -1
- package/components/ui/input-otp/input-otp.mdx +8 -8
- package/components/ui/input-otp/input-otp.stories.tsx +120 -120
- package/components/ui/input-otp/input-otp.test.tsx +74 -74
- package/components/ui/input-otp/input-otp.tsx +101 -101
- package/components/ui/label/index.ts +1 -1
- package/components/ui/label/label.mdx +8 -8
- package/components/ui/label/label.stories.tsx +74 -74
- package/components/ui/label/label.test.tsx +45 -45
- package/components/ui/label/label.tsx +53 -53
- package/components/ui/map/index.ts +1 -1
- package/components/ui/map/map.mdx +8 -8
- package/components/ui/map/map.stories.tsx +86 -86
- package/components/ui/map/map.test.tsx +82 -82
- package/components/ui/map/map.tsx +506 -506
- package/components/ui/map/mock.test.tsx +13 -13
- package/components/ui/map-config/index.ts +1 -1
- package/components/ui/map-config/map-config.ts +18 -18
- package/components/ui/map-layers/index.ts +1 -1
- package/components/ui/map-layers/map-layers.test.tsx +48 -48
- package/components/ui/map-layers/map-layers.tsx +126 -126
- package/components/ui/map.exports/index.ts +1 -1
- package/components/ui/map.exports/map.exports.ts +31 -31
- package/components/ui/menubar/index.ts +1 -1
- package/components/ui/menubar/menubar.mdx +8 -8
- package/components/ui/menubar/menubar.stories.tsx +130 -130
- package/components/ui/menubar/menubar.test.tsx +53 -53
- package/components/ui/menubar/menubar.tsx +265 -265
- package/components/ui/navigation-menu/index.ts +1 -1
- package/components/ui/navigation-menu/navigation-menu.mdx +8 -8
- package/components/ui/navigation-menu/navigation-menu.stories.tsx +126 -126
- package/components/ui/navigation-menu/navigation-menu.test.tsx +47 -47
- package/components/ui/navigation-menu/navigation-menu.tsx +165 -165
- package/components/ui/notification-badge/index.ts +1 -1
- package/components/ui/notification-badge/notification-badge.mdx +8 -8
- package/components/ui/notification-badge/notification-badge.stories.tsx +66 -66
- package/components/ui/notification-badge/notification-badge.test.tsx +61 -61
- package/components/ui/notification-badge/notification-badge.tsx +91 -91
- package/components/ui/page-header/index.ts +1 -1
- package/components/ui/page-header/page-header.stories.tsx +69 -69
- package/components/ui/page-header/page-header.test.tsx +37 -37
- package/components/ui/page-header/page-header.tsx +124 -124
- package/components/ui/pagination/index.ts +3 -3
- package/components/ui/pagination/pagination.mdx +8 -8
- package/components/ui/pagination/pagination.stories.tsx +210 -210
- package/components/ui/pagination/pagination.test.tsx +63 -63
- package/components/ui/pagination/pagination.tsx +140 -140
- package/components/ui/pagination/use-pagination.ts +173 -173
- package/components/ui/popover/index.ts +1 -1
- package/components/ui/popover/popover.mdx +8 -8
- package/components/ui/popover/popover.stories.tsx +73 -73
- package/components/ui/popover/popover.test.tsx +48 -48
- package/components/ui/popover/popover.tsx +54 -54
- package/components/ui/progress/index.ts +1 -1
- package/components/ui/progress/progress.mdx +8 -8
- package/components/ui/progress/progress.stories.tsx +55 -55
- package/components/ui/progress/progress.test.tsx +23 -23
- package/components/ui/progress/progress.tsx +68 -68
- package/components/ui/radio-group/index.ts +1 -1
- package/components/ui/radio-group/radio-group.mdx +8 -8
- package/components/ui/radio-group/radio-group.stories.tsx +114 -114
- package/components/ui/radio-group/radio-group.test.tsx +78 -78
- package/components/ui/radio-group/radio-group.tsx +93 -93
- package/components/ui/rating/index.ts +1 -1
- package/components/ui/rating/rating.mdx +8 -8
- package/components/ui/rating/rating.stories.tsx +50 -50
- package/components/ui/rating/rating.test.tsx +48 -48
- package/components/ui/rating/rating.tsx +145 -145
- package/components/ui/resizable/index.ts +1 -1
- package/components/ui/resizable/resizable.mdx +8 -8
- package/components/ui/resizable/resizable.stories.tsx +88 -88
- package/components/ui/resizable/resizable.test.tsx +61 -61
- package/components/ui/resizable/resizable.tsx +452 -452
- package/components/ui/rich-text-editor/index.ts +7 -7
- package/components/ui/rich-text-editor/rich-text-editor.stories.tsx +290 -290
- package/components/ui/rich-text-editor/rich-text-editor.test.tsx +86 -86
- package/components/ui/rich-text-editor/rich-text-editor.tsx +634 -634
- package/components/ui/rich-text-editor/use-rich-text-editor.ts +453 -453
- package/components/ui/route-map/index.ts +1 -1
- package/components/ui/route-map/route-map.mdx +8 -8
- package/components/ui/route-map/route-map.stories.tsx +48 -48
- package/components/ui/route-map/route-map.test.tsx +108 -108
- package/components/ui/route-map/route-map.tsx +349 -349
- package/components/ui/scroll-area/index.ts +1 -1
- package/components/ui/scroll-area/scroll-area.mdx +8 -8
- package/components/ui/scroll-area/scroll-area.stories.tsx +31 -31
- package/components/ui/scroll-area/scroll-area.test.tsx +27 -27
- package/components/ui/scroll-area/scroll-area.tsx +70 -70
- package/components/ui/search/index.ts +1 -1
- package/components/ui/search/search.mdx +8 -8
- package/components/ui/search/search.stories.tsx +107 -107
- package/components/ui/search/search.test.tsx +67 -67
- package/components/ui/search/search.tsx +141 -141
- package/components/ui/select/index.ts +1 -1
- package/components/ui/select/select.mdx +8 -8
- package/components/ui/select/select.stories.tsx +163 -163
- package/components/ui/select/select.test.tsx +99 -99
- package/components/ui/select/select.tsx +195 -195
- package/components/ui/separator/index.ts +1 -1
- package/components/ui/separator/separator.mdx +8 -8
- package/components/ui/separator/separator.stories.tsx +55 -55
- package/components/ui/separator/separator.test.tsx +23 -23
- package/components/ui/separator/separator.tsx +39 -39
- package/components/ui/sheet/index.ts +1 -1
- package/components/ui/sheet/sheet.mdx +8 -8
- package/components/ui/sheet/sheet.stories.tsx +93 -93
- package/components/ui/sheet/sheet.test.tsx +62 -62
- package/components/ui/sheet/sheet.tsx +149 -149
- package/components/ui/simple-map/index.ts +1 -1
- package/components/ui/simple-map/simple-map.mdx +8 -8
- package/components/ui/simple-map/simple-map.stories.tsx +44 -44
- package/components/ui/simple-map/simple-map.test.tsx +36 -36
- package/components/ui/simple-map/simple-map.tsx +92 -92
- package/components/ui/skeleton/index.ts +1 -1
- package/components/ui/skeleton/skeleton.mdx +8 -8
- package/components/ui/skeleton/skeleton.stories.tsx +36 -36
- package/components/ui/skeleton/skeleton.test.tsx +19 -19
- package/components/ui/skeleton/skeleton.tsx +25 -25
- package/components/ui/slider/index.ts +1 -1
- package/components/ui/slider/slider.mdx +8 -8
- package/components/ui/slider/slider.stories.tsx +44 -44
- package/components/ui/slider/slider.test.tsx +25 -25
- package/components/ui/slider/slider.tsx +66 -66
- package/components/ui/sonner/index.ts +1 -1
- package/components/ui/sonner/sonner.mdx +8 -8
- package/components/ui/sonner/sonner.stories.tsx +41 -41
- package/components/ui/sonner/sonner.test.tsx +24 -24
- package/components/ui/sonner/sonner.tsx +74 -74
- package/components/ui/stats-card/stats-card-skeleton.tsx +62 -62
- package/components/ui/stats-card/stats-card.mdx +8 -8
- package/components/ui/stats-card/stats-card.test.tsx +34 -34
- package/components/ui/stats-card/stats-card.tsx +93 -93
- package/components/ui/stepper/index.ts +3 -3
- package/components/ui/stepper/stepper.mdx +8 -8
- package/components/ui/stepper/stepper.stories.tsx +171 -171
- package/components/ui/stepper/stepper.test.tsx +47 -47
- package/components/ui/stepper/stepper.tsx +190 -190
- package/components/ui/stepper/use-stepper.ts +139 -139
- package/components/ui/switch/index.ts +1 -1
- package/components/ui/switch/switch.mdx +8 -8
- package/components/ui/switch/switch.stories.tsx +93 -93
- package/components/ui/switch/switch.test.tsx +44 -44
- package/components/ui/switch/switch.tsx +70 -70
- package/components/ui/table/index.ts +1 -1
- package/components/ui/table/table.mdx +8 -8
- package/components/ui/table/table.stories.tsx +114 -114
- package/components/ui/table/table.test.tsx +43 -43
- package/components/ui/table/table.tsx +104 -104
- package/components/ui/tabs/index.ts +1 -1
- package/components/ui/tabs/tabs.mdx +8 -8
- package/components/ui/tabs/tabs.stories.tsx +140 -140
- package/components/ui/tabs/tabs.test.tsx +50 -50
- package/components/ui/tabs/tabs.tsx +66 -66
- package/components/ui/textarea/index.ts +1 -1
- package/components/ui/textarea/textarea.mdx +8 -8
- package/components/ui/textarea/textarea.stories.tsx +69 -69
- package/components/ui/textarea/textarea.test.tsx +41 -41
- package/components/ui/textarea/textarea.tsx +61 -61
- package/components/ui/timeline/index.ts +1 -1
- package/components/ui/timeline/timeline.mdx +8 -8
- package/components/ui/timeline/timeline.stories.tsx +97 -97
- package/components/ui/timeline/timeline.test.tsx +53 -53
- package/components/ui/timeline/timeline.tsx +124 -124
- package/components/ui/toggle/index.ts +1 -1
- package/components/ui/toggle/toggle.mdx +8 -8
- package/components/ui/toggle/toggle.stories.tsx +56 -56
- package/components/ui/toggle/toggle.test.tsx +32 -32
- package/components/ui/toggle/toggle.tsx +55 -55
- package/components/ui/toggle-group/index.ts +1 -1
- package/components/ui/toggle-group/toggle-group.mdx +8 -8
- package/components/ui/toggle-group/toggle-group.stories.tsx +66 -66
- package/components/ui/toggle-group/toggle-group.test.tsx +47 -47
- package/components/ui/toggle-group/toggle-group.tsx +79 -79
- package/components/ui/tooltip/index.ts +1 -1
- package/components/ui/tooltip/tooltip.mdx +8 -8
- package/components/ui/tooltip/tooltip.stories.tsx +83 -83
- package/components/ui/tooltip/tooltip.test.tsx +39 -39
- package/components/ui/tooltip/tooltip.tsx +69 -69
- package/components/ui/tree-view/index.ts +4 -4
- package/components/ui/tree-view/tree-view.mdx +8 -8
- package/components/ui/tree-view/tree-view.stories.tsx +154 -154
- package/components/ui/tree-view/tree-view.test.tsx +58 -58
- package/components/ui/tree-view/tree-view.tsx +171 -171
- package/components/ui/tree-view/use-tree-view.ts +237 -237
- package/contexts/ApiKeyContext.test.tsx +26 -26
- package/contexts/ApiKeyContext.tsx +196 -196
- package/contexts/AssistenteContext.test.tsx +17 -17
- package/contexts/AssistenteContext.tsx +113 -113
- package/contexts/AuthContext.tsx +118 -118
- package/contexts/BrandColorsContext.test.tsx +21 -21
- package/contexts/BrandColorsContext.tsx +251 -251
- package/contexts/LanguageContext.test.tsx +121 -121
- package/contexts/LanguageContext.tsx +251 -251
- package/contexts/LayoutContext.test.tsx +29 -29
- package/contexts/LayoutContext.tsx +140 -140
- package/contexts/ThemeContext.test.tsx +38 -38
- package/contexts/ThemeContext.tsx +111 -111
- package/contexts/index.ts +8 -8
- package/contexts/theme-data.ts +340 -340
- package/dist/{AssistantChart-BAx9VQvb.cjs → AssistantChart-Bdd44uBn.cjs} +388 -127
- package/dist/{AssistantChart-CVko2A1W.js → AssistantChart-CFhDdGyU.js} +391 -130
- package/dist/AssistantChart-COGiOV-g.cjs +3541 -0
- package/dist/AssistantChart-CWX1OWNM.js +3373 -0
- package/dist/{AssistantChart-CVzmmhx4.js → AssistantChart-C_hwFRRr.js} +4 -4
- package/dist/{AssistantChart-BAudAfne.cjs → AssistantChart-CldVCVDe.cjs} +5 -5
- package/dist/{AssistantChart-BP8upjMk.js → AssistantChart-Cu3m7RBo.js} +5 -5
- package/dist/AssistantChart-CxGjH7Qk.js +3477 -0
- package/dist/AssistantChart-DIpshm3i.js +4784 -0
- package/dist/AssistantChart-D_PTeu8P.cjs +3503 -0
- package/dist/{AssistantChart-9w31gdAb.cjs → AssistantChart-DoZCyS5r.cjs} +4 -4
- package/dist/AssistantChart-zjsy2GaZ.cjs +4810 -0
- package/dist/AudioPlayer-9psiEucT.cjs +1282 -0
- package/dist/AudioPlayer-B1lt5cPl.cjs +989 -0
- package/dist/AudioPlayer-BZ7bibzU.cjs +982 -0
- package/dist/AudioPlayer-BpRPS4-1.cjs +1277 -0
- package/dist/AudioPlayer-C12BjQBV.cjs +997 -0
- package/dist/{AudioPlayer-1ypwE2Wh.cjs → AudioPlayer-CFeV8t-5.cjs} +1 -1
- package/dist/{AudioPlayer-DuKXrCfy.js → AudioPlayer-CGRUtUdN.js} +1 -1
- package/dist/AudioPlayer-Coly3q5R.js +1278 -0
- package/dist/AudioPlayer-CySJIyvL.js +937 -0
- package/dist/AudioPlayer-DMcG_c7L.js +990 -0
- package/dist/AudioPlayer-DcFKRJE_.js +998 -0
- package/dist/AudioPlayer-Dp2bD1Gk.js +1278 -0
- package/dist/AudioPlayer-IAU5q5T1.cjs +936 -0
- package/dist/AudioPlayer-e8LfNoqO.js +983 -0
- package/dist/BrandColorsContext-565dDHd5.js +660 -0
- package/dist/BrandColorsContext-BcJbtkqn.cjs +659 -0
- package/dist/BrandColorsContext-DZT7JjeD.js +659 -0
- package/dist/BrandColorsContext-awnBCmC4.cjs +666 -0
- package/dist/{xertica-assistant-Qp3ydksa.cjs → CodeBlock-7TTgmdGG.cjs} +263 -51
- package/dist/{xertica-assistant-gnCJdcZY.js → CodeBlock-BeSt1h5P.js} +219 -7
- package/dist/CodeBlock-BgfYL_rD.cjs +2094 -0
- package/dist/CodeBlock-BlcqlA9M.cjs +2094 -0
- package/dist/CodeBlock-Bnmeu5ez.cjs +2094 -0
- package/dist/CodeBlock-BtfPlbAI.js +2078 -0
- package/dist/CodeBlock-CIySIuYr.js +2078 -0
- package/dist/CodeBlock-CuPtUM-7.cjs +2094 -0
- package/dist/CodeBlock-D6ffWXgc.js +2078 -0
- package/dist/CodeBlock-D8dcwbit.cjs +2094 -0
- package/dist/CodeBlock-DMZrFnlw.cjs +2094 -0
- package/dist/CodeBlock-DYkTfR0f.js +221 -0
- package/dist/CodeBlock-DlBehYN8.js +2078 -0
- package/dist/CodeBlock-DnYNI8rQ.js +2078 -0
- package/dist/CodeBlock-DvKWbSnE.cjs +2094 -0
- package/dist/CodeBlock-DwMCfkFY.js +2078 -0
- package/dist/CodeBlock-Dy6CNYyj.js +2078 -0
- package/dist/CodeBlock-EOvp9cVu.cjs +223 -0
- package/dist/CodeBlock-U1pPOQI7.cjs +2094 -0
- package/dist/CodeBlock-f_GpNhEB.js +2078 -0
- package/dist/CodeBlock-oB6u8nI1.js +2078 -0
- package/dist/CodeBlock-tZC31B73.cjs +2094 -0
- package/dist/CustomTooltipContent-BhdIeBEg.cjs +54 -0
- package/dist/CustomTooltipContent-CNbVB2NS.js +33 -0
- package/dist/FeatureCard-BZ4CYxFf.cjs +497 -0
- package/dist/FeatureCard-CxC-7C-C.cjs +300 -0
- package/dist/FeatureCard-DNycVGwT.js +485 -0
- package/dist/FeatureCard-DbHWCb4E.js +301 -0
- package/dist/FeatureCardSkeleton-DZqc96mt.js +27 -0
- package/dist/FeatureCardSkeleton-pTa0YNKP.cjs +29 -0
- package/dist/ImageWithFallback-CGtidP6B.cjs +4542 -0
- package/dist/ImageWithFallback-lsg3pdFg.js +4508 -0
- package/dist/{LanguageContext-DvUt5jBg.cjs → LanguageContext-B_KFTCzT.cjs} +2 -2
- package/dist/{LanguageContext-BwhwC3G2.js → LanguageContext-CS14yCpi.js} +2 -2
- package/dist/{XerticaXLogo-BWaag64t.js → LanguageSelector-B5YfbHra.js} +115 -136
- package/dist/{XerticaXLogo-DTee_y8X.cjs → LanguageSelector-D6uacAIM.cjs} +115 -136
- package/dist/LayoutContext-B45-e9DI.cjs +93 -0
- package/dist/LayoutContext-BAql6ZRY.js +97 -0
- package/dist/LayoutContext-BEq_-n98.cjs +96 -0
- package/dist/LayoutContext-Bav3UMEA.js +94 -0
- package/dist/LayoutContext-BvK-ggDa.cjs +96 -0
- package/dist/LayoutContext-DNl1xSoX.js +92 -0
- package/dist/{ThemeContext-Bo-W2WZH.js → ThemeContext-BWq9ACPo.js} +8 -13
- package/dist/{ThemeContext-ept8jhXI.js → ThemeContext-BXjrgUjW.js} +261 -200
- package/dist/{ThemeContext-BblcjQup.cjs → ThemeContext-Bmod0Cg2.cjs} +8 -13
- package/dist/ThemeContext-BoH4NLfN.js +734 -0
- package/dist/{ThemeContext-BbBNoFTG.js → ThemeContext-C2EwAPDt.js} +2 -2
- package/dist/{ThemeContext-U4dEYc6C.cjs → ThemeContext-CGk3KK0k.cjs} +1 -8
- package/dist/{ThemeContext-CP3a0jxy.cjs → ThemeContext-CMD3z2Dz.cjs} +268 -193
- package/dist/{ThemeContext-D3LzacmG.js → ThemeContext-CQSo4Iwc.js} +1 -8
- package/dist/ThemeContext-j5aGtPky.cjs +1924 -0
- package/dist/ThemeContext-r69W20Xg.cjs +733 -0
- package/dist/{ThemeContext-Cmr8Ex8H.cjs → ThemeContext-vTjumZeM.cjs} +2 -2
- package/dist/ThemeContext-x_F2zsnv.js +1923 -0
- package/dist/{VerifyEmailPage-BRSP-Pwt.cjs → VerifyEmailPage--1Vurewl.cjs} +3 -3
- package/dist/{VerifyEmailPage-BE-L9mB7.js → VerifyEmailPage-1WwWczAn.js} +12 -22
- package/dist/{VerifyEmailPage-DF2ilhum.cjs → VerifyEmailPage-B4peJjAT.cjs} +356 -334
- package/dist/{VerifyEmailPage-CR7kb5df.cjs → VerifyEmailPage-BComraR7.cjs} +12 -22
- package/dist/{VerifyEmailPage-hdB8JQGv.cjs → VerifyEmailPage-By3Jf__L.cjs} +348 -329
- package/dist/{VerifyEmailPage-BiRm7Nh4.cjs → VerifyEmailPage-ByerOcm4.cjs} +348 -329
- package/dist/{VerifyEmailPage-CbgjOF0v.js → VerifyEmailPage-C0c2e5n0.js} +7 -7
- package/dist/{VerifyEmailPage-EhudUdqF.js → VerifyEmailPage-C5TNQTBa.js} +355 -343
- package/dist/{VerifyEmailPage-Dt7zgA4w.cjs → VerifyEmailPage-CFLMls1p.cjs} +4 -4
- package/dist/{VerifyEmailPage-vYHbYK3q.js → VerifyEmailPage-CJLz3jrn.js} +347 -338
- package/dist/VerifyEmailPage-COiyNl1y.js +2825 -0
- package/dist/{VerifyEmailPage-DMBh4NM9.cjs → VerifyEmailPage-CYXtbKi3.cjs} +1 -1
- package/dist/{VerifyEmailPage-DTtFfC-J.js → VerifyEmailPage-CgMxRb4z.js} +3 -3
- package/dist/VerifyEmailPage-CqKsR2v8.js +2827 -0
- package/dist/{VerifyEmailPage-Bae2cBXT.cjs → VerifyEmailPage-Cwi3kbol.cjs} +7 -7
- package/dist/{VerifyEmailPage-BIBOKV7Z.js → VerifyEmailPage-DSBMRHtl.js} +36 -41
- package/dist/{VerifyEmailPage-D-FRj5TU.cjs → VerifyEmailPage-De6bQjrz.cjs} +36 -41
- package/dist/{VerifyEmailPage-Bvfv8HVQ.js → VerifyEmailPage-DgIid028.js} +347 -338
- package/dist/VerifyEmailPage-DjQKRlUS.cjs +2824 -0
- package/dist/{VerifyEmailPage-CdYPSJoO.js → VerifyEmailPage-DvMLZgFt.js} +1 -1
- package/dist/{VerifyEmailPage-C_ihbcth.js → VerifyEmailPage-MTD7AG1Z.js} +4 -4
- package/dist/VerifyEmailPage-s-1X3LDJ.cjs +2826 -0
- package/dist/XerticaOrbe-KL1RBHzw.cjs +1354 -0
- package/dist/XerticaOrbe-Uk2JML1-.cjs +1927 -0
- package/dist/XerticaOrbe-jA5T2iOk.js +1925 -0
- package/dist/XerticaOrbe-zwS1p2a8.js +1355 -0
- package/dist/XerticaProvider-6btlAlzc.js +17 -0
- package/dist/{XerticaProvider-siSt9uG2.js → XerticaProvider-B7EVH-NF.js} +2 -2
- package/dist/{XerticaProvider-AbWlr7Af.cjs → XerticaProvider-BIrqfZ-i.cjs} +11 -8
- package/dist/XerticaProvider-BNoNOxQ5.cjs +16 -0
- package/dist/XerticaProvider-BlY2limY.cjs +38 -0
- package/dist/{XerticaProvider-CWgby5mY.js → XerticaProvider-C1DKnvLh.js} +4 -4
- package/dist/{XerticaProvider-AChwphCO.cjs → XerticaProvider-CBGc4EMA.cjs} +4 -4
- package/dist/{XerticaProvider-BITjgC5p.js → XerticaProvider-CEoWMTxu.js} +2 -2
- package/dist/{XerticaProvider-By8q3Roe.cjs → XerticaProvider-CllrbMEJ.cjs} +2 -2
- package/dist/{XerticaProvider-B8CaV7xu.cjs → XerticaProvider-D-yNhF94.cjs} +1 -1
- package/dist/XerticaProvider-DDuiIcKo.js +39 -0
- package/dist/{XerticaProvider-CWs6EwNa.js → XerticaProvider-DUOJg9iX.js} +10 -10
- package/dist/{XerticaProvider-DQtvJU7m.js → XerticaProvider-DYq4JWtg.js} +1 -1
- package/dist/{XerticaProvider-CjQAQPcn.cjs → XerticaProvider-Dl_b72_l.cjs} +11 -8
- package/dist/{XerticaProvider-D5lLumH-.js → XerticaProvider-Dt5HEzbQ.js} +10 -10
- package/dist/{XerticaProvider-CW9hpCdF.cjs → XerticaProvider-ET0ihewn.cjs} +2 -2
- package/dist/XerticaProvider-cI9hSs27.cjs +38 -0
- package/dist/XerticaProvider-hSwhNQex.js +39 -0
- package/dist/{XerticaXLogo-ChryA6xj.js → XerticaXLogo-B7xQ5dhi.js} +1 -1
- package/dist/{XerticaXLogo-CziKMQil.cjs → XerticaXLogo-CQUUjXoH.cjs} +8 -8
- package/dist/{XerticaXLogo-DfUvz-lD.js → XerticaXLogo-Cmsp-Eey.js} +9 -9
- package/dist/{XerticaXLogo-CFuIlYFH.js → XerticaXLogo-DZbo4vOE.js} +12 -12
- package/dist/{XerticaXLogo-8TTzBjHw.cjs → XerticaXLogo-Zw2B276b.cjs} +1 -1
- package/dist/{XerticaXLogo-kslQ8Tk_.cjs → XerticaXLogo-bvZSgwGF.cjs} +13 -7
- package/dist/{XerticaXLogo-DHz5SugF.js → XerticaXLogo-mqjoBiLI.js} +12 -12
- package/dist/{XerticaXLogo-CU-U-GP4.cjs → XerticaXLogo-uQgwns_E.cjs} +13 -7
- package/dist/alert-dialog-BOje--vD.js +847 -0
- package/dist/alert-dialog-BtEuQqrg.cjs +870 -0
- package/dist/{alert-dialog-yckpaOpy.cjs → alert-dialog-DSKByiKZ.cjs} +3 -3
- package/dist/alert-dialog-DhwPioBa.cjs +885 -0
- package/dist/alert-dialog-DqlRW_An.js +831 -0
- package/dist/{alert-dialog-iDe5VE5o.js → alert-dialog-s-vmNkJ_.js} +3 -3
- package/dist/assistant.cjs.js +8 -4
- package/dist/assistant.es.js +5 -11
- package/dist/avatar-3kO2Anrp.js +54 -0
- package/dist/avatar-BCM7YQRC.cjs +77 -0
- package/dist/blocks.cjs.js +9 -4
- package/dist/blocks.es.js +2 -16
- package/dist/brand.cjs.js +10 -5
- package/dist/brand.es.js +3 -11
- package/dist/breadcrumb-BKtHF4gk.cjs +98 -0
- package/dist/breadcrumb-CqJ7bHY5.js +161 -0
- package/dist/breadcrumb-ifNsA7Zl.js +90 -0
- package/dist/breadcrumb-m9Hb2_XN.cjs +177 -0
- package/dist/button-0BlA47It.cjs +85 -0
- package/dist/button-DZHzN1Gd.js +62 -0
- package/dist/cli.js +391 -66
- package/dist/components/assistant/xertica-assistant/hooks/index.d.ts +6 -0
- package/dist/components/assistant/xertica-assistant/hooks/use-assistant-conversations.d.ts +21 -0
- package/dist/components/assistant/xertica-assistant/hooks/use-assistant-messages.d.ts +49 -0
- package/dist/components/assistant/xertica-assistant/hooks/use-assistant-suggestions.d.ts +16 -0
- package/dist/components/blocks/audio-player/AudioPlayer.d.ts +35 -0
- package/dist/components/blocks/audio-player/index.d.ts +1 -0
- package/dist/components/blocks/document-editor/DocumentEditor.d.ts +26 -0
- package/dist/components/blocks/document-editor/index.d.ts +1 -0
- package/dist/components/blocks/podcast-player/PodcastPlayer.d.ts +41 -0
- package/dist/components/blocks/podcast-player/index.d.ts +1 -0
- package/dist/components/ui/chart/parts/chart-dashboard.d.ts +113 -0
- package/dist/components/ui/chart/parts/chart-metric.d.ts +118 -0
- package/dist/components/ui/chart/parts/chart-primitives.d.ts +101 -0
- package/dist/components/ui/chart/parts/chart-shared.d.ts +20 -0
- package/dist/components/ui/chart/parts/chart-utils.d.ts +12 -0
- package/dist/components/ui/chart/parts/index.d.ts +5 -0
- package/dist/dropdown-menu-BDB5CmQs.cjs +247 -0
- package/dist/dropdown-menu-BMcykFDf.cjs +225 -0
- package/dist/dropdown-menu-DQidbKBD.js +231 -0
- package/dist/dropdown-menu-Dn_eV2Xb.js +190 -0
- package/dist/google-maps-loader-BCe58h9D.js +308 -0
- package/dist/google-maps-loader-BFWp6VPd.js +287 -0
- package/dist/google-maps-loader-BKcdgFbu.cjs +312 -0
- package/dist/{google-maps-loader-t2IlYBzw.js → google-maps-loader-CTYySAun.js} +4 -0
- package/dist/google-maps-loader-CumCNXeG.js +312 -0
- package/dist/{google-maps-loader-BqsYL48U.cjs → google-maps-loader-Y-QkD-Li.cjs} +5 -0
- package/dist/google-maps-loader-casMyxlo.cjs +316 -0
- package/dist/google-maps-loader-eS3uQ5TA.cjs +287 -0
- package/dist/header-Cgy6vYPk.cjs +731 -0
- package/dist/header-DRlT4jgI.js +715 -0
- package/dist/header-Dux00SI4.cjs +731 -0
- package/dist/header-EkGKXPsD.js +715 -0
- package/dist/header-WfEywpyc.cjs +731 -0
- package/dist/header-tifNQn2U.js +715 -0
- package/dist/hooks.cjs.js +12 -8
- package/dist/hooks.es.js +10 -27
- package/dist/index-9GWd0qxq.cjs +12 -0
- package/dist/index-BabBx2pa.js +6 -0
- package/dist/index-BhapVLVj.js +8 -0
- package/dist/{index-D3RLKRAs.cjs → index-COtD8bRW.cjs} +1 -1
- package/dist/index-D6fxYEY8.cjs +7 -0
- package/dist/index-DAIp0_HK.js +8 -0
- package/dist/index-DW5tYe26.js +8 -0
- package/dist/index-GA__GvnG.cjs +7 -0
- package/dist/index.cjs.js +37 -32
- package/dist/index.es.js +30 -363
- package/dist/index.umd.js +1043 -470
- package/dist/input-2R4loU86.js +127 -0
- package/dist/input-C_UiS2Py.cjs +152 -0
- package/dist/input-DWANSKGb.cjs +145 -0
- package/dist/input-cc-PTD4R.js +123 -0
- package/dist/layout.cjs.js +10 -6
- package/dist/layout.es.js +7 -9
- package/dist/media.cjs.js +8 -3
- package/dist/media.es.js +1 -6
- package/dist/pages.cjs.js +8 -3
- package/dist/pages.es.js +1 -11
- package/dist/progress-C7Lti5wo.js +80 -0
- package/dist/progress-Cqwxbqs1.cjs +103 -0
- package/dist/progress-DPtzoVV8.js +175 -0
- package/dist/progress-EeaoqqUs.cjs +191 -0
- package/dist/rich-text-editor-0mraWT5y.cjs +2376 -0
- package/dist/rich-text-editor-B-IkcPD0.js +2874 -0
- package/dist/rich-text-editor-B6jMRLzk.cjs +1939 -0
- package/dist/rich-text-editor-B8_oYcIR.js +1730 -0
- package/dist/rich-text-editor-B9UbSXNb.js +1203 -0
- package/dist/rich-text-editor-BYuRBNBU.js +2373 -0
- package/dist/rich-text-editor-Bb9pySTs.cjs +2374 -0
- package/dist/rich-text-editor-BcL6L3cm.cjs +2374 -0
- package/dist/rich-text-editor-BoVZYtTs.cjs +2391 -0
- package/dist/rich-text-editor-Bp3zQqMC.js +2954 -0
- package/dist/rich-text-editor-CMgSN_w2.js +1189 -0
- package/dist/rich-text-editor-CPV1lEPH.cjs +1748 -0
- package/dist/rich-text-editor-CeucBdIv.cjs +2971 -0
- package/dist/rich-text-editor-CoKqbCtu.cjs +1799 -0
- package/dist/rich-text-editor-Cw56T_mB.js +2356 -0
- package/dist/rich-text-editor-Cyt8qs2b.js +1921 -0
- package/dist/rich-text-editor-D6H84OcX.cjs +1220 -0
- package/dist/rich-text-editor-D76gD-QI.js +2328 -0
- package/dist/rich-text-editor-DKkokOnA.js +1781 -0
- package/dist/rich-text-editor-DNsdpN64.cjs +2359 -0
- package/dist/rich-text-editor-DfG8bCyY.js +2358 -0
- package/dist/rich-text-editor-DqLICivI.js +2832 -0
- package/dist/rich-text-editor-DxO1Hz3a.cjs +2903 -0
- package/dist/rich-text-editor-Dxjw31Z4.js +2341 -0
- package/dist/rich-text-editor-DzP0Epmb.js +2356 -0
- package/dist/rich-text-editor-bRkNoeZY.cjs +2891 -0
- package/dist/rich-text-editor-lyYE2ZG5.cjs +1207 -0
- package/dist/rich-text-editor-skplNlBM.cjs +2345 -0
- package/dist/select-Bkbr0f-Z.cjs +162 -0
- package/dist/select-CH6v_KcQ.cjs +161 -0
- package/dist/select-CvIVdX2n.js +145 -0
- package/dist/select-D-xvCZK2.js +130 -0
- package/dist/{sidebar-CA6_ek3f.js → sidebar-3XyzjVBw.js} +40 -49
- package/dist/{sidebar-CplprZpM.js → sidebar-B6SlKZYN.js} +40 -49
- package/dist/{sidebar-CmvwjnVb.js → sidebar-BViy8Eeu.js} +17 -9
- package/dist/{sidebar-Dz7bd3zP.js → sidebar-BbVIQvlP.js} +1 -1
- package/dist/{sidebar-CVUGHOS_.cjs → sidebar-BxGXsDAd.cjs} +16 -8
- package/dist/sidebar-CK_0ZQHj.cjs +803 -0
- package/dist/sidebar-CUuOvYhK.js +787 -0
- package/dist/{sidebar-KIS0C2JH.js → sidebar-CrQDDdcz.js} +24 -33
- package/dist/{sidebar-zowjejT2.cjs → sidebar-DAaY8bRU.cjs} +24 -33
- package/dist/{sidebar-B9NR0lCe.cjs → sidebar-DQj1z3jG.cjs} +227 -269
- package/dist/sidebar-Djn5syhi.cjs +786 -0
- package/dist/{sidebar-BvF5I2Ue.cjs → sidebar-DyYvgyBj.cjs} +41 -46
- package/dist/sidebar-LluMXfam.js +759 -0
- package/dist/sidebar-_rT7rBMk.js +787 -0
- package/dist/{sidebar-B3EYhli0.cjs → sidebar-nzPoVHBQ.cjs} +41 -46
- package/dist/{sidebar-C5B_LHek.cjs → sidebar-q7P2Godd.cjs} +1 -1
- package/dist/skeleton-DjiHerJn.cjs +87 -0
- package/dist/skeleton-DtR5tkYe.js +78 -0
- package/dist/slider-B00b9SVK.cjs +78 -0
- package/dist/slider-Bc5Hd0y1.js +56 -0
- package/dist/slider-DQCNUUMj.js +56 -0
- package/dist/slider-N7hFFj6X.cjs +73 -0
- package/dist/sonner-B-jWlik1.cjs +68 -0
- package/dist/sonner-C9tiqj4f.js +47 -0
- package/dist/tooltip-D8n9UYoU.cjs +72 -0
- package/dist/tooltip-Ded96neP.cjs +137 -0
- package/dist/tooltip-HDOoD2-0.js +120 -0
- package/dist/tooltip-RtbSmPYJ.js +48 -0
- package/dist/ui.cjs.js +23 -18
- package/dist/ui.es.js +16 -303
- package/dist/use-audio-player-B31J-aqh.cjs +187 -0
- package/dist/use-audio-player-B78fd2ct.js +188 -0
- package/dist/use-audio-player-BkmEmj8Q.js +185 -0
- package/dist/use-audio-player-CLFTWFW1.cjs +184 -0
- package/dist/use-audio-player-CLLn00I6.js +188 -0
- package/dist/use-audio-player-DGvhPrgR.cjs +190 -0
- package/dist/{use-audio-player-Dn1NR9xN.cjs → use-audio-player-NKsWyjWu.cjs} +7 -3
- package/dist/{use-audio-player-Bkh23vQ3.js → use-audio-player-nv8ZSGa1.js} +7 -3
- package/dist/use-file-upload-BcjEo2S5.js +404 -0
- package/dist/use-file-upload-CRJR68Tj.cjs +403 -0
- package/dist/use-mobile-B0hNy_Y6.cjs +4303 -0
- package/dist/use-mobile-BXuYROXM.js +4202 -0
- package/dist/use-mobile-Bbd51ASU.cjs +4392 -0
- package/dist/use-mobile-BdXTRb0Z.cjs +51 -0
- package/dist/use-mobile-Bk6CX-TC.js +4359 -0
- package/dist/use-mobile-BvYdisLP.js +4202 -0
- package/dist/use-mobile-BzuxjzNX.cjs +4392 -0
- package/dist/use-mobile-CG2-SdXV.cjs +4235 -0
- package/dist/use-mobile-CKb5pqTs.js +4269 -0
- package/dist/use-mobile-CYuAuGDl.js +4202 -0
- package/dist/use-mobile-CaENcqm-.js +4508 -0
- package/dist/use-mobile-CbrYgJGJ.js +4203 -0
- package/dist/use-mobile-Cd4xPrKq.cjs +46 -0
- package/dist/use-mobile-Ce2cBAQe.js +29 -0
- package/dist/use-mobile-DMOvImGQ.cjs +4542 -0
- package/dist/use-mobile-DRB3BQgD.cjs +4235 -0
- package/dist/use-mobile-DZvv7QMR.js +4359 -0
- package/dist/use-mobile-DdI_TXam.cjs +4235 -0
- package/dist/use-mobile-DlceKf8a.js +4359 -0
- package/dist/use-mobile-DsOnow1o.cjs +4236 -0
- package/dist/use-mobile-Kcj6jSnK.cjs +4392 -0
- package/dist/use-mobile-bnKcua_i.js +4202 -0
- package/dist/use-mobile-j4w2Jrf1.js +30 -0
- package/dist/use-mobile-ncXBeE2z.cjs +4235 -0
- package/dist/use-rich-text-editor-DjiddBGv.js +282 -0
- package/dist/use-rich-text-editor-lpeswbCs.cjs +281 -0
- package/dist/xertica-assistant-B687qEPU.js +2165 -0
- package/dist/xertica-assistant-BdiZag0h.js +2187 -0
- package/dist/xertica-assistant-CrgTb6Hs.cjs +2155 -0
- package/dist/xertica-assistant-DCsnQyi5.js +2156 -0
- package/dist/xertica-assistant-DUBpmEgo.cjs +2186 -0
- package/dist/{xertica-assistant-Bj3vBCq_.cjs → xertica-assistant-V_IdW4WF.cjs} +27 -9
- package/dist/{xertica-assistant-BMqdyRVi.js → xertica-assistant-ciJaWqm1.js} +28 -10
- package/dist/{xertica-assistant-B1IaHXnB.cjs → xertica-assistant-dyP7KHM5.cjs} +533 -392
- package/dist/xertica-assistant-sOHwTgIP.cjs +2172 -0
- package/dist/{xertica-assistant-DPsESB6t.js → xertica-assistant-yX1CFBBo.js} +535 -394
- package/dist/xertica-ui.css +2 -2
- package/docs/ai-usage.md +195 -195
- package/docs/components/accordion.md +109 -109
- package/docs/components/alert-dialog.md +127 -127
- package/docs/components/alert.md +106 -106
- package/docs/components/aspect-ratio.md +58 -58
- package/docs/components/assistant-chart.md +47 -47
- package/docs/components/assistant.md +2 -0
- package/docs/components/audio-player.md +167 -167
- package/docs/components/avatar.md +101 -101
- package/docs/components/badge.md +84 -84
- package/docs/components/breadcrumb.md +104 -104
- package/docs/components/button.md +156 -156
- package/docs/components/calendar.md +141 -141
- package/docs/components/card.md +245 -245
- package/docs/components/carousel.md +100 -100
- package/docs/components/chart.md +638 -638
- package/docs/components/checkbox.md +88 -88
- package/docs/components/code-block.md +105 -105
- package/docs/components/collapsible.md +86 -86
- package/docs/components/command.md +113 -113
- package/docs/components/context-menu.md +81 -81
- package/docs/components/dialog.md +198 -198
- package/docs/components/drawer.md +105 -105
- package/docs/components/dropdown-menu.md +127 -127
- package/docs/components/empty.md +127 -127
- package/docs/components/error-boundary.md +191 -191
- package/docs/components/file-upload.md +189 -189
- package/docs/components/floating-media-wrapper.md +63 -63
- package/docs/components/form.md +177 -177
- package/docs/components/formatted-document.md +105 -105
- package/docs/components/google-maps-loader.md +44 -44
- package/docs/components/header.md +177 -177
- package/docs/components/hover-card.md +86 -86
- package/docs/components/image-with-fallback.md +107 -107
- package/docs/components/input-otp.md +95 -95
- package/docs/components/input.md +130 -130
- package/docs/components/label.md +69 -69
- package/docs/components/language-selector.md +172 -172
- package/docs/components/map-layers.md +138 -138
- package/docs/components/map.md +84 -84
- package/docs/components/markdown-message.md +47 -47
- package/docs/components/menubar.md +89 -89
- package/docs/components/modern-chat-input.md +164 -164
- package/docs/components/navigation-menu.md +83 -83
- package/docs/components/notification-badge.md +78 -78
- package/docs/components/page-header.md +93 -93
- package/docs/components/pages.md +309 -309
- package/docs/components/pagination.md +334 -334
- package/docs/components/popover.md +116 -116
- package/docs/components/progress.md +103 -103
- package/docs/components/radio-group.md +133 -133
- package/docs/components/rating.md +77 -77
- package/docs/components/resizable.md +84 -84
- package/docs/components/rich-text-editor.md +255 -255
- package/docs/components/route-map.md +124 -124
- package/docs/components/scroll-area.md +58 -58
- package/docs/components/search.md +87 -87
- package/docs/components/select.md +144 -144
- package/docs/components/separator.md +58 -58
- package/docs/components/sheet.md +122 -122
- package/docs/components/sidebar.md +314 -314
- package/docs/components/simple-map.md +51 -51
- package/docs/components/skeleton.md +99 -99
- package/docs/components/slider.md +84 -84
- package/docs/components/sonner.md +115 -115
- package/docs/components/stats-card.md +120 -120
- package/docs/components/stepper.md +268 -268
- package/docs/components/switch.md +106 -106
- package/docs/components/table.md +138 -138
- package/docs/components/tabs.md +117 -117
- package/docs/components/textarea.md +86 -86
- package/docs/components/theme-toggle.md +73 -73
- package/docs/components/timeline.md +121 -121
- package/docs/components/toggle-group.md +68 -68
- package/docs/components/toggle.md +62 -62
- package/docs/components/tooltip.md +116 -116
- package/docs/components/tree-view.md +238 -238
- package/docs/components/use-mobile.md +96 -96
- package/docs/components/video-player.md +68 -68
- package/docs/components/xertica-logo.md +36 -36
- package/docs/components/xertica-orbe.md +35 -35
- package/docs/components/xertica-provider.md +65 -65
- package/docs/components/xertica-xlogo.md +35 -35
- package/docs/decision-tree.md +293 -293
- package/docs/form-sizing.md +162 -162
- package/docs/getting-started.md +24 -12
- package/docs/i18n.md +476 -476
- package/docs/installation.md +267 -267
- package/docs/layout.md +143 -143
- package/docs/patterns/analytics.md +194 -194
- package/docs/patterns/crud.md +149 -149
- package/docs/patterns/dashboard.md +138 -138
- package/docs/patterns/detail-page.md +296 -296
- package/docs/patterns/form.md +241 -241
- package/docs/patterns/login.md +156 -156
- package/docs/patterns/settings.md +368 -368
- package/docs/patterns/wizard.md +213 -213
- package/hooks/useTheme.test.tsx +16 -16
- package/hooks/useTheme.ts +4 -4
- package/imports/Podcast.tsx +540 -540
- package/imports/XerticaAi.tsx +46 -46
- package/imports/XerticaX.tsx +15 -15
- package/imports/svg-aueiaqngck.ts +20 -20
- package/imports/svg-v9krss1ozd.ts +23 -23
- package/imports/svg-vhrdofe3qe.ts +6 -6
- package/llms-compact.txt +2 -1
- package/llms.txt +2 -1
- package/mcp/resources.json +22 -22
- package/mcp/tools.json +35 -35
- package/package.json +10 -4
- package/scripts/ai-validator.ts +91 -91
- package/scripts/cleanup-case-dupes.ts +62 -62
- package/scripts/generate-ai-manifests.ts +107 -107
- package/styles/globals.css +13 -13
- package/styles/xertica/app-overrides/chat.css +61 -61
- package/styles/xertica/app-overrides/scrollbar.css +33 -33
- package/styles/xertica/base.css +84 -71
- package/styles/xertica/integrations/google-maps.css +76 -76
- package/styles/xertica/integrations/sonner.css +73 -73
- package/styles/xertica/theme-map.css +102 -99
- package/styles/xertica/tokens.css +240 -236
- package/templates/.prettierignore +4 -4
- package/templates/.prettierrc +10 -10
- package/templates/CLAUDE.md +165 -165
- package/templates/eslint.config.js +26 -26
- package/templates/package.json +3 -3
- package/templates/postcss.config.js +6 -6
- package/templates/src/app/components/AppLayout.tsx +55 -55
- package/templates/src/app/components/AuthGuard.tsx +82 -82
- package/templates/src/app/context/AuthContext.tsx +108 -108
- package/templates/src/features/assistant/data/mock.ts +75 -75
- package/templates/src/features/assistant/hooks/useAssistantConfig.ts +20 -20
- package/templates/src/features/auth/index.ts +4 -4
- package/templates/src/features/auth/ui/AuthPageShell.tsx +32 -32
- package/templates/src/features/auth/ui/ResetPasswordContent.tsx +179 -179
- package/templates/src/features/auth/ui/VerifyEmailContent.tsx +84 -84
- package/templates/src/features/home/data/mock.ts +35 -35
- package/templates/src/features/home/hooks/useFeatureCards.ts +20 -20
- package/templates/src/features/home/store/dashboardStore.ts +25 -25
- package/templates/src/features/home/ui/HomeContent.tsx +1 -1
- package/templates/src/features/template/index.ts +5 -5
- package/templates/src/features/template/ui/CrudTemplate.tsx +115 -115
- package/templates/src/features/template/ui/DashboardTemplate.tsx +110 -110
- package/templates/src/features/template/ui/FormTemplate.tsx +117 -117
- package/templates/src/features/template/ui/LoginTemplate.tsx +59 -59
- package/templates/src/features/template/ui/TemplateContent.tsx +1314 -1314
- package/templates/src/i18n.ts +124 -124
- package/templates/src/locales/en/common.json +21 -21
- package/templates/src/locales/en/components/activityCard.json +10 -10
- package/templates/src/locales/en/components/assistant.json +119 -119
- package/templates/src/locales/en/components/media.json +29 -29
- package/templates/src/locales/en/components/notificationCard.json +5 -5
- package/templates/src/locales/en/components/profileCard.json +8 -8
- package/templates/src/locales/en/components/projectCard.json +10 -10
- package/templates/src/locales/en/components/sidebar.json +14 -14
- package/templates/src/locales/en/components/stats.json +8 -8
- package/templates/src/locales/en/components/team.json +14 -14
- package/templates/src/locales/en/errors.json +9 -9
- package/templates/src/locales/en/languageSelector.json +7 -7
- package/templates/src/locales/en/nav.json +6 -6
- package/templates/src/locales/en/pages/crudTemplate.json +25 -25
- package/templates/src/locales/en/pages/dashboardTemplate.json +20 -20
- package/templates/src/locales/en/pages/forgotPassword.json +10 -10
- package/templates/src/locales/en/pages/formTemplate.json +16 -16
- package/templates/src/locales/en/pages/home.json +7 -7
- package/templates/src/locales/en/pages/login.json +15 -15
- package/templates/src/locales/en/pages/loginTemplate.json +9 -9
- package/templates/src/locales/en/pages/resetPassword.json +18 -18
- package/templates/src/locales/en/pages/templates.json +317 -317
- package/templates/src/locales/en/pages/verifyEmail.json +12 -12
- package/templates/src/locales/en/themeToggle.json +6 -6
- package/templates/src/locales/es/common.json +21 -21
- package/templates/src/locales/es/components/activityCard.json +10 -10
- package/templates/src/locales/es/components/assistant.json +119 -119
- package/templates/src/locales/es/components/media.json +29 -29
- package/templates/src/locales/es/components/notificationCard.json +5 -5
- package/templates/src/locales/es/components/profileCard.json +8 -8
- package/templates/src/locales/es/components/projectCard.json +10 -10
- package/templates/src/locales/es/components/sidebar.json +14 -14
- package/templates/src/locales/es/components/stats.json +8 -8
- package/templates/src/locales/es/components/team.json +14 -14
- package/templates/src/locales/es/errors.json +9 -9
- package/templates/src/locales/es/languageSelector.json +7 -7
- package/templates/src/locales/es/nav.json +6 -6
- package/templates/src/locales/es/pages/crudTemplate.json +25 -25
- package/templates/src/locales/es/pages/dashboardTemplate.json +20 -20
- package/templates/src/locales/es/pages/forgotPassword.json +10 -10
- package/templates/src/locales/es/pages/formTemplate.json +16 -16
- package/templates/src/locales/es/pages/home.json +7 -7
- package/templates/src/locales/es/pages/login.json +15 -15
- package/templates/src/locales/es/pages/loginTemplate.json +9 -9
- package/templates/src/locales/es/pages/resetPassword.json +18 -18
- package/templates/src/locales/es/pages/templates.json +317 -317
- package/templates/src/locales/es/pages/verifyEmail.json +12 -12
- package/templates/src/locales/es/themeToggle.json +6 -6
- package/templates/src/locales/pt-BR/common.json +21 -21
- package/templates/src/locales/pt-BR/components/activityCard.json +10 -10
- package/templates/src/locales/pt-BR/components/assistant.json +119 -119
- package/templates/src/locales/pt-BR/components/media.json +29 -29
- package/templates/src/locales/pt-BR/components/notificationCard.json +5 -5
- package/templates/src/locales/pt-BR/components/profileCard.json +8 -8
- package/templates/src/locales/pt-BR/components/projectCard.json +10 -10
- package/templates/src/locales/pt-BR/components/sidebar.json +14 -14
- package/templates/src/locales/pt-BR/components/stats.json +8 -8
- package/templates/src/locales/pt-BR/components/team.json +14 -14
- package/templates/src/locales/pt-BR/errors.json +9 -9
- package/templates/src/locales/pt-BR/languageSelector.json +7 -7
- package/templates/src/locales/pt-BR/nav.json +6 -6
- package/templates/src/locales/pt-BR/pages/crudTemplate.json +25 -25
- package/templates/src/locales/pt-BR/pages/dashboardTemplate.json +20 -20
- package/templates/src/locales/pt-BR/pages/forgotPassword.json +10 -10
- package/templates/src/locales/pt-BR/pages/formTemplate.json +16 -16
- package/templates/src/locales/pt-BR/pages/home.json +7 -7
- package/templates/src/locales/pt-BR/pages/login.json +15 -15
- package/templates/src/locales/pt-BR/pages/loginTemplate.json +9 -9
- package/templates/src/locales/pt-BR/pages/resetPassword.json +18 -18
- package/templates/src/locales/pt-BR/pages/templates.json +317 -317
- package/templates/src/locales/pt-BR/pages/verifyEmail.json +12 -12
- package/templates/src/locales/pt-BR/themeToggle.json +6 -6
- package/templates/src/main.tsx +11 -11
- package/templates/src/pages/AssistantPage.tsx +464 -464
- package/templates/src/pages/ForgotPasswordPage.tsx +6 -6
- package/templates/src/pages/LoginPage.tsx +10 -10
- package/templates/src/pages/ResetPasswordPage.tsx +6 -6
- package/templates/src/pages/TemplatePage.tsx +28 -28
- package/templates/src/pages/VerifyEmailPage.tsx +6 -6
- package/templates/src/shared/config/navigation.ts +19 -19
- package/templates/src/shared/error-boundary.tsx +154 -154
- package/templates/src/shared/error-fallbacks.tsx +226 -226
- package/templates/src/shared/lib/auth.ts +20 -20
- package/templates/src/shared/types/auth.ts +3 -3
- package/templates/src/styles/index.css +95 -95
- package/templates/src/styles/xertica/tokens.css +240 -236
- package/templates/tsconfig.json +25 -25
- package/templates/tsconfig.node.json +12 -12
- package/templates/vite-env.d.ts +1 -1
- package/templates/vite.config.ts +1 -1
- package/utils/color-utils.ts +72 -72
- package/utils/demo-responses.test.ts +10 -10
- package/utils/demo-responses.ts +151 -151
- package/utils/gemini.test.ts +25 -25
- package/utils/gemini.ts +155 -155
- package/dist/ThemeContext-CpqYShLq.cjs +0 -324
- package/dist/ThemeContext-Du2nE1PL.js +0 -325
- package/dist/ThemeContext-GeEBTJ3q.cjs +0 -1621
- package/dist/ThemeContext-JyLK9B1o.js +0 -1622
- package/dist/XerticaProvider-CUYJZc32.js +0 -49
- package/dist/XerticaProvider-qQUDop71.cjs +0 -48
- package/dist/index-CkTUgOwX.js +0 -8
- package/dist/sidebar-OTO_up7Z.js +0 -801
- package/dist/{rich-text-editor-BmsjY03B.js → rich-text-editor-DgF8s7xW.js} +26 -26
- package/dist/{rich-text-editor-GS2kpTAK.cjs → rich-text-editor-mWoaSCE4.cjs} +26 -26
package/docs/components/chart.md
CHANGED
|
@@ -1,638 +1,638 @@
|
|
|
1
|
-
# Chart
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
Xertica UI provides a `ChartContainer` wrapper and related components built on top of **Recharts** for theme-aware, token-driven chart rendering. The chart system uses a `ChartConfig` object to define series labels and colors via CSS variables, ensuring full dark-mode support without hard-coded hex values.
|
|
6
|
-
|
|
7
|
-
The library ships **11 dashboard-ready chart wrappers** that handle loading, empty, and error states automatically, so feature layers only need to pass `data`, `isLoading`, `error`, and `onRetry`.
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Exports
|
|
12
|
-
|
|
13
|
-
| Export | Description |
|
|
14
|
-
| ---------------------------- | ------------------------------------------------------------------------------- |
|
|
15
|
-
| `ChartContainer` | Root container that injects CSS color variables and wraps `ResponsiveContainer` |
|
|
16
|
-
| `ChartTooltip` | Re-exported `recharts` `Tooltip` component |
|
|
17
|
-
| `ChartTooltipContent` | Styled tooltip content using the design system |
|
|
18
|
-
| `ChartLegend` | Re-exported `recharts` `Legend` component |
|
|
19
|
-
| `ChartLegendContent` | Styled legend content using the design system |
|
|
20
|
-
| `ChartStyle` | Internal style injector (used by `ChartContainer`, not used directly) |
|
|
21
|
-
| `ChartCard` | Card-based shell for dashboard chart panels |
|
|
22
|
-
| `DashboardBarChart` | Ready-to-use grouped or stacked bar chart |
|
|
23
|
-
| `DashboardLineChart` | Ready-to-use multi-series line chart |
|
|
24
|
-
| `HorizontalBarChart` | Ranking/comparison bar chart with horizontal layout |
|
|
25
|
-
| `InteractiveTimeSeriesChart` | Area time-series chart with metric tabs and period select |
|
|
26
|
-
| `ComboMetricChart` | Composed bar, line, and area chart for mixed metrics |
|
|
27
|
-
| `DonutBreakdownChart` | Donut/pie breakdown chart with interactive segment focus |
|
|
28
|
-
| `SparklineChart` | Compact inline area/line chart for KPI cards |
|
|
29
|
-
| `RadarMetricChart` | Multi-dimensional radar/spider chart |
|
|
30
|
-
| `PieMetricChart` | Proportional pie chart with optional donut, labels, and exploded slice |
|
|
31
|
-
| `RadialBarMetricChart` | Circular progress rings (radial bar chart) |
|
|
32
|
-
| `GaugeChart` | Semicircle gauge with needle, thresholds, and color zones |
|
|
33
|
-
| `ChartConfig` | TypeScript type for chart configuration |
|
|
34
|
-
| `GaugeChartThreshold` | TypeScript type for gauge color zone thresholds |
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
## Required Dependencies
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
npm install recharts
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
## How It Works
|
|
47
|
-
|
|
48
|
-
1. Define a `ChartConfig` mapping each data key to a label and color.
|
|
49
|
-
2. Wrap your Recharts chart in `<ChartContainer config={config}>`.
|
|
50
|
-
3. Reference colors in chart elements using `fill="var(--color-yourKey)"`.
|
|
51
|
-
4. The container automatically injects CSS variables for light and dark themes.
|
|
52
|
-
|
|
53
|
-
Dashboard-ready wrappers (`DashboardBarChart`, `RadarMetricChart`, etc.) build the config internally — you only need to pass `data` and `series`/`nameKey`/`valueKey`.
|
|
54
|
-
|
|
55
|
-
---
|
|
56
|
-
|
|
57
|
-
## ChartConfig Type
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
type ChartConfig = {
|
|
61
|
-
[key: string]: {
|
|
62
|
-
label?: string;
|
|
63
|
-
icon?: React.ComponentType;
|
|
64
|
-
color?: string; // CSS color or hsl() value
|
|
65
|
-
theme?: { light: string; dark: string }; // Per-theme colors
|
|
66
|
-
};
|
|
67
|
-
};
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
---
|
|
71
|
-
|
|
72
|
-
## Color Tokens
|
|
73
|
-
|
|
74
|
-
Chart colors use `--chart-1` through `--chart-8` CSS tokens. These are theme-aware and automatically switch between light and dark mode.
|
|
75
|
-
|
|
76
|
-
```tsx
|
|
77
|
-
// In ChartConfig
|
|
78
|
-
{ revenue: { label: 'Revenue', color: 'var(--chart-1)' } }
|
|
79
|
-
|
|
80
|
-
// In dashboard-ready wrappers — pass as array or per-key map
|
|
81
|
-
colors={['var(--chart-1)', 'var(--chart-2)']}
|
|
82
|
-
colors={{ revenue: 'var(--chart-1)', expenses: 'var(--chart-5)' }}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
---
|
|
86
|
-
|
|
87
|
-
## Examples
|
|
88
|
-
|
|
89
|
-
### Bar Chart (low-level)
|
|
90
|
-
|
|
91
|
-
```tsx
|
|
92
|
-
import {
|
|
93
|
-
ChartContainer,
|
|
94
|
-
ChartTooltip,
|
|
95
|
-
ChartTooltipContent,
|
|
96
|
-
ChartLegend,
|
|
97
|
-
ChartLegendContent,
|
|
98
|
-
type ChartConfig,
|
|
99
|
-
} from 'xertica-ui/ui';
|
|
100
|
-
import { BarChart, Bar, XAxis, YAxis, CartesianGrid } from 'recharts';
|
|
101
|
-
import { Card, CardHeader, CardTitle, CardContent } from 'xertica-ui/ui';
|
|
102
|
-
|
|
103
|
-
const chartConfig: ChartConfig = {
|
|
104
|
-
revenue: { label: 'Revenue', color: 'var(--chart-1)' },
|
|
105
|
-
expenses: { label: 'Expenses', color: 'var(--chart-5)' },
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
const data = [
|
|
109
|
-
{ month: 'Jan', revenue: 4000, expenses: 2400 },
|
|
110
|
-
{ month: 'Feb', revenue: 3000, expenses: 1398 },
|
|
111
|
-
{ month: 'Mar', revenue: 6000, expenses: 3200 },
|
|
112
|
-
];
|
|
113
|
-
|
|
114
|
-
<Card>
|
|
115
|
-
<CardHeader>
|
|
116
|
-
<CardTitle>Revenue vs Expenses</CardTitle>
|
|
117
|
-
</CardHeader>
|
|
118
|
-
<CardContent>
|
|
119
|
-
<ChartContainer config={chartConfig} className="h-[300px]">
|
|
120
|
-
<BarChart data={data}>
|
|
121
|
-
<CartesianGrid vertical={false} />
|
|
122
|
-
<XAxis dataKey="month" tickLine={false} axisLine={false} />
|
|
123
|
-
<YAxis tickLine={false} axisLine={false} />
|
|
124
|
-
<ChartTooltip content={<ChartTooltipContent />} />
|
|
125
|
-
<ChartLegend content={<ChartLegendContent />} />
|
|
126
|
-
<Bar dataKey="revenue" fill="var(--color-revenue)" radius={4} />
|
|
127
|
-
<Bar dataKey="expenses" fill="var(--color-expenses)" radius={4} />
|
|
128
|
-
</BarChart>
|
|
129
|
-
</ChartContainer>
|
|
130
|
-
</CardContent>
|
|
131
|
-
</Card>;
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### Line Chart (low-level)
|
|
135
|
-
|
|
136
|
-
```tsx
|
|
137
|
-
const chartConfig: ChartConfig = {
|
|
138
|
-
users: { label: 'Active Users', color: 'var(--chart-1)' },
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
<ChartContainer config={chartConfig} className="h-[250px]">
|
|
142
|
-
<LineChart data={data}>
|
|
143
|
-
<CartesianGrid vertical={false} />
|
|
144
|
-
<XAxis dataKey="month" />
|
|
145
|
-
<YAxis />
|
|
146
|
-
<ChartTooltip content={<ChartTooltipContent />} />
|
|
147
|
-
<Line type="monotone" dataKey="users" stroke="var(--color-users)" strokeWidth={2} dot={false} />
|
|
148
|
-
</LineChart>
|
|
149
|
-
</ChartContainer>;
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
---
|
|
153
|
-
|
|
154
|
-
### Dashboard-Ready Charts
|
|
155
|
-
|
|
156
|
-
```tsx
|
|
157
|
-
import {
|
|
158
|
-
ChartCard,
|
|
159
|
-
DashboardBarChart,
|
|
160
|
-
DashboardLineChart,
|
|
161
|
-
HorizontalBarChart,
|
|
162
|
-
InteractiveTimeSeriesChart,
|
|
163
|
-
ComboMetricChart,
|
|
164
|
-
DonutBreakdownChart,
|
|
165
|
-
type ChartConfig,
|
|
166
|
-
} from 'xertica-ui/ui';
|
|
167
|
-
|
|
168
|
-
const config: ChartConfig = {
|
|
169
|
-
revenue: { label: 'Revenue', color: 'var(--chart-1)' },
|
|
170
|
-
pipeline: { label: 'Pipeline', color: 'var(--chart-4)' },
|
|
171
|
-
conversion: { label: 'Conversion', color: 'var(--chart-2)' },
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
const data = [
|
|
175
|
-
{ date: 'Apr 01', revenue: 4200, pipeline: 2600, conversion: 32 },
|
|
176
|
-
{ date: 'Apr 08', revenue: 5200, pipeline: 3200, conversion: 38 },
|
|
177
|
-
];
|
|
178
|
-
|
|
179
|
-
<ChartCard title="Executive Trend" description="Metric and period controls">
|
|
180
|
-
<InteractiveTimeSeriesChart
|
|
181
|
-
data={data}
|
|
182
|
-
indexKey="date"
|
|
183
|
-
config={config}
|
|
184
|
-
series={[
|
|
185
|
-
{ key: 'revenue', label: 'Revenue' },
|
|
186
|
-
{ key: 'pipeline', label: 'Pipeline' },
|
|
187
|
-
]}
|
|
188
|
-
/>
|
|
189
|
-
</ChartCard>
|
|
190
|
-
|
|
191
|
-
<ChartCard title="Customer Mix">
|
|
192
|
-
<DonutBreakdownChart data={segments} config={segmentConfig} />
|
|
193
|
-
</ChartCard>
|
|
194
|
-
|
|
195
|
-
<DashboardBarChart data={data} indexKey="date" config={config} stacked />
|
|
196
|
-
|
|
197
|
-
<HorizontalBarChart
|
|
198
|
-
data={[
|
|
199
|
-
{ segment: 'Enterprise', revenue: 7600 },
|
|
200
|
-
{ segment: 'Mid-market', revenue: 5400 },
|
|
201
|
-
]}
|
|
202
|
-
indexKey="segment"
|
|
203
|
-
config={{
|
|
204
|
-
revenue: { label: 'Revenue', color: 'var(--chart-1)' },
|
|
205
|
-
}}
|
|
206
|
-
showLegend={false}
|
|
207
|
-
/>
|
|
208
|
-
|
|
209
|
-
<ComboMetricChart
|
|
210
|
-
data={data}
|
|
211
|
-
indexKey="date"
|
|
212
|
-
config={config}
|
|
213
|
-
series={[
|
|
214
|
-
{ key: 'pipeline', type: 'bar' },
|
|
215
|
-
{ key: 'conversion', type: 'line' },
|
|
216
|
-
]}
|
|
217
|
-
/>
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
---
|
|
221
|
-
|
|
222
|
-
### Radar Chart
|
|
223
|
-
|
|
224
|
-
Multi-dimensional comparison across categorical axes. Use a single series for a simple spider chart, or multiple series for side-by-side comparison.
|
|
225
|
-
|
|
226
|
-
```tsx
|
|
227
|
-
import { RadarMetricChart, ChartCard } from 'xertica-ui/ui';
|
|
228
|
-
|
|
229
|
-
const data = [
|
|
230
|
-
{ skill: 'Speed', frontend: 80, backend: 60 },
|
|
231
|
-
{ skill: 'Quality', frontend: 90, backend: 85 },
|
|
232
|
-
{ skill: 'Coverage', frontend: 70, backend: 95 },
|
|
233
|
-
{ skill: 'Security', frontend: 65, backend: 88 },
|
|
234
|
-
{ skill: 'Perf', frontend: 75, backend: 72 },
|
|
235
|
-
];
|
|
236
|
-
|
|
237
|
-
// Single series — filled polygon
|
|
238
|
-
<ChartCard title="Frontend Skills">
|
|
239
|
-
<RadarMetricChart
|
|
240
|
-
data={data}
|
|
241
|
-
labelKey="skill"
|
|
242
|
-
series={[{ key: 'frontend', label: 'Frontend' }]}
|
|
243
|
-
filled
|
|
244
|
-
fillOpacity={0.3}
|
|
245
|
-
/>
|
|
246
|
-
</ChartCard>
|
|
247
|
-
|
|
248
|
-
// Multi-series comparison
|
|
249
|
-
<ChartCard title="Team Comparison">
|
|
250
|
-
<RadarMetricChart
|
|
251
|
-
data={data}
|
|
252
|
-
labelKey="skill"
|
|
253
|
-
series={[
|
|
254
|
-
{ key: 'frontend', label: 'Frontend' },
|
|
255
|
-
{ key: 'backend', label: 'Backend' },
|
|
256
|
-
]}
|
|
257
|
-
filled={false}
|
|
258
|
-
showDots
|
|
259
|
-
showLegend
|
|
260
|
-
/>
|
|
261
|
-
</ChartCard>
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
**Props:**
|
|
265
|
-
|
|
266
|
-
| Prop | Type | Default | Description |
|
|
267
|
-
| ---------------- | ------------------------ | ------- | --------------------------------------------- |
|
|
268
|
-
| `data` | `DashboardChartDatum[]` | — | Data array; each item is one axis point |
|
|
269
|
-
| `labelKey` | `string` | — | Key used as the axis label |
|
|
270
|
-
| `series` | `DashboardChartSeries[]` | — | Series to render (one `<Radar>` per entry) |
|
|
271
|
-
| `colors` | `DashboardChartColors` | auto | Override colors per key or as ordered array |
|
|
272
|
-
| `filled` | `boolean` | `true` | Fill the radar polygon |
|
|
273
|
-
| `fillOpacity` | `number` | `0.25` | Fill opacity when `filled` is true |
|
|
274
|
-
| `showDots` | `boolean` | `false` | Show dots on each axis point |
|
|
275
|
-
| `showGrid` | `boolean` | `true` | Show polar grid lines |
|
|
276
|
-
| `showLegend` | `boolean` | auto | Show legend (auto-shown when multiple series) |
|
|
277
|
-
| `valueFormatter` | `(v: number) => string` | — | Format axis tick and tooltip values |
|
|
278
|
-
| + state props | — | — | `isLoading`, `error`, `onRetry`, etc. |
|
|
279
|
-
|
|
280
|
-
---
|
|
281
|
-
|
|
282
|
-
### Pie Chart
|
|
283
|
-
|
|
284
|
-
Proportional slices. Supports donut mode (`innerRadius > 0`), percentage labels, and an exploded (offset) slice for emphasis.
|
|
285
|
-
|
|
286
|
-
```tsx
|
|
287
|
-
import { PieMetricChart, ChartCard } from 'xertica-ui/ui';
|
|
288
|
-
|
|
289
|
-
const data = [
|
|
290
|
-
{ segment: 'Enterprise', value: 52 },
|
|
291
|
-
{ segment: 'Mid-market', value: 31 },
|
|
292
|
-
{ segment: 'SMB', value: 17 },
|
|
293
|
-
];
|
|
294
|
-
|
|
295
|
-
// Simple pie
|
|
296
|
-
<ChartCard title="Revenue Mix">
|
|
297
|
-
<PieMetricChart
|
|
298
|
-
data={data}
|
|
299
|
-
nameKey="segment"
|
|
300
|
-
valueKey="value"
|
|
301
|
-
showLabels
|
|
302
|
-
/>
|
|
303
|
-
</ChartCard>
|
|
304
|
-
|
|
305
|
-
// Donut variant
|
|
306
|
-
<ChartCard title="Revenue Mix (Donut)">
|
|
307
|
-
<PieMetricChart
|
|
308
|
-
data={data}
|
|
309
|
-
nameKey="segment"
|
|
310
|
-
valueKey="value"
|
|
311
|
-
innerRadius="55%"
|
|
312
|
-
outerRadius="80%"
|
|
313
|
-
/>
|
|
314
|
-
</ChartCard>
|
|
315
|
-
|
|
316
|
-
// Exploded slice (highlight index 0)
|
|
317
|
-
<ChartCard title="Top Segment">
|
|
318
|
-
<PieMetricChart
|
|
319
|
-
data={data}
|
|
320
|
-
nameKey="segment"
|
|
321
|
-
valueKey="value"
|
|
322
|
-
explodeIndex={0}
|
|
323
|
-
explodeOffset={14}
|
|
324
|
-
/>
|
|
325
|
-
</ChartCard>
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
**Props:**
|
|
329
|
-
|
|
330
|
-
| Prop | Type | Default | Description |
|
|
331
|
-
| ---------------- | ----------------------- | ------- | ------------------------------------------------ |
|
|
332
|
-
| `data` | `DashboardChartDatum[]` | — | Data array; each item is one slice |
|
|
333
|
-
| `nameKey` | `string` | — | Key used as the slice name/label |
|
|
334
|
-
| `valueKey` | `string` | — | Key used as the slice value |
|
|
335
|
-
| `colors` | `DashboardChartColors` | auto | Override colors as ordered array or per-name map |
|
|
336
|
-
| `outerRadius` | `number \| string` | `"80%"` | Outer radius of the pie |
|
|
337
|
-
| `innerRadius` | `number \| string` | `0` | Inner radius — set > 0 for donut |
|
|
338
|
-
| `showLabels` | `boolean` | `false` | Show percentage labels on slices |
|
|
339
|
-
| `showLegend` | `boolean` | `true` | Show the legend |
|
|
340
|
-
| `explodeIndex` | `number` | — | Index of the slice to offset outward |
|
|
341
|
-
| `explodeOffset` | `number` | `12` | Offset distance in px for the exploded slice |
|
|
342
|
-
| `valueFormatter` | `(v: number) => string` | — | Format tooltip values |
|
|
343
|
-
| + state props | — | — | `isLoading`, `error`, `onRetry`, etc. |
|
|
344
|
-
|
|
345
|
-
---
|
|
346
|
-
|
|
347
|
-
### Radial Bar Chart
|
|
348
|
-
|
|
349
|
-
Circular progress rings. Each data item renders as a concentric arc. Useful for showing multiple metrics as percentage completion.
|
|
350
|
-
|
|
351
|
-
```tsx
|
|
352
|
-
import { RadialBarMetricChart, ChartCard } from 'xertica-ui/ui';
|
|
353
|
-
|
|
354
|
-
const data = [
|
|
355
|
-
{ name: 'CPU', value: 72 },
|
|
356
|
-
{ name: 'Memory', value: 58 },
|
|
357
|
-
{ name: 'Storage', value: 41 },
|
|
358
|
-
{ name: 'Network', value: 89 },
|
|
359
|
-
];
|
|
360
|
-
|
|
361
|
-
// Full-circle rings (default)
|
|
362
|
-
<ChartCard title="Resource Usage">
|
|
363
|
-
<RadialBarMetricChart
|
|
364
|
-
data={data}
|
|
365
|
-
dataKey="value"
|
|
366
|
-
nameKey="name"
|
|
367
|
-
valueFormatter={(v) => `${v}%`}
|
|
368
|
-
/>
|
|
369
|
-
</ChartCard>
|
|
370
|
-
|
|
371
|
-
// Semi-circle layout
|
|
372
|
-
<ChartCard title="Resource Usage (Semi)">
|
|
373
|
-
<RadialBarMetricChart
|
|
374
|
-
data={data}
|
|
375
|
-
dataKey="value"
|
|
376
|
-
nameKey="name"
|
|
377
|
-
startAngle={180}
|
|
378
|
-
endAngle={0}
|
|
379
|
-
innerRadius="20%"
|
|
380
|
-
outerRadius="90%"
|
|
381
|
-
/>
|
|
382
|
-
</ChartCard>
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
**Props:**
|
|
386
|
-
|
|
387
|
-
| Prop | Type | Default | Description |
|
|
388
|
-
| ---------------- | ----------------------- | --------- | ------------------------------------------------ |
|
|
389
|
-
| `data` | `DashboardChartDatum[]` | — | Data array; each item is one ring |
|
|
390
|
-
| `dataKey` | `string` | `"value"` | Key used as the bar value |
|
|
391
|
-
| `nameKey` | `string` | `"name"` | Key used as the bar label |
|
|
392
|
-
| `colors` | `DashboardChartColors` | auto | Override colors as ordered array or per-name map |
|
|
393
|
-
| `innerRadius` | `number \| string` | `"30%"` | Inner radius of the radial bar |
|
|
394
|
-
| `outerRadius` | `number \| string` | `"100%"` | Outer radius of the radial bar |
|
|
395
|
-
| `startAngle` | `number` | `90` | Start angle in degrees (90 = top) |
|
|
396
|
-
| `endAngle` | `number` | `-270` | End angle in degrees (-270 = full circle) |
|
|
397
|
-
| `showBackground` | `boolean` | `true` | Show background track behind each bar |
|
|
398
|
-
| `showLegend` | `boolean` | `true` | Show the legend below the chart |
|
|
399
|
-
| `valueFormatter` | `(v: number) => string` | — | Format tooltip and legend values |
|
|
400
|
-
| + state props | — | — | `isLoading`, `error`, `onRetry`, etc. |
|
|
401
|
-
|
|
402
|
-
---
|
|
403
|
-
|
|
404
|
-
### Gauge Chart
|
|
405
|
-
|
|
406
|
-
Semicircle gauge with a needle indicator and optional color zones (thresholds). Implemented as pure SVG — no Recharts dependency.
|
|
407
|
-
|
|
408
|
-
```tsx
|
|
409
|
-
import { GaugeChart, ChartCard, type GaugeChartThreshold } from 'xertica-ui/ui';
|
|
410
|
-
|
|
411
|
-
// Simple percentage gauge
|
|
412
|
-
<ChartCard title="CPU Usage">
|
|
413
|
-
<div className="flex justify-center py-4">
|
|
414
|
-
<GaugeChart value={72} label="CPU" />
|
|
415
|
-
</div>
|
|
416
|
-
</ChartCard>
|
|
417
|
-
|
|
418
|
-
// With color thresholds
|
|
419
|
-
const thresholds: GaugeChartThreshold[] = [
|
|
420
|
-
{ value: 40, color: 'var(--chart-2)', label: 'Healthy' },
|
|
421
|
-
{ value: 70, color: 'var(--chart-3)', label: 'Warning' },
|
|
422
|
-
{ value: 100, color: 'var(--chart-5)', label: 'Critical' },
|
|
423
|
-
];
|
|
424
|
-
|
|
425
|
-
<ChartCard title="Memory Usage">
|
|
426
|
-
<div className="flex justify-center py-4">
|
|
427
|
-
<GaugeChart
|
|
428
|
-
value={85}
|
|
429
|
-
label="Memory"
|
|
430
|
-
thresholds={thresholds}
|
|
431
|
-
/>
|
|
432
|
-
</div>
|
|
433
|
-
</ChartCard>
|
|
434
|
-
|
|
435
|
-
// Custom range and formatter
|
|
436
|
-
<GaugeChart
|
|
437
|
-
value={1250}
|
|
438
|
-
min={0}
|
|
439
|
-
max={2000}
|
|
440
|
-
label="Requests/s"
|
|
441
|
-
valueFormatter={(value) => `${value.toLocaleString()} rps`}
|
|
442
|
-
showNeedle={false}
|
|
443
|
-
/>
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
**Props:**
|
|
447
|
-
|
|
448
|
-
| Prop | Type | Default | Description |
|
|
449
|
-
| ---------------- | -------------------------------------------- | ------- | -------------------------------------------------------------------------- |
|
|
450
|
-
| `value` | `number` | — | Current value (must be within `[min, max]`) |
|
|
451
|
-
| `min` | `number` | `0` | Minimum value |
|
|
452
|
-
| `max` | `number` | `100` | Maximum value |
|
|
453
|
-
| `thresholds` | `GaugeChartThreshold[]` | — | Color zones evaluated in order; first zone where `value >= current %` wins |
|
|
454
|
-
| `label` | `React.ReactNode` | — | Label shown below the center value |
|
|
455
|
-
| `valueFormatter` | `(value: number, percent: number) => string` | — | Format the center value text (default: shows `%`) |
|
|
456
|
-
| `showNeedle` | `boolean` | `true` | Show the needle indicator |
|
|
457
|
-
| `className` | `string` | — | Additional CSS classes |
|
|
458
|
-
|
|
459
|
-
**`GaugeChartThreshold` type:**
|
|
460
|
-
|
|
461
|
-
```typescript
|
|
462
|
-
interface GaugeChartThreshold {
|
|
463
|
-
value: number; // Upper bound of this zone (0–100)
|
|
464
|
-
color: string; // Color for this zone (use CSS var tokens)
|
|
465
|
-
label?: string; // Optional label shown in the legend
|
|
466
|
-
}
|
|
467
|
-
```
|
|
468
|
-
|
|
469
|
-
**Infrastructure dashboard example:**
|
|
470
|
-
|
|
471
|
-
```tsx
|
|
472
|
-
const metrics = [
|
|
473
|
-
{ label: 'CPU', value: 72 },
|
|
474
|
-
{ label: 'Memory', value: 85 },
|
|
475
|
-
{ label: 'Storage', value: 41 },
|
|
476
|
-
];
|
|
477
|
-
|
|
478
|
-
const thresholds: GaugeChartThreshold[] = [
|
|
479
|
-
{ value: 60, color: 'var(--chart-2)', label: 'OK' },
|
|
480
|
-
{ value: 80, color: 'var(--chart-3)', label: 'Warning' },
|
|
481
|
-
{ value: 100, color: 'var(--chart-5)', label: 'Critical' },
|
|
482
|
-
];
|
|
483
|
-
|
|
484
|
-
<div className="grid grid-cols-3 gap-4">
|
|
485
|
-
{metrics.map(m => (
|
|
486
|
-
<ChartCard key={m.label} title={m.label}>
|
|
487
|
-
<div className="flex justify-center py-2">
|
|
488
|
-
<GaugeChart value={m.value} label={m.label} thresholds={thresholds} />
|
|
489
|
-
</div>
|
|
490
|
-
</ChartCard>
|
|
491
|
-
))}
|
|
492
|
-
</div>;
|
|
493
|
-
```
|
|
494
|
-
|
|
495
|
-
---
|
|
496
|
-
|
|
497
|
-
### Sparkline Chart
|
|
498
|
-
|
|
499
|
-
Compact inline chart for KPI cards and metric summaries. Renders as a minimal area or line chart with no axes or labels.
|
|
500
|
-
|
|
501
|
-
```tsx
|
|
502
|
-
import { SparklineChart } from 'xertica-ui/ui';
|
|
503
|
-
|
|
504
|
-
// Filled area sparkline (default)
|
|
505
|
-
<SparklineChart
|
|
506
|
-
data={[{ v: 10 }, { v: 25 }, { v: 18 }, { v: 40 }, { v: 35 }]}
|
|
507
|
-
dataKey="v"
|
|
508
|
-
color="var(--chart-1)"
|
|
509
|
-
filled
|
|
510
|
-
/>
|
|
511
|
-
|
|
512
|
-
// Line-only sparkline
|
|
513
|
-
<SparklineChart
|
|
514
|
-
data={weeklyData}
|
|
515
|
-
dataKey="sessions"
|
|
516
|
-
color="var(--chart-2)"
|
|
517
|
-
filled={false}
|
|
518
|
-
/>
|
|
519
|
-
```
|
|
520
|
-
|
|
521
|
-
---
|
|
522
|
-
|
|
523
|
-
### Empty and Connection States
|
|
524
|
-
|
|
525
|
-
All dashboard-ready chart wrappers handle loading, empty data, and connection errors without forcing each feature to duplicate presentation logic. In an FSD architecture, keep fetching and error mapping in the feature/model layer, then pass the state into the UI component.
|
|
526
|
-
|
|
527
|
-
```tsx
|
|
528
|
-
<DashboardLineChart
|
|
529
|
-
data={analyticsData}
|
|
530
|
-
config={config}
|
|
531
|
-
isLoading={isLoading}
|
|
532
|
-
error={connectionError}
|
|
533
|
-
onRetry={refetchAnalytics}
|
|
534
|
-
emptyTitle="No data available"
|
|
535
|
-
emptyDescription="There is no data available for this period."
|
|
536
|
-
errorTitle="Connection error"
|
|
537
|
-
errorDescription="Unable to load analytics data."
|
|
538
|
-
/>
|
|
539
|
-
|
|
540
|
-
// State props work on all dashboard-ready wrappers:
|
|
541
|
-
<RadarMetricChart
|
|
542
|
-
data={skillData}
|
|
543
|
-
labelKey="skill"
|
|
544
|
-
series={[{ key: 'score', label: 'Score' }]}
|
|
545
|
-
isLoading={isLoading}
|
|
546
|
-
error={error}
|
|
547
|
-
onRetry={refetch}
|
|
548
|
-
/>
|
|
549
|
-
```
|
|
550
|
-
|
|
551
|
-
State props (`isLoading`, `error`, `onRetry`, `retryLabel`, `emptyTitle`, `emptyDescription`, `errorTitle`, `errorDescription`, `loadingLabel`, `stateClassName`) are available on: `DashboardBarChart`, `DashboardLineChart`, `HorizontalBarChart`, `InteractiveTimeSeriesChart`, `ComboMetricChart`, `DonutBreakdownChart`, `RadarMetricChart`, `PieMetricChart`, and `RadialBarMetricChart`.
|
|
552
|
-
|
|
553
|
-
> `GaugeChart` does not extend `ChartStateProps` — it is a pure display component with no async state.
|
|
554
|
-
|
|
555
|
-
---
|
|
556
|
-
|
|
557
|
-
### Stacked Bar Chart
|
|
558
|
-
|
|
559
|
-
Pass `stacked` to `DashboardBarChart` to stack series on top of each other. When stacking, only the **topmost series** in the stack receives rounded top corners — intermediate and bottom bars have flat tops to avoid visual gaps between segments.
|
|
560
|
-
|
|
561
|
-
```tsx
|
|
562
|
-
const config: ChartConfig = {
|
|
563
|
-
receita: { label: 'Receita', color: 'var(--chart-1)' },
|
|
564
|
-
despesa: { label: 'Despesa', color: 'var(--chart-5)' },
|
|
565
|
-
};
|
|
566
|
-
|
|
567
|
-
<DashboardBarChart
|
|
568
|
-
data={data}
|
|
569
|
-
indexKey="month"
|
|
570
|
-
config={config}
|
|
571
|
-
series={[
|
|
572
|
-
{ key: 'receita', label: 'Receita' },
|
|
573
|
-
{ key: 'despesa', label: 'Despesa' }, // ← this series sits on top, gets radius
|
|
574
|
-
]}
|
|
575
|
-
stacked
|
|
576
|
-
/>;
|
|
577
|
-
```
|
|
578
|
-
|
|
579
|
-
> The radius logic is automatic — the last `series` entry in each `stackId` group receives `radius={[4,4,0,0]}`; all others receive `radius={[0,0,0,0]}`. You do not need to configure this manually.
|
|
580
|
-
|
|
581
|
-
> **v2.1.9**: The `topOfStack` computation was extracted from an inline IIFE in JSX into a `React.useMemo([stacked, chartSeries])` before the `return`. This is a performance improvement — the bar element array is no longer recalculated on every render when the chart re-renders for unrelated reasons.
|
|
582
|
-
|
|
583
|
-
---
|
|
584
|
-
|
|
585
|
-
### Bar Thickness
|
|
586
|
-
|
|
587
|
-
Bar-based dashboard charts support `barSize="sm" | "md" | "lg" | "xl"` or a numeric pixel value. This controls the thickness of each rendered bar, not the chart container width.
|
|
588
|
-
|
|
589
|
-
```tsx
|
|
590
|
-
<DashboardBarChart data={data} indexKey="date" config={config} barSize="lg" />
|
|
591
|
-
|
|
592
|
-
<HorizontalBarChart
|
|
593
|
-
data={segmentData}
|
|
594
|
-
indexKey="segment"
|
|
595
|
-
config={config}
|
|
596
|
-
barSize={28}
|
|
597
|
-
/>
|
|
598
|
-
|
|
599
|
-
<ComboMetricChart
|
|
600
|
-
data={data}
|
|
601
|
-
indexKey="date"
|
|
602
|
-
config={config}
|
|
603
|
-
series={[
|
|
604
|
-
{ key: 'pipeline', type: 'bar' },
|
|
605
|
-
{ key: 'conversion', type: 'line' },
|
|
606
|
-
]}
|
|
607
|
-
barSize="sm"
|
|
608
|
-
/>
|
|
609
|
-
```
|
|
610
|
-
|
|
611
|
-
`barSize` is available on `DashboardBarChart`, `HorizontalBarChart`, and the bar series inside `ComboMetricChart`.
|
|
612
|
-
|
|
613
|
-
---
|
|
614
|
-
|
|
615
|
-
## AI Rules
|
|
616
|
-
|
|
617
|
-
- **Always** use `<ChartContainer config={config}>` — never use `<ResponsiveContainer>` directly.
|
|
618
|
-
- **Never** use hard-coded hex colors on chart elements (`fill="#4F46E5"`). Always use `fill="var(--color-keyName)"` — this references the CSS variable injected by `ChartContainer`.
|
|
619
|
-
- Define color via `color: 'var(--chart-1)'` in `ChartConfig`, or pass `colors={['var(--chart-1)', 'var(--chart-2)']}` to dashboard-ready chart wrappers. The `--chart-*` tokens are theme-aware.
|
|
620
|
-
- `ChartContainer` already wraps `ResponsiveContainer width="100%" height="100%"` — do not add another one.
|
|
621
|
-
- Set height on `ChartContainer` via `className="h-[300px]"` — this sizes the container, not the Recharts elements.
|
|
622
|
-
- Import all base Recharts components (`BarChart`, `Bar`, `Line`, etc.) directly from `recharts` — they are not re-exported by `xertica-ui`.
|
|
623
|
-
- For dashboard-ready charts, prefer `ChartCard` plus a dashboard-ready wrapper before hand-assembling Recharts primitives.
|
|
624
|
-
- In FSD apps, keep data fetching in the feature/model layer and pass `data`, `isLoading`, `error`, and `onRetry` into chart wrappers.
|
|
625
|
-
- Use `barSize` to control bar thickness. Do not use a chart wrapper prop to control graph width; layout width belongs to the parent grid/container.
|
|
626
|
-
- When using `stacked`, order your `series` array so the visually topmost series is last — it will automatically receive the rounded top corners.
|
|
627
|
-
- `RadarMetricChart`, `PieMetricChart`, and `RadialBarMetricChart` build their `ChartConfig` internally from the `series`/`nameKey` data — you do not need to pass a `config` prop.
|
|
628
|
-
- When passing `stateClassName` to `RadarMetricChart`, `PieMetricChart`, or `RadialBarMetricChart`, it is included in the state object passed to `getChartState` — it does not need to be (and should not be) passed as a second `className` argument separately.
|
|
629
|
-
- `GaugeChart` is a pure SVG component — it does not use `ChartContainer` or Recharts. Wrap it in a `div` with `flex justify-center` to control its width.
|
|
630
|
-
- For `GaugeChart` thresholds, use `--chart-*` CSS tokens for colors so they remain theme-aware. Never use raw hex values.
|
|
631
|
-
- `RadialBarMetricChart` renders its legend as HTML below the chart (not inside the SVG) — this is intentional to avoid Recharts polar chart legend positioning issues.
|
|
632
|
-
|
|
633
|
-
---
|
|
634
|
-
|
|
635
|
-
## Related Patterns
|
|
636
|
-
|
|
637
|
-
- [Dashboard Pattern](../patterns/dashboard.md)
|
|
638
|
-
- [Analytics Pattern](../patterns/analytics.md)
|
|
1
|
+
# Chart
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Xertica UI provides a `ChartContainer` wrapper and related components built on top of **Recharts** for theme-aware, token-driven chart rendering. The chart system uses a `ChartConfig` object to define series labels and colors via CSS variables, ensuring full dark-mode support without hard-coded hex values.
|
|
6
|
+
|
|
7
|
+
The library ships **11 dashboard-ready chart wrappers** that handle loading, empty, and error states automatically, so feature layers only need to pass `data`, `isLoading`, `error`, and `onRetry`.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Exports
|
|
12
|
+
|
|
13
|
+
| Export | Description |
|
|
14
|
+
| ---------------------------- | ------------------------------------------------------------------------------- |
|
|
15
|
+
| `ChartContainer` | Root container that injects CSS color variables and wraps `ResponsiveContainer` |
|
|
16
|
+
| `ChartTooltip` | Re-exported `recharts` `Tooltip` component |
|
|
17
|
+
| `ChartTooltipContent` | Styled tooltip content using the design system |
|
|
18
|
+
| `ChartLegend` | Re-exported `recharts` `Legend` component |
|
|
19
|
+
| `ChartLegendContent` | Styled legend content using the design system |
|
|
20
|
+
| `ChartStyle` | Internal style injector (used by `ChartContainer`, not used directly) |
|
|
21
|
+
| `ChartCard` | Card-based shell for dashboard chart panels |
|
|
22
|
+
| `DashboardBarChart` | Ready-to-use grouped or stacked bar chart |
|
|
23
|
+
| `DashboardLineChart` | Ready-to-use multi-series line chart |
|
|
24
|
+
| `HorizontalBarChart` | Ranking/comparison bar chart with horizontal layout |
|
|
25
|
+
| `InteractiveTimeSeriesChart` | Area time-series chart with metric tabs and period select |
|
|
26
|
+
| `ComboMetricChart` | Composed bar, line, and area chart for mixed metrics |
|
|
27
|
+
| `DonutBreakdownChart` | Donut/pie breakdown chart with interactive segment focus |
|
|
28
|
+
| `SparklineChart` | Compact inline area/line chart for KPI cards |
|
|
29
|
+
| `RadarMetricChart` | Multi-dimensional radar/spider chart |
|
|
30
|
+
| `PieMetricChart` | Proportional pie chart with optional donut, labels, and exploded slice |
|
|
31
|
+
| `RadialBarMetricChart` | Circular progress rings (radial bar chart) |
|
|
32
|
+
| `GaugeChart` | Semicircle gauge with needle, thresholds, and color zones |
|
|
33
|
+
| `ChartConfig` | TypeScript type for chart configuration |
|
|
34
|
+
| `GaugeChartThreshold` | TypeScript type for gauge color zone thresholds |
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Required Dependencies
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install recharts
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## How It Works
|
|
47
|
+
|
|
48
|
+
1. Define a `ChartConfig` mapping each data key to a label and color.
|
|
49
|
+
2. Wrap your Recharts chart in `<ChartContainer config={config}>`.
|
|
50
|
+
3. Reference colors in chart elements using `fill="var(--color-yourKey)"`.
|
|
51
|
+
4. The container automatically injects CSS variables for light and dark themes.
|
|
52
|
+
|
|
53
|
+
Dashboard-ready wrappers (`DashboardBarChart`, `RadarMetricChart`, etc.) build the config internally — you only need to pass `data` and `series`/`nameKey`/`valueKey`.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## ChartConfig Type
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
type ChartConfig = {
|
|
61
|
+
[key: string]: {
|
|
62
|
+
label?: string;
|
|
63
|
+
icon?: React.ComponentType;
|
|
64
|
+
color?: string; // CSS color or hsl() value
|
|
65
|
+
theme?: { light: string; dark: string }; // Per-theme colors
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Color Tokens
|
|
73
|
+
|
|
74
|
+
Chart colors use `--chart-1` through `--chart-8` CSS tokens. These are theme-aware and automatically switch between light and dark mode.
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
// In ChartConfig
|
|
78
|
+
{ revenue: { label: 'Revenue', color: 'var(--chart-1)' } }
|
|
79
|
+
|
|
80
|
+
// In dashboard-ready wrappers — pass as array or per-key map
|
|
81
|
+
colors={['var(--chart-1)', 'var(--chart-2)']}
|
|
82
|
+
colors={{ revenue: 'var(--chart-1)', expenses: 'var(--chart-5)' }}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Examples
|
|
88
|
+
|
|
89
|
+
### Bar Chart (low-level)
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
import {
|
|
93
|
+
ChartContainer,
|
|
94
|
+
ChartTooltip,
|
|
95
|
+
ChartTooltipContent,
|
|
96
|
+
ChartLegend,
|
|
97
|
+
ChartLegendContent,
|
|
98
|
+
type ChartConfig,
|
|
99
|
+
} from 'xertica-ui/ui';
|
|
100
|
+
import { BarChart, Bar, XAxis, YAxis, CartesianGrid } from 'recharts';
|
|
101
|
+
import { Card, CardHeader, CardTitle, CardContent } from 'xertica-ui/ui';
|
|
102
|
+
|
|
103
|
+
const chartConfig: ChartConfig = {
|
|
104
|
+
revenue: { label: 'Revenue', color: 'var(--chart-1)' },
|
|
105
|
+
expenses: { label: 'Expenses', color: 'var(--chart-5)' },
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const data = [
|
|
109
|
+
{ month: 'Jan', revenue: 4000, expenses: 2400 },
|
|
110
|
+
{ month: 'Feb', revenue: 3000, expenses: 1398 },
|
|
111
|
+
{ month: 'Mar', revenue: 6000, expenses: 3200 },
|
|
112
|
+
];
|
|
113
|
+
|
|
114
|
+
<Card>
|
|
115
|
+
<CardHeader>
|
|
116
|
+
<CardTitle>Revenue vs Expenses</CardTitle>
|
|
117
|
+
</CardHeader>
|
|
118
|
+
<CardContent>
|
|
119
|
+
<ChartContainer config={chartConfig} className="h-[300px]">
|
|
120
|
+
<BarChart data={data}>
|
|
121
|
+
<CartesianGrid vertical={false} />
|
|
122
|
+
<XAxis dataKey="month" tickLine={false} axisLine={false} />
|
|
123
|
+
<YAxis tickLine={false} axisLine={false} />
|
|
124
|
+
<ChartTooltip content={<ChartTooltipContent />} />
|
|
125
|
+
<ChartLegend content={<ChartLegendContent />} />
|
|
126
|
+
<Bar dataKey="revenue" fill="var(--color-revenue)" radius={4} />
|
|
127
|
+
<Bar dataKey="expenses" fill="var(--color-expenses)" radius={4} />
|
|
128
|
+
</BarChart>
|
|
129
|
+
</ChartContainer>
|
|
130
|
+
</CardContent>
|
|
131
|
+
</Card>;
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Line Chart (low-level)
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
const chartConfig: ChartConfig = {
|
|
138
|
+
users: { label: 'Active Users', color: 'var(--chart-1)' },
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
<ChartContainer config={chartConfig} className="h-[250px]">
|
|
142
|
+
<LineChart data={data}>
|
|
143
|
+
<CartesianGrid vertical={false} />
|
|
144
|
+
<XAxis dataKey="month" />
|
|
145
|
+
<YAxis />
|
|
146
|
+
<ChartTooltip content={<ChartTooltipContent />} />
|
|
147
|
+
<Line type="monotone" dataKey="users" stroke="var(--color-users)" strokeWidth={2} dot={false} />
|
|
148
|
+
</LineChart>
|
|
149
|
+
</ChartContainer>;
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
### Dashboard-Ready Charts
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
import {
|
|
158
|
+
ChartCard,
|
|
159
|
+
DashboardBarChart,
|
|
160
|
+
DashboardLineChart,
|
|
161
|
+
HorizontalBarChart,
|
|
162
|
+
InteractiveTimeSeriesChart,
|
|
163
|
+
ComboMetricChart,
|
|
164
|
+
DonutBreakdownChart,
|
|
165
|
+
type ChartConfig,
|
|
166
|
+
} from 'xertica-ui/ui';
|
|
167
|
+
|
|
168
|
+
const config: ChartConfig = {
|
|
169
|
+
revenue: { label: 'Revenue', color: 'var(--chart-1)' },
|
|
170
|
+
pipeline: { label: 'Pipeline', color: 'var(--chart-4)' },
|
|
171
|
+
conversion: { label: 'Conversion', color: 'var(--chart-2)' },
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
const data = [
|
|
175
|
+
{ date: 'Apr 01', revenue: 4200, pipeline: 2600, conversion: 32 },
|
|
176
|
+
{ date: 'Apr 08', revenue: 5200, pipeline: 3200, conversion: 38 },
|
|
177
|
+
];
|
|
178
|
+
|
|
179
|
+
<ChartCard title="Executive Trend" description="Metric and period controls">
|
|
180
|
+
<InteractiveTimeSeriesChart
|
|
181
|
+
data={data}
|
|
182
|
+
indexKey="date"
|
|
183
|
+
config={config}
|
|
184
|
+
series={[
|
|
185
|
+
{ key: 'revenue', label: 'Revenue' },
|
|
186
|
+
{ key: 'pipeline', label: 'Pipeline' },
|
|
187
|
+
]}
|
|
188
|
+
/>
|
|
189
|
+
</ChartCard>
|
|
190
|
+
|
|
191
|
+
<ChartCard title="Customer Mix">
|
|
192
|
+
<DonutBreakdownChart data={segments} config={segmentConfig} />
|
|
193
|
+
</ChartCard>
|
|
194
|
+
|
|
195
|
+
<DashboardBarChart data={data} indexKey="date" config={config} stacked />
|
|
196
|
+
|
|
197
|
+
<HorizontalBarChart
|
|
198
|
+
data={[
|
|
199
|
+
{ segment: 'Enterprise', revenue: 7600 },
|
|
200
|
+
{ segment: 'Mid-market', revenue: 5400 },
|
|
201
|
+
]}
|
|
202
|
+
indexKey="segment"
|
|
203
|
+
config={{
|
|
204
|
+
revenue: { label: 'Revenue', color: 'var(--chart-1)' },
|
|
205
|
+
}}
|
|
206
|
+
showLegend={false}
|
|
207
|
+
/>
|
|
208
|
+
|
|
209
|
+
<ComboMetricChart
|
|
210
|
+
data={data}
|
|
211
|
+
indexKey="date"
|
|
212
|
+
config={config}
|
|
213
|
+
series={[
|
|
214
|
+
{ key: 'pipeline', type: 'bar' },
|
|
215
|
+
{ key: 'conversion', type: 'line' },
|
|
216
|
+
]}
|
|
217
|
+
/>
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
### Radar Chart
|
|
223
|
+
|
|
224
|
+
Multi-dimensional comparison across categorical axes. Use a single series for a simple spider chart, or multiple series for side-by-side comparison.
|
|
225
|
+
|
|
226
|
+
```tsx
|
|
227
|
+
import { RadarMetricChart, ChartCard } from 'xertica-ui/ui';
|
|
228
|
+
|
|
229
|
+
const data = [
|
|
230
|
+
{ skill: 'Speed', frontend: 80, backend: 60 },
|
|
231
|
+
{ skill: 'Quality', frontend: 90, backend: 85 },
|
|
232
|
+
{ skill: 'Coverage', frontend: 70, backend: 95 },
|
|
233
|
+
{ skill: 'Security', frontend: 65, backend: 88 },
|
|
234
|
+
{ skill: 'Perf', frontend: 75, backend: 72 },
|
|
235
|
+
];
|
|
236
|
+
|
|
237
|
+
// Single series — filled polygon
|
|
238
|
+
<ChartCard title="Frontend Skills">
|
|
239
|
+
<RadarMetricChart
|
|
240
|
+
data={data}
|
|
241
|
+
labelKey="skill"
|
|
242
|
+
series={[{ key: 'frontend', label: 'Frontend' }]}
|
|
243
|
+
filled
|
|
244
|
+
fillOpacity={0.3}
|
|
245
|
+
/>
|
|
246
|
+
</ChartCard>
|
|
247
|
+
|
|
248
|
+
// Multi-series comparison
|
|
249
|
+
<ChartCard title="Team Comparison">
|
|
250
|
+
<RadarMetricChart
|
|
251
|
+
data={data}
|
|
252
|
+
labelKey="skill"
|
|
253
|
+
series={[
|
|
254
|
+
{ key: 'frontend', label: 'Frontend' },
|
|
255
|
+
{ key: 'backend', label: 'Backend' },
|
|
256
|
+
]}
|
|
257
|
+
filled={false}
|
|
258
|
+
showDots
|
|
259
|
+
showLegend
|
|
260
|
+
/>
|
|
261
|
+
</ChartCard>
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
**Props:**
|
|
265
|
+
|
|
266
|
+
| Prop | Type | Default | Description |
|
|
267
|
+
| ---------------- | ------------------------ | ------- | --------------------------------------------- |
|
|
268
|
+
| `data` | `DashboardChartDatum[]` | — | Data array; each item is one axis point |
|
|
269
|
+
| `labelKey` | `string` | — | Key used as the axis label |
|
|
270
|
+
| `series` | `DashboardChartSeries[]` | — | Series to render (one `<Radar>` per entry) |
|
|
271
|
+
| `colors` | `DashboardChartColors` | auto | Override colors per key or as ordered array |
|
|
272
|
+
| `filled` | `boolean` | `true` | Fill the radar polygon |
|
|
273
|
+
| `fillOpacity` | `number` | `0.25` | Fill opacity when `filled` is true |
|
|
274
|
+
| `showDots` | `boolean` | `false` | Show dots on each axis point |
|
|
275
|
+
| `showGrid` | `boolean` | `true` | Show polar grid lines |
|
|
276
|
+
| `showLegend` | `boolean` | auto | Show legend (auto-shown when multiple series) |
|
|
277
|
+
| `valueFormatter` | `(v: number) => string` | — | Format axis tick and tooltip values |
|
|
278
|
+
| + state props | — | — | `isLoading`, `error`, `onRetry`, etc. |
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
### Pie Chart
|
|
283
|
+
|
|
284
|
+
Proportional slices. Supports donut mode (`innerRadius > 0`), percentage labels, and an exploded (offset) slice for emphasis.
|
|
285
|
+
|
|
286
|
+
```tsx
|
|
287
|
+
import { PieMetricChart, ChartCard } from 'xertica-ui/ui';
|
|
288
|
+
|
|
289
|
+
const data = [
|
|
290
|
+
{ segment: 'Enterprise', value: 52 },
|
|
291
|
+
{ segment: 'Mid-market', value: 31 },
|
|
292
|
+
{ segment: 'SMB', value: 17 },
|
|
293
|
+
];
|
|
294
|
+
|
|
295
|
+
// Simple pie
|
|
296
|
+
<ChartCard title="Revenue Mix">
|
|
297
|
+
<PieMetricChart
|
|
298
|
+
data={data}
|
|
299
|
+
nameKey="segment"
|
|
300
|
+
valueKey="value"
|
|
301
|
+
showLabels
|
|
302
|
+
/>
|
|
303
|
+
</ChartCard>
|
|
304
|
+
|
|
305
|
+
// Donut variant
|
|
306
|
+
<ChartCard title="Revenue Mix (Donut)">
|
|
307
|
+
<PieMetricChart
|
|
308
|
+
data={data}
|
|
309
|
+
nameKey="segment"
|
|
310
|
+
valueKey="value"
|
|
311
|
+
innerRadius="55%"
|
|
312
|
+
outerRadius="80%"
|
|
313
|
+
/>
|
|
314
|
+
</ChartCard>
|
|
315
|
+
|
|
316
|
+
// Exploded slice (highlight index 0)
|
|
317
|
+
<ChartCard title="Top Segment">
|
|
318
|
+
<PieMetricChart
|
|
319
|
+
data={data}
|
|
320
|
+
nameKey="segment"
|
|
321
|
+
valueKey="value"
|
|
322
|
+
explodeIndex={0}
|
|
323
|
+
explodeOffset={14}
|
|
324
|
+
/>
|
|
325
|
+
</ChartCard>
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**Props:**
|
|
329
|
+
|
|
330
|
+
| Prop | Type | Default | Description |
|
|
331
|
+
| ---------------- | ----------------------- | ------- | ------------------------------------------------ |
|
|
332
|
+
| `data` | `DashboardChartDatum[]` | — | Data array; each item is one slice |
|
|
333
|
+
| `nameKey` | `string` | — | Key used as the slice name/label |
|
|
334
|
+
| `valueKey` | `string` | — | Key used as the slice value |
|
|
335
|
+
| `colors` | `DashboardChartColors` | auto | Override colors as ordered array or per-name map |
|
|
336
|
+
| `outerRadius` | `number \| string` | `"80%"` | Outer radius of the pie |
|
|
337
|
+
| `innerRadius` | `number \| string` | `0` | Inner radius — set > 0 for donut |
|
|
338
|
+
| `showLabels` | `boolean` | `false` | Show percentage labels on slices |
|
|
339
|
+
| `showLegend` | `boolean` | `true` | Show the legend |
|
|
340
|
+
| `explodeIndex` | `number` | — | Index of the slice to offset outward |
|
|
341
|
+
| `explodeOffset` | `number` | `12` | Offset distance in px for the exploded slice |
|
|
342
|
+
| `valueFormatter` | `(v: number) => string` | — | Format tooltip values |
|
|
343
|
+
| + state props | — | — | `isLoading`, `error`, `onRetry`, etc. |
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
### Radial Bar Chart
|
|
348
|
+
|
|
349
|
+
Circular progress rings. Each data item renders as a concentric arc. Useful for showing multiple metrics as percentage completion.
|
|
350
|
+
|
|
351
|
+
```tsx
|
|
352
|
+
import { RadialBarMetricChart, ChartCard } from 'xertica-ui/ui';
|
|
353
|
+
|
|
354
|
+
const data = [
|
|
355
|
+
{ name: 'CPU', value: 72 },
|
|
356
|
+
{ name: 'Memory', value: 58 },
|
|
357
|
+
{ name: 'Storage', value: 41 },
|
|
358
|
+
{ name: 'Network', value: 89 },
|
|
359
|
+
];
|
|
360
|
+
|
|
361
|
+
// Full-circle rings (default)
|
|
362
|
+
<ChartCard title="Resource Usage">
|
|
363
|
+
<RadialBarMetricChart
|
|
364
|
+
data={data}
|
|
365
|
+
dataKey="value"
|
|
366
|
+
nameKey="name"
|
|
367
|
+
valueFormatter={(v) => `${v}%`}
|
|
368
|
+
/>
|
|
369
|
+
</ChartCard>
|
|
370
|
+
|
|
371
|
+
// Semi-circle layout
|
|
372
|
+
<ChartCard title="Resource Usage (Semi)">
|
|
373
|
+
<RadialBarMetricChart
|
|
374
|
+
data={data}
|
|
375
|
+
dataKey="value"
|
|
376
|
+
nameKey="name"
|
|
377
|
+
startAngle={180}
|
|
378
|
+
endAngle={0}
|
|
379
|
+
innerRadius="20%"
|
|
380
|
+
outerRadius="90%"
|
|
381
|
+
/>
|
|
382
|
+
</ChartCard>
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
**Props:**
|
|
386
|
+
|
|
387
|
+
| Prop | Type | Default | Description |
|
|
388
|
+
| ---------------- | ----------------------- | --------- | ------------------------------------------------ |
|
|
389
|
+
| `data` | `DashboardChartDatum[]` | — | Data array; each item is one ring |
|
|
390
|
+
| `dataKey` | `string` | `"value"` | Key used as the bar value |
|
|
391
|
+
| `nameKey` | `string` | `"name"` | Key used as the bar label |
|
|
392
|
+
| `colors` | `DashboardChartColors` | auto | Override colors as ordered array or per-name map |
|
|
393
|
+
| `innerRadius` | `number \| string` | `"30%"` | Inner radius of the radial bar |
|
|
394
|
+
| `outerRadius` | `number \| string` | `"100%"` | Outer radius of the radial bar |
|
|
395
|
+
| `startAngle` | `number` | `90` | Start angle in degrees (90 = top) |
|
|
396
|
+
| `endAngle` | `number` | `-270` | End angle in degrees (-270 = full circle) |
|
|
397
|
+
| `showBackground` | `boolean` | `true` | Show background track behind each bar |
|
|
398
|
+
| `showLegend` | `boolean` | `true` | Show the legend below the chart |
|
|
399
|
+
| `valueFormatter` | `(v: number) => string` | — | Format tooltip and legend values |
|
|
400
|
+
| + state props | — | — | `isLoading`, `error`, `onRetry`, etc. |
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
### Gauge Chart
|
|
405
|
+
|
|
406
|
+
Semicircle gauge with a needle indicator and optional color zones (thresholds). Implemented as pure SVG — no Recharts dependency.
|
|
407
|
+
|
|
408
|
+
```tsx
|
|
409
|
+
import { GaugeChart, ChartCard, type GaugeChartThreshold } from 'xertica-ui/ui';
|
|
410
|
+
|
|
411
|
+
// Simple percentage gauge
|
|
412
|
+
<ChartCard title="CPU Usage">
|
|
413
|
+
<div className="flex justify-center py-4">
|
|
414
|
+
<GaugeChart value={72} label="CPU" />
|
|
415
|
+
</div>
|
|
416
|
+
</ChartCard>
|
|
417
|
+
|
|
418
|
+
// With color thresholds
|
|
419
|
+
const thresholds: GaugeChartThreshold[] = [
|
|
420
|
+
{ value: 40, color: 'var(--chart-2)', label: 'Healthy' },
|
|
421
|
+
{ value: 70, color: 'var(--chart-3)', label: 'Warning' },
|
|
422
|
+
{ value: 100, color: 'var(--chart-5)', label: 'Critical' },
|
|
423
|
+
];
|
|
424
|
+
|
|
425
|
+
<ChartCard title="Memory Usage">
|
|
426
|
+
<div className="flex justify-center py-4">
|
|
427
|
+
<GaugeChart
|
|
428
|
+
value={85}
|
|
429
|
+
label="Memory"
|
|
430
|
+
thresholds={thresholds}
|
|
431
|
+
/>
|
|
432
|
+
</div>
|
|
433
|
+
</ChartCard>
|
|
434
|
+
|
|
435
|
+
// Custom range and formatter
|
|
436
|
+
<GaugeChart
|
|
437
|
+
value={1250}
|
|
438
|
+
min={0}
|
|
439
|
+
max={2000}
|
|
440
|
+
label="Requests/s"
|
|
441
|
+
valueFormatter={(value) => `${value.toLocaleString()} rps`}
|
|
442
|
+
showNeedle={false}
|
|
443
|
+
/>
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
**Props:**
|
|
447
|
+
|
|
448
|
+
| Prop | Type | Default | Description |
|
|
449
|
+
| ---------------- | -------------------------------------------- | ------- | -------------------------------------------------------------------------- |
|
|
450
|
+
| `value` | `number` | — | Current value (must be within `[min, max]`) |
|
|
451
|
+
| `min` | `number` | `0` | Minimum value |
|
|
452
|
+
| `max` | `number` | `100` | Maximum value |
|
|
453
|
+
| `thresholds` | `GaugeChartThreshold[]` | — | Color zones evaluated in order; first zone where `value >= current %` wins |
|
|
454
|
+
| `label` | `React.ReactNode` | — | Label shown below the center value |
|
|
455
|
+
| `valueFormatter` | `(value: number, percent: number) => string` | — | Format the center value text (default: shows `%`) |
|
|
456
|
+
| `showNeedle` | `boolean` | `true` | Show the needle indicator |
|
|
457
|
+
| `className` | `string` | — | Additional CSS classes |
|
|
458
|
+
|
|
459
|
+
**`GaugeChartThreshold` type:**
|
|
460
|
+
|
|
461
|
+
```typescript
|
|
462
|
+
interface GaugeChartThreshold {
|
|
463
|
+
value: number; // Upper bound of this zone (0–100)
|
|
464
|
+
color: string; // Color for this zone (use CSS var tokens)
|
|
465
|
+
label?: string; // Optional label shown in the legend
|
|
466
|
+
}
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
**Infrastructure dashboard example:**
|
|
470
|
+
|
|
471
|
+
```tsx
|
|
472
|
+
const metrics = [
|
|
473
|
+
{ label: 'CPU', value: 72 },
|
|
474
|
+
{ label: 'Memory', value: 85 },
|
|
475
|
+
{ label: 'Storage', value: 41 },
|
|
476
|
+
];
|
|
477
|
+
|
|
478
|
+
const thresholds: GaugeChartThreshold[] = [
|
|
479
|
+
{ value: 60, color: 'var(--chart-2)', label: 'OK' },
|
|
480
|
+
{ value: 80, color: 'var(--chart-3)', label: 'Warning' },
|
|
481
|
+
{ value: 100, color: 'var(--chart-5)', label: 'Critical' },
|
|
482
|
+
];
|
|
483
|
+
|
|
484
|
+
<div className="grid grid-cols-3 gap-4">
|
|
485
|
+
{metrics.map(m => (
|
|
486
|
+
<ChartCard key={m.label} title={m.label}>
|
|
487
|
+
<div className="flex justify-center py-2">
|
|
488
|
+
<GaugeChart value={m.value} label={m.label} thresholds={thresholds} />
|
|
489
|
+
</div>
|
|
490
|
+
</ChartCard>
|
|
491
|
+
))}
|
|
492
|
+
</div>;
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
### Sparkline Chart
|
|
498
|
+
|
|
499
|
+
Compact inline chart for KPI cards and metric summaries. Renders as a minimal area or line chart with no axes or labels.
|
|
500
|
+
|
|
501
|
+
```tsx
|
|
502
|
+
import { SparklineChart } from 'xertica-ui/ui';
|
|
503
|
+
|
|
504
|
+
// Filled area sparkline (default)
|
|
505
|
+
<SparklineChart
|
|
506
|
+
data={[{ v: 10 }, { v: 25 }, { v: 18 }, { v: 40 }, { v: 35 }]}
|
|
507
|
+
dataKey="v"
|
|
508
|
+
color="var(--chart-1)"
|
|
509
|
+
filled
|
|
510
|
+
/>
|
|
511
|
+
|
|
512
|
+
// Line-only sparkline
|
|
513
|
+
<SparklineChart
|
|
514
|
+
data={weeklyData}
|
|
515
|
+
dataKey="sessions"
|
|
516
|
+
color="var(--chart-2)"
|
|
517
|
+
filled={false}
|
|
518
|
+
/>
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
---
|
|
522
|
+
|
|
523
|
+
### Empty and Connection States
|
|
524
|
+
|
|
525
|
+
All dashboard-ready chart wrappers handle loading, empty data, and connection errors without forcing each feature to duplicate presentation logic. In an FSD architecture, keep fetching and error mapping in the feature/model layer, then pass the state into the UI component.
|
|
526
|
+
|
|
527
|
+
```tsx
|
|
528
|
+
<DashboardLineChart
|
|
529
|
+
data={analyticsData}
|
|
530
|
+
config={config}
|
|
531
|
+
isLoading={isLoading}
|
|
532
|
+
error={connectionError}
|
|
533
|
+
onRetry={refetchAnalytics}
|
|
534
|
+
emptyTitle="No data available"
|
|
535
|
+
emptyDescription="There is no data available for this period."
|
|
536
|
+
errorTitle="Connection error"
|
|
537
|
+
errorDescription="Unable to load analytics data."
|
|
538
|
+
/>
|
|
539
|
+
|
|
540
|
+
// State props work on all dashboard-ready wrappers:
|
|
541
|
+
<RadarMetricChart
|
|
542
|
+
data={skillData}
|
|
543
|
+
labelKey="skill"
|
|
544
|
+
series={[{ key: 'score', label: 'Score' }]}
|
|
545
|
+
isLoading={isLoading}
|
|
546
|
+
error={error}
|
|
547
|
+
onRetry={refetch}
|
|
548
|
+
/>
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
State props (`isLoading`, `error`, `onRetry`, `retryLabel`, `emptyTitle`, `emptyDescription`, `errorTitle`, `errorDescription`, `loadingLabel`, `stateClassName`) are available on: `DashboardBarChart`, `DashboardLineChart`, `HorizontalBarChart`, `InteractiveTimeSeriesChart`, `ComboMetricChart`, `DonutBreakdownChart`, `RadarMetricChart`, `PieMetricChart`, and `RadialBarMetricChart`.
|
|
552
|
+
|
|
553
|
+
> `GaugeChart` does not extend `ChartStateProps` — it is a pure display component with no async state.
|
|
554
|
+
|
|
555
|
+
---
|
|
556
|
+
|
|
557
|
+
### Stacked Bar Chart
|
|
558
|
+
|
|
559
|
+
Pass `stacked` to `DashboardBarChart` to stack series on top of each other. When stacking, only the **topmost series** in the stack receives rounded top corners — intermediate and bottom bars have flat tops to avoid visual gaps between segments.
|
|
560
|
+
|
|
561
|
+
```tsx
|
|
562
|
+
const config: ChartConfig = {
|
|
563
|
+
receita: { label: 'Receita', color: 'var(--chart-1)' },
|
|
564
|
+
despesa: { label: 'Despesa', color: 'var(--chart-5)' },
|
|
565
|
+
};
|
|
566
|
+
|
|
567
|
+
<DashboardBarChart
|
|
568
|
+
data={data}
|
|
569
|
+
indexKey="month"
|
|
570
|
+
config={config}
|
|
571
|
+
series={[
|
|
572
|
+
{ key: 'receita', label: 'Receita' },
|
|
573
|
+
{ key: 'despesa', label: 'Despesa' }, // ← this series sits on top, gets radius
|
|
574
|
+
]}
|
|
575
|
+
stacked
|
|
576
|
+
/>;
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
> The radius logic is automatic — the last `series` entry in each `stackId` group receives `radius={[4,4,0,0]}`; all others receive `radius={[0,0,0,0]}`. You do not need to configure this manually.
|
|
580
|
+
|
|
581
|
+
> **v2.1.9**: The `topOfStack` computation was extracted from an inline IIFE in JSX into a `React.useMemo([stacked, chartSeries])` before the `return`. This is a performance improvement — the bar element array is no longer recalculated on every render when the chart re-renders for unrelated reasons.
|
|
582
|
+
|
|
583
|
+
---
|
|
584
|
+
|
|
585
|
+
### Bar Thickness
|
|
586
|
+
|
|
587
|
+
Bar-based dashboard charts support `barSize="sm" | "md" | "lg" | "xl"` or a numeric pixel value. This controls the thickness of each rendered bar, not the chart container width.
|
|
588
|
+
|
|
589
|
+
```tsx
|
|
590
|
+
<DashboardBarChart data={data} indexKey="date" config={config} barSize="lg" />
|
|
591
|
+
|
|
592
|
+
<HorizontalBarChart
|
|
593
|
+
data={segmentData}
|
|
594
|
+
indexKey="segment"
|
|
595
|
+
config={config}
|
|
596
|
+
barSize={28}
|
|
597
|
+
/>
|
|
598
|
+
|
|
599
|
+
<ComboMetricChart
|
|
600
|
+
data={data}
|
|
601
|
+
indexKey="date"
|
|
602
|
+
config={config}
|
|
603
|
+
series={[
|
|
604
|
+
{ key: 'pipeline', type: 'bar' },
|
|
605
|
+
{ key: 'conversion', type: 'line' },
|
|
606
|
+
]}
|
|
607
|
+
barSize="sm"
|
|
608
|
+
/>
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
`barSize` is available on `DashboardBarChart`, `HorizontalBarChart`, and the bar series inside `ComboMetricChart`.
|
|
612
|
+
|
|
613
|
+
---
|
|
614
|
+
|
|
615
|
+
## AI Rules
|
|
616
|
+
|
|
617
|
+
- **Always** use `<ChartContainer config={config}>` — never use `<ResponsiveContainer>` directly.
|
|
618
|
+
- **Never** use hard-coded hex colors on chart elements (`fill="#4F46E5"`). Always use `fill="var(--color-keyName)"` — this references the CSS variable injected by `ChartContainer`.
|
|
619
|
+
- Define color via `color: 'var(--chart-1)'` in `ChartConfig`, or pass `colors={['var(--chart-1)', 'var(--chart-2)']}` to dashboard-ready chart wrappers. The `--chart-*` tokens are theme-aware.
|
|
620
|
+
- `ChartContainer` already wraps `ResponsiveContainer width="100%" height="100%"` — do not add another one.
|
|
621
|
+
- Set height on `ChartContainer` via `className="h-[300px]"` — this sizes the container, not the Recharts elements.
|
|
622
|
+
- Import all base Recharts components (`BarChart`, `Bar`, `Line`, etc.) directly from `recharts` — they are not re-exported by `xertica-ui`.
|
|
623
|
+
- For dashboard-ready charts, prefer `ChartCard` plus a dashboard-ready wrapper before hand-assembling Recharts primitives.
|
|
624
|
+
- In FSD apps, keep data fetching in the feature/model layer and pass `data`, `isLoading`, `error`, and `onRetry` into chart wrappers.
|
|
625
|
+
- Use `barSize` to control bar thickness. Do not use a chart wrapper prop to control graph width; layout width belongs to the parent grid/container.
|
|
626
|
+
- When using `stacked`, order your `series` array so the visually topmost series is last — it will automatically receive the rounded top corners.
|
|
627
|
+
- `RadarMetricChart`, `PieMetricChart`, and `RadialBarMetricChart` build their `ChartConfig` internally from the `series`/`nameKey` data — you do not need to pass a `config` prop.
|
|
628
|
+
- When passing `stateClassName` to `RadarMetricChart`, `PieMetricChart`, or `RadialBarMetricChart`, it is included in the state object passed to `getChartState` — it does not need to be (and should not be) passed as a second `className` argument separately.
|
|
629
|
+
- `GaugeChart` is a pure SVG component — it does not use `ChartContainer` or Recharts. Wrap it in a `div` with `flex justify-center` to control its width.
|
|
630
|
+
- For `GaugeChart` thresholds, use `--chart-*` CSS tokens for colors so they remain theme-aware. Never use raw hex values.
|
|
631
|
+
- `RadialBarMetricChart` renders its legend as HTML below the chart (not inside the SVG) — this is intentional to avoid Recharts polar chart legend positioning issues.
|
|
632
|
+
|
|
633
|
+
---
|
|
634
|
+
|
|
635
|
+
## Related Patterns
|
|
636
|
+
|
|
637
|
+
- [Dashboard Pattern](../patterns/dashboard.md)
|
|
638
|
+
- [Analytics Pattern](../patterns/analytics.md)
|