react-lgpd-consent 0.3.1 → 0.3.2

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 = {
@@ -896,20 +986,8 @@ function FloatingPreferencesButton({
896
986
 
897
987
  // src/context/ConsentContext.tsx
898
988
  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
989
  var PreferencesModal = React5.lazy(
912
- () => import("./PreferencesModal-J27W5XAJ.js").then((m) => ({
990
+ () => import("./PreferencesModal-7RSEEVUK.js").then((m) => ({
913
991
  default: m.PreferencesModal
914
992
  }))
915
993
  );
@@ -964,43 +1042,26 @@ var DEFAULT_TEXTS = {
964
1042
  // Exibido se definido
965
1043
  };
966
1044
  function reducer(state, action) {
967
- log.debug("State transition:", {
968
- action: action.type,
969
- currentState: state.consented
970
- });
1045
+ logger.consentState(action.type, state);
971
1046
  switch (action.type) {
972
1047
  case "ACCEPT_ALL": {
973
1048
  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", {
1049
+ const newState = createFullConsentState(true, prefs, "banner", action.config, false, state);
1050
+ logger.info("User accepted all cookies", {
983
1051
  preferences: newState.preferences
984
1052
  });
985
1053
  return newState;
986
1054
  }
987
1055
  case "REJECT_ALL": {
988
1056
  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", {
1057
+ const newState = createFullConsentState(true, prefs, "banner", action.config, false, state);
1058
+ logger.info("User rejected all cookies", {
998
1059
  preferences: newState.preferences
999
1060
  });
1000
1061
  return newState;
1001
1062
  }
1002
1063
  case "SET_CATEGORY":
1003
- log.debug("Category preference changed", {
1064
+ logger.debug("Category preference changed", {
1004
1065
  category: action.category,
1005
1066
  value: action.value
1006
1067
  });
@@ -1013,26 +1074,12 @@ function reducer(state, action) {
1013
1074
  lastUpdate: (/* @__PURE__ */ new Date()).toISOString()
1014
1075
  };
1015
1076
  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
- );
1077
+ logger.info("Preferences saved", { preferences: action.preferences });
1078
+ return createFullConsentState(true, action.preferences, "modal", action.config, false, state);
1025
1079
  case "OPEN_MODAL":
1026
1080
  return { ...state, isModalOpen: true };
1027
1081
  case "CLOSE_MODAL":
1028
- return createFullConsentState(
1029
- true,
1030
- state.preferences,
1031
- "modal",
1032
- action.config,
1033
- false,
1034
- state
1035
- );
1082
+ return createFullConsentState(true, state.preferences, "modal", action.config, false, state);
1036
1083
  case "RESET": {
1037
1084
  return createFullConsentState(
1038
1085
  false,
@@ -1064,12 +1111,9 @@ var HydrationCtx = React5.createContext(false);
1064
1111
  function ConsentProvider({
1065
1112
  initialState,
1066
1113
  categories,
1067
- // Nova prop para configuração de categorias
1068
1114
  texts: textsProp,
1069
1115
  theme,
1070
1116
  designTokens,
1071
- scriptIntegrations,
1072
- // eslint-disable-line no-unused-vars
1073
1117
  PreferencesModalComponent,
1074
1118
  preferencesModalProps = {},
1075
1119
  CookieBannerComponent,
@@ -1084,18 +1128,12 @@ function ConsentProvider({
1084
1128
  disableDeveloperGuidance,
1085
1129
  children
1086
1130
  }) {
1087
- const texts = React5.useMemo(
1088
- () => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }),
1089
- [textsProp]
1090
- );
1131
+ const texts = React5.useMemo(() => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }), [textsProp]);
1091
1132
  const cookie = React5.useMemo(
1092
1133
  () => ({ ...DEFAULT_COOKIE_OPTS, ...cookieOpts ?? {} }),
1093
1134
  [cookieOpts]
1094
1135
  );
1095
- const appliedTheme = React5.useMemo(
1096
- () => theme || defaultConsentTheme,
1097
- [theme]
1098
- );
1136
+ const appliedTheme = React5.useMemo(() => theme || defaultConsentTheme, [theme]);
1099
1137
  const finalCategoriesConfig = React5.useMemo(() => {
1100
1138
  if (categories) return categories;
1101
1139
  return DEFAULT_PROJECT_CATEGORIES;
@@ -1127,8 +1165,7 @@ function ConsentProvider({
1127
1165
  setIsHydrated(true);
1128
1166
  }, [cookie.name, initialState, finalCategoriesConfig]);
1129
1167
  React5.useEffect(() => {
1130
- if (state.consented)
1131
- writeConsentCookie(state, finalCategoriesConfig, cookie);
1168
+ if (state.consented) writeConsentCookie(state, finalCategoriesConfig, cookie);
1132
1169
  }, [state, cookie, finalCategoriesConfig]);
1133
1170
  const prevConsented = React5.useRef(state.consented);
1134
1171
  React5.useEffect(() => {
@@ -1217,14 +1254,12 @@ function ConsentProvider({
1217
1254
  }
1218
1255
  function useConsentStateInternal() {
1219
1256
  const ctx = React5.useContext(StateCtx);
1220
- if (!ctx)
1221
- throw new Error("useConsentState must be used within ConsentProvider");
1257
+ if (!ctx) throw new Error("useConsentState must be used within ConsentProvider");
1222
1258
  return ctx;
1223
1259
  }
1224
1260
  function useConsentActionsInternal() {
1225
1261
  const ctx = React5.useContext(ActionsCtx);
1226
- if (!ctx)
1227
- throw new Error("useConsentActions must be used within ConsentProvider");
1262
+ if (!ctx) throw new Error("useConsentActions must be used within ConsentProvider");
1228
1263
  return ctx;
1229
1264
  }
1230
1265
  function useConsentTextsInternal() {
@@ -1234,6 +1269,7 @@ function useConsentTextsInternal() {
1234
1269
  function useConsentHydrationInternal() {
1235
1270
  return React5.useContext(HydrationCtx);
1236
1271
  }
1272
+ var defaultTexts = DEFAULT_TEXTS;
1237
1273
 
1238
1274
  // src/hooks/useConsent.ts
1239
1275
  function useConsent() {
@@ -1267,7 +1303,7 @@ function openPreferencesModal() {
1267
1303
  if (globalOpenPreferences) {
1268
1304
  globalOpenPreferences();
1269
1305
  } else {
1270
- console.warn(
1306
+ logger.warn(
1271
1307
  "openPreferencesModal: ConsentProvider n\xE3o foi inicializado ou n\xE3o est\xE1 dispon\xEDvel."
1272
1308
  );
1273
1309
  }
@@ -1288,16 +1324,14 @@ function PreferencesModal2({
1288
1324
  const { preferences, setPreferences, closePreferences, isModalOpen } = useConsent();
1289
1325
  const texts = useConsentTexts();
1290
1326
  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(() => {
1327
+ const [tempPreferences, setTempPreferences] = useState2(() => {
1328
+ const initialPrefs = { necessary: true };
1329
+ toggleableCategories.forEach((category) => {
1330
+ initialPrefs[category.id] = preferences[category.id] ?? false;
1331
+ });
1332
+ return initialPrefs;
1333
+ });
1334
+ useEffect3(() => {
1301
1335
  if (isModalOpen) {
1302
1336
  const syncedPrefs = { necessary: true };
1303
1337
  toggleableCategories.forEach((category) => {
@@ -1314,52 +1348,37 @@ function PreferencesModal2({
1314
1348
  setTempPreferences(preferences);
1315
1349
  closePreferences();
1316
1350
  };
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,
1351
+ return /* @__PURE__ */ jsxs4(Dialog, { "aria-labelledby": "cookie-pref-title", open, onClose: handleCancel, ...DialogProps2, children: [
1352
+ /* @__PURE__ */ jsx8(DialogTitle, { id: "cookie-pref-title", children: texts.modalTitle }),
1353
+ /* @__PURE__ */ jsxs4(DialogContent, { dividers: true, children: [
1354
+ /* @__PURE__ */ jsx8(Typography3, { variant: "body2", sx: { mb: 2 }, children: texts.modalIntro }),
1355
+ /* @__PURE__ */ jsxs4(FormGroup, { children: [
1356
+ toggleableCategories.map((category) => /* @__PURE__ */ jsx8(
1357
+ FormControlLabel,
1358
+ {
1359
+ control: /* @__PURE__ */ jsx8(
1360
+ Switch,
1348
1361
  {
1349
- control: /* @__PURE__ */ jsx8(Switch, { checked: true, disabled: true }),
1350
- label: texts.necessaryAlwaysOn
1362
+ checked: tempPreferences[category.id] ?? false,
1363
+ onChange: (e) => setTempPreferences((prev) => ({
1364
+ ...prev,
1365
+ [category.id]: e.target.checked
1366
+ }))
1351
1367
  }
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
- );
1368
+ ),
1369
+ label: `${category.name} - ${category.description}`
1370
+ },
1371
+ category.id
1372
+ )),
1373
+ /* @__PURE__ */ jsx8(FormControlLabel, { control: /* @__PURE__ */ jsx8(Switch, { checked: true, disabled: true }), label: texts.necessaryAlwaysOn })
1374
+ ] })
1375
+ ] }),
1376
+ /* @__PURE__ */ jsxs4(DialogActions, { children: [
1377
+ /* @__PURE__ */ jsx8(Button2, { variant: "outlined", onClick: handleCancel, children: texts.close }),
1378
+ /* @__PURE__ */ jsx8(Button2, { variant: "contained", onClick: handleSave, children: texts.save })
1379
+ ] }),
1380
+ !hideBranding && /* @__PURE__ */ jsx8(Branding, { variant: "modal" })
1381
+ ] });
1363
1382
  }
1364
1383
 
1365
1384
  export {
@@ -1368,9 +1387,16 @@ export {
1368
1387
  useCategories,
1369
1388
  useCategoryStatus,
1370
1389
  LogLevel,
1390
+ logger,
1371
1391
  setDebugLogging,
1392
+ createProjectPreferences,
1393
+ validateProjectPreferences,
1394
+ getAllProjectCategories,
1372
1395
  defaultConsentTheme,
1396
+ CookieBanner,
1397
+ FloatingPreferencesButton,
1373
1398
  ConsentProvider,
1399
+ defaultTexts,
1374
1400
  useConsent,
1375
1401
  useConsentTexts,
1376
1402
  useConsentHydration,