@c15t/react 3.0.0-alpha.1 → 3.0.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +97 -70
- 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 -0
- package/dist/components/consent-gate/consent-gate.js +2 -0
- package/dist/components/consent-gate/frame.js +2 -0
- package/dist/components/consent-gate/index.js +2 -0
- 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/root.js +1 -1
- package/dist/components/iab-panel/atoms/stack-item.js +1 -1
- package/dist/components/iab-panel/atoms/vendor-list.js +1 -1
- package/dist/components/iab-panel/hooks/use-gvl-data.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/iab-prompt/iab-prompt.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/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/panel-trigger/panel-trigger.js +1 -1
- package/dist/components/panel-trigger/toolbar-loader.js +2 -0
- 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 -0
- package/dist/components/preferences/index.js +1 -1
- package/dist/components/prompt/atoms/early-tap-script.js +2 -0
- 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/prompt/prompt.js +1 -1
- package/dist/components/shared/dialog-sheets.js +1 -0
- package/dist/components/shared/first-paint-sheets.js +1 -0
- package/dist/components/shared/iab-dialog-sheets.js +1 -0
- package/dist/components/shared/iab-first-paint-sheets.js +1 -0
- 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/primitives/legal-links/index.js +1 -1
- package/dist/components/shared/streamed-surface.js +2 -0
- package/dist/components/shared/surface-styles.js +2 -0
- 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/consent-gate.js +2 -0
- package/dist/consent-theme.js +1 -0
- package/dist/context/consent-tracking-context.js +1 -1
- package/dist/context/index.js +1 -1
- package/dist/context.js +1 -1
- package/dist/devtools-launcher.js +2 -0
- package/dist/devtools.js +1 -1
- package/dist/draft-context.js +2 -0
- package/dist/draft.js +1 -1
- package/dist/external-iab-context.js +1 -1
- package/dist/gpp.js +2 -0
- package/dist/headless.js +1 -1
- package/dist/hooks/use-color-scheme.js +1 -1
- package/dist/hooks/use-committed-ref.js +2 -0
- package/dist/hooks/use-focus-trap.js +1 -1
- package/dist/hooks/use-headless-iab-consent-ui.js +1 -1
- package/dist/hooks/use-iab-policy-guard.js +1 -0
- package/dist/hooks/use-late-entry.js +2 -0
- package/dist/hooks.js +1 -1
- package/dist/iab/styles.tw3.css +5 -45
- package/dist/iab-context.js +1 -1
- package/dist/iab-dialog-deferred.js +2 -0
- package/dist/iab.js +1 -1
- package/dist/index-parts/consent-banner.js +1 -0
- package/dist/index-parts/consent-dialog-link.js +1 -0
- package/dist/index-parts/consent-dialog-trigger.js +1 -0
- package/dist/index-parts/consent-dialog.js +1 -0
- package/dist/index-parts/consent-gate.js +1 -0
- package/dist/index-parts/core.js +1 -0
- package/dist/index-parts/draft.js +1 -0
- package/dist/index-parts/frame.js +1 -0
- package/dist/index-parts/hooks.js +1 -0
- package/dist/index-parts/hosted.js +1 -0
- package/dist/index-parts/module-hooks.js +1 -0
- package/dist/index-parts/offline.js +1 -0
- package/dist/index-parts/presets.js +1 -0
- package/dist/index-parts/provider.js +1 -0
- package/dist/index-parts/theme.js +1 -0
- package/dist/index-parts/translations.js +1 -0
- package/dist/index.js +1 -1
- package/dist/kernel-selector.js +1 -0
- package/dist/modes.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-link.js +1 -1
- package/dist/panel-trigger.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 +33 -51
- package/dist/transports/hosted.js +1 -0
- package/dist/transports/manifest.js +1 -0
- package/dist/transports/offline.js +1 -1
- package/dist/utils/deferred-module.js +2 -0
- 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/aggregate-components.d.ts +2 -2
- package/dist-types/chunk-warming.d.ts +42 -8
- package/dist-types/component-hooks/use-headless-consent-ui.d.ts +5 -5
- package/dist-types/component-hooks/use-headless-iab-consent-ui.d.ts +2 -2
- package/dist-types/components/consent-gate/atoms.d.ts +11 -0
- package/dist-types/components/consent-gate/consent-gate.d.ts +2 -0
- package/dist-types/components/consent-gate/frame.d.ts +19 -0
- package/dist-types/components/consent-gate/index.d.ts +25 -0
- package/dist-types/components/{frame → consent-gate}/types.d.ts +7 -7
- package/dist-types/components/consent-preferences-link/consent-preferences-link.d.ts +1 -1
- package/dist-types/components/consent-preferences-link/index.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 +5 -2
- package/dist-types/components/iab-panel/atoms/stack-item.d.ts +7 -2
- package/dist-types/components/iab-panel/atoms/vendor-list.d.ts +1 -1
- package/dist-types/components/iab-panel/iab-panel.d.ts +3 -3
- package/dist-types/components/iab-panel/index.d.ts +29 -26
- package/dist-types/components/iab-panel/use-iab-translations.d.ts +4 -0
- package/dist-types/components/iab-prompt/iab-prompt.d.ts +3 -3
- package/dist-types/components/iab-prompt/index.d.ts +19 -19
- package/dist-types/components/panel/atoms/card.d.ts +5 -4
- package/dist-types/components/panel/atoms/overlay.d.ts +1 -1
- package/dist-types/components/panel/index.d.ts +8 -8
- package/dist-types/components/panel/panel.d.ts +3 -3
- package/dist-types/components/panel-link/index.d.ts +1 -1
- package/dist-types/components/panel-trigger/atoms/button.d.ts +1 -1
- package/dist-types/components/panel-trigger/atoms/icon.d.ts +1 -1
- package/dist-types/components/panel-trigger/atoms/root.d.ts +2 -2
- package/dist-types/components/panel-trigger/atoms/toolbar.d.ts +2 -2
- package/dist-types/components/panel-trigger/atoms/trigger-icons.d.ts +25 -0
- package/dist-types/components/panel-trigger/index.d.ts +4 -4
- package/dist-types/components/panel-trigger/panel-trigger-toolbar.d.ts +1 -1
- package/dist-types/components/panel-trigger/panel-trigger.d.ts +9 -17
- package/dist-types/components/panel-trigger/toolbar-loader.d.ts +34 -0
- package/dist-types/components/panel-trigger/types.d.ts +1 -1
- package/dist-types/components/preferences/atoms/accordion.d.ts +6 -4
- package/dist-types/components/preferences/atoms/button.d.ts +1 -1
- package/dist-types/components/preferences/atoms/footer.d.ts +1 -1
- package/dist-types/components/preferences/atoms/root.d.ts +1 -1
- package/dist-types/components/preferences/atoms/vendor-list.d.ts +23 -0
- package/dist-types/components/preferences/index.d.ts +14 -12
- package/dist-types/components/preferences/policy-actions.d.ts +2 -2
- package/dist-types/components/preferences/preferences.d.ts +1 -1
- package/dist-types/components/preferences/types.d.ts +1 -1
- package/dist-types/components/prompt/atoms/early-tap-script.d.ts +17 -0
- package/dist-types/components/prompt/atoms/root.d.ts +4 -0
- package/dist-types/components/prompt/components.d.ts +9 -3
- package/dist-types/components/prompt/index.d.ts +12 -12
- package/dist-types/components/prompt/policy-actions.d.ts +2 -2
- package/dist-types/components/prompt/prompt.d.ts +5 -1
- package/dist-types/components/shared/dialog-sheets.d.ts +9 -0
- package/dist-types/components/shared/first-paint-sheets.d.ts +8 -0
- package/dist-types/components/shared/iab-dialog-sheets.d.ts +3 -0
- package/dist-types/components/shared/iab-first-paint-sheets.d.ts +3 -0
- package/dist-types/components/shared/libs/compose-refs.d.ts +20 -0
- package/dist-types/components/shared/policy-actions.d.ts +2 -2
- package/dist-types/components/shared/primitives/box.d.ts +1 -1
- package/dist-types/components/shared/primitives/button.d.ts +2 -2
- package/dist-types/components/shared/primitives/button.types.d.ts +1 -1
- package/dist-types/components/shared/streamed-surface.d.ts +23 -0
- package/dist-types/components/shared/surface-styles.d.ts +60 -0
- package/dist-types/components/shared/ui/accordion/accordion.d.ts +2 -2
- package/dist-types/components/shared/ui/accordion/index.d.ts +2 -2
- package/dist-types/components/shared/ui/animated-collapse/index.d.ts +2 -2
- package/dist-types/components/shared/ui/branding.d.ts +1 -1
- package/dist-types/components/shared/ui/button/button.d.ts +1 -1
- package/dist-types/components/shared/ui/button/index.d.ts +2 -2
- package/dist-types/components/shared/ui/collapsible/index.d.ts +1 -1
- package/dist-types/components/shared/ui/dialog/index.d.ts +1 -1
- 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/index.d.ts +1 -1
- package/dist-types/components/shared/ui/preference-item/preference-item.d.ts +13 -0
- package/dist-types/components/shared/ui/switch/index.d.ts +2 -2
- package/dist-types/components/shared/ui/switch/switch.d.ts +1 -1
- package/dist-types/components/shared/ui/tabs/index.d.ts +1 -1
- package/dist-types/consent-gate.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/index.d.ts +3 -3
- package/dist-types/context/theme-context.d.ts +3 -3
- package/dist-types/context.d.ts +25 -1
- package/dist-types/devtools-launcher.d.ts +29 -0
- package/dist-types/devtools.d.ts +13 -2
- package/dist-types/draft-context.d.ts +31 -0
- package/dist-types/draft.d.ts +81 -9
- package/dist-types/gpp.d.ts +27 -0
- package/dist-types/headless.d.ts +6 -7
- 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/use-headless-iab-consent-ui.d.ts +1 -1
- package/dist-types/hooks/use-iab-manager.d.ts +5 -5
- package/dist-types/hooks/use-iab-policy-guard.d.ts +35 -0
- package/dist-types/hooks/use-late-entry.d.ts +14 -0
- package/dist-types/hooks/use-theme.d.ts +1 -1
- package/dist-types/hooks.d.ts +106 -11
- package/dist-types/iab-dialog-deferred.d.ts +36 -0
- package/dist-types/iab.d.ts +8 -7
- package/dist-types/index-parts/consent-banner.d.ts +7 -0
- package/dist-types/index-parts/consent-dialog-link.d.ts +7 -0
- package/dist-types/index-parts/consent-dialog-trigger.d.ts +7 -0
- package/dist-types/index-parts/consent-dialog.d.ts +7 -0
- package/dist-types/index-parts/consent-gate.d.ts +7 -0
- package/dist-types/index-parts/core.d.ts +7 -0
- package/dist-types/index-parts/draft.d.ts +7 -0
- package/dist-types/index-parts/frame.d.ts +7 -0
- package/dist-types/index-parts/hooks.d.ts +7 -0
- package/dist-types/index-parts/hosted.d.ts +7 -0
- package/dist-types/index-parts/module-hooks.d.ts +7 -0
- package/dist-types/index-parts/offline.d.ts +7 -0
- package/dist-types/index-parts/presets.d.ts +7 -0
- package/dist-types/index-parts/provider.d.ts +7 -0
- package/dist-types/index-parts/theme.d.ts +8 -0
- package/dist-types/index-parts/translations.d.ts +7 -0
- package/dist-types/index.d.ts +32 -28
- package/dist-types/kernel-selector.d.ts +68 -0
- package/dist-types/modes.d.ts +26 -0
- package/dist-types/module-hooks/iframe-blocker.d.ts +33 -1
- 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/module-hooks.d.ts +4 -4
- package/dist-types/panel-link.d.ts +1 -1
- package/dist-types/panel-trigger.d.ts +1 -1
- 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/primitives/accordion.d.ts +1 -1
- package/dist-types/primitives/button.d.ts +1 -1
- package/dist-types/primitives/collapsible.d.ts +1 -1
- package/dist-types/primitives/dialog.d.ts +1 -1
- package/dist-types/primitives/preference-item.d.ts +1 -1
- package/dist-types/primitives/switch.d.ts +1 -1
- package/dist-types/primitives/tabs.d.ts +1 -1
- package/dist-types/primitives.d.ts +7 -7
- package/dist-types/prompt.d.ts +1 -1
- package/dist-types/provider.d.ts +169 -28
- package/dist-types/server/fetch-ssr-data.d.ts +1 -1
- package/dist-types/server/headers.d.ts +14 -4
- package/dist-types/server/index.d.ts +5 -5
- package/dist-types/server/normalize-url.d.ts +14 -7
- package/dist-types/server/types.d.ts +12 -1
- package/dist-types/theme-provider.d.ts +2 -2
- package/dist-types/transports/hosted.d.ts +36 -0
- package/dist-types/transports/manifest.d.ts +48 -0
- package/dist-types/transports/offline.d.ts +7 -16
- package/dist-types/types/index.d.ts +3 -3
- package/dist-types/types/manager.d.ts +1 -1
- package/dist-types/types/theme/index.d.ts +1 -1
- package/dist-types/ui-config-context.d.ts +14 -2
- package/dist-types/utils/deferred-module.d.ts +13 -0
- package/dist-types/utils/index.d.ts +4 -4
- package/dist-types/utils/merge-slot-props.d.ts +17 -3
- package/dist-types/utils/merge-styles.d.ts +1 -1
- package/dist-types/utils/theme-utils.d.ts +18 -3
- package/dist-types/version.d.ts +1 -1
- package/docs/README.md +97 -70
- 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 +141 -0
- package/docs/concepts/consent-categories.md +84 -0
- package/docs/concepts/consent-state.md +421 -0
- package/docs/concepts/data-fetching.md +284 -0
- package/docs/concepts/how-consent-works.md +123 -0
- package/docs/concepts/modes.md +281 -0
- package/docs/{frameworks/react/concepts/policy-presets.md → concepts/policies.md} +8 -60
- package/docs/customization/class-names.md +202 -0
- package/docs/customization/dark-mode.md +157 -0
- package/docs/customization/motion.md +128 -0
- package/docs/customization/overview.md +68 -33
- package/docs/customization/recipes.md +838 -47
- package/docs/customization/slots.md +217 -35
- package/docs/customization/stylesheets.md +248 -0
- package/docs/customization/tailwind.md +863 -0
- package/docs/customization/tokens.md +167 -36
- package/docs/customization/translations.md +87 -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 +48 -27
- package/docs/frameworks/react/components/consent-dialog-link.md +13 -11
- package/docs/frameworks/react/components/consent-dialog-trigger.md +86 -76
- package/docs/frameworks/react/components/consent-dialog.md +111 -58
- package/docs/frameworks/react/components/{frame.md → consent-gate.md} +70 -49
- package/docs/frameworks/react/components/consent-provider.md +143 -0
- package/docs/frameworks/react/components/consent-widget.md +69 -24
- package/docs/frameworks/react/components/dev-tools.md +76 -85
- package/docs/frameworks/react/components.md +113 -0
- package/docs/frameworks/react/compose.md +354 -0
- package/docs/frameworks/react/content-security-policy.md +149 -0
- package/docs/frameworks/react/customize.md +258 -0
- package/docs/frameworks/react/embeds.md +89 -0
- package/docs/frameworks/react/gpp.md +163 -0
- package/docs/frameworks/react/headless.md +4 -4
- package/docs/frameworks/react/hooks.md +70 -0
- package/docs/frameworks/react/iab.md +278 -0
- package/docs/frameworks/react/network-blocker.md +140 -0
- package/docs/frameworks/react/quickstart.md +171 -107
- package/docs/frameworks/react/rendering.md +285 -0
- package/docs/frameworks/react/scripts.md +114 -0
- package/docs/frameworks/react/translations.md +155 -0
- package/docs/frameworks/react/troubleshooting.md +189 -61
- package/docs/frameworks/react/upgrade-v3.md +652 -0
- package/docs/frameworks/react/vendor-consent.md +188 -0
- package/docs/guides/banner-experiments.md +688 -0
- package/docs/guides/troubleshooting.md +192 -54
- package/docs/guides/verify-consent.md +96 -49
- package/docs/integrations/adobe-analytics.md +177 -183
- package/docs/integrations/ahrefs-analytics.md +162 -178
- package/docs/integrations/amplitude.md +172 -180
- package/docs/integrations/building-integrations.md +137 -33
- package/docs/integrations/clearbit.md +164 -178
- package/docs/integrations/cloudflare-web-analytics.md +166 -180
- package/docs/integrations/cloudflare-zaraz.md +333 -0
- package/docs/integrations/crisp.md +174 -182
- package/docs/integrations/databuddy.md +167 -197
- package/docs/integrations/fathom-analytics.md +168 -180
- package/docs/integrations/front-chat.md +308 -0
- package/docs/integrations/google-maps.md +142 -108
- package/docs/integrations/google-tag-manager.md +258 -185
- package/docs/integrations/google-tag.md +226 -182
- package/docs/integrations/heap.md +173 -179
- package/docs/integrations/hightouch.md +171 -181
- package/docs/integrations/hotjar.md +169 -179
- package/docs/integrations/intercom.md +193 -177
- package/docs/integrations/klaviyo.md +473 -0
- package/docs/integrations/linkedin-insights.md +184 -174
- package/docs/integrations/logrocket.md +170 -180
- package/docs/integrations/matomo-analytics.md +198 -202
- package/docs/integrations/meta-pixel.md +198 -174
- package/docs/integrations/microsoft-clarity.md +173 -179
- package/docs/integrations/microsoft-uet.md +158 -178
- package/docs/integrations/mixpanel-analytics.md +165 -184
- package/docs/integrations/one-dollar-stats.md +292 -0
- package/docs/integrations/openai-pixel.md +214 -325
- package/docs/integrations/overview.md +153 -83
- package/docs/integrations/pinterest-tag.md +315 -0
- package/docs/integrations/pirsch.md +179 -183
- package/docs/integrations/plausible-analytics.md +182 -182
- package/docs/integrations/posthog.md +323 -264
- package/docs/integrations/promptwatch.md +164 -178
- package/docs/integrations/reddit-pixel.md +195 -181
- package/docs/integrations/rudderstack.md +211 -210
- package/docs/integrations/rybbit-analytics.md +181 -184
- package/docs/integrations/segment.md +192 -178
- package/docs/integrations/sentry.md +402 -0
- package/docs/integrations/snapchat-pixel.md +196 -180
- package/docs/integrations/tiktok-pixel.md +181 -174
- package/docs/integrations/umami-analytics.md +173 -182
- package/docs/integrations/vercel-analytics.md +176 -181
- package/docs/integrations/vercel-speed-insights.md +306 -0
- package/docs/integrations/x-pixel.md +186 -174
- package/docs/integrations/youtube.md +150 -111
- package/package.json +48 -17
- package/dist/component-hooks/use-manager.js +0 -2
- package/dist/components/frame/atoms.js +0 -1
- package/dist/components/frame/frame.js +0 -2
- package/dist/components/frame/index.js +0 -2
- package/dist/frame.js +0 -2
- package/dist/ui-save.js +0 -1
- package/dist-types/component-hooks/use-manager.d.ts +0 -40
- package/dist-types/components/frame/atoms.d.ts +0 -11
- package/dist-types/components/frame/frame.d.ts +0 -2
- package/dist-types/components/frame/index.d.ts +0 -24
- package/dist-types/frame.d.ts +0 -1
- package/dist-types/ui-save.d.ts +0 -5
- 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 -71
- package/docs/frameworks/react/concepts/consent-categories.md +0 -33
- 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/data-fetching.md +0 -163
- package/docs/guides/deployment-modes.md +0 -63
- package/docs/integrations/clear-on-revocation.md +0 -167
- package/docs/upgrade-v3.md +0 -334
- package/readme.json +0 -48
- package/src/iab/styles.css +0 -11
- package/src/styles.css +0 -10
- /package/dist/components/{frame → consent-gate}/types.js +0 -0
|
@@ -1,26 +1,49 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: ConsentBanner
|
|
3
|
-
description:
|
|
3
|
+
description: Render the c15t consent banner in a React app, choose its variant
|
|
4
|
+
and position, and compose its parts.
|
|
4
5
|
group: frameworks
|
|
5
6
|
---
|
|
6
7
|
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
## Render the banner inside `ConsentProvider`
|
|
9
|
+
|
|
10
|
+
Render `ConsentBanner` once inside `ConsentProvider`, next to `ConsentDialog`.
|
|
11
|
+
The [quickstart](../quickstart.md) mounts both in
|
|
12
|
+
`src/consent.tsx`:
|
|
13
|
+
|
|
14
|
+
```tsx title="src/consent.tsx"
|
|
15
|
+
import { posthog } from '@c15t/integrations/posthog';
|
|
16
|
+
import {
|
|
17
|
+
ConsentBanner,
|
|
18
|
+
ConsentDialog,
|
|
19
|
+
ConsentDialogLink,
|
|
20
|
+
ConsentProvider,
|
|
21
|
+
hosted,
|
|
22
|
+
} from 'c15t/react';
|
|
23
|
+
import type { ReactNode } from 'react';
|
|
24
|
+
|
|
25
|
+
const options = {
|
|
26
|
+
// Asks VITE_C15T_BACKEND_URL for each visitor's policy.
|
|
27
|
+
mode: hosted(),
|
|
28
|
+
scripts: [
|
|
29
|
+
posthog({
|
|
30
|
+
id: 'phc_your_project_key',
|
|
31
|
+
initOptions: { cookieless_mode: 'never' },
|
|
32
|
+
loadMode: 'after-consent',
|
|
33
|
+
}),
|
|
34
|
+
],
|
|
35
|
+
};
|
|
14
36
|
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
37
|
+
export const Consent = ({ children }: { children: ReactNode }) => (
|
|
38
|
+
<ConsentProvider options={options}>
|
|
39
|
+
{children}
|
|
40
|
+
<ConsentBanner />
|
|
41
|
+
<ConsentDialog />
|
|
42
|
+
<footer>
|
|
43
|
+
<ConsentDialogLink>Privacy settings</ConsentDialogLink>
|
|
44
|
+
</footer>
|
|
45
|
+
</ConsentProvider>
|
|
46
|
+
);
|
|
24
47
|
```
|
|
25
48
|
|
|
26
49
|
The banner renders whatever the active policy rule requires. It reads the rule
|
|
@@ -122,16 +145,14 @@ button through the provider's theme:
|
|
|
122
145
|
```ts
|
|
123
146
|
const theme = {
|
|
124
147
|
colors: { primary: '#2f6f4e', primaryHover: '#24563c' },
|
|
125
|
-
consentActions: {
|
|
126
|
-
primary: { variant: 'primary', mode: 'filled' },
|
|
127
|
-
},
|
|
148
|
+
consentActions: { primary: { variant: 'primary', mode: 'filled' } },
|
|
128
149
|
} as const;
|
|
129
150
|
```
|
|
130
151
|
|
|
131
152
|
Pass `theme` in `ConsentProvider` options. Per-action theme overrides such
|
|
132
153
|
as `consentActions.dismiss` take precedence over this primary style.
|
|
133
|
-
See [
|
|
134
|
-
[
|
|
154
|
+
See [customize](../customize.md) for tokens and slots, and
|
|
155
|
+
[policies](../../../concepts/policies.md) for the rule IDs and coverage.
|
|
135
156
|
|
|
136
157
|
## Variants
|
|
137
158
|
|
|
@@ -143,14 +164,14 @@ Set the variant on the banner, or on the provider under
|
|
|
143
164
|
`presentation.prompt` when every banner should share it. The prop wins.
|
|
144
165
|
|
|
145
166
|
```tsx
|
|
146
|
-
<ConsentBanner variant="floating" position="bottom-center"
|
|
167
|
+
<ConsentBanner variant="floating" position="bottom-center" />;
|
|
147
168
|
```
|
|
148
169
|
|
|
149
170
|
A floating card in a corner or centered on an edge. This is the default for
|
|
150
171
|
every prompt. A notice keeps the same card, with its right link and "OK" in the footer.
|
|
151
172
|
|
|
152
173
|
```tsx
|
|
153
|
-
<ConsentBanner variant="bar" position="top"
|
|
174
|
+
<ConsentBanner variant="bar" position="top" />;
|
|
154
175
|
```
|
|
155
176
|
|
|
156
177
|
A bar across the full width of the viewport. From 1024px wide the text, the
|
|
@@ -158,14 +179,14 @@ right links, and the controls share one row. Opt in to it for regions that
|
|
|
158
179
|
expect a classic cookie bar.
|
|
159
180
|
|
|
160
181
|
```tsx
|
|
161
|
-
<ConsentBanner variant="widget" position="bottom-right"
|
|
182
|
+
<ConsentBanner variant="widget" position="bottom-right" />;
|
|
162
183
|
```
|
|
163
184
|
|
|
164
185
|
A compact card with smaller type. The full description and its legal links
|
|
165
186
|
remain visible. Pair it with a short notice.
|
|
166
187
|
|
|
167
188
|
```tsx
|
|
168
|
-
<ConsentBanner variant="wall"
|
|
189
|
+
<ConsentBanner variant="wall" />;
|
|
169
190
|
```
|
|
170
191
|
|
|
171
192
|
A centered card over a backdrop that blocks the page until the visitor
|
|
@@ -248,7 +269,7 @@ Use the individual parts when you need a different order or your own markup:
|
|
|
248
269
|
<ConsentBanner.RightLink right="opt-out" asChild>
|
|
249
270
|
<a href="/privacy/do-not-sell">Do not sell or share my data</a>
|
|
250
271
|
</ConsentBanner.RightLink>
|
|
251
|
-
</ConsentBanner.Rights
|
|
272
|
+
</ConsentBanner.Rights>;
|
|
252
273
|
```
|
|
253
274
|
|
|
254
275
|
`useBannerCopy()` returns the title, description, and prompt kind the banner
|
|
@@ -16,15 +16,17 @@ same `ConsentProvider`; the [quickstart](../quickstart.md) mounts both.
|
|
|
16
16
|
import { ConsentDialogLink } from 'c15t/react';
|
|
17
17
|
|
|
18
18
|
export function SiteFooter() {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
19
|
+
return (
|
|
20
|
+
<footer>
|
|
21
|
+
<nav aria-label="Legal">
|
|
22
|
+
<a href="/privacy">Privacy policy</a>
|
|
23
|
+
<a href="/terms">Terms</a>
|
|
24
|
+
<ConsentDialogLink className="footer-link">
|
|
25
|
+
Privacy settings
|
|
26
|
+
</ConsentDialogLink>
|
|
27
|
+
</nav>
|
|
28
|
+
</footer>
|
|
29
|
+
);
|
|
28
30
|
}
|
|
29
31
|
```
|
|
30
32
|
|
|
@@ -37,8 +39,8 @@ To reuse an existing link component, pass `asChild`:
|
|
|
37
39
|
|
|
38
40
|
```tsx
|
|
39
41
|
<ConsentDialogLink asChild>
|
|
40
|
-
|
|
41
|
-
</ConsentDialogLink
|
|
42
|
+
<a href="#cookie-preferences">Manage cookies</a>
|
|
43
|
+
</ConsentDialogLink>;
|
|
42
44
|
```
|
|
43
45
|
|
|
44
46
|
## Props
|
|
@@ -1,35 +1,20 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: ConsentDialogTrigger
|
|
3
|
-
description:
|
|
4
|
-
the
|
|
3
|
+
description: Add the c15t ConsentDialogTrigger floating button or toolbar inside
|
|
4
|
+
a React ConsentProvider so visitors can reopen the preference center after the
|
|
5
|
+
first prompt.
|
|
5
6
|
group: frameworks
|
|
6
7
|
---
|
|
7
8
|
|
|
8
|
-
##
|
|
9
|
+
## Add the trigger inside ConsentProvider
|
|
9
10
|
|
|
10
|
-
`ConsentDialogTrigger` is a draggable floating button that opens the preference center. Place it once
|
|
11
|
+
`ConsentDialogTrigger` is a draggable floating button that opens the preference center. Place it once inside `ConsentProvider`, next to the banner and dialog from the [quickstart](../quickstart.md), so visitors can revisit their choices without a footer link.
|
|
11
12
|
|
|
12
|
-
```tsx
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
ConsentProvider,
|
|
18
|
-
offline,
|
|
19
|
-
} from 'c15t/react';
|
|
20
|
-
import { policyRulePresets } from '@c15t/schema';
|
|
21
|
-
|
|
22
|
-
const mode = offline({ policyRules: [policyRulePresets.europeOptIn()] });
|
|
23
|
-
|
|
24
|
-
export function App() {
|
|
25
|
-
return (
|
|
26
|
-
<ConsentProvider options={{ mode }}>
|
|
27
|
-
<ConsentBanner />
|
|
28
|
-
<ConsentDialog />
|
|
29
|
-
<ConsentDialogTrigger showWhen="after-prompt" />
|
|
30
|
-
</ConsentProvider>
|
|
31
|
-
);
|
|
32
|
-
}
|
|
13
|
+
```tsx title="src/consent.tsx"
|
|
14
|
+
import { ConsentDialogTrigger } from 'c15t/react';
|
|
15
|
+
|
|
16
|
+
// Inside the ConsentProvider from your quickstart, next to the dialog:
|
|
17
|
+
<ConsentDialogTrigger showWhen="after-prompt" />;
|
|
33
18
|
```
|
|
34
19
|
|
|
35
20
|
`showWhen="after-prompt"` keeps the button out of the way while a choice or notice is still owed and shows it once the visitor has answered, so the banner and the trigger never compete for the same corner. The default, `always`, shows it whenever the preference center is closed.
|
|
@@ -56,43 +41,63 @@ Use `ConsentDialogTriggerToolbar` when you want app-owned controls beside the pr
|
|
|
56
41
|
import { ConsentDialogTriggerToolbar } from 'c15t/react';
|
|
57
42
|
|
|
58
43
|
<ConsentDialogTriggerToolbar
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
label: 'Manage privacy settings',
|
|
78
|
-
}}
|
|
79
|
-
/>
|
|
44
|
+
ariaLabel="Site controls"
|
|
45
|
+
actions={[
|
|
46
|
+
{
|
|
47
|
+
id: 'theme',
|
|
48
|
+
label: isDark ? 'Switch to light theme' : 'Switch to dark theme',
|
|
49
|
+
icon: isDark ? <SunIcon /> : <MoonIcon />,
|
|
50
|
+
pressed: isDark,
|
|
51
|
+
onSelect: toggleColorScheme,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: 'support',
|
|
55
|
+
label: 'Open support chat',
|
|
56
|
+
icon: <ChatIcon />,
|
|
57
|
+
onSelect: openSupportChat,
|
|
58
|
+
},
|
|
59
|
+
]}
|
|
60
|
+
preferences={{ icon: 'fingerprint', label: 'Manage privacy settings' }}
|
|
61
|
+
/>;
|
|
80
62
|
```
|
|
81
63
|
|
|
82
64
|
Each custom action needs a stable `id`, an accessible `label`, an `icon`, and an `onSelect` callback. Use `pressed` for toggle actions and `disabled` for unavailable ones. Your app owns the state behind each action. The preferences action moves to the edge nearest the toolbar's snapped corner while custom actions keep their configured order.
|
|
83
65
|
|
|
84
|
-
The toolbar does not depend on the consent policy. Your actions always render, so a theme toggle stays available while a banner is up. On the toolbar, `showWhen` applies only to the built-in preferences action: `after-prompt` hides that one item while a choice or notice is owed and shows it once the visitor has answered, and `never` leaves it out. The toolbar renders nothing only when it has no visible item. On the single `ConsentDialogTrigger`, `showWhen` applies to the whole control.
|
|
85
|
-
|
|
86
|
-
No policy, no UI. When no rule has resolved, because resolution failed, no rule matched and you set no default, or init is still withheld, the built-in preferences action and the single `ConsentDialogTrigger` render nothing; app-owned toolbar actions still do. They appear as soon as a rule resolves, without a remount. A rule with `model: 'none'` owes no rights, so the built-in action and the single trigger hide under it too, unless the rule adds `rights: ['preferences']`. The policy chooses what the control says, you choose where and when it sits, and it disappears only when there is nothing to manage.
|
|
87
|
-
|
|
88
|
-
The built-in action names the strongest right the active rule guarantees. Under a rule that carries the `opt-out` right, such as a US opt-out notice, its accessible name is the translated "Do not sell or share my data" and the button carries `data-right="opt-out"`. Under any other rule it reads "Manage preferences" with `data-right="preferences"`. Either way it opens the preference center, and a `preferences.label` you pass replaces the default. The button also carries `data-c15t-rights` with every right on the rule.
|
|
89
|
-
|
|
90
66
|
Toolbars are horizontal by default. Set `orientation="vertical"` to stack the actions and switch arrow-key navigation to up and down:
|
|
91
67
|
|
|
92
68
|
```tsx
|
|
93
|
-
<ConsentDialogTriggerToolbar orientation="vertical" actions={toolbarActions}
|
|
69
|
+
<ConsentDialogTriggerToolbar orientation="vertical" actions={toolbarActions} />;
|
|
94
70
|
```
|
|
95
71
|
|
|
72
|
+
### When the controls show
|
|
73
|
+
|
|
74
|
+
Your toolbar actions do not depend on the consent policy, so a theme toggle
|
|
75
|
+
stays available while a banner is up. The built-in preferences action, and the
|
|
76
|
+
single `ConsentDialogTrigger`, follow the policy:
|
|
77
|
+
|
|
78
|
+
| Situation | Built-in action and `ConsentDialogTrigger` |
|
|
79
|
+
| ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
|
|
80
|
+
| A choice or notice is still owed, with `showWhen="after-prompt"` | Hidden until the visitor answers |
|
|
81
|
+
| `showWhen="never"` on the toolbar | Left out of the toolbar |
|
|
82
|
+
| No policy rule has resolved: resolution failed, no rule matched and you set no default, or init is still withheld | Hidden; appears without a remount once a rule resolves |
|
|
83
|
+
| The rule has `model: 'none'` | Hidden, unless the rule adds `rights: ['preferences']` |
|
|
84
|
+
| Any other case | Shown |
|
|
85
|
+
|
|
86
|
+
On the toolbar, `showWhen` applies only to the built-in action. On the single
|
|
87
|
+
`ConsentDialogTrigger`, it applies to the whole control. The toolbar renders
|
|
88
|
+
nothing only when it has no visible item.
|
|
89
|
+
|
|
90
|
+
### What the built-in action says
|
|
91
|
+
|
|
92
|
+
* Under a rule with the `opt-out` right, such as a US opt-out notice, its
|
|
93
|
+
accessible name is the translated "Do not sell or share my data" and it
|
|
94
|
+
carries `data-right="opt-out"`.
|
|
95
|
+
* Under any other rule it reads "Manage preferences" and carries
|
|
96
|
+
`data-right="preferences"`.
|
|
97
|
+
* Either way it opens the preference center. A `preferences.label` you pass
|
|
98
|
+
replaces the default name, and the button carries `data-c15t-rights` with
|
|
99
|
+
every right on the rule.
|
|
100
|
+
|
|
96
101
|
### Toolbar props
|
|
97
102
|
|
|
98
103
|
| Prop | Type | Default | Description |
|
|
@@ -107,36 +112,41 @@ Toolbars are horizontal by default. Set `orientation="vertical"` to stack the ac
|
|
|
107
112
|
| `ariaLabel` | `string` | `'Privacy controls'` | Accessible name for the toolbar group. |
|
|
108
113
|
| `noStyle` | `boolean` | `false` | Remove the default styling. |
|
|
109
114
|
|
|
115
|
+
While `<ConsentDevTools>` is mounted, the toolbar adds a DevTools button at
|
|
116
|
+
the end farthest from its corner and opens the DevTools panel beside itself.
|
|
117
|
+
The ready-made `ConsentDialogTrigger` switches to this toolbar layout for as
|
|
118
|
+
long as DevTools is mounted.
|
|
119
|
+
|
|
110
120
|
### Toolbar styling
|
|
111
121
|
|
|
112
122
|
The toolbar follows the standard precedence: bundled styles, then provider slots, then direct `className` and `style` on the toolbar or on one action. Use `noStyle` for a fully custom implementation.
|
|
113
123
|
|
|
114
124
|
```tsx
|
|
115
125
|
<ConsentProvider
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
+
options={{
|
|
127
|
+
mode,
|
|
128
|
+
components: {
|
|
129
|
+
trigger: {
|
|
130
|
+
toolbar: { className: 'my-toolbar' },
|
|
131
|
+
toolbarItem: { className: 'my-toolbar-item' },
|
|
132
|
+
toolbarIcon: { className: 'my-toolbar-icon' },
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
}}
|
|
126
136
|
>
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
</ConsentProvider
|
|
137
|
+
<ConsentDialogTriggerToolbar
|
|
138
|
+
className="fixed-toolbar"
|
|
139
|
+
actions={[
|
|
140
|
+
{
|
|
141
|
+
id: 'support',
|
|
142
|
+
label: 'Open support chat',
|
|
143
|
+
icon: <ChatIcon />,
|
|
144
|
+
onSelect: openSupportChat,
|
|
145
|
+
className: 'support-action',
|
|
146
|
+
},
|
|
147
|
+
]}
|
|
148
|
+
/>
|
|
149
|
+
</ConsentProvider>;
|
|
140
150
|
```
|
|
141
151
|
|
|
142
152
|
The toolbar slot keys are `trigger.toolbar`, `trigger.toolbarItem`, and `trigger.toolbarIcon`. With `noStyle`, style the current position and interaction state through `data-corner`, `data-dragging`, and `data-snapping` on the toolbar element.
|
|
@@ -14,32 +14,44 @@ group: frameworks
|
|
|
14
14
|
code.
|
|
15
15
|
|
|
16
16
|
```tsx title="src/consent.tsx"
|
|
17
|
-
import
|
|
17
|
+
import { posthog } from '@c15t/integrations/posthog';
|
|
18
18
|
import {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
ConsentBanner,
|
|
20
|
+
ConsentDialog,
|
|
21
|
+
ConsentDialogLink,
|
|
22
|
+
ConsentProvider,
|
|
23
|
+
hosted,
|
|
24
24
|
} from 'c15t/react';
|
|
25
|
-
import '
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
25
|
+
import type { ReactNode } from 'react';
|
|
26
|
+
|
|
27
|
+
const options = {
|
|
28
|
+
// Asks VITE_C15T_BACKEND_URL for each visitor's policy.
|
|
29
|
+
mode: hosted(),
|
|
30
|
+
scripts: [
|
|
31
|
+
posthog({
|
|
32
|
+
id: 'phc_your_project_key',
|
|
33
|
+
initOptions: { cookieless_mode: 'never' },
|
|
34
|
+
loadMode: 'after-consent',
|
|
35
|
+
}),
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const Consent = ({ children }: { children: ReactNode }) => (
|
|
40
|
+
<ConsentProvider options={options}>
|
|
41
|
+
{children}
|
|
42
|
+
<ConsentBanner />
|
|
43
|
+
<ConsentDialog />
|
|
44
|
+
<footer>
|
|
45
|
+
<ConsentDialogLink>Privacy settings</ConsentDialogLink>
|
|
46
|
+
</footer>
|
|
47
|
+
</ConsentProvider>
|
|
48
|
+
);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
To hide the "Secured by" tag in the dialog card, pass `hideBranding`:
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
<ConsentDialog hideBranding />;
|
|
43
55
|
```
|
|
44
56
|
|
|
45
57
|
To open it from your own component, set the active surface:
|
|
@@ -48,41 +60,41 @@ To open it from your own component, set the active surface:
|
|
|
48
60
|
import { useSetActiveUI } from 'c15t/react';
|
|
49
61
|
|
|
50
62
|
export function PrivacyMenuItem() {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
63
|
+
const setActiveUI = useSetActiveUI();
|
|
64
|
+
return (
|
|
65
|
+
<button type="button" onClick={() => setActiveUI('dialog')}>
|
|
66
|
+
Cookie preferences
|
|
67
|
+
</button>
|
|
68
|
+
);
|
|
57
69
|
}
|
|
58
70
|
```
|
|
59
71
|
|
|
60
72
|
`ConsentDialogLink` does the same with the policy's rights exposed for
|
|
61
73
|
styling; see [ConsentDialogLink](./consent-dialog-link.md). For a floating
|
|
62
74
|
button, see [ConsentDialogTrigger](./consent-dialog-trigger.md). Under an IAB
|
|
63
|
-
policy, mount `IABConsentDialog` from the [IAB guide](../iab
|
|
75
|
+
policy, mount `IABConsentDialog` from the [IAB guide](../iab.md)
|
|
64
76
|
instead; this dialog stays closed for the `iab` model.
|
|
65
77
|
|
|
66
78
|
## Props
|
|
67
79
|
|
|
68
|
-
| Prop | Type | Default | Description
|
|
69
|
-
| ------------------------- | ------------------------------------- | ------------------------------- |
|
|
70
|
-
| `open` | `boolean` | follows the active surface | Controls the open state. When set, Escape and the dialog's own Save, Accept
|
|
71
|
-
| `showTrigger` | `boolean \|ConsentDialogTriggerProps` | `false` | Renders a floating `ConsentDialogTrigger` next to the dialog. Pass an object to configure that trigger.
|
|
72
|
-
| `models` | `Model[]` | `['opt-in', 'opt-out', 'none']` | Policy models the dialog responds to. Under a model that is not listed, such as `iab`, it stays closed.
|
|
73
|
-
| `legalLinks` | `(keyof LegalLinks)[] \|null` | none | Which of the links configured in the provider `options.legalLinks` render after the description. Omitting the prop renders none. `null` hides them.
|
|
74
|
-
| `hideBranding` | `boolean` | `false` | Hides the "Secured by" tag in the card.
|
|
75
|
-
| `uiSource` | `string` | `'dialog'` | Source identifier recorded with saves made from this dialog.
|
|
76
|
-
| `scrollLock`, `trapFocus` | `boolean` | from `blocking` | Deprecated. Either one set to `false` makes the dialog non-blocking, unless the provider sets `presentation.preferences.blocking` explicitly, which wins. Prefer the provider option.
|
|
77
|
-
| `disableAnimation` | `boolean` | `false` | Skips the enter and exit animation of the backdrop and the card.
|
|
78
|
-
| `noStyle` | `boolean` | `false` | Removes the built-in styling from every part.
|
|
80
|
+
| Prop | Type | Default | Description |
|
|
81
|
+
| ------------------------- | ------------------------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
82
|
+
| `open` | `boolean` | follows the active surface | Controls the open state. When set, Escape and the dialog's own Save Settings, Accept All and Reject All buttons no longer close it; change the prop instead. A missing policy or an unlisted model still keeps it closed. |
|
|
83
|
+
| `showTrigger` | `boolean \|ConsentDialogTriggerProps` | `false` | Renders a floating `ConsentDialogTrigger` next to the dialog. Pass an object to configure that trigger. |
|
|
84
|
+
| `models` | `Model[]` | `['opt-in', 'opt-out', 'none']` | Policy models the dialog responds to. Under a model that is not listed, such as `iab`, it stays closed. |
|
|
85
|
+
| `legalLinks` | `(keyof LegalLinks)[] \|null` | none | Which of the links configured in the provider `options.legalLinks` render after the description. Omitting the prop renders none. `null` hides them. |
|
|
86
|
+
| `hideBranding` | `boolean` | `false` | Hides the "Secured by" tag in the card. |
|
|
87
|
+
| `uiSource` | `string` | `'dialog'` | Source identifier recorded with saves made from this dialog. |
|
|
88
|
+
| `scrollLock`, `trapFocus` | `boolean` | from `blocking` | Deprecated. Either one set to `false` makes the dialog non-blocking, unless the provider sets `presentation.preferences.blocking` explicitly, which wins. Prefer the provider option. |
|
|
89
|
+
| `disableAnimation` | `boolean` | `false` | Skips the enter and exit animation of the backdrop and the card. |
|
|
90
|
+
| `noStyle` | `boolean` | `false` | Removes the built-in styling from every part. |
|
|
79
91
|
|
|
80
92
|
## Behavior
|
|
81
93
|
|
|
82
94
|
The dialog is a modal wrapper around the preference center. Its card has a
|
|
83
95
|
header with the title `consentManagerDialog.title` and the description
|
|
84
96
|
`consentManagerDialog.description` followed by the legal links, then the
|
|
85
|
-
same category accordion and Reject
|
|
97
|
+
same category accordion and Reject All, Accept All and Save Settings actions that
|
|
86
98
|
`ConsentWidget` renders, then the branding tag. It mounts through a portal
|
|
87
99
|
into `document.body` after hydration, so it is never part of the server
|
|
88
100
|
HTML.
|
|
@@ -93,18 +105,49 @@ it is `dialog`. These set that surface:
|
|
|
93
105
|
* The Customize button on a `ConsentBanner`, and the "Manage preferences"
|
|
94
106
|
or "Do not sell or share my data" button a notice renders.
|
|
95
107
|
* `ConsentDialogLink` and `ConsentDialogTrigger`.
|
|
96
|
-
* The button in a `
|
|
108
|
+
* The button in a `ConsentGate` placeholder.
|
|
97
109
|
* `useSetActiveUI()('dialog')` in your own component, or `openDialog()`
|
|
98
110
|
from `useHeadlessConsentUI()` on the headless subpath.
|
|
99
111
|
|
|
100
|
-
The component code is split into its own chunk
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
112
|
+
The component code is split into its own chunk, so it is not part of the
|
|
113
|
+
first page load. It renders nothing until that chunk is ready, and the
|
|
114
|
+
chunk downloads at the first of these:
|
|
115
|
+
|
|
116
|
+
* The browser's first idle period after the page's `load` event, while the
|
|
117
|
+
banner is shown or a `ConsentDialogLink`, `ConsentDialogTrigger`,
|
|
118
|
+
`ConsentGate` button or other button that opens the dialog is mounted.
|
|
119
|
+
This covers a visitor who taps or presses Enter with no hover or focus
|
|
120
|
+
first. Browsers without `requestIdleCallback`, such as Safari, wait
|
|
121
|
+
200 ms after `load` instead.
|
|
122
|
+
* Hover or focus on a button that opens the dialog.
|
|
123
|
+
* The dialog opening.
|
|
124
|
+
|
|
125
|
+
Passing `open={true}` or `showTrigger` loads it on mount. A visit with
|
|
126
|
+
saved consent and nothing on the page that opens the dialog never
|
|
127
|
+
downloads it.
|
|
128
|
+
|
|
129
|
+
Idle loading is skipped when the visitor has Save-Data on
|
|
130
|
+
(`navigator.connection.saveData`), on a `2g` or `slow-2g` connection, and
|
|
131
|
+
while offline; hover and focus still load it. To load the chunk only on
|
|
132
|
+
hover, focus or open, set `preloadDialog: 'intent'` in the provider
|
|
133
|
+
options. The default is `'idle'`. With Next.js, pass it through
|
|
134
|
+
`ConsentRoot`'s `options` prop.
|
|
135
|
+
|
|
136
|
+
If a preload fails, for example because the visitor is offline, nothing is
|
|
137
|
+
cached: the next hover, focus or open tries the download again.
|
|
138
|
+
|
|
139
|
+
The dialog's CSS travels in the same chunk and is applied before the dialog
|
|
140
|
+
renders, so the first page load carries only the banner's rules.
|
|
141
|
+
|
|
142
|
+
Without an `open` prop, Escape closes the dialog without saving. If the
|
|
143
|
+
policy still owes a choice, the banner comes back. Save Settings, Accept All and
|
|
144
|
+
Reject All close it as soon as the choice is recorded in the browser, in
|
|
145
|
+
the same task as the click; the exit animation still plays. The request to
|
|
146
|
+
the backend runs afterwards and never reopens the dialog: a failed request
|
|
147
|
+
keeps the choice, reports through `onError` and is retried later. See
|
|
148
|
+
[when a choice is saved](../../../concepts/consent-state.md#when-a-choice-is-saved)
|
|
149
|
+
for the order of events. A draft that went stale because the policy changed keeps the dialog open
|
|
150
|
+
for review. With `open={true}`, these actions leave the dialog visible; the
|
|
108
151
|
parent must set `open={false}` to close it. Clicking the backdrop does not
|
|
109
152
|
close it. Closing discards toggles that were not saved: the next open starts
|
|
110
153
|
from the recorded choice again. After a save from an uncontrolled dialog,
|
|
@@ -138,11 +181,12 @@ The panel carries `role="dialog"`, `aria-labelledby="consent-dialog-title"`
|
|
|
138
181
|
and `aria-describedby="consent-dialog-description"`, plus `aria-modal="true"`
|
|
139
182
|
while it is blocking. Its `dir` attribute follows the active language.
|
|
140
183
|
|
|
141
|
-
While blocking, focus moves on open to the
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
184
|
+
While blocking, focus moves on open to the first tabbable control in the
|
|
185
|
+
panel, so a keyboard user sees the focus ring on a control rather than
|
|
186
|
+
around the whole panel; the `aria-labelledby` and `aria-describedby`
|
|
187
|
+
wiring means a screen reader still announces the title and description as
|
|
188
|
+
focus enters. Tab and Shift+Tab wrap inside the panel, and on close focus
|
|
189
|
+
returns to the element that opened the dialog. A non-blocking dialog manages no focus: nothing moves focus into the
|
|
146
190
|
panel or back to the opener. The backdrop is `aria-hidden` and is not
|
|
147
191
|
focusable.
|
|
148
192
|
|
|
@@ -186,9 +230,18 @@ for the stock structure are `dialog.root`, `dialog.container`,
|
|
|
186
230
|
`dialog.card`, `dialog.header`, `dialog.title`, `dialog.content`,
|
|
187
231
|
`dialog.overlay`, `description.dialog`, `manager.footer` and `tag.dialog`.
|
|
188
232
|
|
|
233
|
+
`ConsentDialog` from the package root and from the
|
|
234
|
+
`c15t/react/consent-dialog` subpath is the deferred component described
|
|
235
|
+
under Behavior, and each `ConsentDialog.<Part>` loads with the same chunk.
|
|
236
|
+
`c15t/react/components/consent-dialog` exports the dialog without the
|
|
237
|
+
deferral, plus each part as a named export (`Card`, `Header`, `Overlay`,
|
|
238
|
+
`Root` and the rest). Importing from that path puts the dialog's code in
|
|
239
|
+
the bundle of every page that imports it, so the first open needs no
|
|
240
|
+
download but every visitor downloads the dialog.
|
|
241
|
+
|
|
189
242
|
The compound parts import from `c15t/react` as properties of `ConsentDialog`,
|
|
190
243
|
and `ConsentWidget` from the same module. See
|
|
191
|
-
[
|
|
244
|
+
[customize](../customize.md) for slots and tokens.
|
|
192
245
|
|
|
193
246
|
## Verify
|
|
194
247
|
|