ngp-accessibility 1.0.5 → 1.0.6

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",
@@ -16,8 +17,12 @@ const translations = {
16
17
  pauseAnimations: "Pause Animations",
17
18
  readingGuide: "Reading Guide",
18
19
  voiceCommand: "Voice Command",
20
+ readAloud: "Read Aloud",
21
+ colorBlindMode: "Color Blind Mode",
22
+ focusIndicator: "Focus Indicator",
19
23
  },
20
24
  tl: {
25
+ language: "Wika",
21
26
  increaseText: "Palakihin ang Teksto",
22
27
  decreaseText: "Paliitin ang Teksto",
23
28
  textMagnifier: "Text Magnifier",
@@ -30,8 +35,12 @@ const translations = {
30
35
  pauseAnimations: "I-pause ang mga Animation",
31
36
  readingGuide: "Reading Guide",
32
37
  voiceCommand: "Voice Command",
38
+ readAloud: "Basahin nang Malakas",
39
+ colorBlindMode: "Color Blind Mode",
40
+ focusIndicator: "Focus Indicator",
33
41
  },
34
42
  ceb: {
43
+ language: "Pinulongan",
35
44
  increaseText: "Padak-on ang Teksto",
36
45
  decreaseText: "Pagamay-on ang Teksto",
37
46
  textMagnifier: "Text Magnifier",
@@ -44,9 +53,38 @@ const translations = {
44
53
  pauseAnimations: "Ihunong ang mga Animation",
45
54
  readingGuide: "Reading Guide",
46
55
  voiceCommand: "Voice Command",
56
+ readAloud: "Basaha og Kusog",
57
+ colorBlindMode: "Color Blind Mode",
58
+ focusIndicator: "Focus Indicator",
47
59
  },
48
60
  };
49
61
 
62
+ const GOOGLE_TRANSLATE_COOKIE_NAME = "googtrans";
63
+ const GOOGLE_TRANSLATE_SOURCE_LANGUAGE = "en";
64
+ const getCookieDomains = () => {
65
+ const domains = new Set([window.location.hostname]);
66
+ const hostnameParts = window.location.hostname.split(".");
67
+ if (hostnameParts.length > 2) {
68
+ domains.add(hostnameParts.slice(-2).join("."));
69
+ }
70
+ return Array.from(domains);
71
+ };
72
+ const setGoogleTranslateCookie = (targetLanguage) => {
73
+ const cookieValue = `/${GOOGLE_TRANSLATE_SOURCE_LANGUAGE}/${targetLanguage}`;
74
+ document.cookie = `${GOOGLE_TRANSLATE_COOKIE_NAME}=${cookieValue}; path=/; SameSite=Lax`;
75
+ for (const domain of getCookieDomains()) {
76
+ document.cookie = `${GOOGLE_TRANSLATE_COOKIE_NAME}=${cookieValue}; path=/; domain=${domain}; SameSite=Lax`;
77
+ }
78
+ };
79
+ const clearGoogleTranslateCookie = () => {
80
+ document.cookie = `${GOOGLE_TRANSLATE_COOKIE_NAME}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; SameSite=Lax`;
81
+ for (const domain of getCookieDomains()) {
82
+ document.cookie = `${GOOGLE_TRANSLATE_COOKIE_NAME}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${domain}; SameSite=Lax`;
83
+ }
84
+ };
85
+ const dispatchNativeChangeEvent = (element) => {
86
+ element.dispatchEvent(new Event("change", { bubbles: true }));
87
+ };
50
88
  const normalizeMagnifierText = (value) => value.replace(/\s+/g, " ").trim();
51
89
  const magnifierSelector = "p, li, button, h1, h2, h3, h4, h5, h6, [role=heading]";
52
90
  const getMagnifierElement = (target) => {
@@ -67,7 +105,8 @@ const getMagnifierText = (target) => {
67
105
  return normalizeMagnifierText(element.innerText || element.textContent || "");
68
106
  };
69
107
  const AccessibilityContext = React.createContext(undefined);
70
- const AccessibilityProvider = ({ children, translations: customTranslations, }) => {
108
+ const AccessibilityProvider = ({ children, translations: customTranslations, googleTranslateTargetSelector, translationTargetSelector, }) => {
109
+ var _a;
71
110
  const [state, setState] = React.useState({
72
111
  language: "en",
73
112
  textSize: 100,
@@ -81,8 +120,49 @@ const AccessibilityProvider = ({ children, translations: customTranslations, })
81
120
  highlightTitles: false,
82
121
  readableFont: false,
83
122
  voiceEnabled: false,
123
+ readAloud: false,
124
+ colorBlindMode: "none",
125
+ focusIndicator: false,
84
126
  });
85
127
  const allTranslations = customTranslations || translations;
128
+ const defaultUiTranslations = translations.en;
129
+ const manualTranslationsForLanguage = translations[state.language];
130
+ const hasManualTranslations = Boolean(manualTranslationsForLanguage);
131
+ const resolvedTranslationTargetSelector = (_a = googleTranslateTargetSelector !== null && googleTranslateTargetSelector !== void 0 ? googleTranslateTargetSelector : translationTargetSelector) !== null && _a !== void 0 ? _a : "main";
132
+ React.useEffect(() => {
133
+ const target = document.querySelector(resolvedTranslationTargetSelector);
134
+ if (!target) {
135
+ console.warn(`[NGP Accessibility] Google translation target selector "${resolvedTranslationTargetSelector}" did not match any element. Falling back to page-wide translation behavior.`);
136
+ return;
137
+ }
138
+ const markedElements = new Set();
139
+ let current = target;
140
+ while (current && current !== document.body) {
141
+ const parentElement = current.parentElement;
142
+ if (!parentElement)
143
+ break;
144
+ for (const sibling of Array.from(parentElement.children)) {
145
+ if (sibling === current || !(sibling instanceof HTMLElement))
146
+ continue;
147
+ if (sibling.id === "a11y-google-translate-element")
148
+ continue;
149
+ sibling.classList.add("notranslate");
150
+ sibling.setAttribute("translate", "no");
151
+ sibling.dataset.a11yTranslationScoped = "true";
152
+ markedElements.add(sibling);
153
+ }
154
+ current = parentElement;
155
+ }
156
+ return () => {
157
+ for (const element of markedElements) {
158
+ if (element.dataset.a11yTranslationScoped !== "true")
159
+ continue;
160
+ element.classList.remove("notranslate");
161
+ element.removeAttribute("translate");
162
+ delete element.dataset.a11yTranslationScoped;
163
+ }
164
+ };
165
+ }, [resolvedTranslationTargetSelector]);
86
166
  React.useEffect(() => {
87
167
  const root = document.documentElement;
88
168
  root.style.fontSize = `${state.textSize}%`;
@@ -93,7 +173,103 @@ const AccessibilityProvider = ({ children, translations: customTranslations, })
93
173
  root.classList.toggle("highlight-titles", state.highlightTitles);
94
174
  root.classList.toggle("readable-font", state.readableFont);
95
175
  root.classList.toggle("pause-animations", state.pauseAnimations);
176
+ root.classList.toggle("focus-indicator", state.focusIndicator);
177
+ const body = document.body;
178
+ if (state.colorBlindMode !== "none") {
179
+ body.style.filter = `url(#a11y-${state.colorBlindMode})`;
180
+ }
181
+ else {
182
+ body.style.filter = "";
183
+ }
96
184
  }, [state]);
185
+ React.useEffect(() => {
186
+ const svgId = "a11y-colorblind-filters";
187
+ if (document.getElementById(svgId))
188
+ return;
189
+ const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
190
+ svg.id = svgId;
191
+ svg.setAttribute("aria-hidden", "true");
192
+ svg.style.cssText = "position:absolute;width:0;height:0;overflow:hidden;";
193
+ svg.innerHTML = `
194
+ <defs>
195
+ <filter id="a11y-protanopia">
196
+ <feColorMatrix type="matrix" values="
197
+ 0.567 0.433 0 0 0
198
+ 0.558 0.442 0 0 0
199
+ 0 0.242 0.758 0 0
200
+ 0 0 0 1 0"/>
201
+ </filter>
202
+ <filter id="a11y-deuteranopia">
203
+ <feColorMatrix type="matrix" values="
204
+ 0.625 0.375 0 0 0
205
+ 0.7 0.3 0 0 0
206
+ 0 0.3 0.7 0 0
207
+ 0 0 0 1 0"/>
208
+ </filter>
209
+ <filter id="a11y-tritanopia">
210
+ <feColorMatrix type="matrix" values="
211
+ 0.95 0.05 0 0 0
212
+ 0 0.433 0.567 0 0
213
+ 0 0.475 0.525 0 0
214
+ 0 0 0 1 0"/>
215
+ </filter>
216
+ </defs>
217
+ `;
218
+ document.body.prepend(svg);
219
+ return () => {
220
+ var _a;
221
+ (_a = document.getElementById(svgId)) === null || _a === void 0 ? void 0 : _a.remove();
222
+ };
223
+ }, []);
224
+ React.useEffect(() => {
225
+ if (!state.readAloud || !("speechSynthesis" in window))
226
+ return;
227
+ const readableSelector = "p, li, button, a, h1, h2, h3, h4, h5, h6, label, td, th, [role='button'], [role='heading'], [role='link']";
228
+ const speak = (text) => {
229
+ window.speechSynthesis.cancel();
230
+ const utterance = new SpeechSynthesisUtterance(text);
231
+ utterance.lang =
232
+ state.language === "tl"
233
+ ? "tl-PH"
234
+ : state.language === "ceb"
235
+ ? "fil-PH"
236
+ : "en-US";
237
+ utterance.rate = 0.95;
238
+ window.speechSynthesis.speak(utterance);
239
+ };
240
+ const getReadableText = (el) => normalizeMagnifierText(el.getAttribute("aria-label") ||
241
+ el.getAttribute("placeholder") ||
242
+ el.getAttribute("title") ||
243
+ el.innerText ||
244
+ el.textContent ||
245
+ "");
246
+ const handleMouseOver = (event) => {
247
+ const target = event.target;
248
+ if (!target)
249
+ return;
250
+ const el = target.closest(readableSelector);
251
+ if (!el || el.closest(".a11y-root"))
252
+ return;
253
+ const text = getReadableText(el);
254
+ if (text)
255
+ speak(text);
256
+ };
257
+ const handleFocus = (event) => {
258
+ const el = event.target;
259
+ if (!el || el.closest(".a11y-root"))
260
+ return;
261
+ const text = getReadableText(el);
262
+ if (text)
263
+ speak(text);
264
+ };
265
+ document.addEventListener("mouseover", handleMouseOver, true);
266
+ document.addEventListener("focusin", handleFocus, true);
267
+ return () => {
268
+ document.removeEventListener("mouseover", handleMouseOver, true);
269
+ document.removeEventListener("focusin", handleFocus, true);
270
+ window.speechSynthesis.cancel();
271
+ };
272
+ }, [state.readAloud, state.language]);
97
273
  React.useEffect(() => {
98
274
  if (!state.readingGuide)
99
275
  return;
@@ -325,8 +501,81 @@ const AccessibilityProvider = ({ children, translations: customTranslations, })
325
501
  const toggleHighlightTitles = () => setState((s) => (Object.assign(Object.assign({}, s), { highlightTitles: !s.highlightTitles })));
326
502
  const toggleReadableFont = () => setState((s) => (Object.assign(Object.assign({}, s), { readableFont: !s.readableFont })));
327
503
  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; };
504
+ const toggleReadAloud = () => setState((s) => (Object.assign(Object.assign({}, s), { readAloud: !s.readAloud })));
505
+ const setColorBlindMode = (mode) => setState((s) => (Object.assign(Object.assign({}, s), { colorBlindMode: mode })));
506
+ const toggleFocusIndicator = () => setState((s) => (Object.assign(Object.assign({}, s), { focusIndicator: !s.focusIndicator })));
507
+ // Google Translate: auto-translate page content when language changes
508
+ React.useEffect(() => {
509
+ const GTRANSLATE_SCRIPT_ID = "a11y-google-translate-script";
510
+ const GTRANSLATE_CONTAINER_ID = "a11y-google-translate-element";
511
+ const loadGoogleTranslateScript = () => {
512
+ if (document.getElementById(GTRANSLATE_SCRIPT_ID))
513
+ return;
514
+ // Create hidden container for the widget
515
+ const container = document.createElement("div");
516
+ container.id = GTRANSLATE_CONTAINER_ID;
517
+ container.style.display = "none";
518
+ document.body.appendChild(container);
519
+ // Define the init callback
520
+ window.googleTranslateElementInit = () => {
521
+ new window.google.translate.TranslateElement({
522
+ pageLanguage: "en",
523
+ autoDisplay: false,
524
+ }, GTRANSLATE_CONTAINER_ID);
525
+ };
526
+ const script = document.createElement("script");
527
+ script.id = GTRANSLATE_SCRIPT_ID;
528
+ script.src =
529
+ "//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit";
530
+ script.async = true;
531
+ document.body.appendChild(script);
532
+ };
533
+ const triggerTranslation = (langCode) => {
534
+ setGoogleTranslateCookie(langCode);
535
+ const select = document.querySelector(".goog-te-combo");
536
+ if (select) {
537
+ select.value = langCode;
538
+ dispatchNativeChangeEvent(select);
539
+ }
540
+ };
541
+ const resetTranslation = () => {
542
+ const select = document.querySelector(".goog-te-combo");
543
+ if (select) {
544
+ select.value = GOOGLE_TRANSLATE_SOURCE_LANGUAGE;
545
+ dispatchNativeChangeEvent(select);
546
+ }
547
+ clearGoogleTranslateCookie();
548
+ };
549
+ const langMap = {
550
+ en: GOOGLE_TRANSLATE_SOURCE_LANGUAGE,
551
+ tl: "tl",
552
+ ceb: "ceb",
553
+ ja: "ja",
554
+ es: "es",
555
+ fr: "fr",
556
+ de: "de",
557
+ zh: "zh-CN",
558
+ ar: "ar",
559
+ };
560
+ const googleLang = langMap[state.language] || state.language;
561
+ if (googleLang === GOOGLE_TRANSLATE_SOURCE_LANGUAGE) {
562
+ resetTranslation();
563
+ return;
564
+ }
565
+ loadGoogleTranslateScript();
566
+ setGoogleTranslateCookie(googleLang);
567
+ // Wait for Google Translate widget to be ready, then trigger
568
+ const interval = window.setInterval(() => {
569
+ const select = document.querySelector(".goog-te-combo");
570
+ if (select) {
571
+ window.clearInterval(interval);
572
+ triggerTranslation(googleLang);
573
+ }
574
+ }, 300);
575
+ return () => window.clearInterval(interval);
576
+ }, [state.language]);
577
+ const translate = (key) => (manualTranslationsForLanguage === null || manualTranslationsForLanguage === void 0 ? void 0 : manualTranslationsForLanguage[key]) || defaultUiTranslations[key];
578
+ 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
579
  return (React.createElement(AccessibilityContext.Provider, { value: Object.assign(Object.assign({}, state), { setLanguage,
331
580
  increaseText,
332
581
  decreaseText,
@@ -340,6 +589,10 @@ const AccessibilityProvider = ({ children, translations: customTranslations, })
340
589
  toggleHighlightTitles,
341
590
  toggleReadableFont,
342
591
  toggleVoice,
592
+ toggleReadAloud,
593
+ setColorBlindMode,
594
+ toggleFocusIndicator,
595
+ hasManualTranslations,
343
596
  translate,
344
597
  t }) }, children));
345
598
  };
@@ -352,8 +605,8 @@ const useAccessibility = () => {
352
605
 
353
606
  const cn$1 = (...parts) => parts.filter(Boolean).join(" ");
354
607
  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 },
608
+ const { language, setLanguage, increaseText, decreaseText, toggleTextMagnifier, togglePauseAnimations, toggleReadingGuide, toggleHighContrast, toggleNegativeContrast, toggleLightBackground, toggleUnderlineLinks, toggleHighlightTitles, toggleReadableFont, toggleVoice, toggleReadAloud, setColorBlindMode, toggleFocusIndicator, translate, textMagnifier, pauseAnimations, readingGuide, highContrast, negativeContrast, lightBackground, underlineLinks, highlightTitles, readableFont, voiceEnabled, readAloud, colorBlindMode, focusIndicator, } = useAccessibility();
609
+ return (React.createElement("div", { className: cn$1("accessibility-toolbar notranslate", classes === null || classes === void 0 ? void 0 : classes.root, className), style: style, translate: "no" },
357
610
  React.createElement("select", { className: cn$1(classes === null || classes === void 0 ? void 0 : classes.select), value: language, onChange: (e) => setLanguage(e.target.value) },
358
611
  React.createElement("option", { value: "en" }, "English"),
359
612
  React.createElement("option", { value: "tl" }, "Tagalog"),
@@ -375,7 +628,16 @@ const AccessibilityToolbar = ({ className, style, classes, }) => {
375
628
  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
629
  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
630
  "\uD83C\uDFA4 ",
378
- translate("voiceCommand"))));
631
+ translate("voiceCommand")),
632
+ 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 },
633
+ "\uD83D\uDD0A ",
634
+ translate("readAloud")),
635
+ 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")),
636
+ 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") },
637
+ React.createElement("option", { value: "none" }, translate("colorBlindMode")),
638
+ React.createElement("option", { value: "protanopia" }, "Protanopia (Red)"),
639
+ React.createElement("option", { value: "deuteranopia" }, "Deuteranopia (Green)"),
640
+ React.createElement("option", { value: "tritanopia" }, "Tritanopia (Blue)"))));
379
641
  };
