@c15t/react 3.0.0-alpha.1 → 3.0.0-alpha.10

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