@c15t/nextjs 2.2.0 → 3.0.0-alpha.0

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 (220) hide show
  1. package/AGENTS.md +102 -142
  2. package/README.md +4 -4
  3. package/dist/api.js +1 -0
  4. package/dist/config.js +1 -0
  5. package/dist/devtools.js +2 -0
  6. package/dist/headers.js +1 -0
  7. package/dist/iab/styles.css +1 -1
  8. package/dist/iab/styles.tw3.css +133 -19
  9. package/dist/index.js +1 -1
  10. package/dist/middleware.js +1 -0
  11. package/dist/node-bridge.js +1 -0
  12. package/dist/pages.js +1 -0
  13. package/dist/proxy.js +1 -0
  14. package/dist/root.js +2 -0
  15. package/dist/server.js +1 -0
  16. package/dist/static.js +1 -0
  17. package/dist/styles.css +1 -1
  18. package/dist/styles.tw3.css +173 -29
  19. package/dist/version.js +1 -1
  20. package/dist-types/api.d.ts +88 -0
  21. package/dist-types/config.d.ts +110 -0
  22. package/dist-types/devtools.d.ts +1 -0
  23. package/dist-types/headers.d.ts +4 -0
  24. package/dist-types/index.d.ts +28 -10
  25. package/dist-types/middleware.d.ts +15 -0
  26. package/dist-types/node-bridge.d.ts +57 -0
  27. package/dist-types/pages.d.ts +88 -0
  28. package/dist-types/proxy.d.ts +34 -0
  29. package/dist-types/root.d.ts +86 -0
  30. package/dist-types/server.d.ts +164 -0
  31. package/dist-types/static.d.ts +42 -0
  32. package/dist-types/types.d.ts +5 -36
  33. package/dist-types/version.d.ts +1 -1
  34. package/docs/README.md +102 -142
  35. package/docs/assets/v3/brand-bar.png +0 -0
  36. package/docs/assets/v3/brand-card.png +0 -0
  37. package/docs/assets/v3/choice-wall.png +0 -0
  38. package/docs/assets/v3/mobile-card.png +0 -0
  39. package/docs/assets/v3/preferences.png +0 -0
  40. package/docs/customization/overview.md +45 -0
  41. package/docs/customization/recipes.md +79 -0
  42. package/docs/customization/slots.md +55 -0
  43. package/docs/customization/tokens.md +76 -0
  44. package/docs/customization/translations.md +49 -0
  45. package/docs/frameworks/next/api-reference/data-fetching.md +416 -0
  46. package/docs/frameworks/next/app-router.md +403 -0
  47. package/docs/frameworks/next/client-side.md +118 -0
  48. package/docs/frameworks/next/components/consent-banner.md +251 -211
  49. package/docs/frameworks/next/components/consent-dialog-link.md +96 -35
  50. package/docs/frameworks/next/components/consent-dialog-trigger.md +74 -149
  51. package/docs/frameworks/next/components/consent-dialog.md +189 -134
  52. package/docs/frameworks/next/components/consent-manager-provider.md +60 -318
  53. package/docs/frameworks/next/components/consent-widget.md +172 -114
  54. package/docs/frameworks/next/components/dev-tools.md +199 -40
  55. package/docs/frameworks/next/components/frame.md +137 -42
  56. package/docs/frameworks/next/concepts/consent-categories.md +24 -89
  57. package/docs/frameworks/next/concepts/policy-presets.md +142 -0
  58. package/docs/frameworks/next/content-security-policy.md +189 -0
  59. package/docs/frameworks/next/data-fetching.md +74 -0
  60. package/docs/frameworks/next/geography-headers.md +251 -0
  61. package/docs/frameworks/next/headless.md +95 -185
  62. package/docs/frameworks/next/hooks/use-consent-manager/overview.md +42 -163
  63. package/docs/frameworks/next/iab/overview.md +37 -107
  64. package/docs/frameworks/next/optimization.md +158 -194
  65. package/docs/frameworks/next/pages-router.md +296 -0
  66. package/docs/frameworks/next/quickstart.md +31 -132
  67. package/docs/frameworks/next/script-loader.md +134 -467
  68. package/docs/frameworks/next/server-side.md +97 -130
  69. package/docs/frameworks/next/static-export.md +164 -0
  70. package/docs/frameworks/next/styling/overview.md +166 -250
  71. package/docs/frameworks/next/troubleshooting.md +134 -144
  72. package/docs/guides/consent-state.md +60 -0
  73. package/docs/guides/data-fetching.md +163 -0
  74. package/docs/guides/deployment-modes.md +63 -0
  75. package/docs/guides/troubleshooting.md +68 -0
  76. package/docs/guides/verify-consent.md +62 -0
  77. package/docs/integrations/adobe-analytics.md +239 -105
  78. package/docs/integrations/ahrefs-analytics.md +238 -104
  79. package/docs/integrations/amplitude.md +219 -157
  80. package/docs/integrations/building-integrations.md +32 -224
  81. package/docs/integrations/clearbit.md +247 -86
  82. package/docs/integrations/cloudflare-web-analytics.md +250 -84
  83. package/docs/integrations/crisp.md +251 -97
  84. package/docs/integrations/databuddy.md +259 -153
  85. package/docs/integrations/fathom-analytics.md +239 -96
  86. package/docs/integrations/google-maps.md +328 -207
  87. package/docs/integrations/google-tag-manager.md +248 -96
  88. package/docs/integrations/google-tag.md +261 -90
  89. package/docs/integrations/heap.md +222 -149
  90. package/docs/integrations/hightouch.md +225 -131
  91. package/docs/integrations/hotjar.md +239 -90
  92. package/docs/integrations/intercom.md +239 -98
  93. package/docs/integrations/linkedin-insights.md +243 -113
  94. package/docs/integrations/logrocket.md +241 -123
  95. package/docs/integrations/matomo-analytics.md +256 -111
  96. package/docs/integrations/meta-pixel.md +197 -324
  97. package/docs/integrations/microsoft-clarity.md +233 -114
  98. package/docs/integrations/microsoft-uet.md +245 -110
  99. package/docs/integrations/mixpanel-analytics.md +252 -87
  100. package/docs/integrations/openai-pixel.md +441 -0
  101. package/docs/integrations/overview.md +95 -133
  102. package/docs/integrations/pirsch.md +249 -96
  103. package/docs/integrations/plausible-analytics.md +241 -100
  104. package/docs/integrations/posthog.md +353 -214
  105. package/docs/integrations/promptwatch.md +251 -81
  106. package/docs/integrations/reddit-pixel.md +226 -173
  107. package/docs/integrations/rudderstack.md +244 -187
  108. package/docs/integrations/rybbit-analytics.md +244 -91
  109. package/docs/integrations/segment.md +238 -92
  110. package/docs/integrations/snapchat-pixel.md +240 -110
  111. package/docs/integrations/tiktok-pixel.md +249 -81
  112. package/docs/integrations/umami-analytics.md +242 -95
  113. package/docs/integrations/vercel-analytics.md +242 -90
  114. package/docs/integrations/x-pixel.md +238 -104
  115. package/docs/integrations/youtube.md +354 -142
  116. package/docs/upgrade-v3.md +334 -0
  117. package/iab/styles.css +1 -1
  118. package/iab/styles.tw3.css +1 -1
  119. package/package.json +106 -65
  120. package/readme.json +3 -3
  121. package/src/iab/styles.css +1 -1
  122. package/src/iab/styles.tw3.css +1 -1
  123. package/src/styles.css +1 -1
  124. package/src/styles.tw3.css +1 -1
  125. package/styles.css +1 -1
  126. package/styles.tw3.css +1 -1
  127. package/client/components/consent-dialog-link.js +0 -3
  128. package/client/components/integrations.js +0 -3
  129. package/dist/components/integrations/index.cjs +0 -1
  130. package/dist/components/integrations/index.js +0 -1
  131. package/dist/headless.cjs +0 -1
  132. package/dist/index.cjs +0 -1
  133. package/dist/libs/browser-initial-data.cjs +0 -1
  134. package/dist/libs/browser-initial-data.js +0 -1
  135. package/dist/libs/initial-data.cjs +0 -1
  136. package/dist/libs/initial-data.js +0 -1
  137. package/dist/types.cjs +0 -1
  138. package/dist/version.cjs +0 -1
  139. package/dist-types/components/integrations/index.d.ts +0 -1
  140. package/dist-types/libs/browser-initial-data.d.ts +0 -9
  141. package/dist-types/libs/initial-data.d.ts +0 -33
  142. package/docs/frameworks/next/building-headless-components.md +0 -379
  143. package/docs/frameworks/next/callbacks.md +0 -186
  144. package/docs/frameworks/next/concepts/client-modes.md +0 -177
  145. package/docs/frameworks/next/concepts/consent-models.md +0 -117
  146. package/docs/frameworks/next/concepts/cookie-management.md +0 -122
  147. package/docs/frameworks/next/concepts/glossary.md +0 -24
  148. package/docs/frameworks/next/concepts/initialization-flow.md +0 -149
  149. package/docs/frameworks/next/concepts/policy-packs.md +0 -230
  150. package/docs/frameworks/next/hooks/use-color-scheme.md +0 -41
  151. package/docs/frameworks/next/hooks/use-consent-manager/checking-consent.md +0 -96
  152. package/docs/frameworks/next/hooks/use-consent-manager/location-info.md +0 -97
  153. package/docs/frameworks/next/hooks/use-consent-manager/setting-consent.md +0 -94
  154. package/docs/frameworks/next/hooks/use-draggable.md +0 -59
  155. package/docs/frameworks/next/hooks/use-focus-trap.md +0 -42
  156. package/docs/frameworks/next/hooks/use-reduced-motion.md +0 -37
  157. package/docs/frameworks/next/hooks/use-ssr-status.md +0 -32
  158. package/docs/frameworks/next/hooks/use-text-direction.md +0 -50
  159. package/docs/frameworks/next/hooks/use-translations.md +0 -55
  160. package/docs/frameworks/next/iab/consent-banner.md +0 -91
  161. package/docs/frameworks/next/iab/consent-dialog.md +0 -129
  162. package/docs/frameworks/next/iab/use-gvl-data.md +0 -21
  163. package/docs/frameworks/next/iframe-blocking.md +0 -106
  164. package/docs/frameworks/next/internationalization.md +0 -207
  165. package/docs/frameworks/next/network-blocker.md +0 -140
  166. package/docs/frameworks/next/policy-packs.md +0 -248
  167. package/docs/frameworks/next/styling/classnames.md +0 -94
  168. package/docs/frameworks/next/styling/color-scheme.md +0 -84
  169. package/docs/frameworks/next/styling/css-variables.md +0 -53
  170. package/docs/frameworks/next/styling/slots.md +0 -94
  171. package/docs/frameworks/next/styling/tailwind.md +0 -137
  172. package/docs/frameworks/next/styling/tokens.md +0 -156
  173. package/docs/shared/concepts/client-modes.md +0 -103
  174. package/docs/shared/concepts/consent-categories.md +0 -41
  175. package/docs/shared/concepts/consent-models.md +0 -72
  176. package/docs/shared/concepts/cookie-management.md +0 -88
  177. package/docs/shared/concepts/glossary.md +0 -24
  178. package/docs/shared/concepts/initialization-flow.md +0 -105
  179. package/docs/shared/concepts/policy-packs.md +0 -225
  180. package/docs/shared/react/components/consent-banner.md +0 -242
  181. package/docs/shared/react/components/consent-dialog-link.md +0 -45
  182. package/docs/shared/react/components/consent-dialog-trigger.md +0 -185
  183. package/docs/shared/react/components/consent-dialog.md +0 -119
  184. package/docs/shared/react/components/consent-manager-provider.md +0 -225
  185. package/docs/shared/react/components/consent-widget.md +0 -121
  186. package/docs/shared/react/components/dev-tools.md +0 -81
  187. package/docs/shared/react/components/frame.md +0 -52
  188. package/docs/shared/react/guides/building-headless-components.md +0 -110
  189. package/docs/shared/react/guides/callbacks.md +0 -89
  190. package/docs/shared/react/guides/headless.md +0 -31
  191. package/docs/shared/react/guides/iframe-blocking.md +0 -65
  192. package/docs/shared/react/guides/internationalization.md +0 -123
  193. package/docs/shared/react/guides/network-blocker.md +0 -72
  194. package/docs/shared/react/guides/optimization.md +0 -44
  195. package/docs/shared/react/guides/policy-packs.md +0 -173
  196. package/docs/shared/react/guides/script-loader.md +0 -311
  197. package/docs/shared/react/hooks/use-color-scheme.md +0 -31
  198. package/docs/shared/react/hooks/use-consent-manager/checking-consent.md +0 -95
  199. package/docs/shared/react/hooks/use-consent-manager/location-info.md +0 -96
  200. package/docs/shared/react/hooks/use-consent-manager/overview.md +0 -74
  201. package/docs/shared/react/hooks/use-consent-manager/setting-consent.md +0 -93
  202. package/docs/shared/react/hooks/use-draggable.md +0 -30
  203. package/docs/shared/react/hooks/use-focus-trap.md +0 -20
  204. package/docs/shared/react/hooks/use-reduced-motion.md +0 -33
  205. package/docs/shared/react/hooks/use-ssr-status.md +0 -16
  206. package/docs/shared/react/hooks/use-text-direction.md +0 -38
  207. package/docs/shared/react/hooks/use-translations.md +0 -15
  208. package/docs/shared/react/iab/consent-banner.md +0 -60
  209. package/docs/shared/react/iab/consent-dialog.md +0 -76
  210. package/docs/shared/react/iab/overview.md +0 -80
  211. package/docs/shared/react/iab/use-gvl-data.md +0 -21
  212. package/docs/shared/react/styling/classnames.md +0 -93
  213. package/docs/shared/react/styling/color-scheme.md +0 -35
  214. package/docs/shared/react/styling/css-variables.md +0 -53
  215. package/docs/shared/react/styling/overview.md +0 -261
  216. package/docs/shared/react/styling/slots.md +0 -93
  217. package/docs/shared/react/styling/stylesheet-entrypoint.md +0 -8
  218. package/docs/shared/react/styling/tailwind.md +0 -88
  219. package/docs/shared/react/styling/tokens.md +0 -155
  220. package/docs/shared/troubleshooting.md +0 -82
