@react-lgpd-consent/mui 0.6.3 → 0.7.1
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/README.md +40 -1
- package/dist/index.cjs +39 -10
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +39 -10
- package/dist/ui.cjs +617 -0
- package/dist/ui.d.cts +9 -0
- package/dist/ui.d.ts +9 -0
- package/dist/ui.js +572 -0
- package/package.json +10 -5
package/README.md
CHANGED
|
@@ -28,6 +28,12 @@ pnpm add @react-lgpd-consent/mui @mui/material @mui/icons-material
|
|
|
28
28
|
- `@mui/icons-material@^7.0.0 || ^6.0.0 || ^5.15.0` (opcional)
|
|
29
29
|
- `react@^18.2.0 || ^19.0.0`, `react-dom@^18.2.0 || ^19.0.0`
|
|
30
30
|
|
|
31
|
+
### Entradas de importação (evite ambiguidades)
|
|
32
|
+
|
|
33
|
+
- `@react-lgpd-consent/mui/ui`: **apenas UI** (ConsentProvider MUI + componentes). Ideal para bundles menores e sem re-export do core.
|
|
34
|
+
- `@react-lgpd-consent/mui`: compatibilidade total (re-exporta o core); use `headless` ou `ConsentProviderHeadless` daqui se precisar da lógica.
|
|
35
|
+
- `@react-lgpd-consent/core`: headless puro, recomendado para hooks/utils na sua própria UI.
|
|
36
|
+
|
|
31
37
|
## 🚀 Uso Básico
|
|
32
38
|
|
|
33
39
|
```tsx
|
|
@@ -70,6 +76,40 @@ function App() {
|
|
|
70
76
|
}
|
|
71
77
|
```
|
|
72
78
|
|
|
79
|
+
## 🆕 Novidades v0.7.0
|
|
80
|
+
|
|
81
|
+
### Callbacks de Lifecycle
|
|
82
|
+
|
|
83
|
+
Monitore eventos para auditoria:
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
import { ConsentProvider } from '@react-lgpd-consent/mui'
|
|
87
|
+
|
|
88
|
+
<ConsentProvider
|
|
89
|
+
onConsentInit={(state) => console.log('Inicializado:', state)}
|
|
90
|
+
onConsentChange={(current, prev) => console.log('Mudou:', current)}
|
|
91
|
+
onAuditLog={(entry) => {
|
|
92
|
+
fetch('/api/audit', { method: 'POST', body: JSON.stringify(entry) })
|
|
93
|
+
}}
|
|
94
|
+
>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Presets ANPD
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
import { createAnpdCategories } from '@react-lgpd-consent/mui'
|
|
101
|
+
|
|
102
|
+
const categories = createAnpdCategories({
|
|
103
|
+
include: ['analytics', 'marketing']
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
<ConsentProvider categories={categories}>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
📖 **Documentação completa:** [API.md](../react-lgpd-consent/API.md) | [TROUBLESHOOTING.md](../../TROUBLESHOOTING.md)
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
73
113
|
### Uso Headless (Avançado)
|
|
74
114
|
|
|
75
115
|
Se você quiser controle total sobre a UI:
|
|
@@ -135,4 +175,3 @@ function CustomUI() {
|
|
|
135
175
|
## 📄 Licença
|
|
136
176
|
|
|
137
177
|
MIT © [Luciano Édipo](https://github.com/lucianoedipo)
|
|
138
|
-
|
package/dist/index.cjs
CHANGED
|
@@ -42,6 +42,7 @@ function _interopNamespace(e) {
|
|
|
42
42
|
return Object.freeze(n);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
var core__namespace = /*#__PURE__*/_interopNamespace(core);
|
|
45
46
|
var Link__default = /*#__PURE__*/_interopDefault(Link);
|
|
46
47
|
var Typography__default = /*#__PURE__*/_interopDefault(Typography);
|
|
47
48
|
var React3__namespace = /*#__PURE__*/_interopNamespace(React3);
|
|
@@ -211,15 +212,16 @@ function CookieBanner({
|
|
|
211
212
|
] }),
|
|
212
213
|
!hideBranding && /* @__PURE__ */ jsxRuntime.jsx(Branding, { variant: "banner" })
|
|
213
214
|
] }) });
|
|
214
|
-
const
|
|
215
|
+
const resolveBannerZIndex = (theme) => designTokens?.layout?.zIndex?.banner ?? theme?.zIndex?.snackbar ?? 1400;
|
|
216
|
+
const positionStyle = (theme) => ({
|
|
215
217
|
position: "fixed",
|
|
216
|
-
zIndex:
|
|
218
|
+
zIndex: resolveBannerZIndex(theme),
|
|
217
219
|
...designTokens?.layout?.position === "top" ? { top: 0 } : { bottom: 0 },
|
|
218
220
|
left: 0,
|
|
219
221
|
right: 0,
|
|
220
222
|
width: designTokens?.layout?.width?.desktop ?? "100%",
|
|
221
223
|
p: 2
|
|
222
|
-
};
|
|
224
|
+
});
|
|
223
225
|
const backdropToken = designTokens?.layout?.backdrop;
|
|
224
226
|
const resolveBackdropColor = (theme) => {
|
|
225
227
|
if (backdropToken === false) return "transparent";
|
|
@@ -235,8 +237,8 @@ function CookieBanner({
|
|
|
235
237
|
};
|
|
236
238
|
const isSafeRoute = (() => {
|
|
237
239
|
try {
|
|
238
|
-
if (
|
|
239
|
-
const current = new URL(window.location.href);
|
|
240
|
+
if (globalThis?.window === void 0) return false;
|
|
241
|
+
const current = new URL(globalThis.window.location.href);
|
|
240
242
|
const safeUrls = [policyLinkUrl, termsLinkUrl].filter(Boolean);
|
|
241
243
|
return safeUrls.some((u) => {
|
|
242
244
|
try {
|
|
@@ -263,12 +265,12 @@ function CookieBanner({
|
|
|
263
265
|
right: 0,
|
|
264
266
|
bottom: 0,
|
|
265
267
|
backgroundColor: resolveBackdropColor(theme),
|
|
266
|
-
zIndex: 1299
|
|
268
|
+
zIndex: designTokens?.layout?.zIndex?.backdrop ?? (resolveBannerZIndex(theme) ? resolveBannerZIndex(theme) - 1 : 1299)
|
|
267
269
|
}),
|
|
268
270
|
"data-testid": "lgpd-cookie-banner-overlay"
|
|
269
271
|
}
|
|
270
272
|
),
|
|
271
|
-
/* @__PURE__ */ jsxRuntime.jsx(Box2__default.default, { sx: positionStyle, children: bannerContent })
|
|
273
|
+
/* @__PURE__ */ jsxRuntime.jsx(Box2__default.default, { sx: positionStyle, "data-testid": "lgpd-cookie-banner-wrapper", children: bannerContent })
|
|
272
274
|
] });
|
|
273
275
|
}
|
|
274
276
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -401,7 +403,8 @@ function PreferencesModal({
|
|
|
401
403
|
});
|
|
402
404
|
}
|
|
403
405
|
}, [isModalOpen, getInitialPreferences]);
|
|
404
|
-
const open = DialogProps2
|
|
406
|
+
const { open: dialogOpenProp, ...dialogRest } = DialogProps2 ?? {};
|
|
407
|
+
const open = dialogOpenProp ?? isModalOpen ?? false;
|
|
405
408
|
const handleSave = () => {
|
|
406
409
|
setPreferences(tempPreferences);
|
|
407
410
|
};
|
|
@@ -418,7 +421,32 @@ function PreferencesModal({
|
|
|
418
421
|
backgroundColor: designTokens?.colors?.background ?? theme.palette.background.paper,
|
|
419
422
|
color: designTokens?.colors?.text ?? theme.palette.text.primary
|
|
420
423
|
});
|
|
421
|
-
|
|
424
|
+
const resolveModalZIndex = React3__namespace.useCallback(
|
|
425
|
+
(theme) => designTokens?.layout?.zIndex?.modal ?? (theme?.zIndex?.modal ?? 1300) + 10,
|
|
426
|
+
[designTokens?.layout?.zIndex?.modal]
|
|
427
|
+
);
|
|
428
|
+
const modalZIndexToken = designTokens?.layout?.zIndex?.modal;
|
|
429
|
+
const rootSx = [
|
|
430
|
+
DialogProps2?.slotProps?.root && DialogProps2.slotProps.root.sx,
|
|
431
|
+
(theme) => ({ zIndex: resolveModalZIndex(theme) })
|
|
432
|
+
].filter(Boolean);
|
|
433
|
+
const rootSlotProps = {
|
|
434
|
+
...dialogRest?.slotProps?.root,
|
|
435
|
+
sx: rootSx,
|
|
436
|
+
...modalZIndexToken ? { style: { zIndex: modalZIndexToken } } : {},
|
|
437
|
+
"data-testid": dialogRest?.slotProps?.root?.["data-testid"] ?? "lgpd-preferences-modal-root"
|
|
438
|
+
};
|
|
439
|
+
const mergedDialogProps = {
|
|
440
|
+
open,
|
|
441
|
+
fullWidth: true,
|
|
442
|
+
maxWidth: "sm",
|
|
443
|
+
...dialogRest,
|
|
444
|
+
slotProps: {
|
|
445
|
+
...dialogRest?.slotProps,
|
|
446
|
+
root: rootSlotProps
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Dialog__default.default, { "aria-labelledby": "cookie-pref-title", onClose: handleCancel, ...mergedDialogProps, children: [
|
|
422
450
|
/* @__PURE__ */ jsxRuntime.jsx(DialogTitle__default.default, { id: "cookie-pref-title", sx: modalTitleSx, children: texts.modalTitle }),
|
|
423
451
|
/* @__PURE__ */ jsxRuntime.jsxs(DialogContent__default.default, { dividers: true, sx: modalContentSx, children: [
|
|
424
452
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -452,7 +480,7 @@ function PreferencesModal({
|
|
|
452
480
|
});
|
|
453
481
|
const merged = [
|
|
454
482
|
...enrichedDescriptors,
|
|
455
|
-
...namesFromGuidance.filter((n) => !enrichedDescriptors.
|
|
483
|
+
...namesFromGuidance.filter((n) => !enrichedDescriptors.some((d) => d.name === n)).map((n) => ({ name: n, purpose: "-", duration: "-", provider: "-" }))
|
|
456
484
|
];
|
|
457
485
|
let mergedFinal = merged;
|
|
458
486
|
try {
|
|
@@ -587,6 +615,7 @@ Object.defineProperty(exports, "ConsentProviderHeadless", {
|
|
|
587
615
|
enumerable: true,
|
|
588
616
|
get: function () { return core.ConsentProvider; }
|
|
589
617
|
});
|
|
618
|
+
exports.headless = core__namespace;
|
|
590
619
|
exports.Branding = Branding;
|
|
591
620
|
exports.ConsentProvider = ConsentProvider;
|
|
592
621
|
exports.CookieBanner = CookieBanner;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { ConsentProviderProps as ConsentProviderProps$1, ConsentPreferences } from '@react-lgpd-consent/core';
|
|
2
2
|
export * from '@react-lgpd-consent/core';
|
|
3
|
+
import * as core from '@react-lgpd-consent/core';
|
|
4
|
+
export { core as headless };
|
|
3
5
|
export { ConsentProvider as ConsentProviderHeadless } from '@react-lgpd-consent/core';
|
|
4
6
|
import * as React from 'react';
|
|
5
7
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
@@ -468,7 +470,7 @@ interface ConsentProviderProps extends ConsentProviderProps$1 {
|
|
|
468
470
|
* @see {@link FloatingPreferencesButton} Para o botão flutuante usado por padrão
|
|
469
471
|
* @see {@link https://mui.com/material-ui/customization/theming/ | MUI Theming Guide} Para customização de tema
|
|
470
472
|
*/
|
|
471
|
-
declare function ConsentProvider({ disableDefaultModal, disableDefaultBanner, disableDefaultFloatingButton, PreferencesModalComponent, CookieBannerComponent, FloatingPreferencesButtonComponent, theme, hideBranding, cookieBannerProps, preferencesModalProps, floatingPreferencesButtonProps, children, ...coreProps }: ConsentProviderProps): react_jsx_runtime.JSX.Element;
|
|
473
|
+
declare function ConsentProvider({ disableDefaultModal, disableDefaultBanner, disableDefaultFloatingButton, PreferencesModalComponent, CookieBannerComponent, FloatingPreferencesButtonComponent, theme, hideBranding, cookieBannerProps, preferencesModalProps, floatingPreferencesButtonProps, children, ...coreProps }: Readonly<ConsentProviderProps>): react_jsx_runtime.JSX.Element;
|
|
472
474
|
declare namespace ConsentProvider {
|
|
473
475
|
var displayName: string;
|
|
474
476
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { ConsentProviderProps as ConsentProviderProps$1, ConsentPreferences } from '@react-lgpd-consent/core';
|
|
2
2
|
export * from '@react-lgpd-consent/core';
|
|
3
|
+
import * as core from '@react-lgpd-consent/core';
|
|
4
|
+
export { core as headless };
|
|
3
5
|
export { ConsentProvider as ConsentProviderHeadless } from '@react-lgpd-consent/core';
|
|
4
6
|
import * as React from 'react';
|
|
5
7
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
@@ -468,7 +470,7 @@ interface ConsentProviderProps extends ConsentProviderProps$1 {
|
|
|
468
470
|
* @see {@link FloatingPreferencesButton} Para o botão flutuante usado por padrão
|
|
469
471
|
* @see {@link https://mui.com/material-ui/customization/theming/ | MUI Theming Guide} Para customização de tema
|
|
470
472
|
*/
|
|
471
|
-
declare function ConsentProvider({ disableDefaultModal, disableDefaultBanner, disableDefaultFloatingButton, PreferencesModalComponent, CookieBannerComponent, FloatingPreferencesButtonComponent, theme, hideBranding, cookieBannerProps, preferencesModalProps, floatingPreferencesButtonProps, children, ...coreProps }: ConsentProviderProps): react_jsx_runtime.JSX.Element;
|
|
473
|
+
declare function ConsentProvider({ disableDefaultModal, disableDefaultBanner, disableDefaultFloatingButton, PreferencesModalComponent, CookieBannerComponent, FloatingPreferencesButtonComponent, theme, hideBranding, cookieBannerProps, preferencesModalProps, floatingPreferencesButtonProps, children, ...coreProps }: Readonly<ConsentProviderProps>): react_jsx_runtime.JSX.Element;
|
|
472
474
|
declare namespace ConsentProvider {
|
|
473
475
|
var displayName: string;
|
|
474
476
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { useConsentTexts, useDesignTokens, useConsent, logger, useConsentHydration, useCategories, getCookiesInfoForCategory, ConsentProvider as ConsentProvider$1 } from '@react-lgpd-consent/core';
|
|
2
2
|
export * from '@react-lgpd-consent/core';
|
|
3
|
+
import * as core from '@react-lgpd-consent/core';
|
|
4
|
+
export { core as headless };
|
|
3
5
|
export { ConsentProvider as ConsentProviderHeadless } from '@react-lgpd-consent/core';
|
|
4
6
|
import Link from '@mui/material/Link';
|
|
5
7
|
import Typography from '@mui/material/Typography';
|
|
@@ -172,15 +174,16 @@ function CookieBanner({
|
|
|
172
174
|
] }),
|
|
173
175
|
!hideBranding && /* @__PURE__ */ jsx(Branding, { variant: "banner" })
|
|
174
176
|
] }) });
|
|
175
|
-
const
|
|
177
|
+
const resolveBannerZIndex = (theme) => designTokens?.layout?.zIndex?.banner ?? theme?.zIndex?.snackbar ?? 1400;
|
|
178
|
+
const positionStyle = (theme) => ({
|
|
176
179
|
position: "fixed",
|
|
177
|
-
zIndex:
|
|
180
|
+
zIndex: resolveBannerZIndex(theme),
|
|
178
181
|
...designTokens?.layout?.position === "top" ? { top: 0 } : { bottom: 0 },
|
|
179
182
|
left: 0,
|
|
180
183
|
right: 0,
|
|
181
184
|
width: designTokens?.layout?.width?.desktop ?? "100%",
|
|
182
185
|
p: 2
|
|
183
|
-
};
|
|
186
|
+
});
|
|
184
187
|
const backdropToken = designTokens?.layout?.backdrop;
|
|
185
188
|
const resolveBackdropColor = (theme) => {
|
|
186
189
|
if (backdropToken === false) return "transparent";
|
|
@@ -196,8 +199,8 @@ function CookieBanner({
|
|
|
196
199
|
};
|
|
197
200
|
const isSafeRoute = (() => {
|
|
198
201
|
try {
|
|
199
|
-
if (
|
|
200
|
-
const current = new URL(window.location.href);
|
|
202
|
+
if (globalThis?.window === void 0) return false;
|
|
203
|
+
const current = new URL(globalThis.window.location.href);
|
|
201
204
|
const safeUrls = [policyLinkUrl, termsLinkUrl].filter(Boolean);
|
|
202
205
|
return safeUrls.some((u) => {
|
|
203
206
|
try {
|
|
@@ -224,12 +227,12 @@ function CookieBanner({
|
|
|
224
227
|
right: 0,
|
|
225
228
|
bottom: 0,
|
|
226
229
|
backgroundColor: resolveBackdropColor(theme),
|
|
227
|
-
zIndex: 1299
|
|
230
|
+
zIndex: designTokens?.layout?.zIndex?.backdrop ?? (resolveBannerZIndex(theme) ? resolveBannerZIndex(theme) - 1 : 1299)
|
|
228
231
|
}),
|
|
229
232
|
"data-testid": "lgpd-cookie-banner-overlay"
|
|
230
233
|
}
|
|
231
234
|
),
|
|
232
|
-
/* @__PURE__ */ jsx(Box2, { sx: positionStyle, children: bannerContent })
|
|
235
|
+
/* @__PURE__ */ jsx(Box2, { sx: positionStyle, "data-testid": "lgpd-cookie-banner-wrapper", children: bannerContent })
|
|
233
236
|
] });
|
|
234
237
|
}
|
|
235
238
|
return /* @__PURE__ */ jsx(
|
|
@@ -362,7 +365,8 @@ function PreferencesModal({
|
|
|
362
365
|
});
|
|
363
366
|
}
|
|
364
367
|
}, [isModalOpen, getInitialPreferences]);
|
|
365
|
-
const open = DialogProps2
|
|
368
|
+
const { open: dialogOpenProp, ...dialogRest } = DialogProps2 ?? {};
|
|
369
|
+
const open = dialogOpenProp ?? isModalOpen ?? false;
|
|
366
370
|
const handleSave = () => {
|
|
367
371
|
setPreferences(tempPreferences);
|
|
368
372
|
};
|
|
@@ -379,7 +383,32 @@ function PreferencesModal({
|
|
|
379
383
|
backgroundColor: designTokens?.colors?.background ?? theme.palette.background.paper,
|
|
380
384
|
color: designTokens?.colors?.text ?? theme.palette.text.primary
|
|
381
385
|
});
|
|
382
|
-
|
|
386
|
+
const resolveModalZIndex = React3.useCallback(
|
|
387
|
+
(theme) => designTokens?.layout?.zIndex?.modal ?? (theme?.zIndex?.modal ?? 1300) + 10,
|
|
388
|
+
[designTokens?.layout?.zIndex?.modal]
|
|
389
|
+
);
|
|
390
|
+
const modalZIndexToken = designTokens?.layout?.zIndex?.modal;
|
|
391
|
+
const rootSx = [
|
|
392
|
+
DialogProps2?.slotProps?.root && DialogProps2.slotProps.root.sx,
|
|
393
|
+
(theme) => ({ zIndex: resolveModalZIndex(theme) })
|
|
394
|
+
].filter(Boolean);
|
|
395
|
+
const rootSlotProps = {
|
|
396
|
+
...dialogRest?.slotProps?.root,
|
|
397
|
+
sx: rootSx,
|
|
398
|
+
...modalZIndexToken ? { style: { zIndex: modalZIndexToken } } : {},
|
|
399
|
+
"data-testid": dialogRest?.slotProps?.root?.["data-testid"] ?? "lgpd-preferences-modal-root"
|
|
400
|
+
};
|
|
401
|
+
const mergedDialogProps = {
|
|
402
|
+
open,
|
|
403
|
+
fullWidth: true,
|
|
404
|
+
maxWidth: "sm",
|
|
405
|
+
...dialogRest,
|
|
406
|
+
slotProps: {
|
|
407
|
+
...dialogRest?.slotProps,
|
|
408
|
+
root: rootSlotProps
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
return /* @__PURE__ */ jsxs(Dialog, { "aria-labelledby": "cookie-pref-title", onClose: handleCancel, ...mergedDialogProps, children: [
|
|
383
412
|
/* @__PURE__ */ jsx(DialogTitle, { id: "cookie-pref-title", sx: modalTitleSx, children: texts.modalTitle }),
|
|
384
413
|
/* @__PURE__ */ jsxs(DialogContent, { dividers: true, sx: modalContentSx, children: [
|
|
385
414
|
/* @__PURE__ */ jsx(
|
|
@@ -413,7 +442,7 @@ function PreferencesModal({
|
|
|
413
442
|
});
|
|
414
443
|
const merged = [
|
|
415
444
|
...enrichedDescriptors,
|
|
416
|
-
...namesFromGuidance.filter((n) => !enrichedDescriptors.
|
|
445
|
+
...namesFromGuidance.filter((n) => !enrichedDescriptors.some((d) => d.name === n)).map((n) => ({ name: n, purpose: "-", duration: "-", provider: "-" }))
|
|
417
446
|
];
|
|
418
447
|
let mergedFinal = merged;
|
|
419
448
|
try {
|