@c15t/react 2.0.4 → 2.2.0-canary-20260727202135
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 +155 -0
- package/README.md +29 -14
- package/client/components/integrations.js +3 -0
- package/dist/components/consent-banner/atoms/overlay.cjs +1 -1
- package/dist/components/consent-banner/atoms/root.cjs +1 -1
- package/dist/components/consent-banner/components.cjs +1 -1
- package/dist/components/consent-banner/consent-banner.cjs +1 -1
- package/dist/components/consent-banner/error-boundary.cjs +1 -1
- package/dist/components/consent-banner/index.cjs +1 -1
- package/dist/components/consent-banner/policy-actions.cjs +1 -1
- package/dist/components/consent-dialog/atoms/card.cjs +1 -1
- package/dist/components/consent-dialog/atoms/overlay.cjs +1 -1
- package/dist/components/consent-dialog/atoms/root.cjs +1 -1
- package/dist/components/consent-dialog/consent-dialog.cjs +1 -1
- package/dist/components/consent-dialog/index.cjs +1 -1
- package/dist/components/consent-dialog-link/index.cjs +1 -1
- package/dist/components/consent-dialog-trigger/atoms/button.cjs +1 -1
- package/dist/components/consent-dialog-trigger/atoms/button.js +1 -1
- package/dist/components/consent-dialog-trigger/atoms/icon.cjs +1 -1
- package/dist/components/consent-dialog-trigger/atoms/root.cjs +1 -1
- package/dist/components/consent-dialog-trigger/atoms/text.cjs +1 -1
- package/dist/components/consent-dialog-trigger/atoms/toolbar.cjs +1 -0
- package/dist/components/consent-dialog-trigger/atoms/toolbar.js +1 -0
- package/dist/components/consent-dialog-trigger/consent-dialog-trigger-toolbar.cjs +1 -0
- package/dist/components/consent-dialog-trigger/consent-dialog-trigger-toolbar.js +1 -0
- package/dist/components/consent-dialog-trigger/consent-dialog-trigger.cjs +1 -1
- package/dist/components/consent-dialog-trigger/index.cjs +1 -1
- package/dist/components/consent-dialog-trigger/index.js +1 -1
- package/dist/components/consent-dialog-trigger/use-draggable.cjs +1 -1
- package/dist/components/consent-preferences-link/consent-preferences-link.cjs +1 -1
- package/dist/components/consent-preferences-link/index.cjs +1 -1
- package/dist/components/consent-widget/atoms/accordion.cjs +1 -1
- package/dist/components/consent-widget/atoms/button.cjs +1 -1
- package/dist/components/consent-widget/atoms/footer.cjs +1 -1
- package/dist/components/consent-widget/atoms/root.cjs +1 -1
- package/dist/components/consent-widget/consent-widget.cjs +1 -1
- package/dist/components/consent-widget/index.cjs +1 -1
- package/dist/components/consent-widget/policy-actions.cjs +1 -1
- package/dist/components/frame/atoms.cjs +1 -1
- package/dist/components/frame/atoms.js +1 -1
- package/dist/components/frame/frame.cjs +1 -1
- package/dist/components/frame/index.cjs +1 -1
- package/dist/components/iab-consent-banner/atoms/button-group.cjs +1 -1
- package/dist/components/iab-consent-banner/atoms/card.cjs +1 -1
- package/dist/components/iab-consent-banner/atoms/description.cjs +1 -1
- package/dist/components/iab-consent-banner/atoms/footer.cjs +1 -1
- package/dist/components/iab-consent-banner/atoms/header.cjs +1 -1
- package/dist/components/iab-consent-banner/atoms/overlay.cjs +1 -1
- package/dist/components/iab-consent-banner/atoms/root.cjs +1 -1
- package/dist/components/iab-consent-banner/atoms/title.cjs +1 -1
- package/dist/components/iab-consent-banner/iab-consent-banner.cjs +1 -1
- package/dist/components/iab-consent-banner/iab-consent-banner.js +1 -1
- package/dist/components/iab-consent-banner/index.cjs +1 -1
- package/dist/components/iab-consent-dialog/atoms/card.cjs +1 -1
- package/dist/components/iab-consent-dialog/atoms/content.cjs +1 -1
- package/dist/components/iab-consent-dialog/atoms/footer.cjs +1 -1
- package/dist/components/iab-consent-dialog/atoms/header.cjs +1 -1
- package/dist/components/iab-consent-dialog/atoms/overlay.cjs +1 -1
- package/dist/components/iab-consent-dialog/atoms/purpose-item.cjs +1 -1
- package/dist/components/iab-consent-dialog/atoms/root.cjs +1 -1
- package/dist/components/iab-consent-dialog/atoms/stack-item.cjs +1 -1
- package/dist/components/iab-consent-dialog/atoms/tabs.cjs +1 -1
- package/dist/components/iab-consent-dialog/atoms/vendor-list.cjs +1 -1
- package/dist/components/iab-consent-dialog/hooks/use-gvl-data.cjs +1 -1
- package/dist/components/iab-consent-dialog/iab-consent-dialog.cjs +1 -1
- package/dist/components/iab-consent-dialog/index.cjs +1 -1
- package/dist/components/iab-consent-dialog/use-iab-translations.cjs +1 -1
- package/dist/components/integrations/google-map.cjs +1 -0
- package/dist/components/integrations/google-map.js +1 -0
- package/dist/components/integrations/index.cjs +1 -0
- package/dist/components/integrations/index.js +1 -0
- package/dist/components/integrations/shared.cjs +1 -0
- package/dist/components/integrations/shared.js +1 -0
- package/dist/components/integrations/youtube-embed.cjs +1 -0
- package/dist/components/integrations/youtube-embed.js +1 -0
- package/dist/components/shared/libs/recursive-clone-children.cjs +1 -1
- package/dist/components/shared/libs/slot.cjs +1 -1
- package/dist/components/shared/libs/use-controllable-state.cjs +1 -1
- package/dist/components/shared/policy-actions.cjs +1 -1
- package/dist/components/shared/primitives/box.cjs +1 -1
- package/dist/components/shared/primitives/button.cjs +1 -1
- package/dist/components/shared/primitives/button.js +1 -1
- package/dist/components/shared/primitives/legal-links/index.cjs +1 -1
- package/dist/components/shared/primitives/legal-links/index.js +1 -1
- package/dist/components/shared/ui/accordion/accordion.cjs +1 -1
- package/dist/components/shared/ui/accordion/index.cjs +1 -1
- package/dist/components/shared/ui/animated-collapse/animated-collapse.cjs +1 -1
- package/dist/components/shared/ui/animated-collapse/index.cjs +1 -1
- package/dist/components/shared/ui/branding.cjs +1 -1
- package/dist/components/shared/ui/button/button.cjs +1 -1
- package/dist/components/shared/ui/button/index.cjs +1 -1
- package/dist/components/shared/ui/collapsible/collapsible.cjs +1 -1
- package/dist/components/shared/ui/collapsible/index.cjs +1 -1
- package/dist/components/shared/ui/dialog/dialog.cjs +1 -1
- package/dist/components/shared/ui/dialog/index.cjs +1 -1
- package/dist/components/shared/ui/icon.cjs +1 -1
- package/dist/components/shared/ui/logo.cjs +1 -1
- package/dist/components/shared/ui/preference-item/index.cjs +1 -1
- package/dist/components/shared/ui/preference-item/preference-item.cjs +1 -1
- package/dist/components/shared/ui/switch/index.cjs +1 -1
- package/dist/components/shared/ui/switch/switch.cjs +1 -1
- package/dist/components/shared/ui/tabs/index.cjs +1 -1
- package/dist/components/shared/ui/tabs/tabs.cjs +1 -1
- package/dist/context/consent-manager-context.cjs +1 -1
- package/dist/context/consent-tracking-context.cjs +1 -1
- package/dist/context/theme-context.cjs +1 -1
- package/dist/headless.cjs +1 -1
- package/dist/headless.js +1 -1
- package/dist/hooks/index.cjs +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/use-color-scheme.cjs +1 -1
- package/dist/hooks/use-component-config.cjs +1 -1
- package/dist/hooks/use-consent-dialog-trigger.cjs +1 -1
- package/dist/hooks/use-consent-manager.cjs +1 -1
- package/dist/hooks/use-consent-script.cjs +1 -0
- package/dist/hooks/use-consent-script.js +1 -0
- package/dist/hooks/use-focus-trap.cjs +1 -1
- package/dist/hooks/use-headless-consent-ui.cjs +1 -1
- package/dist/hooks/use-headless-iab-consent-ui.cjs +1 -1
- package/dist/hooks/use-reduced-motion.cjs +1 -1
- package/dist/hooks/use-scroll-lock.cjs +1 -1
- package/dist/hooks/use-ssr-status.cjs +1 -1
- package/dist/hooks/use-styles.cjs +1 -1
- package/dist/hooks/use-text-direction.cjs +1 -1
- package/dist/hooks/use-theme.cjs +1 -1
- package/dist/hooks/use-translations.cjs +1 -1
- package/dist/iab.cjs +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/primitives/accordion.cjs +1 -1
- package/dist/primitives/button.cjs +1 -1
- package/dist/primitives/collapsible.cjs +1 -1
- package/dist/primitives/dialog.cjs +1 -1
- package/dist/primitives/preference-item.cjs +1 -1
- package/dist/primitives/switch.cjs +1 -1
- package/dist/primitives/tabs.cjs +1 -1
- package/dist/primitives.cjs +1 -1
- package/dist/providers/consent-manager-provider.cjs +1 -1
- package/dist/server/fetch-ssr-data.cjs +1 -1
- package/dist/server/fetch-ssr-data.js +1 -1
- package/dist/server/headers.cjs +1 -1
- package/dist/server/headers.js +1 -1
- package/dist/server/index.cjs +1 -1
- package/dist/server/init-cache-key.cjs +1 -1
- package/dist/server/normalize-url.cjs +1 -1
- package/dist/styles.tw3.css +1 -1
- package/dist/types/theme/index.cjs +1 -1
- package/dist/types/theme/style-types.cjs +1 -1
- package/dist/utils/cn.cjs +1 -1
- package/dist/utils/merge-styles.cjs +1 -1
- package/dist/utils/test-helpers.cjs +1 -1
- package/dist/utils/theme-utils.cjs +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.js +1 -1
- package/dist-types/components/consent-banner/components.d.ts +2 -2
- package/dist-types/components/consent-banner/policy-actions.d.ts +1 -1
- package/dist-types/components/consent-dialog/atoms/card.d.ts +5 -5
- package/dist-types/components/consent-dialog-trigger/atoms/toolbar.d.ts +22 -0
- package/dist-types/components/consent-dialog-trigger/consent-dialog-trigger-toolbar.d.ts +35 -0
- package/dist-types/components/consent-dialog-trigger/index.d.ts +2 -1
- package/dist-types/components/consent-dialog-trigger/types.d.ts +111 -6
- package/dist-types/components/consent-widget/atoms/accordion.d.ts +4 -4
- package/dist-types/components/consent-widget/consent-widget.d.ts +1 -1
- package/dist-types/components/consent-widget/policy-actions.d.ts +1 -1
- package/dist-types/components/integrations/google-map.d.ts +82 -0
- package/dist-types/components/integrations/index.d.ts +2 -0
- package/dist-types/components/integrations/shared.d.ts +12 -0
- package/dist-types/components/integrations/youtube-embed.d.ts +95 -0
- package/dist-types/components/shared/policy-actions.d.ts +1 -1
- package/dist-types/components/shared/primitives/button.d.ts +36 -2
- package/dist-types/components/shared/primitives/legal-links/index.d.ts +1 -1
- package/dist-types/components/shared/ui/accordion/accordion.d.ts +2 -2
- package/dist-types/components/shared/ui/branding.d.ts +3 -3
- package/dist-types/components/shared/ui/button/button.d.ts +1 -1
- package/dist-types/components/shared/ui/dialog/dialog.d.ts +1 -1
- package/dist-types/components/shared/ui/logo.d.ts +8 -8
- package/dist-types/headless.d.ts +1 -0
- package/dist-types/hooks/index.d.ts +1 -0
- package/dist-types/hooks/use-consent-script.d.ts +80 -0
- package/dist-types/index.d.ts +3 -1
- package/dist-types/providers/consent-manager-provider.d.ts +1 -1
- package/dist-types/server/headers.d.ts +1 -1
- package/dist-types/utils/theme-utils.d.ts +1 -1
- package/dist-types/version.d.ts +1 -1
- package/docs/README.md +155 -76
- package/docs/{building-headless-components.md → frameworks/react/building-headless-components.md} +3 -1
- package/docs/{callbacks.md → frameworks/react/callbacks.md} +3 -1
- package/docs/{components → frameworks/react/components}/consent-banner.md +10 -21
- package/docs/{components → frameworks/react/components}/consent-dialog-link.md +8 -5
- package/docs/frameworks/react/components/consent-dialog-trigger.md +202 -0
- package/docs/{components → frameworks/react/components}/consent-dialog.md +7 -15
- package/docs/frameworks/react/components/consent-manager-provider.md +228 -0
- package/docs/{components → frameworks/react/components}/consent-widget.md +8 -6
- package/docs/{components → frameworks/react/components}/dev-tools.md +9 -6
- package/docs/{components → frameworks/react/components}/frame.md +8 -9
- package/docs/{concepts → frameworks/react/concepts}/client-modes.md +4 -2
- package/docs/{concepts → frameworks/react/concepts}/consent-categories.md +1 -0
- package/docs/{concepts → frameworks/react/concepts}/consent-models.md +1 -0
- package/docs/{concepts → frameworks/react/concepts}/cookie-management.md +3 -3
- package/docs/{concepts → frameworks/react/concepts}/glossary.md +1 -0
- package/docs/{concepts → frameworks/react/concepts}/initialization-flow.md +1 -0
- package/docs/{concepts → frameworks/react/concepts}/policy-packs.md +1 -0
- package/docs/{headless.md → frameworks/react/headless.md} +3 -1
- package/docs/{hooks → frameworks/react/hooks}/use-color-scheme.md +1 -0
- package/docs/{hooks → frameworks/react/hooks}/use-consent-manager/checking-consent.md +3 -1
- package/docs/{hooks → frameworks/react/hooks}/use-consent-manager/location-info.md +3 -1
- package/docs/frameworks/react/hooks/use-consent-manager/overview.md +172 -0
- package/docs/{hooks → frameworks/react/hooks}/use-consent-manager/setting-consent.md +3 -1
- package/docs/{hooks → frameworks/react/hooks}/use-draggable.md +3 -1
- package/docs/{hooks → frameworks/react/hooks}/use-focus-trap.md +1 -0
- package/docs/{hooks → frameworks/react/hooks}/use-reduced-motion.md +3 -1
- package/docs/{hooks → frameworks/react/hooks}/use-ssr-status.md +6 -5
- package/docs/{hooks → frameworks/react/hooks}/use-text-direction.md +1 -0
- package/docs/frameworks/react/hooks/use-translations.md +55 -0
- package/docs/{iab → frameworks/react/iab}/consent-banner.md +9 -12
- package/docs/{iab → frameworks/react/iab}/consent-dialog.md +9 -14
- package/docs/{iab → frameworks/react/iab}/overview.md +4 -2
- package/docs/{iab → frameworks/react/iab}/use-gvl-data.md +3 -2
- package/docs/{iframe-blocking.md → frameworks/react/iframe-blocking.md} +8 -9
- package/docs/{internationalization.md → frameworks/react/internationalization.md} +13 -3
- package/docs/{network-blocker.md → frameworks/react/network-blocker.md} +13 -51
- package/docs/{optimization.md → frameworks/react/optimization.md} +3 -2
- package/docs/{policy-packs.md → frameworks/react/policy-packs.md} +3 -1
- package/docs/{quickstart.md → frameworks/react/quickstart.md} +26 -42
- package/docs/frameworks/react/script-loader.md +553 -0
- package/docs/{server-side.md → frameworks/react/server-side.md} +9 -4
- package/docs/{styling → frameworks/react/styling}/classnames.md +3 -1
- package/docs/{styling → frameworks/react/styling}/color-scheme.md +3 -1
- package/docs/frameworks/react/styling/css-variables.md +53 -0
- package/docs/frameworks/react/styling/overview.md +302 -0
- package/docs/frameworks/react/styling/slots.md +94 -0
- package/docs/{styling → frameworks/react/styling}/tailwind.md +3 -1
- package/docs/frameworks/react/styling/tokens.md +156 -0
- package/docs/{troubleshooting.md → frameworks/react/troubleshooting.md} +3 -1
- package/docs/integrations/adobe-analytics.md +160 -0
- package/docs/integrations/ahrefs-analytics.md +157 -0
- package/docs/integrations/amplitude.md +230 -0
- package/docs/integrations/building-integrations.md +15 -181
- package/docs/integrations/clearbit.md +130 -0
- package/docs/integrations/cloudflare-web-analytics.md +126 -0
- package/docs/integrations/crisp.md +140 -0
- package/docs/integrations/databuddy.md +152 -150
- package/docs/integrations/fathom-analytics.md +150 -0
- package/docs/integrations/google-maps.md +263 -0
- package/docs/integrations/google-tag-manager.md +102 -101
- package/docs/integrations/google-tag.md +104 -92
- package/docs/integrations/heap.md +219 -0
- package/docs/integrations/hightouch.md +199 -0
- package/docs/integrations/hotjar.md +143 -0
- package/docs/integrations/intercom.md +144 -0
- package/docs/integrations/linkedin-insights.md +142 -90
- package/docs/integrations/logrocket.md +175 -0
- package/docs/integrations/matomo-analytics.md +171 -0
- package/docs/integrations/meta-pixel.md +379 -309
- package/docs/integrations/microsoft-clarity.md +173 -0
- package/docs/integrations/microsoft-uet.md +135 -91
- package/docs/integrations/mixpanel-analytics.md +130 -0
- package/docs/integrations/overview.md +119 -75
- package/docs/integrations/pirsch.md +142 -0
- package/docs/integrations/plausible-analytics.md +154 -0
- package/docs/integrations/posthog.md +186 -127
- package/docs/integrations/promptwatch.md +121 -0
- package/docs/integrations/reddit-pixel.md +241 -0
- package/docs/integrations/rudderstack.md +271 -0
- package/docs/integrations/rybbit-analytics.md +143 -0
- package/docs/integrations/segment.md +146 -0
- package/docs/integrations/snapchat-pixel.md +163 -0
- package/docs/integrations/tiktok-pixel.md +101 -91
- package/docs/integrations/umami-analytics.md +148 -0
- package/docs/integrations/vercel-analytics.md +141 -0
- package/docs/integrations/x-pixel.md +123 -109
- package/docs/integrations/youtube.md +193 -0
- package/docs/shared/concepts/client-modes.md +103 -0
- package/docs/shared/concepts/consent-categories.md +41 -0
- package/docs/shared/concepts/consent-models.md +72 -0
- package/docs/shared/concepts/cookie-management.md +88 -0
- package/docs/shared/concepts/glossary.md +24 -0
- package/docs/shared/concepts/initialization-flow.md +105 -0
- package/docs/shared/concepts/policy-packs.md +225 -0
- package/docs/shared/react/components/consent-banner.md +242 -0
- package/docs/shared/react/components/consent-dialog-link.md +45 -0
- package/docs/shared/react/components/consent-dialog-trigger.md +185 -0
- package/docs/shared/react/components/consent-dialog.md +119 -0
- package/docs/shared/react/components/consent-manager-provider.md +183 -0
- package/docs/shared/react/components/consent-widget.md +121 -0
- package/docs/shared/react/components/dev-tools.md +81 -0
- package/docs/shared/react/components/frame.md +52 -0
- package/docs/shared/react/guides/building-headless-components.md +110 -0
- package/docs/shared/react/guides/callbacks.md +89 -0
- package/docs/shared/react/guides/headless.md +31 -0
- package/docs/shared/react/guides/iframe-blocking.md +65 -0
- package/docs/shared/react/guides/internationalization.md +123 -0
- package/docs/shared/react/guides/network-blocker.md +72 -0
- package/docs/shared/react/guides/optimization.md +44 -0
- package/docs/shared/react/guides/policy-packs.md +173 -0
- package/docs/shared/react/guides/script-loader.md +309 -0
- package/docs/shared/react/hooks/use-color-scheme.md +31 -0
- package/docs/shared/react/hooks/use-consent-manager/checking-consent.md +95 -0
- package/docs/shared/react/hooks/use-consent-manager/location-info.md +96 -0
- package/docs/shared/react/hooks/use-consent-manager/overview.md +74 -0
- package/docs/shared/react/hooks/use-consent-manager/setting-consent.md +93 -0
- package/docs/shared/react/hooks/use-draggable.md +30 -0
- package/docs/shared/react/hooks/use-focus-trap.md +20 -0
- package/docs/shared/react/hooks/use-reduced-motion.md +33 -0
- package/docs/shared/react/hooks/use-ssr-status.md +16 -0
- package/docs/shared/react/hooks/use-text-direction.md +38 -0
- package/docs/shared/react/hooks/use-translations.md +15 -0
- package/docs/shared/react/iab/consent-banner.md +60 -0
- package/docs/shared/react/iab/consent-dialog.md +76 -0
- package/docs/shared/react/iab/overview.md +80 -0
- package/docs/shared/react/iab/use-gvl-data.md +21 -0
- package/docs/shared/react/styling/classnames.md +93 -0
- package/docs/shared/react/styling/color-scheme.md +35 -0
- package/docs/shared/react/styling/css-variables.md +53 -0
- package/docs/shared/react/styling/overview.md +261 -0
- package/docs/shared/react/styling/slots.md +93 -0
- package/docs/shared/react/styling/stylesheet-entrypoint.md +8 -0
- package/docs/shared/react/styling/tailwind.md +88 -0
- package/docs/shared/react/styling/tokens.md +155 -0
- package/docs/shared/troubleshooting.md +82 -0
- package/package.json +23 -12
- package/readme.json +12 -7
- package/docs/ai-agents.md +0 -111
- package/docs/components/consent-dialog-trigger.md +0 -103
- package/docs/components/consent-manager-provider.md +0 -425
- package/docs/hooks/use-consent-manager/overview.md +0 -420
- package/docs/hooks/use-translations.md +0 -118
- package/docs/script-loader.md +0 -321
- package/docs/styling/css-variables.md +0 -92
- package/docs/styling/overview.md +0 -460
- package/docs/styling/slots.md +0 -128
- package/docs/styling/tokens.md +0 -216
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Consent Dialog
|
|
3
|
+
description: Reference page for consent dialog.
|
|
4
|
+
group: reference
|
|
5
|
+
---
|
|
6
|
+
`ConsentDialog` is a modal that shows toggles for each consent category. In **opt-in jurisdictions**, it typically opens when users click "Customize" on `ConsentBanner`. It can also be controlled programmatically for use on settings pages regardless of jurisdiction.
|
|
7
|
+
|
|
8
|
+
## Floating Trigger
|
|
9
|
+
|
|
10
|
+
Add a floating button that lets users re-open the dialog after dismissing the banner:
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
{/* Default trigger */}
|
|
14
|
+
<ConsentDialog showTrigger />
|
|
15
|
+
|
|
16
|
+
{/* Custom trigger */}
|
|
17
|
+
<ConsentDialog
|
|
18
|
+
showTrigger={{
|
|
19
|
+
icon: 'settings',
|
|
20
|
+
defaultPosition: 'bottom-left',
|
|
21
|
+
showWhen: 'after-consent',
|
|
22
|
+
size: 'sm',
|
|
23
|
+
}}
|
|
24
|
+
/>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Branding
|
|
28
|
+
|
|
29
|
+
Hide the c15t branding tag:
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
<ConsentDialog hideBranding />
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Styling First
|
|
36
|
+
|
|
37
|
+
> ℹ️ **Info:**
|
|
38
|
+
> If you are only changing visuals, stay with the stock dialog and use the theme system first. Start with tokens and slots such as consentDialogCard, consentWidgetFooter, and consentDialogTag. See Styling Overview.
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
<ConsentManagerProvider
|
|
42
|
+
options={{
|
|
43
|
+
theme: {
|
|
44
|
+
colors: {
|
|
45
|
+
surface: '#fffdf8',
|
|
46
|
+
surfaceHover: '#f6f3ee',
|
|
47
|
+
},
|
|
48
|
+
slots: {
|
|
49
|
+
consentDialogCard: 'rounded-[32px] shadow-xl',
|
|
50
|
+
consentDialogHeader: 'gap-3',
|
|
51
|
+
consentWidgetFooter: 'gap-3 pt-6',
|
|
52
|
+
consentDialogTag: 'shadow-none',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
}}
|
|
56
|
+
>
|
|
57
|
+
<ConsentDialog />
|
|
58
|
+
</ConsentManagerProvider>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Dialog copy should be changed through `ConsentManagerProvider.options.i18n`, not by rebuilding the dialog structure.
|
|
62
|
+
|
|
63
|
+
## Advanced: Compound Components
|
|
64
|
+
|
|
65
|
+
Use compound components only when you need custom dialog markup while still keeping c15t primitives and policy-aware footer actions:
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
<ConsentDialog.Root>
|
|
69
|
+
<ConsentDialog.Overlay />
|
|
70
|
+
<ConsentDialog.Card>
|
|
71
|
+
<ConsentDialog.Header>
|
|
72
|
+
<ConsentDialog.HeaderTitle />
|
|
73
|
+
<ConsentDialog.HeaderDescription />
|
|
74
|
+
</ConsentDialog.Header>
|
|
75
|
+
<ConsentDialog.Content>
|
|
76
|
+
<ConsentWidget.Root>
|
|
77
|
+
<ConsentWidget.Accordion type="single">
|
|
78
|
+
<ConsentWidget.AccordionItems />
|
|
79
|
+
</ConsentWidget.Accordion>
|
|
80
|
+
<ConsentWidget.PolicyActions />
|
|
81
|
+
</ConsentWidget.Root>
|
|
82
|
+
</ConsentDialog.Content>
|
|
83
|
+
<ConsentDialog.Footer />
|
|
84
|
+
</ConsentDialog.Card>
|
|
85
|
+
</ConsentDialog.Root>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
* `ConsentDialog.Root` — Portal container with focus trap, scroll lock, and animation
|
|
89
|
+
* `ConsentDialog.Card` — Main dialog card
|
|
90
|
+
* `ConsentDialog.Header` — Contains title and description
|
|
91
|
+
* `ConsentDialog.HeaderTitle` — Dialog title
|
|
92
|
+
* `ConsentDialog.HeaderDescription` — Description with optional `legalLinks`
|
|
93
|
+
* `ConsentDialog.Content` — Main content area (typically contains `ConsentWidget`)
|
|
94
|
+
* `ConsentDialog.Footer` — Footer with optional branding (`hideBranding` prop)
|
|
95
|
+
* `ConsentDialog.Overlay` — Backdrop overlay
|
|
96
|
+
* `ConsentWidget.PolicyActions` — Renders policy-aware grouped dialog actions
|
|
97
|
+
|
|
98
|
+
For a quick pre-composed layout, use the shorthand card:
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
<ConsentDialog.Root>
|
|
102
|
+
<ConsentDialog.ConsentCustomizationCard />
|
|
103
|
+
</ConsentDialog.Root>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
`ConsentWidget.PolicyActions` uses stock c15t widget buttons and translations by default. Pass `renderAction` only when you need to customize the action mapping, and return stock widget button compounds if you want to preserve built-in behavior and copy.
|
|
107
|
+
|
|
108
|
+
For fully manual control over dialog action rendering, use `useHeadlessConsentUI()` and map `dialog.actionGroups` yourself.
|
|
109
|
+
|
|
110
|
+
If the stock dialog structure still works, prefer tokens, slots, and provider configuration instead.
|
|
111
|
+
|
|
112
|
+
## Props
|
|
113
|
+
|
|
114
|
+
|Property|Value|
|
|
115
|
+
|:--|:--|
|
|
116
|
+
|Type Name|\`ConsentDialogProps\`|
|
|
117
|
+
|Source Path|\`./packages/react/src/components/consent-dialog/consent-dialog.tsx\`|
|
|
118
|
+
|
|
119
|
+
\*ExtractedTypeTable: Could not extract "ConsentDialogProps" from "./packages/react/src/components/consent-dialog/consent-dialog.tsx" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Consent Manager Provider
|
|
3
|
+
description: Reference page for consent manager provider.
|
|
4
|
+
group: reference
|
|
5
|
+
---
|
|
6
|
+
`ConsentManagerProvider` is the root component for the c15t consent system. It initializes the consent store, detects the user's jurisdiction, resolves translations, and provides consent state to all child components via React context.
|
|
7
|
+
|
|
8
|
+
Every other c15t component and hook must be rendered inside this provider.
|
|
9
|
+
|
|
10
|
+
## Options Reference
|
|
11
|
+
|
|
12
|
+
|Property|Value|
|
|
13
|
+
|:--|:--|
|
|
14
|
+
|Type Name|\`CommonInlineStoreOptions\`|
|
|
15
|
+
|Source Path|\`./packages/ui/src/theme/options.ts\`|
|
|
16
|
+
|
|
17
|
+
\*ExtractedTypeTable: Could not extract "CommonInlineStoreOptions" from "./packages/ui/src/theme/options.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
|
|
18
|
+
|
|
19
|
+
|Property|Value|
|
|
20
|
+
|:--|:--|
|
|
21
|
+
|Type Name|\`ConsentManagerContentOptions\`|
|
|
22
|
+
|Source Path|\`./packages/ui/src/theme/options.ts\`|
|
|
23
|
+
|
|
24
|
+
\*ExtractedTypeTable: Could not extract "ConsentManagerContentOptions" from "./packages/ui/src/theme/options.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
|
|
25
|
+
|
|
26
|
+
|Property|Value|
|
|
27
|
+
|:--|:--|
|
|
28
|
+
|Type Name|\`UIOptions\`|
|
|
29
|
+
|Source Path|\`./packages/ui/src/theme/types.ts\`|
|
|
30
|
+
|
|
31
|
+
\*ExtractedTypeTable: Could not extract "UIOptions" from "./packages/ui/src/theme/types.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
|
|
32
|
+
|
|
33
|
+
## Legal Links
|
|
34
|
+
|
|
35
|
+
`legalLinks` defines the URLs shown in consent UI text (banner, dialog, and widget where applicable).
|
|
36
|
+
Configure only the links you want to expose.
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
<ConsentManagerProvider
|
|
40
|
+
options={{
|
|
41
|
+
backendURL: 'https://your-instance.c15t.dev',
|
|
42
|
+
legalLinks: {
|
|
43
|
+
privacyPolicy: {
|
|
44
|
+
href: '/privacy',
|
|
45
|
+
target: '_self',
|
|
46
|
+
},
|
|
47
|
+
cookiePolicy: {
|
|
48
|
+
href: '/cookies',
|
|
49
|
+
target: '_self',
|
|
50
|
+
},
|
|
51
|
+
termsOfService: {
|
|
52
|
+
href: 'https://example.com/terms',
|
|
53
|
+
target: '_blank',
|
|
54
|
+
rel: 'noopener noreferrer',
|
|
55
|
+
label: 'Terms of Service',
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
}}
|
|
59
|
+
>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Notes:
|
|
63
|
+
|
|
64
|
+
* Omitting a key (for example `termsOfService`) hides that link.
|
|
65
|
+
* `label` overrides the translated text for that single link.
|
|
66
|
+
* Use `_self` for internal pages and `_blank` + `rel="noopener noreferrer"` for external pages.
|
|
67
|
+
* Control which of the configured links render in each component via the component's `legalLinks` prop.
|
|
68
|
+
|
|
69
|
+
## Overrides
|
|
70
|
+
|
|
71
|
+
`overrides` lets you force location/language signals instead of browser or network detection.
|
|
72
|
+
This is useful for QA, local development, and preview environments.
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
<ConsentManagerProvider
|
|
76
|
+
options={{
|
|
77
|
+
backendURL: 'https://your-instance.c15t.dev',
|
|
78
|
+
overrides: {
|
|
79
|
+
country: 'DE',
|
|
80
|
+
region: 'BY',
|
|
81
|
+
language: 'de-DE',
|
|
82
|
+
},
|
|
83
|
+
}}
|
|
84
|
+
>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
You can also override Global Privacy Control (GPC) behavior during testing:
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
<ConsentManagerProvider
|
|
91
|
+
options={{
|
|
92
|
+
backendURL: 'https://your-instance.c15t.dev',
|
|
93
|
+
overrides: {
|
|
94
|
+
gpc: true,
|
|
95
|
+
},
|
|
96
|
+
}}
|
|
97
|
+
>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
> ⚠️ **Warning:**
|
|
101
|
+
> Treat overrides as an environment/testing tool. Avoid hard-coding production overrides unless that behavior is intentional for your deployment.
|
|
102
|
+
|
|
103
|
+
## Policy Packs
|
|
104
|
+
|
|
105
|
+
In hosted mode (recommended), the backend resolves the correct policy automatically — no frontend policy config needed:
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
<ConsentManagerProvider
|
|
109
|
+
options={{
|
|
110
|
+
backendURL: 'https://your-instance.c15t.dev',
|
|
111
|
+
}}
|
|
112
|
+
>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Fallback: Offline Policies
|
|
116
|
+
|
|
117
|
+
When no backend is available, `ConsentManagerProvider` accepts `offlinePolicy.policyPacks` for local policy resolution during development, testing, previews, or temporary backend outages:
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
<ConsentManagerProvider
|
|
121
|
+
options={{
|
|
122
|
+
mode: 'offline',
|
|
123
|
+
offlinePolicy: {
|
|
124
|
+
i18n: {
|
|
125
|
+
defaultProfile: 'default',
|
|
126
|
+
messages: {
|
|
127
|
+
default: {
|
|
128
|
+
translations: {
|
|
129
|
+
en: { cookieBanner: { title: 'Privacy choices' } },
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
qc: {
|
|
133
|
+
fallbackLanguage: 'fr',
|
|
134
|
+
translations: {
|
|
135
|
+
en: { cookieBanner: { title: 'Quebec Privacy Settings' } },
|
|
136
|
+
fr: { cookieBanner: { title: 'Paramètres de confidentialité du Québec' } },
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
policyPacks: [
|
|
142
|
+
{
|
|
143
|
+
id: 'qc_opt_in',
|
|
144
|
+
match: { regions: [{ country: 'CA', region: 'QC' }] },
|
|
145
|
+
i18n: { messageProfile: 'qc' },
|
|
146
|
+
consent: { model: 'opt-in', expiryDays: 365 },
|
|
147
|
+
ui: { mode: 'banner' },
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
id: 'default_world',
|
|
151
|
+
match: { isDefault: true },
|
|
152
|
+
consent: { model: 'none' },
|
|
153
|
+
ui: { mode: 'none' },
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
},
|
|
157
|
+
overrides: {
|
|
158
|
+
country: 'CA',
|
|
159
|
+
region: 'QC',
|
|
160
|
+
},
|
|
161
|
+
}}
|
|
162
|
+
>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Notes:
|
|
166
|
+
|
|
167
|
+
* `offlinePolicy` is only used in `offline` mode.
|
|
168
|
+
* Treat offline policies as a development/testing tool or resilience fallback, not the primary production source of truth.
|
|
169
|
+
* `offlinePolicy.i18n` lets offline mode mirror hosted `messageProfile` and profile-local `fallbackLanguage` behavior.
|
|
170
|
+
* Omitting `offlinePolicy.policyPacks` uses the built-in synthetic opt-in fallback banner. Hosted network fallback uses the same opt-in banner.
|
|
171
|
+
* `offlinePolicy: { policyPacks: [] }` is explicit no-banner mode.
|
|
172
|
+
* In hosted mode, backend `policyPacks` remain the source of truth — frontend offline policies never override a live backend decision.
|
|
173
|
+
|
|
174
|
+
Read the full guide at [Policy Packs](/docs/frameworks/react/policy-packs) and the conceptual model at [Policy Packs Concept](/docs/frameworks/react/concepts/policy-packs).
|
|
175
|
+
|
|
176
|
+
## Props
|
|
177
|
+
|
|
178
|
+
|Property|Value|
|
|
179
|
+
|:--|:--|
|
|
180
|
+
|Type Name|\`ConsentManagerProviderProps\`|
|
|
181
|
+
|Source Path|\`./packages/react/src/types/consent-manager.ts\`|
|
|
182
|
+
|
|
183
|
+
\*ExtractedTypeTable: Could not extract "ConsentManagerProviderProps" from "./packages/react/src/types/consent-manager.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Consent Widget
|
|
3
|
+
description: Reference page for consent widget.
|
|
4
|
+
group: reference
|
|
5
|
+
---
|
|
6
|
+
`ConsentWidget` is a standalone, inline consent management widget. Unlike `ConsentDialog` (which is a modal), the widget embeds directly in your page layout - ideal for privacy settings pages, account preferences, or any page where users should be able to manage consent without a modal overlay.
|
|
7
|
+
|
|
8
|
+
## Configuration
|
|
9
|
+
|
|
10
|
+
```tsx
|
|
11
|
+
<ConsentWidget
|
|
12
|
+
hideBranding
|
|
13
|
+
legalLinks={['privacyPolicy', 'cookiePolicy']}
|
|
14
|
+
noStyle={false}
|
|
15
|
+
disableAnimation={false}
|
|
16
|
+
/>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Accordion Behavior
|
|
20
|
+
|
|
21
|
+
Each consent category is rendered as an expandable accordion item. Clicking the category header expands it to show a description and any associated services. Users can toggle individual categories on or off using the switch control. The `necessary` category is always enabled and cannot be toggled.
|
|
22
|
+
|
|
23
|
+
## Styling First
|
|
24
|
+
|
|
25
|
+
> ℹ️ **Info:**
|
|
26
|
+
> Most widget customization should stay in the stock component. Use theme tokens and slots such as consentWidgetAccordion, consentWidgetFooter, consentWidgetFooterSubGroup, and toggle before reaching for compound components. See Styling Overview.
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
<ConsentManagerProvider
|
|
30
|
+
options={{
|
|
31
|
+
theme: {
|
|
32
|
+
colors: {
|
|
33
|
+
surface: '#fffdf8',
|
|
34
|
+
surfaceHover: '#f6f3ee',
|
|
35
|
+
},
|
|
36
|
+
slots: {
|
|
37
|
+
consentWidgetAccordion: 'rounded-3xl border border-black/10',
|
|
38
|
+
consentWidgetFooter: 'border-t border-black/10 px-6',
|
|
39
|
+
consentWidgetFooterSubGroup: 'gap-3',
|
|
40
|
+
toggle: 'shadow-sm',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
}}
|
|
44
|
+
>
|
|
45
|
+
<ConsentWidget />
|
|
46
|
+
</ConsentManagerProvider>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Use `consentWidgetFooter` for styling the whole action area, such as border and padding. Use `consentWidgetFooterSubGroup` for spacing or alignment inside nested button groups.
|
|
50
|
+
|
|
51
|
+
Widget copy should be changed through `ConsentManagerProvider.options.i18n` so the inline UI stays aligned with the rest of the consent experience.
|
|
52
|
+
|
|
53
|
+
## Advanced: Compound Components
|
|
54
|
+
|
|
55
|
+
Use compound components only when you need to rearrange the widget's existing primitives while keeping policy-aware action grouping:
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
<ConsentWidget.Root>
|
|
59
|
+
<ConsentWidget.Accordion type="multiple">
|
|
60
|
+
<ConsentWidget.AccordionItems />
|
|
61
|
+
</ConsentWidget.Accordion>
|
|
62
|
+
<ConsentWidget.PolicyActions />
|
|
63
|
+
</ConsentWidget.Root>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
* `ConsentWidget.Root` — Theme context provider
|
|
67
|
+
* `ConsentWidget.Accordion` — Radix-based accordion root
|
|
68
|
+
* `ConsentWidget.AccordionItems` — Auto-generates toggle items from consent config
|
|
69
|
+
* `ConsentWidget.AccordionItem` — Individual category item
|
|
70
|
+
* `ConsentWidget.AccordionTrigger` — Clickable header for each item
|
|
71
|
+
* `ConsentWidget.AccordionContent` — Collapsible content area
|
|
72
|
+
* `ConsentWidget.AccordionArrow` — Expand/collapse indicator
|
|
73
|
+
* `ConsentWidget.Switch` — Category toggle switch
|
|
74
|
+
* `ConsentWidget.PolicyActions` — Renders grouped policy-aware actions
|
|
75
|
+
* `ConsentWidget.Footer` — Footer container
|
|
76
|
+
* `ConsentWidget.FooterSubGroup` — Groups related buttons
|
|
77
|
+
* `ConsentWidget.AcceptAllButton` — Accepts all consent
|
|
78
|
+
* `ConsentWidget.RejectButton` — Rejects all consent
|
|
79
|
+
* `ConsentWidget.SaveButton` — Saves custom selections
|
|
80
|
+
|
|
81
|
+
## Using `renderAction` with c15t Defaults
|
|
82
|
+
|
|
83
|
+
`ConsentWidget.PolicyActions` renders stock c15t buttons and translations by default.
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
<ConsentWidget.PolicyActions />
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`renderAction` is optional. Return the stock button compounds when you want custom mapping while preserving built-in c15t behavior and copy:
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
<ConsentWidget.PolicyActions
|
|
93
|
+
renderAction={(action, props) => {
|
|
94
|
+
const { key, ...buttonProps } = props
|
|
95
|
+
|
|
96
|
+
switch (action) {
|
|
97
|
+
case 'accept':
|
|
98
|
+
return <ConsentWidget.AcceptAllButton key={key} {...buttonProps} />
|
|
99
|
+
case 'reject':
|
|
100
|
+
return <ConsentWidget.RejectButton key={key} {...buttonProps} />
|
|
101
|
+
case 'customize':
|
|
102
|
+
return <ConsentWidget.SaveButton key={key} {...buttonProps} />
|
|
103
|
+
}
|
|
104
|
+
}}
|
|
105
|
+
/>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`renderAction` is still meant for stock button compounds. If you want completely custom button elements and handlers, use `useHeadlessConsentUI()` and render `dialog.actionGroups` manually instead of `ConsentWidget.PolicyActions`.
|
|
109
|
+
|
|
110
|
+
For a fixed footer layout, render `ConsentWidget.Footer` and `ConsentWidget.FooterSubGroup` manually instead of using `ConsentWidget.PolicyActions`.
|
|
111
|
+
|
|
112
|
+
If the stock widget structure is already correct, stay with tokens and slots instead of rebuilding the layout.
|
|
113
|
+
|
|
114
|
+
## Props
|
|
115
|
+
|
|
116
|
+
|Property|Value|
|
|
117
|
+
|:--|:--|
|
|
118
|
+
|Type Name|\`ConsentWidgetProps\`|
|
|
119
|
+
|Source Path|\`./packages/react/src/components/consent-widget/types.ts\`|
|
|
120
|
+
|
|
121
|
+
\*ExtractedTypeTable: Could not extract "ConsentWidgetProps" from "./packages/react/src/components/consent-widget/types.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Dev Tools
|
|
3
|
+
description: Reference page for dev tools.
|
|
4
|
+
group: reference
|
|
5
|
+
---
|
|
6
|
+
`DevTools` is a floating panel that shows the internal state of the consent manager. Use it during development to inspect consent values, geolocation results, loaded scripts, and debug consent flows. Also exported as `C15TDevTools` if you need to avoid naming conflicts with other devtools.
|
|
7
|
+
|
|
8
|
+
> ⚠️ **Warning:**
|
|
9
|
+
> DevTools should only be included in development builds. The component renders nothing to the React tree - it injects directly into document.body.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
DevTools lives in a separate package to keep it out of production bundles:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bun add -D @c15t/dev-tools
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Configuration
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
<DevTools
|
|
23
|
+
position="bottom-right" // 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
|
|
24
|
+
defaultOpen={false} // Start with panel open
|
|
25
|
+
namespace="c15tStore" // Store namespace to connect to
|
|
26
|
+
disabled={false} // Disable without removing from tree
|
|
27
|
+
/>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Panels
|
|
31
|
+
|
|
32
|
+
|Panel|What it shows|
|
|
33
|
+
|--|--|
|
|
34
|
+
|**Consents**|Current consent state for all categories|
|
|
35
|
+
|**Location**|Detected jurisdiction, country, region, and consent model|
|
|
36
|
+
|**Scripts**|Configured scripts and their load status|
|
|
37
|
+
|**IAB**|IAB TCF state (when enabled) - TC string, vendor consents, purposes|
|
|
38
|
+
|**Events**|Timeline of consent events and state changes|
|
|
39
|
+
|**Actions**|Buttons to trigger consent actions (accept all, reject all, reset)|
|
|
40
|
+
|
|
41
|
+
## TanStack Devtools
|
|
42
|
+
|
|
43
|
+
`@c15t/dev-tools/tanstack` exposes a panel component and plugin factory that match TanStack Devtools' plugin API, so c15t can sit beside Query and Router without a custom mount adapter:
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
import * as React from 'react';
|
|
47
|
+
import { useRouter } from '@tanstack/react-router';
|
|
48
|
+
import { TanStackDevtools } from '@tanstack/react-devtools';
|
|
49
|
+
import { ReactQueryDevtoolsPanel } from '@tanstack/react-query-devtools';
|
|
50
|
+
import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools';
|
|
51
|
+
import { c15tDevtools } from '@c15t/dev-tools/tanstack';
|
|
52
|
+
|
|
53
|
+
export function AppDevtools() {
|
|
54
|
+
const router = useRouter();
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<TanStackDevtools
|
|
58
|
+
plugins={[
|
|
59
|
+
{
|
|
60
|
+
name: 'TanStack Query',
|
|
61
|
+
render: <ReactQueryDevtoolsPanel />,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'TanStack Router',
|
|
65
|
+
render: <TanStackRouterDevtoolsPanel router={router} />,
|
|
66
|
+
},
|
|
67
|
+
c15tDevtools(),
|
|
68
|
+
]}
|
|
69
|
+
/>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Props
|
|
75
|
+
|
|
76
|
+
|Property|Value|
|
|
77
|
+
|:--|:--|
|
|
78
|
+
|Type Name|\`C15TDevToolsProps\`|
|
|
79
|
+
|Source Path|\`./packages/dev-tools/src/react.ts\`|
|
|
80
|
+
|
|
81
|
+
\*ExtractedTypeTable: Could not extract "C15TDevToolsProps" from "./packages/dev-tools/src/react.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Frame
|
|
3
|
+
description: Reference page for frame.
|
|
4
|
+
group: reference
|
|
5
|
+
---
|
|
6
|
+
`Frame` conditionally renders its children based on consent state. When consent for the specified category is not granted, a placeholder is shown instead. Children are not mounted at all until consent is given, preventing any network requests or script execution.
|
|
7
|
+
|
|
8
|
+
## Custom Placeholder
|
|
9
|
+
|
|
10
|
+
Replace the default placeholder:
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
<Frame
|
|
14
|
+
category="experience"
|
|
15
|
+
placeholder={
|
|
16
|
+
<div className="rounded-lg border p-8 text-center">
|
|
17
|
+
<p>This content requires experience cookies.</p>
|
|
18
|
+
<p>Please enable them in your privacy settings.</p>
|
|
19
|
+
</div>
|
|
20
|
+
}
|
|
21
|
+
>
|
|
22
|
+
<InteractiveWidget />
|
|
23
|
+
</Frame>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Compound Components
|
|
27
|
+
|
|
28
|
+
Build fully custom placeholder layouts:
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
<Frame.Root category="marketing">
|
|
32
|
+
<Frame.Title category="marketing" />
|
|
33
|
+
<Frame.Button category="marketing" />
|
|
34
|
+
</Frame.Root>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
* `Frame.Root` - Container with default placeholder styling
|
|
38
|
+
* `Frame.Title` - Displays a consent-request message with the category name
|
|
39
|
+
* `Frame.Button` - Button that opens the consent dialog for the specified category
|
|
40
|
+
|
|
41
|
+
## Automatic Category Registration
|
|
42
|
+
|
|
43
|
+
When `Frame` mounts, it automatically adds its `category` to the active `consentCategories` list. This means you don't need to explicitly list the category in your provider's `consentCategories` option - if a `Frame` component uses it, it will be registered.
|
|
44
|
+
|
|
45
|
+
## Props
|
|
46
|
+
|
|
47
|
+
|Property|Value|
|
|
48
|
+
|:--|:--|
|
|
49
|
+
|Type Name|\`FrameProps\`|
|
|
50
|
+
|Source Path|\`./packages/react/src/components/frame/types.ts\`|
|
|
51
|
+
|
|
52
|
+
\*ExtractedTypeTable: Could not extract "FrameProps" from "./packages/react/src/components/frame/types.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Building Headless Components
|
|
3
|
+
description: Reference page for building headless components.
|
|
4
|
+
group: reference
|
|
5
|
+
---
|
|
6
|
+
Building custom consent UI is easier now because c15t exposes multiple layers of policy-aware primitives instead of forcing you to reconstruct banner rules by hand.
|
|
7
|
+
|
|
8
|
+
Think of customization as a ladder:
|
|
9
|
+
|
|
10
|
+
* stock component props for the shortest path
|
|
11
|
+
* `ConsentBanner.PolicyActions` and `ConsentWidget.PolicyActions` when you want custom structure but still want c15t to resolve policy-aware actions
|
|
12
|
+
* `useHeadlessConsentUI()` when you need fully manual action rendering, custom controls, or non-standard flow
|
|
13
|
+
|
|
14
|
+
> ⚠️ **Warning:**
|
|
15
|
+
> Headless is the last step in the customization ladder. Use this guide only when pre-built components, tokens, slots, compound components, and noStyle are no longer sufficient.
|
|
16
|
+
|
|
17
|
+
The headless stack underneath that is:
|
|
18
|
+
|
|
19
|
+
* `useHeadlessConsentUI()` for policy-aware banner/dialog actions, ordering, layout, and primary actions hints
|
|
20
|
+
* `@c15t/ui/utils` for the pure policy-action helpers that framework packages build on
|
|
21
|
+
* `useConsentManager()` for runtime state, categories, selected consent state, and policy metadata
|
|
22
|
+
* `useTranslations()` for the resolved copy
|
|
23
|
+
* `offlinePolicy.policyPacks` for offline previews that behave like backend policy resolution
|
|
24
|
+
|
|
25
|
+
The split is intentional: `@c15t/ui` owns pure policy-action resolution, while the framework hooks own visibility, consent mutations, and reactive state.
|
|
26
|
+
|
|
27
|
+
> ℹ️ **Info:**
|
|
28
|
+
> This guide is about building your own components while still respecting resolved policy-pack behavior. For the general headless overview, see Headless Mode.
|
|
29
|
+
|
|
30
|
+
## Choose the Smallest Layer That Solves the Job
|
|
31
|
+
|
|
32
|
+
Start with the smallest API surface that still gives you the behavior you need:
|
|
33
|
+
|
|
34
|
+
* Stay with stock components when you only need theming, spacing, copy, or legal-link changes
|
|
35
|
+
* Use `ConsentBanner.PolicyActions` or `ConsentWidget.PolicyActions` when you want a custom compound-component layout but still want grouped actions, ordering, and primary emphasis to come from policy
|
|
36
|
+
* Add `renderAction` when the grouping is still correct but you want to remap actions to stock c15t button compounds
|
|
37
|
+
* Reach for `useHeadlessConsentUI()` only when you need custom button elements, need to map `actionGroups` yourself, wire non-button controls, or coordinate the consent UI with a more custom state machine
|
|
38
|
+
|
|
39
|
+
This order matters because every step down the ladder gives you more control, but also makes it easier for your UI to drift away from the resolved policy if you stop using the provided state.
|
|
40
|
+
|
|
41
|
+
## Before You Build Headless UI
|
|
42
|
+
|
|
43
|
+
Do not use headless mode for problems that are still inside the stock component model:
|
|
44
|
+
|
|
45
|
+
* Use `layout`, `direction`, `primaryButton`, and `legalLinks` before you rebuild banner markup
|
|
46
|
+
* Use `theme.consentActions` before you swap out stock actions
|
|
47
|
+
* Use tokens such as `colors.surface` and `colors.surfaceHover` before raw CSS overrides
|
|
48
|
+
* Use slots such as `consentBannerCard`, `consentBannerFooter`, and `consentDialogCard` before compound components
|
|
49
|
+
* Use `ConsentManagerProvider.options.i18n` before rebuilding UI just to change text
|
|
50
|
+
|
|
51
|
+
A good rule: if the stock banner or dialog structure is still correct, you probably do not need headless mode.
|
|
52
|
+
|
|
53
|
+
## What the Headless Tooling Gives You
|
|
54
|
+
|
|
55
|
+
The main win is that your custom UI can stay aligned with policy packs without duplicating policy logic in your components.
|
|
56
|
+
|
|
57
|
+
`useHeadlessConsentUI()` already resolves:
|
|
58
|
+
|
|
59
|
+
* which actions are allowed
|
|
60
|
+
* the order those actions should render in
|
|
61
|
+
* grouped actions from policy `layout`
|
|
62
|
+
* layout `direction` (`row` or `column`)
|
|
63
|
+
* the primary actions
|
|
64
|
+
* UI profile and scroll-lock hints
|
|
65
|
+
* whether the banner or dialog should currently be visible
|
|
66
|
+
|
|
67
|
+
The hook also gives you the policy-aware action helpers you are expected to call:
|
|
68
|
+
|
|
69
|
+
* `performBannerAction('accept' | 'reject')`
|
|
70
|
+
* `performDialogAction('accept' | 'reject')`
|
|
71
|
+
* `saveCustomPreferences()` for the dialog `customize` action
|
|
72
|
+
* `openDialog()`, `openBanner()`, and `closeUI()` for surface visibility
|
|
73
|
+
|
|
74
|
+
That means your component mostly focuses on markup and design-system concerns instead of re-implementing policy interpretation.
|
|
75
|
+
|
|
76
|
+
For most compound-component layouts, start with `ConsentBanner.PolicyActions` or `ConsentWidget.PolicyActions`. They render stock c15t buttons and translations by default, and `renderAction` is only needed when you want to override which stock compound renders for each action. Reach for manual `actionGroups` mapping when you need action rendering that no longer fits the stock button compounds.
|
|
77
|
+
|
|
78
|
+
## What Headless Is Not For
|
|
79
|
+
|
|
80
|
+
Headless mode is not the recommended path for:
|
|
81
|
+
|
|
82
|
+
* changing the banner footer background
|
|
83
|
+
* rounding the stock banner card
|
|
84
|
+
* restyling stock banner or dialog buttons
|
|
85
|
+
* changing consent copy
|
|
86
|
+
|
|
87
|
+
Those should stay in the pre-built stack with tokens, slots, `theme.consentActions`, and provider `i18n`.
|
|
88
|
+
|
|
89
|
+
## What a Policy-Aware Headless Component Should Respect
|
|
90
|
+
|
|
91
|
+
When you build custom banner or dialog components, make sure they use:
|
|
92
|
+
|
|
93
|
+
* `activeUI` or `banner.isVisible` / `dialog.isVisible` for visibility
|
|
94
|
+
* `allowedActions`, `actionGroups`, and `primaryActions` instead of hard-coding buttons
|
|
95
|
+
* `primaryActions` for visual emphasis
|
|
96
|
+
* `consentCategories` when deciding which category toggles to render
|
|
97
|
+
* `policyDecision` when you want to debug why a specific UI state was chosen
|
|
98
|
+
|
|
99
|
+
If you ignore those values, your custom UI can drift away from the resolved policy pack even though the underlying consent engine is configured correctly.
|
|
100
|
+
|
|
101
|
+
## Validation and Testing
|
|
102
|
+
|
|
103
|
+
If you are building a reusable headless component library, validate your rendered UI against the resolved runtime policy in tests.
|
|
104
|
+
|
|
105
|
+
The core package exposes:
|
|
106
|
+
|
|
107
|
+
* `getEffectivePolicy(initData)` to read the resolved policy from `/init`
|
|
108
|
+
* `validateUIAgainstPolicy({ policy, state })` to detect mismatches such as wrong actions, layout, or mode
|
|
109
|
+
|
|
110
|
+
This is useful when your design system renders custom button arrangements and you want tests to catch policy drift early.
|