@c15t/react 3.0.0-alpha.0 → 3.0.0-alpha.2

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 (145) hide show
  1. package/AGENTS.md +4 -1
  2. package/dist/aggregate-components.js +1 -1
  3. package/dist/component-hooks/use-manager.js +1 -1
  4. package/dist/components/consent-gate/atoms.js +1 -0
  5. package/dist/components/consent-gate/consent-gate.js +2 -0
  6. package/dist/components/consent-gate/index.js +2 -0
  7. package/dist/components/preferences/atoms/accordion.js +1 -1
  8. package/dist/components/preferences/atoms/vendor-list.js +1 -0
  9. package/dist/components/preferences/index.js +1 -1
  10. package/dist/consent-gate.js +2 -0
  11. package/dist/draft.js +1 -1
  12. package/dist/external-iab-context.js +1 -1
  13. package/dist/hooks.js +1 -1
  14. package/dist/iab/styles.tw3.css +4 -110
  15. package/dist/index.js +1 -1
  16. package/dist/provider.js +1 -1
  17. package/dist/styles.tw3.css +10 -113
  18. package/dist/utils/deferred-module.js +2 -0
  19. package/dist/version.js +1 -1
  20. package/dist-types/aggregate-components.d.ts +2 -2
  21. package/dist-types/component-hooks/use-headless-iab-consent-ui.d.ts +1 -1
  22. package/dist-types/component-hooks/use-manager.d.ts +6 -1
  23. package/dist-types/components/consent-gate/atoms.d.ts +11 -0
  24. package/dist-types/components/consent-gate/consent-gate.d.ts +2 -0
  25. package/dist-types/components/consent-gate/index.d.ts +41 -0
  26. package/dist-types/components/{frame → consent-gate}/types.d.ts +7 -7
  27. package/dist-types/components/consent-preferences-link/consent-preferences-link.d.ts +1 -1
  28. package/dist-types/components/consent-preferences-link/index.d.ts +1 -1
  29. package/dist-types/components/iab-panel/atoms/purpose-item.d.ts +1 -1
  30. package/dist-types/components/iab-panel/atoms/stack-item.d.ts +1 -1
  31. package/dist-types/components/iab-panel/atoms/vendor-list.d.ts +1 -1
  32. package/dist-types/components/iab-panel/iab-panel.d.ts +1 -1
  33. package/dist-types/components/iab-panel/index.d.ts +24 -24
  34. package/dist-types/components/iab-prompt/index.d.ts +17 -17
  35. package/dist-types/components/panel/atoms/card.d.ts +4 -4
  36. package/dist-types/components/panel/atoms/overlay.d.ts +1 -1
  37. package/dist-types/components/panel/index.d.ts +7 -7
  38. package/dist-types/components/panel/panel.d.ts +2 -2
  39. package/dist-types/components/panel-link/index.d.ts +1 -1
  40. package/dist-types/components/panel-trigger/atoms/button.d.ts +1 -1
  41. package/dist-types/components/panel-trigger/atoms/icon.d.ts +1 -1
  42. package/dist-types/components/panel-trigger/atoms/root.d.ts +2 -2
  43. package/dist-types/components/panel-trigger/atoms/toolbar.d.ts +2 -2
  44. package/dist-types/components/panel-trigger/index.d.ts +4 -4
  45. package/dist-types/components/panel-trigger/panel-trigger-toolbar.d.ts +1 -1
  46. package/dist-types/components/panel-trigger/panel-trigger.d.ts +9 -9
  47. package/dist-types/components/panel-trigger/types.d.ts +1 -1
  48. package/dist-types/components/preferences/atoms/accordion.d.ts +6 -4
  49. package/dist-types/components/preferences/atoms/button.d.ts +1 -1
  50. package/dist-types/components/preferences/atoms/footer.d.ts +1 -1
  51. package/dist-types/components/preferences/atoms/root.d.ts +1 -1
  52. package/dist-types/components/preferences/atoms/vendor-list.d.ts +23 -0
  53. package/dist-types/components/preferences/index.d.ts +13 -11
  54. package/dist-types/components/preferences/policy-actions.d.ts +2 -2
  55. package/dist-types/components/preferences/preferences.d.ts +1 -1
  56. package/dist-types/components/preferences/types.d.ts +1 -1
  57. package/dist-types/components/prompt/components.d.ts +3 -3
  58. package/dist-types/components/prompt/index.d.ts +11 -11
  59. package/dist-types/components/prompt/policy-actions.d.ts +2 -2
  60. package/dist-types/components/prompt/prompt.d.ts +1 -1
  61. package/dist-types/components/shared/policy-actions.d.ts +2 -2
  62. package/dist-types/components/shared/primitives/box.d.ts +1 -1
  63. package/dist-types/components/shared/primitives/button.d.ts +2 -2
  64. package/dist-types/components/shared/primitives/button.types.d.ts +1 -1
  65. package/dist-types/components/shared/ui/accordion/accordion.d.ts +2 -2
  66. package/dist-types/components/shared/ui/accordion/index.d.ts +2 -2
  67. package/dist-types/components/shared/ui/animated-collapse/index.d.ts +2 -2
  68. package/dist-types/components/shared/ui/branding.d.ts +1 -1
  69. package/dist-types/components/shared/ui/button/button.d.ts +1 -1
  70. package/dist-types/components/shared/ui/button/index.d.ts +2 -2
  71. package/dist-types/components/shared/ui/collapsible/index.d.ts +1 -1
  72. package/dist-types/components/shared/ui/dialog/index.d.ts +1 -1
  73. package/dist-types/components/shared/ui/preference-item/index.d.ts +1 -1
  74. package/dist-types/components/shared/ui/switch/index.d.ts +2 -2
  75. package/dist-types/components/shared/ui/switch/switch.d.ts +1 -1
  76. package/dist-types/components/shared/ui/tabs/index.d.ts +1 -1
  77. package/dist-types/consent-gate.d.ts +1 -0
  78. package/dist-types/context/index.d.ts +3 -3
  79. package/dist-types/context/theme-context.d.ts +1 -1
  80. package/dist-types/draft.d.ts +53 -1
  81. package/dist-types/headless.d.ts +7 -7
  82. package/dist-types/hooks/use-headless-iab-consent-ui.d.ts +1 -1
  83. package/dist-types/hooks/use-iab-manager.d.ts +1 -1
  84. package/dist-types/hooks/use-theme.d.ts +1 -1
  85. package/dist-types/hooks.d.ts +28 -1
  86. package/dist-types/iab.d.ts +5 -5
  87. package/dist-types/index.d.ts +25 -25
  88. package/dist-types/module-hooks.d.ts +4 -4
  89. package/dist-types/panel-link.d.ts +1 -1
  90. package/dist-types/panel-trigger.d.ts +1 -1
  91. package/dist-types/panel.d.ts +1 -1
  92. package/dist-types/preferences.d.ts +1 -1
  93. package/dist-types/primitives/accordion.d.ts +1 -1
  94. package/dist-types/primitives/button.d.ts +1 -1
  95. package/dist-types/primitives/collapsible.d.ts +1 -1
  96. package/dist-types/primitives/dialog.d.ts +1 -1
  97. package/dist-types/primitives/preference-item.d.ts +1 -1
  98. package/dist-types/primitives/switch.d.ts +1 -1
  99. package/dist-types/primitives/tabs.d.ts +1 -1
  100. package/dist-types/primitives.d.ts +7 -7
  101. package/dist-types/prompt.d.ts +1 -1
  102. package/dist-types/provider.d.ts +27 -5
  103. package/dist-types/server/fetch-ssr-data.d.ts +1 -1
  104. package/dist-types/server/index.d.ts +5 -5
  105. package/dist-types/theme-provider.d.ts +2 -2
  106. package/dist-types/types/index.d.ts +3 -3
  107. package/dist-types/types/manager.d.ts +1 -1
  108. package/dist-types/types/theme/index.d.ts +1 -1
  109. package/dist-types/ui-config-context.d.ts +1 -1
  110. package/dist-types/utils/deferred-module.d.ts +11 -0
  111. package/dist-types/utils/index.d.ts +4 -4
  112. package/dist-types/utils/merge-slot-props.d.ts +2 -2
  113. package/dist-types/utils/merge-styles.d.ts +1 -1
  114. package/dist-types/utils/theme-utils.d.ts +1 -1
  115. package/dist-types/version.d.ts +1 -1
  116. package/docs/README.md +4 -1
  117. package/docs/frameworks/react/components/consent-dialog.md +1 -1
  118. package/docs/frameworks/react/components/{frame.md → consent-gate.md} +27 -27
  119. package/docs/frameworks/react/components/consent-manager-provider.md +14 -1
  120. package/docs/frameworks/react/components/consent-widget.md +39 -6
  121. package/docs/frameworks/react/concepts/consent-categories.md +31 -2
  122. package/docs/frameworks/react/script-loader.md +8 -0
  123. package/docs/frameworks/react/styling/overview.md +10 -0
  124. package/docs/guides/deployment-modes.md +12 -0
  125. package/docs/integrations/building-integrations.md +5 -0
  126. package/docs/integrations/clear-on-revocation.md +167 -0
  127. package/docs/integrations/cloudflare-zaraz.md +399 -0
  128. package/docs/integrations/google-maps.md +20 -20
  129. package/docs/integrations/granular-consent.md +208 -0
  130. package/docs/integrations/overview.md +5 -4
  131. package/docs/integrations/youtube.md +26 -21
  132. package/docs/upgrade-v3.md +47 -0
  133. package/package.json +26 -16
  134. package/dist/components/frame/atoms.js +0 -1
  135. package/dist/components/frame/frame.js +0 -2
  136. package/dist/components/frame/index.js +0 -2
  137. package/dist/frame.js +0 -2
  138. package/dist-types/components/frame/atoms.d.ts +0 -11
  139. package/dist-types/components/frame/frame.d.ts +0 -2
  140. package/dist-types/components/frame/index.d.ts +0 -24
  141. package/dist-types/frame.d.ts +0 -1
  142. package/readme.json +0 -48
  143. package/src/iab/styles.css +0 -11
  144. package/src/styles.css +0 -10
  145. /package/dist/components/{frame → consent-gate}/types.js +0 -0