@@ -1,299 +1,215 @@
1
1
  ---
2
- title: Styling Overview
3
- description: Five approaches for theming consent components — design tokens,
4
- component slots, CSS variables, className, and noStyle mode.
2
+ title: Styling
3
+ description: Import the Next.js stylesheet and theme c15t components with
4
+ tokens, slots, and class names through ConsentRoot options.
5
5
  group: frameworks
6
6
  ---
7
- c15t's theming system gives you multiple levels of control, but most customization should stay inside the pre-built components.
8
7
 
9
- Start with the lowest-power tool that solves the problem:
8
+ ## Stylesheet
10
9
 
11
- 1. **Pre-built component APIs** — provider options and component props such as `layout`, `direction`, `primaryButton`, `legalLinks`, and `theme.consentActions`
12
- 2. **Design tokens** — global colors, typography, spacing, radius, shadows, and motion
13
- 3. **Slots** — targeted styling for specific parts such as the banner card, footer, or title
14
- 4. **CSS variables or className-level overrides** — when you need to integrate with external CSS systems
15
- 5. **Compound components** — when you must rearrange markup while still using c15t primitives
16
- 6. **`noStyle`** — when you want c15t structure but you need to own all visual styling
17
- 7. **Headless** — when you want fully custom markup and behavior
10
+ Import c15t once from the global stylesheet loaded by `app/layout.tsx` in the
11
+ App Router or `pages/_app.tsx` in the Pages Router. With Tailwind CSS 4, place
12
+ it after the Tailwind import so the component layers keep their order:
18
13
 
