@c15t/react 3.0.0-alpha.3 → 3.0.0-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/AGENTS.md +92 -72
  2. package/README.md +21 -17
  3. package/SKILL.md +34 -0
  4. package/dist/component-hooks/use-headless-consent-ui.js +1 -1
  5. package/dist/component-hooks/use-headless-iab-consent-ui.js +1 -1
  6. package/dist/components/consent-gate/atoms.js +1 -1
  7. package/dist/components/consent-gate/consent-gate.js +1 -1
  8. package/dist/components/iab-panel/atoms/card.js +1 -1
  9. package/dist/components/iab-panel/atoms/feature-item.js +2 -0
  10. package/dist/components/iab-panel/atoms/header.js +1 -1
  11. package/dist/components/iab-panel/iab-panel.js +1 -1
  12. package/dist/components/iab-panel/index.js +1 -1
  13. package/dist/components/iab-prompt/atoms/overlay.js +1 -1
  14. package/dist/components/iab-prompt/atoms/root.js +1 -1
  15. package/dist/components/panel/atoms/card.js +1 -1
  16. package/dist/components/panel/atoms/root.js +1 -1
  17. package/dist/components/panel-trigger/atoms/button.js +1 -1
  18. package/dist/components/panel-trigger/atoms/toolbar.js +1 -1
  19. package/dist/components/preferences/atoms/accordion.js +1 -1
  20. package/dist/components/prompt/atoms/overlay.js +1 -1
  21. package/dist/components/prompt/atoms/root.js +1 -1
  22. package/dist/components/prompt/components.js +1 -1
  23. package/dist/components/shared/libs/compose-refs.js +1 -0
  24. package/dist/components/shared/libs/slot.js +1 -1
  25. package/dist/components/shared/primitives/button.js +1 -1
  26. package/dist/components/shared/ui/dialog/dialog.js +1 -1
  27. package/dist/components/shared/ui/icon.js +1 -1
  28. package/dist/context/consent-tracking-context.js +1 -1
  29. package/dist/devtools.js +1 -1
  30. package/dist/draft-context.js +2 -0
  31. package/dist/draft.js +1 -1
  32. package/dist/external-iab-context.js +1 -1
  33. package/dist/gpp.js +2 -0
  34. package/dist/hooks/use-color-scheme.js +1 -1
  35. package/dist/hooks/use-focus-trap.js +1 -1
  36. package/dist/hooks.js +1 -1
  37. package/dist/iab/styles.tw3.css +4 -4
  38. package/dist/index-parts/consent-banner.js +1 -0
  39. package/dist/index-parts/consent-dialog-link.js +1 -0
  40. package/dist/index-parts/consent-dialog-trigger.js +1 -0
  41. package/dist/index-parts/consent-dialog.js +1 -0
  42. package/dist/index-parts/consent-gate.js +1 -0
  43. package/dist/index-parts/core.js +1 -0
  44. package/dist/index-parts/draft.js +1 -0
  45. package/dist/index-parts/hooks.js +1 -0
  46. package/dist/index-parts/module-hooks.js +1 -0
  47. package/dist/index-parts/provider.js +1 -0
  48. package/dist/index-parts/theme.js +1 -0
  49. package/dist/index-parts/translations.js +1 -0
  50. package/dist/index.js +1 -1
  51. package/dist/kernel-selector.js +1 -1
  52. package/dist/module-hooks/iframe-blocker.js +1 -1
  53. package/dist/postcss-tailwind3.js +1 -0
  54. package/dist/provider.js +1 -1
  55. package/dist/server/fetch-ssr-data.js +1 -1
  56. package/dist/server/headers.js +1 -1
  57. package/dist/server/normalize-url.js +1 -1
  58. package/dist/styles.tw3.css +16 -16
  59. package/dist/transports/offline.js +1 -1
  60. package/dist/utils/merge-slot-props.js +1 -1
  61. package/dist/utils/theme-utils.js +1 -1
  62. package/dist/version.js +1 -1
  63. package/dist-types/component-hooks/use-headless-consent-ui.d.ts +1 -1
  64. package/dist-types/components/iab-panel/atoms/feature-item.d.ts +28 -0
  65. package/dist-types/components/iab-panel/iab-panel.d.ts +2 -2
  66. package/dist-types/components/iab-panel/index.d.ts +5 -2
  67. package/dist-types/components/iab-panel/use-iab-translations.d.ts +4 -0
  68. package/dist-types/components/iab-prompt/iab-prompt.d.ts +2 -2
  69. package/dist-types/components/iab-prompt/index.d.ts +2 -2
  70. package/dist-types/components/panel/atoms/card.d.ts +1 -0
  71. package/dist-types/components/prompt/components.d.ts +6 -0
  72. package/dist-types/components/shared/libs/compose-refs.d.ts +20 -0
  73. package/dist-types/components/shared/ui/icon.d.ts +2 -1
  74. package/dist-types/context/consent-tracking-context.d.ts +10 -0
  75. package/dist-types/context/theme-context.d.ts +2 -2
  76. package/dist-types/context.d.ts +6 -0
  77. package/dist-types/devtools.d.ts +13 -2
  78. package/dist-types/draft-context.d.ts +31 -0
  79. package/dist-types/draft.d.ts +13 -30
  80. package/dist-types/gpp.d.ts +27 -0
  81. package/dist-types/hooks/use-focus-trap.d.ts +3 -1
  82. package/dist-types/hooks.d.ts +57 -13
  83. package/dist-types/iab.d.ts +1 -1
  84. package/dist-types/index-parts/consent-banner.d.ts +7 -0
  85. package/dist-types/index-parts/consent-dialog-link.d.ts +7 -0
  86. package/dist-types/index-parts/consent-dialog-trigger.d.ts +7 -0
  87. package/dist-types/index-parts/consent-dialog.d.ts +7 -0
  88. package/dist-types/index-parts/consent-gate.d.ts +7 -0
  89. package/dist-types/index-parts/core.d.ts +8 -0
  90. package/dist-types/index-parts/draft.d.ts +7 -0
  91. package/dist-types/index-parts/hooks.d.ts +7 -0
  92. package/dist-types/index-parts/module-hooks.d.ts +7 -0
  93. package/dist-types/index-parts/provider.d.ts +7 -0
  94. package/dist-types/index-parts/theme.d.ts +8 -0
  95. package/dist-types/index-parts/translations.d.ts +7 -0
  96. package/dist-types/index.d.ts +14 -15
  97. package/dist-types/kernel-selector.d.ts +0 -8
  98. package/dist-types/module-hooks/iframe-blocker.d.ts +12 -7
  99. package/dist-types/postcss-tailwind3.d.ts +21 -0
  100. package/dist-types/provider.d.ts +57 -17
  101. package/dist-types/server/headers.d.ts +14 -4
  102. package/dist-types/server/normalize-url.d.ts +14 -7
  103. package/dist-types/server/types.d.ts +12 -1
  104. package/dist-types/transports/offline.d.ts +7 -16
  105. package/dist-types/ui-config-context.d.ts +7 -1
  106. package/dist-types/utils/merge-slot-props.d.ts +15 -1
  107. package/dist-types/utils/theme-utils.d.ts +17 -2
  108. package/dist-types/version.d.ts +1 -1
  109. package/docs/README.md +92 -72
  110. package/docs/assets/v3/bottom-bar.png +0 -0
  111. package/docs/assets/v3/brand-card.png +0 -0
  112. package/docs/assets/v3/brand-preferences.png +0 -0
  113. package/docs/assets/v3/choice-wall.png +0 -0
  114. package/docs/assets/v3/headless-bar-html.png +0 -0
  115. package/docs/assets/v3/headless-bar-mobile.png +0 -0
  116. package/docs/assets/v3/headless-bar.png +0 -0
  117. package/docs/assets/v3/slim-bar.png +0 -0
  118. package/docs/concepts/choose-your-setup.md +87 -0
  119. package/docs/{frameworks/react/concepts → concepts}/consent-categories.md +22 -7
  120. package/docs/{guides → concepts}/consent-state.md +89 -105
  121. package/docs/{guides → concepts}/data-fetching.md +31 -27
  122. package/docs/concepts/how-consent-works.md +123 -0
  123. package/docs/{frameworks/react/concepts/policy-presets.md → concepts/policies.md} +7 -59
  124. package/docs/customization/class-names.md +202 -0
  125. package/docs/customization/dark-mode.md +157 -0
  126. package/docs/customization/motion.md +119 -0
  127. package/docs/customization/overview.md +67 -34
  128. package/docs/customization/recipes.md +839 -49
  129. package/docs/customization/slots.md +216 -35
  130. package/docs/customization/stylesheets.md +147 -0
  131. package/docs/customization/tailwind.md +842 -0
  132. package/docs/customization/tokens.md +163 -96
  133. package/docs/customization/translations.md +60 -3
  134. package/docs/frameworks/react/callbacks.md +118 -0
  135. package/docs/frameworks/react/clear-on-revocation.md +106 -0
  136. package/docs/frameworks/react/components/consent-banner.md +42 -28
  137. package/docs/frameworks/react/components/consent-dialog-link.md +13 -11
  138. package/docs/frameworks/react/components/consent-dialog-trigger.md +81 -76
  139. package/docs/frameworks/react/components/consent-dialog.md +56 -50
  140. package/docs/frameworks/react/components/consent-gate.md +37 -20
  141. package/docs/frameworks/react/components/consent-provider.md +130 -0
  142. package/docs/frameworks/react/components/consent-widget.md +23 -20
  143. package/docs/frameworks/react/components/dev-tools.md +53 -85
  144. package/docs/frameworks/react/components.md +105 -0
  145. package/docs/frameworks/react/compose.md +354 -0
  146. package/docs/frameworks/react/content-security-policy.md +126 -0
  147. package/docs/frameworks/react/customize.md +250 -0
  148. package/docs/frameworks/react/embeds.md +89 -0
  149. package/docs/frameworks/react/gpp.md +163 -0
  150. package/docs/frameworks/react/{hooks/overview.md → hooks.md} +21 -16
  151. package/docs/frameworks/react/{iab/overview.md → iab.md} +80 -31
  152. package/docs/frameworks/react/network-blocker.md +35 -41
  153. package/docs/frameworks/react/quickstart.md +139 -101
  154. package/docs/frameworks/react/rendering.md +128 -0
  155. package/docs/frameworks/react/scripts.md +115 -0
  156. package/docs/frameworks/react/translations.md +155 -0
  157. package/docs/frameworks/react/troubleshooting.md +92 -47
  158. package/docs/frameworks/react/vendor-consent.md +170 -0
  159. package/docs/guides/banner-experiments.md +654 -0
  160. package/docs/guides/troubleshooting.md +120 -47
  161. package/docs/guides/verify-consent.md +81 -49
  162. package/docs/integrations/adobe-analytics.md +167 -159
  163. package/docs/integrations/ahrefs-analytics.md +152 -154
  164. package/docs/integrations/amplitude.md +162 -156
  165. package/docs/integrations/building-integrations.md +136 -37
  166. package/docs/integrations/clearbit.md +154 -154
  167. package/docs/integrations/cloudflare-web-analytics.md +156 -156
  168. package/docs/integrations/cloudflare-zaraz.md +209 -261
  169. package/docs/integrations/crisp.md +164 -158
  170. package/docs/integrations/databuddy.md +157 -173
  171. package/docs/integrations/fathom-analytics.md +158 -156
  172. package/docs/integrations/front-chat.md +167 -167
  173. package/docs/integrations/google-maps.md +118 -83
  174. package/docs/integrations/google-tag-manager.md +178 -163
  175. package/docs/integrations/google-tag.md +163 -160
  176. package/docs/integrations/heap.md +163 -155
  177. package/docs/integrations/hightouch.md +161 -157
  178. package/docs/integrations/hotjar.md +159 -155
  179. package/docs/integrations/intercom.md +183 -153
  180. package/docs/integrations/klaviyo.md +486 -0
  181. package/docs/integrations/linkedin-insights.md +174 -150
  182. package/docs/integrations/logrocket.md +160 -156
  183. package/docs/integrations/matomo-analytics.md +188 -178
  184. package/docs/integrations/meta-pixel.md +188 -150
  185. package/docs/integrations/microsoft-clarity.md +163 -155
  186. package/docs/integrations/microsoft-uet.md +148 -154
  187. package/docs/integrations/mixpanel-analytics.md +155 -160
  188. package/docs/integrations/one-dollar-stats.md +166 -165
  189. package/docs/integrations/openai-pixel.md +204 -301
  190. package/docs/integrations/overview.md +137 -80
  191. package/docs/integrations/pinterest-tag.md +191 -183
  192. package/docs/integrations/pirsch.md +169 -159
  193. package/docs/integrations/plausible-analytics.md +172 -158
  194. package/docs/integrations/posthog.md +313 -240
  195. package/docs/integrations/promptwatch.md +154 -154
  196. package/docs/integrations/reddit-pixel.md +185 -157
  197. package/docs/integrations/rudderstack.md +201 -186
  198. package/docs/integrations/rybbit-analytics.md +171 -160
  199. package/docs/integrations/segment.md +182 -154
  200. package/docs/integrations/snapchat-pixel.md +186 -156
  201. package/docs/integrations/tiktok-pixel.md +171 -150
  202. package/docs/integrations/umami-analytics.md +163 -158
  203. package/docs/integrations/vercel-analytics.md +166 -157
  204. package/docs/integrations/x-pixel.md +176 -150
  205. package/docs/integrations/youtube.md +121 -86
  206. package/docs/upgrade-v3.md +496 -467
  207. package/package.json +20 -9
  208. package/dist/ui-save.js +0 -1
  209. package/dist-types/ui-save.d.ts +0 -25
  210. package/docs/assets/v3/brand-bar.png +0 -0
  211. package/docs/assets/v3/mobile-card.png +0 -0
  212. package/docs/assets/v3/preferences.png +0 -0
  213. package/docs/frameworks/react/components/consent-manager-provider.md +0 -95
  214. package/docs/frameworks/react/script-loader.md +0 -69
  215. package/docs/frameworks/react/styling/overview.md +0 -266
  216. package/docs/guides/deployment-modes.md +0 -75
  217. package/docs/guides/shared-consent-controls.md +0 -158
  218. package/docs/integrations/clear-on-revocation.md +0 -167
  219. package/docs/integrations/granular-consent.md +0 -210
