ngp-accessibility 1.0.5 → 1.0.7

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.esm.js CHANGED
@@ -2,6 +2,7 @@ import React, { createContext, useState, useEffect, useContext } from 'react';
2
2
 
3
3
  const translations = {
4
4
  en: {
5
+ language: "Language",
5
6
  increaseText: "Increase Text",
6
7
  decreaseText: "Decrease Text",
7
8
  textMagnifier: "Text Magnifier",
@@ -13,9 +14,12 @@ const translations = {
13
14
  readableFont: "Readable Font",
14
15
  pauseAnimations: "Pause Animations",
15
16
  readingGuide: "Reading Guide",
16
- voiceCommand: "Voice Command",
17
+ readAloud: "Read Aloud",
18
+ colorBlindMode: "Color Blind Mode",
19
+ focusIndicator: "Focus Indicator",
17
20
  },
18
21
  tl: {
22
+ language: "Wika",
19
23
  increaseText: "Palakihin ang Teksto",
20
24
  decreaseText: "Paliitin ang Teksto",
21
25
  textMagnifier: "Text Magnifier",
@@ -27,9 +31,12 @@ const translations = {
27
31
  readableFont: "Madaling Basahin na Font",
28
32
  pauseAnimations: "I-pause ang mga Animation",
29
33
  readingGuide: "Reading Guide",
30
- voiceCommand: "Voice Command",
34
+ readAloud: "Basahin nang Malakas",
35
+ colorBlindMode: "Color Blind Mode",
36
+ focusIndicator: "Focus Indicator",
31
37
  },
32
38
  ceb: {
39
+ language: "Pinulongan",
33
40
  increaseText: "Padak-on ang Teksto",
34
41
  decreaseText: "Pagamay-on ang Teksto",
35
42
  textMagnifier: "Text Magnifier",
@@ -41,10 +48,38 @@ const translations = {
41
48
  readableFont: "Sayon Basahon nga Font",
42
49
  pauseAnimations: "Ihunong ang mga Animation",
43
50
  readingGuide: "Reading Guide",
44
- voiceCommand: "Voice Command",
51
+ readAloud: "Basaha og Kusog",
52
+ colorBlindMode: "Color Blind Mode",
53
+ focusIndicator: "Focus Indicator",
45
54
  },
46
55
  };
47
56
 
57
+ const GOOGLE_TRANSLATE_COOKIE_NAME = "googtrans";
58
+ const GOOGLE_TRANSLATE_SOURCE_LANGUAGE = "en";
59
+ const getCookieDomains = () => {
60
+ const domains = new Set([window.location.hostname]);
61
+ const hostnameParts = window.location.hostname.split(".");
62
+ if (hostnameParts.length > 2) {
63
+ domains.add(hostnameParts.slice(-2).join("."));
64
+ }
65
+ return Array.from(domains);
66
+ };
67
+ const setGoogleTranslateCookie = (targetLanguage) => {
68
+ const cookieValue = `/${GOOGLE_TRANSLATE_SOURCE_LANGUAGE}/${targetLanguage}`;
69
+ document.cookie = `${GOOGLE_TRANSLATE_COOKIE_NAME}=${cookieValue}; path=/; SameSite=Lax`;
70
+ for (const domain of getCookieDomains()) {
71
+ document.cookie = `${GOOGLE_TRANSLATE_COOKIE_NAME}=${cookieValue}; path=/; domain=${domain}; SameSite=Lax`;
72
+ }
73
+ };
74
+ const clearGoogleTranslateCookie = () => {
75
+ document.cookie = `${GOOGLE_TRANSLATE_COOKIE_NAME}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; SameSite=Lax`;
76
+ for (const domain of getCookieDomains()) {
77
+ document.cookie = `${GOOGLE_TRANSLATE_COOKIE_NAME}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${domain}; SameSite=Lax`;
78
+ }
79
+ };
80
+ const dispatchNativeChangeEvent = (element) => {
81
+ element.dispatchEvent(new Event("change", { bubbles: true }));
82
+ };
48
83
  const normalizeMagnifierText = (value) => value.replace(/\s+/g, " ").trim();
49
84
  const magnifierSelector = "p, li, button, h1, h2, h3, h4, h5, h6, [role=heading]";
50
85
  const getMagnifierElement = (target) => {
@@ -65,7 +100,8 @@ const getMagnifierText = (target) => {
65
100
  return normalizeMagnifierText(element.innerText || element.textContent || "");
66
101
  };
67
102
  const AccessibilityContext = createContext(undefined);
68
- const AccessibilityProvider = ({ children, translations: customTranslations, }) => {
103
+ const AccessibilityProvider = ({ children, translations: customTranslations, googleTranslateTargetSelector, translationTargetSelector, }) => {
104
+ var _a;
69
105
  const [state, setState] = useState({
70
106
  language: "en",
71
107
  textSize: 100,
@@ -78,9 +114,49 @@ const AccessibilityProvider = ({ children, translations: customTranslations, })
78
114
  underlineLinks: false,
79
115
  highlightTitles: false,
80
116
  readableFont: false,
81
- voiceEnabled: false,
117
+ readAloud: false,
118
+ colorBlindMode: "none",
119
+ focusIndicator: false,
82
120
  });
83
121
  const allTranslations = customTranslations || translations;
122
+ const defaultUiTranslations = translations.en;
123
+ const manualTranslationsForLanguage = translations[state.language];
124
+ const hasManualTranslations = Boolean(manualTranslationsForLanguage);
125
+ const resolvedTranslationTargetSelector = (_a = googleTranslateTargetSelector !== null && googleTranslateTargetSelector !== void 0 ? googleTranslateTargetSelector : translationTargetSelector) !== null && _a !== void 0 ? _a : "main";
126
+ useEffect(() => {
127
+ const target = document.querySelector(resolvedTranslationTargetSelector);
128
+ if (!target) {
129
+ console.warn(`[NGP Accessibility] Google translation target selector "${resolvedTranslationTargetSelector}" did not match any element. Falling back to page-wide translation behavior.`);
130
+ return;
131
+ }
132
+ const markedElements = new Set();
133
+ let current = target;
134
+ while (current && current !== document.body) {
135
+ const parentElement = current.parentElement;
136
+ if (!parentElement)
137
+ break;
138
+ for (const sibling of Array.from(parentElement.children)) {
139
+ if (sibling === current || !(sibling instanceof HTMLElement))
140
+ continue;
141
+ if (sibling.id === "a11y-google-translate-element")
142
+ continue;
143
+ sibling.classList.add("notranslate");
144
+ sibling.setAttribute("translate", "no");
145
+ sibling.dataset.a11yTranslationScoped = "true";
146
+ markedElements.add(sibling);
147
+ }
148
+ current = parentElement;
149
+ }
150
+ return () => {
151
+ for (const element of markedElements) {
152
+ if (element.dataset.a11yTranslationScoped !== "true")
153
+ continue;
154
+ element.classList.remove("notranslate");
155
+ element.removeAttribute("translate");
156
+ delete element.dataset.a11yTranslationScoped;
157
+ }
158
+ };
159
+ }, [resolvedTranslationTargetSelector]);
84
160
  useEffect(() => {
85
161
  const root = document.documentElement;
86
162
  root.style.fontSize = `${state.textSize}%`;
@@ -91,7 +167,103 @@ const AccessibilityProvider = ({ children, translations: customTranslations, })
91
167
  root.classList.toggle("highlight-titles", state.highlightTitles);
92
168
  root.classList.toggle("readable-font", state.readableFont);
93
169
  root.classList.toggle("pause-animations", state.pauseAnimations);
170
+ root.classList.toggle("focus-indicator", state.focusIndicator);
171
+ const body = document.body;
172
+ if (state.colorBlindMode !== "none") {
173
+ body.style.filter = `url(#a11y-${state.colorBlindMode})`;
174
+ }
175
+ else {
176
+ body.style.filter = "";
177
+ }
94
178
  }, [state]);
179
+ useEffect(() => {
180
+ const svgId = "a11y-colorblind-filters";
181
+ if (document.getElementById(svgId))
182
+ return;
183
+ const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
184
+ svg.id = svgId;
185
+ svg.setAttribute("aria-hidden", "true");
186
+ svg.style.cssText = "position:absolute;width:0;height:0;overflow:hidden;";
187
+ svg.innerHTML = `
188
+ <defs>
189
+ <filter id="a11y-protanopia">
190
+ <feColorMatrix type="matrix" values="
191
+ 0.567 0.433 0 0 0
192
+ 0.558 0.442 0 0 0
193
+ 0 0.242 0.758 0 0
194
+ 0 0 0 1 0"/>
195
+ </filter>
196
+ <filter id="a11y-deuteranopia">
197
+ <feColorMatrix type="matrix" values="
198
+ 0.625 0.375 0 0 0
199
+ 0.7 0.3 0 0 0
200
+ 0 0.3 0.7 0 0
201
+ 0 0 0 1 0"/>
202
+ </filter>
203
+ <filter id="a11y-tritanopia">
204
+ <feColorMatrix type="matrix" values="
205
+ 0.95 0.05 0 0 0
206
+ 0 0.433 0.567 0 0
207
+ 0 0.475 0.525 0 0
208
+ 0 0 0 1 0"/>
209
+ </filter>
210
+ </defs>
211
+ `;
212
+ document.body.prepend(svg);
213
+ return () => {
214
+ var _a;
215
+ (_a = document.getElementById(svgId)) === null || _a === void 0 ? void 0 : _a.remove();
216
+ };
217
+ }, []);
218
+ useEffect(() => {
219
+ if (!state.readAloud || !("speechSynthesis" in window))
220
+ return;
221
+ const readableSelector = "p, li, button, a, h1, h2, h3, h4, h5, h6, label, td, th, [role='button'], [role='heading'], [role='link']";
222
+ const speak = (text) => {
223
+ window.speechSynthesis.cancel();
224
+ const utterance = new SpeechSynthesisUtterance(text);
225
+ utterance.lang =
226
+ state.language === "tl"
227
+ ? "tl-PH"
228
+ : state.language === "ceb"
229
+ ? "fil-PH"
230
+ : "en-US";
231
+ utterance.rate = 0.95;
232
+ window.speechSynthesis.speak(utterance);
233
+ };
234
+ const getReadableText = (el) => normalizeMagnifierText(el.getAttribute("aria-label") ||
235
+ el.getAttribute("placeholder") ||
236
+ el.getAttribute("title") ||
237
+ el.innerText ||
238
+ el.textContent ||
239
+ "");
240
+ const handleMouseOver = (event) => {
241
+ const target = event.target;
242
+ if (!target)
243
+ return;
244
+ const el = target.closest(readableSelector);
245
+ if (!el || el.closest(".a11y-root"))
246
+ return;
247
+ const text = getReadableText(el);
248
+ if (text)
249
+ speak(text);
250
+ };
251
+ const handleFocus = (event) => {
252
+ const el = event.target;
253
+ if (!el || el.closest(".a11y-root"))
254
+ return;
255
+ const text = getReadableText(el);
256
+ if (text)
257
+ speak(text);
258
+ };
259
+ document.addEventListener("mouseover", handleMouseOver, true);
260
+ document.addEventListener("focusin", handleFocus, true);
261
+ return () => {
262
+ document.removeEventListener("mouseover", handleMouseOver, true);
263
+ document.removeEventListener("focusin", handleFocus, true);
264
+ window.speechSynthesis.cancel();
265
+ };
266
+ }, [state.readAloud, state.language]);
95
267
  useEffect(() => {
96
268
  if (!state.readingGuide)
97
269
  return;
@@ -262,54 +434,6 @@ const AccessibilityProvider = ({ children, translations: customTranslations, })
262
434
  tooltip.remove();
263
435
  };
264
436
  }, [state.textMagnifier]);
265
- useEffect(() => {
266
- if (!state.voiceEnabled ||
267
- !("webkitSpeechRecognition" in window || "SpeechRecognition" in window))
268
- return;
269
- const SpeechRecognition = window.SpeechRecognition ||
270
- window.webkitSpeechRecognition;
271
- const recognition = new SpeechRecognition();
272
- recognition.continuous = true;
273
- recognition.lang =
274
- state.language === "tl"
275
- ? "tl-PH"
276
- : state.language === "ceb"
277
- ? "ceb-PH"
278
- : "en-US";
279
- recognition.onresult = (event) => {
280
- const transcript = event.results[event.results.length - 1][0].transcript.toLowerCase();
281
- if (transcript.includes("increase text") ||
282
- transcript.includes("palakihin"))
283
- increaseText();
284
- if (transcript.includes("decrease text") ||
285
- transcript.includes("paliitin"))
286
- decreaseText();
287
- if (transcript.includes("high contrast") || transcript.includes("mataas"))
288
- toggleHighContrast();
289
- if (transcript.includes("negative contrast") ||
290
- transcript.includes("negatibo"))
291
- toggleNegativeContrast();
292
- if (transcript.includes("light background") ||
293
- transcript.includes("maliwanag"))
294
- toggleLightBackground();
295
- if (transcript.includes("underline") || transcript.includes("guhit"))
296
- toggleUnderlineLinks();
297
- if (transcript.includes("highlight titles") ||
298
- transcript.includes("title highlight"))
299
- toggleHighlightTitles();
300
- if (transcript.includes("pause animations") ||
301
- transcript.includes("stop animations"))
302
- togglePauseAnimations();
303
- if (transcript.includes("reading guide") ||
304
- transcript.includes("reading line"))
305
- toggleReadingGuide();
306
- if (transcript.includes("readable font") ||
307
- transcript.includes("madaling"))
308
- toggleReadableFont();
309
- };
310
- recognition.start();
311
- return () => recognition.stop();
312
- }, [state.voiceEnabled, state.language]);
313
437
  const setLanguage = (lang) => setState((s) => (Object.assign(Object.assign({}, s), { language: lang })));
314
438
  const increaseText = () => setState((s) => (Object.assign(Object.assign({}, s), { textSize: Math.min(s.textSize + 10, 200) })));
315
439
  const decreaseText = () => setState((s) => (Object.assign(Object.assign({}, s), { textSize: Math.max(s.textSize - 10, 80) })));
@@ -322,9 +446,81 @@ const AccessibilityProvider = ({ children, translations: customTranslations, })
322
446
  const toggleUnderlineLinks = () => setState((s) => (Object.assign(Object.assign({}, s), { underlineLinks: !s.underlineLinks })));
323
447
  const toggleHighlightTitles = () => setState((s) => (Object.assign(Object.assign({}, s), { highlightTitles: !s.highlightTitles })));
324
448
  const toggleReadableFont = () => setState((s) => (Object.assign(Object.assign({}, s), { readableFont: !s.readableFont })));
325
- const toggleVoice = () => setState((s) => (Object.assign(Object.assign({}, s), { voiceEnabled: !s.voiceEnabled })));
326
- const translate = (key) => translations[state.language][key];
327
- const t = (key) => { var _a; return ((_a = allTranslations[state.language]) === null || _a === void 0 ? void 0 : _a[key]) || key; };
449
+ const toggleReadAloud = () => setState((s) => (Object.assign(Object.assign({}, s), { readAloud: !s.readAloud })));
450
+ const setColorBlindMode = (mode) => setState((s) => (Object.assign(Object.assign({}, s), { colorBlindMode: mode })));
451
+ const toggleFocusIndicator = () => setState((s) => (Object.assign(Object.assign({}, s), { focusIndicator: !s.focusIndicator })));
452
+ // Google Translate: auto-translate page content when language changes
453
+ useEffect(() => {
454
+ const GTRANSLATE_SCRIPT_ID = "a11y-google-translate-script";
455
+ const GTRANSLATE_CONTAINER_ID = "a11y-google-translate-element";
456
+ const loadGoogleTranslateScript = () => {
457
+ if (document.getElementById(GTRANSLATE_SCRIPT_ID))
458
+ return;
459
+ // Create hidden container for the widget
460
+ const container = document.createElement("div");
461
+ container.id = GTRANSLATE_CONTAINER_ID;
462
+ container.style.display = "none";
463
+ document.body.appendChild(container);
464
+ // Define the init callback
465
+ window.googleTranslateElementInit = () => {
466
+ new window.google.translate.TranslateElement({
467
+ pageLanguage: "en",
468
+ autoDisplay: false,
469
+ }, GTRANSLATE_CONTAINER_ID);
470
+ };
471
+ const script = document.createElement("script");
472
+ script.id = GTRANSLATE_SCRIPT_ID;
473
+ script.src =
474
+ "//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit";
475
+ script.async = true;
476
+ document.body.appendChild(script);
477
+ };
478
+ const triggerTranslation = (langCode) => {
479
+ setGoogleTranslateCookie(langCode);
480
+ const select = document.querySelector(".goog-te-combo");
481
+ if (select) {
482
+ select.value = langCode;
483
+ dispatchNativeChangeEvent(select);
484
+ }
485
+ };
486
+ const resetTranslation = () => {
487
+ const select = document.querySelector(".goog-te-combo");
488
+ if (select) {
489
+ select.value = GOOGLE_TRANSLATE_SOURCE_LANGUAGE;
490
+ dispatchNativeChangeEvent(select);
491
+ }
492
+ clearGoogleTranslateCookie();
493
+ };
494
+ const langMap = {
495
+ en: GOOGLE_TRANSLATE_SOURCE_LANGUAGE,
496
+ tl: "tl",
497
+ ceb: "ceb",
498
+ ja: "ja",
499
+ es: "es",
500
+ fr: "fr",
501
+ de: "de",
502
+ zh: "zh-CN",
503
+ ar: "ar",
504
+ };
505
+ const googleLang = langMap[state.language] || state.language;
506
+ if (googleLang === GOOGLE_TRANSLATE_SOURCE_LANGUAGE) {
507
+ resetTranslation();
508
+ return;
509
+ }
510
+ loadGoogleTranslateScript();
511
+ setGoogleTranslateCookie(googleLang);
512
+ // Wait for Google Translate widget to be ready, then trigger
513
+ const interval = window.setInterval(() => {
514
+ const select = document.querySelector(".goog-te-combo");
515
+ if (select) {
516
+ window.clearInterval(interval);
517
+ triggerTranslation(googleLang);
518
+ }
519
+ }, 300);
520
+ return () => window.clearInterval(interval);
521
+ }, [state.language]);
522
+ const translate = (key) => (manualTranslationsForLanguage === null || manualTranslationsForLanguage === void 0 ? void 0 : manualTranslationsForLanguage[key]) || defaultUiTranslations[key];
523
+ const t = (key) => { var _a, _b; return ((_a = allTranslations[state.language]) === null || _a === void 0 ? void 0 : _a[key]) || ((_b = allTranslations.en) === null || _b === void 0 ? void 0 : _b[key]) || key; };
328
524
  return (React.createElement(AccessibilityContext.Provider, { value: Object.assign(Object.assign({}, state), { setLanguage,
329
525
  increaseText,
330
526
  decreaseText,
@@ -337,7 +533,10 @@ const AccessibilityProvider = ({ children, translations: customTranslations, })
337
533
  toggleUnderlineLinks,
338
534
  toggleHighlightTitles,
339
535
  toggleReadableFont,
340
- toggleVoice,
536
+ toggleReadAloud,
537
+ setColorBlindMode,
538
+ toggleFocusIndicator,
539
+ hasManualTranslations,
341
540
  translate,
342
541
  t }) }, children));
343
542
  };
@@ -350,9 +549,9 @@ const useAccessibility = () => {
350
549
 
351
550
  const cn$1 = (...parts) => parts.filter(Boolean).join(" ");
352
551
  const AccessibilityToolbar = ({ className, style, classes, }) => {
353
- const { language, setLanguage, increaseText, decreaseText, toggleTextMagnifier, togglePauseAnimations, toggleReadingGuide, toggleHighContrast, toggleNegativeContrast, toggleLightBackground, toggleUnderlineLinks, toggleHighlightTitles, toggleReadableFont, toggleVoice, translate, textMagnifier, pauseAnimations, readingGuide, highContrast, negativeContrast, lightBackground, underlineLinks, highlightTitles, readableFont, voiceEnabled, } = useAccessibility();
354
- return (React.createElement("div", { className: cn$1("accessibility-toolbar", classes === null || classes === void 0 ? void 0 : classes.root, className), style: style },
355
- React.createElement("select", { className: cn$1(classes === null || classes === void 0 ? void 0 : classes.select), value: language, onChange: (e) => setLanguage(e.target.value) },
552
+ const { language, setLanguage, increaseText, decreaseText, toggleTextMagnifier, togglePauseAnimations, toggleReadingGuide, toggleHighContrast, toggleNegativeContrast, toggleLightBackground, toggleUnderlineLinks, toggleHighlightTitles, toggleReadableFont, toggleReadAloud, setColorBlindMode, toggleFocusIndicator, translate, textMagnifier, pauseAnimations, readingGuide, highContrast, negativeContrast, lightBackground, underlineLinks, highlightTitles, readableFont, readAloud, colorBlindMode, focusIndicator, } = useAccessibility();
553
+ return (React.createElement("div", { className: cn$1("accessibility-toolbar notranslate", classes === null || classes === void 0 ? void 0 : classes.root, className), style: style, translate: "no" },
554
+ React.createElement("select", { className: cn$1("notranslate", classes === null || classes === void 0 ? void 0 : classes.select), value: language, onChange: (e) => setLanguage(e.target.value), translate: "no" },
356
555
  React.createElement("option", { value: "en" }, "English"),
357
556
  React.createElement("option", { value: "tl" }, "Tagalog"),
358
557
  React.createElement("option", { value: "ceb" }, "Cebuano")),
@@ -371,15 +570,21 @@ const AccessibilityToolbar = ({ className, style, classes, }) => {
371
570
  React.createElement("button", { className: cn$1(classes === null || classes === void 0 ? void 0 : classes.button, readableFont && "active", readableFont && (classes === null || classes === void 0 ? void 0 : classes.activeButton)), "data-active": readableFont, onClick: toggleReadableFont }, translate("readableFont")),
372
571
  React.createElement("button", { className: cn$1(classes === null || classes === void 0 ? void 0 : classes.button, pauseAnimations && "active", pauseAnimations && (classes === null || classes === void 0 ? void 0 : classes.activeButton)), "data-active": pauseAnimations, onClick: togglePauseAnimations }, translate("pauseAnimations")),
373
572
  React.createElement("button", { className: cn$1(classes === null || classes === void 0 ? void 0 : classes.button, readingGuide && "active", readingGuide && (classes === null || classes === void 0 ? void 0 : classes.activeButton)), "data-active": readingGuide, onClick: toggleReadingGuide }, translate("readingGuide")),
374
- React.createElement("button", { className: cn$1(classes === null || classes === void 0 ? void 0 : classes.button, classes === null || classes === void 0 ? void 0 : classes.voiceButton, voiceEnabled && "active", voiceEnabled && (classes === null || classes === void 0 ? void 0 : classes.activeButton)), "data-active": voiceEnabled, onClick: toggleVoice },
375
- "\uD83C\uDFA4 ",
376
- translate("voiceCommand"))));
573
+ React.createElement("button", { className: cn$1(classes === null || classes === void 0 ? void 0 : classes.button, readAloud && "active", readAloud && (classes === null || classes === void 0 ? void 0 : classes.activeButton)), "data-active": readAloud, onClick: toggleReadAloud },
574
+ "\uD83D\uDD0A ",
575
+ translate("readAloud")),
576
+ React.createElement("button", { className: cn$1(classes === null || classes === void 0 ? void 0 : classes.button, focusIndicator && "active", focusIndicator && (classes === null || classes === void 0 ? void 0 : classes.activeButton)), "data-active": focusIndicator, onClick: toggleFocusIndicator }, translate("focusIndicator")),
577
+ React.createElement("select", { className: cn$1(classes === null || classes === void 0 ? void 0 : classes.select), value: colorBlindMode, onChange: (e) => setColorBlindMode(e.target.value), "aria-label": translate("colorBlindMode") },
578
+ React.createElement("option", { value: "none" }, translate("colorBlindMode")),
579
+ React.createElement("option", { value: "protanopia" }, "Protanopia (Red)"),
580
+ React.createElement("option", { value: "deuteranopia" }, "Deuteranopia (Green)"),
581
+ React.createElement("option", { value: "tritanopia" }, "Tritanopia (Blue)"))));
377
582
  };
378
583
 
379
584
  const cn = (...parts) => parts.filter(Boolean).join(" ");
380
585
  const AccessibilityDropdown = ({ className, style, classes, triggerLabel = "♿ Accessibility", renderTrigger, }) => {
381
586
  const [isOpen, setIsOpen] = useState(false);
382
- const { language, setLanguage, textSize, increaseText, decreaseText, toggleTextMagnifier, togglePauseAnimations, toggleReadingGuide, toggleHighContrast, toggleNegativeContrast, toggleLightBackground, toggleUnderlineLinks, toggleHighlightTitles, toggleReadableFont, toggleVoice, translate, textMagnifier, pauseAnimations, readingGuide, highContrast, negativeContrast, lightBackground, underlineLinks, highlightTitles, readableFont, voiceEnabled, } = useAccessibility();
587
+ const { language, setLanguage, textSize, increaseText, decreaseText, toggleTextMagnifier, togglePauseAnimations, toggleReadingGuide, toggleHighContrast, toggleNegativeContrast, toggleLightBackground, toggleUnderlineLinks, toggleHighlightTitles, toggleReadableFont, translate, textMagnifier, pauseAnimations, readingGuide, highContrast, negativeContrast, lightBackground, underlineLinks, highlightTitles, readableFont, } = useAccessibility();
383
588
  const toggle = () => setIsOpen(!isOpen);
384
589
  const closePanel = () => setIsOpen(false);
385
590
  const textScaleDelta = textSize - 100;
@@ -396,39 +601,44 @@ const AccessibilityDropdown = ({ className, style, classes, triggerLabel = "♿
396
601
  React.createElement("div", { className: cn("a11y-panel-header", classes === null || classes === void 0 ? void 0 : classes.panelHeader) },
397
602
  React.createElement("div", { className: "a11y-panel-heading" },
398
603
  React.createElement("span", { className: "a11y-panel-eyebrow" }, "NGP"),
399
- React.createElement("label", { className: "a11y-panel-title" }, "Accessibility Options")),
604
+ React.createElement("label", { className: cn("a11y-panel-title", classes === null || classes === void 0 ? void 0 : classes.title) }, "Accessibility Options")),
400
605
  React.createElement("button", { type: "button", className: cn("a11y-panel-close", classes === null || classes === void 0 ? void 0 : classes.closeButton), onClick: closePanel, "aria-label": "Close accessibility panel" }, "\u00D7")),
401
- React.createElement("div", { className: "a11y-language" },
402
- React.createElement("label", { htmlFor: "a11y-language-select" }, "Language"),
403
- React.createElement("select", { id: "a11y-language-select", value: language, onChange: (e) => setLanguage(e.target.value) },
606
+ React.createElement("div", { className: cn("a11y-language", classes === null || classes === void 0 ? void 0 : classes.section) },
607
+ React.createElement("label", { htmlFor: "a11y-language-select", className: cn("a11y-language-label", classes === null || classes === void 0 ? void 0 : classes.title) }, translate("language")),
608
+ React.createElement("select", { id: "a11y-language-select", className: "notranslate", value: language, onChange: (e) => setLanguage(e.target.value), translate: "no" },
404
609
  React.createElement("option", { value: "en" }, "English"),
405
610
  React.createElement("option", { value: "tl" }, "Tagalog"),
406
- React.createElement("option", { value: "ceb" }, "Cebuano"))),
407
- React.createElement("section", { className: "a11y-section" },
408
- React.createElement("h3", { className: "a11y-section-title" }, "Content Adjustments"),
611
+ React.createElement("option", { value: "ceb" }, "Cebuano"),
612
+ React.createElement("option", { value: "ja" }, "Japanese"),
613
+ React.createElement("option", { value: "es" }, "Spanish"),
614
+ React.createElement("option", { value: "fr" }, "French"),
615
+ React.createElement("option", { value: "de" }, "German"),
616
+ React.createElement("option", { value: "zh" }, "Chinese"),
617
+ React.createElement("option", { value: "ar" }, "Arabic"))),
618
+ React.createElement("section", { className: cn("a11y-section", classes === null || classes === void 0 ? void 0 : classes.section) },
619
+ React.createElement("h3", { className: cn("a11y-section-title", classes === null || classes === void 0 ? void 0 : classes.title) }, "Content Adjustments"),
409
620
  React.createElement("div", { className: "a11y-card" },
410
- React.createElement("span", { className: "a11y-card-title" }, "Content Scaling"),
621
+ React.createElement("span", { className: cn("a11y-card-title", classes === null || classes === void 0 ? void 0 : classes.title) }, "Content Scaling"),
411
622
  React.createElement("div", { className: "a11y-stepper" },
412
623
  React.createElement("button", { onClick: decreaseText }, "\u2212"),
413
624
  React.createElement("span", { className: "a11y-stepper-value" }, textScaleLabel),
414
625
  React.createElement("button", { onClick: increaseText }, "+"))),
415
- React.createElement("div", { className: "a11y-grid" },
416
- React.createElement("button", { className: cn("a11y-card", textMagnifier && "active"), onClick: toggleTextMagnifier }, translate("textMagnifier")),
417
- React.createElement("button", { className: cn("a11y-card", readableFont && "active"), onClick: toggleReadableFont }, "Readable Font"),
418
- React.createElement("button", { className: cn("a11y-card", underlineLinks && "active"), onClick: toggleUnderlineLinks }, "Highlight Links"),
419
- React.createElement("button", { className: cn("a11y-card", highlightTitles && "active"), onClick: toggleHighlightTitles }, "Highlight Titles"))),
420
- React.createElement("section", { className: "a11y-section" },
421
- React.createElement("h3", { className: "a11y-section-title" }, "Color Adjustments"),
422
- React.createElement("div", { className: "a11y-grid" },
423
- React.createElement("button", { className: cn("a11y-card", highContrast && "active"), onClick: toggleHighContrast }, translate("highContrast")),
424
- React.createElement("button", { className: cn("a11y-card", negativeContrast && "active"), onClick: toggleNegativeContrast }, translate("negativeContrast")),
425
- React.createElement("button", { className: cn("a11y-card", lightBackground && "active"), onClick: toggleLightBackground }, translate("lightBackground")))),
426
- React.createElement("section", { className: "a11y-section" },
427
- React.createElement("h3", { className: "a11y-section-title" }, "Accessibility Tools"),
428
- React.createElement("div", { className: "a11y-grid" },
429
- React.createElement("button", { className: cn("a11y-card", pauseAnimations && "active"), onClick: togglePauseAnimations }, translate("pauseAnimations")),
430
- React.createElement("button", { className: cn("a11y-card", readingGuide && "active"), onClick: toggleReadingGuide }, translate("readingGuide")),
431
- React.createElement("button", { className: cn("a11y-card", voiceEnabled && "active"), onClick: toggleVoice }, translate("voiceCommand"))))))));
626
+ React.createElement("div", { className: cn("a11y-grid", classes === null || classes === void 0 ? void 0 : classes.section) },
627
+ React.createElement("button", { className: cn("a11y-card", textMagnifier && "active", classes === null || classes === void 0 ? void 0 : classes.button), onClick: toggleTextMagnifier }, translate("textMagnifier")),
628
+ React.createElement("button", { className: cn("a11y-card", readableFont && "active", classes === null || classes === void 0 ? void 0 : classes.button), onClick: toggleReadableFont }, "Readable Font"),
629
+ React.createElement("button", { className: cn("a11y-card", underlineLinks && "active", classes === null || classes === void 0 ? void 0 : classes.button), onClick: toggleUnderlineLinks }, "Highlight Links"),
630
+ React.createElement("button", { className: cn("a11y-card", highlightTitles && "active", classes === null || classes === void 0 ? void 0 : classes.button), onClick: toggleHighlightTitles }, "Highlight Titles"))),
631
+ React.createElement("section", { className: cn("a11y-section", classes === null || classes === void 0 ? void 0 : classes.section) },
632
+ React.createElement("h3", { className: cn("a11y-section-title", classes === null || classes === void 0 ? void 0 : classes.title) }, "Color Adjustments"),
633
+ React.createElement("div", { className: cn("a11y-grid", classes === null || classes === void 0 ? void 0 : classes.section) },
634
+ React.createElement("button", { className: cn("a11y-card", highContrast && "active", classes === null || classes === void 0 ? void 0 : classes.button), onClick: toggleHighContrast }, translate("highContrast")),
635
+ React.createElement("button", { className: cn("a11y-card", negativeContrast && "active", classes === null || classes === void 0 ? void 0 : classes.button), onClick: toggleNegativeContrast }, translate("negativeContrast")),
636
+ React.createElement("button", { className: cn("a11y-card", lightBackground && "active", classes === null || classes === void 0 ? void 0 : classes.button), onClick: toggleLightBackground }, translate("lightBackground")))),
637
+ React.createElement("section", { className: cn("a11y-section", classes === null || classes === void 0 ? void 0 : classes.section) },
638
+ React.createElement("h3", { className: cn("a11y-section-title", classes === null || classes === void 0 ? void 0 : classes.title) }, "Accessibility Tools"),
639
+ React.createElement("div", { className: cn("a11y-grid", classes === null || classes === void 0 ? void 0 : classes.section) },
640
+ React.createElement("button", { className: cn("a11y-card", pauseAnimations && "active", classes === null || classes === void 0 ? void 0 : classes.button), onClick: togglePauseAnimations }, translate("pauseAnimations")),
641
+ React.createElement("button", { className: cn("a11y-card", readingGuide && "active", classes === null || classes === void 0 ? void 0 : classes.button), onClick: toggleReadingGuide }, translate("readingGuide"))))))));
432
642
  };
433
643
 
434
644
  const T = ({ k, children }) => {