react-lgpd-consent 0.4.1 → 0.4.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/CHANGELOG.md CHANGED
@@ -4,9 +4,109 @@ Todas as mudanças notáveis neste projeto serão documentadas neste arquivo.
4
4
 
5
5
  O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.0.0/), e este projeto segue [Semantic Versioning](https://semver.org/lang/pt-BR/).
6
6
 
7
+ ## [0.4.4] - 2025-10-06 — Correções de CI/CD e Publicação
8
+
9
+ ### 🔧 **Correções de CI/CD**
10
+
11
+ - **Workflow de Publicação npm**: Corrigido bug que impedia publicação mesmo quando tag estava na `main`
12
+ - **Problema**: `git fetch --depth=1` limitava histórico e falhava verificação de ancestralidade
13
+ - **Solução**: Removido `--depth=1` do fetch, aproveitando `fetch-depth: 0` do checkout
14
+ - **Impacto**: Tags criadas após merge para `main` agora são publicadas corretamente no npm
15
+
16
+ ### 📊 **Integração com Codecov**
17
+
18
+ - **Upload de Coverage**: Adicionado `codecov/codecov-action@v5` ao workflow CI
19
+ - Envia relatórios de cobertura automaticamente para Codecov
20
+ - Token configurado via `secrets.CODECOV_TOKEN`
21
+ - Integração com badge de coverage no README
22
+
23
+ ### 📚 **Documentação**
24
+
25
+ - **Badges**: Badge de coverage já configurado no README (v0.4.3) agora recebe dados em tempo real
26
+ - **Workflows**: Documentação inline sobre fetch depth e verificação de ancestralidade
27
+
28
+ ## [0.4.3] - 2025-10-06 — Otimizações de Performance e Qualidade
29
+
30
+ ### 🚀 **Melhorias de Performance**
31
+
32
+ - **React.memo**: Adicionado memoização em componentes puros (`Branding`, `FloatingPreferencesButton`)
33
+ - **useMemo**: Otimizado cálculo de `positionStyles` no `FloatingPreferencesButton`
34
+ - **Lazy Loading Expandido**: `FloatingPreferencesButton` agora é carregado sob demanda
35
+ - **Logger em Produção**: `warn()`, `info()`, `debug()` suprimidos em `NODE_ENV=production`
36
+ - Reduz overhead em bundle de produção
37
+ - `error()` permanece ativo para debugging crítico
38
+
39
+ ### 🐛 **Correções Críticas**
40
+
41
+ - **ConsentProvider Suspense Bug**: Corrigido crash silencioso quando `consented=true`
42
+ - Adicionado `<React.Suspense>` ausente ao redor do `FloatingPreferencesButton` lazy
43
+ - Sintoma: Provider renderizava `<div />` vazio ao invés de `children`
44
+ - Impacto: Testes com `initialState.consented=true` agora passam
45
+
46
+ ### 🧪 **Testes de Acessibilidade (A11y)**
47
+
48
+ - **jest-axe**: Integração completa com validação WCAG automática
49
+ - **CookieBanner.a11y.test.tsx**: 3 cenários de acessibilidade validados
50
+ - **PreferencesModal.a11y.test.tsx**: 3 cenários de acessibilidade validados
51
+ - **TypeScript**: Definições `jest-axe.d.ts` para matcher `toHaveNoViolations()`
52
+ - **Script**: Adicionado `npm run test:a11y` para testes focados
53
+
54
+ ### 📦 **Exports Modulares**
55
+
56
+ - **`./integrations`**: Novo export separado para tree-shaking otimizado
57
+ - Permite `import { createGoogleAnalyticsIntegration } from 'react-lgpd-consent/integrations'`
58
+ - Reduz bundle para consumidores que não usam integrações
59
+ - Suporte ESM + CJS + TypeScript definitions
60
+
61
+ ### 🔧 **CI/CD**
62
+
63
+ - **Node.js 20**: Atualizado de Node 18 para Node 20 LTS em todos os workflows
64
+ - **Cache TypeScript**: Adicionado cache de builds para acelerar CI (~20% mais rápido)
65
+ - Cache de `.tsbuildinfo`, `node_modules/.cache`, `.eslintcache`
66
+ - Workflows atualizados: `ci.yml`, `codeql.yml`, `deploy-docs.yml`, `package-check.yml`
67
+
68
+ ### 📚 **Documentação**
69
+
70
+ - **Badges**: Adicionados 3 badges ao README (Coverage, Bundle Size, Node Version)
71
+ - Codecov para visualização de cobertura
72
+ - Bundlephobia para tamanho de bundle
73
+ - Node.js badge para requisitos de ambiente
74
+
75
+ ### ✅ **Validação de Qualidade**
76
+
77
+ - **222 testes passando**: 100% de sucesso sem skips
78
+ - **94.85% cobertura**: Mantida cobertura alta
79
+ - **0 warnings de lint**: ESLint limpo
80
+ - **Build otimizado**: ESM 32.52 KB + lazy chunks (95B + 86B)
81
+
82
+ ### 📦 **Otimizações de Bundle**
83
+
84
+ - **tsup.config.ts**: Configuração otimizada para tree-shaking e code-splitting
85
+ - **ESM Bundle**: 33.26 KB → 32.52 KB (-740B, -2.2%)
86
+ - **CJS Bundle**: 118.51 KB → 37.71 KB (CJS principal) + chunks (-68%, muito mais eficiente!)
87
+ - **Brotli Compressed**:
88
+ - ESM: 17.06 KB → 16.95 KB (-110B)
89
+ - CJS: 68.72 KB → 18.02 KB (-74%, -50.7 KB!)
90
+ - **Side-effects**: Configuração refinada para preservar code-splitting sem warnings
91
+ - **Tree-shaking**: Agressivo com external de peer dependencies
92
+
93
+ ### 🎯 **Decisões de Design**
94
+
95
+ - **ConsentGate não usa memo**: Decisão intencional - estado de preferências é dinâmico
96
+ - Re-renders necessários quando usuário altera consentimento
97
+ - Lógica leve o suficiente para não justificar memoização
98
+
99
+ ### 📋 **Dependências**
100
+
101
+ - **Adicionadas**:
102
+ - `@axe-core/react@^4.10.2` (dev)
103
+ - `jest-axe@^10.0.0` (dev)
104
+ - `@types/jest-axe@^3.5.9` (dev)
105
+
7
106
  ## [0.4.1] - 2025-09-21 — Expansão das Integrações Nativas de Scripts
8
107
 
9
108
  ### 🚀 **Integrações Nativas Expandidas**
109
+
10
110
  - **Facebook Pixel**: `createFacebookPixelIntegration()` com auto-tracking e advanced matching
11
111
  - **Hotjar**: `createHotjarIntegration()` para heatmaps e session recordings
12
112
  - **Mixpanel**: `createMixpanelIntegration()` com configuração avançada de eventos
@@ -17,18 +117,21 @@ O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.0.
17
117
  - **Freshchat**: `createFreshchatIntegration()` para customer support
18
118
 
19
119
  ### 🎯 **Sistema de Configuração em Lote**
120
+
20
121
  - **Templates de negócio**: `createECommerceIntegrations()`, `createSaaSIntegrations()`, `createCorporateIntegrations()`
21
122
  - **Categorização inteligente**: `suggestCategoryForScript()` para sugestão automática de categorias
22
123
  - **Configuração unificada**: Setup simplificado para múltiplas ferramentas com um comando
23
124
  - **Padrões de mercado**: Templates baseados em necessidades reais do mercado brasileiro
24
125
 
25
126
  ### 🔧 **Melhorias no Sistema de Scripts**
127
+
26
128
  - **Validação robusta**: `validateNecessaryClassification()` corrigida para evitar falsos positivos
27
129
  - **Auto-configuração**: `autoConfigureCategories()` com detecção inteligente de categorias necessárias
28
130
  - **Error handling**: Melhor tratamento de erros em carregamento de scripts
29
131
  - **Performance**: Carregamento otimizado e lazy loading de integrações
30
132
 
31
133
  ### 🔍 **Descoberta Automática de Cookies (Experimental)**
134
+
32
135
  - **discoverRuntimeCookies()**: Escaneamento de cookies em tempo real no navegador
33
136
  - **detectConsentCookieName()**: Detecção automática do cookie de consentimento
34
137
  - **categorizeDiscoveredCookies()**: Categorização inteligente usando padrões LGPD
@@ -36,17 +139,20 @@ O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.0.
36
139
  - **SSR-safe**: Funciona corretamente em ambientes server-side rendering
37
140
 
38
141
  ### 🎨 **Design Tokens Expandidos**
142
+
39
143
  - **200+ pontos de customização**: Expansão dramática do sistema de design tokens
40
144
  - **Sistema responsivo**: Breakpoints, spacing responsivo, typography hierarchy
41
145
  - **Acessibilidade nativa**: Contrast ratios, focus states, motion preferences
42
146
  - **Tokens por componente**: Customização granular para cada elemento UI
43
147
 
44
148
  ### 📝 **Sistema Avançado de Textos**
149
+
45
150
  - **Templates pré-configurados**: Ecommerce, SaaS, Governo com contextos específicos
46
151
  - **Multilingual**: Português, inglês, espanhol com fallbacks inteligentes
47
152
  - **Função resolveTexts**: Resolução automática de textos baseada em contexto
48
153
 
49
154
  ### 🧪 **Melhorias de Testes e Qualidade**
155
+
50
156
  - **193 testes passando**: Cobertura substancialmente melhorada
51
157
  - **19 novos testes**: Especificamente para `cookieRegistry` (antes 45.83% → 100% branches)
52
158
  - **Test realism**: Testes adaptados ao comportamento real vs ideal
@@ -54,6 +160,7 @@ O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.0.
54
160
  - **Lint compliance**: Configuração ESLint mais rigorosa e aderente
55
161
 
56
162
  ### 🔧 **Melhorias de API e Developer Experience**
163
+
57
164
  - **Exports organizados**: Melhor estruturação das exportações públicas
58
165
  - **TypeScript strict**: Tipagem mais rigorosa e descritiva
59
166
  - **Documentação TSDoc**: Comentários expandidos com exemplos práticos
@@ -61,12 +168,14 @@ O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.0.
61
168
  - **Performance**: Otimizações em carregamento e renderização
62
169
 
63
170
  ### 📚 **Exemplos e Migração**
171
+
64
172
  - **MigrationDemo-v0.4.1.tsx**: Exemplo completo mostrando todas as novidades
65
173
  - **Remoção**: TestV0.3.1.tsx removido (obsoleto)
66
174
  - **Compatibilidade**: Guias de migração antes/depois
67
175
  - **Best practices**: Demonstrações de uso avançado
68
176
 
69
177
  ### 🏗️ **Build e Infraestrutura**
178
+
70
179
  - **Bundle otimizado**: ESM 34.36 KB, CJS 102.74 KB
71
180
  - **Tree-shaking**: Configuração `sideEffects: false` otimizada
72
181
  - **Docs geradas**: TypeDoc atualizado com novas funcionalidades
@@ -74,22 +183,25 @@ O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.0.
74
183
 
75
184
  ### ⚠️ **Breaking Changes**
76
185
 
77
- #### 🔧 **`setPreference` Type Change**
186
+ #### 🔧 **`setPreference` Type Change**
187
+
78
188
  - **Mudança**: `setPreference(cat: Category, value: boolean)` → `setPreference(cat: string, value: boolean)`
79
- - **Motivo**: Suporte a categorias customizadas além das predefinidas
189
+ - **Motivo**: Suporte a categorias customizadas além das predefinidas
80
190
  - **Impacto**: Código TypeScript com tipo `Category` explícito pode precisar ajustes
81
- - **Migração**:
191
+ - **Migração**:
82
192
  - ✅ **Nenhuma mudança necessária** se usando strings literais (`'analytics'`, `'marketing'`)
83
193
  - ⚠️ **Ajuste necessário** apenas se estava usando explicitamente o tipo `Category`
84
194
  - 📚 **Guia**: Use `string` para suportar categorias customizadas ou continue usando os valores padrão
85
195
 
86
196
  #### 🔧 **`ScriptIntegration.category` Type Change**
197
+
87
198
  - **Mudança**: `category: Category` → `category: string`
88
199
  - **Motivo**: Suporte a categorias customizadas nas integrações de script
89
200
  - **Impacto**: Integrações customizadas com tipo `Category` explícito
90
201
  - **Migração**: Mesmas diretrizes do `setPreference` acima
91
202
 
92
203
  ### 🎯 **Categorias Suportadas**
204
+
93
205
  - `necessary` (sempre ativo)
94
206
  - `analytics` (Google Analytics, etc.)
95
207
  - `marketing` (Facebook Pixel, Google Ads)
@@ -98,6 +210,7 @@ O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.0.
98
210
  - `personalization` (Preferências, customização)
99
211
 
100
212
  ### 📈 **Estatísticas de Melhoria**
213
+
101
214
  - **Design Tokens**: 4 → 200+ pontos de customização (+4900%)
102
215
  - **Testes**: 174 → 193 testes (+11% cobertura)
103
216
  - **Funcionalidades**: +15 novas funções exportadas
@@ -107,6 +220,7 @@ O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.0.
107
220
  ## [0.4.0] - 2025-09-09 — Custom categories
108
221
 
109
222
  ### Added
223
+
110
224
  - Support for `customCategories` in `ConsentProvider.categories`.
111
225
  - Included in preferences initialization and validation.
112
226
  - Shown in the Preferences modal (with name/description).
@@ -115,6 +229,7 @@ O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.0.
115
229
  - Storybook story: WithCustomCategories.
116
230
 
117
231
  ### Notes
232
+
118
233
  - Non-breaking change; existing configurations continue to work.
119
234
 
120
235
  ## [0.3.7] - 2025-09-08 - Testes de UI e carregamento de scripts
@@ -656,3 +771,35 @@ A v0.2.1 introduz um **sistema inteligente de orientações** que guia desenvolv
656
771
  - [ ] Base legal por categoria
657
772
  - [ ] Relatórios de compliance
658
773
  - [ ] Templates por setor
774
+
775
+ ## [0.4.2] - 06/10/2025 — Quickstarts + SSR Guide + Validação (DEV)
776
+
777
+ ### ✨ Quickstarts executáveis
778
+
779
+ - Next.js (App Router) e Vite com Consent Mode v2 integrado e bloqueio real de scripts (GTM/GA4 não carregam antes do consentimento).
780
+ - Seções no QUICKSTART.md com passos copy‑paste e validação do comportamento esperado.
781
+
782
+ ### 🧱 Guia SSR/Next.js (App Router)
783
+
784
+ - Padrões seguros para evitar hydration mismatch: wrapper client‑only com `'use client'` e `dynamic({ ssr: false })`, efeitos que acessam `window/document` apenas no cliente.
785
+ - Ordem de provedores/estilos (Emotion/MUI) e z-index/portals documentados (overlay 1299, modais ≥ 1300).
786
+
787
+ ### ✅ Validação de configuração do ConsentProvider (DEV)
788
+
789
+ - Validação com Zod em desenvolvimento (import dinâmico) e sanitização leve em produção.
790
+ - Mensagens amigáveis: alerta quando `categories` não é fornecida; remove `'necessary'` de `enabledCategories`; detecta duplicidades/valores inválidos; valida `customCategories`.
791
+ - Testes cobrindo casos inválidos e asserts de mensagens.
792
+
793
+ ### 📚 Categorias — definição, uso e exemplos
794
+
795
+ - Fonte única de verdade: `ConsentProvider.categories`. UI, hooks e integrações leem a mesma definição.
796
+ - Esclarecimento: apenas “necessários” é obrigatório; demais categorias são opcionais conforme o negócio.
797
+ - Exemplos mínimo (somente necessários) e completo (analytics/marketing/functional).
798
+
799
+ ### 🔧 Dependências
800
+
801
+ - Adicionado: `zod@^3.23.8` (usado somente em DEV via import dinâmico; não impacta o bundle de produção).
802
+
803
+ ### 🧩 Sem breaking changes
804
+
805
+ - Alterações são compatíveis; padrões seguros preservados.
package/QUICKSTART.md CHANGED
@@ -62,9 +62,263 @@ export default App
62
62
 
63
63
  ````
64
64
 
65
+ ## ⚡ Quickstarts: Next.js (App Router) e Vite
66
+
67
+ Os exemplos a seguir integram GTM/GA4 com Consent Mode v2 e garantem que nenhum script de tracking rode antes do consentimento. Eles também mostram como usar `ConsentScriptLoader` e sincronizar os sinais do Consent Mode via `gtag('consent', ...)`.
68
+
69
+ - Exemplos completos: `examples/next-app-router/*`, `examples/vite/*`
70
+
71
+ ### Next.js 14/15 — App Router (SSR-safe)
72
+
73
+ 1) Criar app Next e instalar deps
74
+
75
+ ```bash
76
+ npm create next-app@latest my-app --ts --eslint --src-dir --app --no-tailwind --no-experimental-app
77
+ cd my-app
78
+ npm i react-lgpd-consent @mui/material @mui/icons-material @emotion/react @emotion/styled
79
+ ```
80
+
81
+ 2) Variáveis públicas no `.env.local`
82
+
83
+ ```
84
+ NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX
85
+ NEXT_PUBLIC_GTM_ID=GTM-XXXXXXX
86
+ ```
87
+
88
+ 3) Copiar os arquivos do exemplo e ajustar imports
89
+
90
+ - De `examples/next-app-router/app/layout.tsx` → `app/layout.tsx`
91
+ - De `examples/next-app-router/app/page.tsx` → `app/page.tsx`
92
+ - De `examples/next-app-router/components/ClientConsent.tsx` → `app/components/ClientConsent.tsx`
93
+
94
+ Observação: nos arquivos copiados, troque imports relativos para `import { ConsentProvider, ConsentScriptLoader } from 'react-lgpd-consent'`.
95
+
96
+ 4) O que esse setup faz
97
+
98
+ - `ClientConsent` é um componente client-only (via `dynamic(..., { ssr: false })` no layout) que:
99
+ - Injeta um stub de `dataLayer/gtag` e define `consent default = denied` para todos os sinais (ad_storage, ad_user_data, ad_personalization, analytics_storage).
100
+ - Sincroniza as mudanças do consentimento com `gtag('consent','update', ...)` mapeando as categorias: `analytics → analytics_storage`, `marketing → ad_*`.
101
+ - Usa `ConsentScriptLoader` para carregar GTM/GA4 somente quando as categorias permitirem. Antes disso, nenhum script de tracking é carregado.
102
+
103
+ 5) Rodar
104
+
105
+ ```bash
106
+ npm run dev
107
+ ```
108
+
109
+ Validação rápida:
110
+ - Acesse em aba anônima: a rede não carrega `gtm.js`/`gtag/js` até aceitar preferências.
111
+ - Ao aceitar `analytics`, o GA4 é carregado; ao aceitar `marketing`, os sinais `ad_*` são atualizados como granted.
112
+
113
+ ### Vite (CSR)
114
+
115
+ 1) Criar app Vite e instalar deps
116
+
117
+ ```bash
118
+ npm create vite@latest my-app -- --template react-ts
119
+ cd my-app
120
+ npm i react-lgpd-consent @mui/material @mui/icons-material @emotion/react @emotion/styled
121
+ ```
122
+
123
+ 2) Variáveis no `.env`
124
+
125
+ ```
126
+ VITE_GA_ID=G-XXXXXXXXXX
127
+ VITE_GTM_ID=GTM-XXXXXXX
128
+ ```
129
+
130
+ 3) Copiar os arquivos do exemplo e ajustar imports
131
+
132
+ - De `examples/vite/index.html` → `index.html` (não adicione scripts do GA/GTM aqui)
133
+ - De `examples/vite/src/main.tsx` → `src/main.tsx`
134
+ - De `examples/vite/src/App.tsx` → `src/App.tsx`
135
+ - De `examples/vite/src/consent/GtagConsent.tsx` → `src/consent/GtagConsent.tsx`
136
+
137
+ Observação: nos arquivos copiados, troque imports relativos para `import { ... } from 'react-lgpd-consent'`.
138
+
139
+ 4) Rodar
140
+
141
+ ```bash
142
+ npm run dev
143
+ ```
144
+
145
+ Validação rápida:
146
+ - Ao abrir a app (em nova sessão), nenhum script de tracking é baixado até que o usuário consinta.
147
+ - Preferências atualizam `gtag('consent','update', ...)` corretamente por categoria.
148
+
65
149
  ## 🧩 Categorias customizadas (customCategories)
