@c15t/nextjs 2.0.0-rc.1 → 2.0.0-rc.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -3
- package/client/components/consent-dialog-link.js +3 -0
- package/dist/headless.cjs +1 -1
- package/dist/iab/styles.css +12 -0
- package/dist/iab/styles.tw3.css +14 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/libs/browser-initial-data.cjs +1 -0
- package/dist/libs/browser-initial-data.js +1 -0
- package/dist/libs/initial-data.cjs +1 -1
- package/dist/libs/initial-data.js +1 -1
- package/dist/styles.css +10 -0
- package/dist/styles.tw3.css +13 -0
- package/dist/types.cjs +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.js +1 -1
- package/{dist → dist-types}/headless.d.ts +0 -1
- package/{dist → dist-types}/index.d.ts +3 -2
- package/dist-types/libs/browser-initial-data.d.ts +9 -0
- package/{dist → dist-types}/libs/initial-data.d.ts +7 -2
- package/dist-types/types.d.ts +38 -0
- package/dist-types/version.d.ts +1 -0
- package/docs/README.md +73 -0
- package/docs/building-headless-components.md +377 -0
- package/docs/callbacks.md +184 -0
- package/docs/components/consent-banner.md +269 -0
- package/docs/components/consent-dialog-link.md +59 -0
- package/docs/components/consent-dialog-trigger.md +103 -0
- package/docs/components/consent-dialog.md +177 -0
- package/docs/components/consent-manager-provider.md +425 -0
- package/docs/components/consent-widget.md +133 -0
- package/docs/components/dev-tools.md +63 -0
- package/docs/components/frame.md +73 -0
- package/docs/concepts/client-modes.md +175 -0
- package/docs/concepts/consent-categories.md +97 -0
- package/docs/concepts/consent-models.md +116 -0
- package/docs/concepts/cookie-management.md +122 -0
- package/docs/concepts/glossary.md +23 -0
- package/docs/concepts/initialization-flow.md +148 -0
- package/docs/concepts/policy-packs.md +229 -0
- package/docs/headless.md +190 -0
- package/docs/hooks/use-color-scheme.md +40 -0
- package/docs/hooks/use-consent-manager/checking-consent.md +94 -0
- package/docs/hooks/use-consent-manager/location-info.md +95 -0
- package/docs/hooks/use-consent-manager/overview.md +420 -0
- package/docs/hooks/use-consent-manager/setting-consent.md +92 -0
- package/docs/hooks/use-draggable.md +57 -0
- package/docs/hooks/use-focus-trap.md +41 -0
- package/docs/hooks/use-reduced-motion.md +35 -0
- package/docs/hooks/use-ssr-status.md +31 -0
- package/docs/hooks/use-text-direction.md +49 -0
- package/docs/hooks/use-translations.md +118 -0
- package/docs/iab/consent-banner.md +94 -0
- package/docs/iab/consent-dialog.md +134 -0
- package/docs/iab/overview.md +126 -0
- package/docs/iab/use-gvl-data.md +20 -0
- package/docs/iframe-blocking.md +107 -0
- package/docs/integrations/building-integrations.md +405 -0
- package/docs/integrations/databuddy.md +203 -0
- package/docs/integrations/google-tag-manager.md +153 -0
- package/docs/integrations/google-tag.md +122 -0
- package/docs/integrations/linkedin-insights.md +109 -0
- package/docs/integrations/meta-pixel.md +342 -0
- package/docs/integrations/microsoft-uet.md +112 -0
- package/docs/integrations/overview.md +105 -0
- package/docs/integrations/posthog.md +199 -0
- package/docs/integrations/tiktok-pixel.md +113 -0
- package/docs/integrations/x-pixel.md +143 -0
- package/docs/internationalization.md +197 -0
- package/docs/network-blocker.md +178 -0
- package/docs/optimization.md +234 -0
- package/docs/policy-packs.md +246 -0
- package/docs/quickstart.md +161 -0
- package/docs/script-loader.md +321 -0
- package/docs/server-side.md +176 -0
- package/docs/styling/classnames.md +92 -0
- package/docs/styling/color-scheme.md +82 -0
- package/docs/styling/css-variables.md +92 -0
- package/docs/styling/overview.md +456 -0
- package/docs/styling/slots.md +127 -0
- package/docs/styling/tailwind.md +113 -0
- package/docs/styling/tokens.md +216 -0
- package/docs/troubleshooting.md +146 -0
- package/iab/styles.css +1 -0
- package/package.json +36 -15
- package/readme.json +4 -0
- package/src/iab/styles.css +12 -0
- package/src/iab/styles.tw3.css +14 -0
- package/src/styles.css +10 -0
- package/src/styles.tw3.css +13 -0
- package/styles.css +1 -0
- package/dist/headless.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/libs/initial-data.d.ts.map +0 -1
- package/dist/types.d.ts +0 -16
- package/dist/types.d.ts.map +0 -1
- package/dist/version.d.ts +0 -2
- package/dist/version.d.ts.map +0 -1
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Class Names
|
|
3
|
+
description: Style consent components using className props and per-slot className targeting via the theme.
|
|
4
|
+
---
|
|
5
|
+
## Prefer Slots for Stock Components
|
|
6
|
+
|
|
7
|
+
There is no single top-level `className` contract across every pre-built consent component.
|
|
8
|
+
|
|
9
|
+
For the stock `ConsentBanner`, `ConsentDialog`, and `ConsentWidget`, prefer `theme.slots` first. That keeps the markup intact and lets you target the exact part you need.
|
|
10
|
+
|
|
11
|
+
## Per-Slot className
|
|
12
|
+
|
|
13
|
+
Target individual component parts via the theme's `slots` object. Each slot accepts a string (className) or an object with `className` and `style`:
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
const theme = {
|
|
17
|
+
slots: {
|
|
18
|
+
consentBannerTitle: 'text-xl font-semibold',
|
|
19
|
+
consentBannerDescription: 'text-sm text-gray-600',
|
|
20
|
+
consentBannerFooter: 'flex gap-3',
|
|
21
|
+
buttonPrimary: 'rounded-full px-6',
|
|
22
|
+
},
|
|
23
|
+
} satisfies Theme;
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Combining with CSS Modules
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
import styles from './consent.module.css';
|
|
30
|
+
|
|
31
|
+
const theme = {
|
|
32
|
+
slots: {
|
|
33
|
+
consentBannerCard: styles.bannerCard,
|
|
34
|
+
consentBannerTitle: styles.bannerTitle,
|
|
35
|
+
buttonPrimary: styles.primaryButton,
|
|
36
|
+
},
|
|
37
|
+
} satisfies Theme;
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```css title="consent.module.css"
|
|
41
|
+
.bannerCard {
|
|
42
|
+
backdrop-filter: blur(12px);
|
|
43
|
+
background: rgba(255, 255, 255, 0.9);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.bannerTitle {
|
|
47
|
+
font-size: 1.25rem;
|
|
48
|
+
font-weight: 700;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.primaryButton {
|
|
52
|
+
border-radius: 9999px;
|
|
53
|
+
text-transform: uppercase;
|
|
54
|
+
letter-spacing: 0.05em;
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## When to Use Raw className
|
|
59
|
+
|
|
60
|
+
Use raw className-level styling when:
|
|
61
|
+
|
|
62
|
+
* your styling system is already class-driven
|
|
63
|
+
* tokens are too broad for the change
|
|
64
|
+
* slots already identify the correct element
|
|
65
|
+
|
|
66
|
+
If the request is "make the banner footer darker", prefer `theme.colors.surfaceHover` first. If the request is "add a border and spacing only to the footer", prefer `theme.slots.consentBannerFooter`.
|
|
67
|
+
|
|
68
|
+
## Advanced: `noStyle`
|
|
69
|
+
|
|
70
|
+
Use `noStyle` only when you want to remove defaults and style from scratch while still keeping c15t's component structure:
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
{/* Remove all styles from a specific component */}
|
|
74
|
+
<ConsentBanner noStyle />
|
|
75
|
+
|
|
76
|
+
{/* Remove all styles globally */}
|
|
77
|
+
<ConsentManagerProvider options={{ noStyle: true, ... }}>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
You can also set `noStyle` per-slot:
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
const theme = {
|
|
84
|
+
slots: {
|
|
85
|
+
consentBannerCard: { noStyle: true, className: 'my-custom-card' },
|
|
86
|
+
},
|
|
87
|
+
} satisfies Theme;
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Treat `noStyle` as an advanced escape hatch. Do not jump to it just because a token or slot needs debugging.
|
|
91
|
+
|
|
92
|
+
For full custom markup and behavior, continue to [Headless Mode](../headless).
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Color Scheme
|
|
3
|
+
description: Support light mode, dark mode, and system preference detection in consent components.
|
|
4
|
+
---
|
|
5
|
+
c15t supports light and dark mode through the theme's `colors` and `dark` token groups. The active color scheme is determined by one of three methods:
|
|
6
|
+
|
|
7
|
+
1. **Explicit setting** via the `colorScheme` option
|
|
8
|
+
2. **CSS class detection** - c15t checks for `.dark` on the document element
|
|
9
|
+
3. **System preference** - matches `prefers-color-scheme` media query
|
|
10
|
+
|
|
11
|
+
## Configuration
|
|
12
|
+
|
|
13
|
+
Set the color scheme on the provider:
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { type ReactNode } from 'react';
|
|
17
|
+
import { ConsentManagerProvider } from '@c15t/nextjs';
|
|
18
|
+
|
|
19
|
+
function ConsentManager({ children }: { children: ReactNode }) {
|
|
20
|
+
return (
|
|
21
|
+
<ConsentManagerProvider
|
|
22
|
+
options={{
|
|
23
|
+
mode: 'hosted',
|
|
24
|
+
backendURL: '/api/c15t',
|
|
25
|
+
colorScheme: 'system', // 'light' | 'dark' | 'system'
|
|
26
|
+
theme: {
|
|
27
|
+
colors: {
|
|
28
|
+
primary: '#6366f1',
|
|
29
|
+
surface: '#ffffff',
|
|
30
|
+
text: '#1f2937',
|
|
31
|
+
},
|
|
32
|
+
dark: {
|
|
33
|
+
primary: '#818cf8',
|
|
34
|
+
surface: '#1f2937',
|
|
35
|
+
text: '#f9fafb',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
{children}
|
|
41
|
+
</ConsentManagerProvider>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## useColorScheme Hook
|
|
47
|
+
|
|
48
|
+
For programmatic control over the color scheme:
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
import { useColorScheme } from '@c15t/nextjs';
|
|
52
|
+
|
|
53
|
+
function ThemeToggle() {
|
|
54
|
+
// Pass the desired scheme - 'light', 'dark', 'system', or null (disable)
|
|
55
|
+
useColorScheme('system');
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
|Value|Behavior|
|
|
60
|
+
|--|--|
|
|
61
|
+
|`'light'`|Force light mode|
|
|
62
|
+
|`'dark'`|Force dark mode|
|
|
63
|
+
|`'system'`|Follow `prefers-color-scheme` media query|
|
|
64
|
+
|`null`|Disable - c15t won't manage color scheme|
|
|
65
|
+
|
|
66
|
+
## How Dark Mode Works
|
|
67
|
+
|
|
68
|
+
When dark mode is active, c15t applies the `dark` token values as CSS variable overrides. Only tokens specified in `dark` are overridden - unset tokens fall back to the `colors` values. This also applies to `textOnPrimary`: if you omit it, c15t derives a readable foreground from the active `primary` color in that scheme.
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
const theme = {
|
|
72
|
+
colors: {
|
|
73
|
+
surface: '#ffffff', // Light mode
|
|
74
|
+
text: '#1f2937', // Light mode
|
|
75
|
+
},
|
|
76
|
+
dark: {
|
|
77
|
+
surface: '#1f2937', // Dark mode override
|
|
78
|
+
text: '#f9fafb', // Dark mode override
|
|
79
|
+
// primary is NOT set - inherits from colors.primary
|
|
80
|
+
},
|
|
81
|
+
} satisfies Theme;
|
|
82
|
+
```
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: CSS Variables
|
|
3
|
+
description: Reference for all --c15t-* CSS custom properties generated by the theme system.
|
|
4
|
+
---
|
|
5
|
+
Every theme token is converted to a `--c15t-*` CSS custom property at runtime. You can override these variables in your stylesheet without using the JavaScript theme API.
|
|
6
|
+
|
|
7
|
+
## Variable Reference
|
|
8
|
+
|
|
9
|
+
### ThemeCSSVariables
|
|
10
|
+
|
|
11
|
+
|Property|Type|Description|Default|Required|
|
|
12
|
+
|:--|:--|:--|:--|:--:|
|
|
13
|
+
|--c15t-primary|string \|undefined|\`colors.primary\` (default: \`hsl(228, 100%, 60%)\`)|-|Optional|
|
|
14
|
+
|--c15t-primary-hover|string \|undefined|\`colors.primaryHover\` (default: \`hsl(228, 100%, 55%)\`)|-|Optional|
|
|
15
|
+
|--c15t-surface|string \|undefined|\`colors.surface\` (default: \`hsl(0, 0%, 100%)\`)|-|Optional|
|
|
16
|
+
|--c15t-surface-hover|string \|undefined|\`colors.surfaceHover\` (default: \`hsl(0, 0%, 98%)\`)|-|Optional|
|
|
17
|
+
|--c15t-border|string \|undefined|\`colors.border\` (default: \`hsl(0, 0%, 90%)\`)|-|Optional|
|
|
18
|
+
|--c15t-border-hover|string \|undefined|\`colors.borderHover\` (default: \`hsl(0, 0%, 85%)\`)|-|Optional|
|
|
19
|
+
|--c15t-text|string \|undefined|\`colors.text\` (default: \`hsl(0, 0%, 10%)\`)|-|Optional|
|
|
20
|
+
|--c15t-text-muted|string \|undefined|\`colors.textMuted\` (default: \`hsl(0, 0%, 40%)\`)|-|Optional|
|
|
21
|
+
|--c15t-text-on-primary|string \|undefined|\`colors.textOnPrimary\` (auto-derived from \`colors.primary\` when omitted)|-|Optional|
|
|
22
|
+
|--c15t-overlay|string \|undefined|\`colors.overlay\` (default: \`hsla(0, 0%, 0%, 0.5)\`)|-|Optional|
|
|
23
|
+
|--c15t-switch-track|string \|undefined|\`colors.switchTrack\` (default: \`hsl(0, 0%, 85%)\`)|-|Optional|
|
|
24
|
+
|--c15t-switch-track-active|string \|undefined|\`colors.switchTrackActive\` (default: \`hsl(228, 100%, 60%)\`)|-|Optional|
|
|
25
|
+
|--c15t-switch-thumb|string \|undefined|\`colors.switchThumb\` (default: \`hsl(0, 0%, 100%)\`)|-|Optional|
|
|
26
|
+
|--c15t-font-family|string \|undefined|\`typography.fontFamily\` (default: \`system-ui, -apple-system, sans-serif\`)|-|Optional|
|
|
27
|
+
|--c15t-font-size-sm|string \|undefined|\`typography.fontSize.sm\` (default: \`0.875rem\`)|-|Optional|
|
|
28
|
+
|--c15t-font-size-base|string \|undefined|\`typography.fontSize.base\` (default: \`1rem\`)|-|Optional|
|
|
29
|
+
|--c15t-font-size-lg|string \|undefined|\`typography.fontSize.lg\` (default: \`1.125rem\`)|-|Optional|
|
|
30
|
+
|--c15t-font-weight-normal|string \|undefined|\`typography.fontWeight.normal\` (default: \`400\`)|-|Optional|
|
|
31
|
+
|--c15t-font-weight-medium|string \|undefined|\`typography.fontWeight.medium\` (default: \`500\`)|-|Optional|
|
|
32
|
+
|--c15t-font-weight-semibold|string \|undefined|\`typography.fontWeight.semibold\` (default: \`600\`)|-|Optional|
|
|
33
|
+
|--c15t-line-height-tight|string \|undefined|\`typography.lineHeight.tight\` (default: \`1.25\`)|-|Optional|
|
|
34
|
+
|--c15t-line-height-normal|string \|undefined|\`typography.lineHeight.normal\` (default: \`1.5\`)|-|Optional|
|
|
35
|
+
|--c15t-line-height-relaxed|string \|undefined|\`typography.lineHeight.relaxed\` (default: \`1.75\`)|-|Optional|
|
|
36
|
+
|--c15t-space-xs|string \|undefined|\`spacing.xs\` (default: \`0.25rem\`)|-|Optional|
|
|
37
|
+
|--c15t-space-sm|string \|undefined|\`spacing.sm\` (default: \`0.5rem\`)|-|Optional|
|
|
38
|
+
|--c15t-space-md|string \|undefined|\`spacing.md\` (default: \`1rem\`)|-|Optional|
|
|
39
|
+
|--c15t-space-lg|string \|undefined|\`spacing.lg\` (default: \`1.5rem\`)|-|Optional|
|
|
40
|
+
|--c15t-space-xl|string \|undefined|\`spacing.xl\` (default: \`2rem\`)|-|Optional|
|
|
41
|
+
|--c15t-radius-sm|string \|undefined|\`radius.sm\` (default: \`0.25rem\`)|-|Optional|
|
|
42
|
+
|--c15t-radius-md|string \|undefined|\`radius.md\` (default: \`0.5rem\`)|-|Optional|
|
|
43
|
+
|--c15t-radius-lg|string \|undefined|\`radius.lg\` (default: \`0.75rem\`)|-|Optional|
|
|
44
|
+
|--c15t-radius-full|string \|undefined|\`radius.full\` (default: \`9999px\`)|-|Optional|
|
|
45
|
+
|--c15t-shadow-sm|string \|undefined|\`shadows.sm\` (default: \`0 1px 2px hsla(0, 0%, 0%, 0.05)\`)|-|Optional|
|
|
46
|
+
|--c15t-shadow-md|string \|undefined|\`shadows.md\` (default: \`0 4px 12px hsla(0, 0%, 0%, 0.08)\`)|-|Optional|
|
|
47
|
+
|--c15t-shadow-lg|string \|undefined|\`shadows.lg\` (default: \`0 8px 24px hsla(0, 0%, 0%, 0.12)\`)|-|Optional|
|
|
48
|
+
|--c15t-duration-fast|string \|undefined|\`motion.duration.fast\` (default: \`100ms\`)|-|Optional|
|
|
49
|
+
|--c15t-duration-normal|string \|undefined|\`motion.duration.normal\` (default: \`200ms\`)|-|Optional|
|
|
50
|
+
|--c15t-duration-slow|string \|undefined|\`motion.duration.slow\` (default: \`300ms\`)|-|Optional|
|
|
51
|
+
|--c15t-easing|string \|undefined|\`motion.easing\` (default: \`cubic-bezier(0.4, 0, 0.2, 1)\`)|-|Optional|
|
|
52
|
+
|--c15t-easing-out|string \|undefined|\`motion.easingOut\` (default: \`cubic-bezier(0.215, 0.61, 0.355, 1)\`)|-|Optional|
|
|
53
|
+
|--c15t-easing-in-out|string \|undefined|\`motion.easingInOut\` (default: \`cubic-bezier(0.645, 0.045, 0.355, 1)\`)|-|Optional|
|
|
54
|
+
|--c15t-easing-spring|string \|undefined|\`motion.easingSpring\` (default: \`cubic-bezier(0.34, 1.56, 0.64, 1)\`)|-|Optional|
|
|
55
|
+
|
|
56
|
+
## Overriding Variables
|
|
57
|
+
|
|
58
|
+
Override in your stylesheet:
|
|
59
|
+
|
|
60
|
+
```css
|
|
61
|
+
:root {
|
|
62
|
+
--c15t-primary: #8b5cf6;
|
|
63
|
+
--c15t-surface: #fafafa;
|
|
64
|
+
--c15t-radius-md: 1rem;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* Dark mode overrides */
|
|
68
|
+
.dark,
|
|
69
|
+
.c15t-dark {
|
|
70
|
+
--c15t-primary: #a78bfa;
|
|
71
|
+
--c15t-surface: #18181b;
|
|
72
|
+
--c15t-text: #fafafa;
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Scoped Overrides
|
|
77
|
+
|
|
78
|
+
Target specific components by scoping variables:
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
<div className="checkout-consent">
|
|
82
|
+
<ConsentBanner />
|
|
83
|
+
</div>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
```css
|
|
87
|
+
/* Only affect c15t components inside .checkout-consent */
|
|
88
|
+
.checkout-consent {
|
|
89
|
+
--c15t-surface: #f0f9ff;
|
|
90
|
+
--c15t-radius-lg: 1.5rem;
|
|
91
|
+
}
|
|
92
|
+
```
|