19
- Keep styling and escalation as separate decisions:
20
-
21
- * If you are still using the stock banner, dialog, or widget, stay with props, tokens, and slots.
22
- * Escalate to compound components, `noStyle`, or headless only when the structure or behavior itself must change.
23
-
24
- ## Styling Approaches
25
-
26
- |Approach|Control|Use When|
27
- |--|--|--|
28
- |**Component and provider APIs**|High|Reordering actions, changing button emphasis, configuring links, hiding branding, changing copy via `i18n`|
29
- |**Tokens**|High|Changing global colors, typography, spacing, radius, shadows, or motion|
30
- |**Slots**|Medium|Targeting specific component parts (for example `consentBannerFooter` or `consentDialogCard`)|
31
- |**CSS variables / className**|Medium|Integrating with an existing stylesheet or utility classes after tokens and slots|
32
- |**Compound components**|Structure|Rearranging existing c15t primitives without going fully custom|
33
- |**noStyle**|Full visuals|Keeping c15t structure but replacing all visual defaults|
34
- |**Headless**|Full|Replacing both markup and behavior|
35
-
36
- ## Quick Start
37
-
38
- ```tsx
39
- import { type Theme, ConsentManagerProvider, ConsentBanner, ConsentDialog } from '@c15t/nextjs';
40
-
41
- const theme = {
42
- colors: {
43
- primary: '#6366f1',
44
- primaryHover: '#4f46e5',
45
- },
46
- radius: {
47
- md: '0.75rem',
48
- lg: '1rem',
49
- },
50
- slots: {
51
- consentBannerTitle: 'text-xl font-semibold',
52
- buttonPrimary: 'rounded-full',
53
- },
54
- } satisfies Theme;
55
-
56
- export function ConsentManager({ children }) {
57
- return (
58
- <ConsentManagerProvider
59
- options={{
60
- mode: 'hosted',
61
- backendURL: '/api/c15t',
62
- theme,
63
- }}
64
- >
65
- <ConsentBanner />
66
- <ConsentDialog />
67
- {children}
68
- </ConsentManagerProvider>
69
- );
70
- }
14
+ ```css
15
+ @import 'tailwindcss';
16
+ @import 'c15t/next/styles.css';
71
17
  ```
72
18
 
73
- ## Styling Inside Pre-Built Components
74
-
75
- Start here before you consider compound components or headless mode.
19
+ Without Tailwind, omit its import. Keep the existing global CSS import in the
20
+ layout or `_app.tsx`. Tailwind CSS 3 uses the separate build shown below.
76
21
 
77
- ### 1. Provider and component configuration
22
+ Every rule lives in `@layer components`, so unlayered utilities from Tailwind
23
+ v4 and atomic classes from StyleX override it without specificity tricks.
24
+ Tailwind v3 treats `@layer components` as its own directive, so import the
25
+ Tailwind 3 build from your Tailwind entry instead, between the `components`
26
+ and `utilities` directives:
78
27
 
79
- Use the stock APIs first:
80
-
81
- * `layout`, `direction`, and `primaryButton` for banner action arrangement
82
- * `legalLinks` for link visibility
83
- * `hideBranding` and `showTrigger` for dialog and widget behavior
84
- * `theme.consentActions` for stock banner and dialog button treatment
85
- * `i18n` on `ConsentManagerProvider` for copy changes
86
-
87
- ```tsx
88
- <ConsentBanner layout={['customize', ['reject', 'accept']]} primaryButton="accept" />
28
+ ```css
29
+ @tailwind base;
30
+ @tailwind components;
31
+ @import 'c15t/next/styles.tw3.css';
32
+ @tailwind utilities;
89
33
  ```