@@ -0,0 +1,119 @@
1
+ ---
2
+ title: Motion and animation
3
+ description: Change how fast c15t's banner and dialog animate with duration and
4
+ easing tokens, turn animations off per surface with disableAnimation, and
5
+ check reduced-motion behavior in each framework.
6
+ group: customization
7
+ ---
8
+
9
+ ## Change the speed with motion tokens
10
+
11
+ c15t animates its surfaces with three durations and four easing curves. Set
12
+ them in the theme's `motion` object, or as CSS variables:
13
+
14
+ | CSS variable | Theme key | Default | Used by |
15
+ | ------------------------ | ------------------------ | -------------------------------------- | ----------------------------------------------- |
16
+ | `--c15t-duration-fast` | `motion.duration.fast` | `80ms` | Banner, buttons, tabs |
17
+ | `--c15t-duration-normal` | `motion.duration.normal` | `150ms` | Preference dialog, switches, accordions |
18
+ | `--c15t-duration-slow` | `motion.duration.slow` | `200ms` | Legal links, floating trigger |
19
+ | `--c15t-easing` | `motion.easing` | `cubic-bezier(0.4, 0, 0.2, 1)` | Banner fade, switches, accordions |
20
+ | `--c15t-easing-out` | `motion.easingOut` | `cubic-bezier(0.215, 0.61, 0.355, 1)` | Preference dialog, floating trigger hover |
21
+ | `--c15t-easing-in-out` | `motion.easingInOut` | `cubic-bezier(0.645, 0.045, 0.355, 1)` | Floating trigger snapping to a corner |
22
+ | `--c15t-easing-spring` | `motion.easingSpring` | `cubic-bezier(0.34, 1.56, 0.64, 1)` | The banner's slide in and the dialog's scale in |
23
+
24
+ This theme slows the dialog down and removes the banner's overshoot:
25
+
26
+ ```ts title="consent-theme.ts"
27
+ export const theme = {
28
+ motion: {
29
+ duration: { fast: '120ms', normal: '220ms' },
30
+ easingSpring: 'cubic-bezier(0.215, 0.61, 0.355, 1)',
31
+ },
32
+ };
33
+ ```
34
+
35
+ The theme goes where your framework's other tokens go. See
36
+ [theme tokens](./tokens.md) and your framework's customize page.
37
+ In Vue and Nuxt, set `tokens` with the variable name without the leading
38
+ `--`, such as `'c15t-duration-normal': '220ms'`.
39
+
40
+ ## Turn animations off
41
+
42
+ `disableAnimation` removes the enter and exit transitions of the banner and
43
+ dialogs, and the hover and snap transitions of the floating
44
+ `ConsentDialogTrigger`. Set it once for every surface, then override it for one
45
+ surface where your framework allows:
46
+
47
+ | Framework | For every surface | For one surface |
48
+ | ----------------------- | -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
49
+ | Next.js, TanStack Start | `options.disableAnimation` on `ConsentRoot` | `disableAnimation` prop on `ConsentBanner`, `ConsentDialog`, `IABConsentBanner`, `IABConsentDialog` |
50
+ | React | `disableAnimation` in the `ConsentProvider` options | The same component props |
51
+ | Nuxt | `disableAnimation` in the `c15t` module options | `disableAnimation` prop on `consent-banner.vue`, `consent-manager.vue` and the IAB banner and dialog, when you render them yourself |
52
+ | Vue | `disableAnimation` in the `c15tVue` options | The same component props |
53
+ | Astro | `disableAnimation` in the `c15t()` integration options | `disableAnimation` prop on `ConsentBanner`, `ConsentDialog`, `IABConsentBanner`, `IABConsentDialog` |
54
+ | Svelte, SvelteKit | `disableAnimation` on `ConsentManagerProvider` | `disableAnimation` prop on `ConsentBanner`, `ConsentDialog`, `IABConsentBanner`, `IABConsentDialog` |
55
+ | HTML | `data-disable-animation` on the script tag, or `ui.disableAnimation` in `config` | `ui.banner.disableAnimation`, `ui.dialog.disableAnimation` |
56
+ | JavaScript | `ui.disableAnimation` in `init()` | `ui.banner.disableAnimation`, `ui.dialog.disableAnimation` |
57
+
58
+ A value on one surface wins over the value for every surface.
59
+
60
+ Vue's `ConsentRoot` renders the banner and dialog without props, so in Vue and
61
+ Nuxt a per-surface value only applies when you render the surface components
62
+ yourself.
63
+
64
+ ## Follow the visitor's reduced motion setting
65
+
66
+ c15t's stylesheet stops the banner, dialog, floating trigger, switches, tabs
67
+ and accordions from animating while the visitor asks for reduced motion. The
68
+ rules sit in a `prefers-reduced-motion: reduce` media query, so they apply in
69
+ every framework and follow the setting as it changes, with no option to set.
70
+
71
+ `disableAnimation: false` does not bring the animations back for these
72
+ visitors, because the stylesheet rule applies whatever the option says.
73
+
74
+ ## Animate your own rules on dialog state
75
+
76
+ The preference dialog marks its open state with `data-state`, `open` or
77
+ `closed`, so a rule can animate your own additions to it. Which element
78
+ carries the attribute depends on the framework:
79
+
80
+ | Framework | Elements with `data-state` |
81
+ | ------------------------------ | --------------------------------------------------------------------------------------------------- |
82
+ | HTML, JavaScript | Dialog overlay, positioner and content |
83
+ | Svelte, SvelteKit | Dialog backdrop, positioner and content |
84
+ | Vue, Nuxt | Dialog content and overlay. The dialog unmounts when it closes, so you only see `open` |
85
+ | React, Next.js, TanStack Start | Not on `ConsentDialog`. The `Dialog` primitive's trigger, overlay, content and close parts carry it |
86
+
87
+ Banners do not carry `data-state`. Read `data-prompt`, `data-variant` and the
88
+ other attributes in [component parts](./slots.md) instead.
89
+
90
+ ## Stop transitions while you switch themes
91
+
92
+ Every c15t stylesheet has a `c15t-no-transitions` class that sets
93
+ `transition` and `animation` to `none` on an element and its children. Add it
94
+ to `<html>` while your app swaps themes, so colors change in one frame. Force
95
+ a style and layout pass before you remove it. Otherwise the browser computes
96
+ the new theme only after the class is gone, and the change animates:
97
+
98
+ ```ts
99
+ const root = document.documentElement;
100
+ root.classList.add('c15t-no-transitions');
101
+ applyYourTheme();
102
+ // Reading layout applies the new theme while transitions are off.
103
+ root.getBoundingClientRect();
104
+ root.classList.remove('c15t-no-transitions');
105
+ ```
106
+
107
+ This assumes `applyYourTheme` changes classes or custom properties
108
+ synchronously. If your framework applies the theme in a later render, run the
109
+ last two lines after that render commits.
110
+
111
+ ## Check the result
112
+
113
+ 1. In DevTools, open the Rendering panel and emulate
114
+ `prefers-reduced-motion: reduce`. Reload with site data cleared.
115
+ 2. The banner appears without sliding in.
116
+ 3. Open the preference dialog and toggle a switch. The switch changes without
117
+ animating.
118
+ 4. Turn the emulation off, set a slower `motion.duration.normal`, and open the
119
+ dialog again. It fades in at the new speed.
@@ -1,46 +1,79 @@
1
1
  ---
