xertica-ui 2.3.0 → 2.4.1
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 +22 -2
- package/README.md +33 -22
- package/bin/cli.ts +136 -47
- package/bin/language-config.ts +5 -8
- package/components/assistant/modern-chat-input/ModernChatInput.tsx +17 -7
- package/components/assistant/xertica-assistant/parts/AssistantConversationList.tsx +1 -3
- package/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.tsx +13 -3
- package/components/assistant/xertica-assistant/parts/AssistantMessageBubble.tsx +10 -6
- package/components/assistant/xertica-assistant/xertica-assistant.tsx +1 -3
- package/components/blocks/card-patterns/FeatureCardSkeleton.tsx +1 -6
- package/components/blocks/card-patterns/ProfileCard.tsx +1 -3
- package/components/blocks/card-patterns/ProjectCardSkeleton.tsx +1 -6
- package/components/brand/language-selector/language-selector.stories.tsx +1 -4
- package/components/brand/theme-toggle/ThemeToggle.tsx +5 -1
- package/components/brand/xertica-provider/XerticaProvider.tsx +1 -4
- package/components/index.ts +1 -5
- package/components/layout/sidebar/sidebar.tsx +9 -3
- package/components/media/audio-player/AudioPlayer.tsx +4 -2
- package/components/pages/forgot-password-page/ForgotPasswordPage.tsx +188 -188
- package/components/pages/home-content/HomeContent.tsx +55 -55
- package/components/pages/home-page/HomePage.tsx +5 -1
- package/components/pages/login-page/LoginPage.tsx +4 -2
- package/components/pages/reset-password-page/ResetPasswordPage.tsx +7 -3
- package/components/pages/template-content/TemplateContent.tsx +268 -149
- package/components/pages/verify-email-page/VerifyEmailPage.tsx +9 -9
- package/components/shared/error-boundary.stories.tsx +114 -132
- package/components/shared/error-boundary.tsx +150 -154
- package/components/shared/error-fallbacks.tsx +222 -226
- package/components/ui/stats-card/stats-card-skeleton.tsx +1 -3
- package/components/ui/stats-card/stats-card.stories.tsx +18 -0
- package/components/ui/stats-card/stats-card.tsx +18 -2
- package/components.json +512 -892
- package/contexts/AuthContext.tsx +121 -118
- package/contexts/LanguageContext.tsx +1 -2
- package/dist/AssistantChart-BKVtGUKF.js +3383 -0
- package/dist/AssistantChart-WeycT5Pd.cjs +3551 -0
- package/dist/VerifyEmailPage-Bp1XXl3H.cjs +3305 -0
- package/dist/VerifyEmailPage-DGhuIqkb.js +3296 -0
- package/dist/XerticaProvider-BErr83Bg.js +42 -0
- package/dist/XerticaProvider-CwOkHxiT.cjs +44 -0
- package/dist/XerticaXLogo-BX3ueACh.js +255 -0
- package/dist/XerticaXLogo-qBPhwK3g.cjs +260 -0
- 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/components/ui/stats-card/stats-card.d.ts +10 -0
- package/dist/index.cjs.js +6 -6
- package/dist/index.es.js +6 -6
- 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-B4ZWaMrE.js +792 -0
- package/dist/sidebar-BS1p2V7t.cjs +795 -0
- package/dist/ui.cjs.js +1 -1
- package/dist/ui.es.js +1 -1
- package/dist/xertica-assistant-B1NaSFFj.js +2173 -0
- package/dist/xertica-assistant-CIaUlbIt.cjs +2180 -0
- package/dist/xertica-ui.css +1 -1
- package/docs/architecture-improvements.md +5 -5
- package/docs/architecture.md +16 -10
- package/docs/components/card-patterns.md +19 -17
- package/docs/components/error-boundary.md +201 -191
- package/docs/components/hooks.md +15 -13
- package/docs/components/language-selector.md +20 -16
- package/docs/components/pages.md +323 -309
- package/docs/components/stats-card.md +20 -2
- package/docs/doc-audit.md +12 -11
- package/docs/getting-started.md +41 -28
- package/docs/guidelines.md +14 -12
- package/docs/i18n.md +61 -57
- package/docs/installation.md +268 -267
- package/docs/llms.md +17 -17
- package/docs/state-management.md +17 -17
- package/guidelines/Guidelines.md +17 -14
- package/llms-compact.txt +1 -1
- package/llms-full.txt +11553 -7133
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/styles/xertica/base.css +90 -84
- package/templates/CLAUDE.md +16 -1
- package/templates/guidelines/Guidelines.md +42 -18
- package/templates/package.json +3 -3
- package/templates/src/app/components/AuthGuard.tsx +131 -82
- package/templates/src/features/auth/ui/AuthPageShell.tsx +32 -32
- package/templates/src/features/auth/ui/ForgotPasswordContent.tsx +1 -3
- package/templates/src/features/auth/ui/ResetPasswordContent.tsx +6 -2
- package/templates/src/features/auth/ui/VerifyEmailContent.tsx +2 -6
- package/templates/src/features/home/data/mock.ts +41 -35
- package/templates/src/features/home/ui/HomeContent.tsx +62 -64
- package/templates/src/features/template/ui/CrudTemplate.tsx +1 -4
- package/templates/src/features/template/ui/LoginTemplate.tsx +1 -1
- package/templates/src/features/template/ui/TemplateContent.tsx +28 -20
- package/templates/src/locales/en/pages/templates.json +17 -17
- package/templates/src/locales/es/pages/templates.json +17 -17
- package/templates/src/locales/pt-BR/pages/templates.json +17 -17
- package/templates/src/pages/AssistantPage.tsx +26 -20
- package/templates/src/pages/HomePage.tsx +5 -1
- package/templates/src/shared/error-boundary.tsx +150 -154
- package/templates/src/shared/error-fallbacks.tsx +222 -226
- package/templates/vite.config.ts +12 -9
|
@@ -403,11 +403,11 @@ O projeto já tem excelentes exemplos do padrão headless hook que devem servir
|
|
|
403
403
|
|
|
404
404
|
### Fase 1 — Correções Críticas (1-2 dias)
|
|
405
405
|
|
|
406
|
-
| #
|
|
407
|
-
|
|
|
408
|
-
| ~~1.1~~ | ~~Corrigir `ThemeToggle` para usar `useTheme()`~~
|
|
409
|
-
| 1.2
|
|
410
|
-
| 1.3
|
|
406
|
+
| # | Tarefa | Arquivo(s) | Esforço |
|
|
407
|
+
| ------- | ------------------------------------------------------------- | ---------------------- | ------- |
|
|
408
|
+
| ~~1.1~~ | ~~Corrigir `ThemeToggle` para usar `useTheme()`~~ | ✅ Resolvido em v2.2.0 | — |
|
|
409
|
+
| 1.2 | Criar `types.ts` compartilhado para o assistente | `types.ts` (novo) | 1h |
|
|
410
|
+
| 1.3 | Atualizar imports em `AssistenteContext` e `use-assistant.ts` | 2 arquivos | 30min |
|
|
411
411
|
|
|
412
412
|
### Fase 2 — Eliminação de Duplicações (2-3 dias)
|
|
413
413
|
|
package/docs/architecture.md
CHANGED
|
@@ -12,14 +12,14 @@ The library underwent a **complete architectural modularization**. The flat `com
|
|
|
12
12
|
|
|
13
13
|
### Component Domains
|
|
14
14
|
|
|
15
|
-
| Domain | Path | Contains
|
|
16
|
-
| ----------- | ----------------------- |
|
|
17
|
-
| `ui` | `components/ui/[name]/` | Design system primitives (Button, Card, Calendar, Chart, etc.)
|
|
18
|
-
| `layout` | `components/layout/` | Sidebar, Header, SidebarPrimitive
|
|
19
|
-
| `blocks` | `components/blocks/` | High-level composed components built from `ui/` primitives
|
|
20
|
-
| `assistant` | `components/assistant/` | XerticaAssistant, MarkdownMessage, CodeBlock, etc.
|
|
21
|
-
| `brand` | `components/brand/` | XerticaLogo, ThemeToggle, LanguageSelector, XerticaProvider
|
|
22
|
-
| `pages` | `components/pages/` | LoginPage, HomePage, TemplatePage, etc.
|
|
15
|
+
| Domain | Path | Contains |
|
|
16
|
+
| ----------- | ----------------------- | ------------------------------------------------------------------------------------------------------------ |
|
|
17
|
+
| `ui` | `components/ui/[name]/` | Design system primitives (Button, Card, Calendar, Chart, etc.) |
|
|
18
|
+
| `layout` | `components/layout/` | Sidebar, Header, SidebarPrimitive |
|
|
19
|
+
| `blocks` | `components/blocks/` | High-level composed components built from `ui/` primitives |
|
|
20
|
+
| `assistant` | `components/assistant/` | XerticaAssistant, MarkdownMessage, CodeBlock, etc. |
|
|
21
|
+
| `brand` | `components/brand/` | XerticaLogo, ThemeToggle, LanguageSelector, XerticaProvider |
|
|
22
|
+
| `pages` | `components/pages/` | LoginPage, HomePage, TemplatePage, etc. |
|
|
23
23
|
| `shared` | `components/shared/` | utils.ts, use-mobile.ts, layout-constants.ts, navigation.ts, **error-boundary.tsx**, **error-fallbacks.tsx** |
|
|
24
24
|
|
|
25
25
|
### State Layer — `features/`
|
|
@@ -117,6 +117,7 @@ components/shared/
|
|
|
117
117
|
```
|
|
118
118
|
|
|
119
119
|
Placement in `App.tsx`:
|
|
120
|
+
|
|
120
121
|
```
|
|
121
122
|
AppErrorBoundary (outermost — before QueryClientProvider)
|
|
122
123
|
└─ QueryClientProvider
|
|
@@ -139,6 +140,7 @@ contexts/
|
|
|
139
140
|
```
|
|
140
141
|
|
|
141
142
|
`AuthProvider` must be rendered **inside** `<BrowserRouter>` (it uses `useNavigate`). It:
|
|
143
|
+
|
|
142
144
|
- Hydrates session from `localStorage` on mount (`isLoading` flag prevents flash redirects)
|
|
143
145
|
- Exposes `user`, `login(email, password) → boolean`, `logout()`
|
|
144
146
|
- Redirects authenticated users away from auth-only pages automatically
|
|
@@ -158,7 +160,9 @@ const HomePage = React.lazy(() =>
|
|
|
158
160
|
### Provider Stack
|
|
159
161
|
|
|
160
162
|
```tsx
|
|
161
|
-
<QueryClientProvider client={queryClient}>
|
|
163
|
+
<QueryClientProvider client={queryClient}>
|
|
164
|
+
{' '}
|
|
165
|
+
// ← TanStack React Query
|
|
162
166
|
<ApiKeyProvider>
|
|
163
167
|
<GoogleMapsLoaderProvider>
|
|
164
168
|
<LanguageProvider>
|
|
@@ -167,7 +171,9 @@ const HomePage = React.lazy(() =>
|
|
|
167
171
|
<AssistenteProvider>
|
|
168
172
|
<LayoutProvider>
|
|
169
173
|
<Router>
|
|
170
|
-
<AuthProvider>
|
|
174
|
+
<AuthProvider>
|
|
175
|
+
{' '}
|
|
176
|
+
// ← must be inside Router
|
|
171
177
|
<Suspense fallback={null}>
|
|
172
178
|
<AppRoutes />
|
|
173
179
|
</Suspense>
|
|
@@ -362,14 +362,14 @@ import { Briefcase, Users, BarChart2 } from 'lucide-react';
|
|
|
362
362
|
|
|
363
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
364
|
|
|
365
|
-
| Card
|
|
366
|
-
|
|
|
367
|
-
| `ActivityCard`
|
|
368
|
-
| `ProfileCard`
|
|
369
|
-
| `ProjectCard`
|
|
370
|
-
| `NotificationCard`
|
|
371
|
-
| `QuickActionCard`
|
|
372
|
-
| `FeatureCard`
|
|
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
373
|
|
|
374
374
|
> A matching `StatsCardSkeleton` is also available from `xertica-ui` (lives in `ui/stats-card/`, with props `showIcon` and `showTrend`).
|
|
375
375
|
|
|
@@ -390,15 +390,17 @@ function ActivityFeed() {
|
|
|
390
390
|
For grids, render one skeleton per expected card:
|
|
391
391
|
|
|
392
392
|
```tsx
|
|
393
|
-
{
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
)
|
|
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
|
+
}
|
|
402
404
|
```
|
|
403
405
|
|
|
404
406
|
### Examples
|
|
@@ -1,191 +1,201 @@
|
|
|
1
|
-
# ErrorBoundary — Xertica UI
|
|
2
|
-
|
|
3
|
-
React Error Boundaries catch JavaScript errors in the component tree, log them, and render a fallback UI instead of crashing the application. Xertica UI ships a single reusable `ErrorBoundary` class with **three pre-configured wrapper variants** covering every granularity of protection.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Import
|
|
8
|
-
|
|
9
|
-
```tsx
|
|
10
|
-
// Pre-configured wrappers (recommended)
|
|
11
|
-
import {
|
|
12
|
-
AppErrorBoundary,
|
|
13
|
-
PageErrorBoundary,
|
|
14
|
-
SectionErrorBoundary,
|
|
15
|
-
} from '@/components/shared/error-boundary';
|
|
16
|
-
|
|
17
|
-
// Base class (for custom fallbacks)
|
|
18
|
-
import { ErrorBoundary } from '@/components/shared/error-boundary';
|
|
19
|
-
import type { FallbackProps } from '@/components/shared/error-boundary';
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## The Three Variants
|
|
25
|
-
|
|
26
|
-
| Variant
|
|
27
|
-
|
|
28
|
-
| `AppErrorBoundary`
|
|
29
|
-
| `PageErrorBoundary`
|
|
30
|
-
| `SectionErrorBoundary` | Compact inline badge
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## Provider Stack Placement
|
|
35
|
-
|
|
36
|
-
```tsx
|
|
37
|
-
<AppErrorBoundary>
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
</
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
1
|
+
# ErrorBoundary — Xertica UI
|
|
2
|
+
|
|
3
|
+
React Error Boundaries catch JavaScript errors in the component tree, log them, and render a fallback UI instead of crashing the application. Xertica UI ships a single reusable `ErrorBoundary` class with **three pre-configured wrapper variants** covering every granularity of protection.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
// Pre-configured wrappers (recommended)
|
|
11
|
+
import {
|
|
12
|
+
AppErrorBoundary,
|
|
13
|
+
PageErrorBoundary,
|
|
14
|
+
SectionErrorBoundary,
|
|
15
|
+
} from '@/components/shared/error-boundary';
|
|
16
|
+
|
|
17
|
+
// Base class (for custom fallbacks)
|
|
18
|
+
import { ErrorBoundary } from '@/components/shared/error-boundary';
|
|
19
|
+
import type { FallbackProps } from '@/components/shared/error-boundary';
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## The Three Variants
|
|
25
|
+
|
|
26
|
+
| Variant | Fallback UI | Placement | Purpose |
|
|
27
|
+
| ---------------------- | ---------------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------- |
|
|
28
|
+
| `AppErrorBoundary` | Full-screen, inline-styled | Outside `QueryClientProvider`, wraps entire `App` | Catches provider/context crashes; works even if Tailwind/CSS fails |
|
|
29
|
+
| `PageErrorBoundary` | Half-height, Tailwind-styled | Wraps `<Routes>` / `<AuthGuard>` inside the router | Catches lazy-chunk load failures and page render errors; app chrome stays alive |
|
|
30
|
+
| `SectionErrorBoundary` | Compact inline badge | Wraps individual sections (table, chart, assistant) | Catches isolated data-rendering errors; page layout stays intact |
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Provider Stack Placement
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
<AppErrorBoundary>
|
|
38
|
+
{' '}
|
|
39
|
+
{/* ← catches: provider init, context crashes */}
|
|
40
|
+
<QueryClientProvider client={queryClient}>
|
|
41
|
+
<XerticaProvider>
|
|
42
|
+
<Router>
|
|
43
|
+
<AuthProvider>
|
|
44
|
+
<PageErrorBoundary>
|
|
45
|
+
{' '}
|
|
46
|
+
{/* ← catches: lazy chunk failures, route renders */}
|
|
47
|
+
<Suspense fallback={null}>
|
|
48
|
+
<Routes>
|
|
49
|
+
<Route
|
|
50
|
+
path="/home"
|
|
51
|
+
element={
|
|
52
|
+
<ProtectedRoute>
|
|
53
|
+
<HomePage /> {/* ← page internals */}
|
|
54
|
+
</ProtectedRoute>
|
|
55
|
+
}
|
|
56
|
+
/>
|
|
57
|
+
</Routes>
|
|
58
|
+
</Suspense>
|
|
59
|
+
</PageErrorBoundary>
|
|
60
|
+
</AuthProvider>
|
|
61
|
+
</Router>
|
|
62
|
+
</XerticaProvider>
|
|
63
|
+
</QueryClientProvider>
|
|
64
|
+
</AppErrorBoundary>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Props
|
|
70
|
+
|
|
71
|
+
### `AppErrorBoundary` / `PageErrorBoundary` / `SectionErrorBoundary`
|
|
72
|
+
|
|
73
|
+
| Prop | Type | Default | Description |
|
|
74
|
+
| ----------- | ----------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------- |
|
|
75
|
+
| `children` | `ReactNode` | — | **Required.** Content to protect |
|
|
76
|
+
| `onError` | `(error: Error, info: React.ErrorInfo) => void` | — | Called when an error is caught. Wire to Sentry, Datadog, etc. |
|
|
77
|
+
| `resetKeys` | `unknown[]` | — | When any value in this array changes, the boundary auto-resets. Pass `[location.pathname]` to reset on navigation |
|
|
78
|
+
|
|
79
|
+
### Base `ErrorBoundary`
|
|
80
|
+
|
|
81
|
+
Same props plus:
|
|
82
|
+
|
|
83
|
+
| Prop | Type | Description |
|
|
84
|
+
| ---------- | ------------------------------------ | ------------------------------------------------------------- |
|
|
85
|
+
| `fallback` | `React.ComponentType<FallbackProps>` | **Required.** The component to render when an error is caught |
|
|
86
|
+
|
|
87
|
+
### `FallbackProps` interface
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
interface FallbackProps {
|
|
91
|
+
error: Error; // The caught error
|
|
92
|
+
reset: () => void; // Call to clear the error and re-render children
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Usage Examples
|
|
99
|
+
|
|
100
|
+
### Protecting a data table section
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
import { SectionErrorBoundary } from '@/components/shared/error-boundary';
|
|
104
|
+
|
|
105
|
+
function TeamSection() {
|
|
106
|
+
return (
|
|
107
|
+
<SectionErrorBoundary>
|
|
108
|
+
<TeamDataTable />
|
|
109
|
+
</SectionErrorBoundary>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Resetting on route change
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
import { PageErrorBoundary } from '@/components/shared/error-boundary';
|
|
118
|
+
import { useLocation } from 'react-router-dom';
|
|
119
|
+
|
|
120
|
+
function AppRoutes() {
|
|
121
|
+
const location = useLocation();
|
|
122
|
+
return (
|
|
123
|
+
<PageErrorBoundary resetKeys={[location.pathname]}>
|
|
124
|
+
<Suspense fallback={null}>
|
|
125
|
+
<Routes>{/* ... */}</Routes>
|
|
126
|
+
</Suspense>
|
|
127
|
+
</PageErrorBoundary>
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Logging to an error monitoring service
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
import { AppErrorBoundary } from '@/components/shared/error-boundary';
|
|
136
|
+
import * as Sentry from '@sentry/react';
|
|
137
|
+
|
|
138
|
+
<AppErrorBoundary onError={(error, info) => Sentry.captureException(error, { extra: info })}>
|
|
139
|
+
<App />
|
|
140
|
+
</AppErrorBoundary>;
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Custom fallback with base `ErrorBoundary`
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
import { ErrorBoundary } from '@/components/shared/error-boundary';
|
|
147
|
+
import type { FallbackProps } from '@/components/shared/error-boundary';
|
|
148
|
+
|
|
149
|
+
function MyFallback({ error, reset }: FallbackProps) {
|
|
150
|
+
return (
|
|
151
|
+
<div role="alert">
|
|
152
|
+
<p>Erro: {error.message}</p>
|
|
153
|
+
<button onClick={reset}>Tentar novamente</button>
|
|
154
|
+
</div>
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
<ErrorBoundary fallback={MyFallback}>
|
|
159
|
+
<MyComponent />
|
|
160
|
+
</ErrorBoundary>;
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Fallback UIs
|
|
166
|
+
|
|
167
|
+
### `AppErrorFallback`
|
|
168
|
+
|
|
169
|
+
- Full-screen centered layout using **inline styles** (no Tailwind dependency)
|
|
170
|
+
- Shows a destructive info icon, error title, and message
|
|
171
|
+
- Two buttons: "Tentar novamente" (calls `reset()`) and "Ir para o início" (`window.location.assign('/')`)
|
|
172
|
+
- In `DEV` mode: displays the full error stack trace in a `<pre>` block
|
|
173
|
+
|
|
174
|
+
### `PageErrorFallback`
|
|
175
|
+
|
|
176
|
+
- Uses Tailwind / xertica-ui token classes
|
|
177
|
+
- Centered within the page content area (sidebar and header remain visible)
|
|
178
|
+
- Triangle warning icon + descriptive message
|
|
179
|
+
- Same two action buttons
|
|
180
|
+
|
|
181
|
+
### `SectionErrorFallback`
|
|
182
|
+
|
|
183
|
+
- Compact `rounded-lg` card with `destructive/30` border
|
|
184
|
+
- Circle info icon + short message
|
|
185
|
+
- Single "Tentar novamente" button
|
|
186
|
+
- In `DEV` mode: shows `error.message` in a mono paragraph
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## AI Rules
|
|
191
|
+
|
|
192
|
+
> [!IMPORTANT]
|
|
193
|
+
>
|
|
194
|
+
> - **ALWAYS** place `<AppErrorBoundary>` as the **outermost** element in `App.tsx`, before `QueryClientProvider`. If the query client itself crashes, the app must still show something.
|
|
195
|
+
> - **ALWAYS** place `<PageErrorBoundary>` around `<Routes>` / `<AuthGuard>`. This is the primary protection against lazy-chunk load failures (network errors, chunk not found).
|
|
196
|
+
> - **USE** `<SectionErrorBoundary>` around any section that fetches data or renders complex content (tables, charts, the assistant panel, embedded maps). An error in one section must not crash the page.
|
|
197
|
+
> - **DO NOT** place `<AppErrorBoundary>` inside `<Router>` — it must be outside the router so `AppErrorFallback` can use `window.location.assign` (not `useNavigate`).
|
|
198
|
+
> - **DO NOT** use `try/catch` as a substitute for `ErrorBoundary` — try/catch does not catch render-time errors in React component trees. Both are needed for different error classes.
|
|
199
|
+
> - **Pass `onError`** to the `AppErrorBoundary` in production to send errors to Sentry, Datadog, or another observability service.
|
|
200
|
+
> - **Pass `resetKeys={[location.pathname]}`** to `PageErrorBoundary` if you want errors to auto-clear when the user navigates to a different route.
|
|
201
|
+
> - Error boundaries do **not** catch: errors in event handlers (use try/catch there), async errors outside render (use React Query's `onError`), errors in server-side rendering, and errors thrown in the boundary itself.
|
package/docs/components/hooks.md
CHANGED
|
@@ -65,12 +65,12 @@ Accesses and controls the current UI language preference, plus the list of avail
|
|
|
65
65
|
|
|
66
66
|
### Return Value
|
|
67
67
|
|
|
68
|
-
| Property | Type
|
|
69
|
-
| -------------------- |
|
|
70
|
-
| `language` | `string`
|
|
68
|
+
| Property | Type | Description |
|
|
69
|
+
| -------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------- |
|
|
70
|
+
| `language` | `string` | Current language code (e.g. `'pt-BR'`, `'en'`, `'fr'`) |
|
|
71
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
|
|
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
74
|
|
|
75
75
|
### Usage
|
|
76
76
|
|
|
@@ -83,7 +83,9 @@ function LanguageDisplay() {
|
|
|
83
83
|
return (
|
|
84
84
|
<select value={language} onChange={e => setLanguage(e.target.value)}>
|
|
85
85
|
{availableLanguages.map(lang => (
|
|
86
|
-
<option key={lang.code} value={lang.code}>
|
|
86
|
+
<option key={lang.code} value={lang.code}>
|
|
87
|
+
{lang.label}
|
|
88
|
+
</option>
|
|
87
89
|
))}
|
|
88
90
|
</select>
|
|
89
91
|
);
|
|
@@ -139,13 +141,13 @@ Accesses the global AI Assistant context — conversation list, current conversa
|
|
|
139
141
|
|
|
140
142
|
### Return Value
|
|
141
143
|
|
|
142
|
-
| Property | Type
|
|
143
|
-
| ------------------ |
|
|
144
|
-
| `conversas` | `Conversation[]`
|
|
145
|
-
| `conversaAtual` | `string \| null`
|
|
146
|
-
| `setConversaAtual` | `(id: string \| null) => void`
|
|
147
|
-
| `sugestoes` | `Suggestion[]`
|
|
148
|
-
| `setSugestoes` | `(s: Suggestion[]) => void`
|
|
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 |
|
|
149
151
|
|
|
150
152
|
### Usage
|
|
151
153
|
|