xertica-ui 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +564 -552
- package/README.md +417 -406
- package/assets/xertica-logo.svg +37 -37
- package/assets/xertica-x-logo.svg +20 -20
- package/bin/cli.ts +1244 -1155
- package/bin/language-config.ts +358 -361
- 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 -554
- package/components/assistant/xertica-assistant/parts/AssistantCollapsedView.tsx +99 -99
- package/components/assistant/xertica-assistant/parts/AssistantConversationList.tsx +104 -106
- package/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.tsx +81 -81
- package/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.tsx +88 -78
- package/components/assistant/xertica-assistant/parts/AssistantHeader.tsx +75 -75
- package/components/assistant/xertica-assistant/parts/AssistantMessageBubble.tsx +564 -560
- package/components/assistant/xertica-assistant/parts/AssistantTabBar.tsx +67 -67
- package/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.tsx +103 -103
- package/components/assistant/xertica-assistant/use-assistant.ts +615 -615
- package/components/assistant/xertica-assistant/xertica-assistant.tsx +611 -613
- 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 -63
- 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 -114
- 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 -72
- 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 -114
- package/components/brand/language-selector/language-selector.test.tsx +101 -101
- package/components/brand/theme-toggle/ThemeToggle.tsx +74 -70
- package/components/brand/xertica-provider/XerticaProvider.tsx +109 -112
- package/components/brand/xertica-provider/xertica-provider.mdx +61 -61
- package/components/index.ts +86 -90
- package/components/layout/sidebar/sidebar.mdx +1 -1
- package/components/layout/sidebar/sidebar.tsx +1079 -1073
- package/components/media/FloatingMediaWrapper.tsx +371 -371
- package/components/media/audio-player/AudioPlayer.tsx +768 -766
- package/components/media/video-player/VideoPlayer.tsx +310 -310
- package/components/pages/forgot-password-page/ForgotPasswordPage.tsx +1 -1
- 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 -74
- package/components/pages/home-page/home-page.mdx +53 -53
- package/components/pages/login-page/LoginPage.tsx +218 -216
- package/components/pages/reset-password-page/ResetPasswordPage.tsx +243 -239
- package/components/pages/template-content/TemplateContent.tsx +1354 -1235
- package/components/pages/template-content/template-content.mdx +61 -61
- package/components/pages/template-page/template-page.mdx +53 -53
- package/components/pages/verify-email-page/VerifyEmailPage.tsx +206 -206
- package/components/shared/error-boundary.stories.tsx +4 -22
- package/components/shared/error-boundary.tsx +1 -5
- package/components/shared/error-fallbacks.tsx +4 -8
- 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/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 -62
- package/components/ui/stats-card/stats-card.mdx +8 -8
- package/components/ui/stats-card/stats-card.stories.tsx +99 -99
- 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 +892 -892
- package/contexts/AuthContext.tsx +11 -8
- package/contexts/LanguageContext.test.tsx +121 -121
- package/contexts/LanguageContext.tsx +250 -251
- 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-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-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-DF2ilhum.cjs +3210 -0
- 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-EhudUdqF.js +3211 -0
- package/dist/{VerifyEmailPage-C5TNQTBa.js → VerifyEmailPage-X14vhdyl.js} +148 -75
- package/dist/VerifyEmailPage-hdB8JQGv.cjs +3213 -0
- package/dist/{VerifyEmailPage-B4peJjAT.cjs → VerifyEmailPage-u_Dn7t1U.cjs} +148 -75
- 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-DDuiIcKo.js → XerticaProvider-BErr83Bg.js} +14 -11
- 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-CwOkHxiT.cjs +44 -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-BX3ueACh.js} +5 -2
- package/dist/XerticaXLogo-CFuIlYFH.js +252 -0
- package/dist/XerticaXLogo-CU-U-GP4.cjs +251 -0
- 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/{XerticaXLogo-bvZSgwGF.cjs → XerticaXLogo-qBPhwK3g.cjs} +5 -2
- 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/assistant.cjs.js +1 -1
- package/dist/assistant.es.js +1 -1
- package/dist/brand.cjs.js +2 -2
- package/dist/brand.es.js +2 -2
- package/dist/cli.js +90 -37
- package/dist/components/brand/theme-toggle/ThemeToggle.d.ts +1 -1
- package/dist/components/index.d.ts +1 -1
- 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 +5 -5
- package/dist/index.es.js +5 -5
- 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-B6SlKZYN.js → sidebar-B4ZWaMrE.js} +1 -1
- package/dist/{sidebar-DQj1z3jG.cjs → sidebar-B9NR0lCe.cjs} +269 -227
- package/dist/{sidebar-nzPoVHBQ.cjs → sidebar-BS1p2V7t.cjs} +1 -1
- package/dist/sidebar-BvF5I2Ue.cjs +800 -0
- 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-BxGXsDAd.cjs → sidebar-CVUGHOS_.cjs} +8 -16
- package/dist/{sidebar-BViy8Eeu.js → sidebar-CmvwjnVb.js} +9 -17
- package/dist/sidebar-CplprZpM.js +801 -0
- package/dist/{sidebar-BbVIQvlP.js → sidebar-Dz7bd3zP.js} +1 -1
- package/dist/sidebar-KIS0C2JH.js +801 -0
- 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-DCsnQyi5.js → xertica-assistant-B1NaSFFj.js} +46 -29
- 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-CrgTb6Hs.cjs → xertica-assistant-CIaUlbIt.cjs} +47 -22
- package/dist/{xertica-assistant-yX1CFBBo.js → xertica-assistant-DPsESB6t.js} +390 -531
- package/dist/{CodeBlock-BgfYL_rD.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 -306
- package/docs/components/assistant.md +428 -428
- package/docs/components/branding.md +252 -252
- package/docs/components/card-patterns.md +447 -445
- package/docs/components/error-boundary.md +32 -22
- package/docs/components/hooks.md +432 -430
- package/docs/components/language-selector.md +176 -172
- package/docs/components/pages.md +20 -6
- package/docs/doc-audit.md +244 -243
- package/docs/getting-started.md +616 -603
- package/docs/guidelines.md +330 -328
- package/docs/i18n.md +480 -476
- package/docs/installation.md +7 -6
- package/docs/llms.md +295 -295
- package/docs/state-management.md +289 -289
- package/guidelines/Guidelines.md +409 -406
- package/llms-compact.txt +1 -1
- package/llms.txt +1 -1
- package/package.json +219 -219
- package/styles/xertica/base.css +6 -0
- package/templates/.prettierignore +4 -4
- package/templates/.prettierrc +10 -10
- package/templates/CLAUDE.md +180 -165
- package/templates/guidelines/Guidelines.md +577 -553
- package/templates/package.json +69 -69
- package/templates/src/app/App.tsx +46 -46
- package/templates/src/app/components/AuthGuard.tsx +57 -8
- 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/AuthPageShell.tsx +1 -1
- package/templates/src/features/auth/ui/ForgotPasswordContent.tsx +70 -72
- package/templates/src/features/auth/ui/LoginContent.tsx +92 -92
- package/templates/src/features/auth/ui/ResetPasswordContent.tsx +183 -179
- package/templates/src/features/auth/ui/SocialLoginButtons.tsx +78 -78
- package/templates/src/features/auth/ui/VerifyEmailContent.tsx +80 -84
- package/templates/src/features/home/data/mock.ts +6 -0
- 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 -119
- package/templates/src/features/template/ui/CrudTemplate.tsx +112 -115
- 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 -1314
- 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 -464
- package/templates/src/pages/HomePage.tsx +53 -49
- package/templates/src/shared/error-boundary.tsx +1 -5
- package/templates/src/shared/error-fallbacks.tsx +4 -8
- package/templates/vite.config.js +20 -20
- package/templates/vite.config.ts +55 -52
- 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-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-7TTgmdGG.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-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-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-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
package/docs/components/hooks.md
CHANGED
|
@@ -1,430 +1,432 @@
|
|
|
1
|
-
# Hooks — Xertica UI
|
|
2
|
-
|
|
3
|
-
Xertica UI exposes a set of React hooks via the `xertica-ui/hooks` subpath. These hooks provide access to global contexts (theme, language, layout, assistant, API keys, brand colors) and utility behaviors (audio player, keyboard shortcuts, mobile detection).
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Import
|
|
8
|
-
|
|
9
|
-
```tsx
|
|
10
|
-
import {
|
|
11
|
-
useTheme,
|
|
12
|
-
useLanguage,
|
|
13
|
-
useBrandColors,
|
|
14
|
-
useAssistente,
|
|
15
|
-
useApiKey,
|
|
16
|
-
useLayout,
|
|
17
|
-
useAudioPlayer,
|
|
18
|
-
useLayoutShortcuts,
|
|
19
|
-
useIsMobile,
|
|
20
|
-
} from 'xertica-ui/hooks';
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
All hooks are also available from the root barrel:
|
|
24
|
-
|
|
25
|
-
```tsx
|
|
26
|
-
import { useTheme, useLayout } from 'xertica-ui';
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
## `useTheme`
|
|
32
|
-
|
|
33
|
-
Accesses and controls the current color theme (light/dark).
|
|
34
|
-
|
|
35
|
-
**Source**: `contexts/ThemeContext.tsx`
|
|
36
|
-
|
|
37
|
-
### Return Value
|
|
38
|
-
|
|
39
|
-
| Property | Type | Description |
|
|
40
|
-
| ------------- | ------------------------------- | ------------------------------ |
|
|
41
|
-
| `theme` | `'light' \| 'dark' \| 'system'` | Current active theme |
|
|
42
|
-
| `setTheme` | `(theme: Theme) => void` | Sets the theme explicitly |
|
|
43
|
-
| `toggleTheme` | `() => void` | Toggles between light and dark |
|
|
44
|
-
|
|
45
|
-
### Usage
|
|
46
|
-
|
|
47
|
-
```tsx
|
|
48
|
-
import { useTheme } from 'xertica-ui/hooks';
|
|
49
|
-
|
|
50
|
-
function ThemeButton() {
|
|
51
|
-
const { theme, toggleTheme } = useTheme();
|
|
52
|
-
return <button onClick={toggleTheme}>Current: {theme}</button>;
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
> **Note**: `useTheme` must be used inside `<XerticaProvider>` (which includes `ThemeProvider`). For a self-contained toggle that does not require context, use the `<ThemeToggle>` component instead.
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
## `useLanguage`
|
|
61
|
-
|
|
62
|
-
Accesses and controls the current UI language preference, plus the list of available languages.
|
|
63
|
-
|
|
64
|
-
**Source**: `contexts/LanguageContext.tsx`
|
|
65
|
-
|
|
66
|
-
### Return Value
|
|
67
|
-
|
|
68
|
-
| Property | Type
|
|
69
|
-
| -------------------- |
|
|
70
|
-
| `language` | `string`
|
|
71
|
-
| `setLanguage` | `(language: Language) => void` | Changes the language: persists to localStorage, calls `i18n.changeLanguage`, and invalidates React Query cache |
|
|
72
|
-
| `availableLanguages` | `LanguageDefinition[]` | The full list of languages configured via `availableLanguages` prop on `<XerticaProvider>`
|
|
73
|
-
| `isMonolingual` | `boolean` | `true` when only one language is configured. The `LanguageSelector` uses this to auto-hide
|
|
74
|
-
|
|
75
|
-
### Usage
|
|
76
|
-
|
|
77
|
-
```tsx
|
|
78
|
-
import { useLanguage } from 'xertica-ui/hooks';
|
|
79
|
-
|
|
80
|
-
function LanguageDisplay() {
|
|
81
|
-
const { language, setLanguage, availableLanguages } = useLanguage();
|
|
82
|
-
// The dropdown is fully data-driven — works with any number of languages
|
|
83
|
-
return (
|
|
84
|
-
<select value={language} onChange={e => setLanguage(e.target.value)}>
|
|
85
|
-
{availableLanguages.map(lang => (
|
|
86
|
-
<option key={lang.code} value={lang.code}>
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
> **
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
|
110
|
-
|
|
|
111
|
-
| `
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
|
145
|
-
|
|
|
146
|
-
| `
|
|
147
|
-
| `
|
|
148
|
-
| `
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
|
176
|
-
|
|
|
177
|
-
| `
|
|
178
|
-
| `
|
|
179
|
-
| `
|
|
180
|
-
| `
|
|
181
|
-
| `
|
|
182
|
-
| `
|
|
183
|
-
| `
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
|
218
|
-
|
|
|
219
|
-
| `
|
|
220
|
-
| `
|
|
221
|
-
| `
|
|
222
|
-
| `
|
|
223
|
-
| `
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
|
251
|
-
|
|
|
252
|
-
| `
|
|
253
|
-
| `
|
|
254
|
-
| `
|
|
255
|
-
| `
|
|
256
|
-
| `
|
|
257
|
-
| `
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
|
266
|
-
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
|
273
|
-
|
|
|
274
|
-
| `
|
|
275
|
-
| `
|
|
276
|
-
| `
|
|
277
|
-
| `
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
|
284
|
-
|
|
|
285
|
-
| `
|
|
286
|
-
| `
|
|
287
|
-
| `
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
|
294
|
-
|
|
|
295
|
-
| `
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
|
302
|
-
|
|
|
303
|
-
| `
|
|
304
|
-
| `
|
|
305
|
-
| `
|
|
306
|
-
| `
|
|
307
|
-
| `
|
|
308
|
-
| `
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
|
315
|
-
|
|
|
316
|
-
| `
|
|
317
|
-
| `
|
|
318
|
-
| `
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
**
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
>
|
|
428
|
-
>
|
|
429
|
-
> - **
|
|
430
|
-
> - **`
|
|
1
|
+
# Hooks — Xertica UI
|
|
2
|
+
|
|
3
|
+
Xertica UI exposes a set of React hooks via the `xertica-ui/hooks` subpath. These hooks provide access to global contexts (theme, language, layout, assistant, API keys, brand colors) and utility behaviors (audio player, keyboard shortcuts, mobile detection).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import {
|
|
11
|
+
useTheme,
|
|
12
|
+
useLanguage,
|
|
13
|
+
useBrandColors,
|
|
14
|
+
useAssistente,
|
|
15
|
+
useApiKey,
|
|
16
|
+
useLayout,
|
|
17
|
+
useAudioPlayer,
|
|
18
|
+
useLayoutShortcuts,
|
|
19
|
+
useIsMobile,
|
|
20
|
+
} from 'xertica-ui/hooks';
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
All hooks are also available from the root barrel:
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
import { useTheme, useLayout } from 'xertica-ui';
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## `useTheme`
|
|
32
|
+
|
|
33
|
+
Accesses and controls the current color theme (light/dark).
|
|
34
|
+
|
|
35
|
+
**Source**: `contexts/ThemeContext.tsx`
|
|
36
|
+
|
|
37
|
+
### Return Value
|
|
38
|
+
|
|
39
|
+
| Property | Type | Description |
|
|
40
|
+
| ------------- | ------------------------------- | ------------------------------ |
|
|
41
|
+
| `theme` | `'light' \| 'dark' \| 'system'` | Current active theme |
|
|
42
|
+
| `setTheme` | `(theme: Theme) => void` | Sets the theme explicitly |
|
|
43
|
+
| `toggleTheme` | `() => void` | Toggles between light and dark |
|
|
44
|
+
|
|
45
|
+
### Usage
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import { useTheme } from 'xertica-ui/hooks';
|
|
49
|
+
|
|
50
|
+
function ThemeButton() {
|
|
51
|
+
const { theme, toggleTheme } = useTheme();
|
|
52
|
+
return <button onClick={toggleTheme}>Current: {theme}</button>;
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
> **Note**: `useTheme` must be used inside `<XerticaProvider>` (which includes `ThemeProvider`). For a self-contained toggle that does not require context, use the `<ThemeToggle>` component instead.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## `useLanguage`
|
|
61
|
+
|
|
62
|
+
Accesses and controls the current UI language preference, plus the list of available languages.
|
|
63
|
+
|
|
64
|
+
**Source**: `contexts/LanguageContext.tsx`
|
|
65
|
+
|
|
66
|
+
### Return Value
|
|
67
|
+
|
|
68
|
+
| Property | Type | Description |
|
|
69
|
+
| -------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------- |
|
|
70
|
+
| `language` | `string` | Current language code (e.g. `'pt-BR'`, `'en'`, `'fr'`) |
|
|
71
|
+
| `setLanguage` | `(language: Language) => void` | Changes the language: persists to localStorage, calls `i18n.changeLanguage`, and invalidates React Query cache |
|
|
72
|
+
| `availableLanguages` | `LanguageDefinition[]` | The full list of languages configured via `availableLanguages` prop on `<XerticaProvider>` |
|
|
73
|
+
| `isMonolingual` | `boolean` | `true` when only one language is configured. The `LanguageSelector` uses this to auto-hide |
|
|
74
|
+
|
|
75
|
+
### Usage
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
import { useLanguage } from 'xertica-ui/hooks';
|
|
79
|
+
|
|
80
|
+
function LanguageDisplay() {
|
|
81
|
+
const { language, setLanguage, availableLanguages } = useLanguage();
|
|
82
|
+
// The dropdown is fully data-driven — works with any number of languages
|
|
83
|
+
return (
|
|
84
|
+
<select value={language} onChange={e => setLanguage(e.target.value)}>
|
|
85
|
+
{availableLanguages.map(lang => (
|
|
86
|
+
<option key={lang.code} value={lang.code}>
|
|
87
|
+
{lang.label}
|
|
88
|
+
</option>
|
|
89
|
+
))}
|
|
90
|
+
</select>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
> **Note**: The language preference is persisted in `localStorage` under the key `xertica_language`. Calling `setLanguage(lang)` also (1) calls `i18n.changeLanguage(lang)` from `i18next` — all components that use `useTranslation()` re-render immediately, and (2) invalidates the React Query cache — data-layer strings (like mock API responses) are refetched in the new language. The `LanguageSelector` component wires this automatically — you only need to call `setLanguage` directly when changing the language programmatically (e.g., from a settings page).
|
|
96
|
+
|
|
97
|
+
> **Type note**: `Language` is `string`, not a strict union, to support runtime-added locales. Use `availableLanguages` from this hook to discover valid codes.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## `useBrandColors`
|
|
102
|
+
|
|
103
|
+
Accesses and modifies the brand color palette applied as CSS custom properties.
|
|
104
|
+
|
|
105
|
+
**Source**: `contexts/BrandColorsContext.tsx`
|
|
106
|
+
|
|
107
|
+
### Return Value
|
|
108
|
+
|
|
109
|
+
| Property | Type | Description |
|
|
110
|
+
| --------------- | ------------------------------------------------- | ------------------------------------- |
|
|
111
|
+
| `colors` | `BrandColors` | Current brand color values |
|
|
112
|
+
| `setBrandColor` | `(key: keyof BrandColors, value: string) => void` | Updates a single brand color |
|
|
113
|
+
| `currentTheme` | `string` | Name of the active color theme preset |
|
|
114
|
+
|
|
115
|
+
### Usage
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
import { useBrandColors } from 'xertica-ui/hooks';
|
|
119
|
+
|
|
120
|
+
function BrandCustomizer() {
|
|
121
|
+
const { colors, setBrandColor } = useBrandColors();
|
|
122
|
+
return (
|
|
123
|
+
<input
|
|
124
|
+
type="color"
|
|
125
|
+
value={colors.primary}
|
|
126
|
+
onChange={e => setBrandColor('primary', e.target.value)}
|
|
127
|
+
/>
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
> **Note**: Color changes are applied immediately as CSS variables on `:root`. They persist across re-renders but are not saved to `localStorage` by default.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## `useAssistente`
|
|
137
|
+
|
|
138
|
+
Accesses the global AI Assistant context — conversation list, current conversation, and navigation helpers.
|
|
139
|
+
|
|
140
|
+
**Source**: `contexts/AssistenteContext.tsx`
|
|
141
|
+
|
|
142
|
+
### Return Value
|
|
143
|
+
|
|
144
|
+
| Property | Type | Description |
|
|
145
|
+
| ------------------ | ------------------------------ | ---------------------------------------------- |
|
|
146
|
+
| `conversas` | `Conversation[]` | List of all conversations |
|
|
147
|
+
| `conversaAtual` | `string \| null` | ID of the currently active conversation |
|
|
148
|
+
| `setConversaAtual` | `(id: string \| null) => void` | Selects a conversation |
|
|
149
|
+
| `sugestoes` | `Suggestion[]` | Quick-reply suggestions for the welcome screen |
|
|
150
|
+
| `setSugestoes` | `(s: Suggestion[]) => void` | Replaces the suggestion list |
|
|
151
|
+
|
|
152
|
+
### Usage
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
import { useAssistente } from 'xertica-ui/hooks';
|
|
156
|
+
|
|
157
|
+
function ConversationCount() {
|
|
158
|
+
const { conversas } = useAssistente();
|
|
159
|
+
return <span>{conversas.length} conversations</span>;
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
> **Note**: This hook must be used inside `<XerticaProvider>` (which includes `AssistenteProvider`). It is primarily used internally by `XerticaAssistant`.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## `useApiKey`
|
|
168
|
+
|
|
169
|
+
Accesses and manages API keys for Xertica services, Gemini AI, and Google Maps.
|
|
170
|
+
|
|
171
|
+
**Source**: `contexts/ApiKeyContext.tsx`
|
|
172
|
+
|
|
173
|
+
### Return Value
|
|
174
|
+
|
|
175
|
+
| Property | Type | Description |
|
|
176
|
+
| ---------------------- | ----------------------- | ---------------------------------------- |
|
|
177
|
+
| `apiKey` | `string` | Xertica platform API key |
|
|
178
|
+
| `setApiKey` | `(key: string) => void` | Updates the Xertica API key |
|
|
179
|
+
| `geminiApiKey` | `string` | Google Gemini API key |
|
|
180
|
+
| `setGeminiApiKey` | `(key: string) => void` | Updates the Gemini API key |
|
|
181
|
+
| `isApiKeyValid` | `boolean` | Whether the Xertica API key is non-empty |
|
|
182
|
+
| `googleMapsApiKey` | `string` | Google Maps API key |
|
|
183
|
+
| `setGoogleMapsApiKey` | `(key: string) => void` | Updates the Maps API key |
|
|
184
|
+
| `isGoogleMapsKeyValid` | `boolean` | Whether the Maps key is non-empty |
|
|
185
|
+
| `reloadMapsApi` | `() => Promise<void>` | Reloads the Maps script after key change |
|
|
186
|
+
|
|
187
|
+
### Usage
|
|
188
|
+
|
|
189
|
+
```tsx
|
|
190
|
+
import { useApiKey } from 'xertica-ui/hooks';
|
|
191
|
+
|
|
192
|
+
function ApiKeySettings() {
|
|
193
|
+
const { geminiApiKey, setGeminiApiKey, isApiKeyValid } = useApiKey();
|
|
194
|
+
return (
|
|
195
|
+
<input
|
|
196
|
+
type="password"
|
|
197
|
+
value={geminiApiKey}
|
|
198
|
+
onChange={e => setGeminiApiKey(e.target.value)}
|
|
199
|
+
placeholder="Enter Gemini API key"
|
|
200
|
+
/>
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
> **Note**: API keys are persisted in `localStorage`. The `XerticaAssistant` component reads `geminiApiKey` automatically when `demoMode={false}` (real AI mode). When `demoMode={true}` (default), no API key is required.
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## `useLayout`
|
|
210
|
+
|
|
211
|
+
Accesses and controls the global layout state — sidebar expansion, assistant panel, and width values.
|
|
212
|
+
|
|
213
|
+
**Source**: `contexts/LayoutContext.tsx`
|
|
214
|
+
|
|
215
|
+
### Return Value
|
|
216
|
+
|
|
217
|
+
| Property | Type | Description |
|
|
218
|
+
| ------------------------- | ------------------------- | -------------------------------------- |
|
|
219
|
+
| `sidebarExpanded` | `boolean` | Whether the sidebar is expanded |
|
|
220
|
+
| `sidebarWidth` | `number` | Current sidebar width in pixels |
|
|
221
|
+
| `setSidebarWidth` | `(width: number) => void` | Updates the sidebar width |
|
|
222
|
+
| `toggleSidebar` | `() => void` | Toggles sidebar expanded state |
|
|
223
|
+
| `assistenteExpanded` | `boolean` | Whether the AI assistant panel is open |
|
|
224
|
+
| `toggleAssistente` | `() => void` | Toggles the assistant panel |
|
|
225
|
+
| `toggleAssistenteWithTab` | `(tab: string) => void` | Opens the assistant on a specific tab |
|
|
226
|
+
|
|
227
|
+
### Usage
|
|
228
|
+
|
|
229
|
+
```tsx
|
|
230
|
+
import { useLayout } from 'xertica-ui/hooks';
|
|
231
|
+
|
|
232
|
+
function ContentArea() {
|
|
233
|
+
const { sidebarExpanded, sidebarWidth } = useLayout();
|
|
234
|
+
return <main style={{ marginLeft: sidebarWidth }}>{/* content */}</main>;
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
> **See also**: `docs/layout.md` for the complete layout system reference.
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## `useAudioPlayer`
|
|
243
|
+
|
|
244
|
+
Headless hook that encapsulates all state and side effects for audio playback. Use this to build a fully custom audio player UI while reusing the library's playback logic.
|
|
245
|
+
|
|
246
|
+
**Source**: `components/media/audio-player/use-audio-player.ts`
|
|
247
|
+
|
|
248
|
+
### Props (`UseAudioPlayerProps`)
|
|
249
|
+
|
|
250
|
+
| Prop | Type | Default | Description |
|
|
251
|
+
| ----------------- | ----------------- | -------- | ---------------------------------------------------- |
|
|
252
|
+
| `src` | `string` | — | Audio file URL |
|
|
253
|
+
| `autoPlay` | `boolean` | `false` | Start playing on mount |
|
|
254
|
+
| `initialTime` | `number` | `0` | Initial seek position in seconds |
|
|
255
|
+
| `initialDuration` | `number` | — | Pre-known duration (loaded from metadata if omitted) |
|
|
256
|
+
| `variant` | `'card' \| 'bar'` | `'card'` | Layout variant (affects floating behavior) |
|
|
257
|
+
| `isOpen` | `boolean` | `true` | Whether the bar variant is visible |
|
|
258
|
+
| `enableAutoFloat` | `boolean` | `true` | Auto-float when scrolled out of view (card only) |
|
|
259
|
+
| `onCloseFloating` | `() => void` | — | Called when user closes the floating player |
|
|
260
|
+
|
|
261
|
+
### Return Value (`UseAudioPlayerReturn`)
|
|
262
|
+
|
|
263
|
+
**Refs**
|
|
264
|
+
|
|
265
|
+
| Property | Type | Description |
|
|
266
|
+
| -------------- | ----------------------------- | --------------------------------------------------- |
|
|
267
|
+
| `audioRef` | `RefObject<HTMLAudioElement>` | Attach to `<audio>` element |
|
|
268
|
+
| `containerRef` | `RefObject<HTMLDivElement>` | Attach to the player container for scroll detection |
|
|
269
|
+
|
|
270
|
+
**Playback State**
|
|
271
|
+
|
|
272
|
+
| Property | Type | Description |
|
|
273
|
+
| --------------- | --------- | --------------------------------------- |
|
|
274
|
+
| `isPlaying` | `boolean` | Whether audio is currently playing |
|
|
275
|
+
| `currentTime` | `number` | Current playback position in seconds |
|
|
276
|
+
| `duration` | `number` | Total duration in seconds |
|
|
277
|
+
| `volume` | `number` | Volume level (0–1) |
|
|
278
|
+
| `isMuted` | `boolean` | Whether audio is muted |
|
|
279
|
+
| `playbackSpeed` | `number` | Current playback speed (0.5, 1, 1.5, 2) |
|
|
280
|
+
|
|
281
|
+
**UI State**
|
|
282
|
+
|
|
283
|
+
| Property | Type | Description |
|
|
284
|
+
| ---------------------- | --------- | ---------------------------------------- |
|
|
285
|
+
| `isFloating` | `boolean` | Whether the player is in floating mode |
|
|
286
|
+
| `isManualFloating` | `boolean` | Whether floating was triggered manually |
|
|
287
|
+
| `isVisible` | `boolean` | Whether the container is in the viewport |
|
|
288
|
+
| `isMobile` | `boolean` | Whether the viewport is mobile-sized |
|
|
289
|
+
| `enableAutoFloatLocal` | `boolean` | Current auto-float setting |
|
|
290
|
+
|
|
291
|
+
**Layout Context**
|
|
292
|
+
|
|
293
|
+
| Property | Type | Description |
|
|
294
|
+
| -------------------- | --------- | ----------------------------------- |
|
|
295
|
+
| `sidebarExpanded` | `boolean` | Sidebar state (for bar positioning) |
|
|
296
|
+
| `sidebarWidth` | `number` | Sidebar width in pixels |
|
|
297
|
+
| `assistenteExpanded` | `boolean` | Assistant panel state |
|
|
298
|
+
|
|
299
|
+
**Handlers**
|
|
300
|
+
|
|
301
|
+
| Property | Type | Description |
|
|
302
|
+
| ------------------------- | ----------------------------- | ------------------------------------ |
|
|
303
|
+
| `togglePlay` | `() => void` | Play/pause toggle |
|
|
304
|
+
| `toggleMute` | `() => void` | Mute/unmute toggle |
|
|
305
|
+
| `handleSeek` | `(value: number[]) => void` | Seek to position (Slider-compatible) |
|
|
306
|
+
| `handleVolumeChange` | `(value: number[]) => void` | Change volume (Slider-compatible) |
|
|
307
|
+
| `handleSetFloating` | `(floating: boolean) => void` | Set floating state |
|
|
308
|
+
| `handleEnableManualFloat` | `() => void` | Trigger manual float |
|
|
309
|
+
| `setPlaybackSpeed` | `(speed: number) => void` | Change playback speed |
|
|
310
|
+
| `resetAudio` | `() => void` | Reset to beginning |
|
|
311
|
+
|
|
312
|
+
**Audio Element Event Handlers**
|
|
313
|
+
|
|
314
|
+
| Property | Type | Description |
|
|
315
|
+
| ------------------ | ------------- | ------------------------------------ |
|
|
316
|
+
| `onPlay` | `() => void` | Attach to `<audio onPlay>` |
|
|
317
|
+
| `onPause` | `() => void` | Attach to `<audio onPause>` |
|
|
318
|
+
| `onEnded` | `() => void` | Attach to `<audio onEnded>` |
|
|
319
|
+
| `onTimeUpdate` | `(e) => void` | Attach to `<audio onTimeUpdate>` |
|
|
320
|
+
| `onLoadedMetadata` | `(e) => void` | Attach to `<audio onLoadedMetadata>` |
|
|
321
|
+
|
|
322
|
+
**Utilities**
|
|
323
|
+
|
|
324
|
+
| Property | Type | Description |
|
|
325
|
+
| ------------ | -------------------------- | -------------------------- |
|
|
326
|
+
| `formatTime` | `(time: number) => string` | Formats seconds as `MM:SS` |
|
|
327
|
+
|
|
328
|
+
### Usage
|
|
329
|
+
|
|
330
|
+
```tsx
|
|
331
|
+
import { useAudioPlayer } from 'xertica-ui/hooks';
|
|
332
|
+
|
|
333
|
+
function MyCustomPlayer({ src }: { src: string }) {
|
|
334
|
+
const {
|
|
335
|
+
audioRef,
|
|
336
|
+
containerRef,
|
|
337
|
+
isPlaying,
|
|
338
|
+
togglePlay,
|
|
339
|
+
currentTime,
|
|
340
|
+
duration,
|
|
341
|
+
formatTime,
|
|
342
|
+
onPlay,
|
|
343
|
+
onPause,
|
|
344
|
+
onEnded,
|
|
345
|
+
onTimeUpdate,
|
|
346
|
+
onLoadedMetadata,
|
|
347
|
+
} = useAudioPlayer({ src });
|
|
348
|
+
|
|
349
|
+
return (
|
|
350
|
+
<div ref={containerRef}>
|
|
351
|
+
<audio
|
|
352
|
+
ref={audioRef}
|
|
353
|
+
src={src}
|
|
354
|
+
onPlay={onPlay}
|
|
355
|
+
onPause={onPause}
|
|
356
|
+
onEnded={onEnded}
|
|
357
|
+
onTimeUpdate={onTimeUpdate}
|
|
358
|
+
onLoadedMetadata={onLoadedMetadata}
|
|
359
|
+
/>
|
|
360
|
+
<button onClick={togglePlay}>{isPlaying ? 'Pause' : 'Play'}</button>
|
|
361
|
+
<span>
|
|
362
|
+
{formatTime(currentTime)} / {formatTime(duration)}
|
|
363
|
+
</span>
|
|
364
|
+
</div>
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
> **Note**: For most use cases, use the `<AudioPlayer>` component directly. Use `useAudioPlayer` only when you need a fully custom player UI.
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
## `useLayoutShortcuts`
|
|
374
|
+
|
|
375
|
+
Registers global keyboard shortcuts for layout control. Must be called **once** in the root layout component.
|
|
376
|
+
|
|
377
|
+
**Source**: `components/hooks/use-layout-shortcuts.ts`
|
|
378
|
+
|
|
379
|
+
### Registered Shortcuts
|
|
380
|
+
|
|
381
|
+
| Shortcut | Action |
|
|
382
|
+
| ------------------ | -------------- |
|
|
383
|
+
| `Ctrl+B` / `Cmd+B` | Toggle sidebar |
|
|
384
|
+
|
|
385
|
+
### Usage
|
|
386
|
+
|
|
387
|
+
```tsx
|
|
388
|
+
import { useLayoutShortcuts } from 'xertica-ui/hooks';
|
|
389
|
+
|
|
390
|
+
function AppLayout({ children }: { children: React.ReactNode }) {
|
|
391
|
+
useLayoutShortcuts(); // registers Ctrl+B for sidebar toggle
|
|
392
|
+
return <div>{children}</div>;
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
> **Important**: Call this hook only once in your application. Calling it in multiple components will register duplicate event listeners.
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
## `useIsMobile` / `useMobile`
|
|
401
|
+
|
|
402
|
+
Detects whether the current viewport is mobile-sized (< 768px).
|
|
403
|
+
|
|
404
|
+
**Source**: `components/shared/use-mobile.ts`
|
|
405
|
+
|
|
406
|
+
### Return Value
|
|
407
|
+
|
|
408
|
+
Returns `boolean` — `true` if the viewport width is below the mobile breakpoint.
|
|
409
|
+
|
|
410
|
+
### Usage
|
|
411
|
+
|
|
412
|
+
```tsx
|
|
413
|
+
import { useIsMobile } from 'xertica-ui/hooks';
|
|
414
|
+
|
|
415
|
+
function ResponsiveComponent() {
|
|
416
|
+
const isMobile = useIsMobile();
|
|
417
|
+
return isMobile ? <MobileView /> : <DesktopView />;
|
|
418
|
+
}
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
> **Note**: Both `useIsMobile` and `useMobile` are exported and are identical. `useIsMobile` is the preferred name. See [`use-mobile.md`](./use-mobile.md) for the full reference.
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
## AI Rules
|
|
426
|
+
|
|
427
|
+
> [!IMPORTANT]
|
|
428
|
+
>
|
|
429
|
+
> - **Always use hooks inside providers**: All context hooks (`useTheme`, `useLanguage`, `useBrandColors`, `useAssistente`, `useApiKey`, `useLayout`) require `<XerticaProvider>` in the component tree. Calling them outside a provider throws an error.
|
|
430
|
+
> - **`useLayoutShortcuts` is singleton**: Call it exactly once in your root layout component, never in page-level or feature components.
|
|
431
|
+
> - **Prefer `<AudioPlayer>` over `useAudioPlayer`**: The headless hook is for advanced custom UIs only. For standard playback, use the component.
|
|
432
|
+
> - **`useLayout` for sidebar state**: Never manage sidebar width or expansion state manually. Always read from `useLayout()`.
|