66
150
  Disponível a partir da v0.4.0.
67
151
 
152
+ ## 🍪 Categorias: definição, uso e exemplos
153
+
154
+ Fonte única de verdade
155
+ - Defina as categorias do seu projeto SOMENTE na prop `categories` do `ConsentProvider`.
156
+ - A UI (Banner/Modal), os hooks (`useConsent`, `useCategories`) e as integrações (`ConsentScriptLoader`) leem a mesma definição. Não declare categorias em outros lugares.
157
+
158
+ O que é obrigatório?
159
+ - Apenas a categoria `necessary` é obrigatória (e já é sempre incluída automaticamente).
160
+ - Todas as demais (`analytics`, `marketing`, `functional`, etc.) são opcionais e dependem do seu caso de negócio. Se você não usa analytics/ads/chat, simplesmente não habilite essas categorias.
161
+
162
+ Como “esconder” categorias que não uso?
163
+ - Basta não incluí-las em `enabledCategories` e não declará-las em `customCategories`. A UI não exibirá toggles para categorias ausentes.
164
+
165
+ Exemplo A — Somente necessários (mínimo, comum para apps internos/governo sem tracking)
166
+ ```tsx
167
+ import { ConsentProvider } from 'react-lgpd-consent'
168
+
169
+ export default function App() {
170
+ return (
171
+ <ConsentProvider
172
+ categories={{ enabledCategories: [] }}
173
+ texts={{ bannerMessage: 'Usamos apenas cookies necessários para funcionamento.' }}
174
+ >
175
+ <YourApp />
176
+ </ConsentProvider>
177
+ )
178
+ }
179
+ ```
180
+
181
+ Exemplo B — Conjunto completo (site com analytics e marketing)
182
+ ```tsx
183
+ import { ConsentProvider } from 'react-lgpd-consent'
184
+
185
+ export default function App() {
186
+ return (
187
+ <ConsentProvider
188
+ categories={{ enabledCategories: ['analytics', 'marketing', 'functional'] }}
189
+ >
190
+ <YourApp />
191
+ </ConsentProvider>
192
+ )
193
+ }
194
+ ```
195
+
196
+ Boas práticas
197
+ - Sempre passe `categories` explicitamente. Em DEV, a biblioteca avisa quando `categories` não foi configurado para evitar ambiguidades.
198
+ - Não classifique scripts de analytics/ads como “necessary” — use `ConsentScriptLoader` e categorias adequadas.
199
+ - Em dúvidas, comece com “somente necessários” e evolua quando o negócio exigir outras categorias.
200
+
201
+ ### 🔎 Validação de configuração (DEV)
202
+
203
+ Em desenvolvimento, a biblioteca valida a configuração e mostra mensagens amigáveis no console. Nada disso impacta produção (onde só ocorre uma sanitização leve).
204
+
205
+ Avisos comuns e como corrigir:
206
+ - `Prop 'categories' não fornecida...` — defina `categories.enabledCategories` de forma explícita; exemplo mínimo: `categories={{ enabledCategories: [] }}`.
207
+ - `'necessary' é sempre incluída automaticamente` — remova `'necessary'` de `enabledCategories` (ela já é incluída por padrão).
208
+ - `IDs de categoria duplicados detectados` — revise `enabledCategories` e `customCategories` para garantir que não há IDs repetidos.
209
+ - `enabledCategories contém valores inválidos` — verifique se todos os itens são strings não vazias (IDs de categoria).
210
+ - `customCategories: ... — ... deve ser uma string não vazia` — preencha `id`, `name` e `description` das categorias customizadas.
211
+
212
+ Notas:
213
+ - Validação detalhada roda apenas em `NODE_ENV !== 'production'`.
214
+ - Em produção, a lib não carrega o validador; somente remove `'necessary'` se vier por engano, mantendo o comportamento seguro.
215
+
216
+ ## 🧱 SSR/Next.js (App Router) — Padrões seguros
217
+
218
+ Objetivo: evitar hydration mismatch, hooks em Server Components e vazamento de scripts.
219
+
220
+ Padrões recomendados
221
+ - Envolva o app com o `ConsentProvider` apenas no cliente.
222
+ - Use `dynamic(() => import('./ClientConsent'), { ssr: false })` no `RootLayout` (Server Component) e mova hooks e efeitos para o componente cliente.
223
+ - Nenhum acesso a `window`/`document` no topo de módulo; use apenas dentro de `useEffect`.
224
+ - Inicialize Consent Mode v2 com `gtag('consent','default', denied)` antes de carregar GTM/GA4; depois, atualize sinais na mudança de preferências.
225
+
226
+ Exemplo de RootLayout (Server) + Client wrapper
227
+
228
+ ```tsx
229
+ // app/layout.tsx (Server Component)
230
+ import dynamic from 'next/dynamic'
231
+
232
+ const ClientConsent = dynamic(() => import('./components/ClientConsent'), { ssr: false })
233
+
234
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
235
+ return (
236
+ <html lang="pt-BR">
237
+ <body>
238
+ <ClientConsent>{children}</ClientConsent>
239
+ </body>
240
+ </html>
241
+ )
242
+ }
243
+ ```
244
+
245
+ ```tsx
246
+ // app/components/ClientConsent.tsx (Client Component)
247
+ 'use client'
248
+ import React from 'react'
249
+ import { ConsentProvider, ConsentScriptLoader } from 'react-lgpd-consent'
250
+ import { COMMON_INTEGRATIONS } from 'react-lgpd-consent'
251
+ import { useConsent } from 'react-lgpd-consent'
252
+
253
+ function BootstrapConsentMode() {
254
+ React.useEffect(() => {
255
+ const w = window as any
256
+ w.dataLayer = w.dataLayer ?? []
257
+ w.gtag = w.gtag ?? ((...args: any[]) => w.dataLayer.push(args))
258
+ w.gtag('consent', 'default', {
259
+ ad_storage: 'denied',
260
+ ad_user_data: 'denied',
261
+ ad_personalization: 'denied',
262
+ analytics_storage: 'denied',
263
+ })
264
+ }, [])
265
+ return null
266
+ }
267
+
268
+ function SyncConsentMode() {
269
+ const { consented, preferences } = useConsent()
270
+ React.useEffect(() => {
271
+ if (!consented) return
272
+ const w = window as any
273
+ w.gtag?.('consent', 'update', {
274
+ analytics_storage: preferences.analytics ? 'granted' : 'denied',
275
+ ad_storage: preferences.marketing ? 'granted' : 'denied',
276
+ ad_user_data: preferences.marketing ? 'granted' : 'denied',
277
+ ad_personalization: preferences.marketing ? 'granted' : 'denied',
278
+ })
279
+ }, [consented, preferences])
280
+ return null
281
+ }
282
+
283
+ export default function ClientConsent({ children }: { children: React.ReactNode }) {
284
+ const GA = process.env.NEXT_PUBLIC_GA_ID!
285
+ const GTM = process.env.NEXT_PUBLIC_GTM_ID!
286
+ return (
287
+ <ConsentProvider categories={{ enabledCategories: ['analytics', 'marketing', 'functional'] }} blocking>
288
+ <BootstrapConsentMode />
289
+ <SyncConsentMode />
290
+ <ConsentScriptLoader
291
+ integrations={[
292
+ COMMON_INTEGRATIONS.googleAnalytics({ measurementId: GA }),
293
+ COMMON_INTEGRATIONS.googleTagManager({ containerId: GTM }),
294
+ ]}
295
+ />
296
+ {children}
297
+ </ConsentProvider>
298
+ )
299
+ }
300
+ ```
301
+
302
+ Ordem de provedores e estilos (MUI/Emotion)
303
+ - Preferência de ordem recomendada:
304
+ - `CacheProvider` (Emotion) ou `StyledEngineProvider` com `injectFirst`
305
+ - `ThemeProvider` (MUI)
306
+ - `CssBaseline`
307
+ - `ConsentProvider` (sem criar tema por padrão)
308
+ - Motivo: garante injeção de estilos do MUI antes de CSS da app e evita desalinhamento visual; os componentes da lib herdam o tema quando presente.
309
+
310
+ Z-index e Portals
311
+ - Componentes MUI usam o `zIndex` do tema; modals/portals padrão usam `zIndex.modal = 1300`.
312
+ - O overlay bloqueante do Provider usa `z-index: 1299`; o Modal/Banner usa camadas ≥ 1300.
313
+ - Em caso de conflito com headers fixos, ajuste o `theme.zIndex` (ex.: `appBar: 1200`, `modal: 1300+`) ou os `designTokens` conforme a necessidade.
314
+
315
+ Checklist SSR (evite hydration mismatch)
316
+ - [ ] Hooks somente em Client Components (`'use client'` no topo).
317
+ - [ ] Nada de `window`/`document`/`localStorage` no topo de módulo (apenas em `useEffect`).
318
+ - [ ] `dynamic(..., { ssr: false })` para wrappers que usam hooks e efeitos do consentimento.
319
+ - [ ] GTM/GA4 carregados apenas após consentimento (via `ConsentScriptLoader`).
320
+ - [ ] Sem `<script>` de GTM/GA4 em `head`/`body`; todo carregamento vem do loader.
321
+
68
322
  ## 🎨 Dica de estilo: Backdrop sensível ao tema
