@c15t/react 3.0.0-alpha.2 → 3.0.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +91 -67
- package/README.md +21 -17
- package/SKILL.md +34 -0
- package/dist/aggregate-components.js +1 -1
- package/dist/chunk-warming.js +1 -1
- package/dist/component-hooks/use-headless-consent-ui.js +1 -1
- package/dist/component-hooks/use-headless-iab-consent-ui.js +1 -1
- package/dist/component-hooks/use-panel-trigger.js +1 -1
- package/dist/components/consent-gate/atoms.js +1 -1
- package/dist/components/consent-gate/consent-gate.js +1 -1
- package/dist/components/consent-preferences-link/consent-preferences-link.js +1 -1
- package/dist/components/iab-panel/atoms/card.js +1 -1
- package/dist/components/iab-panel/atoms/feature-item.js +2 -0
- package/dist/components/iab-panel/atoms/header.js +1 -1
- package/dist/components/iab-panel/atoms/purpose-item.js +1 -1
- package/dist/components/iab-panel/atoms/stack-item.js +1 -1
- package/dist/components/iab-panel/iab-panel.js +1 -1
- package/dist/components/iab-panel/index.js +1 -1
- package/dist/components/iab-prompt/atoms/overlay.js +1 -1
- package/dist/components/iab-prompt/atoms/root.js +1 -1
- package/dist/components/panel/atoms/card.js +1 -1
- package/dist/components/panel/atoms/overlay.js +1 -1
- package/dist/components/panel/atoms/root.js +1 -1
- package/dist/components/panel/index.js +1 -1
- package/dist/components/panel/panel.js +1 -1
- package/dist/components/panel-trigger/atoms/button.js +1 -1
- package/dist/components/panel-trigger/atoms/icon.js +1 -1
- package/dist/components/panel-trigger/atoms/root.js +1 -1
- package/dist/components/panel-trigger/atoms/toolbar.js +1 -1
- package/dist/components/panel-trigger/atoms/trigger-icons.js +1 -0
- package/dist/components/panel-trigger/panel-trigger-toolbar.js +1 -1
- package/dist/components/preferences/atoms/accordion.js +1 -1
- package/dist/components/preferences/atoms/root.js +1 -1
- package/dist/components/preferences/atoms/vendor-list.js +1 -1
- package/dist/components/preferences/index.js +1 -1
- package/dist/components/prompt/atoms/overlay.js +1 -1
- package/dist/components/prompt/atoms/root.js +1 -1
- package/dist/components/prompt/components.js +1 -1
- package/dist/components/prompt/policy-actions.js +1 -1
- package/dist/components/shared/libs/compose-refs.js +1 -0
- package/dist/components/shared/libs/slot.js +1 -1
- package/dist/components/shared/primitives/button.js +1 -1
- package/dist/components/shared/ui/accordion/accordion.js +1 -1
- package/dist/components/shared/ui/collapsible/collapsible.js +1 -1
- package/dist/components/shared/ui/dialog/dialog.js +1 -1
- package/dist/components/shared/ui/icon.js +1 -1
- package/dist/components/shared/ui/logo.js +1 -1
- package/dist/components/shared/ui/preference-item/preference-item.js +1 -1
- package/dist/components/shared/ui/switch/switch.js +1 -1
- package/dist/components/shared/ui/tabs/tabs.js +1 -1
- package/dist/consent-theme.js +1 -0
- package/dist/context/consent-tracking-context.js +1 -1
- package/dist/devtools.js +1 -1
- package/dist/draft.js +1 -1
- package/dist/external-iab-context.js +1 -1
- package/dist/headless.js +1 -1
- package/dist/hooks/use-committed-ref.js +2 -0
- package/dist/hooks/use-focus-trap.js +1 -1
- package/dist/hooks.js +1 -1
- package/dist/iab/styles.tw3.css +5 -45
- package/dist/iab-context.js +1 -1
- package/dist/index.js +1 -1
- package/dist/kernel-selector.js +1 -0
- package/dist/module-hooks/iframe-blocker.js +1 -1
- package/dist/module-hooks/network-blocker.js +1 -1
- package/dist/module-hooks/network-hold.js +2 -0
- package/dist/module-hooks/persistence.js +1 -1
- package/dist/panel.js +1 -1
- package/dist/postcss-tailwind3.js +1 -0
- package/dist/preferences.js +1 -2
- package/dist/provider.js +1 -1
- package/dist/server/fetch-ssr-data.js +1 -1
- package/dist/server/headers.js +1 -1
- package/dist/server/normalize-url.js +1 -1
- package/dist/styles.tw3.css +16 -61
- package/dist/transports/offline.js +1 -1
- package/dist/ui-save.js +1 -1
- package/dist/utils/deferred-module.js +1 -1
- package/dist/utils/merge-slot-props.js +1 -1
- package/dist/utils/theme-utils.js +1 -1
- package/dist/version.js +1 -1
- package/dist-types/chunk-warming.d.ts +41 -8
- package/dist-types/component-hooks/use-headless-consent-ui.d.ts +1 -1
- package/dist-types/component-hooks/use-headless-iab-consent-ui.d.ts +1 -1
- package/dist-types/components/iab-panel/atoms/feature-item.d.ts +28 -0
- package/dist-types/components/iab-panel/atoms/purpose-item.d.ts +4 -1
- package/dist-types/components/iab-panel/atoms/stack-item.d.ts +6 -1
- package/dist-types/components/iab-panel/iab-panel.d.ts +2 -2
- package/dist-types/components/iab-panel/index.d.ts +6 -2
- package/dist-types/components/iab-panel/use-iab-translations.d.ts +4 -0
- package/dist-types/components/iab-prompt/iab-prompt.d.ts +2 -2
- package/dist-types/components/iab-prompt/index.d.ts +2 -2
- package/dist-types/components/panel/atoms/card.d.ts +1 -0
- package/dist-types/components/panel/index.d.ts +1 -0
- package/dist-types/components/panel/panel.d.ts +1 -1
- package/dist-types/components/panel-trigger/atoms/trigger-icons.d.ts +20 -0
- package/dist-types/components/preferences/index.d.ts +1 -0
- package/dist-types/components/prompt/components.d.ts +6 -0
- package/dist-types/components/shared/libs/compose-refs.d.ts +20 -0
- package/dist-types/components/shared/ui/accordion/accordion.d.ts +1 -0
- package/dist-types/components/shared/ui/collapsible/collapsible.d.ts +1 -0
- package/dist-types/components/shared/ui/icon.d.ts +2 -1
- package/dist-types/components/shared/ui/logo.d.ts +0 -10
- package/dist-types/components/shared/ui/preference-item/preference-item.d.ts +14 -0
- package/dist-types/components/shared/ui/switch/switch.d.ts +1 -0
- package/dist-types/components/shared/ui/tabs/tabs.d.ts +1 -0
- package/dist-types/consent-theme.d.ts +38 -0
- package/dist-types/context/consent-tracking-context.d.ts +10 -0
- package/dist-types/context/theme-context.d.ts +2 -2
- package/dist-types/context.d.ts +6 -0
- package/dist-types/devtools.d.ts +13 -2
- package/dist-types/draft.d.ts +50 -7
- package/dist-types/headless.d.ts +0 -1
- package/dist-types/hooks/use-committed-ref.d.ts +24 -0
- package/dist-types/hooks/use-focus-trap.d.ts +3 -1
- package/dist-types/hooks.d.ts +56 -13
- package/dist-types/iab.d.ts +1 -1
- package/dist-types/index.d.ts +4 -3
- package/dist-types/kernel-selector.d.ts +66 -0
- package/dist-types/module-hooks/iframe-blocker.d.ts +27 -0
- package/dist-types/module-hooks/network-blocker.d.ts +23 -0
- package/dist-types/module-hooks/network-hold.d.ts +47 -0
- package/dist-types/panel.d.ts +13 -1
- package/dist-types/postcss-tailwind3.d.ts +21 -0
- package/dist-types/preferences.d.ts +12 -1
- package/dist-types/provider.d.ts +62 -12
- package/dist-types/server/headers.d.ts +14 -4
- package/dist-types/server/normalize-url.d.ts +14 -7
- package/dist-types/server/types.d.ts +12 -1
- package/dist-types/transports/offline.d.ts +7 -16
- package/dist-types/ui-config-context.d.ts +9 -1
- package/dist-types/ui-save.d.ts +21 -1
- package/dist-types/utils/deferred-module.d.ts +3 -1
- package/dist-types/utils/merge-slot-props.d.ts +15 -1
- package/dist-types/utils/theme-utils.d.ts +17 -2
- package/dist-types/version.d.ts +1 -1
- package/docs/README.md +91 -67
- package/docs/assets/v3/bottom-bar.png +0 -0
- package/docs/assets/v3/brand-card.png +0 -0
- package/docs/assets/v3/brand-preferences.png +0 -0
- package/docs/assets/v3/choice-wall.png +0 -0
- package/docs/assets/v3/headless-bar-html.png +0 -0
- package/docs/assets/v3/headless-bar-mobile.png +0 -0
- package/docs/assets/v3/headless-bar.png +0 -0
- package/docs/assets/v3/slim-bar.png +0 -0
- package/docs/concepts/choose-your-setup.md +87 -0
- package/docs/{frameworks/react/concepts → concepts}/consent-categories.md +30 -8
- package/docs/concepts/consent-state.md +357 -0
- package/docs/{guides → concepts}/data-fetching.md +31 -27
- package/docs/concepts/how-consent-works.md +123 -0
- package/docs/{frameworks/react/concepts/policy-presets.md → concepts/policies.md} +7 -59
- package/docs/customization/class-names.md +202 -0
- package/docs/customization/dark-mode.md +157 -0
- package/docs/customization/motion.md +119 -0
- package/docs/customization/overview.md +67 -33
- package/docs/customization/recipes.md +839 -47
- package/docs/customization/slots.md +216 -35
- package/docs/customization/stylesheets.md +147 -0
- package/docs/customization/tailwind.md +842 -0
- package/docs/customization/tokens.md +166 -36
- package/docs/customization/translations.md +61 -3
- package/docs/frameworks/react/callbacks.md +118 -0
- package/docs/frameworks/react/clear-on-revocation.md +106 -0
- package/docs/frameworks/react/components/consent-banner.md +42 -28
- package/docs/frameworks/react/components/consent-dialog-link.md +13 -11
- package/docs/frameworks/react/components/consent-dialog-trigger.md +81 -76
- package/docs/frameworks/react/components/consent-dialog.md +100 -55
- package/docs/frameworks/react/components/consent-gate.md +45 -24
- package/docs/frameworks/react/components/consent-provider.md +126 -0
- package/docs/frameworks/react/components/consent-widget.md +32 -20
- package/docs/frameworks/react/components/dev-tools.md +52 -84
- package/docs/frameworks/react/components.md +105 -0
- package/docs/frameworks/react/compose.md +354 -0
- package/docs/frameworks/react/content-security-policy.md +126 -0
- package/docs/frameworks/react/customize.md +250 -0
- package/docs/frameworks/react/embeds.md +89 -0
- package/docs/frameworks/react/hooks.md +65 -0
- package/docs/frameworks/react/iab.md +222 -0
- package/docs/frameworks/react/network-blocker.md +140 -0
- package/docs/frameworks/react/quickstart.md +139 -101
- package/docs/frameworks/react/rendering.md +128 -0
- package/docs/frameworks/react/scripts.md +115 -0
- package/docs/frameworks/react/translations.md +155 -0
- package/docs/frameworks/react/troubleshooting.md +92 -47
- package/docs/frameworks/react/vendor-consent.md +170 -0
- package/docs/guides/banner-experiments.md +654 -0
- package/docs/guides/troubleshooting.md +120 -47
- package/docs/guides/verify-consent.md +81 -49
- package/docs/integrations/adobe-analytics.md +168 -160
- package/docs/integrations/ahrefs-analytics.md +153 -155
- package/docs/integrations/amplitude.md +163 -157
- package/docs/integrations/building-integrations.md +136 -37
- package/docs/integrations/clearbit.md +155 -155
- package/docs/integrations/cloudflare-web-analytics.md +157 -157
- package/docs/integrations/cloudflare-zaraz.md +210 -262
- package/docs/integrations/crisp.md +165 -159
- package/docs/integrations/databuddy.md +158 -174
- package/docs/integrations/fathom-analytics.md +159 -157
- package/docs/integrations/front-chat.md +322 -0
- package/docs/integrations/google-maps.md +119 -84
- package/docs/integrations/google-tag-manager.md +179 -164
- package/docs/integrations/google-tag.md +164 -161
- package/docs/integrations/heap.md +164 -156
- package/docs/integrations/hightouch.md +162 -158
- package/docs/integrations/hotjar.md +160 -156
- package/docs/integrations/intercom.md +184 -154
- package/docs/integrations/klaviyo.md +486 -0
- package/docs/integrations/linkedin-insights.md +175 -151
- package/docs/integrations/logrocket.md +161 -157
- package/docs/integrations/matomo-analytics.md +189 -179
- package/docs/integrations/meta-pixel.md +189 -151
- package/docs/integrations/microsoft-clarity.md +164 -156
- package/docs/integrations/microsoft-uet.md +149 -155
- package/docs/integrations/mixpanel-analytics.md +156 -161
- package/docs/integrations/one-dollar-stats.md +306 -0
- package/docs/integrations/openai-pixel.md +205 -302
- package/docs/integrations/overview.md +143 -83
- package/docs/integrations/pinterest-tag.md +329 -0
- package/docs/integrations/pirsch.md +170 -160
- package/docs/integrations/plausible-analytics.md +173 -159
- package/docs/integrations/posthog.md +227 -242
- package/docs/integrations/promptwatch.md +155 -155
- package/docs/integrations/reddit-pixel.md +186 -158
- package/docs/integrations/rudderstack.md +202 -187
- package/docs/integrations/rybbit-analytics.md +172 -161
- package/docs/integrations/segment.md +183 -155
- package/docs/integrations/snapchat-pixel.md +187 -157
- package/docs/integrations/tiktok-pixel.md +172 -151
- package/docs/integrations/umami-analytics.md +164 -159
- package/docs/integrations/vercel-analytics.md +167 -158
- package/docs/integrations/x-pixel.md +177 -151
- package/docs/integrations/youtube.md +122 -87
- package/docs/upgrade-v3.md +490 -354
- package/package.json +15 -9
- package/dist/component-hooks/use-manager.js +0 -2
- package/dist-types/component-hooks/use-manager.d.ts +0 -45
- package/docs/assets/v3/brand-bar.png +0 -0
- package/docs/assets/v3/mobile-card.png +0 -0
- package/docs/assets/v3/preferences.png +0 -0
- package/docs/frameworks/react/components/consent-manager-provider.md +0 -75
- package/docs/frameworks/react/hooks/use-consent-manager/overview.md +0 -58
- package/docs/frameworks/react/iab/overview.md +0 -53
- package/docs/frameworks/react/script-loader.md +0 -63
- package/docs/frameworks/react/styling/overview.md +0 -217
- package/docs/guides/consent-state.md +0 -60
- package/docs/guides/deployment-modes.md +0 -75
- package/docs/integrations/clear-on-revocation.md +0 -167
- package/docs/integrations/granular-consent.md +0 -208
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A ref that holds `value` from the render React most recently committed.
|
|
3
|
+
*
|
|
4
|
+
* Consent guards use it to answer "is this still the kernel, draft or IAB
|
|
5
|
+
* selection this component renders?" when a kept callback runs, including
|
|
6
|
+
* from a descendant's layout effect in the very commit that switched
|
|
7
|
+
* runtimes.
|
|
8
|
+
*
|
|
9
|
+
* Why an insertion effect: React runs insertion effects while it applies a
|
|
10
|
+
* commit, before any layout effect of that commit, and never for a render it
|
|
11
|
+
* discards. Assigning the ref during render would publish values from
|
|
12
|
+
* renders React throws away (an interrupted concurrent render, StrictMode's
|
|
13
|
+
* second render). A layout effect is too late, because descendants' layout
|
|
14
|
+
* effects run before their ancestors'. A passive effect is later still.
|
|
15
|
+
* Assigning the committed value is idempotent, so StrictMode's replayed
|
|
16
|
+
* effects cannot leave a stale value behind.
|
|
17
|
+
*
|
|
18
|
+
* @param value - The value this render uses.
|
|
19
|
+
* @returns A ref whose `current` is the last committed `value`.
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
export declare const useCommittedRef: <Value>(value: Value) => {
|
|
23
|
+
readonly current: Value;
|
|
24
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { FocusTrapOptions } from '@c15t/ui/utils/dom';
|
|
1
2
|
import type { RefObject } from 'react';
|
|
2
3
|
/**
|
|
3
4
|
* Hook that manages focus trapping within a container.
|
|
@@ -8,7 +9,8 @@ import type { RefObject } from 'react';
|
|
|
8
9
|
*
|
|
9
10
|
* @param shouldTrap - Boolean indicating whether focus should be trapped
|
|
10
11
|
* @param containerRef - Reference to the container element
|
|
12
|
+
* @param options - Where the trap puts focus when it starts
|
|
11
13
|
*
|
|
12
14
|
* @public
|
|
13
15
|
*/
|
|
14
|
-
export declare const useFocusTrap: (shouldTrap: boolean, containerRef: RefObject<HTMLElement | null> | null) => void;
|
|
16
|
+
export declare const useFocusTrap: (shouldTrap: boolean, containerRef: RefObject<HTMLElement | null> | null, options?: FocusTrapOptions) => void;
|
package/dist-types/hooks.d.ts
CHANGED
|
@@ -17,7 +17,8 @@
|
|
|
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, ResolvedVendor, VendorChoice } from '@c15t/core';
|
|
20
|
+
import type { AllConsentNames, ConsentKernel, ConsentPresentation, ExperimentAssignment, PromptPresentation, PreferencesPresentation, ConsentSnapshot, ConsentState, KernelActiveUI, KernelBranding, KernelIABState, KernelModel, KernelOverrides, KernelTranslations, KernelUser, LocationResponse, PolicyScopeMode, ResolvedVendor, VendorChoice } from '@c15t/core';
|
|
21
|
+
import type { Theme } from './types/theme/index.js';
|
|
21
22
|
/**
|
|
22
23
|
* Full snapshot accessor. Escape hatch for consumers that genuinely need
|
|
23
24
|
* multiple slices. Prefer narrow hooks for re-render isolation.
|
|
@@ -65,6 +66,8 @@ export declare const useHasConsentPolicy: () => boolean;
|
|
|
65
66
|
* {@link useHasConsentPolicy}.
|
|
66
67
|
*/
|
|
67
68
|
export declare const useHasConsentUI: () => boolean;
|
|
69
|
+
/** Whether c15t or an external CMP offers a preferences control. */
|
|
70
|
+
export declare const useHasConsentPreferences: () => boolean;
|
|
68
71
|
/**
|
|
69
72
|
* Derived consent model (opt-in / opt-out / iab), or `null` while no policy
|
|
70
73
|
* rule is resolved. The kernel keeps a safe fallback rule internally; this
|
|
@@ -106,14 +109,13 @@ export declare const useDeclaredVendors: () => readonly ResolvedVendor[];
|
|
|
106
109
|
*/
|
|
107
110
|
export declare const useVendorChoice: () => Readonly<VendorChoice> | null;
|
|
108
111
|
/**
|
|
109
|
-
* Whether one vendor
|
|
110
|
-
* visitor has not turned it off.
|
|
112
|
+
* Whether one vendor may load: it is declared, its category condition
|
|
113
|
+
* passes, and outside IAB the visitor has not turned it off.
|
|
111
114
|
*
|
|
112
|
-
* @param vendorId - Vendor
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
* the visitor saw.
|
|
115
|
+
* @param vendorId - Vendor id as declared in `vendors`, on a script or by
|
|
116
|
+
* the backend.
|
|
117
|
+
* @returns `true` while the vendor may load. An id nothing declares, such
|
|
118
|
+
* as a typo, returns `false` and logs a development warning.
|
|
117
119
|
*/
|
|
118
120
|
export declare const useVendorAllowed: (vendorId: string) => boolean;
|
|
119
121
|
/** Register categories used by scripts, frames, or other integrations. */
|
|
@@ -123,7 +125,21 @@ export declare const useRegisterConsentCategories: () => (categories: readonly A
|
|
|
123
125
|
*/
|
|
124
126
|
export declare const useSetOverrides: () => (input: KernelOverrides) => void;
|
|
125
127
|
/**
|
|
126
|
-
*
|
|
128
|
+
* Switch the consent language and load its copy.
|
|
129
|
+
*
|
|
130
|
+
* Stores the language override and runs init again, so the banner and
|
|
131
|
+
* dialog show copy in that language: a hosted backend returns it, and
|
|
132
|
+
* offline mode takes it from the bundled translations and `i18n.messages`.
|
|
133
|
+
* Setting the current language does nothing. A disabled provider stores
|
|
134
|
+
* the language without running init.
|
|
135
|
+
*
|
|
136
|
+
* @returns A setter that takes a language code such as `'de'`.
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```tsx
|
|
140
|
+
* const setLanguage = useSetLanguage();
|
|
141
|
+
* <button onClick={() => setLanguage('de')}>Deutsch</button>
|
|
142
|
+
* ```
|
|
127
143
|
*/
|
|
128
144
|
export declare const useSetLanguage: () => (code: string) => void;
|
|
129
145
|
/**
|
|
@@ -159,8 +175,6 @@ export declare const usePromptRequirement: () => ConsentSnapshot['promptRequirem
|
|
|
159
175
|
export declare const useNoticeDismissal: () => ConsentSnapshot['noticeDismissal'];
|
|
160
176
|
/** Read privacySignals from the kernel without a competing projection. */
|
|
161
177
|
export declare const usePrivacySignals: () => ConsentSnapshot['privacySignals'];
|
|
162
|
-
/** Read optOutDirectives from the kernel without a competing projection. */
|
|
163
|
-
export declare const useOptOutDirectives: () => ConsentSnapshot['optOutDirectives'];
|
|
164
178
|
/** Read resolution from the kernel without a competing projection. */
|
|
165
179
|
export declare const usePolicyResolution: () => ConsentSnapshot['resolution'];
|
|
166
180
|
/** Read policyRule from the kernel without a competing projection. */
|
|
@@ -169,7 +183,36 @@ export declare const usePolicyRule: () => ConsentSnapshot['policyRule'];
|
|
|
169
183
|
export declare const useRestrictions: () => ConsentSnapshot['restrictions'];
|
|
170
184
|
/** Dismiss the current local notice without recording a category choice. */
|
|
171
185
|
export declare const useDismissNotice: () => ConsentKernel['commands']['dismissNotice'];
|
|
172
|
-
/**
|
|
186
|
+
/**
|
|
187
|
+
* The presentation experiment arm this visitor runs. Built-in assignment
|
|
188
|
+
* lands after mount; a host-resolved `variant` is known at once.
|
|
189
|
+
*
|
|
190
|
+
* @returns The assignment, or `null` while no experiment is configured, the
|
|
191
|
+
* arm is not assigned yet, or the visitor's policy rejects it.
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* ```tsx
|
|
195
|
+
* const arm = useExperiment();
|
|
196
|
+
* return arm ? <p>{arm.id}: {arm.variant}</p> : null;
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
export declare const useExperiment: () => Readonly<ExperimentAssignment> | null;
|
|
200
|
+
/**
|
|
201
|
+
* The host presentation with the assigned experiment arm merged over it.
|
|
202
|
+
*
|
|
203
|
+
* @returns The presentation to render: `options.presentation` itself while
|
|
204
|
+
* no arm is assigned.
|
|
205
|
+
*/
|
|
206
|
+
export declare const useResolvedPresentation: () => ConsentPresentation | undefined;
|
|
207
|
+
/**
|
|
208
|
+
* The host theme with the assigned experiment arm's `theme` merged over it.
|
|
209
|
+
* Render its tokens with `<ConsentTheme theme={useResolvedTheme()} />`.
|
|
210
|
+
*
|
|
211
|
+
* @returns The theme to render: `options.theme` itself while no arm is
|
|
212
|
+
* assigned or the arm has no theme.
|
|
213
|
+
*/
|
|
214
|
+
export declare const useResolvedTheme: () => Theme | undefined;
|
|
215
|
+
/** Host first-layer presentation, with the experiment arm applied. */
|
|
173
216
|
export declare const usePromptPresentation: () => PromptPresentation;
|
|
174
|
-
/** Host persistent preferences presentation. */
|
|
217
|
+
/** Host persistent preferences presentation, with the experiment arm applied. */
|
|
175
218
|
export declare const usePreferencesPresentation: () => PreferencesPresentation;
|
package/dist-types/iab.d.ts
CHANGED
package/dist-types/index.d.ts
CHANGED
|
@@ -48,14 +48,15 @@ export type { ConsentGateProps, FrameProps } from './components/consent-gate/ind
|
|
|
48
48
|
export { ConsentGate, Frame } from './components/consent-gate/index.js';
|
|
49
49
|
export type { ConsentDraftHandle, ConsentDraftProviderProps, VendorDraftHandle, } from './draft.js';
|
|
50
50
|
export { ConsentDraftProvider, useConsentDraft, useVendorDraft } from './draft.js';
|
|
51
|
-
export { useConsentManager } from './component-hooks/use-manager.js';
|
|
52
51
|
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';
|
|
52
|
+
export { useActiveUI, useBranding, useConsent, useConsents, useExperiment, useHasConsentPolicy, useHasConsentPreferences, useHasConsentUI, useIABEnabled, useIABSnapshot, useIdentify, useInit, useLocation, useModel, useOverrides, usePromptPresentation, usePolicyCategories, usePreferencesPresentation, useResolvedPresentation, useResolvedTheme, usePolicyScopeMode, usePurposeConsent, useRegisterConsentCategories, useSaveConsents, useSetActiveUI, useSetLanguage, useSetOverrides, useSnapshot, useSpecialFeatureOptIn, useSubscribeToConsentChanges, useTCString, useUser, useDeclaredVendors, useVendorAllowed, useVendorChoice, useVendorConsent, } from './hooks.js';
|
|
54
53
|
export type { UseIframeBlockerOptions, UseNetworkBlockerOptions, UsePersistenceOptions, UseScriptLoaderOptions, } from './module-hooks.js';
|
|
55
54
|
export { useIframeBlocker, useNetworkBlocker, usePersistence, useScriptLoader, } from './module-hooks.js';
|
|
56
55
|
export type { ConsentProviderOptions, ConsentProviderCallbacks, ConsentProviderPrefetch, ConsentProviderProps, ExternalRuntimeProviderOptions, ExternalRuntimeProviderProps, OwnedRuntimeProviderProps, } from './provider.js';
|
|
57
56
|
export { ConsentProvider } from './provider.js';
|
|
57
|
+
export { ConsentTheme } from './consent-theme.js';
|
|
58
|
+
export type { ConsentThemeProps } from './consent-theme.js';
|
|
58
59
|
export type { ReactUIOptions } from './types/manager.js';
|
|
59
60
|
export { defineTheme, type Theme } from './types/theme/index.js';
|
|
60
|
-
export { useExplicitChoice, useEffectivePermissions, usePromptRequirement, useNoticeDismissal, usePrivacySignals,
|
|
61
|
+
export { useExplicitChoice, useEffectivePermissions, usePromptRequirement, useNoticeDismissal, usePrivacySignals, usePolicyResolution, usePolicyRule, useRestrictions, useDismissNotice, } from './hooks.js';
|
|
61
62
|
export type { ConsentPresentation, PromptPresentation, PreferencesPresentation, PresentationAction, PromptPosition, PromptVariant, ResolvedConsentPresentation, } from '@c15t/core';
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kernel access for the hooks and the stock components. The component
|
|
3
|
+
* selectors below each read a single derived value, so a component
|
|
4
|
+
* re-renders only when that value changes. Not exported from any package
|
|
5
|
+
* entry.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
import type { AllConsentNames, ConsentKernel, ConsentSnapshot } from '@c15t/core';
|
|
11
|
+
/**
|
|
12
|
+
* Reads the kernel from the nearest provider.
|
|
13
|
+
*
|
|
14
|
+
* @returns The provider's kernel.
|
|
15
|
+
* @throws {Error} When called outside a `ConsentProvider`.
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export declare const useKernel: () => ConsentKernel;
|
|
19
|
+
/**
|
|
20
|
+
* Subscribes to one slice of the kernel snapshot. React re-renders the
|
|
21
|
+
* caller only when the selected value `Object.is`-differs, so a selector
|
|
22
|
+
* must return a primitive or a reference the snapshot already holds.
|
|
23
|
+
*
|
|
24
|
+
* @param selector - Picks the slice from a snapshot.
|
|
25
|
+
* @returns The selected slice.
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export declare const useKernelSelector: <SliceType>(selector: (snap: ConsentSnapshot) => SliceType) => SliceType;
|
|
29
|
+
/**
|
|
30
|
+
* Like `useKernelSelector`, for selectors that evaluate a gate at a point in
|
|
31
|
+
* time. The server render and hydration evaluate at the snapshot's own
|
|
32
|
+
* `evaluatedAt`, so they never read the clock: a Next.js `cacheComponents`
|
|
33
|
+
* prerender rejects `Date.now()` in a Client Component. In the browser the
|
|
34
|
+
* gate is evaluated at `Date.now()`, so an expiry the kernel's deadline
|
|
35
|
+
* timer has not processed yet still denies.
|
|
36
|
+
*
|
|
37
|
+
* @param selector - Picks the slice from a snapshot at the given time.
|
|
38
|
+
* @returns The selected slice.
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
export declare const useGateSelector: <SliceType>(selector: (snap: ConsentSnapshot, now: number) => SliceType) => SliceType;
|
|
42
|
+
/**
|
|
43
|
+
* Whether content gated on one category may render, with the kernel's gate
|
|
44
|
+
* semantics. Server rendering and hydration read no clock; see
|
|
45
|
+
* `useGateSelector`.
|
|
46
|
+
*
|
|
47
|
+
* @param category - Category the content needs.
|
|
48
|
+
* @returns `true` while the category is permitted.
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
51
|
+
export declare const useCategoryAllowed: (category: AllConsentNames) => boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Language of the active translation bundle.
|
|
54
|
+
*
|
|
55
|
+
* @returns The bundle's language, or the default language before one loads.
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
export declare const useTranslationLanguage: () => string;
|
|
59
|
+
/**
|
|
60
|
+
* Categories the preference surface lists: `necessary` plus the recorded
|
|
61
|
+
* choice scope, or the policy scope when no choice scope applies.
|
|
62
|
+
*
|
|
63
|
+
* @returns A list whose identity changes only when the scope does.
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
66
|
+
export declare const useDisplayedCategories: () => readonly AllConsentNames[];
|
|
@@ -1,6 +1,33 @@
|
|
|
1
|
+
import type { ConsentKernel } from '@c15t/core';
|
|
1
2
|
import type { IframeBlockerHandle } from '@c15t/core/modules/iframe-blocker';
|
|
2
3
|
export interface UseIframeBlockerOptions {
|
|
3
4
|
disableAutomaticBlocking?: boolean;
|
|
4
5
|
}
|
|
5
6
|
export declare const useIframeBlocker: (options?: UseIframeBlockerOptions) => IframeBlockerHandle;
|
|
7
|
+
/**
|
|
8
|
+
* Call `onFound` when a gated iframe is on the page: at once when one is
|
|
9
|
+
* there already, and again for each batch of gated frames that arrives.
|
|
10
|
+
*
|
|
11
|
+
* Until the returned stop function runs, a gated frame that arrives with a
|
|
12
|
+
* `src` the snapshot does not clearly allow is paused (`src` moved to
|
|
13
|
+
* `data-src`), as the loaded blocker would pause it. Frames on the page at
|
|
14
|
+
* the first call are left to the blocker, which is what happens when it
|
|
15
|
+
* loads with the provider.
|
|
16
|
+
*
|
|
17
|
+
* @param kernel - The kernel whose snapshot decides what is clearly allowed.
|
|
18
|
+
* @param onFound - Called for every sighting; the caller dedupes.
|
|
19
|
+
* @returns Stops watching.
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
export declare const watchGatedIframes: (kernel: ConsentKernel, onFound: () => void) => () => void;
|
|
23
|
+
/**
|
|
24
|
+
* The provider's default iframe blocker. Loads the blocker module when the
|
|
25
|
+
* first gated iframe (`data-category` or `data-vendor`) is on the page
|
|
26
|
+
* instead of on every mount, so pages without one never download it.
|
|
27
|
+
*
|
|
28
|
+
* @param options - Blocker options. With `disableAutomaticBlocking` the
|
|
29
|
+
* module loads at once, as it did before.
|
|
30
|
+
* @internal
|
|
31
|
+
*/
|
|
32
|
+
export declare const useIframeBlockerOnDemand: (options?: UseIframeBlockerOptions) => void;
|
|
6
33
|
export type { IframeBlockerHandle };
|
|
@@ -5,5 +5,28 @@ export interface UseNetworkBlockerOptions {
|
|
|
5
5
|
logBlockedRequests?: boolean;
|
|
6
6
|
onRequestBlocked?: (info: BlockedRequestInfo) => void;
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Block `fetch` and XHR requests that match `rules` until the visitor's
|
|
10
|
+
* consent allows them.
|
|
11
|
+
*
|
|
12
|
+
* Blocking starts during the first render in the browser: matching requests
|
|
13
|
+
* wait from then on, including ones sent from this component's children's
|
|
14
|
+
* mount effects and from effects that run before this component's. The
|
|
15
|
+
* blocker loads after mount and decides each waiting request. On the
|
|
16
|
+
* server the hook does nothing.
|
|
17
|
+
*
|
|
18
|
+
* Rendering has a side effect: the first render patches `fetch` and
|
|
19
|
+
* `XMLHttpRequest` to hold matching requests. If React discards that
|
|
20
|
+
* render and never commits it, the hold ends after 10 seconds. Nothing
|
|
21
|
+
* checked consent for the requests it held, so they fail as blocked: a 451
|
|
22
|
+
* response for `fetch`, a failed XHR.
|
|
23
|
+
*
|
|
24
|
+
* Prefer the provider's `networkBlocker` option. It starts blocking when
|
|
25
|
+
* the provider renders, so it also covers components rendered before this
|
|
26
|
+
* one.
|
|
27
|
+
*
|
|
28
|
+
* @param options - Rules and logging options.
|
|
29
|
+
* @returns A handle to update rules or toggle blocking.
|
|
30
|
+
*/
|
|
8
31
|
export declare const useNetworkBlocker: (options: UseNetworkBlockerOptions) => NetworkBlockerHandle;
|
|
9
32
|
export type { BlockedRequestInfo, NetworkBlockerHandle, NetworkBlockerRule };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { NetworkBlockerRule } from '@c15t/core/modules/network-blocker';
|
|
2
|
+
import type { NetworkHold } from '@c15t/core/modules/network-hold';
|
|
3
|
+
/**
|
|
4
|
+
* How long a hold started during render waits for its component to commit.
|
|
5
|
+
* A render React throws away never commits, so nothing else would end its
|
|
6
|
+
* hold. When this runs out the hold ends, and since nothing checked consent
|
|
7
|
+
* for the requests it held, they get the blocker's answer for a blocked
|
|
8
|
+
* request instead of being sent.
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
export declare const UNCOMMITTED_HOLD_MS = 10000;
|
|
12
|
+
/**
|
|
13
|
+
* The render-time hold behind one network blocker mount.
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export interface EarlyNetworkHold {
|
|
17
|
+
/**
|
|
18
|
+
* Call from the mount effect, before loading the blocker. Keeps the hold
|
|
19
|
+
* from expiring, starts a new one if it already ended (a StrictMode or
|
|
20
|
+
* kernel re-run after the blocker took over, or a commit that came after
|
|
21
|
+
* the expiry), and returns it for `createNetworkBlocker({ hold })`. A
|
|
22
|
+
* disabled blocker gets a hold that holds nothing, so it cannot end
|
|
23
|
+
* another caller's hold.
|
|
24
|
+
*/
|
|
25
|
+
claim: (rules: readonly NetworkBlockerRule[], enabled: boolean | undefined) => NetworkHold;
|
|
26
|
+
/**
|
|
27
|
+
* Call from the mount effect's cleanup. Ends a hold no blocker took
|
|
28
|
+
* over, unless the effect runs again first (StrictMode, a kernel change).
|
|
29
|
+
* Nothing checked consent for what that hold held, so those requests get
|
|
30
|
+
* the blocker's answer for a blocked request instead of being sent.
|
|
31
|
+
*/
|
|
32
|
+
unmount: () => void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Hold requests matching `rules` from this component's first render in the
|
|
36
|
+
* browser, before any child renders or runs an effect. The network blocker
|
|
37
|
+
* loads after mount and takes the hold over.
|
|
38
|
+
*
|
|
39
|
+
* Rendering is not side-effect free: the first render patches `fetch` and
|
|
40
|
+
* `XMLHttpRequest`. That is safe because the hold only delays matching
|
|
41
|
+
* requests, a render React discards ends its hold after
|
|
42
|
+
* {@link UNCOMMITTED_HOLD_MS} (failing what it held as blocked), and on the
|
|
43
|
+
* server it does nothing.
|
|
44
|
+
*
|
|
45
|
+
* @internal
|
|
46
|
+
*/
|
|
47
|
+
export declare const useEarlyNetworkHold: (rules: readonly NetworkBlockerRule[], enabled: boolean | undefined) => EarlyNetworkHold;
|
package/dist-types/panel.d.ts
CHANGED
|
@@ -1 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* `@c15t/react/consent-dialog`: the deferred `ConsentDialog`, the same
|
|
3
|
+
* component the `@c15t/react` entry exports. Its implementation and styles
|
|
4
|
+
* load when the dialog first opens, or earlier when something preloads it,
|
|
5
|
+
* so importing this entry adds nothing heavy to the first load.
|
|
6
|
+
*
|
|
7
|
+
* The eager dialog and its individual parts (`Card`, `Header`, `Overlay`,
|
|
8
|
+
* ...) are in `@c15t/react/components/consent-dialog`.
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
export { ConsentDialog } from './aggregate-components.js';
|
|
13
|
+
export type { ConsentDialogCompoundComponent, ConsentDialogProps, } from './components/panel/index.js';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tailwind 3 PostCSS plugin for c15t stylesheets, re-exported from
|
|
3
|
+
* `@c15t/ui/postcss-tailwind3` so an app that installs `@c15t/react` can list
|
|
4
|
+
* `@c15t/react/postcss-tailwind3` without installing `@c15t/ui`.
|
|
5
|
+
* See `@c15t/ui/postcss-tailwind3` for what the plugin does. It must come
|
|
6
|
+
* before `tailwindcss`.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```js
|
|
10
|
+
* // postcss.config.mjs
|
|
11
|
+
* export default {
|
|
12
|
+
* plugins: {
|
|
13
|
+
* '@c15t/react/postcss-tailwind3': {},
|
|
14
|
+
* tailwindcss: {},
|
|
15
|
+
* autoprefixer: {},
|
|
16
|
+
* },
|
|
17
|
+
* };
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export * from '@c15t/ui/postcss-tailwind3';
|
|
21
|
+
export { default } from '@c15t/ui/postcss-tailwind3';
|
|
@@ -1 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* `@c15t/react/consent-widget`: the deferred `ConsentWidget`, the same
|
|
3
|
+
* component the `@c15t/react` entry exports. Its implementation and styles
|
|
4
|
+
* load when the widget first renders.
|
|
5
|
+
*
|
|
6
|
+
* The eager widget and its individual parts (`Accordion`, `Switch`, `Footer`,
|
|
7
|
+
* ...) are in `@c15t/react/components/consent-widget`.
|
|
8
|
+
*
|
|
9
|
+
* @packageDocumentation
|
|
10
|
+
*/
|
|
11
|
+
export { ConsentWidget } from './aggregate-components.js';
|
|
12
|
+
export type { ConsentWidgetCompoundComponent, ConsentWidgetProps, } from './components/preferences/index.js';
|
package/dist-types/provider.d.ts
CHANGED
|
@@ -1,26 +1,39 @@
|
|
|
1
|
-
import type { AllConsentNames, ClearOnRevocationConfig, ConsentPresentation, Callbacks, I18nConfig, KernelConfig, KernelOverrides, KernelUser, LegalLinks, ProviderTransportFactory, StorageConfig, User, Vendor } from '@c15t/core';
|
|
1
|
+
import type { AllConsentNames, ClearOnRevocationConfig, ConsentExperiment, ExperimentState, 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
|
-
import type { ConsentRuntime } from '@c15t/core/runtime';
|
|
3
|
+
import type { ConsentControlOptions, ConsentRuntime } from '@c15t/core/runtime';
|
|
4
4
|
import type { ReactNode } from 'react';
|
|
5
|
+
import type { DialogPreload } from './chunk-warming.js';
|
|
5
6
|
import type { UseNetworkBlockerOptions, UsePersistenceOptions, UseScriptLoaderOptions } from './module-hooks.js';
|
|
6
7
|
import type { UseIframeBlockerOptions } from './module-hooks/iframe-blocker.js';
|
|
7
8
|
import type { ReactUIOptions } from './types/manager.js';
|
|
8
9
|
import type { ReactComponentSlots } from './types/slots.js';
|
|
9
10
|
/** Events emitted by the mounted provider without snapshot-derived consent aliases. */
|
|
10
|
-
export type ConsentProviderCallbacks = Pick<Callbacks, 'onChoiceRecorded' | 'onPermissionsChanged' | 'onError'>;
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
export type ConsentProviderCallbacks = Pick<Callbacks, 'onChoiceRecorded' | 'onPermissionsChanged' | 'onSurfaceShown' | 'onError' | 'onBeforeConsentRevocationReload'>;
|
|
12
|
+
/**
|
|
13
|
+
* Prepared policy and records; legacy consent projections are not provider
|
|
14
|
+
* inputs. An `experiment` a server helper resolved runs instead of
|
|
15
|
+
* `options.experiment`.
|
|
16
|
+
*/
|
|
17
|
+
export type ConsentProviderPrefetch = Omit<KernelConfig, 'initialDraft' | 'transport'> & ExperimentState;
|
|
18
|
+
export interface ConsentProviderOptions extends ConsentControlOptions, Pick<ReactUIOptions, 'colorScheme' | 'disableAnimation' | 'noStyle' | 'scrollLock' | 'theme' | 'trapFocus'> {
|
|
14
19
|
enabled?: boolean;
|
|
15
20
|
presentation?: ConsentPresentation;
|
|
21
|
+
/**
|
|
22
|
+
* A/B experiment on prompt/preferences presentation. The assigned arm is
|
|
23
|
+
* merged over `presentation`, exposed through `useExperiment()`, and
|
|
24
|
+
* recorded with every impression and choice. Initial-only: remount the
|
|
25
|
+
* provider to change the experiment.
|
|
26
|
+
*/
|
|
27
|
+
experiment?: ConsentExperiment;
|
|
16
28
|
/**
|
|
17
29
|
* Content Security Policy nonce applied to DOM nodes c15t injects.
|
|
18
30
|
*
|
|
19
31
|
* @remarks
|
|
20
32
|
* Set this when your CSP uses a nonce-based policy instead of
|
|
21
|
-
* `'unsafe-inline'`. The provider forwards it to
|
|
22
|
-
*
|
|
23
|
-
*
|
|
33
|
+
* `'unsafe-inline'`. The provider forwards it to every `<script>`
|
|
34
|
+
* element created by the script loader. A per-script `nonce` still takes
|
|
35
|
+
* precedence. Pass the same nonce to `ConsentTheme`, which renders the
|
|
36
|
+
* theme `<style>` element.
|
|
24
37
|
*/
|
|
25
38
|
nonce?: string;
|
|
26
39
|
/**
|
|
@@ -83,6 +96,15 @@ export interface ConsentProviderOptions extends Pick<ReactUIOptions, 'colorSchem
|
|
|
83
96
|
* Initial-only: remount the provider to replace its cleanup configuration.
|
|
84
97
|
*/
|
|
85
98
|
clearOnRevocation?: ClearOnRevocationConfig;
|
|
99
|
+
/**
|
|
100
|
+
* Reload the page after an accept, reject or save turns off a category or
|
|
101
|
+
* vendor that was granted, or after a `consentSource` withdraws one.
|
|
102
|
+
* Removing a script cannot stop code that already ran, so the reload
|
|
103
|
+
* starts a document with only permitted code. Waits for the save request.
|
|
104
|
+
* Set `false` to handle revocation yourself.
|
|
105
|
+
* @default true
|
|
106
|
+
*/
|
|
107
|
+
reloadOnConsentRevoked?: boolean;
|
|
86
108
|
scripts?: Script[];
|
|
87
109
|
/**
|
|
88
110
|
* Vendors offered for vendor-level consent outside IAB. Each sits inside a
|
|
@@ -94,7 +116,12 @@ export interface ConsentProviderOptions extends Pick<ReactUIOptions, 'colorSchem
|
|
|
94
116
|
vendors?: Vendor[];
|
|
95
117
|
scriptLoader?: UseScriptLoaderOptions;
|
|
96
118
|
networkBlocker?: UseNetworkBlockerOptions | false;
|
|
97
|
-
/**
|
|
119
|
+
/**
|
|
120
|
+
* Discover and gate DOM iframes with data-category. Enabled by default.
|
|
121
|
+
* The blocker loads when the first gated iframe is on the page; until it
|
|
122
|
+
* runs, a gated iframe that arrives with a `src` consent does not allow
|
|
123
|
+
* is paused.
|
|
124
|
+
*/
|
|
98
125
|
iframeBlocker?: UseIframeBlockerOptions | false;
|
|
99
126
|
persistence?: boolean | UsePersistenceOptions;
|
|
100
127
|
i18n?: Partial<I18nConfig>;
|
|
@@ -103,6 +130,21 @@ export interface ConsentProviderOptions extends Pick<ReactUIOptions, 'colorSchem
|
|
|
103
130
|
/** Per-component slot attribute overrides (shared contract with @c15t/vue). */
|
|
104
131
|
components?: ReactComponentSlots;
|
|
105
132
|
legalLinks?: LegalLinks;
|
|
133
|
+
/**
|
|
134
|
+
* When the deferred `<ConsentDialog />` starts loading before it opens.
|
|
135
|
+
*
|
|
136
|
+
* - `'idle'` (default): after the page's load event, in browser idle time,
|
|
137
|
+
* while the banner is shown or a button that opens the dialog is
|
|
138
|
+
* mounted, and on hover or focus of such a button. Skipped when the
|
|
139
|
+
* visitor has Save-Data on or a 2G-class connection.
|
|
140
|
+
* - `'intent'`: only on hover or focus of a button that opens the dialog.
|
|
141
|
+
*
|
|
142
|
+
* Neither loads the dialog on a visit that shows no banner and has no
|
|
143
|
+
* dialog trigger.
|
|
144
|
+
*
|
|
145
|
+
* @default 'idle'
|
|
146
|
+
*/
|
|
147
|
+
preloadDialog?: DialogPreload;
|
|
106
148
|
/**
|
|
107
149
|
* Adapter package name reported by `window.c15t`.
|
|
108
150
|
* @internal
|
|
@@ -116,13 +158,19 @@ export interface ConsentProviderOptions extends Pick<ReactUIOptions, 'colorSchem
|
|
|
116
158
|
* Everything the component tree still owns — theme, slots, legal links —
|
|
117
159
|
* is unchanged.
|
|
118
160
|
*/
|
|
119
|
-
export type ExternalRuntimeProviderOptions = Omit<ConsentProviderOptions, 'mode' | 'vendors'> & {
|
|
161
|
+
export type ExternalRuntimeProviderOptions = Omit<ConsentProviderOptions, 'callbacks' | 'mode' | 'vendors'> & {
|
|
120
162
|
mode?: ConsentProviderOptions['mode'];
|
|
121
163
|
/**
|
|
122
164
|
* Not accepted here: the runtime owner declares vendors through
|
|
123
165
|
* `createConsentRuntime({ vendors })`, and the kernel carries them.
|
|
124
166
|
*/
|
|
125
167
|
vendors?: never;
|
|
168
|
+
/**
|
|
169
|
+
* Not accepted here: the runtime owner passes callbacks to
|
|
170
|
+
* `createConsentRuntime({ callbacks })`, and the runtime runs them.
|
|
171
|
+
* Passing them anyway logs a warning in development.
|
|
172
|
+
*/
|
|
173
|
+
callbacks?: never;
|
|
126
174
|
};
|
|
127
175
|
/** The provider builds and owns its own kernel. */
|
|
128
176
|
export interface OwnedRuntimeProviderProps {
|
|
@@ -149,7 +197,9 @@ export type ConsentProviderProps = OwnedRuntimeProviderProps | ExternalRuntimePr
|
|
|
149
197
|
* Pass `runtime` to render a runtime someone else created. The provider
|
|
150
198
|
* then borrows its kernel and mounts none of the side-effecting modules —
|
|
151
199
|
* no second `init()`, no second persistence handle, no second `window.c15t`
|
|
152
|
-
* — and does not dispose it on unmount.
|
|
200
|
+
* — and does not dispose it on unmount. Handing it a different runtime
|
|
201
|
+
* switches the tree to that runtime's kernel; switching between a borrowed
|
|
202
|
+
* runtime and a provider-built kernel still needs a remount.
|
|
153
203
|
*
|
|
154
204
|
* @example
|
|
155
205
|
* ```tsx
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
declare const FORWARDED_HEADERS: readonly ["x-c15t-country", "cf-ipcountry", "x-vercel-ip-country", "x-amz-cf-ipcountry", "x-country-code", "x-country", "x-c15t-region", "cf-region-code", "x-vercel-ip-country-region", "x-region-code", "accept-language", "x-c15t-gpc", "sec-gpc", "x-c15t-version", "user-agent", "x-forwarded-
|
|
2
|
-
|
|
1
|
+
declare const FORWARDED_HEADERS: readonly ["x-c15t-country", "cf-ipcountry", "x-vercel-ip-country", "x-amz-cf-ipcountry", "x-country-code", "x-country", "x-c15t-region", "cf-region-code", "x-vercel-ip-country-region", "x-region-code", "accept-language", "x-c15t-gpc", "sec-gpc", "x-c15t-version", "user-agent", "x-forwarded-for", "purpose", "sec-purpose", "next-router-prefetch", "x-middleware-prefetch"];
|
|
2
|
+
/**
|
|
3
|
+
* Forwarding headers a client can set to name a host or scheme. Passed to
|
|
4
|
+
* the backend only when the app trusts them.
|
|
5
|
+
*/
|
|
6
|
+
export declare const CLIENT_FORWARDING_HEADERS: readonly ['forwarded', 'x-forwarded-host', 'x-forwarded-proto'];
|
|
7
|
+
type ForwardedHeader = (typeof FORWARDED_HEADERS)[number] | (typeof CLIENT_FORWARDING_HEADERS)[number];
|
|
3
8
|
type RelevantHeaders = Partial<Record<ForwardedHeader, string>>;
|
|
4
9
|
/**
|
|
5
10
|
* Extracts relevant headers for consent management from the request headers.
|
|
@@ -12,10 +17,13 @@ type RelevantHeaders = Partial<Record<ForwardedHeader, string>>;
|
|
|
12
17
|
* The extracted headers include:
|
|
13
18
|
* - Country headers (cf-ipcountry, x-vercel-ip-country, etc.)
|
|
14
19
|
* - Region headers (x-vercel-ip-country-region, x-region-code)
|
|
15
|
-
* - Standard headers (accept-language, user-agent, x-forwarded
|
|
20
|
+
* - Standard headers (accept-language, user-agent, x-forwarded-for)
|
|
16
21
|
* - Prefetch headers (purpose, sec-purpose, next-router-prefetch, x-middleware-prefetch)
|
|
17
22
|
*
|
|
18
23
|
* @param headersList - The Headers object from the incoming request
|
|
24
|
+
* @param options - `trustForwardedHeaders` also copies `forwarded`,
|
|
25
|
+
* `x-forwarded-host` and `x-forwarded-proto`, which any client can send.
|
|
26
|
+
* Leave it off unless a proxy you control sets them and drops incoming ones.
|
|
19
27
|
* @returns An object containing the relevant headers for consent management
|
|
20
28
|
*
|
|
21
29
|
* @example
|
|
@@ -28,5 +36,7 @@ type RelevantHeaders = Partial<Record<ForwardedHeader, string>>;
|
|
|
28
36
|
*
|
|
29
37
|
* @public
|
|
30
38
|
*/
|
|
31
|
-
export declare const extractRelevantHeaders: (headersList: Headers
|
|
39
|
+
export declare const extractRelevantHeaders: (headersList: Headers, options?: {
|
|
40
|
+
trustForwardedHeaders?: boolean;
|
|
41
|
+
}) => RelevantHeaders;
|
|
32
42
|
export {};
|
|
@@ -21,16 +21,21 @@ export declare const validateBackendURL: (backendURL: string) => {
|
|
|
21
21
|
normalizedURL: string;
|
|
22
22
|
};
|
|
23
23
|
/**
|
|
24
|
-
* Normalizes a backend URL, resolving relative URLs
|
|
24
|
+
* Normalizes a backend URL, resolving relative URLs against the request.
|
|
25
25
|
*
|
|
26
26
|
* @remarks
|
|
27
27
|
* For absolute URLs, returns the URL as-is (with trailing slash trimmed).
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
28
|
+
* A relative URL resolves against the `host` header: over `https` for a
|
|
29
|
+
* domain name, and over `http` for `localhost`, an IP address or a
|
|
30
|
+
* single-label host. `x-forwarded-host`, `x-forwarded-proto` and `forwarded`
|
|
31
|
+
* are read only when `trustForwardedHeaders` is set, because any client can
|
|
32
|
+
* send them; the `referer` header is never used.
|
|
31
33
|
*
|
|
32
34
|
* @param backendURL - The backend URL (absolute or relative)
|
|
33
35
|
* @param headersList - The Headers object from the incoming request
|
|
36
|
+
* @param options - `trustForwardedHeaders`: resolve against the request's
|
|
37
|
+
* forwarding headers. Set it only behind a proxy that sets them and drops
|
|
38
|
+
* incoming ones.
|
|
34
39
|
* @returns The normalized absolute URL, or null if it cannot be determined
|
|
35
40
|
*
|
|
36
41
|
* @example
|
|
@@ -41,11 +46,13 @@ export declare const validateBackendURL: (backendURL: string) => {
|
|
|
41
46
|
* normalizeBackendURL('https://api.example.com/', headers);
|
|
42
47
|
* // Returns: 'https://api.example.com'
|
|
43
48
|
*
|
|
44
|
-
* // Relative URL - resolved from
|
|
49
|
+
* // Relative URL - resolved from the host header
|
|
45
50
|
* normalizeBackendURL('/api/consent', headers);
|
|
46
|
-
* // Returns: 'https://example.com/api/consent' (
|
|
51
|
+
* // Returns: 'https://example.com/api/consent' (for `host: example.com`)
|
|
47
52
|
* ```
|
|
48
53
|
*
|
|
49
54
|
* @public
|
|
50
55
|
*/
|
|
51
|
-
export declare const normalizeBackendURL: (backendURL: string, headersList: Headers
|
|
56
|
+
export declare const normalizeBackendURL: (backendURL: string, headersList: Headers, options?: {
|
|
57
|
+
trustForwardedHeaders?: boolean;
|
|
58
|
+
}) => string | null;
|