@tantainnovative/ndpr-toolkit 5.5.1 → 5.7.0
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/CHANGELOG.md +28 -0
- package/README.md +36 -0
- package/dist/{chunk-C77CRJLD.mjs → chunk-2T5MY2Q6.mjs} +1 -1
- package/dist/chunk-7PV64WEZ.js +1 -0
- package/dist/{chunk-VTBHDHYK.js → chunk-NTEYQLYM.js} +1 -1
- package/dist/chunk-PEUAA5EC.js +1 -0
- package/dist/chunk-PYSYBUIV.mjs +1 -0
- package/dist/chunk-QNXLY5EJ.mjs +1 -0
- package/dist/chunk-YMKN3YQL.js +1 -0
- package/dist/chunk-ZY4RCV5C.mjs +1 -0
- package/dist/consent.d.mts +114 -0
- package/dist/consent.d.ts +114 -0
- package/dist/consent.js +1 -1
- package/dist/consent.mjs +1 -1
- package/dist/core.d.mts +88 -0
- package/dist/core.d.ts +88 -0
- package/dist/core.js +1 -1
- package/dist/core.mjs +1 -1
- package/dist/headless.d.mts +163 -0
- package/dist/headless.d.ts +163 -0
- package/dist/headless.js +1 -1
- package/dist/headless.mjs +1 -1
- package/dist/hooks.d.mts +90 -0
- package/dist/hooks.d.ts +90 -0
- package/dist/hooks.js +1 -1
- package/dist/hooks.mjs +1 -1
- package/dist/index.d.mts +131 -0
- package/dist/index.d.ts +131 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/presets-consent.d.mts +2 -0
- package/dist/presets-consent.d.ts +2 -0
- package/dist/presets-consent.js +1 -1
- package/dist/presets-consent.mjs +1 -1
- package/dist/presets.d.mts +2 -0
- package/dist/presets.d.ts +2 -0
- package/dist/presets.js +1 -1
- package/dist/presets.mjs +1 -1
- package/dist/server.d.mts +88 -0
- package/dist/server.d.ts +88 -0
- package/dist/server.js +1 -1
- package/dist/server.mjs +1 -1
- package/dist/unstyled.d.mts +64 -0
- package/dist/unstyled.d.ts +64 -0
- package/dist/unstyled.js +1 -1
- package/dist/unstyled.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-HMKXK23C.mjs +0 -1
- package/dist/chunk-L2VO3MEJ.js +0 -1
- package/dist/chunk-PXUX4FYM.js +0 -1
- package/dist/chunk-YTU4FNM2.mjs +0 -1
- /package/dist/{chunk-YQTZWPOS.mjs → chunk-23CULZBM.mjs} +0 -0
- /package/dist/{chunk-OVW5ASY3.js → chunk-VKDW2IHV.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [5.7.0](https://github.com/mr-tanta/ndpr-toolkit/compare/v5.6.0...v5.7.0) (2026-06-02)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **consent:** surface the cookie scanner in ConsentBanner ([cdafcd8](https://github.com/mr-tanta/ndpr-toolkit/commit/cdafcd89179302d8c7c95dd0e2797df7faf1a6ea))
|
|
11
|
+
|
|
12
|
+
## [5.6.0](https://github.com/mr-tanta/ndpr-toolkit/compare/v5.5.1...v5.6.0) (2026-06-01)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* **consent:** add cookie scanner (declared vs present audit) ([d74366f](https://github.com/mr-tanta/ndpr-toolkit/commit/d74366f8356857621a94729eb79225cdfbef2024))
|
|
18
|
+
* **packages:** refresh create-ndpr and ndpr-recipes for GAID 2025 ([bf709cf](https://github.com/mr-tanta/ndpr-toolkit/commit/bf709cf4f40176e65f21f2db61a946542fac7479))
|
|
19
|
+
* **site:** make the /score audit a full-screen cinematic experience ([52cc0e8](https://github.com/mr-tanta/ndpr-toolkit/commit/52cc0e8b6b889df0ca6c1842a71d25029f4e4aaa))
|
|
20
|
+
* **site:** turn the /score audit into a guided step-by-step wizard ([18f26ad](https://github.com/mr-tanta/ndpr-toolkit/commit/18f26ad36726f4b3ef9228e032e3d60eb4de1786))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
* **packages:** use canonical bin path (no ./ prefix) in create-ndpr manifests ([600d989](https://github.com/mr-tanta/ndpr-toolkit/commit/600d989f1f73fe5174f4d3fc035980bfa6c8fa27))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Documentation
|
|
29
|
+
|
|
30
|
+
* **marketing:** refresh the X thread + LinkedIn post for current state ([58c6fca](https://github.com/mr-tanta/ndpr-toolkit/commit/58c6fca46899765bf3a09eee5cc0fca387f6cd99))
|
|
31
|
+
* **site:** add Cookie Scanner guide page ([5813686](https://github.com/mr-tanta/ndpr-toolkit/commit/58136865de16e9f1f8b74c7918294fdcd0c5b78f))
|
|
32
|
+
|
|
5
33
|
## [5.5.1](https://github.com/mr-tanta/ndpr-toolkit/compare/v5.5.0...v5.5.1) (2026-05-31)
|
|
6
34
|
|
|
7
35
|
|
package/README.md
CHANGED
|
@@ -536,6 +536,42 @@ The content checklist (`notificationToCommission`) maps each item to its source
|
|
|
536
536
|
|
|
537
537
|
---
|
|
538
538
|
|
|
539
|
+
## Cookie Scanner
|
|
540
|
+
|
|
541
|
+
`scanCookies()` audits the cookies **actually present** against the cookies you've **declared**, surfacing undeclared cookies that put you out of step with your cookie notice (**NDPA 2023 S.25–26** / **NDPC GAID 2025** — consent must be specific and informed). It's pure and DOM-optional: pass a `cookieString` (a `Cookie:` header server-side, or a fixture) or let it read `document.cookie` in the browser.
|
|
542
|
+
|
|
543
|
+
```ts
|
|
544
|
+
import { scanCookies } from '@tantainnovative/ndpr-toolkit/core'; // or /server
|
|
545
|
+
|
|
546
|
+
const scan = scanCookies(
|
|
547
|
+
[{ name: 'sid', category: 'necessary', provider: 'App', purpose: 'Login session' }],
|
|
548
|
+
{ cookieString: document.cookie }, // omit in the browser to read it automatically
|
|
549
|
+
);
|
|
550
|
+
|
|
551
|
+
scan.complete; // false while any undeclared cookie is present
|
|
552
|
+
scan.undeclared; // cookies on the page you didn't declare — the compliance gap
|
|
553
|
+
scan.identified; // undeclared, but the built-in registry knows them (_ga → Google Analytics, …)
|
|
554
|
+
scan.unknown; // undeclared and unidentifiable
|
|
555
|
+
scan.byCategory; // present cookies grouped by resolved category
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
A built-in `KNOWN_COOKIES` registry recognises common third-party cookies (Google Analytics/Ads, Meta, Hotjar, Microsoft Clarity, LinkedIn, Stripe, HubSpot, TikTok, Intercom, …) so even undeclared cookies are usually identified with a provider and likely category; extend it via `knownCookies` or disable it with `useKnownRegistry: false`. Your own declarations always take precedence. Also available as the client-side `useCookieScan(declared?, options?)` hook from `/hooks`, which scans on mount and returns a stable `rescan()`.
|
|
559
|
+
|
|
560
|
+
`ConsentBanner` can surface this directly: pass `showCookieScan` (plus `declaredCookies`) and the customize view renders a "Cookies on this page" panel that flags undeclared cookies live — a transparency/self-audit aid for your visitors and DPO.
|
|
561
|
+
|
|
562
|
+
```tsx
|
|
563
|
+
<ConsentBanner
|
|
564
|
+
options={options}
|
|
565
|
+
onSave={save}
|
|
566
|
+
showCookieScan
|
|
567
|
+
declaredCookies={[{ name: 'sid', category: 'necessary', provider: 'App' }]}
|
|
568
|
+
/>
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
> A compliance-discovery aid, not legal advice — verify against current NDPC guidance.
|
|
572
|
+
|
|
573
|
+
---
|
|
574
|
+
|
|
539
575
|
## Compliance Audit CLI
|
|
540
576
|
|
|
541
577
|
The package ships an `ndpr` binary. `ndpr audit` scores a compliance config against the toolkit's engine — the compliance score plus the GAID 2025 DCPMI, CAR, and breach-notification checks — and **exits non-zero when the audit fails**, so you can drop it into CI as a compliance gate.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import {a}from'./chunk-
|
|
1
|
+
import {a}from'./chunk-PYSYBUIV.mjs';import {jsx}from'react/jsx-runtime';var m=[{id:"essential",label:"Essential Cookies",description:"Required for basic site functionality. Cannot be disabled.",required:true,purpose:"Site operation"},{id:"analytics",label:"Analytics",description:"Help us understand how visitors use our site to improve the experience.",required:false,purpose:"Usage analytics"},{id:"marketing",label:"Marketing",description:"Used to deliver relevant advertisements and track campaign effectiveness.",required:false,purpose:"Targeted advertising"},{id:"preferences",label:"Preferences",description:"Remember your settings and preferences for a personalised experience.",required:false,purpose:"Personalisation"}],g=({options:t,adapter:n,position:a$1="bottom",classNames:o,unstyled:l,onSave:s,copy:e})=>{let d=t!=null?t:m;return jsx(a,{options:d,onSave:i=>{n&&n.save(i),s==null||s(i);},position:a$1,classNames:o,unstyled:l,manageStorage:!n,title:e==null?void 0:e.title,description:e==null?void 0:e.description,acceptAllButtonText:e==null?void 0:e.acceptAll,rejectAllButtonText:e==null?void 0:e.rejectAll,customizeButtonText:e==null?void 0:e.customize,saveButtonText:e==null?void 0:e.save})};export{g as a};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';var chunkYMKN3YQL_js=require('./chunk-YMKN3YQL.js'),chunkAME4HJR4_js=require('./chunk-AME4HJR4.js'),chunkI5ZDNSX5_js=require('./chunk-I5ZDNSX5.js'),chunkRFPLZDIO_js=require('./chunk-RFPLZDIO.js'),react=require('react'),reactDom=require('react-dom'),jsxRuntime=require('react/jsx-runtime');var mn=({options:c,onSave:gn,title:A,description:R,acceptAllButtonText:P,rejectAllButtonText:D,customizeButtonText:x,saveButtonText:E,position:vn="bottom",variant:s="bar",zIndex:J=9999,version:C="1.0",show:_,manageStorage:z=true,storageKey:w="ndpr_consent",className:W="",buttonClassName:L="",primaryButtonClassName:Cn="",secondaryButtonClassName:_n="",classNames:n,unstyled:o,onAnalytics:k,showCookieScan:$=false,declaredCookies:hn,cookieScanOptions:sn,cookieScanTitle:j})=>{var T,N,nn,en,tn,on,rn,dn,cn;let p=chunkI5ZDNSX5_js.c(),kn=(T=A!=null?A:p.consent.title)!=null?T:"We Value Your Privacy",Sn=(N=R!=null?R:p.consent.description)!=null?N:"We use cookies and similar technologies to provide our services and enhance your experience. Your consent is collected in accordance with NDPA Sections 25-26.",yn=(nn=P!=null?P:p.consent.acceptAll)!=null?nn:"Accept All",Bn=(en=D!=null?D:p.consent.rejectAll)!=null?en:"Reject All",An=(tn=x!=null?x:p.consent.customize)!=null?tn:"Customize",Rn=(on=E!=null?E:p.consent.savePreferences)!=null?on:"Save Preferences",Pn=(rn=p.consent.selectAll)!=null?rn:"Select All",Dn=(dn=p.consent.deselectAll)!=null?dn:"Deselect All",xn=j!=null?j:"Cookies on this page",[b,l]=react.useState(false),[u,I]=react.useState(false),{result:h,rescan:Y}=chunkYMKN3YQL_js.b(hn,sn);react.useEffect(()=>{$&&u&&Y();},[$,u,Y]);let[S,y]=react.useState({}),[K,En]=react.useState(false),zn=chunkYMKN3YQL_js.a({active:b}),O=react.useRef(null),q=react.useRef(false);react.useEffect(()=>{En(true);},[]);let f=react.useCallback((e,t)=>{k==null||k(chunkRFPLZDIO_js.a({action:e,timestamp:Date.now(),version:C},t!==void 0?{categories:t}:{}));},[k,C]);react.useEffect(()=>{let e={};if(c.forEach(t=>{e[t.id]=t.defaultValue||false;}),y(e),_===void 0)if(!z)l(true);else {let t=localStorage.getItem(w);if(t)try{JSON.parse(t).version!==C?l(!0):l(!1);}catch(M){l(true);}else l(true);}else l(_);},[c,w,C,z]),react.useEffect(()=>{_!==void 0&&l(_);},[_]);let wn=()=>{let e={};c.forEach(t=>{e[t.id]=true;}),f("accepted_all",e),H(e);},Q=()=>{let e={};c.forEach(t=>{e[t.id]=t.required||false;}),f("rejected_all",e),H(e);},Ln=(e,t)=>{y(M=>chunkRFPLZDIO_js.b(chunkRFPLZDIO_js.a({},M),{[e]:t}));},$n=()=>{let e={};c.forEach(t=>{e[t.id]=true;}),y(e);},jn=()=>{let e={};c.forEach(t=>{e[t.id]=t.required||false;}),y(e);},U=c.length>0&&c.every(e=>S[e.id]),In=()=>{f("customized",S),H(S);},H=e=>{let t={consents:e,timestamp:Date.now(),version:C,method:u?"customize":"banner",hasInteracted:true};z&&localStorage.setItem(w,JSON.stringify(t)),gn(t),l(false),I(false);};if(react.useEffect(()=>{if(!b)return;let e=t=>{t.key==="Escape"&&(f("dismissed"),Q());};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[b,f,c,u]),react.useEffect(()=>{b&&!q.current&&(q.current=true,f("shown")),b||(q.current=false);},[b,f]),react.useEffect(()=>{if(u&&O.current){let e=O.current;e.style.maxHeight="0px",e.style.opacity="0",e.offsetHeight,e.style.maxHeight=`${e.scrollHeight}px`,e.style.opacity="1";}},[u]),!b)return null;let g=s==="modal"?"center":vn,X=g==="inline",F=g==="center",v=["ndpr-consent-banner"];s!=="bar"&&v.push(`ndpr-consent-banner--${s}`),g==="top"?v.push("ndpr-consent-banner--top"):g==="bottom"?v.push("ndpr-consent-banner--bottom"):g==="inline"&&v.push("ndpr-consent-banner--inline"),W&&v.push(W);let On=v.join(" "),Z=`ndpr-consent-banner__button ndpr-consent-banner__button--primary ${L} ${Cn}`.trim(),qn=`ndpr-consent-banner__button ndpr-consent-banner__button--secondary ${L} ${_n}`.trim(),Hn=`ndpr-consent-banner__button ndpr-consent-banner__button--ghost ${L}`.trim(),Fn=(n==null?void 0:n.primaryButton)||(n==null?void 0:n.acceptButton)||Z,m=(n==null?void 0:n.secondaryButton)||(n==null?void 0:n.rejectButton)||qn,Gn=(n==null?void 0:n.customizeButton)||Hn,Mn=(n==null?void 0:n.saveButton)||Z,G=jsxRuntime.jsx("div",{ref:zn,tabIndex:-1,"data-ndpr-component":"consent-banner","data-ndpr-variant":s,"data-ndpr-position":g,className:chunkAME4HJR4_js.a(On,n==null?void 0:n.root,o),style:!X&&!F?{zIndex:J}:void 0,role:"dialog","aria-modal":F||void 0,"aria-labelledby":"consent-banner-title","aria-describedby":"consent-banner-description",children:jsxRuntime.jsxs("div",{className:chunkAME4HJR4_js.a("ndpr-consent-banner__container",n==null?void 0:n.container,o),children:[jsxRuntime.jsx("h2",{id:"consent-banner-title",className:chunkAME4HJR4_js.a("ndpr-consent-banner__title",n==null?void 0:n.title,o),children:kn}),jsxRuntime.jsx("p",{id:"consent-banner-description",className:chunkAME4HJR4_js.a("ndpr-consent-banner__description",n==null?void 0:n.description,o),children:Sn}),u&&jsxRuntime.jsxs("div",{ref:O,className:chunkAME4HJR4_js.a("ndpr-consent-banner__customize-panel",n==null?void 0:n.customizePanel,o),children:[jsxRuntime.jsx("div",{className:o?"":"ndpr-consent-banner__select-all-row",children:jsxRuntime.jsx("button",{type:"button",onClick:U?jn:$n,className:chunkAME4HJR4_js.a("ndpr-consent-banner__select-all-button",n==null?void 0:n.selectAllButton,o),children:U?Dn:Pn})}),jsxRuntime.jsx("div",{className:chunkAME4HJR4_js.a("ndpr-consent-banner__options-list",n==null?void 0:n.optionsList,o),children:c.map(e=>jsxRuntime.jsxs("div",{className:chunkAME4HJR4_js.a("ndpr-consent-banner__option",n==null?void 0:n.optionItem,o),children:[jsxRuntime.jsx("input",{id:`consent-${e.id}`,type:"checkbox",checked:S[e.id]||false,onChange:t=>Ln(e.id,t.target.checked),disabled:e.required,className:chunkAME4HJR4_js.a("ndpr-consent-banner__option-checkbox",n==null?void 0:n.optionCheckbox,o)}),jsxRuntime.jsxs("div",{className:o?"":"ndpr-consent-banner__option-text",children:[jsxRuntime.jsxs("label",{htmlFor:`consent-${e.id}`,className:chunkAME4HJR4_js.a("ndpr-consent-banner__option-label",n==null?void 0:n.optionLabel,o),children:[e.label,e.required&&jsxRuntime.jsx("span",{className:o?"":"ndpr-consent-banner__required-marker",children:" *"})]}),jsxRuntime.jsx("p",{className:chunkAME4HJR4_js.a("ndpr-consent-banner__option-description",n==null?void 0:n.optionDescription,o),children:e.description})]})]},e.id))}),$&&h&&jsxRuntime.jsxs("div",{"data-ndpr-section":"cookie-scan",className:chunkAME4HJR4_js.a("ndpr-alert ndpr-alert--info mb-2",n==null?void 0:n.cookieScanPanel,o),children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between mb-1",children:[jsxRuntime.jsx("h3",{className:"text-sm font-bold ndpr-text-info",children:xn}),jsxRuntime.jsx("span",{className:"text-sm font-semibold ndpr-text-info",children:h.total})]}),h.undeclared.length===0?jsxRuntime.jsx("p",{className:"text-sm ndpr-text-info",children:"All cookies on this page are declared."}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("p",{className:"text-sm ndpr-text-warning",children:[h.undeclared.length," undeclared cookie(s) detected \u2014 review your cookie notice (NDPA S.25-26)."]}),jsxRuntime.jsx("ul",{className:"mt-1 list-disc pl-5",children:h.undeclared.map(e=>jsxRuntime.jsxs("li",{className:"text-xs ndpr-text-muted",children:[jsxRuntime.jsx("code",{children:e.name})," ",jsxRuntime.jsx("span",{className:"opacity-70",children:e.provider?`\u2014 ${e.provider} (${e.category})`:"\u2014 unrecognized"})]},e.name))})]})]}),jsxRuntime.jsxs("div",{className:chunkAME4HJR4_js.a("ndpr-consent-banner__buttons",n==null?void 0:n.buttonGroup,o),children:[jsxRuntime.jsx("button",{onClick:In,className:chunkAME4HJR4_js.a(Mn,n==null?void 0:n.saveButton,o),children:Rn}),jsxRuntime.jsx("button",{onClick:()=>I(false),className:chunkAME4HJR4_js.a(m,n==null?void 0:n.rejectButton,o),children:(cn=p.common.back)!=null?cn:"Back"})]})]}),!u&&jsxRuntime.jsxs("div",{className:chunkAME4HJR4_js.a("ndpr-consent-banner__buttons",n==null?void 0:n.buttonGroup,o),children:[jsxRuntime.jsx("button",{onClick:wn,className:chunkAME4HJR4_js.a(Fn,n==null?void 0:n.acceptButton,o),children:yn}),jsxRuntime.jsx("button",{onClick:Q,className:chunkAME4HJR4_js.a(m,n==null?void 0:n.rejectButton,o),children:Bn}),jsxRuntime.jsx("button",{onClick:()=>I(true),className:chunkAME4HJR4_js.a(Gn,n==null?void 0:n.customizeButton,o),children:An})]}),jsxRuntime.jsx("div",{className:chunkAME4HJR4_js.a("ndpr-consent-banner__footer-text",void 0,o),children:'By clicking "Accept All", you agree to the use of ALL cookies. Visit our Cookie Policy to learn more.'})]})});if(X)return G;if(F){let e=jsxRuntime.jsx("div",{className:o?"":"ndpr-consent-banner__overlay",style:{zIndex:J},children:G});return K?reactDom.createPortal(e,document.body):null}return K?reactDom.createPortal(G,document.body):null};exports.a=mn;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var
|
|
1
|
+
'use strict';var chunk7PV64WEZ_js=require('./chunk-7PV64WEZ.js'),jsxRuntime=require('react/jsx-runtime');var m=[{id:"essential",label:"Essential Cookies",description:"Required for basic site functionality. Cannot be disabled.",required:true,purpose:"Site operation"},{id:"analytics",label:"Analytics",description:"Help us understand how visitors use our site to improve the experience.",required:false,purpose:"Usage analytics"},{id:"marketing",label:"Marketing",description:"Used to deliver relevant advertisements and track campaign effectiveness.",required:false,purpose:"Targeted advertising"},{id:"preferences",label:"Preferences",description:"Remember your settings and preferences for a personalised experience.",required:false,purpose:"Personalisation"}],g=({options:t,adapter:n,position:a="bottom",classNames:o,unstyled:l,onSave:s,copy:e})=>{let d=t!=null?t:m;return jsxRuntime.jsx(chunk7PV64WEZ_js.a,{options:d,onSave:i=>{n&&n.save(i),s==null||s(i);},position:a,classNames:o,unstyled:l,manageStorage:!n,title:e==null?void 0:e.title,description:e==null?void 0:e.description,acceptAllButtonText:e==null?void 0:e.acceptAll,rejectAllButtonText:e==null?void 0:e.rejectAll,customizeButtonText:e==null?void 0:e.customize,saveButtonText:e==null?void 0:e.save})};exports.a=g;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';var C=[{name:"_ga",category:"analytics",provider:"Google Analytics",purpose:"Distinguishes users"},{name:"_ga_",prefix:true,category:"analytics",provider:"Google Analytics (GA4)",purpose:"Persists session state"},{name:"_gid",category:"analytics",provider:"Google Analytics",purpose:"Distinguishes users"},{name:"_gat",prefix:true,category:"analytics",provider:"Google Analytics",purpose:"Throttles request rate"},{name:"_dc_gtm_",prefix:true,category:"analytics",provider:"Google Tag Manager",purpose:"Throttles request rate"},{name:"_gcl_",prefix:true,category:"marketing",provider:"Google Ads",purpose:"Conversion tracking"},{name:"IDE",category:"marketing",provider:"Google DoubleClick",purpose:"Ad targeting"},{name:"test_cookie",category:"marketing",provider:"Google DoubleClick",purpose:"Checks cookie support"},{name:"_fbp",category:"marketing",provider:"Meta (Facebook)",purpose:"Ad delivery and measurement"},{name:"_fbc",category:"marketing",provider:"Meta (Facebook)",purpose:"Click attribution"},{name:"fr",category:"marketing",provider:"Meta (Facebook)",purpose:"Ad delivery and measurement"},{name:"_clck",category:"analytics",provider:"Microsoft Clarity",purpose:"Session analytics"},{name:"_clsk",category:"analytics",provider:"Microsoft Clarity",purpose:"Session analytics"},{name:"_hj",prefix:true,category:"analytics",provider:"Hotjar",purpose:"Behaviour analytics"},{name:"bcookie",category:"marketing",provider:"LinkedIn",purpose:"Browser identification"},{name:"lidc",category:"marketing",provider:"LinkedIn",purpose:"Routing / ad delivery"},{name:"li_",prefix:true,category:"marketing",provider:"LinkedIn",purpose:"Ad delivery"},{name:"_ttp",category:"marketing",provider:"TikTok",purpose:"Ad measurement"},{name:"personalization_id",category:"marketing",provider:"X (Twitter)",purpose:"Ad personalisation"},{name:"guest_id",category:"marketing",provider:"X (Twitter)",purpose:"Identifies the browser"},{name:"hubspotutk",category:"marketing",provider:"HubSpot",purpose:"Visitor identification"},{name:"__hs",prefix:true,category:"analytics",provider:"HubSpot",purpose:"Analytics / session"},{name:"__stripe_mid",category:"necessary",provider:"Stripe",purpose:"Fraud prevention"},{name:"__stripe_sid",category:"necessary",provider:"Stripe",purpose:"Fraud prevention"},{name:"intercom-",prefix:true,category:"functional",provider:"Intercom",purpose:"Live chat / messaging"},{name:"ndpr_consent",category:"necessary",provider:"NDPR Toolkit",purpose:"Stores the consent decision"}];function f(t,r){return r.name instanceof RegExp?r.name.test(t):r.prefix?t.startsWith(r.name):t===r.name}function h(t){return t.split(";").map(r=>{let i=r.trim(),a=i.indexOf("=");return (a===-1?i:i.slice(0,a)).trim()}).filter(r=>r.length>0)}function S(t=[],r={}){var g,u,l,y,m,k;let i=(g=r.cookieString)!=null?g:typeof document!="undefined"?document.cookie:"",a=(u=r.asOf)!=null?u:Date.now(),v=((l=r.useKnownRegistry)!=null?l:true)?[...(y=r.knownCookies)!=null?y:[],...C]:[],n=h(i).map(e=>{let o=t.find(p=>f(e,p));if(o)return {name:e,category:o.category,matchedBy:"declared",provider:o.provider,purpose:o.purpose};let c=v.find(p=>f(e,p));return c?{name:e,category:c.category,matchedBy:"known",provider:c.provider,purpose:c.purpose}:{name:e,category:null,matchedBy:"none"}}),s={};for(let e of n){let o=(m=e.category)!=null?m:"uncategorized";((k=s[o])!=null?k:s[o]=[]).push(e);}let d=n.filter(e=>e.matchedBy!=="declared");return {scannedAt:a,total:n.length,cookies:n,declared:n.filter(e=>e.matchedBy==="declared"),undeclared:d,identified:n.filter(e=>e.matchedBy==="known"),unknown:n.filter(e=>e.matchedBy==="none"),byCategory:s,complete:d.length===0}}exports.a=C;exports.b=S;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import {b,a}from'./chunk-QNXLY5EJ.mjs';import {a as a$2}from'./chunk-SFGW37LE.mjs';import {c}from'./chunk-PHA3YMFO.mjs';import {a as a$1,b as b$1}from'./chunk-ZJYULEER.mjs';import {useState,useEffect,useRef,useCallback}from'react';import {createPortal}from'react-dom';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var mn=({options:c$1,onSave:gn,title:A,description:R,acceptAllButtonText:P,rejectAllButtonText:D,customizeButtonText:x,saveButtonText:E,position:vn="bottom",variant:s="bar",zIndex:J=9999,version:C="1.0",show:_,manageStorage:z=true,storageKey:w="ndpr_consent",className:W="",buttonClassName:L="",primaryButtonClassName:Cn="",secondaryButtonClassName:_n="",classNames:n,unstyled:o,onAnalytics:k,showCookieScan:$=false,declaredCookies:hn,cookieScanOptions:sn,cookieScanTitle:j})=>{var T,N,nn,en,tn,on,rn,dn,cn;let p=c(),kn=(T=A!=null?A:p.consent.title)!=null?T:"We Value Your Privacy",Sn=(N=R!=null?R:p.consent.description)!=null?N:"We use cookies and similar technologies to provide our services and enhance your experience. Your consent is collected in accordance with NDPA Sections 25-26.",yn=(nn=P!=null?P:p.consent.acceptAll)!=null?nn:"Accept All",Bn=(en=D!=null?D:p.consent.rejectAll)!=null?en:"Reject All",An=(tn=x!=null?x:p.consent.customize)!=null?tn:"Customize",Rn=(on=E!=null?E:p.consent.savePreferences)!=null?on:"Save Preferences",Pn=(rn=p.consent.selectAll)!=null?rn:"Select All",Dn=(dn=p.consent.deselectAll)!=null?dn:"Deselect All",xn=j!=null?j:"Cookies on this page",[b$2,l]=useState(false),[u,I]=useState(false),{result:h,rescan:Y}=b(hn,sn);useEffect(()=>{$&&u&&Y();},[$,u,Y]);let[S,y]=useState({}),[K,En]=useState(false),zn=a({active:b$2}),O=useRef(null),q=useRef(false);useEffect(()=>{En(true);},[]);let f=useCallback((e,t)=>{k==null||k(a$1({action:e,timestamp:Date.now(),version:C},t!==void 0?{categories:t}:{}));},[k,C]);useEffect(()=>{let e={};if(c$1.forEach(t=>{e[t.id]=t.defaultValue||false;}),y(e),_===void 0)if(!z)l(true);else {let t=localStorage.getItem(w);if(t)try{JSON.parse(t).version!==C?l(!0):l(!1);}catch(M){l(true);}else l(true);}else l(_);},[c$1,w,C,z]),useEffect(()=>{_!==void 0&&l(_);},[_]);let wn=()=>{let e={};c$1.forEach(t=>{e[t.id]=true;}),f("accepted_all",e),H(e);},Q=()=>{let e={};c$1.forEach(t=>{e[t.id]=t.required||false;}),f("rejected_all",e),H(e);},Ln=(e,t)=>{y(M=>b$1(a$1({},M),{[e]:t}));},$n=()=>{let e={};c$1.forEach(t=>{e[t.id]=true;}),y(e);},jn=()=>{let e={};c$1.forEach(t=>{e[t.id]=t.required||false;}),y(e);},U=c$1.length>0&&c$1.every(e=>S[e.id]),In=()=>{f("customized",S),H(S);},H=e=>{let t={consents:e,timestamp:Date.now(),version:C,method:u?"customize":"banner",hasInteracted:true};z&&localStorage.setItem(w,JSON.stringify(t)),gn(t),l(false),I(false);};if(useEffect(()=>{if(!b$2)return;let e=t=>{t.key==="Escape"&&(f("dismissed"),Q());};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[b$2,f,c$1,u]),useEffect(()=>{b$2&&!q.current&&(q.current=true,f("shown")),b$2||(q.current=false);},[b$2,f]),useEffect(()=>{if(u&&O.current){let e=O.current;e.style.maxHeight="0px",e.style.opacity="0",e.offsetHeight,e.style.maxHeight=`${e.scrollHeight}px`,e.style.opacity="1";}},[u]),!b$2)return null;let g=s==="modal"?"center":vn,X=g==="inline",F=g==="center",v=["ndpr-consent-banner"];s!=="bar"&&v.push(`ndpr-consent-banner--${s}`),g==="top"?v.push("ndpr-consent-banner--top"):g==="bottom"?v.push("ndpr-consent-banner--bottom"):g==="inline"&&v.push("ndpr-consent-banner--inline"),W&&v.push(W);let On=v.join(" "),Z=`ndpr-consent-banner__button ndpr-consent-banner__button--primary ${L} ${Cn}`.trim(),qn=`ndpr-consent-banner__button ndpr-consent-banner__button--secondary ${L} ${_n}`.trim(),Hn=`ndpr-consent-banner__button ndpr-consent-banner__button--ghost ${L}`.trim(),Fn=(n==null?void 0:n.primaryButton)||(n==null?void 0:n.acceptButton)||Z,m=(n==null?void 0:n.secondaryButton)||(n==null?void 0:n.rejectButton)||qn,Gn=(n==null?void 0:n.customizeButton)||Hn,Mn=(n==null?void 0:n.saveButton)||Z,G=jsx("div",{ref:zn,tabIndex:-1,"data-ndpr-component":"consent-banner","data-ndpr-variant":s,"data-ndpr-position":g,className:a$2(On,n==null?void 0:n.root,o),style:!X&&!F?{zIndex:J}:void 0,role:"dialog","aria-modal":F||void 0,"aria-labelledby":"consent-banner-title","aria-describedby":"consent-banner-description",children:jsxs("div",{className:a$2("ndpr-consent-banner__container",n==null?void 0:n.container,o),children:[jsx("h2",{id:"consent-banner-title",className:a$2("ndpr-consent-banner__title",n==null?void 0:n.title,o),children:kn}),jsx("p",{id:"consent-banner-description",className:a$2("ndpr-consent-banner__description",n==null?void 0:n.description,o),children:Sn}),u&&jsxs("div",{ref:O,className:a$2("ndpr-consent-banner__customize-panel",n==null?void 0:n.customizePanel,o),children:[jsx("div",{className:o?"":"ndpr-consent-banner__select-all-row",children:jsx("button",{type:"button",onClick:U?jn:$n,className:a$2("ndpr-consent-banner__select-all-button",n==null?void 0:n.selectAllButton,o),children:U?Dn:Pn})}),jsx("div",{className:a$2("ndpr-consent-banner__options-list",n==null?void 0:n.optionsList,o),children:c$1.map(e=>jsxs("div",{className:a$2("ndpr-consent-banner__option",n==null?void 0:n.optionItem,o),children:[jsx("input",{id:`consent-${e.id}`,type:"checkbox",checked:S[e.id]||false,onChange:t=>Ln(e.id,t.target.checked),disabled:e.required,className:a$2("ndpr-consent-banner__option-checkbox",n==null?void 0:n.optionCheckbox,o)}),jsxs("div",{className:o?"":"ndpr-consent-banner__option-text",children:[jsxs("label",{htmlFor:`consent-${e.id}`,className:a$2("ndpr-consent-banner__option-label",n==null?void 0:n.optionLabel,o),children:[e.label,e.required&&jsx("span",{className:o?"":"ndpr-consent-banner__required-marker",children:" *"})]}),jsx("p",{className:a$2("ndpr-consent-banner__option-description",n==null?void 0:n.optionDescription,o),children:e.description})]})]},e.id))}),$&&h&&jsxs("div",{"data-ndpr-section":"cookie-scan",className:a$2("ndpr-alert ndpr-alert--info mb-2",n==null?void 0:n.cookieScanPanel,o),children:[jsxs("div",{className:"flex items-center justify-between mb-1",children:[jsx("h3",{className:"text-sm font-bold ndpr-text-info",children:xn}),jsx("span",{className:"text-sm font-semibold ndpr-text-info",children:h.total})]}),h.undeclared.length===0?jsx("p",{className:"text-sm ndpr-text-info",children:"All cookies on this page are declared."}):jsxs(Fragment,{children:[jsxs("p",{className:"text-sm ndpr-text-warning",children:[h.undeclared.length," undeclared cookie(s) detected \u2014 review your cookie notice (NDPA S.25-26)."]}),jsx("ul",{className:"mt-1 list-disc pl-5",children:h.undeclared.map(e=>jsxs("li",{className:"text-xs ndpr-text-muted",children:[jsx("code",{children:e.name})," ",jsx("span",{className:"opacity-70",children:e.provider?`\u2014 ${e.provider} (${e.category})`:"\u2014 unrecognized"})]},e.name))})]})]}),jsxs("div",{className:a$2("ndpr-consent-banner__buttons",n==null?void 0:n.buttonGroup,o),children:[jsx("button",{onClick:In,className:a$2(Mn,n==null?void 0:n.saveButton,o),children:Rn}),jsx("button",{onClick:()=>I(false),className:a$2(m,n==null?void 0:n.rejectButton,o),children:(cn=p.common.back)!=null?cn:"Back"})]})]}),!u&&jsxs("div",{className:a$2("ndpr-consent-banner__buttons",n==null?void 0:n.buttonGroup,o),children:[jsx("button",{onClick:wn,className:a$2(Fn,n==null?void 0:n.acceptButton,o),children:yn}),jsx("button",{onClick:Q,className:a$2(m,n==null?void 0:n.rejectButton,o),children:Bn}),jsx("button",{onClick:()=>I(true),className:a$2(Gn,n==null?void 0:n.customizeButton,o),children:An})]}),jsx("div",{className:a$2("ndpr-consent-banner__footer-text",void 0,o),children:'By clicking "Accept All", you agree to the use of ALL cookies. Visit our Cookie Policy to learn more.'})]})});if(X)return G;if(F){let e=jsx("div",{className:o?"":"ndpr-consent-banner__overlay",style:{zIndex:J},children:G});return K?createPortal(e,document.body):null}return K?createPortal(G,document.body):null};export{mn as a};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import {b}from'./chunk-ZY4RCV5C.mjs';import {useRef,useEffect,useState,useCallback}from'react';var T='a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function x(r){let{active:n,onEscape:o,autoFocus:u=true}=r,t=useRef(null),c=useRef(null);return useEffect(()=>{if(!n||(c.current=typeof document!="undefined"?document.activeElement:null,!t.current))return;let a=false,l;u&&(l=setTimeout(()=>{if(a||!t.current)return;let e=t.current.querySelectorAll(T);e.length>0?e[0].focus():(t.current.tabIndex<0&&(t.current.tabIndex=-1),t.current.focus());},0));let f=e=>{if(e.key==="Escape"&&o){o();return}if(e.key!=="Tab"||!t.current)return;let i=t.current.querySelectorAll(T);if(i.length===0)return;let d=i[0],m=i[i.length-1];e.shiftKey?document.activeElement===d&&(e.preventDefault(),m.focus()):document.activeElement===m&&(e.preventDefault(),d.focus());};return document.addEventListener("keydown",f),()=>{a=true,l&&clearTimeout(l),document.removeEventListener("keydown",f);let e=c.current;e&&typeof document!="undefined"&&document.contains(e)&&typeof e.focus=="function"&&e.focus();}},[n,o,u]),t}function h(r,n){let[o,u]=useState(null),t=useRef(r),c=useRef(n);t.current=r,c.current=n;let s=useCallback(()=>{u(b(t.current,c.current));},[]);return useEffect(()=>{s();},[s]),{result:o,rescan:s}}export{x as a,h as b};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';var chunkPEUAA5EC_js=require('./chunk-PEUAA5EC.js'),react=require('react');var T='a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function x(r){let{active:n,onEscape:o,autoFocus:u=true}=r,t=react.useRef(null),c=react.useRef(null);return react.useEffect(()=>{if(!n||(c.current=typeof document!="undefined"?document.activeElement:null,!t.current))return;let a=false,l;u&&(l=setTimeout(()=>{if(a||!t.current)return;let e=t.current.querySelectorAll(T);e.length>0?e[0].focus():(t.current.tabIndex<0&&(t.current.tabIndex=-1),t.current.focus());},0));let f=e=>{if(e.key==="Escape"&&o){o();return}if(e.key!=="Tab"||!t.current)return;let i=t.current.querySelectorAll(T);if(i.length===0)return;let d=i[0],m=i[i.length-1];e.shiftKey?document.activeElement===d&&(e.preventDefault(),m.focus()):document.activeElement===m&&(e.preventDefault(),d.focus());};return document.addEventListener("keydown",f),()=>{a=true,l&&clearTimeout(l),document.removeEventListener("keydown",f);let e=c.current;e&&typeof document!="undefined"&&document.contains(e)&&typeof e.focus=="function"&&e.focus();}},[n,o,u]),t}function h(r,n){let[o,u]=react.useState(null),t=react.useRef(r),c=react.useRef(n);t.current=r,c.current=n;let s=react.useCallback(()=>{u(chunkPEUAA5EC_js.b(t.current,c.current));},[]);return react.useEffect(()=>{s();},[s]),{result:o,rescan:s}}exports.a=x;exports.b=h;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var C=[{name:"_ga",category:"analytics",provider:"Google Analytics",purpose:"Distinguishes users"},{name:"_ga_",prefix:true,category:"analytics",provider:"Google Analytics (GA4)",purpose:"Persists session state"},{name:"_gid",category:"analytics",provider:"Google Analytics",purpose:"Distinguishes users"},{name:"_gat",prefix:true,category:"analytics",provider:"Google Analytics",purpose:"Throttles request rate"},{name:"_dc_gtm_",prefix:true,category:"analytics",provider:"Google Tag Manager",purpose:"Throttles request rate"},{name:"_gcl_",prefix:true,category:"marketing",provider:"Google Ads",purpose:"Conversion tracking"},{name:"IDE",category:"marketing",provider:"Google DoubleClick",purpose:"Ad targeting"},{name:"test_cookie",category:"marketing",provider:"Google DoubleClick",purpose:"Checks cookie support"},{name:"_fbp",category:"marketing",provider:"Meta (Facebook)",purpose:"Ad delivery and measurement"},{name:"_fbc",category:"marketing",provider:"Meta (Facebook)",purpose:"Click attribution"},{name:"fr",category:"marketing",provider:"Meta (Facebook)",purpose:"Ad delivery and measurement"},{name:"_clck",category:"analytics",provider:"Microsoft Clarity",purpose:"Session analytics"},{name:"_clsk",category:"analytics",provider:"Microsoft Clarity",purpose:"Session analytics"},{name:"_hj",prefix:true,category:"analytics",provider:"Hotjar",purpose:"Behaviour analytics"},{name:"bcookie",category:"marketing",provider:"LinkedIn",purpose:"Browser identification"},{name:"lidc",category:"marketing",provider:"LinkedIn",purpose:"Routing / ad delivery"},{name:"li_",prefix:true,category:"marketing",provider:"LinkedIn",purpose:"Ad delivery"},{name:"_ttp",category:"marketing",provider:"TikTok",purpose:"Ad measurement"},{name:"personalization_id",category:"marketing",provider:"X (Twitter)",purpose:"Ad personalisation"},{name:"guest_id",category:"marketing",provider:"X (Twitter)",purpose:"Identifies the browser"},{name:"hubspotutk",category:"marketing",provider:"HubSpot",purpose:"Visitor identification"},{name:"__hs",prefix:true,category:"analytics",provider:"HubSpot",purpose:"Analytics / session"},{name:"__stripe_mid",category:"necessary",provider:"Stripe",purpose:"Fraud prevention"},{name:"__stripe_sid",category:"necessary",provider:"Stripe",purpose:"Fraud prevention"},{name:"intercom-",prefix:true,category:"functional",provider:"Intercom",purpose:"Live chat / messaging"},{name:"ndpr_consent",category:"necessary",provider:"NDPR Toolkit",purpose:"Stores the consent decision"}];function f(t,r){return r.name instanceof RegExp?r.name.test(t):r.prefix?t.startsWith(r.name):t===r.name}function h(t){return t.split(";").map(r=>{let i=r.trim(),a=i.indexOf("=");return (a===-1?i:i.slice(0,a)).trim()}).filter(r=>r.length>0)}function S(t=[],r={}){var g,u,l,y,m,k;let i=(g=r.cookieString)!=null?g:typeof document!="undefined"?document.cookie:"",a=(u=r.asOf)!=null?u:Date.now(),v=((l=r.useKnownRegistry)!=null?l:true)?[...(y=r.knownCookies)!=null?y:[],...C]:[],n=h(i).map(e=>{let o=t.find(p=>f(e,p));if(o)return {name:e,category:o.category,matchedBy:"declared",provider:o.provider,purpose:o.purpose};let c=v.find(p=>f(e,p));return c?{name:e,category:c.category,matchedBy:"known",provider:c.provider,purpose:c.purpose}:{name:e,category:null,matchedBy:"none"}}),s={};for(let e of n){let o=(m=e.category)!=null?m:"uncategorized";((k=s[o])!=null?k:s[o]=[]).push(e);}let d=n.filter(e=>e.matchedBy!=="declared");return {scannedAt:a,total:n.length,cookies:n,declared:n.filter(e=>e.matchedBy==="declared"),undeclared:d,identified:n.filter(e=>e.matchedBy==="known"),unknown:n.filter(e=>e.matchedBy==="none"),byCategory:s,complete:d.length===0}}export{C as a,S as b};
|
package/dist/consent.d.mts
CHANGED
|
@@ -79,6 +79,8 @@ export declare interface ConsentBannerClassNames {
|
|
|
79
79
|
saveButton?: string;
|
|
80
80
|
customizePanel?: string;
|
|
81
81
|
selectAllButton?: string;
|
|
82
|
+
/** The optional on-page cookie scan panel (shown in the customize view) */
|
|
83
|
+
cookieScanPanel?: string;
|
|
82
84
|
/** Alias for acceptButton */
|
|
83
85
|
primaryButton?: string;
|
|
84
86
|
/** Alias for rejectButton */
|
|
@@ -202,6 +204,30 @@ declare interface ConsentBannerProps {
|
|
|
202
204
|
* Called when the banner is shown, accepted, rejected, customized, or dismissed.
|
|
203
205
|
*/
|
|
204
206
|
onAnalytics?: (event: ConsentAnalyticsEvent) => void;
|
|
207
|
+
/**
|
|
208
|
+
* Show a "cookies on this page" scan panel inside the customize view. It
|
|
209
|
+
* audits the cookies actually present against `declaredCookies` and flags
|
|
210
|
+
* undeclared ones — a transparency / self-audit aid (NDPA S.25-26 specific,
|
|
211
|
+
* informed consent). Off by default.
|
|
212
|
+
* @default false
|
|
213
|
+
*/
|
|
214
|
+
showCookieScan?: boolean;
|
|
215
|
+
/**
|
|
216
|
+
* The cookies you declare, matched against what's present when
|
|
217
|
+
* `showCookieScan` is on. Without it, every present cookie is treated as
|
|
218
|
+
* undeclared (though the built-in registry may still identify it).
|
|
219
|
+
*/
|
|
220
|
+
declaredCookies?: DeclaredCookie[];
|
|
221
|
+
/**
|
|
222
|
+
* Options forwarded to the scan (e.g. `knownCookies`, `useKnownRegistry`,
|
|
223
|
+
* or a `cookieString` to scan instead of `document.cookie`).
|
|
224
|
+
*/
|
|
225
|
+
cookieScanOptions?: CookieScanOptions;
|
|
226
|
+
/**
|
|
227
|
+
* Heading for the cookie scan panel.
|
|
228
|
+
* @default "Cookies on this page"
|
|
229
|
+
*/
|
|
230
|
+
cookieScanTitle?: string;
|
|
205
231
|
}
|
|
206
232
|
|
|
207
233
|
declare interface ConsentContextValue {
|
|
@@ -487,6 +513,44 @@ declare interface ConsentStorageProps {
|
|
|
487
513
|
}) => React__default.ReactNode);
|
|
488
514
|
}
|
|
489
515
|
|
|
516
|
+
/** How a present cookie was classified. */
|
|
517
|
+
export declare type CookieMatchSource = 'declared' | 'known' | 'none';
|
|
518
|
+
|
|
519
|
+
export declare interface CookieScanOptions {
|
|
520
|
+
/**
|
|
521
|
+
* The cookie string to scan, in `document.cookie` form (`a=1; b=2`).
|
|
522
|
+
* Defaults to `document.cookie` in the browser, or `''` on the server.
|
|
523
|
+
*/
|
|
524
|
+
cookieString?: string;
|
|
525
|
+
/** Reference timestamp (epoch ms) recorded on the result. Defaults to `Date.now()`. */
|
|
526
|
+
asOf?: number;
|
|
527
|
+
/** Extra known cookies, checked before the built-in registry (so they can override it). */
|
|
528
|
+
knownCookies?: DeclaredCookie[];
|
|
529
|
+
/** Whether to fall back to the built-in known-cookie registry for undeclared cookies. @default true */
|
|
530
|
+
useKnownRegistry?: boolean;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
export declare interface CookieScanResult {
|
|
534
|
+
/** When the scan ran (epoch ms). */
|
|
535
|
+
scannedAt: number;
|
|
536
|
+
/** Number of cookies present. */
|
|
537
|
+
total: number;
|
|
538
|
+
/** Every present cookie, classified. */
|
|
539
|
+
cookies: ScannedCookie[];
|
|
540
|
+
/** Cookies that matched one of your declared cookies. */
|
|
541
|
+
declared: ScannedCookie[];
|
|
542
|
+
/** Cookies present but NOT in your declaration — the compliance gap. */
|
|
543
|
+
undeclared: ScannedCookie[];
|
|
544
|
+
/** Undeclared cookies the built-in registry could still identify. */
|
|
545
|
+
identified: ScannedCookie[];
|
|
546
|
+
/** Undeclared cookies that could not be identified at all. */
|
|
547
|
+
unknown: ScannedCookie[];
|
|
548
|
+
/** Present cookies grouped by resolved category; unclassified cookies go under `uncategorized`. */
|
|
549
|
+
byCategory: Record<string, ScannedCookie[]>;
|
|
550
|
+
/** True when there are no undeclared cookies. */
|
|
551
|
+
complete: boolean;
|
|
552
|
+
}
|
|
553
|
+
|
|
490
554
|
/**
|
|
491
555
|
* Creates a new audit entry from consent settings. If `previousSettings` is
|
|
492
556
|
* provided, the action is automatically determined by comparing old and new
|
|
@@ -494,6 +558,30 @@ declare interface ConsentStorageProps {
|
|
|
494
558
|
*/
|
|
495
559
|
export declare function createAuditEntry(settings: ConsentSettings, previousSettings?: ConsentSettings | null, actionOverride?: ConsentAuditEntry['action']): ConsentAuditEntry;
|
|
496
560
|
|
|
561
|
+
/**
|
|
562
|
+
* Cookie scanner — audits the cookies actually present in the browser against
|
|
563
|
+
* the cookies you have declared, surfacing undeclared cookies that put you out
|
|
564
|
+
* of step with your cookie notice (NDPA 2023 S.25-26 / NDPC GAID 2025 on
|
|
565
|
+
* specific, informed consent).
|
|
566
|
+
*
|
|
567
|
+
* Pure and DOM-optional: pass `cookieString` to scan an arbitrary value (a
|
|
568
|
+
* `Cookie:` header on the server, a test fixture), or call it in the browser
|
|
569
|
+
* and it reads `document.cookie`. Safe to import from a server bundle.
|
|
570
|
+
*/
|
|
571
|
+
/** A cookie you declare against a consent category. */
|
|
572
|
+
export declare interface DeclaredCookie {
|
|
573
|
+
/** Exact cookie name, a prefix (with `prefix: true`), or a RegExp matched against the name. */
|
|
574
|
+
name: string | RegExp;
|
|
575
|
+
/** Consent category this cookie belongs to (e.g. 'necessary', 'analytics', 'marketing'). */
|
|
576
|
+
category: string;
|
|
577
|
+
/** Who sets the cookie (e.g. 'Google Analytics'). */
|
|
578
|
+
provider?: string;
|
|
579
|
+
/** What the cookie is used for — surfaced in your cookie policy. */
|
|
580
|
+
purpose?: string;
|
|
581
|
+
/** Treat a string `name` as a prefix match instead of an exact match. Ignored for RegExp names. */
|
|
582
|
+
prefix?: boolean;
|
|
583
|
+
}
|
|
584
|
+
|
|
497
585
|
/**
|
|
498
586
|
* Retrieves the full consent audit log from localStorage.
|
|
499
587
|
* Returns an empty array if no log exists or parsing fails.
|
|
@@ -502,6 +590,14 @@ export declare function createAuditEntry(settings: ConsentSettings, previousSett
|
|
|
502
590
|
*/
|
|
503
591
|
export declare function getAuditLog(storageKey?: string): ConsentAuditEntry[];
|
|
504
592
|
|
|
593
|
+
/**
|
|
594
|
+
* Built-in registry of widely deployed third-party cookies, so an undeclared
|
|
595
|
+
* cookie can often still be identified (provider + likely category). Override
|
|
596
|
+
* or extend via {@link CookieScanOptions.knownCookies}; categories follow the
|
|
597
|
+
* common necessary / functional / analytics / marketing taxonomy.
|
|
598
|
+
*/
|
|
599
|
+
export declare const KNOWN_COOKIES: DeclaredCookie[];
|
|
600
|
+
|
|
505
601
|
/**
|
|
506
602
|
* Lawful basis for processing personal data per NDPA Section 25(1)
|
|
507
603
|
*/
|
|
@@ -539,6 +635,24 @@ declare interface SaveButtonProps {
|
|
|
539
635
|
consents?: Record<string, boolean>;
|
|
540
636
|
}
|
|
541
637
|
|
|
638
|
+
/**
|
|
639
|
+
* Scan the cookies present against your declared cookies and a registry of
|
|
640
|
+
* well-known third-party cookies. Returns which cookies are declared, which are
|
|
641
|
+
* undeclared (and whether they can still be identified), and a per-category view.
|
|
642
|
+
*/
|
|
643
|
+
export declare function scanCookies(declared?: DeclaredCookie[], options?: CookieScanOptions): CookieScanResult;
|
|
644
|
+
|
|
645
|
+
export declare interface ScannedCookie {
|
|
646
|
+
/** The cookie name as found in the cookie string. */
|
|
647
|
+
name: string;
|
|
648
|
+
/** Resolved consent category, or `null` when it could not be classified. */
|
|
649
|
+
category: string | null;
|
|
650
|
+
/** Whether it matched your declaration, only the known registry, or nothing. */
|
|
651
|
+
matchedBy: CookieMatchSource;
|
|
652
|
+
provider?: string;
|
|
653
|
+
purpose?: string;
|
|
654
|
+
}
|
|
655
|
+
|
|
542
656
|
export declare interface StorageAdapter<T = unknown> {
|
|
543
657
|
/** Load persisted data. Called once on hook mount. */
|
|
544
658
|
load(): T | null | Promise<T | null>;
|
package/dist/consent.d.ts
CHANGED
|
@@ -79,6 +79,8 @@ export declare interface ConsentBannerClassNames {
|
|
|
79
79
|
saveButton?: string;
|
|
80
80
|
customizePanel?: string;
|
|
81
81
|
selectAllButton?: string;
|
|
82
|
+
/** The optional on-page cookie scan panel (shown in the customize view) */
|
|
83
|
+
cookieScanPanel?: string;
|
|
82
84
|
/** Alias for acceptButton */
|
|
83
85
|
primaryButton?: string;
|
|
84
86
|
/** Alias for rejectButton */
|
|
@@ -202,6 +204,30 @@ declare interface ConsentBannerProps {
|
|
|
202
204
|
* Called when the banner is shown, accepted, rejected, customized, or dismissed.
|
|
203
205
|
*/
|
|
204
206
|
onAnalytics?: (event: ConsentAnalyticsEvent) => void;
|
|
207
|
+
/**
|
|
208
|
+
* Show a "cookies on this page" scan panel inside the customize view. It
|
|
209
|
+
* audits the cookies actually present against `declaredCookies` and flags
|
|
210
|
+
* undeclared ones — a transparency / self-audit aid (NDPA S.25-26 specific,
|
|
211
|
+
* informed consent). Off by default.
|
|
212
|
+
* @default false
|
|
213
|
+
*/
|
|
214
|
+
showCookieScan?: boolean;
|
|
215
|
+
/**
|
|
216
|
+
* The cookies you declare, matched against what's present when
|
|
217
|
+
* `showCookieScan` is on. Without it, every present cookie is treated as
|
|
218
|
+
* undeclared (though the built-in registry may still identify it).
|
|
219
|
+
*/
|
|
220
|
+
declaredCookies?: DeclaredCookie[];
|
|
221
|
+
/**
|
|
222
|
+
* Options forwarded to the scan (e.g. `knownCookies`, `useKnownRegistry`,
|
|
223
|
+
* or a `cookieString` to scan instead of `document.cookie`).
|
|
224
|
+
*/
|
|
225
|
+
cookieScanOptions?: CookieScanOptions;
|
|
226
|
+
/**
|
|
227
|
+
* Heading for the cookie scan panel.
|
|
228
|
+
* @default "Cookies on this page"
|
|
229
|
+
*/
|
|
230
|
+
cookieScanTitle?: string;
|
|
205
231
|
}
|
|
206
232
|
|
|
207
233
|
declare interface ConsentContextValue {
|
|
@@ -487,6 +513,44 @@ declare interface ConsentStorageProps {
|
|
|
487
513
|
}) => React__default.ReactNode);
|
|
488
514
|
}
|
|
489
515
|
|
|
516
|
+
/** How a present cookie was classified. */
|
|
517
|
+
export declare type CookieMatchSource = 'declared' | 'known' | 'none';
|
|
518
|
+
|
|
519
|
+
export declare interface CookieScanOptions {
|
|
520
|
+
/**
|
|
521
|
+
* The cookie string to scan, in `document.cookie` form (`a=1; b=2`).
|
|
522
|
+
* Defaults to `document.cookie` in the browser, or `''` on the server.
|
|
523
|
+
*/
|
|
524
|
+
cookieString?: string;
|
|
525
|
+
/** Reference timestamp (epoch ms) recorded on the result. Defaults to `Date.now()`. */
|
|
526
|
+
asOf?: number;
|
|
527
|
+
/** Extra known cookies, checked before the built-in registry (so they can override it). */
|
|
528
|
+
knownCookies?: DeclaredCookie[];
|
|
529
|
+
/** Whether to fall back to the built-in known-cookie registry for undeclared cookies. @default true */
|
|
530
|
+
useKnownRegistry?: boolean;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
export declare interface CookieScanResult {
|
|
534
|
+
/** When the scan ran (epoch ms). */
|
|
535
|
+
scannedAt: number;
|
|
536
|
+
/** Number of cookies present. */
|
|
537
|
+
total: number;
|
|
538
|
+
/** Every present cookie, classified. */
|
|
539
|
+
cookies: ScannedCookie[];
|
|
540
|
+
/** Cookies that matched one of your declared cookies. */
|
|
541
|
+
declared: ScannedCookie[];
|
|
542
|
+
/** Cookies present but NOT in your declaration — the compliance gap. */
|
|
543
|
+
undeclared: ScannedCookie[];
|
|
544
|
+
/** Undeclared cookies the built-in registry could still identify. */
|
|
545
|
+
identified: ScannedCookie[];
|
|
546
|
+
/** Undeclared cookies that could not be identified at all. */
|
|
547
|
+
unknown: ScannedCookie[];
|
|
548
|
+
/** Present cookies grouped by resolved category; unclassified cookies go under `uncategorized`. */
|
|
549
|
+
byCategory: Record<string, ScannedCookie[]>;
|
|
550
|
+
/** True when there are no undeclared cookies. */
|
|
551
|
+
complete: boolean;
|
|
552
|
+
}
|
|
553
|
+
|
|
490
554
|
/**
|
|
491
555
|
* Creates a new audit entry from consent settings. If `previousSettings` is
|
|
492
556
|
* provided, the action is automatically determined by comparing old and new
|
|
@@ -494,6 +558,30 @@ declare interface ConsentStorageProps {
|
|
|
494
558
|
*/
|
|
495
559
|
export declare function createAuditEntry(settings: ConsentSettings, previousSettings?: ConsentSettings | null, actionOverride?: ConsentAuditEntry['action']): ConsentAuditEntry;
|
|
496
560
|
|
|
561
|
+
/**
|
|
562
|
+
* Cookie scanner — audits the cookies actually present in the browser against
|
|
563
|
+
* the cookies you have declared, surfacing undeclared cookies that put you out
|
|
564
|
+
* of step with your cookie notice (NDPA 2023 S.25-26 / NDPC GAID 2025 on
|
|
565
|
+
* specific, informed consent).
|
|
566
|
+
*
|
|
567
|
+
* Pure and DOM-optional: pass `cookieString` to scan an arbitrary value (a
|
|
568
|
+
* `Cookie:` header on the server, a test fixture), or call it in the browser
|
|
569
|
+
* and it reads `document.cookie`. Safe to import from a server bundle.
|
|
570
|
+
*/
|
|
571
|
+
/** A cookie you declare against a consent category. */
|
|
572
|
+
export declare interface DeclaredCookie {
|
|
573
|
+
/** Exact cookie name, a prefix (with `prefix: true`), or a RegExp matched against the name. */
|
|
574
|
+
name: string | RegExp;
|
|
575
|
+
/** Consent category this cookie belongs to (e.g. 'necessary', 'analytics', 'marketing'). */
|
|
576
|
+
category: string;
|
|
577
|
+
/** Who sets the cookie (e.g. 'Google Analytics'). */
|
|
578
|
+
provider?: string;
|
|
579
|
+
/** What the cookie is used for — surfaced in your cookie policy. */
|
|
580
|
+
purpose?: string;
|
|
581
|
+
/** Treat a string `name` as a prefix match instead of an exact match. Ignored for RegExp names. */
|
|
582
|
+
prefix?: boolean;
|
|
583
|
+
}
|
|
584
|
+
|
|
497
585
|
/**
|
|
498
586
|
* Retrieves the full consent audit log from localStorage.
|
|
499
587
|
* Returns an empty array if no log exists or parsing fails.
|
|
@@ -502,6 +590,14 @@ export declare function createAuditEntry(settings: ConsentSettings, previousSett
|
|
|
502
590
|
*/
|
|
503
591
|
export declare function getAuditLog(storageKey?: string): ConsentAuditEntry[];
|
|
504
592
|
|
|
593
|
+
/**
|
|
594
|
+
* Built-in registry of widely deployed third-party cookies, so an undeclared
|
|
595
|
+
* cookie can often still be identified (provider + likely category). Override
|
|
596
|
+
* or extend via {@link CookieScanOptions.knownCookies}; categories follow the
|
|
597
|
+
* common necessary / functional / analytics / marketing taxonomy.
|
|
598
|
+
*/
|
|
599
|
+
export declare const KNOWN_COOKIES: DeclaredCookie[];
|
|
600
|
+
|
|
505
601
|
/**
|
|
506
602
|
* Lawful basis for processing personal data per NDPA Section 25(1)
|
|
507
603
|
*/
|
|
@@ -539,6 +635,24 @@ declare interface SaveButtonProps {
|
|
|
539
635
|
consents?: Record<string, boolean>;
|
|
540
636
|
}
|
|
541
637
|
|
|
638
|
+
/**
|
|
639
|
+
* Scan the cookies present against your declared cookies and a registry of
|
|
640
|
+
* well-known third-party cookies. Returns which cookies are declared, which are
|
|
641
|
+
* undeclared (and whether they can still be identified), and a per-category view.
|
|
642
|
+
*/
|
|
643
|
+
export declare function scanCookies(declared?: DeclaredCookie[], options?: CookieScanOptions): CookieScanResult;
|
|
644
|
+
|
|
645
|
+
export declare interface ScannedCookie {
|
|
646
|
+
/** The cookie name as found in the cookie string. */
|
|
647
|
+
name: string;
|
|
648
|
+
/** Resolved consent category, or `null` when it could not be classified. */
|
|
649
|
+
category: string | null;
|
|
650
|
+
/** Whether it matched your declaration, only the known registry, or nothing. */
|
|
651
|
+
matchedBy: CookieMatchSource;
|
|
652
|
+
provider?: string;
|
|
653
|
+
purpose?: string;
|
|
654
|
+
}
|
|
655
|
+
|
|
542
656
|
export declare interface StorageAdapter<T = unknown> {
|
|
543
657
|
/** Load persisted data. Called once on hook mount. */
|
|
544
658
|
load(): T | null | Promise<T | null>;
|
package/dist/consent.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
'use strict';var chunkSJDDNB6M_js=require('./chunk-SJDDNB6M.js'),chunkC32TMS75_js=require('./chunk-C32TMS75.js'),
|
|
2
|
+
'use strict';var chunkSJDDNB6M_js=require('./chunk-SJDDNB6M.js'),chunkC32TMS75_js=require('./chunk-C32TMS75.js'),chunk7PV64WEZ_js=require('./chunk-7PV64WEZ.js'),chunk3IA3KDII_js=require('./chunk-3IA3KDII.js'),chunkQKXGVT2Q_js=require('./chunk-QKXGVT2Q.js');require('./chunk-YMKN3YQL.js'),require('./chunk-C2KEXHRX.js');var chunkDKLJ5DYN_js=require('./chunk-DKLJ5DYN.js'),chunkPEUAA5EC_js=require('./chunk-PEUAA5EC.js'),chunkAME4HJR4_js=require('./chunk-AME4HJR4.js');require('./chunk-I5ZDNSX5.js'),require('./chunk-7563FVMY.js'),require('./chunk-VWED6UTN.js');var chunkRFPLZDIO_js=require('./chunk-RFPLZDIO.js'),react=require('react'),jsxRuntime=require('react/jsx-runtime');var v=react.createContext(null);function p(){let t=react.useContext(v);if(!t)throw new Error("Consent compound components must be wrapped in <Consent.Provider>. Example: <Consent.Provider options={...}><Consent.Banner /></Consent.Provider>");return t}var g=({options:t,adapter:n,version:s,onChange:r,children:c})=>{let d=chunkQKXGVT2Q_js.a({options:t,adapter:n,version:s,onChange:r}),o=chunkRFPLZDIO_js.b(chunkRFPLZDIO_js.a({},d),{options:t});return jsxRuntime.jsx(v.Provider,{value:o,children:c})};var B=({classNames:t,unstyled:n})=>{let{options:s,settings:r}=p(),[c,d]=react.useState(()=>{let o={};return s.forEach(i=>{var a,_;o[i.id]=(_=(a=r==null?void 0:r.consents[i.id])!=null?a:i.defaultValue)!=null?_:false;}),o});return jsxRuntime.jsx("div",{className:chunkAME4HJR4_js.a("ndpr-consent-banner__options-list",t==null?void 0:t.root,n),"data-ndpr-component":"consent-option-list",children:s.map(o=>jsxRuntime.jsxs("div",{className:chunkAME4HJR4_js.a("ndpr-consent-banner__option",t==null?void 0:t.optionItem,n),children:[jsxRuntime.jsx("input",{id:`consent-${o.id}`,type:"checkbox",checked:c[o.id]||false,onChange:i=>d(a=>chunkRFPLZDIO_js.b(chunkRFPLZDIO_js.a({},a),{[o.id]:i.target.checked})),disabled:o.required,className:chunkAME4HJR4_js.a("ndpr-consent-banner__option-checkbox",t==null?void 0:t.optionCheckbox,n),"aria-label":o.label}),jsxRuntime.jsxs("div",{className:n?"":"ndpr-consent-banner__option-text",children:[jsxRuntime.jsxs("label",{htmlFor:`consent-${o.id}`,className:chunkAME4HJR4_js.a("ndpr-consent-banner__option-label",t==null?void 0:t.optionLabel,n),children:[o.label,o.required&&jsxRuntime.jsx("span",{className:n?"":"ndpr-consent-banner__required-marker",children:" *"})]}),jsxRuntime.jsx("p",{className:chunkAME4HJR4_js.a("ndpr-consent-banner__option-description",t==null?void 0:t.optionDescription,n),children:o.description})]})]},o.id))})};var R=({children:t,className:n,unstyled:s})=>{let{acceptAll:r}=p();return jsxRuntime.jsx("button",{onClick:r,className:chunkAME4HJR4_js.a("ndpr-consent-banner__button ndpr-consent-banner__button--primary",n,s),"data-ndpr-component":"consent-accept-button",children:t!=null?t:"Accept All"})};var P=({children:t,className:n,unstyled:s})=>{let{rejectAll:r}=p();return jsxRuntime.jsx("button",{onClick:r,className:chunkAME4HJR4_js.a("ndpr-consent-banner__button ndpr-consent-banner__button--secondary",n,s),"data-ndpr-component":"consent-reject-button",children:t!=null?t:"Reject All"})};var y=({children:t,className:n,unstyled:s,consents:r})=>{let{updateConsent:c,options:d}=p();return jsxRuntime.jsx("button",{onClick:()=>{if(r)c(r);else {let i={};d.forEach(a=>{i[a.id]=a.required||false;}),c(i);}},className:chunkAME4HJR4_js.a("ndpr-consent-banner__button ndpr-consent-banner__button--primary",n,s),"data-ndpr-component":"consent-save-button",children:t!=null?t:"Save Preferences"})};var K={Provider:g,OptionList:B,AcceptButton:R,RejectButton:P,SaveButton:y,Banner:chunk7PV64WEZ_js.a,Settings:chunkC32TMS75_js.a,Storage:chunkSJDDNB6M_js.a};Object.defineProperty(exports,"ConsentStorage",{enumerable:true,get:function(){return chunkSJDDNB6M_js.a}});Object.defineProperty(exports,"ConsentManager",{enumerable:true,get:function(){return chunkC32TMS75_js.a}});Object.defineProperty(exports,"ConsentBanner",{enumerable:true,get:function(){return chunk7PV64WEZ_js.a}});Object.defineProperty(exports,"appendAuditEntry",{enumerable:true,get:function(){return chunk3IA3KDII_js.c}});Object.defineProperty(exports,"createAuditEntry",{enumerable:true,get:function(){return chunk3IA3KDII_js.a}});Object.defineProperty(exports,"getAuditLog",{enumerable:true,get:function(){return chunk3IA3KDII_js.b}});Object.defineProperty(exports,"useConsent",{enumerable:true,get:function(){return chunkQKXGVT2Q_js.a}});Object.defineProperty(exports,"validateConsentOptionsStructured",{enumerable:true,get:function(){return chunkDKLJ5DYN_js.b}});Object.defineProperty(exports,"validateConsentStructured",{enumerable:true,get:function(){return chunkDKLJ5DYN_js.a}});Object.defineProperty(exports,"KNOWN_COOKIES",{enumerable:true,get:function(){return chunkPEUAA5EC_js.a}});Object.defineProperty(exports,"scanCookies",{enumerable:true,get:function(){return chunkPEUAA5EC_js.b}});Object.defineProperty(exports,"resolveClass",{enumerable:true,get:function(){return chunkAME4HJR4_js.a}});exports.Consent=K;exports.ConsentAcceptButton=R;exports.ConsentOptionList=B;exports.ConsentProvider=g;exports.ConsentRejectButton=P;exports.ConsentSaveButton=y;exports.useConsentCompound=p;
|
package/dist/consent.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {a}from'./chunk-XOH4WXOZ.mjs';export{a as ConsentStorage}from'./chunk-XOH4WXOZ.mjs';import {a as a$1}from'./chunk-CNCEP66F.mjs';export{a as ConsentManager}from'./chunk-CNCEP66F.mjs';import {a as a$2}from'./chunk-
|
|
2
|
+
import {a}from'./chunk-XOH4WXOZ.mjs';export{a as ConsentStorage}from'./chunk-XOH4WXOZ.mjs';import {a as a$1}from'./chunk-CNCEP66F.mjs';export{a as ConsentManager}from'./chunk-CNCEP66F.mjs';import {a as a$2}from'./chunk-PYSYBUIV.mjs';export{a as ConsentBanner}from'./chunk-PYSYBUIV.mjs';export{c as appendAuditEntry,a as createAuditEntry,b as getAuditLog}from'./chunk-V7UFP6QU.mjs';import {a as a$3}from'./chunk-PQ5IPUJN.mjs';export{a as useConsent}from'./chunk-PQ5IPUJN.mjs';import'./chunk-QNXLY5EJ.mjs';import'./chunk-XC3DLYEG.mjs';export{b as validateConsentOptionsStructured,a as validateConsentStructured}from'./chunk-R3ZKV2J7.mjs';export{a as KNOWN_COOKIES,b as scanCookies}from'./chunk-ZY4RCV5C.mjs';import {a as a$5}from'./chunk-SFGW37LE.mjs';export{a as resolveClass}from'./chunk-SFGW37LE.mjs';import'./chunk-PHA3YMFO.mjs';import'./chunk-5LJ652AH.mjs';import'./chunk-DBZSN4WP.mjs';import {b,a as a$4}from'./chunk-ZJYULEER.mjs';import {createContext,useContext,useState}from'react';import {jsx,jsxs}from'react/jsx-runtime';var v=createContext(null);function p(){let t=useContext(v);if(!t)throw new Error("Consent compound components must be wrapped in <Consent.Provider>. Example: <Consent.Provider options={...}><Consent.Banner /></Consent.Provider>");return t}var g=({options:t,adapter:n,version:s,onChange:r,children:c})=>{let d=a$3({options:t,adapter:n,version:s,onChange:r}),o=b(a$4({},d),{options:t});return jsx(v.Provider,{value:o,children:c})};var B=({classNames:t,unstyled:n})=>{let{options:s,settings:r}=p(),[c,d]=useState(()=>{let o={};return s.forEach(i=>{var a,_;o[i.id]=(_=(a=r==null?void 0:r.consents[i.id])!=null?a:i.defaultValue)!=null?_:false;}),o});return jsx("div",{className:a$5("ndpr-consent-banner__options-list",t==null?void 0:t.root,n),"data-ndpr-component":"consent-option-list",children:s.map(o=>jsxs("div",{className:a$5("ndpr-consent-banner__option",t==null?void 0:t.optionItem,n),children:[jsx("input",{id:`consent-${o.id}`,type:"checkbox",checked:c[o.id]||false,onChange:i=>d(a=>b(a$4({},a),{[o.id]:i.target.checked})),disabled:o.required,className:a$5("ndpr-consent-banner__option-checkbox",t==null?void 0:t.optionCheckbox,n),"aria-label":o.label}),jsxs("div",{className:n?"":"ndpr-consent-banner__option-text",children:[jsxs("label",{htmlFor:`consent-${o.id}`,className:a$5("ndpr-consent-banner__option-label",t==null?void 0:t.optionLabel,n),children:[o.label,o.required&&jsx("span",{className:n?"":"ndpr-consent-banner__required-marker",children:" *"})]}),jsx("p",{className:a$5("ndpr-consent-banner__option-description",t==null?void 0:t.optionDescription,n),children:o.description})]})]},o.id))})};var R=({children:t,className:n,unstyled:s})=>{let{acceptAll:r}=p();return jsx("button",{onClick:r,className:a$5("ndpr-consent-banner__button ndpr-consent-banner__button--primary",n,s),"data-ndpr-component":"consent-accept-button",children:t!=null?t:"Accept All"})};var P=({children:t,className:n,unstyled:s})=>{let{rejectAll:r}=p();return jsx("button",{onClick:r,className:a$5("ndpr-consent-banner__button ndpr-consent-banner__button--secondary",n,s),"data-ndpr-component":"consent-reject-button",children:t!=null?t:"Reject All"})};var y=({children:t,className:n,unstyled:s,consents:r})=>{let{updateConsent:c,options:d}=p();return jsx("button",{onClick:()=>{if(r)c(r);else {let i={};d.forEach(a=>{i[a.id]=a.required||false;}),c(i);}},className:a$5("ndpr-consent-banner__button ndpr-consent-banner__button--primary",n,s),"data-ndpr-component":"consent-save-button",children:t!=null?t:"Save Preferences"})};var K={Provider:g,OptionList:B,AcceptButton:R,RejectButton:P,SaveButton:y,Banner:a$2,Settings:a$1,Storage:a};export{K as Consent,R as ConsentAcceptButton,B as ConsentOptionList,g as ConsentProvider,P as ConsentRejectButton,y as ConsentSaveButton,p as useConsentCompound};
|