380
642
 
381
643
  const cn = (...parts) => parts.filter(Boolean).join(" ");
@@ -398,39 +660,45 @@ const AccessibilityDropdown = ({ className, style, classes, triggerLabel = "♿
398
660
  React.createElement("div", { className: cn("a11y-panel-header", classes === null || classes === void 0 ? void 0 : classes.panelHeader) },
399
661
  React.createElement("div", { className: "a11y-panel-heading" },
400
662
  React.createElement("span", { className: "a11y-panel-eyebrow" }, "NGP"),
401
- React.createElement("label", { className: "a11y-panel-title" }, "Accessibility Options")),
663
+ React.createElement("label", { className: cn("a11y-panel-title", classes === null || classes === void 0 ? void 0 : classes.title) }, "Accessibility Options")),
402
664
  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"),
665
+ React.createElement("div", { className: cn("a11y-language", classes === null || classes === void 0 ? void 0 : classes.section) },
666
+ React.createElement("label", { htmlFor: "a11y-language-select", className: cn("a11y-language-label", classes === null || classes === void 0 ? void 0 : classes.title) }, translate("language")),
405
667
  React.createElement("select", { id: "a11y-language-select", value: language, onChange: (e) => setLanguage(e.target.value) },
406
668
  React.createElement("option", { value: "en" }, "English"),
407
669
  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"),
670
+ React.createElement("option", { value: "ceb" }, "Cebuano"),
671
+ React.createElement("option", { value: "ja" }, "Japanese"),
672
+ React.createElement("option", { value: "es" }, "Spanish"),
673
+ React.createElement("option", { value: "fr" }, "French"),
674
+ React.createElement("option", { value: "de" }, "German"),
675
+ React.createElement("option", { value: "zh" }, "Chinese"),
676
+ React.createElement("option", { value: "ar" }, "Arabic"))),
677
+ React.createElement("section", { className: cn("a11y-section", classes === null || classes === void 0 ? void 0 : classes.section) },
678
+ React.createElement("h3", { className: cn("a11y-section-title", classes === null || classes === void 0 ? void 0 : classes.title) }, "Content Adjustments"),
411
679
  React.createElement("div", { className: "a11y-card" },
412
- React.createElement("span", { className: "a11y-card-title" }, "Content Scaling"),
680
+ React.createElement("span", { className: cn("a11y-card-title", classes === null || classes === void 0 ? void 0 : classes.title) }, "Content Scaling"),
413
681
  React.createElement("div", { className: "a11y-stepper" },
414
682
  React.createElement("button", { onClick: decreaseText }, "\u2212"),
415
683
  React.createElement("span", { className: "a11y-stepper-value" }, textScaleLabel),
416
684
  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"))))))));
685
+ React.createElement("div", { className: cn("a11y-grid", classes === null || classes === void 0 ? void 0 : classes.section) },
686
+ React.createElement("button", { className: cn("a11y-card", textMagnifier && "active", classes === null || classes === void 0 ? void 0 : classes.button), onClick: toggleTextMagnifier }, translate("textMagnifier")),
687
+ React.createElement("button", { className: cn("a11y-card", readableFont && "active", classes === null || classes === void 0 ? void 0 : classes.button), onClick: toggleReadableFont }, "Readable Font"),
688
+ React.createElement("button", { className: cn("a11y-card", underlineLinks && "active", classes === null || classes === void 0 ? void 0 : classes.button), onClick: toggleUnderlineLinks }, "Highlight Links"),
689
+ React.createElement("button", { className: cn("a11y-card", highlightTitles && "active", classes === null || classes === void 0 ? void 0 : classes.button), onClick: toggleHighlightTitles }, "Highlight Titles"))),
690
+ React.createElement("section", { className: cn("a11y-section", classes === null || classes === void 0 ? void 0 : classes.section) },
691
+ React.createElement("h3", { className: cn("a11y-section-title", classes === null || classes === void 0 ? void 0 : classes.title) }, "Color Adjustments"),
692
+ React.createElement("div", { className: cn("a11y-grid", classes === null || classes === void 0 ? void 0 : classes.section) },
693
+ React.createElement("button", { className: cn("a11y-card", highContrast && "active", classes === null || classes === void 0 ? void 0 : classes.button), onClick: toggleHighContrast }, translate("highContrast")),
694
+ React.createElement("button", { className: cn("a11y-card", negativeContrast && "active", classes === null || classes === void 0 ? void 0 : classes.button), onClick: toggleNegativeContrast }, translate("negativeContrast")),
695
+ React.createElement("button", { className: cn("a11y-card", lightBackground && "active", classes === null || classes === void 0 ? void 0 : classes.button), onClick: toggleLightBackground }, translate("lightBackground")))),
696
+ React.createElement("section", { className: cn("a11y-section", classes === null || classes === void 0 ? void 0 : classes.section) },
697
+ React.createElement("h3", { className: cn("a11y-section-title", classes === null || classes === void 0 ? void 0 : classes.title) }, "Accessibility Tools"),
698
+ React.createElement("div", { className: cn("a11y-grid", classes === null || classes === void 0 ? void 0 : classes.section) },
699
+ React.createElement("button", { className: cn("a11y-card", pauseAnimations && "active", classes === null || classes === void 0 ? void 0 : classes.button), onClick: togglePauseAnimations }, translate("pauseAnimations")),
700
+ React.createElement("button", { className: cn("a11y-card", readingGuide && "active", classes === null || classes === void 0 ? void 0 : classes.button), onClick: toggleReadingGuide }, translate("readingGuide")),
701
+ React.createElement("button", { className: cn("a11y-card", voiceEnabled && "active", classes === null || classes === void 0 ? void 0 : classes.button), onClick: toggleVoice }, translate("voiceCommand"))))))));
434
702
  };
435
703
 
436
704
  const T = ({ k, children }) => {