@redacto.io/consent-sdk-react 10.3.0 → 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();
@@ -620,5 +722,7 @@ export {
620
722
  prefersReducedMotion,
621
723
  useIsomorphicLayoutEffect,
622
724
  Collapse,
725
+ configureNoticeFonts,
726
+ loadNoticeWebfont,
623
727
  useMediaQuery
624
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
@@ -3284,6 +3284,11 @@ var preselectionForRows = (rows, preselection) => {
3284
3284
  };
3285
3285
  var isBlockingRequiredElement = (element) => element.required && element.enabled;
3286
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
+ };
3287
3292
 
3288
3293
  // src/RedactoNoticeConsent/layout.ts
3289
3294
  var resolveLogoPosition = (raw) => raw === "center" || raw === "right" ? raw : DEFAULT_LOGO_POSITION;
@@ -7373,12 +7378,7 @@ var NoticeConsentView = ({
7373
7378
  ...prev,
7374
7379
  [key]: newPurposeState
7375
7380
  }));
7376
- const mandatory = purpose.data_elements.filter(
7377
- isBlockingRequiredElement
7378
- );
7379
- const seeded = new Set(
7380
- (mandatory.length > 0 ? mandatory : purpose.data_elements.filter((el) => el.enabled)).map((el) => el.uuid)
7381
- );
7381
+ const seeded = seededDataElements(purpose);
7382
7382
  setSelectedDataElements((prev) => {
7383
7383
  const updated = { ...prev };
7384
7384
  purpose.data_elements.forEach((el) => {
@@ -7409,8 +7409,9 @@ var NoticeConsentView = ({
7409
7409
  const elementOverrides = {};
7410
7410
  sectionPurposes.forEach((purpose) => {
7411
7411
  const key = productPurposeKey(keyProductUuid, purpose.uuid);
7412
+ const seeded = seededDataElements(purpose);
7412
7413
  purpose.data_elements.forEach((element) => {
7413
- elementOverrides[`${key}-${element.uuid}`] = element.enabled ? nextState : false;
7414
+ elementOverrides[`${key}-${element.uuid}`] = nextState && seeded.has(element.uuid);
7414
7415
  });
7415
7416
  });
7416
7417
  setSelectedDataElements((prev) => ({ ...prev, ...elementOverrides }));
package/dist/index.mjs CHANGED
@@ -17,10 +17,12 @@ import {
17
17
  TTS_TEXT_ATTRIBUTE,
18
18
  buildTtsCssVariables,
19
19
  buildTtsRootAttributes,
20
+ configureNoticeFonts,
20
21
  getAppearanceLayout,
21
22
  glassPalette,
22
23
  isAppearance,
23
24
  isSafeCustomCss,
25
+ loadNoticeWebfont,
24
26
  opaqueOver,
25
27
  paintableColor,
26
28
  prefersReducedMotion,
@@ -31,20 +33,15 @@ import {
31
33
  withAlpha,
32
34
  withColorScheme,
33
35
  withIdempotencyKey
34
- } from "./chunk-SZWLAJB7.mjs";
36
+ } from "./chunk-RG4PVVKF.mjs";
35
37
  import {
36
- FONT_FAMILY_SEPARATOR,
37
- FONT_NAME_QUOTE_CHARACTERS,
38
- NOTICE_FONT_ENTRY_BY_ID,
39
- NOTICE_FONT_FACE_STYLE_ID_PREFIX,
40
- NOTICE_FONT_LOAD_ERROR_MESSAGE,
41
38
  NOTICE_FONT_ROOT_PROPS,
42
39
  REQUIRED_MARKER_ARIA_LABEL,
43
40
  REQUIRED_MARKER_GLYPH,
44
41
  REQUIRED_MARKER_STYLE,
45
42
  injectNoticeFontStyles,
46
43
  resolveNoticeFontFamily
47
- } from "./chunk-FT5G2PXK.mjs";
44
+ } from "./chunk-4SCWX74J.mjs";
48
45
 
49
46
  // src/RedactoNoticeConsent/RedactoNoticeConsent.tsx
50
47
  import {
@@ -2688,6 +2685,11 @@ var preselectionForRows = (rows, preselection) => {
2688
2685
  };
2689
2686
  var isBlockingRequiredElement = (element) => element.required && element.enabled;
2690
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
+ };
2691
2693
 
2692
2694
  // src/RedactoNoticeConsent/layout.ts
2693
2695
  var resolveLogoPosition = (raw) => raw === "center" || raw === "right" ? raw : DEFAULT_LOGO_POSITION;
@@ -2880,102 +2882,6 @@ var RequiredMarker = ({
2880
2882
 
2881
2883
  // src/shared/useNoticeFont.ts
2882
2884
  import { useEffect as useEffect3, useMemo } from "react";
2883
-
2884
- // src/shared/fonts/font-sources.generated.ts
2885
- var NOTICE_FONT_SOURCE_IMPORTS = {
2886
- "montserrat": () => import("./montserrat.generated-NBTECYRW.mjs")
2887
- };
2888
-
2889
- // src/shared/notice-webfont.ts
2890
- var noticeFontOptions = {};
2891
- var configureNoticeFonts = (options) => {
2892
- noticeFontOptions = { ...noticeFontOptions, ...options };
2893
- };
2894
- var toFamilyTokens = (value) => value.split(FONT_FAMILY_SEPARATOR).map(
2895
- (token) => token.trim().replace(FONT_NAME_QUOTE_CHARACTERS, "").toLowerCase()
2896
- );
2897
- var findNoticeFontEntry = (value) => {
2898
- const id = toFamilyTokens(value).find(
2899
- (token) => Boolean(NOTICE_FONT_ENTRY_BY_ID[token])
2900
- );
2901
- if (!id) {
2902
- return void 0;
2903
- }
2904
- return NOTICE_FONT_ENTRY_BY_ID[id];
2905
- };
2906
- var toFontFaceCss = (entry, sources) => sources.map(
2907
- ({ weight, url }) => [
2908
- "@font-face {",
2909
- ` font-family: "${entry.cssFamily}";`,
2910
- " font-style: normal;",
2911
- ` font-weight: ${weight};`,
2912
- // `swap`, never the `auto` default: auto gives most browsers a ~3s block
2913
- // period with INVISIBLE text, which is unacceptable for a consent notice.
2914
- " font-display: swap;",
2915
- // `local()` still leads: the bundled copy is Latin + Latin-Extended only,
2916
- // so a visitor's own installation covers more scripts than ours does.
2917
- ` src: local("${entry.cssFamily}"),`,
2918
- // Quoted url(): a data URI carries `,` and `;`, which are hostile to an
2919
- // unquoted url token. Base64 never contains a double quote.
2920
- ` url("${url}") format("woff2");`,
2921
- "}"
2922
- ].join("\n")
2923
- ).join("\n\n");
2924
- var fontSourceLoads = /* @__PURE__ */ new Map();
2925
- var loadFontSources = (entry, importSources) => {
2926
- const pending = fontSourceLoads.get(entry.id);
2927
- if (pending) {
2928
- return pending;
2929
- }
2930
- const load = importSources().then((module) => module.NOTICE_FONT_SOURCES).catch((error) => {
2931
- fontSourceLoads.delete(entry.id);
2932
- throw error;
2933
- });
2934
- fontSourceLoads.set(entry.id, load);
2935
- return load;
2936
- };
2937
- var injectedFontFaceIds = /* @__PURE__ */ new Set();
2938
- var injectFontFace = (entry, sources) => {
2939
- if (injectedFontFaceIds.has(entry.id)) {
2940
- return;
2941
- }
2942
- injectedFontFaceIds.add(entry.id);
2943
- const styleId = `${NOTICE_FONT_FACE_STYLE_ID_PREFIX}${entry.slug}`;
2944
- if (document.getElementById(styleId)) {
2945
- return;
2946
- }
2947
- const style = document.createElement("style");
2948
- style.id = styleId;
2949
- style.textContent = toFontFaceCss(entry, sources);
2950
- document.head.appendChild(style);
2951
- };
2952
- var loadNoticeWebfont = async (value, signal) => {
2953
- if (typeof document === "undefined" || noticeFontOptions.disabled) {
2954
- return;
2955
- }
2956
- if (signal == null ? void 0 : signal.aborted) {
2957
- return;
2958
- }
2959
- const entry = findNoticeFontEntry(value);
2960
- if (!entry || entry.source !== "webfont" || injectedFontFaceIds.has(entry.id)) {
2961
- return;
2962
- }
2963
- const importSources = NOTICE_FONT_SOURCE_IMPORTS[entry.slug];
2964
- if (!importSources) {
2965
- return;
2966
- }
2967
- try {
2968
- const sources = await loadFontSources(entry, importSources);
2969
- if (signal == null ? void 0 : signal.aborted) {
2970
- return;
2971
- }
2972
- injectFontFace(entry, sources);
2973
- } catch (error) {
2974
- console.error(NOTICE_FONT_LOAD_ERROR_MESSAGE, error);
2975
- }
2976
- };
2977
-
2978
- // src/shared/useNoticeFont.ts
2979
2885
  var useNoticeFont = ({
2980
2886
  hostFont,
2981
2887
  noticeFont
@@ -6576,12 +6482,7 @@ var NoticeConsentView = ({
6576
6482
  ...prev,
6577
6483
  [key]: newPurposeState
6578
6484
  }));
6579
- const mandatory = purpose.data_elements.filter(
6580
- isBlockingRequiredElement
6581
- );
6582
- const seeded = new Set(
6583
- (mandatory.length > 0 ? mandatory : purpose.data_elements.filter((el) => el.enabled)).map((el) => el.uuid)
6584
- );
6485
+ const seeded = seededDataElements(purpose);
6585
6486
  setSelectedDataElements((prev) => {
6586
6487
  const updated = { ...prev };
6587
6488
  purpose.data_elements.forEach((el) => {
@@ -6612,8 +6513,9 @@ var NoticeConsentView = ({
6612
6513
  const elementOverrides = {};
6613
6514
  sectionPurposes.forEach((purpose) => {
6614
6515
  const key = productPurposeKey(keyProductUuid, purpose.uuid);
6516
+ const seeded = seededDataElements(purpose);
6615
6517
  purpose.data_elements.forEach((element) => {
6616
- elementOverrides[`${key}-${element.uuid}`] = element.enabled ? nextState : false;
6518
+ elementOverrides[`${key}-${element.uuid}`] = nextState && seeded.has(element.uuid);
6617
6519
  });
6618
6520
  });
6619
6521
  setSelectedDataElements((prev) => ({ ...prev, ...elementOverrides }));