@@ -1,2 +1,2 @@
1
- import type { ThemeContextValue } from '../context/theme-context';
1
+ import type { ThemeContextValue } from '../context/theme-context.js';
2
2
  export declare const useTheme: () => ThemeContextValue;
@@ -17,7 +17,7 @@
17
17
  * observed through the selector hooks, whose subscription model handles
18
18
  * invalidation correctly.
19
19
  */
20
- import type { AllConsentNames, ConsentKernel, PromptPresentation, PreferencesPresentation, ConsentSnapshot, ConsentState, KernelActiveUI, KernelBranding, KernelIABState, KernelModel, KernelOverrides, KernelTranslations, KernelUser, LocationResponse, PolicyScopeMode } from '@c15t/core';
20
+ import type { AllConsentNames, ConsentKernel, PromptPresentation, PreferencesPresentation, ConsentSnapshot, ConsentState, KernelActiveUI, KernelBranding, KernelIABState, KernelModel, KernelOverrides, KernelTranslations, KernelUser, LocationResponse, PolicyScopeMode, ResolvedVendor, VendorChoice } from '@c15t/core';
21
21
  /**
22
22
  * Full snapshot accessor. Escape hatch for consumers that genuinely need
23
23
  * multiple slices. Prefer narrow hooks for re-render isolation.
@@ -91,6 +91,33 @@ export declare const usePurposeConsent: (purposeId: number) => boolean;
91
91
  export declare const useSpecialFeatureOptIn: (featureId: number) => boolean;
92
92
  /** Latest TCF string. `null` until the IAB module encodes one. */
93
93
  export declare const useTCString: () => string | null;
