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