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,91 +1,91 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { cn } from '../../shared/utils';
|
|
3
|
-
|
|
4
|
-
type NotificationBadgeVariant =
|
|
5
|
-
| 'default'
|
|
6
|
-
| 'secondary'
|
|
7
|
-
| 'destructive'
|
|
8
|
-
| 'outline'
|
|
9
|
-
| 'success'
|
|
10
|
-
| 'info'
|
|
11
|
-
| 'warning';
|
|
12
|
-
|
|
13
|
-
interface NotificationBadgeProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
14
|
-
count?: number;
|
|
15
|
-
max?: number;
|
|
16
|
-
showZero?: boolean;
|
|
17
|
-
dot?: boolean;
|
|
18
|
-
variant?: NotificationBadgeVariant;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const variantStyles: Record<NotificationBadgeVariant, string> = {
|
|
22
|
-
default: 'bg-primary text-primary-foreground',
|
|
23
|
-
secondary: 'bg-secondary text-secondary-foreground',
|
|
24
|
-
destructive: 'bg-destructive text-destructive-foreground',
|
|
25
|
-
outline: 'border-2 border-primary bg-background text-primary',
|
|
26
|
-
success: 'bg-success text-success-foreground',
|
|
27
|
-
info: 'bg-info text-info-foreground',
|
|
28
|
-
warning: 'bg-warning text-warning-foreground',
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Floating notification count or dot indicator overlay.
|
|
33
|
-
*
|
|
34
|
-
* @description
|
|
35
|
-
* Renders a small floating badge in the top-right corner of its child element
|
|
36
|
-
* to indicate unread counts or alert dots. Supports number display with overflow
|
|
37
|
-
* capping (e.g., `99+`) or a simple dot via `dot={true}`.
|
|
38
|
-
*
|
|
39
|
-
* @ai-rules
|
|
40
|
-
* 1. Use `count` for numeric badges or `dot={true}` for a simple presence indicator.
|
|
41
|
-
* 2. Wrap the target element as a child — the badge positions relative to it automatically.
|
|
42
|
-
* 3. For standalone status labels (not overlays), use `<Badge>` instead.
|
|
43
|
-
* 4. Available variants: `default`, `secondary`, `destructive`, `outline`, `success`, `info`, `warning`.
|
|
44
|
-
*/
|
|
45
|
-
const NotificationBadge = React.forwardRef<HTMLDivElement, NotificationBadgeProps>(
|
|
46
|
-
(
|
|
47
|
-
{
|
|
48
|
-
className,
|
|
49
|
-
count = 0,
|
|
50
|
-
max = 99,
|
|
51
|
-
showZero = false,
|
|
52
|
-
dot = false,
|
|
53
|
-
variant = 'destructive',
|
|
54
|
-
children,
|
|
55
|
-
...props
|
|
56
|
-
},
|
|
57
|
-
ref
|
|
58
|
-
) => {
|
|
59
|
-
const displayCount = count > max ? `${max}+` : count;
|
|
60
|
-
const shouldShow = count > 0 || showZero;
|
|
61
|
-
|
|
62
|
-
if (!shouldShow && !dot) {
|
|
63
|
-
return (
|
|
64
|
-
<div ref={ref} className={className} {...props}>
|
|
65
|
-
{children}
|
|
66
|
-
</div>
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return (
|
|
71
|
-
<div ref={ref} className={cn('relative inline-block', className)} {...props}>
|
|
72
|
-
{children}
|
|
73
|
-
<span
|
|
74
|
-
className={cn(
|
|
75
|
-
'absolute -right-1 -top-1 flex items-center justify-center rounded-full',
|
|
76
|
-
variantStyles[variant],
|
|
77
|
-
dot ? 'h-2 w-2' : 'min-w-[1.25rem] h-5 px-1.5'
|
|
78
|
-
)}
|
|
79
|
-
>
|
|
80
|
-
{!dot && shouldShow && (
|
|
81
|
-
<span className="text-[10px] font-medium leading-none">{displayCount}</span>
|
|
82
|
-
)}
|
|
83
|
-
</span>
|
|
84
|
-
</div>
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
);
|
|
88
|
-
NotificationBadge.displayName = 'NotificationBadge';
|
|
89
|
-
|
|
90
|
-
export { NotificationBadge };
|
|
91
|
-
export type { NotificationBadgeProps, NotificationBadgeVariant };
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { cn } from '../../shared/utils';
|
|
3
|
+
|
|
4
|
+
type NotificationBadgeVariant =
|
|
5
|
+
| 'default'
|
|
6
|
+
| 'secondary'
|
|
7
|
+
| 'destructive'
|
|
8
|
+
| 'outline'
|
|
9
|
+
| 'success'
|
|
10
|
+
| 'info'
|
|
11
|
+
| 'warning';
|
|
12
|
+
|
|
13
|
+
interface NotificationBadgeProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
14
|
+
count?: number;
|
|
15
|
+
max?: number;
|
|
16
|
+
showZero?: boolean;
|
|
17
|
+
dot?: boolean;
|
|
18
|
+
variant?: NotificationBadgeVariant;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const variantStyles: Record<NotificationBadgeVariant, string> = {
|
|
22
|
+
default: 'bg-primary text-primary-foreground',
|
|
23
|
+
secondary: 'bg-secondary text-secondary-foreground',
|
|
24
|
+
destructive: 'bg-destructive text-destructive-foreground',
|
|
25
|
+
outline: 'border-2 border-primary bg-background text-primary',
|
|
26
|
+
success: 'bg-success text-success-foreground',
|
|
27
|
+
info: 'bg-info text-info-foreground',
|
|
28
|
+
warning: 'bg-warning text-warning-foreground',
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Floating notification count or dot indicator overlay.
|
|
33
|
+
*
|
|
34
|
+
* @description
|
|
35
|
+
* Renders a small floating badge in the top-right corner of its child element
|
|
36
|
+
* to indicate unread counts or alert dots. Supports number display with overflow
|
|
37
|
+
* capping (e.g., `99+`) or a simple dot via `dot={true}`.
|
|
38
|
+
*
|
|
39
|
+
* @ai-rules
|
|
40
|
+
* 1. Use `count` for numeric badges or `dot={true}` for a simple presence indicator.
|
|
41
|
+
* 2. Wrap the target element as a child — the badge positions relative to it automatically.
|
|
42
|
+
* 3. For standalone status labels (not overlays), use `<Badge>` instead.
|
|
43
|
+
* 4. Available variants: `default`, `secondary`, `destructive`, `outline`, `success`, `info`, `warning`.
|
|
44
|
+
*/
|
|
45
|
+
const NotificationBadge = React.forwardRef<HTMLDivElement, NotificationBadgeProps>(
|
|
46
|
+
(
|
|
47
|
+
{
|
|
48
|
+
className,
|
|
49
|
+
count = 0,
|
|
50
|
+
max = 99,
|
|
51
|
+
showZero = false,
|
|
52
|
+
dot = false,
|
|
53
|
+
variant = 'destructive',
|
|
54
|
+
children,
|
|
55
|
+
...props
|
|
56
|
+
},
|
|
57
|
+
ref
|
|
58
|
+
) => {
|
|
59
|
+
const displayCount = count > max ? `${max}+` : count;
|
|
60
|
+
const shouldShow = count > 0 || showZero;
|
|
61
|
+
|
|
62
|
+
if (!shouldShow && !dot) {
|
|
63
|
+
return (
|
|
64
|
+
<div ref={ref} className={className} {...props}>
|
|
65
|
+
{children}
|
|
66
|
+
</div>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<div ref={ref} className={cn('relative inline-block', className)} {...props}>
|
|
72
|
+
{children}
|
|
73
|
+
<span
|
|
74
|
+
className={cn(
|
|
75
|
+
'absolute -right-1 -top-1 flex items-center justify-center rounded-full',
|
|
76
|
+
variantStyles[variant],
|
|
77
|
+
dot ? 'h-2 w-2' : 'min-w-[1.25rem] h-5 px-1.5'
|
|
78
|
+
)}
|
|
79
|
+
>
|
|
80
|
+
{!dot && shouldShow && (
|
|
81
|
+
<span className="text-[10px] font-medium leading-none">{displayCount}</span>
|
|
82
|
+
)}
|
|
83
|
+
</span>
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
NotificationBadge.displayName = 'NotificationBadge';
|
|
89
|
+
|
|
90
|
+
export { NotificationBadge };
|
|
91
|
+
export type { NotificationBadgeProps, NotificationBadgeVariant };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './page-header';
|
|
1
|
+
export * from './page-header';
|
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
-
import { PageHeader, PageHeaderHeading, PageHeaderDescription } from './page-header';
|
|
3
|
-
import { Plus, Download, Mail } from 'lucide-react';
|
|
4
|
-
import { Button } from '../button';
|
|
5
|
-
import React from 'react';
|
|
6
|
-
|
|
7
|
-
const meta: Meta<typeof PageHeader> = {
|
|
8
|
-
title: 'UI/PageHeader',
|
|
9
|
-
component: PageHeader,
|
|
10
|
-
render: args => <PageHeader {...args} />,
|
|
11
|
-
parameters: {
|
|
12
|
-
layout: 'padded',
|
|
13
|
-
},
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export default meta;
|
|
17
|
-
type Story = StoryObj<typeof PageHeader>;
|
|
18
|
-
|
|
19
|
-
export const Default: Story = {
|
|
20
|
-
args: {
|
|
21
|
-
title: 'User Management',
|
|
22
|
-
subtitle: 'View and manage team member permissions.',
|
|
23
|
-
},
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export const WithBackButton: Story = {
|
|
27
|
-
args: {
|
|
28
|
-
title: 'Edit Profile',
|
|
29
|
-
subtitle: 'Update your personal information and preferences.',
|
|
30
|
-
backHref: '/users',
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export const WithActions: Story = {
|
|
35
|
-
args: {
|
|
36
|
-
title: 'Sales Report',
|
|
37
|
-
subtitle: 'Detailed analysis of commercial performance for the last quarter.',
|
|
38
|
-
actions: (
|
|
39
|
-
<>
|
|
40
|
-
<Button variant="outline" size="sm" className="gap-2">
|
|
41
|
-
<Download className="h-4 w-4" /> Export
|
|
42
|
-
</Button>
|
|
43
|
-
<Button size="sm" className="gap-2">
|
|
44
|
-
<Plus className="h-4 w-4" /> New Record
|
|
45
|
-
</Button>
|
|
46
|
-
</>
|
|
47
|
-
),
|
|
48
|
-
},
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export const Compact: Story = {
|
|
52
|
-
args: {
|
|
53
|
-
title: 'Settings',
|
|
54
|
-
onBack: () => alert('Going back...'),
|
|
55
|
-
actions: <Button size="sm">Save Changes</Button>,
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
export const Typography: Story = {
|
|
60
|
-
render: () => (
|
|
61
|
-
<div className="space-y-4 max-w-2xl">
|
|
62
|
-
<PageHeaderHeading>Demo Page</PageHeaderHeading>
|
|
63
|
-
<PageHeaderDescription>
|
|
64
|
-
This is an example description using the PageHeaderDescription component, maintaining
|
|
65
|
-
typographic consistency across the entire system.
|
|
66
|
-
</PageHeaderDescription>
|
|
67
|
-
</div>
|
|
68
|
-
),
|
|
69
|
-
};
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { PageHeader, PageHeaderHeading, PageHeaderDescription } from './page-header';
|
|
3
|
+
import { Plus, Download, Mail } from 'lucide-react';
|
|
4
|
+
import { Button } from '../button';
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof PageHeader> = {
|
|
8
|
+
title: 'UI/PageHeader',
|
|
9
|
+
component: PageHeader,
|
|
10
|
+
render: args => <PageHeader {...args} />,
|
|
11
|
+
parameters: {
|
|
12
|
+
layout: 'padded',
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default meta;
|
|
17
|
+
type Story = StoryObj<typeof PageHeader>;
|
|
18
|
+
|
|
19
|
+
export const Default: Story = {
|
|
20
|
+
args: {
|
|
21
|
+
title: 'User Management',
|
|
22
|
+
subtitle: 'View and manage team member permissions.',
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const WithBackButton: Story = {
|
|
27
|
+
args: {
|
|
28
|
+
title: 'Edit Profile',
|
|
29
|
+
subtitle: 'Update your personal information and preferences.',
|
|
30
|
+
backHref: '/users',
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const WithActions: Story = {
|
|
35
|
+
args: {
|
|
36
|
+
title: 'Sales Report',
|
|
37
|
+
subtitle: 'Detailed analysis of commercial performance for the last quarter.',
|
|
38
|
+
actions: (
|
|
39
|
+
<>
|
|
40
|
+
<Button variant="outline" size="sm" className="gap-2">
|
|
41
|
+
<Download className="h-4 w-4" /> Export
|
|
42
|
+
</Button>
|
|
43
|
+
<Button size="sm" className="gap-2">
|
|
44
|
+
<Plus className="h-4 w-4" /> New Record
|
|
45
|
+
</Button>
|
|
46
|
+
</>
|
|
47
|
+
),
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const Compact: Story = {
|
|
52
|
+
args: {
|
|
53
|
+
title: 'Settings',
|
|
54
|
+
onBack: () => alert('Going back...'),
|
|
55
|
+
actions: <Button size="sm">Save Changes</Button>,
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const Typography: Story = {
|
|
60
|
+
render: () => (
|
|
61
|
+
<div className="space-y-4 max-w-2xl">
|
|
62
|
+
<PageHeaderHeading>Demo Page</PageHeaderHeading>
|
|
63
|
+
<PageHeaderDescription>
|
|
64
|
+
This is an example description using the PageHeaderDescription component, maintaining
|
|
65
|
+
typographic consistency across the entire system.
|
|
66
|
+
</PageHeaderDescription>
|
|
67
|
+
</div>
|
|
68
|
+
),
|
|
69
|
+
};
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
import { render, screen, fireEvent } from '@testing-library/react';
|
|
2
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
3
|
-
import { PageHeader } from './page-header';
|
|
4
|
-
import React from 'react';
|
|
5
|
-
|
|
6
|
-
describe('PageHeader', () => {
|
|
7
|
-
it('renders correctly with title and subtitle', () => {
|
|
8
|
-
render(<PageHeader title="Main Title" subtitle="Description" />);
|
|
9
|
-
|
|
10
|
-
expect(screen.getByText('Main Title')).toBeInTheDocument();
|
|
11
|
-
expect(screen.getByText('Description')).toBeInTheDocument();
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('renders back button when onBack is provided', () => {
|
|
15
|
-
const onBack = vi.fn();
|
|
16
|
-
render(<PageHeader title="Title" onBack={onBack} />);
|
|
17
|
-
|
|
18
|
-
const backButton = screen.getByLabelText('Back');
|
|
19
|
-
expect(backButton).toBeInTheDocument();
|
|
20
|
-
|
|
21
|
-
fireEvent.click(backButton);
|
|
22
|
-
expect(onBack).toHaveBeenCalled();
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it('renders back link when backHref is provided', () => {
|
|
26
|
-
render(<PageHeader title="Title" backHref="/home" />);
|
|
27
|
-
|
|
28
|
-
const backLink = screen.getByRole('link');
|
|
29
|
-
expect(backLink).toHaveAttribute('href', '/home');
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('renders actions correctly', () => {
|
|
33
|
-
render(<PageHeader title="Title" actions={<button>Create</button>} />);
|
|
34
|
-
|
|
35
|
-
expect(screen.getByRole('button', { name: /create/i })).toBeInTheDocument();
|
|
36
|
-
});
|
|
37
|
-
});
|
|
1
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
2
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
3
|
+
import { PageHeader } from './page-header';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
|
|
6
|
+
describe('PageHeader', () => {
|
|
7
|
+
it('renders correctly with title and subtitle', () => {
|
|
8
|
+
render(<PageHeader title="Main Title" subtitle="Description" />);
|
|
9
|
+
|
|
10
|
+
expect(screen.getByText('Main Title')).toBeInTheDocument();
|
|
11
|
+
expect(screen.getByText('Description')).toBeInTheDocument();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('renders back button when onBack is provided', () => {
|
|
15
|
+
const onBack = vi.fn();
|
|
16
|
+
render(<PageHeader title="Title" onBack={onBack} />);
|
|
17
|
+
|
|
18
|
+
const backButton = screen.getByLabelText('Back');
|
|
19
|
+
expect(backButton).toBeInTheDocument();
|
|
20
|
+
|
|
21
|
+
fireEvent.click(backButton);
|
|
22
|
+
expect(onBack).toHaveBeenCalled();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('renders back link when backHref is provided', () => {
|
|
26
|
+
render(<PageHeader title="Title" backHref="/home" />);
|
|
27
|
+
|
|
28
|
+
const backLink = screen.getByRole('link');
|
|
29
|
+
expect(backLink).toHaveAttribute('href', '/home');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('renders actions correctly', () => {
|
|
33
|
+
render(<PageHeader title="Title" actions={<button>Create</button>} />);
|
|
34
|
+
|
|
35
|
+
expect(screen.getByRole('button', { name: /create/i })).toBeInTheDocument();
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -1,124 +1,124 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { ChevronLeft } from 'lucide-react';
|
|
3
|
-
import { cn } from '../../shared/utils';
|
|
4
|
-
import { Button } from '../button';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Props for the PageHeader component.
|
|
8
|
-
*/
|
|
9
|
-
export interface PageHeaderProps {
|
|
10
|
-
/** Main title of the page */
|
|
11
|
-
title: string;
|
|
12
|
-
/** Optional subtitle or description */
|
|
13
|
-
subtitle?: string;
|
|
14
|
-
/** Optional URL for the back button (renders a native `<a>`). */
|
|
15
|
-
backHref?: string;
|
|
16
|
-
/** Optional click handler for the back button. */
|
|
17
|
-
onBack?: () => void;
|
|
18
|
-
/**
|
|
19
|
-
* Custom back link renderer — use this for SPA router links (React Router, Next.js, etc.)
|
|
20
|
-
* so the navigation does not trigger a full page reload.
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* // React Router
|
|
24
|
-
* renderBackLink={(icon) => <Link to="/previous">{icon}</Link>}
|
|
25
|
-
* // Next.js
|
|
26
|
-
* renderBackLink={(icon) => <NextLink href="/previous">{icon}</NextLink>}
|
|
27
|
-
*/
|
|
28
|
-
renderBackLink?: (icon: React.ReactNode) => React.ReactElement;
|
|
29
|
-
/** Action buttons or elements to display on the right */
|
|
30
|
-
actions?: React.ReactNode;
|
|
31
|
-
/** Additional CSS classes */
|
|
32
|
-
className?: string;
|
|
33
|
-
/** Accessible label for the back button. @default "Back" */
|
|
34
|
-
backLabel?: string;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Standard Header for individual pages or sections.
|
|
39
|
-
*
|
|
40
|
-
* @description
|
|
41
|
-
* Use this component at the top of your page content to provide a consistent
|
|
42
|
-
* title, optional subtitle, navigation (back button), and primary actions.
|
|
43
|
-
*
|
|
44
|
-
* @ai-rules
|
|
45
|
-
* 1. Use `title` for the primary H1-level descriptor of the page.
|
|
46
|
-
* 2. Prefer `renderBackLink` over `backHref` in SPA projects (React Router, Next.js) to avoid full reloads.
|
|
47
|
-
* 3. Use `actions` for buttons like "Save", "Create", or secondary dropdowns.
|
|
48
|
-
*/
|
|
49
|
-
export function PageHeader({
|
|
50
|
-
title,
|
|
51
|
-
subtitle,
|
|
52
|
-
backHref,
|
|
53
|
-
onBack,
|
|
54
|
-
renderBackLink,
|
|
55
|
-
actions,
|
|
56
|
-
className,
|
|
57
|
-
backLabel = 'Back',
|
|
58
|
-
}: PageHeaderProps) {
|
|
59
|
-
const showBack = !!(backHref || onBack || renderBackLink);
|
|
60
|
-
const icon = <ChevronLeft className="h-5 w-5" />;
|
|
61
|
-
|
|
62
|
-
return (
|
|
63
|
-
<div
|
|
64
|
-
className={cn(
|
|
65
|
-
'flex flex-col gap-4 md:flex-row md:items-center md:justify-between mb-8',
|
|
66
|
-
className
|
|
67
|
-
)}
|
|
68
|
-
>
|
|
69
|
-
<div className="flex items-start gap-4">
|
|
70
|
-
{showBack && (
|
|
71
|
-
<Button
|
|
72
|
-
variant="outline"
|
|
73
|
-
size="icon"
|
|
74
|
-
className="h-10 w-10 shrink-0"
|
|
75
|
-
onClick={onBack}
|
|
76
|
-
asChild={!!renderBackLink || !!backHref}
|
|
77
|
-
aria-label={backLabel}
|
|
78
|
-
>
|
|
79
|
-
{renderBackLink ? (
|
|
80
|
-
renderBackLink(icon)
|
|
81
|
-
) : backHref ? (
|
|
82
|
-
<a href={backHref}>{icon}</a>
|
|
83
|
-
) : (
|
|
84
|
-
icon
|
|
85
|
-
)}
|
|
86
|
-
</Button>
|
|
87
|
-
)}
|
|
88
|
-
<div className="flex flex-col space-y-1">
|
|
89
|
-
<h1 className="text-2xl font-semibold tracking-tight text-foreground">{title}</h1>
|
|
90
|
-
{subtitle && <p className="text-sm text-muted-foreground">{subtitle}</p>}
|
|
91
|
-
</div>
|
|
92
|
-
</div>
|
|
93
|
-
{actions && <div className="flex items-center gap-2">{actions}</div>}
|
|
94
|
-
</div>
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Styled Heading for custom page headers.
|
|
100
|
-
*/
|
|
101
|
-
export function PageHeaderHeading({
|
|
102
|
-
className,
|
|
103
|
-
...props
|
|
104
|
-
}: React.HTMLAttributes<HTMLHeadingElement>) {
|
|
105
|
-
return (
|
|
106
|
-
<h1
|
|
107
|
-
className={cn(
|
|
108
|
-
'text-3xl font-bold leading-tight tracking-tighter md:text-4xl lg:leading-[1.1]',
|
|
109
|
-
className
|
|
110
|
-
)}
|
|
111
|
-
{...props}
|
|
112
|
-
/>
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Styled Description for custom page headers.
|
|
118
|
-
*/
|
|
119
|
-
export function PageHeaderDescription({
|
|
120
|
-
className,
|
|
121
|
-
...props
|
|
122
|
-
}: React.HTMLAttributes<HTMLParagraphElement>) {
|
|
123
|
-
return <p className={cn('text-lg text-muted-foreground sm:text-xl', className)} {...props} />;
|
|
124
|
-
}
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ChevronLeft } from 'lucide-react';
|
|
3
|
+
import { cn } from '../../shared/utils';
|
|
4
|
+
import { Button } from '../button';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Props for the PageHeader component.
|
|
8
|
+
*/
|
|
9
|
+
export interface PageHeaderProps {
|
|
10
|
+
/** Main title of the page */
|
|
11
|
+
title: string;
|
|
12
|
+
/** Optional subtitle or description */
|
|
13
|
+
subtitle?: string;
|
|
14
|
+
/** Optional URL for the back button (renders a native `<a>`). */
|
|
15
|
+
backHref?: string;
|
|
16
|
+
/** Optional click handler for the back button. */
|
|
17
|
+
onBack?: () => void;
|
|
18
|
+
/**
|
|
19
|
+
* Custom back link renderer — use this for SPA router links (React Router, Next.js, etc.)
|
|
20
|
+
* so the navigation does not trigger a full page reload.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // React Router
|
|
24
|
+
* renderBackLink={(icon) => <Link to="/previous">{icon}</Link>}
|
|
25
|
+
* // Next.js
|
|
26
|
+
* renderBackLink={(icon) => <NextLink href="/previous">{icon}</NextLink>}
|
|
27
|
+
*/
|
|
28
|
+
renderBackLink?: (icon: React.ReactNode) => React.ReactElement;
|
|
29
|
+
/** Action buttons or elements to display on the right */
|
|
30
|
+
actions?: React.ReactNode;
|
|
31
|
+
/** Additional CSS classes */
|
|
32
|
+
className?: string;
|
|
33
|
+
/** Accessible label for the back button. @default "Back" */
|
|
34
|
+
backLabel?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Standard Header for individual pages or sections.
|
|
39
|
+
*
|
|
40
|
+
* @description
|
|
41
|
+
* Use this component at the top of your page content to provide a consistent
|
|
42
|
+
* title, optional subtitle, navigation (back button), and primary actions.
|
|
43
|
+
*
|
|
44
|
+
* @ai-rules
|
|
45
|
+
* 1. Use `title` for the primary H1-level descriptor of the page.
|
|
46
|
+
* 2. Prefer `renderBackLink` over `backHref` in SPA projects (React Router, Next.js) to avoid full reloads.
|
|
47
|
+
* 3. Use `actions` for buttons like "Save", "Create", or secondary dropdowns.
|
|
48
|
+
*/
|
|
49
|
+
export function PageHeader({
|
|
50
|
+
title,
|
|
51
|
+
subtitle,
|
|
52
|
+
backHref,
|
|
53
|
+
onBack,
|
|
54
|
+
renderBackLink,
|
|
55
|
+
actions,
|
|
56
|
+
className,
|
|
57
|
+
backLabel = 'Back',
|
|
58
|
+
}: PageHeaderProps) {
|
|
59
|
+
const showBack = !!(backHref || onBack || renderBackLink);
|
|
60
|
+
const icon = <ChevronLeft className="h-5 w-5" />;
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<div
|
|
64
|
+
className={cn(
|
|
65
|
+
'flex flex-col gap-4 md:flex-row md:items-center md:justify-between mb-8',
|
|
66
|
+
className
|
|
67
|
+
)}
|
|
68
|
+
>
|
|
69
|
+
<div className="flex items-start gap-4">
|
|
70
|
+
{showBack && (
|
|
71
|
+
<Button
|
|
72
|
+
variant="outline"
|
|
73
|
+
size="icon"
|
|
74
|
+
className="h-10 w-10 shrink-0"
|
|
75
|
+
onClick={onBack}
|
|
76
|
+
asChild={!!renderBackLink || !!backHref}
|
|
77
|
+
aria-label={backLabel}
|
|
78
|
+
>
|
|
79
|
+
{renderBackLink ? (
|
|
80
|
+
renderBackLink(icon)
|
|
81
|
+
) : backHref ? (
|
|
82
|
+
<a href={backHref}>{icon}</a>
|
|
83
|
+
) : (
|
|
84
|
+
icon
|
|
85
|
+
)}
|
|
86
|
+
</Button>
|
|
87
|
+
)}
|
|
88
|
+
<div className="flex flex-col space-y-1">
|
|
89
|
+
<h1 className="text-2xl font-semibold tracking-tight text-foreground">{title}</h1>
|
|
90
|
+
{subtitle && <p className="text-sm text-muted-foreground">{subtitle}</p>}
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
{actions && <div className="flex items-center gap-2">{actions}</div>}
|
|
94
|
+
</div>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Styled Heading for custom page headers.
|
|
100
|
+
*/
|
|
101
|
+
export function PageHeaderHeading({
|
|
102
|
+
className,
|
|
103
|
+
...props
|
|
104
|
+
}: React.HTMLAttributes<HTMLHeadingElement>) {
|
|
105
|
+
return (
|
|
106
|
+
<h1
|
|
107
|
+
className={cn(
|
|
108
|
+
'text-3xl font-bold leading-tight tracking-tighter md:text-4xl lg:leading-[1.1]',
|
|
109
|
+
className
|
|
110
|
+
)}
|
|
111
|
+
{...props}
|
|
112
|
+
/>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Styled Description for custom page headers.
|
|
118
|
+
*/
|
|
119
|
+
export function PageHeaderDescription({
|
|
120
|
+
className,
|
|
121
|
+
...props
|
|
122
|
+
}: React.HTMLAttributes<HTMLParagraphElement>) {
|
|
123
|
+
return <p className={cn('text-lg text-muted-foreground sm:text-xl', className)} {...props} />;
|
|
124
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from './pagination';
|
|
2
|
-
export { usePagination } from './use-pagination';
|
|
3
|
-
export type { PaginationPageItem, UsePaginationProps, UsePaginationReturn } from './use-pagination';
|
|
1
|
+
export * from './pagination';
|
|
2
|
+
export { usePagination } from './use-pagination';
|
|
3
|
+
export type { PaginationPageItem, UsePaginationProps, UsePaginationReturn } from './use-pagination';
|