94
+ /**
95
+ * Vendors declared for vendor-level consent outside IAB, merged from the
96
+ * provider's `vendors` option, the backend and script slugs. Empty under an
97
+ * `iab` policy, where the TC string decides and vendor rows are not shown.
98
+ */
99
+ export declare const useDeclaredVendors: () => readonly ResolvedVendor[];
100
+ /**
101
+ * The visitor's recorded vendor decision.
102
+ *
103
+ * @returns The decision, whose `denied` list may be empty after a bulk
104
+ * action lifted every denial, or `null` when no vendor decision was ever
105
+ * recorded.
106
+ */
107
+ export declare const useVendorChoice: () => Readonly<VendorChoice> | null;
108
+ /**
109
+ * Whether one vendor is allowed: its category condition passes and the
110
+ * visitor has not turned it off.
111
+ *
112
+ * @param vendorId - Vendor slug as declared in `vendors` or on a script.
113
+ * @returns `false` while the vendor is denied outside `iab`, otherwise the
114
+ * result of its declared category condition. An undeclared id is `true`:
115
+ * nothing is known about its category, and a denial only exists for a vendor
116
+ * the visitor saw.
117
+ */
118
+ export declare const useVendorAllowed: (vendorId: string) => boolean;
119
+ /** Register categories used by scripts, frames, or other integrations. */
120
+ export declare const useRegisterConsentCategories: () => (categories: readonly AllConsentNames[]) => void;
94
121
  /**
95
122
  * Sync mutation: apply overrides (country, region, language, GPC).
96
123
  */
@@ -23,8 +23,8 @@
23
23
  *
24
24
  * @packageDocumentation
25
25
  */
26
- export { IABConsentBanner, type IABConsentBannerProps, } from './components/iab-prompt';
27
- export { IABConsentDialog, type IABConsentDialogProps, } from './components/iab-panel';
28
- export { type HeadlessIABBannerAction, type HeadlessIABBannerState, type HeadlessIABDialogAction, type HeadlessIABDialogState, type HeadlessIABPreferenceTab, type UseHeadlessIABConsentUIResult, useHeadlessIABConsentUI, } from './hooks/use-headless-iab-consent-ui';
29
- export { IABProvider } from './iab-context';
30
- export type { IABProviderProps } from './iab-context';
26
+ export { IABConsentBanner, type IABConsentBannerProps, } from './components/iab-prompt/index.js';
27
+ export { IABConsentDialog, type IABConsentDialogProps, } from './components/iab-panel/index.js';
28
+ export { type HeadlessIABBannerAction, type HeadlessIABBannerState, type HeadlessIABDialogAction, type HeadlessIABDialogState, type HeadlessIABPreferenceTab, type UseHeadlessIABConsentUIResult, useHeadlessIABConsentUI, } from './hooks/use-headless-iab-consent-ui.js';
29
+ export { IABProvider } from './iab-context.js';
30
+ export type { IABProviderProps } from './iab-context.js';
@@ -33,29 +33,29 @@
33
33
  */
34
34
  export type { ConsentKernel, ConsentSnapshot, ConsentState, HostedTransportOptions, InitContext, InitResponse, InitResult, KernelConfig, KernelEvent, KernelOverrides, KernelTransport, KernelUser, Listener, HostedModeOptions, ProviderTransportContext, ProviderTransportFactory, ProviderTransportKind, SavePayload, SaveResult, Unsubscribe, } from '@c15t/core';
35
35
  export { createConsentKernel, custom, hosted } from '@c15t/core';
