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,268 +1,268 @@
|
|
|
1
|
-
# Stepper
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
A visual multi-step progress indicator that shows the user's current position within a sequential process. Uses a composable primitive pattern: `<Stepper>` wraps one or more `<Step>` children, automatically inferring the total number of steps.
|
|
6
|
-
|
|
7
|
-
The package also exports a **headless `useStepper` hook** for building fully custom step-navigation UIs — including async validation guards before advancing — while reusing all the step-state logic.
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Exports
|
|
12
|
-
|
|
13
|
-
| Export | Description |
|
|
14
|
-
| ------------------ | ------------------------------------------------ |
|
|
15
|
-
| `Stepper` | Visual step indicator component |
|
|
16
|
-
| `Step` | Individual step item |
|
|
17
|
-
| `useStepper` | Headless hook — all step navigation logic, no UI |
|
|
18
|
-
| `UseStepperProps` | TypeScript props type for the hook |
|
|
19
|
-
| `UseStepperReturn` | TypeScript return type for the hook |
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## When to Use
|
|
24
|
-
|
|
25
|
-
- Multi-step forms (checkout, registration, onboarding)
|
|
26
|
-
- Sequential configuration wizards
|
|
27
|
-
- Any process with 2–7 ordered steps
|
|
28
|
-
|
|
29
|
-
## When NOT to Use
|
|
30
|
-
|
|
31
|
-
- Processes with more than 7 steps — collapse or restructure.
|
|
32
|
-
- Simple 2-step flows — a dialog with "Next"/"Back" is sufficient.
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## Anatomy
|
|
37
|
-
|
|
38
|
-
```tsx
|
|
39
|
-
<Stepper currentStep={2}>
|
|
40
|
-
<Step step={1} label="Account" description="Create your account" />
|
|
41
|
-
<Step step={2} label="Plan" description="Choose a plan" />
|
|
42
|
-
<Step step={3} label="Confirm" description="Review and confirm" />
|
|
43
|
-
</Stepper>
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
- Steps are numbered from `1` (not `0`).
|
|
47
|
-
- Steps before `currentStep` render as **completed** (green checkmark).
|
|
48
|
-
- The step equal to `currentStep` renders as **active** (filled primary).
|
|
49
|
-
- Steps after `currentStep` render as **pending** (muted).
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
## Sub-Components
|
|
54
|
-
|
|
55
|
-
### `Stepper`
|
|
56
|
-
|
|
57
|
-
| Prop | Type | Required | Description |
|
|
58
|
-
| ------------- | ---------------------------- | -------- | ------------------------------------------ |
|
|
59
|
-
| `currentStep` | `number` | **Yes** | The currently active step (1-indexed) |
|
|
60
|
-
| `orientation` | `'horizontal' \| 'vertical'` | No | Layout direction (default: `'horizontal'`) |
|
|
61
|
-
| `className` | `string` | No | Additional CSS classes |
|
|
62
|
-
|
|
63
|
-
The step wrapper div renders with `role="list"` and `aria-label="Progresso: etapa N de M"` automatically.
|
|
64
|
-
|
|
65
|
-
### `Step`
|
|
66
|
-
|
|
67
|
-
| Prop | Type | Required | Description |
|
|
68
|
-
| ------------- | --------- | -------- | --------------------------------------------------- |
|
|
69
|
-
| `step` | `number` | **Yes** | Position of this step (1-indexed, must match order) |
|
|
70
|
-
| `label` | `string` | **Yes** | Step label text |
|
|
71
|
-
| `description` | `string` | No | Optional supplementary text below the label |
|
|
72
|
-
| `error` | `boolean` | No | When `true`, renders the step in error state (red) |
|
|
73
|
-
| `className` | `string` | No | Additional CSS classes |
|
|
74
|
-
|
|
75
|
-
Each `<Step>` renders with `role="listitem"`, `aria-current="step"` (active step only), and `aria-label="Etapa N: Label[, concluída | , atual]"` automatically — no manual ARIA attributes needed.
|
|
76
|
-
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
## Examples
|
|
80
|
-
|
|
81
|
-
### Basic 3-Step Flow
|
|
82
|
-
|
|
83
|
-
```tsx
|
|
84
|
-
import { Stepper, Step, Button } from 'xertica-ui/ui';
|
|
85
|
-
import { useState } from 'react';
|
|
86
|
-
|
|
87
|
-
const [currentStep, setCurrentStep] = useState(1);
|
|
88
|
-
|
|
89
|
-
<div className="space-y-8">
|
|
90
|
-
<Stepper currentStep={currentStep}>
|
|
91
|
-
<Step step={1} label="Account" description="Create your account" />
|
|
92
|
-
<Step step={2} label="Plan" description="Choose a plan" />
|
|
93
|
-
<Step step={3} label="Confirm" description="Review and confirm" />
|
|
94
|
-
</Stepper>
|
|
95
|
-
|
|
96
|
-
<div className="min-h-[200px] flex items-center justify-center">
|
|
97
|
-
<p className="text-muted-foreground">Content for step {currentStep}</p>
|
|
98
|
-
</div>
|
|
99
|
-
|
|
100
|
-
<div className="flex justify-between">
|
|
101
|
-
<Button
|
|
102
|
-
variant="outline"
|
|
103
|
-
onClick={() => setCurrentStep(s => Math.max(1, s - 1))}
|
|
104
|
-
disabled={currentStep === 1}
|
|
105
|
-
>
|
|
106
|
-
Previous
|
|
107
|
-
</Button>
|
|
108
|
-
<Button onClick={() => setCurrentStep(s => Math.min(3, s + 1))} disabled={currentStep === 3}>
|
|
109
|
-
{currentStep === 3 ? 'Finish' : 'Next'}
|
|
110
|
-
</Button>
|
|
111
|
-
</div>
|
|
112
|
-
</div>;
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
---
|
|
116
|
-
|
|
117
|
-
## `useStepper` Hook
|
|
118
|
-
|
|
119
|
-
A headless hook that manages step navigation state. Supports both **uncontrolled** (internal state) and **controlled** (external `step` prop) modes, plus an optional async `onBeforeNext` guard for validating the current step before advancing.
|
|
120
|
-
|
|
121
|
-
### Props
|
|
122
|
-
|
|
123
|
-
| Prop | Type | Default | Description |
|
|
124
|
-
| -------------- | ------------------------------------------------------ | ------- | ----------------------------------------------------------------------------------------------------------------- |
|
|
125
|
-
| `totalSteps` | `number` | — | **Required.** Total number of steps in the flow |
|
|
126
|
-
| `initialStep` | `number` | `1` | Starting step (uncontrolled mode only). Automatically clamped to `[1, totalSteps]` — out-of-range values are safe |
|
|
127
|
-
| `step` | `number` | — | Controlled current step — when provided, the hook uses this value instead of internal state |
|
|
128
|
-
| `onStepChange` | `(step: number) => void` | — | Called whenever the step changes |
|
|
129
|
-
| `onBeforeNext` | `(currentStep: number) => boolean \| Promise<boolean>` | — | Optional async guard — return `false` (or resolve to `false`) to block advancing to the next step |
|
|
130
|
-
|
|
131
|
-
### Return Value
|
|
132
|
-
|
|
133
|
-
| Property | Type | Description |
|
|
134
|
-
| ------------- | ------------------------ | ---------------------------------------------------------------- |
|
|
135
|
-
| `currentStep` | `number` | The currently active step (1-indexed) |
|
|
136
|
-
| `totalSteps` | `number` | Total number of steps |
|
|
137
|
-
| `isFirstStep` | `boolean` | Whether the current step is the first step |
|
|
138
|
-
| `isLastStep` | `boolean` | Whether the current step is the last step |
|
|
139
|
-
| `canGoPrev` | `boolean` | Whether navigating to the previous step is possible |
|
|
140
|
-
| `canGoNext` | `boolean` | Whether navigating to the next step is possible |
|
|
141
|
-
| `next` | `() => Promise<void>` | Advance to the next step (runs `onBeforeNext` guard if provided) |
|
|
142
|
-
| `prev` | `() => void` | Go back to the previous step |
|
|
143
|
-
| `goTo` | `(step: number) => void` | Jump to a specific step number |
|
|
144
|
-
| `reset` | `() => void` | Reset to the initial step |
|
|
145
|
-
|
|
146
|
-
### Uncontrolled Example
|
|
147
|
-
|
|
148
|
-
```tsx
|
|
149
|
-
import { useStepper, Stepper, Step, Button } from 'xertica-ui/ui';
|
|
150
|
-
|
|
151
|
-
function OnboardingWizard() {
|
|
152
|
-
const { currentStep, isFirstStep, isLastStep, next, prev } = useStepper({
|
|
153
|
-
totalSteps: 3,
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
return (
|
|
157
|
-
<div className="space-y-8">
|
|
158
|
-
<Stepper currentStep={currentStep}>
|
|
159
|
-
<Step step={1} label="Account" />
|
|
160
|
-
<Step step={2} label="Plan" />
|
|
161
|
-
<Step step={3} label="Confirm" />
|
|
162
|
-
</Stepper>
|
|
163
|
-
|
|
164
|
-
<div className="min-h-[200px]">
|
|
165
|
-
{currentStep === 1 && <AccountForm />}
|
|
166
|
-
{currentStep === 2 && <PlanSelector />}
|
|
167
|
-
{currentStep === 3 && <ConfirmationSummary />}
|
|
168
|
-
</div>
|
|
169
|
-
|
|
170
|
-
<div className="flex justify-between">
|
|
171
|
-
<Button variant="outline" onClick={prev} disabled={isFirstStep}>
|
|
172
|
-
Previous
|
|
173
|
-
</Button>
|
|
174
|
-
<Button onClick={next} disabled={isLastStep}>
|
|
175
|
-
{isLastStep ? 'Finish' : 'Next'}
|
|
176
|
-
</Button>
|
|
177
|
-
</div>
|
|
178
|
-
</div>
|
|
179
|
-
);
|
|
180
|
-
}
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### With Async Validation Guard
|
|
184
|
-
|
|
185
|
-
```tsx
|
|
186
|
-
import { useStepper, Stepper, Step, Button } from 'xertica-ui/ui';
|
|
187
|
-
import { useForm } from 'react-hook-form';
|
|
188
|
-
|
|
189
|
-
function ValidatedWizard() {
|
|
190
|
-
const form = useForm();
|
|
191
|
-
|
|
192
|
-
const { currentStep, isFirstStep, isLastStep, next, prev } = useStepper({
|
|
193
|
-
totalSteps: 3,
|
|
194
|
-
onBeforeNext: async step => {
|
|
195
|
-
// Validate only the fields relevant to the current step
|
|
196
|
-
const fieldsPerStep: Record<number, string[]> = {
|
|
197
|
-
1: ['email', 'password'],
|
|
198
|
-
2: ['plan'],
|
|
199
|
-
};
|
|
200
|
-
const fields = fieldsPerStep[step];
|
|
201
|
-
if (!fields) return true;
|
|
202
|
-
return form.trigger(fields as never[]);
|
|
203
|
-
},
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
return (
|
|
207
|
-
<div className="space-y-8">
|
|
208
|
-
<Stepper currentStep={currentStep}>
|
|
209
|
-
<Step step={1} label="Account" />
|
|
210
|
-
<Step step={2} label="Plan" />
|
|
211
|
-
<Step step={3} label="Confirm" />
|
|
212
|
-
</Stepper>
|
|
213
|
-
|
|
214
|
-
<form>{/* step content */}</form>
|
|
215
|
-
|
|
216
|
-
<div className="flex justify-between">
|
|
217
|
-
<Button variant="outline" onClick={prev} disabled={isFirstStep}>
|
|
218
|
-
Previous
|
|
219
|
-
</Button>
|
|
220
|
-
<Button onClick={next}>{isLastStep ? 'Submit' : 'Next'}</Button>
|
|
221
|
-
</div>
|
|
222
|
-
</div>
|
|
223
|
-
);
|
|
224
|
-
}
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
### Controlled Example
|
|
228
|
-
|
|
229
|
-
```tsx
|
|
230
|
-
import { useStepper } from 'xertica-ui/ui';
|
|
231
|
-
import { useState } from 'react';
|
|
232
|
-
|
|
233
|
-
function ControlledWizard() {
|
|
234
|
-
const [step, setStep] = useState(1);
|
|
235
|
-
|
|
236
|
-
const { currentStep, next, prev, isFirstStep, isLastStep } = useStepper({
|
|
237
|
-
totalSteps: 4,
|
|
238
|
-
step, // controlled
|
|
239
|
-
onStepChange: setStep,
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
// currentStep === step at all times
|
|
243
|
-
return (/* ... */);
|
|
244
|
-
}
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
---
|
|
248
|
-
|
|
249
|
-
## AI Rules
|
|
250
|
-
|
|
251
|
-
- `step` props on `<Step>` are **1-indexed** — the first step is `step={1}`, not `step={0}`.
|
|
252
|
-
- Each `<Step>` `step` prop must match its position sequentially: `1, 2, 3, ...`.
|
|
253
|
-
- `currentStep` on `<Stepper>` must be a number from `1` to the total number of steps.
|
|
254
|
-
- Always render the navigation buttons (Previous/Next) below the Stepper.
|
|
255
|
-
- Disable "Previous" on step `1` (`isFirstStep`) and "Next" on the final step (`isLastStep`).
|
|
256
|
-
- Use `onBeforeNext` for async form validation — return `false` to block advancing.
|
|
257
|
-
- `next()` is **async** — always `await` it or use it as an `onClick` handler directly (React handles the Promise).
|
|
258
|
-
- In controlled mode, pass both `step` and `onStepChange` — omitting `onStepChange` makes the hook read-only.
|
|
259
|
-
- Use `reset()` to return to step 1 after a successful submission.
|
|
260
|
-
- `initialStep` is automatically clamped to `[1, totalSteps]` — passing `0`, negative values, or values beyond `totalSteps` is safe and will not throw.
|
|
261
|
-
- Do NOT add `role="list"`, `aria-current`, or `aria-label` manually to `<Stepper>` or `<Step>` — they are applied automatically since v2.1.9.
|
|
262
|
-
|
|
263
|
-
---
|
|
264
|
-
|
|
265
|
-
## Related Components
|
|
266
|
-
|
|
267
|
-
- [`Progress`](./progress.md) — For generic percentage progress display
|
|
268
|
-
- [`Form`](./form.md) — Commonly used inside multi-step steppers
|
|
1
|
+
# Stepper
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
A visual multi-step progress indicator that shows the user's current position within a sequential process. Uses a composable primitive pattern: `<Stepper>` wraps one or more `<Step>` children, automatically inferring the total number of steps.
|
|
6
|
+
|
|
7
|
+
The package also exports a **headless `useStepper` hook** for building fully custom step-navigation UIs — including async validation guards before advancing — while reusing all the step-state logic.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Exports
|
|
12
|
+
|
|
13
|
+
| Export | Description |
|
|
14
|
+
| ------------------ | ------------------------------------------------ |
|
|
15
|
+
| `Stepper` | Visual step indicator component |
|
|
16
|
+
| `Step` | Individual step item |
|
|
17
|
+
| `useStepper` | Headless hook — all step navigation logic, no UI |
|
|
18
|
+
| `UseStepperProps` | TypeScript props type for the hook |
|
|
19
|
+
| `UseStepperReturn` | TypeScript return type for the hook |
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## When to Use
|
|
24
|
+
|
|
25
|
+
- Multi-step forms (checkout, registration, onboarding)
|
|
26
|
+
- Sequential configuration wizards
|
|
27
|
+
- Any process with 2–7 ordered steps
|
|
28
|
+
|
|
29
|
+
## When NOT to Use
|
|
30
|
+
|
|
31
|
+
- Processes with more than 7 steps — collapse or restructure.
|
|
32
|
+
- Simple 2-step flows — a dialog with "Next"/"Back" is sufficient.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Anatomy
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
<Stepper currentStep={2}>
|
|
40
|
+
<Step step={1} label="Account" description="Create your account" />
|
|
41
|
+
<Step step={2} label="Plan" description="Choose a plan" />
|
|
42
|
+
<Step step={3} label="Confirm" description="Review and confirm" />
|
|
43
|
+
</Stepper>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- Steps are numbered from `1` (not `0`).
|
|
47
|
+
- Steps before `currentStep` render as **completed** (green checkmark).
|
|
48
|
+
- The step equal to `currentStep` renders as **active** (filled primary).
|
|
49
|
+
- Steps after `currentStep` render as **pending** (muted).
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Sub-Components
|
|
54
|
+
|
|
55
|
+
### `Stepper`
|
|
56
|
+
|
|
57
|
+
| Prop | Type | Required | Description |
|
|
58
|
+
| ------------- | ---------------------------- | -------- | ------------------------------------------ |
|
|
59
|
+
| `currentStep` | `number` | **Yes** | The currently active step (1-indexed) |
|
|
60
|
+
| `orientation` | `'horizontal' \| 'vertical'` | No | Layout direction (default: `'horizontal'`) |
|
|
61
|
+
| `className` | `string` | No | Additional CSS classes |
|
|
62
|
+
|
|
63
|
+
The step wrapper div renders with `role="list"` and `aria-label="Progresso: etapa N de M"` automatically.
|
|
64
|
+
|
|
65
|
+
### `Step`
|
|
66
|
+
|
|
67
|
+
| Prop | Type | Required | Description |
|
|
68
|
+
| ------------- | --------- | -------- | --------------------------------------------------- |
|
|
69
|
+
| `step` | `number` | **Yes** | Position of this step (1-indexed, must match order) |
|
|
70
|
+
| `label` | `string` | **Yes** | Step label text |
|
|
71
|
+
| `description` | `string` | No | Optional supplementary text below the label |
|
|
72
|
+
| `error` | `boolean` | No | When `true`, renders the step in error state (red) |
|
|
73
|
+
| `className` | `string` | No | Additional CSS classes |
|
|
74
|
+
|
|
75
|
+
Each `<Step>` renders with `role="listitem"`, `aria-current="step"` (active step only), and `aria-label="Etapa N: Label[, concluída | , atual]"` automatically — no manual ARIA attributes needed.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Examples
|
|
80
|
+
|
|
81
|
+
### Basic 3-Step Flow
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
import { Stepper, Step, Button } from 'xertica-ui/ui';
|
|
85
|
+
import { useState } from 'react';
|
|
86
|
+
|
|
87
|
+
const [currentStep, setCurrentStep] = useState(1);
|
|
88
|
+
|
|
89
|
+
<div className="space-y-8">
|
|
90
|
+
<Stepper currentStep={currentStep}>
|
|
91
|
+
<Step step={1} label="Account" description="Create your account" />
|
|
92
|
+
<Step step={2} label="Plan" description="Choose a plan" />
|
|
93
|
+
<Step step={3} label="Confirm" description="Review and confirm" />
|
|
94
|
+
</Stepper>
|
|
95
|
+
|
|
96
|
+
<div className="min-h-[200px] flex items-center justify-center">
|
|
97
|
+
<p className="text-muted-foreground">Content for step {currentStep}</p>
|
|
98
|
+
</div>
|
|
99
|
+
|
|
100
|
+
<div className="flex justify-between">
|
|
101
|
+
<Button
|
|
102
|
+
variant="outline"
|
|
103
|
+
onClick={() => setCurrentStep(s => Math.max(1, s - 1))}
|
|
104
|
+
disabled={currentStep === 1}
|
|
105
|
+
>
|
|
106
|
+
Previous
|
|
107
|
+
</Button>
|
|
108
|
+
<Button onClick={() => setCurrentStep(s => Math.min(3, s + 1))} disabled={currentStep === 3}>
|
|
109
|
+
{currentStep === 3 ? 'Finish' : 'Next'}
|
|
110
|
+
</Button>
|
|
111
|
+
</div>
|
|
112
|
+
</div>;
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## `useStepper` Hook
|
|
118
|
+
|
|
119
|
+
A headless hook that manages step navigation state. Supports both **uncontrolled** (internal state) and **controlled** (external `step` prop) modes, plus an optional async `onBeforeNext` guard for validating the current step before advancing.
|
|
120
|
+
|
|
121
|
+
### Props
|
|
122
|
+
|
|
123
|
+
| Prop | Type | Default | Description |
|
|
124
|
+
| -------------- | ------------------------------------------------------ | ------- | ----------------------------------------------------------------------------------------------------------------- |
|
|
125
|
+
| `totalSteps` | `number` | — | **Required.** Total number of steps in the flow |
|
|
126
|
+
| `initialStep` | `number` | `1` | Starting step (uncontrolled mode only). Automatically clamped to `[1, totalSteps]` — out-of-range values are safe |
|
|
127
|
+
| `step` | `number` | — | Controlled current step — when provided, the hook uses this value instead of internal state |
|
|
128
|
+
| `onStepChange` | `(step: number) => void` | — | Called whenever the step changes |
|
|
129
|
+
| `onBeforeNext` | `(currentStep: number) => boolean \| Promise<boolean>` | — | Optional async guard — return `false` (or resolve to `false`) to block advancing to the next step |
|
|
130
|
+
|
|
131
|
+
### Return Value
|
|
132
|
+
|
|
133
|
+
| Property | Type | Description |
|
|
134
|
+
| ------------- | ------------------------ | ---------------------------------------------------------------- |
|
|
135
|
+
| `currentStep` | `number` | The currently active step (1-indexed) |
|
|
136
|
+
| `totalSteps` | `number` | Total number of steps |
|
|
137
|
+
| `isFirstStep` | `boolean` | Whether the current step is the first step |
|
|
138
|
+
| `isLastStep` | `boolean` | Whether the current step is the last step |
|
|
139
|
+
| `canGoPrev` | `boolean` | Whether navigating to the previous step is possible |
|
|
140
|
+
| `canGoNext` | `boolean` | Whether navigating to the next step is possible |
|
|
141
|
+
| `next` | `() => Promise<void>` | Advance to the next step (runs `onBeforeNext` guard if provided) |
|
|
142
|
+
| `prev` | `() => void` | Go back to the previous step |
|
|
143
|
+
| `goTo` | `(step: number) => void` | Jump to a specific step number |
|
|
144
|
+
| `reset` | `() => void` | Reset to the initial step |
|
|
145
|
+
|
|
146
|
+
### Uncontrolled Example
|
|
147
|
+
|
|
148
|
+
```tsx
|
|
149
|
+
import { useStepper, Stepper, Step, Button } from 'xertica-ui/ui';
|
|
150
|
+
|
|
151
|
+
function OnboardingWizard() {
|
|
152
|
+
const { currentStep, isFirstStep, isLastStep, next, prev } = useStepper({
|
|
153
|
+
totalSteps: 3,
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
return (
|
|
157
|
+
<div className="space-y-8">
|
|
158
|
+
<Stepper currentStep={currentStep}>
|
|
159
|
+
<Step step={1} label="Account" />
|
|
160
|
+
<Step step={2} label="Plan" />
|
|
161
|
+
<Step step={3} label="Confirm" />
|
|
162
|
+
</Stepper>
|
|
163
|
+
|
|
164
|
+
<div className="min-h-[200px]">
|
|
165
|
+
{currentStep === 1 && <AccountForm />}
|
|
166
|
+
{currentStep === 2 && <PlanSelector />}
|
|
167
|
+
{currentStep === 3 && <ConfirmationSummary />}
|
|
168
|
+
</div>
|
|
169
|
+
|
|
170
|
+
<div className="flex justify-between">
|
|
171
|
+
<Button variant="outline" onClick={prev} disabled={isFirstStep}>
|
|
172
|
+
Previous
|
|
173
|
+
</Button>
|
|
174
|
+
<Button onClick={next} disabled={isLastStep}>
|
|
175
|
+
{isLastStep ? 'Finish' : 'Next'}
|
|
176
|
+
</Button>
|
|
177
|
+
</div>
|
|
178
|
+
</div>
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### With Async Validation Guard
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
import { useStepper, Stepper, Step, Button } from 'xertica-ui/ui';
|
|
187
|
+
import { useForm } from 'react-hook-form';
|
|
188
|
+
|
|
189
|
+
function ValidatedWizard() {
|
|
190
|
+
const form = useForm();
|
|
191
|
+
|
|
192
|
+
const { currentStep, isFirstStep, isLastStep, next, prev } = useStepper({
|
|
193
|
+
totalSteps: 3,
|
|
194
|
+
onBeforeNext: async step => {
|
|
195
|
+
// Validate only the fields relevant to the current step
|
|
196
|
+
const fieldsPerStep: Record<number, string[]> = {
|
|
197
|
+
1: ['email', 'password'],
|
|
198
|
+
2: ['plan'],
|
|
199
|
+
};
|
|
200
|
+
const fields = fieldsPerStep[step];
|
|
201
|
+
if (!fields) return true;
|
|
202
|
+
return form.trigger(fields as never[]);
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
return (
|
|
207
|
+
<div className="space-y-8">
|
|
208
|
+
<Stepper currentStep={currentStep}>
|
|
209
|
+
<Step step={1} label="Account" />
|
|
210
|
+
<Step step={2} label="Plan" />
|
|
211
|
+
<Step step={3} label="Confirm" />
|
|
212
|
+
</Stepper>
|
|
213
|
+
|
|
214
|
+
<form>{/* step content */}</form>
|
|
215
|
+
|
|
216
|
+
<div className="flex justify-between">
|
|
217
|
+
<Button variant="outline" onClick={prev} disabled={isFirstStep}>
|
|
218
|
+
Previous
|
|
219
|
+
</Button>
|
|
220
|
+
<Button onClick={next}>{isLastStep ? 'Submit' : 'Next'}</Button>
|
|
221
|
+
</div>
|
|
222
|
+
</div>
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Controlled Example
|
|
228
|
+
|
|
229
|
+
```tsx
|
|
230
|
+
import { useStepper } from 'xertica-ui/ui';
|
|
231
|
+
import { useState } from 'react';
|
|
232
|
+
|
|
233
|
+
function ControlledWizard() {
|
|
234
|
+
const [step, setStep] = useState(1);
|
|
235
|
+
|
|
236
|
+
const { currentStep, next, prev, isFirstStep, isLastStep } = useStepper({
|
|
237
|
+
totalSteps: 4,
|
|
238
|
+
step, // controlled
|
|
239
|
+
onStepChange: setStep,
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
// currentStep === step at all times
|
|
243
|
+
return (/* ... */);
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## AI Rules
|
|
250
|
+
|
|
251
|
+
- `step` props on `<Step>` are **1-indexed** — the first step is `step={1}`, not `step={0}`.
|
|
252
|
+
- Each `<Step>` `step` prop must match its position sequentially: `1, 2, 3, ...`.
|
|
253
|
+
- `currentStep` on `<Stepper>` must be a number from `1` to the total number of steps.
|
|
254
|
+
- Always render the navigation buttons (Previous/Next) below the Stepper.
|
|
255
|
+
- Disable "Previous" on step `1` (`isFirstStep`) and "Next" on the final step (`isLastStep`).
|
|
256
|
+
- Use `onBeforeNext` for async form validation — return `false` to block advancing.
|
|
257
|
+
- `next()` is **async** — always `await` it or use it as an `onClick` handler directly (React handles the Promise).
|
|
258
|
+
- In controlled mode, pass both `step` and `onStepChange` — omitting `onStepChange` makes the hook read-only.
|
|
259
|
+
- Use `reset()` to return to step 1 after a successful submission.
|
|
260
|
+
- `initialStep` is automatically clamped to `[1, totalSteps]` — passing `0`, negative values, or values beyond `totalSteps` is safe and will not throw.
|
|
261
|
+
- Do NOT add `role="list"`, `aria-current`, or `aria-label` manually to `<Stepper>` or `<Step>` — they are applied automatically since v2.1.9.
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Related Components
|
|
266
|
+
|
|
267
|
+
- [`Progress`](./progress.md) — For generic percentage progress display
|
|
268
|
+
- [`Form`](./form.md) — Commonly used inside multi-step steppers
|