69
323
 
70
324
  No modo bloqueante, o banner usa um backdrop para focar a atenção do usuário. Você pode controlar via design tokens:
package/README.en.md CHANGED
@@ -15,6 +15,12 @@
15
15
  <a href="https://nextjs.org/"><img src="https://img.shields.io/badge/Next.js-Compatible-000000?style=for-the-badge&logo=next.js&logoColor=white" alt="Next.js Compatible"></a>
16
16
  </div>
17
17
 
18
+ <div>
19
+ <a href="https://codecov.io/gh/lucianoedipo/react-lgpd-consent"><img src="https://img.shields.io/codecov/c/github/lucianoedipo/react-lgpd-consent?style=for-the-badge&logo=codecov&logoColor=white" alt="Coverage"></a>
20
+ <a href="https://bundlephobia.com/package/react-lgpd-consent"><img src="https://img.shields.io/bundlephobia/minzip/react-lgpd-consent?style=for-the-badge&logo=webpack&logoColor=white" alt="Bundle Size"></a>
21
+ <a href="https://nodejs.org"><img src="https://img.shields.io/node/v/react-lgpd-consent?style=for-the-badge&logo=node.js&logoColor=white" alt="Node Version"></a>
22
+ </div>
23
+
18
24
  <br />
19
25
 