36
- export type { OfflineModeOptions } from './transports/offline';
37
- export { offline } from './transports/offline';
38
- export { ConsentDialog, ConsentWidget } from './aggregate-components';
39
- export type { ConsentBannerButton, ConsentBannerLayout, ConsentBannerProps, ConsentBannerRight, ConsentBannerRightLinkProps, ConsentBannerRightsProps, ConsentBannerSurface, } from './components/prompt';
40
- export { ConsentBanner, type ConsentBannerCompoundComponent, useConsentBannerSurface, } from './components/prompt';
41
- export type { ConsentDialogCompoundComponent, ConsentDialogProps, } from './components/panel';
42
- export type { ConsentDialogLinkProps } from './components/panel-link';
43
- export { ConsentDialogLink } from './components/panel-link';
44
- export type { ConsentDialogTriggerProps, ConsentDialogTriggerToolbarAction, ConsentDialogTriggerToolbarPreferences, ConsentDialogTriggerToolbarProps, TriggerOrientation, } from './components/panel-trigger';
45
- export { ConsentDialogTrigger, ConsentDialogTriggerToolbar, } from './components/panel-trigger';
46
- export type { ConsentWidgetCompoundComponent, ConsentWidgetProps, } from './components/preferences';
47
- export type { FrameProps } from './components/frame';
48
- export { Frame } from './components/frame';
49
- export type { ConsentDraftHandle, ConsentDraftProviderProps } from './draft';
50
- export { ConsentDraftProvider, useConsentDraft } from './draft';
51
- export { useConsentManager } from './component-hooks/use-manager';
52
- export { useTranslations } from './component-hooks/use-translations';
53
- export { useActiveUI, useBranding, useConsent, useConsents, useHasConsentPolicy, useHasConsentUI, useIABEnabled, useIABSnapshot, useIdentify, useInit, useLocation, useModel, useOverrides, usePromptPresentation, usePolicyCategories, usePreferencesPresentation, usePolicyScopeMode, usePurposeConsent, useSaveConsents, useSetActiveUI, useSetLanguage, useSetOverrides, useSnapshot, useSpecialFeatureOptIn, useTCString, useUser, useVendorConsent, } from './hooks';
54
- export type { UseIframeBlockerOptions, UseNetworkBlockerOptions, UsePersistenceOptions, UseScriptLoaderOptions, } from './module-hooks';
55
- export { useIframeBlocker, useNetworkBlocker, usePersistence, useScriptLoader, } from './module-hooks';
56
- export type { ConsentProviderOptions, ConsentProviderCallbacks, ConsentProviderPrefetch, ConsentProviderProps, ExternalRuntimeProviderOptions, ExternalRuntimeProviderProps, OwnedRuntimeProviderProps, } from './provider';
57
- export { ConsentProvider } from './provider';
58
- export type { ReactUIOptions } from './types/manager';
59
- export { defineTheme, type Theme } from './types/theme';
60
- export { useExplicitChoice, useEffectivePermissions, usePromptRequirement, useNoticeDismissal, usePrivacySignals, useOptOutDirectives, usePolicyResolution, usePolicyRule, useRestrictions, useDismissNotice, } from './hooks';
36
+ export type { OfflineModeOptions } from './transports/offline.js';
37
+ export { offline } from './transports/offline.js';
38
+ export { ConsentDialog, ConsentWidget } from './aggregate-components.js';
39
+ export type { ConsentBannerButton, ConsentBannerLayout, ConsentBannerProps, ConsentBannerRight, ConsentBannerRightLinkProps, ConsentBannerRightsProps, ConsentBannerSurface, } from './components/prompt/index.js';
40
+ export { ConsentBanner, type ConsentBannerCompoundComponent, useConsentBannerSurface, } from './components/prompt/index.js';
41
+ export type { ConsentDialogCompoundComponent, ConsentDialogProps, } from './components/panel/index.js';
42
+ export type { ConsentDialogLinkProps } from './components/panel-link/index.js';
43
+ export { ConsentDialogLink } from './components/panel-link/index.js';
44
+ export type { ConsentDialogTriggerProps, ConsentDialogTriggerToolbarAction, ConsentDialogTriggerToolbarPreferences, ConsentDialogTriggerToolbarProps, TriggerOrientation, } from './components/panel-trigger/index.js';
45
+ export { ConsentDialogTrigger, ConsentDialogTriggerToolbar, } from './components/panel-trigger/index.js';
46
+ export type { ConsentWidgetCompoundComponent, ConsentWidgetProps, } from './components/preferences/index.js';
47
+ export type { ConsentGateProps, FrameProps } from './components/consent-gate/index.js';
48
+ export { ConsentGate, Frame } from './components/consent-gate/index.js';
49
+ export type { ConsentDraftHandle, ConsentDraftProviderProps, VendorDraftHandle, } from './draft.js';
50
+ export { ConsentDraftProvider, useConsentDraft, useVendorDraft } from './draft.js';
51
+ export { useConsentManager } from './component-hooks/use-manager.js';
52
+ export { useTranslations } from './component-hooks/use-translations.js';
53
+ export { useActiveUI, useBranding, useConsent, useConsents, useHasConsentPolicy, useHasConsentUI, useIABEnabled, useIABSnapshot, useIdentify, useInit, useLocation, useModel, useOverrides, usePromptPresentation, usePolicyCategories, usePreferencesPresentation, usePolicyScopeMode, usePurposeConsent, useSaveConsents, useSetActiveUI, useSetLanguage, useSetOverrides, useSnapshot, useSpecialFeatureOptIn, useTCString, useUser, useDeclaredVendors, useVendorAllowed, useVendorChoice, useVendorConsent, } from './hooks.js';
54
+ export type { UseIframeBlockerOptions, UseNetworkBlockerOptions, UsePersistenceOptions, UseScriptLoaderOptions, } from './module-hooks.js';
55
+ export { useIframeBlocker, useNetworkBlocker, usePersistence, useScriptLoader, } from './module-hooks.js';
56
+ export type { ConsentProviderOptions, ConsentProviderCallbacks, ConsentProviderPrefetch, ConsentProviderProps, ExternalRuntimeProviderOptions, ExternalRuntimeProviderProps, OwnedRuntimeProviderProps, } from './provider.js';
57
+ export { ConsentProvider } from './provider.js';
58
+ export type { ReactUIOptions } from './types/manager.js';
59
+ export { defineTheme, type Theme } from './types/theme/index.js';
60
+ export { useExplicitChoice, useEffectivePermissions, usePromptRequirement, useNoticeDismissal, usePrivacySignals, useOptOutDirectives, usePolicyResolution, usePolicyRule, useRestrictions, useDismissNotice, } from './hooks.js';
61
61
  export type { ConsentPresentation, PromptPresentation, PreferencesPresentation, PresentationAction, PromptPosition, PromptVariant, ResolvedConsentPresentation, } from '@c15t/core';
@@ -1,4 +1,4 @@
1
- export { type IframeBlockerHandle, type UseIframeBlockerOptions, useIframeBlocker, } from './module-hooks/iframe-blocker';
2
- export { type BlockedRequestInfo, type NetworkBlockerHandle, type NetworkBlockerRule, type UseNetworkBlockerOptions, useNetworkBlocker, } from './module-hooks/network-blocker';
3
- export { type PersistenceHandle, type PersistenceOptions, type UsePersistenceOptions, usePersistence, } from './module-hooks/persistence';
4
- export { type Script, type ScriptLoaderDebugEvent, type ScriptLoaderHandle, type UseScriptLoaderOptions, useScriptLoader, } from './module-hooks/script-loader';
1
+ export { type IframeBlockerHandle, type UseIframeBlockerOptions, useIframeBlocker, } from './module-hooks/iframe-blocker.js';
2
+ export { type BlockedRequestInfo, type NetworkBlockerHandle, type NetworkBlockerRule, type UseNetworkBlockerOptions, useNetworkBlocker, } from './module-hooks/network-blocker.js';
3
+ export { type PersistenceHandle, type PersistenceOptions, type UsePersistenceOptions, usePersistence, } from './module-hooks/persistence.js';
4
+ export { type Script, type ScriptLoaderDebugEvent, type ScriptLoaderHandle, type UseScriptLoaderOptions, useScriptLoader, } from './module-hooks/script-loader.js';
@@ -1 +1 @@
1
- export * from './components/panel-link';
1
+ export * from './components/panel-link/index.js';
@@ -1 +1 @@
1
- export * from './components/panel-trigger';
1
+ export * from './components/panel-trigger/index.js';
@@ -1 +1 @@
1
- export * from './components/panel';
1
+ export * from './components/panel/index.js';
@@ -1 +1 @@
1
- export * from './components/preferences';
1
+ export * from './components/preferences/index.js';
@@ -1 +1 @@
1
- export * from '../components/shared/ui/accordion';
1
+ export * from '../components/shared/ui/accordion/index.js';
@@ -1 +1 @@
1
- export * from '../components/shared/ui/button';
1
+ export * from '../components/shared/ui/button/index.js';
@@ -1 +1 @@
1
- export * from '../components/shared/ui/collapsible';
1
+ export * from '../components/shared/ui/collapsible/index.js';
@@ -1 +1 @@
1
- export * from '../components/shared/ui/dialog';
1
+ export * from '../components/shared/ui/dialog/index.js';
@@ -1 +1 @@
1
- export * from '../components/shared/ui/preference-item';
1
+ export * from '../components/shared/ui/preference-item/index.js';
@@ -1 +1 @@
1
- export * from '../components/shared/ui/switch';
1
+ export * from '../components/shared/ui/switch/index.js';
@@ -1 +1 @@
1
- export * from '../components/shared/ui/tabs';
1
+ export * from '../components/shared/ui/tabs/index.js';
@@ -1,7 +1,7 @@
1
- export * as Accordion from './components/shared/ui/accordion';
2
- export * as Button from './components/shared/ui/button';
3
- export * as Collapsible from './components/shared/ui/collapsible';
4
- export * as Dialog from './components/shared/ui/dialog';
5
- export * as PreferenceItem from './components/shared/ui/preference-item';
6
- export * as Switch from './components/shared/ui/switch';
7
- export * as Tabs from './components/shared/ui/tabs';
1
+ export * as Accordion from './components/shared/ui/accordion/index.js';
2
+ export * as Button from './components/shared/ui/button/index.js';
3
+ export * as Collapsible from './components/shared/ui/collapsible/index.js';
4
+ export * as Dialog from './components/shared/ui/dialog/index.js';
5
+ export * as PreferenceItem from './components/shared/ui/preference-item/index.js';
6
+ export * as Switch from './components/shared/ui/switch/index.js';
7
+ export * as Tabs from './components/shared/ui/tabs/index.js';
@@ -1 +1 @@
1
- export * from './components/prompt';
1
+ export * from './components/prompt/index.js';
@@ -1,10 +1,11 @@
1
- import type { AllConsentNames, ConsentPresentation, Callbacks, I18nConfig, KernelConfig, KernelOverrides, KernelUser, LegalLinks, ProviderTransportFactory, StorageConfig, User } from '@c15t/core';
1
+ import type { AllConsentNames, ClearOnRevocationConfig, ConsentPresentation, Callbacks, I18nConfig, KernelConfig, KernelOverrides, KernelUser, LegalLinks, ProviderTransportFactory, StorageConfig, User, Vendor } from '@c15t/core';
2
2
  import type { Script } from '@c15t/core/modules/script-loader';
