react-lgpd-consent 0.5.3 → 0.5.4

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/QUICKSTART.md CHANGED
@@ -25,7 +25,7 @@ npm install @mui/material @mui/icons-material @emotion/react @emotion/styled
25
25
 
26
26
  ## 🎯 Uso Básico (30 segundos)
27
27
 
28
- ````tsx
28
+ ```tsx
29
29
  import React from 'react'
30
30
  import { ConsentProvider } from 'react-lgpd-consent'
31
31
 
@@ -42,6 +42,7 @@ function App() {
42
42
  </main>
43
43
  </ConsentProvider>
44
44
  )
45
+ ```
45
46
 
46
47
  ## 🧭 Storybook — quick note
47
48
 
@@ -51,7 +52,7 @@ This repository ships an interactive Storybook playground used for manual testin
51
52
 
52
53
  ```bash
53
54
  npm run storybook
54
- ````
55
+ ```
55
56
 
56
57
  - Build static Storybook (for publishing to GitHub Pages):
57
58
 
@@ -63,11 +64,6 @@ Notes:
63
64
 
64
65
  - The Storybook preview (`.storybook/preview.tsx`) applies a clean environment between stories (removes consent cookie and performs defensive DOM cleanup). Check that file when creating stories that rely on a clean initial state.
65
66
 
66
- }
67
-
68
- export default App
69
-
70
- ````
71
67
 
72
68
  ## ⚡ Quickstarts: Next.js (App Router) e Vite
73
69
 
