react-lgpd-consent 0.1.4 → 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,286 +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
- acceptAll,
241
- rejectAll,
242
- setPreference,
243
- openPreferences,
244
- closePreferences,
245
- resetConsent
246
- };
247
- }, [state, cookie]);
248
- 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 }) }) }) });
249
- }
250
- function useConsentStateInternal() {
251
- const ctx = React.useContext(StateCtx);
252
- if (!ctx)
253
- throw new Error("useConsentState must be used within ConsentProvider");
254
- return ctx;
255
- }
256
- function useConsentActionsInternal() {
257
- const ctx = React.useContext(ActionsCtx);
258
- if (!ctx)
259
- throw new Error("useConsentActions must be used within ConsentProvider");
260
- return ctx;
261
- }
262
- function useConsentTextsInternal() {
263
- const ctx = React.useContext(TextsCtx);
264
- return ctx;
265
- }
266
-
267
- // src/hooks/useConsent.ts
268
- function useConsent() {
269
- const state = useConsentStateInternal();
270
- const actions = useConsentActionsInternal();
271
- return {
272
- consented: state.consented,
273
- preferences: state.preferences,
274
- isModalOpen: state.isModalOpen,
275
- acceptAll: actions.acceptAll,
276
- rejectAll: actions.rejectAll,
277
- setPreference: actions.setPreference,
278
- openPreferences: actions.openPreferences,
279
- closePreferences: actions.closePreferences,
280
- resetConsent: actions.resetConsent
281
- };
282
- }
283
- function useConsentTexts() {
284
- return useConsentTextsInternal();
285
- }
286
-
287
- // src/components/CookieBanner.tsx
288
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
17
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
289
18
  function CookieBanner({
290
19
  policyLinkUrl,
291
20
  debug,
@@ -298,7 +27,7 @@ function CookieBanner({
298
27
  const texts = useConsentTexts();
299
28
  const open = debug ? true : !consented;
300
29
  if (!open) return null;
301
- const bannerContent = /* @__PURE__ */ jsx2(
30
+ const bannerContent = /* @__PURE__ */ jsx(
302
31
  Paper,
303
32
  {
304
33
  elevation: 3,
@@ -308,7 +37,7 @@ function CookieBanner({
308
37
  /* @__PURE__ */ jsxs(Typography, { variant: "body2", children: [
309
38
  texts.bannerMessage,
310
39
  " ",
311
- policyLinkUrl && /* @__PURE__ */ jsx2(
40
+ policyLinkUrl && /* @__PURE__ */ jsx(
312
41
  Link,
313
42
  {
314
43
  href: policyLinkUrl,
@@ -326,9 +55,9 @@ function CookieBanner({
326
55
  spacing: 1,
327
56
  justifyContent: "flex-end",
328
57
  children: [
329
- /* @__PURE__ */ jsx2(Button, { variant: "outlined", onClick: rejectAll, children: texts.declineAll }),
330
- /* @__PURE__ */ jsx2(Button, { variant: "contained", onClick: acceptAll, children: texts.acceptAll }),
331
- /* @__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 })
332
61
  ]
333
62
  }
334
63
  )
@@ -336,28 +65,40 @@ function CookieBanner({
336
65
  }
337
66
  );
338
67
  if (blocking) {
339
- return /* @__PURE__ */ jsx2(
340
- Box,
341
- {
342
- sx: {
343
- position: "fixed",
344
- top: 0,
345
- left: 0,
346
- right: 0,
347
- bottom: 0,
348
- backgroundColor: "rgba(0, 0, 0, 0.5)",
349
- display: "flex",
350
- alignItems: "center",
351
- justifyContent: "center",
352
- zIndex: 1300,
353
- // Above MUI Modal
354
- p: 2
355
- },
356
- children: bannerContent
357
- }
358
- );
68
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
69
+ /* @__PURE__ */ jsx(
70
+ Box,
71
+ {
72
+ sx: {
73
+ position: "fixed",
74
+ top: 0,
75
+ left: 0,
76
+ right: 0,
77
+ bottom: 0,
78
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
79
+ zIndex: 1299
80
+ // Abaixo do banner mas acima do conteúdo
81
+ }
82
+ }
83
+ ),
84
+ /* @__PURE__ */ jsx(
85
+ Box,
86
+ {
87
+ sx: {
88
+ position: "fixed",
89
+ bottom: 0,
90
+ left: 0,
91
+ right: 0,
92
+ zIndex: 1300,
93
+ // Acima do overlay
94
+ p: 2
95
+ },
96
+ children: bannerContent
97
+ }
98
+ )
99
+ ] });
359
100
  }
360
- return /* @__PURE__ */ jsx2(
101
+ return /* @__PURE__ */ jsx(
361
102
  Snackbar,
362
103
  {
363
104
  open,
@@ -368,113 +109,48 @@ function CookieBanner({
368
109
  );
369
110
  }
370
111
 
371
- // src/components/PreferencesModal.tsx
372
- import Button2 from "@mui/material/Button";
373
- import Dialog from "@mui/material/Dialog";
374
- import DialogActions from "@mui/material/DialogActions";
375
- import DialogContent from "@mui/material/DialogContent";
376
- import DialogTitle from "@mui/material/DialogTitle";
377
- import FormControlLabel from "@mui/material/FormControlLabel";
378
- import FormGroup from "@mui/material/FormGroup";
379
- import Switch from "@mui/material/Switch";
380
- import Typography2 from "@mui/material/Typography";
381
- import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
382
- function PreferencesModal({
383
- DialogProps: DialogProps2
384
- }) {
385
- const { preferences, setPreference, closePreferences, isModalOpen } = useConsent();
386
- const texts = useConsentTexts();
387
- const open = DialogProps2?.open ?? isModalOpen ?? false;
388
- return /* @__PURE__ */ jsxs2(
389
- Dialog,
390
- {
391
- "aria-labelledby": "cookie-pref-title",
392
- open,
393
- onClose: closePreferences,
394
- ...DialogProps2,
395
- children: [
396
- /* @__PURE__ */ jsx3(DialogTitle, { id: "cookie-pref-title", children: texts.modalTitle }),
397
- /* @__PURE__ */ jsxs2(DialogContent, { dividers: true, children: [
398
- /* @__PURE__ */ jsx3(Typography2, { variant: "body2", sx: { mb: 2 }, children: texts.modalIntro }),
399
- /* @__PURE__ */ jsxs2(FormGroup, { children: [
400
- /* @__PURE__ */ jsx3(
401
- FormControlLabel,
402
- {
403
- control: /* @__PURE__ */ jsx3(
404
- Switch,
405
- {
406
- checked: preferences.analytics,
407
- onChange: (e) => setPreference("analytics", e.target.checked)
408
- }
409
- ),
410
- label: "Cookies Anal\xEDticos (medem uso do site)"
411
- }
412
- ),
413
- /* @__PURE__ */ jsx3(
414
- FormControlLabel,
415
- {
416
- control: /* @__PURE__ */ jsx3(
417
- Switch,
418
- {
419
- checked: preferences.marketing,
420
- onChange: (e) => setPreference("marketing", e.target.checked)
421
- }
422
- ),
423
- label: "Cookies de Marketing/Publicidade"
424
- }
425
- ),
426
- /* @__PURE__ */ jsx3(
427
- FormControlLabel,
428
- {
429
- control: /* @__PURE__ */ jsx3(Switch, { checked: true, disabled: true }),
430
- label: texts.necessaryAlwaysOn
431
- }
432
- )
433
- ] })
434
- ] }),
435
- /* @__PURE__ */ jsx3(DialogActions, { children: /* @__PURE__ */ jsx3(Button2, { variant: "contained", onClick: closePreferences, children: texts.save }) })
436
- ]
437
- }
438
- );
439
- }
440
-
441
112
  // src/utils/ConsentGate.tsx
442
- import { Fragment, jsx as jsx4 } from "react/jsx-runtime";
113
+ import { Fragment as Fragment2, jsx as jsx2 } from "react/jsx-runtime";
443
114
  function ConsentGate(props) {
444
115
  const { preferences } = useConsent();
445
116
  if (!preferences[props.category]) return null;
446
- return /* @__PURE__ */ jsx4(Fragment, { children: props.children });
117
+ return /* @__PURE__ */ jsx2(Fragment2, { children: props.children });
447
118
  }
448
119
 
449
120
  // src/utils/scriptLoader.ts
450
- function loadScript(id, src, attrs = {}) {
451
- if (typeof document === "undefined") return;
452
- if (document.getElementById(id)) return;
453
- const s = document.createElement("script");
454
- s.id = id;
455
- s.src = src;
456
- s.async = true;
457
- for (const [k, v] of Object.entries(attrs)) s.setAttribute(k, v);
458
- document.body.appendChild(s);
459
- }
460
- function loadConditionalScript(id, src, condition, attrs = {}, maxWaitMs = 5e3) {
121
+ function loadScript(id, src, category = null, attrs = {}) {
461
122
  if (typeof document === "undefined") return Promise.resolve();
462
123
  if (document.getElementById(id)) return Promise.resolve();
463
124
  return new Promise((resolve, reject) => {
464
- const startTime = Date.now();
465
- const checkCondition = () => {
466
- if (condition()) {
467
- loadScript(id, src, attrs);
468
- resolve();
469
- } else if (Date.now() - startTime > maxWaitMs) {
470
- reject(
471
- new Error(`Timeout waiting for consent condition for script ${id}`)
472
- );
473
- } else {
474
- 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);
475
151
  }
476
152
  };
477
- checkCondition();
153
+ checkConsent();
478
154
  });
479
155
  }
480
156
  export {
@@ -483,7 +159,6 @@ export {
483
159
  CookieBanner,
484
160
  PreferencesModal,
485
161
  defaultConsentTheme,
486
- loadConditionalScript,
487
162
  loadScript,
488
163
  useConsent,
489
164
  useConsentTexts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-lgpd-consent",
3
- "version": "0.1.4",
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",