UNPKG

cookiebanner-finally

Version:

Headless cookie banner library for Next.js with shadcn philosophy

2 lines 7.13 kB
'use strict';var react=require('react'),A=require('js-cookie'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var A__default=/*#__PURE__*/_interopDefault(A);var w=(o=>(o.Necessary="necessary",o.Preferences="preferences",o.Analytics="analytics",o.Marketing="marketing",o))(w||{}),u={necessary:true,preferences:false,analytics:false,marketing:false};var D="cookie-consent",V={expires:365,path:"/",sameSite:"strict"},g=class{cookieName;cookieOptions;constructor(e=D,t=V){this.cookieName=e,this.cookieOptions=t;}getConsentPreferences(){try{let e=this.getCookieValue();if(!e)return {...u};let t=JSON.parse(e);return {...u,...t,necessary:!0}}catch(e){return console.error("Error parsing consent preferences",e),{...u}}}saveConsentPreferences(e){let r={...this.getConsentPreferences(),...e,necessary:true,lastUpdated:new Date().toISOString()};try{this.setCookieValue(JSON.stringify(r));}catch(o){console.error("Error saving consent preferences",o);}return r}hasConsent(e){return this.getConsentPreferences()[e]===true}acceptAll(){return this.saveConsentPreferences({necessary:true,preferences:true,analytics:true,marketing:true})}denyAll(){return this.saveConsentPreferences({necessary:true,preferences:false,analytics:false,marketing:false})}hasConsentBeenGiven(){try{return this.getCookieValue()!==null}catch{return false}}getCookieValue(){return typeof window<"u"&&typeof document<"u"&&A__default.default.get(this.cookieName)||null}setCookieValue(e){typeof window<"u"&&typeof document<"u"&&A__default.default.set(this.cookieName,e,this.cookieOptions);}},x=new g;var N=react.createContext({preferences:u,isConsentGiven:false,showBanner:false,acceptAll:()=>{},denyAll:()=>{},updatePreferences:()=>{},closeBanner:()=>{},resetBanner:()=>{},hasConsentFor:()=>false}),K=({children:n,cookieName:e,cookieExpires:t,initialPreferences:r,autoShowBanner:o=true})=>{let[s]=react.useState(()=>e||t?new g(e,t?{expires:t,path:"/",sameSite:"strict"}:void 0):x),[a,l]=react.useState(u),[i,f]=react.useState(false),[v,C]=react.useState(false),[R,M]=react.useState(false);react.useEffect(()=>{let c=s.hasConsentBeenGiven();r&&!c&&s.saveConsentPreferences(r);let b=s.getConsentPreferences();l(b),f(c),C(o&&!c),M(true);},[s,r,o]);let O=()=>{let c=s.acceptAll();l(c),f(true),C(false);},F=()=>{let c=s.denyAll();l(c),f(true),C(false);},G=(c,b=false)=>{let _=s.saveConsentPreferences(c);l(_),f(true),b&&C(false);},U=()=>{C(false);},I=()=>{C(true);},T=c=>s.hasConsent(c);return R?jsxRuntime.jsx(N.Provider,{value:{preferences:a,isConsentGiven:i,showBanner:v,acceptAll:O,denyAll:F,updatePreferences:G,closeBanner:U,resetBanner:I,hasConsentFor:T},children:n}):jsxRuntime.jsx(jsxRuntime.Fragment,{children:n})},p=()=>{let n=react.useContext(N);if(n===void 0)throw new Error("useConsentContext must be used within a ConsentProvider");return n};function z(){let{showBanner:n,isConsentGiven:e,acceptAll:t,denyAll:r,closeBanner:o,resetBanner:s}=p();return {isVisible:n,isConsentGiven:e,acceptAll:t,denyAll:r,close:o,show:s}}function H(){let{preferences:n,updatePreferences:e,hasConsentFor:t}=p(),r=!n||Object.keys(n).length===0;return {preferences:n,isLoading:r,isEnabled:a=>t(a),updatePreferences:e,updateCategory:(a,l)=>{e({[a]:l},false);}}}function E(n){let{hasConsentFor:e,resetBanner:t}=p(),[r,o]=react.useState(false);return react.useEffect(()=>{o(true);},[]),{hasConsent:r?e(n):false,isLoading:!r,showConsentPrompt:()=>{t();}}}var h=class{scripts=new Map;loadedScripts=new Set;register(e){if(!e.id)throw new Error("Script ID is required");if(!e.category)throw new Error("Script category is required");if(!e.src&&!e.content)throw new Error("Either src or content is required");this.scripts.set(e.id,e);}registerBatch(e){e.forEach(t=>this.register(t));}loadScript(e,t){let r=this.scripts.get(e);return r?this.loadedScripts.has(e)?Promise.resolve(true):t?new Promise(o=>{r.src?this.loadExternalScript(r,()=>{this.loadedScripts.add(e),o(true);}):r.content&&(this.loadInlineScript(r),this.loadedScripts.add(e),o(true));}):Promise.resolve(false):(console.error(`Script with ID ${e} not found`),Promise.resolve(false))}loadScriptsByCategory(e,t){let r=Array.from(this.scripts.values()).filter(o=>o.category===e);return Promise.all(r.map(o=>this.loadScript(o.id,t)))}isLoaded(e){return this.loadedScripts.has(e)}getAllScripts(){return Array.from(this.scripts.values())}getScriptsByCategory(e){return Array.from(this.scripts.values()).filter(t=>t.category===e)}loadExternalScript(e,t){if(typeof document>"u")return;let r=document.createElement("script");e.src&&(r.src=e.src),e.attributes&&Object.entries(e.attributes).forEach(([o,s])=>{r.setAttribute(o,s);}),r.onload=t,r.onerror=o=>{console.error(`Failed to load script: ${e.id}`,o),t();},document.head.appendChild(r);}loadInlineScript(e){if(typeof document>"u"||!e.content)return;let t=document.createElement("script");t.text=e.content,e.attributes&&Object.entries(e.attributes).forEach(([r,o])=>{t.setAttribute(r,o);});try{document.head.appendChild(t);}catch(r){console.error(`Error executing inline script: ${e.id}`,r);}}},d=new h;function P(){let{hasConsentFor:n}=p(),[e,t]=react.useState(false);return react.useEffect(()=>{t(true);},[]),{register:i=>{e&&d.register(i);},registerBatch:i=>{e&&d.registerBatch(i);},load:async i=>{if(!e)return false;let f=d.getAllScripts().find(C=>C.id===i);if(!f)return console.error(`Script with ID ${i} not found`),false;let v=n(f.category);return d.loadScript(i,v)},loadCategory:i=>{if(!e)return Promise.resolve([]);let f=n(i);return d.loadScriptsByCategory(i,f)},isLoaded:i=>e?d.isLoaded(i):false}}var Z=({children:n,category:e,fallback:t,loading:r,showPromptOnClick:o=true})=>{let{hasConsent:s,isLoading:a,showConsentPrompt:l}=E(e);return a?r?jsxRuntime.jsx(jsxRuntime.Fragment,{children:r}):jsxRuntime.jsx("div",{children:"Loading..."}):s?jsxRuntime.jsx(jsxRuntime.Fragment,{children:n}):t?jsxRuntime.jsx(jsxRuntime.Fragment,{children:t}):jsxRuntime.jsxs("div",{className:"cookie-consent-gate-fallback",children:[jsxRuntime.jsxs("p",{children:["This content requires consent for ",e," cookies."]}),o&&jsxRuntime.jsx("button",{onClick:l,className:"cookie-consent-gate-button",children:"Manage Cookie Preferences"})]})};var ee=({script:n,onLoad:e,autoLoad:t=true})=>{let{register:r,load:o,isLoaded:s}=P();return react.useEffect(()=>{r(n);},[r,n]),react.useEffect(()=>{t&&o(n.id).then(a=>{a&&e&&e();});},[o,n.id,t,e]),null},te=({scripts:n,onLoad:e,autoLoad:t=true})=>{let{registerBatch:r,load:o}=P();return react.useEffect(()=>{r(n);},[r,n]),react.useEffect(()=>{t&&Promise.all(n.map(s=>o(s.id))).then(s=>{s.every(Boolean)&&e&&e();});},[o,n,t,e]),null};exports.ConsentCategory=w;exports.ConsentGate=Z;exports.ConsentProvider=K;exports.CookieManager=g;exports.DEFAULT_CONSENT_PREFERENCES=u;exports.ScriptBatchLoader=te;exports.ScriptLoader=ee;exports.ScriptManager=h;exports.cookieManager=x;exports.scriptManager=d;exports.useConsentContext=p;exports.useConsentGate=E;exports.useCookieBanner=z;exports.useCookiePreferences=H;exports.useScriptLoader=P;//# sourceMappingURL=index.cjs.map //# sourceMappingURL=index.cjs.map