@c15t/react 2.0.0-rc.4 → 2.0.0-rc.6

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 (527) hide show
  1. package/dist/components/consent-banner/atoms/overlay.cjs +1 -1
  2. package/dist/components/consent-banner/atoms/root.cjs +1 -1
  3. package/dist/components/consent-banner/atoms/root.js +1 -1
  4. package/dist/components/consent-banner/components.cjs +1 -1
  5. package/dist/components/consent-banner/components.js +1 -1
  6. package/dist/components/consent-banner/consent-banner.cjs +1 -1
  7. package/dist/components/consent-banner/consent-banner.js +1 -1
  8. package/dist/components/consent-banner/error-boundary.cjs +1 -1
  9. package/dist/components/consent-banner/index.cjs +1 -1
  10. package/dist/components/consent-banner/index.js +1 -1
  11. package/dist/components/consent-dialog/atoms/card.cjs +1 -1
  12. package/dist/components/consent-dialog/atoms/card.js +1 -1
  13. package/dist/components/consent-dialog/atoms/overlay.cjs +1 -1
  14. package/dist/components/consent-dialog/atoms/overlay.js +1 -1
  15. package/dist/components/consent-dialog/atoms/root.cjs +1 -1
  16. package/dist/components/consent-dialog/atoms/root.js +1 -1
  17. package/dist/components/consent-dialog/consent-dialog.cjs +1 -1
  18. package/dist/components/consent-dialog/consent-dialog.js +1 -1
  19. package/dist/components/consent-dialog/index.cjs +1 -1
  20. package/dist/components/consent-dialog/index.js +1 -1
  21. package/dist/components/consent-dialog-link/index.cjs +1 -1
  22. package/dist/components/consent-dialog-link/index.js +1 -1
  23. package/dist/components/consent-dialog-trigger/atoms/button.cjs +1 -1
  24. package/dist/components/consent-dialog-trigger/atoms/icon.cjs +1 -1
  25. package/dist/components/consent-dialog-trigger/atoms/icon.js +1 -1
  26. package/dist/components/consent-dialog-trigger/atoms/root.cjs +1 -1
  27. package/dist/components/consent-dialog-trigger/atoms/root.js +1 -1
  28. package/dist/components/consent-dialog-trigger/atoms/text.cjs +1 -1
  29. package/dist/components/consent-dialog-trigger/atoms/text.js +1 -1
  30. package/dist/components/consent-dialog-trigger/consent-dialog-trigger.cjs +1 -1
  31. package/dist/components/consent-dialog-trigger/consent-dialog-trigger.js +1 -1
  32. package/dist/components/consent-dialog-trigger/index.cjs +1 -1
  33. package/dist/components/consent-dialog-trigger/index.js +1 -1
  34. package/dist/components/consent-dialog-trigger/types.cjs +1 -1
  35. package/dist/components/consent-dialog-trigger/use-draggable.cjs +1 -1
  36. package/dist/components/consent-dialog-trigger/use-draggable.js +1 -1
  37. package/dist/components/consent-preferences-link/consent-preferences-link.cjs +1 -1
  38. package/dist/components/consent-preferences-link/index.cjs +1 -1
  39. package/dist/components/consent-preferences-link/index.js +1 -1
  40. package/dist/components/consent-widget/atoms/accordion.cjs +1 -1
  41. package/dist/components/consent-widget/atoms/accordion.js +1 -1
  42. package/dist/components/consent-widget/atoms/button.cjs +1 -1
  43. package/dist/components/consent-widget/atoms/button.js +1 -1
  44. package/dist/components/consent-widget/atoms/footer.cjs +1 -1
  45. package/dist/components/consent-widget/atoms/root.cjs +1 -1
  46. package/dist/components/consent-widget/consent-widget.cjs +1 -1
  47. package/dist/components/consent-widget/consent-widget.js +1 -1
  48. package/dist/components/consent-widget/index.cjs +1 -1
  49. package/dist/components/consent-widget/index.js +1 -1
  50. package/dist/components/consent-widget/types.cjs +1 -1
  51. package/dist/components/frame/atoms.cjs +1 -1
  52. package/dist/components/frame/frame.cjs +1 -1
  53. package/dist/components/frame/frame.js +1 -1
  54. package/dist/components/frame/index.cjs +1 -1
  55. package/dist/components/frame/index.js +1 -1
  56. package/dist/components/frame/types.cjs +1 -1
  57. package/dist/components/iab-consent-banner/atoms/button-group.cjs +1 -1
  58. package/dist/components/iab-consent-banner/atoms/card.cjs +1 -1
  59. package/dist/components/iab-consent-banner/atoms/description.cjs +1 -1
  60. package/dist/components/iab-consent-banner/atoms/footer.cjs +1 -1
  61. package/dist/components/iab-consent-banner/atoms/header.cjs +1 -1
  62. package/dist/components/iab-consent-banner/atoms/overlay.cjs +1 -1
  63. package/dist/components/iab-consent-banner/atoms/root.cjs +1 -1
  64. package/dist/components/iab-consent-banner/atoms/root.js +1 -1
  65. package/dist/components/iab-consent-banner/atoms/title.cjs +1 -1
  66. package/dist/components/iab-consent-banner/iab-consent-banner.cjs +1 -1
  67. package/dist/components/iab-consent-banner/iab-consent-banner.js +1 -1
  68. package/dist/components/iab-consent-banner/index.cjs +1 -1
  69. package/dist/components/iab-consent-banner/index.js +1 -1
  70. package/dist/components/iab-consent-dialog/atoms/card.cjs +1 -1
  71. package/dist/components/iab-consent-dialog/atoms/content.cjs +1 -1
  72. package/dist/components/iab-consent-dialog/atoms/footer.cjs +1 -1
  73. package/dist/components/iab-consent-dialog/atoms/footer.js +1 -1
  74. package/dist/components/iab-consent-dialog/atoms/header.cjs +1 -1
  75. package/dist/components/iab-consent-dialog/atoms/header.js +1 -1
  76. package/dist/components/iab-consent-dialog/atoms/overlay.cjs +1 -1
  77. package/dist/components/iab-consent-dialog/atoms/purpose-item.cjs +1 -1
  78. package/dist/components/iab-consent-dialog/atoms/purpose-item.js +1 -1
  79. package/dist/components/iab-consent-dialog/atoms/root.cjs +1 -1
  80. package/dist/components/iab-consent-dialog/atoms/root.js +1 -1
  81. package/dist/components/iab-consent-dialog/atoms/stack-item.cjs +1 -1
  82. package/dist/components/iab-consent-dialog/atoms/stack-item.js +1 -1
  83. package/dist/components/iab-consent-dialog/atoms/tabs.cjs +1 -1
  84. package/dist/components/iab-consent-dialog/atoms/tabs.js +1 -1
  85. package/dist/components/iab-consent-dialog/atoms/vendor-list.cjs +1 -1
  86. package/dist/components/iab-consent-dialog/atoms/vendor-list.js +1 -1
  87. package/dist/components/iab-consent-dialog/hooks/use-gvl-data.cjs +1 -1
  88. package/dist/components/iab-consent-dialog/iab-consent-dialog.cjs +1 -1
  89. package/dist/components/iab-consent-dialog/iab-consent-dialog.js +1 -1
  90. package/dist/components/iab-consent-dialog/index.cjs +1 -1
  91. package/dist/components/iab-consent-dialog/index.js +1 -1
  92. package/dist/components/iab-consent-dialog/types.cjs +1 -1
  93. package/dist/components/iab-consent-dialog/use-iab-translations.cjs +1 -1
  94. package/dist/components/shared/libs/policy-actions.cjs +1 -0
  95. package/dist/components/shared/libs/policy-actions.js +1 -0
  96. package/dist/components/shared/libs/polymorphic.cjs +1 -1
  97. package/dist/components/shared/libs/recursive-clone-children.cjs +1 -1
  98. package/dist/components/shared/libs/slot.cjs +1 -0
  99. package/dist/components/shared/libs/slot.js +1 -0
  100. package/dist/components/shared/libs/use-controllable-state.cjs +1 -0
  101. package/dist/components/shared/libs/use-controllable-state.js +1 -0
  102. package/dist/components/shared/primitives/box.cjs +1 -1
  103. package/dist/components/shared/primitives/box.js +1 -1
  104. package/dist/components/shared/primitives/button.cjs +1 -1
  105. package/dist/components/shared/primitives/button.js +1 -1
  106. package/dist/components/shared/primitives/button.types.cjs +1 -1
  107. package/dist/components/shared/primitives/legal-links/index.cjs +1 -1
  108. package/dist/components/shared/primitives/legal-links/index.js +1 -1
  109. package/dist/components/shared/ui/accordion/accordion.cjs +1 -1
  110. package/dist/components/shared/ui/accordion/accordion.js +1 -1
  111. package/dist/components/shared/ui/accordion/accordion.types.cjs +1 -1
  112. package/dist/components/shared/ui/accordion/index.cjs +1 -1
  113. package/dist/components/shared/ui/animated-collapse/animated-collapse.cjs +1 -1
  114. package/dist/components/shared/ui/animated-collapse/index.cjs +1 -1
  115. package/dist/components/shared/ui/animated-collapse/index.js +1 -1
  116. package/dist/components/shared/ui/button/button.cjs +1 -1
  117. package/dist/components/shared/ui/button/button.js +1 -1
  118. package/dist/components/shared/ui/button/button.types.cjs +1 -1
  119. package/dist/components/shared/ui/button/index.cjs +1 -1
  120. package/dist/components/shared/ui/collapsible/collapsible.cjs +1 -0
  121. package/dist/components/shared/ui/collapsible/collapsible.js +1 -0
  122. package/dist/components/shared/ui/collapsible/index.cjs +1 -0
  123. package/dist/components/shared/ui/collapsible/index.js +1 -0
  124. package/dist/components/shared/ui/dialog/dialog.cjs +1 -0
  125. package/dist/components/shared/ui/dialog/dialog.js +1 -0
  126. package/dist/components/shared/ui/dialog/index.cjs +1 -0
  127. package/dist/components/shared/ui/dialog/index.js +1 -0
  128. package/dist/components/shared/ui/icon.cjs +1 -1
  129. package/dist/components/shared/ui/logo.cjs +1 -1
  130. package/dist/components/shared/ui/preference-item/index.cjs +1 -0
  131. package/dist/components/shared/ui/preference-item/index.js +1 -0
  132. package/dist/components/shared/ui/preference-item/preference-item.cjs +1 -0
  133. package/dist/components/shared/ui/preference-item/preference-item.js +1 -0
  134. package/dist/components/shared/ui/switch/index.cjs +1 -1
  135. package/dist/components/shared/ui/switch/switch.cjs +1 -1
  136. package/dist/components/shared/ui/switch/switch.js +1 -1
  137. package/dist/components/shared/ui/switch/switch.types.cjs +1 -1
  138. package/dist/components/shared/ui/tabs/index.cjs +1 -0
  139. package/dist/components/shared/ui/tabs/index.js +1 -0
  140. package/dist/components/shared/ui/tabs/tabs.cjs +1 -0
  141. package/dist/components/shared/ui/tabs/tabs.js +1 -0
  142. package/dist/context/consent-manager-context.cjs +1 -1
  143. package/dist/context/consent-tracking-context.cjs +1 -1
  144. package/dist/context/theme-context.cjs +1 -1
  145. package/dist/headless.cjs +1 -1
  146. package/dist/headless.js +1 -1
  147. package/dist/hooks/index.cjs +1 -1
  148. package/dist/hooks/index.js +1 -1
  149. package/dist/hooks/use-color-scheme.cjs +1 -1
  150. package/dist/hooks/use-component-config.cjs +1 -1
  151. package/dist/hooks/use-consent-dialog-trigger.cjs +1 -0
  152. package/dist/hooks/use-consent-dialog-trigger.js +1 -0
  153. package/dist/hooks/use-consent-manager.cjs +1 -1
  154. package/dist/hooks/use-consent-manager.js +1 -1
  155. package/dist/hooks/use-focus-trap.cjs +1 -1
  156. package/dist/hooks/use-focus-trap.js +1 -1
  157. package/dist/hooks/use-headless-consent-ui.cjs +1 -0
  158. package/dist/hooks/use-headless-consent-ui.js +1 -0
  159. package/dist/hooks/use-headless-iab-consent-ui.cjs +1 -0
  160. package/dist/hooks/use-headless-iab-consent-ui.js +1 -0
  161. package/dist/hooks/use-reduced-motion.cjs +1 -1
  162. package/dist/hooks/use-reduced-motion.js +1 -1
  163. package/dist/hooks/use-scroll-lock.cjs +1 -1
  164. package/dist/hooks/use-scroll-lock.js +1 -1
  165. package/dist/hooks/use-ssr-status.cjs +1 -1
  166. package/dist/hooks/use-styles.cjs +1 -1
  167. package/dist/hooks/use-text-direction.cjs +1 -1
  168. package/dist/hooks/use-theme.cjs +1 -1
  169. package/dist/hooks/use-theme.js +1 -1
  170. package/dist/hooks/use-translations.cjs +1 -1
  171. package/dist/iab/styles.css +1 -0
  172. package/dist/iab.cjs +1 -0
  173. package/dist/iab.js +1 -0
  174. package/dist/index.cjs +1 -1
  175. package/dist/index.js +1 -1
  176. package/dist/primitives/accordion.cjs +1 -0
  177. package/dist/primitives/accordion.js +1 -0
  178. package/dist/primitives/button.cjs +1 -0
  179. package/dist/primitives/button.js +1 -0
  180. package/dist/primitives/collapsible.cjs +1 -0
  181. package/dist/primitives/collapsible.js +1 -0
  182. package/dist/primitives/dialog.cjs +1 -0
  183. package/dist/primitives/dialog.js +1 -0
  184. package/dist/primitives/preference-item.cjs +1 -0
  185. package/dist/primitives/preference-item.js +1 -0
  186. package/dist/primitives/switch.cjs +1 -0
  187. package/dist/primitives/switch.js +1 -0
  188. package/dist/primitives/tabs.cjs +1 -0
  189. package/dist/primitives/tabs.js +1 -0
  190. package/dist/primitives.cjs +1 -0
  191. package/dist/primitives.js +1 -0
  192. package/dist/providers/consent-manager-provider.cjs +1 -1
  193. package/dist/providers/consent-manager-provider.js +1 -1
  194. package/dist/server/fetch-ssr-data.cjs +1 -1
  195. package/dist/server/fetch-ssr-data.js +1 -1
  196. package/dist/server/headers.cjs +1 -1
  197. package/dist/server/headers.js +1 -1
  198. package/dist/server/index.cjs +1 -1
  199. package/dist/server/index.js +1 -1
  200. package/dist/server/init-cache-key.cjs +1 -0
  201. package/dist/server/init-cache-key.js +1 -0
  202. package/dist/server/normalize-url.cjs +1 -1
  203. package/dist/server/types.cjs +1 -1
  204. package/dist/styles.css +1 -0
  205. package/dist/types/consent-manager.cjs +1 -1
  206. package/dist/types/theme/index.cjs +1 -1
  207. package/dist/types/theme/style-keys.cjs +1 -1
  208. package/dist/types/theme/style-types.cjs +1 -1
  209. package/dist/utils/cn.cjs +1 -1
  210. package/dist/utils/merge-styles.cjs +1 -1
  211. package/dist/utils/test-helpers.cjs +1 -1
  212. package/dist/utils/test-helpers.js +1 -1
  213. package/dist/utils/theme-utils.cjs +1 -1
  214. package/dist/version.cjs +1 -1
  215. package/dist/version.js +1 -1
  216. package/{dist → dist-types}/components/consent-banner/atoms/overlay.d.ts +1 -2
  217. package/{dist → dist-types}/components/consent-banner/atoms/root.d.ts +2 -3
  218. package/{dist → dist-types}/components/consent-banner/components.d.ts +1 -2
  219. package/{dist → dist-types}/components/consent-banner/consent-banner.d.ts +8 -7
  220. package/{dist → dist-types}/components/consent-banner/error-boundary.d.ts +0 -1
  221. package/{dist → dist-types}/components/consent-banner/index.d.ts +1 -2
  222. package/{dist → dist-types}/components/consent-dialog/atoms/card.d.ts +1 -2
  223. package/{dist → dist-types}/components/consent-dialog/atoms/overlay.d.ts +1 -2
  224. package/{dist → dist-types}/components/consent-dialog/atoms/root.d.ts +2 -3
  225. package/{dist → dist-types}/components/consent-dialog/consent-dialog.d.ts +1 -2
  226. package/{dist → dist-types}/components/consent-dialog/index.d.ts +1 -2
  227. package/{dist → dist-types}/components/consent-dialog-link/index.d.ts +0 -1
  228. package/{dist → dist-types}/components/consent-dialog-trigger/atoms/button.d.ts +0 -1
  229. package/{dist → dist-types}/components/consent-dialog-trigger/atoms/icon.d.ts +0 -1
  230. package/{dist → dist-types}/components/consent-dialog-trigger/atoms/root.d.ts +0 -1
  231. package/{dist → dist-types}/components/consent-dialog-trigger/atoms/text.d.ts +0 -1
  232. package/{dist → dist-types}/components/consent-dialog-trigger/consent-dialog-trigger.d.ts +2 -3
  233. package/{dist → dist-types}/components/consent-dialog-trigger/index.d.ts +0 -1
  234. package/{dist → dist-types}/components/consent-dialog-trigger/types.d.ts +1 -2
  235. package/{dist → dist-types}/components/consent-dialog-trigger/use-draggable.d.ts +1 -2
  236. package/{dist → dist-types}/components/consent-preferences-link/consent-preferences-link.d.ts +1 -1
  237. package/{dist → dist-types}/components/consent-preferences-link/index.d.ts +0 -1
  238. package/dist-types/components/consent-widget/atoms/accordion.d.ts +27 -0
  239. package/{dist → dist-types}/components/consent-widget/atoms/button.d.ts +1 -2
  240. package/{dist → dist-types}/components/consent-widget/atoms/footer.d.ts +0 -1
  241. package/{dist → dist-types}/components/consent-widget/atoms/root.d.ts +1 -2
  242. package/{dist → dist-types}/components/consent-widget/consent-widget.d.ts +0 -1
  243. package/{dist → dist-types}/components/consent-widget/index.d.ts +1 -2
  244. package/{dist → dist-types}/components/consent-widget/types.d.ts +0 -1
  245. package/{dist → dist-types}/components/frame/atoms.d.ts +2 -3
  246. package/{dist → dist-types}/components/frame/frame.d.ts +0 -1
  247. package/{dist → dist-types}/components/frame/index.d.ts +1 -2
  248. package/{dist → dist-types}/components/frame/types.d.ts +1 -2
  249. package/{dist → dist-types}/components/iab-consent-banner/atoms/button-group.d.ts +0 -1
  250. package/{dist → dist-types}/components/iab-consent-banner/atoms/card.d.ts +0 -1
  251. package/{dist → dist-types}/components/iab-consent-banner/atoms/description.d.ts +0 -1
  252. package/{dist → dist-types}/components/iab-consent-banner/atoms/footer.d.ts +0 -1
  253. package/{dist → dist-types}/components/iab-consent-banner/atoms/header.d.ts +0 -1
  254. package/{dist → dist-types}/components/iab-consent-banner/atoms/overlay.d.ts +0 -1
  255. package/{dist → dist-types}/components/iab-consent-banner/atoms/root.d.ts +1 -2
  256. package/{dist → dist-types}/components/iab-consent-banner/atoms/title.d.ts +0 -1
  257. package/{dist → dist-types}/components/iab-consent-banner/iab-consent-banner.d.ts +1 -2
  258. package/{dist → dist-types}/components/iab-consent-banner/index.d.ts +1 -2
  259. package/{dist → dist-types}/components/iab-consent-dialog/atoms/card.d.ts +0 -1
  260. package/{dist → dist-types}/components/iab-consent-dialog/atoms/content.d.ts +0 -1
  261. package/{dist → dist-types}/components/iab-consent-dialog/atoms/footer.d.ts +0 -1
  262. package/{dist → dist-types}/components/iab-consent-dialog/atoms/header.d.ts +0 -1
  263. package/{dist → dist-types}/components/iab-consent-dialog/atoms/overlay.d.ts +0 -1
  264. package/{dist → dist-types}/components/iab-consent-dialog/atoms/purpose-item.d.ts +0 -1
  265. package/{dist → dist-types}/components/iab-consent-dialog/atoms/root.d.ts +1 -2
  266. package/{dist → dist-types}/components/iab-consent-dialog/atoms/stack-item.d.ts +0 -1
  267. package/dist-types/components/iab-consent-dialog/atoms/tabs.d.ts +12 -0
  268. package/{dist → dist-types}/components/iab-consent-dialog/atoms/vendor-list.d.ts +1 -2
  269. package/{dist → dist-types}/components/iab-consent-dialog/hooks/use-gvl-data.d.ts +0 -1
  270. package/{dist → dist-types}/components/iab-consent-dialog/iab-consent-dialog.d.ts +1 -2
  271. package/{dist → dist-types}/components/iab-consent-dialog/index.d.ts +1 -2
  272. package/{dist → dist-types}/components/iab-consent-dialog/types.d.ts +0 -1
  273. package/{dist → dist-types}/components/iab-consent-dialog/use-iab-translations.d.ts +0 -1
  274. package/dist-types/components/shared/libs/policy-actions.d.ts +26 -0
  275. package/{dist → dist-types}/components/shared/libs/polymorphic.d.ts +0 -1
  276. package/{dist → dist-types}/components/shared/libs/recursive-clone-children.d.ts +0 -1
  277. package/dist-types/components/shared/libs/slot.d.ts +6 -0
  278. package/dist-types/components/shared/libs/use-controllable-state.d.ts +7 -0
  279. package/{dist → dist-types}/components/shared/primitives/box.d.ts +0 -1
  280. package/{dist → dist-types}/components/shared/primitives/button.d.ts +5 -2
  281. package/{dist → dist-types}/components/shared/primitives/button.types.d.ts +17 -1
  282. package/{dist → dist-types}/components/shared/primitives/legal-links/index.d.ts +1 -2
  283. package/dist-types/components/shared/ui/accordion/accordion.d.ts +74 -0
  284. package/{dist → dist-types}/components/shared/ui/accordion/accordion.types.d.ts +1 -2
  285. package/{dist → dist-types}/components/shared/ui/accordion/index.d.ts +0 -1
  286. package/{dist → dist-types}/components/shared/ui/animated-collapse/animated-collapse.d.ts +0 -1
  287. package/{dist → dist-types}/components/shared/ui/animated-collapse/index.d.ts +0 -1
  288. package/{dist → dist-types}/components/shared/ui/button/button.d.ts +2 -3
  289. package/{dist → dist-types}/components/shared/ui/button/button.types.d.ts +0 -1
  290. package/{dist → dist-types}/components/shared/ui/button/index.d.ts +0 -1
  291. package/dist-types/components/shared/ui/collapsible/collapsible.d.ts +20 -0
  292. package/dist-types/components/shared/ui/collapsible/index.d.ts +1 -0
  293. package/dist-types/components/shared/ui/dialog/dialog.d.ts +29 -0
  294. package/dist-types/components/shared/ui/dialog/index.d.ts +1 -0
  295. package/{dist → dist-types}/components/shared/ui/icon.d.ts +0 -1
  296. package/{dist → dist-types}/components/shared/ui/logo.d.ts +0 -1
  297. package/dist-types/components/shared/ui/preference-item/index.d.ts +1 -0
  298. package/dist-types/components/shared/ui/preference-item/preference-item.d.ts +33 -0
  299. package/{dist → dist-types}/components/shared/ui/switch/index.d.ts +0 -1
  300. package/dist-types/components/shared/ui/switch/switch.d.ts +20 -0
  301. package/{dist → dist-types}/components/shared/ui/switch/switch.types.d.ts +1 -2
  302. package/dist-types/components/shared/ui/tabs/index.d.ts +1 -0
  303. package/dist-types/components/shared/ui/tabs/tabs.d.ts +28 -0
  304. package/{dist → dist-types}/context/consent-manager-context.d.ts +1 -2
  305. package/{dist → dist-types}/context/consent-tracking-context.d.ts +0 -1
  306. package/{dist → dist-types}/context/theme-context.d.ts +0 -1
  307. package/dist-types/headless.d.ts +9 -0
  308. package/{dist → dist-types}/hooks/index.d.ts +3 -1
  309. package/{dist → dist-types}/hooks/use-color-scheme.d.ts +0 -1
  310. package/{dist → dist-types}/hooks/use-component-config.d.ts +1 -2
  311. package/dist-types/hooks/use-consent-dialog-trigger.d.ts +10 -0
  312. package/{dist → dist-types}/hooks/use-consent-manager.d.ts +1 -2
  313. package/{dist → dist-types}/hooks/use-focus-trap.d.ts +0 -1
  314. package/dist-types/hooks/use-headless-consent-ui.d.ts +46 -0
  315. package/dist-types/hooks/use-headless-iab-consent-ui.d.ts +41 -0
  316. package/{dist → dist-types}/hooks/use-reduced-motion.d.ts +0 -1
  317. package/{dist → dist-types}/hooks/use-scroll-lock.d.ts +0 -1
  318. package/{dist → dist-types}/hooks/use-ssr-status.d.ts +0 -1
  319. package/{dist → dist-types}/hooks/use-styles.d.ts +0 -1
  320. package/{dist → dist-types}/hooks/use-text-direction.d.ts +0 -1
  321. package/{dist → dist-types}/hooks/use-theme.d.ts +0 -1
  322. package/{dist → dist-types}/hooks/use-translations.d.ts +1 -2
  323. package/dist-types/iab.d.ts +24 -0
  324. package/{dist → dist-types}/index.d.ts +4 -5
  325. package/dist-types/primitives/accordion.d.ts +1 -0
  326. package/dist-types/primitives/button.d.ts +1 -0
  327. package/dist-types/primitives/collapsible.d.ts +1 -0
  328. package/dist-types/primitives/dialog.d.ts +1 -0
  329. package/dist-types/primitives/preference-item.d.ts +1 -0
  330. package/dist-types/primitives/switch.d.ts +1 -0
  331. package/dist-types/primitives/tabs.d.ts +1 -0
  332. package/dist-types/primitives.d.ts +7 -0
  333. package/{dist → dist-types}/providers/consent-manager-provider.d.ts +0 -1
  334. package/{dist → dist-types}/server/fetch-ssr-data.d.ts +1 -2
  335. package/{dist → dist-types}/server/headers.d.ts +2 -2
  336. package/{dist → dist-types}/server/index.d.ts +1 -1
  337. package/dist-types/server/init-cache-key.d.ts +21 -0
  338. package/{dist → dist-types}/server/normalize-url.d.ts +0 -1
  339. package/{dist → dist-types}/server/types.d.ts +1 -2
  340. package/{dist → dist-types}/types/consent-manager.d.ts +8 -2
  341. package/{dist → dist-types}/types/theme/index.d.ts +0 -1
  342. package/dist-types/types/theme/style-keys.d.ts +1 -0
  343. package/{dist → dist-types}/types/theme/style-types.d.ts +4 -3
  344. package/{dist → dist-types}/utils/cn.d.ts +1 -2
  345. package/{dist → dist-types}/utils/merge-styles.d.ts +0 -1
  346. package/{dist → dist-types}/utils/test-helpers.d.ts +0 -1
  347. package/{dist → dist-types}/utils/theme-utils.d.ts +1 -2
  348. package/dist-types/version.d.ts +1 -0
  349. package/docs/README.md +76 -0
  350. package/docs/building-headless-components.md +245 -0
  351. package/docs/callbacks.md +117 -0
  352. package/docs/components/consent-banner.md +174 -0
  353. package/docs/components/consent-dialog-link.md +59 -0
  354. package/docs/components/consent-dialog-trigger.md +103 -0
  355. package/docs/components/consent-dialog.md +137 -0
  356. package/docs/components/consent-manager-provider.md +423 -0
  357. package/docs/components/consent-widget.md +78 -0
  358. package/docs/components/dev-tools.md +63 -0
  359. package/docs/components/frame.md +73 -0
  360. package/docs/concepts/client-modes.md +163 -0
  361. package/docs/concepts/consent-categories.md +97 -0
  362. package/docs/concepts/consent-models.md +112 -0
  363. package/docs/concepts/cookie-management.md +122 -0
  364. package/docs/concepts/glossary.md +23 -0
  365. package/docs/concepts/initialization-flow.md +141 -0
  366. package/docs/concepts/policy-packs.md +227 -0
  367. package/docs/headless.md +184 -0
  368. package/docs/hooks/use-color-scheme.md +40 -0
  369. package/docs/hooks/use-consent-manager/checking-consent.md +94 -0
  370. package/docs/hooks/use-consent-manager/location-info.md +95 -0
  371. package/docs/hooks/use-consent-manager/overview.md +390 -0
  372. package/docs/hooks/use-consent-manager/setting-consent.md +92 -0
  373. package/docs/hooks/use-draggable.md +57 -0
  374. package/docs/hooks/use-focus-trap.md +41 -0
  375. package/docs/hooks/use-reduced-motion.md +35 -0
  376. package/docs/hooks/use-ssr-status.md +31 -0
  377. package/docs/hooks/use-text-direction.md +49 -0
  378. package/docs/hooks/use-translations.md +117 -0
  379. package/docs/iab/consent-banner.md +95 -0
  380. package/docs/iab/consent-dialog.md +135 -0
  381. package/docs/iab/overview.md +119 -0
  382. package/docs/iab/use-gvl-data.md +208 -0
  383. package/docs/iframe-blocking.md +107 -0
  384. package/docs/integrations/databuddy.md +186 -0
  385. package/docs/integrations/google-tag-manager.md +153 -0
  386. package/docs/integrations/google-tag.md +149 -0
  387. package/docs/integrations/linkedin-insights.md +109 -0
  388. package/docs/integrations/meta-pixel.md +342 -0
  389. package/docs/integrations/microsoft-uet.md +112 -0
  390. package/docs/integrations/overview.md +89 -0
  391. package/docs/integrations/posthog.md +177 -0
  392. package/docs/integrations/tiktok-pixel.md +113 -0
  393. package/docs/integrations/x-pixel.md +143 -0
  394. package/docs/internationalization.md +197 -0
  395. package/docs/network-blocker.md +178 -0
  396. package/docs/optimization.md +117 -0
  397. package/docs/policy-packs.md +240 -0
  398. package/docs/quickstart.md +146 -0
  399. package/docs/script-loader.md +300 -0
  400. package/docs/server-side.md +153 -0
  401. package/docs/styling/classnames.md +84 -0
  402. package/docs/styling/color-scheme.md +82 -0
  403. package/docs/styling/css-variables.md +92 -0
  404. package/docs/styling/overview.md +315 -0
  405. package/docs/styling/slots.md +93 -0
  406. package/docs/styling/tailwind.md +115 -0
  407. package/docs/styling/tokens.md +214 -0
  408. package/docs/troubleshooting.md +137 -0
  409. package/package.json +48 -36
  410. package/client/components/iab-consent-banner.js +0 -4
  411. package/client/components/iab-consent-dialog.js +0 -4
  412. package/dist/components/consent-banner/atoms/overlay.d.ts.map +0 -1
  413. package/dist/components/consent-banner/atoms/root.d.ts.map +0 -1
  414. package/dist/components/consent-banner/components.d.ts.map +0 -1
  415. package/dist/components/consent-banner/consent-banner.d.ts.map +0 -1
  416. package/dist/components/consent-banner/error-boundary.d.ts.map +0 -1
  417. package/dist/components/consent-banner/index.d.ts.map +0 -1
  418. package/dist/components/consent-dialog/atoms/card.d.ts.map +0 -1
  419. package/dist/components/consent-dialog/atoms/overlay.d.ts.map +0 -1
  420. package/dist/components/consent-dialog/atoms/root.d.ts.map +0 -1
  421. package/dist/components/consent-dialog/consent-dialog.d.ts.map +0 -1
  422. package/dist/components/consent-dialog/index.d.ts.map +0 -1
  423. package/dist/components/consent-dialog-link/index.d.ts.map +0 -1
  424. package/dist/components/consent-dialog-trigger/atoms/button.d.ts.map +0 -1
  425. package/dist/components/consent-dialog-trigger/atoms/icon.d.ts.map +0 -1
  426. package/dist/components/consent-dialog-trigger/atoms/root.d.ts.map +0 -1
  427. package/dist/components/consent-dialog-trigger/atoms/text.d.ts.map +0 -1
  428. package/dist/components/consent-dialog-trigger/consent-dialog-trigger.d.ts.map +0 -1
  429. package/dist/components/consent-dialog-trigger/index.d.ts.map +0 -1
  430. package/dist/components/consent-dialog-trigger/types.d.ts.map +0 -1
  431. package/dist/components/consent-dialog-trigger/use-draggable.d.ts.map +0 -1
  432. package/dist/components/consent-preferences-link/consent-preferences-link.d.ts.map +0 -1
  433. package/dist/components/consent-preferences-link/index.d.ts.map +0 -1
  434. package/dist/components/consent-widget/atoms/accordion.d.ts +0 -46
  435. package/dist/components/consent-widget/atoms/accordion.d.ts.map +0 -1
  436. package/dist/components/consent-widget/atoms/button.d.ts.map +0 -1
  437. package/dist/components/consent-widget/atoms/footer.d.ts.map +0 -1
  438. package/dist/components/consent-widget/atoms/root.d.ts.map +0 -1
  439. package/dist/components/consent-widget/consent-widget.d.ts.map +0 -1
  440. package/dist/components/consent-widget/index.d.ts.map +0 -1
  441. package/dist/components/consent-widget/types.d.ts.map +0 -1
  442. package/dist/components/frame/atoms.d.ts.map +0 -1
  443. package/dist/components/frame/frame.d.ts.map +0 -1
  444. package/dist/components/frame/index.d.ts.map +0 -1
  445. package/dist/components/frame/types.d.ts.map +0 -1
  446. package/dist/components/iab-consent-banner/atoms/button-group.d.ts.map +0 -1
  447. package/dist/components/iab-consent-banner/atoms/card.d.ts.map +0 -1
  448. package/dist/components/iab-consent-banner/atoms/description.d.ts.map +0 -1
  449. package/dist/components/iab-consent-banner/atoms/footer.d.ts.map +0 -1
  450. package/dist/components/iab-consent-banner/atoms/header.d.ts.map +0 -1
  451. package/dist/components/iab-consent-banner/atoms/overlay.d.ts.map +0 -1
  452. package/dist/components/iab-consent-banner/atoms/root.d.ts.map +0 -1
  453. package/dist/components/iab-consent-banner/atoms/title.d.ts.map +0 -1
  454. package/dist/components/iab-consent-banner/iab-consent-banner.d.ts.map +0 -1
  455. package/dist/components/iab-consent-banner/index.d.ts.map +0 -1
  456. package/dist/components/iab-consent-dialog/atoms/card.d.ts.map +0 -1
  457. package/dist/components/iab-consent-dialog/atoms/content.d.ts.map +0 -1
  458. package/dist/components/iab-consent-dialog/atoms/footer.d.ts.map +0 -1
  459. package/dist/components/iab-consent-dialog/atoms/header.d.ts.map +0 -1
  460. package/dist/components/iab-consent-dialog/atoms/overlay.d.ts.map +0 -1
  461. package/dist/components/iab-consent-dialog/atoms/purpose-item.d.ts.map +0 -1
  462. package/dist/components/iab-consent-dialog/atoms/root.d.ts.map +0 -1
  463. package/dist/components/iab-consent-dialog/atoms/stack-item.d.ts.map +0 -1
  464. package/dist/components/iab-consent-dialog/atoms/tabs.d.ts +0 -40
  465. package/dist/components/iab-consent-dialog/atoms/tabs.d.ts.map +0 -1
  466. package/dist/components/iab-consent-dialog/atoms/vendor-list.d.ts.map +0 -1
  467. package/dist/components/iab-consent-dialog/hooks/use-gvl-data.d.ts.map +0 -1
  468. package/dist/components/iab-consent-dialog/iab-consent-dialog.d.ts.map +0 -1
  469. package/dist/components/iab-consent-dialog/index.d.ts.map +0 -1
  470. package/dist/components/iab-consent-dialog/types.d.ts.map +0 -1
  471. package/dist/components/iab-consent-dialog/use-iab-translations.d.ts.map +0 -1
  472. package/dist/components/shared/libs/polymorphic.d.ts.map +0 -1
  473. package/dist/components/shared/libs/recursive-clone-children.d.ts.map +0 -1
  474. package/dist/components/shared/primitives/box.d.ts.map +0 -1
  475. package/dist/components/shared/primitives/button.d.ts.map +0 -1
  476. package/dist/components/shared/primitives/button.types.d.ts.map +0 -1
  477. package/dist/components/shared/primitives/legal-links/index.d.ts.map +0 -1
  478. package/dist/components/shared/ui/accordion/accordion.d.ts +0 -110
  479. package/dist/components/shared/ui/accordion/accordion.d.ts.map +0 -1
  480. package/dist/components/shared/ui/accordion/accordion.types.d.ts.map +0 -1
  481. package/dist/components/shared/ui/accordion/index.d.ts.map +0 -1
  482. package/dist/components/shared/ui/animated-collapse/animated-collapse.d.ts.map +0 -1
  483. package/dist/components/shared/ui/animated-collapse/index.d.ts.map +0 -1
  484. package/dist/components/shared/ui/button/button.d.ts.map +0 -1
  485. package/dist/components/shared/ui/button/button.types.d.ts.map +0 -1
  486. package/dist/components/shared/ui/button/index.d.ts.map +0 -1
  487. package/dist/components/shared/ui/icon.d.ts.map +0 -1
  488. package/dist/components/shared/ui/logo.d.ts.map +0 -1
  489. package/dist/components/shared/ui/switch/index.d.ts.map +0 -1
  490. package/dist/components/shared/ui/switch/switch.d.ts +0 -45
  491. package/dist/components/shared/ui/switch/switch.d.ts.map +0 -1
  492. package/dist/components/shared/ui/switch/switch.types.d.ts.map +0 -1
  493. package/dist/context/consent-manager-context.d.ts.map +0 -1
  494. package/dist/context/consent-tracking-context.d.ts.map +0 -1
  495. package/dist/context/theme-context.d.ts.map +0 -1
  496. package/dist/headless.d.ts +0 -8
  497. package/dist/headless.d.ts.map +0 -1
  498. package/dist/hooks/index.d.ts.map +0 -1
  499. package/dist/hooks/use-color-scheme.d.ts.map +0 -1
  500. package/dist/hooks/use-component-config.d.ts.map +0 -1
  501. package/dist/hooks/use-consent-manager.d.ts.map +0 -1
  502. package/dist/hooks/use-focus-trap.d.ts.map +0 -1
  503. package/dist/hooks/use-reduced-motion.d.ts.map +0 -1
  504. package/dist/hooks/use-scroll-lock.d.ts.map +0 -1
  505. package/dist/hooks/use-ssr-status.d.ts.map +0 -1
  506. package/dist/hooks/use-styles.d.ts.map +0 -1
  507. package/dist/hooks/use-text-direction.d.ts.map +0 -1
  508. package/dist/hooks/use-theme.d.ts.map +0 -1
  509. package/dist/hooks/use-translations.d.ts.map +0 -1
  510. package/dist/index.d.ts.map +0 -1
  511. package/dist/providers/consent-manager-provider.d.ts.map +0 -1
  512. package/dist/server/fetch-ssr-data.d.ts.map +0 -1
  513. package/dist/server/headers.d.ts.map +0 -1
  514. package/dist/server/index.d.ts.map +0 -1
  515. package/dist/server/normalize-url.d.ts.map +0 -1
  516. package/dist/server/types.d.ts.map +0 -1
  517. package/dist/types/consent-manager.d.ts.map +0 -1
  518. package/dist/types/theme/index.d.ts.map +0 -1
  519. package/dist/types/theme/style-keys.d.ts +0 -2
  520. package/dist/types/theme/style-keys.d.ts.map +0 -1
  521. package/dist/types/theme/style-types.d.ts.map +0 -1
  522. package/dist/utils/cn.d.ts.map +0 -1
  523. package/dist/utils/merge-styles.d.ts.map +0 -1
  524. package/dist/utils/test-helpers.d.ts.map +0 -1
  525. package/dist/utils/theme-utils.d.ts.map +0 -1
  526. package/dist/version.d.ts +0 -2
  527. package/dist/version.d.ts.map +0 -1
