xertica-ui 2.5.2 → 2.6.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 +687 -656
- package/README.md +482 -482
- package/assets/xertica-logo.svg +37 -37
- package/assets/xertica-x-logo.svg +20 -20
- package/bin/cli.ts +1293 -1256
- package/bin/generate-tokens.ts +256 -262
- package/bin/language-config.test.ts +32 -0
- package/bin/language-config.ts +36 -11
- package/components/Introduction.mdx +121 -121
- package/components/assistant/code-block/CodeBlock.tsx +7 -6
- package/components/assistant/code-block/code-block.mdx +38 -38
- package/components/assistant/code-block/code-block.test.tsx +2 -1
- package/components/assistant/formatted-document/FormattedDocument.tsx +3 -0
- package/components/assistant/formatted-document/formatted-document.mdx +31 -31
- package/components/assistant/formatted-document/formatted-document.test.tsx +5 -4
- package/components/assistant/markdown-message/MarkdownMessage.tsx +1 -1
- package/components/assistant/markdown-message/markdown-message.mdx +44 -44
- package/components/assistant/modern-chat-input/modern-chat-input.mdx +71 -71
- package/components/assistant/modern-chat-input/modern-chat-input.test.tsx +3 -2
- package/components/assistant/xertica-assistant/parts/AssistantMessageBubble.tsx +1 -1
- package/components/assistant/xertica-assistant/types.ts +3 -2
- package/components/assistant/xertica-assistant/use-assistant.ts +5 -4
- package/components/assistant/xertica-assistant/xertica-assistant.mdx +66 -66
- package/components/assistant/xertica-assistant/xertica-assistant.test.tsx +2 -1
- package/components/blocks/card-patterns/card-patterns.mdx +123 -123
- package/components/brand/branding/branding.mdx +27 -27
- package/components/brand/language-selector/language-selector.mdx +126 -126
- package/components/brand/theme-toggle/theme-toggle.mdx +47 -47
- package/components/brand/theme-toggle/theme-toggle.test.tsx +6 -2
- package/components/brand/xertica-logo/xertica-logo.mdx +56 -56
- package/components/brand/xertica-orbe/xertica-orbe.mdx +38 -38
- package/components/brand/xertica-provider/XerticaProvider.tsx +112 -112
- package/components/brand/xertica-provider/xertica-provider.mdx +61 -61
- package/components/brand/xertica-provider/xertica-provider.test.tsx +25 -13
- package/components/brand/xertica-xlogo/xertica-xlogo.mdx +55 -55
- package/components/examples/DrawingMapExample.tsx +1 -4
- package/components/layout/header/header.mdx +117 -117
- package/components/layout/header/header.test.tsx +2 -1
- package/components/layout/sidebar/sidebar.mdx +99 -99
- package/components/layout/sidebar/sidebar.stories.tsx +1033 -1033
- package/components/layout/sidebar/sidebar.test.tsx +2 -1
- package/components/layout/sidebar/sidebar.tsx +1509 -1501
- package/components/media/audio-player/AudioPlayer.mdx +67 -67
- package/components/media/audio-player/AudioPlayer.test.tsx +2 -1
- package/components/media/floating-media-wrapper.mdx +74 -74
- package/components/media/video-player/VideoPlayer.mdx +102 -102
- package/components/media/video-player/VideoPlayer.test.tsx +3 -2
- package/components/pages/forgot-password-page/ForgotPasswordPage.tsx +188 -188
- package/components/pages/forgot-password-page/forgot-password-page.mdx +60 -60
- package/components/pages/forgot-password-page/forgot-password-page.test.tsx +2 -1
- package/components/pages/home-content/HomeContent.tsx +2 -3
- package/components/pages/home-content/home-content.mdx +62 -62
- package/components/pages/home-page/HomePage.stories.tsx +8 -15
- package/components/pages/home-page/home-page.mdx +53 -53
- package/components/pages/home-page/home-page.test.tsx +2 -1
- package/components/pages/login-page/LoginPage.mdx +31 -31
- package/components/pages/login-page/LoginPage.tsx +218 -218
- package/components/pages/login-page/login-page.test.tsx +2 -1
- package/components/pages/reset-password-page/ResetPasswordPage.tsx +243 -243
- package/components/pages/reset-password-page/reset-password-page.mdx +63 -63
- package/components/pages/template-content/TemplateContent.tsx +2 -3
- package/components/pages/template-content/template-content.mdx +61 -61
- package/components/pages/template-page/TemplatePage.stories.tsx +32 -32
- package/components/pages/template-page/template-page.mdx +53 -53
- package/components/pages/template-page/template-page.test.tsx +2 -1
- package/components/pages/verify-email-page/VerifyEmailPage.tsx +206 -206
- package/components/pages/verify-email-page/verify-email-page.mdx +55 -55
- package/components/public-api-smoke.test.tsx +10 -6
- package/components/shared/assistant-utils.ts +3 -2
- package/components/shared/navigation.ts +2 -2
- package/components/ui/accordion/accordion.mdx +29 -29
- package/components/ui/alert/alert.mdx +29 -29
- package/components/ui/alert-dialog/alert-dialog.mdx +26 -26
- package/components/ui/aspect-ratio/aspect-ratio.mdx +25 -25
- package/components/ui/assistant-chart/AssistantChart.tsx +8 -2
- package/components/ui/assistant-chart/assistant-chart.mdx +25 -25
- package/components/ui/avatar/avatar.mdx +26 -26
- package/components/ui/badge/badge.mdx +28 -28
- package/components/ui/breadcrumb/breadcrumb.mdx +26 -26
- package/components/ui/button/button.mdx +29 -29
- package/components/ui/calendar/calendar.mdx +26 -26
- package/components/ui/card/card.mdx +26 -26
- package/components/ui/carousel/carousel.mdx +26 -26
- package/components/ui/chart/chart.mdx +26 -26
- package/components/ui/chart/chart.test.tsx +178 -178
- package/components/ui/chart/chart.tsx +2252 -2245
- package/components/ui/checkbox/checkbox.mdx +26 -26
- package/components/ui/collapsible/collapsible.mdx +25 -25
- package/components/ui/command/command.mdx +26 -26
- package/components/ui/context-menu/context-menu.mdx +26 -26
- package/components/ui/dialog/dialog.mdx +26 -26
- package/components/ui/drawer/drawer.mdx +26 -26
- package/components/ui/dropdown-menu/dropdown-menu.mdx +26 -26
- package/components/ui/empty/empty.mdx +26 -26
- package/components/ui/file-upload/file-upload.mdx +26 -26
- package/components/ui/form/form.mdx +20 -20
- package/components/ui/google-maps-loader/google-maps-loader.mdx +68 -68
- package/components/ui/hover-card/hover-card.mdx +26 -26
- package/components/ui/input/input.mdx +29 -29
- package/components/ui/input-otp/input-otp.mdx +26 -26
- package/components/ui/label/label.mdx +25 -25
- package/components/ui/map/map.mdx +26 -26
- package/components/ui/map/map.tsx +6 -1
- package/components/ui/menubar/menubar.mdx +26 -26
- package/components/ui/navigation-menu/navigation-menu.mdx +26 -26
- package/components/ui/notification-badge/notification-badge.mdx +26 -26
- package/components/ui/page-header/page-header.mdx +44 -44
- package/components/ui/pagination/pagination.mdx +26 -26
- package/components/ui/popover/popover.mdx +26 -26
- package/components/ui/progress/progress.mdx +25 -25
- package/components/ui/radio-group/radio-group.mdx +26 -26
- package/components/ui/rating/rating.mdx +26 -26
- package/components/ui/resizable/resizable.mdx +26 -26
- package/components/ui/resizable/resizable.tsx +13 -8
- package/components/ui/rich-text-editor/rich-text-editor.mdx +47 -47
- package/components/ui/route-map/route-map.mdx +26 -26
- package/components/ui/scroll-area/scroll-area.mdx +25 -25
- package/components/ui/search/search.mdx +27 -27
- package/components/ui/select/select.mdx +26 -26
- package/components/ui/separator/separator.mdx +25 -25
- package/components/ui/sheet/sheet.mdx +26 -26
- package/components/ui/simple-map/simple-map.mdx +25 -25
- package/components/ui/skeleton/skeleton.mdx +25 -25
- package/components/ui/slider/slider.mdx +26 -26
- package/components/ui/sonner/sonner.mdx +26 -26
- package/components/ui/stats-card/stats-card.mdx +26 -26
- package/components/ui/stats-card/stats-card.stories.tsx +117 -117
- package/components/ui/stats-card/stats-card.tsx +109 -109
- package/components/ui/stepper/stepper.mdx +26 -26
- package/components/ui/switch/switch.mdx +25 -25
- package/components/ui/table/table.mdx +27 -27
- package/components/ui/tabs/tabs.mdx +26 -26
- package/components/ui/textarea/textarea.mdx +25 -25
- package/components/ui/timeline/timeline.mdx +26 -26
- package/components/ui/toggle/toggle.mdx +26 -26
- package/components/ui/toggle-group/toggle-group.mdx +26 -26
- package/components/ui/tooltip/tooltip.mdx +26 -26
- package/components/ui/tree-view/tree-view.mdx +26 -26
- package/components.json +511 -511
- package/contexts/BrandColorsContext.tsx +282 -282
- package/contexts/i18n-singleton.test.tsx +57 -0
- package/contexts/theme-data.ts +391 -391
- package/dist/{AssistantChart-DMJJ_Amf.js → AssistantChart-BMNSA_Pk.js} +5 -5
- package/dist/{AssistantChart-D0A1FPYt.cjs → AssistantChart-BzM7plyc.cjs} +150 -114
- package/dist/{AssistantChart-BXU1ACnh.js → AssistantChart-C842evTi.js} +134 -240
- package/dist/{AssistantChart-BZTPJ5dP.cjs → AssistantChart-CVF2uh37.cjs} +5 -5
- package/dist/{AssistantChart-COGiOV-g.cjs → AssistantChart-JooMdVQU.cjs} +17 -7
- package/dist/{AssistantChart-CWX1OWNM.js → AssistantChart-KHS-tp-L.js} +17 -7
- package/dist/{BrandColorsContext-BwY-b6M4.cjs → BrandColorsContext-B4_81eas.cjs} +2 -2
- package/dist/{BrandColorsContext-BMRJ04Wf.js → BrandColorsContext-DbK5LnQ_.js} +2 -2
- package/dist/{CodeBlock-CjeFavqV.js → CodeBlock-DiKO8ocT.js} +11 -11
- package/dist/{CodeBlock-CV6dtsTM.cjs → CodeBlock-ZYThr7Kn.cjs} +12 -9
- package/dist/{XerticaXLogo-mqjoBiLI.js → LanguageSelector-CmTj3lWq.js} +85 -82
- package/dist/{XerticaXLogo-BX3ueACh.js → LanguageSelector-DxW6o7bt.js} +81 -81
- package/dist/{XerticaXLogo-uQgwns_E.cjs → LanguageSelector-Sw73qvWV.cjs} +84 -81
- package/dist/{ThemeContext-BgclCB35.js → ThemeContext-BGeh_Kdr.js} +290 -212
- package/dist/{ThemeContext-BblcjQup.cjs → ThemeContext-D50irx5T.cjs} +291 -205
- package/dist/{VerifyEmailPage-C_Zk6Gen.cjs → VerifyEmailPage-B6bOrybJ.cjs} +17 -17
- package/dist/{VerifyEmailPage-B31mCrMc.js → VerifyEmailPage-BRE5Fz59.js} +8 -8
- package/dist/{VerifyEmailPage-BJjAMUTW.js → VerifyEmailPage-BcCluouh.js} +151 -78
- package/dist/VerifyEmailPage-Bx1sr0uQ.cjs +3298 -0
- package/dist/{VerifyEmailPage-X14vhdyl.js → VerifyEmailPage-DUYyXCX9.js} +12 -12
- package/dist/VerifyEmailPage-DXXMHbzq.js +3289 -0
- package/dist/{VerifyEmailPage-u_Dn7t1U.cjs → VerifyEmailPage-DpYtFk35.cjs} +21 -21
- package/dist/{VerifyEmailPage-Cyl55sJb.js → VerifyEmailPage-NXKWW3Dk.js} +134 -64
- package/dist/{VerifyEmailPage-Bv8Ah_TK.cjs → VerifyEmailPage-QrCz4Wqr.cjs} +143 -73
- package/dist/{VerifyEmailPage-CkBYfsNy.cjs → VerifyEmailPage-ZmQra0Wi.cjs} +160 -87
- package/dist/{XerticaProvider-BErr83Bg.js → XerticaProvider-BF3q_myt.js} +5 -4
- package/dist/{XerticaProvider-CeS5G_n5.cjs → XerticaProvider-C_JSOz1U.cjs} +2 -2
- package/dist/{XerticaProvider-CwOkHxiT.cjs → XerticaProvider-D5zjrqZq.cjs} +5 -4
- package/dist/{XerticaProvider-ra2NciRq.js → XerticaProvider-KTGl4Cn1.js} +2 -2
- package/dist/{alert-dialog-DqlRW_An.js → alert-dialog-BrpwXKwS.js} +3 -3
- package/dist/{alert-dialog-DhwPioBa.cjs → alert-dialog-CZU1Zase.cjs} +3 -3
- package/dist/{alert-dialog-KpoabzJb.js → alert-dialog-ClRoLH7l.js} +40 -56
- package/dist/{alert-dialog-B4M3vQKS.cjs → alert-dialog-DBBqvU-V.cjs} +53 -38
- package/dist/assistant.cjs.js +2 -2
- package/dist/assistant.es.js +2 -2
- package/dist/brand.cjs.js +6 -6
- package/dist/brand.es.js +2 -2
- package/dist/cli.js +63 -21
- package/dist/components/assistant/code-block/CodeBlock.d.ts +2 -1
- package/dist/components/assistant/formatted-document/FormattedDocument.d.ts +2 -1
- package/dist/components/assistant/markdown-message/MarkdownMessage.d.ts +2 -1
- package/dist/components/assistant/modern-chat-input/ModernChatInput.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/parts/AssistantCollapsedView.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/parts/AssistantConversationList.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/parts/AssistantHeader.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/parts/AssistantMessageBubble.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/parts/AssistantTabBar.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/parts/AssistantTypingIndicator.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.d.ts +2 -1
- package/dist/components/assistant/xertica-assistant/types.d.ts +3 -2
- package/dist/components/assistant/xertica-assistant/use-assistant.d.ts +1 -1
- package/dist/components/assistant/xertica-assistant/xertica-assistant.d.ts +2 -1
- package/dist/components/blocks/card-patterns/ActivityCard.d.ts +1 -1
- package/dist/components/blocks/card-patterns/ActivityCardSkeleton.d.ts +1 -1
- package/dist/components/blocks/card-patterns/FeatureCard.d.ts +1 -1
- package/dist/components/blocks/card-patterns/FeatureCardSkeleton.d.ts +1 -1
- package/dist/components/blocks/card-patterns/NotificationCard.d.ts +1 -1
- package/dist/components/blocks/card-patterns/NotificationCardSkeleton.d.ts +1 -1
- package/dist/components/blocks/card-patterns/ProfileCard.d.ts +1 -1
- package/dist/components/blocks/card-patterns/ProfileCardSkeleton.d.ts +1 -1
- package/dist/components/blocks/card-patterns/ProjectCard.d.ts +1 -1
- package/dist/components/blocks/card-patterns/ProjectCardSkeleton.d.ts +1 -1
- package/dist/components/blocks/card-patterns/QuickActionCard.d.ts +1 -1
- package/dist/components/blocks/card-patterns/QuickActionCardSkeleton.d.ts +1 -1
- package/dist/components/brand/language-selector/LanguageSelector.d.ts +2 -1
- package/dist/components/brand/theme-toggle/ThemeToggle.d.ts +2 -1
- package/dist/components/brand/xertica-logo/XerticaLogo.d.ts +2 -1
- package/dist/components/brand/xertica-orbe/XerticaOrbe.d.ts +2 -1
- package/dist/components/brand/xertica-provider/XerticaProvider.d.ts +1 -1
- package/dist/components/brand/xertica-xlogo/XerticaXLogo.d.ts +2 -1
- package/dist/components/examples/DrawingMapExample.d.ts +2 -1
- package/dist/components/examples/FilterableMapExample.d.ts +1 -1
- package/dist/components/examples/MapShowcase.d.ts +2 -1
- package/dist/components/examples/SimpleFilterableMap.d.ts +2 -1
- package/dist/components/figma/ImageWithFallback.d.ts +1 -1
- package/dist/components/layout/header/header.d.ts +1 -1
- package/dist/components/layout/sidebar/sidebar.d.ts +25 -13
- package/dist/components/media/FloatingMediaWrapper.d.ts +1 -1
- package/dist/components/media/audio-player/AudioPlayer.d.ts +2 -1
- package/dist/components/media/video-player/VideoPlayer.d.ts +2 -1
- package/dist/components/pages/forgot-password-page/ForgotPasswordPage.d.ts +2 -1
- package/dist/components/pages/home-content/HomeContent.d.ts +2 -1
- package/dist/components/pages/home-page/HomePage.d.ts +2 -1
- package/dist/components/pages/login-page/LoginPage.d.ts +2 -1
- package/dist/components/pages/reset-password-page/ResetPasswordPage.d.ts +2 -1
- package/dist/components/pages/template-content/TemplateContent.d.ts +2 -1
- package/dist/components/pages/template-page/TemplatePage.d.ts +2 -1
- package/dist/components/pages/verify-email-page/VerifyEmailPage.d.ts +2 -1
- package/dist/components/shared/CustomTooltipContent.d.ts +1 -1
- package/dist/components/shared/assistant-utils.d.ts +3 -2
- package/dist/components/shared/error-boundary.d.ts +4 -4
- package/dist/components/shared/error-fallbacks.d.ts +4 -3
- package/dist/components/shared/navigation.d.ts +6 -2
- package/dist/components/ui/accordion/accordion.d.ts +4 -4
- package/dist/components/ui/alert/alert.d.ts +3 -3
- package/dist/components/ui/alert-dialog/alert-dialog.d.ts +10 -10
- package/dist/components/ui/aspect-ratio/aspect-ratio.d.ts +1 -1
- package/dist/components/ui/assistant-chart/AssistantChart.d.ts +4 -3
- package/dist/components/ui/avatar/avatar.d.ts +3 -3
- package/dist/components/ui/badge/badge.d.ts +1 -1
- package/dist/components/ui/breadcrumb/breadcrumb.d.ts +7 -7
- package/dist/components/ui/calendar/calendar.d.ts +2 -2
- package/dist/components/ui/card/card.d.ts +7 -7
- package/dist/components/ui/carousel/carousel.d.ts +5 -5
- package/dist/components/ui/chart/chart.d.ts +16 -16
- package/dist/components/ui/collapsible/collapsible.d.ts +3 -3
- package/dist/components/ui/command/command.d.ts +9 -9
- package/dist/components/ui/context-menu/context-menu.d.ts +15 -15
- package/dist/components/ui/dialog/dialog.d.ts +9 -9
- package/dist/components/ui/drawer/drawer.d.ts +10 -10
- package/dist/components/ui/dropdown-menu/dropdown-menu.d.ts +15 -15
- package/dist/components/ui/form/form.d.ts +7 -7
- package/dist/components/ui/google-maps-loader/google-maps-loader.d.ts +3 -3
- package/dist/components/ui/hover-card/hover-card.d.ts +3 -3
- package/dist/components/ui/input-otp/input-otp.d.ts +4 -4
- package/dist/components/ui/label/label.d.ts +1 -1
- package/dist/components/ui/menubar/menubar.d.ts +16 -16
- package/dist/components/ui/navigation-menu/navigation-menu.d.ts +8 -8
- package/dist/components/ui/page-header/page-header.d.ts +3 -3
- package/dist/components/ui/pagination/pagination.d.ts +7 -7
- package/dist/components/ui/popover/popover.d.ts +4 -4
- package/dist/components/ui/progress/progress.d.ts +1 -1
- package/dist/components/ui/resizable/resizable.d.ts +11 -7
- package/dist/components/ui/rich-text-editor/rich-text-editor.d.ts +1 -1
- package/dist/components/ui/scroll-area/scroll-area.d.ts +2 -2
- package/dist/components/ui/separator/separator.d.ts +1 -1
- package/dist/components/ui/sheet/sheet.d.ts +10 -10
- package/dist/components/ui/skeleton/skeleton.d.ts +1 -1
- package/dist/components/ui/sonner/sonner.d.ts +2 -1
- package/dist/components/ui/stats-card/stats-card-skeleton.d.ts +1 -1
- package/dist/components/ui/table/table.d.ts +8 -8
- package/dist/components/ui/tabs/tabs.d.ts +4 -4
- package/dist/components/ui/tooltip/tooltip.d.ts +4 -4
- package/dist/contexts/ApiKeyContext.d.ts +2 -2
- package/dist/contexts/AssistenteContext.d.ts +1 -1
- package/dist/contexts/AuthContext.d.ts +1 -1
- package/dist/contexts/LanguageContext.d.ts +2 -2
- package/dist/contexts/LayoutContext.d.ts +2 -2
- package/dist/contexts/ThemeContext.d.ts +1 -1
- package/dist/features/assistant/hooks/useAssistantConfig.d.ts +1 -1
- package/dist/features/home/hooks/useDashboardStats.d.ts +1 -1
- package/dist/features/home/hooks/useFeatureCards.d.ts +1 -1
- package/dist/features/home/hooks/useTeamMembers.d.ts +1 -1
- package/dist/{google-maps-loader-BCe58h9D.js → google-maps-loader-BOug999f.js} +0 -4
- package/dist/{google-maps-loader-casMyxlo.cjs → google-maps-loader-DfeBRI8Q.cjs} +0 -5
- package/dist/hooks.cjs.js +2 -2
- package/dist/hooks.es.js +2 -2
- package/dist/{index-9GWd0qxq.cjs → index-BQjx1Mdf.cjs} +1 -1
- package/dist/index-Bei5DzAL.js +6 -0
- package/dist/index.cjs.js +18 -18
- package/dist/index.es.js +12 -12
- package/dist/{input-cc-PTD4R.js → input-B0_vbA3g.js} +3 -61
- package/dist/{input-C_UiS2Py.cjs → input-ByYuOv8A.cjs} +1 -62
- package/dist/layout.cjs.js +1 -1
- package/dist/layout.es.js +1 -1
- package/dist/pages.cjs.js +1 -1
- package/dist/pages.es.js +1 -1
- package/dist/{rich-text-editor-DxO1Hz3a.cjs → rich-text-editor-BuqSu718.cjs} +70 -5
- package/dist/{rich-text-editor-DqLICivI.js → rich-text-editor-CV8FtA_l.js} +68 -6
- package/dist/{rich-text-editor-DloeW0wc.js → rich-text-editor-DV1SixzE.js} +61 -3
- package/dist/{rich-text-editor-B2CKz7nx.cjs → rich-text-editor-DnSDglzW.cjs} +63 -2
- package/dist/{sidebar-BS1p2V7t.cjs → sidebar-BGJ0j567.cjs} +367 -9
- package/dist/{sidebar-3XyzjVBw.js → sidebar-BI6mZlC8.js} +364 -6
- package/dist/{sidebar-DyYvgyBj.cjs → sidebar-BtmotOg-.cjs} +367 -9
- package/dist/{sidebar-Duermn32.js → sidebar-D3EgGVxF.js} +77 -63
- package/dist/{sidebar-CLmIjgNd.cjs → sidebar-DDTqMGnR.cjs} +80 -66
- package/dist/{sidebar-B4ZWaMrE.js → sidebar-I7EXyf5D.js} +364 -6
- package/dist/ui.cjs.js +7 -7
- package/dist/ui.es.js +5 -5
- package/dist/{xertica-assistant-QFUnv5I2.cjs → xertica-assistant-BrF9jScR.cjs} +4 -4
- package/dist/{xertica-assistant-BbgzsgsG.js → xertica-assistant-CJVnvMqU.js} +55 -45
- package/dist/{xertica-assistant-d2qs2Vd9.cjs → xertica-assistant-CKPtc1z5.cjs} +58 -40
- package/dist/{xertica-assistant-CyikE3N_.js → xertica-assistant-CsBsxTsI.js} +2 -2
- package/dist/{xertica-assistant-CIaUlbIt.cjs → xertica-assistant-DER0brPQ.cjs} +6 -5
- package/dist/{xertica-assistant-B1NaSFFj.js → xertica-assistant-DQCjpk5M.js} +4 -3
- package/dist/{xertica-assistant-B687qEPU.js → xertica-assistant-Dk-9AJzw.js} +16 -7
- package/dist/{xertica-assistant-sOHwTgIP.cjs → xertica-assistant-DxhIKvuY.cjs} +18 -9
- package/dist/xertica-ui.css +2 -2
- package/docs/components/audio-player.md +1 -1
- package/docs/components/sidebar.md +331 -331
- package/docs/components/stats-card.md +138 -138
- package/docs/components/toggle.md +12 -0
- package/docs/doc-audit.md +35 -229
- package/docs/i18n.md +31 -10
- package/docs/llms.md +6 -4
- package/llms-compact.txt +444 -444
- package/llms-full.txt +12144 -12144
- package/llms.txt +187 -187
- package/package.json +223 -219
- package/scripts/a11y-audit.mjs +162 -162
- package/scripts/fix-stories.cjs +19 -19
- package/styles/globals.css +0 -1
- package/styles/xertica/base.css +8 -0
- package/styles/xertica/tokens.css +240 -240
- package/templates/.env.example +2 -2
- package/templates/.prettierignore +4 -4
- package/templates/.prettierrc +10 -10
- package/templates/guidelines/Guidelines.md +865 -865
- package/templates/index.html +13 -13
- package/templates/package.json +69 -69
- package/templates/src/app/components/AuthGuard.tsx +11 -0
- package/templates/src/features/auth/ui/AuthPageShell.tsx +32 -32
- package/templates/src/features/home/ui/HomeContent.tsx +2 -3
- package/templates/src/features/settings/index.ts +2 -0
- package/templates/src/features/settings/ui/SettingsContent.tsx +134 -0
- package/templates/src/features/template/ui/TemplateContent.tsx +2 -3
- package/templates/src/i18n.ts +36 -13
- package/templates/src/locales/en/pages/settings.json +15 -0
- package/templates/src/locales/es/pages/settings.json +15 -0
- package/templates/src/locales/pt-BR/pages/settings.json +15 -0
- package/templates/src/pages/SettingsPage.tsx +28 -0
- package/templates/src/shared/config/navigation.ts +2 -2
- package/templates/src/styles/xertica/tokens.css +240 -240
- package/templates/vite.config.d.ts +2 -2
- package/templates/vite.config.js +20 -20
- package/utils/gemini.ts +2 -2
- package/dist/AssistantChart-9w31gdAb.cjs +0 -3363
- package/dist/AssistantChart-BAudAfne.cjs +0 -3591
- package/dist/AssistantChart-BAx9VQvb.cjs +0 -3374
- package/dist/AssistantChart-BP8upjMk.js +0 -3565
- package/dist/AssistantChart-CVko2A1W.js +0 -3348
- package/dist/AssistantChart-CVzmmhx4.js +0 -3337
- package/dist/AssistantChart-CeU2dIb6.js +0 -3469
- package/dist/AssistantChart-DO5UuX4J.cjs +0 -3495
- package/dist/AudioPlayer-1ypwE2Wh.cjs +0 -936
- package/dist/AudioPlayer-BJ2IuRQW.cjs +0 -1275
- package/dist/AudioPlayer-BWDW6TN9.cjs +0 -1279
- package/dist/AudioPlayer-CM962GEh.js +0 -1280
- package/dist/AudioPlayer-CbZId7cj.cjs +0 -998
- package/dist/AudioPlayer-DU8zt8-z.js +0 -999
- package/dist/AudioPlayer-DuKXrCfy.js +0 -937
- package/dist/AudioPlayer-Xxma6_-H.js +0 -1276
- package/dist/BrandColorsContext-DLVJgtmH.js +0 -666
- package/dist/BrandColorsContext-DZT7JjeD.js +0 -659
- package/dist/BrandColorsContext-GUyFmkX0.cjs +0 -665
- package/dist/BrandColorsContext-awnBCmC4.cjs +0 -666
- package/dist/CodeBlock-C2ZUXt8V.js +0 -219
- package/dist/CodeBlock-C5oYnLQp.cjs +0 -218
- package/dist/CodeBlock-DuxdtN-l.js +0 -219
- package/dist/CodeBlock-POVYONvC.cjs +0 -218
- package/dist/CustomTooltipContent-BT6brkVJ.cjs +0 -49
- package/dist/CustomTooltipContent-CfOfikhq.js +0 -33
- package/dist/CustomTooltipContent-DHjkY0ww.js +0 -40
- package/dist/CustomTooltipContent-c_K-DWRr.cjs +0 -56
- package/dist/FeatureCard-9GhnlgL3.js +0 -336
- package/dist/FeatureCard-Bcb3Zi54.js +0 -302
- package/dist/FeatureCard-Cfs6Ishq.js +0 -485
- package/dist/FeatureCard-CkPd2psQ.cjs +0 -301
- package/dist/FeatureCard-Dkp-xmzM.cjs +0 -335
- package/dist/FeatureCard-ie3L8Fpr.cjs +0 -484
- package/dist/FeatureCardSkeleton-CAgu8stE.js +0 -27
- package/dist/FeatureCardSkeleton-mO3Bdm_V.cjs +0 -26
- package/dist/LanguageContext-BwhwC3G2.js +0 -657
- package/dist/LanguageContext-DvUt5jBg.cjs +0 -656
- package/dist/LayoutContext-BDmcZfMH.cjs +0 -84
- package/dist/LayoutContext-C4kKN9RV.cjs +0 -93
- package/dist/LayoutContext-CGEe1oPq.js +0 -94
- package/dist/LayoutContext-CwT5KLiW.cjs +0 -104
- package/dist/LayoutContext-DVLCsoQn.js +0 -105
- package/dist/LayoutContext-dbQvdC4O.js +0 -85
- package/dist/ThemeContext-BbBNoFTG.js +0 -735
- package/dist/ThemeContext-Bo-W2WZH.js +0 -1856
- package/dist/ThemeContext-CP3a0jxy.cjs +0 -1855
- package/dist/ThemeContext-Cmr8Ex8H.cjs +0 -734
- package/dist/ThemeContext-CpqYShLq.cjs +0 -324
- package/dist/ThemeContext-D3LzacmG.js +0 -188
- package/dist/ThemeContext-DQUOeziy.cjs +0 -1855
- package/dist/ThemeContext-Du2nE1PL.js +0 -325
- package/dist/ThemeContext-GeEBTJ3q.cjs +0 -1621
- package/dist/ThemeContext-JyLK9B1o.js +0 -1622
- package/dist/ThemeContext-RTy1m2Uq.js +0 -82
- package/dist/ThemeContext-U4dEYc6C.cjs +0 -187
- package/dist/ThemeContext-bSzuOit2.cjs +0 -81
- package/dist/ThemeContext-ept8jhXI.js +0 -1856
- package/dist/VerifyEmailPage-BE-L9mB7.js +0 -2828
- package/dist/VerifyEmailPage-BIBOKV7Z.js +0 -3214
- package/dist/VerifyEmailPage-BRSP-Pwt.cjs +0 -3196
- package/dist/VerifyEmailPage-Bae2cBXT.cjs +0 -2827
- package/dist/VerifyEmailPage-BiRm7Nh4.cjs +0 -3213
- package/dist/VerifyEmailPage-Bvfv8HVQ.js +0 -3214
- package/dist/VerifyEmailPage-CR7kb5df.cjs +0 -2827
- package/dist/VerifyEmailPage-C_ihbcth.js +0 -2828
- package/dist/VerifyEmailPage-CbgjOF0v.js +0 -2828
- package/dist/VerifyEmailPage-CdYPSJoO.js +0 -2828
- package/dist/VerifyEmailPage-D-FRj5TU.cjs +0 -3213
- package/dist/VerifyEmailPage-DF2ilhum.cjs +0 -3210
- package/dist/VerifyEmailPage-DMBh4NM9.cjs +0 -2827
- package/dist/VerifyEmailPage-DTtFfC-J.js +0 -3197
- package/dist/VerifyEmailPage-Dt7zgA4w.cjs +0 -2827
- package/dist/VerifyEmailPage-EhudUdqF.js +0 -3211
- package/dist/VerifyEmailPage-RrUApqBN.js +0 -3214
- package/dist/VerifyEmailPage-VoMI7MYH.cjs +0 -3213
- package/dist/VerifyEmailPage-hdB8JQGv.cjs +0 -3213
- package/dist/VerifyEmailPage-vYHbYK3q.js +0 -3214
- package/dist/XerticaOrbe-BCUVSPPB.cjs +0 -1924
- package/dist/XerticaOrbe-BGIB1CTK.js +0 -1355
- package/dist/XerticaOrbe-By8eEvR-.js +0 -1925
- package/dist/XerticaOrbe-FWGjBj0U.cjs +0 -1354
- package/dist/XerticaProvider-AChwphCO.cjs +0 -48
- package/dist/XerticaProvider-AbWlr7Af.cjs +0 -48
- package/dist/XerticaProvider-B8CaV7xu.cjs +0 -39
- package/dist/XerticaProvider-BITjgC5p.js +0 -39
- package/dist/XerticaProvider-BSyFrmC0.js +0 -49
- package/dist/XerticaProvider-By8q3Roe.cjs +0 -38
- package/dist/XerticaProvider-CUYJZc32.js +0 -49
- package/dist/XerticaProvider-CW9hpCdF.cjs +0 -39
- package/dist/XerticaProvider-CWgby5mY.js +0 -49
- package/dist/XerticaProvider-CWs6EwNa.js +0 -49
- package/dist/XerticaProvider-CiNKjMx1.cjs +0 -48
- package/dist/XerticaProvider-CjQAQPcn.cjs +0 -48
- package/dist/XerticaProvider-D5lLumH-.js +0 -49
- package/dist/XerticaProvider-DQtvJU7m.js +0 -40
- package/dist/XerticaProvider-DUOJg9iX.js +0 -49
- package/dist/XerticaProvider-Dl_b72_l.cjs +0 -51
- package/dist/XerticaProvider-qQUDop71.cjs +0 -48
- package/dist/XerticaProvider-siSt9uG2.js +0 -40
- package/dist/XerticaXLogo-8TTzBjHw.cjs +0 -251
- package/dist/XerticaXLogo-B2svDGZh.cjs +0 -251
- package/dist/XerticaXLogo-BWaag64t.js +0 -252
- package/dist/XerticaXLogo-CFuIlYFH.js +0 -252
- package/dist/XerticaXLogo-CU-U-GP4.cjs +0 -251
- package/dist/XerticaXLogo-ChryA6xj.js +0 -252
- package/dist/XerticaXLogo-CowGv7BC.js +0 -252
- package/dist/XerticaXLogo-CziKMQil.cjs +0 -242
- package/dist/XerticaXLogo-D8jf0SNv.cjs +0 -214
- package/dist/XerticaXLogo-DHz5SugF.js +0 -252
- package/dist/XerticaXLogo-DTee_y8X.cjs +0 -251
- package/dist/XerticaXLogo-DfUvz-lD.js +0 -243
- package/dist/XerticaXLogo-DzXKZBtG.js +0 -231
- package/dist/XerticaXLogo-fAJMy3H4.js +0 -215
- package/dist/XerticaXLogo-kslQ8Tk_.cjs +0 -251
- package/dist/XerticaXLogo-xWbElCZj.cjs +0 -230
- package/dist/alert-dialog-iDe5VE5o.js +0 -842
- package/dist/alert-dialog-yckpaOpy.cjs +0 -865
- package/dist/avatar-Cq5_E8r9.cjs +0 -78
- package/dist/avatar-CuYu2MKt.cjs +0 -72
- package/dist/avatar-Cxyofu1H.js +0 -56
- package/dist/avatar-DSBfJMRJ.js +0 -62
- package/dist/breadcrumb-CVzzzqfo.js +0 -103
- package/dist/breadcrumb-DIJ0X3Ot.js +0 -96
- package/dist/breadcrumb-DjSxkjlQ.cjs +0 -95
- package/dist/breadcrumb-DnDlQFg2.cjs +0 -102
- package/dist/button-0CXwCRTm.cjs +0 -85
- package/dist/button-Bnv9SvYK.cjs +0 -79
- package/dist/button-C6uvh0rV.js +0 -63
- package/dist/button-qkz7Icqf.js +0 -69
- package/dist/card-B8-Gl5DL.js +0 -73
- package/dist/card-Bv_c57KU.cjs +0 -72
- package/dist/card-DJTsYhLL.cjs +0 -89
- package/dist/card-fi8zAN-I.js +0 -90
- package/dist/dropdown-menu-B_uEXNc4.cjs +0 -220
- package/dist/dropdown-menu-CFuCssWA.js +0 -204
- package/dist/dropdown-menu-Ze1YZFyc.cjs +0 -247
- package/dist/dropdown-menu-nc_Lvg-u.js +0 -231
- package/dist/google-maps-loader-BVoVhUwA.js +0 -316
- package/dist/google-maps-loader-BqsYL48U.cjs +0 -285
- package/dist/google-maps-loader-DjJaYhV6.cjs +0 -316
- package/dist/google-maps-loader-t2IlYBzw.js +0 -286
- package/dist/index-B7A523O_.js +0 -8
- package/dist/index-BabBx2pa.js +0 -6
- package/dist/index-CkTUgOwX.js +0 -8
- package/dist/index-D3RLKRAs.cjs +0 -7
- package/dist/index-DmHhnb7a.cjs +0 -7
- package/dist/index.umd.js +0 -13712
- package/dist/input-CNFHVKvo.cjs +0 -145
- package/dist/input-CPl84zAx.cjs +0 -151
- package/dist/input-D-6IsAca.js +0 -133
- package/dist/input-wPYg0d0P.js +0 -127
- package/dist/progress-BLwqortq.cjs +0 -105
- package/dist/progress-Cs9i4DPx.js +0 -81
- package/dist/progress-D9mtsf6j.js +0 -89
- package/dist/progress-DDeuWPZw.cjs +0 -97
- package/dist/rich-text-editor-1UW3Y2JK.js +0 -2891
- package/dist/rich-text-editor-BM-LPpTh.js +0 -2902
- package/dist/rich-text-editor-BmsjY03B.js +0 -2949
- package/dist/rich-text-editor-BrdC5evx.js +0 -2244
- package/dist/rich-text-editor-CyggTOLQ.cjs +0 -2908
- package/dist/rich-text-editor-DbV-S7Fi.cjs +0 -2261
- package/dist/rich-text-editor-DoCkKhzk.cjs +0 -2919
- package/dist/rich-text-editor-GS2kpTAK.cjs +0 -2966
- package/dist/routes.d.ts +0 -10
- package/dist/select-Cmb8zF7w.cjs +0 -156
- package/dist/select-CprSNX0z.js +0 -139
- package/dist/select-DT7Zjn42.cjs +0 -162
- package/dist/select-En8DkoaQ.js +0 -145
- package/dist/sidebar-B3EYhli0.cjs +0 -800
- package/dist/sidebar-B9NR0lCe.cjs +0 -800
- package/dist/sidebar-BcJ6LxvX.cjs +0 -733
- package/dist/sidebar-BvF5I2Ue.cjs +0 -800
- package/dist/sidebar-C5B_LHek.cjs +0 -795
- package/dist/sidebar-CA6_ek3f.js +0 -801
- package/dist/sidebar-CRMiBtAi.js +0 -801
- package/dist/sidebar-CVUGHOS_.cjs +0 -756
- package/dist/sidebar-CZ2mWaMM.cjs +0 -800
- package/dist/sidebar-CmvwjnVb.js +0 -757
- package/dist/sidebar-CplprZpM.js +0 -801
- package/dist/sidebar-Dz7bd3zP.js +0 -796
- package/dist/sidebar-KIS0C2JH.js +0 -801
- package/dist/sidebar-OTO_up7Z.js +0 -801
- package/dist/sidebar-WoKvFWCN.js +0 -717
- package/dist/sidebar-zowjejT2.cjs +0 -800
- package/dist/skeleton-4zoHiFJ_.cjs +0 -83
- package/dist/skeleton-C4bHqUBf.js +0 -84
- package/dist/slider-C0JKA9k3.js +0 -56
- package/dist/slider-CPmwzm_3.cjs +0 -73
- package/dist/slider-DcJharR9.cjs +0 -73
- package/dist/slider-Pay3fka2.js +0 -56
- package/dist/sonner-DeUIj0Zg.cjs +0 -63
- package/dist/sonner-g9RIfi35.js +0 -47
- package/dist/tooltip-CNtsL5cB.cjs +0 -71
- package/dist/tooltip-CTyZCD8h.js +0 -55
- package/dist/tooltip-CwgSdy3h.cjs +0 -67
- package/dist/tooltip-D-OrYnKO.js +0 -51
- package/dist/use-audio-player-BJFV24XW.js +0 -188
- package/dist/use-audio-player-Bkh23vQ3.js +0 -177
- package/dist/use-audio-player-Dn1NR9xN.cjs +0 -176
- package/dist/use-audio-player-DyVYlOnR.cjs +0 -187
- package/dist/use-mobile-BB4M_4Ru.cjs +0 -47
- package/dist/use-mobile-CLu9nqGL.js +0 -31
- package/dist/use-mobile-CNwiBNxu.js +0 -33
- package/dist/use-mobile-Dlf74ufz.cjs +0 -49
- package/dist/xertica-assistant-B1IaHXnB.cjs +0 -1894
- package/dist/xertica-assistant-BMqdyRVi.js +0 -2082
- package/dist/xertica-assistant-Bj3vBCq_.cjs +0 -2081
- package/dist/xertica-assistant-CfBCo21g.js +0 -2148
- package/dist/xertica-assistant-DIM_Do1k.js +0 -1866
- package/dist/xertica-assistant-DPsESB6t.js +0 -1878
- package/dist/xertica-assistant-DrsRwla1.cjs +0 -2147
- package/dist/xertica-assistant-Qp3ydksa.cjs +0 -1882
- package/dist/xertica-assistant-gnCJdcZY.js +0 -1866
- package/dist/xertica-assistant-yyrR0JKl.cjs +0 -1882
- package/styles/xertica/app-overrides/scrollbar.css +0 -33
- package/dist/{XerticaXLogo-qBPhwK3g.cjs → LanguageSelector-1cINLJ23.cjs} +80 -80
|
@@ -1,1033 +1,1033 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
-
import { Sidebar, useSidebar } from './sidebar';
|
|
3
|
-
import { useLayout } from '../../../contexts/LayoutContext';
|
|
4
|
-
import { BrowserRouter } from 'react-router-dom';
|
|
5
|
-
import {
|
|
6
|
-
Home,
|
|
7
|
-
Users,
|
|
8
|
-
Settings,
|
|
9
|
-
BarChart,
|
|
10
|
-
Plus,
|
|
11
|
-
Clock,
|
|
12
|
-
FileEdit,
|
|
13
|
-
ArrowRightLeft,
|
|
14
|
-
PanelLeft,
|
|
15
|
-
Menu,
|
|
16
|
-
Trash2,
|
|
17
|
-
Map,
|
|
18
|
-
Archive,
|
|
19
|
-
ShoppingCart,
|
|
20
|
-
Package,
|
|
21
|
-
Tag,
|
|
22
|
-
Truck,
|
|
23
|
-
CreditCard,
|
|
24
|
-
Bell,
|
|
25
|
-
Shield,
|
|
26
|
-
Key,
|
|
27
|
-
Database,
|
|
28
|
-
Server,
|
|
29
|
-
Activity,
|
|
30
|
-
TrendingUp,
|
|
31
|
-
PieChart,
|
|
32
|
-
BarChart2,
|
|
33
|
-
FileText,
|
|
34
|
-
Folder,
|
|
35
|
-
MessageSquare,
|
|
36
|
-
Mail,
|
|
37
|
-
Phone,
|
|
38
|
-
Globe,
|
|
39
|
-
Layers,
|
|
40
|
-
Zap,
|
|
41
|
-
} from 'lucide-react';
|
|
42
|
-
import React, { useState } from 'react';
|
|
43
|
-
import { Badge } from '../../ui/badge';
|
|
44
|
-
import { Button } from '../../ui/button';
|
|
45
|
-
import { Progress } from '../../ui/progress';
|
|
46
|
-
|
|
47
|
-
const meta: Meta<typeof Sidebar> = {
|
|
48
|
-
title: 'Layout/Sidebar',
|
|
49
|
-
component: Sidebar,
|
|
50
|
-
decorators: [
|
|
51
|
-
Story => (
|
|
52
|
-
<BrowserRouter>
|
|
53
|
-
<div className="flex h-screen w-full overflow-hidden bg-background">
|
|
54
|
-
<Story />
|
|
55
|
-
</div>
|
|
56
|
-
</BrowserRouter>
|
|
57
|
-
),
|
|
58
|
-
],
|
|
59
|
-
parameters: {
|
|
60
|
-
layout: 'fullscreen',
|
|
61
|
-
},
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
export default meta;
|
|
65
|
-
type Story = StoryObj<typeof Sidebar>;
|
|
66
|
-
|
|
67
|
-
export const Default: Story = {
|
|
68
|
-
args: {
|
|
69
|
-
variant: 'default',
|
|
70
|
-
expanded: false,
|
|
71
|
-
user: { email: 'admin@example.com' },
|
|
72
|
-
onLogout: () => console.log('Logged out'),
|
|
73
|
-
location: { pathname: '/home' },
|
|
74
|
-
routes: [
|
|
75
|
-
{ path: '/home', label: 'Home', icon: Home },
|
|
76
|
-
{ path: '/dashboard', label: 'Dashboard', icon: Users },
|
|
77
|
-
{ path: '/settings', label: 'Settings', icon: Settings },
|
|
78
|
-
],
|
|
79
|
-
footer: {
|
|
80
|
-
showUser: true,
|
|
81
|
-
showSettings: true,
|
|
82
|
-
showLogout: true,
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
render: args => {
|
|
86
|
-
const { sidebarWidth: contextWidth } = useLayout();
|
|
87
|
-
const [isExpanded, setIsExpanded] = useState(args.expanded);
|
|
88
|
-
|
|
89
|
-
// In Storybook, we match the sidebar widths (280 expanded, 80 collapsed)
|
|
90
|
-
const currentWidth = isExpanded ? 280 : 80;
|
|
91
|
-
|
|
92
|
-
return (
|
|
93
|
-
<div
|
|
94
|
-
className="relative h-screen w-full border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
95
|
-
style={{ transform: 'translateZ(0)' }}
|
|
96
|
-
>
|
|
97
|
-
<Sidebar
|
|
98
|
-
{...args}
|
|
99
|
-
expanded={isExpanded}
|
|
100
|
-
onToggle={() => setIsExpanded(!isExpanded)}
|
|
101
|
-
width={currentWidth}
|
|
102
|
-
navigate={() => {}}
|
|
103
|
-
/>
|
|
104
|
-
<div
|
|
105
|
-
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
106
|
-
style={{ left: `${currentWidth}px` }}
|
|
107
|
-
>
|
|
108
|
-
<div className="text-center">
|
|
109
|
-
<p className="text-muted-foreground">Traditional System Navigation</p>
|
|
110
|
-
<p className="text-xs text-muted-foreground mt-2">Click on the menu icon to expand</p>
|
|
111
|
-
</div>
|
|
112
|
-
</div>
|
|
113
|
-
</div>
|
|
114
|
-
);
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
export const DefaultWithGroups: Story = {
|
|
119
|
-
args: {
|
|
120
|
-
variant: 'default',
|
|
121
|
-
expanded: false,
|
|
122
|
-
user: { name: 'Admin', email: 'admin@example.com' },
|
|
123
|
-
onLogout: () => console.log('Logged out'),
|
|
124
|
-
location: { pathname: '/home' },
|
|
125
|
-
navigationGroups: [
|
|
126
|
-
{
|
|
127
|
-
id: 'main',
|
|
128
|
-
label: 'Principal',
|
|
129
|
-
items: [
|
|
130
|
-
{ path: '/home', label: 'Início', icon: Home },
|
|
131
|
-
{
|
|
132
|
-
path: '/dashboard',
|
|
133
|
-
label: 'Dashboard',
|
|
134
|
-
icon: BarChart,
|
|
135
|
-
children: [
|
|
136
|
-
{ path: '/dashboard/overview', label: 'Visão Geral', icon: BarChart },
|
|
137
|
-
{ path: '/dashboard/reports', label: 'Relatórios', icon: FileEdit },
|
|
138
|
-
{ path: '/dashboard/analytics', label: 'Analytics', icon: Map },
|
|
139
|
-
],
|
|
140
|
-
},
|
|
141
|
-
],
|
|
142
|
-
},
|
|
143
|
-
{
|
|
144
|
-
id: 'admin',
|
|
145
|
-
label: 'Administração',
|
|
146
|
-
items: [
|
|
147
|
-
{
|
|
148
|
-
path: '/users',
|
|
149
|
-
label: 'Usuários',
|
|
150
|
-
icon: Users,
|
|
151
|
-
children: [
|
|
152
|
-
{ path: '/users/list', label: 'Lista de Usuários', icon: Users },
|
|
153
|
-
{ path: '/users/roles', label: 'Perfis de Acesso', icon: Settings },
|
|
154
|
-
],
|
|
155
|
-
},
|
|
156
|
-
{ path: '/settings', label: 'Configurações', icon: Settings },
|
|
157
|
-
],
|
|
158
|
-
},
|
|
159
|
-
],
|
|
160
|
-
footer: {
|
|
161
|
-
showUser: true,
|
|
162
|
-
showSettings: false,
|
|
163
|
-
showLogout: true,
|
|
164
|
-
},
|
|
165
|
-
},
|
|
166
|
-
render: args => {
|
|
167
|
-
const [isExpanded, setIsExpanded] = useState(args.expanded);
|
|
168
|
-
const currentWidth = isExpanded ? 280 : 80;
|
|
169
|
-
|
|
170
|
-
return (
|
|
171
|
-
<div
|
|
172
|
-
className="relative h-screen w-full border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
173
|
-
style={{ transform: 'translateZ(0)' }}
|
|
174
|
-
>
|
|
175
|
-
<Sidebar
|
|
176
|
-
{...args}
|
|
177
|
-
expanded={isExpanded}
|
|
178
|
-
onToggle={() => setIsExpanded(!isExpanded)}
|
|
179
|
-
width={currentWidth}
|
|
180
|
-
navigate={() => {}}
|
|
181
|
-
/>
|
|
182
|
-
<div
|
|
183
|
-
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
184
|
-
style={{ left: `${currentWidth}px` }}
|
|
185
|
-
>
|
|
186
|
-
<div className="text-center">
|
|
187
|
-
<p className="text-muted-foreground">Navigation with Groups and Children</p>
|
|
188
|
-
<p className="text-xs text-muted-foreground mt-2">
|
|
189
|
-
Expand and click the arrow button on items to see sub-menus
|
|
190
|
-
</p>
|
|
191
|
-
</div>
|
|
192
|
-
</div>
|
|
193
|
-
</div>
|
|
194
|
-
);
|
|
195
|
-
},
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
export const Assistant: Story = {
|
|
199
|
-
args: {
|
|
200
|
-
variant: 'assistant',
|
|
201
|
-
expanded: false,
|
|
202
|
-
user: { email: 'admin@example.com' },
|
|
203
|
-
onLogout: () => console.log('Logged out'),
|
|
204
|
-
location: { pathname: '/assistant/refatoracao' },
|
|
205
|
-
search: {
|
|
206
|
-
show: true,
|
|
207
|
-
placeholder: 'Buscar tópicos...',
|
|
208
|
-
filter: {
|
|
209
|
-
show: true,
|
|
210
|
-
content: (
|
|
211
|
-
<div className="p-2 space-y-2">
|
|
212
|
-
<div className="text-xs font-semibold uppercase text-muted-foreground px-2 text-left">
|
|
213
|
-
Filter by Status
|
|
214
|
-
</div>
|
|
215
|
-
<div className="flex flex-wrap gap-2 p-1">
|
|
216
|
-
<Badge className="bg-sidebar-foreground/20 text-sidebar-foreground border-none cursor-pointer hover:bg-sidebar-foreground/30">
|
|
217
|
-
Active
|
|
218
|
-
</Badge>
|
|
219
|
-
<Badge
|
|
220
|
-
variant="outline"
|
|
221
|
-
className="text-sidebar-foreground/70 border-sidebar-foreground/20 cursor-pointer hover:bg-sidebar-foreground/10"
|
|
222
|
-
>
|
|
223
|
-
Archived
|
|
224
|
-
</Badge>
|
|
225
|
-
<Badge
|
|
226
|
-
variant="outline"
|
|
227
|
-
className="text-sidebar-foreground/70 border-sidebar-foreground/20 cursor-pointer hover:bg-sidebar-foreground/10"
|
|
228
|
-
>
|
|
229
|
-
Pending
|
|
230
|
-
</Badge>
|
|
231
|
-
</div>
|
|
232
|
-
</div>
|
|
233
|
-
),
|
|
234
|
-
},
|
|
235
|
-
},
|
|
236
|
-
fixedArea: {
|
|
237
|
-
show: true,
|
|
238
|
-
icon: Plus,
|
|
239
|
-
onClick: () => console.log('New Conversation clicked'),
|
|
240
|
-
content: (
|
|
241
|
-
<Button className="w-full bg-sidebar-primary hover:bg-sidebar-primary/90 text-sidebar-primary-foreground shadow-lg font-bold border-none transition-all duration-300 transform hover:scale-[1.02] active:scale-[0.98]">
|
|
242
|
-
<Plus className="w-4 h-4 mr-2" />
|
|
243
|
-
New Conversation
|
|
244
|
-
</Button>
|
|
245
|
-
),
|
|
246
|
-
},
|
|
247
|
-
navigationGroups: [
|
|
248
|
-
{
|
|
249
|
-
id: 'recent',
|
|
250
|
-
label: 'Recent',
|
|
251
|
-
icon: Clock,
|
|
252
|
-
items: [
|
|
253
|
-
{
|
|
254
|
-
path: '/assistant/refatoracao',
|
|
255
|
-
label: 'Edit Sidebar',
|
|
256
|
-
description: 'Active now',
|
|
257
|
-
actions: [
|
|
258
|
-
{ label: 'Rename', icon: FileEdit, onClick: () => console.log('Open rename...') },
|
|
259
|
-
{
|
|
260
|
-
label: 'Move',
|
|
261
|
-
icon: ArrowRightLeft,
|
|
262
|
-
children: [
|
|
263
|
-
{
|
|
264
|
-
label: 'Active Projects',
|
|
265
|
-
onClick: () => console.log('Moved to Active Projects'),
|
|
266
|
-
},
|
|
267
|
-
{ label: 'Monitoring', onClick: () => console.log('Moved to Monitoring') },
|
|
268
|
-
{ label: 'Archive', onClick: () => console.log('Moved to Archive') },
|
|
269
|
-
],
|
|
270
|
-
},
|
|
271
|
-
{
|
|
272
|
-
label: 'Clear',
|
|
273
|
-
icon: Trash2,
|
|
274
|
-
onClick: () => console.log('History Cleared!'),
|
|
275
|
-
variant: 'destructive',
|
|
276
|
-
},
|
|
277
|
-
],
|
|
278
|
-
},
|
|
279
|
-
],
|
|
280
|
-
},
|
|
281
|
-
{
|
|
282
|
-
id: 'projects',
|
|
283
|
-
label: 'Project Monitoring',
|
|
284
|
-
icon: Map,
|
|
285
|
-
actions: [
|
|
286
|
-
{
|
|
287
|
-
label: 'New Category',
|
|
288
|
-
icon: Plus,
|
|
289
|
-
onClick: () => console.log('Create new category...'),
|
|
290
|
-
},
|
|
291
|
-
{
|
|
292
|
-
label: 'Archive Group',
|
|
293
|
-
icon: Archive,
|
|
294
|
-
onClick: () => console.log('Archiving group...'),
|
|
295
|
-
},
|
|
296
|
-
],
|
|
297
|
-
items: [
|
|
298
|
-
{
|
|
299
|
-
path: '/assistant/br163',
|
|
300
|
-
label: 'Panel Status',
|
|
301
|
-
icon: () => <div className="w-2 h-2 rounded-full bg-yellow-500" />,
|
|
302
|
-
description: (
|
|
303
|
-
<div className="space-y-1.5 min-w-[160px]">
|
|
304
|
-
<Progress value={67} className="h-1.5 bg-sidebar-foreground/10" />
|
|
305
|
-
<div className="flex justify-between items-center text-[10px] text-sidebar-foreground/60">
|
|
306
|
-
<span>Label</span>
|
|
307
|
-
<span>67%</span>
|
|
308
|
-
</div>
|
|
309
|
-
</div>
|
|
310
|
-
),
|
|
311
|
-
},
|
|
312
|
-
],
|
|
313
|
-
},
|
|
314
|
-
],
|
|
315
|
-
},
|
|
316
|
-
render: args => {
|
|
317
|
-
const [isExpanded, setIsExpanded] = useState(args.expanded);
|
|
318
|
-
const currentWidth = isExpanded ? 280 : 80;
|
|
319
|
-
|
|
320
|
-
return (
|
|
321
|
-
<div
|
|
322
|
-
className="relative h-screen w-full border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
323
|
-
style={{ transform: 'translateZ(0)' }}
|
|
324
|
-
>
|
|
325
|
-
<Sidebar
|
|
326
|
-
{...args}
|
|
327
|
-
expanded={isExpanded}
|
|
328
|
-
onToggle={() => setIsExpanded(!isExpanded)}
|
|
329
|
-
width={currentWidth}
|
|
330
|
-
navigate={() => {}}
|
|
331
|
-
/>
|
|
332
|
-
<div
|
|
333
|
-
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
334
|
-
style={{ left: `${currentWidth}px` }}
|
|
335
|
-
>
|
|
336
|
-
<div className="text-center">
|
|
337
|
-
<p className="text-muted-foreground">Assistant Mode Content</p>
|
|
338
|
-
<p className="text-xs text-muted-foreground mt-2">Click on the menu icon to expand</p>
|
|
339
|
-
</div>
|
|
340
|
-
</div>
|
|
341
|
-
</div>
|
|
342
|
-
);
|
|
343
|
-
},
|
|
344
|
-
};
|
|
345
|
-
|
|
346
|
-
export const Collapsed: Story = {
|
|
347
|
-
args: {
|
|
348
|
-
...Default.args,
|
|
349
|
-
expanded: false,
|
|
350
|
-
},
|
|
351
|
-
render: args => {
|
|
352
|
-
const [isExpanded, setIsExpanded] = useState(args.expanded);
|
|
353
|
-
const currentWidth = isExpanded ? 280 : 80;
|
|
354
|
-
|
|
355
|
-
return (
|
|
356
|
-
<div
|
|
357
|
-
className="relative h-screen w-full border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
358
|
-
style={{ transform: 'translateZ(0)' }}
|
|
359
|
-
>
|
|
360
|
-
<Sidebar
|
|
361
|
-
{...args}
|
|
362
|
-
expanded={isExpanded}
|
|
363
|
-
onToggle={() => setIsExpanded(!isExpanded)}
|
|
364
|
-
width={currentWidth}
|
|
365
|
-
navigate={() => {}}
|
|
366
|
-
/>
|
|
367
|
-
<div
|
|
368
|
-
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
369
|
-
style={{ left: `${currentWidth}px` }}
|
|
370
|
-
>
|
|
371
|
-
<div className="text-center">
|
|
372
|
-
<p className="text-muted-foreground">Compact Navigation</p>
|
|
373
|
-
<p className="text-xs text-muted-foreground mt-2">Click on the menu icon to expand</p>
|
|
374
|
-
</div>
|
|
375
|
-
</div>
|
|
376
|
-
</div>
|
|
377
|
-
);
|
|
378
|
-
},
|
|
379
|
-
};
|
|
380
|
-
export const NoFooter: Story = {
|
|
381
|
-
args: {
|
|
382
|
-
...Default.args,
|
|
383
|
-
showFooter: false,
|
|
384
|
-
},
|
|
385
|
-
render: args => {
|
|
386
|
-
const [isExpanded, setIsExpanded] = useState(args.expanded);
|
|
387
|
-
const currentWidth = isExpanded ? 280 : 80;
|
|
388
|
-
|
|
389
|
-
return (
|
|
390
|
-
<div
|
|
391
|
-
className="relative h-screen w-full border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
392
|
-
style={{ transform: 'translateZ(0)' }}
|
|
393
|
-
>
|
|
394
|
-
<Sidebar
|
|
395
|
-
{...args}
|
|
396
|
-
expanded={isExpanded}
|
|
397
|
-
onToggle={() => setIsExpanded(!isExpanded)}
|
|
398
|
-
width={currentWidth}
|
|
399
|
-
navigate={() => {}}
|
|
400
|
-
/>
|
|
401
|
-
<div
|
|
402
|
-
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
403
|
-
style={{ left: `${currentWidth}px` }}
|
|
404
|
-
>
|
|
405
|
-
<div className="text-center">
|
|
406
|
-
<p className="text-muted-foreground">Sidebar without Footer</p>
|
|
407
|
-
<p className="text-xs text-muted-foreground mt-2">Click on the menu icon to expand</p>
|
|
408
|
-
</div>
|
|
409
|
-
</div>
|
|
410
|
-
</div>
|
|
411
|
-
);
|
|
412
|
-
},
|
|
413
|
-
};
|
|
414
|
-
|
|
415
|
-
export const Autonomous: Story = {
|
|
416
|
-
args: {
|
|
417
|
-
...Default.args,
|
|
418
|
-
expanded: undefined,
|
|
419
|
-
onToggle: undefined,
|
|
420
|
-
},
|
|
421
|
-
render: args => {
|
|
422
|
-
return (
|
|
423
|
-
<div
|
|
424
|
-
className="relative h-screen w-full border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
425
|
-
style={{ transform: 'translateZ(0)' }}
|
|
426
|
-
>
|
|
427
|
-
<Sidebar {...args} />
|
|
428
|
-
<div
|
|
429
|
-
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
430
|
-
style={{ left: `80px` }}
|
|
431
|
-
>
|
|
432
|
-
<div className="text-center max-w-md">
|
|
433
|
-
<p className="text-muted-foreground font-bold">Autonomous Sidebar</p>
|
|
434
|
-
<p className="text-sm text-muted-foreground/80 mt-2">
|
|
435
|
-
This instance is managing its own state internally. No `expanded` or `onToggle` props
|
|
436
|
-
are passed.
|
|
437
|
-
</p>
|
|
438
|
-
<p className="text-xs text-muted-foreground mt-4">
|
|
439
|
-
Note: Layout coordination (content padding) must be handled manually when using
|
|
440
|
-
autonomous mode without LayoutProvider.
|
|
441
|
-
</p>
|
|
442
|
-
</div>
|
|
443
|
-
</div>
|
|
444
|
-
</div>
|
|
445
|
-
);
|
|
446
|
-
},
|
|
447
|
-
};
|
|
448
|
-
|
|
449
|
-
/**
|
|
450
|
-
* Desktop view with sub-items expanded.
|
|
451
|
-
* Items with `children` show a ChevronRight button; clicking it opens a
|
|
452
|
-
* dropdown listing the child routes positioned to the right of the sidebar.
|
|
453
|
-
*/
|
|
454
|
-
export const WithSubitemsDesktop: Story = {
|
|
455
|
-
name: 'With Sub-items (Desktop)',
|
|
456
|
-
args: {
|
|
457
|
-
variant: 'default',
|
|
458
|
-
expanded: true,
|
|
459
|
-
user: { name: 'Admin', email: 'admin@example.com' },
|
|
460
|
-
onLogout: () => console.log('Logged out'),
|
|
461
|
-
location: { pathname: '/dashboard' },
|
|
462
|
-
navigationGroups: [
|
|
463
|
-
{
|
|
464
|
-
id: 'main',
|
|
465
|
-
label: 'Principal',
|
|
466
|
-
items: [
|
|
467
|
-
{ path: '/home', label: 'Início', icon: Home },
|
|
468
|
-
{
|
|
469
|
-
path: '/dashboard',
|
|
470
|
-
label: 'Dashboard',
|
|
471
|
-
icon: BarChart,
|
|
472
|
-
children: [
|
|
473
|
-
{ path: '/dashboard/overview', label: 'Visão Geral', icon: BarChart },
|
|
474
|
-
{ path: '/dashboard/reports', label: 'Relatórios', icon: FileEdit },
|
|
475
|
-
{ path: '/dashboard/analytics', label: 'Analytics', icon: Map },
|
|
476
|
-
{ path: '/dashboard/trends', label: 'Tendências', icon: TrendingUp },
|
|
477
|
-
{ path: '/dashboard/kpis', label: 'KPIs', icon: Activity },
|
|
478
|
-
{ path: '/dashboard/charts', label: 'Gráficos', icon: PieChart },
|
|
479
|
-
{ path: '/dashboard/comparison', label: 'Comparativos', icon: BarChart2 },
|
|
480
|
-
],
|
|
481
|
-
},
|
|
482
|
-
{
|
|
483
|
-
path: '/reports',
|
|
484
|
-
label: 'Relatórios',
|
|
485
|
-
icon: FileText,
|
|
486
|
-
children: [
|
|
487
|
-
{ path: '/reports/sales', label: 'Vendas', icon: ShoppingCart },
|
|
488
|
-
{ path: '/reports/financial', label: 'Financeiro', icon: CreditCard },
|
|
489
|
-
{ path: '/reports/operational', label: 'Operacional', icon: Layers },
|
|
490
|
-
{ path: '/reports/exports', label: 'Exportações', icon: FileEdit },
|
|
491
|
-
],
|
|
492
|
-
},
|
|
493
|
-
{
|
|
494
|
-
path: '/catalog',
|
|
495
|
-
label: 'Catálogo',
|
|
496
|
-
icon: Package,
|
|
497
|
-
children: [
|
|
498
|
-
{ path: '/catalog/products', label: 'Produtos', icon: Package },
|
|
499
|
-
{ path: '/catalog/categories', label: 'Categorias', icon: Tag },
|
|
500
|
-
{ path: '/catalog/inventory', label: 'Estoque', icon: Database },
|
|
501
|
-
],
|
|
502
|
-
},
|
|
503
|
-
],
|
|
504
|
-
},
|
|
505
|
-
{
|
|
506
|
-
id: 'commerce',
|
|
507
|
-
label: 'Comercial',
|
|
508
|
-
items: [
|
|
509
|
-
{
|
|
510
|
-
path: '/orders',
|
|
511
|
-
label: 'Pedidos',
|
|
512
|
-
icon: ShoppingCart,
|
|
513
|
-
children: [
|
|
514
|
-
{ path: '/orders/pending', label: 'Pendentes', icon: Clock },
|
|
515
|
-
{ path: '/orders/processing', label: 'Em Andamento', icon: Zap },
|
|
516
|
-
{ path: '/orders/shipped', label: 'Enviados', icon: Truck },
|
|
517
|
-
{ path: '/orders/delivered', label: 'Entregues', icon: Package },
|
|
518
|
-
{ path: '/orders/cancelled', label: 'Cancelados', icon: Trash2 },
|
|
519
|
-
],
|
|
520
|
-
},
|
|
521
|
-
{
|
|
522
|
-
path: '/logistics',
|
|
523
|
-
label: 'Logística',
|
|
524
|
-
icon: Truck,
|
|
525
|
-
children: [
|
|
526
|
-
{ path: '/logistics/carriers', label: 'Transportadoras', icon: Truck },
|
|
527
|
-
{ path: '/logistics/tracking', label: 'Rastreamento', icon: Map },
|
|
528
|
-
{ path: '/logistics/warehouses', label: 'Armazéns', icon: Archive },
|
|
529
|
-
],
|
|
530
|
-
},
|
|
531
|
-
{
|
|
532
|
-
path: '/billing',
|
|
533
|
-
label: 'Faturamento',
|
|
534
|
-
icon: CreditCard,
|
|
535
|
-
children: [
|
|
536
|
-
{ path: '/billing/invoices', label: 'Faturas', icon: FileText },
|
|
537
|
-
{ path: '/billing/payments', label: 'Pagamentos', icon: CreditCard },
|
|
538
|
-
{ path: '/billing/refunds', label: 'Estornos', icon: ArrowRightLeft },
|
|
539
|
-
],
|
|
540
|
-
},
|
|
541
|
-
],
|
|
542
|
-
},
|
|
543
|
-
{
|
|
544
|
-
id: 'communication',
|
|
545
|
-
label: 'Comunicação',
|
|
546
|
-
items: [
|
|
547
|
-
{
|
|
548
|
-
path: '/notifications',
|
|
549
|
-
label: 'Notificações',
|
|
550
|
-
icon: Bell,
|
|
551
|
-
children: [
|
|
552
|
-
{ path: '/notifications/email', label: 'E-mail', icon: Mail },
|
|
553
|
-
{ path: '/notifications/sms', label: 'SMS', icon: Phone },
|
|
554
|
-
{ path: '/notifications/push', label: 'Push', icon: Bell },
|
|
555
|
-
],
|
|
556
|
-
},
|
|
557
|
-
{
|
|
558
|
-
path: '/messages',
|
|
559
|
-
label: 'Mensagens',
|
|
560
|
-
icon: MessageSquare,
|
|
561
|
-
children: [
|
|
562
|
-
{ path: '/messages/inbox', label: 'Caixa de Entrada', icon: Mail },
|
|
563
|
-
{ path: '/messages/sent', label: 'Enviadas', icon: MessageSquare },
|
|
564
|
-
{ path: '/messages/templates', label: 'Templates', icon: FileText },
|
|
565
|
-
],
|
|
566
|
-
},
|
|
567
|
-
{ path: '/integrations', label: 'Integrações', icon: Globe },
|
|
568
|
-
],
|
|
569
|
-
},
|
|
570
|
-
{
|
|
571
|
-
id: 'admin',
|
|
572
|
-
label: 'Administração',
|
|
573
|
-
items: [
|
|
574
|
-
{
|
|
575
|
-
path: '/users',
|
|
576
|
-
label: 'Usuários',
|
|
577
|
-
icon: Users,
|
|
578
|
-
children: [
|
|
579
|
-
{ path: '/users/list', label: 'Lista de Usuários', icon: Users },
|
|
580
|
-
{ path: '/users/roles', label: 'Perfis de Acesso', icon: Shield },
|
|
581
|
-
{ path: '/users/permissions', label: 'Permissões', icon: Key },
|
|
582
|
-
{ path: '/users/audit', label: 'Auditoria', icon: Activity },
|
|
583
|
-
],
|
|
584
|
-
},
|
|
585
|
-
{
|
|
586
|
-
path: '/infrastructure',
|
|
587
|
-
label: 'Infraestrutura',
|
|
588
|
-
icon: Server,
|
|
589
|
-
children: [
|
|
590
|
-
{ path: '/infrastructure/servers', label: 'Servidores', icon: Server },
|
|
591
|
-
{ path: '/infrastructure/databases', label: 'Bancos de Dados', icon: Database },
|
|
592
|
-
{ path: '/infrastructure/backups', label: 'Backups', icon: Archive },
|
|
593
|
-
],
|
|
594
|
-
},
|
|
595
|
-
{
|
|
596
|
-
path: '/files',
|
|
597
|
-
label: 'Arquivos',
|
|
598
|
-
icon: Folder,
|
|
599
|
-
children: [
|
|
600
|
-
{ path: '/files/documents', label: 'Documentos', icon: FileText },
|
|
601
|
-
{ path: '/files/media', label: 'Mídia', icon: Layers },
|
|
602
|
-
{ path: '/files/exports', label: 'Exportações', icon: FileEdit },
|
|
603
|
-
],
|
|
604
|
-
},
|
|
605
|
-
{ path: '/settings', label: 'Configurações', icon: Settings },
|
|
606
|
-
],
|
|
607
|
-
},
|
|
608
|
-
],
|
|
609
|
-
footer: {
|
|
610
|
-
showUser: true,
|
|
611
|
-
showSettings: false,
|
|
612
|
-
showLogout: true,
|
|
613
|
-
},
|
|
614
|
-
},
|
|
615
|
-
render: args => {
|
|
616
|
-
const [isExpanded, setIsExpanded] = useState(true);
|
|
617
|
-
const currentWidth = isExpanded ? 280 : 80;
|
|
618
|
-
|
|
619
|
-
return (
|
|
620
|
-
<div
|
|
621
|
-
className="relative h-screen w-full border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
622
|
-
style={{ transform: 'translateZ(0)' }}
|
|
623
|
-
>
|
|
624
|
-
<Sidebar
|
|
625
|
-
{...args}
|
|
626
|
-
expanded={isExpanded}
|
|
627
|
-
onToggle={() => setIsExpanded(!isExpanded)}
|
|
628
|
-
width={currentWidth}
|
|
629
|
-
navigate={() => {}}
|
|
630
|
-
/>
|
|
631
|
-
<div
|
|
632
|
-
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
633
|
-
style={{ left: `${currentWidth}px` }}
|
|
634
|
-
>
|
|
635
|
-
<div className="text-center max-w-sm space-y-2">
|
|
636
|
-
<p className="text-muted-foreground font-medium">Desktop — Subitens</p>
|
|
637
|
-
<p className="text-xs text-muted-foreground">
|
|
638
|
-
Itens com subitens exibem um botão{' '}
|
|
639
|
-
<code className="bg-muted px-1 rounded text-xs">ChevronRight</code> ao final da
|
|
640
|
-
linha. Clique nele para abrir o dropdown de rotas filhas.
|
|
641
|
-
</p>
|
|
642
|
-
<p className="text-xs text-muted-foreground mt-2">
|
|
643
|
-
Use o botão de toggle para alternar entre expandido e recolhido.
|
|
644
|
-
</p>
|
|
645
|
-
</div>
|
|
646
|
-
</div>
|
|
647
|
-
</div>
|
|
648
|
-
);
|
|
649
|
-
},
|
|
650
|
-
};
|
|
651
|
-
|
|
652
|
-
/**
|
|
653
|
-
* Mobile view with sub-items.
|
|
654
|
-
* Simulates a narrow viewport (375 px) so the sidebar renders in its
|
|
655
|
-
* full-screen overlay mode. When expanded the sidebar covers the entire
|
|
656
|
-
* container; clicking a nav item (or the back-arrow toggle) closes it.
|
|
657
|
-
*
|
|
658
|
-
* Sub-item dropdowns behave identically to desktop — the ChevronRight
|
|
659
|
-
* button opens a `DropdownMenuContent` positioned to the right.
|
|
660
|
-
* This story exists so the mobile layout can be inspected and adjusted.
|
|
661
|
-
*/
|
|
662
|
-
export const WithSubitemsMobile: Story = {
|
|
663
|
-
name: 'With Sub-items (Mobile)',
|
|
664
|
-
parameters: {
|
|
665
|
-
viewport: { defaultViewport: 'mobile1' },
|
|
666
|
-
},
|
|
667
|
-
args: {
|
|
668
|
-
variant: 'default',
|
|
669
|
-
expanded: false,
|
|
670
|
-
user: { name: 'Admin', email: 'admin@example.com' },
|
|
671
|
-
onLogout: () => console.log('Logged out'),
|
|
672
|
-
location: { pathname: '/dashboard' },
|
|
673
|
-
navigationGroups: [
|
|
674
|
-
{
|
|
675
|
-
id: 'main',
|
|
676
|
-
label: 'Principal',
|
|
677
|
-
items: [
|
|
678
|
-
{ path: '/home', label: 'Início', icon: Home },
|
|
679
|
-
{
|
|
680
|
-
path: '/dashboard',
|
|
681
|
-
label: 'Dashboard',
|
|
682
|
-
icon: BarChart,
|
|
683
|
-
children: [
|
|
684
|
-
{ path: '/dashboard/overview', label: 'Visão Geral', icon: BarChart },
|
|
685
|
-
{ path: '/dashboard/reports', label: 'Relatórios', icon: FileEdit },
|
|
686
|
-
{ path: '/dashboard/analytics', label: 'Analytics', icon: Map },
|
|
687
|
-
{ path: '/dashboard/trends', label: 'Tendências', icon: TrendingUp },
|
|
688
|
-
{ path: '/dashboard/kpis', label: 'KPIs', icon: Activity },
|
|
689
|
-
{ path: '/dashboard/charts', label: 'Gráficos', icon: PieChart },
|
|
690
|
-
{ path: '/dashboard/comparison', label: 'Comparativos', icon: BarChart2 },
|
|
691
|
-
],
|
|
692
|
-
},
|
|
693
|
-
{
|
|
694
|
-
path: '/reports',
|
|
695
|
-
label: 'Relatórios',
|
|
696
|
-
icon: FileText,
|
|
697
|
-
children: [
|
|
698
|
-
{ path: '/reports/sales', label: 'Vendas', icon: ShoppingCart },
|
|
699
|
-
{ path: '/reports/financial', label: 'Financeiro', icon: CreditCard },
|
|
700
|
-
{ path: '/reports/operational', label: 'Operacional', icon: Layers },
|
|
701
|
-
{ path: '/reports/exports', label: 'Exportações', icon: FileEdit },
|
|
702
|
-
],
|
|
703
|
-
},
|
|
704
|
-
{
|
|
705
|
-
path: '/catalog',
|
|
706
|
-
label: 'Catálogo',
|
|
707
|
-
icon: Package,
|
|
708
|
-
children: [
|
|
709
|
-
{ path: '/catalog/products', label: 'Produtos', icon: Package },
|
|
710
|
-
{ path: '/catalog/categories', label: 'Categorias', icon: Tag },
|
|
711
|
-
{ path: '/catalog/inventory', label: 'Estoque', icon: Database },
|
|
712
|
-
],
|
|
713
|
-
},
|
|
714
|
-
],
|
|
715
|
-
},
|
|
716
|
-
{
|
|
717
|
-
id: 'commerce',
|
|
718
|
-
label: 'Comercial',
|
|
719
|
-
items: [
|
|
720
|
-
{
|
|
721
|
-
path: '/orders',
|
|
722
|
-
label: 'Pedidos',
|
|
723
|
-
icon: ShoppingCart,
|
|
724
|
-
children: [
|
|
725
|
-
{ path: '/orders/pending', label: 'Pendentes', icon: Clock },
|
|
726
|
-
{ path: '/orders/processing', label: 'Em Andamento', icon: Zap },
|
|
727
|
-
{ path: '/orders/shipped', label: 'Enviados', icon: Truck },
|
|
728
|
-
{ path: '/orders/delivered', label: 'Entregues', icon: Package },
|
|
729
|
-
{ path: '/orders/cancelled', label: 'Cancelados', icon: Trash2 },
|
|
730
|
-
],
|
|
731
|
-
},
|
|
732
|
-
{
|
|
733
|
-
path: '/logistics',
|
|
734
|
-
label: 'Logística',
|
|
735
|
-
icon: Truck,
|
|
736
|
-
children: [
|
|
737
|
-
{ path: '/logistics/carriers', label: 'Transportadoras', icon: Truck },
|
|
738
|
-
{ path: '/logistics/tracking', label: 'Rastreamento', icon: Map },
|
|
739
|
-
{ path: '/logistics/warehouses', label: 'Armazéns', icon: Archive },
|
|
740
|
-
],
|
|
741
|
-
},
|
|
742
|
-
{
|
|
743
|
-
path: '/billing',
|
|
744
|
-
label: 'Faturamento',
|
|
745
|
-
icon: CreditCard,
|
|
746
|
-
children: [
|
|
747
|
-
{ path: '/billing/invoices', label: 'Faturas', icon: FileText },
|
|
748
|
-
{ path: '/billing/payments', label: 'Pagamentos', icon: CreditCard },
|
|
749
|
-
{ path: '/billing/refunds', label: 'Estornos', icon: ArrowRightLeft },
|
|
750
|
-
],
|
|
751
|
-
},
|
|
752
|
-
],
|
|
753
|
-
},
|
|
754
|
-
{
|
|
755
|
-
id: 'communication',
|
|
756
|
-
label: 'Comunicação',
|
|
757
|
-
items: [
|
|
758
|
-
{
|
|
759
|
-
path: '/notifications',
|
|
760
|
-
label: 'Notificações',
|
|
761
|
-
icon: Bell,
|
|
762
|
-
children: [
|
|
763
|
-
{ path: '/notifications/email', label: 'E-mail', icon: Mail },
|
|
764
|
-
{ path: '/notifications/sms', label: 'SMS', icon: Phone },
|
|
765
|
-
{ path: '/notifications/push', label: 'Push', icon: Bell },
|
|
766
|
-
],
|
|
767
|
-
},
|
|
768
|
-
{
|
|
769
|
-
path: '/messages',
|
|
770
|
-
label: 'Mensagens',
|
|
771
|
-
icon: MessageSquare,
|
|
772
|
-
children: [
|
|
773
|
-
{ path: '/messages/inbox', label: 'Caixa de Entrada', icon: Mail },
|
|
774
|
-
{ path: '/messages/sent', label: 'Enviadas', icon: MessageSquare },
|
|
775
|
-
{ path: '/messages/templates', label: 'Templates', icon: FileText },
|
|
776
|
-
],
|
|
777
|
-
},
|
|
778
|
-
{ path: '/integrations', label: 'Integrações', icon: Globe },
|
|
779
|
-
],
|
|
780
|
-
},
|
|
781
|
-
{
|
|
782
|
-
id: 'admin',
|
|
783
|
-
label: 'Administração',
|
|
784
|
-
items: [
|
|
785
|
-
{
|
|
786
|
-
path: '/users',
|
|
787
|
-
label: 'Usuários',
|
|
788
|
-
icon: Users,
|
|
789
|
-
children: [
|
|
790
|
-
{ path: '/users/list', label: 'Lista de Usuários', icon: Users },
|
|
791
|
-
{ path: '/users/roles', label: 'Perfis de Acesso', icon: Shield },
|
|
792
|
-
{ path: '/users/permissions', label: 'Permissões', icon: Key },
|
|
793
|
-
{ path: '/users/audit', label: 'Auditoria', icon: Activity },
|
|
794
|
-
],
|
|
795
|
-
},
|
|
796
|
-
{
|
|
797
|
-
path: '/infrastructure',
|
|
798
|
-
label: 'Infraestrutura',
|
|
799
|
-
icon: Server,
|
|
800
|
-
children: [
|
|
801
|
-
{ path: '/infrastructure/servers', label: 'Servidores', icon: Server },
|
|
802
|
-
{ path: '/infrastructure/databases', label: 'Bancos de Dados', icon: Database },
|
|
803
|
-
{ path: '/infrastructure/backups', label: 'Backups', icon: Archive },
|
|
804
|
-
],
|
|
805
|
-
},
|
|
806
|
-
{
|
|
807
|
-
path: '/files',
|
|
808
|
-
label: 'Arquivos',
|
|
809
|
-
icon: Folder,
|
|
810
|
-
children: [
|
|
811
|
-
{ path: '/files/documents', label: 'Documentos', icon: FileText },
|
|
812
|
-
{ path: '/files/media', label: 'Mídia', icon: Layers },
|
|
813
|
-
{ path: '/files/exports', label: 'Exportações', icon: FileEdit },
|
|
814
|
-
],
|
|
815
|
-
},
|
|
816
|
-
{ path: '/settings', label: 'Configurações', icon: Settings },
|
|
817
|
-
],
|
|
818
|
-
},
|
|
819
|
-
],
|
|
820
|
-
footer: {
|
|
821
|
-
showUser: true,
|
|
822
|
-
showSettings: false,
|
|
823
|
-
showLogout: true,
|
|
824
|
-
},
|
|
825
|
-
},
|
|
826
|
-
render: args => {
|
|
827
|
-
const [isExpanded, setIsExpanded] = useState(false);
|
|
828
|
-
|
|
829
|
-
return (
|
|
830
|
-
/* Constrain to ~375 px to reproduce a mobile viewport inside Storybook */
|
|
831
|
-
<div
|
|
832
|
-
className="relative bg-muted/20 overflow-hidden border rounded-[var(--radius-lg)]"
|
|
833
|
-
style={{ width: '375px', height: '100vh', margin: '0 auto' }}
|
|
834
|
-
>
|
|
835
|
-
{/* Page content visible when sidebar is closed */}
|
|
836
|
-
{!isExpanded && (
|
|
837
|
-
<div className="h-full flex flex-col">
|
|
838
|
-
<div className="flex items-center gap-3 px-4 py-3 border-b border-border bg-background">
|
|
839
|
-
<button
|
|
840
|
-
onClick={() => setIsExpanded(true)}
|
|
841
|
-
className="p-2 rounded-md hover:bg-accent transition-colors"
|
|
842
|
-
aria-label="Abrir menu"
|
|
843
|
-
>
|
|
844
|
-
<Menu className="w-5 h-5" />
|
|
845
|
-
</button>
|
|
846
|
-
<span className="font-semibold text-sm">Minha Aplicação</span>
|
|
847
|
-
</div>
|
|
848
|
-
<div className="flex-1 flex items-center justify-center p-8">
|
|
849
|
-
<div className="text-center space-y-2">
|
|
850
|
-
<p className="text-muted-foreground font-medium">Mobile — Subitens</p>
|
|
851
|
-
<p className="text-xs text-muted-foreground">
|
|
852
|
-
Clique no ícone de menu (☰) no topo para abrir a sidebar em modo
|
|
853
|
-
tela-cheia. Itens com subitens mostram um{' '}
|
|
854
|
-
<code className="bg-muted px-1 rounded text-xs">ChevronRight</code> ao final
|
|
855
|
-
da linha.
|
|
856
|
-
</p>
|
|
857
|
-
</div>
|
|
858
|
-
</div>
|
|
859
|
-
</div>
|
|
860
|
-
)}
|
|
861
|
-
|
|
862
|
-
<Sidebar
|
|
863
|
-
{...args}
|
|
864
|
-
expanded={isExpanded}
|
|
865
|
-
onToggle={() => setIsExpanded(prev => !prev)}
|
|
866
|
-
width={375}
|
|
867
|
-
navigate={() => setIsExpanded(false)}
|
|
868
|
-
/>
|
|
869
|
-
</div>
|
|
870
|
-
);
|
|
871
|
-
},
|
|
872
|
-
};
|
|
873
|
-
|
|
874
|
-
/**
|
|
875
|
-
* Compound Component API — demonstrates using Sidebar.Root + sub-components
|
|
876
|
-
* for full layout control. This is the recommended pattern for advanced
|
|
877
|
-
* customization without forking the component.
|
|
878
|
-
*/
|
|
879
|
-
export const CompoundComponentAPI: Story = {
|
|
880
|
-
name: 'Compound Component API',
|
|
881
|
-
render: () => {
|
|
882
|
-
const [isExpanded, setIsExpanded] = React.useState(true);
|
|
883
|
-
const currentWidth = isExpanded ? 280 : 80;
|
|
884
|
-
const groups = [
|
|
885
|
-
{
|
|
886
|
-
id: 'main',
|
|
887
|
-
label: 'Principal',
|
|
888
|
-
items: [
|
|
889
|
-
{ path: '/home', label: 'Início', icon: Home },
|
|
890
|
-
{ path: '/dashboard', label: 'Dashboard', icon: BarChart },
|
|
891
|
-
],
|
|
892
|
-
},
|
|
893
|
-
{
|
|
894
|
-
id: 'admin',
|
|
895
|
-
label: 'Administração',
|
|
896
|
-
items: [
|
|
897
|
-
{ path: '/users', label: 'Usuários', icon: Users },
|
|
898
|
-
{ path: '/settings', label: 'Configurações', icon: Settings },
|
|
899
|
-
],
|
|
900
|
-
},
|
|
901
|
-
];
|
|
902
|
-
|
|
903
|
-
return (
|
|
904
|
-
<div
|
|
905
|
-
className="relative h-screen w-full border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
906
|
-
style={{ transform: 'translateZ(0)' }}
|
|
907
|
-
>
|
|
908
|
-
{/* Compound Component usage */}
|
|
909
|
-
<Sidebar.Root
|
|
910
|
-
expanded={isExpanded}
|
|
911
|
-
onToggle={() => setIsExpanded(prev => !prev)}
|
|
912
|
-
width={currentWidth}
|
|
913
|
-
location={{ pathname: '/home' }}
|
|
914
|
-
navigate={() => {}}
|
|
915
|
-
>
|
|
916
|
-
<Sidebar.Header />
|
|
917
|
-
<Sidebar.Nav navigationGroups={groups} />
|
|
918
|
-
<Sidebar.Footer
|
|
919
|
-
user={{ name: 'Admin', email: 'admin@example.com' }}
|
|
920
|
-
onLogout={() => console.log('logout')}
|
|
921
|
-
showUser
|
|
922
|
-
showSettings
|
|
923
|
-
showLogout
|
|
924
|
-
/>
|
|
925
|
-
</Sidebar.Root>
|
|
926
|
-
|
|
927
|
-
<div
|
|
928
|
-
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
929
|
-
style={{ left: `${currentWidth}px` }}
|
|
930
|
-
>
|
|
931
|
-
<div className="text-center max-w-md space-y-3">
|
|
932
|
-
<p className="text-muted-foreground font-bold">Compound Component API</p>
|
|
933
|
-
<p className="text-sm text-muted-foreground/80">
|
|
934
|
-
Built with <code className="bg-muted px-1 rounded text-xs"><Sidebar.Root></code>
|
|
935
|
-
, <code className="bg-muted px-1 rounded text-xs"><Sidebar.Header></code>,{' '}
|
|
936
|
-
<code className="bg-muted px-1 rounded text-xs"><Sidebar.Nav></code>, and{' '}
|
|
937
|
-
<code className="bg-muted px-1 rounded text-xs"><Sidebar.Footer></code>.
|
|
938
|
-
</p>
|
|
939
|
-
<p className="text-xs text-muted-foreground">
|
|
940
|
-
Each sub-component reads shared state from{' '}
|
|
941
|
-
<code className="bg-muted px-1 rounded text-xs">SidebarContext</code> via{' '}
|
|
942
|
-
<code className="bg-muted px-1 rounded text-xs">Sidebar.Root</code>.
|
|
943
|
-
</p>
|
|
944
|
-
</div>
|
|
945
|
-
</div>
|
|
946
|
-
</div>
|
|
947
|
-
);
|
|
948
|
-
},
|
|
949
|
-
};
|
|
950
|
-
|
|
951
|
-
/**
|
|
952
|
-
* Headless Hook — demonstrates using `useSidebar` directly for fully custom rendering.
|
|
953
|
-
* The hook manages all state; the UI is entirely up to the consumer.
|
|
954
|
-
*/
|
|
955
|
-
export const HeadlessHook: Story = {
|
|
956
|
-
name: 'Headless Hook (useSidebar)',
|
|
957
|
-
render: () => {
|
|
958
|
-
const groups = [
|
|
959
|
-
{
|
|
960
|
-
id: 'main',
|
|
961
|
-
label: 'Principal',
|
|
962
|
-
items: [
|
|
963
|
-
{ path: '/home', label: 'Início', icon: Home },
|
|
964
|
-
{ path: '/dashboard', label: 'Dashboard', icon: BarChart },
|
|
965
|
-
{ path: '/users', label: 'Usuários', icon: Users },
|
|
966
|
-
],
|
|
967
|
-
},
|
|
968
|
-
];
|
|
969
|
-
|
|
970
|
-
const {
|
|
971
|
-
expanded,
|
|
972
|
-
toggleExpanded,
|
|
973
|
-
navigationGroups: resolvedGroups,
|
|
974
|
-
} = useSidebar({ defaultExpanded: true, navigationGroups: groups });
|
|
975
|
-
|
|
976
|
-
const width = expanded ? 280 : 80;
|
|
977
|
-
|
|
978
|
-
return (
|
|
979
|
-
<div
|
|
980
|
-
className="relative h-screen w-full border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
981
|
-
style={{ transform: 'translateZ(0)' }}
|
|
982
|
-
>
|
|
983
|
-
{/* Fully custom sidebar built with useSidebar hook */}
|
|
984
|
-
<div
|
|
985
|
-
className="absolute inset-y-0 left-0 bg-sidebar text-sidebar-foreground flex flex-col transition-all duration-300 z-50"
|
|
986
|
-
style={{ width: `${width}px` }}
|
|
987
|
-
>
|
|
988
|
-
<div className="p-4">
|
|
989
|
-
<button
|
|
990
|
-
onClick={toggleExpanded}
|
|
991
|
-
className="w-full h-10 flex items-center justify-center rounded-md bg-sidebar-foreground/10 hover:bg-sidebar-foreground/20 text-sidebar-foreground transition-colors"
|
|
992
|
-
aria-label={expanded ? 'Collapse' : 'Expand'}
|
|
993
|
-
>
|
|
994
|
-
{expanded ? <PanelLeft className="w-5 h-5" /> : <Menu className="w-5 h-5" />}
|
|
995
|
-
</button>
|
|
996
|
-
</div>
|
|
997
|
-
<nav className="flex-1 px-3 space-y-1">
|
|
998
|
-
{resolvedGroups
|
|
999
|
-
.flatMap(g => g.items)
|
|
1000
|
-
.map(item => {
|
|
1001
|
-
const Icon = item.icon;
|
|
1002
|
-
return (
|
|
1003
|
-
<button
|
|
1004
|
-
key={item.path}
|
|
1005
|
-
className="w-full h-10 flex items-center gap-3 px-3 rounded-md text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground transition-colors"
|
|
1006
|
-
>
|
|
1007
|
-
{Icon && <Icon className="w-5 h-5 flex-shrink-0" />}
|
|
1008
|
-
{expanded && <span className="truncate text-sm">{item.label}</span>}
|
|
1009
|
-
</button>
|
|
1010
|
-
);
|
|
1011
|
-
})}
|
|
1012
|
-
</nav>
|
|
1013
|
-
</div>
|
|
1014
|
-
|
|
1015
|
-
<div
|
|
1016
|
-
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
1017
|
-
style={{ left: `${width}px` }}
|
|
1018
|
-
>
|
|
1019
|
-
<div className="text-center max-w-md space-y-3">
|
|
1020
|
-
<p className="text-muted-foreground font-bold">Headless Hook</p>
|
|
1021
|
-
<p className="text-sm text-muted-foreground/80">
|
|
1022
|
-
State managed by <code className="bg-muted px-1 rounded text-xs">useSidebar()</code>.
|
|
1023
|
-
The entire UI is custom — no Sidebar component used.
|
|
1024
|
-
</p>
|
|
1025
|
-
<p className="text-xs text-muted-foreground">
|
|
1026
|
-
Sidebar is currently: <strong>{expanded ? 'Expanded' : 'Collapsed'}</strong>
|
|
1027
|
-
</p>
|
|
1028
|
-
</div>
|
|
1029
|
-
</div>
|
|
1030
|
-
</div>
|
|
1031
|
-
);
|
|
1032
|
-
},
|
|
1033
|
-
};
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { Sidebar, useSidebar } from './sidebar';
|
|
3
|
+
import { useLayout } from '../../../contexts/LayoutContext';
|
|
4
|
+
import { BrowserRouter } from 'react-router-dom';
|
|
5
|
+
import {
|
|
6
|
+
Home,
|
|
7
|
+
Users,
|
|
8
|
+
Settings,
|
|
9
|
+
BarChart,
|
|
10
|
+
Plus,
|
|
11
|
+
Clock,
|
|
12
|
+
FileEdit,
|
|
13
|
+
ArrowRightLeft,
|
|
14
|
+
PanelLeft,
|
|
15
|
+
Menu,
|
|
16
|
+
Trash2,
|
|
17
|
+
Map,
|
|
18
|
+
Archive,
|
|
19
|
+
ShoppingCart,
|
|
20
|
+
Package,
|
|
21
|
+
Tag,
|
|
22
|
+
Truck,
|
|
23
|
+
CreditCard,
|
|
24
|
+
Bell,
|
|
25
|
+
Shield,
|
|
26
|
+
Key,
|
|
27
|
+
Database,
|
|
28
|
+
Server,
|
|
29
|
+
Activity,
|
|
30
|
+
TrendingUp,
|
|
31
|
+
PieChart,
|
|
32
|
+
BarChart2,
|
|
33
|
+
FileText,
|
|
34
|
+
Folder,
|
|
35
|
+
MessageSquare,
|
|
36
|
+
Mail,
|
|
37
|
+
Phone,
|
|
38
|
+
Globe,
|
|
39
|
+
Layers,
|
|
40
|
+
Zap,
|
|
41
|
+
} from 'lucide-react';
|
|
42
|
+
import React, { useState } from 'react';
|
|
43
|
+
import { Badge } from '../../ui/badge';
|
|
44
|
+
import { Button } from '../../ui/button';
|
|
45
|
+
import { Progress } from '../../ui/progress';
|
|
46
|
+
|
|
47
|
+
const meta: Meta<typeof Sidebar> = {
|
|
48
|
+
title: 'Layout/Sidebar',
|
|
49
|
+
component: Sidebar,
|
|
50
|
+
decorators: [
|
|
51
|
+
Story => (
|
|
52
|
+
<BrowserRouter>
|
|
53
|
+
<div className="flex h-screen w-full overflow-hidden bg-background">
|
|
54
|
+
<Story />
|
|
55
|
+
</div>
|
|
56
|
+
</BrowserRouter>
|
|
57
|
+
),
|
|
58
|
+
],
|
|
59
|
+
parameters: {
|
|
60
|
+
layout: 'fullscreen',
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export default meta;
|
|
65
|
+
type Story = StoryObj<typeof Sidebar>;
|
|
66
|
+
|
|
67
|
+
export const Default: Story = {
|
|
68
|
+
args: {
|
|
69
|
+
variant: 'default',
|
|
70
|
+
expanded: false,
|
|
71
|
+
user: { email: 'admin@example.com' },
|
|
72
|
+
onLogout: () => console.log('Logged out'),
|
|
73
|
+
location: { pathname: '/home' },
|
|
74
|
+
routes: [
|
|
75
|
+
{ path: '/home', label: 'Home', icon: Home },
|
|
76
|
+
{ path: '/dashboard', label: 'Dashboard', icon: Users },
|
|
77
|
+
{ path: '/settings', label: 'Settings', icon: Settings },
|
|
78
|
+
],
|
|
79
|
+
footer: {
|
|
80
|
+
showUser: true,
|
|
81
|
+
showSettings: true,
|
|
82
|
+
showLogout: true,
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
render: args => {
|
|
86
|
+
const { sidebarWidth: contextWidth } = useLayout();
|
|
87
|
+
const [isExpanded, setIsExpanded] = useState(args.expanded);
|
|
88
|
+
|
|
89
|
+
// In Storybook, we match the sidebar widths (280 expanded, 80 collapsed)
|
|
90
|
+
const currentWidth = isExpanded ? 280 : 80;
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<div
|
|
94
|
+
className="relative h-screen w-full border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
95
|
+
style={{ transform: 'translateZ(0)' }}
|
|
96
|
+
>
|
|
97
|
+
<Sidebar
|
|
98
|
+
{...args}
|
|
99
|
+
expanded={isExpanded}
|
|
100
|
+
onToggle={() => setIsExpanded(!isExpanded)}
|
|
101
|
+
width={currentWidth}
|
|
102
|
+
navigate={() => {}}
|
|
103
|
+
/>
|
|
104
|
+
<div
|
|
105
|
+
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
106
|
+
style={{ left: `${currentWidth}px` }}
|
|
107
|
+
>
|
|
108
|
+
<div className="text-center">
|
|
109
|
+
<p className="text-muted-foreground">Traditional System Navigation</p>
|
|
110
|
+
<p className="text-xs text-muted-foreground mt-2">Click on the menu icon to expand</p>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
);
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export const DefaultWithGroups: Story = {
|
|
119
|
+
args: {
|
|
120
|
+
variant: 'default',
|
|
121
|
+
expanded: false,
|
|
122
|
+
user: { name: 'Admin', email: 'admin@example.com' },
|
|
123
|
+
onLogout: () => console.log('Logged out'),
|
|
124
|
+
location: { pathname: '/home' },
|
|
125
|
+
navigationGroups: [
|
|
126
|
+
{
|
|
127
|
+
id: 'main',
|
|
128
|
+
label: 'Principal',
|
|
129
|
+
items: [
|
|
130
|
+
{ path: '/home', label: 'Início', icon: Home },
|
|
131
|
+
{
|
|
132
|
+
path: '/dashboard',
|
|
133
|
+
label: 'Dashboard',
|
|
134
|
+
icon: BarChart,
|
|
135
|
+
children: [
|
|
136
|
+
{ path: '/dashboard/overview', label: 'Visão Geral', icon: BarChart },
|
|
137
|
+
{ path: '/dashboard/reports', label: 'Relatórios', icon: FileEdit },
|
|
138
|
+
{ path: '/dashboard/analytics', label: 'Analytics', icon: Map },
|
|
139
|
+
],
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
id: 'admin',
|
|
145
|
+
label: 'Administração',
|
|
146
|
+
items: [
|
|
147
|
+
{
|
|
148
|
+
path: '/users',
|
|
149
|
+
label: 'Usuários',
|
|
150
|
+
icon: Users,
|
|
151
|
+
children: [
|
|
152
|
+
{ path: '/users/list', label: 'Lista de Usuários', icon: Users },
|
|
153
|
+
{ path: '/users/roles', label: 'Perfis de Acesso', icon: Settings },
|
|
154
|
+
],
|
|
155
|
+
},
|
|
156
|
+
{ path: '/settings', label: 'Configurações', icon: Settings },
|
|
157
|
+
],
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
footer: {
|
|
161
|
+
showUser: true,
|
|
162
|
+
showSettings: false,
|
|
163
|
+
showLogout: true,
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
render: args => {
|
|
167
|
+
const [isExpanded, setIsExpanded] = useState(args.expanded);
|
|
168
|
+
const currentWidth = isExpanded ? 280 : 80;
|
|
169
|
+
|
|
170
|
+
return (
|
|
171
|
+
<div
|
|
172
|
+
className="relative h-screen w-full border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
173
|
+
style={{ transform: 'translateZ(0)' }}
|
|
174
|
+
>
|
|
175
|
+
<Sidebar
|
|
176
|
+
{...args}
|
|
177
|
+
expanded={isExpanded}
|
|
178
|
+
onToggle={() => setIsExpanded(!isExpanded)}
|
|
179
|
+
width={currentWidth}
|
|
180
|
+
navigate={() => {}}
|
|
181
|
+
/>
|
|
182
|
+
<div
|
|
183
|
+
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
184
|
+
style={{ left: `${currentWidth}px` }}
|
|
185
|
+
>
|
|
186
|
+
<div className="text-center">
|
|
187
|
+
<p className="text-muted-foreground">Navigation with Groups and Children</p>
|
|
188
|
+
<p className="text-xs text-muted-foreground mt-2">
|
|
189
|
+
Expand and click the arrow button on items to see sub-menus
|
|
190
|
+
</p>
|
|
191
|
+
</div>
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
);
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
export const Assistant: Story = {
|
|
199
|
+
args: {
|
|
200
|
+
variant: 'assistant',
|
|
201
|
+
expanded: false,
|
|
202
|
+
user: { email: 'admin@example.com' },
|
|
203
|
+
onLogout: () => console.log('Logged out'),
|
|
204
|
+
location: { pathname: '/assistant/refatoracao' },
|
|
205
|
+
search: {
|
|
206
|
+
show: true,
|
|
207
|
+
placeholder: 'Buscar tópicos...',
|
|
208
|
+
filter: {
|
|
209
|
+
show: true,
|
|
210
|
+
content: (
|
|
211
|
+
<div className="p-2 space-y-2">
|
|
212
|
+
<div className="text-xs font-semibold uppercase text-muted-foreground px-2 text-left">
|
|
213
|
+
Filter by Status
|
|
214
|
+
</div>
|
|
215
|
+
<div className="flex flex-wrap gap-2 p-1">
|
|
216
|
+
<Badge className="bg-sidebar-foreground/20 text-sidebar-foreground border-none cursor-pointer hover:bg-sidebar-foreground/30">
|
|
217
|
+
Active
|
|
218
|
+
</Badge>
|
|
219
|
+
<Badge
|
|
220
|
+
variant="outline"
|
|
221
|
+
className="text-sidebar-foreground/70 border-sidebar-foreground/20 cursor-pointer hover:bg-sidebar-foreground/10"
|
|
222
|
+
>
|
|
223
|
+
Archived
|
|
224
|
+
</Badge>
|
|
225
|
+
<Badge
|
|
226
|
+
variant="outline"
|
|
227
|
+
className="text-sidebar-foreground/70 border-sidebar-foreground/20 cursor-pointer hover:bg-sidebar-foreground/10"
|
|
228
|
+
>
|
|
229
|
+
Pending
|
|
230
|
+
</Badge>
|
|
231
|
+
</div>
|
|
232
|
+
</div>
|
|
233
|
+
),
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
fixedArea: {
|
|
237
|
+
show: true,
|
|
238
|
+
icon: Plus,
|
|
239
|
+
onClick: () => console.log('New Conversation clicked'),
|
|
240
|
+
content: (
|
|
241
|
+
<Button className="w-full bg-sidebar-primary hover:bg-sidebar-primary/90 text-sidebar-primary-foreground shadow-lg font-bold border-none transition-all duration-300 transform hover:scale-[1.02] active:scale-[0.98]">
|
|
242
|
+
<Plus className="w-4 h-4 mr-2" />
|
|
243
|
+
New Conversation
|
|
244
|
+
</Button>
|
|
245
|
+
),
|
|
246
|
+
},
|
|
247
|
+
navigationGroups: [
|
|
248
|
+
{
|
|
249
|
+
id: 'recent',
|
|
250
|
+
label: 'Recent',
|
|
251
|
+
icon: Clock,
|
|
252
|
+
items: [
|
|
253
|
+
{
|
|
254
|
+
path: '/assistant/refatoracao',
|
|
255
|
+
label: 'Edit Sidebar',
|
|
256
|
+
description: 'Active now',
|
|
257
|
+
actions: [
|
|
258
|
+
{ label: 'Rename', icon: FileEdit, onClick: () => console.log('Open rename...') },
|
|
259
|
+
{
|
|
260
|
+
label: 'Move',
|
|
261
|
+
icon: ArrowRightLeft,
|
|
262
|
+
children: [
|
|
263
|
+
{
|
|
264
|
+
label: 'Active Projects',
|
|
265
|
+
onClick: () => console.log('Moved to Active Projects'),
|
|
266
|
+
},
|
|
267
|
+
{ label: 'Monitoring', onClick: () => console.log('Moved to Monitoring') },
|
|
268
|
+
{ label: 'Archive', onClick: () => console.log('Moved to Archive') },
|
|
269
|
+
],
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
label: 'Clear',
|
|
273
|
+
icon: Trash2,
|
|
274
|
+
onClick: () => console.log('History Cleared!'),
|
|
275
|
+
variant: 'destructive',
|
|
276
|
+
},
|
|
277
|
+
],
|
|
278
|
+
},
|
|
279
|
+
],
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
id: 'projects',
|
|
283
|
+
label: 'Project Monitoring',
|
|
284
|
+
icon: Map,
|
|
285
|
+
actions: [
|
|
286
|
+
{
|
|
287
|
+
label: 'New Category',
|
|
288
|
+
icon: Plus,
|
|
289
|
+
onClick: () => console.log('Create new category...'),
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
label: 'Archive Group',
|
|
293
|
+
icon: Archive,
|
|
294
|
+
onClick: () => console.log('Archiving group...'),
|
|
295
|
+
},
|
|
296
|
+
],
|
|
297
|
+
items: [
|
|
298
|
+
{
|
|
299
|
+
path: '/assistant/br163',
|
|
300
|
+
label: 'Panel Status',
|
|
301
|
+
icon: () => <div className="w-2 h-2 rounded-full bg-yellow-500" />,
|
|
302
|
+
description: (
|
|
303
|
+
<div className="space-y-1.5 min-w-[160px]">
|
|
304
|
+
<Progress value={67} className="h-1.5 bg-sidebar-foreground/10" />
|
|
305
|
+
<div className="flex justify-between items-center text-[10px] text-sidebar-foreground/60">
|
|
306
|
+
<span>Label</span>
|
|
307
|
+
<span>67%</span>
|
|
308
|
+
</div>
|
|
309
|
+
</div>
|
|
310
|
+
),
|
|
311
|
+
},
|
|
312
|
+
],
|
|
313
|
+
},
|
|
314
|
+
],
|
|
315
|
+
},
|
|
316
|
+
render: args => {
|
|
317
|
+
const [isExpanded, setIsExpanded] = useState(args.expanded);
|
|
318
|
+
const currentWidth = isExpanded ? 280 : 80;
|
|
319
|
+
|
|
320
|
+
return (
|
|
321
|
+
<div
|
|
322
|
+
className="relative h-screen w-full border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
323
|
+
style={{ transform: 'translateZ(0)' }}
|
|
324
|
+
>
|
|
325
|
+
<Sidebar
|
|
326
|
+
{...args}
|
|
327
|
+
expanded={isExpanded}
|
|
328
|
+
onToggle={() => setIsExpanded(!isExpanded)}
|
|
329
|
+
width={currentWidth}
|
|
330
|
+
navigate={() => {}}
|
|
331
|
+
/>
|
|
332
|
+
<div
|
|
333
|
+
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
334
|
+
style={{ left: `${currentWidth}px` }}
|
|
335
|
+
>
|
|
336
|
+
<div className="text-center">
|
|
337
|
+
<p className="text-muted-foreground">Assistant Mode Content</p>
|
|
338
|
+
<p className="text-xs text-muted-foreground mt-2">Click on the menu icon to expand</p>
|
|
339
|
+
</div>
|
|
340
|
+
</div>
|
|
341
|
+
</div>
|
|
342
|
+
);
|
|
343
|
+
},
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
export const Collapsed: Story = {
|
|
347
|
+
args: {
|
|
348
|
+
...Default.args,
|
|
349
|
+
expanded: false,
|
|
350
|
+
},
|
|
351
|
+
render: args => {
|
|
352
|
+
const [isExpanded, setIsExpanded] = useState(args.expanded);
|
|
353
|
+
const currentWidth = isExpanded ? 280 : 80;
|
|
354
|
+
|
|
355
|
+
return (
|
|
356
|
+
<div
|
|
357
|
+
className="relative h-screen w-full border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
358
|
+
style={{ transform: 'translateZ(0)' }}
|
|
359
|
+
>
|
|
360
|
+
<Sidebar
|
|
361
|
+
{...args}
|
|
362
|
+
expanded={isExpanded}
|
|
363
|
+
onToggle={() => setIsExpanded(!isExpanded)}
|
|
364
|
+
width={currentWidth}
|
|
365
|
+
navigate={() => {}}
|
|
366
|
+
/>
|
|
367
|
+
<div
|
|
368
|
+
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
369
|
+
style={{ left: `${currentWidth}px` }}
|
|
370
|
+
>
|
|
371
|
+
<div className="text-center">
|
|
372
|
+
<p className="text-muted-foreground">Compact Navigation</p>
|
|
373
|
+
<p className="text-xs text-muted-foreground mt-2">Click on the menu icon to expand</p>
|
|
374
|
+
</div>
|
|
375
|
+
</div>
|
|
376
|
+
</div>
|
|
377
|
+
);
|
|
378
|
+
},
|
|
379
|
+
};
|
|
380
|
+
export const NoFooter: Story = {
|
|
381
|
+
args: {
|
|
382
|
+
...Default.args,
|
|
383
|
+
showFooter: false,
|
|
384
|
+
},
|
|
385
|
+
render: args => {
|
|
386
|
+
const [isExpanded, setIsExpanded] = useState(args.expanded);
|
|
387
|
+
const currentWidth = isExpanded ? 280 : 80;
|
|
388
|
+
|
|
389
|
+
return (
|
|
390
|
+
<div
|
|
391
|
+
className="relative h-screen w-full border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
392
|
+
style={{ transform: 'translateZ(0)' }}
|
|
393
|
+
>
|
|
394
|
+
<Sidebar
|
|
395
|
+
{...args}
|
|
396
|
+
expanded={isExpanded}
|
|
397
|
+
onToggle={() => setIsExpanded(!isExpanded)}
|
|
398
|
+
width={currentWidth}
|
|
399
|
+
navigate={() => {}}
|
|
400
|
+
/>
|
|
401
|
+
<div
|
|
402
|
+
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
403
|
+
style={{ left: `${currentWidth}px` }}
|
|
404
|
+
>
|
|
405
|
+
<div className="text-center">
|
|
406
|
+
<p className="text-muted-foreground">Sidebar without Footer</p>
|
|
407
|
+
<p className="text-xs text-muted-foreground mt-2">Click on the menu icon to expand</p>
|
|
408
|
+
</div>
|
|
409
|
+
</div>
|
|
410
|
+
</div>
|
|
411
|
+
);
|
|
412
|
+
},
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
export const Autonomous: Story = {
|
|
416
|
+
args: {
|
|
417
|
+
...Default.args,
|
|
418
|
+
expanded: undefined,
|
|
419
|
+
onToggle: undefined,
|
|
420
|
+
},
|
|
421
|
+
render: args => {
|
|
422
|
+
return (
|
|
423
|
+
<div
|
|
424
|
+
className="relative h-screen w-full border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
425
|
+
style={{ transform: 'translateZ(0)' }}
|
|
426
|
+
>
|
|
427
|
+
<Sidebar {...args} />
|
|
428
|
+
<div
|
|
429
|
+
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
430
|
+
style={{ left: `80px` }}
|
|
431
|
+
>
|
|
432
|
+
<div className="text-center max-w-md">
|
|
433
|
+
<p className="text-muted-foreground font-bold">Autonomous Sidebar</p>
|
|
434
|
+
<p className="text-sm text-muted-foreground/80 mt-2">
|
|
435
|
+
This instance is managing its own state internally. No `expanded` or `onToggle` props
|
|
436
|
+
are passed.
|
|
437
|
+
</p>
|
|
438
|
+
<p className="text-xs text-muted-foreground mt-4">
|
|
439
|
+
Note: Layout coordination (content padding) must be handled manually when using
|
|
440
|
+
autonomous mode without LayoutProvider.
|
|
441
|
+
</p>
|
|
442
|
+
</div>
|
|
443
|
+
</div>
|
|
444
|
+
</div>
|
|
445
|
+
);
|
|
446
|
+
},
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Desktop view with sub-items expanded.
|
|
451
|
+
* Items with `children` show a ChevronRight button; clicking it opens a
|
|
452
|
+
* dropdown listing the child routes positioned to the right of the sidebar.
|
|
453
|
+
*/
|
|
454
|
+
export const WithSubitemsDesktop: Story = {
|
|
455
|
+
name: 'With Sub-items (Desktop)',
|
|
456
|
+
args: {
|
|
457
|
+
variant: 'default',
|
|
458
|
+
expanded: true,
|
|
459
|
+
user: { name: 'Admin', email: 'admin@example.com' },
|
|
460
|
+
onLogout: () => console.log('Logged out'),
|
|
461
|
+
location: { pathname: '/dashboard' },
|
|
462
|
+
navigationGroups: [
|
|
463
|
+
{
|
|
464
|
+
id: 'main',
|
|
465
|
+
label: 'Principal',
|
|
466
|
+
items: [
|
|
467
|
+
{ path: '/home', label: 'Início', icon: Home },
|
|
468
|
+
{
|
|
469
|
+
path: '/dashboard',
|
|
470
|
+
label: 'Dashboard',
|
|
471
|
+
icon: BarChart,
|
|
472
|
+
children: [
|
|
473
|
+
{ path: '/dashboard/overview', label: 'Visão Geral', icon: BarChart },
|
|
474
|
+
{ path: '/dashboard/reports', label: 'Relatórios', icon: FileEdit },
|
|
475
|
+
{ path: '/dashboard/analytics', label: 'Analytics', icon: Map },
|
|
476
|
+
{ path: '/dashboard/trends', label: 'Tendências', icon: TrendingUp },
|
|
477
|
+
{ path: '/dashboard/kpis', label: 'KPIs', icon: Activity },
|
|
478
|
+
{ path: '/dashboard/charts', label: 'Gráficos', icon: PieChart },
|
|
479
|
+
{ path: '/dashboard/comparison', label: 'Comparativos', icon: BarChart2 },
|
|
480
|
+
],
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
path: '/reports',
|
|
484
|
+
label: 'Relatórios',
|
|
485
|
+
icon: FileText,
|
|
486
|
+
children: [
|
|
487
|
+
{ path: '/reports/sales', label: 'Vendas', icon: ShoppingCart },
|
|
488
|
+
{ path: '/reports/financial', label: 'Financeiro', icon: CreditCard },
|
|
489
|
+
{ path: '/reports/operational', label: 'Operacional', icon: Layers },
|
|
490
|
+
{ path: '/reports/exports', label: 'Exportações', icon: FileEdit },
|
|
491
|
+
],
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
path: '/catalog',
|
|
495
|
+
label: 'Catálogo',
|
|
496
|
+
icon: Package,
|
|
497
|
+
children: [
|
|
498
|
+
{ path: '/catalog/products', label: 'Produtos', icon: Package },
|
|
499
|
+
{ path: '/catalog/categories', label: 'Categorias', icon: Tag },
|
|
500
|
+
{ path: '/catalog/inventory', label: 'Estoque', icon: Database },
|
|
501
|
+
],
|
|
502
|
+
},
|
|
503
|
+
],
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
id: 'commerce',
|
|
507
|
+
label: 'Comercial',
|
|
508
|
+
items: [
|
|
509
|
+
{
|
|
510
|
+
path: '/orders',
|
|
511
|
+
label: 'Pedidos',
|
|
512
|
+
icon: ShoppingCart,
|
|
513
|
+
children: [
|
|
514
|
+
{ path: '/orders/pending', label: 'Pendentes', icon: Clock },
|
|
515
|
+
{ path: '/orders/processing', label: 'Em Andamento', icon: Zap },
|
|
516
|
+
{ path: '/orders/shipped', label: 'Enviados', icon: Truck },
|
|
517
|
+
{ path: '/orders/delivered', label: 'Entregues', icon: Package },
|
|
518
|
+
{ path: '/orders/cancelled', label: 'Cancelados', icon: Trash2 },
|
|
519
|
+
],
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
path: '/logistics',
|
|
523
|
+
label: 'Logística',
|
|
524
|
+
icon: Truck,
|
|
525
|
+
children: [
|
|
526
|
+
{ path: '/logistics/carriers', label: 'Transportadoras', icon: Truck },
|
|
527
|
+
{ path: '/logistics/tracking', label: 'Rastreamento', icon: Map },
|
|
528
|
+
{ path: '/logistics/warehouses', label: 'Armazéns', icon: Archive },
|
|
529
|
+
],
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
path: '/billing',
|
|
533
|
+
label: 'Faturamento',
|
|
534
|
+
icon: CreditCard,
|
|
535
|
+
children: [
|
|
536
|
+
{ path: '/billing/invoices', label: 'Faturas', icon: FileText },
|
|
537
|
+
{ path: '/billing/payments', label: 'Pagamentos', icon: CreditCard },
|
|
538
|
+
{ path: '/billing/refunds', label: 'Estornos', icon: ArrowRightLeft },
|
|
539
|
+
],
|
|
540
|
+
},
|
|
541
|
+
],
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
id: 'communication',
|
|
545
|
+
label: 'Comunicação',
|
|
546
|
+
items: [
|
|
547
|
+
{
|
|
548
|
+
path: '/notifications',
|
|
549
|
+
label: 'Notificações',
|
|
550
|
+
icon: Bell,
|
|
551
|
+
children: [
|
|
552
|
+
{ path: '/notifications/email', label: 'E-mail', icon: Mail },
|
|
553
|
+
{ path: '/notifications/sms', label: 'SMS', icon: Phone },
|
|
554
|
+
{ path: '/notifications/push', label: 'Push', icon: Bell },
|
|
555
|
+
],
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
path: '/messages',
|
|
559
|
+
label: 'Mensagens',
|
|
560
|
+
icon: MessageSquare,
|
|
561
|
+
children: [
|
|
562
|
+
{ path: '/messages/inbox', label: 'Caixa de Entrada', icon: Mail },
|
|
563
|
+
{ path: '/messages/sent', label: 'Enviadas', icon: MessageSquare },
|
|
564
|
+
{ path: '/messages/templates', label: 'Templates', icon: FileText },
|
|
565
|
+
],
|
|
566
|
+
},
|
|
567
|
+
{ path: '/integrations', label: 'Integrações', icon: Globe },
|
|
568
|
+
],
|
|
569
|
+
},
|
|
570
|
+
{
|
|
571
|
+
id: 'admin',
|
|
572
|
+
label: 'Administração',
|
|
573
|
+
items: [
|
|
574
|
+
{
|
|
575
|
+
path: '/users',
|
|
576
|
+
label: 'Usuários',
|
|
577
|
+
icon: Users,
|
|
578
|
+
children: [
|
|
579
|
+
{ path: '/users/list', label: 'Lista de Usuários', icon: Users },
|
|
580
|
+
{ path: '/users/roles', label: 'Perfis de Acesso', icon: Shield },
|
|
581
|
+
{ path: '/users/permissions', label: 'Permissões', icon: Key },
|
|
582
|
+
{ path: '/users/audit', label: 'Auditoria', icon: Activity },
|
|
583
|
+
],
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
path: '/infrastructure',
|
|
587
|
+
label: 'Infraestrutura',
|
|
588
|
+
icon: Server,
|
|
589
|
+
children: [
|
|
590
|
+
{ path: '/infrastructure/servers', label: 'Servidores', icon: Server },
|
|
591
|
+
{ path: '/infrastructure/databases', label: 'Bancos de Dados', icon: Database },
|
|
592
|
+
{ path: '/infrastructure/backups', label: 'Backups', icon: Archive },
|
|
593
|
+
],
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
path: '/files',
|
|
597
|
+
label: 'Arquivos',
|
|
598
|
+
icon: Folder,
|
|
599
|
+
children: [
|
|
600
|
+
{ path: '/files/documents', label: 'Documentos', icon: FileText },
|
|
601
|
+
{ path: '/files/media', label: 'Mídia', icon: Layers },
|
|
602
|
+
{ path: '/files/exports', label: 'Exportações', icon: FileEdit },
|
|
603
|
+
],
|
|
604
|
+
},
|
|
605
|
+
{ path: '/settings', label: 'Configurações', icon: Settings },
|
|
606
|
+
],
|
|
607
|
+
},
|
|
608
|
+
],
|
|
609
|
+
footer: {
|
|
610
|
+
showUser: true,
|
|
611
|
+
showSettings: false,
|
|
612
|
+
showLogout: true,
|
|
613
|
+
},
|
|
614
|
+
},
|
|
615
|
+
render: args => {
|
|
616
|
+
const [isExpanded, setIsExpanded] = useState(true);
|
|
617
|
+
const currentWidth = isExpanded ? 280 : 80;
|
|
618
|
+
|
|
619
|
+
return (
|
|
620
|
+
<div
|
|
621
|
+
className="relative h-screen w-full border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
622
|
+
style={{ transform: 'translateZ(0)' }}
|
|
623
|
+
>
|
|
624
|
+
<Sidebar
|
|
625
|
+
{...args}
|
|
626
|
+
expanded={isExpanded}
|
|
627
|
+
onToggle={() => setIsExpanded(!isExpanded)}
|
|
628
|
+
width={currentWidth}
|
|
629
|
+
navigate={() => {}}
|
|
630
|
+
/>
|
|
631
|
+
<div
|
|
632
|
+
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
633
|
+
style={{ left: `${currentWidth}px` }}
|
|
634
|
+
>
|
|
635
|
+
<div className="text-center max-w-sm space-y-2">
|
|
636
|
+
<p className="text-muted-foreground font-medium">Desktop — Subitens</p>
|
|
637
|
+
<p className="text-xs text-muted-foreground">
|
|
638
|
+
Itens com subitens exibem um botão{' '}
|
|
639
|
+
<code className="bg-muted px-1 rounded text-xs">ChevronRight</code> ao final da
|
|
640
|
+
linha. Clique nele para abrir o dropdown de rotas filhas.
|
|
641
|
+
</p>
|
|
642
|
+
<p className="text-xs text-muted-foreground mt-2">
|
|
643
|
+
Use o botão de toggle para alternar entre expandido e recolhido.
|
|
644
|
+
</p>
|
|
645
|
+
</div>
|
|
646
|
+
</div>
|
|
647
|
+
</div>
|
|
648
|
+
);
|
|
649
|
+
},
|
|
650
|
+
};
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* Mobile view with sub-items.
|
|
654
|
+
* Simulates a narrow viewport (375 px) so the sidebar renders in its
|
|
655
|
+
* full-screen overlay mode. When expanded the sidebar covers the entire
|
|
656
|
+
* container; clicking a nav item (or the back-arrow toggle) closes it.
|
|
657
|
+
*
|
|
658
|
+
* Sub-item dropdowns behave identically to desktop — the ChevronRight
|
|
659
|
+
* button opens a `DropdownMenuContent` positioned to the right.
|
|
660
|
+
* This story exists so the mobile layout can be inspected and adjusted.
|
|
661
|
+
*/
|
|
662
|
+
export const WithSubitemsMobile: Story = {
|
|
663
|
+
name: 'With Sub-items (Mobile)',
|
|
664
|
+
parameters: {
|
|
665
|
+
viewport: { defaultViewport: 'mobile1' },
|
|
666
|
+
},
|
|
667
|
+
args: {
|
|
668
|
+
variant: 'default',
|
|
669
|
+
expanded: false,
|
|
670
|
+
user: { name: 'Admin', email: 'admin@example.com' },
|
|
671
|
+
onLogout: () => console.log('Logged out'),
|
|
672
|
+
location: { pathname: '/dashboard' },
|
|
673
|
+
navigationGroups: [
|
|
674
|
+
{
|
|
675
|
+
id: 'main',
|
|
676
|
+
label: 'Principal',
|
|
677
|
+
items: [
|
|
678
|
+
{ path: '/home', label: 'Início', icon: Home },
|
|
679
|
+
{
|
|
680
|
+
path: '/dashboard',
|
|
681
|
+
label: 'Dashboard',
|
|
682
|
+
icon: BarChart,
|
|
683
|
+
children: [
|
|
684
|
+
{ path: '/dashboard/overview', label: 'Visão Geral', icon: BarChart },
|
|
685
|
+
{ path: '/dashboard/reports', label: 'Relatórios', icon: FileEdit },
|
|
686
|
+
{ path: '/dashboard/analytics', label: 'Analytics', icon: Map },
|
|
687
|
+
{ path: '/dashboard/trends', label: 'Tendências', icon: TrendingUp },
|
|
688
|
+
{ path: '/dashboard/kpis', label: 'KPIs', icon: Activity },
|
|
689
|
+
{ path: '/dashboard/charts', label: 'Gráficos', icon: PieChart },
|
|
690
|
+
{ path: '/dashboard/comparison', label: 'Comparativos', icon: BarChart2 },
|
|
691
|
+
],
|
|
692
|
+
},
|
|
693
|
+
{
|
|
694
|
+
path: '/reports',
|
|
695
|
+
label: 'Relatórios',
|
|
696
|
+
icon: FileText,
|
|
697
|
+
children: [
|
|
698
|
+
{ path: '/reports/sales', label: 'Vendas', icon: ShoppingCart },
|
|
699
|
+
{ path: '/reports/financial', label: 'Financeiro', icon: CreditCard },
|
|
700
|
+
{ path: '/reports/operational', label: 'Operacional', icon: Layers },
|
|
701
|
+
{ path: '/reports/exports', label: 'Exportações', icon: FileEdit },
|
|
702
|
+
],
|
|
703
|
+
},
|
|
704
|
+
{
|
|
705
|
+
path: '/catalog',
|
|
706
|
+
label: 'Catálogo',
|
|
707
|
+
icon: Package,
|
|
708
|
+
children: [
|
|
709
|
+
{ path: '/catalog/products', label: 'Produtos', icon: Package },
|
|
710
|
+
{ path: '/catalog/categories', label: 'Categorias', icon: Tag },
|
|
711
|
+
{ path: '/catalog/inventory', label: 'Estoque', icon: Database },
|
|
712
|
+
],
|
|
713
|
+
},
|
|
714
|
+
],
|
|
715
|
+
},
|
|
716
|
+
{
|
|
717
|
+
id: 'commerce',
|
|
718
|
+
label: 'Comercial',
|
|
719
|
+
items: [
|
|
720
|
+
{
|
|
721
|
+
path: '/orders',
|
|
722
|
+
label: 'Pedidos',
|
|
723
|
+
icon: ShoppingCart,
|
|
724
|
+
children: [
|
|
725
|
+
{ path: '/orders/pending', label: 'Pendentes', icon: Clock },
|
|
726
|
+
{ path: '/orders/processing', label: 'Em Andamento', icon: Zap },
|
|
727
|
+
{ path: '/orders/shipped', label: 'Enviados', icon: Truck },
|
|
728
|
+
{ path: '/orders/delivered', label: 'Entregues', icon: Package },
|
|
729
|
+
{ path: '/orders/cancelled', label: 'Cancelados', icon: Trash2 },
|
|
730
|
+
],
|
|
731
|
+
},
|
|
732
|
+
{
|
|
733
|
+
path: '/logistics',
|
|
734
|
+
label: 'Logística',
|
|
735
|
+
icon: Truck,
|
|
736
|
+
children: [
|
|
737
|
+
{ path: '/logistics/carriers', label: 'Transportadoras', icon: Truck },
|
|
738
|
+
{ path: '/logistics/tracking', label: 'Rastreamento', icon: Map },
|
|
739
|
+
{ path: '/logistics/warehouses', label: 'Armazéns', icon: Archive },
|
|
740
|
+
],
|
|
741
|
+
},
|
|
742
|
+
{
|
|
743
|
+
path: '/billing',
|
|
744
|
+
label: 'Faturamento',
|
|
745
|
+
icon: CreditCard,
|
|
746
|
+
children: [
|
|
747
|
+
{ path: '/billing/invoices', label: 'Faturas', icon: FileText },
|
|
748
|
+
{ path: '/billing/payments', label: 'Pagamentos', icon: CreditCard },
|
|
749
|
+
{ path: '/billing/refunds', label: 'Estornos', icon: ArrowRightLeft },
|
|
750
|
+
],
|
|
751
|
+
},
|
|
752
|
+
],
|
|
753
|
+
},
|
|
754
|
+
{
|
|
755
|
+
id: 'communication',
|
|
756
|
+
label: 'Comunicação',
|
|
757
|
+
items: [
|
|
758
|
+
{
|
|
759
|
+
path: '/notifications',
|
|
760
|
+
label: 'Notificações',
|
|
761
|
+
icon: Bell,
|
|
762
|
+
children: [
|
|
763
|
+
{ path: '/notifications/email', label: 'E-mail', icon: Mail },
|
|
764
|
+
{ path: '/notifications/sms', label: 'SMS', icon: Phone },
|
|
765
|
+
{ path: '/notifications/push', label: 'Push', icon: Bell },
|
|
766
|
+
],
|
|
767
|
+
},
|
|
768
|
+
{
|
|
769
|
+
path: '/messages',
|
|
770
|
+
label: 'Mensagens',
|
|
771
|
+
icon: MessageSquare,
|
|
772
|
+
children: [
|
|
773
|
+
{ path: '/messages/inbox', label: 'Caixa de Entrada', icon: Mail },
|
|
774
|
+
{ path: '/messages/sent', label: 'Enviadas', icon: MessageSquare },
|
|
775
|
+
{ path: '/messages/templates', label: 'Templates', icon: FileText },
|
|
776
|
+
],
|
|
777
|
+
},
|
|
778
|
+
{ path: '/integrations', label: 'Integrações', icon: Globe },
|
|
779
|
+
],
|
|
780
|
+
},
|
|
781
|
+
{
|
|
782
|
+
id: 'admin',
|
|
783
|
+
label: 'Administração',
|
|
784
|
+
items: [
|
|
785
|
+
{
|
|
786
|
+
path: '/users',
|
|
787
|
+
label: 'Usuários',
|
|
788
|
+
icon: Users,
|
|
789
|
+
children: [
|
|
790
|
+
{ path: '/users/list', label: 'Lista de Usuários', icon: Users },
|
|
791
|
+
{ path: '/users/roles', label: 'Perfis de Acesso', icon: Shield },
|
|
792
|
+
{ path: '/users/permissions', label: 'Permissões', icon: Key },
|
|
793
|
+
{ path: '/users/audit', label: 'Auditoria', icon: Activity },
|
|
794
|
+
],
|
|
795
|
+
},
|
|
796
|
+
{
|
|
797
|
+
path: '/infrastructure',
|
|
798
|
+
label: 'Infraestrutura',
|
|
799
|
+
icon: Server,
|
|
800
|
+
children: [
|
|
801
|
+
{ path: '/infrastructure/servers', label: 'Servidores', icon: Server },
|
|
802
|
+
{ path: '/infrastructure/databases', label: 'Bancos de Dados', icon: Database },
|
|
803
|
+
{ path: '/infrastructure/backups', label: 'Backups', icon: Archive },
|
|
804
|
+
],
|
|
805
|
+
},
|
|
806
|
+
{
|
|
807
|
+
path: '/files',
|
|
808
|
+
label: 'Arquivos',
|
|
809
|
+
icon: Folder,
|
|
810
|
+
children: [
|
|
811
|
+
{ path: '/files/documents', label: 'Documentos', icon: FileText },
|
|
812
|
+
{ path: '/files/media', label: 'Mídia', icon: Layers },
|
|
813
|
+
{ path: '/files/exports', label: 'Exportações', icon: FileEdit },
|
|
814
|
+
],
|
|
815
|
+
},
|
|
816
|
+
{ path: '/settings', label: 'Configurações', icon: Settings },
|
|
817
|
+
],
|
|
818
|
+
},
|
|
819
|
+
],
|
|
820
|
+
footer: {
|
|
821
|
+
showUser: true,
|
|
822
|
+
showSettings: false,
|
|
823
|
+
showLogout: true,
|
|
824
|
+
},
|
|
825
|
+
},
|
|
826
|
+
render: args => {
|
|
827
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
828
|
+
|
|
829
|
+
return (
|
|
830
|
+
/* Constrain to ~375 px to reproduce a mobile viewport inside Storybook */
|
|
831
|
+
<div
|
|
832
|
+
className="relative bg-muted/20 overflow-hidden border rounded-[var(--radius-lg)]"
|
|
833
|
+
style={{ width: '375px', height: '100vh', margin: '0 auto' }}
|
|
834
|
+
>
|
|
835
|
+
{/* Page content visible when sidebar is closed */}
|
|
836
|
+
{!isExpanded && (
|
|
837
|
+
<div className="h-full flex flex-col">
|
|
838
|
+
<div className="flex items-center gap-3 px-4 py-3 border-b border-border bg-background">
|
|
839
|
+
<button
|
|
840
|
+
onClick={() => setIsExpanded(true)}
|
|
841
|
+
className="p-2 rounded-md hover:bg-accent transition-colors"
|
|
842
|
+
aria-label="Abrir menu"
|
|
843
|
+
>
|
|
844
|
+
<Menu className="w-5 h-5" />
|
|
845
|
+
</button>
|
|
846
|
+
<span className="font-semibold text-sm">Minha Aplicação</span>
|
|
847
|
+
</div>
|
|
848
|
+
<div className="flex-1 flex items-center justify-center p-8">
|
|
849
|
+
<div className="text-center space-y-2">
|
|
850
|
+
<p className="text-muted-foreground font-medium">Mobile — Subitens</p>
|
|
851
|
+
<p className="text-xs text-muted-foreground">
|
|
852
|
+
Clique no ícone de menu (☰) no topo para abrir a sidebar em modo
|
|
853
|
+
tela-cheia. Itens com subitens mostram um{' '}
|
|
854
|
+
<code className="bg-muted px-1 rounded text-xs">ChevronRight</code> ao final
|
|
855
|
+
da linha.
|
|
856
|
+
</p>
|
|
857
|
+
</div>
|
|
858
|
+
</div>
|
|
859
|
+
</div>
|
|
860
|
+
)}
|
|
861
|
+
|
|
862
|
+
<Sidebar
|
|
863
|
+
{...args}
|
|
864
|
+
expanded={isExpanded}
|
|
865
|
+
onToggle={() => setIsExpanded(prev => !prev)}
|
|
866
|
+
width={375}
|
|
867
|
+
navigate={() => setIsExpanded(false)}
|
|
868
|
+
/>
|
|
869
|
+
</div>
|
|
870
|
+
);
|
|
871
|
+
},
|
|
872
|
+
};
|
|
873
|
+
|
|
874
|
+
/**
|
|
875
|
+
* Compound Component API — demonstrates using Sidebar.Root + sub-components
|
|
876
|
+
* for full layout control. This is the recommended pattern for advanced
|
|
877
|
+
* customization without forking the component.
|
|
878
|
+
*/
|
|
879
|
+
export const CompoundComponentAPI: Story = {
|
|
880
|
+
name: 'Compound Component API',
|
|
881
|
+
render: () => {
|
|
882
|
+
const [isExpanded, setIsExpanded] = React.useState(true);
|
|
883
|
+
const currentWidth = isExpanded ? 280 : 80;
|
|
884
|
+
const groups = [
|
|
885
|
+
{
|
|
886
|
+
id: 'main',
|
|
887
|
+
label: 'Principal',
|
|
888
|
+
items: [
|
|
889
|
+
{ path: '/home', label: 'Início', icon: Home },
|
|
890
|
+
{ path: '/dashboard', label: 'Dashboard', icon: BarChart },
|
|
891
|
+
],
|
|
892
|
+
},
|
|
893
|
+
{
|
|
894
|
+
id: 'admin',
|
|
895
|
+
label: 'Administração',
|
|
896
|
+
items: [
|
|
897
|
+
{ path: '/users', label: 'Usuários', icon: Users },
|
|
898
|
+
{ path: '/settings', label: 'Configurações', icon: Settings },
|
|
899
|
+
],
|
|
900
|
+
},
|
|
901
|
+
];
|
|
902
|
+
|
|
903
|
+
return (
|
|
904
|
+
<div
|
|
905
|
+
className="relative h-screen w-full border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
906
|
+
style={{ transform: 'translateZ(0)' }}
|
|
907
|
+
>
|
|
908
|
+
{/* Compound Component usage */}
|
|
909
|
+
<Sidebar.Root
|
|
910
|
+
expanded={isExpanded}
|
|
911
|
+
onToggle={() => setIsExpanded(prev => !prev)}
|
|
912
|
+
width={currentWidth}
|
|
913
|
+
location={{ pathname: '/home' }}
|
|
914
|
+
navigate={() => {}}
|
|
915
|
+
>
|
|
916
|
+
<Sidebar.Header />
|
|
917
|
+
<Sidebar.Nav navigationGroups={groups} />
|
|
918
|
+
<Sidebar.Footer
|
|
919
|
+
user={{ name: 'Admin', email: 'admin@example.com' }}
|
|
920
|
+
onLogout={() => console.log('logout')}
|
|
921
|
+
showUser
|
|
922
|
+
showSettings
|
|
923
|
+
showLogout
|
|
924
|
+
/>
|
|
925
|
+
</Sidebar.Root>
|
|
926
|
+
|
|
927
|
+
<div
|
|
928
|
+
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
929
|
+
style={{ left: `${currentWidth}px` }}
|
|
930
|
+
>
|
|
931
|
+
<div className="text-center max-w-md space-y-3">
|
|
932
|
+
<p className="text-muted-foreground font-bold">Compound Component API</p>
|
|
933
|
+
<p className="text-sm text-muted-foreground/80">
|
|
934
|
+
Built with <code className="bg-muted px-1 rounded text-xs"><Sidebar.Root></code>
|
|
935
|
+
, <code className="bg-muted px-1 rounded text-xs"><Sidebar.Header></code>,{' '}
|
|
936
|
+
<code className="bg-muted px-1 rounded text-xs"><Sidebar.Nav></code>, and{' '}
|
|
937
|
+
<code className="bg-muted px-1 rounded text-xs"><Sidebar.Footer></code>.
|
|
938
|
+
</p>
|
|
939
|
+
<p className="text-xs text-muted-foreground">
|
|
940
|
+
Each sub-component reads shared state from{' '}
|
|
941
|
+
<code className="bg-muted px-1 rounded text-xs">SidebarContext</code> via{' '}
|
|
942
|
+
<code className="bg-muted px-1 rounded text-xs">Sidebar.Root</code>.
|
|
943
|
+
</p>
|
|
944
|
+
</div>
|
|
945
|
+
</div>
|
|
946
|
+
</div>
|
|
947
|
+
);
|
|
948
|
+
},
|
|
949
|
+
};
|
|
950
|
+
|
|
951
|
+
/**
|
|
952
|
+
* Headless Hook — demonstrates using `useSidebar` directly for fully custom rendering.
|
|
953
|
+
* The hook manages all state; the UI is entirely up to the consumer.
|
|
954
|
+
*/
|
|
955
|
+
export const HeadlessHook: Story = {
|
|
956
|
+
name: 'Headless Hook (useSidebar)',
|
|
957
|
+
render: () => {
|
|
958
|
+
const groups = [
|
|
959
|
+
{
|
|
960
|
+
id: 'main',
|
|
961
|
+
label: 'Principal',
|
|
962
|
+
items: [
|
|
963
|
+
{ path: '/home', label: 'Início', icon: Home },
|
|
964
|
+
{ path: '/dashboard', label: 'Dashboard', icon: BarChart },
|
|
965
|
+
{ path: '/users', label: 'Usuários', icon: Users },
|
|
966
|
+
],
|
|
967
|
+
},
|
|
968
|
+
];
|
|
969
|
+
|
|
970
|
+
const {
|
|
971
|
+
expanded,
|
|
972
|
+
toggleExpanded,
|
|
973
|
+
navigationGroups: resolvedGroups,
|
|
974
|
+
} = useSidebar({ defaultExpanded: true, navigationGroups: groups });
|
|
975
|
+
|
|
976
|
+
const width = expanded ? 280 : 80;
|
|
977
|
+
|
|
978
|
+
return (
|
|
979
|
+
<div
|
|
980
|
+
className="relative h-screen w-full border rounded-[var(--radius-lg)] bg-muted/20 overflow-hidden"
|
|
981
|
+
style={{ transform: 'translateZ(0)' }}
|
|
982
|
+
>
|
|
983
|
+
{/* Fully custom sidebar built with useSidebar hook */}
|
|
984
|
+
<div
|
|
985
|
+
className="absolute inset-y-0 left-0 bg-sidebar text-sidebar-foreground flex flex-col transition-all duration-300 z-50"
|
|
986
|
+
style={{ width: `${width}px` }}
|
|
987
|
+
>
|
|
988
|
+
<div className="p-4">
|
|
989
|
+
<button
|
|
990
|
+
onClick={toggleExpanded}
|
|
991
|
+
className="w-full h-10 flex items-center justify-center rounded-md bg-sidebar-foreground/10 hover:bg-sidebar-foreground/20 text-sidebar-foreground transition-colors"
|
|
992
|
+
aria-label={expanded ? 'Collapse' : 'Expand'}
|
|
993
|
+
>
|
|
994
|
+
{expanded ? <PanelLeft className="w-5 h-5" /> : <Menu className="w-5 h-5" />}
|
|
995
|
+
</button>
|
|
996
|
+
</div>
|
|
997
|
+
<nav className="flex-1 px-3 space-y-1">
|
|
998
|
+
{resolvedGroups
|
|
999
|
+
.flatMap(g => g.items)
|
|
1000
|
+
.map(item => {
|
|
1001
|
+
const Icon = item.icon;
|
|
1002
|
+
return (
|
|
1003
|
+
<button
|
|
1004
|
+
key={item.path}
|
|
1005
|
+
className="w-full h-10 flex items-center gap-3 px-3 rounded-md text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground transition-colors"
|
|
1006
|
+
>
|
|
1007
|
+
{Icon && <Icon className="w-5 h-5 flex-shrink-0" />}
|
|
1008
|
+
{expanded && <span className="truncate text-sm">{item.label}</span>}
|
|
1009
|
+
</button>
|
|
1010
|
+
);
|
|
1011
|
+
})}
|
|
1012
|
+
</nav>
|
|
1013
|
+
</div>
|
|
1014
|
+
|
|
1015
|
+
<div
|
|
1016
|
+
className="absolute inset-y-0 right-0 p-8 flex items-center justify-center transition-all duration-300"
|
|
1017
|
+
style={{ left: `${width}px` }}
|
|
1018
|
+
>
|
|
1019
|
+
<div className="text-center max-w-md space-y-3">
|
|
1020
|
+
<p className="text-muted-foreground font-bold">Headless Hook</p>
|
|
1021
|
+
<p className="text-sm text-muted-foreground/80">
|
|
1022
|
+
State managed by <code className="bg-muted px-1 rounded text-xs">useSidebar()</code>.
|
|
1023
|
+
The entire UI is custom — no Sidebar component used.
|
|
1024
|
+
</p>
|
|
1025
|
+
<p className="text-xs text-muted-foreground">
|
|
1026
|
+
Sidebar is currently: <strong>{expanded ? 'Expanded' : 'Collapsed'}</strong>
|
|
1027
|
+
</p>
|
|
1028
|
+
</div>
|
|
1029
|
+
</div>
|
|
1030
|
+
</div>
|
|
1031
|
+
);
|
|
1032
|
+
},
|
|
1033
|
+
};
|