react-lgpd-consent 0.1.5 → 0.1.6

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/dist/index.d.cts CHANGED
@@ -80,6 +80,12 @@ interface ConsentProviderProps {
80
80
  texts?: Partial<ConsentTexts>;
81
81
  /** Tema customizado para os componentes MUI. */
82
82
  theme?: any;
83
+ /** Componente customizado para modal de preferências. */
84
+ PreferencesModalComponent?: React.ComponentType<any>;
85
+ /** Props adicionais para o modal customizado. */
86
+ preferencesModalProps?: Record<string, any>;
87
+ /** Desabilita o modal automático (para usar componente totalmente customizado). */
88
+ disableAutomaticModal?: boolean;
83
89
  /** Callback chamado quando o consentimento é dado. */
84
90
  onConsentGiven?: (state: ConsentState) => void;
85
91
  /** Callback chamado ao salvar preferências. */
@@ -113,7 +119,7 @@ interface ConsentContextValue {
113
119
  resetConsent: () => void;
114
120
  }
115
121
 
116
- declare function ConsentProvider({ initialState, texts: textsProp, theme, onConsentGiven, onPreferencesSaved, cookie: cookieOpts, children, }: Readonly<ConsentProviderProps>): react_jsx_runtime.JSX.Element;
122
+ declare function ConsentProvider({ initialState, texts: textsProp, theme, PreferencesModalComponent, preferencesModalProps, disableAutomaticModal, onConsentGiven, onPreferencesSaved, cookie: cookieOpts, children, }: Readonly<ConsentProviderProps>): react_jsx_runtime.JSX.Element;
117
123
 
118
124
  declare function useConsent(): ConsentContextValue;
119
125
  /**
@@ -128,15 +134,10 @@ declare function ConsentGate(props: Readonly<{
128
134
  }>): react_jsx_runtime.JSX.Element | null;
129
135
 
130
136
  /**
131
- * Carrega um script dinamicamente após verificação de consentimento.
132
- * Recomenda-se usar com ConsentGate para melhor controle.
137
+ * Carrega um script dinamicamente após consentimento finalizado.
138
+ * Aguarda que o usuário tome uma decisão definitiva (banner fechado ou preferências salvas).
133
139
  */
134
- declare function loadScript(id: string, src: string, attrs?: Record<string, string>): void;
135
- /**
136
- * Carrega script condicionalmente baseado no consentimento.
137
- * Aguarda o consentimento ser dado antes de executar.
138
- */
139
- declare function loadConditionalScript(id: string, src: string, condition: () => boolean, attrs?: Record<string, string>, maxWaitMs?: number): Promise<void>;
140
+ declare function loadScript(id: string, src: string, category?: 'analytics' | 'marketing' | null, attrs?: Record<string, string>): Promise<void>;
140
141
 
141
142
  /**
142
143
  * Tema padrão para os componentes de consentimento.
@@ -144,4 +145,4 @@ declare function loadConditionalScript(id: string, src: string, condition: () =>
144
145
  */
145
146
  declare const defaultConsentTheme: _mui_material_styles.Theme;
146
147
 
147
- export { type Category, type ConsentCookieOptions, ConsentGate, type ConsentPreferences, ConsentProvider, type ConsentState, type ConsentTexts, CookieBanner, PreferencesModal, defaultConsentTheme, loadConditionalScript, loadScript, useConsent, useConsentTexts };
148
+ export { type Category, type ConsentCookieOptions, ConsentGate, type ConsentPreferences, ConsentProvider, type ConsentState, type ConsentTexts, CookieBanner, PreferencesModal, defaultConsentTheme, loadScript, useConsent, useConsentTexts };
package/dist/index.d.ts CHANGED
@@ -80,6 +80,12 @@ interface ConsentProviderProps {
80
80
  texts?: Partial<ConsentTexts>;
81
81
  /** Tema customizado para os componentes MUI. */
82
82
  theme?: any;
83
+ /** Componente customizado para modal de preferências. */
84
+ PreferencesModalComponent?: React.ComponentType<any>;
85
+ /** Props adicionais para o modal customizado. */
86
+ preferencesModalProps?: Record<string, any>;
87
+ /** Desabilita o modal automático (para usar componente totalmente customizado). */
88
+ disableAutomaticModal?: boolean;
83
89
  /** Callback chamado quando o consentimento é dado. */
84
90
  onConsentGiven?: (state: ConsentState) => void;
85
91
  /** Callback chamado ao salvar preferências. */
@@ -113,7 +119,7 @@ interface ConsentContextValue {
113
119
  resetConsent: () => void;
114
120
  }
115
121
 
116
- declare function ConsentProvider({ initialState, texts: textsProp, theme, onConsentGiven, onPreferencesSaved, cookie: cookieOpts, children, }: Readonly<ConsentProviderProps>): react_jsx_runtime.JSX.Element;
122
+ declare function ConsentProvider({ initialState, texts: textsProp, theme, PreferencesModalComponent, preferencesModalProps, disableAutomaticModal, onConsentGiven, onPreferencesSaved, cookie: cookieOpts, children, }: Readonly<ConsentProviderProps>): react_jsx_runtime.JSX.Element;
117
123
 
118
124
  declare function useConsent(): ConsentContextValue;
119
125
  /**
@@ -128,15 +134,10 @@ declare function ConsentGate(props: Readonly<{
128
134
  }>): react_jsx_runtime.JSX.Element | null;
129
135
 
130
136
  /**
131
- * Carrega um script dinamicamente após verificação de consentimento.
132
- * Recomenda-se usar com ConsentGate para melhor controle.
137
+ * Carrega um script dinamicamente após consentimento finalizado.
138
+ * Aguarda que o usuário tome uma decisão definitiva (banner fechado ou preferências salvas).
133
139
  */
134
- declare function loadScript(id: string, src: string, attrs?: Record<string, string>): void;
135
- /**
136
- * Carrega script condicionalmente baseado no consentimento.
137
- * Aguarda o consentimento ser dado antes de executar.
138
- */
139
- declare function loadConditionalScript(id: string, src: string, condition: () => boolean, attrs?: Record<string, string>, maxWaitMs?: number): Promise<void>;
140
+ declare function loadScript(id: string, src: string, category?: 'analytics' | 'marketing' | null, attrs?: Record<string, string>): Promise<void>;
140
141
 
141
142
  /**
142
143
  * Tema padrão para os componentes de consentimento.
@@ -144,4 +145,4 @@ declare function loadConditionalScript(id: string, src: string, condition: () =>
144
145
  */
145
146
  declare const defaultConsentTheme: _mui_material_styles.Theme;
146
147
 
147
- export { type Category, type ConsentCookieOptions, ConsentGate, type ConsentPreferences, ConsentProvider, type ConsentState, type ConsentTexts, CookieBanner, PreferencesModal, defaultConsentTheme, loadConditionalScript, loadScript, useConsent, useConsentTexts };
148
+ export { type Category, type ConsentCookieOptions, ConsentGate, type ConsentPreferences, ConsentProvider, type ConsentState, type ConsentTexts, CookieBanner, PreferencesModal, defaultConsentTheme, loadScript, useConsent, useConsentTexts };
package/dist/index.js CHANGED
@@ -1,3 +1,11 @@
1
+ import {
2
+ ConsentProvider,
3
+ PreferencesModal,
4
+ defaultConsentTheme,
5
+ useConsent,
6
+ useConsentTexts
7
+ } from "./chunk-K3EVSUMQ.js";
8
+
1
9
  // src/components/CookieBanner.tsx
2
10
  import Button from "@mui/material/Button";
3
11
  import Box from "@mui/material/Box";
@@ -6,287 +14,7 @@ import Paper from "@mui/material/Paper";
6
14
  import Snackbar from "@mui/material/Snackbar";
7
15
  import Stack from "@mui/material/Stack";
8
16
  import Typography from "@mui/material/Typography";
9
-
10
- // src/context/ConsentContext.tsx
11
- import * as React from "react";
12
- import { ThemeProvider } from "@mui/material/styles";
13
-
14
- // src/utils/cookieUtils.ts
15
- import Cookies from "js-cookie";
16
- var DEFAULT_COOKIE_OPTS = {
17
- name: "cookieConsent",
18
- maxAgeDays: 365,
19
- sameSite: "Lax",
20
- secure: true,
21
- path: "/"
22
- };
23
- function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
24
- if (typeof document === "undefined") return null;
25
- const raw = Cookies.get(name);
26
- if (!raw) return null;
27
- try {
28
- return JSON.parse(raw);
29
- } catch {
30
- return null;
31
- }
32
- }
33
- function writeConsentCookie(state, opts) {
34
- if (typeof document === "undefined") return;
35
- const o = { ...DEFAULT_COOKIE_OPTS, ...opts };
36
- Cookies.set(o.name, JSON.stringify(state), {
37
- expires: o.maxAgeDays,
38
- sameSite: o.sameSite,
39
- secure: o.secure,
40
- path: o.path
41
- });
42
- }
43
- function removeConsentCookie(opts) {
44
- if (typeof document === "undefined") return;
45
- const o = { ...DEFAULT_COOKIE_OPTS, ...opts };
46
- Cookies.remove(o.name, { path: o.path });
47
- }
48
-
49
- // src/utils/theme.ts
50
- import { createTheme } from "@mui/material/styles";
51
- var defaultConsentTheme = createTheme({
52
- palette: {
53
- primary: {
54
- main: "#1976d2",
55
- // Azul institucional
56
- contrastText: "#ffffff"
57
- },
58
- secondary: {
59
- main: "#dc004e",
60
- // Rosa/vermelho para ações importantes
61
- contrastText: "#ffffff"
62
- },
63
- background: {
64
- default: "#fafafa",
65
- paper: "#ffffff"
66
- },
67
- text: {
68
- primary: "#333333",
69
- secondary: "#666666"
70
- },
71
- action: {
72
- hover: "rgba(25, 118, 210, 0.04)"
73
- }
74
- },
75
- typography: {
76
- fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
77
- body2: {
78
- fontSize: "0.875rem",
79
- lineHeight: 1.43
80
- },
81
- button: {
82
- fontWeight: 500,
83
- textTransform: "none"
84
- // Manter capitalização original
85
- }
86
- },
87
- components: {
88
- MuiButton: {
89
- styleOverrides: {
90
- root: {
91
- borderRadius: 8,
92
- paddingX: 16,
93
- paddingY: 8
94
- },
95
- contained: {
96
- boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
97
- "&:hover": {
98
- boxShadow: "0 4px 8px rgba(0,0,0,0.15)"
99
- }
100
- }
101
- }
102
- },
103
- MuiPaper: {
104
- styleOverrides: {
105
- root: {
106
- borderRadius: 12
107
- }
108
- }
109
- },
110
- MuiDialog: {
111
- styleOverrides: {
112
- paper: {
113
- borderRadius: 16
114
- }
115
- }
116
- }
117
- }
118
- });
119
-
120
- // src/context/ConsentContext.tsx
121
- import { jsx } from "react/jsx-runtime";
122
- var DEFAULT_PREFERENCES = {
123
- analytics: false,
124
- marketing: false
125
- };
126
- var DEFAULT_TEXTS = {
127
- bannerMessage: "Utilizamos cookies para melhorar sua experi\xEAncia.",
128
- acceptAll: "Aceitar todos",
129
- declineAll: "Recusar",
130
- preferences: "Prefer\xEAncias",
131
- policyLink: "Saiba mais",
132
- modalTitle: "Prefer\xEAncias de Cookies",
133
- modalIntro: "Ajuste as categorias de cookies. Cookies necess\xE1rios s\xE3o sempre utilizados para funcionalidades b\xE1sicas.",
134
- save: "Salvar prefer\xEAncias",
135
- necessaryAlwaysOn: "Cookies necess\xE1rios (sempre ativos)"
136
- };
137
- function reducer(state, action) {
138
- switch (action.type) {
139
- case "ACCEPT_ALL":
140
- return {
141
- consented: true,
142
- preferences: { analytics: true, marketing: true },
143
- isModalOpen: false
144
- };
145
- case "REJECT_ALL":
146
- return {
147
- consented: true,
148
- preferences: { analytics: false, marketing: false },
149
- isModalOpen: false
150
- };
151
- case "SET_CATEGORY":
152
- return {
153
- ...state,
154
- preferences: {
155
- ...state.preferences,
156
- [action.category]: action.value
157
- }
158
- };
159
- case "OPEN_MODAL":
160
- return { ...state, isModalOpen: true };
161
- case "CLOSE_MODAL":
162
- return { ...state, isModalOpen: false, consented: true };
163
- // houve interação
164
- case "RESET":
165
- return {
166
- consented: false,
167
- preferences: { ...DEFAULT_PREFERENCES },
168
- isModalOpen: false
169
- };
170
- case "HYDRATE":
171
- return { ...action.state };
172
- default:
173
- return state;
174
- }
175
- }
176
- var StateCtx = React.createContext(null);
177
- var ActionsCtx = React.createContext(null);
178
- var TextsCtx = React.createContext(DEFAULT_TEXTS);
179
- function ConsentProvider({
180
- initialState,
181
- texts: textsProp,
182
- theme,
183
- onConsentGiven,
184
- onPreferencesSaved,
185
- cookie: cookieOpts,
186
- children
187
- }) {
188
- const texts = React.useMemo(
189
- () => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }),
190
- [textsProp]
191
- );
192
- const cookie = React.useMemo(
193
- () => ({ ...DEFAULT_COOKIE_OPTS, ...cookieOpts ?? {} }),
194
- [cookieOpts]
195
- );
196
- const appliedTheme = React.useMemo(
197
- () => theme || defaultConsentTheme,
198
- [theme]
199
- );
200
- const boot = React.useMemo(() => {
201
- if (initialState) return { ...initialState, isModalOpen: false };
202
- const saved = readConsentCookie(cookie.name);
203
- return saved ?? {
204
- consented: false,
205
- preferences: { ...DEFAULT_PREFERENCES },
206
- isModalOpen: false
207
- };
208
- }, [initialState, cookie.name]);
209
- const [state, dispatch] = React.useReducer(reducer, boot);
210
- React.useEffect(() => {
211
- if (state.consented) writeConsentCookie(state, cookie);
212
- }, [state, cookie]);
213
- const prevConsented = React.useRef(state.consented);
214
- React.useEffect(() => {
215
- if (!prevConsented.current && state.consented && onConsentGiven) {
216
- setTimeout(() => onConsentGiven(state), 150);
217
- }
218
- prevConsented.current = state.consented;
219
- }, [state, onConsentGiven]);
220
- const prevPrefs = React.useRef(state.preferences);
221
- React.useEffect(() => {
222
- if (state.consented && onPreferencesSaved && prevPrefs.current !== state.preferences) {
223
- setTimeout(() => onPreferencesSaved(state.preferences), 150);
224
- prevPrefs.current = state.preferences;
225
- }
226
- }, [state, onPreferencesSaved]);
227
- const api = React.useMemo(() => {
228
- const acceptAll = () => dispatch({ type: "ACCEPT_ALL" });
229
- const rejectAll = () => dispatch({ type: "REJECT_ALL" });
230
- const setPreference = (category, value) => dispatch({ type: "SET_CATEGORY", category, value });
231
- const openPreferences = () => dispatch({ type: "OPEN_MODAL" });
232
- const closePreferences = () => dispatch({ type: "CLOSE_MODAL" });
233
- const resetConsent = () => {
234
- removeConsentCookie(cookie);
235
- dispatch({ type: "RESET" });
236
- };
237
- return {
238
- consented: !!state.consented,
239
- preferences: state.preferences,
240
- isModalOpen: state.isModalOpen,
241
- acceptAll,
242
- rejectAll,
243
- setPreference,
244
- openPreferences,
245
- closePreferences,
246
- resetConsent
247
- };
248
- }, [state, cookie]);
249
- return /* @__PURE__ */ jsx(ThemeProvider, { theme: appliedTheme, children: /* @__PURE__ */ jsx(StateCtx.Provider, { value: state, children: /* @__PURE__ */ jsx(ActionsCtx.Provider, { value: api, children: /* @__PURE__ */ jsx(TextsCtx.Provider, { value: texts, children }) }) }) });
250
- }
251
- function useConsentStateInternal() {
252
- const ctx = React.useContext(StateCtx);
253
- if (!ctx)
254
- throw new Error("useConsentState must be used within ConsentProvider");
255
- return ctx;
256
- }
257
- function useConsentActionsInternal() {
258
- const ctx = React.useContext(ActionsCtx);
259
- if (!ctx)
260
- throw new Error("useConsentActions must be used within ConsentProvider");
261
- return ctx;
262
- }
263
- function useConsentTextsInternal() {
264
- const ctx = React.useContext(TextsCtx);
265
- return ctx;
266
- }
267
-
268
- // src/hooks/useConsent.ts
269
- function useConsent() {
270
- const state = useConsentStateInternal();
271
- const actions = useConsentActionsInternal();
272
- return {
273
- consented: state.consented,
274
- preferences: state.preferences,
275
- isModalOpen: state.isModalOpen,
276
- acceptAll: actions.acceptAll,
277
- rejectAll: actions.rejectAll,
278
- setPreference: actions.setPreference,
279
- openPreferences: actions.openPreferences,
280
- closePreferences: actions.closePreferences,
281
- resetConsent: actions.resetConsent
282
- };
283
- }
284
- function useConsentTexts() {
285
- return useConsentTextsInternal();
286
- }
287
-
288
- // src/components/CookieBanner.tsx
289
- import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
17
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
290
18
  function CookieBanner({
291
19
  policyLinkUrl,
292
20
  debug,
@@ -299,7 +27,7 @@ function CookieBanner({
299
27
  const texts = useConsentTexts();
300
28
  const open = debug ? true : !consented;
301
29
  if (!open) return null;
302
- const bannerContent = /* @__PURE__ */ jsx2(
30
+ const bannerContent = /* @__PURE__ */ jsx(
303
31
  Paper,
304
32
  {
305
33
  elevation: 3,
@@ -309,7 +37,7 @@ function CookieBanner({
309
37
  /* @__PURE__ */ jsxs(Typography, { variant: "body2", children: [
310
38
  texts.bannerMessage,
311
39
  " ",
312
- policyLinkUrl && /* @__PURE__ */ jsx2(
40
+ policyLinkUrl && /* @__PURE__ */ jsx(
313
41
  Link,
314
42
  {
315
43
  href: policyLinkUrl,
@@ -327,9 +55,9 @@ function CookieBanner({
327
55
  spacing: 1,
328
56
  justifyContent: "flex-end",
329
57
  children: [
330
- /* @__PURE__ */ jsx2(Button, { variant: "outlined", onClick: rejectAll, children: texts.declineAll }),
331
- /* @__PURE__ */ jsx2(Button, { variant: "contained", onClick: acceptAll, children: texts.acceptAll }),
332
- /* @__PURE__ */ jsx2(Button, { variant: "text", onClick: openPreferences, children: texts.preferences })
58
+ /* @__PURE__ */ jsx(Button, { variant: "outlined", onClick: rejectAll, children: texts.declineAll }),
59
+ /* @__PURE__ */ jsx(Button, { variant: "contained", onClick: acceptAll, children: texts.acceptAll }),
60
+ /* @__PURE__ */ jsx(Button, { variant: "text", onClick: openPreferences, children: texts.preferences })
333
61
  ]
334
62
  }
335
63
  )
@@ -338,7 +66,7 @@ function CookieBanner({
338
66
  );
339
67
  if (blocking) {
340
68
  return /* @__PURE__ */ jsxs(Fragment, { children: [
341
- /* @__PURE__ */ jsx2(
69
+ /* @__PURE__ */ jsx(
342
70
  Box,
343
71
  {
344
72
  sx: {
@@ -353,7 +81,7 @@ function CookieBanner({
353
81
  }
354
82
  }
355
83
  ),
356
- /* @__PURE__ */ jsx2(
84
+ /* @__PURE__ */ jsx(
357
85
  Box,
358
86
  {
359
87
  sx: {
@@ -370,7 +98,7 @@ function CookieBanner({
370
98
  )
371
99
  ] });
372
100
  }
373
- return /* @__PURE__ */ jsx2(
101
+ return /* @__PURE__ */ jsx(
374
102
  Snackbar,
375
103
  {
376
104
  open,
@@ -381,113 +109,48 @@ function CookieBanner({
381
109
  );
382
110
  }
383
111
 
384
- // src/components/PreferencesModal.tsx
385
- import Button2 from "@mui/material/Button";
386
- import Dialog from "@mui/material/Dialog";
387
- import DialogActions from "@mui/material/DialogActions";
388
- import DialogContent from "@mui/material/DialogContent";
389
- import DialogTitle from "@mui/material/DialogTitle";
390
- import FormControlLabel from "@mui/material/FormControlLabel";
391
- import FormGroup from "@mui/material/FormGroup";
392
- import Switch from "@mui/material/Switch";
393
- import Typography2 from "@mui/material/Typography";
394
- import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
395
- function PreferencesModal({
396
- DialogProps: DialogProps2
397
- }) {
398
- const { preferences, setPreference, closePreferences, isModalOpen } = useConsent();
399
- const texts = useConsentTexts();
400
- const open = DialogProps2?.open ?? isModalOpen ?? false;
401
- return /* @__PURE__ */ jsxs2(
402
- Dialog,
403
- {
404
- "aria-labelledby": "cookie-pref-title",
405
- open,
406
- onClose: closePreferences,
407
- ...DialogProps2,
408
- children: [
409
- /* @__PURE__ */ jsx3(DialogTitle, { id: "cookie-pref-title", children: texts.modalTitle }),
410
- /* @__PURE__ */ jsxs2(DialogContent, { dividers: true, children: [
411
- /* @__PURE__ */ jsx3(Typography2, { variant: "body2", sx: { mb: 2 }, children: texts.modalIntro }),
412
- /* @__PURE__ */ jsxs2(FormGroup, { children: [
413
- /* @__PURE__ */ jsx3(
414
- FormControlLabel,
415
- {
416
- control: /* @__PURE__ */ jsx3(
417
- Switch,
418
- {
419
- checked: preferences.analytics,
420
- onChange: (e) => setPreference("analytics", e.target.checked)
421
- }
422
- ),
423
- label: "Cookies Anal\xEDticos (medem uso do site)"
424
- }
425
- ),
426
- /* @__PURE__ */ jsx3(
427
- FormControlLabel,
428
- {
429
- control: /* @__PURE__ */ jsx3(
430
- Switch,
431
- {
432
- checked: preferences.marketing,
433
- onChange: (e) => setPreference("marketing", e.target.checked)
434
- }
435
- ),
436
- label: "Cookies de Marketing/Publicidade"
437
- }
438
- ),
439
- /* @__PURE__ */ jsx3(
440
- FormControlLabel,
441
- {
442
- control: /* @__PURE__ */ jsx3(Switch, { checked: true, disabled: true }),
443
- label: texts.necessaryAlwaysOn
444
- }
445
- )
446
- ] })
447
- ] }),
448
- /* @__PURE__ */ jsx3(DialogActions, { children: /* @__PURE__ */ jsx3(Button2, { variant: "contained", onClick: closePreferences, children: texts.save }) })
449
- ]
450
- }
451
- );
452
- }
453
-
454
112
  // src/utils/ConsentGate.tsx
455
- import { Fragment as Fragment2, jsx as jsx4 } from "react/jsx-runtime";
113
+ import { Fragment as Fragment2, jsx as jsx2 } from "react/jsx-runtime";
456
114
  function ConsentGate(props) {
457
115
  const { preferences } = useConsent();
458
116
  if (!preferences[props.category]) return null;
459
- return /* @__PURE__ */ jsx4(Fragment2, { children: props.children });
117
+ return /* @__PURE__ */ jsx2(Fragment2, { children: props.children });
460
118
  }
461
119
 
462
120
  // src/utils/scriptLoader.ts
463
- function loadScript(id, src, attrs = {}) {
464
- if (typeof document === "undefined") return;
465
- if (document.getElementById(id)) return;
466
- const s = document.createElement("script");
467
- s.id = id;
468
- s.src = src;
469
- s.async = true;
470
- for (const [k, v] of Object.entries(attrs)) s.setAttribute(k, v);
471
- document.body.appendChild(s);
472
- }
473
- function loadConditionalScript(id, src, condition, attrs = {}, maxWaitMs = 5e3) {
121
+ function loadScript(id, src, category = null, attrs = {}) {
474
122
  if (typeof document === "undefined") return Promise.resolve();
475
123
  if (document.getElementById(id)) return Promise.resolve();
476
124
  return new Promise((resolve, reject) => {
477
- const startTime = Date.now();
478
- const checkCondition = () => {
479
- if (condition()) {
480
- loadScript(id, src, attrs);
481
- resolve();
482
- } else if (Date.now() - startTime > maxWaitMs) {
483
- reject(
484
- new Error(`Timeout waiting for consent condition for script ${id}`)
485
- );
486
- } else {
487
- setTimeout(checkCondition, 100);
125
+ const checkConsent = () => {
126
+ const consentCookie = document.cookie.split("; ").find((row) => row.startsWith("cookieConsent="))?.split("=")[1];
127
+ if (!consentCookie) {
128
+ setTimeout(checkConsent, 100);
129
+ return;
130
+ }
131
+ try {
132
+ const consent = JSON.parse(decodeURIComponent(consentCookie));
133
+ if (!consent.consented) {
134
+ setTimeout(checkConsent, 100);
135
+ return;
136
+ }
137
+ if (category && !consent.preferences[category]) {
138
+ reject(new Error(`Consent not given for ${category} scripts`));
139
+ return;
140
+ }
141
+ const s = document.createElement("script");
142
+ s.id = id;
143
+ s.src = src;
144
+ s.async = true;
145
+ for (const [k, v] of Object.entries(attrs)) s.setAttribute(k, v);
146
+ s.onload = () => resolve();
147
+ s.onerror = () => reject(new Error(`Failed to load script: ${src}`));
148
+ document.body.appendChild(s);
149
+ } catch {
150
+ setTimeout(checkConsent, 100);
488
151
  }
489
152
  };
490
- checkCondition();
153
+ checkConsent();
491
154
  });
492
155
  }
493
156
  export {
@@ -496,7 +159,6 @@ export {
496
159
  CookieBanner,
497
160
  PreferencesModal,
498
161
  defaultConsentTheme,
499
- loadConditionalScript,
500
162
  loadScript,
501
163
  useConsent,
502
164
  useConsentTexts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-lgpd-consent",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Biblioteca de consentimento de cookies (LGPD) para React e Next.js, com contexto, banner e modal personalizáveis usando MUI.",
5
5
  "keywords": [
6
6
  "lgpd",