xertica-ui 2.5.0 → 2.5.2
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 +35 -0
- package/README.md +56 -17
- package/assets/xertica-logo.svg +37 -37
- package/assets/xertica-x-logo.svg +20 -20
- package/bin/cli.ts +14 -2
- package/bin/generate-tokens.ts +262 -262
- package/bin/language-config.ts +359 -358
- package/components/assistant/code-block/CodeBlock.tsx +268 -268
- package/components/assistant/formatted-document/FormattedDocument.tsx +147 -147
- package/components/assistant/modern-chat-input/ModernChatInput.tsx +564 -564
- package/components/assistant/xertica-assistant/parts/AssistantCollapsedView.tsx +99 -99
- package/components/assistant/xertica-assistant/parts/AssistantConversationList.tsx +104 -104
- package/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.tsx +81 -81
- package/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.tsx +88 -88
- package/components/assistant/xertica-assistant/parts/AssistantHeader.tsx +75 -75
- package/components/assistant/xertica-assistant/parts/AssistantMessageBubble.tsx +564 -564
- package/components/assistant/xertica-assistant/parts/AssistantTabBar.tsx +67 -67
- package/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.tsx +103 -103
- package/components/assistant/xertica-assistant/use-assistant.ts +615 -615
- package/components/assistant/xertica-assistant/xertica-assistant.tsx +611 -611
- package/components/blocks/card-patterns/ActivityCard.tsx +100 -100
- package/components/blocks/card-patterns/ActivityCardSkeleton.tsx +56 -56
- package/components/blocks/card-patterns/FeatureCardSkeleton.tsx +58 -58
- package/components/blocks/card-patterns/NotificationCard.tsx +140 -140
- package/components/blocks/card-patterns/NotificationCardSkeleton.tsx +81 -81
- package/components/blocks/card-patterns/ProfileCard.tsx +112 -112
- package/components/blocks/card-patterns/ProfileCardSkeleton.tsx +69 -69
- package/components/blocks/card-patterns/ProjectCard.tsx +123 -123
- package/components/blocks/card-patterns/ProjectCardSkeleton.tsx +67 -67
- package/components/blocks/card-patterns/QuickActionCardSkeleton.tsx +44 -44
- package/components/blocks/card-patterns/card-patterns.stories.tsx +594 -594
- package/components/blocks/card-patterns/index.ts +29 -29
- package/components/brand/language-selector/LanguageSelector.tsx +102 -102
- package/components/brand/language-selector/language-selector.stories.tsx +111 -111
- package/components/brand/language-selector/language-selector.test.tsx +101 -101
- package/components/brand/theme-toggle/ThemeToggle.tsx +74 -74
- package/components/brand/xertica-provider/xertica-provider.mdx +61 -61
- package/components/index.ts +86 -86
- package/components/layout/sidebar/sidebar.mdx +1 -1
- package/components/layout/sidebar/sidebar.stories.tsx +1033 -787
- package/components/layout/sidebar/sidebar.tsx +338 -1
- package/components/media/FloatingMediaWrapper.tsx +371 -371
- package/components/media/audio-player/AudioPlayer.tsx +768 -768
- package/components/media/video-player/VideoPlayer.tsx +310 -310
- package/components/pages/home-content/HomeContent.tsx +120 -120
- package/components/pages/home-content/home-content.mdx +62 -62
- package/components/pages/home-page/HomePage.tsx +78 -78
- package/components/pages/home-page/home-page.mdx +53 -53
- package/components/pages/template-content/TemplateContent.tsx +1354 -1354
- 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/shared/error-boundary.stories.tsx +114 -114
- package/components/shared/error-boundary.tsx +150 -150
- package/components/shared/error-fallbacks.tsx +222 -222
- package/components/ui/accordion/accordion.mdx +8 -8
- package/components/ui/alert/alert.mdx +8 -8
- package/components/ui/alert-dialog/alert-dialog.mdx +8 -8
- package/components/ui/aspect-ratio/aspect-ratio.mdx +8 -8
- package/components/ui/assistant-chart/assistant-chart.mdx +8 -8
- package/components/ui/avatar/avatar.mdx +8 -8
- package/components/ui/badge/badge.mdx +8 -8
- package/components/ui/breadcrumb/breadcrumb.mdx +8 -8
- package/components/ui/button/button.mdx +8 -8
- package/components/ui/calendar/calendar.mdx +8 -8
- package/components/ui/card/card.mdx +8 -8
- package/components/ui/carousel/carousel.mdx +8 -8
- package/components/ui/chart/chart.mdx +8 -8
- package/components/ui/chart/chart.test.tsx +178 -178
- package/components/ui/chart/chart.tsx +2245 -2239
- package/components/ui/checkbox/checkbox.mdx +8 -8
- package/components/ui/collapsible/collapsible.mdx +8 -8
- package/components/ui/command/command.mdx +8 -8
- package/components/ui/context-menu/context-menu.mdx +8 -8
- package/components/ui/dialog/dialog.mdx +8 -8
- package/components/ui/drawer/drawer.mdx +8 -8
- package/components/ui/dropdown-menu/dropdown-menu.mdx +8 -8
- package/components/ui/empty/empty.mdx +8 -8
- package/components/ui/file-upload/file-upload.mdx +8 -8
- package/components/ui/hover-card/hover-card.mdx +8 -8
- package/components/ui/input/input.mdx +8 -8
- package/components/ui/input-otp/input-otp.mdx +8 -8
- package/components/ui/label/label.mdx +8 -8
- package/components/ui/map/map.mdx +8 -8
- package/components/ui/menubar/menubar.mdx +8 -8
- package/components/ui/navigation-menu/navigation-menu.mdx +8 -8
- package/components/ui/notification-badge/notification-badge.mdx +8 -8
- package/components/ui/pagination/pagination.mdx +8 -8
- package/components/ui/popover/popover.mdx +8 -8
- package/components/ui/progress/progress.mdx +8 -8
- package/components/ui/radio-group/radio-group.mdx +8 -8
- package/components/ui/rating/rating.mdx +8 -8
- package/components/ui/resizable/resizable.mdx +8 -8
- package/components/ui/route-map/route-map.mdx +8 -8
- package/components/ui/scroll-area/scroll-area.mdx +8 -8
- package/components/ui/search/search.mdx +8 -8
- package/components/ui/select/select.mdx +8 -8
- package/components/ui/separator/separator.mdx +8 -8
- package/components/ui/sheet/sheet.mdx +8 -8
- package/components/ui/simple-map/simple-map.mdx +8 -8
- package/components/ui/skeleton/skeleton.mdx +8 -8
- package/components/ui/slider/slider.mdx +8 -8
- package/components/ui/sonner/sonner.mdx +8 -8
- package/components/ui/stats-card/index.ts +2 -2
- package/components/ui/stats-card/stats-card-skeleton.tsx +60 -60
- package/components/ui/stats-card/stats-card.mdx +8 -8
- package/components/ui/stats-card/stats-card.tsx +109 -109
- package/components/ui/stepper/stepper.mdx +8 -8
- package/components/ui/switch/switch.mdx +8 -8
- package/components/ui/table/table.mdx +8 -8
- package/components/ui/tabs/tabs.mdx +8 -8
- package/components/ui/textarea/textarea.mdx +8 -8
- package/components/ui/timeline/timeline.mdx +8 -8
- package/components/ui/toggle/toggle.mdx +8 -8
- package/components/ui/toggle-group/toggle-group.mdx +8 -8
- package/components/ui/tooltip/tooltip.mdx +8 -8
- package/components/ui/tree-view/tree-view.mdx +8 -8
- package/components.json +511 -511
- package/contexts/AuthContext.tsx +121 -121
- package/contexts/BrandColorsContext.tsx +282 -282
- package/contexts/LanguageContext.test.tsx +121 -121
- package/contexts/LanguageContext.tsx +250 -250
- package/contexts/theme-data.ts +391 -391
- package/dist/{AssistantChart-DoZCyS5r.cjs → AssistantChart-9w31gdAb.cjs} +4 -4
- package/dist/{AssistantChart-CldVCVDe.cjs → AssistantChart-BAudAfne.cjs} +5 -5
- package/dist/{AssistantChart-Bdd44uBn.cjs → AssistantChart-BAx9VQvb.cjs} +127 -388
- package/dist/{AssistantChart-Cu3m7RBo.js → AssistantChart-BP8upjMk.js} +5 -5
- package/dist/{AssistantChart-CFhDdGyU.js → AssistantChart-CVko2A1W.js} +130 -391
- package/dist/{AssistantChart-C_hwFRRr.js → AssistantChart-CVzmmhx4.js} +4 -4
- package/dist/{AudioPlayer-IAU5q5T1.cjs → AudioPlayer-1ypwE2Wh.cjs} +1 -1
- package/dist/{AudioPlayer-CGRUtUdN.js → AudioPlayer-DuKXrCfy.js} +1 -1
- package/dist/{LanguageContext-CS14yCpi.js → LanguageContext-BwhwC3G2.js} +2 -2
- package/dist/{LanguageContext-B_KFTCzT.cjs → LanguageContext-DvUt5jBg.cjs} +2 -2
- package/dist/{ThemeContext-C2EwAPDt.js → ThemeContext-BbBNoFTG.js} +2 -2
- package/dist/{ThemeContext-Bmod0Cg2.cjs → ThemeContext-BblcjQup.cjs} +13 -8
- package/dist/{ThemeContext-BWq9ACPo.js → ThemeContext-Bo-W2WZH.js} +13 -8
- package/dist/{ThemeContext-j5aGtPky.cjs → ThemeContext-CP3a0jxy.cjs} +193 -262
- package/dist/{ThemeContext-vTjumZeM.cjs → ThemeContext-Cmr8Ex8H.cjs} +2 -2
- package/dist/ThemeContext-CpqYShLq.cjs +324 -0
- package/dist/{ThemeContext-CQSo4Iwc.js → ThemeContext-D3LzacmG.js} +8 -1
- package/dist/ThemeContext-Du2nE1PL.js +325 -0
- package/dist/ThemeContext-GeEBTJ3q.cjs +1621 -0
- package/dist/ThemeContext-JyLK9B1o.js +1622 -0
- package/dist/{ThemeContext-CGk3KK0k.cjs → ThemeContext-U4dEYc6C.cjs} +8 -1
- package/dist/{ThemeContext-BXjrgUjW.js → ThemeContext-ept8jhXI.js} +200 -261
- package/dist/{VerifyEmailPage-CGIwmWrm.js → VerifyEmailPage-B31mCrMc.js} +1 -1
- package/dist/{VerifyEmailPage-C0c2e5n0.js → VerifyEmailPage-BE-L9mB7.js} +7 -7
- package/dist/{VerifyEmailPage-DSBMRHtl.js → VerifyEmailPage-BIBOKV7Z.js} +41 -36
- package/dist/{VerifyEmailPage-DgIid028.js → VerifyEmailPage-BJjAMUTW.js} +4 -4
- package/dist/{VerifyEmailPage--1Vurewl.cjs → VerifyEmailPage-BRSP-Pwt.cjs} +3 -3
- package/dist/{VerifyEmailPage-Cwi3kbol.cjs → VerifyEmailPage-Bae2cBXT.cjs} +7 -7
- package/dist/{VerifyEmailPage-De6bQjrz.cjs → VerifyEmailPage-BiRm7Nh4.cjs} +41 -36
- package/dist/{VerifyEmailPage-ByerOcm4.cjs → VerifyEmailPage-Bv8Ah_TK.cjs} +23 -20
- package/dist/VerifyEmailPage-Bvfv8HVQ.js +3214 -0
- package/dist/{VerifyEmailPage-BComraR7.cjs → VerifyEmailPage-CR7kb5df.cjs} +22 -12
- package/dist/{VerifyEmailPage-CpqqpLpo.cjs → VerifyEmailPage-C_Zk6Gen.cjs} +1 -1
- package/dist/{VerifyEmailPage-MTD7AG1Z.js → VerifyEmailPage-C_ihbcth.js} +4 -4
- package/dist/{VerifyEmailPage-1WwWczAn.js → VerifyEmailPage-CbgjOF0v.js} +22 -12
- package/dist/{VerifyEmailPage-DvMLZgFt.js → VerifyEmailPage-CdYPSJoO.js} +1 -1
- package/dist/{VerifyEmailPage-By3Jf__L.cjs → VerifyEmailPage-CkBYfsNy.cjs} +4 -4
- package/dist/{VerifyEmailPage-CJLz3jrn.js → VerifyEmailPage-Cyl55sJb.js} +23 -20
- package/dist/VerifyEmailPage-D-FRj5TU.cjs +3213 -0
- package/dist/{VerifyEmailPage-B4peJjAT.cjs → VerifyEmailPage-DF2ilhum.cjs} +334 -356
- package/dist/{VerifyEmailPage-CYXtbKi3.cjs → VerifyEmailPage-DMBh4NM9.cjs} +1 -1
- package/dist/{VerifyEmailPage-CgMxRb4z.js → VerifyEmailPage-DTtFfC-J.js} +3 -3
- package/dist/{VerifyEmailPage-CFLMls1p.cjs → VerifyEmailPage-Dt7zgA4w.cjs} +4 -4
- package/dist/{VerifyEmailPage-C5TNQTBa.js → VerifyEmailPage-EhudUdqF.js} +343 -355
- package/dist/{VerifyEmailPage-DGhuIqkb.js → VerifyEmailPage-X14vhdyl.js} +4 -4
- package/dist/VerifyEmailPage-hdB8JQGv.cjs +3213 -0
- package/dist/{VerifyEmailPage-Bp1XXl3H.cjs → VerifyEmailPage-u_Dn7t1U.cjs} +4 -4
- package/dist/VerifyEmailPage-vYHbYK3q.js +3214 -0
- package/dist/{XerticaProvider-CBGc4EMA.cjs → XerticaProvider-AChwphCO.cjs} +4 -4
- package/dist/{XerticaProvider-BIrqfZ-i.cjs → XerticaProvider-AbWlr7Af.cjs} +8 -11
- package/dist/{XerticaProvider-D-yNhF94.cjs → XerticaProvider-B8CaV7xu.cjs} +1 -1
- package/dist/{XerticaProvider-CEoWMTxu.js → XerticaProvider-BITjgC5p.js} +2 -2
- package/dist/{XerticaProvider-CllrbMEJ.cjs → XerticaProvider-By8q3Roe.cjs} +2 -2
- package/dist/{XerticaProvider-C1DKnvLh.js → XerticaProvider-CUYJZc32.js} +4 -4
- package/dist/{XerticaProvider-ET0ihewn.cjs → XerticaProvider-CW9hpCdF.cjs} +2 -2
- package/dist/{XerticaProvider-Dt5HEzbQ.js → XerticaProvider-CWgby5mY.js} +10 -10
- package/dist/XerticaProvider-CWs6EwNa.js +49 -0
- package/dist/XerticaProvider-CjQAQPcn.cjs +48 -0
- package/dist/XerticaProvider-D5lLumH-.js +49 -0
- package/dist/{XerticaProvider-DYq4JWtg.js → XerticaProvider-DQtvJU7m.js} +1 -1
- package/dist/XerticaProvider-qQUDop71.cjs +48 -0
- package/dist/{XerticaProvider-B7EVH-NF.js → XerticaProvider-siSt9uG2.js} +2 -2
- package/dist/{XerticaXLogo-Zw2B276b.cjs → XerticaXLogo-8TTzBjHw.cjs} +1 -1
- package/dist/{XerticaXLogo-B7xQ5dhi.js → XerticaXLogo-BWaag64t.js} +1 -1
- package/dist/{XerticaXLogo-DZbo4vOE.js → XerticaXLogo-CFuIlYFH.js} +12 -12
- package/dist/{XerticaXLogo-bvZSgwGF.cjs → XerticaXLogo-CU-U-GP4.cjs} +7 -13
- package/dist/XerticaXLogo-ChryA6xj.js +252 -0
- package/dist/{XerticaXLogo-CQUUjXoH.cjs → XerticaXLogo-CziKMQil.cjs} +8 -8
- package/dist/XerticaXLogo-DHz5SugF.js +252 -0
- package/dist/XerticaXLogo-DTee_y8X.cjs +251 -0
- package/dist/{XerticaXLogo-Cmsp-Eey.js → XerticaXLogo-DfUvz-lD.js} +9 -9
- package/dist/XerticaXLogo-kslQ8Tk_.cjs +251 -0
- package/dist/{alert-dialog-s-vmNkJ_.js → alert-dialog-iDe5VE5o.js} +3 -3
- package/dist/{alert-dialog-DSKByiKZ.cjs → alert-dialog-yckpaOpy.cjs} +3 -3
- package/dist/cli.js +16 -6
- package/dist/components/ui/chart/chart.d.ts +7 -5
- package/dist/{google-maps-loader-Y-QkD-Li.cjs → google-maps-loader-BqsYL48U.cjs} +0 -5
- package/dist/{google-maps-loader-CTYySAun.js → google-maps-loader-t2IlYBzw.js} +0 -4
- package/dist/index-CkTUgOwX.js +8 -0
- package/dist/{index-COtD8bRW.cjs → index-D3RLKRAs.cjs} +1 -1
- package/dist/index.cjs.js +2 -2
- package/dist/index.es.js +2 -2
- package/dist/index.umd.js +454 -1027
- 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/{sidebar-DAaY8bRU.cjs → sidebar-B3EYhli0.cjs} +33 -24
- package/dist/{sidebar-nzPoVHBQ.cjs → sidebar-B9NR0lCe.cjs} +46 -41
- package/dist/{sidebar-CeTMuzOx.cjs → sidebar-BvF5I2Ue.cjs} +47 -128
- package/dist/{sidebar-q7P2Godd.cjs → sidebar-C5B_LHek.cjs} +1 -1
- package/dist/{sidebar-CrQDDdcz.js → sidebar-CA6_ek3f.js} +33 -24
- package/dist/sidebar-CLmIjgNd.cjs +1136 -0
- package/dist/{sidebar-BxGXsDAd.cjs → sidebar-CVUGHOS_.cjs} +8 -16
- package/dist/{sidebar-BViy8Eeu.js → sidebar-CmvwjnVb.js} +9 -17
- package/dist/{sidebar-B6SlKZYN.js → sidebar-CplprZpM.js} +49 -40
- package/dist/sidebar-Duermn32.js +1133 -0
- package/dist/{sidebar-BbVIQvlP.js → sidebar-Dz7bd3zP.js} +1 -1
- package/dist/{sidebar-0ocFLSks.js → sidebar-KIS0C2JH.js} +50 -127
- package/dist/sidebar-OTO_up7Z.js +801 -0
- package/dist/sidebar-zowjejT2.cjs +800 -0
- package/dist/{use-audio-player-nv8ZSGa1.js → use-audio-player-Bkh23vQ3.js} +3 -7
- package/dist/{use-audio-player-NKsWyjWu.cjs → use-audio-player-Dn1NR9xN.cjs} +3 -7
- package/dist/{xertica-assistant-dyP7KHM5.cjs → xertica-assistant-B1IaHXnB.cjs} +388 -529
- package/dist/{xertica-assistant-ciJaWqm1.js → xertica-assistant-BMqdyRVi.js} +10 -28
- package/dist/{xertica-assistant-V_IdW4WF.cjs → xertica-assistant-Bj3vBCq_.cjs} +9 -27
- package/dist/{xertica-assistant-yX1CFBBo.js → xertica-assistant-DPsESB6t.js} +390 -531
- package/dist/{CodeBlock-7TTgmdGG.cjs → xertica-assistant-Qp3ydksa.cjs} +51 -263
- package/dist/{CodeBlock-BeSt1h5P.js → xertica-assistant-gnCJdcZY.js} +7 -219
- package/dist/xertica-ui.css +2 -2
- package/docs/architecture-improvements.md +456 -456
- package/docs/architecture.md +312 -312
- package/docs/components/assistant.md +428 -428
- package/docs/components/branding.md +252 -252
- package/docs/components/card-patterns.md +447 -447
- package/docs/components/error-boundary.md +201 -201
- package/docs/components/hooks.md +432 -432
- package/docs/components/language-selector.md +176 -176
- package/docs/components/pages.md +323 -323
- package/docs/components/sidebar.md +331 -331
- package/docs/components/stats-card.md +138 -138
- package/docs/doc-audit.md +244 -244
- package/docs/getting-started.md +616 -616
- package/docs/guidelines.md +330 -330
- package/docs/i18n.md +480 -480
- package/docs/installation.md +268 -268
- package/docs/llms.md +295 -295
- package/docs/state-management.md +289 -289
- package/guidelines/Guidelines.md +409 -409
- package/llms-compact.txt +1 -1
- package/llms-full.txt +10688 -10688
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/styles/xertica/base.css +90 -90
- package/styles/xertica/tokens.css +240 -240
- package/templates/.prettierignore +4 -4
- package/templates/.prettierrc +10 -10
- package/templates/CLAUDE.md +180 -180
- package/templates/package.json +2 -2
- package/templates/src/app/App.tsx +46 -46
- package/templates/src/app/components/AuthGuard.tsx +131 -131
- package/templates/src/features/assistant/data/mock.ts +75 -75
- package/templates/src/features/assistant/hooks/useAssistantConfig.ts +20 -20
- package/templates/src/features/assistant/index.ts +5 -5
- package/templates/src/features/auth/ui/ForgotPasswordContent.tsx +70 -70
- package/templates/src/features/auth/ui/LoginContent.tsx +92 -92
- package/templates/src/features/auth/ui/ResetPasswordContent.tsx +183 -183
- package/templates/src/features/auth/ui/SocialLoginButtons.tsx +78 -78
- package/templates/src/features/auth/ui/VerifyEmailContent.tsx +80 -80
- package/templates/src/features/home/data/mock.ts +41 -41
- package/templates/src/features/home/hooks/useFeatureCards.ts +20 -20
- package/templates/src/features/home/index.ts +11 -11
- package/templates/src/features/home/ui/HomeContent.tsx +117 -117
- package/templates/src/features/template/ui/CrudTemplate.tsx +112 -112
- package/templates/src/features/template/ui/DashboardTemplate.tsx +110 -110
- package/templates/src/features/template/ui/FormTemplate.tsx +117 -117
- package/templates/src/features/template/ui/LoginTemplate.tsx +59 -59
- package/templates/src/features/template/ui/TemplateContent.tsx +1322 -1322
- package/templates/src/i18n.ts +124 -124
- package/templates/src/locales/en/common.json +21 -21
- package/templates/src/locales/en/components/activityCard.json +10 -10
- package/templates/src/locales/en/components/assistant.json +119 -119
- package/templates/src/locales/en/components/media.json +29 -29
- package/templates/src/locales/en/components/notificationCard.json +5 -5
- package/templates/src/locales/en/components/profileCard.json +8 -8
- package/templates/src/locales/en/components/projectCard.json +10 -10
- package/templates/src/locales/en/components/sidebar.json +14 -14
- package/templates/src/locales/en/components/stats.json +8 -8
- package/templates/src/locales/en/components/team.json +14 -14
- package/templates/src/locales/en/errors.json +9 -9
- package/templates/src/locales/en/languageSelector.json +7 -7
- package/templates/src/locales/en/nav.json +6 -6
- package/templates/src/locales/en/pages/crudTemplate.json +25 -25
- package/templates/src/locales/en/pages/dashboardTemplate.json +20 -20
- package/templates/src/locales/en/pages/forgotPassword.json +10 -10
- package/templates/src/locales/en/pages/formTemplate.json +16 -16
- package/templates/src/locales/en/pages/home.json +7 -7
- package/templates/src/locales/en/pages/login.json +15 -15
- package/templates/src/locales/en/pages/loginTemplate.json +9 -9
- package/templates/src/locales/en/pages/resetPassword.json +18 -18
- package/templates/src/locales/en/pages/templates.json +317 -317
- package/templates/src/locales/en/pages/verifyEmail.json +12 -12
- package/templates/src/locales/en/themeToggle.json +6 -6
- package/templates/src/locales/es/common.json +21 -21
- package/templates/src/locales/es/components/activityCard.json +10 -10
- package/templates/src/locales/es/components/assistant.json +119 -119
- package/templates/src/locales/es/components/media.json +29 -29
- package/templates/src/locales/es/components/notificationCard.json +5 -5
- package/templates/src/locales/es/components/profileCard.json +8 -8
- package/templates/src/locales/es/components/projectCard.json +10 -10
- package/templates/src/locales/es/components/sidebar.json +14 -14
- package/templates/src/locales/es/components/stats.json +8 -8
- package/templates/src/locales/es/components/team.json +14 -14
- package/templates/src/locales/es/errors.json +9 -9
- package/templates/src/locales/es/languageSelector.json +7 -7
- package/templates/src/locales/es/nav.json +6 -6
- package/templates/src/locales/es/pages/crudTemplate.json +25 -25
- package/templates/src/locales/es/pages/dashboardTemplate.json +20 -20
- package/templates/src/locales/es/pages/forgotPassword.json +10 -10
- package/templates/src/locales/es/pages/formTemplate.json +16 -16
- package/templates/src/locales/es/pages/home.json +7 -7
- package/templates/src/locales/es/pages/login.json +15 -15
- package/templates/src/locales/es/pages/loginTemplate.json +9 -9
- package/templates/src/locales/es/pages/resetPassword.json +18 -18
- package/templates/src/locales/es/pages/templates.json +317 -317
- package/templates/src/locales/es/pages/verifyEmail.json +12 -12
- package/templates/src/locales/es/themeToggle.json +6 -6
- package/templates/src/locales/pt-BR/common.json +21 -21
- package/templates/src/locales/pt-BR/components/activityCard.json +10 -10
- package/templates/src/locales/pt-BR/components/assistant.json +119 -119
- package/templates/src/locales/pt-BR/components/media.json +29 -29
- package/templates/src/locales/pt-BR/components/notificationCard.json +5 -5
- package/templates/src/locales/pt-BR/components/profileCard.json +8 -8
- package/templates/src/locales/pt-BR/components/projectCard.json +10 -10
- package/templates/src/locales/pt-BR/components/sidebar.json +14 -14
- package/templates/src/locales/pt-BR/components/stats.json +8 -8
- package/templates/src/locales/pt-BR/components/team.json +14 -14
- package/templates/src/locales/pt-BR/errors.json +9 -9
- package/templates/src/locales/pt-BR/languageSelector.json +7 -7
- package/templates/src/locales/pt-BR/nav.json +6 -6
- package/templates/src/locales/pt-BR/pages/crudTemplate.json +25 -25
- package/templates/src/locales/pt-BR/pages/dashboardTemplate.json +20 -20
- package/templates/src/locales/pt-BR/pages/forgotPassword.json +10 -10
- package/templates/src/locales/pt-BR/pages/formTemplate.json +16 -16
- package/templates/src/locales/pt-BR/pages/home.json +7 -7
- package/templates/src/locales/pt-BR/pages/login.json +15 -15
- package/templates/src/locales/pt-BR/pages/loginTemplate.json +9 -9
- package/templates/src/locales/pt-BR/pages/resetPassword.json +18 -18
- package/templates/src/locales/pt-BR/pages/templates.json +317 -317
- package/templates/src/locales/pt-BR/pages/verifyEmail.json +12 -12
- package/templates/src/locales/pt-BR/themeToggle.json +6 -6
- package/templates/src/pages/AssistantPage.tsx +470 -470
- package/templates/src/pages/HomePage.tsx +53 -53
- package/templates/src/shared/error-boundary.tsx +150 -150
- package/templates/src/shared/error-fallbacks.tsx +222 -222
- package/templates/src/styles/xertica/tokens.css +240 -240
- package/templates/vite.config.js +20 -20
- package/templates/vite.config.ts +55 -55
- package/dist/AssistantChart-BKVtGUKF.js +0 -3383
- package/dist/AssistantChart-CxGjH7Qk.js +0 -3477
- package/dist/AssistantChart-DIpshm3i.js +0 -4784
- package/dist/AssistantChart-D_PTeu8P.cjs +0 -3503
- package/dist/AssistantChart-WeycT5Pd.cjs +0 -3551
- package/dist/AssistantChart-zjsy2GaZ.cjs +0 -4810
- package/dist/AudioPlayer-B1lt5cPl.cjs +0 -989
- package/dist/AudioPlayer-BZ7bibzU.cjs +0 -982
- package/dist/AudioPlayer-BpRPS4-1.cjs +0 -1277
- package/dist/AudioPlayer-C12BjQBV.cjs +0 -997
- package/dist/AudioPlayer-CFeV8t-5.cjs +0 -936
- package/dist/AudioPlayer-Coly3q5R.js +0 -1278
- package/dist/AudioPlayer-CySJIyvL.js +0 -937
- package/dist/AudioPlayer-DMcG_c7L.js +0 -990
- package/dist/AudioPlayer-DcFKRJE_.js +0 -998
- package/dist/AudioPlayer-e8LfNoqO.js +0 -983
- package/dist/BrandColorsContext-565dDHd5.js +0 -660
- package/dist/BrandColorsContext-BcJbtkqn.cjs +0 -659
- package/dist/CodeBlock-BgfYL_rD.cjs +0 -2094
- package/dist/CodeBlock-BlcqlA9M.cjs +0 -2094
- package/dist/CodeBlock-Bnmeu5ez.cjs +0 -2094
- package/dist/CodeBlock-BtfPlbAI.js +0 -2078
- package/dist/CodeBlock-CIySIuYr.js +0 -2078
- package/dist/CodeBlock-CuPtUM-7.cjs +0 -2094
- package/dist/CodeBlock-D6ffWXgc.js +0 -2078
- package/dist/CodeBlock-D8dcwbit.cjs +0 -2094
- package/dist/CodeBlock-DMZrFnlw.cjs +0 -2094
- package/dist/CodeBlock-DlBehYN8.js +0 -2078
- package/dist/CodeBlock-DnYNI8rQ.js +0 -2078
- package/dist/CodeBlock-DvKWbSnE.cjs +0 -2094
- package/dist/CodeBlock-DwMCfkFY.js +0 -2078
- package/dist/CodeBlock-Dy6CNYyj.js +0 -2078
- package/dist/CodeBlock-U1pPOQI7.cjs +0 -2094
- package/dist/CodeBlock-f_GpNhEB.js +0 -2078
- package/dist/CodeBlock-oB6u8nI1.js +0 -2078
- package/dist/CodeBlock-tZC31B73.cjs +0 -2094
- package/dist/FeatureCard-CxC-7C-C.cjs +0 -300
- package/dist/FeatureCard-DbHWCb4E.js +0 -301
- package/dist/ImageWithFallback-CGtidP6B.cjs +0 -4542
- package/dist/ImageWithFallback-lsg3pdFg.js +0 -4508
- package/dist/LanguageSelector-B5YfbHra.js +0 -231
- package/dist/LanguageSelector-D6uacAIM.cjs +0 -230
- package/dist/LayoutContext-B45-e9DI.cjs +0 -93
- package/dist/LayoutContext-BAql6ZRY.js +0 -97
- package/dist/LayoutContext-Bav3UMEA.js +0 -94
- package/dist/LayoutContext-BvK-ggDa.cjs +0 -96
- package/dist/ThemeContext-BoH4NLfN.js +0 -734
- package/dist/ThemeContext-r69W20Xg.cjs +0 -733
- package/dist/VerifyEmailPage-COiyNl1y.js +0 -2825
- package/dist/VerifyEmailPage-CqKsR2v8.js +0 -2827
- package/dist/VerifyEmailPage-DjQKRlUS.cjs +0 -2824
- package/dist/VerifyEmailPage-s-1X3LDJ.cjs +0 -2826
- package/dist/XerticaOrbe-KL1RBHzw.cjs +0 -1354
- package/dist/XerticaOrbe-zwS1p2a8.js +0 -1355
- package/dist/XerticaProvider-6btlAlzc.js +0 -17
- package/dist/XerticaProvider-BNoNOxQ5.cjs +0 -16
- package/dist/XerticaProvider-BlY2limY.cjs +0 -38
- package/dist/XerticaProvider-DDuiIcKo.js +0 -39
- package/dist/XerticaProvider-cI9hSs27.cjs +0 -38
- package/dist/XerticaProvider-hSwhNQex.js +0 -39
- package/dist/alert-dialog-BOje--vD.js +0 -847
- package/dist/alert-dialog-BtEuQqrg.cjs +0 -870
- package/dist/breadcrumb-CqJ7bHY5.js +0 -161
- package/dist/breadcrumb-m9Hb2_XN.cjs +0 -177
- package/dist/components/assistant/xertica-assistant/hooks/index.d.ts +0 -6
- package/dist/components/assistant/xertica-assistant/hooks/use-assistant-conversations.d.ts +0 -21
- package/dist/components/assistant/xertica-assistant/hooks/use-assistant-messages.d.ts +0 -49
- package/dist/components/assistant/xertica-assistant/hooks/use-assistant-suggestions.d.ts +0 -16
- package/dist/components/blocks/audio-player/AudioPlayer.d.ts +0 -35
- package/dist/components/blocks/audio-player/index.d.ts +0 -1
- package/dist/components/blocks/document-editor/DocumentEditor.d.ts +0 -26
- package/dist/components/blocks/document-editor/index.d.ts +0 -1
- package/dist/components/blocks/podcast-player/PodcastPlayer.d.ts +0 -41
- package/dist/components/blocks/podcast-player/index.d.ts +0 -1
- package/dist/components/ui/chart/parts/chart-dashboard.d.ts +0 -113
- package/dist/components/ui/chart/parts/chart-metric.d.ts +0 -118
- package/dist/components/ui/chart/parts/chart-primitives.d.ts +0 -101
- package/dist/components/ui/chart/parts/chart-shared.d.ts +0 -20
- package/dist/components/ui/chart/parts/chart-utils.d.ts +0 -12
- package/dist/components/ui/chart/parts/index.d.ts +0 -5
- package/dist/dropdown-menu-BDB5CmQs.cjs +0 -247
- package/dist/dropdown-menu-DQidbKBD.js +0 -231
- package/dist/google-maps-loader-BFWp6VPd.js +0 -287
- package/dist/google-maps-loader-BKcdgFbu.cjs +0 -312
- package/dist/google-maps-loader-CumCNXeG.js +0 -312
- package/dist/google-maps-loader-eS3uQ5TA.cjs +0 -287
- package/dist/header-Cgy6vYPk.cjs +0 -731
- package/dist/header-DRlT4jgI.js +0 -715
- package/dist/header-Dux00SI4.cjs +0 -731
- package/dist/header-EkGKXPsD.js +0 -715
- package/dist/header-WfEywpyc.cjs +0 -731
- package/dist/header-tifNQn2U.js +0 -715
- package/dist/index-BhapVLVj.js +0 -8
- package/dist/index-D6fxYEY8.cjs +0 -7
- package/dist/index-DAIp0_HK.js +0 -8
- package/dist/index-DW5tYe26.js +0 -8
- package/dist/index-GA__GvnG.cjs +0 -7
- package/dist/input-2R4loU86.js +0 -127
- package/dist/input-DWANSKGb.cjs +0 -145
- package/dist/progress-DPtzoVV8.js +0 -175
- package/dist/progress-EeaoqqUs.cjs +0 -191
- package/dist/rich-text-editor-0mraWT5y.cjs +0 -2376
- package/dist/rich-text-editor-B-IkcPD0.js +0 -2874
- package/dist/rich-text-editor-B6jMRLzk.cjs +0 -1939
- package/dist/rich-text-editor-B8_oYcIR.js +0 -1730
- package/dist/rich-text-editor-B9UbSXNb.js +0 -1203
- package/dist/rich-text-editor-BYuRBNBU.js +0 -2373
- package/dist/rich-text-editor-Bb9pySTs.cjs +0 -2374
- package/dist/rich-text-editor-BcL6L3cm.cjs +0 -2374
- package/dist/rich-text-editor-BoVZYtTs.cjs +0 -2391
- package/dist/rich-text-editor-Bp3zQqMC.js +0 -2954
- package/dist/rich-text-editor-CMgSN_w2.js +0 -1189
- package/dist/rich-text-editor-CPV1lEPH.cjs +0 -1748
- package/dist/rich-text-editor-CeucBdIv.cjs +0 -2971
- package/dist/rich-text-editor-CoKqbCtu.cjs +0 -1799
- package/dist/rich-text-editor-Cw56T_mB.js +0 -2356
- package/dist/rich-text-editor-Cyt8qs2b.js +0 -1921
- package/dist/rich-text-editor-D6H84OcX.cjs +0 -1220
- package/dist/rich-text-editor-D76gD-QI.js +0 -2328
- package/dist/rich-text-editor-DKkokOnA.js +0 -1781
- package/dist/rich-text-editor-DNsdpN64.cjs +0 -2359
- package/dist/rich-text-editor-DfG8bCyY.js +0 -2358
- package/dist/rich-text-editor-Dxjw31Z4.js +0 -2341
- package/dist/rich-text-editor-DzP0Epmb.js +0 -2356
- package/dist/rich-text-editor-bRkNoeZY.cjs +0 -2891
- package/dist/rich-text-editor-lyYE2ZG5.cjs +0 -1207
- package/dist/rich-text-editor-skplNlBM.cjs +0 -2345
- package/dist/select-Bkbr0f-Z.cjs +0 -162
- package/dist/select-CvIVdX2n.js +0 -145
- package/dist/sidebar-CK_0ZQHj.cjs +0 -803
- package/dist/sidebar-CUuOvYhK.js +0 -787
- package/dist/sidebar-DQj1z3jG.cjs +0 -758
- package/dist/sidebar-Djn5syhi.cjs +0 -786
- package/dist/sidebar-LluMXfam.js +0 -759
- package/dist/sidebar-_rT7rBMk.js +0 -787
- package/dist/slider-Bc5Hd0y1.js +0 -56
- package/dist/slider-N7hFFj6X.cjs +0 -73
- package/dist/tooltip-Ded96neP.cjs +0 -137
- package/dist/tooltip-HDOoD2-0.js +0 -120
- package/dist/use-audio-player-B31J-aqh.cjs +0 -187
- package/dist/use-audio-player-BkmEmj8Q.js +0 -185
- package/dist/use-audio-player-CLFTWFW1.cjs +0 -184
- package/dist/use-audio-player-CLLn00I6.js +0 -188
- package/dist/use-file-upload-BcjEo2S5.js +0 -404
- package/dist/use-file-upload-CRJR68Tj.cjs +0 -403
- package/dist/use-mobile-B0hNy_Y6.cjs +0 -4303
- package/dist/use-mobile-BXuYROXM.js +0 -4202
- package/dist/use-mobile-Bbd51ASU.cjs +0 -4392
- package/dist/use-mobile-Bk6CX-TC.js +0 -4359
- package/dist/use-mobile-BvYdisLP.js +0 -4202
- package/dist/use-mobile-BzuxjzNX.cjs +0 -4392
- package/dist/use-mobile-CG2-SdXV.cjs +0 -4235
- package/dist/use-mobile-CKb5pqTs.js +0 -4269
- package/dist/use-mobile-CYuAuGDl.js +0 -4202
- package/dist/use-mobile-CaENcqm-.js +0 -4508
- package/dist/use-mobile-CbrYgJGJ.js +0 -4203
- package/dist/use-mobile-Cd4xPrKq.cjs +0 -46
- package/dist/use-mobile-DMOvImGQ.cjs +0 -4542
- package/dist/use-mobile-DRB3BQgD.cjs +0 -4235
- package/dist/use-mobile-DZvv7QMR.js +0 -4359
- package/dist/use-mobile-DdI_TXam.cjs +0 -4235
- package/dist/use-mobile-DlceKf8a.js +0 -4359
- package/dist/use-mobile-DsOnow1o.cjs +0 -4236
- package/dist/use-mobile-Kcj6jSnK.cjs +0 -4392
- package/dist/use-mobile-bnKcua_i.js +0 -4202
- package/dist/use-mobile-j4w2Jrf1.js +0 -30
- package/dist/use-mobile-ncXBeE2z.cjs +0 -4235
- package/dist/use-rich-text-editor-DjiddBGv.js +0 -282
- package/dist/use-rich-text-editor-lpeswbCs.cjs +0 -281
- package/dist/xertica-assistant-BdiZag0h.js +0 -2187
- package/dist/xertica-assistant-CrgTb6Hs.cjs +0 -2155
- package/dist/xertica-assistant-DCsnQyi5.js +0 -2156
- package/dist/xertica-assistant-DUBpmEgo.cjs +0 -2186
- package/dist/{rich-text-editor-DgF8s7xW.js → rich-text-editor-BmsjY03B.js} +26 -26
- package/dist/{rich-text-editor-mWoaSCE4.cjs → rich-text-editor-GS2kpTAK.cjs} +26 -26
|
@@ -1,447 +1,447 @@
|
|
|
1
|
-
# Card Patterns
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
Pre-composed card blocks for dashboards, project management, and feature pages. Each component is built exclusively from `ui/` primitives — no external dependencies. They live in `components/blocks/card-patterns/` and are available from the root `xertica-ui` import.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## When to Use
|
|
10
|
-
|
|
11
|
-
- You need a recurring dashboard pattern (activity feed, KPI, project status, notifications) and don't want to re-compose it from scratch in every feature.
|
|
12
|
-
- The pattern is stable and reused across multiple pages.
|
|
13
|
-
|
|
14
|
-
## When NOT to Use
|
|
15
|
-
|
|
16
|
-
- One-off layouts specific to a single page — compose directly from `Card` and `ui/` primitives instead.
|
|
17
|
-
- When the pattern has significant data-fetching logic — keep the block as a pure presentational component and handle state in the feature layer.
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Import
|
|
22
|
-
|
|
23
|
-
```tsx
|
|
24
|
-
// from root barrel
|
|
25
|
-
import { ActivityCard, ProjectCard, FeatureCard } from 'xertica-ui';
|
|
26
|
-
|
|
27
|
-
// or from blocks subpath (when available)
|
|
28
|
-
import { ActivityCard, ProjectCard, FeatureCard } from 'xertica-ui/blocks';
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## Components
|
|
34
|
-
|
|
35
|
-
### FeatureCard
|
|
36
|
-
|
|
37
|
-
Icon with a colored background, title, optional badge, description, and an action button. Matches the card pattern used on the Home page.
|
|
38
|
-
|
|
39
|
-
```tsx
|
|
40
|
-
import { FeatureCard } from 'xertica-ui';
|
|
41
|
-
import { FileText } from 'lucide-react';
|
|
42
|
-
|
|
43
|
-
<FeatureCard
|
|
44
|
-
title="Template CLI"
|
|
45
|
-
description="Página de template pronta para uso com todos os componentes configurados."
|
|
46
|
-
icon={<FileText />}
|
|
47
|
-
color="chart-2"
|
|
48
|
-
badge="Novo"
|
|
49
|
-
actionLabel="Visualizar"
|
|
50
|
-
onAction={() => navigate('/template')}
|
|
51
|
-
/>;
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
**Props:**
|
|
55
|
-
|
|
56
|
-
| Prop | Type | Default | Description |
|
|
57
|
-
| --------------- | ------------------ | ----------- | -------------------------------------------- |
|
|
58
|
-
| `title` | `string` | — | Card title |
|
|
59
|
-
| `description` | `string` | — | Body text |
|
|
60
|
-
| `icon` | `ReactNode` | — | Icon element (size is controlled internally) |
|
|
61
|
-
| `color` | `FeatureCardColor` | `'primary'` | Icon background color token |
|
|
62
|
-
| `badge` | `string` | — | Optional badge label |
|
|
63
|
-
| `badgeVariant` | `BadgeVariant` | `'default'` | Badge color variant |
|
|
64
|
-
| `actionLabel` | `string` | — | Button label (omit to hide button) |
|
|
65
|
-
| `actionVariant` | `ButtonVariant` | `'outline'` | Button variant |
|
|
66
|
-
| `onAction` | `() => void` | — | Button click handler |
|
|
67
|
-
|
|
68
|
-
**`FeatureCardColor` values:** `primary` · `chart-1` · `chart-2` · `chart-3` · `chart-4` · `chart-5` · `success` · `info` · `warning` · `destructive`
|
|
69
|
-
|
|
70
|
-
---
|
|
71
|
-
|
|
72
|
-
### ActivityCard
|
|
73
|
-
|
|
74
|
-
Chronological feed of user actions with avatar, action description, timestamp, and type badge.
|
|
75
|
-
|
|
76
|
-
```tsx
|
|
77
|
-
import { ActivityCard } from 'xertica-ui';
|
|
78
|
-
|
|
79
|
-
<ActivityCard
|
|
80
|
-
title="Atividade Recente"
|
|
81
|
-
items={[
|
|
82
|
-
{
|
|
83
|
-
id: '1',
|
|
84
|
-
user: { name: 'Ana Souza', initials: 'AS' },
|
|
85
|
-
action: 'criou o projeto',
|
|
86
|
-
target: 'Xertica Dashboard',
|
|
87
|
-
time: 'há 2 min',
|
|
88
|
-
type: 'create',
|
|
89
|
-
},
|
|
90
|
-
]}
|
|
91
|
-
action={
|
|
92
|
-
<Button variant="ghost" size="sm">
|
|
93
|
-
Ver tudo
|
|
94
|
-
</Button>
|
|
95
|
-
}
|
|
96
|
-
maxItems={5}
|
|
97
|
-
/>;
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
**Props:**
|
|
101
|
-
|
|
102
|
-
| Prop | Type | Default | Description |
|
|
103
|
-
| ---------- | ---------------- | --------------------- | --------------------------- |
|
|
104
|
-
| `title` | `string` | `'Atividade Recente'` | Card title |
|
|
105
|
-
| `items` | `ActivityItem[]` | — | Feed entries |
|
|
106
|
-
| `action` | `ReactNode` | — | Right-aligned header action |
|
|
107
|
-
| `maxItems` | `number` | `5` | Maximum visible items |
|
|
108
|
-
|
|
109
|
-
**`ActivityItem` shape:**
|
|
110
|
-
|
|
111
|
-
```ts
|
|
112
|
-
{
|
|
113
|
-
id: string
|
|
114
|
-
user: { name: string; initials: string; avatar?: string }
|
|
115
|
-
action: string // verb: "criou", "atualizou", etc.
|
|
116
|
-
target: string // object of the action
|
|
117
|
-
time: string // relative time string
|
|
118
|
-
type?: 'create' | 'update' | 'delete' | 'comment' | 'deploy'
|
|
119
|
-
}
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
---
|
|
123
|
-
|
|
124
|
-
### ProfileCard
|
|
125
|
-
|
|
126
|
-
User or team member card with avatar, status badge, stat row, and primary/secondary actions.
|
|
127
|
-
|
|
128
|
-
```tsx
|
|
129
|
-
import { ProfileCard } from 'xertica-ui';
|
|
130
|
-
|
|
131
|
-
<ProfileCard
|
|
132
|
-
name="Ana Souza"
|
|
133
|
-
role="Senior Frontend Engineer"
|
|
134
|
-
department="Design System"
|
|
135
|
-
initials="AS"
|
|
136
|
-
status="online"
|
|
137
|
-
stats={[
|
|
138
|
-
{ label: 'Projetos', value: 12 },
|
|
139
|
-
{ label: 'Commits', value: 348 },
|
|
140
|
-
{ label: 'Reviews', value: 57 },
|
|
141
|
-
]}
|
|
142
|
-
primaryAction={{ label: 'Ver Perfil' }}
|
|
143
|
-
secondaryAction={{ label: 'Mensagem' }}
|
|
144
|
-
/>;
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
**Props:**
|
|
148
|
-
|
|
149
|
-
| Prop | Type | Default | Description |
|
|
150
|
-
| ----------------- | ---------------------------------------------- | ------- | -------------------------------- |
|
|
151
|
-
| `name` | `string` | — | Full name |
|
|
152
|
-
| `role` | `string` | — | Job title |
|
|
153
|
-
| `department` | `string` | — | Department or team |
|
|
154
|
-
| `initials` | `string` | — | Avatar fallback (2 chars) |
|
|
155
|
-
| `avatar` | `string` | — | Avatar image URL |
|
|
156
|
-
| `status` | `'online' \| 'offline' \| 'away' \| 'busy'` | — | Presence badge |
|
|
157
|
-
| `stats` | `{ label: string; value: string \| number }[]` | — | Up to 3 stats in the divider row |
|
|
158
|
-
| `primaryAction` | `{ label: string; onClick?: () => void }` | — | Primary button |
|
|
159
|
-
| `secondaryAction` | `{ label: string; onClick?: () => void }` | — | Secondary (outline) button |
|
|
160
|
-
|
|
161
|
-
---
|
|
162
|
-
|
|
163
|
-
### ProjectCard
|
|
164
|
-
|
|
165
|
-
Project status widget with title, description, status badge, progress bar, member avatar stack, and due date.
|
|
166
|
-
|
|
167
|
-
```tsx
|
|
168
|
-
import { ProjectCard } from 'xertica-ui';
|
|
169
|
-
|
|
170
|
-
<ProjectCard
|
|
171
|
-
title="Xertica Dashboard v3"
|
|
172
|
-
description="Redesign completo do painel."
|
|
173
|
-
status="active"
|
|
174
|
-
progress={68}
|
|
175
|
-
dueDate="Vence em 12 dias"
|
|
176
|
-
members={[
|
|
177
|
-
{ name: 'Ana', initials: 'AS' },
|
|
178
|
-
{ name: 'Bruno', initials: 'BL' },
|
|
179
|
-
]}
|
|
180
|
-
/>;
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
**Props:**
|
|
184
|
-
|
|
185
|
-
| Prop | Type | Default | Description |
|
|
186
|
-
| ------------- | ----------------- | ------- | ----------------------------------------- |
|
|
187
|
-
| `title` | `string` | — | Project name |
|
|
188
|
-
| `description` | `string` | — | Short description |
|
|
189
|
-
| `status` | `ProjectStatus` | — | Controls badge color and progress color |
|
|
190
|
-
| `progress` | `number` | — | 0–100 completion percentage |
|
|
191
|
-
| `dueDate` | `string` | — | Due date label string |
|
|
192
|
-
| `members` | `ProjectMember[]` | `[]` | Avatar stack |
|
|
193
|
-
| `maxMembers` | `number` | `4` | Max visible avatars before overflow count |
|
|
194
|
-
| `action` | `ReactNode` | — | Extra action appended to the status badge |
|
|
195
|
-
|
|
196
|
-
**`ProjectStatus` values:** `active` · `review` · `done` · `paused` · `at-risk`
|
|
197
|
-
|
|
198
|
-
---
|
|
199
|
-
|
|
200
|
-
### QuickActionCard
|
|
201
|
-
|
|
202
|
-
Action tile with icon in colored box, title, description, optional badge, and a full-width action button.
|
|
203
|
-
|
|
204
|
-
```tsx
|
|
205
|
-
import { QuickActionCard } from 'xertica-ui';
|
|
206
|
-
import { FileText } from 'lucide-react';
|
|
207
|
-
|
|
208
|
-
<QuickActionCard
|
|
209
|
-
title="Novo Relatório"
|
|
210
|
-
description="Gere relatórios personalizados de métricas."
|
|
211
|
-
icon={<FileText className="size-5" />}
|
|
212
|
-
actionLabel="Criar Relatório"
|
|
213
|
-
badge="Pro"
|
|
214
|
-
badgeVariant="warning"
|
|
215
|
-
onAction={() => openReportModal()}
|
|
216
|
-
/>;
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
**Props:**
|
|
220
|
-
|
|
221
|
-
| Prop | Type | Default | Description |
|
|
222
|
-
| --------------- | --------------- | ------------- | ------------------------ |
|
|
223
|
-
| `title` | `string` | — | Tile title |
|
|
224
|
-
| `description` | `string` | — | Supporting text |
|
|
225
|
-
| `icon` | `ReactNode` | — | Icon in the colored box |
|
|
226
|
-
| `badge` | `string` | — | Optional badge |
|
|
227
|
-
| `badgeVariant` | `BadgeVariant` | `'secondary'` | Badge color variant |
|
|
228
|
-
| `actionLabel` | `string` | — | Button label |
|
|
229
|
-
| `actionVariant` | `ButtonVariant` | `'default'` | Button variant |
|
|
230
|
-
| `onAction` | `() => void` | — | Button click handler |
|
|
231
|
-
| `disabled` | `boolean` | `false` | Disables the entire card |
|
|
232
|
-
|
|
233
|
-
---
|
|
234
|
-
|
|
235
|
-
### NotificationCard
|
|
236
|
-
|
|
237
|
-
Notification list with unread indicator dots, type badges, timestamps, and bulk mark-as-read action.
|
|
238
|
-
|
|
239
|
-
```tsx
|
|
240
|
-
import { NotificationCard } from 'xertica-ui';
|
|
241
|
-
|
|
242
|
-
<NotificationCard
|
|
243
|
-
title="Notificações"
|
|
244
|
-
items={[
|
|
245
|
-
{
|
|
246
|
-
id: '1',
|
|
247
|
-
title: 'Deploy concluído',
|
|
248
|
-
message: 'v2.1.0 publicado com sucesso.',
|
|
249
|
-
time: 'há 2 min',
|
|
250
|
-
read: false,
|
|
251
|
-
type: 'success',
|
|
252
|
-
},
|
|
253
|
-
]}
|
|
254
|
-
onMarkAllRead={() => markAllRead()}
|
|
255
|
-
onViewAll={() => navigate('/notifications')}
|
|
256
|
-
maxItems={4}
|
|
257
|
-
/>;
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
**Props:**
|
|
261
|
-
|
|
262
|
-
| Prop | Type | Default | Description |
|
|
263
|
-
| --------------- | -------------------- | ---------------- | ----------------------------------------------- |
|
|
264
|
-
| `title` | `string` | `'Notificações'` | Card title |
|
|
265
|
-
| `items` | `NotificationItem[]` | — | Notification entries |
|
|
266
|
-
| `unreadCount` | `number` | auto-counted | Override unread count badge |
|
|
267
|
-
| `onMarkAllRead` | `() => void` | — | Shows "Marcar todas como lidas" button when set |
|
|
268
|
-
| `onViewAll` | `() => void` | — | Shows "Ver todas" footer button when set |
|
|
269
|
-
| `maxItems` | `number` | `4` | Maximum visible items |
|
|
270
|
-
|
|
271
|
-
**`NotificationItem` shape:**
|
|
272
|
-
|
|
273
|
-
```ts
|
|
274
|
-
{
|
|
275
|
-
id: string
|
|
276
|
-
title: string
|
|
277
|
-
message: string
|
|
278
|
-
time: string
|
|
279
|
-
read?: boolean
|
|
280
|
-
type?: 'info' | 'warning' | 'success' | 'error' | 'default'
|
|
281
|
-
user?: { name: string; initials: string; avatar?: string }
|
|
282
|
-
}
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
---
|
|
286
|
-
|
|
287
|
-
## Dashboard Layout Example
|
|
288
|
-
|
|
289
|
-
```tsx
|
|
290
|
-
import {
|
|
291
|
-
ActivityCard,
|
|
292
|
-
ChartCard,
|
|
293
|
-
NotificationCard,
|
|
294
|
-
ProfileCard,
|
|
295
|
-
ProjectCard,
|
|
296
|
-
QuickActionCard,
|
|
297
|
-
} from 'xertica-ui';
|
|
298
|
-
import { DashboardLineChart } from 'xertica-ui/ui';
|
|
299
|
-
import { Briefcase, Users, BarChart2 } from 'lucide-react';
|
|
300
|
-
|
|
301
|
-
<div className="grid gap-4">
|
|
302
|
-
{/* Quick actions row */}
|
|
303
|
-
<div className="grid gap-4 md:grid-cols-3">
|
|
304
|
-
<QuickActionCard title="Novo Projeto" icon={<Briefcase />} actionLabel="Criar" />
|
|
305
|
-
<QuickActionCard
|
|
306
|
-
title="Convidar Equipe"
|
|
307
|
-
icon={<Users />}
|
|
308
|
-
actionLabel="Convidar"
|
|
309
|
-
actionVariant="outline"
|
|
310
|
-
/>
|
|
311
|
-
<QuickActionCard
|
|
312
|
-
title="Relatórios"
|
|
313
|
-
icon={<BarChart2 />}
|
|
314
|
-
actionLabel="Abrir"
|
|
315
|
-
badge="Novo"
|
|
316
|
-
badgeVariant="success"
|
|
317
|
-
/>
|
|
318
|
-
</div>
|
|
319
|
-
|
|
320
|
-
{/* Chart + Notifications */}
|
|
321
|
-
<div className="grid gap-4 md:grid-cols-3">
|
|
322
|
-
<div className="md:col-span-2">
|
|
323
|
-
<ChartCard title="Usuários Ativos" description="Esta semana" contentClassName="h-[220px]">
|
|
324
|
-
<DashboardLineChart
|
|
325
|
-
data={lineData}
|
|
326
|
-
config={lineConfig}
|
|
327
|
-
series={[{ key: 'usuarios', label: 'Usuários' }]}
|
|
328
|
-
indexKey="dia"
|
|
329
|
-
className="h-full w-full"
|
|
330
|
-
/>
|
|
331
|
-
</ChartCard>
|
|
332
|
-
</div>
|
|
333
|
-
<NotificationCard title="Alertas" items={notifications} onViewAll={() => {}} />
|
|
334
|
-
</div>
|
|
335
|
-
|
|
336
|
-
{/* Activity + Profile + Project */}
|
|
337
|
-
<div className="grid gap-4 md:grid-cols-2">
|
|
338
|
-
<ActivityCard items={activityItems} />
|
|
339
|
-
<div className="grid gap-4">
|
|
340
|
-
<ProfileCard
|
|
341
|
-
name="Ana Souza"
|
|
342
|
-
role="Designer"
|
|
343
|
-
initials="AS"
|
|
344
|
-
status="online"
|
|
345
|
-
stats={[{ label: 'Projetos', value: 12 }]}
|
|
346
|
-
/>
|
|
347
|
-
<ProjectCard
|
|
348
|
-
title="Dashboard v3"
|
|
349
|
-
status="active"
|
|
350
|
-
progress={68}
|
|
351
|
-
dueDate="12 dias"
|
|
352
|
-
members={members}
|
|
353
|
-
/>
|
|
354
|
-
</div>
|
|
355
|
-
</div>
|
|
356
|
-
</div>;
|
|
357
|
-
```
|
|
358
|
-
|
|
359
|
-
---
|
|
360
|
-
|
|
361
|
-
## Loading States — Skeleton Components
|
|
362
|
-
|
|
363
|
-
Every card pattern ships with a matching `*Skeleton` companion that mirrors its layout with pulsing placeholders. Use them while data is loading to avoid layout shift and provide visual feedback.
|
|
364
|
-
|
|
365
|
-
| Card | Skeleton companion | Configurable props |
|
|
366
|
-
| ------------------ | -------------------------- | ----------------------------------- |
|
|
367
|
-
| `ActivityCard` | `ActivityCardSkeleton` | `rows` (default `5`) |
|
|
368
|
-
| `ProfileCard` | `ProfileCardSkeleton` | `showStats`, `showActions` |
|
|
369
|
-
| `ProjectCard` | `ProjectCardSkeleton` | `memberCount` (default `3`) |
|
|
370
|
-
| `NotificationCard` | `NotificationCardSkeleton` | `rows` (default `4`), `showViewAll` |
|
|
371
|
-
| `QuickActionCard` | `QuickActionCardSkeleton` | — |
|
|
372
|
-
| `FeatureCard` | `FeatureCardSkeleton` | `showAction` |
|
|
373
|
-
|
|
374
|
-
> A matching `StatsCardSkeleton` is also available from `xertica-ui` (lives in `ui/stats-card/`, with props `showIcon` and `showTrend`).
|
|
375
|
-
|
|
376
|
-
### Usage pattern
|
|
377
|
-
|
|
378
|
-
```tsx
|
|
379
|
-
import { useQuery } from '@tanstack/react-query';
|
|
380
|
-
import { ActivityCard, ActivityCardSkeleton } from 'xertica-ui';
|
|
381
|
-
|
|
382
|
-
function ActivityFeed() {
|
|
383
|
-
const { data: items, isLoading } = useActivityItems();
|
|
384
|
-
|
|
385
|
-
if (isLoading) return <ActivityCardSkeleton rows={5} />;
|
|
386
|
-
return <ActivityCard items={items!} />;
|
|
387
|
-
}
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
For grids, render one skeleton per expected card:
|
|
391
|
-
|
|
392
|
-
```tsx
|
|
393
|
-
{
|
|
394
|
-
isLoading ? (
|
|
395
|
-
<>
|
|
396
|
-
<FeatureCardSkeleton showAction />
|
|
397
|
-
<FeatureCardSkeleton showAction />
|
|
398
|
-
<FeatureCardSkeleton showAction />
|
|
399
|
-
</>
|
|
400
|
-
) : (
|
|
401
|
-
data.map(item => <FeatureCard key={item.id} {...item} />)
|
|
402
|
-
);
|
|
403
|
-
}
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
### Examples
|
|
407
|
-
|
|
408
|
-
```tsx
|
|
409
|
-
// ActivityCard with 4 row placeholders
|
|
410
|
-
<ActivityCardSkeleton rows={4} />
|
|
411
|
-
|
|
412
|
-
// ProfileCard without stats grid and without action buttons
|
|
413
|
-
<ProfileCardSkeleton showStats={false} showActions={false} />
|
|
414
|
-
|
|
415
|
-
// ProjectCard with 5 member-avatar placeholders
|
|
416
|
-
<ProjectCardSkeleton memberCount={5} />
|
|
417
|
-
|
|
418
|
-
// NotificationCard with footer placeholder
|
|
419
|
-
<NotificationCardSkeleton rows={3} showViewAll />
|
|
420
|
-
|
|
421
|
-
// FeatureCard without footer action button
|
|
422
|
-
<FeatureCardSkeleton showAction={false} />
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
> All skeletons use the `Skeleton` primitive from `ui/skeleton`, inheriting the `bg-accent animate-pulse` styling. They render plain `<div>` placeholders — no real Card/Header/Footer subcomponents — so they're cheap to render at scale.
|
|
426
|
-
|
|
427
|
-
---
|
|
428
|
-
|
|
429
|
-
## AI Rules
|
|
430
|
-
|
|
431
|
-
- Import block components from `xertica-ui` — they are included in the root barrel.
|
|
432
|
-
- Pass all data as props — never embed fetch calls inside block components.
|
|
433
|
-
- Keep `maxItems` at a sensible limit (4–6) to avoid overflow in fixed-height containers.
|
|
434
|
-
- For chart panels, use `ChartCard` from `xertica-ui/ui` (not a block component) with any dashboard-ready chart as `children`.
|
|
435
|
-
- `FeatureCard` badge wraps to a new line when title + badge don't fit — this is intentional; do not constrain the container width to force inline layout.
|
|
436
|
-
- **Always pair each card with its matching `*Skeleton` for loading states** — do not render a spinner or empty container while data fetches. The skeleton variants mirror the final layout closely, preventing layout shift when data arrives.
|
|
437
|
-
- **Skeleton row counts should match the expected data count when possible** — pass `rows={maxItems}` to `ActivityCardSkeleton`/`NotificationCardSkeleton` so the placeholder height matches the loaded state.
|
|
438
|
-
|
|
439
|
-
---
|
|
440
|
-
|
|
441
|
-
## Related
|
|
442
|
-
|
|
443
|
-
- [`Card`](./card.md) — Primitive used internally by all block components
|
|
444
|
-
- [`StatsCard`](./stats-card.md) — KPI card (lives in `ui/`, not `blocks/`) — also has `StatsCardSkeleton`
|
|
445
|
-
- [`Skeleton`](./skeleton.md) — Low-level pulsing placeholder primitive used by every `*Skeleton` here
|
|
446
|
-
- [`Chart`](./chart.md) — `ChartCard` and dashboard-ready chart wrappers
|
|
447
|
-
- [Dashboard Pattern](../patterns/dashboard.md)
|
|
1
|
+
# Card Patterns
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Pre-composed card blocks for dashboards, project management, and feature pages. Each component is built exclusively from `ui/` primitives — no external dependencies. They live in `components/blocks/card-patterns/` and are available from the root `xertica-ui` import.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## When to Use
|
|
10
|
+
|
|
11
|
+
- You need a recurring dashboard pattern (activity feed, KPI, project status, notifications) and don't want to re-compose it from scratch in every feature.
|
|
12
|
+
- The pattern is stable and reused across multiple pages.
|
|
13
|
+
|
|
14
|
+
## When NOT to Use
|
|
15
|
+
|
|
16
|
+
- One-off layouts specific to a single page — compose directly from `Card` and `ui/` primitives instead.
|
|
17
|
+
- When the pattern has significant data-fetching logic — keep the block as a pure presentational component and handle state in the feature layer.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Import
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
// from root barrel
|
|
25
|
+
import { ActivityCard, ProjectCard, FeatureCard } from 'xertica-ui';
|
|
26
|
+
|
|
27
|
+
// or from blocks subpath (when available)
|
|
28
|
+
import { ActivityCard, ProjectCard, FeatureCard } from 'xertica-ui/blocks';
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Components
|
|
34
|
+
|
|
35
|
+
### FeatureCard
|
|
36
|
+
|
|
37
|
+
Icon with a colored background, title, optional badge, description, and an action button. Matches the card pattern used on the Home page.
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
import { FeatureCard } from 'xertica-ui';
|
|
41
|
+
import { FileText } from 'lucide-react';
|
|
42
|
+
|
|
43
|
+
<FeatureCard
|
|
44
|
+
title="Template CLI"
|
|
45
|
+
description="Página de template pronta para uso com todos os componentes configurados."
|
|
46
|
+
icon={<FileText />}
|
|
47
|
+
color="chart-2"
|
|
48
|
+
badge="Novo"
|
|
49
|
+
actionLabel="Visualizar"
|
|
50
|
+
onAction={() => navigate('/template')}
|
|
51
|
+
/>;
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Props:**
|
|
55
|
+
|
|
56
|
+
| Prop | Type | Default | Description |
|
|
57
|
+
| --------------- | ------------------ | ----------- | -------------------------------------------- |
|
|
58
|
+
| `title` | `string` | — | Card title |
|
|
59
|
+
| `description` | `string` | — | Body text |
|
|
60
|
+
| `icon` | `ReactNode` | — | Icon element (size is controlled internally) |
|
|
61
|
+
| `color` | `FeatureCardColor` | `'primary'` | Icon background color token |
|
|
62
|
+
| `badge` | `string` | — | Optional badge label |
|
|
63
|
+
| `badgeVariant` | `BadgeVariant` | `'default'` | Badge color variant |
|
|
64
|
+
| `actionLabel` | `string` | — | Button label (omit to hide button) |
|
|
65
|
+
| `actionVariant` | `ButtonVariant` | `'outline'` | Button variant |
|
|
66
|
+
| `onAction` | `() => void` | — | Button click handler |
|
|
67
|
+
|
|
68
|
+
**`FeatureCardColor` values:** `primary` · `chart-1` · `chart-2` · `chart-3` · `chart-4` · `chart-5` · `success` · `info` · `warning` · `destructive`
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
### ActivityCard
|
|
73
|
+
|
|
74
|
+
Chronological feed of user actions with avatar, action description, timestamp, and type badge.
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
import { ActivityCard } from 'xertica-ui';
|
|
78
|
+
|
|
79
|
+
<ActivityCard
|
|
80
|
+
title="Atividade Recente"
|
|
81
|
+
items={[
|
|
82
|
+
{
|
|
83
|
+
id: '1',
|
|
84
|
+
user: { name: 'Ana Souza', initials: 'AS' },
|
|
85
|
+
action: 'criou o projeto',
|
|
86
|
+
target: 'Xertica Dashboard',
|
|
87
|
+
time: 'há 2 min',
|
|
88
|
+
type: 'create',
|
|
89
|
+
},
|
|
90
|
+
]}
|
|
91
|
+
action={
|
|
92
|
+
<Button variant="ghost" size="sm">
|
|
93
|
+
Ver tudo
|
|
94
|
+
</Button>
|
|
95
|
+
}
|
|
96
|
+
maxItems={5}
|
|
97
|
+
/>;
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Props:**
|
|
101
|
+
|
|
102
|
+
| Prop | Type | Default | Description |
|
|
103
|
+
| ---------- | ---------------- | --------------------- | --------------------------- |
|
|
104
|
+
| `title` | `string` | `'Atividade Recente'` | Card title |
|
|
105
|
+
| `items` | `ActivityItem[]` | — | Feed entries |
|
|
106
|
+
| `action` | `ReactNode` | — | Right-aligned header action |
|
|
107
|
+
| `maxItems` | `number` | `5` | Maximum visible items |
|
|
108
|
+
|
|
109
|
+
**`ActivityItem` shape:**
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
{
|
|
113
|
+
id: string
|
|
114
|
+
user: { name: string; initials: string; avatar?: string }
|
|
115
|
+
action: string // verb: "criou", "atualizou", etc.
|
|
116
|
+
target: string // object of the action
|
|
117
|
+
time: string // relative time string
|
|
118
|
+
type?: 'create' | 'update' | 'delete' | 'comment' | 'deploy'
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### ProfileCard
|
|
125
|
+
|
|
126
|
+
User or team member card with avatar, status badge, stat row, and primary/secondary actions.
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
import { ProfileCard } from 'xertica-ui';
|
|
130
|
+
|
|
131
|
+
<ProfileCard
|
|
132
|
+
name="Ana Souza"
|
|
133
|
+
role="Senior Frontend Engineer"
|
|
134
|
+
department="Design System"
|
|
135
|
+
initials="AS"
|
|
136
|
+
status="online"
|
|
137
|
+
stats={[
|
|
138
|
+
{ label: 'Projetos', value: 12 },
|
|
139
|
+
{ label: 'Commits', value: 348 },
|
|
140
|
+
{ label: 'Reviews', value: 57 },
|
|
141
|
+
]}
|
|
142
|
+
primaryAction={{ label: 'Ver Perfil' }}
|
|
143
|
+
secondaryAction={{ label: 'Mensagem' }}
|
|
144
|
+
/>;
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Props:**
|
|
148
|
+
|
|
149
|
+
| Prop | Type | Default | Description |
|
|
150
|
+
| ----------------- | ---------------------------------------------- | ------- | -------------------------------- |
|
|
151
|
+
| `name` | `string` | — | Full name |
|
|
152
|
+
| `role` | `string` | — | Job title |
|
|
153
|
+
| `department` | `string` | — | Department or team |
|
|
154
|
+
| `initials` | `string` | — | Avatar fallback (2 chars) |
|
|
155
|
+
| `avatar` | `string` | — | Avatar image URL |
|
|
156
|
+
| `status` | `'online' \| 'offline' \| 'away' \| 'busy'` | — | Presence badge |
|
|
157
|
+
| `stats` | `{ label: string; value: string \| number }[]` | — | Up to 3 stats in the divider row |
|
|
158
|
+
| `primaryAction` | `{ label: string; onClick?: () => void }` | — | Primary button |
|
|
159
|
+
| `secondaryAction` | `{ label: string; onClick?: () => void }` | — | Secondary (outline) button |
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
### ProjectCard
|
|
164
|
+
|
|
165
|
+
Project status widget with title, description, status badge, progress bar, member avatar stack, and due date.
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
import { ProjectCard } from 'xertica-ui';
|
|
169
|
+
|
|
170
|
+
<ProjectCard
|
|
171
|
+
title="Xertica Dashboard v3"
|
|
172
|
+
description="Redesign completo do painel."
|
|
173
|
+
status="active"
|
|
174
|
+
progress={68}
|
|
175
|
+
dueDate="Vence em 12 dias"
|
|
176
|
+
members={[
|
|
177
|
+
{ name: 'Ana', initials: 'AS' },
|
|
178
|
+
{ name: 'Bruno', initials: 'BL' },
|
|
179
|
+
]}
|
|
180
|
+
/>;
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Props:**
|
|
184
|
+
|
|
185
|
+
| Prop | Type | Default | Description |
|
|
186
|
+
| ------------- | ----------------- | ------- | ----------------------------------------- |
|
|
187
|
+
| `title` | `string` | — | Project name |
|
|
188
|
+
| `description` | `string` | — | Short description |
|
|
189
|
+
| `status` | `ProjectStatus` | — | Controls badge color and progress color |
|
|
190
|
+
| `progress` | `number` | — | 0–100 completion percentage |
|
|
191
|
+
| `dueDate` | `string` | — | Due date label string |
|
|
192
|
+
| `members` | `ProjectMember[]` | `[]` | Avatar stack |
|
|
193
|
+
| `maxMembers` | `number` | `4` | Max visible avatars before overflow count |
|
|
194
|
+
| `action` | `ReactNode` | — | Extra action appended to the status badge |
|
|
195
|
+
|
|
196
|
+
**`ProjectStatus` values:** `active` · `review` · `done` · `paused` · `at-risk`
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
### QuickActionCard
|
|
201
|
+
|
|
202
|
+
Action tile with icon in colored box, title, description, optional badge, and a full-width action button.
|
|
203
|
+
|
|
204
|
+
```tsx
|
|
205
|
+
import { QuickActionCard } from 'xertica-ui';
|
|
206
|
+
import { FileText } from 'lucide-react';
|
|
207
|
+
|
|
208
|
+
<QuickActionCard
|
|
209
|
+
title="Novo Relatório"
|
|
210
|
+
description="Gere relatórios personalizados de métricas."
|
|
211
|
+
icon={<FileText className="size-5" />}
|
|
212
|
+
actionLabel="Criar Relatório"
|
|
213
|
+
badge="Pro"
|
|
214
|
+
badgeVariant="warning"
|
|
215
|
+
onAction={() => openReportModal()}
|
|
216
|
+
/>;
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**Props:**
|
|
220
|
+
|
|
221
|
+
| Prop | Type | Default | Description |
|
|
222
|
+
| --------------- | --------------- | ------------- | ------------------------ |
|
|
223
|
+
| `title` | `string` | — | Tile title |
|
|
224
|
+
| `description` | `string` | — | Supporting text |
|
|
225
|
+
| `icon` | `ReactNode` | — | Icon in the colored box |
|
|
226
|
+
| `badge` | `string` | — | Optional badge |
|
|
227
|
+
| `badgeVariant` | `BadgeVariant` | `'secondary'` | Badge color variant |
|
|
228
|
+
| `actionLabel` | `string` | — | Button label |
|
|
229
|
+
| `actionVariant` | `ButtonVariant` | `'default'` | Button variant |
|
|
230
|
+
| `onAction` | `() => void` | — | Button click handler |
|
|
231
|
+
| `disabled` | `boolean` | `false` | Disables the entire card |
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
### NotificationCard
|
|
236
|
+
|
|
237
|
+
Notification list with unread indicator dots, type badges, timestamps, and bulk mark-as-read action.
|
|
238
|
+
|
|
239
|
+
```tsx
|
|
240
|
+
import { NotificationCard } from 'xertica-ui';
|
|
241
|
+
|
|
242
|
+
<NotificationCard
|
|
243
|
+
title="Notificações"
|
|
244
|
+
items={[
|
|
245
|
+
{
|
|
246
|
+
id: '1',
|
|
247
|
+
title: 'Deploy concluído',
|
|
248
|
+
message: 'v2.1.0 publicado com sucesso.',
|
|
249
|
+
time: 'há 2 min',
|
|
250
|
+
read: false,
|
|
251
|
+
type: 'success',
|
|
252
|
+
},
|
|
253
|
+
]}
|
|
254
|
+
onMarkAllRead={() => markAllRead()}
|
|
255
|
+
onViewAll={() => navigate('/notifications')}
|
|
256
|
+
maxItems={4}
|
|
257
|
+
/>;
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**Props:**
|
|
261
|
+
|
|
262
|
+
| Prop | Type | Default | Description |
|
|
263
|
+
| --------------- | -------------------- | ---------------- | ----------------------------------------------- |
|
|
264
|
+
| `title` | `string` | `'Notificações'` | Card title |
|
|
265
|
+
| `items` | `NotificationItem[]` | — | Notification entries |
|
|
266
|
+
| `unreadCount` | `number` | auto-counted | Override unread count badge |
|
|
267
|
+
| `onMarkAllRead` | `() => void` | — | Shows "Marcar todas como lidas" button when set |
|
|
268
|
+
| `onViewAll` | `() => void` | — | Shows "Ver todas" footer button when set |
|
|
269
|
+
| `maxItems` | `number` | `4` | Maximum visible items |
|
|
270
|
+
|
|
271
|
+
**`NotificationItem` shape:**
|
|
272
|
+
|
|
273
|
+
```ts
|
|
274
|
+
{
|
|
275
|
+
id: string
|
|
276
|
+
title: string
|
|
277
|
+
message: string
|
|
278
|
+
time: string
|
|
279
|
+
read?: boolean
|
|
280
|
+
type?: 'info' | 'warning' | 'success' | 'error' | 'default'
|
|
281
|
+
user?: { name: string; initials: string; avatar?: string }
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Dashboard Layout Example
|
|
288
|
+
|
|
289
|
+
```tsx
|
|
290
|
+
import {
|
|
291
|
+
ActivityCard,
|
|
292
|
+
ChartCard,
|
|
293
|
+
NotificationCard,
|
|
294
|
+
ProfileCard,
|
|
295
|
+
ProjectCard,
|
|
296
|
+
QuickActionCard,
|
|
297
|
+
} from 'xertica-ui';
|
|
298
|
+
import { DashboardLineChart } from 'xertica-ui/ui';
|
|
299
|
+
import { Briefcase, Users, BarChart2 } from 'lucide-react';
|
|
300
|
+
|
|
301
|
+
<div className="grid gap-4">
|
|
302
|
+
{/* Quick actions row */}
|
|
303
|
+
<div className="grid gap-4 md:grid-cols-3">
|
|
304
|
+
<QuickActionCard title="Novo Projeto" icon={<Briefcase />} actionLabel="Criar" />
|
|
305
|
+
<QuickActionCard
|
|
306
|
+
title="Convidar Equipe"
|
|
307
|
+
icon={<Users />}
|
|
308
|
+
actionLabel="Convidar"
|
|
309
|
+
actionVariant="outline"
|
|
310
|
+
/>
|
|
311
|
+
<QuickActionCard
|
|
312
|
+
title="Relatórios"
|
|
313
|
+
icon={<BarChart2 />}
|
|
314
|
+
actionLabel="Abrir"
|
|
315
|
+
badge="Novo"
|
|
316
|
+
badgeVariant="success"
|
|
317
|
+
/>
|
|
318
|
+
</div>
|
|
319
|
+
|
|
320
|
+
{/* Chart + Notifications */}
|
|
321
|
+
<div className="grid gap-4 md:grid-cols-3">
|
|
322
|
+
<div className="md:col-span-2">
|
|
323
|
+
<ChartCard title="Usuários Ativos" description="Esta semana" contentClassName="h-[220px]">
|
|
324
|
+
<DashboardLineChart
|
|
325
|
+
data={lineData}
|
|
326
|
+
config={lineConfig}
|
|
327
|
+
series={[{ key: 'usuarios', label: 'Usuários' }]}
|
|
328
|
+
indexKey="dia"
|
|
329
|
+
className="h-full w-full"
|
|
330
|
+
/>
|
|
331
|
+
</ChartCard>
|
|
332
|
+
</div>
|
|
333
|
+
<NotificationCard title="Alertas" items={notifications} onViewAll={() => {}} />
|
|
334
|
+
</div>
|
|
335
|
+
|
|
336
|
+
{/* Activity + Profile + Project */}
|
|
337
|
+
<div className="grid gap-4 md:grid-cols-2">
|
|
338
|
+
<ActivityCard items={activityItems} />
|
|
339
|
+
<div className="grid gap-4">
|
|
340
|
+
<ProfileCard
|
|
341
|
+
name="Ana Souza"
|
|
342
|
+
role="Designer"
|
|
343
|
+
initials="AS"
|
|
344
|
+
status="online"
|
|
345
|
+
stats={[{ label: 'Projetos', value: 12 }]}
|
|
346
|
+
/>
|
|
347
|
+
<ProjectCard
|
|
348
|
+
title="Dashboard v3"
|
|
349
|
+
status="active"
|
|
350
|
+
progress={68}
|
|
351
|
+
dueDate="12 dias"
|
|
352
|
+
members={members}
|
|
353
|
+
/>
|
|
354
|
+
</div>
|
|
355
|
+
</div>
|
|
356
|
+
</div>;
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## Loading States — Skeleton Components
|
|
362
|
+
|
|
363
|
+
Every card pattern ships with a matching `*Skeleton` companion that mirrors its layout with pulsing placeholders. Use them while data is loading to avoid layout shift and provide visual feedback.
|
|
364
|
+
|
|
365
|
+
| Card | Skeleton companion | Configurable props |
|
|
366
|
+
| ------------------ | -------------------------- | ----------------------------------- |
|
|
367
|
+
| `ActivityCard` | `ActivityCardSkeleton` | `rows` (default `5`) |
|
|
368
|
+
| `ProfileCard` | `ProfileCardSkeleton` | `showStats`, `showActions` |
|
|
369
|
+
| `ProjectCard` | `ProjectCardSkeleton` | `memberCount` (default `3`) |
|
|
370
|
+
| `NotificationCard` | `NotificationCardSkeleton` | `rows` (default `4`), `showViewAll` |
|
|
371
|
+
| `QuickActionCard` | `QuickActionCardSkeleton` | — |
|
|
372
|
+
| `FeatureCard` | `FeatureCardSkeleton` | `showAction` |
|
|
373
|
+
|
|
374
|
+
> A matching `StatsCardSkeleton` is also available from `xertica-ui` (lives in `ui/stats-card/`, with props `showIcon` and `showTrend`).
|
|
375
|
+
|
|
376
|
+
### Usage pattern
|
|
377
|
+
|
|
378
|
+
```tsx
|
|
379
|
+
import { useQuery } from '@tanstack/react-query';
|
|
380
|
+
import { ActivityCard, ActivityCardSkeleton } from 'xertica-ui';
|
|
381
|
+
|
|
382
|
+
function ActivityFeed() {
|
|
383
|
+
const { data: items, isLoading } = useActivityItems();
|
|
384
|
+
|
|
385
|
+
if (isLoading) return <ActivityCardSkeleton rows={5} />;
|
|
386
|
+
return <ActivityCard items={items!} />;
|
|
387
|
+
}
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
For grids, render one skeleton per expected card:
|
|
391
|
+
|
|
392
|
+
```tsx
|
|
393
|
+
{
|
|
394
|
+
isLoading ? (
|
|
395
|
+
<>
|
|
396
|
+
<FeatureCardSkeleton showAction />
|
|
397
|
+
<FeatureCardSkeleton showAction />
|
|
398
|
+
<FeatureCardSkeleton showAction />
|
|
399
|
+
</>
|
|
400
|
+
) : (
|
|
401
|
+
data.map(item => <FeatureCard key={item.id} {...item} />)
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Examples
|
|
407
|
+
|
|
408
|
+
```tsx
|
|
409
|
+
// ActivityCard with 4 row placeholders
|
|
410
|
+
<ActivityCardSkeleton rows={4} />
|
|
411
|
+
|
|
412
|
+
// ProfileCard without stats grid and without action buttons
|
|
413
|
+
<ProfileCardSkeleton showStats={false} showActions={false} />
|
|
414
|
+
|
|
415
|
+
// ProjectCard with 5 member-avatar placeholders
|
|
416
|
+
<ProjectCardSkeleton memberCount={5} />
|
|
417
|
+
|
|
418
|
+
// NotificationCard with footer placeholder
|
|
419
|
+
<NotificationCardSkeleton rows={3} showViewAll />
|
|
420
|
+
|
|
421
|
+
// FeatureCard without footer action button
|
|
422
|
+
<FeatureCardSkeleton showAction={false} />
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
> All skeletons use the `Skeleton` primitive from `ui/skeleton`, inheriting the `bg-accent animate-pulse` styling. They render plain `<div>` placeholders — no real Card/Header/Footer subcomponents — so they're cheap to render at scale.
|
|
426
|
+
|
|
427
|
+
---
|
|
428
|
+
|
|
429
|
+
## AI Rules
|
|
430
|
+
|
|
431
|
+
- Import block components from `xertica-ui` — they are included in the root barrel.
|
|
432
|
+
- Pass all data as props — never embed fetch calls inside block components.
|
|
433
|
+
- Keep `maxItems` at a sensible limit (4–6) to avoid overflow in fixed-height containers.
|
|
434
|
+
- For chart panels, use `ChartCard` from `xertica-ui/ui` (not a block component) with any dashboard-ready chart as `children`.
|
|
435
|
+
- `FeatureCard` badge wraps to a new line when title + badge don't fit — this is intentional; do not constrain the container width to force inline layout.
|
|
436
|
+
- **Always pair each card with its matching `*Skeleton` for loading states** — do not render a spinner or empty container while data fetches. The skeleton variants mirror the final layout closely, preventing layout shift when data arrives.
|
|
437
|
+
- **Skeleton row counts should match the expected data count when possible** — pass `rows={maxItems}` to `ActivityCardSkeleton`/`NotificationCardSkeleton` so the placeholder height matches the loaded state.
|
|
438
|
+
|
|
439
|
+
---
|
|
440
|
+
|
|
441
|
+
## Related
|
|
442
|
+
|
|
443
|
+
- [`Card`](./card.md) — Primitive used internally by all block components
|
|
444
|
+
- [`StatsCard`](./stats-card.md) — KPI card (lives in `ui/`, not `blocks/`) — also has `StatsCardSkeleton`
|
|
445
|
+
- [`Skeleton`](./skeleton.md) — Low-level pulsing placeholder primitive used by every `*Skeleton` here
|
|
446
|
+
- [`Chart`](./chart.md) — `ChartCard` and dashboard-ready chart wrappers
|
|
447
|
+
- [Dashboard Pattern](../patterns/dashboard.md)
|