react-lgpd-consent 0.3.1 → 0.3.3

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.
@@ -8,16 +8,15 @@ import FormControlLabel from "@mui/material/FormControlLabel";
8
8
  import FormGroup from "@mui/material/FormGroup";
9
9
  import Switch from "@mui/material/Switch";
10
10
  import Typography3 from "@mui/material/Typography";
11
- import { useEffect as useEffect4, useState as useState2 } from "react";
11
+ import { useEffect as useEffect3, useState as useState2 } from "react";
12
12
 
13
13
  // src/context/CategoriesContext.tsx
14
14
  import * as React2 from "react";
15
15
 
16
16
  // src/utils/developerGuidance.ts
17
- import * as React from "react";
17
+ import React from "react";
18
18
  var DEFAULT_PROJECT_CATEGORIES = {
19
19
  enabledCategories: ["analytics"]
20
- // Só analytics além de necessary
21
20
  };
22
21
  function analyzeDeveloperConfiguration(config) {
23
22
  const guidance = {
@@ -38,7 +37,6 @@ function analyzeDeveloperConfiguration(config) {
38
37
  description: "Essenciais para funcionamento b\xE1sico do site",
39
38
  essential: true,
40
39
  uiRequired: false
41
- // Não precisa de toggle (sempre ativo)
42
40
  });
43
41
  const enabledCategories = finalConfig.enabledCategories || [];
44
42
  const categoryNames = {
@@ -72,13 +70,10 @@ function analyzeDeveloperConfiguration(config) {
72
70
  description: categoryInfo.description,
73
71
  essential: false,
74
72
  uiRequired: true
75
- // Precisa de toggle na UI
76
73
  });
77
74
  }
78
75
  });
79
- const totalToggleable = guidance.activeCategoriesInfo.filter(
80
- (c) => c.uiRequired
81
- ).length;
76
+ const totalToggleable = guidance.activeCategoriesInfo.filter((c) => c.uiRequired).length;
82
77
  if (totalToggleable === 0) {
83
78
  guidance.suggestions.push(
84
79
  'Apenas cookies necess\xE1rios est\xE3o configurados. Para compliance completo LGPD, considere adicionar categorias como "analytics" ou "functional" conforme uso real.'
@@ -86,88 +81,72 @@ function analyzeDeveloperConfiguration(config) {
86
81
  }
87
82
  if (totalToggleable > 5) {
88
83
  guidance.warnings.push(
89
- `${totalToggleable} categorias opcionais detectadas. UI com muitas op\xE7\xF5es pode ' +
90
- 'prejudicar experi\xEAncia do usu\xE1rio. Considere agrupar categorias similares.`
84
+ `${totalToggleable} categorias opcionais detectadas. UI com muitas op\xE7\xF5es pode prejudicar experi\xEAncia do usu\xE1rio. Considere agrupar categorias similares.`
91
85
  );
92
86
  }
93
87
  return guidance;
94
88
  }
95
89
  function logDeveloperGuidance(guidance, disableGuidanceProp) {
96
- if (disableGuidanceProp) {
97
- return;
98
- }
99
- const isProduction = (
100
- // 1. NODE_ENV de bundlers (Vite, webpack, etc.)
101
- typeof globalThis.process !== "undefined" && globalThis.process.env?.NODE_ENV === "production" || // 2. Flag customizada para desabilitar logs
102
- typeof globalThis !== "undefined" && globalThis.__LGPD_PRODUCTION__ === true || // 3. Flag de desenvolvimento desabilitada via window global (legado)
103
- typeof window !== "undefined" && window.__LGPD_DISABLE_GUIDANCE__ === true
104
- );
105
- if (isProduction) return;
90
+ const nodeEnv = typeof globalThis.process !== "undefined" ? globalThis.process.env?.NODE_ENV : void 0;
91
+ const isProd = nodeEnv === "production" || globalThis.__LGPD_PRODUCTION__ === true && typeof globalThis !== "undefined";
92
+ const isDisabled = !!disableGuidanceProp || globalThis.__LGPD_DISABLE_GUIDANCE__ === true && typeof globalThis !== "undefined";
93
+ if (isProd || isDisabled) return;
106
94
  const PREFIX = "[\u{1F36A} LGPD-CONSENT]";
107
95
  if (guidance.warnings.length > 0) {
108
96
  console.group(`${PREFIX} \u26A0\uFE0F Avisos de Configura\xE7\xE3o`);
109
- guidance.warnings.forEach((warning) => console.warn(`${PREFIX} ${warning}`));
97
+ guidance.warnings.forEach((msg) => console.warn(`${PREFIX} ${msg}`));
110
98
  console.groupEnd();
111
99
  }
112
100
  if (guidance.suggestions.length > 0) {
113
101
  console.group(`${PREFIX} \u{1F4A1} Sugest\xF5es`);
114
- guidance.suggestions.forEach(
115
- (suggestion) => console.info(`${PREFIX} ${suggestion}`)
116
- );
102
+ guidance.suggestions.forEach((msg) => console.info(`${PREFIX} ${msg}`));
117
103
  console.groupEnd();
118
104
  }
119
105
  if (guidance.usingDefaults) {
120
106
  console.warn(
121
- // Changed from console.info to console.warn
122
107
  `${PREFIX} \u{1F4CB} Usando configura\xE7\xE3o padr\xE3o. Para personalizar, use a prop "categories" no ConsentProvider.`
123
108
  );
124
109
  }
125
- console.group(`${PREFIX} \u{1F527} Categorias Ativas (para UI customizada)`);
126
- console.table(
127
- guidance.activeCategoriesInfo.map((cat) => ({
128
- ID: cat.id,
129
- Nome: cat.name,
130
- "Toggle UI?": cat.uiRequired ? "\u2705 SIM" : "\u274C N\xC3O (sempre ativo)",
131
- "Essencial?": cat.essential ? "\u{1F512} SIM" : "\u2699\uFE0F N\xC3O"
132
- }))
133
- );
134
- console.info(
135
- `${PREFIX} \u2139\uFE0F Use estes dados para criar componentes customizados adequados.`
136
- );
137
- console.groupEnd();
110
+ const rows = guidance.activeCategoriesInfo.map((cat) => ({
111
+ ID: cat.id,
112
+ Nome: cat.name,
113
+ "Toggle UI?": cat.uiRequired ? "\u2705 SIM" : "\u274C N\xC3O (sempre ativo)",
114
+ "Essencial?": cat.essential ? "\u{1F512} SIM" : "\u2699\uFE0F N\xC3O"
115
+ }));
116
+ if (typeof console.table === "function") {
117
+ console.group(`${PREFIX} \u{1F527} Categorias Ativas (para UI customizada)`);
118
+ console.table(rows);
119
+ console.info(`${PREFIX} \u2139\uFE0F Use estes dados para criar componentes customizados adequados.`);
120
+ console.groupEnd();
121
+ } else {
122
+ console.log(`${PREFIX} \u{1F527} Categorias Ativas (para UI customizada)`, rows);
123
+ console.info(`${PREFIX} \u2139\uFE0F Use estes dados para criar componentes customizados adequados.`);
124
+ }
138
125
  }
139
126
  function useDeveloperGuidance(config, disableGuidanceProp) {
140
- const guidance = analyzeDeveloperConfiguration(config);
141
- const stringifiedConfig = React.useMemo(
142
- () => JSON.stringify(config),
143
- [config]
144
- );
127
+ const guidance = React.useMemo(() => {
128
+ return analyzeDeveloperConfiguration(config);
129
+ }, [config]);
145
130
  React.useEffect(() => {
146
- if (disableGuidanceProp === true) {
147
- return;
131
+ if (!disableGuidanceProp) {
132
+ logDeveloperGuidance(guidance, disableGuidanceProp);
148
133
  }
149
- logDeveloperGuidance(guidance, disableGuidanceProp);
150
- }, [guidance, stringifiedConfig, disableGuidanceProp]);
134
+ }, [guidance, disableGuidanceProp]);
151
135
  return guidance;
152
136
  }