20
26
  <p>
package/README.md CHANGED
@@ -15,6 +15,12 @@
15
15
  <a href="https://nextjs.org/"><img src="https://img.shields.io/badge/Next.js-Compatible-000000?style=for-the-badge&logo=next.js&logoColor=white" alt="Next.js Compatible"></a>
16
16
  </div>
17
17
 
18
+ <div>
19
+ <a href="https://codecov.io/gh/lucianoedipo/react-lgpd-consent"><img src="https://img.shields.io/codecov/c/github/lucianoedipo/react-lgpd-consent?style=for-the-badge&logo=codecov&logoColor=white" alt="Coverage"></a>
20
+ <a href="https://bundlephobia.com/package/react-lgpd-consent"><img src="https://img.shields.io/bundlephobia/minzip/react-lgpd-consent?style=for-the-badge&logo=webpack&logoColor=white" alt="Bundle Size"></a>
21
+ <a href="https://nodejs.org"><img src="https://img.shields.io/node/v/react-lgpd-consent?style=for-the-badge&logo=node.js&logoColor=white" alt="Node Version"></a>
22
+ </div>
23
+
18
24
  <br />
19
25
 
20
26
  <p>
@@ -46,6 +52,19 @@ npm install react-lgpd-consent @mui/material @emotion/react @emotion/styled js-c
46
52
 