3
3
  import type { ConsentRuntime } from '@c15t/core/runtime';
4
4
  import type { ReactNode } from 'react';
5
- import type { UseNetworkBlockerOptions, UsePersistenceOptions, UseScriptLoaderOptions } from './module-hooks';
6
- import type { ReactUIOptions } from './types/manager';
7
- import type { ReactComponentSlots } from './types/slots';
5
+ import type { UseNetworkBlockerOptions, UsePersistenceOptions, UseScriptLoaderOptions } from './module-hooks.js';
6
+ import type { UseIframeBlockerOptions } from './module-hooks/iframe-blocker.js';
7
+ import type { ReactUIOptions } from './types/manager.js';
8
+ import type { ReactComponentSlots } from './types/slots.js';
8
9
  /** Events emitted by the mounted provider without snapshot-derived consent aliases. */
9
10
  export type ConsentProviderCallbacks = Pick<Callbacks, 'onChoiceRecorded' | 'onPermissionsChanged' | 'onError'>;
10
11
  /** Prepared policy and records; legacy consent projections are not provider inputs. */
@@ -77,11 +78,27 @@ export interface ConsentProviderOptions extends Pick<ReactUIOptions, 'colorSchem
77
78
  */
78
79
  prefetch?: ConsentProviderPrefetch | Promise<ConsentProviderPrefetch>;
79
80
  callbacks?: ConsentProviderCallbacks;
81
+ /**
82
+ * Remove configured browser data when its consent permission is revoked.
83
+ * Initial-only: remount the provider to replace its cleanup configuration.
84
+ */
85
+ clearOnRevocation?: ClearOnRevocationConfig;
80
86
  scripts?: Script[];
87
+ /**
88
+ * Vendors offered for vendor-level consent outside IAB. Each sits inside a
89
+ * category; a visitor can grant the category and still turn one vendor
90
+ * off. Scripts, network rules and iframes name a vendor through `vendor`
91
+ * or `data-vendor`. Merged with vendors the backend returns and with slugs
92
+ * found on scripts and rules; presentation declared here wins.
93
+ */
94
+ vendors?: Vendor[];
81
95
  scriptLoader?: UseScriptLoaderOptions;
82
96
  networkBlocker?: UseNetworkBlockerOptions | false;
97
+ /** Discover and gate DOM iframes with data-category. Enabled by default. */
98
+ iframeBlocker?: UseIframeBlockerOptions | false;
83
99
  persistence?: boolean | UsePersistenceOptions;
84
100
  i18n?: Partial<I18nConfig>;
101
+ /** Categories to offer alongside discovered integration categories, within policy scope. */
85
102
  consentCategories?: AllConsentNames[];
86
103
  /** Per-component slot attribute overrides (shared contract with @c15t/vue). */
87
104
  components?: ReactComponentSlots;
@@ -99,8 +116,13 @@ export interface ConsentProviderOptions extends Pick<ReactUIOptions, 'colorSchem
99
116
  * Everything the component tree still owns — theme, slots, legal links —
100
117
  * is unchanged.
101
118
  */