90
34
 
91
- ### 2. Design tokens
35
+ ## Tokens
92
36
 
93
- Set global values for colors, typography, spacing, radius, shadows, and motion:
37
+ The provider snippets below are partial configuration examples. Apply them in
38
+ your existing Client Component wrapper, keeping its transport, prefetch,
39
+ children and other options. `ConsentRoot` also accepts `theme` and
40
+ `components` through `options`.
94
41
 
95
- ```tsx
96
- options={{ theme: { colors: { primary: '#6366f1' } } }}
97
- ```
98
-
99
- Use tokens first when the change is semantic:
100
-
101
- * Banner card background -> `theme.colors.surface`
102
- * Banner footer background -> `theme.colors.surfaceHover`
103
- * Shared copy color -> `theme.colors.text` and `theme.colors.textMuted`
104
- * Primary-filled surfaces such as stock branding tags and filled actions -> `theme.colors.primary` with `theme.colors.textOnPrimary` as the matching foreground override
105
-
106
- ```tsx
107
- options={{
108
- theme: {
109
- colors: {
110
- surface: '#ffffff',
111
- surfaceHover: '#f6f3ee',
112
- },
113
- },
114
- }}
115
- ```
116
-
117
- If you set `theme.colors.primary` but omit `theme.colors.textOnPrimary`, c15t derives a readable foreground automatically. Add `textOnPrimary` only when you need to force a specific branded foreground color.
118
-
119
- ### 3. Component slots
120
-
121
- Target specific component parts via the `slots` object:
42
+ Colors, radii, shadows, typography, and motion come from `--c15t-*` custom
43
+ properties. Set them on the provider through `theme`, or override the
44
+ variables directly in your CSS.
122
45
 