2
- title: Customize your consent interface
3
- description: Choose presentation, theme tokens, slots or custom markup for the
4
- change you need.
2
+ title: Customize the interface
3
+ description: Change c15t's consent banner and dialog one step at a time, from a
4
+ prop to your own markup, and find where each step lives in your framework.
5
5
  group: customization
6
6
  ---
7
7
 
8
- ## Start with the change you want
8
+ ## Climb the ladder one step at a time
9
9
 
10
- | Change | Use | Why |
11
- | ----------------------------------------- | ----------------------------------- | ------------------------------------------------------------ |
12
- | Banner shape or location | Presentation or banner props | Keeps policy actions and built-in layout behavior |
13
- | Brand colors, radius, typography, spacing | Theme tokens | Changes related component parts together |
14
- | One card, footer, title or button group | Component slots | Targets existing markup |
15
- | Labels, descriptions or language | i18n configuration | Keeps banner and preferences copy consistent |
16
- | A different component structure | Compound components where available | Retains the component behavior while changing markup |
17
- | Your own interaction and markup | Headless APIs | You own rendering, focus behavior and policy action coverage |
10
+ Each step keeps everything the step below it gives you. Stop at the first one
11
+ that makes the change you need:
18
12
 
19
- Most brand changes need tokens and a few slots. Start there before opting out
20
- of the stock styles. The [recipes](./recipes.md) show how each
21
- choice affects a real banner.
13
+ 1. **Props and presentation.** Pick a shape, a position, button order or
14
+ blocking. c15t keeps its markup, styles and behavior.
15
+ 2. **Theme tokens.** Change colors, type, radius, spacing, shadows and motion
16
+ everywhere at once. Dark mode is a second set of tokens.
17
+ 3. **Parts and classes.** Add a class or inline style to one part of one
18
+ component, such as the banner card. Tailwind, CSS Modules and CSS-in-JS
19
+ classes go here.
20
+ 4. **Compose.** Rebuild a component from c15t's parts, in your own layout, while
21
+ c15t still renders the actions the policy requires.
22
+ 5. **Headless.** Render your own markup from c15t's state and actions. You own
23
+ the layout, focus handling and labels.
22
24
 