102
- export type ExternalRuntimeProviderOptions = Omit<ConsentProviderOptions, 'mode'> & {
119
+ export type ExternalRuntimeProviderOptions = Omit<ConsentProviderOptions, 'mode' | 'vendors'> & {
103
120
  mode?: ConsentProviderOptions['mode'];
121
+ /**
122
+ * Not accepted here: the runtime owner declares vendors through
123
+ * `createConsentRuntime({ vendors })`, and the kernel carries them.
124
+ */
125
+ vendors?: never;
104
126
  };
105
127
  /** The provider builds and owns its own kernel. */
106
128
  export interface OwnedRuntimeProviderProps {
@@ -1,5 +1,5 @@
1
1
  import type { SSRInitialData } from '@c15t/core';
2
- import type { FetchSSRDataOptions } from './types';
2
+ import type { FetchSSRDataOptions } from './types.js';
3
3
  /**
4
4
  * Fetches initial consent data on the server for SSR hydration.
5
5
  *
@@ -24,8 +24,8 @@
24
24
  *
25
25
  * @packageDocumentation
26
26
  */
27
- export { fetchSSRData } from './fetch-ssr-data';
28
- export { extractRelevantHeaders } from './headers';
29
- export { createSSRInitCacheKey } from './init-cache-key';
30
- export { normalizeBackendURL, validateBackendURL } from './normalize-url';
31
- export type { FetchSSRDataOptions, FetchSSRDataOptionsBase, FetchSSRDataResult, } from './types';
27
+ export { fetchSSRData } from './fetch-ssr-data.js';
28
+ export { extractRelevantHeaders } from './headers.js';
29
+ export { createSSRInitCacheKey } from './init-cache-key.js';
30
+ export { normalizeBackendURL, validateBackendURL } from './normalize-url.js';
31
+ export type { FetchSSRDataOptions, FetchSSRDataOptionsBase, FetchSSRDataResult, } from './types.js';
@@ -1,6 +1,6 @@
1
1
  import type { ReactNode } from 'react';
2
- import type { ThemeContextValue } from './context/theme-context';
3
- import type { V3UIConfigValue } from './ui-config-context';
2
+ import type { ThemeContextValue } from './context/theme-context.js';
3
+ import type { V3UIConfigValue } from './ui-config-context.js';
4
4
  interface V3ThemeProviderProps {
5
5
  themeConfig: ThemeContextValue;
6
6
  uiConfig: V3UIConfigValue;
@@ -1,3 +1,3 @@
1
- export * from './manager';
2
- export * from './slots';
3
- export * from './theme';
1
+ export * from './manager.js';
2
+ export * from './slots.js';
3
+ export * from './theme/index.js';
@@ -1,5 +1,5 @@
1
1
  import type { UIOptions } from '@c15t/ui/theme';
2
- import type { ReactComponentSlots } from './slots';
2
+ import type { ReactComponentSlots } from './slots.js';
3
3
  /**
4
4
  * React-specific UI configuration options.
5
5
  *
@@ -1 +1 @@
1
- export * from './style-types';
1
+ export * from './style-types.js';
@@ -1,5 +1,5 @@
1
1
  import type { LegalLinks, ConsentPresentation } from '@c15t/core';
2
- import type { ReactComponentSlots } from './types/slots';
2
+ import type { ReactComponentSlots } from './types/slots.js';
3
3
  export interface V3UIConfigValue {
4
4
  components?: ReactComponentSlots;
5
5
  presentation?: ConsentPresentation;
@@ -0,0 +1,11 @@
1
+ import type { ComponentType } from 'react';
2
+ /**
3
+ * Share an on-demand module across exports and intent preloading. Ready client
4
+ * retries run synchronously; Suspense retains server rendering and hydration.
5
+ *
6
+ * @internal
7
+ */
8
+ export declare const createDeferredModule: <ModuleType>(importModule: () => Promise<ModuleType>) => {
9
+ component<Props extends object>(select: (module: ModuleType) => ComponentType<Props>): ComponentType<Props>;
10
+ preload(): Promise<void>;
11
+ };
@@ -1,4 +1,4 @@
1
- export * from './cn';
2
- export * from './default-translation-config';
3
- export * from './merge-styles';
4
- export * from './theme-utils';
1
+ export * from './cn.js';
2
+ export * from './default-translation-config.js';
3
+ export * from './merge-styles.js';
4
+ export * from './theme-utils.js';
@@ -1,7 +1,7 @@
1
1
  import type { ConsentComponentSlotKey } from '@c15t/schema/config';
2
2
  import type { ClassValue } from '@c15t/ui/utils';
3
- import type { ReactComponentSlots, ReactSlotProps } from '../types/slots';
4
- import type { CSSPropertiesWithVars } from '../types/theme';
3
+ import type { ReactComponentSlots, ReactSlotProps } from '../types/slots.js';
4
+ import type { CSSPropertiesWithVars } from '../types/theme/index.js';
5
5
  type MergeSlotPropsInput = ReactSlotProps & {
6
6
  baseClassName?: ClassValue;
7
7
  noStyle?: boolean;
@@ -1,4 +1,4 @@
1
- import type { ClassNameStyle, ThemeValue } from '../types/theme';
1
+ import type { ClassNameStyle, ThemeValue } from '../types/theme/index.js';
2
2
  /**
3
3
  * Merges two styles objects, handling theme values and style properties.
4
4
  * This React version uses React-specific types but uses the core logic from @c15t/ui.
@@ -3,7 +3,7 @@
3
3
  * Handles token-to-CSS variable conversion and dark mode overrides.
4
4
  */
5
5
  import type { ThemeCSSVariables } from '@c15t/ui/theme';
6
- import type { Theme } from '../types/theme/style-types';
6
+ import type { Theme } from '../types/theme/style-types.js';
7
7
  /**
8
8
  * Default design tokens for the v2 theme system.
9
9
  */
@@ -1 +1 @@
1
- export declare const version = "3.0.0-alpha.0";
1
+ export declare const version = "3.0.0-alpha.2";
package/docs/README.md CHANGED
@@ -25,10 +25,10 @@ These docs describe v3. Start with Inth hosted setup, identify the framework, ro
25
25
  - [ConsentDialog](./frameworks/react/components/consent-dialog.md): Open the c15t preference center as a modal ConsentDialog in a React app, wire its triggers and control blocking, focus and policy gating.
26
26
  - [ConsentDialogLink](./frameworks/react/components/consent-dialog-link.md): Add a ConsentDialogLink to a React footer so visitors reopen the c15t preference center from your own text link, with asChild and rights data.
27
27
  - [ConsentDialogTrigger](./frameworks/react/components/consent-dialog-trigger.md): Floating button and toolbar that reopen the preference center after the first prompt.
28
+ - [ConsentGate](./frameworks/react/components/consent-gate.md): Gate a YouTube or map iframe behind consent with ConsentGate in React, showing a placeholder that opens the preference center until the category is allowed.
28
29
  - [ConsentProvider](./frameworks/react/components/consent-manager-provider.md): Configure the v3 consent runtime and share its state with child components.
29
30
  - [ConsentWidget](./frameworks/react/components/consent-widget.md): Embed the c15t preference center inline with ConsentWidget on a React privacy page, with draft toggles that record a choice only on Save.
30
31
  - [DevTools](./frameworks/react/components/dev-tools.md): A development tool for inspecting consent state, geolocation, loaded scripts, and consent events in real time.
31
- - [Frame](./frameworks/react/components/frame.md): Gate a YouTube or map iframe behind consent with Frame in React, showing a placeholder that opens the preference center until the category is allowed.
32
32
  - [Consent categories](./frameworks/react/concepts/consent-categories.md): Assign optional features to categories and understand how policy scope affects permission.
33
33
  - [Policy presets](./frameworks/react/concepts/policy-presets.md): Understand how policy rules affect React prompts, permissions and persistent privacy controls.
34
34
  - [Headless](./frameworks/react/headless.md): Build a custom consent banner in React with the c15t/react/headless hooks inside your ConsentProvider.
@@ -61,14 +61,17 @@ These docs describe v3. Start with Inth hosted setup, identify the framework, ro
61
61
  - [Ahrefs Analytics](./integrations/ahrefs-analytics.md): Configure Ahrefs Analytics with c15t v3, understand measurement permission and verify loading and revocation.
62
62
  - [Amplitude](./integrations/amplitude.md): Configure Amplitude with c15t v3, understand measurement permission and verify loading and revocation.
63
63
  - [Custom integrations](./integrations/building-integrations.md): Define loading, initialization and consent-change behavior for a vendor without a helper.
64
+ - [Clear on revocation](./integrations/clear-on-revocation.md): Remove configured first-party cookies and Web Storage keys when their consent category is denied.
64
65
  - [Clearbit](./integrations/clearbit.md): Configure Clearbit with c15t v3, understand marketing permission and verify loading and revocation.
65
66
  - [Cloudflare Web Analytics](./integrations/cloudflare-web-analytics.md): Configure Cloudflare Web Analytics with c15t v3, understand measurement permission and verify loading and revocation.
67
+ - [Cloudflare Zaraz](./integrations/cloudflare-zaraz.md): Synchronize c15t permissions with Zaraz purposes while Cloudflare manages your tools.
66
68
  - [Crisp](./integrations/crisp.md): Configure Crisp with c15t v3, understand functionality permission and verify loading and revocation.
67
69
  - [Databuddy](./integrations/databuddy.md): Configure Databuddy's initial and updated consent state with c15t v3.
68
70
  - [Fathom Analytics](./integrations/fathom-analytics.md): Configure Fathom Analytics with c15t v3, understand measurement permission and verify loading and revocation.
69
71
  - [Google Maps](./integrations/google-maps.md): Prevent a map iframe from mounting before the required permission.
70
72
  - [Google Tag](./integrations/google-tag.md): Configure gtag with c15t Consent Mode signals and understand its loading behavior.
71
73
  - [Google Tag Manager](./integrations/google-tag-manager.md): Load GTM with c15t consent signals and verify the tags inside your container.
74
+ - [Granular consent](./integrations/granular-consent.md): Let visitors grant a category and still turn one vendor off, without adopting IAB TCF.
72
75
  - [Heap](./integrations/heap.md): Configure Heap with c15t v3, understand measurement permission and verify loading and revocation.
73
76
  - [Hightouch](./integrations/hightouch.md): Configure Hightouch with c15t v3, understand measurement permission and verify loading and revocation.
74
77
  - [Hotjar](./integrations/hotjar.md): Configure Hotjar with c15t v3, understand measurement permission and verify loading and revocation.
@@ -93,7 +93,7 @@ it is `dialog`. These set that surface:
93
93
  * The Customize button on a `ConsentBanner`, and the "Manage preferences"
94
94
  or "Do not sell or share my data" button a notice renders.
95
95
  * `ConsentDialogLink` and `ConsentDialogTrigger`.
96
- * The button in a `Frame` placeholder.
96
+ * The button in a `ConsentGate` placeholder.
97
97
  * `useSetActiveUI()('dialog')` in your own component, or `openDialog()`
98
98
  from `useHeadlessConsentUI()` on the headless subpath.
99
99
 
@@ -1,14 +1,14 @@
1
1
  ---
2
- title: Frame
3
- description: Gate a YouTube or map iframe behind consent with Frame in React,
4
- showing a placeholder that opens the preference center until the category is
5
- allowed.
2
+ title: ConsentGate
3
+ description: Gate a YouTube or map iframe behind consent with ConsentGate in
4
+ React, showing a placeholder that opens the preference center until the
5
+ category is allowed.
6
6
  group: frameworks
7
7
  ---
8
8
 
9
9
  ## Gate an embed behind consent
10
10
 
11
- `Frame` mounts its children only while the effective permission for one
11
+ `ConsentGate` mounts its children only while the effective permission for one
12
12
  consent category is granted, and shows a placeholder otherwise. Wrap any
13
13
  iframe or third-party widget that would set cookies or contact a vendor on
14
14
  load. Render it anywhere inside the `ConsentProvider` from your
@@ -16,11 +16,11 @@ load. Render it anywhere inside the `ConsentProvider` from your
16
16
  placeholder button opens.
17
17
 
18
18
  ```tsx title="src/product-video.tsx"
19
- import { Frame } from 'c15t/react';
19
+ import { ConsentGate } from 'c15t/react';
20
20
 
21
21
  export function ProductVideo() {
22
22
  return (
23
- <Frame category="marketing" className="video-frame">
23
+ <ConsentGate category="marketing" className="video-frame">
24
24
  <iframe
25
25
  src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ"
26
26
  title="Product tour"
@@ -28,18 +28,18 @@ export function ProductVideo() {
28
28
  allowFullScreen
29
29
  style={{ width: '100%', aspectRatio: '16 / 9', border: 0 }}
30
30
  />
31
- </Frame>
31
+ </ConsentGate>
32
32
  );
33
33
  }
34
34
  ```
35
35
 
36
36
  `marketing` must be in your policy scope. If you set a non-empty
37
37
  `options.consentCategories` list on `ConsentProvider`, include `marketing`
38
- there too so the preference center can display and save it. `Frame` does
38
+ there too so the preference center can display and save it. `ConsentGate` does
39
39
  not add categories to that list.
40
40
 
41
41
  The placeholder names the category using its title from your translations. Set `className` or `style`
42
- on `Frame` to reserve the embed's space, so the page does not shift when the
42
+ on `ConsentGate` to reserve the embed's space, so the page does not shift when the
43
43
  placeholder is replaced.
44
44
 
45
45
  ## Props
@@ -51,22 +51,22 @@ placeholder is replaced.
51
51
  | `placeholder` | `ReactNode` | built-in placeholder | Replaces the built-in title and button while the category is not allowed. Falsy values such as `null`, `false`, `0` and an empty string use the built-in placeholder. Pass an empty fragment, `<></>`, to render no placeholder content. |
52
52
 
53
53
  Other `div` attributes such as `className`, `style` and `ref` apply to the
54
- wrapper element that stays in the page in both states. `FrameProps` also
54
+ wrapper element that stays in the page in both states. `ConsentGateProps` also
55
55
  declares `noStyle` and `theme`, but the component does not apply them yet;
56
56
  style the wrapper with `className` and theme the placeholder through the
57
57
  provider `theme` option.
58
58
 
59
59
  ## Behavior
60
60
 
61
- `Frame` renders a `div` wrapper. Inside it, when the effective permission for
61
+ `ConsentGate` renders a `div` wrapper. Inside it, when the effective permission for
62
62
  `category` is granted, it renders the children; otherwise it renders the
63
63
  placeholder. Permission is the same value `useConsent(category)` returns,
64
64
  so it can be granted under an opt-out rule before the visitor records a
65
65
  choice, and a recorded grant can be overridden by a privacy signal.
66
66
 
67
67
  While effective permission is denied, the children are absent from the DOM,
68
- so an iframe or a third-party widget inside `Frame` sends no requests. When the visitor later revokes it, the
69
- children unmount and the embed disappears. `Frame` does not depend on the
68
+ so an iframe or a third-party widget inside `ConsentGate` sends no requests. When the visitor later revokes it, the
69
+ children unmount and the embed disappears. `ConsentGate` does not depend on the
70
70
  network blocker or the iframe blocker modules; use those for markup you
71
71
  cannot wrap in a component.
72
72
 
@@ -89,13 +89,13 @@ A grant in the request cookie allows the embed only when policy and privacy
89
89
  signals permit it. Browser privacy signals detected during hydration can
90
90
  withdraw that permission. In a browser-only setup the
91
91
  provider has no permission until it resolves policy on the client, so
92
- `Frame` shows the placeholder first and swaps in the embed after resolution
92
+ `ConsentGate` shows the placeholder first and swaps in the embed after resolution
93
93
  when the category is already granted.
94
94
 
95
- `Frame` is one component on this page; the per-vendor embed guides for
95
+ `ConsentGate` is one component on this page; the per-vendor embed guides for
96
96
  [YouTube](../../../integrations/youtube.md) and
97
97
  [Google Maps](../../../integrations/google-maps.md) show a complete embed
98
- configuration with sizing, titles and the same `Frame` usage across
98
+ configuration with sizing, titles and the same `ConsentGate` usage across
99
99
  frameworks.
100
100
 
101
101
  To read the same permission in your own components, use `useConsent` from
@@ -104,24 +104,24 @@ also import from there.
104
104
 
105
105
  ## Composition
106
106
 
107
- The placeholder parts are available as `Frame.Root`, `Frame.Title` and
108
- `Frame.Button` for a custom placeholder that keeps the built-in copy and
109
- behavior. `Frame.Title` and `Frame.Button` accept `category` and fill in the
107
+ The placeholder parts are available as `ConsentGate.Root`, `ConsentGate.Title` and
108
+ `ConsentGate.Button` for a custom placeholder that keeps the built-in copy and
109
+ behavior. `ConsentGate.Title` and `ConsentGate.Button` accept `category` and fill in the
110
110
  translated text; pass children to either to replace it.
111
111
 
112
112
  ```tsx
113
- <Frame
113
+ <ConsentGate
114
114
  category="marketing"
115
115
  placeholder={
116
- <Frame.Root>
117
- <Frame.Title category="marketing" />
116
+ <ConsentGate.Root>
117
+ <ConsentGate.Title category="marketing" />
118
118
  <p>The video is also available on our channel.</p>
119
- <Frame.Button category="marketing">Choose cookies</Frame.Button>
120
- </Frame.Root>
119
+ <ConsentGate.Button category="marketing">Choose cookies</ConsentGate.Button>
120
+ </ConsentGate.Root>
121
121
  }
122
122
  >
123
123
  <iframe src="https://www.youtube-nocookie.com/embed/..." title="Product tour" />
124
- </Frame>
124
+ </ConsentGate>
125
125
  ```
126
126
 
127
127
  The built-in placeholder carries `data-testid="frame-placeholder"` and its
@@ -131,7 +131,7 @@ button `data-testid="frame-open-dialog"`.
131
131
 
132
132
  The placeholder is plain text and a `button`, so it is readable and
133
133
  operable without the embed. Give the iframe a descriptive `title`, and keep a
134
- transcript, address or link outside the `Frame` for visitors who decline
134
+ transcript, address or link outside the `ConsentGate` for visitors who decline
135
135
  the category. A denied category may be fixed by policy, so opening the
136
136
  preference center does not guarantee that the visitor can grant it.
137
137
 
@@ -58,5 +58,18 @@ signals. Hydration and notice dismissal do not become explicit choices.
58
58
 
59
59
  An externally owned runtime can be passed through `runtime`. Its owner must
60
60
  start and dispose it. A provider borrowing that runtime must not initialize or
61
- dispose a second copy. See [consent state](../../../guides/consent-state.md) and
61
+ dispose a second copy. Keep the runtime stable for the provider's lifetime and
62
+ unmount the borrowing provider when disposing the runtime. IAB actions taken
63
+ before its handle is ready wait for that handle. If the provider unmounts first,
64
+ a pending `save()` rejects with an `AbortError` instead of waiting indefinitely.
65
+ See [consent state](../../../guides/consent-state.md) and
62
66
  [deployment modes](../../../guides/deployment-modes.md).
67
+
68
+ ## Clear data when consent is denied
69
+
70
+ Set `options.clearOnRevocation` to declare cookies, localStorage keys, and
71
+ sessionStorage keys by optional consent category. Cleanup waits for policy
72
+ resolution, then clears denied categories and later allowed-to-denied
73
+ transitions. This option is initial-only. See
74
+ [clear on revocation](../../../integrations/clear-on-revocation.md) for examples,
75
+ cookie scopes, and browser limits.