@redacto.io/consent-sdk-react 10.3.0-beta.6 → 10.3.1-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -182,6 +182,7 @@ export {
182
182
  REQUIRED_MARKER_GLYPH,
183
183
  REQUIRED_MARKER_ARIA_LABEL,
184
184
  REQUIRED_MARKER_STYLE,
185
+ INHERIT_FONT_FAMILY,
185
186
  FONT_NAME_QUOTE_CHARACTERS,
186
187
  FONT_FAMILY_SEPARATOR,
187
188
  NOTICE_FONT_FACE_STYLE_ID_PREFIX,
@@ -1,3 +1,105 @@
1
+ import {
2
+ FONT_FAMILY_SEPARATOR,
3
+ FONT_NAME_QUOTE_CHARACTERS,
4
+ NOTICE_FONT_ENTRY_BY_ID,
5
+ NOTICE_FONT_FACE_STYLE_ID_PREFIX,
6
+ NOTICE_FONT_LOAD_ERROR_MESSAGE
7
+ } from "./chunk-4SCWX74J.mjs";
8
+
9
+ // src/shared/fonts/font-sources.generated.ts
10
+ var NOTICE_FONT_SOURCE_IMPORTS = {
11
+ "montserrat": () => import("./montserrat.generated-NBTECYRW.mjs")
12
+ };
13
+
14
+ // src/shared/notice-webfont.ts
15
+ var noticeFontOptions = {};
16
+ var configureNoticeFonts = (options) => {
17
+ noticeFontOptions = { ...noticeFontOptions, ...options };
18
+ };
19
+ var toFamilyTokens = (value) => value.split(FONT_FAMILY_SEPARATOR).map(
20
+ (token) => token.trim().replace(FONT_NAME_QUOTE_CHARACTERS, "").toLowerCase()
21
+ );
22
+ var findNoticeFontEntry = (value) => {
23
+ const id = toFamilyTokens(value).find(
24
+ (token) => Boolean(NOTICE_FONT_ENTRY_BY_ID[token])
25
+ );
26
+ if (!id) {
27
+ return void 0;
28
+ }
29
+ return NOTICE_FONT_ENTRY_BY_ID[id];
30
+ };
31
+ var toFontFaceCss = (entry, sources) => sources.map(
32
+ ({ weight, url }) => [
33
+ "@font-face {",
34
+ ` font-family: "${entry.cssFamily}";`,
35
+ " font-style: normal;",
36
+ ` font-weight: ${weight};`,
37
+ // `swap`, never the `auto` default: auto gives most browsers a ~3s block
38
+ // period with INVISIBLE text, which is unacceptable for a consent notice.
39
+ " font-display: swap;",
40
+ // `local()` still leads: the bundled copy is Latin + Latin-Extended only,
41
+ // so a visitor's own installation covers more scripts than ours does.
42
+ ` src: local("${entry.cssFamily}"),`,
43
+ // Quoted url(): a data URI carries `,` and `;`, which are hostile to an
44
+ // unquoted url token. Base64 never contains a double quote.
45
+ ` url("${url}") format("woff2");`,
46
+ "}"
47
+ ].join("\n")
48
+ ).join("\n\n");
49
+ var fontSourceLoads = /* @__PURE__ */ new Map();
50
+ var loadFontSources = (entry, importSources) => {
51
+ const pending2 = fontSourceLoads.get(entry.id);
52
+ if (pending2) {
53
+ return pending2;
54
+ }
55
+ const load = importSources().then((module) => module.NOTICE_FONT_SOURCES).catch((error) => {
56
+ fontSourceLoads.delete(entry.id);
57
+ throw error;
58
+ });
59
+ fontSourceLoads.set(entry.id, load);
60
+ return load;
61
+ };
62
+ var injectedFontFaceIds = /* @__PURE__ */ new Set();
63
+ var injectFontFace = (entry, sources) => {
64
+ if (injectedFontFaceIds.has(entry.id)) {
65
+ return;
66
+ }
67
+ injectedFontFaceIds.add(entry.id);
68
+ const styleId = `${NOTICE_FONT_FACE_STYLE_ID_PREFIX}${entry.slug}`;
69
+ if (document.getElementById(styleId)) {
70
+ return;
71
+ }
72
+ const style = document.createElement("style");
73
+ style.id = styleId;
74
+ style.textContent = toFontFaceCss(entry, sources);
75
+ document.head.appendChild(style);
76
+ };
77
+ var loadNoticeWebfont = async (value, signal) => {
78
+ if (typeof document === "undefined" || noticeFontOptions.disabled) {
79
+ return;
80
+ }
81
+ if (signal == null ? void 0 : signal.aborted) {
82
+ return;
83
+ }
84
+ const entry = findNoticeFontEntry(value);
85
+ if (!entry || entry.source !== "webfont" || injectedFontFaceIds.has(entry.id)) {
86
+ return;
87
+ }
88
+ const importSources = NOTICE_FONT_SOURCE_IMPORTS[entry.slug];
89
+ if (!importSources) {
90
+ return;
91
+ }
92
+ try {
93
+ const sources = await loadFontSources(entry, importSources);
94
+ if (signal == null ? void 0 : signal.aborted) {
95
+ return;
96
+ }
97
+ injectFontFace(entry, sources);
98
+ } catch (error) {
99
+ console.error(NOTICE_FONT_LOAD_ERROR_MESSAGE, error);
100
+ }
101
+ };
102
+
1
103
  // src/shared/idempotency.ts
2
104
  var HEADER = "Idempotency-Key";
3
105
  var pending = /* @__PURE__ */ new Map();
@@ -581,9 +683,15 @@ var useMediaQuery = (query) => {
581
683
  // src/shared/sandbox.ts
582
684
  var SANDBOX_TOKEN_HEADER = "X-Consent-Token";
583
685
 
686
+ // src/constants.ts
687
+ var DEFAULT_CONSENT_API_BASE_URL = "https://api.redacto.io/consent";
688
+ var USER_SERVICE_PATH = "/user/api/0";
689
+
584
690
  export {
585
691
  SANDBOX_TOKEN_HEADER,
586
692
  withIdempotencyKey,
693
+ DEFAULT_CONSENT_API_BASE_URL,
694
+ USER_SERVICE_PATH,
587
695
  DEFAULT_TEXT_SCALE,
588
696
  NOTICE_TEXT_SCALE_FACTORS,
589
697
  NOTICE_THEME_VARS,
@@ -614,5 +722,7 @@ export {
614
722
  prefersReducedMotion,
615
723
  useIsomorphicLayoutEffect,
616
724
  Collapse,
725
+ configureNoticeFonts,
726
+ loadNoticeWebfont,
617
727
  useMediaQuery
618
728
  };
package/dist/fonts.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  NOTICE_FONT_CATALOGUE,
3
3
  resolveNoticeFontFamily,
4
4
  toNoticeFontValue
5
- } from "./chunk-FT5G2PXK.mjs";
5
+ } from "./chunk-4SCWX74J.mjs";
6
6
  export {
7
7
  NOTICE_FONT_CATALOGUE,
8
8
  resolveNoticeFontFamily,
package/dist/index.js CHANGED
@@ -278,6 +278,9 @@ ${body}`;
278
278
  }
279
279
  };
280
280
 
281
+ // src/constants.ts
282
+ var DEFAULT_CONSENT_API_BASE_URL = "https://api.redacto.io/consent";
283
+
281
284
  // src/shared/notice-consent-status.ts
282
285
  var import_jwt_decode = require("jwt-decode");
283
286
  var decodeNoticeConsentToken = (token) => {
@@ -356,7 +359,7 @@ var fetchNoticeConsentStatus = async ({
356
359
  var isNoticeFullyConsented = (status) => status.consented && status.all_mandatory_active;
357
360
 
358
361
  // src/RedactoNoticeConsent/api/index.ts
359
- var BASE_URL = "https://api.redacto.io/consent";
362
+ var BASE_URL = DEFAULT_CONSENT_API_BASE_URL;
360
363
  var apiCache = /* @__PURE__ */ new Map();
361
364
  var CACHE_TTL = 5 * 60 * 1e3;
362
365
  function getCachedData(key) {
@@ -3281,6 +3284,11 @@ var preselectionForRows = (rows, preselection) => {
3281
3284
  };
3282
3285
  var isBlockingRequiredElement = (element) => element.required && element.enabled;
3283
3286
  var hasRequiredDataElement = (purpose) => purpose.data_elements.some(isBlockingRequiredElement);
3287
+ var seededDataElements = (purpose) => {
3288
+ const mandatory = purpose.data_elements.filter(isBlockingRequiredElement);
3289
+ const granted = mandatory.length > 0 ? mandatory : purpose.data_elements.filter((element) => element.enabled);
3290
+ return new Set(granted.map((element) => element.uuid));
3291
+ };
3284
3292
 
3285
3293
  // src/RedactoNoticeConsent/layout.ts
3286
3294
  var resolveLogoPosition = (raw) => raw === "center" || raw === "right" ? raw : DEFAULT_LOGO_POSITION;
@@ -7370,12 +7378,7 @@ var NoticeConsentView = ({
7370
7378
  ...prev,
7371
7379
  [key]: newPurposeState
7372
7380
  }));
7373
- const mandatory = purpose.data_elements.filter(
7374
- isBlockingRequiredElement
7375
- );
7376
- const seeded = new Set(
7377
- (mandatory.length > 0 ? mandatory : purpose.data_elements.filter((el) => el.enabled)).map((el) => el.uuid)
7378
- );
7381
+ const seeded = seededDataElements(purpose);
7379
7382
  setSelectedDataElements((prev) => {
7380
7383
  const updated = { ...prev };
7381
7384
  purpose.data_elements.forEach((el) => {
@@ -7406,8 +7409,9 @@ var NoticeConsentView = ({
7406
7409
  const elementOverrides = {};
7407
7410
  sectionPurposes.forEach((purpose) => {
7408
7411
  const key = productPurposeKey(keyProductUuid, purpose.uuid);
7412
+ const seeded = seededDataElements(purpose);
7409
7413
  purpose.data_elements.forEach((element) => {
7410
- elementOverrides[`${key}-${element.uuid}`] = element.enabled ? nextState : false;
7414
+ elementOverrides[`${key}-${element.uuid}`] = nextState && seeded.has(element.uuid);
7411
7415
  });
7412
7416
  });
7413
7417
  setSelectedDataElements((prev) => ({ ...prev, ...elementOverrides }));
@@ -9801,7 +9805,7 @@ var RedactoNoticeConsent = (props) => /* @__PURE__ */ (0, import_jsx_runtime7.js
9801
9805
  var import_react10 = require("react");
9802
9806
 
9803
9807
  // src/RedactoNoticeConsentInline/api/index.ts
9804
- var BASE_URL2 = "https://api.redacto.tech/consent";
9808
+ var BASE_URL2 = DEFAULT_CONSENT_API_BASE_URL;
9805
9809
  var fetchConsentContent2 = async ({
9806
9810
  org_uuid,
9807
9811
  workspace_uuid,
@@ -12059,7 +12063,7 @@ var DPO_AUDIO_ELEMENT_MAP2 = [
12059
12063
  ];
12060
12064
 
12061
12065
  // src/RedactoNoticeAssisted/api/index.ts
12062
- var BASE_URL3 = "https://api.redacto.io/consent";
12066
+ var BASE_URL3 = DEFAULT_CONSENT_API_BASE_URL;
12063
12067
  var publicScope = (baseUrl, organisationUuid, workspaceUuid) => `${baseUrl || BASE_URL3}/public/organisations/${organisationUuid}/workspaces/${workspaceUuid}`;
12064
12068
  var fetchAssistedNotice = async ({
12065
12069
  organisationUuid,
package/dist/index.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  APPEARANCE_ATTRIBUTE,
3
3
  Collapse,
4
+ DEFAULT_CONSENT_API_BASE_URL,
4
5
  DEFAULT_TEXT_SCALE,
5
6
  GLASS_BLUR,
6
7
  GLASS_DEFAULT_TINT,
@@ -16,10 +17,12 @@ import {
16
17
  TTS_TEXT_ATTRIBUTE,
17
18
  buildTtsCssVariables,
18
19
  buildTtsRootAttributes,
20
+ configureNoticeFonts,
19
21
  getAppearanceLayout,
20
22
  glassPalette,
21
23
  isAppearance,
22
24
  isSafeCustomCss,
25
+ loadNoticeWebfont,
23
26
  opaqueOver,
24
27
  paintableColor,
25
28
  prefersReducedMotion,
@@ -30,20 +33,15 @@ import {
30
33
  withAlpha,
31
34
  withColorScheme,
32
35
  withIdempotencyKey
33
- } from "./chunk-EYHKLIAJ.mjs";
36
+ } from "./chunk-RG4PVVKF.mjs";
34
37
  import {
35
- FONT_FAMILY_SEPARATOR,
36
- FONT_NAME_QUOTE_CHARACTERS,
37
- NOTICE_FONT_ENTRY_BY_ID,
38
- NOTICE_FONT_FACE_STYLE_ID_PREFIX,
39
- NOTICE_FONT_LOAD_ERROR_MESSAGE,
40
38
  NOTICE_FONT_ROOT_PROPS,
41
39
  REQUIRED_MARKER_ARIA_LABEL,
42
40
  REQUIRED_MARKER_GLYPH,
43
41
  REQUIRED_MARKER_STYLE,
44
42
  injectNoticeFontStyles,
45
43
  resolveNoticeFontFamily
46
- } from "./chunk-FT5G2PXK.mjs";
44
+ } from "./chunk-4SCWX74J.mjs";
47
45
 
48
46
  // src/RedactoNoticeConsent/RedactoNoticeConsent.tsx
49
47
  import {
@@ -259,7 +257,7 @@ var fetchNoticeConsentStatus = async ({
259
257
  var isNoticeFullyConsented = (status) => status.consented && status.all_mandatory_active;
260
258
 
261
259
  // src/RedactoNoticeConsent/api/index.ts
262
- var BASE_URL = "https://api.redacto.io/consent";
260
+ var BASE_URL = DEFAULT_CONSENT_API_BASE_URL;
263
261
  var apiCache = /* @__PURE__ */ new Map();
264
262
  var CACHE_TTL = 5 * 60 * 1e3;
265
263
  function getCachedData(key) {
@@ -2687,6 +2685,11 @@ var preselectionForRows = (rows, preselection) => {
2687
2685
  };
2688
2686
  var isBlockingRequiredElement = (element) => element.required && element.enabled;
2689
2687
  var hasRequiredDataElement = (purpose) => purpose.data_elements.some(isBlockingRequiredElement);
2688
+ var seededDataElements = (purpose) => {
2689
+ const mandatory = purpose.data_elements.filter(isBlockingRequiredElement);
2690
+ const granted = mandatory.length > 0 ? mandatory : purpose.data_elements.filter((element) => element.enabled);
2691
+ return new Set(granted.map((element) => element.uuid));
2692
+ };
2690
2693
 
2691
2694
  // src/RedactoNoticeConsent/layout.ts
2692
2695
  var resolveLogoPosition = (raw) => raw === "center" || raw === "right" ? raw : DEFAULT_LOGO_POSITION;
@@ -2879,102 +2882,6 @@ var RequiredMarker = ({
2879
2882
 
2880
2883
  // src/shared/useNoticeFont.ts
2881
2884
  import { useEffect as useEffect3, useMemo } from "react";
2882
-
2883
- // src/shared/fonts/font-sources.generated.ts
2884
- var NOTICE_FONT_SOURCE_IMPORTS = {
2885
- "montserrat": () => import("./montserrat.generated-NBTECYRW.mjs")
2886
- };
2887
-
2888
- // src/shared/notice-webfont.ts
2889
- var noticeFontOptions = {};
2890
- var configureNoticeFonts = (options) => {
2891
- noticeFontOptions = { ...noticeFontOptions, ...options };
2892
- };
2893
- var toFamilyTokens = (value) => value.split(FONT_FAMILY_SEPARATOR).map(
2894
- (token) => token.trim().replace(FONT_NAME_QUOTE_CHARACTERS, "").toLowerCase()
2895
- );
2896
- var findNoticeFontEntry = (value) => {
2897
- const id = toFamilyTokens(value).find(
2898
- (token) => Boolean(NOTICE_FONT_ENTRY_BY_ID[token])
2899
- );
2900
- if (!id) {
2901
- return void 0;
2902
- }
2903
- return NOTICE_FONT_ENTRY_BY_ID[id];
2904
- };
2905
- var toFontFaceCss = (entry, sources) => sources.map(
2906
- ({ weight, url }) => [
2907
- "@font-face {",
2908
- ` font-family: "${entry.cssFamily}";`,
2909
- " font-style: normal;",
2910
- ` font-weight: ${weight};`,
2911
- // `swap`, never the `auto` default: auto gives most browsers a ~3s block
2912
- // period with INVISIBLE text, which is unacceptable for a consent notice.
2913
- " font-display: swap;",
2914
- // `local()` still leads: the bundled copy is Latin + Latin-Extended only,
2915
- // so a visitor's own installation covers more scripts than ours does.
2916
- ` src: local("${entry.cssFamily}"),`,
2917
- // Quoted url(): a data URI carries `,` and `;`, which are hostile to an
2918
- // unquoted url token. Base64 never contains a double quote.
2919
- ` url("${url}") format("woff2");`,
2920
- "}"
2921
- ].join("\n")
2922
- ).join("\n\n");
2923
- var fontSourceLoads = /* @__PURE__ */ new Map();
2924
- var loadFontSources = (entry, importSources) => {
2925
- const pending = fontSourceLoads.get(entry.id);
2926
- if (pending) {
2927
- return pending;
2928
- }
2929
- const load = importSources().then((module) => module.NOTICE_FONT_SOURCES).catch((error) => {
2930
- fontSourceLoads.delete(entry.id);
2931
- throw error;
2932
- });
2933
- fontSourceLoads.set(entry.id, load);
2934
- return load;
2935
- };
2936
- var injectedFontFaceIds = /* @__PURE__ */ new Set();
2937
- var injectFontFace = (entry, sources) => {
2938
- if (injectedFontFaceIds.has(entry.id)) {
2939
- return;
2940
- }
2941
- injectedFontFaceIds.add(entry.id);
2942
- const styleId = `${NOTICE_FONT_FACE_STYLE_ID_PREFIX}${entry.slug}`;
2943
- if (document.getElementById(styleId)) {
2944
- return;
2945
- }
2946
- const style = document.createElement("style");
2947
- style.id = styleId;
2948
- style.textContent = toFontFaceCss(entry, sources);
2949
- document.head.appendChild(style);
2950
- };
2951
- var loadNoticeWebfont = async (value, signal) => {
2952
- if (typeof document === "undefined" || noticeFontOptions.disabled) {
2953
- return;
2954
- }
2955
- if (signal == null ? void 0 : signal.aborted) {
2956
- return;
2957
- }
2958
- const entry = findNoticeFontEntry(value);
2959
- if (!entry || entry.source !== "webfont" || injectedFontFaceIds.has(entry.id)) {
2960
- return;
2961
- }
2962
- const importSources = NOTICE_FONT_SOURCE_IMPORTS[entry.slug];
2963
- if (!importSources) {
2964
- return;
2965
- }
2966
- try {
2967
- const sources = await loadFontSources(entry, importSources);
2968
- if (signal == null ? void 0 : signal.aborted) {
2969
- return;
2970
- }
2971
- injectFontFace(entry, sources);
2972
- } catch (error) {
2973
- console.error(NOTICE_FONT_LOAD_ERROR_MESSAGE, error);
2974
- }
2975
- };
2976
-
2977
- // src/shared/useNoticeFont.ts
2978
2885
  var useNoticeFont = ({
2979
2886
  hostFont,
2980
2887
  noticeFont
@@ -6575,12 +6482,7 @@ var NoticeConsentView = ({
6575
6482
  ...prev,
6576
6483
  [key]: newPurposeState
6577
6484
  }));
6578
- const mandatory = purpose.data_elements.filter(
6579
- isBlockingRequiredElement
6580
- );
6581
- const seeded = new Set(
6582
- (mandatory.length > 0 ? mandatory : purpose.data_elements.filter((el) => el.enabled)).map((el) => el.uuid)
6583
- );
6485
+ const seeded = seededDataElements(purpose);
6584
6486
  setSelectedDataElements((prev) => {
6585
6487
  const updated = { ...prev };
6586
6488
  purpose.data_elements.forEach((el) => {
@@ -6611,8 +6513,9 @@ var NoticeConsentView = ({
6611
6513
  const elementOverrides = {};
6612
6514
  sectionPurposes.forEach((purpose) => {
6613
6515
  const key = productPurposeKey(keyProductUuid, purpose.uuid);
6516
+ const seeded = seededDataElements(purpose);
6614
6517
  purpose.data_elements.forEach((element) => {
6615
- elementOverrides[`${key}-${element.uuid}`] = element.enabled ? nextState : false;
6518
+ elementOverrides[`${key}-${element.uuid}`] = nextState && seeded.has(element.uuid);
6616
6519
  });
6617
6520
  });
6618
6521
  setSelectedDataElements((prev) => ({ ...prev, ...elementOverrides }));
@@ -9006,7 +8909,7 @@ var RedactoNoticeConsent = (props) => /* @__PURE__ */ jsx6(NoticeConsentView, {
9006
8909
  import { useEffect as useEffect7, useMemo as useMemo4, useState as useState3, useRef as useRef4, useCallback as useCallback4, memo } from "react";
9007
8910
 
9008
8911
  // src/RedactoNoticeConsentInline/api/index.ts
9009
- var BASE_URL2 = "https://api.redacto.tech/consent";
8912
+ var BASE_URL2 = DEFAULT_CONSENT_API_BASE_URL;
9010
8913
  var fetchConsentContent2 = async ({
9011
8914
  org_uuid,
9012
8915
  workspace_uuid,
@@ -11264,7 +11167,7 @@ var DPO_AUDIO_ELEMENT_MAP2 = [
11264
11167
  ];
11265
11168
 
11266
11169
  // src/RedactoNoticeAssisted/api/index.ts
11267
- var BASE_URL3 = "https://api.redacto.io/consent";
11170
+ var BASE_URL3 = DEFAULT_CONSENT_API_BASE_URL;
11268
11171
  var publicScope = (baseUrl, organisationUuid, workspaceUuid) => `${baseUrl || BASE_URL3}/public/organisations/${organisationUuid}/workspaces/${workspaceUuid}`;
11269
11172
  var fetchAssistedNotice = async ({
11270
11173
  organisationUuid,