123
46
  ```tsx
124
- options={{
125
- theme: {
126
- slots: {
127
- consentBannerCard: 'rounded-[28px] shadow-xl',
128
- consentBannerFooter: 'border-t border-black/10',
129
- consentBannerTitle: 'tracking-tight',
130
- },
131
- },
132
- }}
47
+ import { ConsentProvider, defineTheme } from 'c15t/next';
48
+
49
+ const theme = defineTheme({
50
+ colors: { primary: '#2f6f4e' },
51
+ radius: { lg: '4px' },
52
+ consentActions: {
53
+ primary: { variant: 'primary', mode: 'filled' },
54
+ dismiss: { variant: 'neutral', mode: 'stroke' },
55
+ },
56
+ });
57
+
58
+ <ConsentProvider options={{ mode, theme }} />;
133
59
  ```
134
60
 
135
- Use slots when the component part is right but the local styling needs adjustment.
136
-
137
- ### 4. CSS variables and className-level overrides
138
-
139
- Override `--c15t-*` custom properties in your stylesheet or attach classes through slots when your app styling is driven externally.
61
+ `consentActions` decides how each action role looks: `default` applies to
62
+ every button, `primary` to whichever actions the policy or your props mark
63
+ primary, and `accept`, `reject`, `customize`, and `dismiss` to one role each.
64
+ Per-action keys win over `primary`, which wins over `default`.
140
65
 
