react-lgpd-consent - v0.3.4
    Preparing search index...

    🚀 Guia de Início Rápido

    Este guia fornece tudo o que você precisa para integrar rapidamente a biblioteca react-lgpd-consent em seu projeto React.

    npm install react-lgpd-consent
    # ou
    yarn add react-lgpd-consent
    npm install @mui/material @mui/icons-material @emotion/react @emotion/styled
    
    import React from 'react'
    import { ConsentProvider } from 'react-lgpd-consent'

    function App() {
    return (
    <ConsentProvider
    categories={{
    enabledCategories: ['analytics', 'marketing'],
    }}
    >
    <main>
    <h1>Minha Aplicação</h1>
    {/* Seu conteúdo aqui */}
    </main>
    </ConsentProvider>
    )

    ## 🧭 Storybookquick note

    This repository ships an interactive Storybook playground used for manual testing and visual exploration of components. Quick commands:

    - Run locally (development):

    ```bash
    npm run storybook
    • Build static Storybook (for publishing to GitHub Pages):
    npm run build-storybook
    

    Notes:

    • 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.

    }

    export default App


    ## 📋 Tabela Completa de Props do ConsentProvider

    | Prop | Tipo | Obrigatória | Padrão | Descrição |
    | ------------------------------------ | ----------------------------------------------------------- | ----------- | ------------------- | ---------------------------------------------- |
    | `categories` | `ProjectCategoriesConfig` | ✅ **Sim** | - | Define as categorias de cookies do projeto |
    | `texts` | `Partial<ConsentTexts>` | ❌ Não | Textos padrão PT-BR | Customiza textos da interface |
    | `theme` | `any` | ❌ Não | Tema padrão | Tema Material-UI para os componentes |
    | `designTokens` | `DesignTokens` | ❌ Não | Tokens padrão | Tokens de design para customização avançada |
    | `blocking` | `boolean` | ❌ Não | `false` | Exibe overlay bloqueando interação até decisão |
    | `blockingStrategy` | `'auto' \| 'provider'` | ❌ Não | `'auto'` | Estratégia de renderização do overlay |
    | `hideBranding` | `boolean` | ❌ Não | `false` | Oculta branding "fornecido por" |
    | `onConsentGiven` | `(state: ConsentState) => void` | ❌ Não | - | Callback na primeira vez que usuário consente |
    | `onPreferencesSaved` | `(prefs: ConsentPreferences) => void` | ❌ Não | - | Callback quando preferências são salvas |
    | `disableDeveloperGuidance` | `boolean` | ❌ Não | `false` | Desativa orientações no console |
    | `disableFloatingPreferencesButton` | `boolean` | ❌ Não | `false` | Desabilita botão flutuante de preferências |
    | `CookieBannerComponent` | `React.ComponentType<CustomCookieBannerProps>` | ❌ Não | Banner padrão | Componente de banner customizado |
    | `PreferencesModalComponent` | `React.ComponentType<CustomPreferencesModalProps>` | ❌ Não | Modal padrão | Componente de modal customizado |
    | `FloatingPreferencesButtonComponent` | `React.ComponentType<CustomFloatingPreferencesButtonProps>` | ❌ Não | Botão padrão | Componente de botão flutuante customizado |
    | `cookieBannerProps` | `object` | ❌ Não | `{}` | Props adicionais para o banner |
    | `preferencesModalProps` | `object` | ❌ Não | `{}` | Props adicionais para o modal |
    | `floatingPreferencesButtonProps` | `object` | ❌ Não | `{}` | Props adicionais para o botão flutuante |
    | `initialState` | `ConsentState` | ❌ Não | - | Estado inicial para hidratação SSR |
    | `cookie` | `Partial<ConsentCookieOptions>` | ❌ Não | Opções padrão | Configurações do cookie de consentimento |

    ## 🎨 Componentes Customizados com TypeScript

    ### Banner Personalizado

    ```tsx
    import React from 'react'
    import { ConsentProvider, type CustomCookieBannerProps } from 'react-lgpd-consent'

    // Componente de banner customizado
    const MeuBannerCustomizado: React.FC<CustomCookieBannerProps> = ({
    consented,
    acceptAll,
    rejectAll,
    openPreferences,
    texts,
    blocking,
    }) => {
    return (
    <div
    style={{
    position: 'fixed',
    bottom: 0,
    left: 0,
    right: 0,
    backgroundColor: blocking ? 'red' : 'blue',
    color: 'white',
    padding: '1rem',
    zIndex: 1000,
    }}
    >
    <p>{texts.bannerMessage}</p>
    <div style={{ display: 'flex', gap: '1rem', marginTop: '1rem' }}>
    <button onClick={acceptAll}>{texts.acceptAll}</button>
    <button onClick={rejectAll}>{texts.declineAll}</button>
    <button onClick={openPreferences}>{texts.preferences}</button>
    </div>
    </div>
    )
    }

    // Usando o banner customizado
    function App() {
    return (
    <ConsentProvider
    categories={{ enabledCategories: ['analytics'] }}
    CookieBannerComponent={MeuBannerCustomizado}
    blocking={true}
    >
    <main>Minha App</main>
    </ConsentProvider>
    )
    }
    import React from 'react'
    import { ConsentProvider, type CustomPreferencesModalProps } from 'react-lgpd-consent'

    const MeuModalCustomizado: React.FC<CustomPreferencesModalProps> = ({
    preferences,
    setPreferences,
    closePreferences,
    isModalOpen,
    texts,
    }) => {
    if (!isModalOpen) return null

    return (
    <div
    style={{
    position: 'fixed',
    top: '50%',
    left: '50%',
    transform: 'translate(-50%, -50%)',
    backgroundColor: 'white',
    border: '2px solid #ccc',
    borderRadius: '8px',
    padding: '2rem',
    zIndex: 2000,
    minWidth: '400px',
    }}
    >
    <h2>{texts.modalTitle}</h2>
    <p>{texts.modalIntro}</p>

    {/* Lista de categorias */}
    <div style={{ margin: '1rem 0' }}>
    {Object.entries(preferences).map(([category, enabled]) => (
    <label key={category} style={{ display: 'block', marginBottom: '0.5rem' }}>
    <input
    type="checkbox"
    checked={enabled}
    onChange={(e) =>
    setPreferences({
    ...preferences,
    [category]: e.target.checked,
    })
    }
    disabled={category === 'necessary'}
    />{' '}
    {category === 'necessary' ? texts.necessaryAlwaysOn : `Cookies ${category}`}
    </label>
    ))}
    </div>

    <div style={{ display: 'flex', gap: '1rem', justifyContent: 'flex-end' }}>
    <button onClick={closePreferences}>Cancelar</button>
    <button onClick={closePreferences}>{texts.save}</button>
    </div>
    </div>
    )
    }

    function App() {
    return (
    <ConsentProvider
    categories={{ enabledCategories: ['analytics', 'marketing'] }}
    PreferencesModalComponent={MeuModalCustomizado}
    >
    <main>Minha App</main>
    </ConsentProvider>
    )
    }
    import React from 'react'
    import { useOpenPreferencesModal, useConsent } from 'react-lgpd-consent'

    function MeuComponente() {
    const openPreferences = useOpenPreferencesModal()
    const { preferences, acceptAll, rejectAll } = useConsent()

    return (
    <div>
    <h3>Status atual: {preferences.analytics ? 'Analytics ativo' : 'Analytics inativo'}</h3>

    <button onClick={openPreferences}>⚙️ Gerenciar Preferências</button>

    <button onClick={acceptAll}>✅ Aceitar Todos</button>

    <button onClick={rejectAll}>❌ Recusar Todos</button>
    </div>
    )
    }
    <!-- Em templates HTML, emails ou widgets externos -->
    <button onclick="window.openPreferencesModal?.()">Configurar Cookies</button>

    <script>
    // Ou em JavaScript puro
    function abrirConfiguracoesCookies() {
    if (window.openPreferencesModal) {
    window.openPreferencesModal()
    } else {
    console.warn('Sistema de consentimento não carregado')
    }
    }

    // Verificar se função está disponível
    if (typeof window.openPreferencesModal === 'function') {
    console.log('✅ Sistema de consentimento disponível')
    }
    </script>
    import { setDebugLogging, LogLevel } from 'react-lgpd-consent'

    // Ativar todos os logs (desenvolvimento)
    setDebugLogging(true, LogLevel.DEBUG)

    // Apenas logs importantes (staging)
    setDebugLogging(true, LogLevel.INFO)

    // Apenas erros (produção)
    setDebugLogging(true, LogLevel.ERROR)

    // Desativar completamente
    setDebugLogging(false)
    // Em desenvolvimento, você verá logs como:
    // [🍪 LGPD-CONSENT] 🔧 Categorias Ativas (para UI customizada)
    // [🍪 LGPD-CONSENT] ℹ️ User accepted all cookies
    // [🍪 LGPD-CONSENT] 🐛 Category preference changed: analytics = true
    
    import { useConsent } from 'react-lgpd-consent'

    function DebugPanel() {
    const { preferences, consented } = useConsent()

    // Apenas mostrar em desenvolvimento
    if (process.env.NODE_ENV !== 'development') return null

    return (
    <div
    style={{
    position: 'fixed',
    top: 0,
    right: 0,
    background: 'rgba(0,0,0,0.8)',
    color: 'white',
    padding: '1rem',
    fontSize: '12px',
    fontFamily: 'monospace',
    }}
    >
    <h4>🍪 Debug LGPD</h4>
    <p>Consentimento: {consented ? '✅' : '❌'}</p>
    <pre>{JSON.stringify(preferences, null, 2)}</pre>
    </div>
    )
    }
    import React from 'react'
    import { ThemeProvider, createTheme } from '@mui/material/styles'
    import CssBaseline from '@mui/material/CssBaseline'
    import { ConsentProvider } from 'react-lgpd-consent'

    // Seu tema personalizado
    const meuTema = createTheme({
    palette: {
    primary: {
    main: '#1976d2',
    },
    secondary: {
    main: '#dc004e',
    },
    },
    typography: {
    fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
    },
    })

    // Tema específico para componentes de consentimento (opcional)
    const temaConsentimento = createTheme({
    ...meuTema,
    components: {
    MuiPaper: {
    styleOverrides: {
    root: {
    borderRadius: 12,
    },
    },
    },
    MuiButton: {
    styleOverrides: {
    root: {
    textTransform: 'none',
    fontWeight: 600,
    },
    },
    },
    },
    })

    function App() {
    return (
    <ThemeProvider theme={meuTema}>
    <CssBaseline />
    <ConsentProvider
    categories={{
    enabledCategories: ['analytics', 'marketing', 'advertising'],
    }}
    theme={temaConsentimento} // Tema específico para consentimento
    texts={{
    bannerMessage: 'Utilizamos cookies para personalizar sua experiência.',
    acceptAll: 'Aceitar Todos',
    declineAll: 'Apenas Necessários',
    preferences: 'Personalizar',
    }}
    onConsentGiven={(state) => {
    console.log('✅ Consentimento dado:', state.preferences)
    }}
    >
    <main>
    <h1>Minha Aplicação com Material-UI</h1>
    {/* Seus componentes aqui */}
    </main>
    </ConsentProvider>
    </ThemeProvider>
    )
    }

    export default App
    import { ConsentProvider, type DesignTokens } from 'react-lgpd-consent'

    const meusTokens: DesignTokens = {
    colors: {
    primary: '#6366f1',
    secondary: '#f59e0b',
    background: '#ffffff',
    text: '#1f2937',
    border: '#e5e7eb',
    },
    layout: {
    borderRadius: '12px',
    spacing: '1rem',
    backdrop: 'rgba(0, 0, 0, 0.6)', // ou false para transparente
    },
    typography: {
    fontFamily: '"Inter", system-ui, sans-serif',
    fontSize: '14px',
    fontWeight: '500',
    },
    }

    function App() {
    return (
    <ConsentProvider
    categories={{ enabledCategories: ['analytics'] }}
    designTokens={meusTokens}
    blocking={true}
    blockingStrategy="provider"
    >
    <main>Minha App</main>
    </ConsentProvider>
    )
    }
    import { ConsentProvider } from 'react-lgpd-consent'

    function App() {
    return (
    <ConsentProvider
    categories={{ enabledCategories: ['analytics'] }}
    cookie={{
    name: 'meu_app_consent', // Nome customizado
    maxAge: 365 * 24 * 60 * 60, // 1 ano em segundos
    domain: '.meudominio.com.br', // Cookie compartilhado entre subdomínios
    secure: true, // Apenas HTTPS
    sameSite: 'Lax', // Política SameSite
    }}
    >
    <main>Minha App</main>
    </ConsentProvider>
    )
    }
    <ConsentProvider
    categories={{
    enabledCategories: ['analytics', 'marketing', 'advertising'],
    }}
    texts={{
    bannerMessage:
    'Usamos cookies para melhorar sua experiência de compra e exibir ofertas personalizadas.',
    acceptAll: 'Aceitar e continuar',
    declineAll: 'Apenas essenciais',
    }}
    onConsentGiven={(state) => {
    // Inicializar ferramentas baseado no consentimento
    if (state.preferences.analytics) {
    // gtag('config', 'GA_MEASUREMENT_ID')
    }
    if (state.preferences.marketing) {
    // fbq('init', 'FACEBOOK_PIXEL_ID')
    }
    }}
    >
    {/* Sua loja */}
    </ConsentProvider>
    <ConsentProvider
    categories={{
    enabledCategories: ['analytics'],
    }}
    disableFloatingPreferencesButton={false}
    hideBranding={true}
    >
    {/* Seu conteúdo */}
    </ConsentProvider>
    <ConsentProvider
    categories={{
    enabledCategories: ['analytics', 'functional'],
    }}
    blocking={true}
    blockingStrategy="provider"
    disableDeveloperGuidance={false}
    onPreferencesSaved={(prefs) => {
    // Log de auditoria
    console.log('Audit: User preferences updated', prefs)
    }}
    >
    {/* Sua app corporativa */}
    </ConsentProvider>
    // ❌ Errado - hook usado fora do provider
    function MeuComponente() {
    const { preferences } = useConsent() // Erro!
    return <div>...</div>
    }

    function App() {
    return (
    <div>
    <MeuComponente /> {/* useConsent usado aqui falhará */}
    <ConsentProvider categories={{ enabledCategories: ['analytics'] }}>
    <main>App</main>
    </ConsentProvider>
    </div>
    )
    }

    // ✅ Correto - hook usado dentro do provider
    function App() {
    return (
    <ConsentProvider categories={{ enabledCategories: ['analytics'] }}>
    <div>
    <MeuComponente /> {/* Agora funciona */}
    <main>App</main>
    </div>
    </ConsentProvider>
    )
    }
    1. Verificar se não há consentimento salvo no cookie:
    // Limpar cookie para teste
    document.cookie = 'cookieConsent=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/'
    1. Verificar se hideBranding e outras configs estão corretas
    2. Conferir se o z-index não está sendo sobrescrito por outros elementos
    // Se você tiver problemas com tipos, adicione ao tsconfig.json:
    {
    "compilerOptions": {
    "moduleResolution": "bundler", // ou "node"
    "skipLibCheck": true
    }
    }

    💡 Dica: Use setDebugLogging(true, LogLevel.DEBUG) durante o desenvolvimento para ver logs detalhados do comportamento da biblioteca.