47
53
  ---
48
54
 
55
+ ## ✨ Novidades v0.4.4
56
+
57
+ ### 🔧 CI/CD e Publicação
58
+ - **Workflow de Publicação**: Corrigido bug que impedia publicação automática no npm quando tags eram criadas após merge para `main`
59
+ - **Codecov Integration**: Adicionado upload automático de coverage reports para melhor visualização de cobertura de testes
60
+ - **Badge de Coverage**: Agora atualizado em tempo real via Codecov
61
+
62
+ ### 📊 Qualidade e Confiabilidade
63
+ - **Publicação Confiável**: Tags agora são publicadas corretamente quando commit está no histórico da `main`
64
+ - **Visibilidade de Cobertura**: Integração completa com Codecov para tracking de qualidade
65
+
66
+ ---
67
+
49
68
  ## ✨ Novidades v0.4.1
50
69
 
51
70
  ### 🎨 Design Tokens Expandidos
@@ -113,6 +132,7 @@ Para mais detalhes sobre customização, hooks e funcionalidades, consulte os se
113
132
  ### 📋 Documentação Principal
114
133
 
115
134
  - **[📚 Guia de Início Rápido (`QUICKSTART.md`)](./QUICKSTART.md)**: Tutorial passo a passo com exemplos práticos, tabela completa de props, debugging e integrações.