141
- Reach for this after tokens and slots, not before.
66
+ Banner sizing has its own variables. Override them in CSS when a variant
67
+ needs a different footprint:
142
68
 
143
- ```tsx
144
- options={{
145
- theme: {
146
- slots: {
147
- consentBannerFooter: 'bg-[var(--banner-footer)]',
148
- },
149
- },
150
- }}
151
- ```
69
+ | Variable | Default | Applies to |
70
+ | ----------------------------------- | ------- | ---------------- |
71
+ | `--consent-banner-max-width` | `440px` | `floating` cards |
72
+ | `--consent-banner-widget-max-width` | `20rem` | `widget` chips |
73
+ | `--consent-banner-wall-max-width` | `30rem` | `wall` cards |
152
74
 
153
- ## Escalating Beyond Pre-Built Components
75
+ ## Colors by consent model
154
76
 
155
- Only move up this ladder when the lower rung cannot satisfy the request.
77
+ The primary action can change while the brand color stays the same. Set
78
+ `consentActions.primary` once, then select `primaryButton` per policy as
79
+ shown in [ConsentBanner](../components/consent-banner.md#per-policy-buttons).
156
80
 
157
- ### 5. Compound components
81
+ To give opt-in and opt-out banners different colors, scope the tokens to
82
+ the root's attributes. Include hover and foreground colors when overriding
83
+ CSS tokens directly:
158
84
 
159
- Use compound components when you need to rearrange existing c15t primitives:
85
+ ```css
86
+ [data-prompt][data-model='opt-in'] {
87
+ --c15t-primary: #2f6f4e;
88
+ --c15t-primary-hover: #24563c;
89
+ --c15t-text-on-primary: #fff;
90
+ }
160
91
 
161
- ```tsx
162
- <ConsentBanner.Root>
163
- <ConsentBanner.Card>
164
- <ConsentBanner.Header>
165
- <ConsentBanner.Title />
166
- <ConsentBanner.Description />
167
- </ConsentBanner.Header>
168
- <ConsentBanner.Footer>
169
- <ConsentBanner.CustomizeButton />
170
- <ConsentBanner.FooterSubGroup>
171
- <ConsentBanner.RejectButton />
172
- <ConsentBanner.AcceptButton />
173
- </ConsentBanner.FooterSubGroup>
174
- </ConsentBanner.Footer>
175
- </ConsentBanner.Card>
176
- </ConsentBanner.Root>
92
+ [data-prompt][data-model='opt-out'] {
93
+ --c15t-primary: #6b3fa0;
94
+ --c15t-primary-hover: #55327f;
95
+ --c15t-text-on-primary: #fff;
96
+ }
177
97
  ```
178
98
 
179
- ### 6. `noStyle`
99
+ These colors apply to the action marked primary. Button layout and color
100
+ changes do not change the policy or expire a saved choice.
180
101
 
181
- Use `noStyle` only when the c15t structure is still correct but you want to replace all visual defaults:
102
+ ## Slots
182
103
 
183
- ```tsx
184
- <ConsentBanner noStyle />
185
- ```
104
+ Each component part is a slot. A slot accepts any attributes the element
105
+ takes, so the contract is the same whether you write class strings or pass an
106
+ object with `className` and `style`. Set slots on the provider under
107
+ `components`, keyed by component and part.
186
108
 
187
- ### 7. Headless
109
+ For a full-width notice, use the supported `bar` variant. In a Client Component
110
+ inside the existing boundary, replace the stock banner with:
188
111
 
189
- Go headless only when you are replacing both markup and behavior. For that path, continue to [Headless Mode](../headless).
112
+ ```tsx title="components/regional-banner.tsx"
113
+ 'use client';
190
114
 
191
- ## Common Styling Tasks
115
+ import { ConsentBanner, usePolicyRule } from 'c15t/next';
192
116
 
193
- ### Change the banner footer background
194
-
195
- ```tsx
196
- options={{
197
- theme: {
198
- colors: {
199
- surfaceHover: '#f6f3ee',
200
- },
201
- },
202
- }}
117
+ export function RegionalBanner() {
118
+ const policy = usePolicyRule();
119
+ return <ConsentBanner variant={policy?.prompt === 'notice' ? 'bar' : 'floating'} />;
120
+ }
203
121
  ```
204
122
 
205
- Use `theme.colors.surfaceHover` before trying raw CSS.
123
+ To remove the notice card's radius, add these values to the existing
124
+ `options.components.banner` slots. The root owns `data-prompt`, so the card
125
+ uses Tailwind's `group` selector to read it:
206
126
 
207
- ### Change the banner card background
208
-
209
- ```tsx
210
- options={{
211
- theme: {
212
- colors: {
213
- surface: '#fffdf8',
214
- },
127
+ ```ts
128
+ const bannerSlots = {
129
+ root: { className: 'group' },
130
+ card: { className: 'group-data-[prompt=notice]:rounded-none' },
131
+ rightLink: {
132
+ className: 'underline-offset-4 data-[right=opt-out]:text-red-700',
215
133
  },
216
- }}
217
- ```
134
+ };
218
135
 
219
- Use `theme.colors.surface` before overriding banner CSS variables directly.
220
-
221
- ### Tweak the banner card, footer, or title styling without changing markup
222
-
223
- ```tsx
224
- options={{
225
- theme: {
226
- slots: {
227
- consentBannerCard: 'rounded-[28px] shadow-xl',
228
- consentBannerFooter: 'border-t border-black/10 px-6',
229
- consentBannerTitle: 'text-xl tracking-tight',
230
- },
231
- },
232
- }}
136
+ // In the existing options.components object:
137
+ // banner: bannerSlots
233
138
  ```
234
139
 
235
- ### Change stock consent action button styles semantically
140
+ The root also carries `data-variant`, so you can restyle one shape without
141
+ touching the others. Tailwind, giving a `bar` a brand-colored top edge and
142
+ tighter text:
236
143
 
237
144
  ```tsx
