@c15t/react 3.0.0-alpha.10 → 3.0.0-alpha.11

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.
Files changed (45) hide show
  1. package/AGENTS.md +1 -0
  2. package/dist/aggregate-components.js +1 -1
  3. package/dist/chunk-warming.js +1 -1
  4. package/dist/components/consent-gate/atoms.js +1 -1
  5. package/dist/components/iab-panel/atoms/root.js +1 -1
  6. package/dist/components/iab-panel/iab-panel.js +1 -1
  7. package/dist/components/iab-prompt/atoms/root.js +1 -1
  8. package/dist/components/iab-prompt/iab-prompt.js +1 -1
  9. package/dist/components/panel/atoms/root.js +1 -1
  10. package/dist/components/panel-trigger/atoms/root.js +1 -1
  11. package/dist/components/panel-trigger/panel-trigger.js +1 -1
  12. package/dist/components/panel-trigger/toolbar-loader.js +2 -0
  13. package/dist/components/preferences/atoms/root.js +1 -1
  14. package/dist/components/prompt/atoms/root.js +1 -1
  15. package/dist/components/shared/surface-styles.js +1 -1
  16. package/dist/devtools.js +1 -1
  17. package/dist/iab-dialog-deferred.js +2 -0
  18. package/dist/iab.js +1 -1
  19. package/dist/utils/deferred-module.js +1 -1
  20. package/dist/version.js +1 -1
  21. package/dist-types/chunk-warming.d.ts +8 -11
  22. package/dist-types/components/panel-trigger/toolbar-loader.d.ts +34 -0
  23. package/dist-types/components/shared/surface-styles.d.ts +26 -2
  24. package/dist-types/iab-dialog-deferred.d.ts +36 -0
  25. package/dist-types/iab.d.ts +2 -1
  26. package/dist-types/version.d.ts +1 -1
  27. package/docs/README.md +1 -0
  28. package/docs/concepts/choose-your-setup.md +5 -2
  29. package/docs/concepts/data-fetching.md +24 -10
  30. package/docs/concepts/modes.md +9 -6
  31. package/docs/frameworks/react/components/consent-banner.md +3 -3
  32. package/docs/frameworks/react/components/consent-dialog.md +3 -3
  33. package/docs/frameworks/react/components/consent-provider.md +12 -9
  34. package/docs/frameworks/react/components.md +3 -3
  35. package/docs/frameworks/react/content-security-policy.md +8 -2
  36. package/docs/frameworks/react/iab.md +19 -0
  37. package/docs/frameworks/react/quickstart.md +25 -79
  38. package/docs/frameworks/react/rendering.md +161 -139
  39. package/docs/frameworks/react/scripts.md +3 -3
  40. package/docs/frameworks/react/troubleshooting.md +17 -16
  41. package/docs/frameworks/react/upgrade-v3.md +5 -4
  42. package/docs/guides/banner-experiments.md +16 -0
  43. package/docs/integrations/overview.md +1 -0
  44. package/docs/integrations/vercel-speed-insights.md +306 -0
  45. package/package.json +7 -7
package/AGENTS.md CHANGED
@@ -125,5 +125,6 @@ These docs describe c15t v3. Find your app's row in Choose your setup, then foll
125
125
  - [TikTok Pixel](./docs/integrations/tiktok-pixel.md): Load the TikTok Pixel only after marketing consent with the c15t tiktokPixel helper, guard ttq event calls, and check it in DevTools.
126
126
  - [Umami Analytics](./docs/integrations/umami-analytics.md): Load the Umami Analytics tracker only after measurement consent with the c15t umamiAnalytics helper, point it at a self-hosted instance, and check it in DevTools.
127
127
  - [Vercel Analytics](./docs/integrations/vercel-analytics.md): Load the Vercel Web Analytics script only after measurement consent with the c15t vercelAnalytics helper, choose the debug script, and check it in DevTools.
128
+ - [Vercel Speed Insights](./docs/integrations/vercel-speed-insights.md): Load the Vercel Speed Insights collector only after measurement consent with the c15t vercelSpeedInsights helper, drop Web Vitals reports on revocation, and check it in DevTools.
128
129
  - [X Pixel](./docs/integrations/x-pixel.md): Load the X Pixel only after marketing consent with the c15t xPixel helper, guard twq conversion events, and check it in DevTools.