23
- ## Keep behavior and appearance separate
25
+ Most brand work needs tokens and a few part classes. See
26
+ [banner designs](./recipes.md) for five banners built at
27
+ different steps, with screenshots and tested code.
28
+
29
+ ## Where each step lives in your framework
30
+
31
+ | Framework | Props and presentation | Tokens | Parts and classes | Compose | Headless |
32
+ | -------------- | --------------------------------------------- | ----------------------------------------- | ----------------------------------------- | ------------------------------------------------------------------------------ | -------------------------------------------------------------------- |
33
+ | Next.js | `ConsentBanner` props, `options.presentation` | `ConsentTheme` in a Server Component | `options.components`, `className` | [Compose](https://c15t.com/docs/frameworks/next/compose) | [Headless](https://c15t.com/docs/frameworks/next/headless) |
34
+ | TanStack Start | `ConsentBanner` props, `options.presentation` | `ConsentTheme` in the root route | `options.components`, `className` | [Compose](https://c15t.com/docs/frameworks/tanstack-start/compose) | [Headless](https://c15t.com/docs/frameworks/tanstack-start/headless) |
35
+ | React | `ConsentBanner` props, `presentation` | `ConsentTheme`, or CSS variables | `components`, `className` | [Compose](../frameworks/react/compose.md) | [Headless](../frameworks/react/headless.md) |
36
+ | Nuxt | `presentation` in `nuxt.config.ts` | `tokens` or `theme` in the module options | `components`, `class` | None | [Headless](https://c15t.com/docs/frameworks/nuxt/headless) |
37
+ | Vue | `presentation` in the `c15tVue` options | `tokens` or `theme` in the plugin options | `components`, `class` | None | [Headless](https://c15t.com/docs/frameworks/vue/headless) |
38
+ | Astro | `presentation` in the integration options | `theme` in the integration options | `theme.slots`, `class` on `ConsentBanner` | None | None |
39
+ | Svelte | `ConsentBanner` props, `presentation` | CSS variables, or `generateThemeCSS()` | `theme.slots`, `class` on `ConsentBanner` | [Primitives](https://c15t.com/docs/frameworks/svelte/components/primitives) | [Headless](https://c15t.com/docs/frameworks/svelte/headless) |
40
+ | SvelteKit | `ConsentBanner` props, `presentation` | `generateThemeCSS()` in a server load | `theme.slots`, `class` on `ConsentBanner` | [Primitives](https://c15t.com/docs/frameworks/sveltekit/components/primitives) | [Headless](https://c15t.com/docs/frameworks/sveltekit/headless) |
41
+ | HTML | `presentation.prompt` in `config` | `ui.theme` | `ui.theme.slots`, `::part()`, `ui.css` | None | [Headless](https://c15t.com/docs/frameworks/html/headless) |
42
+ | JavaScript | `presentation.prompt` in `init()` | `ui.theme` | `ui.theme.slots`, `::part()`, `ui.css` | None | [Headless](https://c15t.com/docs/frameworks/javascript/headless) |
24
43
 
25
- Presentation controls the prompt's shape, position and blocking behavior.
26
- Policy controls which actions and rights are required. Changing colors or button
27
- order does not change a saved choice or policy scope.
44
+ Configuration shapes differ between frameworks. React's
45
+ `components.banner.card`, Vue's `components.banner.card` with `class`, and the
46
+ `consentBannerCard` key in `theme.slots` target the same part through
47
+ different APIs. Check your framework's customize page before you move a
48
+ configuration from one framework to another.
49
+
50
+ ## Keep behavior and appearance separate
28
51
 
29
- A choice wall always blocks. Notices never block and cannot become a wall merely
30
- because `variant: 'wall'` was requested. Preference dialogs remain centered;
31
- prompt positioning does not move them. Required actions omitted from a custom
32
- layout can be restored by the policy renderer.
52
+ Presentation controls the prompt's shape, position and blocking. The policy
53
+ controls which actions and rights the visitor gets. Changing colors or button
54
+ order does not change a saved choice or the policy's scope.
33
55
 
34
- ## Use the adapter's configuration shape
56
+ A choice wall always blocks. A notice never blocks and does not become a wall
57
+ because you asked for `variant: 'wall'`. The preference dialog stays centered,
58
+ whatever position the banner has. If a custom layout leaves out an action the
59
+ policy requires, c15t puts it back.
35
60
 
36
- React and Next.js accept provider `theme`, `presentation` and `components`
37
- options, and render theme tokens with `ConsentTheme` on the server. Vue and Nuxt expose their own shared configuration, including CSS
38
- `tokens` and component slots. Svelte accepts its provider options and theme
39
- slots; SvelteKit renders the token CSS from a server `load`. Astro serializes
40
- integration options, renders the theme tokens on the server and uses the
41
- selected adapter for dialogs. Do not move a configuration object between frameworks without checking
42
- the target types.
61
+ ## Read the rest of this section
43
62
 
44
- Read [tokens and CSS](./tokens.md),
45
- [slots](./slots.md) or
46
- [copy and translations](./translations.md) for the next step.
63
+ * [Banner designs](./recipes.md): five designs with tested code.
64
+ * [Theme tokens](./tokens.md): every `--c15t-*` variable and
65
+ its theme key.
66
+ * [Dark mode](./dark-mode.md): `colorScheme`, dark tokens and a
67
+ dark first paint.
68
+ * [Motion and animation](./motion.md): duration and easing
69
+ tokens, `disableAnimation` and reduced motion.
70
+ * [Stylesheets and CSS layers](./stylesheets.md): which file to
71
+ load, when the dialog's CSS loads, and how to run without c15t's styles.
72
+ * [Component parts](./slots.md): every part, its keys in each
73
+ framework, and the `data-*` attributes to select on.
74
+ * [Class names and CSS-in-JS](./class-names.md): CSS Modules,
75
+ vanilla-extract, StyleX and Emotion on c15t's parts.
76
+ * [Tailwind CSS](./tailwind.md): Tailwind 4 and 3 in every
77
+ framework.
78
+ * [Copy and translations](./translations.md): labels,
79
+ languages and right-to-left text.