238
- options={{
239
- theme: {
240
- consentActions: {
241
- default: { mode: 'stroke' },
242
- accept: { variant: 'primary', mode: 'stroke' },
243
- customize: { variant: 'neutral', mode: 'ghost' },
244
- },
245
- },
246
- }}
145
+ <ConsentProvider
146
+ options={{
147
+ mode,
148
+ presentation: { prompt: { variant: 'bar' } },
149
+ components: {
150
+ banner: {
151
+ root: { className: 'group' },
152
+ card: {
153
+ className:
154
+ 'group-data-[variant=bar]:border-t-4 group-data-[variant=bar]:border-t-emerald-600',
155
+ },
156
+ },
157
+ description: {
158
+ banner: { className: 'group-data-[variant=bar]:text-xs' },
159
+ },
160
+ },
161
+ }}
162
+ />
247
163
  ```
248
164
 
249
- Use `theme.consentActions` when you want to change the stock banner/dialog button treatment without rewriting the component layout. Policy packs still control action arrangement and primary-action hints. The theme controls whether those actions render as `stroke`, `filled`, `ghost`, or `lighter`.
250
-
251
- ### Change banner copy without replacing the component
252
-
253
- ```tsx
254
- options={{
255
- i18n: {
256
- locale: 'en',
257
- messages: {
258
- en: {
259
- cookieBanner: {
260
- title: 'We value your privacy',
261
- description: 'We use cookies to improve the site and measure performance.',
262
- },
263
- common: {
264
- acceptAll: 'Accept all',
265
- rejectAll: 'Reject all',
266
- customize: 'Manage preferences',
267
- },
268
- },
269
- },
270
- },
271
- }}
272
- ```
165
+ `data-variant` sits on the root, so child slots use Tailwind's `group`
166
+ prefix to read it.
273
167
 
274
- ### Enable dark mode safely
168
+ StyleX, spreading the result of `stylex.props()` into a slot:
275
169
 
276
170
  ```tsx