@@ -0,0 +1,141 @@
1
+ ---
2
+ title: Initialization Flow
3
+ description: What happens from provider mount to first render — the full consent lifecycle.
4
+ ---
5
+ When the consent provider mounts, it creates a cached consent runtime, reads any stored consent from the browser, fetches the resolved policy from the backend (or uses SSR/offline data), and decides whether to show the banner. This entire sequence completes before the first meaningful consent-aware render.
6
+
7
+ ## Lifecycle Sequence
8
+
9
+ **Simplified**
10
+
11
+ 1. **Provider mounts** — creates (or retrieves from cache) a consent runtime and store
12
+ 2. **Check stored consent** — reads existing consent from cookies / localStorage; if found and the policy fingerprint hasn't changed, the banner stays hidden
13
+ 3. **Fetch init data** — calls the backend `GET /init` (or uses SSR/offline data) for the resolved policy, location, and translations
14
+ 4. **Apply resolved policy** — the backend resolves the policy from your [policy pack](/docs/frameworks/react/concepts/policy-packs) based on visitor geo (region → country → fallback → default). The response includes the consent model, categories, UI mode, and a material fingerprint. If no policy pack is configured, the legacy jurisdiction-to-model mapping is used instead.
15
+ 5. **Decide banner visibility** — shows the banner only if no prior consent exists, the resolved policy requires it (`ui.mode` is `banner` or `dialog`), or the policy fingerprint changed since last consent
16
+ 6. **Gating enforced** — scripts, iframes, and network requests tagged with a consent category are blocked until that category is granted
17
+ 7. **User interacts** — choices are persisted to storage, synced to the backend (with `policySnapshotToken` if configured), and blocked scripts/iframes load immediately after consent is granted
18
+
19
+ **Sequence Diagram**
20
+
21
+ ```mermaid
22
+ sequenceDiagram
23
+ participant Provider as ConsentManagerProvider
24
+ participant Store as Consent Store
25
+ participant Storage as localStorage / Cookie
26
+ participant API as c15t Backend
27
+ participant UI as Banner / Dialog
28
+ participant Scripts as Script Loader
29
+
30
+ Provider->>Store: getOrCreateConsentRuntime()
31
+ Store->>Storage: getStoredConsent()
32
+ alt Stored consent exists
33
+ Storage-->>Store: consentInfo + consents
34
+ Store->>Store: activeUI = 'none'
35
+ else No stored consent
36
+ Store->>Store: isLoadingConsentInfo = true
37
+ end
38
+
39
+ Store->>Store: initConsentManager()
40
+ Store->>Storage: Check pending consent sync
41
+ opt Pending sync from revocation reload
42
+ Store->>API: Deferred setConsent() (non-blocking)
43
+ end
44
+
45
+ alt SSR data provided
46
+ Store->>Store: tryUseSSRData()
47
+ else No SSR data
48
+ Store->>API: GET /init
49
+ API-->>Store: policy, policyDecision, location, translations
50
+ end
51
+
52
+ Store->>Store: Apply resolved policy (model, categories, ui.mode)
53
+ Store->>Store: Check fingerprint change → re-prompt if needed
54
+ Store->>Store: Set activeUI, auto-grant if opt-out/none
55
+
56
+ alt User has no prior consent or policy changed
57
+ UI->>UI: Banner / Dialog appears (per policy ui.mode)
58
+ UI->>Store: saveConsents({ type })
59
+ Store->>Storage: Persist consent + subjectId + fingerprint
60
+ Store->>Scripts: updateScripts(), updateIframes(), updateNetwork()
61
+ Store->>API: POST /subjects + policySnapshotToken (non-blocking)
62
+ end
63
+ ```
64
+
65
+ ## How It Works
66
+
67
+ **Mount** — When the provider renders, it creates (or retrieves from cache) a consent runtime and store. Any existing consent is read from localStorage/cookies immediately. If consent already exists and the policy fingerprint matches, the banner stays hidden and gating rules apply right away. See [Client Modes](/docs/frameworks/react/concepts/client-modes) for how the mode affects runtime creation.
68
+
69
+ **Init** — The store fetches the resolved policy, location, and translation data. In hosted mode this calls `GET /init` on your backend; in offline mode it resolves from `offlinePolicy.policyPacks` locally. If SSR data was passed to the provider, the network fetch is skipped entirely. See [Server-Side Utilities](/docs/frameworks/react/server-side) for SSR setup.
70
+
71
+ **Policy resolution** — When [policy packs](/docs/frameworks/react/concepts/policy-packs) are configured, the backend resolves the right policy for the visitor based on their geo-location (region → country → fallback → default). The resolved policy determines the consent model (`opt-in`, `opt-out`, `iab`, or `none`), which categories are in scope, and what UI to show. For `opt-out` and `none` models, all categories are auto-granted — unless the resolved policy has `consent.gpc: true` and the browser sends a Global Privacy Control signal, in which case `marketing` and `measurement` are denied. If no policy pack is configured, the legacy jurisdiction-to-model mapping is used instead. See [Consent Models](/docs/frameworks/react/concepts/consent-models) for details.
72
+
73
+ **Re-prompting** — If the resolved policy's material fingerprint differs from the fingerprint stored with the user's last consent, the banner is shown again. This happens automatically when you change consent-affecting fields (model, categories, scope mode, allowed actions). Presentation-only changes do not trigger re-prompts. See [Policy Packs — Re-Prompting](/docs/frameworks/react/concepts/policy-packs#re-prompting) for details.
74
+
75
+ **Save** — When the user interacts with the banner or dialog, their choices are persisted to localStorage/cookies and synced to the backend (along with the `policySnapshotToken` if snapshot signing is configured). Script, iframe, and network gating rules update immediately based on the new consent state. See the [Script Loader](/docs/frameworks/react/script-loader), [Iframe Blocking](/docs/frameworks/react/iframe-blocking), and [Network Blocker](/docs/frameworks/react/network-blocker) guides for gating details.
76
+
77
+ **Revocation** — If a user revokes a previously granted category, the page reloads by default to ensure a clean execution environment. The API sync is deferred to the fresh page load. See [Cookie Management](/docs/frameworks/react/concepts/cookie-management) for revocation and persistence details.
78
+
79
+ ## When Does the Banner Show?
80
+
81
+ The banner appears when any of these conditions are true:
82
+
83
+ 1. **No existing consent** — the user has never consented (or their consent was cleared), **and** the resolved policy requires a UI (`ui.mode` is `banner` or `dialog`, or the model is `opt-in` or `iab`)
84
+ 2. **Policy changed** — the material policy fingerprint differs from the fingerprint stored with the user's last consent (re-prompting)
85
+ 3. **Storage is accessible** — the browser allows localStorage (not blocked in private mode)
86
+
87
+ If the resolved model is `none` or `opt-out` (and `ui.mode` is `none`), consents are auto-granted and the banner never appears. See [Consent Models](/docs/frameworks/react/concepts/consent-models) and [Policy Packs](/docs/frameworks/react/concepts/policy-packs) for details.
88
+
89
+ ## Debugging the Lifecycle
90
+
91
+ Use the DevTools panel and callbacks to inspect each step of the initialization flow:
92
+
93
+ |Step|DevTools Panel|Callback|What to check|
94
+ |--|--|--|--|
95
+ |Init / SSR hydration|Location|`onBannerFetched`|jurisdiction, countryCode, regionCode populated?|
96
+ |Policy resolution|Policy|`onBannerFetched`|`policyId`, `matchedBy`, `fingerprint` in policyDecision|
97
+ |Model resolution|Location|`onBannerFetched`|`model` value matches the resolved policy|
98
+ |Banner visibility|Consents|—|`activeUI` in store state; does policy `ui.mode` require it?|
99
+ |Re-prompting|Policy|—|Fingerprint mismatch between stored and resolved policy?|
100
+ |Consent save|Consents + Events|`onConsentSet`|`preferences` object in callback payload|
101
+ |Script loading|Scripts|`onConsentSet`|Script IDs and their load/blocked status|
102
+ |Reload on revocation|Events|`onBeforeConsentRevocationReload`|Fires before reload; check localStorage for `c15t:pending-consent-sync`|
103
+ |Deferred sync|Events|`onError` (if sync fails)|After reload, check Events panel for successful API call|
104
+
105
+ Configure callbacks in the provider to log lifecycle events, and add DevTools for a visual inspector:
106
+
107
+ ```tsx
108
+ import { type ReactNode } from 'react';
109
+ import { ConsentManagerProvider, ConsentBanner, ConsentDialog } from '@c15t/react';
110
+ import { DevTools } from '@c15t/dev-tools/react';
111
+
112
+ export default function ConsentManager({ children }: { children: ReactNode }) {
113
+ return (
114
+ <ConsentManagerProvider
115
+ options={{
116
+ mode: 'hosted',
117
+ backendURL: 'https://your-instance.c15t.dev',
118
+ callbacks: {
119
+ onBannerFetched: ({ jurisdiction, location }) => {
120
+ console.log('Init complete:', { jurisdiction, location });
121
+ },
122
+ onConsentSet: ({ preferences }) => {
123
+ console.log('Consent saved:', preferences);
124
+ },
125
+ onBeforeConsentRevocationReload: ({ preferences }) => {
126
+ console.log('Reloading due to revocation:', preferences);
127
+ },
128
+ onError: ({ error }) => {
129
+ console.error('Consent error:', error);
130
+ },
131
+ },
132
+ }}
133
+ >
134
+ <ConsentBanner />
135
+ <ConsentDialog />
136
+ {process.env.NODE_ENV !== 'production' && <DevTools />}
137
+ {children}
138
+ </ConsentManagerProvider>
139
+ );
140
+ }
141
+ ```
@@ -0,0 +1,227 @@
1
+ ---
2
+ title: Policy Packs
3
+ description: How c15t resolves regional consent policies and what a policy pack controls.
4
+ ---
5
+ Different countries need different consent experiences. Policy packs let you define those rules once — c15t picks the right one automatically based on where the visitor is.
6
+
7
+ A policy pack is an ordered array of policies. Each policy targets a region or country and controls the consent model, which categories are in scope, what UI is shown, and how consent is recorded.
8
+
9
+ There are three ways to configure policy packs:
10
+
11
+ 1. **consent.io (recommended)** — use [consent.io](https://consent.io) as your hosted backend. Configure packs visually in the dashboard or via API — no code changes required. Works with any frontend, including static sites.
12
+ 2. **Self-hosted backend** — define packs in code via `policyPacks` and resolve them from real request geo data. Full control over policy logic and storage.
13
+ 3. **Offline fallback** — pass the same policy shapes to the frontend via `offlinePolicy.policyPacks`. Used as a resilience fallback when the backend is unreachable, or for quick local experimentation and demos. If you omit `offlinePolicy.policyPacks`, c15t falls back to a synthetic worldwide opt-in banner instead of no-banner mode.
14
+
15
+ In both hosted and self-hosted modes, the **backend is always the source of truth**. Offline packs never override a live backend decision.
16
+
17
+ ## Quickstart
18
+
19
+ The fastest way to get started is with the built-in presets:
20
+
21
+ ```ts
22
+ import { policyPackPresets } from 'c15t';
23
+
24
+ const policies = [
25
+ policyPackPresets.europeOptIn(), // GDPR opt-in banner
26
+ policyPackPresets.californiaOptOut(), // CCPA opt-out banner
27
+ policyPackPresets.worldNoBanner(), // No banner elsewhere
28
+ ];
29
+ ```
30
+
31
+ |Preset|Model|UI|Matches|
32
+ |--|--|--|--|
33
+ |`europeOptIn()`|`opt-in`|banner|EEA + UK countries + geo fallback|
34
+ |`europeIab()`|`iab`|banner|EEA + UK countries + geo fallback (TCF 2.3)|
35
+ |`californiaOptOut()`|`opt-out`|none|US-CA region|
36
+ |`quebecOptIn()`|`opt-in`|banner|CA-QC region|
37
+ |`worldNoBanner()`|`none`|none|default fallback|
38
+
39
+ Most apps only need these presets — pick the ones that match your regions, pass them to your backend config or provider, and you're done. Customize individual fields or write fully custom policies when you need more control.
40
+
41
+ For banner/dialog actions, policy packs can also control grouped button arrangement:
42
+
43
+ ```ts
44
+ ui: {
45
+ mode: 'banner',
46
+ banner: {
47
+ allowedActions: ['reject', 'accept', 'customize'],
48
+ layout: [['reject', 'accept'], 'customize'],
49
+ direction: 'row',
50
+ primaryActions: ['accept', 'customize'],
51
+ },
52
+ }
53
+ ```
54
+
55
+ That expresses arrangement only. Button appearance like `stroke`, `filled`, or `ghost` lives in the UI theme.
56
+
57
+ ## What Users See
58
+
59
+ Each policy combination produces a different consent experience:
60
+
61
+ |Policy Config|User Experience|
62
+ |--|--|
63
+ |`model: 'opt-in'`, `ui.mode: 'banner'`|Banner appears, nothing loads until the user consents|
64
+ |`model: 'opt-out'`, `ui.mode: 'none'`|No banner, everything loads immediately — user opts out via a "Do Not Sell" link|
65
+ |`model: 'none'`, `ui.mode: 'none'`|No banner, all categories auto-granted silently|
66
+ |`model: 'opt-in'`, `ui.mode: 'dialog'`|Full-screen dialog, nothing loads until the user consents|
67
+ |`model: 'iab'`, `ui.mode: 'banner'`|IAB TCF 2.3 banner with vendor-level controls|
68
+
69
+ ## How Policy Resolution Works
70
+
71
+ When a visitor arrives, c15t walks the policy pack in priority order:
72
+
73
+ 1. **Match by region** — checks for a policy targeting the specific region (e.g., US-CA, CA-QC)
74
+ 2. **Match by country** — if no region match, checks for a country-level policy (e.g., US, DE)
75
+ 3. **Fallback (geo failure)** — if geo-location failed (no country detected), uses the policy marked with `match.fallback`
76
+ 4. **Fall back to default** — if nothing matches, uses the policy marked as the default
77
+ 5. **No match, no default** — resolves to no-banner mode (silent, no consent UI)
78
+
79
+ Within the same matcher type, the first policy in the array wins. Pack order matters when two policies target the same country or region.
80
+
81
+ The **fallback** step is distinct from **default**: `isDefault` is a catch-all for known locations that don't match any specific policy ("rest of world"), while `fallback` is a safety net for unknown locations when geo-headers are missing ("assume strictest"). The `europeOptIn()` and `europeIab()` presets include `fallback: true` by default so EU-level consent applies when geo fails.
82
+
83
+ > ⚠️ **Warning:**
84
+ > Only one default and one fallback policy are allowed. Use inspectPolicies() to surface overlapping matchers and other warnings before deployment.
85
+
86
+ Inspect the resolved policy at runtime with `useConsentManager()`:
87
+
88
+ ```tsx
89
+ import { useConsentManager } from '@c15t/react';
90
+
91
+ function PolicyDebug() {
92
+ const { locationInfo, model, policy, policyDecision } = useConsentManager();
93
+
94
+ return (
95
+ <pre>
96
+ {JSON.stringify(
97
+ {
98
+ country: locationInfo?.countryCode,
99
+ region: locationInfo?.regionCode,
100
+ model,
101
+ policyId: policy?.id,
102
+ matchedBy: policyDecision?.matchedBy,
103
+ fingerprint: policyDecision?.fingerprint,
104
+ },
105
+ null,
106
+ 2
107
+ )}
108
+ </pre>
109
+ );
110
+ }
111
+ ```
112
+
113
+ ## Common Patterns
114
+
115
+ **The 80% case** — strict in Europe, light in California, silent everywhere else:
116
+
117
+ ```ts
118
+ const policies = [
119
+ {
120
+ id: 'eu',
121
+ match: { countries: ['DE', 'FR', 'IT'] },
122
+ consent: { model: 'opt-in', categories: ['necessary', 'measurement', 'marketing'] },
123
+ ui: { mode: 'banner' },
124
+ },
125
+ {
126
+ id: 'ca',
127
+ match: { regions: [{ country: 'US', region: 'CA' }] },
128
+ consent: { model: 'opt-out', gpc: true },
129
+ ui: { mode: 'none' },
130
+ },
131
+ {
132
+ id: 'default',
133
+ match: { isDefault: true },
134
+ consent: { model: 'none' },
135
+ ui: { mode: 'none' },
136
+ },
137
+ ];
138
+ ```
139
+
140
+ **Region overrides country** — stricter rules for California than the rest of the US:
141
+
142
+ ```ts
143
+ const policies = [
144
+ {
145
+ id: 'us_ca',
146
+ match: { regions: [{ country: 'US', region: 'CA' }] },
147
+ consent: { model: 'opt-in', scopeMode: 'strict' },
148
+ ui: { mode: 'banner' },
149
+ },
150
+ {
151
+ id: 'us',
152
+ match: { countries: ['US'] },
153
+ consent: { model: 'opt-out' },
154
+ ui: { mode: 'banner' },
155
+ },
156
+ ];
157
+ // US-CA → us_ca (region match wins)
158
+ // US-NY → us (country match)
159
+ ```
160
+
161
+ **Different wording per region** — use `i18n.messageProfile` to vary copy without changing the consent model:
162
+
163
+ ```ts
164
+ const c15t = c15tInstance({
165
+ i18n: {
166
+ defaultProfile: 'default',
167
+ messages: {
168
+ default: {
169
+ translations: {
170
+ en: { cookieBanner: { title: 'Privacy choices' } },
171
+ es: { cookieBanner: { title: 'Tus opciones de privacidad' } },
172
+ },
173
+ },
174
+ eu: {
175
+ fallbackLanguage: 'en',
176
+ translations: {
177
+ en: { cookieBanner: { title: 'EU GDPR Consent' } },
178
+ fr: { cookieBanner: { title: 'Consentement RGPD' } },
179
+ de: { cookieBanner: { title: 'GDPR-Einwilligung' } },
180
+ },
181
+ },
182
+ },
183
+ },
184
+ policyPacks: [
185
+ {
186
+ id: 'eu',
187
+ match: { countries: ['DE', 'FR', 'IT'] },
188
+ i18n: { messageProfile: 'eu' },
189
+ consent: { model: 'opt-in' },
190
+ ui: { mode: 'banner' },
191
+ },
192
+ ],
193
+ });
194
+ ```
195
+
196
+ In that setup, the `eu` policy uses only the `eu` language set. So Europe can
197
+ resolve to `en`, `fr`, or `de`, but not to `es` or any other locale defined
198
+ only in `default`. If the browser asks for an unsupported locale, c15t falls
199
+ back to the `eu` profile's `fallbackLanguage`.
200
+
201
+ ## Re-Prompting on Policy Change
202
+
203
+ When you change a policy in a way that affects consent semantics — like adding a category, changing the consent model, or modifying allowed actions — c15t automatically re-prompts returning users.
204
+
205
+ This works through the **material policy fingerprint**: a hash of only the consent-affecting fields (model, categories, scope, allowed actions, grouped action layout, direction, proof settings). Presentation-only changes like copy, button styling, or scroll lock do not trigger re-prompts.
206
+
207
+ |Change|Re-prompts?|
208
+ |--|--|
209
+ |Add a consent category|Yes|
210
+ |Change `model` from `opt-out` to `opt-in`|Yes|
211
+ |Remove an `allowedAction`|Yes|
212
+ |Change `uiProfile` or button styling|No|
213
+ |Update translation copy|No|
214
+ |Change `scrollLock`|No|
215
+
216
+ ## Design Guidelines
217
+
218
+ * **Start from presets.** Use `policyPackPresets` to get running, then customize for your needs.
219
+ * **Keep packs small.** A handful of regional policies is better than dozens of tiny fragments.
220
+ * **Think risk, not geography.** Geography is just a matcher — the real question is what consent behavior each region needs.
221
+ * **Always include a default.** Unless "no banner for unmatched traffic" is intentional.
222
+ * **Set a fallback for geo failures.** Mark your strictest policy with `match.fallback=true` so users in unknown locations still see a consent banner. The `europeOptIn()` and `europeIab()` presets do this automatically.
223
+ * **Keep policy IDs stable.** They appear in debugging output, snapshots, and audit records.
224
+ * **Use `inspectPolicies()` before deploying.** It catches overlapping matchers, missing defaults, and IAB misconfigurations.
225
+
226
+ > ℹ️ **Info:**
227
+ > For provider setup, see the React policy pack guide. For backend configuration, see the self-host guide.
@@ -0,0 +1,184 @@
1
+ ---
2
+ title: Headless Mode
3
+ description: Build fully custom consent UI using only hooks - no pre-built components required.
4
+ ---
5
+ c15t's headless mode means using the hooks (`useConsentManager`, `useTranslations`, etc.) without any pre-built UI components. This gives you complete control over the consent experience.
6
+
7
+ There are three levels of customization:
8
+
9
+ 1. **Props** - Use pre-built components with custom text and configuration
10
+ 2. **noStyle** - Use pre-built components with their structure but strip all styles
11
+ 3. **Headless** - Use only hooks and build the entire UI yourself
12
+
13
+ ## When to Go Headless
14
+
15
+ Go headless when:
16
+
17
+ * Your design system requires complete control over markup
18
+ * You need a consent flow that doesn't fit the banner/dialog pattern
19
+ * You want to embed consent choices inline rather than as overlays
20
+
21
+ Use `noStyle` instead when:
22
+
23
+ * The component structure works but the styling doesn't
24
+ * You want to apply your own CSS/Tailwind without fighting defaults
25
+
26
+ > ℹ️ **Info:**
27
+ > Need a policy-aware implementation guide? See Building Headless Components.
28
+
29
+ ## Full Example: Custom Consent Banner
30
+
31
+ ```tsx
32
+ import { useConsentManager, useTranslations } from '@c15t/react';
33
+
34
+ function CustomConsentBanner() {
35
+ const {
36
+ activeUI,
37
+ consents,
38
+ consentCategories,
39
+ consentTypes,
40
+ saveConsents,
41
+ setSelectedConsent,
42
+ selectedConsents,
43
+ } = useConsentManager();
44
+ const translations = useTranslations();
45
+
46
+ if (activeUI !== 'banner') return null;
47
+
48
+ const displayedTypes = consentTypes.filter(
49
+ (t) => consentCategories.includes(t.name) && t.display
50
+ );
51
+
52
+ return (
53
+ <div className="fixed bottom-0 inset-x-0 bg-white border-t p-6 shadow-lg z-50">
54
+ <h2 className="text-lg font-semibold">
55
+ {translations.cookieBanner.title}
56
+ </h2>
57
+ <p className="text-sm text-gray-600 mt-1">
58
+ {translations.cookieBanner.description}
59
+ </p>
60
+
61
+ <div className="mt-4 space-y-3">
62
+ {displayedTypes.map((type) => (
63
+ <label key={type.name} className="flex items-center gap-3">
64
+ <input
65
+ type="checkbox"
66
+ checked={selectedConsents[type.name] ?? consents[type.name] ?? false}
67
+ disabled={type.disabled}
68
+ onChange={(e) => setSelectedConsent(type.name, e.target.checked)}
69
+ />
70
+ <div>
71
+ <span className="font-medium">
72
+ {translations.consentTypes[type.name]?.title ?? type.name}
73
+ </span>
74
+ <p className="text-xs text-gray-500">{type.description}</p>
75
+ </div>
76
+ </label>
77
+ ))}
78
+ </div>
79
+
80
+ <div className="mt-4 flex gap-3">
81
+ <button
82
+ onClick={() => saveConsents('necessary')}
83
+ className="px-4 py-2 border rounded"
84
+ >
85
+ {translations.common.rejectAll}
86
+ </button>
87
+ <button
88
+ onClick={() => saveConsents('custom')}
89
+ className="px-4 py-2 border rounded"
90
+ >
91
+ {translations.common.save}
92
+ </button>
93
+ <button
94
+ onClick={() => saveConsents('all')}
95
+ className="px-4 py-2 bg-blue-600 text-white rounded"
96
+ >
97
+ {translations.common.acceptAll}
98
+ </button>
99
+ </div>
100
+ </div>
101
+ );
102
+ }
103
+ ```
104
+
105
+ ## Usage with Provider
106
+
107
+ The headless UI still needs a `ConsentManagerProvider`:
108
+
109
+ ```tsx
110
+ import { type ReactNode } from 'react';
111
+ import { ConsentManagerProvider } from '@c15t/react';
112
+
113
+ export function ConsentManager({ children }: { children: ReactNode }) {
114
+ return (
115
+ <ConsentManagerProvider
116
+ options={{
117
+ mode: 'hosted',
118
+ backendURL: 'https://your-instance.c15t.dev',
119
+ consentCategories: ['necessary', 'measurement', 'marketing'],
120
+ }}
121
+ >
122
+ <CustomConsentBanner />
123
+ {children}
124
+ </ConsentManagerProvider>
125
+ );
126
+ }
127
+ ```
128
+
129
+ ## Custom Dialog
130
+
131
+ Build a custom consent dialog for detailed category management:
132
+
133
+ ```tsx
134
+ import { useConsentManager, useTranslations } from '@c15t/react';
135
+
136
+ function CustomConsentDialog() {
137
+ const {
138
+ activeUI,
139
+ setActiveUI,
140
+ consentTypes,
141
+ consentCategories,
142
+ selectedConsents,
143
+ consents,
144
+ setSelectedConsent,
145
+ saveConsents,
146
+ has,
147
+ } = useConsentManager();
148
+ const translations = useTranslations();
149
+
150
+ if (activeUI !== 'dialog') return null;
151
+
152
+ return (
153
+ <div className="fixed inset-0 z-50 flex items-center justify-center">
154
+ <div className="absolute inset-0 bg-black/50" onClick={() => setActiveUI('none')} />
155
+ <div className="relative bg-white rounded-xl p-6 max-w-md w-full">
156
+ <h2 className="text-lg font-semibold">{translations.consentManagerDialog.title}</h2>
157
+
158
+ {consentTypes
159
+ .filter((t) => consentCategories.includes(t.name))
160
+ .map((type) => (
161
+ <div key={type.name} className="flex items-center justify-between py-3 border-b">
162
+ <div>
163
+ <p className="font-medium">{translations.consentTypes[type.name]?.title}</p>
164
+ <p className="text-sm text-gray-500">{type.description}</p>
165
+ </div>
166
+ <input
167
+ type="checkbox"
168
+ checked={selectedConsents[type.name] ?? consents[type.name] ?? false}
169
+ disabled={type.disabled}
170
+ onChange={(e) => setSelectedConsent(type.name, e.target.checked)}
171
+ />
172
+ </div>
173
+ ))}
174
+
175
+ <div className="mt-4 flex justify-end gap-2">
176
+ <button onClick={() => saveConsents('necessary')}>Reject</button>
177
+ <button onClick={() => saveConsents('custom')}>Save</button>
178
+ <button onClick={() => saveConsents('all')}>Accept All</button>
179
+ </div>
180
+ </div>
181
+ </div>
182
+ );
183
+ }
184
+ ```
@@ -0,0 +1,40 @@
1
+ ---
2
+ title: useColorScheme
3
+ description: Manage light/dark mode preferences for consent components.
4
+ ---
5
+ `useColorScheme()` manages the color scheme preference for c15t components. It sets up the appropriate CSS class and media query listeners.
6
+
7
+ ```tsx
8
+ import { useColorScheme } from '@c15t/react';
9
+
10
+ function ThemeManager() {
11
+ useColorScheme('system'); // Follow system preference
12
+ }
13
+ ```
14
+
15
+ ## Parameters
16
+
17
+ |Value|Behavior|
18
+ |--|--|
19
+ |`'light'`|Force light mode|
20
+ |`'dark'`|Force dark mode|
21
+ |`'system'`|Follow `prefers-color-scheme` media query|
22
+ |`null`|Disable - c15t won't manage color scheme|
23
+ |`undefined`|No-op|
24
+
25
+ ## Provider-Level Configuration
26
+
27
+ You can also set the color scheme on the provider without using this hook:
28
+
29
+ ```tsx
30
+ <ConsentManagerProvider
31
+ options={{
32
+ colorScheme: 'system',
33
+ // ...
34
+ }}
35
+ >
36
+ ```
37
+
38
+ ## System Preference Detection
39
+
40
+ When set to `'system'`, the hook listens for changes to the `prefers-color-scheme` media query and updates automatically when the user changes their OS theme.
@@ -0,0 +1,94 @@
1
+ ---
2
+ title: Checking Consent
3
+ description: Use has() for flexible consent checks with AND, OR, and NOT logic. Check if any consent exists with hasConsented().
4
+ ---
5
+ ## has(condition)
6
+
7
+ The `has()` method evaluates whether the current consent state satisfies a condition. It supports simple category checks and complex logical expressions.
8
+
9
+ ### Simple Check
10
+
11
+ ```tsx
12
+ const { has } = useConsentManager();
13
+
14
+ if (has('measurement')) {
15
+ // User has granted measurement consent
16
+ }
17
+ ```
18
+
19
+ ### AND Logic
20
+
21
+ All conditions must be true:
22
+
23
+ ```tsx
24
+ has({ and: ['measurement', 'marketing'] })
25
+ // true only if BOTH measurement AND marketing are granted
26
+ ```
27
+
28
+ ### OR Logic
29
+
30
+ At least one condition must be true:
31
+
32
+ ```tsx
33
+ has({ or: ['measurement', 'marketing'] })
34
+ // true if EITHER measurement OR marketing is granted
35
+ ```
36
+
37
+ ### NOT Logic
38
+
39
+ Negates a condition:
40
+
41
+ ```tsx
42
+ has({ not: 'marketing' })
43
+ // true if marketing consent is NOT granted
44
+ ```
45
+
46
+ ### Nested Conditions
47
+
48
+ Combine operators for complex logic:
49
+
50
+ ```tsx
51
+ has({
52
+ and: [
53
+ 'necessary',
54
+ { or: ['measurement', 'marketing'] },
55
+ { not: 'functionality' },
56
+ ],
57
+ })
58
+ // true if: necessary AND (measurement OR marketing) AND NOT functionality
59
+ ```
60
+
61
+ ### HasCondition Type
62
+
63
+ ```ts
64
+ type HasCondition<CategoryType> =
65
+ | CategoryType // "measurement"
66
+ | { and: HasCondition[] | HasCondition } // { and: ["a", "b"] }
67
+ | { or: HasCondition[] | HasCondition } // { or: ["a", "b"] }
68
+ | { not: HasCondition } // { not: "a" }
69
+ ```
70
+
71
+ ## hasConsented()
72
+
73
+ Returns `true` if the user has made any consent choice (accepted, rejected, or customized). Returns `false` if no consent has been recorded yet.
74
+
75
+ ```tsx
76
+ const { hasConsented } = useConsentManager();
77
+
78
+ if (hasConsented()) {
79
+ // User has previously made a consent choice
80
+ } else {
81
+ // First visit — no consent recorded
82
+ }
83
+ ```
84
+
85
+ ## getDisplayedConsents()
86
+
87
+ Returns the consent types that should be displayed in the UI (based on active `consentCategories` and each type's `display` property):
88
+
89
+ ```tsx
90
+ const { getDisplayedConsents } = useConsentManager();
91
+
92
+ const visibleCategories = getDisplayedConsents();
93
+ // Returns ConsentType[] with name, description, defaultValue, etc.
94
+ ```