153
137
 
154
138
  // src/context/CategoriesContext.tsx
155
139
  import { jsx } from "react/jsx-runtime";
156
- var CategoriesContext = React2.createContext(
157
- null
158
- );
140
+ var CategoriesContext = React2.createContext(null);
159
141
  function CategoriesProvider({
160
142
  children,
161
143
  config,
162
- // NOVO: configuração completa
163
144
  disableDeveloperGuidance
164
145
  }) {
165
146
  const contextValue = React2.useMemo(() => {
166
147
  const finalConfig = config || DEFAULT_PROJECT_CATEGORIES;
167
148
  const guidance = analyzeDeveloperConfiguration(config);
168
- const toggleableCategories = guidance.activeCategoriesInfo.filter(
169
- (cat) => cat.uiRequired
170
- );
149
+ const toggleableCategories = guidance.activeCategoriesInfo.filter((cat) => cat.uiRequired);
171
150
  return {
172
151
  config: finalConfig,
173
152
  guidance,
@@ -280,10 +259,7 @@ var createSafeTheme = (userTheme) => {
280
259
  }
281
260
  });
282
261
  };
283
- function SafeThemeProvider({
284
- theme,
285
- children
286
- }) {
262
+ function SafeThemeProvider({ theme, children }) {
287
263
  const safeTheme = React3.useMemo(() => createSafeTheme(theme), [theme]);
288
264
  return /* @__PURE__ */ jsx2(ThemeProvider, { theme: safeTheme, children });
289
265
  }
@@ -292,8 +268,6 @@ function SafeThemeProvider({
292
268
  import Cookies from "js-cookie";
293
269
 
294
270
  // src/utils/logger.ts
295
- var IS_DEVELOPMENT = typeof window !== "undefined" && window.__REACT_DEVTOOLS_GLOBAL_HOOK__ || typeof globalThis !== "undefined" && globalThis.process?.env?.NODE_ENV === "development";
296
- var LOG_PREFIX = "[react-lgpd-consent]";
297
271
  var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
298
272
  LogLevel2[LogLevel2["ERROR"] = 0] = "ERROR";
299
273
  LogLevel2[LogLevel2["WARN"] = 1] = "WARN";
@@ -301,38 +275,93 @@ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
301
275
  LogLevel2[LogLevel2["DEBUG"] = 3] = "DEBUG";
302
276
  return LogLevel2;
303
277
  })(LogLevel || {});
304
- var ConsentLogger = class {
278
+ var _ConsentLogger = class _ConsentLogger {
305
279
  constructor() {
306
- this.enabled = IS_DEVELOPMENT;
280
+ this.enabled = _ConsentLogger.IS_DEVELOPMENT;
307
281
  this.level = 2 /* INFO */;
308
282
  }
283
+ /**
284
+ * Habilita ou desabilita o sistema de logging.
285
+ * @param {boolean} enabled Se `true`, os logs serão exibidos; caso contrário, serão suprimidos.
286
+ */
309
287
  setEnabled(enabled) {
310
288
  this.enabled = enabled;
311
289
  }
290
+ /**
291
+ * Define o nível mínimo de severidade para os logs.
292
+ * Mensagens com severidade menor que o nível definido não serão exibidas.
293
+ * @param {LogLevel} level O nível mínimo de severidade (ex: `LogLevel.DEBUG` para ver todos os logs).
294
+ */
312
295
  setLevel(level) {
313
296
  this.level = level;
314
297
  }
298
+ /**
299
+ * Registra uma mensagem de erro.
300
+ * @param {...any[]} args Os argumentos a serem logados.
301
+ */
315
302
  error(...args) {
316
303
  if (this.enabled && this.level >= 0 /* ERROR */) {
317
- console.error(LOG_PREFIX, "[ERROR]", ...args);
304
+ console.error(_ConsentLogger.LOG_PREFIX, "[ERROR]", ...args);
318
305
  }
319
306
  }
307
+ /**
308
+ * Registra uma mensagem de aviso.
309
+ * @param {...any[]} args Os argumentos a serem logados.
310
+ */
320
311
  warn(...args) {
321
312
  if (this.enabled && this.level >= 1 /* WARN */) {
322
- console.warn(LOG_PREFIX, "[WARN]", ...args);
313
+ console.warn(_ConsentLogger.LOG_PREFIX, "[WARN]", ...args);
323
314
  }
324
315
  }
316
+ /**
317
+ * Registra uma mensagem informativa.
318
+ * @param {...any[]} args Os argumentos a serem logados.
319
+ */
325
320
  info(...args) {
326
321
  if (this.enabled && this.level >= 2 /* INFO */) {
327
- console.info(LOG_PREFIX, "[INFO]", ...args);
322
+ console.info(_ConsentLogger.LOG_PREFIX, "[INFO]", ...args);
328
323
  }
329
324
  }
325
+ /**
326
+ * Registra uma mensagem de depuração.
327
+ * @param {...any[]} args Os argumentos a serem logados.
328
+ */
330
329
  debug(...args) {
331
330
  if (this.enabled && this.level >= 3 /* DEBUG */) {
332
- console.debug(LOG_PREFIX, "[DEBUG]", ...args);
331
+ console.debug(_ConsentLogger.LOG_PREFIX, "[DEBUG]", ...args);
333
332
  }
334
333
  }
335
- // Logs específicos para troubleshooting
334
+ /**
335
+ * Inicia um grupo de logs no console.
336
+ * @param {...any[]} args Os argumentos para o título do grupo.
337
+ */
338
+ group(...args) {
339
+ if (this.enabled && this.level >= 3 /* DEBUG */) {
340
+ console.group(_ConsentLogger.LOG_PREFIX, ...args);
341
+ }
342
+ }
343
+ /**
344
+ * Finaliza o grupo de logs mais recente no console.
345
+ */
346
+ groupEnd() {
347
+ if (this.enabled && this.level >= 3 /* DEBUG */) {
348
+ console.groupEnd();
349
+ }
350
+ }
351
+ /**
352
+ * Exibe dados tabulares no console.
353
+ * @param {any} tabularData Os dados a serem exibidos na tabela.
354
+ * @param {string[]} [properties] Um array opcional de propriedades para exibir.
355
+ */
356
+ table(tabularData, properties) {
357
+ if (this.enabled && this.level >= 3 /* DEBUG */) {
358
+ console.table(tabularData, properties);
359
+ }
360
+ }
361
+ /**
362
+ * Registra informações sobre a compatibilidade do tema Material-UI.
363
+ * @param {any} themeInfo Objeto com informações do tema.
364
+ */
336
365
  themeCompatibility(themeInfo) {
337
366
  this.debug("Theme compatibility check:", {
338
367
  hasTheme: !!themeInfo,
@@ -342,6 +371,11 @@ var ConsentLogger = class {
342
371
  hasDuration: !!themeInfo?.transitions?.duration
343
372
  });
344
373
  }
374
+ /**
375
+ * Registra mudanças no estado de consentimento.
376
+ * @param {string} action A ação que causou a mudança de estado.
377
+ * @param {any} state O estado atual do consentimento.
378
+ */
345
379
  consentState(action, state) {
346
380
  this.debug(`Consent state change [${action}]:`, {
347
381
  consented: state.consented,
@@ -349,6 +383,12 @@ var ConsentLogger = class {
349
383
  preferencesCount: Object.keys(state.preferences || {}).length
350
384
  });
351
385
  }
386
+ /**
387
+ * Registra operações de cookie (leitura, escrita, remoção).
388
+ * @param {'read' | 'write' | 'delete'} operation O tipo de operação de cookie.
389
+ * @param {string} cookieName O nome do cookie.
390
+ * @param {any} [data] Os dados do cookie, se aplicável.
391
+ */
352
392
  cookieOperation(operation, cookieName, data) {
353
393
  this.debug(`Cookie ${operation}:`, {
354
394
  name: cookieName,
@@ -356,29 +396,43 @@ var ConsentLogger = class {
356
396
  dataSize: data ? JSON.stringify(data).length : 0
357
397
  });
358
398
  }
399
+ /**
400
+ * Registra a renderização de um componente.
401
+ * @param {string} componentName O nome do componente.
402
+ * @param {any} [props] As propriedades do componente.
403
+ */
359
404
  componentRender(componentName, props) {
360
405
  this.debug(`Component render [${componentName}]:`, {
361
406
  hasProps: !!props,
362
407
  propsKeys: props ? Object.keys(props) : []
363
408
  });
364
409
  }
410
+ /**
411
+ * Registra o status de carregamento de scripts de integração.
412
+ * @param {string} scriptName O nome do script.
413
+ * @param {'load' | 'remove'} action A ação realizada (carregar ou remover).
414
+ * @param {boolean} success Se a operação foi bem-sucedida.
415
+ */
365
416
  scriptIntegration(scriptName, action, success) {
366
- this.info(
367
- `Script ${action} [${scriptName}]:`,
368
- success ? "SUCCESS" : "FAILED"
369
- );
417
+ this.info(`Script ${action} [${scriptName}]:`, success ? "SUCCESS" : "FAILED");
370
418
  }
419
+ /**
420
+ * Registra chamadas à API interna da biblioteca.
421
+ * @param {string} method O nome do método da API chamado.
422
+ * @param {any} [params] Os parâmetros passados para o método.
423
+ */
371
424
  apiUsage(method, params) {
372
425
  this.debug(`API call [${method}]:`, params);
373
426
  }
374
427
  };
428
+ _ConsentLogger.IS_DEVELOPMENT = typeof globalThis !== "undefined" && globalThis.process?.env?.NODE_ENV === "development";
429
+ _ConsentLogger.LOG_PREFIX = "[react-lgpd-consent]";
430
+ var ConsentLogger = _ConsentLogger;
375
431
  var logger = new ConsentLogger();
376
432
  function setDebugLogging(enabled, level = 2 /* INFO */) {
377
433
  logger.setEnabled(enabled);
378
434
  logger.setLevel(level);
379
- logger.info(
380
- `Debug logging ${enabled ? "enabled" : "disabled"} with level ${LogLevel[level]}`
381
- );
435
+ logger.info(`Debug logging ${enabled ? "enabled" : "disabled"} with level ${LogLevel[level]}`);
382
436
  }
383
437
 
384
438
  // src/utils/cookieUtils.ts
@@ -409,9 +463,7 @@ function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
409
463
  return migrateLegacyCookie(data);
410
464
  }
411
465
  if (data.version !== COOKIE_SCHEMA_VERSION) {
412
- logger.warn(
413
- `Cookie version mismatch: ${data.version} != ${COOKIE_SCHEMA_VERSION}`
414
- );
466
+ logger.warn(`Cookie version mismatch: ${data.version} != ${COOKIE_SCHEMA_VERSION}`);
415
467
  return null;
416
468
  }
417
469
  return data;
@@ -428,12 +480,9 @@ function migrateLegacyCookie(legacyData) {
428
480
  consented: legacyData.consented || false,
429
481
  preferences: legacyData.preferences || { necessary: true },
430
482
  consentDate: now,
431
- // Não temos o original, usar data atual
432
483
  lastUpdate: now,
433
484
  source: "banner",
434
- // Assumir origem banner
435
485
  isModalOpen: false
436
- // Nunca persistir estado de UI
437
486
  };
438
487
  } catch {
439
488
  return null;
@@ -451,11 +500,9 @@ function writeConsentCookie(state, config, opts, source = "banner") {
451
500
  consented: state.consented,
452
501
  preferences: state.preferences,
453
502
  consentDate: state.consentDate || now,
454
- // Preservar data original ou usar atual
455
503
  lastUpdate: now,
456
504
  source,
457
505
  projectConfig: config
458
- // isModalOpen NÃO é persistido (campo de UI apenas)
459
506
  };
460
507
  logger.cookieOperation("write", o.name, cookieData);
461
508
  Cookies.set(o.name, JSON.stringify(cookieData), {
@@ -508,6 +555,64 @@ function validateProjectPreferences(preferences, config) {
508
555
  });
509
556
  return validPreferences;
510
557
  }
558
+ function getAllProjectCategories(config) {
559
+ const allCategories = [
560
+ {
561
+ id: "necessary",
562
+ name: "Necess\xE1rios",
563
+ description: "Cookies essenciais para funcionamento b\xE1sico do site",
564
+ essential: true
565
+ }
566
+ ];
567
+ const enabledCategories = config?.enabledCategories || [];
568
+ enabledCategories.forEach((category) => {
569
+ if (category !== "necessary") {
570
+ allCategories.push(getDefaultCategoryDefinition(category));
571
+ }
572
+ });
573
+ return allCategories;
574
+ }
575
+ function getDefaultCategoryDefinition(category) {
576
+ const definitions = {
577
+ necessary: {
578
+ id: "necessary",
579
+ name: "Necess\xE1rios",
580
+ description: "Cookies essenciais para funcionamento b\xE1sico do site",
581
+ essential: true
582
+ },
583
+ analytics: {
584
+ id: "analytics",
585
+ name: "An\xE1lise e Estat\xEDsticas",
586
+ description: "Cookies para an\xE1lise de uso e estat\xEDsticas do site",
587
+ essential: false
588
+ },
589
+ functional: {
590
+ id: "functional",
591
+ name: "Funcionalidades",
592
+ description: "Cookies para funcionalidades extras como prefer\xEAncias e idioma",
593
+ essential: false
594
+ },
595
+ marketing: {
596
+ id: "marketing",
597
+ name: "Marketing e Publicidade",
598
+ description: "Cookies para publicidade direcionada e marketing",
599
+ essential: false
600
+ },
601
+ social: {
602
+ id: "social",
603
+ name: "Redes Sociais",
604
+ description: "Cookies para integra\xE7\xE3o com redes sociais e compartilhamento",
605
+ essential: false
606
+ },
607
+ personalization: {
608
+ id: "personalization",
609
+ name: "Personaliza\xE7\xE3o",
610
+ description: "Cookies para personaliza\xE7\xE3o de conte\xFAdo e experi\xEAncia",
611
+ essential: false
612
+ }
613
+ };
614
+ return definitions[category];
615
+ }
511
616
 
512
617
  // src/utils/theme.ts
513
618
  import { createTheme as createTheme2 } from "@mui/material/styles";
@@ -695,74 +800,59 @@ function CookieBanner({
695
800
  fontFamily: designTokens?.typography?.fontFamily
696
801
  };
697
802
  const bannerContent = /* @__PURE__ */ jsx5(Paper, { elevation: 3, sx: bannerStyle, ...PaperProps, children: /* @__PURE__ */ jsxs2(Stack, { spacing: 1, children: [
698
- /* @__PURE__ */ jsxs2(
699
- Typography2,
700
- {
701
- variant: "body2",
702
- sx: { fontSize: designTokens?.typography?.fontSize?.banner },
703
- children: [
704
- texts.bannerMessage,
705
- " ",
706
- policyLinkUrl && /* @__PURE__ */ jsx5(
707
- Link2,
708
- {
709
- href: policyLinkUrl,
710
- underline: "hover",
711
- target: "_blank",
712
- rel: "noopener noreferrer",
713
- sx: { color: designTokens?.colors?.primary },
714
- children: texts.policyLink ?? "Saiba mais"
715
- }
716
- )
717
- ]
718
- }
719
- ),
720
- /* @__PURE__ */ jsxs2(
721
- Stack,
722
- {
723
- direction: { xs: "column", sm: "row" },
724
- spacing: 1,
725
- justifyContent: "flex-end",
726
- children: [
727
- /* @__PURE__ */ jsx5(
728
- Button,
729
- {
730
- variant: "outlined",
731
- onClick: () => {
732
- logger.apiUsage("rejectAll", { source: "banner" });
733
- rejectAll();
734
- },
735
- sx: { color: designTokens?.colors?.secondary },
736
- children: texts.declineAll
737
- }
738
- ),
739
- /* @__PURE__ */ jsx5(
740
- Button,
741
- {
742
- variant: "contained",
743
- onClick: () => {
744
- logger.apiUsage("acceptAll", { source: "banner" });
745
- acceptAll();
746
- },
747
- sx: { backgroundColor: designTokens?.colors?.primary },
748
- children: texts.acceptAll
749
- }
750
- ),
751
- /* @__PURE__ */ jsx5(
752
- Button,
753
- {
754
- variant: "text",
755
- onClick: () => {
756
- logger.apiUsage("openPreferences", { source: "banner" });
757
- openPreferences();
758
- },
759
- sx: { color: designTokens?.colors?.text },
760
- children: texts.preferences
761
- }
762
- )
763
- ]
764
- }
765
- ),
803
+ /* @__PURE__ */ jsxs2(Typography2, { variant: "body2", sx: { fontSize: designTokens?.typography?.fontSize?.banner }, children: [
804
+ texts.bannerMessage,
805
+ " ",
806
+ policyLinkUrl && /* @__PURE__ */ jsx5(
807
+ Link2,
808
+ {
809
+ href: policyLinkUrl,
810
+ underline: "hover",
811
+ target: "_blank",
812
+ rel: "noopener noreferrer",
813
+ sx: { color: designTokens?.colors?.primary },
814
+ children: texts.policyLink ?? "Saiba mais"
815
+ }
816
+ )
817
+ ] }),
818
+ /* @__PURE__ */ jsxs2(Stack, { direction: { xs: "column", sm: "row" }, spacing: 1, justifyContent: "flex-end", children: [
819
+ /* @__PURE__ */ jsx5(
820
+ Button,
821
+ {
822
+ variant: "outlined",
823
+ onClick: () => {
824
+ logger.apiUsage("rejectAll", { source: "banner" });
825
+ rejectAll();
826
+ },
827
+ sx: { color: designTokens?.colors?.secondary },
828
+ children: texts.declineAll
829
+ }
830
+ ),
831
+ /* @__PURE__ */ jsx5(
832
+ Button,
833
+ {
834
+ variant: "contained",
835
+ onClick: () => {
836
+ logger.apiUsage("acceptAll", { source: "banner" });
837
+ acceptAll();
838
+ },
839
+ sx: { backgroundColor: designTokens?.colors?.primary },
840
+ children: texts.acceptAll
841
+ }
842
+ ),
843
+ /* @__PURE__ */ jsx5(
844
+ Button,
845
+ {
846
+ variant: "text",
847
+ onClick: () => {
848
+ logger.apiUsage("openPreferences", { source: "banner" });
849
+ openPreferences();
850
+ },
851
+ sx: { color: designTokens?.colors?.text },
852
+ children: texts.preferences
853
+ }
854
+ )
855
+ ] }),
766
856
  !hideBranding && /* @__PURE__ */ jsx5(Branding, { variant: "banner" })
767
857
  ] }) });
768
858
  const positionStyle = {
@@ -774,6 +864,7 @@ function CookieBanner({
774
864
  width: designTokens?.layout?.width?.desktop ?? "100%",
775
865
  p: 2
776
866
  };
867
+ const backdropColor = designTokens?.layout?.backdrop === false ? "transparent" : typeof designTokens?.layout?.backdrop === "string" ? designTokens.layout.backdrop : "rgba(0, 0, 0, 0.4)";
777
868
  if (blocking) {
778
869
  return /* @__PURE__ */ jsxs2(Fragment, { children: [
779
870
  /* @__PURE__ */ jsx5(
@@ -785,7 +876,7 @@ function CookieBanner({
785
876
  left: 0,
786
877
  right: 0,
787
878
  bottom: 0,
788
- backgroundColor: designTokens?.layout?.backdrop ? "rgba(0, 0, 0, 0.5)" : "transparent",
879
+ backgroundColor: backdropColor,
789
880
  zIndex: 1299
790
881
  }
791
882
  }
@@ -896,20 +987,8 @@ function FloatingPreferencesButton({
896
987
 
897
988
  // src/context/ConsentContext.tsx
898
989
  import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
899
- var log = {
900
- debug: (message, data) => {
901
- if (typeof window !== "undefined" && window.__REACT_DEVTOOLS_GLOBAL_HOOK__) {
902
- console.debug("[react-lgpd-consent] [DEBUG]", message, data);
903
- }
904
- },
905
- info: (message, data) => {
906
- if (typeof window !== "undefined" && window.__REACT_DEVTOOLS_GLOBAL_HOOK__) {
907
- console.info("[react-lgpd-consent] [INFO]", message, data);
908
- }
909
- }
910
- };
911
990
  var PreferencesModal = React5.lazy(
912
- () => import("./PreferencesModal-J27W5XAJ.js").then((m) => ({
991
+ () => import("./PreferencesModal-HTTMUZND.js").then((m) => ({
913
992
  default: m.PreferencesModal
914
993
  }))
915
994
  );
@@ -964,43 +1043,26 @@ var DEFAULT_TEXTS = {
964
1043
  // Exibido se definido
965
1044
  };
966
1045
  function reducer(state, action) {
967
- log.debug("State transition:", {
968
- action: action.type,
969
- currentState: state.consented
970
- });
1046
+ logger.consentState(action.type, state);
971
1047
  switch (action.type) {
972
1048
  case "ACCEPT_ALL": {
973
1049
  const prefs = createProjectPreferences(action.config, true);
974
- const newState = createFullConsentState(
975
- true,
976
- prefs,
977
- "banner",
978
- action.config,
979
- false,
980
- state
981
- );
982
- log.info("User accepted all cookies", {
1050
+ const newState = createFullConsentState(true, prefs, "banner", action.config, false, state);
1051
+ logger.info("User accepted all cookies", {
983
1052
  preferences: newState.preferences
984
1053
  });
985
1054
  return newState;
986
1055
  }
987
1056
  case "REJECT_ALL": {
988
1057
  const prefs = createProjectPreferences(action.config, false);
989
- const newState = createFullConsentState(
990
- true,
991
- prefs,
992
- "banner",
993
- action.config,
994
- false,
995
- state
996
- );
997
- log.info("User rejected all cookies", {
1058
+ const newState = createFullConsentState(true, prefs, "banner", action.config, false, state);
1059
+ logger.info("User rejected all cookies", {
998
1060
  preferences: newState.preferences
999
1061
  });
1000
1062
  return newState;
1001
1063
  }
1002
1064
  case "SET_CATEGORY":
1003
- log.debug("Category preference changed", {
1065
+ logger.debug("Category preference changed", {
1004
1066
  category: action.category,
1005
1067
  value: action.value
1006
1068
  });
@@ -1013,26 +1075,12 @@ function reducer(state, action) {
1013
1075
  lastUpdate: (/* @__PURE__ */ new Date()).toISOString()
1014
1076
  };
1015
1077
  case "SET_PREFERENCES":
1016
- log.info("Preferences saved", { preferences: action.preferences });
1017
- return createFullConsentState(
1018
- true,
1019
- action.preferences,
1020
- "modal",
1021
- action.config,
1022
- false,
1023
- state
1024
- );
1078
+ logger.info("Preferences saved", { preferences: action.preferences });
1079
+ return createFullConsentState(true, action.preferences, "modal", action.config, false, state);
1025
1080
  case "OPEN_MODAL":
1026
1081
  return { ...state, isModalOpen: true };
1027
1082
  case "CLOSE_MODAL":
1028
- return createFullConsentState(
1029
- true,
1030
- state.preferences,
1031
- "modal",
1032
- action.config,
1033
- false,
1034
- state
1035
- );
1083
+ return createFullConsentState(true, state.preferences, "modal", action.config, false, state);
1036
1084
  case "RESET": {
1037
1085
  return createFullConsentState(
1038
1086
  false,
@@ -1064,12 +1112,9 @@ var HydrationCtx = React5.createContext(false);
1064
1112
  function ConsentProvider({
1065
1113
  initialState,
1066
1114
  categories,
1067
- // Nova prop para configuração de categorias
1068
1115
  texts: textsProp,
1069
1116
  theme,
1070
1117
  designTokens,
1071
- scriptIntegrations,
1072
- // eslint-disable-line no-unused-vars
1073
1118
  PreferencesModalComponent,
1074
1119
  preferencesModalProps = {},
1075
1120
  CookieBannerComponent,
@@ -1084,18 +1129,12 @@ function ConsentProvider({
1084
1129
  disableDeveloperGuidance,
1085
1130
  children
1086
1131
  }) {
1087
- const texts = React5.useMemo(
1088
- () => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }),
1089
- [textsProp]
1090
- );
1132
+ const texts = React5.useMemo(() => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }), [textsProp]);
1091
1133
  const cookie = React5.useMemo(
1092
1134
  () => ({ ...DEFAULT_COOKIE_OPTS, ...cookieOpts ?? {} }),
1093
1135
  [cookieOpts]
1094
1136
  );
1095
- const appliedTheme = React5.useMemo(
1096
- () => theme || defaultConsentTheme,
1097
- [theme]
1098
- );
1137
+ const appliedTheme = React5.useMemo(() => theme || defaultConsentTheme, [theme]);
1099
1138
  const finalCategoriesConfig = React5.useMemo(() => {
1100
1139
  if (categories) return categories;
1101
1140
  return DEFAULT_PROJECT_CATEGORIES;
@@ -1127,8 +1166,7 @@ function ConsentProvider({
1127
1166
  setIsHydrated(true);
1128
1167
  }, [cookie.name, initialState, finalCategoriesConfig]);
1129
1168
  React5.useEffect(() => {
1130
- if (state.consented)
1131
- writeConsentCookie(state, finalCategoriesConfig, cookie);
1169
+ if (state.consented) writeConsentCookie(state, finalCategoriesConfig, cookie);
1132
1170
  }, [state, cookie, finalCategoriesConfig]);
1133
1171
  const prevConsented = React5.useRef(state.consented);
1134
1172
  React5.useEffect(() => {
@@ -1217,14 +1255,12 @@ function ConsentProvider({
1217
1255
  }
1218
1256
  function useConsentStateInternal() {
1219
1257
  const ctx = React5.useContext(StateCtx);
1220
- if (!ctx)
1221
- throw new Error("useConsentState must be used within ConsentProvider");
1258
+ if (!ctx) throw new Error("useConsentState must be used within ConsentProvider");
1222
1259
  return ctx;
1223
1260
  }
1224
1261
  function useConsentActionsInternal() {
1225
1262
  const ctx = React5.useContext(ActionsCtx);
1226
- if (!ctx)
1227
- throw new Error("useConsentActions must be used within ConsentProvider");
1263
+ if (!ctx) throw new Error("useConsentActions must be used within ConsentProvider");
1228
1264
  return ctx;
1229
1265
  }
1230
1266
  function useConsentTextsInternal() {
@@ -1234,6 +1270,7 @@ function useConsentTextsInternal() {
1234
1270
  function useConsentHydrationInternal() {
1235
1271
  return React5.useContext(HydrationCtx);
1236
1272
  }
1273
+ var defaultTexts = DEFAULT_TEXTS;
1237
1274
 
1238
1275
  // src/hooks/useConsent.ts
1239
1276
  function useConsent() {
@@ -1267,7 +1304,7 @@ function openPreferencesModal() {
1267
1304
  if (globalOpenPreferences) {
1268
1305
  globalOpenPreferences();
1269
1306
  } else {
1270
- console.warn(
1307
+ logger.warn(
1271
1308
  "openPreferencesModal: ConsentProvider n\xE3o foi inicializado ou n\xE3o est\xE1 dispon\xEDvel."
1272
1309
  );
1273
1310
  }
@@ -1288,16 +1325,14 @@ function PreferencesModal2({
1288
1325
  const { preferences, setPreferences, closePreferences, isModalOpen } = useConsent();
1289
1326
  const texts = useConsentTexts();
1290
1327
  const { toggleableCategories } = useCategories();
1291
- const [tempPreferences, setTempPreferences] = useState2(
1292
- () => {
1293
- const initialPrefs = { necessary: true };
1294
- toggleableCategories.forEach((category) => {
1295
- initialPrefs[category.id] = preferences[category.id] ?? false;
1296
- });
1297
- return initialPrefs;
1298
- }
1299
- );
1300
- useEffect4(() => {
1328
+ const [tempPreferences, setTempPreferences] = useState2(() => {
1329
+ const initialPrefs = { necessary: true };
1330
+ toggleableCategories.forEach((category) => {
1331
+ initialPrefs[category.id] = preferences[category.id] ?? false;
1332
+ });
1333
+ return initialPrefs;
1334
+ });
1335
+ useEffect3(() => {
1301
1336
  if (isModalOpen) {
1302
1337
  const syncedPrefs = { necessary: true };
1303
1338
  toggleableCategories.forEach((category) => {
@@ -1314,52 +1349,37 @@ function PreferencesModal2({
1314
1349
  setTempPreferences(preferences);
1315
1350
  closePreferences();
1316
1351
  };
1317
- return /* @__PURE__ */ jsxs4(
1318
- Dialog,
1319
- {
1320
- "aria-labelledby": "cookie-pref-title",
1321
- open,
1322
- onClose: handleCancel,
1323
- ...DialogProps2,
1324
- children: [
1325
- /* @__PURE__ */ jsx8(DialogTitle, { id: "cookie-pref-title", children: texts.modalTitle }),
1326
- /* @__PURE__ */ jsxs4(DialogContent, { dividers: true, children: [
1327
- /* @__PURE__ */ jsx8(Typography3, { variant: "body2", sx: { mb: 2 }, children: texts.modalIntro }),
1328
- /* @__PURE__ */ jsxs4(FormGroup, { children: [
1329
- toggleableCategories.map((category) => /* @__PURE__ */ jsx8(
1330
- FormControlLabel,
1331
- {
1332
- control: /* @__PURE__ */ jsx8(
1333
- Switch,
1334
- {
1335
- checked: tempPreferences[category.id] ?? false,
1336
- onChange: (e) => setTempPreferences((prev) => ({
1337
- ...prev,
1338
- [category.id]: e.target.checked
1339
- }))
1340
- }
1341
- ),
1342
- label: `${category.name} - ${category.description}`
1343
- },
1344
- category.id
1345
- )),
1346
- /* @__PURE__ */ jsx8(
1347
- FormControlLabel,
1352
+ return /* @__PURE__ */ jsxs4(Dialog, { "aria-labelledby": "cookie-pref-title", open, onClose: handleCancel, ...DialogProps2, children: [
1353
+ /* @__PURE__ */ jsx8(DialogTitle, { id: "cookie-pref-title", children: texts.modalTitle }),
1354
+ /* @__PURE__ */ jsxs4(DialogContent, { dividers: true, children: [
1355
+ /* @__PURE__ */ jsx8(Typography3, { variant: "body2", sx: { mb: 2 }, children: texts.modalIntro }),
1356
+ /* @__PURE__ */ jsxs4(FormGroup, { children: [
1357
+ toggleableCategories.map((category) => /* @__PURE__ */ jsx8(
1358
+ FormControlLabel,
1359
+ {
1360
+ control: /* @__PURE__ */ jsx8(
1361
+ Switch,
1348
1362
  {
1349
- control: /* @__PURE__ */ jsx8(Switch, { checked: true, disabled: true }),
1350
- label: texts.necessaryAlwaysOn
1363
+ checked: tempPreferences[category.id] ?? false,
1364
+ onChange: (e) => setTempPreferences((prev) => ({
1365
+ ...prev,
1366
+ [category.id]: e.target.checked
1367
+ }))
1351
1368
  }
1352
- )
1353
- ] })
1354
- ] }),
1355
- /* @__PURE__ */ jsxs4(DialogActions, { children: [
1356
- /* @__PURE__ */ jsx8(Button2, { variant: "outlined", onClick: handleCancel, children: texts.close }),
1357
- /* @__PURE__ */ jsx8(Button2, { variant: "contained", onClick: handleSave, children: texts.save })
1358
- ] }),
1359
- !hideBranding && /* @__PURE__ */ jsx8(Branding, { variant: "modal" })
1360
- ]
1361
- }
1362
- );
1369
+ ),
1370
+ label: `${category.name} - ${category.description}`
1371
+ },
1372
+ category.id
1373
+ )),
1374
+ /* @__PURE__ */ jsx8(FormControlLabel, { control: /* @__PURE__ */ jsx8(Switch, { checked: true, disabled: true }), label: texts.necessaryAlwaysOn })
1375
+ ] })
1376
+ ] }),
1377
+ /* @__PURE__ */ jsxs4(DialogActions, { children: [
1378
+ /* @__PURE__ */ jsx8(Button2, { variant: "outlined", onClick: handleCancel, children: texts.close }),
1379
+ /* @__PURE__ */ jsx8(Button2, { variant: "contained", onClick: handleSave, children: texts.save })
1380
+ ] }),
1381
+ !hideBranding && /* @__PURE__ */ jsx8(Branding, { variant: "modal" })
1382
+ ] });
1363
1383
  }
1364
1384
 
1365
1385
  export {
@@ -1368,9 +1388,16 @@ export {
1368
1388
  useCategories,
1369
1389
  useCategoryStatus,
1370
1390
  LogLevel,
1391
+ logger,
1371
1392
  setDebugLogging,
1393
+ createProjectPreferences,
1394
+ validateProjectPreferences,
1395
+ getAllProjectCategories,
1372
1396
  defaultConsentTheme,
1397
+ CookieBanner,
1398
+ FloatingPreferencesButton,
1373
1399
  ConsentProvider,
1400
+ defaultTexts,
1374
1401
  useConsent,
1375
1402
  useConsentTexts,
1376
1403
  useConsentHydration,