@redacto.io/consent-sdk-react 10.3.1-beta.0 → 10.4.0-beta.1
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 +105 -12
- package/dist/{chunk-RG4PVVKF.mjs → chunk-DGMUTOWJ.mjs} +91 -58
- package/dist/index.js +109 -96
- package/dist/index.mjs +8 -26
- package/dist/privacy-center.d.mts +301 -15
- package/dist/privacy-center.d.ts +301 -15
- package/dist/privacy-center.js +4738 -2159
- package/dist/privacy-center.mjs +4589 -2122
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -974,23 +974,116 @@ import { RedactoPrivacyCenter } from "@redacto.io/consent-sdk-react/privacy-cent
|
|
|
974
974
|
|
|
975
975
|
**Props:**
|
|
976
976
|
|
|
977
|
-
| Prop
|
|
978
|
-
|
|
|
979
|
-
| `baseUrl`
|
|
980
|
-
| `ledgerBaseUrl`
|
|
981
|
-
| `slug`
|
|
982
|
-
| `accessToken`
|
|
983
|
-
| `refreshToken`
|
|
984
|
-
| `
|
|
985
|
-
| `
|
|
986
|
-
| `
|
|
987
|
-
| `
|
|
977
|
+
| Prop | Type | Required | Default | Description |
|
|
978
|
+
| ----------------- | ------------------------------------------------- | -------- | ------------------- | ----------- |
|
|
979
|
+
| `baseUrl` | `string` | Yes | - | Consent server base URL |
|
|
980
|
+
| `ledgerBaseUrl` | `string` | No | - | Go ledger base URL. When set, user consents, group purposes, receipts, and manage-consent route through the ledger, and the DSAR form's product picker is overlaid from ledger-served consents. Omit to use the legacy `/dsar/privacy-center/*` routes. |
|
|
981
|
+
| `slug` | `string` | Yes | - | Organisation slug |
|
|
982
|
+
| `accessToken` | `string` | No | - | JWT access token. Without one the Privacy Center waits for it, or shows its built-in sign-in when `builtInSignIn` is on (see [Sign-in](#privacy-center-sign-in)) |
|
|
983
|
+
| `refreshToken` | `string` | No | - | JWT refresh token |
|
|
984
|
+
| `organisationUuid`| `string` | No | - | Organisation UUID for sign-in and settings when there is no token; looked up from `slug` when omitted (also the sandbox org) |
|
|
985
|
+
| `workspaceUuid` | `string` | No | - | Workspace UUID for sign-in when there is no token; looked up from `slug` when omitted (also the sandbox workspace) |
|
|
986
|
+
| `onError` | `(error: Error) => boolean` | Yes | - | Error handler; return `true` if handled |
|
|
987
|
+
| `settings` | `PrivacyCenterSettings` | No | - | Overrides for the settings published from the console, merged field by field per group (see [Settings](#privacy-center-settings)). `theme` is kept as an alias for `branding.style` |
|
|
988
|
+
| `builtInSignIn` | `boolean` | No | `false` | Show the built-in OTP sign-in when there is no token. Off, the Privacy Center keeps its loading state until the host passes a token |
|
|
989
|
+
| `initialPage` | `"consent-manager" \| "form" \| "activity" \| "case-details" \| "notifications" \| "receipts"` | No | `"consent-manager"` | Page to render first; a section switched off in the settings falls back to the first enabled one |
|
|
990
|
+
| `onBack` | `"back" \| "signout"` | No | - | Behaviour of the navbar back/signout control |
|
|
991
|
+
| `onReady` | `(event: { signedIn: boolean }) => void` | No | - | Called once, when the first screen (sign-in or the Privacy Center) is on show |
|
|
992
|
+
| `onConsentChange` | `(change: PrivacyCenterConsentChange) => void` | No | - | Called after a consent was withdrawn, re-granted or renewed |
|
|
993
|
+
| `onRequestSubmit` | `(request: PrivacyCenterRequestSubmission) => void` | No | - | Called after a data request (case) was created |
|
|
994
|
+
| `onSignOut` | `(event: { reason: "user" \| "timeout" \| "session-expired" }) => void` | No | - | Called when the visitor is signed out |
|
|
995
|
+
|
|
996
|
+
The callbacks never throw into the Privacy Center: an exception in a handler is logged and ignored. Their payloads:
|
|
997
|
+
|
|
998
|
+
```ts
|
|
999
|
+
type PrivacyCenterConsentChange = {
|
|
1000
|
+
action: "revoke" | "regrant" | "renew";
|
|
1001
|
+
purposeUuid: string;
|
|
1002
|
+
productUuid: string | null;
|
|
1003
|
+
dataElementUuids: readonly string[]; // empty when the change covered the whole purpose
|
|
1004
|
+
nominatorUuid: string | null; // set when acting on behalf of a nominator
|
|
1005
|
+
};
|
|
1006
|
+
|
|
1007
|
+
type PrivacyCenterRequestSubmission = {
|
|
1008
|
+
caseId: string; // the case id shown to the visitor
|
|
1009
|
+
caseUuid: string;
|
|
1010
|
+
requestType: "access" | "correction" | "erasure" | "nomination" | "grievance";
|
|
1011
|
+
productUuid: string | null; // null for nomination and grievance
|
|
1012
|
+
};
|
|
1013
|
+
```
|
|
1014
|
+
|
|
1015
|
+
<a id="privacy-center-settings"></a>
|
|
1016
|
+
|
|
1017
|
+
### Settings
|
|
1018
|
+
|
|
1019
|
+
The Privacy Center reads the settings an admin publishes in the Redacto console (Rights Management › Privacy Center › Settings) from the public endpoint `GET {baseUrl}/public/organisations/{organisation_uuid}/privacy-center-settings/?lang={language}`. The organisation comes from `organisationUuid`, the access token, the session, or a lookup by `slug`. The settings are fetched again, localised, when the visitor changes language, and cached in memory per organisation and language.
|
|
1020
|
+
|
|
1021
|
+
Rendering never waits for them: the Privacy Center starts with the defaults and swaps the published values in when they arrive. **With nothing published, or if the request fails, it looks and behaves exactly as before settings existed.**
|
|
1022
|
+
|
|
1023
|
+
What the settings control:
|
|
1024
|
+
|
|
1025
|
+
- **Branding**: classic or glass style, the organisation's own colours, font, name and logo instead of the workspace branding, logo height and corner radius.
|
|
1026
|
+
- **Menu**: section order, labels, and which sections are on. A section switched off disappears from the menu and can't be opened; switching off `notifications` hides the bell too.
|
|
1027
|
+
- **Welcome message** at the top of the consent manager.
|
|
1028
|
+
- **Requests**: which request types the form offers, in what order and under what names (narrowed to the server's own list when it sends one), which grievance categories are offered, whether erasure also revokes consent, and the default withdraw warning (a purpose's own warning still wins).
|
|
1029
|
+
- **Languages**: which languages the switcher offers, whether it shows, the default language and whether the browser's language is detected. Once settings are published (or the host overrides them), Urdu, Sindhi and Kashmiri render right to left; with nothing published the text direction is inherited as before.
|
|
1030
|
+
- **Session timeout**: sign the visitor out after 15, 30 or 60 minutes without activity.
|
|
1031
|
+
- **Footer**: links, privacy policy, grievance contact, copyright and "Powered by".
|
|
1032
|
+
- **Sign-in screen**: layout, background, copy, channels and default country code (see below).
|
|
1033
|
+
- **Custom CSS** (see below).
|
|
1034
|
+
|
|
1035
|
+
Copy can use `{brand}`, `{legal}`, `{year}`, `{contact}` and `{name}`; `resolvePlaceholders(text, context)` is exported for the same substitution in your own UI.
|
|
1036
|
+
|
|
1037
|
+
Override any of it in code; each group merges field by field over what was published:
|
|
1038
|
+
|
|
1039
|
+
```tsx
|
|
1040
|
+
<RedactoPrivacyCenter
|
|
1041
|
+
baseUrl={BASE_URL}
|
|
1042
|
+
slug="acme-co"
|
|
1043
|
+
accessToken={accessToken}
|
|
1044
|
+
onError={() => false}
|
|
1045
|
+
settings={{
|
|
1046
|
+
branding: { style: "glass" },
|
|
1047
|
+
portal: { welcome_enabled: true, session_timeout_minutes: 30 },
|
|
1048
|
+
languages: { enabled: ["en", "hi"], default: "en" },
|
|
1049
|
+
}}
|
|
1050
|
+
/>
|
|
1051
|
+
```
|
|
1052
|
+
|
|
1053
|
+
The full shape is exported as `ResolvedPrivacyCenterSettings` (with `DEFAULT_PRIVACY_CENTER_SETTINGS`); `PrivacyCenterSettings` is the override type.
|
|
1054
|
+
|
|
1055
|
+
<a id="privacy-center-sign-in"></a>
|
|
1056
|
+
|
|
1057
|
+
### Sign-in
|
|
1058
|
+
|
|
1059
|
+
Pass `builtInSignIn` and, with no `accessToken`, the Privacy Center shows its own sign-in instead of a loader: the visitor enters a mobile number or email, receives a one-time code (resend after 50 seconds) and is signed straight in with the tokens it issues. Layout (card, split or minimal), background, copy, channels (SMS, email or both), default country code, notice line and support link come from the `sign_in` settings. It is off by default, so a host that passes its token a moment after mounting never flashes a sign-in screen.
|
|
1060
|
+
|
|
1061
|
+
```tsx
|
|
1062
|
+
<RedactoPrivacyCenter baseUrl={BASE_URL} slug="acme-co" builtInSignIn onError={() => false} />
|
|
1063
|
+
```
|
|
1064
|
+
|
|
1065
|
+
### Custom CSS
|
|
1066
|
+
|
|
1067
|
+
`custom_css` from the settings is injected inside an `@scope` for this Privacy Center only, after the same safety checks as a notice's custom CSS, so it never reaches the host page. Target these stable parts:
|
|
1068
|
+
|
|
1069
|
+
| Part | Element |
|
|
1070
|
+
| --- | --- |
|
|
1071
|
+
| `[data-redacto-part="topbar"]` | Top bar |
|
|
1072
|
+
| `[data-redacto-part="nav"]` / `"nav-item"` | Menu and each menu entry |
|
|
1073
|
+
| `[data-redacto-part="welcome"]` | Welcome message |
|
|
1074
|
+
| `[data-redacto-part="consent-card"]` | Consent manager card (and each product card on phones) |
|
|
1075
|
+
| `[data-redacto-part="request-form"]` | Data request form |
|
|
1076
|
+
| `[data-redacto-part="button-primary"]` | Primary buttons |
|
|
1077
|
+
| `[data-redacto-part="footer"]` | Footer |
|
|
1078
|
+
| `[data-redacto-part="signin-card"]` | Sign-in form |
|
|
1079
|
+
|
|
1080
|
+
The `--pc-*` theme variables are scoped the same way: workspace branding and the settings' colours apply to this Privacy Center (and its menus and tooltips) without writing to the host page's `<html>`.
|
|
988
1081
|
|
|
989
1082
|
<a id="privacy-center-appearance"></a>
|
|
990
1083
|
|
|
991
1084
|
### Theme
|
|
992
1085
|
|
|
993
|
-
`settings.theme` picks the visual style; colours, logo and brand name
|
|
1086
|
+
`settings.theme` (or `settings.branding.style`) picks the visual style; colours, logo and brand name come from the workspace's branding unless the published settings replace them.
|
|
994
1087
|
|
|
995
1088
|
- **`classic`** (default): the standard look.
|
|
996
1089
|
- **`glass`**: frosted, translucent surfaces over a soft wash of the brand colour, pill-shaped controls and motion. On phones, dialogs and the navigation menu rise as bottom sheets; on wider screens dialogs float as centred cards. Motion respects `prefers-reduced-motion`.
|
|
@@ -218,6 +218,8 @@ var NOTICE_DISALLOWED_CSS_TOKENS = [
|
|
|
218
218
|
"expression(",
|
|
219
219
|
"behavior:"
|
|
220
220
|
];
|
|
221
|
+
var CSS_SCOPE_AT_RULE = "@scope";
|
|
222
|
+
var CSS_STRING_SPECIALS_RE = /["\\\n]/g;
|
|
221
223
|
var CSS_ESCAPE_RE = /\\([0-9a-f]{1,6})(?:\r\n|[ \t\r\n\f])?|\\([\s\S])/gi;
|
|
222
224
|
var CSS_BRACKET_PAIRS = {
|
|
223
225
|
"{": "}",
|
|
@@ -255,6 +257,63 @@ var buildTtsCssVariables = (colors) => Object.fromEntries(
|
|
|
255
257
|
);
|
|
256
258
|
var buildTtsRootAttributes = (colors) => colors.tts_highlight_text ? { [TTS_TEXT_ATTRIBUTE]: "" } : {};
|
|
257
259
|
|
|
260
|
+
// src/shared/appearance/customCss.ts
|
|
261
|
+
var decodeCssEscapes = (value) => value.replace(
|
|
262
|
+
CSS_ESCAPE_RE,
|
|
263
|
+
(_match, hex, literal) => {
|
|
264
|
+
if (hex === void 0) {
|
|
265
|
+
return literal;
|
|
266
|
+
}
|
|
267
|
+
const codePoint = Number.parseInt(hex, HEX_RADIX);
|
|
268
|
+
if (codePoint === 0 || codePoint > MAX_CODE_POINT || codePoint >= SURROGATE_MIN && codePoint <= SURROGATE_MAX) {
|
|
269
|
+
return CSS_REPLACEMENT_CHARACTER;
|
|
270
|
+
}
|
|
271
|
+
return String.fromCodePoint(codePoint);
|
|
272
|
+
}
|
|
273
|
+
);
|
|
274
|
+
var hasBalancedBlocks = (css) => {
|
|
275
|
+
const open = [];
|
|
276
|
+
let quote;
|
|
277
|
+
let inComment = false;
|
|
278
|
+
for (let index = 0; index < css.length; index += 1) {
|
|
279
|
+
const char = css[index];
|
|
280
|
+
if (inComment) {
|
|
281
|
+
if (char === "*" && css[index + 1] === "/") {
|
|
282
|
+
inComment = false;
|
|
283
|
+
index += 1;
|
|
284
|
+
}
|
|
285
|
+
} else if (char === "\\") {
|
|
286
|
+
index += 1;
|
|
287
|
+
} else if (quote) {
|
|
288
|
+
if (char === quote) {
|
|
289
|
+
quote = void 0;
|
|
290
|
+
} else if (CSS_NEWLINES.includes(char)) {
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
} else if (char === "/" && css[index + 1] === "*") {
|
|
294
|
+
inComment = true;
|
|
295
|
+
index += 1;
|
|
296
|
+
} else if (CSS_QUOTES.includes(char)) {
|
|
297
|
+
quote = char;
|
|
298
|
+
} else if (char in CSS_BRACKET_PAIRS) {
|
|
299
|
+
open.push(CSS_BRACKET_PAIRS[char]);
|
|
300
|
+
} else if (CSS_CLOSING_BRACKETS.includes(char) && open.pop() !== char) {
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return open.length === 0 && !quote && !inComment;
|
|
305
|
+
};
|
|
306
|
+
var isSafeCustomCss = (css) => {
|
|
307
|
+
if (css.length > NOTICE_CUSTOM_CSS_MAX_LENGTH || !hasBalancedBlocks(css)) {
|
|
308
|
+
return false;
|
|
309
|
+
}
|
|
310
|
+
const lowered = css.toLowerCase();
|
|
311
|
+
const decoded = decodeCssEscapes(css).toLowerCase();
|
|
312
|
+
return NOTICE_DISALLOWED_CSS_TOKENS.every(
|
|
313
|
+
(token) => !lowered.includes(token) && !decoded.includes(token)
|
|
314
|
+
);
|
|
315
|
+
};
|
|
316
|
+
|
|
258
317
|
// src/shared/appearance/registry.ts
|
|
259
318
|
var DEFAULT_APPEARANCE = "classic";
|
|
260
319
|
var APPEARANCE_ATTRIBUTE = "data-redacto-appearance";
|
|
@@ -325,63 +384,6 @@ var prefersReducedMotion = () => {
|
|
|
325
384
|
return typeof window !== "undefined" && ((_b = (_a = window.matchMedia) == null ? void 0 : _a.call(window, "(prefers-reduced-motion: reduce)")) == null ? void 0 : _b.matches) === true;
|
|
326
385
|
};
|
|
327
386
|
|
|
328
|
-
// src/shared/appearance/customCss.ts
|
|
329
|
-
var decodeCssEscapes = (value) => value.replace(
|
|
330
|
-
CSS_ESCAPE_RE,
|
|
331
|
-
(_match, hex, literal) => {
|
|
332
|
-
if (hex === void 0) {
|
|
333
|
-
return literal;
|
|
334
|
-
}
|
|
335
|
-
const codePoint = Number.parseInt(hex, HEX_RADIX);
|
|
336
|
-
if (codePoint === 0 || codePoint > MAX_CODE_POINT || codePoint >= SURROGATE_MIN && codePoint <= SURROGATE_MAX) {
|
|
337
|
-
return CSS_REPLACEMENT_CHARACTER;
|
|
338
|
-
}
|
|
339
|
-
return String.fromCodePoint(codePoint);
|
|
340
|
-
}
|
|
341
|
-
);
|
|
342
|
-
var hasBalancedBlocks = (css) => {
|
|
343
|
-
const open = [];
|
|
344
|
-
let quote;
|
|
345
|
-
let inComment = false;
|
|
346
|
-
for (let index = 0; index < css.length; index += 1) {
|
|
347
|
-
const char = css[index];
|
|
348
|
-
if (inComment) {
|
|
349
|
-
if (char === "*" && css[index + 1] === "/") {
|
|
350
|
-
inComment = false;
|
|
351
|
-
index += 1;
|
|
352
|
-
}
|
|
353
|
-
} else if (char === "\\") {
|
|
354
|
-
index += 1;
|
|
355
|
-
} else if (quote) {
|
|
356
|
-
if (char === quote) {
|
|
357
|
-
quote = void 0;
|
|
358
|
-
} else if (CSS_NEWLINES.includes(char)) {
|
|
359
|
-
return false;
|
|
360
|
-
}
|
|
361
|
-
} else if (char === "/" && css[index + 1] === "*") {
|
|
362
|
-
inComment = true;
|
|
363
|
-
index += 1;
|
|
364
|
-
} else if (CSS_QUOTES.includes(char)) {
|
|
365
|
-
quote = char;
|
|
366
|
-
} else if (char in CSS_BRACKET_PAIRS) {
|
|
367
|
-
open.push(CSS_BRACKET_PAIRS[char]);
|
|
368
|
-
} else if (CSS_CLOSING_BRACKETS.includes(char) && open.pop() !== char) {
|
|
369
|
-
return false;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
return open.length === 0 && !quote && !inComment;
|
|
373
|
-
};
|
|
374
|
-
var isSafeCustomCss = (css) => {
|
|
375
|
-
if (css.length > NOTICE_CUSTOM_CSS_MAX_LENGTH || !hasBalancedBlocks(css)) {
|
|
376
|
-
return false;
|
|
377
|
-
}
|
|
378
|
-
const lowered = css.toLowerCase();
|
|
379
|
-
const decoded = decodeCssEscapes(css).toLowerCase();
|
|
380
|
-
return NOTICE_DISALLOWED_CSS_TOKENS.every(
|
|
381
|
-
(token) => !lowered.includes(token) && !decoded.includes(token)
|
|
382
|
-
);
|
|
383
|
-
};
|
|
384
|
-
|
|
385
387
|
// src/shared/appearance/resolve.ts
|
|
386
388
|
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
387
389
|
var pickColors = (raw) => {
|
|
@@ -687,6 +689,36 @@ var SANDBOX_TOKEN_HEADER = "X-Consent-Token";
|
|
|
687
689
|
var DEFAULT_CONSENT_API_BASE_URL = "https://api.redacto.io/consent";
|
|
688
690
|
var USER_SERVICE_PATH = "/user/api/0";
|
|
689
691
|
|
|
692
|
+
// src/shared/appearance/scopedCss.ts
|
|
693
|
+
var escapesScope = (style) => {
|
|
694
|
+
var _a, _b;
|
|
695
|
+
return Array.from((_b = (_a = style.sheet) == null ? void 0 : _a.cssRules) != null ? _b : []).some(
|
|
696
|
+
(rule) => !rule.cssText.startsWith(CSS_SCOPE_AT_RULE)
|
|
697
|
+
);
|
|
698
|
+
};
|
|
699
|
+
var applyScopedCustomCss = ({
|
|
700
|
+
scopeAttribute,
|
|
701
|
+
scopeId,
|
|
702
|
+
markerAttribute,
|
|
703
|
+
css
|
|
704
|
+
}) => {
|
|
705
|
+
if (typeof document === "undefined" || !css.trim() || !isSafeCustomCss(css)) {
|
|
706
|
+
return () => void 0;
|
|
707
|
+
}
|
|
708
|
+
const id = scopeId.replace(CSS_STRING_SPECIALS_RE, "\\$&");
|
|
709
|
+
const style = document.createElement("style");
|
|
710
|
+
style.setAttribute(markerAttribute, scopeId);
|
|
711
|
+
style.textContent = `${CSS_SCOPE_AT_RULE} ([${scopeAttribute}="${id}"]) {
|
|
712
|
+
${css}
|
|
713
|
+
}`;
|
|
714
|
+
document.head.appendChild(style);
|
|
715
|
+
if (escapesScope(style)) {
|
|
716
|
+
style.remove();
|
|
717
|
+
return () => void 0;
|
|
718
|
+
}
|
|
719
|
+
return () => style.remove();
|
|
720
|
+
};
|
|
721
|
+
|
|
690
722
|
export {
|
|
691
723
|
SANDBOX_TOKEN_HEADER,
|
|
692
724
|
withIdempotencyKey,
|
|
@@ -724,5 +756,6 @@ export {
|
|
|
724
756
|
Collapse,
|
|
725
757
|
configureNoticeFonts,
|
|
726
758
|
loadNoticeWebfont,
|
|
727
|
-
useMediaQuery
|
|
759
|
+
useMediaQuery,
|
|
760
|
+
applyScopedCustomCss
|
|
728
761
|
};
|
package/dist/index.js
CHANGED
|
@@ -1297,6 +1297,96 @@ var noticeChromeCopy = (language) => {
|
|
|
1297
1297
|
};
|
|
1298
1298
|
var NOTICE_CHROME_LANGUAGES = Object.keys(TRANSLATIONS);
|
|
1299
1299
|
|
|
1300
|
+
// src/shared/appearance/constants.ts
|
|
1301
|
+
var NOTICE_COLOR_KEYS = [
|
|
1302
|
+
"background",
|
|
1303
|
+
"surface",
|
|
1304
|
+
"heading",
|
|
1305
|
+
"text",
|
|
1306
|
+
"muted_text",
|
|
1307
|
+
"link",
|
|
1308
|
+
"border",
|
|
1309
|
+
"overlay",
|
|
1310
|
+
"accept_all_bg",
|
|
1311
|
+
"accept_all_text",
|
|
1312
|
+
"accept_bg",
|
|
1313
|
+
"accept_text",
|
|
1314
|
+
"decline_bg",
|
|
1315
|
+
"decline_text",
|
|
1316
|
+
"decline_border",
|
|
1317
|
+
"language_bg",
|
|
1318
|
+
"language_text",
|
|
1319
|
+
"language_selected_bg",
|
|
1320
|
+
"language_selected_text",
|
|
1321
|
+
"toggle_on",
|
|
1322
|
+
"toggle_off",
|
|
1323
|
+
"toggle_knob",
|
|
1324
|
+
"tts_highlight_bg",
|
|
1325
|
+
"tts_highlight_text"
|
|
1326
|
+
];
|
|
1327
|
+
var NOTICE_SELECTION_CONTROLS = ["checkbox", "radio", "dropdown"];
|
|
1328
|
+
var NOTICE_CONTROL_STYLES = ["checkbox", "switch"];
|
|
1329
|
+
var NOTICE_RADIUS_MIN = 0;
|
|
1330
|
+
var NOTICE_RADIUS_MAX = 28;
|
|
1331
|
+
var NOTICE_MOBILE_LAYOUTS = ["modal", "sheet"];
|
|
1332
|
+
var NOTICE_DESKTOP_POSITIONS = [
|
|
1333
|
+
"center",
|
|
1334
|
+
"bottom-right",
|
|
1335
|
+
"bottom-left",
|
|
1336
|
+
"bottom-bar"
|
|
1337
|
+
];
|
|
1338
|
+
var NOTICE_BACKDROPS = ["dim", "none"];
|
|
1339
|
+
var NOTICE_PHONE_FOOTERS = ["stacked", "paired"];
|
|
1340
|
+
var NOTICE_TEXT_SCALES = ["sm", "md", "lg"];
|
|
1341
|
+
var DEFAULT_TEXT_SCALE = "md";
|
|
1342
|
+
var DEFAULT_DESKTOP_POSITION = "center";
|
|
1343
|
+
var NOTICE_TEXT_SCALE_FACTORS = {
|
|
1344
|
+
sm: 0.92,
|
|
1345
|
+
md: 1,
|
|
1346
|
+
lg: 1.1
|
|
1347
|
+
};
|
|
1348
|
+
var NOTICE_WIDTH_MIN = 320;
|
|
1349
|
+
var NOTICE_WIDTH_MAX = 960;
|
|
1350
|
+
var NOTICE_LOGO_SIZE_MIN = 16;
|
|
1351
|
+
var NOTICE_LOGO_SIZE_MAX = 96;
|
|
1352
|
+
var NOTICE_CUSTOM_CSS_MAX_LENGTH = 2e4;
|
|
1353
|
+
var NOTICE_DISALLOWED_CSS_TOKENS = [
|
|
1354
|
+
"</style",
|
|
1355
|
+
"@import",
|
|
1356
|
+
"javascript:",
|
|
1357
|
+
"expression(",
|
|
1358
|
+
"behavior:"
|
|
1359
|
+
];
|
|
1360
|
+
var CSS_SCOPE_AT_RULE = "@scope";
|
|
1361
|
+
var CSS_STRING_SPECIALS_RE = /["\\\n]/g;
|
|
1362
|
+
var CSS_ESCAPE_RE = /\\([0-9a-f]{1,6})(?:\r\n|[ \t\r\n\f])?|\\([\s\S])/gi;
|
|
1363
|
+
var CSS_BRACKET_PAIRS = {
|
|
1364
|
+
"{": "}",
|
|
1365
|
+
"(": ")",
|
|
1366
|
+
"[": "]"
|
|
1367
|
+
};
|
|
1368
|
+
var CSS_CLOSING_BRACKETS = Object.values(CSS_BRACKET_PAIRS);
|
|
1369
|
+
var CSS_QUOTES = ['"', "'"];
|
|
1370
|
+
var CSS_NEWLINES = ["\n", "\r", "\f"];
|
|
1371
|
+
var CSS_REPLACEMENT_CHARACTER = "\uFFFD";
|
|
1372
|
+
var MAX_CODE_POINT = 1114111;
|
|
1373
|
+
var HEX_RADIX = 16;
|
|
1374
|
+
var SURROGATE_MIN = 55296;
|
|
1375
|
+
var SURROGATE_MAX = 57343;
|
|
1376
|
+
var NOTICE_HEX_COLOR_RE = /^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i;
|
|
1377
|
+
var DEFAULT_TTS_HIGHLIGHT_BG = "#FFF9C4";
|
|
1378
|
+
var NOTICE_THEME_VARS = {
|
|
1379
|
+
accent: "--redacto-accent",
|
|
1380
|
+
controlOff: "--redacto-control-off",
|
|
1381
|
+
knob: "--redacto-toggle-knob",
|
|
1382
|
+
ttsBackground: "--redacto-tts-bg",
|
|
1383
|
+
ttsText: "--redacto-tts-text"
|
|
1384
|
+
};
|
|
1385
|
+
var THEMED_ACCENT = `var(${NOTICE_THEME_VARS.accent}, #4f87ff)`;
|
|
1386
|
+
var THEMED_CONTROL_OFF = `var(${NOTICE_THEME_VARS.controlOff}, #d0d5dd)`;
|
|
1387
|
+
var THEMED_TTS_BACKGROUND = `var(${NOTICE_THEME_VARS.ttsBackground}, ${DEFAULT_TTS_HIGHLIGHT_BG})`;
|
|
1388
|
+
var TTS_TEXT_ATTRIBUTE = "data-redacto-tts-text";
|
|
1389
|
+
|
|
1300
1390
|
// src/RedactoNoticeConsent/constants.ts
|
|
1301
1391
|
var DEFAULT_LOGO_POSITION = "left";
|
|
1302
1392
|
var DEFAULT_PURPOSE_SECTION_HEADING = "Manage What You Share";
|
|
@@ -1414,8 +1504,6 @@ var MOTION_ATTRIBUTE = "data-redacto-motion";
|
|
|
1414
1504
|
var MOTION_OFF = "off";
|
|
1415
1505
|
var NOTICE_ID_ATTRIBUTE = "data-redacto-notice-id";
|
|
1416
1506
|
var CUSTOM_CSS_ATTRIBUTE = "data-redacto-notice-css";
|
|
1417
|
-
var CSS_SCOPE_AT_RULE = "@scope";
|
|
1418
|
-
var CSS_STRING_SPECIALS_RE = /["\\\n]/g;
|
|
1419
1507
|
var PX_LENGTH_RE = /^(\d+(?:\.\d+)?)px$/;
|
|
1420
1508
|
var FONT_SIZE_PRECISION = 10;
|
|
1421
1509
|
var DARK_SCHEME_QUERY = "(prefers-color-scheme: dark)";
|
|
@@ -2153,94 +2241,6 @@ var NoticeFooter = ({
|
|
|
2153
2241
|
] });
|
|
2154
2242
|
};
|
|
2155
2243
|
|
|
2156
|
-
// src/shared/appearance/constants.ts
|
|
2157
|
-
var NOTICE_COLOR_KEYS = [
|
|
2158
|
-
"background",
|
|
2159
|
-
"surface",
|
|
2160
|
-
"heading",
|
|
2161
|
-
"text",
|
|
2162
|
-
"muted_text",
|
|
2163
|
-
"link",
|
|
2164
|
-
"border",
|
|
2165
|
-
"overlay",
|
|
2166
|
-
"accept_all_bg",
|
|
2167
|
-
"accept_all_text",
|
|
2168
|
-
"accept_bg",
|
|
2169
|
-
"accept_text",
|
|
2170
|
-
"decline_bg",
|
|
2171
|
-
"decline_text",
|
|
2172
|
-
"decline_border",
|
|
2173
|
-
"language_bg",
|
|
2174
|
-
"language_text",
|
|
2175
|
-
"language_selected_bg",
|
|
2176
|
-
"language_selected_text",
|
|
2177
|
-
"toggle_on",
|
|
2178
|
-
"toggle_off",
|
|
2179
|
-
"toggle_knob",
|
|
2180
|
-
"tts_highlight_bg",
|
|
2181
|
-
"tts_highlight_text"
|
|
2182
|
-
];
|
|
2183
|
-
var NOTICE_SELECTION_CONTROLS = ["checkbox", "radio", "dropdown"];
|
|
2184
|
-
var NOTICE_CONTROL_STYLES = ["checkbox", "switch"];
|
|
2185
|
-
var NOTICE_RADIUS_MIN = 0;
|
|
2186
|
-
var NOTICE_RADIUS_MAX = 28;
|
|
2187
|
-
var NOTICE_MOBILE_LAYOUTS = ["modal", "sheet"];
|
|
2188
|
-
var NOTICE_DESKTOP_POSITIONS = [
|
|
2189
|
-
"center",
|
|
2190
|
-
"bottom-right",
|
|
2191
|
-
"bottom-left",
|
|
2192
|
-
"bottom-bar"
|
|
2193
|
-
];
|
|
2194
|
-
var NOTICE_BACKDROPS = ["dim", "none"];
|
|
2195
|
-
var NOTICE_PHONE_FOOTERS = ["stacked", "paired"];
|
|
2196
|
-
var NOTICE_TEXT_SCALES = ["sm", "md", "lg"];
|
|
2197
|
-
var DEFAULT_TEXT_SCALE = "md";
|
|
2198
|
-
var DEFAULT_DESKTOP_POSITION = "center";
|
|
2199
|
-
var NOTICE_TEXT_SCALE_FACTORS = {
|
|
2200
|
-
sm: 0.92,
|
|
2201
|
-
md: 1,
|
|
2202
|
-
lg: 1.1
|
|
2203
|
-
};
|
|
2204
|
-
var NOTICE_WIDTH_MIN = 320;
|
|
2205
|
-
var NOTICE_WIDTH_MAX = 960;
|
|
2206
|
-
var NOTICE_LOGO_SIZE_MIN = 16;
|
|
2207
|
-
var NOTICE_LOGO_SIZE_MAX = 96;
|
|
2208
|
-
var NOTICE_CUSTOM_CSS_MAX_LENGTH = 2e4;
|
|
2209
|
-
var NOTICE_DISALLOWED_CSS_TOKENS = [
|
|
2210
|
-
"</style",
|
|
2211
|
-
"@import",
|
|
2212
|
-
"javascript:",
|
|
2213
|
-
"expression(",
|
|
2214
|
-
"behavior:"
|
|
2215
|
-
];
|
|
2216
|
-
var CSS_ESCAPE_RE = /\\([0-9a-f]{1,6})(?:\r\n|[ \t\r\n\f])?|\\([\s\S])/gi;
|
|
2217
|
-
var CSS_BRACKET_PAIRS = {
|
|
2218
|
-
"{": "}",
|
|
2219
|
-
"(": ")",
|
|
2220
|
-
"[": "]"
|
|
2221
|
-
};
|
|
2222
|
-
var CSS_CLOSING_BRACKETS = Object.values(CSS_BRACKET_PAIRS);
|
|
2223
|
-
var CSS_QUOTES = ['"', "'"];
|
|
2224
|
-
var CSS_NEWLINES = ["\n", "\r", "\f"];
|
|
2225
|
-
var CSS_REPLACEMENT_CHARACTER = "\uFFFD";
|
|
2226
|
-
var MAX_CODE_POINT = 1114111;
|
|
2227
|
-
var HEX_RADIX = 16;
|
|
2228
|
-
var SURROGATE_MIN = 55296;
|
|
2229
|
-
var SURROGATE_MAX = 57343;
|
|
2230
|
-
var NOTICE_HEX_COLOR_RE = /^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i;
|
|
2231
|
-
var DEFAULT_TTS_HIGHLIGHT_BG = "#FFF9C4";
|
|
2232
|
-
var NOTICE_THEME_VARS = {
|
|
2233
|
-
accent: "--redacto-accent",
|
|
2234
|
-
controlOff: "--redacto-control-off",
|
|
2235
|
-
knob: "--redacto-toggle-knob",
|
|
2236
|
-
ttsBackground: "--redacto-tts-bg",
|
|
2237
|
-
ttsText: "--redacto-tts-text"
|
|
2238
|
-
};
|
|
2239
|
-
var THEMED_ACCENT = `var(${NOTICE_THEME_VARS.accent}, #4f87ff)`;
|
|
2240
|
-
var THEMED_CONTROL_OFF = `var(${NOTICE_THEME_VARS.controlOff}, #d0d5dd)`;
|
|
2241
|
-
var THEMED_TTS_BACKGROUND = `var(${NOTICE_THEME_VARS.ttsBackground}, ${DEFAULT_TTS_HIGHLIGHT_BG})`;
|
|
2242
|
-
var TTS_TEXT_ATTRIBUTE = "data-redacto-tts-text";
|
|
2243
|
-
|
|
2244
2244
|
// src/shared/appearance/ttsCssVariables.ts
|
|
2245
2245
|
var buildTtsCssVariables = (colors) => Object.fromEntries(
|
|
2246
2246
|
[
|
|
@@ -4884,21 +4884,26 @@ var showsNoticePolicyLink = (productCount, entryCount) => entryCount === 0 || pr
|
|
|
4884
4884
|
// src/RedactoNoticeConsent/useNoticeAppearance.ts
|
|
4885
4885
|
var import_react7 = require("react");
|
|
4886
4886
|
|
|
4887
|
-
// src/
|
|
4887
|
+
// src/shared/appearance/scopedCss.ts
|
|
4888
4888
|
var escapesScope = (style) => {
|
|
4889
4889
|
var _a, _b;
|
|
4890
4890
|
return Array.from((_b = (_a = style.sheet) == null ? void 0 : _a.cssRules) != null ? _b : []).some(
|
|
4891
4891
|
(rule) => !rule.cssText.startsWith(CSS_SCOPE_AT_RULE)
|
|
4892
4892
|
);
|
|
4893
4893
|
};
|
|
4894
|
-
var
|
|
4895
|
-
|
|
4894
|
+
var applyScopedCustomCss = ({
|
|
4895
|
+
scopeAttribute,
|
|
4896
|
+
scopeId,
|
|
4897
|
+
markerAttribute,
|
|
4898
|
+
css: css3
|
|
4899
|
+
}) => {
|
|
4900
|
+
if (typeof document === "undefined" || !css3.trim() || !isSafeCustomCss(css3)) {
|
|
4896
4901
|
return () => void 0;
|
|
4897
4902
|
}
|
|
4898
|
-
const id =
|
|
4903
|
+
const id = scopeId.replace(CSS_STRING_SPECIALS_RE, "\\$&");
|
|
4899
4904
|
const style = document.createElement("style");
|
|
4900
|
-
style.setAttribute(
|
|
4901
|
-
style.textContent = `${CSS_SCOPE_AT_RULE} ([${
|
|
4905
|
+
style.setAttribute(markerAttribute, scopeId);
|
|
4906
|
+
style.textContent = `${CSS_SCOPE_AT_RULE} ([${scopeAttribute}="${id}"]) {
|
|
4902
4907
|
${css3}
|
|
4903
4908
|
}`;
|
|
4904
4909
|
document.head.appendChild(style);
|
|
@@ -4909,6 +4914,14 @@ ${css3}
|
|
|
4909
4914
|
return () => style.remove();
|
|
4910
4915
|
};
|
|
4911
4916
|
|
|
4917
|
+
// src/RedactoNoticeConsent/services/customCss.ts
|
|
4918
|
+
var applyNoticeCustomCss = (noticeId, css3) => applyScopedCustomCss({
|
|
4919
|
+
scopeAttribute: NOTICE_ID_ATTRIBUTE,
|
|
4920
|
+
scopeId: noticeId,
|
|
4921
|
+
markerAttribute: CUSTOM_CSS_ATTRIBUTE,
|
|
4922
|
+
css: css3
|
|
4923
|
+
});
|
|
4924
|
+
|
|
4912
4925
|
// src/RedactoNoticeConsent/utils/mergeHostSettings.ts
|
|
4913
4926
|
var definedColors = (colors) => Object.fromEntries(
|
|
4914
4927
|
Object.entries(colors).filter(([, value]) => Boolean(value))
|
package/dist/index.mjs
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
THEMED_CONTROL_OFF,
|
|
16
16
|
THEMED_TTS_BACKGROUND,
|
|
17
17
|
TTS_TEXT_ATTRIBUTE,
|
|
18
|
+
applyScopedCustomCss,
|
|
18
19
|
buildTtsCssVariables,
|
|
19
20
|
buildTtsRootAttributes,
|
|
20
21
|
configureNoticeFonts,
|
|
@@ -33,7 +34,7 @@ import {
|
|
|
33
34
|
withAlpha,
|
|
34
35
|
withColorScheme,
|
|
35
36
|
withIdempotencyKey
|
|
36
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-DGMUTOWJ.mjs";
|
|
37
38
|
import {
|
|
38
39
|
NOTICE_FONT_ROOT_PROPS,
|
|
39
40
|
REQUIRED_MARKER_ARIA_LABEL,
|
|
@@ -1312,8 +1313,6 @@ var MOTION_ATTRIBUTE = "data-redacto-motion";
|
|
|
1312
1313
|
var MOTION_OFF = "off";
|
|
1313
1314
|
var NOTICE_ID_ATTRIBUTE = "data-redacto-notice-id";
|
|
1314
1315
|
var CUSTOM_CSS_ATTRIBUTE = "data-redacto-notice-css";
|
|
1315
|
-
var CSS_SCOPE_AT_RULE = "@scope";
|
|
1316
|
-
var CSS_STRING_SPECIALS_RE = /["\\\n]/g;
|
|
1317
1316
|
var PX_LENGTH_RE = /^(\d+(?:\.\d+)?)px$/;
|
|
1318
1317
|
var FONT_SIZE_PRECISION = 10;
|
|
1319
1318
|
var DARK_SCHEME_QUERY = "(prefers-color-scheme: dark)";
|
|
@@ -3989,29 +3988,12 @@ var showsNoticePolicyLink = (productCount, entryCount) => entryCount === 0 || pr
|
|
|
3989
3988
|
import { useEffect as useEffect4, useMemo as useMemo2 } from "react";
|
|
3990
3989
|
|
|
3991
3990
|
// src/RedactoNoticeConsent/services/customCss.ts
|
|
3992
|
-
var
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
};
|
|
3998
|
-
var applyNoticeCustomCss = (noticeId, css3) => {
|
|
3999
|
-
if (typeof document === "undefined") {
|
|
4000
|
-
return () => void 0;
|
|
4001
|
-
}
|
|
4002
|
-
const id = noticeId.replace(CSS_STRING_SPECIALS_RE, "\\$&");
|
|
4003
|
-
const style = document.createElement("style");
|
|
4004
|
-
style.setAttribute(CUSTOM_CSS_ATTRIBUTE, noticeId);
|
|
4005
|
-
style.textContent = `${CSS_SCOPE_AT_RULE} ([${NOTICE_ID_ATTRIBUTE}="${id}"]) {
|
|
4006
|
-
${css3}
|
|
4007
|
-
}`;
|
|
4008
|
-
document.head.appendChild(style);
|
|
4009
|
-
if (escapesScope(style)) {
|
|
4010
|
-
style.remove();
|
|
4011
|
-
return () => void 0;
|
|
4012
|
-
}
|
|
4013
|
-
return () => style.remove();
|
|
4014
|
-
};
|
|
3991
|
+
var applyNoticeCustomCss = (noticeId, css3) => applyScopedCustomCss({
|
|
3992
|
+
scopeAttribute: NOTICE_ID_ATTRIBUTE,
|
|
3993
|
+
scopeId: noticeId,
|
|
3994
|
+
markerAttribute: CUSTOM_CSS_ATTRIBUTE,
|
|
3995
|
+
css: css3
|
|
3996
|
+
});
|
|
4015
3997
|
|
|
4016
3998
|
// src/RedactoNoticeConsent/utils/mergeHostSettings.ts
|
|
4017
3999
|
var definedColors = (colors) => Object.fromEntries(
|