135
+ - Seção recomendada: “SSR/Next.js (App Router) — Padrões seguros” com boas práticas de `'use client'`, `dynamic({ ssr: false })` e ordem dos provedores/estilos (MUI/Emotion) para evitar hydration mismatch.
116
136
  - Novo na v0.4.0: suporte a `customCategories` — veja a seção “Categorias customizadas (customCategories)” no Quickstart.
117
137
  - Novo na v0.4.1: integrações nativas para Facebook Pixel, Hotjar, Mixpanel, Clarity, Intercom e Zendesk — veja o guia [INTEGRACOES.md](./INTEGRACOES.md).
118
138
  - Dica: use `designTokens.layout.backdrop: 'auto'` para backdrop sensível ao tema no banner bloqueante.
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ var chunkFJKRAERJ_cjs = require('./chunk-FJKRAERJ.cjs');
4
+ require('./chunk-ORI4PLVG.cjs');
5
+
6
+
7
+
8
+ Object.defineProperty(exports, "FloatingPreferencesButton", {
9
+ enumerable: true,
10
+ get: function () { return chunkFJKRAERJ_cjs.FloatingPreferencesButton; }
11
+ });
@@ -0,0 +1,2 @@
1
+ export { FloatingPreferencesButton } from './chunk-PJFGQMCI.js';
2
+ import './chunk-RWT2ORFE.js';
@@ -0,0 +1,2 @@
1
+ export { PreferencesModal } from './chunk-N3QOW4SA.js';
2
+ import './chunk-RWT2ORFE.js';
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ var chunk25XEI2DZ_cjs = require('./chunk-25XEI2DZ.cjs');
4
+ require('./chunk-ORI4PLVG.cjs');
5
+
6
+
7
+
8
+ Object.defineProperty(exports, "PreferencesModal", {
9
+ enumerable: true,
10
+ get: function () { return chunk25XEI2DZ_cjs.PreferencesModal; }
11
+ });