129
130
  - [YouTube](./docs/integrations/youtube.md): Gate YouTube embeds with c15t v3 in Next.js, TanStack Start, React, Nuxt, Vue, Astro, Svelte, SvelteKit or JavaScript.
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as o}from"react/jsx-runtime";import{registerDialogChunkWarmer as e,useIdleDialogWarming as n}from"./chunk-warming.js";import{useActiveUI as t}from"./hooks.js";import{createDeferredModule as r}from"./utils/deferred-module.js";let i=r(()=>import("./components/panel/index.js")),c=r(()=>import("./components/preferences/index.js"));e(()=>{i.preload()});let s=i.component(o=>o.ConsentDialog),l=c.component(o=>o.ConsentWidget),a=function(o,e,n){let t={};for(let r of e)Object.defineProperty(o,r,{configurable:!0,enumerable:!0,get:()=>(t[r]??=n(r),t[r])});return o},d=a(e=>{let r=t();return(n("banner"===r),!0===e.open||"dialog"===r||e.showTrigger)?o(s,{...e}):null},["Card","Header","HeaderTitle","HeaderDescription","Content","Footer","ConsentCustomizationCard","ConsentDialogFooter","ConsentDialogHeader","ConsentDialogHeaderTitle","ConsentDialogHeaderDescription","ConsentDialogContent","Overlay","Root"],o=>i.component(e=>e[o])),m=a(e=>o(l,{...e}),["AccordionTrigger","AccordionTriggerInner","AccordionContent","AccordionArrow","Accordion","Switch","AccordionItems","AccordionItem","VendorList","Root","AcceptAllButton","CustomizeButton","SaveButton","RejectButton","PolicyActions","Footer","FooterSubGroup"],o=>c.component(e=>e[o]));export{d as ConsentDialog,m as ConsentWidget};
2
+ import{jsx as o}from"react/jsx-runtime";import{registerDialogChunkWarmer as e,useIdleDialogWarming as t}from"./chunk-warming.js";import{FIRST_PAINT_SHEETS as n}from"./components/shared/first-paint-sheets.js";import{preloadSurfaceSheets as r}from"./components/shared/surface-styles.js";import{useActiveUI as i}from"./hooks.js";import{createDeferredModule as s}from"./utils/deferred-module.js";let c=s(()=>(r(n),import("./components/panel/index.js"))),a=s(()=>import("./components/preferences/index.js"));e(()=>{c.preload()});let m=c.component(o=>o.ConsentDialog),d=a.component(o=>o.ConsentWidget),l=function(o,e,t){let n={};for(let r of e)Object.defineProperty(o,r,{configurable:!0,enumerable:!0,get:()=>(n[r]??=t(r),n[r])});return o},p=l(e=>{let n=i();return(t("banner"===n),!0===e.open||"dialog"===n||e.showTrigger)?o(m,{...e}):null},["Card","Header","HeaderTitle","HeaderDescription","Content","Footer","ConsentCustomizationCard","ConsentDialogFooter","ConsentDialogHeader","ConsentDialogHeaderTitle","ConsentDialogHeaderDescription","ConsentDialogContent","Overlay","Root"],o=>c.component(e=>e[o])),g=l(e=>o(d,{...e}),["AccordionTrigger","AccordionTriggerInner","AccordionContent","AccordionArrow","Accordion","Switch","AccordionItems","AccordionItem","VendorList","Root","AcceptAllButton","CustomizeButton","SaveButton","RejectButton","PolicyActions","Footer","FooterSubGroup"],o=>a.component(e=>e[o]));export{p as ConsentDialog,g as ConsentWidget};
@@ -1 +1 @@
1
- let e;import{useEffect as n}from"react";import{useUIConfig as t}from"./ui-config-context.js";let r=new Set,o=!1,i=function(e){return r.add(e),o&&e(),()=>{r.delete(e)}},a=function(){for(let e of(o=!0,r))e()},l=new Set(["slow-2g","2g"]),u=3e3,g=function(){if("u"<typeof navigator||!1===navigator.onLine)return!1;let{connection:e}=navigator;return e?.saveData!==!0&&!l.has(e?.effectiveType??"")},s=0,c=!1,f=function(){c=!1,s>0&&g()&&a()},m=function(){if(c||o||!g())return;c=!0;let n=()=>{"function"==typeof window.requestIdleCallback?window.requestIdleCallback(f):window.setTimeout(f,200)},t=()=>{e??=performance.now();let t=u-(performance.now()-e);t>0?window.setTimeout(n,t):n()};if("complete"===document.readyState){let[n]=performance.getEntriesByType("navigation");e??=n?.loadEventEnd||performance.now(),t()}else window.addEventListener("load",t,{once:!0})},d=function(e){let{preloadDialog:r="idle"}=t(),o=e&&"idle"===r;n(()=>{if(o)return s+=1,m(),()=>{s-=1}},[o])},w=function(n={}){o=!1,s=0,c=!1,e=void 0,u=n.idleWarmDelayMs??0};export{i as registerDialogChunkWarmer,w as resetDialogChunkWarmingForTests,d as useIdleDialogWarming,a as warmDialogChunk};
1
+ import{useEffect as e}from"react";import{useUIConfig as n}from"./ui-config-context.js";let t=new Set,i=!1,r=function(e){return t.add(e),i&&e(),()=>{t.delete(e)}},a=function(){for(let e of(i=!0,t))e()},o=new Set(["slow-2g","2g"]),u=function(){if("u"<typeof navigator||!1===navigator.onLine)return!1;let{connection:e}=navigator;return e?.saveData!==!0&&!o.has(e?.effectiveType??"")},l=0,g=!1,s=function(){g=!1,l>0&&u()&&a()},c=function(){if(g||i||!u())return;g=!0;let e=()=>{"function"==typeof window.requestIdleCallback?window.requestIdleCallback(s):window.setTimeout(s,200)};"complete"===document.readyState?e():window.addEventListener("load",e,{once:!0})},f=function(t){let{preloadDialog:i="idle"}=n(),r=t&&"idle"===i;e(()=>{if(r)return l+=1,c(),()=>{l-=1}},[r])},m=function(){i=!1,l=0,g=!1};export{r as registerDialogChunkWarmer,m as resetDialogChunkWarmingForTests,f as useIdleDialogWarming,a as warmDialogChunk};
@@ -1 +1 @@
1
- import{Fragment as t,jsx as e,jsxs as o}from"react/jsx-runtime";import s from"@c15t/ui/styles/components/consent-gate";import{forwardRef as r}from"react";import{useTranslations as n}from"../../component-hooks/use-translations.js";import{useUIConfig as a}from"../../ui-config-context.js";import{getSlotProps as i,mergeSlotProps as l}from"../../utils/merge-slot-props.js";import{FIRST_PAINT_SHEETS as m}from"../shared/first-paint-sheets.js";import{Box as c}from"../shared/primitives/box.js";import{ConsentButton as p}from"../shared/primitives/button.js";import{SurfaceStyles as d}from"../shared/surface-styles.js";let f=r(({children:r,...n},a)=>o(t,{children:[e(d,{sheets:m,noStyle:n.noStyle}),e(c,{ref:a,baseClassName:s.placeholder,"data-testid":"consent-gate-placeholder",slotKey:"consent-gate.root",...n,children:r})]})),u=r(({children:t,category:o,...r},a)=>{let{consentGate:i,consentTypes:l}=n(),m=o&&i?.title?i.title.replace("{category}",l?.[o]?.title??o):void 0;return e(c,{ref:a,baseClassName:s.title,"data-testid":"consent-gate-title",slotKey:"consent-gate.title",...r,children:t??m})}),g=r(({children:t,category:o,className:s,style:r,...m},c)=>{let{consentGate:d,consentTypes:f}=n(),{components:u}=a(),g=l(i(u,"consent-gate.button"),{className:s,style:r}),h=f?.[o]?.title??o,y=d?.actionButton?.replace("{category}",h);return e(p,{mode:"stroke",size:"small",variant:"primary",...g,...m,ref:c,action:"open-consent-dialog",category:o,"data-testid":"consent-gate-button",children:t??y})});f.displayName="ConsentGateRoot",u.displayName="ConsentGateTitle",g.displayName="ConsentGateButton";export{g as ConsentGateButton,f as ConsentGateRoot,u as ConsentGateTitle};
1
+ import{Fragment as t,jsx as e,jsxs as o}from"react/jsx-runtime";import s from"@c15t/ui/styles/components/consent-gate";import{forwardRef as n}from"react";import{useTranslations as r}from"../../component-hooks/use-translations.js";import{useUIConfig as a}from"../../ui-config-context.js";import{getSlotProps as i,mergeSlotProps as l}from"../../utils/merge-slot-props.js";import{FIRST_PAINT_SHEETS as m}from"../shared/first-paint-sheets.js";import{Box as c}from"../shared/primitives/box.js";import{ConsentButton as p}from"../shared/primitives/button.js";import{SurfaceStyles as d,useSurfaceSheetsReady as f}from"../shared/surface-styles.js";let u=n(({children:n,...r},a)=>f(m,r.noStyle)?o(t,{children:[e(d,{sheets:m,noStyle:r.noStyle}),e(c,{ref:a,baseClassName:s.placeholder,"data-testid":"consent-gate-placeholder",slotKey:"consent-gate.root",...r,children:n})]}):null),y=n(({children:t,category:o,...n},a)=>{let{consentGate:i,consentTypes:l}=r(),m=o&&i?.title?i.title.replace("{category}",l?.[o]?.title??o):void 0;return e(c,{ref:a,baseClassName:s.title,"data-testid":"consent-gate-title",slotKey:"consent-gate.title",...n,children:t??m})}),g=n(({children:t,category:o,className:s,style:n,...m},c)=>{let{consentGate:d,consentTypes:f}=r(),{components:u}=a(),y=l(i(u,"consent-gate.button"),{className:s,style:n}),g=f?.[o]?.title??o,h=d?.actionButton?.replace("{category}",g);return e(p,{mode:"stroke",size:"small",variant:"primary",...y,...m,ref:c,action:"open-consent-dialog",category:o,"data-testid":"consent-gate-button",children:t??h})});u.displayName="ConsentGateRoot",y.displayName="ConsentGateTitle",g.displayName="ConsentGateButton";export{g as ConsentGateButton,u as ConsentGateRoot,y as ConsentGateTitle};
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as o,jsxs as e}from"react/jsx-runtime";import{isDialogDismissKey as t}from"@c15t/ui/primitives/dialog";import r from"@c15t/ui/styles/components/iab-consent-dialog";import{useEffect as i,useMemo as n,useState as s}from"react";import{createPortal as m}from"react-dom";import{ConsentTrackingContext as a}from"../../../context/consent-tracking-context.js";import{LocalThemeContext as l}from"../../../context/theme-context.js";import{useSetActiveUI as c}from"../../../hooks.js";import{useIABConsentManager as d}from"../../../hooks/use-iab-manager.js";import{useIsHydrated as u}from"../../../hooks/use-is-hydrated.js";import{useScrollLock as p}from"../../../hooks/use-scroll-lock.js";import{useTextDirection as f}from"../../../hooks/use-text-direction.js";import{useUIConfig as g}from"../../../ui-config-context.js";import{cnExt as h}from"../../../utils/cn.js";import{mergeSlotProps as j}from"../../../utils/merge-slot-props.js";import{IAB_DIALOG_SHEETS as b}from"../../shared/iab-dialog-sheets.js";import{SurfaceStyles as k}from"../../shared/surface-styles.js";import{IABConsentDialogOverlay as v}from"./overlay.js";let y=["iab"],x=({children:x,open:A,models:F=y,noStyle:L,disableAnimation:C,scrollLock:D,trapFocus:q,uiSource:w})=>{let{activeUI:B,translationConfig:E,iab:I,policyDialog:N,model:P}=d({preferences:{scrollLock:D,trapFocus:q}}),R=c(),{components:S}=g(),T=f(E.defaultLanguage),H=u(),[O,V]=s(!1),_=null!==P&&F.includes(P)&&(A??"dialog"===B),z=N.blocking,G=n(()=>({disableAnimation:C,noStyle:L,scrollLock:z,trapFocus:z}),[C,L,z]);p(!!(_&&z)),i(()=>{if(!_)return;let o=o=>{t(o.key)&&(o.preventDefault(),R("none"))};return document.addEventListener("keydown",o),()=>document.removeEventListener("keydown",o)},[_,R]),i(()=>{if(_){let o=requestAnimationFrame(()=>V(!0));return()=>cancelAnimationFrame(o)}if(C){let o=requestAnimationFrame(()=>V(!1));return()=>cancelAnimationFrame(o)}let o=setTimeout(()=>{V(!1)},150);return()=>clearTimeout(o)},[_,C]);let J=j(S?.["iab-dialog"]?.root,{baseClassName:h(r.root,C?void 0:O?r.dialogVisible:r.dialogHidden)}),K=n(()=>({uiSource:w??"iab_dialog"}),[w]);return H&&I?.config.enabled&&(_||O)?m(o(a.Provider,{value:K,children:e(l.Provider,{value:G,children:[o(k,{sheets:b,noStyle:L}),o(v,{isOpen:_}),o("div",{...J,"data-testid":"iab-consent-dialog-root",dir:T,children:x})]})}),document.body):null};x.displayName="IABConsentDialogRoot";export{x as IABConsentDialogRoot};
2
+ import{jsx as o,jsxs as e}from"react/jsx-runtime";import{isDialogDismissKey as t}from"@c15t/ui/primitives/dialog";import r from"@c15t/ui/styles/components/iab-consent-dialog";import{useEffect as i,useMemo as n,useState as s}from"react";import{createPortal as m}from"react-dom";import{ConsentTrackingContext as a}from"../../../context/consent-tracking-context.js";import{LocalThemeContext as l}from"../../../context/theme-context.js";import{useSetActiveUI as c}from"../../../hooks.js";import{useIABConsentManager as d}from"../../../hooks/use-iab-manager.js";import{useIsHydrated as u}from"../../../hooks/use-is-hydrated.js";import{useScrollLock as p}from"../../../hooks/use-scroll-lock.js";import{useTextDirection as f}from"../../../hooks/use-text-direction.js";import{useUIConfig as g}from"../../../ui-config-context.js";import{cnExt as h}from"../../../utils/cn.js";import{mergeSlotProps as j}from"../../../utils/merge-slot-props.js";import{IAB_DIALOG_SHEETS as b}from"../../shared/iab-dialog-sheets.js";import{SurfaceStyles as k,useSurfaceSheetsReady as v}from"../../shared/surface-styles.js";import{IABConsentDialogOverlay as y}from"./overlay.js";let x=["iab"],A=({children:A,open:F,models:L=x,noStyle:C,disableAnimation:D,scrollLock:q,trapFocus:w,uiSource:B})=>{let{activeUI:E,translationConfig:I,iab:N,policyDialog:P,model:R}=d({preferences:{scrollLock:q,trapFocus:w}}),S=c(),{components:T}=g(),H=f(I.defaultLanguage),O=u(),[V,_]=s(!1),z=v(b,C)&&null!==R&&L.includes(R)&&(F??"dialog"===E),G=P.blocking,J=n(()=>({disableAnimation:D,noStyle:C,scrollLock:G,trapFocus:G}),[D,C,G]);p(!!(z&&G)),i(()=>{if(!z)return;let o=o=>{t(o.key)&&(o.preventDefault(),S("none"))};return document.addEventListener("keydown",o),()=>document.removeEventListener("keydown",o)},[z,S]),i(()=>{if(z){let o=requestAnimationFrame(()=>_(!0));return()=>cancelAnimationFrame(o)}if(D){let o=requestAnimationFrame(()=>_(!1));return()=>cancelAnimationFrame(o)}let o=setTimeout(()=>{_(!1)},150);return()=>clearTimeout(o)},[z,D]);let K=j(T?.["iab-dialog"]?.root,{baseClassName:h(r.root,D?void 0:V?r.dialogVisible:r.dialogHidden)}),M=n(()=>({uiSource:B??"iab_dialog"}),[B]);return O&&N?.config.enabled&&(z||V)?m(o(a.Provider,{value:M,children:e(l.Provider,{value:J,children:[o(k,{sheets:b,noStyle:C}),o(y,{isOpen:z}),o("div",{...K,"data-testid":"iab-consent-dialog-root",dir:H,children:A})]})}),document.body):null};A.displayName="IABConsentDialogRoot";export{A as IABConsentDialogRoot};
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{Fragment as e,jsx as t,jsxs as o}from"react/jsx-runtime";import{applyPublisherRestrictionsToGVL as n}from"@c15t/iab/headless";import{isDialogDismissKey as i}from"@c15t/ui/primitives/dialog";import r from"@c15t/ui/styles/components/consent-actions";import a from"@c15t/ui/styles/components/iab-consent-dialog";import{useCallback as s,useEffect as l,useLayoutEffect as d,useMemo as c,useRef as m,useState as p}from"react";import{createPortal as u}from"react-dom";import{useHeadlessIABConsentUI as g}from"../../component-hooks/use-headless-iab-consent-ui.js";import{useTranslations as h}from"../../component-hooks/use-translations.js";import{ConsentDialogTrigger as b}from"../panel-trigger/index.js";import{Branding as y}from"../panel/atoms/card.js";import{ConsentTrackingContext as f}from"../../context/consent-tracking-context.js";import{LocalThemeContext as v}from"../../context/theme-context.js";import{useComponentConfig as C}from"../../hooks/use-component-config.js";import{useFocusTrap as S}from"../../hooks/use-focus-trap.js";import{useIABConsentManager as k}from"../../hooks/use-iab-manager.js";import{useScrollLock as N}from"../../hooks/use-scroll-lock.js";import{useTextDirection as I}from"../../hooks/use-text-direction.js";import{useUIConfig as x}from"../../ui-config-context.js";import{mergeSlotProps as L}from"../../utils/merge-slot-props.js";import{IAB_DIALOG_SHEETS as j}from"../shared/iab-dialog-sheets.js";import{SurfaceStyles as T}from"../shared/surface-styles.js";import{FeatureItem as A}from"./atoms/feature-item.js";import{IABConsentDialogOverlay as F}from"./atoms/overlay.js";import{PurposeItem as V}from"./atoms/purpose-item.js";import{StackItem as w}from"./atoms/stack-item.js";import{VendorList as P}from"./atoms/vendor-list.js";import{useIABDisplayModel as B}from"./hooks/use-display-model.js";import{useIABTranslations as R}from"./use-iab-translations.js";import*as $ from"../shared/ui/button/index.js";import*as M from"../shared/ui/tabs/index.js";let q=["iab"],z={tabIndex:-1},E=({open:E,noStyle:H,disableAnimation:D,scrollLock:W,trapFocus:G,hideBranding:O,initialTab:_,showTrigger:J=!1,models:K=q,uiSource:Q})=>{let U=R(),{common:X}=h(),{components:Y}=x(),{iab:Z,activeUI:ee,policyDialog:et,translationConfig:eo,model:en}=k({preferences:{scrollLock:W,trapFocus:G}}),{banner:ei,closeUI:er,openDialog:ea,performDialogAction:es}=g(),el=et.blocking,ed=I(eo.defaultLanguage),ec=m(null),em=m(null),ep=m(null),[eu,eg]=p(_??Z?.preferenceCenterTab??"purposes"),[eh,eb]=p(null),[ey,ef]=p(!1),[ev,eC]=p(!1),[eS,ek]=p(!1),eN=null!==en&&K.includes(en)&&(E??"dialog"===ee),eI=C({disableAnimation:D,noStyle:H,scrollLock:el,trapFocus:et.blocking}),{consentRows:ex,essentialRows:eL,essentialPartnerCount:ej,featureRows:eT,featuresStandardText:eA,purposeTabCount:eF,vendorTabCount:eV,data:{purposes:ew}}=B(),eP=Z?.gvl??null,eB=Z?.publisherRestrictions,eR=c(()=>eP?n(eP,eB):null,[eP,eB]),e$=s((e,t)=>{Z?.setPurposeConsent(e,t)},[Z]),eM=s((e,t)=>{Z?.setSpecialFeatureOptIn(e,t)},[Z]),eq=s((e,t)=>{Z?.setVendorConsent(e,t)},[Z]),ez=s((e,t)=>{Z?.setVendorLegitimateInterest(e,t)},[Z]),eE=s((e,t)=>{Z?.setPurposeLegitimateInterest(e,t)},[Z]),eH=async()=>{try{await es("accept")}catch{}},eD=async()=>{try{await es("reject")}catch{}},eW=async()=>{try{await es("customize")}catch{}},eG=s(()=>{er()},[er]),eO=e=>{eb(e),eg("vendors"),ea({tab:"vendors"})};S(!!(ev&&eN&&eI.trapFocus),ec,{initialFocus:"first-tabbable"}),N(!!(eN&&eI.scrollLock)),l(()=>{if(!eN)return;let e=e=>{i(e.key)&&(e.preventDefault(),eG())};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[eG,eN]),l(()=>{let e=requestAnimationFrame(()=>eC(!0));return()=>cancelAnimationFrame(e)},[]),l(()=>{if(eN){let e=requestAnimationFrame(()=>ek(!0));return()=>cancelAnimationFrame(e)}if(eI.disableAnimation){let e=requestAnimationFrame(()=>ek(!1));return()=>cancelAnimationFrame(e)}let e=setTimeout(()=>{ek(!1)},150);return()=>clearTimeout(e)},[eN,eI.disableAnimation]);let e_=m(!!_);l(()=>{let e=Z?.preferenceCenterTab;if(!(eN&&e))return;if(e_.current){e_.current=!1;return}let t=requestAnimationFrame(()=>{eg(e)});return()=>cancelAnimationFrame(t)},[eN,Z?.preferenceCenterTab]),d(()=>{let e,t;if("purposes"!==eu&&"vendors"!==eu)return;let o=em.current;if(!o||null===ep.current)return;let n=ep.current;if(ep.current=null,!window.matchMedia("(prefers-reduced-motion: reduce)").matches)return o.style.height=`${n}px`,o.style.overflow="hidden",o.style.transition="none",e=requestAnimationFrame(()=>{t=requestAnimationFrame(()=>{if(!o)return;o.style.height="auto";let e=o.getBoundingClientRect().height;if(o.style.height=`${n}px`,1>Math.abs(n-e)){o.style.height="",o.style.overflow="",o.style.transition="";return}o.getBoundingClientRect(),o.style.transition="height 180ms cubic-bezier(0.33, 1, 0.68, 1)",o.style.height=`${e}px`,o.addEventListener("transitionend",e=>{"height"===e.propertyName&&(o.style.height="",o.style.overflow="",o.style.transition="")},{once:!0})})}),()=>{cancelAnimationFrame(e),cancelAnimationFrame(t)}},[eu]);let eJ=s(e=>{em.current&&(ep.current=em.current.offsetHeight),eg(e),ea({tab:e})},[ea]),eK=c(()=>({uiSource:Q??"iab_dialog"}),[Q]);if(!ev||!Z?.config.enabled)return null;let eQ=Z.isLoadingGVL||!Z.gvl,eU=L(Y?.["iab-dialog"]?.root,{baseClassName:`${a.root} ${eS?a.dialogVisible:a.dialogHidden}`,noStyle:eI.noStyle}),eX=L(Y?.["iab-dialog"]?.card,{baseClassName:`${a.card} ${eS?a.contentVisible:a.contentHidden}`,noStyle:eI.noStyle}),eY=L(Y?.["iab-dialog"]?.header,{baseClassName:a.header,noStyle:eI.noStyle}),eZ=L(Y?.["iab-dialog"]?.headerContent,{baseClassName:a.headerContent,noStyle:eI.noStyle}),e1=L(Y?.["iab-dialog"]?.title,{baseClassName:a.title,noStyle:eI.noStyle}),e0=L(Y?.["iab-dialog"]?.description,{baseClassName:a.description,noStyle:eI.noStyle}),e2=L(Y?.["iab-dialog"]?.closeButton,{baseClassName:a.closeButton,noStyle:eI.noStyle}),e7=L(Y?.["iab-dialog"]?.body,{baseClassName:a.body,noStyle:eI.noStyle}),e4=L(Y?.["iab-dialog"]?.tabs,{baseClassName:a.tabsContainer,noStyle:eI.noStyle}),e5=L(Y?.["iab-dialog"]?.tabsList,{baseClassName:a.tabsList,noStyle:eI.noStyle}),e8=L(Y?.["iab-dialog"]?.tabTrigger,{baseClassName:a.tabButton,noStyle:eI.noStyle}),e6=L(Y?.["iab-dialog"]?.tabIndicator,{baseClassName:a.tabIndicator,noStyle:eI.noStyle}),e3=L(Y?.["iab-dialog"]?.content,{baseClassName:a.content,noStyle:eI.noStyle}),e9=L(Y?.["iab-dialog"]?.loading,{baseClassName:a.loadingContainer,noStyle:eI.noStyle}),te=L(Y?.["iab-dialog"]?.tabPanel,{baseClassName:a.tabPanel,noStyle:eI.noStyle}),tt=L(Y?.["iab-dialog"]?.specialPurposes,{baseClassName:a.specialPurposesSection,noStyle:eI.noStyle}),to=L(Y?.["iab-dialog"]?.consentNotice,{baseClassName:a.consentNotice,noStyle:eI.noStyle}),tn=L(Y?.["iab-dialog"]?.actions,{baseClassName:r.actionRoot,noStyle:eI.noStyle}),ti=L(Y?.["iab-dialog"]?.footer,{baseClassName:a.footer,noStyle:eI.noStyle,...tn}),tr=L(Y?.["iab-dialog"]?.actionGroup,{baseClassName:r.actionGroup,"data-direction":"row",noStyle:eI.noStyle}),ta=t(f.Provider,{value:eK,children:o(v.Provider,{value:eI,children:[t(T,{sheets:j,noStyle:eI.noStyle}),t(F,{isOpen:eN}),t("div",{...eU,"data-testid":"iab-consent-dialog-root",dir:ed,children:o("div",{"aria-describedby":"iab-consent-dialog-description",...eX,ref:ec,"aria-label":U.preferenceCenter.title,"aria-modal":eI.trapFocus?"true":void 0,role:"dialog",...z,"data-testid":"iab-consent-dialog-card",children:[o("div",{...eY,children:[o("div",{...eZ,children:[t("h2",{...e1,children:U.preferenceCenter.title}),t("p",{...e0,id:"iab-consent-dialog-description",children:U.preferenceCenter.description})]}),t("button",{...e2,type:"button","data-testid":"iab-consent-dialog-close",onClick:eG,"aria-label":X.close,children:o("svg",{"aria-hidden":"true",style:{height:"1rem",width:"1rem"},viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[t("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),t("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]}),o(M.Root,{...e7,noStyle:!0,onValueChange:e=>eJ(e),value:eu,children:[t("div",{...e4,children:o(M.List,{...e5,noStyle:!0,children:[o(M.Trigger,{...e8,noStyle:!0,value:"purposes",children:[U.preferenceCenter.tabs.purposes,!eQ&&` (${eF})`]}),o(M.Trigger,{...e8,noStyle:!0,value:"vendors",children:[U.preferenceCenter.tabs.vendors,!eQ&&` (${eV})`]}),t("div",{...e6,"aria-hidden":"true","data-active-tab":eu})]})}),t("div",{...e3,ref:em,children:eQ?o("div",{...e9,children:[t("div",{className:a.loadingSpinner}),t("p",{className:a.loadingText,children:U.common.loading})]}):o(e,{children:[o(M.Content,{...te,forceMount:!0,noStyle:!0,value:"purposes",children:[ex.map(e=>"stack"===e.kind?t(w,{stack:e,consents:Z.purposeConsents,onToggle:e$,vendorConsents:Z.vendorConsents,onVendorToggle:eq,onVendorClick:eO,vendorLegitimateInterests:Z.vendorLegitimateInterests,onVendorLegitimateInterestToggle:ez,purposeLegitimateInterests:Z.purposeLegitimateInterests,onPurposeLegitimateInterestToggle:eE},e.testId):t(V,{purpose:e,testId:e.testId,isEnabled:"special-feature"===e.toggle?Z.specialFeatureOptIns[e.id]??!1:Z.purposeConsents[e.id]??!1,onToggle:t=>{"special-feature"===e.toggle?eM(e.id,t):e$(e.id,t)},vendorConsents:Z.vendorConsents,onVendorToggle:eq,onVendorClick:eO,vendorLegitimateInterests:Z.vendorLegitimateInterests,onVendorLegitimateInterestToggle:ez,purposeLegitimateInterests:"purpose"===e.kind?Z.purposeLegitimateInterests:void 0,onPurposeLegitimateInterestToggle:"purpose"===e.kind?eE:void 0},e.testId)),eL.length>0&&o("div",{...tt,children:[o("div",{className:a.specialPurposesHeader,children:[o("button",{type:"button","aria-expanded":ey,onClick:()=>ef(!ey),className:a.purposeTrigger,children:[t("svg",{"aria-hidden":"true",className:a.purposeArrow,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:ey?t("path",{d:"M19 9l-7 7-7-7"}):t("path",{d:"M9 5l7 7-7 7"})}),o("div",{className:a.purposeInfo,children:[o("h3",{className:a.specialPurposesTitle,children:[U.preferenceCenter.specialPurposes.title,o("svg",{"aria-hidden":"true",className:a.lockIcon,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[t("rect",{x:"3",y:"11",width:"18",height:"11",rx:"2",ry:"2"}),t("path",{d:"M7 11V7a5 5 0 0 1 10 0v4"})]})]}),o("p",{className:a.purposeMeta,children:[ej," ",1===ej?U.preferenceCenter.vendorList.partnerSingular:U.preferenceCenter.vendorList.partnerPlural]})]})]}),t("div",{style:{position:"relative"},children:o("svg",{className:a.infoIcon,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2","aria-label":U.preferenceCenter.specialPurposes.tooltip,children:[t("circle",{cx:"12",cy:"12",r:"10"}),t("line",{x1:"12",y1:"16",x2:"12",y2:"12"}),t("line",{x1:"12",y1:"8",x2:"12.01",y2:"8"})]})})]}),ey&&t("div",{style:{padding:"0.75rem"},children:eL.map(e=>t(V,{purpose:e,testId:e.testId,isEnabled:!0,onToggle:()=>{},vendorConsents:Z.vendorConsents,onVendorToggle:eq,onVendorClick:eO,isLocked:!0},e.testId))})]}),eT.length>0&&o("section",{"aria-label":U.preferenceCenter.features.title,className:eI.noStyle?void 0:a.featuresSection,"data-testid":"iab-consent-dialog-features",children:[o("div",{className:eI.noStyle?void 0:a.featuresHeader,children:[t("h3",{className:eI.noStyle?void 0:a.featuresTitle,children:U.preferenceCenter.features.title}),t("p",{className:eI.noStyle?void 0:a.featuresDescription,children:eA??U.preferenceCenter.features.description})]}),t("div",{className:eI.noStyle?void 0:a.featuresList,children:eT.map(e=>t(A,{feature:e,testId:e.testId},e.testId))})]}),t("div",{...to,children:t("p",{className:a.consentNoticeText,children:U.preferenceCenter.footer.consentStorage})})]}),t(M.Content,{...te,forceMount:!0,noStyle:!0,value:"vendors",children:t(P,{vendorData:eR,purposes:ew,vendorConsents:Z.vendorConsents,onVendorToggle:eq,selectedVendorId:eh,onClearSelection:()=>eb(null),customVendors:Z.nonIABVendors,vendorLegitimateInterests:Z.vendorLegitimateInterests,onVendorLegitimateInterestToggle:ez})})]})})]}),o("div",{...ti,children:[o("div",{...tr,children:[t($.Root,{variant:"neutral",mode:"stroke",size:"small",onClick:eD,disabled:!ei.isReady,"data-action":"reject",children:U.common.rejectAll}),t($.Root,{variant:"neutral",mode:"stroke",size:"small",onClick:eH,disabled:!ei.isReady,"data-action":"accept",children:U.common.acceptAll})]}),t("div",{...tr,children:t($.Root,{variant:"primary",mode:"filled",size:"small",onClick:eW,disabled:eQ,"data-action":"customize",children:U.common.saveSettings})})]}),t(y,{hideBranding:O??!1,variant:"dialog-tag",slotContext:"iab-dialog","data-testid":"iab-consent-dialog-branding"})]})})]})}),ts=!0===J?{}:!1===J?null:J,tl=ts?t(b,{...ts}):null;return eN||eS?o(e,{children:[tl,u(ta,document.body)]}):tl};export{E as IABConsentDialog};
2
+ import{Fragment as e,jsx as t,jsxs as o}from"react/jsx-runtime";import{applyPublisherRestrictionsToGVL as n}from"@c15t/iab/headless";import{isDialogDismissKey as i}from"@c15t/ui/primitives/dialog";import r from"@c15t/ui/styles/components/consent-actions";import a from"@c15t/ui/styles/components/iab-consent-dialog";import{useCallback as s,useEffect as l,useLayoutEffect as d,useMemo as c,useRef as m,useState as p}from"react";import{createPortal as u}from"react-dom";import{useHeadlessIABConsentUI as g}from"../../component-hooks/use-headless-iab-consent-ui.js";import{useTranslations as h}from"../../component-hooks/use-translations.js";import{ConsentDialogTrigger as b}from"../panel-trigger/index.js";import{Branding as y}from"../panel/atoms/card.js";import{ConsentTrackingContext as f}from"../../context/consent-tracking-context.js";import{LocalThemeContext as v}from"../../context/theme-context.js";import{useComponentConfig as C}from"../../hooks/use-component-config.js";import{useFocusTrap as S}from"../../hooks/use-focus-trap.js";import{useIABConsentManager as k}from"../../hooks/use-iab-manager.js";import{useScrollLock as N}from"../../hooks/use-scroll-lock.js";import{useTextDirection as I}from"../../hooks/use-text-direction.js";import{useUIConfig as x}from"../../ui-config-context.js";import{mergeSlotProps as L}from"../../utils/merge-slot-props.js";import{IAB_DIALOG_SHEETS as j}from"../shared/iab-dialog-sheets.js";import{SurfaceStyles as T,useSurfaceSheetsReady as A}from"../shared/surface-styles.js";import{FeatureItem as F}from"./atoms/feature-item.js";import{IABConsentDialogOverlay as V}from"./atoms/overlay.js";import{PurposeItem as w}from"./atoms/purpose-item.js";import{StackItem as P}from"./atoms/stack-item.js";import{VendorList as B}from"./atoms/vendor-list.js";import{useIABDisplayModel as R}from"./hooks/use-display-model.js";import{useIABTranslations as $}from"./use-iab-translations.js";import*as M from"../shared/ui/button/index.js";import*as q from"../shared/ui/tabs/index.js";let z=["iab"],E={tabIndex:-1},H=({open:H,noStyle:D,disableAnimation:W,scrollLock:G,trapFocus:O,hideBranding:_,initialTab:J,showTrigger:K=!1,models:Q=z,uiSource:U})=>{let X=$(),{common:Y}=h(),{components:Z}=x(),{iab:ee,activeUI:et,policyDialog:eo,translationConfig:en,model:ei}=k({preferences:{scrollLock:G,trapFocus:O}}),{banner:er,closeUI:ea,openDialog:es,performDialogAction:el}=g(),ed=eo.blocking,ec=I(en.defaultLanguage),em=m(null),ep=m(null),eu=m(null),[eg,eh]=p(J??ee?.preferenceCenterTab??"purposes"),[eb,ey]=p(null),[ef,ev]=p(!1),[eC,eS]=p(!1),[ek,eN]=p(!1),eI=A(j,D)&&null!==ei&&Q.includes(ei)&&(H??"dialog"===et),ex=C({disableAnimation:W,noStyle:D,scrollLock:ed,trapFocus:eo.blocking}),{consentRows:eL,essentialRows:ej,essentialPartnerCount:eT,featureRows:eA,featuresStandardText:eF,purposeTabCount:eV,vendorTabCount:ew,data:{purposes:eP}}=R(),eB=ee?.gvl??null,eR=ee?.publisherRestrictions,e$=c(()=>eB?n(eB,eR):null,[eB,eR]),eM=s((e,t)=>{ee?.setPurposeConsent(e,t)},[ee]),eq=s((e,t)=>{ee?.setSpecialFeatureOptIn(e,t)},[ee]),ez=s((e,t)=>{ee?.setVendorConsent(e,t)},[ee]),eE=s((e,t)=>{ee?.setVendorLegitimateInterest(e,t)},[ee]),eH=s((e,t)=>{ee?.setPurposeLegitimateInterest(e,t)},[ee]),eD=async()=>{try{await el("accept")}catch{}},eW=async()=>{try{await el("reject")}catch{}},eG=async()=>{try{await el("customize")}catch{}},eO=s(()=>{ea()},[ea]),e_=e=>{ey(e),eh("vendors"),es({tab:"vendors"})};S(!!(eC&&eI&&ex.trapFocus),em,{initialFocus:"first-tabbable"}),N(!!(eI&&ex.scrollLock)),l(()=>{if(!eI)return;let e=e=>{i(e.key)&&(e.preventDefault(),eO())};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[eO,eI]),l(()=>{let e=requestAnimationFrame(()=>eS(!0));return()=>cancelAnimationFrame(e)},[]),l(()=>{if(eI){let e=requestAnimationFrame(()=>eN(!0));return()=>cancelAnimationFrame(e)}if(ex.disableAnimation){let e=requestAnimationFrame(()=>eN(!1));return()=>cancelAnimationFrame(e)}let e=setTimeout(()=>{eN(!1)},150);return()=>clearTimeout(e)},[eI,ex.disableAnimation]);let eJ=m(!!J);l(()=>{let e=ee?.preferenceCenterTab;if(!(eI&&e))return;if(eJ.current){eJ.current=!1;return}let t=requestAnimationFrame(()=>{eh(e)});return()=>cancelAnimationFrame(t)},[eI,ee?.preferenceCenterTab]),d(()=>{let e,t;if("purposes"!==eg&&"vendors"!==eg)return;let o=ep.current;if(!o||null===eu.current)return;let n=eu.current;if(eu.current=null,!window.matchMedia("(prefers-reduced-motion: reduce)").matches)return o.style.height=`${n}px`,o.style.overflow="hidden",o.style.transition="none",e=requestAnimationFrame(()=>{t=requestAnimationFrame(()=>{if(!o)return;o.style.height="auto";let e=o.getBoundingClientRect().height;if(o.style.height=`${n}px`,1>Math.abs(n-e)){o.style.height="",o.style.overflow="",o.style.transition="";return}o.getBoundingClientRect(),o.style.transition="height 180ms cubic-bezier(0.33, 1, 0.68, 1)",o.style.height=`${e}px`,o.addEventListener("transitionend",e=>{"height"===e.propertyName&&(o.style.height="",o.style.overflow="",o.style.transition="")},{once:!0})})}),()=>{cancelAnimationFrame(e),cancelAnimationFrame(t)}},[eg]);let eK=s(e=>{ep.current&&(eu.current=ep.current.offsetHeight),eh(e),es({tab:e})},[es]),eQ=c(()=>({uiSource:U??"iab_dialog"}),[U]);if(!eC||!ee?.config.enabled)return null;let eU=ee.isLoadingGVL||!ee.gvl,eX=L(Z?.["iab-dialog"]?.root,{baseClassName:`${a.root} ${ek?a.dialogVisible:a.dialogHidden}`,noStyle:ex.noStyle}),eY=L(Z?.["iab-dialog"]?.card,{baseClassName:`${a.card} ${ek?a.contentVisible:a.contentHidden}`,noStyle:ex.noStyle}),eZ=L(Z?.["iab-dialog"]?.header,{baseClassName:a.header,noStyle:ex.noStyle}),e1=L(Z?.["iab-dialog"]?.headerContent,{baseClassName:a.headerContent,noStyle:ex.noStyle}),e0=L(Z?.["iab-dialog"]?.title,{baseClassName:a.title,noStyle:ex.noStyle}),e2=L(Z?.["iab-dialog"]?.description,{baseClassName:a.description,noStyle:ex.noStyle}),e7=L(Z?.["iab-dialog"]?.closeButton,{baseClassName:a.closeButton,noStyle:ex.noStyle}),e4=L(Z?.["iab-dialog"]?.body,{baseClassName:a.body,noStyle:ex.noStyle}),e5=L(Z?.["iab-dialog"]?.tabs,{baseClassName:a.tabsContainer,noStyle:ex.noStyle}),e8=L(Z?.["iab-dialog"]?.tabsList,{baseClassName:a.tabsList,noStyle:ex.noStyle}),e6=L(Z?.["iab-dialog"]?.tabTrigger,{baseClassName:a.tabButton,noStyle:ex.noStyle}),e3=L(Z?.["iab-dialog"]?.tabIndicator,{baseClassName:a.tabIndicator,noStyle:ex.noStyle}),e9=L(Z?.["iab-dialog"]?.content,{baseClassName:a.content,noStyle:ex.noStyle}),te=L(Z?.["iab-dialog"]?.loading,{baseClassName:a.loadingContainer,noStyle:ex.noStyle}),tt=L(Z?.["iab-dialog"]?.tabPanel,{baseClassName:a.tabPanel,noStyle:ex.noStyle}),to=L(Z?.["iab-dialog"]?.specialPurposes,{baseClassName:a.specialPurposesSection,noStyle:ex.noStyle}),tn=L(Z?.["iab-dialog"]?.consentNotice,{baseClassName:a.consentNotice,noStyle:ex.noStyle}),ti=L(Z?.["iab-dialog"]?.actions,{baseClassName:r.actionRoot,noStyle:ex.noStyle}),tr=L(Z?.["iab-dialog"]?.footer,{baseClassName:a.footer,noStyle:ex.noStyle,...ti}),ta=L(Z?.["iab-dialog"]?.actionGroup,{baseClassName:r.actionGroup,"data-direction":"row",noStyle:ex.noStyle}),ts=t(f.Provider,{value:eQ,children:o(v.Provider,{value:ex,children:[t(T,{sheets:j,noStyle:ex.noStyle}),t(V,{isOpen:eI}),t("div",{...eX,"data-testid":"iab-consent-dialog-root",dir:ec,children:o("div",{"aria-describedby":"iab-consent-dialog-description",...eY,ref:em,"aria-label":X.preferenceCenter.title,"aria-modal":ex.trapFocus?"true":void 0,role:"dialog",...E,"data-testid":"iab-consent-dialog-card",children:[o("div",{...eZ,children:[o("div",{...e1,children:[t("h2",{...e0,children:X.preferenceCenter.title}),t("p",{...e2,id:"iab-consent-dialog-description",children:X.preferenceCenter.description})]}),t("button",{...e7,type:"button","data-testid":"iab-consent-dialog-close",onClick:eO,"aria-label":Y.close,children:o("svg",{"aria-hidden":"true",style:{height:"1rem",width:"1rem"},viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[t("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),t("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]}),o(q.Root,{...e4,noStyle:!0,onValueChange:e=>eK(e),value:eg,children:[t("div",{...e5,children:o(q.List,{...e8,noStyle:!0,children:[o(q.Trigger,{...e6,noStyle:!0,value:"purposes",children:[X.preferenceCenter.tabs.purposes,!eU&&` (${eV})`]}),o(q.Trigger,{...e6,noStyle:!0,value:"vendors",children:[X.preferenceCenter.tabs.vendors,!eU&&` (${ew})`]}),t("div",{...e3,"aria-hidden":"true","data-active-tab":eg})]})}),t("div",{...e9,ref:ep,children:eU?o("div",{...te,children:[t("div",{className:a.loadingSpinner}),t("p",{className:a.loadingText,children:X.common.loading})]}):o(e,{children:[o(q.Content,{...tt,forceMount:!0,noStyle:!0,value:"purposes",children:[eL.map(e=>"stack"===e.kind?t(P,{stack:e,consents:ee.purposeConsents,onToggle:eM,vendorConsents:ee.vendorConsents,onVendorToggle:ez,onVendorClick:e_,vendorLegitimateInterests:ee.vendorLegitimateInterests,onVendorLegitimateInterestToggle:eE,purposeLegitimateInterests:ee.purposeLegitimateInterests,onPurposeLegitimateInterestToggle:eH},e.testId):t(w,{purpose:e,testId:e.testId,isEnabled:"special-feature"===e.toggle?ee.specialFeatureOptIns[e.id]??!1:ee.purposeConsents[e.id]??!1,onToggle:t=>{"special-feature"===e.toggle?eq(e.id,t):eM(e.id,t)},vendorConsents:ee.vendorConsents,onVendorToggle:ez,onVendorClick:e_,vendorLegitimateInterests:ee.vendorLegitimateInterests,onVendorLegitimateInterestToggle:eE,purposeLegitimateInterests:"purpose"===e.kind?ee.purposeLegitimateInterests:void 0,onPurposeLegitimateInterestToggle:"purpose"===e.kind?eH:void 0},e.testId)),ej.length>0&&o("div",{...to,children:[o("div",{className:a.specialPurposesHeader,children:[o("button",{type:"button","aria-expanded":ef,onClick:()=>ev(!ef),className:a.purposeTrigger,children:[t("svg",{"aria-hidden":"true",className:a.purposeArrow,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:ef?t("path",{d:"M19 9l-7 7-7-7"}):t("path",{d:"M9 5l7 7-7 7"})}),o("div",{className:a.purposeInfo,children:[o("h3",{className:a.specialPurposesTitle,children:[X.preferenceCenter.specialPurposes.title,o("svg",{"aria-hidden":"true",className:a.lockIcon,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[t("rect",{x:"3",y:"11",width:"18",height:"11",rx:"2",ry:"2"}),t("path",{d:"M7 11V7a5 5 0 0 1 10 0v4"})]})]}),o("p",{className:a.purposeMeta,children:[eT," ",1===eT?X.preferenceCenter.vendorList.partnerSingular:X.preferenceCenter.vendorList.partnerPlural]})]})]}),t("div",{style:{position:"relative"},children:o("svg",{className:a.infoIcon,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2","aria-label":X.preferenceCenter.specialPurposes.tooltip,children:[t("circle",{cx:"12",cy:"12",r:"10"}),t("line",{x1:"12",y1:"16",x2:"12",y2:"12"}),t("line",{x1:"12",y1:"8",x2:"12.01",y2:"8"})]})})]}),ef&&t("div",{style:{padding:"0.75rem"},children:ej.map(e=>t(w,{purpose:e,testId:e.testId,isEnabled:!0,onToggle:()=>{},vendorConsents:ee.vendorConsents,onVendorToggle:ez,onVendorClick:e_,isLocked:!0},e.testId))})]}),eA.length>0&&o("section",{"aria-label":X.preferenceCenter.features.title,className:ex.noStyle?void 0:a.featuresSection,"data-testid":"iab-consent-dialog-features",children:[o("div",{className:ex.noStyle?void 0:a.featuresHeader,children:[t("h3",{className:ex.noStyle?void 0:a.featuresTitle,children:X.preferenceCenter.features.title}),t("p",{className:ex.noStyle?void 0:a.featuresDescription,children:eF??X.preferenceCenter.features.description})]}),t("div",{className:ex.noStyle?void 0:a.featuresList,children:eA.map(e=>t(F,{feature:e,testId:e.testId},e.testId))})]}),t("div",{...tn,children:t("p",{className:a.consentNoticeText,children:X.preferenceCenter.footer.consentStorage})})]}),t(q.Content,{...tt,forceMount:!0,noStyle:!0,value:"vendors",children:t(B,{vendorData:e$,purposes:eP,vendorConsents:ee.vendorConsents,onVendorToggle:ez,selectedVendorId:eb,onClearSelection:()=>ey(null),customVendors:ee.nonIABVendors,vendorLegitimateInterests:ee.vendorLegitimateInterests,onVendorLegitimateInterestToggle:eE})})]})})]}),o("div",{...tr,children:[o("div",{...ta,children:[t(M.Root,{variant:"neutral",mode:"stroke",size:"small",onClick:eW,disabled:!er.isReady,"data-action":"reject",children:X.common.rejectAll}),t(M.Root,{variant:"neutral",mode:"stroke",size:"small",onClick:eD,disabled:!er.isReady,"data-action":"accept",children:X.common.acceptAll})]}),t("div",{...ta,children:t(M.Root,{variant:"primary",mode:"filled",size:"small",onClick:eG,disabled:eU,"data-action":"customize",children:X.common.saveSettings})})]}),t(y,{hideBranding:_??!1,variant:"dialog-tag",slotContext:"iab-dialog","data-testid":"iab-consent-dialog-branding"})]})})]})}),tl=!0===K?{}:!1===K?null:K,td=tl?t(b,{...tl}):null;return eI||ek?o(e,{children:[td,u(ts,document.body)]}):td};export{H as IABConsentDialog};
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{Fragment as e,jsx as t,jsxs as o}from"react/jsx-runtime";import r from"@c15t/ui/styles/components/iab-consent-banner";import{forwardRef as n,useMemo as s}from"react";import{ConsentTrackingContext as a}from"../../../context/consent-tracking-context.js";import{LocalThemeContext as i}from"../../../context/theme-context.js";import{useActiveUI as m,useModel as l,useTranslations as c}from"../../../hooks.js";import{useIABConsentManager as d}from"../../../hooks/use-iab-manager.js";import{useLateEntry as p}from"../../../hooks/use-late-entry.js";import{useTextDirection as b}from"../../../hooks/use-text-direction.js";import{useUIConfig as f}from"../../../ui-config-context.js";import{mergeSlotProps as u}from"../../../utils/merge-slot-props.js";import{IAB_FIRST_PAINT_SHEETS as h}from"../../shared/iab-first-paint-sheets.js";import{SurfaceStyles as j}from"../../shared/surface-styles.js";import{IABConsentBannerOverlay as g}from"./overlay.js";let x=["iab"],y=n(({children:n,className:s,style:a,className:i,disableAnimation:d,noStyle:y,models:N=x,...k},v)=>{let B=m(),{components:C}=f(),$=l(),A=c(),I=b(A?.language??"en"),S=null!==$&&"banner"===B&&N.includes($),P=p(S)&&!d,R=u(C?.["iab-banner"]?.root,{baseClassName:[r.root],className:s||i,noStyle:y,style:a,...k}),E=y?R.className||"":`${R.className||""} ${r.bannerVisible}${d?"":` ${r.bannerEntering}`}`;return S?o(e,{children:[t(j,{sheets:h,noStyle:y}),t(g,{}),o("div",{ref:v,...R,className:E,"data-position":"ltr"===I?"bottom-left":"bottom-right","data-entry":P?"late":void 0,"data-testid":"iab-consent-banner-root","data-c15t-streamed":"",dir:I,tabIndex:-1,children:[n,t("span",{"data-c15t-stream-end":"",hidden:!0})]})]}):null}),N=({children:e,className:o,noStyle:r,disableAnimation:n,scrollLock:m,trapFocus:l,models:c,uiSource:p,...b})=>{let{policyBanner:f}=d({prompt:{scrollLock:m,trapFocus:l}}),u=f.blocking,h=s(()=>({disableAnimation:n,noStyle:r,scrollLock:u,trapFocus:u}),[n,r,u]),j=s(()=>({uiSource:p??"iab_banner"}),[p]);return t(a.Provider,{value:j,children:t(i.Provider,{value:h,children:t(y,{disableAnimation:n,className:o,noStyle:r,models:c,...b,children:e})})})};y.displayName="IABConsentBannerRootChildren";export{N as IABConsentBannerRoot};
2
+ import{Fragment as e,jsx as t,jsxs as o}from"react/jsx-runtime";import r from"@c15t/ui/styles/components/iab-consent-banner";import{forwardRef as n,useMemo as s}from"react";import{ConsentTrackingContext as a}from"../../../context/consent-tracking-context.js";import{LocalThemeContext as i}from"../../../context/theme-context.js";import{useActiveUI as m,useModel as l,useTranslations as c}from"../../../hooks.js";import{useIABConsentManager as d}from"../../../hooks/use-iab-manager.js";import{useLateEntry as p}from"../../../hooks/use-late-entry.js";import{useTextDirection as b}from"../../../hooks/use-text-direction.js";import{useUIConfig as f}from"../../../ui-config-context.js";import{mergeSlotProps as u}from"../../../utils/merge-slot-props.js";import{IAB_FIRST_PAINT_SHEETS as h}from"../../shared/iab-first-paint-sheets.js";import{SurfaceStyles as j,useSurfaceSheetsReady as g}from"../../shared/surface-styles.js";import{IABConsentBannerOverlay as x}from"./overlay.js";let y=["iab"],N=n(({children:n,className:s,style:a,className:i,disableAnimation:d,noStyle:N,models:k=y,...v},B)=>{let C=m(),{components:$}=f(),A=l(),I=c(),S=b(I?.language??"en"),P=g(h,N)&&null!==A&&"banner"===C&&k.includes(A),R=p(P)&&!d,E=u($?.["iab-banner"]?.root,{baseClassName:[r.root],className:s||i,noStyle:N,style:a,...v}),F=N?E.className||"":`${E.className||""} ${r.bannerVisible}${d?"":` ${r.bannerEntering}`}`;return P?o(e,{children:[t(j,{sheets:h,noStyle:N}),t(x,{}),o("div",{ref:B,...E,className:F,"data-position":"ltr"===S?"bottom-left":"bottom-right","data-entry":R?"late":void 0,"data-testid":"iab-consent-banner-root","data-c15t-streamed":"",dir:S,tabIndex:-1,children:[n,t("span",{"data-c15t-stream-end":"",hidden:!0})]})]}):null}),k=({children:e,className:o,noStyle:r,disableAnimation:n,scrollLock:m,trapFocus:l,models:c,uiSource:p,...b})=>{let{policyBanner:f}=d({prompt:{scrollLock:m,trapFocus:l}}),u=f.blocking,h=s(()=>({disableAnimation:n,noStyle:r,scrollLock:u,trapFocus:u}),[n,r,u]),j=s(()=>({uiSource:p??"iab_banner"}),[p]);return t(a.Provider,{value:j,children:t(i.Provider,{value:h,children:t(N,{disableAnimation:n,className:o,noStyle:r,models:c,...b,children:e})})})};N.displayName="IABConsentBannerRootChildren";export{k as IABConsentBannerRoot};
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as e,jsxs as t}from"react/jsx-runtime";import n from"@c15t/ui/styles/components/consent-actions";import a from"@c15t/ui/styles/components/iab-consent-banner";import{useHeadlessIABConsentUI as o}from"../../component-hooks/use-headless-iab-consent-ui.js";import{Box as i}from"../shared/primitives/box.js";import{BrandingLink as r}from"../shared/ui/branding.js";import{useComponentConfig as s}from"../../hooks/use-component-config.js";import{useIABConsentManager as l}from"../../hooks/use-iab-manager.js";import{useUIConfig as c}from"../../ui-config-context.js";import{mergeSlotProps as m}from"../../utils/merge-slot-props.js";import{useIABTranslations as b}from"../iab-panel/use-iab-translations.js";import{IABConsentBannerCard as d}from"./atoms/card.js";import{IABConsentBannerRoot as p}from"./atoms/root.js";import*as u from"../shared/ui/button/index.js";let h=({noStyle:h,disableAnimation:y,scrollLock:S,trapFocus:f,primaryButton:C="customize",models:g,uiSource:k})=>{let j=b(),{iab:N,banner:v,openVendorsDialog:z,performBannerAction:L}=o(),{policyBanner:x}=l({prompt:{scrollLock:S,trapFocus:f}}),{components:A}=c(),I=s({disableAnimation:y,noStyle:h,scrollLock:x.blocking,trapFocus:x.blocking}),R=async()=>{try{await L("accept")}catch{}},w=async()=>{try{await L("reject")}catch{}};if(!N?.config.enabled||!v.isReady)return null;let M=j.banner.description.replace("{partnerCount}",String(v.vendorCount)),B=j.banner.partnersLink.replace("{count}",String(v.vendorCount)),F=j.banner.scopeServiceSpecific,K=m(A?.["iab-banner"]?.title,{baseClassName:a.title,noStyle:I.noStyle}),G=m(A?.["iab-banner"]?.description,{baseClassName:a.description,noStyle:I.noStyle}),$=m(A?.["iab-banner"]?.partnersLink,{baseClassName:a.partnersLink,noStyle:I.noStyle}),E=m(A?.["iab-banner"]?.purposeList,{baseClassName:a.purposeList,noStyle:I.noStyle}),q=m(A?.["iab-banner"]?.purposeMore,{baseClassName:a.purposeMore,noStyle:I.noStyle}),D=m(A?.["iab-banner"]?.legitimateInterestNotice,{baseClassName:a.legitimateInterestNotice,noStyle:I.noStyle}),H=m(A?.["iab-banner"]?.actions,{baseClassName:n.actionRoot,"data-direction":"row","data-split":!0,noStyle:I.noStyle}),J=m(A?.["iab-banner"]?.actionGroup,{baseClassName:n.actionGroup,"data-direction":"row",noStyle:I.noStyle});return e(p,{...I,models:g,uiSource:k,children:t(i,{baseClassName:a.cardShell,slotKey:"iab-banner.cardShell",children:[e(r,{hideBranding:!1,variant:"banner-tag",slotContext:"iab-banner","data-testid":"iab-consent-banner-branding"}),t(d,{"aria-label":j.banner.title,children:[t(i,{baseClassName:a.header,slotKey:"iab-banner.header","data-testid":"iab-consent-banner-header",children:[e("h2",{...K,children:j.banner.title}),t("p",{...G,children:[M.split(B)[0],e("button",{...$,type:"button","data-testid":"iab-consent-banner-partners-link",onClick:()=>{z()},onMouseEnter:()=>{},children:B}),M.split(B)[1]]}),t("ul",{...E,children:[v.displayItems.map((t,n)=>e("li",{children:t},n)),v.remainingCount>0&&e("li",{...q,children:j.banner.andMore.replace("{count}",String(v.remainingCount))})]}),e("p",{...D,children:`${j.banner.legitimateInterestNotice} ${F}`})]}),t(i,{baseClassName:a.footer,slotKey:"iab-banner.footer","data-testid":"iab-consent-banner-footer",...H,children:[t("div",{...J,children:[e(u.Root,{variant:"reject"===C?"primary":"neutral",mode:"stroke",size:"small",onClick:w,"data-action":"reject","data-testid":"iab-consent-banner-reject-button",children:j.common.rejectAll}),e(u.Root,{variant:"accept"===C?"primary":"neutral",mode:"accept"===C?"filled":"stroke",size:"small",onClick:R,"data-action":"accept","data-testid":"iab-consent-banner-accept-button",children:j.common.acceptAll})]}),e("div",{...J,children:e(u.Root,{variant:"customize"===C?"primary":"neutral",mode:"customize"===C?"filled":"stroke",size:"small",onClick:()=>{L("customize")},"data-action":"customize","data-testid":"iab-consent-banner-customize-button",children:j.common.customize})})]})]})]})})};export{h as IABConsentBanner};
2
+ import{jsx as e,jsxs as n}from"react/jsx-runtime";import t from"@c15t/ui/styles/components/consent-actions";import a from"@c15t/ui/styles/components/iab-consent-banner";import{warmDialogChunk as o}from"../../chunk-warming.js";import{useHeadlessIABConsentUI as r}from"../../component-hooks/use-headless-iab-consent-ui.js";import{Box as i}from"../shared/primitives/box.js";import{BrandingLink as s}from"../shared/ui/branding.js";import{useComponentConfig as c}from"../../hooks/use-component-config.js";import{useIABConsentManager as l}from"../../hooks/use-iab-manager.js";import{useUIConfig as m}from"../../ui-config-context.js";import{mergeSlotProps as b}from"../../utils/merge-slot-props.js";import{useIABTranslations as d}from"../iab-panel/use-iab-translations.js";import{IABConsentBannerCard as p}from"./atoms/card.js";import{IABConsentBannerRoot as u}from"./atoms/root.js";import*as h from"../shared/ui/button/index.js";let y=({noStyle:y,disableAnimation:S,scrollLock:f,trapFocus:C,primaryButton:g="customize",models:k,uiSource:j})=>{let N=d(),{iab:v,banner:z,openVendorsDialog:L,performBannerAction:x}=r(),{policyBanner:F}=l({prompt:{scrollLock:f,trapFocus:C}}),{components:w}=m(),A=c({disableAnimation:S,noStyle:y,scrollLock:F.blocking,trapFocus:F.blocking}),I=async()=>{try{await x("accept")}catch{}},R=async()=>{try{await x("reject")}catch{}};if(!v?.config.enabled||!z.isReady)return null;let B=N.banner.description.replace("{partnerCount}",String(z.vendorCount)),E=N.banner.partnersLink.replace("{count}",String(z.vendorCount)),K=N.banner.scopeServiceSpecific,M=b(w?.["iab-banner"]?.title,{baseClassName:a.title,noStyle:A.noStyle}),P=b(w?.["iab-banner"]?.description,{baseClassName:a.description,noStyle:A.noStyle}),G=b(w?.["iab-banner"]?.partnersLink,{baseClassName:a.partnersLink,noStyle:A.noStyle}),$=b(w?.["iab-banner"]?.purposeList,{baseClassName:a.purposeList,noStyle:A.noStyle}),q=b(w?.["iab-banner"]?.purposeMore,{baseClassName:a.purposeMore,noStyle:A.noStyle}),D=b(w?.["iab-banner"]?.legitimateInterestNotice,{baseClassName:a.legitimateInterestNotice,noStyle:A.noStyle}),H=b(w?.["iab-banner"]?.actions,{baseClassName:t.actionRoot,"data-direction":"row","data-split":!0,noStyle:A.noStyle}),J=b(w?.["iab-banner"]?.actionGroup,{baseClassName:t.actionGroup,"data-direction":"row",noStyle:A.noStyle});return e(u,{...A,models:k,uiSource:j,children:n(i,{baseClassName:a.cardShell,slotKey:"iab-banner.cardShell",children:[e(s,{hideBranding:!1,variant:"banner-tag",slotContext:"iab-banner","data-testid":"iab-consent-banner-branding"}),n(p,{"aria-label":N.banner.title,children:[n(i,{baseClassName:a.header,slotKey:"iab-banner.header","data-testid":"iab-consent-banner-header",children:[e("h2",{...M,children:N.banner.title}),n("p",{...P,children:[B.split(E)[0],e("button",{...G,type:"button","data-testid":"iab-consent-banner-partners-link",onClick:()=>{L()},onFocus:e=>{G.onFocus?.(e),o()},onPointerEnter:e=>{G.onPointerEnter?.(e),o()},children:E}),B.split(E)[1]]}),n("ul",{...$,children:[z.displayItems.map((n,t)=>e("li",{children:n},t)),z.remainingCount>0&&e("li",{...q,children:N.banner.andMore.replace("{count}",String(z.remainingCount))})]}),e("p",{...D,children:`${N.banner.legitimateInterestNotice} ${K}`})]}),n(i,{baseClassName:a.footer,slotKey:"iab-banner.footer","data-testid":"iab-consent-banner-footer",...H,children:[n("div",{...J,children:[e(h.Root,{variant:"reject"===g?"primary":"neutral",mode:"stroke",size:"small",onClick:R,"data-action":"reject","data-testid":"iab-consent-banner-reject-button",children:N.common.rejectAll}),e(h.Root,{variant:"accept"===g?"primary":"neutral",mode:"accept"===g?"filled":"stroke",size:"small",onClick:I,"data-action":"accept","data-testid":"iab-consent-banner-accept-button",children:N.common.acceptAll})]}),e("div",{...J,children:e(h.Root,{variant:"customize"===g?"primary":"neutral",mode:"customize"===g?"filled":"stroke",size:"small",onClick:()=>{x("customize")},onFocus:o,onPointerEnter:o,"data-action":"customize","data-testid":"iab-consent-banner-customize-button",children:N.common.customize})})]})]})]})})};export{y as IABConsentBanner};
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{Fragment as o,jsx as e,jsxs as t}from"react/jsx-runtime";import{isDialogDismissKey as r}from"@c15t/ui/primitives/dialog";import i from"@c15t/ui/styles/components/consent-dialog";import{useEffect as n,useMemo as s,useRef as l,useState as a}from"react";import{createPortal as m}from"react-dom";import{useHeadlessConsentUI as c}from"../../../component-hooks/use-headless-consent-ui.js";import{ConsentTrackingContext as d}from"../../../context/consent-tracking-context.js";import{LocalThemeContext as u}from"../../../context/theme-context.js";import{useActiveUI as p,useHasConsentUI as f,useModel as h}from"../../../hooks.js";import{useFocusTrap as g}from"../../../hooks/use-focus-trap.js";import{useIABPolicyGuard as b}from"../../../hooks/use-iab-policy-guard.js";import{useIsHydrated as k}from"../../../hooks/use-is-hydrated.js";import{useScrollLock as j}from"../../../hooks/use-scroll-lock.js";import{useTextDirection as y}from"../../../hooks/use-text-direction.js";import{useTheme as v}from"../../../hooks/use-theme.js";import{useTranslationLanguage as x}from"../../../kernel-selector.js";import{useUIConfig as F}from"../../../ui-config-context.js";import{cnExt as A}from"../../../utils/cn.js";import{mergeSlotProps as L}from"../../../utils/merge-slot-props.js";import{DIALOG_SHEETS as N}from"../../shared/dialog-sheets.js";import{SurfaceStyles as S}from"../../shared/surface-styles.js";import{Overlay as C}from"./overlay.js";let q=["opt-in","opt-out","none"],w=({children:w,open:D,models:E=q,noStyle:H,disableAnimation:I,scrollLock:P,trapFocus:R,overlay:T,uiSource:V,className:z,style:B,...G})=>{var J;let K,M,O;b();let Q=v(),{components:U}=F(),W=p(),X=h(),Y=x(),{closeUI:Z,dialog:$}=c({preferences:{scrollLock:P,trapFocus:R}}),{disableAnimation:_,noStyle:oo,scrollLock:oe,trapFocus:ot}=(K=Q.disableAnimation,M=Q.noStyle,{disableAnimation:I??K??!1,noStyle:H??M??!1,scrollLock:O=$.blocking,trapFocus:O}),or=y(Y),oi=(J=f(),!!J&&!!E.includes(X??"opt-in")&&(D??"dialog"===W)),[on,os]=a(!1),ol=l(null),oa=l(null),om=k(),oc=Q.theme?.motion?.duration?.normal;n(()=>{if(oi){let o=requestAnimationFrame(()=>os(!0));return()=>cancelAnimationFrame(o)}if(_){let o=requestAnimationFrame(()=>os(!1));return()=>cancelAnimationFrame(o)}let o=setTimeout(()=>os(!1),Number.parseInt((oc||"200ms").replace("ms",""),10));return()=>clearTimeout(o)},[oi,_,oc]),g(oi&&ot,oa,{initialFocus:"first-tabbable"}),n(()=>{if(!oi)return;let o=o=>{r(o.key)&&(o.preventDefault(),Z())};return document.addEventListener("keydown",o),()=>document.removeEventListener("keydown",o)},[Z,oi]),j(oi&&oe);let od=_?i.root:A(i.root,on?i.dialogVisible:i.dialogHidden),ou=L(U?.dialog?.root,{baseClassName:od,className:z,noStyle:oo,style:B,...G}),op=L(U?.dialog?.container,{baseClassName:A(i.container,!_&&(on?i.contentVisible:i.contentHidden)),noStyle:oo}),of=s(()=>({disableAnimation:_,noStyle:oo,scrollLock:oe,theme:Q.theme,trapFocus:ot}),[_,Q.theme,oo,oe,ot]),oh=s(()=>({uiSource:V??"dialog"}),[V]),og=$.blocking?"true":void 0,ob=e(d.Provider,{value:oh,children:e(u.Provider,{value:of,children:oi&&t(o,{children:[e(S,{sheets:N,noStyle:oo}),$.blocking&&!1!==T?T??e(C,{open:oi}):null,e("div",{ref:ol,"data-slot":"dialog-positioner","data-blocking":og,...ou,className:ou.className,children:e("div",{ref:oa,...op,"aria-describedby":"consent-dialog-description","aria-labelledby":"consent-dialog-title","aria-modal":ot?"true":void 0,"data-blocking":og,"data-testid":"consent-dialog-root",dir:or,role:"dialog",tabIndex:-1,children:w})})]})})});return om?m(ob,document.body):null},D=w;export{w as ConsentDialogRoot,D as Root};
2
+ import{Fragment as o,jsx as e,jsxs as t}from"react/jsx-runtime";import{isDialogDismissKey as r}from"@c15t/ui/primitives/dialog";import i from"@c15t/ui/styles/components/consent-dialog";import{useEffect as n,useMemo as s,useRef as l,useState as a}from"react";import{createPortal as m}from"react-dom";import{useHeadlessConsentUI as c}from"../../../component-hooks/use-headless-consent-ui.js";import{ConsentTrackingContext as d}from"../../../context/consent-tracking-context.js";import{LocalThemeContext as u}from"../../../context/theme-context.js";import{useActiveUI as p,useHasConsentUI as f,useModel as h}from"../../../hooks.js";import{useFocusTrap as g}from"../../../hooks/use-focus-trap.js";import{useIABPolicyGuard as b}from"../../../hooks/use-iab-policy-guard.js";import{useIsHydrated as k}from"../../../hooks/use-is-hydrated.js";import{useScrollLock as j}from"../../../hooks/use-scroll-lock.js";import{useTextDirection as y}from"../../../hooks/use-text-direction.js";import{useTheme as v}from"../../../hooks/use-theme.js";import{useTranslationLanguage as x}from"../../../kernel-selector.js";import{useUIConfig as F}from"../../../ui-config-context.js";import{cnExt as A}from"../../../utils/cn.js";import{mergeSlotProps as L}from"../../../utils/merge-slot-props.js";import{DIALOG_SHEETS as N}from"../../shared/dialog-sheets.js";import{SurfaceStyles as S,useSurfaceSheetsReady as C}from"../../shared/surface-styles.js";import{Overlay as q}from"./overlay.js";let w=["opt-in","opt-out","none"],D=({children:D,open:E,models:H=w,noStyle:I,disableAnimation:P,scrollLock:R,trapFocus:T,overlay:V,uiSource:z,className:B,style:G,...J})=>{var K;let M,O,Q;b();let U=v(),{components:W}=F(),X=p(),Y=h(),Z=x(),{closeUI:$,dialog:_}=c({preferences:{scrollLock:R,trapFocus:T}}),{disableAnimation:oo,noStyle:oe,scrollLock:ot,trapFocus:or}=(M=U.disableAnimation,O=U.noStyle,{disableAnimation:P??M??!1,noStyle:I??O??!1,scrollLock:Q=_.blocking,trapFocus:Q}),oi=y(Z),on=f(),os=(K=C(N,oe),!!on&&!!H.includes(Y??"opt-in")&&K&&(E??"dialog"===X)),[ol,oa]=a(!1),om=l(null),oc=l(null),od=k(),ou=U.theme?.motion?.duration?.normal;n(()=>{if(os){let o=requestAnimationFrame(()=>oa(!0));return()=>cancelAnimationFrame(o)}if(oo){let o=requestAnimationFrame(()=>oa(!1));return()=>cancelAnimationFrame(o)}let o=setTimeout(()=>oa(!1),Number.parseInt((ou||"200ms").replace("ms",""),10));return()=>clearTimeout(o)},[os,oo,ou]),g(os&&or,oc,{initialFocus:"first-tabbable"}),n(()=>{if(!os)return;let o=o=>{r(o.key)&&(o.preventDefault(),$())};return document.addEventListener("keydown",o),()=>document.removeEventListener("keydown",o)},[$,os]),j(os&&ot);let op=oo?i.root:A(i.root,ol?i.dialogVisible:i.dialogHidden),of=L(W?.dialog?.root,{baseClassName:op,className:B,noStyle:oe,style:G,...J}),oh=L(W?.dialog?.container,{baseClassName:A(i.container,!oo&&(ol?i.contentVisible:i.contentHidden)),noStyle:oe}),og=s(()=>({disableAnimation:oo,noStyle:oe,scrollLock:ot,theme:U.theme,trapFocus:or}),[oo,U.theme,oe,ot,or]),ob=s(()=>({uiSource:z??"dialog"}),[z]),ok=_.blocking?"true":void 0,oj=e(d.Provider,{value:ob,children:e(u.Provider,{value:og,children:os&&t(o,{children:[e(S,{sheets:N,noStyle:oe}),_.blocking&&!1!==V?V??e(q,{open:os}):null,e("div",{ref:om,"data-slot":"dialog-positioner","data-blocking":ok,...of,className:of.className,children:e("div",{ref:oc,...oh,"aria-describedby":"consent-dialog-description","aria-labelledby":"consent-dialog-title","aria-modal":or?"true":void 0,"data-blocking":ok,"data-testid":"consent-dialog-root",dir:oi,role:"dialog",tabIndex:-1,children:D})})]})})});return od?m(oj,document.body):null},E=D;export{D as ConsentDialogRoot,E as Root};
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as r,jsxs as o}from"react/jsx-runtime";import{createContext as t,useContext as e,useMemo as s}from"react";import{createPortal as i}from"react-dom";import{useConsentDialogTrigger as n}from"../../../component-hooks/use-panel-trigger.js";import{useBranding as m}from"../../../hooks.js";import{useIsHydrated as g}from"../../../hooks/use-is-hydrated.js";import{FIRST_PAINT_SHEETS as a}from"../../shared/first-paint-sheets.js";import{SurfaceStyles as l}from"../../shared/surface-styles.js";import{useDraggable as p}from"../use-draggable.js";let u=t(null),f=function(){let r=e(u);if(!r)throw Error("ConsentDialogTrigger components must be used within a ConsentDialogTrigger.Root");return r},d=({children:t,defaultPosition:e="bottom-right",persistPosition:f=!0,showWhen:d="always",visible:h,onPositionChange:c,onClick:j})=>{let T=m()??"c15t",{isVisible:C,openDialog:b}=n({onClick:j,showWhen:d}),x=h??C,{corner:y,isDragging:k,isSnapping:w,wasDragged:D,handlers:P,dragStyle:R}=p({defaultPosition:e,onPositionChange:c,persistPosition:f}),v=g(),E=s(()=>({branding:T,corner:y,dragStyle:R,handlers:P,isDragging:k,isSnapping:w,isVisible:x,openDialog:b,wasDragged:D}),[T,y,R,P,k,w,x,b,D]);return v&&x?i(o(u.Provider,{value:E,children:[r(l,{sheets:a}),t]}),document.body):null};d.displayName="ConsentDialogTrigger.Root";export{u as TriggerContext,d as TriggerRoot,f as useTriggerContext};
2
+ import{jsx as r,jsxs as o}from"react/jsx-runtime";import{createContext as t,useContext as e,useMemo as s}from"react";import{createPortal as i}from"react-dom";import{useConsentDialogTrigger as n}from"../../../component-hooks/use-panel-trigger.js";import{useBranding as m}from"../../../hooks.js";import{useIsHydrated as g}from"../../../hooks/use-is-hydrated.js";import{FIRST_PAINT_SHEETS as a}from"../../shared/first-paint-sheets.js";import{SurfaceStyles as l,useSurfaceSheetsReady as p}from"../../shared/surface-styles.js";import{useDraggable as u}from"../use-draggable.js";let f=t(null),d=function(){let r=e(f);if(!r)throw Error("ConsentDialogTrigger components must be used within a ConsentDialogTrigger.Root");return r},h=({children:t,defaultPosition:e="bottom-right",persistPosition:d=!0,showWhen:h="always",visible:c,onPositionChange:j,onClick:T})=>{let C=m()??"c15t",{isVisible:b,openDialog:x}=n({onClick:T,showWhen:h}),y=c??b,{corner:k,isDragging:w,isSnapping:D,wasDragged:P,handlers:R,dragStyle:v}=u({defaultPosition:e,onPositionChange:j,persistPosition:d}),E=g(),N=p(a),V=s(()=>({branding:C,corner:k,dragStyle:v,handlers:R,isDragging:w,isSnapping:D,isVisible:y,openDialog:x,wasDragged:P}),[C,k,v,R,w,D,y,x,P]);return E&&y&&N?i(o(f.Provider,{value:V,children:[r(l,{sheets:a}),t]}),document.body):null};h.displayName="ConsentDialogTrigger.Root";export{f as TriggerContext,h as TriggerRoot,d as useTriggerContext};
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as o}from"react/jsx-runtime";import{useMemo as t}from"react";import{useDevToolsLauncherAvailable as r}from"../../devtools-launcher.js";import{TriggerButton as e}from"./atoms/button.js";import{TriggerIcon as i}from"./atoms/icon.js";import{TriggerRoot as n,useTriggerContext as s}from"./atoms/root.js";import{TriggerText as a}from"./atoms/text.js";import{TriggerToolbar as m}from"./atoms/toolbar.js";let g=[],l=({icon:s="branding",defaultPosition:a="bottom-right",persistPosition:l=!0,ariaLabel:c="Open privacy settings",showWhen:p="always",size:f="md",className:T,noStyle:j,onClick:u,onPositionChange:b})=>{let d=r(),h=t(()=>({className:T,icon:s,label:c}),[c,T,s]);return o(n,{defaultPosition:a,persistPosition:l,showWhen:p,onClick:u,onPositionChange:b,children:d?o(m,{actions:g,noStyle:j,preferences:h,size:f}):o(e,{size:f,ariaLabel:c,className:T,noStyle:j,children:o(i,{icon:s,noStyle:j})})})};l.displayName="ConsentDialogTrigger";let c=Object.assign(l,{Button:e,Icon:i,Root:n,Text:a});export{c as ConsentDialogTrigger,e as TriggerButton,i as TriggerIcon,n as TriggerRoot,a as TriggerText,s as useTriggerContext};
2
+ import{jsx as t}from"react/jsx-runtime";import{createElement as o,useEffect as r,useMemo as e,useState as i}from"react";import{useDevToolsLauncherAvailable as n}from"../../devtools-launcher.js";import{TriggerButton as s}from"./atoms/button.js";import{TriggerIcon as a}from"./atoms/icon.js";import{TriggerRoot as l,useTriggerContext as m}from"./atoms/root.js";import{TriggerText as g}from"./atoms/text.js";import{getTriggerToolbar as c,loadTriggerToolbar as p}from"./toolbar-loader.js";let f=[],u=({fallback:t,...e})=>{let[n,s]=i(void 0),a=n??c();return r(()=>{if(a)return;let t=!0;return(async()=>{try{let o=await p();t&&s(()=>o)}catch{}})(),()=>{t=!1}},[a]),a?o(a,e):t},d=({icon:o="branding",defaultPosition:r="bottom-right",persistPosition:i=!0,ariaLabel:m="Open privacy settings",showWhen:g="always",size:c="md",className:p,noStyle:d,onClick:T,onPositionChange:b})=>{let h=n(),j=e(()=>({className:p,icon:o,label:m}),[m,p,o]),y=t(s,{size:c,ariaLabel:m,className:p,noStyle:d,children:t(a,{icon:o,noStyle:d})});return t(l,{defaultPosition:r,persistPosition:i,showWhen:g,onClick:T,onPositionChange:b,children:h?t(u,{actions:f,fallback:y,noStyle:d,preferences:j,size:c}):y})};d.displayName="ConsentDialogTrigger";let T=Object.assign(d,{Button:s,Icon:a,Root:l,Text:g});export{T as ConsentDialogTrigger,s as TriggerButton,a as TriggerIcon,l as TriggerRoot,g as TriggerText,m as useTriggerContext};
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ let r,o;let e=function(o){r=o},a=function(){return r},t=function(){return r?Promise.resolve(r):o??=(async()=>{try{let o=await import("./atoms/toolbar.js");return r??=o.TriggerToolbar}catch(r){throw o=void 0,r}})()};export{a as getTriggerToolbar,t as loadTriggerToolbar,e as registerTriggerToolbar};
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{Fragment as e,jsx as r,jsxs as t}from"react/jsx-runtime";import o from"@c15t/ui/styles/components/consent-manager";import{useMemo as i}from"react";import{DIALOG_SHEETS as s}from"../../shared/dialog-sheets.js";import{Box as m}from"../../shared/primitives/box.js";import{SurfaceStyles as n}from"../../shared/surface-styles.js";import{ConsentTrackingContext as c,useConsentTracking as a}from"../../../context/consent-tracking-context.js";import{LocalThemeContext as l}from"../../../context/theme-context.js";import{ConsentDraftProvider as d}from"../../../draft.js";import{useHasConsentUI as f}from"../../../hooks.js";import{useTextDirection as h}from"../../../hooks/use-text-direction.js";import{useTranslationLanguage as p}from"../../../kernel-selector.js";let u=({children:u,noStyle:j=!1,disableAnimation:g=!1,useProvider:x=!0,uiSource:v})=>{let k=h(p()),y=a(),P=i(()=>({disableAnimation:g,noStyle:j}),[g,j]),S=v??y.uiSource??"widget",b=i(()=>({uiSource:S}),[S]);if(!f())return null;let w=t(e,{children:[r(n,{sheets:s,noStyle:j}),r(m,{baseClassName:o.manager,"data-testid":"consent-widget-root",slotKey:"manager.root",dir:k,children:u})]});return x?r(c.Provider,{value:b,children:r(l.Provider,{value:P,children:r(d,{children:w})})}):r(c.Provider,{value:b,children:r(d,{children:w})})},j=u;export{u as ConsentWidgetRoot,j as Root};
2
+ import{Fragment as e,jsx as r,jsxs as t}from"react/jsx-runtime";import o from"@c15t/ui/styles/components/consent-manager";import{useMemo as i}from"react";import{DIALOG_SHEETS as s}from"../../shared/dialog-sheets.js";import{Box as m}from"../../shared/primitives/box.js";import{SurfaceStyles as n,useSurfaceSheetsReady as c}from"../../shared/surface-styles.js";import{ConsentTrackingContext as a,useConsentTracking as l}from"../../../context/consent-tracking-context.js";import{LocalThemeContext as d}from"../../../context/theme-context.js";import{ConsentDraftProvider as f}from"../../../draft.js";import{useHasConsentUI as h}from"../../../hooks.js";import{useTextDirection as p}from"../../../hooks/use-text-direction.js";import{useTranslationLanguage as u}from"../../../kernel-selector.js";let j=({children:j,noStyle:g=!1,disableAnimation:x=!1,useProvider:v=!0,uiSource:k})=>{let y=p(u()),P=l(),S=i(()=>({disableAnimation:x,noStyle:g}),[x,g]),b=k??P.uiSource??"widget",w=i(()=>({uiSource:b}),[b]),C=h(),R=c(s,g);if(!(C&&R))return null;let K=t(e,{children:[r(n,{sheets:s,noStyle:g}),r(m,{baseClassName:o.manager,"data-testid":"consent-widget-root",slotKey:"manager.root",dir:y,children:j})]});return v?r(a.Provider,{value:w,children:r(d.Provider,{value:S,children:r(f,{children:K})})}):r(a.Provider,{value:w,children:r(f,{children:K})})},g=j;export{j as ConsentWidgetRoot,g as Root};
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{Fragment as o,jsx as t,jsxs as r}from"react/jsx-runtime";import e from"@c15t/ui/styles/components/consent-banner";import{forwardRef as i,useMemo as s}from"react";import{useHeadlessConsentUI as n}from"../../../component-hooks/use-headless-consent-ui.js";import{ConsentTrackingContext as a}from"../../../context/consent-tracking-context.js";import{LocalThemeContext as l}from"../../../context/theme-context.js";import{useActiveUI as m,useHasConsentUI as c,useModel as p,usePolicyRule as d,useTranslations as u}from"../../../hooks.js";import{useIABPolicyGuard as f}from"../../../hooks/use-iab-policy-guard.js";import{useLateEntry as h}from"../../../hooks/use-late-entry.js";import{useTextDirection as j}from"../../../hooks/use-text-direction.js";import{useUIConfig as b}from"../../../ui-config-context.js";import{defaultTranslationConfig as v}from"../../../utils/default-translation-config.js";import{mergeSlotProps as g}from"../../../utils/merge-slot-props.js";import{FIRST_PAINT_SHEETS as k}from"../../shared/first-paint-sheets.js";import{StreamedSurface as y}from"../../shared/streamed-surface.js";import{SurfaceStyles as x}from"../../shared/surface-styles.js";import{ConsentBannerSurfaceContext as N,mirrorDefaultPosition as S,useConsentBannerSurface as C}from"../surface-context.js";import{EarlyTapScript as $}from"./early-tap-script.js";import{Overlay as L}from"./overlay.js";let P=["opt-in","opt-out"],R=i(({asChild:i,children:s,className:n,style:a,className:l,disableAnimation:y,noStyle:N,models:R=P,...B},F)=>{f();let A=m(),{components:E}=b(),V=c(),q=p()??"opt-in",w=d(),z=C(),D=u(),G=j(D?.language??v.defaultLanguage),H=S(z.position,z.positionSource,z.variant,G),I=V&&"banner"===A&&R.includes(q),J=h(I)&&!y,K=g(E?.banner?.root,{baseClassName:e.root,className:n||l,noStyle:N,style:a,...B}),M=N?K.className||"":`${K.className||""} ${y?"":`${e.bannerVisible} ${e.bannerEntering}`}`;return I?r(o,{children:[t($,{}),t(x,{sheets:k,noStyle:N}),t(L,{}),t("div",{ref:F,...K,className:M,"data-variant":z.variant,"data-position":H,"data-blocking":z.blocking?"true":void 0,"data-prompt":w.prompt,"data-model":w.model,"data-entry":J?"late":void 0,"data-testid":"consent-banner-root",dir:G,children:s})]}):null}),B=({children:o,className:r,noStyle:e,disableAnimation:i,scrollLock:m,trapFocus:c,models:p,uiSource:d,variant:u,position:f,blocking:h,...j})=>{let{banner:b}=n({prompt:{blocking:h,position:f,scrollLock:m,trapFocus:c,variant:u}}),v=b.scrollLock,g=b.trapFocus,k=s(()=>({disableAnimation:i,noStyle:e,scrollLock:v,trapFocus:g}),[i,e,v,g]),y=s(()=>({blocking:b.blocking,position:b.position,positionSource:b.positionSource,variant:b.variant}),[b.blocking,b.position,b.positionSource,b.variant]),x=s(()=>({uiSource:d??"banner"}),[d]);return t(a.Provider,{value:x,children:t(l.Provider,{value:k,children:t(N.Provider,{value:y,children:t(R,{disableAnimation:i,className:r,noStyle:e,models:p,...j,children:o})})})})};R.displayName="ConsentBannerRootChildren";let F=o=>t(y,{children:t(B,{...o})}),A=F;export{F as ConsentBannerRoot,A as Root};
2
+ import{Fragment as o,jsx as t,jsxs as r}from"react/jsx-runtime";import e from"@c15t/ui/styles/components/consent-banner";import{forwardRef as i,useMemo as s}from"react";import{useHeadlessConsentUI as n}from"../../../component-hooks/use-headless-consent-ui.js";import{ConsentTrackingContext as a}from"../../../context/consent-tracking-context.js";import{LocalThemeContext as l}from"../../../context/theme-context.js";import{useActiveUI as m,useHasConsentUI as c,useModel as p,usePolicyRule as d,useTranslations as u}from"../../../hooks.js";import{useIABPolicyGuard as f}from"../../../hooks/use-iab-policy-guard.js";import{useLateEntry as h}from"../../../hooks/use-late-entry.js";import{useTextDirection as j}from"../../../hooks/use-text-direction.js";import{useUIConfig as b}from"../../../ui-config-context.js";import{defaultTranslationConfig as v}from"../../../utils/default-translation-config.js";import{mergeSlotProps as g}from"../../../utils/merge-slot-props.js";import{FIRST_PAINT_SHEETS as k}from"../../shared/first-paint-sheets.js";import{StreamedSurface as y}from"../../shared/streamed-surface.js";import{SurfaceStyles as x,useSurfaceSheetsReady as N}from"../../shared/surface-styles.js";import{ConsentBannerSurfaceContext as S,mirrorDefaultPosition as C,useConsentBannerSurface as $}from"../surface-context.js";import{EarlyTapScript as L}from"./early-tap-script.js";import{Overlay as P}from"./overlay.js";let R=["opt-in","opt-out"],B=i(({asChild:i,children:s,className:n,style:a,className:l,disableAnimation:y,noStyle:S,models:B=R,...F},A)=>{f();let E=m(),{components:V}=b(),q=c(),w=p()??"opt-in",z=d(),D=$(),G=u(),H=j(G?.language??v.defaultLanguage),I=C(D.position,D.positionSource,D.variant,H),J=N(k,S)&&q&&"banner"===E&&B.includes(w),K=h(J)&&!y,M=g(V?.banner?.root,{baseClassName:e.root,className:n||l,noStyle:S,style:a,...F}),O=S?M.className||"":`${M.className||""} ${y?"":`${e.bannerVisible} ${e.bannerEntering}`}`;return J?r(o,{children:[t(L,{}),t(x,{sheets:k,noStyle:S}),t(P,{}),t("div",{ref:A,...M,className:O,"data-variant":D.variant,"data-position":I,"data-blocking":D.blocking?"true":void 0,"data-prompt":z.prompt,"data-model":z.model,"data-entry":K?"late":void 0,"data-testid":"consent-banner-root",dir:H,children:s})]}):null}),F=({children:o,className:r,noStyle:e,disableAnimation:i,scrollLock:m,trapFocus:c,models:p,uiSource:d,variant:u,position:f,blocking:h,...j})=>{let{banner:b}=n({prompt:{blocking:h,position:f,scrollLock:m,trapFocus:c,variant:u}}),v=b.scrollLock,g=b.trapFocus,k=s(()=>({disableAnimation:i,noStyle:e,scrollLock:v,trapFocus:g}),[i,e,v,g]),y=s(()=>({blocking:b.blocking,position:b.position,positionSource:b.positionSource,variant:b.variant}),[b.blocking,b.position,b.positionSource,b.variant]),x=s(()=>({uiSource:d??"banner"}),[d]);return t(a.Provider,{value:x,children:t(l.Provider,{value:k,children:t(S.Provider,{value:y,children:t(B,{disableAnimation:i,className:r,noStyle:e,models:p,...j,children:o})})})})};B.displayName="ConsentBannerRootChildren";let A=o=>t(y,{children:t(F,{...o})}),E=A;export{A as ConsentBannerRoot,E as Root};
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as e}from"react/jsx-runtime";import{useContext as t,version as r}from"react";import{GlobalThemeContext as n}from"../../context/theme-context.js";import{useUIConfig as o}from"../../ui-config-context.js";let c=Number.parseInt(r,10)>=19,s=({sheets:r,noStyle:s})=>{let{nonce:m,styles:i}=o(),l=t(n);return!1===i||s||l.noStyle?null:r.map(t=>c&&!m?e("style",{href:t.id,precedence:"c15t",children:t.css},t.id):e("style",{"data-c15t-styles":t.id,nonce:m,dangerouslySetInnerHTML:{__html:t.css}},t.id))};export{s as SurfaceStyles};
2
+ import{jsx as e}from"react/jsx-runtime";import{useContext as t,useEffect as r,useSyncExternalStore as n,version as a}from"react";import{GlobalThemeContext as o}from"../../context/theme-context.js";import{useUIConfig as l}from"../../ui-config-context.js";let u=new Map,c=new Set,s=new Map,i=new Set,f=new Set,d=0,y=()=>d,m=()=>0,S=function(){for(let e of(d+=1,f))e()},h=function(e){return f.add(e),()=>{f.delete(e)}},p=function(e){if(c.has(e)||u.has(e))return!0;if("u"<typeof document)return!1;if(document.querySelector(`style[data-href~="${e}"]`))return c.add(e),!0;let t=document.querySelector(`style[data-c15t-styles="${e}"]`);return!!t?.textContent&&(u.set(e,t.textContent),!0)},w=e=>!e.load||i.has(e.id)||p(e.id),x=async function(e,t){try{u.set(e,await t()),i.delete(e)}catch(t){throw s.delete(e),i.add(e),t}finally{S()}},_=async function(e){let t=[];for(let r of e){let{id:e,load:n}=r;if(!n||p(e))continue;let a=s.get(e);a||(a=x(e,n),s.set(e,a)),t.push(a)}try{await Promise.all(t)}catch{}},g=Number.parseInt(a,10)>=19,j=function(e){let{styles:r}=l(),n=t(o);return!1===r||!!e||!!n.noStyle},M=function(e,t){let a=j(t),o=n(h,()=>a||e.every(w),()=>!0);return r(()=>{a||_(e)},[a,e]),o},q=({sheets:t,noStyle:r})=>{let{nonce:a}=l();if(n(h,y,m),j(r))return null;let o=g&&!a;return t.map(t=>{let{css:r}=t;if(t.load){if(!p(t.id))return null;r=u.get(t.id)??""}return o?e("style",{href:t.id,precedence:"c15t",children:r},t.id):e("style",{"data-c15t-styles":t.id,nonce:a,dangerouslySetInnerHTML:{__html:r}},t.id)})};export{q as SurfaceStyles,_ as preloadSurfaceSheets,M as useSurfaceSheetsReady};
package/dist/devtools.js CHANGED
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as e}from"react/jsx-runtime";import{createDevTools as t}from"@c15t/dev-tools";import{createElement as r,forwardRef as o,useCallback as n,useContext as s,useEffect as l,useLayoutEffect as i,useMemo as c,useRef as u}from"react";import{KernelContext as d,ProviderServicesContext as a}from"./context.js";import{publishDevToolsLauncher as f}from"./devtools-launcher.js";import{useIsHydrated as m}from"./hooks/use-is-hydrated.js";let v=e=>{if(!e)throw Error("c15t: DevTools must be rendered inside <ConsentProvider> from @c15t/react.");return e},g=(e,t)=>{let r=m(),o=u(e);i(()=>{o.current=e},[e]);let n=r&&!t&&e?JSON.stringify([...new Set(e())].sort()):void 0;return c(()=>{if(void 0===n)return;let e=JSON.parse(n);return()=>o.current?.()??e},[n])},C=(e,t)=>{let r=u({clearRecords:e,getPresentation:t});i(()=>{r.current={clearRecords:e,getPresentation:t}},[e,t]);let o=void 0!==e,n=void 0!==t;return c(()=>({clearRecords:o?()=>r.current.clearRecords?.():void 0,getPresentation:n?()=>r.current.getPresentation?.():void 0}),[o,n])},h=({disabled:e=!1,clearRecords:r,getPresentation:o,defaultOpen:n,defaultTab:i,getConsentCategories:c,maxEvents:u,position:m,shadow:h})=>{let p=s(a),y=C(r??p?.clearRecords,o??p?.getPresentation),D=s(d),P=e?null:v(D),T=g(c??p?.getConsentCategories,e);return l(()=>{if(!P)return;let e=t({...y,defaultOpen:n,defaultTab:i,getConsentCategories:T,kernel:P,maxEvents:u,position:m,shadow:h}),r=f(P,e);return()=>{r(),e.destroy()}},[n,i,T,y,P,u,m,h]),null},p=h,y=h,D={height:"100%",minHeight:0,width:"100%"},P=o(function({disabled:r=!1,clearRecords:o,getPresentation:l,defaultTab:c,getConsentCategories:f,maxEvents:m,style:h,theme:p,...y},P){let T=s(a),S=C(o??T?.clearRecords,l??T?.getPresentation),j=s(d),R=r?null:v(j),k=g(f??T?.getConsentCategories,r),w=u(null),x=n(e=>{w.current=e;let t=((e,t)=>{if("function"==typeof e)return e(t);e&&(e.current=t)})(P,e);if("function"==typeof t)return()=>{w.current=null,t()}},[P]);return i(()=>{let e=w.current;if(!R||!e)return;let r=t({...S,container:e,defaultTab:c,embedded:!0,getConsentCategories:k,kernel:R,maxEvents:m});return()=>r.destroy()},[c,k,S,R,m]),e("div",{...y,ref:x,style:{...D,...p?{"--c15t-dev-tools-color-scheme":p}:void 0,...h}})}),T=(e={})=>{let{id:t="c15t",name:o="c15t",defaultOpen:n=!1,...s}=e;return{defaultOpen:n,id:t,name:o,render:(e,t)=>r(P,{...s,theme:("string"==typeof t?t:t?.theme)??s.theme})}},S=T;export{y as C15TDevTools,h as ConsentDevTools,p as DevTools,T as c15tDevtools,S as c15tDevtoolsPlugin,P as C15tTanStackDevtoolsPanel};
2
+ import{jsx as e}from"react/jsx-runtime";import{createDevTools as t}from"@c15t/dev-tools";import{createElement as r,forwardRef as o,useCallback as n,useContext as s,useEffect as l,useLayoutEffect as i,useMemo as c,useRef as u}from"react";import{TriggerToolbar as a}from"./components/panel-trigger/atoms/toolbar.js";import{registerTriggerToolbar as d}from"./components/panel-trigger/toolbar-loader.js";import{KernelContext as m,ProviderServicesContext as f}from"./context.js";import{publishDevToolsLauncher as g}from"./devtools-launcher.js";import{useIsHydrated as v}from"./hooks/use-is-hydrated.js";let p=e=>{if(!e)throw Error("c15t: DevTools must be rendered inside <ConsentProvider> from @c15t/react.");return e},C=(e,t)=>{let r=v(),o=u(e);i(()=>{o.current=e},[e]);let n=r&&!t&&e?JSON.stringify([...new Set(e())].sort()):void 0;return c(()=>{if(void 0===n)return;let e=JSON.parse(n);return()=>o.current?.()??e},[n])},h=(e,t)=>{let r=u({clearRecords:e,getPresentation:t});i(()=>{r.current={clearRecords:e,getPresentation:t}},[e,t]);let o=void 0!==e,n=void 0!==t;return c(()=>({clearRecords:o?()=>r.current.clearRecords?.():void 0,getPresentation:n?()=>r.current.getPresentation?.():void 0}),[o,n])},y=({disabled:e=!1,clearRecords:r,getPresentation:o,defaultOpen:n,defaultTab:i,getConsentCategories:c,maxEvents:u,position:v,shadow:y})=>{let D=s(f),P=h(r??D?.clearRecords,o??D?.getPresentation),T=s(m),j=e?null:p(T),S=C(c??D?.getConsentCategories,e);return l(()=>{d(a)},[]),l(()=>{if(!j)return;let e=t({...P,defaultOpen:n,defaultTab:i,getConsentCategories:S,kernel:j,maxEvents:u,position:v,shadow:y}),r=g(j,e);return()=>{r(),e.destroy()}},[n,i,S,P,j,u,v,y]),null},D=y,P=y,T={height:"100%",minHeight:0,width:"100%"},j=o(function({disabled:r=!1,clearRecords:o,getPresentation:l,defaultTab:c,getConsentCategories:a,maxEvents:d,style:g,theme:v,...y},D){let P=s(f),j=h(o??P?.clearRecords,l??P?.getPresentation),S=s(m),b=r?null:p(S),R=C(a??P?.getConsentCategories,r),k=u(null),w=n(e=>{k.current=e;let t=((e,t)=>{if("function"==typeof e)return e(t);e&&(e.current=t)})(D,e);if("function"==typeof t)return()=>{k.current=null,t()}},[D]);return i(()=>{let e=k.current;if(!b||!e)return;let r=t({...j,container:e,defaultTab:c,embedded:!0,getConsentCategories:R,kernel:b,maxEvents:d});return()=>r.destroy()},[c,R,j,b,d]),e("div",{...y,ref:w,style:{...T,...v?{"--c15t-dev-tools-color-scheme":v}:void 0,...g}})}),S=(e={})=>{let{id:t="c15t",name:o="c15t",defaultOpen:n=!1,...s}=e;return{defaultOpen:n,id:t,name:o,render:(e,t)=>r(j,{...s,theme:("string"==typeof t?t:t?.theme)??s.theme})}},b=S;export{P as C15TDevTools,y as ConsentDevTools,D as DevTools,S as c15tDevtools,b as c15tDevtoolsPlugin,j as C15tTanStackDevtoolsPanel};
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ import{jsx as e}from"react/jsx-runtime";import{useEffect as o,useState as r}from"react";import{registerDialogChunkWarmer as t,useIdleDialogWarming as n}from"./chunk-warming.js";import{useActiveUI as i,useModel as a}from"./hooks.js";import{useIsHydrated as l}from"./hooks/use-is-hydrated.js";import{useIAB as s}from"./iab-context.js";import{createDeferredModule as m}from"./utils/deferred-module.js";let g=["iab"],p=m(()=>import("./components/iab-panel/index.js")),d=0,f=!1;t(()=>{f=!0,d>0&&p.preload()});let u=p.component(e=>e.IABConsentDialog),c=m(()=>import("./components/panel-trigger/index.js")).component(e=>e.ConsentDialogTrigger),b=t=>{let m=i(),b=a(),j=s(),I=l(),T=t.models??g,h=null!==b&&T.includes(b)&&!!j?.config.enabled;o(()=>{if(h)return d+=1,f&&p.preload(),()=>{d-=1}},[h]),n(h&&"banner"===m);let B=h&&((t.open??"dialog"===m)||!!t.showTrigger),[C,D]=r(B);if(B&&!C&&D(!0),!(B||C)){var x;let o=!0===(x=t.showTrigger)?{}:x||null;return o&&I&&j?.config.enabled?e(c,{...o}):null}return e(u,{...t})},j={};for(let e of["Root","Card","Header","Tabs","TabButton","Content","Footer","Overlay","FeatureItem","PurposeItem","StackItem","VendorList"])Object.defineProperty(b,e,{configurable:!0,enumerable:!0,get:()=>(j[e]??=p.component(o=>o.IABConsentDialog[e]),j[e])});let I=b,T=function(){d=0,f=!1};export{I as IABConsentDialog,T as resetIABDialogWarmingForTests};
package/dist/iab.js CHANGED
@@ -1 +1 @@
1
- export{IABConsentBanner}from"./components/iab-prompt/index.js";export{IABConsentDialog}from"./components/iab-panel/index.js";export{useHeadlessIABConsentUI}from"./hooks/use-headless-iab-consent-ui.js";export{IABProvider}from"./iab-context.js";
1
+ export{IABConsentBanner}from"./components/iab-prompt/index.js";export{IABConsentDialog}from"./iab-dialog-deferred.js";export{useHeadlessIABConsentUI}from"./hooks/use-headless-iab-consent-ui.js";export{IABProvider}from"./iab-context.js";
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as t}from"react/jsx-runtime";import{Suspense as r,lazy as e,useSyncExternalStore as a}from"react";let o=o=>{let n,l={status:"pending"},u=l,c=!1,s=new Set,i=()=>u,d=()=>l,f=t=>(c||=t,n??=(async()=>{try{let t=await o();return u={module:t,status:"ready"},t}catch(t){throw c?u={error:t,status:"error"}:n=void 0,t}})()),h=!1,m=()=>{h||(h=!0,queueMicrotask(()=>{for(let t of(h=!1,u={...u},s))t()}))},p=t=>(s.add(t),()=>{s.delete(t)});return{component(o){let n=e(()=>{let t=(async()=>({default:o(await f(!0))}))();return t.then(m,m),t});return function(e){let o=a(p,i,d);if("error"===o.status)throw o.error;return t(r,{fallback:null,children:t(n,{...e})})}},async preload(){try{await f(!1)}catch{}}}};export{o as createDeferredModule};
2
+ import{jsx as e}from"react/jsx-runtime";import{Suspense as r,forwardRef as t,lazy as a,useSyncExternalStore as o}from"react";let n=n=>{let l,u={status:"pending"},c=u,s=!1,d=new Set,i=()=>c,f=()=>u,m=e=>(s||=e,l??=(async()=>{try{let e=await n();return c={module:e,status:"ready"},e}catch(e){throw s?c={error:e,status:"error"}:l=void 0,e}})()),p=!1,y=()=>{p||(p=!0,queueMicrotask(()=>{for(let e of(p=!1,c={...c},d))e()}))},h=e=>(d.add(e),()=>{d.delete(e)});return{component(n){let l=a(()=>{let e=(async()=>({default:n(await m(!0))}))();return e.then(y,y),e}),u=t((t,a)=>{let n=o(h,i,f);if("error"===n.status)throw n.error;return e(r,{fallback:null,children:e(l,{...t,ref:a})})});return u.displayName="DeferredComponent",u},async preload(){try{await m(!1)}catch{}}}};export{n as createDeferredModule};
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- let e="3.0.0-alpha.10";export{e as version};
1
+ let e="3.0.0-alpha.11";export{e as version};
@@ -7,10 +7,10 @@
7
7
  *
8
8
  * - Intent: pointerenter or focus on any `ConsentButton` that opens the
9
9
  * dialog, including the stock banner's Customize button.
10
- * - Idle: a few seconds after the page's load event, in browser idle time,
11
- * while the banner is shown or a dialog trigger is mounted. The wait keeps
12
- * the dialog out of first-load JavaScript; a visitor who opens it sooner
13
- * hovers, focuses or touches the button first, which warms it at once.
10
+ * - Idle: in the browser's first idle period after the page's load event,
11
+ * while the banner is shown or a dialog trigger is mounted. This covers a
12
+ * tap, which leaves intent warming no lead time: on touch, pointerenter
13
+ * fires with the tap itself.
14
14
  *
15
15
  * Module-level registry keeps banner components decoupled from the
16
16
  * aggregate exports (no context change, tree-shakes with the aggregate).
@@ -19,8 +19,8 @@ type Warmer = () => void;
19
19
  /**
20
20
  * When the deferred consent dialog starts loading before it opens.
21
21
  *
22
- * - `'idle'`: a few seconds after the page's load event, in browser idle
23
- * time, while the banner is shown or a button that opens the dialog is
22
+ * - `'idle'`: in the browser's first idle period after the page's load
23
+ * event, while the banner is shown or a button that opens the dialog is
24
24
  * mounted. Also on hover or focus of such a button.
25
25
  * - `'intent'`: only on hover or focus of a button that opens the dialog.
26
26
  *
@@ -45,12 +45,9 @@ export declare const warmDialogChunk: () => void;
45
45
  */
46
46
  export declare const useIdleDialogWarming: (active: boolean) => void;
47
47
  /**
48
- * Reset module state between tests. Idle warming waits `idleWarmDelayMs`
49
- * after load, `0` unless a test passes another delay.
48
+ * Reset module state between tests.
50
49
  *
51
50
  * @internal
52
51
  */
53
- export declare const resetDialogChunkWarmingForTests: (options?: {
54
- idleWarmDelayMs?: number;
55
- }) => void;
52
+ export declare const resetDialogChunkWarmingForTests: () => void;
56
53
  export {};
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Loads the trigger toolbar on demand. The single-button trigger becomes a
3
+ * toolbar only while `<ConsentDevTools>` is mounted, so apps without
4
+ * DevTools never download it. The DevTools entry registers the toolbar when
5
+ * it loads, so the swap to a toolbar never waits on a request.
6
+ *
7
+ * @internal
8
+ * @packageDocumentation
9
+ */
10
+ import type { TriggerToolbar } from './atoms/toolbar.js';
11
+ /** The toolbar view the trigger renders while DevTools is mounted. */
12
+ export type TriggerToolbarComponent = typeof TriggerToolbar;
13
+ /**
14
+ * Make the toolbar available synchronously.
15
+ *
16
+ * @param component - The toolbar view.
17
+ * @internal
18
+ */
19
+ export declare const registerTriggerToolbar: (component: TriggerToolbarComponent) => void;
20
+ /**
21
+ * The toolbar view when it has loaded or been registered.
22
+ *
23
+ * @returns The toolbar view, or `undefined` while it is not loaded.
24
+ * @internal
25
+ */
26
+ export declare const getTriggerToolbar: () => TriggerToolbarComponent | undefined;
27
+ /**
28
+ * Load the toolbar view. A failed load is not cached, so a later call
29
+ * retries.
30
+ *
31
+ * @returns The toolbar view.
32
+ * @internal
33
+ */
34
+ export declare const loadTriggerToolbar: () => Promise<TriggerToolbarComponent>;
@@ -2,9 +2,33 @@
2
2
  export interface SurfaceStyleSheet {
3
3
  /** Dedupes the stylesheet: a page renders each `id` once. */
4
4
  id: string;
5
- /** The stylesheet text. */
5
+ /** The stylesheet text. Empty for a deferred sheet. */
6
6
  css: string;
7
+ /**
8
+ * Loads the text of a deferred sheet. A browser bundle gets one in place
9
+ * of `css` when the framework already put the sheet in the server HTML,
10
+ * as the Next.js adapter does, so the text ships once.
11
+ */
12
+ load?: () => Promise<string>;
7
13
  }
14
+ /**
15
+ * Starts loading the deferred sheets the page does not hold yet. Safe to
16
+ * call often: each sheet loads once, and the next call retries a failed
17
+ * load.
18
+ *
19
+ * @internal
20
+ */
21
+ export declare const preloadSurfaceSheets: (sheets: readonly SurfaceStyleSheet[]) => Promise<void>;
22
+ /**
23
+ * Whether a surface can show: its deferred sheets are in the page or
24
+ * loaded. Starts loading the missing ones after mount, so a surface that
25
+ * renders later, like a banner waiting on the browser's consent fetch,
26
+ * finds them ready. Hydration reads `true`: the server rendered the sheets
27
+ * it rendered the surface with.
28
+ *
29
+ * @internal
30
+ */
31
+ export declare const useSurfaceSheetsReady: (sheets: readonly SurfaceStyleSheet[], noStyle?: boolean) => boolean;
8
32
  /**
9
33
  * Renders the stylesheets a stock surface needs as `<style>` elements.
10
34
  *
@@ -33,4 +57,4 @@ export interface SurfaceStyleSheet {
33
57
  export declare const SurfaceStyles: ({ sheets, noStyle, }: {
34
58
  sheets: readonly SurfaceStyleSheet[];
35
59
  noStyle?: boolean;
36
- }) => import("react").JSX.Element[] | null;
60
+ }) => (import("react").JSX.Element | null)[] | null;
@@ -0,0 +1,36 @@
1
+ import type { IABConsentDialogCompoundComponent } from './components/iab-panel/index.js';
2
+ /**
3
+ * The IAB TCF preference centre: purposes, stacks, special features and
4
+ * per-vendor consent and legitimate-interest controls.
5
+ *
6
+ * @remarks
7
+ * The component code loads on demand. It downloads in the browser's first
8
+ * idle period after the page's `load` event while the IAB banner is shown,
9
+ * on hover or focus of the banner's Customize button or partners link, or
10
+ * when the dialog opens, whichever comes first. `preloadDialog: 'intent'` in
11
+ * the provider options skips the idle load. `open={true}` or `showTrigger`
12
+ * loads it on mount under a model `models` lists; under another model,
13
+ * `showTrigger` loads only the trigger.
14
+ *
15
+ * The compound parts (`IABConsentDialog.Root`, `.Card`, `.Header`, `.Tabs`,
16
+ * `.TabButton`, `.Content`, `.Footer`, `.Overlay`, `.FeatureItem`,
17
+ * `.PurposeItem`, `.StackItem`, `.VendorList`) load the same module when
18
+ * they render.
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * <IABProvider cmpId={28}>
23
+ * <IABConsentBanner />
24
+ * <IABConsentDialog />
25
+ * </IABProvider>
26
+ * ```
27
+ *
28
+ * @public
29
+ */
30
+ export declare const IABConsentDialog: IABConsentDialogCompoundComponent;
31
+ /**
32
+ * Reset the warming state shared by mounted dialogs between tests.
33
+ *
34
+ * @internal
35
+ */
36
+ export declare const resetIABDialogWarmingForTests: () => void;
@@ -24,7 +24,8 @@
24
24
  * @packageDocumentation
25
25
  */
26
26
  export { IABConsentBanner, type IABConsentBannerProps, } from './components/iab-prompt/index.js';
27
- export { IABConsentDialog, type IABConsentDialogProps, } from './components/iab-panel/index.js';
27
+ export type { IABConsentDialogProps } from './components/iab-panel/index.js';
28
+ export { IABConsentDialog } from './iab-dialog-deferred.js';
28
29
  export { type HeadlessIABBannerAction, type HeadlessIABBannerState, type HeadlessIABDialogAction, type HeadlessIABDialogState, type HeadlessIABPreferenceTab, type UseHeadlessIABConsentUIResult, useHeadlessIABConsentUI, } from './hooks/use-headless-iab-consent-ui.js';
29
30
  export { IABProvider } from './iab-context.js';
30
31
  export type { IABProviderProps } from './iab-context.js';
@@ -1 +1 @@
1
- export declare const version = "3.0.0-alpha.10";
1
+ export declare const version = "3.0.0-alpha.11";
package/docs/README.md CHANGED
@@ -125,5 +125,6 @@ These docs describe c15t v3. Find your app's row in Choose your setup, then foll
125
125
  - [TikTok Pixel](./integrations/tiktok-pixel.md): Load the TikTok Pixel only after marketing consent with the c15t tiktokPixel helper, guard ttq event calls, and check it in DevTools.
126
126
  - [Umami Analytics](./integrations/umami-analytics.md): Load the Umami Analytics tracker only after measurement consent with the c15t umamiAnalytics helper, point it at a self-hosted instance, and check it in DevTools.
127
127
  - [Vercel Analytics](./integrations/vercel-analytics.md): Load the Vercel Web Analytics script only after measurement consent with the c15t vercelAnalytics helper, choose the debug script, and check it in DevTools.
128
+ - [Vercel Speed Insights](./integrations/vercel-speed-insights.md): Load the Vercel Speed Insights collector only after measurement consent with the c15t vercelSpeedInsights helper, drop Web Vitals reports on revocation, and check it in DevTools.
128
129
  - [X Pixel](./integrations/x-pixel.md): Load the X Pixel only after marketing consent with the c15t xPixel helper, guard twq conversion events, and check it in DevTools.
129
130
  - [YouTube](./integrations/youtube.md): Gate YouTube embeds with c15t v3 in Next.js, TanStack Start, React, Nuxt, Vue, Astro, Svelte, SvelteKit or JavaScript.
@@ -78,8 +78,11 @@ public policy manifest, never a response that contains a visitor's consent.
78
78
  Use a build-time manifest as the default for supported production builds.
79
79
  `manifest()` is the default mode in Next.js, TanStack Start, Nuxt, Astro and
80
80
  SvelteKit, so their servers resolve requests from the deployment's snapshot.
81
- Vite apps can bundle it for browser resolution too; location-based policies
82
- may still need a location request. The framework quickstarts show the build
81
+ React, Vue and Svelte single-page apps have no server, so their quickstarts
82
+ use `hosted()`: the backend reads each visitor's location from the `/init`
83
+ request. They can bundle the manifest for browser resolution too, but a
84
+ regional policy still needs `/init` on a first visit unless the page knows
85
+ the location. The framework quickstarts show the build
83
86
  integration. [Consent modes](./modes.md) lists every mode, its
84
87
  options and the backend URL variable each framework reads.
85
88