xertica-ui 2.2.1 → 2.4.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 +564 -525
- package/README.md +417 -382
- package/bin/cli.ts +1244 -748
- package/bin/generate-tokens.ts +262 -262
- package/bin/language-config.ts +5 -8
- package/components/assets/xertica-orbe-animation.ts +1162 -1162
- package/components/assistant/code-block/CodeBlock.tsx +268 -268
- 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/FormattedDocument.tsx +147 -147
- 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 +17 -7
- 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/AssistantCollapsedView.tsx +99 -99
- package/components/assistant/xertica-assistant/parts/AssistantConversationList.tsx +104 -106
- package/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.tsx +81 -81
- package/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.tsx +88 -78
- package/components/assistant/xertica-assistant/parts/AssistantHeader.tsx +75 -75
- package/components/assistant/xertica-assistant/parts/AssistantMessageBubble.tsx +564 -560
- package/components/assistant/xertica-assistant/parts/AssistantTabBar.tsx +67 -67
- package/components/assistant/xertica-assistant/parts/AssistantTypingIndicator.tsx +41 -41
- package/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.tsx +103 -103
- package/components/assistant/xertica-assistant/parts/index.ts +16 -16
- package/components/assistant/xertica-assistant/types.ts +134 -134
- package/components/assistant/xertica-assistant/use-assistant.ts +615 -615
- package/components/assistant/xertica-assistant/xertica-assistant.stories.tsx +407 -407
- package/components/assistant/xertica-assistant/xertica-assistant.test.tsx +65 -65
- package/components/assistant/xertica-assistant/xertica-assistant.tsx +611 -613
- package/components/blocks/card-patterns/ActivityCard.tsx +100 -100
- package/components/blocks/card-patterns/FeatureCard.tsx +109 -109
- package/components/blocks/card-patterns/FeatureCardSkeleton.tsx +1 -6
- package/components/blocks/card-patterns/NotificationCard.tsx +140 -140
- package/components/blocks/card-patterns/ProfileCard.tsx +112 -114
- package/components/blocks/card-patterns/ProjectCard.tsx +123 -123
- package/components/blocks/card-patterns/ProjectCardSkeleton.tsx +1 -6
- package/components/blocks/card-patterns/QuickActionCard.tsx +68 -68
- package/components/blocks/card-patterns/card-patterns.mdx +123 -123
- package/components/blocks/card-patterns/card-patterns.stories.tsx +594 -594
- package/components/blocks/card-patterns/index.ts +29 -29
- 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/index.ts +1 -1
- package/components/brand/language-selector/language-selector.mdx +126 -126
- package/components/brand/language-selector/language-selector.stories.tsx +1 -4
- package/components/brand/theme-toggle/ThemeToggle.tsx +74 -70
- 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 +1 -4
- package/components/brand/xertica-provider/index.ts +1 -1
- 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/index.ts +86 -90
- 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.stories.tsx +586 -586
- package/components/layout/sidebar/sidebar.test.tsx +76 -76
- package/components/layout/sidebar/sidebar.tsx +1079 -1073
- package/components/layout/sidebar/use-sidebar.ts +104 -104
- package/components/media/FloatingMediaWrapper.tsx +371 -371
- 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 +767 -765
- 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/VideoPlayer.tsx +310 -310
- 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 +120 -120
- package/components/pages/home-content/index.ts +1 -1
- package/components/pages/home-page/HomePage.stories.tsx +39 -39
- package/components/pages/home-page/HomePage.tsx +78 -74
- 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/LoginPage.tsx +218 -216
- 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/ResetPasswordPage.tsx +243 -239
- 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 +1354 -1235
- package/components/pages/template-content/index.ts +1 -1
- 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.test.tsx +52 -52
- package/components/pages/verify-email-page/VerifyEmailPage.stories.tsx +41 -41
- package/components/pages/verify-email-page/VerifyEmailPage.tsx +206 -206
- 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 +114 -132
- package/components/shared/error-boundary.tsx +150 -154
- package/components/shared/error-fallbacks.tsx +222 -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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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/index.ts +2 -2
- package/components/ui/stats-card/stats-card-skeleton.tsx +1 -3
- package/components/ui/stats-card/stats-card.stories.tsx +99 -99
- 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.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.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.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.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.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.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.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.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.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.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/components.json +892 -892
- 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 +121 -118
- package/contexts/BrandColorsContext.test.tsx +21 -21
- package/contexts/BrandColorsContext.tsx +251 -251
- package/contexts/LanguageContext.tsx +1 -2
- 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-COGiOV-g.cjs +3541 -0
- package/dist/AssistantChart-CWX1OWNM.js +3373 -0
- package/dist/AudioPlayer-9psiEucT.cjs +1282 -0
- package/dist/AudioPlayer-Dp2bD1Gk.js +1278 -0
- package/dist/BrandColorsContext-DZT7JjeD.js +659 -0
- package/dist/BrandColorsContext-awnBCmC4.cjs +666 -0
- package/dist/CodeBlock-DYkTfR0f.js +221 -0
- package/dist/CodeBlock-EOvp9cVu.cjs +223 -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-DNycVGwT.js +485 -0
- package/dist/FeatureCardSkeleton-DZqc96mt.js +27 -0
- package/dist/FeatureCardSkeleton-pTa0YNKP.cjs +29 -0
- package/dist/LayoutContext-BEq_-n98.cjs +96 -0
- package/dist/LayoutContext-DNl1xSoX.js +92 -0
- package/dist/ThemeContext-CMD3z2Dz.cjs +1930 -0
- package/dist/ThemeContext-x_F2zsnv.js +1923 -0
- package/dist/VerifyEmailPage-BJjAMUTW.js +3223 -0
- package/dist/VerifyEmailPage-Bv8Ah_TK.cjs +3235 -0
- package/dist/VerifyEmailPage-CkBYfsNy.cjs +3232 -0
- package/dist/VerifyEmailPage-Cyl55sJb.js +3226 -0
- package/dist/VerifyEmailPage-X14vhdyl.js +3296 -0
- package/dist/VerifyEmailPage-u_Dn7t1U.cjs +3305 -0
- package/dist/XerticaOrbe-Uk2JML1-.cjs +1927 -0
- package/dist/XerticaOrbe-jA5T2iOk.js +1925 -0
- package/dist/XerticaProvider-BErr83Bg.js +42 -0
- package/dist/XerticaProvider-CwOkHxiT.cjs +44 -0
- package/dist/XerticaProvider-DUOJg9iX.js +49 -0
- package/dist/XerticaProvider-Dl_b72_l.cjs +51 -0
- package/dist/XerticaXLogo-BX3ueACh.js +255 -0
- package/dist/XerticaXLogo-mqjoBiLI.js +252 -0
- package/dist/XerticaXLogo-qBPhwK3g.cjs +260 -0
- package/dist/XerticaXLogo-uQgwns_E.cjs +257 -0
- package/dist/alert-dialog-DhwPioBa.cjs +885 -0
- package/dist/alert-dialog-DqlRW_An.js +831 -0
- 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-ifNsA7Zl.js +90 -0
- package/dist/button-0BlA47It.cjs +85 -0
- package/dist/button-DZHzN1Gd.js +62 -0
- package/dist/cli.js +471 -93
- package/dist/components/brand/theme-toggle/ThemeToggle.d.ts +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/dropdown-menu-BMcykFDf.cjs +225 -0
- package/dist/dropdown-menu-Dn_eV2Xb.js +190 -0
- package/dist/google-maps-loader-BCe58h9D.js +308 -0
- package/dist/google-maps-loader-casMyxlo.cjs +316 -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.cjs.js +37 -32
- package/dist/index.es.js +30 -363
- package/dist/input-C_UiS2Py.cjs +152 -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/rich-text-editor-DqLICivI.js +2832 -0
- package/dist/rich-text-editor-DxO1Hz3a.cjs +2903 -0
- package/dist/select-CH6v_KcQ.cjs +161 -0
- package/dist/select-D-xvCZK2.js +130 -0
- package/dist/sidebar-3XyzjVBw.js +792 -0
- package/dist/sidebar-B4ZWaMrE.js +792 -0
- package/dist/sidebar-BS1p2V7t.cjs +795 -0
- package/dist/sidebar-DyYvgyBj.cjs +795 -0
- package/dist/skeleton-DjiHerJn.cjs +87 -0
- package/dist/skeleton-DtR5tkYe.js +78 -0
- package/dist/slider-B00b9SVK.cjs +78 -0
- package/dist/slider-DQCNUUMj.js +56 -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-RtbSmPYJ.js +48 -0
- package/dist/ui.cjs.js +23 -18
- package/dist/ui.es.js +16 -303
- package/dist/use-audio-player-B78fd2ct.js +188 -0
- package/dist/use-audio-player-DGvhPrgR.cjs +190 -0
- package/dist/use-mobile-BdXTRb0Z.cjs +51 -0
- package/dist/use-mobile-Ce2cBAQe.js +29 -0
- package/dist/xertica-assistant-B1NaSFFj.js +2173 -0
- package/dist/xertica-assistant-B687qEPU.js +2165 -0
- package/dist/xertica-assistant-CIaUlbIt.cjs +2180 -0
- package/dist/xertica-assistant-sOHwTgIP.cjs +2172 -0
- package/dist/xertica-ui.css +1 -1
- package/docs/ai-usage.md +195 -195
- package/docs/architecture-improvements.md +456 -456
- package/docs/architecture.md +312 -306
- 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 +428 -426
- 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/branding.md +252 -252
- 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-patterns.md +447 -445
- 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 +201 -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/hooks.md +432 -430
- 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 +20 -16
- 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 +323 -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/doc-audit.md +244 -243
- package/docs/form-sizing.md +162 -162
- package/docs/getting-started.md +616 -591
- package/docs/guidelines.md +330 -328
- package/docs/i18n.md +61 -57
- package/docs/installation.md +268 -267
- package/docs/layout.md +143 -143
- package/docs/llms.md +295 -295
- 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/docs/state-management.md +289 -289
- package/guidelines/Guidelines.md +409 -406
- 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 +219 -213
- 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 +90 -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/CLAUDE.md +16 -1
- package/templates/eslint.config.js +26 -26
- package/templates/guidelines/Guidelines.md +577 -553
- package/templates/package.json +69 -69
- package/templates/postcss.config.js +6 -6
- package/templates/src/app/App.tsx +46 -46
- package/templates/src/app/components/AppLayout.tsx +55 -55
- package/templates/src/app/components/AuthGuard.tsx +131 -82
- package/templates/src/app/context/AuthContext.tsx +108 -108
- package/templates/src/features/assistant/index.ts +5 -5
- 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/ForgotPasswordContent.tsx +70 -72
- package/templates/src/features/auth/ui/LoginContent.tsx +92 -92
- package/templates/src/features/auth/ui/ResetPasswordContent.tsx +6 -2
- package/templates/src/features/auth/ui/SocialLoginButtons.tsx +78 -78
- package/templates/src/features/auth/ui/VerifyEmailContent.tsx +2 -6
- package/templates/src/features/home/data/mock.ts +41 -35
- package/templates/src/features/home/index.ts +11 -11
- package/templates/src/features/home/store/dashboardStore.ts +25 -25
- package/templates/src/features/home/ui/HomeContent.tsx +117 -119
- package/templates/src/features/template/index.ts +5 -5
- package/templates/src/features/template/ui/CrudTemplate.tsx +1 -4
- package/templates/src/features/template/ui/LoginTemplate.tsx +1 -1
- package/templates/src/features/template/ui/TemplateContent.tsx +29 -21
- package/templates/src/locales/en/pages/templates.json +17 -17
- package/templates/src/locales/es/pages/templates.json +17 -17
- package/templates/src/locales/pt-BR/pages/templates.json +17 -17
- package/templates/src/main.tsx +11 -11
- package/templates/src/pages/AssistantPage.tsx +26 -20
- package/templates/src/pages/ForgotPasswordPage.tsx +6 -6
- package/templates/src/pages/HomePage.tsx +53 -49
- 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 +150 -154
- package/templates/src/shared/error-fallbacks.tsx +222 -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.js +20 -20
- package/templates/vite.config.ts +54 -51
- 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
|
@@ -1,238 +1,238 @@
|
|
|
1
|
-
# TreeView
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
An interactive hierarchical tree component for displaying and navigating nested data structures — file systems, organizational charts, category trees, and recursive navigation menus. Supports keyboard navigation (Arrow keys, Home, End, Space), expand/collapse, and single-node selection.
|
|
6
|
-
|
|
7
|
-
The package also exports a **headless `useTreeView` hook** for building fully custom tree UIs while reusing all the expand/collapse, selection, keyboard navigation, and focus management logic.
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Exports
|
|
12
|
-
|
|
13
|
-
| Export | Description |
|
|
14
|
-
| ------------------- | ---------------------------------------- |
|
|
15
|
-
| `TreeView` | Ready-to-use hierarchical tree component |
|
|
16
|
-
| `useTreeView` | Headless hook — all logic, no UI |
|
|
17
|
-
| `TreeNode` | TypeScript type for a single tree node |
|
|
18
|
-
| `UseTreeViewProps` | TypeScript props type for the hook |
|
|
19
|
-
| `UseTreeViewReturn` | TypeScript return type for the hook |
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## When to Use
|
|
24
|
-
|
|
25
|
-
- File system browsers
|
|
26
|
-
- Organizational hierarchy viewers
|
|
27
|
-
- Category/tag tree navigation
|
|
28
|
-
- Nested menu items in the assistant sidebar variant
|
|
29
|
-
|
|
30
|
-
---
|
|
31
|
-
|
|
32
|
-
## Props
|
|
33
|
-
|
|
34
|
-
### `TreeView`
|
|
35
|
-
|
|
36
|
-
| Prop | Type | Required | Description |
|
|
37
|
-
| ----------------- | -------------------------- | -------- | ------------------------------------------------------------------------------------- |
|
|
38
|
-
| `data` | `TreeNode[]` | **Yes** | The tree data structure |
|
|
39
|
-
| `defaultExpanded` | `string[]` | No | Node IDs to expand on initial render |
|
|
40
|
-
| `selectedNodeId` | `string` | No | Controlled selected node ID |
|
|
41
|
-
| `onNodeClick` | `(node: TreeNode) => void` | No | Called when any node is clicked |
|
|
42
|
-
| `onNodeSelect` | `(node: TreeNode) => void` | No | Called when a node is selected (leaf or branch) |
|
|
43
|
-
| `ariaLabel` | `string` | No | Accessible label for the `role="tree"` container. Defaults to `"Navegação em árvore"` |
|
|
44
|
-
| `className` | `string` | No | Additional CSS classes |
|
|
45
|
-
|
|
46
|
-
### `TreeNode`
|
|
47
|
-
|
|
48
|
-
```typescript
|
|
49
|
-
interface TreeNode {
|
|
50
|
-
id: string;
|
|
51
|
-
label: string;
|
|
52
|
-
icon?: ReactNode;
|
|
53
|
-
children?: TreeNode[];
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
## Examples
|
|
60
|
-
|
|
61
|
-
### File System Browser
|
|
62
|
-
|
|
63
|
-
```tsx
|
|
64
|
-
import { TreeView } from 'xertica-ui/ui';
|
|
65
|
-
import { Folder, File } from 'lucide-react';
|
|
66
|
-
|
|
67
|
-
const tree = [
|
|
68
|
-
{
|
|
69
|
-
id: 'src',
|
|
70
|
-
label: 'src',
|
|
71
|
-
icon: <Folder className="size-4" />,
|
|
72
|
-
children: [
|
|
73
|
-
{
|
|
74
|
-
id: 'components',
|
|
75
|
-
label: 'components',
|
|
76
|
-
icon: <Folder className="size-4" />,
|
|
77
|
-
children: [
|
|
78
|
-
{ id: 'button', label: 'Button.tsx', icon: <File className="size-4" /> },
|
|
79
|
-
{ id: 'card', label: 'Card.tsx', icon: <File className="size-4" /> },
|
|
80
|
-
],
|
|
81
|
-
},
|
|
82
|
-
{ id: 'app', label: 'App.tsx', icon: <File className="size-4" /> },
|
|
83
|
-
],
|
|
84
|
-
},
|
|
85
|
-
];
|
|
86
|
-
|
|
87
|
-
<TreeView data={tree} onNodeSelect={node => console.log('Selected:', node.id)} />;
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### Pre-expanded Nodes
|
|
91
|
-
|
|
92
|
-
```tsx
|
|
93
|
-
<TreeView
|
|
94
|
-
data={tree}
|
|
95
|
-
defaultExpanded={['src', 'components']}
|
|
96
|
-
onNodeSelect={node => setSelectedFile(node.id)}
|
|
97
|
-
/>
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
## `useTreeView` Hook
|
|
103
|
-
|
|
104
|
-
A headless hook that manages expand/collapse state, selection, keyboard navigation, and focus refs for a tree structure. Use it when the `<TreeView>` component's visual design doesn't fit your needs.
|
|
105
|
-
|
|
106
|
-
### Props
|
|
107
|
-
|
|
108
|
-
| Prop | Type | Default | Description |
|
|
109
|
-
| ----------------- | -------------------------- | ------- | ----------------------------------------------------------------------------------------------- |
|
|
110
|
-
| `data` | `TreeNode[]` | — | **Required.** The tree data structure |
|
|
111
|
-
| `defaultExpanded` | `string[]` | `[]` | Node IDs to expand on initial render |
|
|
112
|
-
| `selectedNodeId` | `string` | — | Controlled selected node ID — when provided, the hook uses this value instead of internal state |
|
|
113
|
-
| `onNodeClick` | `(node: TreeNode) => void` | — | Called when any node is clicked |
|
|
114
|
-
| `onNodeSelect` | `(node: TreeNode) => void` | — | Called when a node is selected |
|
|
115
|
-
|
|
116
|
-
### Return Value
|
|
117
|
-
|
|
118
|
-
| Property | Type | Description |
|
|
119
|
-
| --------------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------- |
|
|
120
|
-
| `expanded` | `Set<string>` | Set of currently expanded node IDs |
|
|
121
|
-
| `effectiveSelectedId` | `string \| undefined` | The currently selected node ID (controlled or internal) |
|
|
122
|
-
| `nodeRefs` | `Map<string, HTMLButtonElement>` | Map of node ID → DOM button element refs |
|
|
123
|
-
| `getNodeRef` | `(nodeId: string) => (el: HTMLButtonElement \| null) => void` | Ref callback factory — attach to each node's button element |
|
|
124
|
-
| `toggleExpand` | `(nodeId: string) => void` | Toggle the expand/collapse state of a node |
|
|
125
|
-
| `handleSelect` | `(node: TreeNode) => void` | Handle node selection (updates internal state and calls callbacks) |
|
|
126
|
-
| `handleKeyDown` | `(e: KeyboardEvent, node: TreeNode) => void` | Full keyboard navigation handler — attach to each node's `onKeyDown` |
|
|
127
|
-
| `getVisibleNodes` | `() => TreeNode[]` | Returns the flat list of currently visible (non-collapsed) nodes in DOM order |
|
|
128
|
-
|
|
129
|
-
### Keyboard Navigation
|
|
130
|
-
|
|
131
|
-
The `handleKeyDown` handler implements the WAI-ARIA Tree Pattern 1.2:
|
|
132
|
-
|
|
133
|
-
| Key | Action |
|
|
134
|
-
| ------------ | -------------------------------------------------------------------------- |
|
|
135
|
-
| `ArrowDown` | Move focus to the next visible node |
|
|
136
|
-
| `ArrowUp` | Move focus to the previous visible node |
|
|
137
|
-
| `ArrowRight` | Expand a collapsed branch node; or move to first child if already expanded |
|
|
138
|
-
| `ArrowLeft` | Collapse an expanded branch node; or move to parent if already collapsed |
|
|
139
|
-
| `Home` | Move focus to the first node in the tree |
|
|
140
|
-
| `End` | Move focus to the last visible node in the tree |
|
|
141
|
-
| `Space` | **Branch nodes**: toggle expand/collapse. **Leaf nodes**: select |
|
|
142
|
-
| `Enter` | **All nodes**: toggle expand/collapse (if branch) **and** select |
|
|
143
|
-
|
|
144
|
-
> **Space vs Enter (v2.1.9+)**: These keys have distinct behaviors. `Space` on a branch expands/collapses without selecting; on a leaf it selects. `Enter` always selects the node and also toggles expand if it has children. This follows WAI-ARIA Tree Pattern specification.
|
|
145
|
-
|
|
146
|
-
### Roving Tabindex (v2.1.9+)
|
|
147
|
-
|
|
148
|
-
The `<TreeView>` component uses a roving tabindex strategy: only one node is in the tab sequence at a time (`tabIndex={0}`), the rest have `tabIndex={-1}`. The focusable node is `effectiveSelectedId ?? data[0]?.id`. This means:
|
|
149
|
-
|
|
150
|
-
- Arrow keys move focus between nodes without changing tab order
|
|
151
|
-
- `Tab` exits the tree entirely — screen reader users navigate with Arrow keys inside the tree
|
|
152
|
-
|
|
153
|
-
### Custom Tree Example
|
|
154
|
-
|
|
155
|
-
```tsx
|
|
156
|
-
import { useTreeView, TreeNode } from 'xertica-ui/ui';
|
|
157
|
-
import { ChevronRight, ChevronDown, Folder, File } from 'lucide-react';
|
|
158
|
-
import { cn } from '@/shared/utils';
|
|
159
|
-
|
|
160
|
-
function CustomTree({ data }: { data: TreeNode[] }) {
|
|
161
|
-
const { expanded, effectiveSelectedId, getNodeRef, toggleExpand, handleSelect, handleKeyDown } =
|
|
162
|
-
useTreeView({
|
|
163
|
-
data,
|
|
164
|
-
defaultExpanded: [],
|
|
165
|
-
onNodeSelect: node => console.log('Selected:', node.id),
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
const renderNode = (node: TreeNode, level: number): React.ReactNode => {
|
|
169
|
-
const hasChildren = !!node.children?.length;
|
|
170
|
-
const isExpanded = expanded.has(node.id);
|
|
171
|
-
const isSelected = effectiveSelectedId === node.id;
|
|
172
|
-
|
|
173
|
-
return (
|
|
174
|
-
<div key={node.id}>
|
|
175
|
-
<button
|
|
176
|
-
ref={getNodeRef(node.id)}
|
|
177
|
-
role="treeitem"
|
|
178
|
-
aria-expanded={hasChildren ? isExpanded : undefined}
|
|
179
|
-
aria-selected={isSelected}
|
|
180
|
-
onClick={() => {
|
|
181
|
-
if (hasChildren) toggleExpand(node.id);
|
|
182
|
-
handleSelect(node);
|
|
183
|
-
}}
|
|
184
|
-
onKeyDown={e => handleKeyDown(e, node)}
|
|
185
|
-
style={{ paddingLeft: `${level * 16}px` }}
|
|
186
|
-
className={cn(
|
|
187
|
-
'flex w-full items-center gap-2 rounded px-2 py-1 text-sm',
|
|
188
|
-
isSelected ? 'bg-primary text-primary-foreground' : 'hover:bg-accent'
|
|
189
|
-
)}
|
|
190
|
-
>
|
|
191
|
-
{hasChildren ? (
|
|
192
|
-
isExpanded ? (
|
|
193
|
-
<ChevronDown className="size-4 shrink-0" />
|
|
194
|
-
) : (
|
|
195
|
-
<ChevronRight className="size-4 shrink-0" />
|
|
196
|
-
)
|
|
197
|
-
) : (
|
|
198
|
-
<span className="size-4 shrink-0" />
|
|
199
|
-
)}
|
|
200
|
-
{node.icon}
|
|
201
|
-
<span>{node.label}</span>
|
|
202
|
-
</button>
|
|
203
|
-
|
|
204
|
-
{hasChildren && isExpanded && (
|
|
205
|
-
<div role="group">{node.children!.map(child => renderNode(child, level + 1))}</div>
|
|
206
|
-
)}
|
|
207
|
-
</div>
|
|
208
|
-
);
|
|
209
|
-
};
|
|
210
|
-
|
|
211
|
-
return (
|
|
212
|
-
<div role="tree" className="w-full">
|
|
213
|
-
{data.map(node => renderNode(node, 0))}
|
|
214
|
-
</div>
|
|
215
|
-
);
|
|
216
|
-
}
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
## AI Rules
|
|
222
|
-
|
|
223
|
-
- Each `TreeNode` must have a unique `id` — the component uses it to track expand/collapse state and selection.
|
|
224
|
-
- Leaf nodes (no `children`) do not show expand arrows.
|
|
225
|
-
- Use `lucide-react` icons with `className="size-4"` consistently across all tree nodes.
|
|
226
|
-
- When using `useTreeView`, attach `getNodeRef(node.id)` as the `ref` on each node's button — keyboard navigation (`handleKeyDown`) requires DOM refs to move focus.
|
|
227
|
-
- Attach `handleKeyDown` to `onKeyDown` on every node button — omitting it breaks keyboard accessibility.
|
|
228
|
-
- `getVisibleNodes()` returns only nodes that are currently visible (not inside a collapsed branch) — use it to compute `ArrowDown`/`ArrowUp` targets.
|
|
229
|
-
- For controlled selection, pass `selectedNodeId` — the hook will use it as `effectiveSelectedId` instead of internal state.
|
|
230
|
-
- `expanded` is a `Set<string>` — use `expanded.has(nodeId)` to check if a node is expanded.
|
|
231
|
-
- Pass `ariaLabel` to `<TreeView>` to provide a meaningful label for screen readers (e.g., `ariaLabel="File system"`, `ariaLabel="Category navigation"`). The default `"Navegação em árvore"` is in Portuguese — always override it for English-language apps.
|
|
232
|
-
- Do NOT manually set `tabIndex` on tree item buttons when using `<TreeView>` — roving tabindex is managed automatically since v2.1.9. When using `useTreeView`, implement roving tabindex: `tabIndex={node.id === focusableId ? 0 : -1}` where `focusableId = effectiveSelectedId ?? data[0]?.id`.
|
|
233
|
-
|
|
234
|
-
---
|
|
235
|
-
|
|
236
|
-
## Related Components
|
|
237
|
-
|
|
238
|
-
- [`Sidebar`](./sidebar.md) — Uses TreeView-style navigation for nested menu items
|
|
1
|
+
# TreeView
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
An interactive hierarchical tree component for displaying and navigating nested data structures — file systems, organizational charts, category trees, and recursive navigation menus. Supports keyboard navigation (Arrow keys, Home, End, Space), expand/collapse, and single-node selection.
|
|
6
|
+
|
|
7
|
+
The package also exports a **headless `useTreeView` hook** for building fully custom tree UIs while reusing all the expand/collapse, selection, keyboard navigation, and focus management logic.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Exports
|
|
12
|
+
|
|
13
|
+
| Export | Description |
|
|
14
|
+
| ------------------- | ---------------------------------------- |
|
|
15
|
+
| `TreeView` | Ready-to-use hierarchical tree component |
|
|
16
|
+
| `useTreeView` | Headless hook — all logic, no UI |
|
|
17
|
+
| `TreeNode` | TypeScript type for a single tree node |
|
|
18
|
+
| `UseTreeViewProps` | TypeScript props type for the hook |
|
|
19
|
+
| `UseTreeViewReturn` | TypeScript return type for the hook |
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## When to Use
|
|
24
|
+
|
|
25
|
+
- File system browsers
|
|
26
|
+
- Organizational hierarchy viewers
|
|
27
|
+
- Category/tag tree navigation
|
|
28
|
+
- Nested menu items in the assistant sidebar variant
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Props
|
|
33
|
+
|
|
34
|
+
### `TreeView`
|
|
35
|
+
|
|
36
|
+
| Prop | Type | Required | Description |
|
|
37
|
+
| ----------------- | -------------------------- | -------- | ------------------------------------------------------------------------------------- |
|
|
38
|
+
| `data` | `TreeNode[]` | **Yes** | The tree data structure |
|
|
39
|
+
| `defaultExpanded` | `string[]` | No | Node IDs to expand on initial render |
|
|
40
|
+
| `selectedNodeId` | `string` | No | Controlled selected node ID |
|
|
41
|
+
| `onNodeClick` | `(node: TreeNode) => void` | No | Called when any node is clicked |
|
|
42
|
+
| `onNodeSelect` | `(node: TreeNode) => void` | No | Called when a node is selected (leaf or branch) |
|
|
43
|
+
| `ariaLabel` | `string` | No | Accessible label for the `role="tree"` container. Defaults to `"Navegação em árvore"` |
|
|
44
|
+
| `className` | `string` | No | Additional CSS classes |
|
|
45
|
+
|
|
46
|
+
### `TreeNode`
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
interface TreeNode {
|
|
50
|
+
id: string;
|
|
51
|
+
label: string;
|
|
52
|
+
icon?: ReactNode;
|
|
53
|
+
children?: TreeNode[];
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Examples
|
|
60
|
+
|
|
61
|
+
### File System Browser
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
import { TreeView } from 'xertica-ui/ui';
|
|
65
|
+
import { Folder, File } from 'lucide-react';
|
|
66
|
+
|
|
67
|
+
const tree = [
|
|
68
|
+
{
|
|
69
|
+
id: 'src',
|
|
70
|
+
label: 'src',
|
|
71
|
+
icon: <Folder className="size-4" />,
|
|
72
|
+
children: [
|
|
73
|
+
{
|
|
74
|
+
id: 'components',
|
|
75
|
+
label: 'components',
|
|
76
|
+
icon: <Folder className="size-4" />,
|
|
77
|
+
children: [
|
|
78
|
+
{ id: 'button', label: 'Button.tsx', icon: <File className="size-4" /> },
|
|
79
|
+
{ id: 'card', label: 'Card.tsx', icon: <File className="size-4" /> },
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
{ id: 'app', label: 'App.tsx', icon: <File className="size-4" /> },
|
|
83
|
+
],
|
|
84
|
+
},
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
<TreeView data={tree} onNodeSelect={node => console.log('Selected:', node.id)} />;
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Pre-expanded Nodes
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
<TreeView
|
|
94
|
+
data={tree}
|
|
95
|
+
defaultExpanded={['src', 'components']}
|
|
96
|
+
onNodeSelect={node => setSelectedFile(node.id)}
|
|
97
|
+
/>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## `useTreeView` Hook
|
|
103
|
+
|
|
104
|
+
A headless hook that manages expand/collapse state, selection, keyboard navigation, and focus refs for a tree structure. Use it when the `<TreeView>` component's visual design doesn't fit your needs.
|
|
105
|
+
|
|
106
|
+
### Props
|
|
107
|
+
|
|
108
|
+
| Prop | Type | Default | Description |
|
|
109
|
+
| ----------------- | -------------------------- | ------- | ----------------------------------------------------------------------------------------------- |
|
|
110
|
+
| `data` | `TreeNode[]` | — | **Required.** The tree data structure |
|
|
111
|
+
| `defaultExpanded` | `string[]` | `[]` | Node IDs to expand on initial render |
|
|
112
|
+
| `selectedNodeId` | `string` | — | Controlled selected node ID — when provided, the hook uses this value instead of internal state |
|
|
113
|
+
| `onNodeClick` | `(node: TreeNode) => void` | — | Called when any node is clicked |
|
|
114
|
+
| `onNodeSelect` | `(node: TreeNode) => void` | — | Called when a node is selected |
|
|
115
|
+
|
|
116
|
+
### Return Value
|
|
117
|
+
|
|
118
|
+
| Property | Type | Description |
|
|
119
|
+
| --------------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------- |
|
|
120
|
+
| `expanded` | `Set<string>` | Set of currently expanded node IDs |
|
|
121
|
+
| `effectiveSelectedId` | `string \| undefined` | The currently selected node ID (controlled or internal) |
|
|
122
|
+
| `nodeRefs` | `Map<string, HTMLButtonElement>` | Map of node ID → DOM button element refs |
|
|
123
|
+
| `getNodeRef` | `(nodeId: string) => (el: HTMLButtonElement \| null) => void` | Ref callback factory — attach to each node's button element |
|
|
124
|
+
| `toggleExpand` | `(nodeId: string) => void` | Toggle the expand/collapse state of a node |
|
|
125
|
+
| `handleSelect` | `(node: TreeNode) => void` | Handle node selection (updates internal state and calls callbacks) |
|
|
126
|
+
| `handleKeyDown` | `(e: KeyboardEvent, node: TreeNode) => void` | Full keyboard navigation handler — attach to each node's `onKeyDown` |
|
|
127
|
+
| `getVisibleNodes` | `() => TreeNode[]` | Returns the flat list of currently visible (non-collapsed) nodes in DOM order |
|
|
128
|
+
|
|
129
|
+
### Keyboard Navigation
|
|
130
|
+
|
|
131
|
+
The `handleKeyDown` handler implements the WAI-ARIA Tree Pattern 1.2:
|
|
132
|
+
|
|
133
|
+
| Key | Action |
|
|
134
|
+
| ------------ | -------------------------------------------------------------------------- |
|
|
135
|
+
| `ArrowDown` | Move focus to the next visible node |
|
|
136
|
+
| `ArrowUp` | Move focus to the previous visible node |
|
|
137
|
+
| `ArrowRight` | Expand a collapsed branch node; or move to first child if already expanded |
|
|
138
|
+
| `ArrowLeft` | Collapse an expanded branch node; or move to parent if already collapsed |
|
|
139
|
+
| `Home` | Move focus to the first node in the tree |
|
|
140
|
+
| `End` | Move focus to the last visible node in the tree |
|
|
141
|
+
| `Space` | **Branch nodes**: toggle expand/collapse. **Leaf nodes**: select |
|
|
142
|
+
| `Enter` | **All nodes**: toggle expand/collapse (if branch) **and** select |
|
|
143
|
+
|
|
144
|
+
> **Space vs Enter (v2.1.9+)**: These keys have distinct behaviors. `Space` on a branch expands/collapses without selecting; on a leaf it selects. `Enter` always selects the node and also toggles expand if it has children. This follows WAI-ARIA Tree Pattern specification.
|
|
145
|
+
|
|
146
|
+
### Roving Tabindex (v2.1.9+)
|
|
147
|
+
|
|
148
|
+
The `<TreeView>` component uses a roving tabindex strategy: only one node is in the tab sequence at a time (`tabIndex={0}`), the rest have `tabIndex={-1}`. The focusable node is `effectiveSelectedId ?? data[0]?.id`. This means:
|
|
149
|
+
|
|
150
|
+
- Arrow keys move focus between nodes without changing tab order
|
|
151
|
+
- `Tab` exits the tree entirely — screen reader users navigate with Arrow keys inside the tree
|
|
152
|
+
|
|
153
|
+
### Custom Tree Example
|
|
154
|
+
|
|
155
|
+
```tsx
|
|
156
|
+
import { useTreeView, TreeNode } from 'xertica-ui/ui';
|
|
157
|
+
import { ChevronRight, ChevronDown, Folder, File } from 'lucide-react';
|
|
158
|
+
import { cn } from '@/shared/utils';
|
|
159
|
+
|
|
160
|
+
function CustomTree({ data }: { data: TreeNode[] }) {
|
|
161
|
+
const { expanded, effectiveSelectedId, getNodeRef, toggleExpand, handleSelect, handleKeyDown } =
|
|
162
|
+
useTreeView({
|
|
163
|
+
data,
|
|
164
|
+
defaultExpanded: [],
|
|
165
|
+
onNodeSelect: node => console.log('Selected:', node.id),
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const renderNode = (node: TreeNode, level: number): React.ReactNode => {
|
|
169
|
+
const hasChildren = !!node.children?.length;
|
|
170
|
+
const isExpanded = expanded.has(node.id);
|
|
171
|
+
const isSelected = effectiveSelectedId === node.id;
|
|
172
|
+
|
|
173
|
+
return (
|
|
174
|
+
<div key={node.id}>
|
|
175
|
+
<button
|
|
176
|
+
ref={getNodeRef(node.id)}
|
|
177
|
+
role="treeitem"
|
|
178
|
+
aria-expanded={hasChildren ? isExpanded : undefined}
|
|
179
|
+
aria-selected={isSelected}
|
|
180
|
+
onClick={() => {
|
|
181
|
+
if (hasChildren) toggleExpand(node.id);
|
|
182
|
+
handleSelect(node);
|
|
183
|
+
}}
|
|
184
|
+
onKeyDown={e => handleKeyDown(e, node)}
|
|
185
|
+
style={{ paddingLeft: `${level * 16}px` }}
|
|
186
|
+
className={cn(
|
|
187
|
+
'flex w-full items-center gap-2 rounded px-2 py-1 text-sm',
|
|
188
|
+
isSelected ? 'bg-primary text-primary-foreground' : 'hover:bg-accent'
|
|
189
|
+
)}
|
|
190
|
+
>
|
|
191
|
+
{hasChildren ? (
|
|
192
|
+
isExpanded ? (
|
|
193
|
+
<ChevronDown className="size-4 shrink-0" />
|
|
194
|
+
) : (
|
|
195
|
+
<ChevronRight className="size-4 shrink-0" />
|
|
196
|
+
)
|
|
197
|
+
) : (
|
|
198
|
+
<span className="size-4 shrink-0" />
|
|
199
|
+
)}
|
|
200
|
+
{node.icon}
|
|
201
|
+
<span>{node.label}</span>
|
|
202
|
+
</button>
|
|
203
|
+
|
|
204
|
+
{hasChildren && isExpanded && (
|
|
205
|
+
<div role="group">{node.children!.map(child => renderNode(child, level + 1))}</div>
|
|
206
|
+
)}
|
|
207
|
+
</div>
|
|
208
|
+
);
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
return (
|
|
212
|
+
<div role="tree" className="w-full">
|
|
213
|
+
{data.map(node => renderNode(node, 0))}
|
|
214
|
+
</div>
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## AI Rules
|
|
222
|
+
|
|
223
|
+
- Each `TreeNode` must have a unique `id` — the component uses it to track expand/collapse state and selection.
|
|
224
|
+
- Leaf nodes (no `children`) do not show expand arrows.
|
|
225
|
+
- Use `lucide-react` icons with `className="size-4"` consistently across all tree nodes.
|
|
226
|
+
- When using `useTreeView`, attach `getNodeRef(node.id)` as the `ref` on each node's button — keyboard navigation (`handleKeyDown`) requires DOM refs to move focus.
|
|
227
|
+
- Attach `handleKeyDown` to `onKeyDown` on every node button — omitting it breaks keyboard accessibility.
|
|
228
|
+
- `getVisibleNodes()` returns only nodes that are currently visible (not inside a collapsed branch) — use it to compute `ArrowDown`/`ArrowUp` targets.
|
|
229
|
+
- For controlled selection, pass `selectedNodeId` — the hook will use it as `effectiveSelectedId` instead of internal state.
|
|
230
|
+
- `expanded` is a `Set<string>` — use `expanded.has(nodeId)` to check if a node is expanded.
|
|
231
|
+
- Pass `ariaLabel` to `<TreeView>` to provide a meaningful label for screen readers (e.g., `ariaLabel="File system"`, `ariaLabel="Category navigation"`). The default `"Navegação em árvore"` is in Portuguese — always override it for English-language apps.
|
|
232
|
+
- Do NOT manually set `tabIndex` on tree item buttons when using `<TreeView>` — roving tabindex is managed automatically since v2.1.9. When using `useTreeView`, implement roving tabindex: `tabIndex={node.id === focusableId ? 0 : -1}` where `focusableId = effectiveSelectedId ?? data[0]?.id`.
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Related Components
|
|
237
|
+
|
|
238
|
+
- [`Sidebar`](./sidebar.md) — Uses TreeView-style navigation for nested menu items
|