xertica-ui 2.9.6 → 2.9.8
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 +20 -0
- package/README.md +1 -1
- package/bin/cli.ts +1 -1
- package/bin/language-config.ts +18 -10
- package/components/ui/input-otp/input-otp.test.tsx +14 -1
- package/dist/cli.js +14 -9
- package/dist/xertica-ui.css +1 -1
- package/package.json +4 -2
- package/templates/src/pages/LandingPage.tsx +348 -2
- package/templates/src/styles/index.css +5 -0
- package/templates/tsconfig.node.json +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -11,12 +11,32 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
+
## [2.9.8] — 2026-07-14
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **Projeto gerado pelo scaffold "Web page" não compilava — erros de tipo de bibliotecas de terceiros** — `tsconfig.node.json` não tinha `skipLibCheck`, então o type-check processava as definições de tipo de dependências transitivas usadas internamente pelo Vite (`d3-array`, `prismjs`, etc.), e qualquer inconsistência nelas quebrava a compilação do projeto gerado, mesmo sem nenhum erro real no código do usuário. Corrigido adicionando `"skipLibCheck": true` a `templates/tsconfig.node.json`, usado tanto pelo scaffold "Web page" quanto pelo "Full system".
|
|
19
|
+
- **Tela em branco no scaffold "Web page" — `Error: No QueryClient set, use QueryClientProvider to set one`** — o `App.tsx` gerado por `generateLandingAppTsx` (`bin/language-config.ts`) renderizava `<LandingPage>` direto dentro de `<XerticaProvider>`, sem `QueryClientProvider`, partindo do pressuposto de que a landing page não dependia de React Query. Só que `XerticaProvider` monta `LanguageProvider` internamente, e este chama `useQueryClient()` para invalidar queries traduzíveis na troca de idioma — sem um `QueryClientProvider` acima na árvore, o app quebra no primeiro render. Corrigido envolvendo o `App.tsx` gerado em `<QueryClientProvider client={queryClient}>` (com `queryClient = new QueryClient()`), o mesmo padrão que o scaffold "Full system" (`generateAppTsx`) já usava.
|
|
20
|
+
- **Scroll não funcionava no scaffold "Web page"** — o CSS da própria lib (`styles/xertica/base.css`) define `html, body { height: 100%; overflow: hidden; }`, delegando o scroll a um container interno com altura própria resolvida. Como o `#root` gerado pelo Vite não tinha altura definida, a `LandingPage` (que usa `h-full overflow-y-auto`) não tinha em relação a que altura calcular seu próprio limite de scroll. Corrigido adicionando `#root { height: 100%; }` a `templates/src/styles/index.css`.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## [2.9.7] — 2026-07-14
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- **Suíte de testes com exceção não tratada bloqueando `npm publish`** — o pacote de terceiros `input-otp` agenda três `setTimeout` internos (0ms/10ms/50ms) em um `useEffect` sem função de limpeza no unmount. Ao rodar a suíte completa, o cleanup automático do Testing Library desmontava o `InputOTP` entre um teste e outro sem cancelar esses timers, que disparavam mais tarde — já fora do ambiente jsdom daquele arquivo — lançando `ReferenceError: window is not defined` como exceção não tratada. Isso fazia `vitest run` sair com erro mesmo com todos os 358 testes passando, derrubando a etapa `test:unit` do `prepublishOnly` e, com isso, qualquer tentativa de `npm publish`. Corrigido em `components/ui/input-otp/input-otp.test.tsx` usando `vi.useFakeTimers()`/`vi.useRealTimers()` ao redor de cada teste, impedindo que os timers da lib vazem para fora do ciclo de vida do teste.
|
|
29
|
+
- **`npm publish` alertava sobre correção automática do campo `bin`** — `"bin": "./dist/cli.js"` (string, com prefixo `./`) era normalizado pelo próprio npm no momento do publish, gerando o aviso `npm auto-corrected some errors in your package.json`. Corrigido escrevendo `bin` já na forma canônica esperada (`{ "xertica-ui": "dist/cli.js" }`), sem mudança de comportamento — apenas elimina o aviso.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
14
33
|
## [2.9.6] — 2026-07-14
|
|
15
34
|
|
|
16
35
|
### Added
|
|
17
36
|
|
|
18
37
|
- **CLI `init` pergunta o tipo de projeto antes de tudo** — novo primeiro prompt `O que você deseja criar?` com duas opções: `Full system` (o fluxo completo existente, inalterado: auth, sidebar, páginas, i18n) e `Web page` (um scaffold mínimo com apenas a landing page de marketing). Escolhendo `Web page`, o fluxo se reduz a 3 prompts — idiomas (multiselect), tema (select) e instalação de dependências (confirm) — e o projeto já sai pronto, sem nenhuma outra configuração.
|
|
19
38
|
- **Novo scaffold mínimo para "Web page"** (`initPageProject` em `bin/cli.ts`) — gera um `App.tsx` que renderiza `LandingPage` (via novo `generateLandingAppTsx` em `bin/language-config.ts`) diretamente dentro de `XerticaProvider`, sem `Router`, `QueryClientProvider` ou `AuthProvider`. Não cria `AuthContext.tsx`, `AuthGuard.tsx`, `AppLayout.tsx`, `src/shared/` nem `src/features/` — apenas `src/app/App.tsx`, `src/pages/LandingPage.tsx`, i18n/locales e tokens de tema. Também omite `CLAUDE.md`/`guidelines/` (documentam a arquitetura FSD de auth, inexistente neste scaffold) e `.env.example` (chaves usadas só pelo assistente/mapa).
|
|
39
|
+
- **`src/pages/LandingPage.tsx` do scaffold "Web page" ganha conteúdo de demonstração real** — em vez de um re-export de `xertica-ui/pages`, o template (`templates/src/pages/LandingPage.tsx`) agora traz a composição completa da landing page (Hero, cards, feature rows, "how it works", compliance/stats, CTA, footer) montada localmente a partir de `xertica-ui/blocks`/`xertica-ui/brand`, igual ao padrão já usado pelos demais templates (`HomeContent.tsx` etc.) — o usuário recebe algo editável como base, não uma caixa-preta importada da lib.
|
|
20
40
|
- **`.xertica.json` ganha o campo `projectType: 'page' | 'system'`** — projetos escaffoldados antes desta versão não têm o campo e são tratados como `'system'` em todos os pontos que o leem, preservando compatibilidade.
|
|
21
41
|
|
|
22
42
|
### Changed
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> **Enterprise-grade React design system** built on Tailwind CSS v4, Radix UI, and Lucide Icons — with a robust AI-first documentation layer for precise LLM-driven composition and autonomous agent interaction.
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/xertica-ui)
|
|
6
6
|
[](./LICENSE)
|
|
7
7
|
|
|
8
8
|
---
|
package/bin/cli.ts
CHANGED
|
@@ -439,7 +439,7 @@ async function initPageProject(targetDir: string, templatesDir: string): Promise
|
|
|
439
439
|
}
|
|
440
440
|
console.log(chalk.cyan(' npm run dev'));
|
|
441
441
|
console.log();
|
|
442
|
-
console.log(chalk.gray('
|
|
442
|
+
console.log(chalk.gray(' Edit the demo content in src/pages/LandingPage.tsx'));
|
|
443
443
|
console.log(chalk.gray(' Customize the theme in src/styles/xertica/tokens.css'));
|
|
444
444
|
console.log(chalk.gray(' To change the theme or languages later: npx xertica-ui update'));
|
|
445
445
|
} catch (error) {
|
package/bin/language-config.ts
CHANGED
|
@@ -362,27 +362,35 @@ export default function App() {
|
|
|
362
362
|
/**
|
|
363
363
|
* Generate the App.tsx source for a minimal "web page" project — renders the
|
|
364
364
|
* marketing `LandingPage` directly under `XerticaProvider`, with none of the
|
|
365
|
-
* router/
|
|
366
|
-
*
|
|
365
|
+
* router/auth machinery the full system scaffold needs. `QueryClientProvider`
|
|
366
|
+
* is still required, though: `XerticaProvider` mounts `LanguageProvider`
|
|
367
|
+
* internally, which calls `useQueryClient()` to invalidate translated queries
|
|
368
|
+
* on language change — without a provider above it, the app throws "No
|
|
369
|
+
* QueryClient set" at render time.
|
|
367
370
|
*/
|
|
368
371
|
export function generateLandingAppTsx(
|
|
369
372
|
selectedCodes: string[],
|
|
370
373
|
disableDarkMode: boolean = false
|
|
371
374
|
): string {
|
|
372
|
-
const disableDarkModeProp = disableDarkMode ? `\n
|
|
373
|
-
const availableLanguagesProp = buildAvailableLanguagesProp(selectedCodes, '
|
|
375
|
+
const disableDarkModeProp = disableDarkMode ? `\n disableDarkMode={true}` : '';
|
|
376
|
+
const availableLanguagesProp = buildAvailableLanguagesProp(selectedCodes, ' ');
|
|
374
377
|
|
|
375
378
|
return `import React from 'react';
|
|
379
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
376
380
|
import { XerticaProvider } from 'xertica-ui/brand';
|
|
377
|
-
import { LandingPage } from '
|
|
381
|
+
import { LandingPage } from '../pages/LandingPage';
|
|
382
|
+
|
|
383
|
+
const queryClient = new QueryClient();
|
|
378
384
|
|
|
379
385
|
export default function App() {
|
|
380
386
|
return (
|
|
381
|
-
<
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
387
|
+
<QueryClientProvider client={queryClient}>
|
|
388
|
+
<XerticaProvider
|
|
389
|
+
useCustomTokens={true}${availableLanguagesProp}${disableDarkModeProp}
|
|
390
|
+
>
|
|
391
|
+
<LandingPage />
|
|
392
|
+
</XerticaProvider>
|
|
393
|
+
</QueryClientProvider>
|
|
386
394
|
);
|
|
387
395
|
}
|
|
388
396
|
`;
|
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
import { render, screen, fireEvent } from '@testing-library/react';
|
|
2
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
3
3
|
import { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } from './input-otp';
|
|
4
4
|
import { OTPInputContext } from 'input-otp';
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
7
7
|
describe('InputOTP', () => {
|
|
8
|
+
// input-otp schedules internal setTimeout(0/10/50) calls on mount that it
|
|
9
|
+
// never cancels on unmount. Under real timers those fire after this file's
|
|
10
|
+
// jsdom environment is torn down, throwing `window is not defined` as an
|
|
11
|
+
// unhandled error in later test files. Fake timers keep them from ever
|
|
12
|
+
// firing for real.
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
vi.useFakeTimers();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
vi.useRealTimers();
|
|
19
|
+
});
|
|
20
|
+
|
|
8
21
|
it('renders children correctly', () => {
|
|
9
22
|
render(
|
|
10
23
|
<OTPInputContext.Provider value={{ slots: [{ char: 'A' }] } as any}>
|
package/dist/cli.js
CHANGED
|
@@ -901,19 +901,24 @@ export default function App() {
|
|
|
901
901
|
}
|
|
902
902
|
function generateLandingAppTsx(selectedCodes, disableDarkMode = false) {
|
|
903
903
|
const disableDarkModeProp = disableDarkMode ? `
|
|
904
|
-
|
|
905
|
-
const availableLanguagesProp = buildAvailableLanguagesProp(selectedCodes, "
|
|
904
|
+
disableDarkMode={true}` : "";
|
|
905
|
+
const availableLanguagesProp = buildAvailableLanguagesProp(selectedCodes, " ");
|
|
906
906
|
return `import React from 'react';
|
|
907
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
907
908
|
import { XerticaProvider } from 'xertica-ui/brand';
|
|
908
|
-
import { LandingPage } from '
|
|
909
|
+
import { LandingPage } from '../pages/LandingPage';
|
|
910
|
+
|
|
911
|
+
const queryClient = new QueryClient();
|
|
909
912
|
|
|
910
913
|
export default function App() {
|
|
911
914
|
return (
|
|
912
|
-
<
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
915
|
+
<QueryClientProvider client={queryClient}>
|
|
916
|
+
<XerticaProvider
|
|
917
|
+
useCustomTokens={true}${availableLanguagesProp}${disableDarkModeProp}
|
|
918
|
+
>
|
|
919
|
+
<LandingPage />
|
|
920
|
+
</XerticaProvider>
|
|
921
|
+
</QueryClientProvider>
|
|
917
922
|
);
|
|
918
923
|
}
|
|
919
924
|
`;
|
|
@@ -1261,7 +1266,7 @@ async function initPageProject(targetDir, templatesDir) {
|
|
|
1261
1266
|
}
|
|
1262
1267
|
console.log(chalk.cyan(" npm run dev"));
|
|
1263
1268
|
console.log();
|
|
1264
|
-
console.log(chalk.gray("
|
|
1269
|
+
console.log(chalk.gray(" Edit the demo content in src/pages/LandingPage.tsx"));
|
|
1265
1270
|
console.log(chalk.gray(" Customize the theme in src/styles/xertica/tokens.css"));
|
|
1266
1271
|
console.log(chalk.gray(" To change the theme or languages later: npx xertica-ui update"));
|
|
1267
1272
|
} catch (error) {
|