@redacto.io/consent-sdk-react 1.4.0 → 2.0.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.
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@ __export(src_exports, {
26
26
  module.exports = __toCommonJS(src_exports);
27
27
 
28
28
  // src/RedactoNoticeConsent/RedactoNoticeConsent.tsx
29
- var import_react3 = require("react");
29
+ var import_react2 = require("react");
30
30
 
31
31
  // src/RedactoNoticeConsent/api/index.ts
32
32
  var import_jwt_decode = require("jwt-decode");
@@ -311,6 +311,60 @@ var submitGuardianInfo = async ({
311
311
  throw error;
312
312
  }
313
313
  };
314
+ var fetchTTSAudioUrls = async ({
315
+ accessToken,
316
+ baseUrl,
317
+ noticeUuid,
318
+ language,
319
+ signal
320
+ // AbortSignal for request cancellation
321
+ }) => {
322
+ try {
323
+ if (!accessToken || !noticeUuid || !language) {
324
+ throw new Error("accessToken, noticeUuid, and language are required");
325
+ }
326
+ const decodedToken = decodeTokenSafely(accessToken);
327
+ if (!decodedToken) {
328
+ throw new Error("Invalid access token");
329
+ }
330
+ const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
331
+ if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
332
+ throw new Error("Invalid token: missing organization or workspace UUID");
333
+ }
334
+ const apiBaseUrl = baseUrl || BASE_URL;
335
+ const url = `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeUuid}/audio/${language}`;
336
+ const response = await fetch(url, {
337
+ method: "GET",
338
+ headers: {
339
+ Authorization: `Bearer ${accessToken}`,
340
+ Accept: "application/json",
341
+ "Content-Type": "application/json"
342
+ },
343
+ signal
344
+ // Add abort signal for request cancellation
345
+ });
346
+ if (!response.ok) {
347
+ let errorMessage = `Failed to fetch TTS audio URLs: ${response.status} ${response.statusText}`;
348
+ if (response.status === 401) {
349
+ errorMessage = "Unauthorized: Invalid or expired token";
350
+ } else if (response.status === 403) {
351
+ errorMessage = "Forbidden: Access denied";
352
+ } else if (response.status === 404) {
353
+ errorMessage = "Notice or audio not found";
354
+ } else if (response.status >= 500) {
355
+ errorMessage = "Server error: Please try again later";
356
+ }
357
+ const error = new Error(errorMessage);
358
+ error.status = response.status;
359
+ throw error;
360
+ }
361
+ const data = await response.json();
362
+ return data;
363
+ } catch (error) {
364
+ console.error("Error fetching TTS audio URLs:", error instanceof Error ? error.message : error);
365
+ throw error;
366
+ }
367
+ };
314
368
 
315
369
  // src/RedactoNoticeConsent/assets/redacto-logo.png
316
370
  var redacto_logo_default = "data:image/png;base64,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";
@@ -408,20 +462,42 @@ var injectCheckboxStyles = () => {
408
462
  outline-offset: 2px !important;
409
463
  }
410
464
 
411
- /* Text-to-Speech Highlight Styles */
465
+ /* TTS Highlight Styles - Visible highlighting without layout shift */
412
466
  .redacto-tts-highlight {
467
+ position: relative !important;
468
+ transition: background-color 0.3s ease, outline 0.3s ease !important;
469
+ }
470
+
471
+ /* Block-level elements - headings */
472
+ h2.redacto-tts-highlight,
473
+ h3.redacto-tts-highlight {
413
474
  background-color: #FFF9C4 !important;
414
- transition: background-color 0.3s ease !important;
415
- border-radius: 2px !important;
475
+ border-radius: 3px !important;
416
476
  padding: 2px 4px !important;
477
+ margin: -2px -4px !important;
417
478
  }
418
479
 
419
- /* Word-by-word highlighting */
420
- .redacto-tts-word-highlight {
480
+ /* Inline elements - spans, links */
481
+ span.redacto-tts-highlight,
482
+ a.redacto-tts-highlight {
421
483
  background-color: #FFF9C4 !important;
422
- transition: background-color 0.2s ease !important;
423
- border-radius: 2px !important;
424
- padding: 0 1px !important;
484
+ border-radius: 3px !important;
485
+ padding: 2px 4px !important;
486
+ margin: -2px -4px !important;
487
+ }
488
+
489
+ /* Paragraphs - handle carefully to avoid layout shift */
490
+ p.redacto-tts-highlight {
491
+ background-color: #FFF9C4 !important;
492
+ border-radius: 3px !important;
493
+ padding: 2px 4px !important;
494
+ margin: -2px -4px !important;
495
+ }
496
+
497
+ /* Buttons - use outline to keep button styles intact */
498
+ button.redacto-tts-highlight {
499
+ outline: 3px solid #FFF9C4 !important;
500
+ outline-offset: 2px !important;
425
501
  }
426
502
  `;
427
503
  document.head.appendChild(style);
@@ -808,284 +884,6 @@ var useMediaQuery = (query) => {
808
884
  return matches;
809
885
  };
810
886
 
811
- // src/RedactoNoticeConsent/useTextToSpeech.ts
812
- var import_react2 = require("react");
813
- var useTextToSpeech = (segments, language = "en") => {
814
- const [isPlaying, setIsPlaying] = (0, import_react2.useState)(false);
815
- const [isPaused, setIsPaused] = (0, import_react2.useState)(false);
816
- const [currentIndex, setCurrentIndex] = (0, import_react2.useState)(0);
817
- const utteranceRef = (0, import_react2.useRef)(null);
818
- const synthRef = (0, import_react2.useRef)(null);
819
- const currentSegmentRef = (0, import_react2.useRef)(0);
820
- const wordSpansRef = (0, import_react2.useRef)([]);
821
- const originalTextsRef = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
822
- const originalHTMLRef = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
823
- const currentWordIndexRef = (0, import_react2.useRef)(-1);
824
- const isInitializedRef = (0, import_react2.useRef)(false);
825
- (0, import_react2.useEffect)(() => {
826
- if (typeof window !== "undefined" && "speechSynthesis" in window) {
827
- synthRef.current = window.speechSynthesis;
828
- }
829
- }, []);
830
- (0, import_react2.useEffect)(() => {
831
- return () => {
832
- cleanupWordSpans();
833
- if (synthRef.current) {
834
- synthRef.current.cancel();
835
- }
836
- };
837
- }, []);
838
- const cleanupWordSpans = (0, import_react2.useCallback)(() => {
839
- wordSpansRef.current.forEach((wordSpan) => {
840
- if (wordSpan.span.parentNode) {
841
- wordSpan.span.classList.remove("redacto-tts-word-highlight");
842
- wordSpan.span.style.backgroundColor = "";
843
- }
844
- });
845
- wordSpansRef.current = [];
846
- currentWordIndexRef.current = -1;
847
- isInitializedRef.current = false;
848
- originalHTMLRef.current.forEach((originalHTML, elementId) => {
849
- const element = document.getElementById(elementId);
850
- if (element && originalHTML) {
851
- element.innerHTML = originalHTML;
852
- }
853
- });
854
- originalHTMLRef.current.clear();
855
- originalTextsRef.current.clear();
856
- }, []);
857
- const removeAllHighlights = (0, import_react2.useCallback)(() => {
858
- wordSpansRef.current.forEach((wordSpan) => {
859
- wordSpan.span.classList.remove("redacto-tts-word-highlight");
860
- wordSpan.span.style.backgroundColor = "";
861
- });
862
- }, []);
863
- const createWordSpans = (0, import_react2.useCallback)((elementId, text) => {
864
- const element = document.getElementById(elementId);
865
- if (!element) return [];
866
- if (!originalHTMLRef.current.has(elementId)) {
867
- const originalHTML = element.innerHTML || "";
868
- originalHTMLRef.current.set(elementId, originalHTML);
869
- const originalText = element.textContent || element.innerText || "";
870
- originalTextsRef.current.set(elementId, originalText);
871
- }
872
- const words = text.split(/(\s+)/);
873
- const wordSpans = [];
874
- let charIndex = 0;
875
- element.innerHTML = "";
876
- words.forEach((word) => {
877
- if (word.trim()) {
878
- const span = document.createElement("span");
879
- span.textContent = word;
880
- span.style.display = "inline";
881
- span.style.transition = "background-color 0.2s ease";
882
- span.style.padding = "0 1px";
883
- element.appendChild(span);
884
- const startIndex = charIndex;
885
- const endIndex = charIndex + word.length;
886
- wordSpans.push({
887
- word,
888
- span,
889
- startIndex,
890
- endIndex
891
- });
892
- } else if (word) {
893
- element.appendChild(document.createTextNode(word));
894
- }
895
- charIndex += word.length;
896
- });
897
- return wordSpans;
898
- }, []);
899
- const highlightWordByIndex = (0, import_react2.useCallback)((wordIndex) => {
900
- if (wordIndex >= 0 && wordIndex < wordSpansRef.current.length) {
901
- removeAllHighlights();
902
- const wordSpan = wordSpansRef.current[wordIndex];
903
- wordSpan.span.classList.add("redacto-tts-word-highlight");
904
- wordSpan.span.style.backgroundColor = "#FFF9C4";
905
- wordSpan.span.scrollIntoView({
906
- behavior: "smooth",
907
- block: "center",
908
- inline: "nearest"
909
- });
910
- }
911
- }, [removeAllHighlights]);
912
- const speakSegment = (0, import_react2.useCallback)(
913
- (index) => {
914
- if (!synthRef.current || index >= segments.length) {
915
- setIsPlaying(false);
916
- setIsPaused(false);
917
- setCurrentIndex(0);
918
- currentSegmentRef.current = 0;
919
- cleanupWordSpans();
920
- return;
921
- }
922
- const segment = segments[index];
923
- if (!segment.text.trim()) {
924
- speakSegment(index + 1);
925
- return;
926
- }
927
- setCurrentIndex(index);
928
- currentSegmentRef.current = index;
929
- if (!isInitializedRef.current || wordSpansRef.current.length === 0) {
930
- const wordSpans = createWordSpans(segment.elementId, segment.text);
931
- wordSpansRef.current = wordSpans;
932
- currentWordIndexRef.current = -1;
933
- isInitializedRef.current = true;
934
- }
935
- if (wordSpansRef.current.length === 0) {
936
- const utterance2 = new SpeechSynthesisUtterance(segment.text);
937
- const langCode2 = language === "English" || language === "en" ? "en-US" : language;
938
- utterance2.lang = langCode2;
939
- utterance2.rate = 1;
940
- utterance2.pitch = 1;
941
- utterance2.volume = 1;
942
- utterance2.onend = () => {
943
- const nextIndex = index + 1;
944
- currentSegmentRef.current = nextIndex;
945
- if (nextIndex < segments.length) {
946
- speakSegment(nextIndex);
947
- } else {
948
- setIsPlaying(false);
949
- setIsPaused(false);
950
- setCurrentIndex(0);
951
- currentSegmentRef.current = 0;
952
- cleanupWordSpans();
953
- }
954
- };
955
- utterance2.onerror = (event) => {
956
- console.error("Speech synthesis error:", event);
957
- setIsPlaying(false);
958
- setIsPaused(false);
959
- cleanupWordSpans();
960
- };
961
- utteranceRef.current = utterance2;
962
- synthRef.current.speak(utterance2);
963
- return;
964
- }
965
- const utterance = new SpeechSynthesisUtterance(segment.text);
966
- const langCode = language === "English" || language === "en" ? "en-US" : language;
967
- utterance.lang = langCode;
968
- utterance.rate = 1;
969
- utterance.pitch = 1;
970
- utterance.volume = 1;
971
- utterance.onboundary = (event) => {
972
- if (event.name === "word" && event.charIndex !== void 0) {
973
- const wordIndex = wordSpansRef.current.findIndex(
974
- (ws) => event.charIndex >= ws.startIndex && event.charIndex < ws.endIndex
975
- );
976
- if (wordIndex !== -1) {
977
- currentWordIndexRef.current = wordIndex;
978
- highlightWordByIndex(wordIndex);
979
- }
980
- }
981
- };
982
- utterance.onstart = () => {
983
- if (currentWordIndexRef.current === -1 && wordSpansRef.current.length > 0) {
984
- highlightWordByIndex(0);
985
- currentWordIndexRef.current = 0;
986
- }
987
- };
988
- utterance.onend = () => {
989
- removeAllHighlights();
990
- isInitializedRef.current = false;
991
- wordSpansRef.current = [];
992
- currentWordIndexRef.current = -1;
993
- const nextIndex = index + 1;
994
- currentSegmentRef.current = nextIndex;
995
- if (nextIndex < segments.length) {
996
- speakSegment(nextIndex);
997
- } else {
998
- setIsPlaying(false);
999
- setIsPaused(false);
1000
- setCurrentIndex(0);
1001
- currentSegmentRef.current = 0;
1002
- cleanupWordSpans();
1003
- }
1004
- };
1005
- utterance.onerror = (event) => {
1006
- console.error("Speech synthesis error:", event);
1007
- setIsPlaying(false);
1008
- setIsPaused(false);
1009
- cleanupWordSpans();
1010
- };
1011
- utteranceRef.current = utterance;
1012
- synthRef.current.speak(utterance);
1013
- },
1014
- [segments, language, createWordSpans, highlightWordByIndex, removeAllHighlights, cleanupWordSpans]
1015
- );
1016
- const play = (0, import_react2.useCallback)(() => {
1017
- if (!synthRef.current || segments.length === 0) return;
1018
- if (isPaused) {
1019
- try {
1020
- setIsPaused(false);
1021
- setIsPlaying(true);
1022
- if (synthRef.current.paused) {
1023
- synthRef.current.resume();
1024
- } else {
1025
- const currentSegment = currentSegmentRef.current;
1026
- if (currentSegment < segments.length) {
1027
- isInitializedRef.current = false;
1028
- speakSegment(currentSegment);
1029
- }
1030
- }
1031
- } catch (error) {
1032
- console.error("Error resuming speech:", error);
1033
- const currentSegment = currentSegmentRef.current;
1034
- if (currentSegment < segments.length) {
1035
- isInitializedRef.current = false;
1036
- speakSegment(currentSegment);
1037
- }
1038
- }
1039
- } else {
1040
- setIsPlaying(true);
1041
- setIsPaused(false);
1042
- currentSegmentRef.current = 0;
1043
- currentWordIndexRef.current = -1;
1044
- isInitializedRef.current = false;
1045
- cleanupWordSpans();
1046
- speakSegment(0);
1047
- }
1048
- }, [isPaused, segments, speakSegment, cleanupWordSpans]);
1049
- const pause = (0, import_react2.useCallback)(() => {
1050
- if (synthRef.current && isPlaying && !isPaused) {
1051
- try {
1052
- synthRef.current.pause();
1053
- setIsPaused(true);
1054
- } catch (error) {
1055
- console.error("Error pausing speech:", error);
1056
- stop();
1057
- }
1058
- }
1059
- }, [isPlaying, isPaused]);
1060
- const stop = (0, import_react2.useCallback)(() => {
1061
- if (synthRef.current) {
1062
- synthRef.current.cancel();
1063
- setIsPlaying(false);
1064
- setIsPaused(false);
1065
- setCurrentIndex(0);
1066
- currentSegmentRef.current = 0;
1067
- currentWordIndexRef.current = -1;
1068
- cleanupWordSpans();
1069
- }
1070
- }, [cleanupWordSpans]);
1071
- const toggle = (0, import_react2.useCallback)(() => {
1072
- if (isPlaying && !isPaused) {
1073
- pause();
1074
- } else {
1075
- play();
1076
- }
1077
- }, [isPlaying, isPaused, play, pause]);
1078
- return {
1079
- isPlaying,
1080
- isPaused,
1081
- currentIndex,
1082
- play,
1083
- pause,
1084
- stop,
1085
- toggle
1086
- };
1087
- };
1088
-
1089
887
  // src/RedactoNoticeConsent/RedactoNoticeConsent.tsx
1090
888
  var import_jsx_runtime = require("react/jsx-runtime");
1091
889
  var PurposeItem = ({
@@ -1100,16 +898,17 @@ var PurposeItem = ({
1100
898
  onPurposeCollapse,
1101
899
  onDataElementToggle,
1102
900
  getTranslatedText,
1103
- isAlreadyConsented
901
+ isAlreadyConsented,
902
+ selectedLanguage
1104
903
  }) => {
1105
- const headingStyle = (0, import_react3.useMemo)(
904
+ const headingStyle = (0, import_react2.useMemo)(
1106
905
  () => ({
1107
906
  color: (settings == null ? void 0 : settings.headingColor) || "#323B4B",
1108
907
  fontFamily: (settings == null ? void 0 : settings.font) || "inherit"
1109
908
  }),
1110
909
  [settings]
1111
910
  );
1112
- const textStyle = (0, import_react3.useMemo)(
911
+ const textStyle = (0, import_react2.useMemo)(
1113
912
  () => ({
1114
913
  color: (settings == null ? void 0 : settings.textColor) || "#344054",
1115
914
  fontFamily: (settings == null ? void 0 : settings.font) || "inherit"
@@ -1127,6 +926,11 @@ var PurposeItem = ({
1127
926
  tabIndex: 0,
1128
927
  "aria-expanded": !collapsedPurposes[purpose.uuid],
1129
928
  "aria-controls": `purpose-${purpose.uuid}`,
929
+ "aria-label": `${collapsedPurposes[purpose.uuid] ? "Expand" : "Collapse"} ${getTranslatedText(
930
+ `purposes.name`,
931
+ purpose.name,
932
+ purpose.uuid
933
+ )} details`,
1130
934
  onKeyDown: (e) => {
1131
935
  if (e.key === "Enter" || e.key === " ") {
1132
936
  e.preventDefault();
@@ -1176,7 +980,8 @@ var PurposeItem = ({
1176
980
  ...headingStyle
1177
981
  },
1178
982
  children: getTranslatedText(`purposes.name`, purpose.name, purpose.uuid)
1179
- }
983
+ },
984
+ `purpose-name-${purpose.uuid}-${selectedLanguage}`
1180
985
  ),
1181
986
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1182
987
  "h3",
@@ -1192,7 +997,8 @@ var PurposeItem = ({
1192
997
  purpose.description,
1193
998
  purpose.uuid
1194
999
  )
1195
- }
1000
+ },
1001
+ `purpose-description-${purpose.uuid}-${selectedLanguage}`
1196
1002
  )
1197
1003
  ] })
1198
1004
  ]
@@ -1225,6 +1031,11 @@ var PurposeItem = ({
1225
1031
  backgroundColor: "#10B981",
1226
1032
  marginLeft: "12px"
1227
1033
  },
1034
+ "aria-label": `Already consented to ${getTranslatedText(
1035
+ `purposes.name`,
1036
+ purpose.name,
1037
+ purpose.uuid
1038
+ )}`,
1228
1039
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1229
1040
  "svg",
1230
1041
  {
@@ -1233,6 +1044,7 @@ var PurposeItem = ({
1233
1044
  viewBox: "0 0 12 12",
1234
1045
  fill: "none",
1235
1046
  xmlns: "http://www.w3.org/2000/svg",
1047
+ "aria-hidden": "true",
1236
1048
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1237
1049
  "path",
1238
1050
  {
@@ -1253,86 +1065,101 @@ var PurposeItem = ({
1253
1065
  {
1254
1066
  id: `purpose-${purpose.uuid}`,
1255
1067
  style: styles3.dataElementsContainer,
1256
- children: purpose.data_elements.map((dataElement) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles3.dataElementItem, children: [
1257
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1258
- "span",
1259
- {
1260
- id: `data-element-${purpose.uuid}-${dataElement.uuid}`,
1261
- style: {
1262
- ...styles3.dataElementText,
1263
- ...responsiveStyles.dataElementText,
1264
- ...textStyle
1265
- },
1266
- children: [
1267
- getTranslatedText(
1268
- `data_elements.name`,
1269
- dataElement.name,
1270
- dataElement.uuid
1271
- ),
1272
- dataElement.required && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1273
- "span",
1274
- {
1275
- style: {
1276
- color: "red",
1277
- marginLeft: "4px"
1278
- },
1279
- "aria-label": "required",
1280
- children: "*"
1281
- }
1282
- )
1283
- ]
1284
- }
1285
- ),
1286
- !isAlreadyConsented && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1287
- "input",
1288
- {
1289
- className: "redacto-checkbox-small",
1290
- type: "checkbox",
1291
- checked: selectedDataElements[`${purpose.uuid}-${dataElement.uuid}`] || false,
1292
- onChange: () => onDataElementToggle(dataElement.uuid, purpose.uuid),
1293
- "aria-label": `Select ${getTranslatedText(
1294
- `data_elements.name`,
1295
- dataElement.name,
1296
- dataElement.uuid
1297
- )}${dataElement.required ? " (required)" : ""}`
1298
- }
1299
- ),
1300
- isAlreadyConsented && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1301
- "div",
1302
- {
1303
- style: {
1304
- display: "flex",
1305
- alignItems: "center",
1306
- justifyContent: "center",
1307
- width: "16px",
1308
- height: "16px",
1309
- borderRadius: "50%",
1310
- backgroundColor: "#10B981"
1311
- },
1312
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1313
- "svg",
1068
+ children: purpose.data_elements.map((dataElement) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1069
+ "div",
1070
+ {
1071
+ style: styles3.dataElementItem,
1072
+ children: [
1073
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1074
+ "span",
1075
+ {
1076
+ id: `data-element-${purpose.uuid}-${dataElement.uuid}`,
1077
+ style: {
1078
+ ...styles3.dataElementText,
1079
+ ...responsiveStyles.dataElementText,
1080
+ ...textStyle
1081
+ },
1082
+ children: [
1083
+ getTranslatedText(
1084
+ `data_elements.name`,
1085
+ dataElement.name,
1086
+ dataElement.uuid
1087
+ ),
1088
+ dataElement.required && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1089
+ "span",
1090
+ {
1091
+ style: {
1092
+ color: "red",
1093
+ marginLeft: "4px"
1094
+ },
1095
+ "aria-label": "required",
1096
+ children: "*"
1097
+ }
1098
+ )
1099
+ ]
1100
+ },
1101
+ `data-element-${purpose.uuid}-${dataElement.uuid}-${selectedLanguage}`
1102
+ ),
1103
+ !isAlreadyConsented && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1104
+ "input",
1314
1105
  {
1315
- width: "10",
1316
- height: "10",
1317
- viewBox: "0 0 10 10",
1318
- fill: "none",
1319
- xmlns: "http://www.w3.org/2000/svg",
1106
+ className: "redacto-checkbox-small",
1107
+ type: "checkbox",
1108
+ checked: selectedDataElements[`${purpose.uuid}-${dataElement.uuid}`] || false,
1109
+ onChange: () => onDataElementToggle(dataElement.uuid, purpose.uuid),
1110
+ "aria-label": `Select ${getTranslatedText(
1111
+ `data_elements.name`,
1112
+ dataElement.name,
1113
+ dataElement.uuid
1114
+ )}${dataElement.required ? " (required)" : ""}`
1115
+ }
1116
+ ),
1117
+ isAlreadyConsented && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1118
+ "div",
1119
+ {
1120
+ style: {
1121
+ display: "flex",
1122
+ alignItems: "center",
1123
+ justifyContent: "center",
1124
+ width: "16px",
1125
+ height: "16px",
1126
+ borderRadius: "50%",
1127
+ backgroundColor: "#10B981"
1128
+ },
1129
+ "aria-label": `Already consented to ${getTranslatedText(
1130
+ `data_elements.name`,
1131
+ dataElement.name,
1132
+ dataElement.uuid
1133
+ )}`,
1320
1134
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1321
- "path",
1135
+ "svg",
1322
1136
  {
1323
- d: "M3 5L4.5 6.5L7.5 3.5",
1324
- stroke: "white",
1325
- strokeWidth: "1.5",
1326
- strokeLinecap: "round",
1327
- strokeLinejoin: "round"
1137
+ width: "10",
1138
+ height: "10",
1139
+ viewBox: "0 0 10 10",
1140
+ fill: "none",
1141
+ xmlns: "http://www.w3.org/2000/svg",
1142
+ "aria-hidden": "true",
1143
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1144
+ "path",
1145
+ {
1146
+ d: "M3 5L4.5 6.5L7.5 3.5",
1147
+ stroke: "white",
1148
+ strokeWidth: "1.5",
1149
+ strokeLinecap: "round",
1150
+ strokeLinejoin: "round"
1151
+ }
1152
+ )
1328
1153
  }
1329
1154
  )
1330
1155
  }
1331
1156
  )
1332
- }
1333
- )
1334
- ] }, dataElement.uuid))
1335
- }
1157
+ ]
1158
+ },
1159
+ `${dataElement.uuid}-${selectedLanguage}`
1160
+ ))
1161
+ },
1162
+ `purpose-${purpose.uuid}-container-${selectedLanguage}`
1336
1163
  )
1337
1164
  ] }, purpose.uuid);
1338
1165
  };
@@ -1547,6 +1374,7 @@ var GuardianForm = ({
1547
1374
  onClick: onNext,
1548
1375
  disabled: isSubmitting,
1549
1376
  type: "button",
1377
+ "aria-label": isSubmitting ? "Submitting guardian information" : "Submit guardian information and proceed",
1550
1378
  children: isSubmitting ? "Submitting..." : "Next"
1551
1379
  }
1552
1380
  ),
@@ -1561,6 +1389,7 @@ var GuardianForm = ({
1561
1389
  },
1562
1390
  onClick: onDecline,
1563
1391
  type: "button",
1392
+ "aria-label": "Cancel guardian information form",
1564
1393
  children: "Cancel"
1565
1394
  }
1566
1395
  )
@@ -1694,6 +1523,7 @@ var AgeVerification = ({
1694
1523
  },
1695
1524
  onClick: onYes,
1696
1525
  type: "button",
1526
+ "aria-label": "Confirm that I am 18 years of age or older",
1697
1527
  children: "Yes, I am 18 or older"
1698
1528
  }
1699
1529
  ),
@@ -1708,6 +1538,7 @@ var AgeVerification = ({
1708
1538
  },
1709
1539
  onClick: onNo,
1710
1540
  type: "button",
1541
+ "aria-label": "Indicate that I am under 18 years of age",
1711
1542
  children: "No, I am under 18"
1712
1543
  }
1713
1544
  )
@@ -1731,7 +1562,7 @@ var RedactoNoticeConsent = ({
1731
1562
  validateAgainst = "all"
1732
1563
  }) => {
1733
1564
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w;
1734
- const propValidationError = (0, import_react3.useMemo)(() => {
1565
+ const propValidationError = (0, import_react2.useMemo)(() => {
1735
1566
  if (!(noticeId == null ? void 0 : noticeId.trim())) {
1736
1567
  return "RedactoNoticeConsent: 'noticeId' prop is required and cannot be empty";
1737
1568
  }
@@ -1759,34 +1590,41 @@ var RedactoNoticeConsent = ({
1759
1590
  }
1760
1591
  );
1761
1592
  }
1762
- const [isLoading, setIsLoading] = (0, import_react3.useState)(true);
1763
- const [isSubmitting, setIsSubmitting] = (0, import_react3.useState)(false);
1764
- const [content, setContent] = (0, import_react3.useState)(null);
1765
- const [categorizedPurposes, setCategorizedPurposes] = (0, import_react3.useState)(null);
1766
- const [selectedPurposes, setSelectedPurposes] = (0, import_react3.useState)({});
1767
- const [selectedDataElements, setSelectedDataElements] = (0, import_react3.useState)({});
1768
- const [collapsedPurposes, setCollapsedPurposes] = (0, import_react3.useState)({});
1769
- const [hasAlreadyConsented, setHasAlreadyConsented] = (0, import_react3.useState)(false);
1770
- const [isLanguageDropdownOpen, setIsLanguageDropdownOpen] = (0, import_react3.useState)(false);
1771
- const [selectedLanguage, setSelectedLanguage] = (0, import_react3.useState)(language);
1772
- const [errorMessage, setErrorMessage] = (0, import_react3.useState)(null);
1773
- const [fetchError, setFetchError] = (0, import_react3.useState)(null);
1774
- const [showAgeVerification, setShowAgeVerification] = (0, import_react3.useState)(false);
1775
- const [showGuardianForm, setShowGuardianForm] = (0, import_react3.useState)(false);
1776
- const [isSubmittingGuardian, setIsSubmittingGuardian] = (0, import_react3.useState)(false);
1777
- const [guardianFormData, setGuardianFormData] = (0, import_react3.useState)({
1593
+ const [isLoading, setIsLoading] = (0, import_react2.useState)(true);
1594
+ const [isSubmitting, setIsSubmitting] = (0, import_react2.useState)(false);
1595
+ const [content, setContent] = (0, import_react2.useState)(null);
1596
+ const [categorizedPurposes, setCategorizedPurposes] = (0, import_react2.useState)(null);
1597
+ const [selectedPurposes, setSelectedPurposes] = (0, import_react2.useState)({});
1598
+ const [selectedDataElements, setSelectedDataElements] = (0, import_react2.useState)({});
1599
+ const [collapsedPurposes, setCollapsedPurposes] = (0, import_react2.useState)({});
1600
+ const [hasAlreadyConsented, setHasAlreadyConsented] = (0, import_react2.useState)(false);
1601
+ const [isLanguageDropdownOpen, setIsLanguageDropdownOpen] = (0, import_react2.useState)(false);
1602
+ const [selectedLanguage, setSelectedLanguage] = (0, import_react2.useState)(language);
1603
+ const [errorMessage, setErrorMessage] = (0, import_react2.useState)(null);
1604
+ const [fetchError, setFetchError] = (0, import_react2.useState)(null);
1605
+ const [ttsAudioUrls, setTtsAudioUrls] = (0, import_react2.useState)(null);
1606
+ const [isTTSAvailable, setIsTTSAvailable] = (0, import_react2.useState)(false);
1607
+ const [isPlaying, setIsPlaying] = (0, import_react2.useState)(false);
1608
+ const [isPaused, setIsPaused] = (0, import_react2.useState)(false);
1609
+ const [currentAudioIndex, setCurrentAudioIndex] = (0, import_react2.useState)(0);
1610
+ const [highlightedElementId, setHighlightedElementId] = (0, import_react2.useState)(null);
1611
+ const [showAgeVerification, setShowAgeVerification] = (0, import_react2.useState)(false);
1612
+ const [showGuardianForm, setShowGuardianForm] = (0, import_react2.useState)(false);
1613
+ const [isSubmittingGuardian, setIsSubmittingGuardian] = (0, import_react2.useState)(false);
1614
+ const [guardianFormData, setGuardianFormData] = (0, import_react2.useState)({
1778
1615
  guardianName: "",
1779
1616
  guardianContact: "",
1780
1617
  guardianRelationship: ""
1781
1618
  });
1782
- const [guardianFormErrors, setGuardianFormErrors] = (0, import_react3.useState)({});
1783
- const modalRef = (0, import_react3.useRef)(null);
1784
- const firstFocusableRef = (0, import_react3.useRef)(null);
1785
- const lastFocusableRef = (0, import_react3.useRef)(null);
1786
- const abortControllerRef = (0, import_react3.useRef)(null);
1787
- const isRequestInProgressRef = (0, import_react3.useRef)(false);
1619
+ const [guardianFormErrors, setGuardianFormErrors] = (0, import_react2.useState)({});
1620
+ const modalRef = (0, import_react2.useRef)(null);
1621
+ const firstFocusableRef = (0, import_react2.useRef)(null);
1622
+ const lastFocusableRef = (0, import_react2.useRef)(null);
1623
+ const abortControllerRef = (0, import_react2.useRef)(null);
1624
+ const isRequestInProgressRef = (0, import_react2.useRef)(false);
1625
+ const currentAudioRef = (0, import_react2.useRef)(null);
1788
1626
  const isMobile = useMediaQuery("(max-width: 768px)");
1789
- const responsiveStyles = (0, import_react3.useMemo)(
1627
+ const responsiveStyles = (0, import_react2.useMemo)(
1790
1628
  () => ({
1791
1629
  modal: {
1792
1630
  width: isMobile ? "90%" : "700px"
@@ -1858,28 +1696,28 @@ var RedactoNoticeConsent = ({
1858
1696
  }),
1859
1697
  [isMobile]
1860
1698
  );
1861
- const componentHeadingStyle = (0, import_react3.useMemo)(
1699
+ const componentHeadingStyle = (0, import_react2.useMemo)(
1862
1700
  () => ({
1863
1701
  color: (settings == null ? void 0 : settings.headingColor) || "#323B4B",
1864
1702
  fontFamily: (settings == null ? void 0 : settings.font) || "inherit"
1865
1703
  }),
1866
1704
  [settings == null ? void 0 : settings.headingColor, settings == null ? void 0 : settings.font]
1867
1705
  );
1868
- const componentTextStyle = (0, import_react3.useMemo)(
1706
+ const componentTextStyle = (0, import_react2.useMemo)(
1869
1707
  () => ({
1870
1708
  color: (settings == null ? void 0 : settings.textColor) || "#344054",
1871
1709
  fontFamily: (settings == null ? void 0 : settings.font) || "inherit"
1872
1710
  }),
1873
1711
  [settings == null ? void 0 : settings.textColor, settings == null ? void 0 : settings.font]
1874
1712
  );
1875
- const sectionStyle = (0, import_react3.useMemo)(
1713
+ const sectionStyle = (0, import_react2.useMemo)(
1876
1714
  () => ({
1877
1715
  color: (settings == null ? void 0 : settings.textColor) || "#344054",
1878
1716
  fontFamily: (settings == null ? void 0 : settings.font) || "inherit"
1879
1717
  }),
1880
1718
  [settings == null ? void 0 : settings.textColor, settings == null ? void 0 : settings.font]
1881
1719
  );
1882
- const areAllRequiredElementsChecked = (0, import_react3.useMemo)(() => {
1720
+ const areAllRequiredElementsChecked = (0, import_react2.useMemo)(() => {
1883
1721
  if (!content) return false;
1884
1722
  return content.purposes.every((purpose) => {
1885
1723
  const requiredElements = purpose.data_elements.filter(
@@ -1891,7 +1729,7 @@ var RedactoNoticeConsent = ({
1891
1729
  });
1892
1730
  }, [content, selectedDataElements]);
1893
1731
  const acceptDisabled = isSubmitting || !areAllRequiredElementsChecked;
1894
- (0, import_react3.useEffect)(() => {
1732
+ (0, import_react2.useEffect)(() => {
1895
1733
  clearApiCache();
1896
1734
  isRequestInProgressRef.current = false;
1897
1735
  setContent(null);
@@ -1913,7 +1751,7 @@ var RedactoNoticeConsent = ({
1913
1751
  });
1914
1752
  setGuardianFormErrors({});
1915
1753
  }, [accessToken]);
1916
- (0, import_react3.useEffect)(() => {
1754
+ (0, import_react2.useEffect)(() => {
1917
1755
  if (hasAlreadyConsented) {
1918
1756
  onAccept == null ? void 0 : onAccept();
1919
1757
  }
@@ -1925,6 +1763,18 @@ var RedactoNoticeConsent = ({
1925
1763
  if (key === "privacy_policy_anchor_text" && content.privacy_policy_anchor_text) {
1926
1764
  return content.privacy_policy_anchor_text;
1927
1765
  }
1766
+ if (key === "purpose_section_heading" && content.purpose_section_heading) {
1767
+ return content.purpose_section_heading;
1768
+ }
1769
+ if (key === "notice_banner_heading" && content.notice_banner_heading) {
1770
+ return content.notice_banner_heading;
1771
+ }
1772
+ if (key === "privacy_policy_prefix_text" && content.privacy_policy_prefix_text) {
1773
+ return content.privacy_policy_prefix_text;
1774
+ }
1775
+ if (key === "notice_text" && content.notice_text) {
1776
+ return content.notice_text;
1777
+ }
1928
1778
  return defaultText;
1929
1779
  }
1930
1780
  if (!content.supported_languages_and_translations) {
@@ -2039,7 +1889,6 @@ var RedactoNoticeConsent = ({
2039
1889
  setIsLoading(false);
2040
1890
  } catch (err) {
2041
1891
  if (err instanceof Error && err.name === "AbortError") {
2042
- console.log("Request was cancelled");
2043
1892
  return;
2044
1893
  }
2045
1894
  console.error(err);
@@ -2055,7 +1904,7 @@ var RedactoNoticeConsent = ({
2055
1904
  isRequestInProgressRef.current = false;
2056
1905
  }
2057
1906
  };
2058
- (0, import_react3.useEffect)(() => {
1907
+ (0, import_react2.useEffect)(() => {
2059
1908
  injectCheckboxStyles();
2060
1909
  fetchNotice();
2061
1910
  }, [
@@ -2150,7 +1999,6 @@ var RedactoNoticeConsent = ({
2150
1999
  onAccept == null ? void 0 : onAccept();
2151
2000
  } catch (error) {
2152
2001
  if (error instanceof Error && error.name === "AbortError") {
2153
- console.log("Consent submission was cancelled");
2154
2002
  return;
2155
2003
  }
2156
2004
  console.error("Error submitting consent:", error);
@@ -2165,10 +2013,10 @@ var RedactoNoticeConsent = ({
2165
2013
  setIsSubmitting(false);
2166
2014
  }
2167
2015
  };
2168
- const handleDecline = (0, import_react3.useCallback)(async () => {
2016
+ const handleDecline = (0, import_react2.useCallback)(async () => {
2169
2017
  onDecline == null ? void 0 : onDecline();
2170
2018
  }, [onDecline]);
2171
- const handleGuardianFormChange = (0, import_react3.useCallback)(
2019
+ const handleGuardianFormChange = (0, import_react2.useCallback)(
2172
2020
  (field, value) => {
2173
2021
  setGuardianFormData((prev) => ({
2174
2022
  ...prev,
@@ -2197,7 +2045,7 @@ var RedactoNoticeConsent = ({
2197
2045
  setGuardianFormErrors(errors);
2198
2046
  return Object.keys(errors).length === 0;
2199
2047
  };
2200
- const handleGuardianFormNext = (0, import_react3.useCallback)(async () => {
2048
+ const handleGuardianFormNext = (0, import_react2.useCallback)(async () => {
2201
2049
  if (!validateGuardianForm()) {
2202
2050
  return;
2203
2051
  }
@@ -2236,14 +2084,14 @@ var RedactoNoticeConsent = ({
2236
2084
  setIsSubmittingGuardian(false);
2237
2085
  }
2238
2086
  }, [accessToken, baseUrl, guardianFormData, onError]);
2239
- const handleAgeVerificationYes = (0, import_react3.useCallback)(() => {
2087
+ const handleAgeVerificationYes = (0, import_react2.useCallback)(() => {
2240
2088
  setShowAgeVerification(false);
2241
2089
  }, []);
2242
- const handleAgeVerificationNo = (0, import_react3.useCallback)(() => {
2090
+ const handleAgeVerificationNo = (0, import_react2.useCallback)(() => {
2243
2091
  setShowAgeVerification(false);
2244
2092
  setShowGuardianForm(true);
2245
2093
  }, []);
2246
- const availableLanguages = (0, import_react3.useMemo)(() => {
2094
+ const availableLanguages = (0, import_react2.useMemo)(() => {
2247
2095
  if (!content) return [language];
2248
2096
  const languages = ["English"];
2249
2097
  if (content.default_language && content.default_language !== "English" && content.default_language !== "en") {
@@ -2260,143 +2108,288 @@ var RedactoNoticeConsent = ({
2260
2108
  }
2261
2109
  return languages;
2262
2110
  }, [content, language]);
2263
- const textSegments = (0, import_react3.useMemo)(() => {
2264
- if (!content) return [];
2265
- const segments = [];
2266
- const noticeHeading = getTranslatedText(
2267
- "notice_banner_heading",
2268
- content.notice_banner_heading || "Privacy Notice"
2269
- );
2270
- if (noticeHeading) {
2271
- segments.push({
2272
- text: noticeHeading,
2273
- elementId: "privacy-notice-title"
2274
- });
2111
+ const getLanguageCode = (0, import_react2.useCallback)(
2112
+ (displayLanguage) => {
2113
+ if (!content) return "English";
2114
+ if (displayLanguage === "English" || displayLanguage === "en") {
2115
+ return "English";
2116
+ }
2117
+ if (content.supported_languages_and_translations && content.supported_languages_and_translations[displayLanguage]) {
2118
+ return displayLanguage;
2119
+ }
2120
+ return content.default_language === "en" || content.default_language === "EN" ? "English" : content.default_language || "English";
2121
+ },
2122
+ [content]
2123
+ );
2124
+ const audioSequence = (0, import_react2.useMemo)(() => {
2125
+ if (!ttsAudioUrls || !content) return [];
2126
+ const sequence = [];
2127
+ if (ttsAudioUrls.notice_banner_heading_audio_url) {
2128
+ sequence.push(ttsAudioUrls.notice_banner_heading_audio_url);
2275
2129
  }
2276
- const noticeText = getTranslatedText("notice_text", content.notice_text);
2277
- if (noticeText) {
2278
- segments.push({
2279
- text: noticeText,
2280
- elementId: "privacy-notice-text"
2281
- });
2130
+ if (ttsAudioUrls.notice_text_audio_url) {
2131
+ sequence.push(ttsAudioUrls.notice_text_audio_url);
2282
2132
  }
2283
- const privacyPrefix = getTranslatedText(
2284
- "privacy_policy_prefix_text",
2285
- content.privacy_policy_prefix_text || ""
2286
- );
2287
- const privacyAnchor = getTranslatedText(
2288
- "privacy_policy_anchor_text",
2289
- content.privacy_policy_anchor_text || "Privacy Policy"
2290
- );
2291
- if (privacyPrefix || privacyAnchor) {
2292
- const privacyText = `${privacyPrefix} ${privacyAnchor}`.trim();
2293
- if (privacyText) {
2294
- segments.push({
2295
- text: privacyText,
2296
- elementId: "privacy-policy-text"
2133
+ if (ttsAudioUrls.privacy_policy_prefix_text_audio_url) {
2134
+ sequence.push(ttsAudioUrls.privacy_policy_prefix_text_audio_url);
2135
+ }
2136
+ if (ttsAudioUrls.privacy_policy_anchor_text_audio_url) {
2137
+ sequence.push(ttsAudioUrls.privacy_policy_anchor_text_audio_url);
2138
+ }
2139
+ if (ttsAudioUrls.purpose_section_heading_audio_url) {
2140
+ sequence.push(ttsAudioUrls.purpose_section_heading_audio_url);
2141
+ }
2142
+ const purposesToProcess = categorizedPurposes ? [
2143
+ ...categorizedPurposes.alreadyConsented,
2144
+ ...categorizedPurposes.needsConsent
2145
+ ] : content.purposes || [];
2146
+ purposesToProcess.forEach((purpose) => {
2147
+ var _a2, _b2;
2148
+ if ((_a2 = ttsAudioUrls.purposes_audio[purpose.uuid]) == null ? void 0 : _a2.name_audio_url) {
2149
+ sequence.push(ttsAudioUrls.purposes_audio[purpose.uuid].name_audio_url);
2150
+ }
2151
+ if ((_b2 = ttsAudioUrls.purposes_audio[purpose.uuid]) == null ? void 0 : _b2.description_audio_url) {
2152
+ sequence.push(
2153
+ ttsAudioUrls.purposes_audio[purpose.uuid].description_audio_url
2154
+ );
2155
+ }
2156
+ if (purpose.data_elements && purpose.data_elements.length > 0) {
2157
+ purpose.data_elements.forEach((dataElement) => {
2158
+ var _a3;
2159
+ if ((_a3 = ttsAudioUrls.data_elements_audio[dataElement.uuid]) == null ? void 0 : _a3.name_audio_url) {
2160
+ sequence.push(
2161
+ ttsAudioUrls.data_elements_audio[dataElement.uuid].name_audio_url
2162
+ );
2163
+ }
2297
2164
  });
2298
2165
  }
2166
+ });
2167
+ if (ttsAudioUrls.confirm_button_text_audio_url) {
2168
+ sequence.push(ttsAudioUrls.confirm_button_text_audio_url);
2299
2169
  }
2300
- const purposeHeading = getTranslatedText(
2301
- "purpose_section_heading",
2302
- "Manage What You Share"
2303
- );
2304
- if (purposeHeading) {
2305
- segments.push({
2306
- text: purposeHeading,
2307
- elementId: "purpose-section-heading"
2308
- });
2170
+ if (ttsAudioUrls.decline_button_text_audio_url) {
2171
+ sequence.push(ttsAudioUrls.decline_button_text_audio_url);
2172
+ }
2173
+ return sequence;
2174
+ }, [ttsAudioUrls, content, categorizedPurposes]);
2175
+ const elementIdSequence = (0, import_react2.useMemo)(() => {
2176
+ if (!ttsAudioUrls || !content) return [];
2177
+ const elementIds = [];
2178
+ if (ttsAudioUrls.notice_banner_heading_audio_url) {
2179
+ elementIds.push("privacy-notice-title");
2180
+ }
2181
+ if (ttsAudioUrls.notice_text_audio_url) {
2182
+ elementIds.push("privacy-notice-text");
2183
+ }
2184
+ if (ttsAudioUrls.privacy_policy_prefix_text_audio_url) {
2185
+ elementIds.push("privacy-policy-text");
2186
+ }
2187
+ if (ttsAudioUrls.privacy_policy_anchor_text_audio_url) {
2188
+ elementIds.push("privacy-policy-link");
2189
+ }
2190
+ if (ttsAudioUrls.purpose_section_heading_audio_url) {
2191
+ elementIds.push("purpose-section-heading");
2309
2192
  }
2310
- const purposesToRead = categorizedPurposes ? [
2193
+ const purposesToProcess = categorizedPurposes ? [
2311
2194
  ...categorizedPurposes.alreadyConsented,
2312
2195
  ...categorizedPurposes.needsConsent
2313
2196
  ] : content.purposes || [];
2314
- purposesToRead.forEach((purpose) => {
2315
- const purposeName = getTranslatedText(
2316
- `purposes.name`,
2317
- purpose.name,
2318
- purpose.uuid
2319
- );
2320
- if (purposeName) {
2321
- segments.push({
2322
- text: purposeName,
2323
- elementId: `purpose-name-${purpose.uuid}`
2324
- });
2197
+ purposesToProcess.forEach((purpose) => {
2198
+ var _a2, _b2;
2199
+ if ((_a2 = ttsAudioUrls.purposes_audio[purpose.uuid]) == null ? void 0 : _a2.name_audio_url) {
2200
+ elementIds.push(`purpose-name-${purpose.uuid}`);
2325
2201
  }
2326
- const purposeDescription = getTranslatedText(
2327
- `purposes.description`,
2328
- purpose.description,
2329
- purpose.uuid
2330
- );
2331
- if (purposeDescription) {
2332
- segments.push({
2333
- text: purposeDescription,
2334
- elementId: `purpose-description-${purpose.uuid}`
2335
- });
2202
+ if ((_b2 = ttsAudioUrls.purposes_audio[purpose.uuid]) == null ? void 0 : _b2.description_audio_url) {
2203
+ elementIds.push(`purpose-description-${purpose.uuid}`);
2336
2204
  }
2337
2205
  if (purpose.data_elements && purpose.data_elements.length > 0) {
2338
2206
  purpose.data_elements.forEach((dataElement) => {
2339
- const elementName = getTranslatedText(
2340
- `data_elements.name`,
2341
- dataElement.name,
2342
- dataElement.uuid
2343
- );
2344
- if (elementName) {
2345
- const requiredText = dataElement.required ? " (required)" : "";
2346
- segments.push({
2347
- text: `${elementName}${requiredText}`,
2348
- elementId: `data-element-${purpose.uuid}-${dataElement.uuid}`
2349
- });
2207
+ var _a3;
2208
+ if ((_a3 = ttsAudioUrls.data_elements_audio[dataElement.uuid]) == null ? void 0 : _a3.name_audio_url) {
2209
+ elementIds.push(`data-element-${purpose.uuid}-${dataElement.uuid}`);
2350
2210
  }
2351
2211
  });
2352
2212
  }
2353
2213
  });
2354
- return segments;
2355
- }, [content, categorizedPurposes, getTranslatedText]);
2356
- const tts = useTextToSpeech(textSegments, selectedLanguage);
2357
- (0, import_react3.useEffect)(() => {
2358
- if (!tts.isPlaying || !content || textSegments.length === 0) return;
2359
- const currentSegment = textSegments[tts.currentIndex];
2360
- if (!currentSegment) return;
2361
- let purposeUuid = null;
2362
- const dataElementMatch = currentSegment.elementId.match(
2363
- /^data-element-(.+?)-(.+)$/
2364
- );
2365
- if (dataElementMatch) {
2366
- purposeUuid = dataElementMatch[1];
2367
- } else {
2368
- const purposeNameMatch = currentSegment.elementId.match(/^purpose-name-(.+)$/);
2369
- const purposeDescMatch = currentSegment.elementId.match(
2370
- /^purpose-description-(.+)$/
2371
- );
2372
- if (purposeNameMatch) {
2373
- purposeUuid = purposeNameMatch[1];
2374
- } else if (purposeDescMatch) {
2375
- purposeUuid = purposeDescMatch[1];
2214
+ if (ttsAudioUrls.confirm_button_text_audio_url) {
2215
+ elementIds.push("confirm-button-text");
2216
+ }
2217
+ if (ttsAudioUrls.decline_button_text_audio_url) {
2218
+ elementIds.push("decline-button-text");
2219
+ }
2220
+ return elementIds;
2221
+ }, [ttsAudioUrls, content, categorizedPurposes]);
2222
+ const stopAudio = (0, import_react2.useCallback)(() => {
2223
+ if (currentAudioRef.current) {
2224
+ currentAudioRef.current.pause();
2225
+ currentAudioRef.current.currentTime = 0;
2226
+ currentAudioRef.current = null;
2227
+ }
2228
+ setIsPlaying(false);
2229
+ setIsPaused(false);
2230
+ setCurrentAudioIndex(0);
2231
+ setHighlightedElementId(null);
2232
+ }, []);
2233
+ const playNextAudio = (0, import_react2.useCallback)(
2234
+ (index) => {
2235
+ if (index >= audioSequence.length) {
2236
+ stopAudio();
2237
+ return;
2376
2238
  }
2239
+ if (currentAudioRef.current) {
2240
+ currentAudioRef.current.pause();
2241
+ currentAudioRef.current = null;
2242
+ }
2243
+ const audio = new Audio(audioSequence[index]);
2244
+ currentAudioRef.current = audio;
2245
+ setCurrentAudioIndex(index);
2246
+ setIsPlaying(true);
2247
+ setIsPaused(false);
2248
+ const elementId = elementIdSequence[index];
2249
+ if (elementId) {
2250
+ setHighlightedElementId(elementId);
2251
+ }
2252
+ audio.onended = () => {
2253
+ playNextAudio(index + 1);
2254
+ };
2255
+ audio.onerror = () => {
2256
+ console.warn(`Failed to load audio at index ${index}`);
2257
+ playNextAudio(index + 1);
2258
+ };
2259
+ audio.play().catch((error) => {
2260
+ console.warn(`Failed to play audio at index ${index}:`, error);
2261
+ setIsPlaying(false);
2262
+ });
2263
+ },
2264
+ [audioSequence, elementIdSequence, stopAudio]
2265
+ );
2266
+ const playAudio = (0, import_react2.useCallback)(() => {
2267
+ if (audioSequence.length === 0) return;
2268
+ if (isPaused && currentAudioRef.current) {
2269
+ currentAudioRef.current.play().then(() => {
2270
+ setIsPlaying(true);
2271
+ setIsPaused(false);
2272
+ }).catch((error) => {
2273
+ console.warn("Failed to resume audio:", error);
2274
+ });
2275
+ } else {
2276
+ const startIndex = isPlaying ? currentAudioIndex : 0;
2277
+ playNextAudio(startIndex);
2377
2278
  }
2378
- if (purposeUuid && collapsedPurposes[purposeUuid]) {
2379
- setCollapsedPurposes((prev) => ({
2380
- ...prev,
2381
- [purposeUuid]: false
2382
- }));
2279
+ }, [audioSequence, isPaused, isPlaying, currentAudioIndex, playNextAudio]);
2280
+ const pauseAudio = (0, import_react2.useCallback)(() => {
2281
+ if (currentAudioRef.current && isPlaying) {
2282
+ currentAudioRef.current.pause();
2283
+ setIsPlaying(false);
2284
+ setIsPaused(true);
2285
+ }
2286
+ }, [isPlaying]);
2287
+ const toggleAudio = (0, import_react2.useCallback)(() => {
2288
+ if (isPlaying) {
2289
+ pauseAudio();
2290
+ } else {
2291
+ playAudio();
2292
+ }
2293
+ }, [isPlaying, playAudio, pauseAudio]);
2294
+ (0, import_react2.useEffect)(() => {
2295
+ var _a2;
2296
+ if (!isPlaying || !content || audioSequence.length === 0) return;
2297
+ const currentIndex = currentAudioIndex;
2298
+ const headerAudioCount = 5;
2299
+ if (currentIndex < headerAudioCount) return;
2300
+ const purposesToProcess = categorizedPurposes ? [
2301
+ ...categorizedPurposes.alreadyConsented,
2302
+ ...categorizedPurposes.needsConsent
2303
+ ] : content.purposes || [];
2304
+ let audioOffset = headerAudioCount;
2305
+ for (const purpose of purposesToProcess) {
2306
+ const purposeAudioCount = 2;
2307
+ const dataElementsAudioCount = ((_a2 = purpose.data_elements) == null ? void 0 : _a2.length) || 0;
2308
+ const totalPurposeAudioCount = purposeAudioCount + dataElementsAudioCount;
2309
+ if (currentIndex >= audioOffset && currentIndex < audioOffset + totalPurposeAudioCount) {
2310
+ if (collapsedPurposes[purpose.uuid]) {
2311
+ setCollapsedPurposes((prev) => ({
2312
+ ...prev,
2313
+ [purpose.uuid]: false
2314
+ }));
2315
+ }
2316
+ break;
2317
+ }
2318
+ audioOffset += totalPurposeAudioCount;
2383
2319
  }
2384
2320
  }, [
2385
- tts.isPlaying,
2386
- tts.currentIndex,
2387
- textSegments,
2321
+ isPlaying,
2322
+ currentAudioIndex,
2323
+ audioSequence,
2388
2324
  content,
2325
+ categorizedPurposes,
2389
2326
  collapsedPurposes
2390
2327
  ]);
2391
- (0, import_react3.useEffect)(() => {
2392
- tts.stop();
2393
- }, [selectedLanguage]);
2394
- (0, import_react3.useEffect)(() => {
2395
- tts.stop();
2396
- }, [content]);
2397
- const handleTTSButtonClick = (0, import_react3.useCallback)(() => {
2398
- tts.toggle();
2399
- }, [tts]);
2328
+ (0, import_react2.useEffect)(() => {
2329
+ const removeAllHighlights = () => {
2330
+ document.querySelectorAll(".redacto-tts-highlight").forEach((el) => {
2331
+ el.classList.remove("redacto-tts-highlight");
2332
+ });
2333
+ };
2334
+ if (!highlightedElementId || !isPlaying) {
2335
+ removeAllHighlights();
2336
+ return;
2337
+ }
2338
+ removeAllHighlights();
2339
+ const highlightTimeout = setTimeout(() => {
2340
+ const element = document.getElementById(highlightedElementId);
2341
+ if (element) {
2342
+ element.classList.add("redacto-tts-highlight");
2343
+ void element.offsetHeight;
2344
+ const rect = element.getBoundingClientRect();
2345
+ const isVisible = rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth);
2346
+ if (!isVisible) {
2347
+ element.scrollIntoView({
2348
+ behavior: "smooth",
2349
+ block: "center",
2350
+ inline: "nearest"
2351
+ });
2352
+ }
2353
+ } else {
2354
+ console.warn(
2355
+ `TTS Highlight: Element with ID "${highlightedElementId}" not found`
2356
+ );
2357
+ }
2358
+ }, 50);
2359
+ return () => {
2360
+ clearTimeout(highlightTimeout);
2361
+ removeAllHighlights();
2362
+ };
2363
+ }, [highlightedElementId, isPlaying]);
2364
+ (0, import_react2.useEffect)(() => {
2365
+ setIsTTSAvailable(false);
2366
+ setTtsAudioUrls(null);
2367
+ stopAudio();
2368
+ if (!content || !content.notice_uuid) {
2369
+ return;
2370
+ }
2371
+ const languageCode = getLanguageCode(selectedLanguage);
2372
+ const ttsAbortController = new AbortController();
2373
+ fetchTTSAudioUrls({
2374
+ accessToken,
2375
+ baseUrl,
2376
+ noticeUuid: content.notice_uuid,
2377
+ language: languageCode,
2378
+ signal: ttsAbortController.signal
2379
+ }).then((response) => {
2380
+ setTtsAudioUrls(response.detail);
2381
+ setIsTTSAvailable(true);
2382
+ }).catch((error) => {
2383
+ if (error instanceof Error && error.name !== "AbortError") {
2384
+ console.warn("Failed to fetch TTS audio URLs:", error.message);
2385
+ setIsTTSAvailable(false);
2386
+ setTtsAudioUrls(null);
2387
+ }
2388
+ });
2389
+ return () => {
2390
+ ttsAbortController.abort();
2391
+ };
2392
+ }, [content, selectedLanguage, accessToken, baseUrl, getLanguageCode]);
2400
2393
  const modalStyle = {
2401
2394
  borderRadius: (settings == null ? void 0 : settings.borderRadius) || "8px",
2402
2395
  backgroundColor: (settings == null ? void 0 : settings.backgroundColor) || "#ffffff"
@@ -2433,7 +2426,7 @@ var RedactoNoticeConsent = ({
2433
2426
  const handleCloseError = () => {
2434
2427
  setErrorMessage(null);
2435
2428
  };
2436
- (0, import_react3.useEffect)(() => {
2429
+ (0, import_react2.useEffect)(() => {
2437
2430
  const handleKeyDown = (event) => {
2438
2431
  if (!modalRef.current) return;
2439
2432
  const focusableElements = modalRef.current.querySelectorAll(
@@ -2472,13 +2465,20 @@ var RedactoNoticeConsent = ({
2472
2465
  modal == null ? void 0 : modal.removeEventListener("keydown", handleKeyDown);
2473
2466
  };
2474
2467
  }, [isLoading, handleDecline]);
2475
- (0, import_react3.useEffect)(() => {
2468
+ (0, import_react2.useEffect)(() => {
2469
+ stopAudio();
2470
+ }, [selectedLanguage, stopAudio]);
2471
+ (0, import_react2.useEffect)(() => {
2472
+ stopAudio();
2473
+ }, [content, stopAudio]);
2474
+ (0, import_react2.useEffect)(() => {
2476
2475
  return () => {
2477
2476
  if (abortControllerRef.current) {
2478
2477
  abortControllerRef.current.abort();
2479
2478
  }
2479
+ stopAudio();
2480
2480
  };
2481
- }, []);
2481
+ }, [stopAudio]);
2482
2482
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: hasAlreadyConsented ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
2483
2483
  blockUI && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2484
2484
  "div",
@@ -2623,6 +2623,7 @@ var RedactoNoticeConsent = ({
2623
2623
  },
2624
2624
  onMouseOver: (e) => e.currentTarget.style.backgroundColor = "#B91C1C",
2625
2625
  onMouseOut: (e) => e.currentTarget.style.backgroundColor = "#DC2626",
2626
+ "aria-label": "Refresh and retry loading consent notice",
2626
2627
  children: "Refresh"
2627
2628
  }
2628
2629
  )
@@ -2749,7 +2750,8 @@ var RedactoNoticeConsent = ({
2749
2750
  "notice_banner_heading",
2750
2751
  (content == null ? void 0 : content.notice_banner_heading) || "Privacy Notice"
2751
2752
  )
2752
- }
2753
+ },
2754
+ `privacy-notice-title-${selectedLanguage}`
2753
2755
  )
2754
2756
  ] }),
2755
2757
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.languageSelectorContainer, children: [
@@ -2762,57 +2764,44 @@ var RedactoNoticeConsent = ({
2762
2764
  gap: "8px"
2763
2765
  },
2764
2766
  children: [
2765
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2767
+ isTTSAvailable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2766
2768
  "button",
2767
2769
  {
2768
- ref: firstFocusableRef,
2770
+ onClick: toggleAudio,
2769
2771
  style: {
2770
2772
  ...styles.topRight,
2771
2773
  ...responsiveStyles.topRight,
2772
- ...languageSelectorStyle
2774
+ ...languageSelectorStyle,
2775
+ padding: "3px 9px",
2776
+ display: "flex",
2777
+ alignItems: "center",
2778
+ justifyContent: "center"
2773
2779
  },
2774
- onClick: toggleLanguageDropdown,
2775
- "aria-expanded": isLanguageDropdownOpen,
2776
- "aria-haspopup": "listbox",
2777
- "aria-controls": "language-listbox",
2778
- children: [
2779
- selectedLanguage,
2780
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2780
+ "aria-label": isPlaying && !isPaused ? "Pause audio playback" : isPaused ? "Resume audio playback" : "Start audio playback",
2781
+ title: isPlaying && !isPaused ? "Pause Talkback" : isPaused ? "Resume Talkback" : "Start Talkback",
2782
+ children: isPlaying && !isPaused ? (
2783
+ // Pause icon
2784
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2781
2785
  "svg",
2782
2786
  {
2783
2787
  xmlns: "http://www.w3.org/2000/svg",
2784
2788
  width: "16",
2785
2789
  height: "16",
2786
- viewBox: "0 0 16 16",
2790
+ viewBox: "0 0 24 24",
2787
2791
  fill: "none",
2788
2792
  stroke: ((_r = (_q = settings == null ? void 0 : settings.button) == null ? void 0 : _q.language) == null ? void 0 : _r.textColor) || "currentColor",
2789
2793
  strokeWidth: "2",
2790
2794
  strokeLinecap: "round",
2791
2795
  strokeLinejoin: "round",
2792
- style: { flexShrink: 0, marginLeft: "4px" },
2793
2796
  "aria-hidden": "true",
2794
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M4 6l4 4 4-4" })
2797
+ children: [
2798
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "6", y: "4", width: "4", height: "16" }),
2799
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "14", y: "4", width: "4", height: "16" })
2800
+ ]
2795
2801
  }
2796
2802
  )
2797
- ]
2798
- }
2799
- ) }),
2800
- (selectedLanguage === "English" || selectedLanguage === "en") && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2801
- "button",
2802
- {
2803
- onClick: handleTTSButtonClick,
2804
- style: {
2805
- ...styles.topRight,
2806
- ...responsiveStyles.topRight,
2807
- ...languageSelectorStyle,
2808
- padding: "3px 9px",
2809
- opacity: textSegments.length === 0 ? 0.5 : 1
2810
- },
2811
- "aria-label": tts.isPlaying && !tts.isPaused ? "Pause text-to-speech" : tts.isPaused ? "Resume text-to-speech" : "Start text-to-speech",
2812
- title: tts.isPlaying && !tts.isPaused ? "Pause Talkback" : tts.isPaused ? "Resume Talkback" : "Start Talkback",
2813
- disabled: textSegments.length === 0,
2814
- children: tts.isPlaying && !tts.isPaused ? (
2815
- // Pause icon
2803
+ ) : (
2804
+ // Play/Sound icon
2816
2805
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2817
2806
  "svg",
2818
2807
  {
@@ -2827,35 +2816,50 @@ var RedactoNoticeConsent = ({
2827
2816
  strokeLinejoin: "round",
2828
2817
  "aria-hidden": "true",
2829
2818
  children: [
2830
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "6", y: "4", width: "4", height: "16" }),
2831
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "14", y: "4", width: "4", height: "16" })
2819
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polygon", { points: "11 5 6 9 2 9 2 15 6 15 11 19 11 5" }),
2820
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07" })
2832
2821
  ]
2833
2822
  }
2834
2823
  )
2835
- ) : (
2836
- // Play/Sound icon
2837
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2824
+ )
2825
+ }
2826
+ ),
2827
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2828
+ "button",
2829
+ {
2830
+ ref: firstFocusableRef,
2831
+ style: {
2832
+ ...styles.topRight,
2833
+ ...responsiveStyles.topRight,
2834
+ ...languageSelectorStyle
2835
+ },
2836
+ onClick: toggleLanguageDropdown,
2837
+ "aria-expanded": isLanguageDropdownOpen,
2838
+ "aria-haspopup": "listbox",
2839
+ "aria-controls": "language-listbox",
2840
+ "aria-label": `Select language. Current language: ${selectedLanguage}`,
2841
+ children: [
2842
+ selectedLanguage,
2843
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2838
2844
  "svg",
2839
2845
  {
2840
2846
  xmlns: "http://www.w3.org/2000/svg",
2841
2847
  width: "16",
2842
2848
  height: "16",
2843
- viewBox: "0 0 24 24",
2849
+ viewBox: "0 0 16 16",
2844
2850
  fill: "none",
2845
2851
  stroke: ((_v = (_u = settings == null ? void 0 : settings.button) == null ? void 0 : _u.language) == null ? void 0 : _v.textColor) || "currentColor",
2846
2852
  strokeWidth: "2",
2847
2853
  strokeLinecap: "round",
2848
2854
  strokeLinejoin: "round",
2855
+ style: { flexShrink: 0, marginLeft: "4px" },
2849
2856
  "aria-hidden": "true",
2850
- children: [
2851
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polygon", { points: "11 5 6 9 2 9 2 15 6 15 11 19 11 5" }),
2852
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07" })
2853
- ]
2857
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M4 6l4 4 4-4" })
2854
2858
  }
2855
2859
  )
2856
- )
2860
+ ]
2857
2861
  }
2858
- )
2862
+ ) })
2859
2863
  ]
2860
2864
  }
2861
2865
  ),
@@ -2882,6 +2886,7 @@ var RedactoNoticeConsent = ({
2882
2886
  role: "option",
2883
2887
  "aria-selected": selectedLanguage === lang,
2884
2888
  tabIndex: 0,
2889
+ "aria-label": `Select ${lang} language`,
2885
2890
  children: lang
2886
2891
  },
2887
2892
  lang
@@ -2909,32 +2914,47 @@ var RedactoNoticeConsent = ({
2909
2914
  ...componentTextStyle
2910
2915
  },
2911
2916
  children: [
2912
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { id: "privacy-notice-text", children: content ? getTranslatedText("notice_text", content.notice_text) : "" }),
2917
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2918
+ "span",
2919
+ {
2920
+ id: "privacy-notice-text",
2921
+ children: content ? getTranslatedText("notice_text", content.notice_text) : ""
2922
+ },
2923
+ `privacy-notice-text-${selectedLanguage}`
2924
+ ),
2913
2925
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
2914
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { id: "privacy-policy-text", children: [
2915
- getTranslatedText(
2916
- "privacy_policy_prefix_text",
2917
- (content == null ? void 0 : content.privacy_policy_prefix_text) || ""
2918
- ),
2919
- " ",
2920
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2921
- "a",
2922
- {
2923
- id: "privacy-policy-link",
2924
- style: { ...styles.link, ...linkStyle },
2925
- href: (content == null ? void 0 : content.privacy_policy_url) || "#",
2926
- target: "_blank",
2927
- rel: "noopener noreferrer",
2928
- "aria-label": "Privacy Policy (opens in new tab)",
2929
- children: getTranslatedText(
2930
- "privacy_policy_anchor_text",
2931
- (content == null ? void 0 : content.privacy_policy_anchor_text) || "Privacy Policy"
2926
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2927
+ "span",
2928
+ {
2929
+ id: "privacy-policy-text",
2930
+ children: [
2931
+ getTranslatedText(
2932
+ "privacy_policy_prefix_text",
2933
+ (content == null ? void 0 : content.privacy_policy_prefix_text) || ""
2934
+ ),
2935
+ " ",
2936
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2937
+ "a",
2938
+ {
2939
+ id: "privacy-policy-link",
2940
+ style: { ...styles.link, ...linkStyle },
2941
+ href: (content == null ? void 0 : content.privacy_policy_url) || "#",
2942
+ target: "_blank",
2943
+ rel: "noopener noreferrer",
2944
+ "aria-label": "Privacy Policy (opens in new tab)",
2945
+ children: getTranslatedText(
2946
+ "privacy_policy_anchor_text",
2947
+ (content == null ? void 0 : content.privacy_policy_anchor_text) || "Privacy Policy"
2948
+ )
2949
+ }
2932
2950
  )
2933
- }
2934
- )
2935
- ] })
2951
+ ]
2952
+ },
2953
+ `privacy-policy-text-${selectedLanguage}`
2954
+ )
2936
2955
  ]
2937
- }
2956
+ },
2957
+ `privacy-text-${selectedLanguage}`
2938
2958
  ),
2939
2959
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2940
2960
  "h2",
@@ -2949,7 +2969,8 @@ var RedactoNoticeConsent = ({
2949
2969
  "purpose_section_heading",
2950
2970
  "Manage What You Share"
2951
2971
  )
2952
- }
2972
+ },
2973
+ `purpose-section-heading-${selectedLanguage}`
2953
2974
  ),
2954
2975
  categorizedPurposes ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.optionsContainer, children: [
2955
2976
  categorizedPurposes.alreadyConsented.map((purpose) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -2966,9 +2987,10 @@ var RedactoNoticeConsent = ({
2966
2987
  onPurposeCollapse: togglePurposeCollapse,
2967
2988
  onDataElementToggle: handleDataElementCheckboxChange,
2968
2989
  getTranslatedText,
2969
- isAlreadyConsented: true
2990
+ isAlreadyConsented: true,
2991
+ selectedLanguage
2970
2992
  },
2971
- purpose.uuid
2993
+ `${purpose.uuid}-${selectedLanguage}`
2972
2994
  )),
2973
2995
  categorizedPurposes.needsConsent.map((purpose) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2974
2996
  PurposeItem,
@@ -2984,9 +3006,10 @@ var RedactoNoticeConsent = ({
2984
3006
  onPurposeCollapse: togglePurposeCollapse,
2985
3007
  onDataElementToggle: handleDataElementCheckboxChange,
2986
3008
  getTranslatedText,
2987
- isAlreadyConsented: false
3009
+ isAlreadyConsented: false,
3010
+ selectedLanguage
2988
3011
  },
2989
- purpose.uuid
3012
+ `${purpose.uuid}-${selectedLanguage}`
2990
3013
  ))
2991
3014
  ] }) : (
2992
3015
  /* Regular consent UI */
@@ -3004,9 +3027,10 @@ var RedactoNoticeConsent = ({
3004
3027
  onPurposeCollapse: togglePurposeCollapse,
3005
3028
  onDataElementToggle: handleDataElementCheckboxChange,
3006
3029
  getTranslatedText,
3007
- isAlreadyConsented: false
3030
+ isAlreadyConsented: false,
3031
+ selectedLanguage
3008
3032
  },
3009
- purpose.uuid
3033
+ `${purpose.uuid}-${selectedLanguage}`
3010
3034
  )) })
3011
3035
  )
3012
3036
  ]
@@ -3025,6 +3049,7 @@ var RedactoNoticeConsent = ({
3025
3049
  "button",
3026
3050
  {
3027
3051
  ref: lastFocusableRef,
3052
+ id: "confirm-button-text",
3028
3053
  style: {
3029
3054
  ...styles.button,
3030
3055
  ...responsiveStyles.button,
@@ -3047,6 +3072,7 @@ var RedactoNoticeConsent = ({
3047
3072
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3048
3073
  "button",
3049
3074
  {
3075
+ id: "decline-button-text",
3050
3076
  style: {
3051
3077
  ...styles.button,
3052
3078
  ...responsiveStyles.button,
@@ -3075,7 +3101,7 @@ var RedactoNoticeConsent = ({
3075
3101
  };
3076
3102
 
3077
3103
  // src/RedactoNoticeConsentInline/RedactoNoticeConsentInline.tsx
3078
- var import_react5 = require("react");
3104
+ var import_react4 = require("react");
3079
3105
 
3080
3106
  // src/RedactoNoticeConsentInline/api/index.ts
3081
3107
  var BASE_URL2 = "https://api.redacto.tech/consent";
@@ -3549,11 +3575,11 @@ var styles2 = {
3549
3575
  };
3550
3576
 
3551
3577
  // src/RedactoNoticeConsentInline/useMediaQuery.ts
3552
- var import_react4 = require("react");
3578
+ var import_react3 = require("react");
3553
3579
  var useMediaQuery2 = (query) => {
3554
3580
  const getMatches = () => typeof window !== "undefined" ? window.matchMedia(query).matches : false;
3555
- const [matches, setMatches] = (0, import_react4.useState)(getMatches);
3556
- (0, import_react4.useEffect)(() => {
3581
+ const [matches, setMatches] = (0, import_react3.useState)(getMatches);
3582
+ (0, import_react3.useEffect)(() => {
3557
3583
  if (typeof window === "undefined") return;
3558
3584
  const media = window.matchMedia(query);
3559
3585
  const listener = (e) => {
@@ -3619,22 +3645,22 @@ var RedactoConsentInlineComponent = ({
3619
3645
  applicationId
3620
3646
  }) => {
3621
3647
  var _a;
3622
- const [content, setContent] = (0, import_react5.useState)(null);
3623
- const [isLoading, setIsLoading] = (0, import_react5.useState)(true);
3624
- const [isSubmitting, setIsSubmitting] = (0, import_react5.useState)(false);
3625
- const [selectedLanguage, setSelectedLanguage] = (0, import_react5.useState)(language);
3626
- const [collapsedPurposes, setCollapsedPurposes] = (0, import_react5.useState)({});
3627
- const [selectedPurposes, setSelectedPurposes] = (0, import_react5.useState)({});
3628
- const [selectedDataElements, setSelectedDataElements] = (0, import_react5.useState)({});
3629
- const [hasAlreadyConsented, setHasAlreadyConsented] = (0, import_react5.useState)(false);
3630
- const [fetchError, setFetchError] = (0, import_react5.useState)(null);
3631
- const [errorMessage, setErrorMessage] = (0, import_react5.useState)(null);
3632
- const hasSubmittedRef = (0, import_react5.useRef)(false);
3633
- (0, import_react5.useEffect)(() => {
3648
+ const [content, setContent] = (0, import_react4.useState)(null);
3649
+ const [isLoading, setIsLoading] = (0, import_react4.useState)(true);
3650
+ const [isSubmitting, setIsSubmitting] = (0, import_react4.useState)(false);
3651
+ const [selectedLanguage, setSelectedLanguage] = (0, import_react4.useState)(language);
3652
+ const [collapsedPurposes, setCollapsedPurposes] = (0, import_react4.useState)({});
3653
+ const [selectedPurposes, setSelectedPurposes] = (0, import_react4.useState)({});
3654
+ const [selectedDataElements, setSelectedDataElements] = (0, import_react4.useState)({});
3655
+ const [hasAlreadyConsented, setHasAlreadyConsented] = (0, import_react4.useState)(false);
3656
+ const [fetchError, setFetchError] = (0, import_react4.useState)(null);
3657
+ const [errorMessage, setErrorMessage] = (0, import_react4.useState)(null);
3658
+ const hasSubmittedRef = (0, import_react4.useRef)(false);
3659
+ (0, import_react4.useEffect)(() => {
3634
3660
  injectSpinnerAnimation();
3635
3661
  }, []);
3636
3662
  const isMobile = useMediaQuery2("(max-width: 768px)");
3637
- const responsiveStyles = (0, import_react5.useMemo)(
3663
+ const responsiveStyles = (0, import_react4.useMemo)(
3638
3664
  () => ({
3639
3665
  optionTitle: {
3640
3666
  fontSize: isMobile ? "14px" : "16px"
@@ -3652,7 +3678,7 @@ var RedactoConsentInlineComponent = ({
3652
3678
  }),
3653
3679
  [isMobile]
3654
3680
  );
3655
- const areAllRequiredElementsChecked = (0, import_react5.useMemo)(() => {
3681
+ const areAllRequiredElementsChecked = (0, import_react4.useMemo)(() => {
3656
3682
  if (!content) return false;
3657
3683
  return content.purposes.every((purpose) => {
3658
3684
  const requiredElements = purpose.data_elements.filter(
@@ -3663,11 +3689,11 @@ var RedactoConsentInlineComponent = ({
3663
3689
  );
3664
3690
  });
3665
3691
  }, [content, selectedDataElements]);
3666
- (0, import_react5.useEffect)(() => {
3692
+ (0, import_react4.useEffect)(() => {
3667
3693
  onValidationChange == null ? void 0 : onValidationChange(areAllRequiredElementsChecked);
3668
3694
  }, [areAllRequiredElementsChecked, onValidationChange]);
3669
3695
  const acceptDisabled = isSubmitting || !areAllRequiredElementsChecked || !accessToken;
3670
- (0, import_react5.useEffect)(() => {
3696
+ (0, import_react4.useEffect)(() => {
3671
3697
  if (hasAlreadyConsented) {
3672
3698
  onAccept == null ? void 0 : onAccept();
3673
3699
  }
@@ -3762,7 +3788,7 @@ var RedactoConsentInlineComponent = ({
3762
3788
  setIsLoading(false);
3763
3789
  }
3764
3790
  };
3765
- (0, import_react5.useEffect)(() => {
3791
+ (0, import_react4.useEffect)(() => {
3766
3792
  fetchNotice();
3767
3793
  }, [org_uuid, workspace_uuid, notice_uuid, language, applicationId]);
3768
3794
  const togglePurposeCollapse = (purposeUuid) => {
@@ -3818,7 +3844,7 @@ var RedactoConsentInlineComponent = ({
3818
3844
  return newState;
3819
3845
  });
3820
3846
  };
3821
- const handleAcceptWithToken = (0, import_react5.useCallback)(
3847
+ const handleAcceptWithToken = (0, import_react4.useCallback)(
3822
3848
  async (tokenToUse) => {
3823
3849
  if (!tokenToUse || !content) {
3824
3850
  setErrorMessage("Unable to submit consent. Please try again.");
@@ -3880,7 +3906,7 @@ var RedactoConsentInlineComponent = ({
3880
3906
  onAccept
3881
3907
  ]
3882
3908
  );
3883
- (0, import_react5.useEffect)(() => {
3909
+ (0, import_react4.useEffect)(() => {
3884
3910
  if (accessToken && content && areAllRequiredElementsChecked && !isSubmitting && !hasSubmittedRef.current) {
3885
3911
  hasSubmittedRef.current = true;
3886
3912
  const autoSubmit = async () => {
@@ -3901,7 +3927,7 @@ var RedactoConsentInlineComponent = ({
3901
3927
  isSubmitting,
3902
3928
  handleAcceptWithToken
3903
3929
  ]);
3904
- (0, import_react5.useEffect)(() => {
3930
+ (0, import_react4.useEffect)(() => {
3905
3931
  if (!accessToken) {
3906
3932
  hasSubmittedRef.current = false;
3907
3933
  }
@@ -3951,6 +3977,11 @@ var RedactoConsentInlineComponent = ({
3951
3977
  tabIndex: 0,
3952
3978
  "aria-expanded": !collapsedPurposes[purpose.uuid],
3953
3979
  "aria-controls": `purpose-${purpose.uuid}`,
3980
+ "aria-label": `${collapsedPurposes[purpose.uuid] ? "Expand" : "Collapse"} ${getTranslatedText(
3981
+ `purposes.name`,
3982
+ purpose.name,
3983
+ purpose.uuid
3984
+ )} details`,
3954
3985
  onKeyDown: (e) => {
3955
3986
  if (e.key === "Enter" || e.key === " ") {
3956
3987
  e.preventDefault();
@@ -4095,7 +4126,7 @@ var RedactoConsentInlineComponent = ({
4095
4126
  ] });
4096
4127
  };
4097
4128
  RedactoConsentInlineComponent.displayName = "RedactoConsentInline";
4098
- var RedactoConsentInline = (0, import_react5.memo)(RedactoConsentInlineComponent);
4129
+ var RedactoConsentInline = (0, import_react4.memo)(RedactoConsentInlineComponent);
4099
4130
  // Annotate the CommonJS export names for ESM import in node:
4100
4131
  0 && (module.exports = {
4101
4132
  RedactoNoticeConsent,