@@ -402,8 +398,8 @@ function MyComponent() {
402
398
 
403
399
  ## 📋 Tabela Completa de Props do ConsentProvider
404
400
 
405
- | Prop | Tipo | Obrigatória | Padrão | Descrição |
406
- | ------------------------------------ | ----------------------------------------------------------- | ----------- | ------------------- | ---------------------------------------------- |
401
+ | Prop | Tipo | Obrigatória | Padrão | Descrição |
402
+ | ----------------- | ------------------------------------------------ | ----------- | -------------- | --------------------------------------- |
407
403
  | `categories` | `ProjectCategoriesConfig` | ✅ **Sim** | - | Define as categorias de cookies do projeto |
408
404
  | `texts` | `Partial<ConsentTexts>` | ❌ Não | Textos padrão PT-BR | Customiza textos da interface |
409
405
  | `theme` | `any` | ❌ Não | Tema padrão | Tema Material-UI para os componentes |
@@ -422,7 +418,89 @@ function MyComponent() {
422
418
  | `preferencesModalProps` | `object` | ❌ Não | `{}` | Props adicionais para o modal |
423
419
  | `floatingPreferencesButtonProps` | `object` | ❌ Não | `{}` | Props adicionais para o botão flutuante |
424
420
  | `initialState` | `ConsentState` | ❌ Não | - | Estado inicial para hidratação SSR |
425
- | `cookie` | `Partial<ConsentCookieOptions>` | ❌ Não | Opções padrão | Configurações do cookie de consentimento |
421
+ | `cookie` | `Partial<ConsentCookieOptions>` | ❌ Não | Opções padrão | Configurações do cookie (override fino de `name`, `domain`, `sameSite` etc.) |
422
+ | `storage` | `ConsentStorageConfig` | ❌ Não | `{ namespace: 'lgpd-consent', version: '1' }` | Namespace, versão e domínio compartilhado da chave de consentimento |
423
+ | `onConsentVersionChange` | `(context: ConsentVersionChangeContext) => void` | ❌ Não | Reset automático | Hook disparado após bump da chave; use para limpar caches adicionais |
424
+
425
+ ## 🔄 Versionamento de Consentimento (0.5.x)
426
+
427
+ - **Resumo da solicitação**: namespace + versão para a chave de consentimento e estratégia de migração entre releases, garantindo compartilhamento entre subdomínios.
428
+ - **Caso de uso — problema que resolve**: quando o escopo de dados muda (novas categorias, integrações etc.), usuários precisam reafirmar consentimento. Sem um identificador de versão, o estado antigo permanece ativo e quebra conformidade.
429
+
430
+ ### Solução proposta
431
+ - `storage.namespace` e `storage.version` geram automaticamente o nome do cookie via `buildConsentStorageKey`, mantendo o schema `namespace__v<versão>` (`lgpd-consent__v1` por padrão).
432
+ - `storage.domain` centraliza o domínio compartilhado (ex.: `.gov.br`) para que um único banner sirva múltiplos subdomínios.
433
+ - `onConsentVersionChange` é chamado sempre que a chave muda. O reset do estado é automático, mas o hook permite limpar caches customizados (ex.: localStorage, indexedDB) antes de liberar a nova experiência.
434
+ - Guia de migração: documente no seu changelog interno quando e por que o valor de `storage.version` mudou. O bump NÃO é breaking change porque a API pública permanece compatível—apenas força o fluxo de re-consent.
435
+ - Breaking change? **Não** — quem não configurar `storage` continua usando `lgpd-consent__v1`; ao aumentar a versão apenas ocorre re-consentimento.
436
+
437
+ ### Critérios de aceitação
438
+ - Trocar `storage.version` força o fluxo completo: cookie antigo removido, `ConsentProvider` volta ao estado sem consentimento e o usuário vê o banner novamente.
439
+ - Subdomínios compartilham o mesmo consentimento quando `storage.domain` usa um domínio com ponto (`.example.com`).
440
+ - `onConsentVersionChange` entrega `previousKey`, `nextKey` e `resetConsent` para coordenar invalidação de caches externos.
441
+
442
+ ## 🔒 Cookies necessários sempre ativos
443
+
444
+ - **Resumo da solicitação**: implementar a política de “necessários sempre ativos” tanto na UI quanto na persistência.
445
+ - **Caso de uso — problema resolvido**: atende ao requisito LGPD/ANPD de que cookies estritamente necessários não podem ser desativados; evita confusão na interface e garante consistência nos hooks.
446
+
447
+ ### Como a biblioteca reforça a regra
448
+ - A categoria `necessary` é adicionada automaticamente pelo `ConsentProvider` e sempre persistida como `true`.
449
+ - `setPreference('necessary', false)` e `setPreferences({ necessary: false, ... })` são ignorados com logs de aviso — o estado permanece com `necessary=true`.
450
+ - O `PreferencesModal` padrão exibe a categoria com switch desabilitado e o texto `Cookies necessários (sempre ativos)`.
451
+ - `writeConsentCookie` garante `necessary=true` mesmo que o estado enviado esteja corrompido.
452
+ - Hooks (`useConsent`, `useCategoryStatus`) e integrações (`ConsentScriptLoader`, dataLayer) sempre recebem `necessary=true`.
453
+
454
+ ### Exemplo (apenas cookies necessários)
455
+
456
+ ```tsx
457
+ import { ConsentProvider } from '@react-lgpd-consent/core'
458
+
459
+ export function MinimalBoundary({ children }: { children: React.ReactNode }) {
460
+ return <ConsentProvider categories={{ enabledCategories: [] }}>{children}</ConsentProvider>
461
+ }
462
+ ```
463
+
464
+ ### Critérios de aceitação
465
+ - UI, hooks, persistência e dataLayer mantêm `necessary=true` em todos os caminhos.
466
+ - Testes automatizados cobrem tentativas de toggle/programmatic override e serialização.
467
+ - Breaking change? **Não** — o comportamento já era esperado; agora é reforçado pelo runtime com avisos para cenários indevidos.
468
+
469
+ ### Exemplo completo (namespace + versão + subdomínio)
470
+
471
+ ```tsx
472
+ import { buildConsentStorageKey, ConsentProvider } from 'react-lgpd-consent'
473
+
474
+ function ComplianceWrapper({ children }: { children: React.ReactNode }) {
475
+ return (
476
+ <ConsentProvider
477
+ categories={{ enabledCategories: ['analytics', 'marketing'] }}
478
+ storage={{
479
+ namespace: 'portal.gov.br',
480
+ version: '2025-Q4',
481
+ domain: '.gov.br',
482
+ }}
483
+ cookie={{
484
+ // Opcional: sobrescreva o nome explicitamente (útil para auditoria legada)
485
+ name: buildConsentStorageKey({ namespace: 'portal.gov.br', version: '2025-Q4' }),
486
+ }}
487
+ onConsentVersionChange={({ previousKey, nextKey, resetConsent }) => {
488
+ console.info('[consent] versão atualizada', { previousKey, nextKey })
489
+ window.dataLayer?.push({ event: 'consent_version_bumped', previousKey, nextKey })
490
+ localStorage.removeItem('marketing-optins')
491
+ resetConsent()
492
+ }}
493
+ >
494
+ {children}
495
+ </ConsentProvider>
496
+ )
497
+ }
498
+ ```
499
+
500
+ ### Alternativas consideradas
501
+ - **Invalidar sempre** (reset em toda visita) prejudica a UX e reduz taxas de aceitação.
502
+ - **Nunca invalidar** mantém consentimentos fora de escopo e compromete a conformidade.
503
+ - A solução de namespace + versão expõe explicitamente quando o reconsentimento é necessário.
426
504
 
427
505
  ## 🎨 Componentes Customizados com TypeScript
428
506
 
@@ -488,7 +566,7 @@ A biblioteca `react-lgpd-consent` não injeta um `ThemeProvider` global por cont
488
566
 
489
567
  ```tsx
490
568
  import { ConsentProvider, createDefaultConsentTheme } from 'react-lgpd-consent'
491
- ;<ConsentProvider
569
+ <ConsentProvider
492
570
  theme={createDefaultConsentTheme()}
493
571
  categories={{ enabledCategories: ['analytics'] }}
494
572
  >
@@ -496,6 +574,7 @@ import { ConsentProvider, createDefaultConsentTheme } from 'react-lgpd-consent'
496
574
  </ConsentProvider>
497
575
  ```
498
576
 
577
+
499
578
  Isso evita alterações indesejadas no contexto do MUI do seu app e problemas de SSR.
500
579
 
501
580
  ```tsx