277
- options={{
278
- colorScheme: 'system',
279
- theme: {
280
- colors: { surface: '#ffffff', text: '#1f2937' },
281
- dark: { surface: '#111827', text: '#f9fafb' },
282
- },
283
- }}
171
+ import * as stylex from '@stylexjs/stylex';
172
+
173
+ const styles = stylex.create({
174
+ card: { borderRadius: 0, boxShadow: 'none' },
175
+ rightLink: { textUnderlineOffset: 4, color: 'rgb(185 28 28)' },
176
+ });
177
+
178
+ <ConsentProvider
179
+ options={{
180
+ mode,
181
+ components: {
182
+ banner: {
183
+ card: stylex.props(styles.card),
184
+ rightLink: stylex.props(styles.rightLink),
185
+ },
186
+ },
187
+ }}
188
+ />;
284
189
  ```
285
190
 
286
- > ℹ️ **Info:**
287
- > If a token change does not show up where you expect, check how that component maps tokens to CSS variables before escalating. For example, the stock banner footer background comes from colors.surfaceHover, not a separate footer token.
288
- >
289
- > ⚠️ **Warning:**
290
- > Do not jump to CSS overrides or !important because a token did not appear to work at first glance.noStyle: true removes layout and visual defaults. Treat it as an advanced opt-out, not a normal theming step.Headless mode is for replacing markup and behavior, not for styling-only requests.Use either tokens/slots or raw CSS variable overrides intentionally to avoid conflicting style sources.For dark mode, c15t supports .dark and .c15t-dark.
291
-
292
- ## API Reference
293
-
294
- |Property|Value|
295
- |:--|:--|
296
- |Type Name|\`Theme\`|
297
- |Source Path|\`./packages/ui/src/theme/types.ts\`|
298
-
299
- \*ExtractedTypeTable: Could not extract "Theme" 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.\*
191
+ Set `noStyle` on a component to drop the built-in classes from every part and
192
+ keep only what your slots pass. Set `noStyle` in the provider options to do it
193
+ for every component.
194
+
195
+ Banner slot keys under `components.banner`:
196
+
197
+ | Key | Element |
198
+ | ------------- | ----------------------------------------------------------------------------------------------------------------- |
199
+ | `root` | Fixed-position wrapper carrying `data-prompt`, `data-model`, `data-variant`, `data-position`, and `data-blocking` |
200
+ | `cardShell` | Sizes the card and holds the branding tag |
201
+ | `card` | The visible card, carrying `data-state` |
202
+ | `header` | Title and description container |
203
+ | `title` | Heading |
204
+ | `footer` | Action area |
205
+ | `actions` | Group of action groups |
206
+ | `actionGroup` | One group of equally prominent actions |
207
+ | `rights` | Group of right links, rendered before the actions |
208
+ | `rightLink` | One right link, carrying `data-action="right"` and `data-right` |
209
+ | `overlay` | Backdrop shown when the banner blocks the page |
210
+
211
+ Action buttons carry `data-action` and `data-variant`, and right links carry
212
+ `data-action="right"`, so a single rule such as `[data-action='dismiss']` or
213
+ `[data-action='right']` styles one role across every surface. Right links are
214
+ underlined text by default, so the only button on a notice is the primary
215
+ action.