@swalha1999/a11y-react 1.0.2

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.mjs ADDED
@@ -0,0 +1,1097 @@
1
+ // src/AccessibilityWidget.tsx
2
+ import { useState as useState3, useRef as useRef2, useEffect as useEffect4, useId } from "react";
3
+ import { createPortal } from "react-dom";
4
+
5
+ // src/hooks/useAccessibilitySettings.ts
6
+ import { useState, useEffect, useCallback } from "react";
7
+ var DEFAULT_SETTINGS = {
8
+ textSize: 0,
9
+ lineHeight: 0,
10
+ letterSpacing: 0,
11
+ invertColors: false,
12
+ grayscale: false,
13
+ underlineLinks: false,
14
+ bigCursor: false,
15
+ readingGuide: false,
16
+ hideImages: false
17
+ };
18
+ function useAccessibilitySettings({
19
+ storageKey = "accessibility-settings",
20
+ defaultSettings,
21
+ onSettingsChange,
22
+ disablePersistence = false
23
+ } = {}) {
24
+ const [settings, setSettings] = useState(() => {
25
+ const initial = { ...DEFAULT_SETTINGS, ...defaultSettings };
26
+ if (!disablePersistence && typeof window !== "undefined") {
27
+ try {
28
+ const saved = localStorage.getItem(storageKey);
29
+ if (saved) {
30
+ return { ...initial, ...JSON.parse(saved) };
31
+ }
32
+ } catch {
33
+ }
34
+ }
35
+ return initial;
36
+ });
37
+ useEffect(() => {
38
+ if (!disablePersistence && typeof window !== "undefined") {
39
+ try {
40
+ localStorage.setItem(storageKey, JSON.stringify(settings));
41
+ } catch {
42
+ }
43
+ }
44
+ onSettingsChange?.(settings);
45
+ }, [settings, storageKey, onSettingsChange, disablePersistence]);
46
+ useEffect(() => {
47
+ const root = document.documentElement;
48
+ const body = document.body;
49
+ const WRAPPER_ID = "a11y-content-wrapper";
50
+ const PORTAL_ID = "a11y-widget-portal";
51
+ let wrapper = document.getElementById(WRAPPER_ID);
52
+ if (!wrapper) {
53
+ wrapper = document.createElement("div");
54
+ wrapper.id = WRAPPER_ID;
55
+ wrapper.style.minHeight = "100vh";
56
+ wrapper.style.background = "inherit";
57
+ const children = Array.from(body.children);
58
+ children.forEach((child) => {
59
+ if (child.id !== PORTAL_ID && child.id !== WRAPPER_ID) {
60
+ wrapper.appendChild(child);
61
+ }
62
+ });
63
+ body.insertBefore(wrapper, body.firstChild);
64
+ }
65
+ const textScale = 1 + settings.textSize * 0.05;
66
+ root.style.setProperty("--a11y-text-scale", String(textScale));
67
+ body.classList.toggle("a11y-text-scaled", settings.textSize !== 0);
68
+ const lineHeight = 1.5 + settings.lineHeight * 0.2;
69
+ root.style.setProperty("--a11y-line-height", String(lineHeight));
70
+ body.classList.toggle("a11y-line-height-active", settings.lineHeight !== 0);
71
+ const letterSpacing = settings.letterSpacing * 0.05;
72
+ root.style.setProperty("--a11y-letter-spacing", `${letterSpacing}em`);
73
+ body.classList.toggle("a11y-letter-spacing-active", settings.letterSpacing !== 0);
74
+ wrapper.classList.toggle("a11y-invert", settings.invertColors);
75
+ wrapper.classList.toggle("a11y-grayscale", settings.grayscale);
76
+ body.classList.toggle("a11y-underline-links", settings.underlineLinks);
77
+ body.classList.toggle("a11y-big-cursor", settings.bigCursor);
78
+ body.classList.toggle("a11y-reading-guide", settings.readingGuide);
79
+ body.classList.toggle("a11y-hide-images", settings.hideImages);
80
+ return () => {
81
+ root.style.removeProperty("--a11y-text-scale");
82
+ root.style.removeProperty("--a11y-line-height");
83
+ root.style.removeProperty("--a11y-letter-spacing");
84
+ body.classList.remove(
85
+ "a11y-text-scaled",
86
+ "a11y-line-height-active",
87
+ "a11y-letter-spacing-active",
88
+ "a11y-underline-links",
89
+ "a11y-big-cursor",
90
+ "a11y-reading-guide",
91
+ "a11y-hide-images"
92
+ );
93
+ if (wrapper) {
94
+ wrapper.classList.remove("a11y-invert", "a11y-grayscale");
95
+ }
96
+ };
97
+ }, [settings]);
98
+ const updateSetting = useCallback((key, value) => {
99
+ setSettings((prev) => ({ ...prev, [key]: value }));
100
+ }, []);
101
+ const toggleSetting = useCallback((key) => {
102
+ setSettings((prev) => {
103
+ const current = prev[key];
104
+ if (typeof current === "boolean") {
105
+ return { ...prev, [key]: !current };
106
+ }
107
+ return prev;
108
+ });
109
+ }, []);
110
+ const resetSettings = useCallback(() => {
111
+ setSettings({ ...DEFAULT_SETTINGS, ...defaultSettings });
112
+ }, [defaultSettings]);
113
+ const incrementSetting = useCallback((key, min = -2, max = 2) => {
114
+ setSettings((prev) => ({
115
+ ...prev,
116
+ [key]: Math.min(max, prev[key] + 1)
117
+ }));
118
+ }, []);
119
+ const decrementSetting = useCallback((key, min = -2, max = 2) => {
120
+ setSettings((prev) => ({
121
+ ...prev,
122
+ [key]: Math.max(min, prev[key] - 1)
123
+ }));
124
+ }, []);
125
+ return {
126
+ settings,
127
+ updateSetting,
128
+ toggleSetting,
129
+ resetSettings,
130
+ incrementSetting,
131
+ decrementSetting
132
+ };
133
+ }
134
+
135
+ // src/hooks/useReadingGuide.ts
136
+ import { useEffect as useEffect2, useRef } from "react";
137
+ function useReadingGuide(enabled, primaryColor = "#2d2d2d") {
138
+ const lineRef = useRef(null);
139
+ useEffect2(() => {
140
+ if (!enabled) {
141
+ if (lineRef.current) {
142
+ lineRef.current.remove();
143
+ lineRef.current = null;
144
+ }
145
+ return;
146
+ }
147
+ const line = document.createElement("div");
148
+ line.className = "a11y-reading-guide-line";
149
+ line.setAttribute("aria-hidden", "true");
150
+ line.style.cssText = `
151
+ position: fixed;
152
+ left: 0;
153
+ right: 0;
154
+ height: 2px;
155
+ background: ${primaryColor};
156
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
157
+ pointer-events: none;
158
+ z-index: 9997;
159
+ transition: top 0.1s ease-out;
160
+ `;
161
+ document.body.appendChild(line);
162
+ lineRef.current = line;
163
+ const handleMouseMove = (e) => {
164
+ if (lineRef.current) {
165
+ lineRef.current.style.top = `${e.clientY}px`;
166
+ }
167
+ };
168
+ document.addEventListener("mousemove", handleMouseMove);
169
+ return () => {
170
+ document.removeEventListener("mousemove", handleMouseMove);
171
+ if (lineRef.current) {
172
+ lineRef.current.remove();
173
+ lineRef.current = null;
174
+ }
175
+ };
176
+ }, [enabled, primaryColor]);
177
+ }
178
+
179
+ // src/hooks/useBackgroundContrast.ts
180
+ import { useState as useState2, useEffect as useEffect3, useCallback as useCallback2 } from "react";
181
+ function useBackgroundContrast(buttonRef) {
182
+ const [isDarkBackground, setIsDarkBackground] = useState2(false);
183
+ const detectBackground = useCallback2(() => {
184
+ const button = buttonRef.current;
185
+ if (!button) return;
186
+ const rect = button.getBoundingClientRect();
187
+ const x = rect.left + rect.width / 2;
188
+ const y = rect.top + rect.height / 2;
189
+ const originalPointerEvents = button.style.pointerEvents;
190
+ button.style.pointerEvents = "none";
191
+ const elementBehind = document.elementFromPoint(x, y);
192
+ button.style.pointerEvents = originalPointerEvents;
193
+ if (elementBehind) {
194
+ const bgColor = window.getComputedStyle(elementBehind).backgroundColor;
195
+ const rgb = bgColor.match(/\d+/g);
196
+ if (rgb && rgb.length >= 3) {
197
+ const luminance = (0.299 * parseInt(rgb[0], 10) + 0.587 * parseInt(rgb[1], 10) + 0.114 * parseInt(rgb[2], 10)) / 255;
198
+ setIsDarkBackground(luminance < 0.5);
199
+ }
200
+ }
201
+ }, [buttonRef]);
202
+ useEffect3(() => {
203
+ detectBackground();
204
+ window.addEventListener("scroll", detectBackground);
205
+ window.addEventListener("resize", detectBackground);
206
+ return () => {
207
+ window.removeEventListener("scroll", detectBackground);
208
+ window.removeEventListener("resize", detectBackground);
209
+ };
210
+ }, [detectBackground]);
211
+ return isDarkBackground;
212
+ }
213
+
214
+ // src/icons.tsx
215
+ import { jsx } from "react/jsx-runtime";
216
+ var AccessibilityIcon = ({
217
+ size = 24,
218
+ className,
219
+ "aria-hidden": ariaHidden = true
220
+ }) => /* @__PURE__ */ jsx(
221
+ "svg",
222
+ {
223
+ viewBox: "0 0 24 24",
224
+ fill: "currentColor",
225
+ width: size,
226
+ height: size,
227
+ className: `a11y-widget-icon ${className || ""}`,
228
+ "aria-hidden": ariaHidden,
229
+ role: "img",
230
+ children: /* @__PURE__ */ jsx("path", { d: "M12 2C13.1 2 14 2.9 14 4S13.1 6 12 6 10 5.1 10 4 10.9 2 12 2M21 9H15V22H13V16H11V22H9V9H3V7H21V9Z" })
231
+ }
232
+ );
233
+ var TextSizeIcon = ({
234
+ size = 24,
235
+ className,
236
+ "aria-hidden": ariaHidden = true
237
+ }) => /* @__PURE__ */ jsx(
238
+ "svg",
239
+ {
240
+ viewBox: "0 0 24 24",
241
+ fill: "currentColor",
242
+ width: size,
243
+ height: size,
244
+ className: `a11y-widget-icon ${className || ""}`,
245
+ "aria-hidden": ariaHidden,
246
+ children: /* @__PURE__ */ jsx("path", { d: "M3 7V5H21V7H3M10 17V9H14V17H10M8 19H16V21H8V19Z" })
247
+ }
248
+ );
249
+ var LineHeightIcon = ({
250
+ size = 24,
251
+ className,
252
+ "aria-hidden": ariaHidden = true
253
+ }) => /* @__PURE__ */ jsx(
254
+ "svg",
255
+ {
256
+ viewBox: "0 0 24 24",
257
+ fill: "currentColor",
258
+ width: size,
259
+ height: size,
260
+ className: `a11y-widget-icon ${className || ""}`,
261
+ "aria-hidden": ariaHidden,
262
+ children: /* @__PURE__ */ jsx("path", { d: "M10 13H22V11H10M10 19H22V17H10M10 7H22V5H10M6 7H8.5L5 3.5L1.5 7H4V17H1.5L5 20.5L8.5 17H6V7Z" })
263
+ }
264
+ );
265
+ var LetterSpacingIcon = ({
266
+ size = 24,
267
+ className,
268
+ "aria-hidden": ariaHidden = true
269
+ }) => /* @__PURE__ */ jsx(
270
+ "svg",
271
+ {
272
+ viewBox: "0 0 24 24",
273
+ fill: "currentColor",
274
+ width: size,
275
+ height: size,
276
+ className: `a11y-widget-icon ${className || ""}`,
277
+ "aria-hidden": ariaHidden,
278
+ children: /* @__PURE__ */ jsx("path", { d: "M11 3L5.5 17H7.75L8.85 14H15.15L16.25 17H18.5L13 3H11M9.55 12L12 5.67L14.45 12H9.55M2 20H22V22H2V20Z" })
279
+ }
280
+ );
281
+ var InvertIcon = ({
282
+ size = 24,
283
+ className,
284
+ "aria-hidden": ariaHidden = true
285
+ }) => /* @__PURE__ */ jsx(
286
+ "svg",
287
+ {
288
+ viewBox: "0 0 24 24",
289
+ fill: "currentColor",
290
+ width: size,
291
+ height: size,
292
+ className: `a11y-widget-icon ${className || ""}`,
293
+ "aria-hidden": ariaHidden,
294
+ children: /* @__PURE__ */ jsx("path", { d: "M12,18C11.11,18 10.26,17.8 9.5,17.45C11.56,16.5 13,14.42 13,12C13,9.58 11.56,7.5 9.5,6.55C10.26,6.2 11.11,6 12,6A6,6 0 0,1 18,12A6,6 0 0,1 12,18M20,8.69V4H15.31L12,0.69L8.69,4H4V8.69L0.69,12L4,15.31V20H8.69L12,23.31L15.31,20H20V15.31L23.31,12L20,8.69Z" })
295
+ }
296
+ );
297
+ var GrayscaleIcon = ({
298
+ size = 24,
299
+ className,
300
+ "aria-hidden": ariaHidden = true
301
+ }) => /* @__PURE__ */ jsx(
302
+ "svg",
303
+ {
304
+ viewBox: "0 0 24 24",
305
+ fill: "currentColor",
306
+ width: size,
307
+ height: size,
308
+ className: `a11y-widget-icon ${className || ""}`,
309
+ "aria-hidden": ariaHidden,
310
+ children: /* @__PURE__ */ jsx("path", { d: "M12,18.54L19.37,12.8L21,14.07L12,21.07L3,14.07L4.62,12.81L12,18.54M12,16L3,9L12,2L21,9L12,16M12,4.53L6.26,9L12,13.47L17.74,9L12,4.53Z" })
311
+ }
312
+ );
313
+ var LinkIcon = ({
314
+ size = 24,
315
+ className,
316
+ "aria-hidden": ariaHidden = true
317
+ }) => /* @__PURE__ */ jsx(
318
+ "svg",
319
+ {
320
+ viewBox: "0 0 24 24",
321
+ fill: "currentColor",
322
+ width: size,
323
+ height: size,
324
+ className: `a11y-widget-icon ${className || ""}`,
325
+ "aria-hidden": ariaHidden,
326
+ children: /* @__PURE__ */ jsx("path", { d: "M10.59,13.41C11,13.8 11,14.44 10.59,14.83C10.2,15.22 9.56,15.22 9.17,14.83C7.22,12.88 7.22,9.71 9.17,7.76V7.76L12.71,4.22C14.66,2.27 17.83,2.27 19.78,4.22C21.73,6.17 21.73,9.34 19.78,11.29L18.29,12.78C18.3,11.96 18.17,11.14 17.89,10.36L18.36,9.88C19.54,8.71 19.54,6.81 18.36,5.64C17.19,4.46 15.29,4.46 14.12,5.64L10.59,9.17C9.41,10.34 9.41,12.24 10.59,13.41M13.41,9.17C13.8,8.78 14.44,8.78 14.83,9.17C16.78,11.12 16.78,14.29 14.83,16.24V16.24L11.29,19.78C9.34,21.73 6.17,21.73 4.22,19.78C2.27,17.83 2.27,14.66 4.22,12.71L5.71,11.22C5.7,12.04 5.83,12.86 6.11,13.65L5.64,14.12C4.46,15.29 4.46,17.19 5.64,18.36C6.81,19.54 8.71,19.54 9.88,18.36L13.41,14.83C14.59,13.66 14.59,11.76 13.41,10.59C13,10.2 13,9.56 13.41,9.17Z" })
327
+ }
328
+ );
329
+ var CursorIcon = ({
330
+ size = 24,
331
+ className,
332
+ "aria-hidden": ariaHidden = true
333
+ }) => /* @__PURE__ */ jsx(
334
+ "svg",
335
+ {
336
+ viewBox: "0 0 24 24",
337
+ fill: "currentColor",
338
+ width: size,
339
+ height: size,
340
+ className: `a11y-widget-icon ${className || ""}`,
341
+ "aria-hidden": ariaHidden,
342
+ children: /* @__PURE__ */ jsx("path", { d: "M13.64,21.97C13.14,22.21 12.54,22 12.31,21.5L10.13,16.76L7.62,18.78C7.45,18.92 7.24,19 7,19A1,1 0 0,1 6,18V3A1,1 0 0,1 7,2C7.24,2 7.47,2.09 7.64,2.23L7.65,2.22L19.14,11.86C19.57,12.22 19.62,12.85 19.27,13.27C19.12,13.45 18.91,13.57 18.7,13.61L15.54,14.23L17.74,18.96C17.97,19.46 17.76,20.06 17.26,20.28L13.64,21.97Z" })
343
+ }
344
+ );
345
+ var ReadingGuideIcon = ({
346
+ size = 24,
347
+ className,
348
+ "aria-hidden": ariaHidden = true
349
+ }) => /* @__PURE__ */ jsx(
350
+ "svg",
351
+ {
352
+ viewBox: "0 0 24 24",
353
+ fill: "currentColor",
354
+ width: size,
355
+ height: size,
356
+ className: `a11y-widget-icon ${className || ""}`,
357
+ "aria-hidden": ariaHidden,
358
+ children: /* @__PURE__ */ jsx("path", { d: "M21,5C19.89,4.65 18.67,4.5 17.5,4.5C15.55,4.5 13.45,4.9 12,6C10.55,4.9 8.45,4.5 6.5,4.5C4.55,4.5 2.45,4.9 1,6V20.65C1,20.9 1.25,21.15 1.5,21.15C1.6,21.15 1.65,21.1 1.75,21.1C3.1,20.45 5.05,20 6.5,20C8.45,20 10.55,20.4 12,21.5C13.35,20.65 15.8,20 17.5,20C19.15,20 20.85,20.3 22.25,21.05C22.35,21.1 22.4,21.1 22.5,21.1C22.75,21.1 23,20.85 23,20.6V6C22.4,5.55 21.75,5.25 21,5M21,18.5C19.9,18.15 18.7,18 17.5,18C15.8,18 13.35,18.65 12,19.5V8C13.35,7.15 15.8,6.5 17.5,6.5C18.7,6.5 19.9,6.65 21,7V18.5Z" })
359
+ }
360
+ );
361
+ var ImageIcon = ({
362
+ size = 24,
363
+ className,
364
+ "aria-hidden": ariaHidden = true
365
+ }) => /* @__PURE__ */ jsx(
366
+ "svg",
367
+ {
368
+ viewBox: "0 0 24 24",
369
+ fill: "currentColor",
370
+ width: size,
371
+ height: size,
372
+ className: `a11y-widget-icon ${className || ""}`,
373
+ "aria-hidden": ariaHidden,
374
+ children: /* @__PURE__ */ jsx("path", { d: "M8.5,13.5L11,16.5L14.5,12L19,18H5M21,19V5C21,3.89 20.1,3 19,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19Z" })
375
+ }
376
+ );
377
+ var ResetIcon = ({
378
+ size = 24,
379
+ className,
380
+ "aria-hidden": ariaHidden = true
381
+ }) => /* @__PURE__ */ jsx(
382
+ "svg",
383
+ {
384
+ viewBox: "0 0 24 24",
385
+ fill: "currentColor",
386
+ width: size,
387
+ height: size,
388
+ className: `a11y-widget-icon ${className || ""}`,
389
+ "aria-hidden": ariaHidden,
390
+ children: /* @__PURE__ */ jsx("path", { d: "M12.5,8C9.85,8 7.45,9 5.6,10.6L2,7V16H11L7.38,12.38C8.77,11.22 10.54,10.5 12.5,10.5C16.04,10.5 19.05,12.81 20.1,16L22.47,15.22C21.08,11.03 17.15,8 12.5,8Z" })
391
+ }
392
+ );
393
+ var CloseIcon = ({
394
+ size = 24,
395
+ className,
396
+ "aria-hidden": ariaHidden = true
397
+ }) => /* @__PURE__ */ jsx(
398
+ "svg",
399
+ {
400
+ viewBox: "0 0 24 24",
401
+ fill: "currentColor",
402
+ width: size,
403
+ height: size,
404
+ className: `a11y-widget-icon ${className || ""}`,
405
+ "aria-hidden": ariaHidden,
406
+ children: /* @__PURE__ */ jsx("path", { d: "M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" })
407
+ }
408
+ );
409
+
410
+ // src/AccessibilityWidget.tsx
411
+ import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
412
+ var getPortalContainer = () => {
413
+ const PORTAL_ID = "a11y-widget-portal";
414
+ let container = document.getElementById(PORTAL_ID);
415
+ if (!container) {
416
+ container = document.createElement("div");
417
+ container.id = PORTAL_ID;
418
+ document.body.appendChild(container);
419
+ }
420
+ return container;
421
+ };
422
+ var AccessibilityWidget = ({
423
+ translations,
424
+ dir = "ltr",
425
+ styles = {},
426
+ classNames = {},
427
+ position = "bottom-right",
428
+ storageKey = "accessibility-settings",
429
+ onSettingsChange,
430
+ defaultSettings,
431
+ zIndex = 9999,
432
+ disablePersistence = false,
433
+ buttonIcon,
434
+ primaryColor = "#6366f1",
435
+ buttonAriaLabel
436
+ }) => {
437
+ const [isOpen, setIsOpen] = useState3(false);
438
+ const [portalContainer, setPortalContainer] = useState3(null);
439
+ const buttonRef = useRef2(null);
440
+ const panelRef = useRef2(null);
441
+ const uniqueId = useId();
442
+ useEffect4(() => {
443
+ setPortalContainer(getPortalContainer());
444
+ }, []);
445
+ const isDarkBackground = useBackgroundContrast(buttonRef);
446
+ const {
447
+ settings,
448
+ toggleSetting,
449
+ resetSettings,
450
+ incrementSetting,
451
+ decrementSetting
452
+ } = useAccessibilitySettings({
453
+ storageKey,
454
+ defaultSettings,
455
+ onSettingsChange,
456
+ disablePersistence
457
+ });
458
+ useReadingGuide(settings.readingGuide, primaryColor);
459
+ const handleOpen = () => {
460
+ setIsOpen(true);
461
+ };
462
+ const handleClose = () => {
463
+ setIsOpen(false);
464
+ };
465
+ useEffect4(() => {
466
+ const handleKeyDown = (e) => {
467
+ if (e.key === "Escape" && isOpen) {
468
+ handleClose();
469
+ buttonRef.current?.focus();
470
+ }
471
+ };
472
+ document.addEventListener("keydown", handleKeyDown);
473
+ return () => document.removeEventListener("keydown", handleKeyDown);
474
+ }, [isOpen]);
475
+ useEffect4(() => {
476
+ if (!isOpen || !panelRef.current) return;
477
+ const panel = panelRef.current;
478
+ const focusableElements = panel.querySelectorAll(
479
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
480
+ );
481
+ const firstElement = focusableElements[0];
482
+ const lastElement = focusableElements[focusableElements.length - 1];
483
+ const handleTabKey = (e) => {
484
+ if (e.key !== "Tab") return;
485
+ if (e.shiftKey && document.activeElement === firstElement) {
486
+ e.preventDefault();
487
+ lastElement?.focus();
488
+ } else if (!e.shiftKey && document.activeElement === lastElement) {
489
+ e.preventDefault();
490
+ firstElement?.focus();
491
+ }
492
+ };
493
+ panel.addEventListener("keydown", handleTabKey);
494
+ firstElement?.focus();
495
+ return () => panel.removeEventListener("keydown", handleTabKey);
496
+ }, [isOpen]);
497
+ const getPositionStyles = () => {
498
+ const base = { position: "fixed" };
499
+ const offset = 24;
500
+ switch (position) {
501
+ case "bottom-left":
502
+ return { ...base, bottom: offset, left: offset };
503
+ case "bottom-right":
504
+ return { ...base, bottom: offset, right: offset };
505
+ case "top-left":
506
+ return { ...base, top: offset, left: offset };
507
+ case "top-right":
508
+ return { ...base, top: offset, right: offset };
509
+ default:
510
+ return { ...base, bottom: offset, right: offset };
511
+ }
512
+ };
513
+ const getPanelPositionStyles = () => {
514
+ const base = { position: "fixed" };
515
+ if (position.includes("bottom")) {
516
+ base.bottom = 100;
517
+ } else {
518
+ base.top = 100;
519
+ }
520
+ if (position.includes("left")) {
521
+ base.left = 24;
522
+ } else {
523
+ base.right = 24;
524
+ }
525
+ return base;
526
+ };
527
+ const buttonStyle = {
528
+ ...getPositionStyles(),
529
+ width: 64,
530
+ height: 64,
531
+ border: "none",
532
+ borderRadius: "50%",
533
+ cursor: "pointer",
534
+ zIndex,
535
+ display: "flex",
536
+ alignItems: "center",
537
+ justifyContent: "center",
538
+ background: isDarkBackground ? "#ffffff" : primaryColor,
539
+ color: isDarkBackground ? primaryColor : "white",
540
+ boxShadow: isDarkBackground ? "0 4px 20px rgba(0, 0, 0, 0.1), 0 2px 8px rgba(0, 0, 0, 0.05)" : `0 4px 20px ${primaryColor}40, 0 2px 8px ${primaryColor}20`,
541
+ ...styles.button,
542
+ ...isDarkBackground ? styles.buttonLight : styles.buttonDark
543
+ };
544
+ const overlayStyle = {
545
+ position: "fixed",
546
+ top: 0,
547
+ left: 0,
548
+ right: 0,
549
+ bottom: 0,
550
+ background: "rgba(0, 0, 0, 0.4)",
551
+ zIndex: zIndex - 1,
552
+ ...styles.overlay
553
+ };
554
+ const panelStyle = {
555
+ ...getPanelPositionStyles(),
556
+ width: 400,
557
+ maxWidth: "calc(100vw - 48px)",
558
+ maxHeight: "85vh",
559
+ background: "#ffffff",
560
+ borderRadius: 24,
561
+ boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
562
+ zIndex,
563
+ overflow: "hidden",
564
+ direction: dir,
565
+ border: "1px solid #e2e8f0",
566
+ ...styles.panel
567
+ };
568
+ const headerStyle = {
569
+ display: "flex",
570
+ justifyContent: "space-between",
571
+ alignItems: "center",
572
+ padding: "24px 28px",
573
+ background: primaryColor,
574
+ color: "white",
575
+ ...styles.panelHeader
576
+ };
577
+ const headerTitleStyle = {
578
+ margin: 0,
579
+ fontSize: 22,
580
+ fontWeight: 700,
581
+ lineHeight: 1.2,
582
+ letterSpacing: "-0.02em"
583
+ };
584
+ const closeButtonStyle = {
585
+ background: "rgba(255, 255, 255, 0.15)",
586
+ border: "none",
587
+ width: 36,
588
+ height: 36,
589
+ borderRadius: 12,
590
+ color: "white",
591
+ cursor: "pointer",
592
+ display: "flex",
593
+ alignItems: "center",
594
+ justifyContent: "center"
595
+ };
596
+ const contentStyle = {
597
+ padding: "20px 24px",
598
+ maxHeight: "calc(85vh - 160px)",
599
+ overflowY: "auto",
600
+ overflowX: "hidden",
601
+ ...styles.panelContent
602
+ };
603
+ const getSettingItemStyle = (isToggle) => ({
604
+ background: "#f8fafc",
605
+ borderRadius: 16,
606
+ padding: "18px 20px",
607
+ marginBottom: 12,
608
+ border: "1px solid #e2e8f0",
609
+ cursor: "default",
610
+ ...isToggle && {
611
+ display: "flex",
612
+ justifyContent: "space-between",
613
+ alignItems: "center"
614
+ },
615
+ ...styles.settingItem
616
+ });
617
+ const itemHeaderStyle = (isToggle) => ({
618
+ display: "flex",
619
+ alignItems: "center",
620
+ gap: 14,
621
+ ...isToggle ? { flex: 1 } : { marginBottom: 14 }
622
+ });
623
+ const iconContainerStyle = {
624
+ width: 40,
625
+ height: 40,
626
+ borderRadius: 12,
627
+ background: `${primaryColor}15`,
628
+ display: "flex",
629
+ alignItems: "center",
630
+ justifyContent: "center",
631
+ flexShrink: 0
632
+ };
633
+ const iconStyle = {
634
+ width: 22,
635
+ height: 22,
636
+ color: primaryColor
637
+ };
638
+ const labelStyle = {
639
+ fontWeight: 600,
640
+ color: "#1e293b",
641
+ fontSize: 15,
642
+ lineHeight: 1.4,
643
+ letterSpacing: "-0.01em"
644
+ };
645
+ const controlContainerStyle = {
646
+ display: "flex",
647
+ gap: 10,
648
+ alignItems: "center",
649
+ justifyContent: "center",
650
+ background: "#ffffff",
651
+ padding: "8px 12px",
652
+ borderRadius: 14
653
+ };
654
+ const controlButtonStyle = (disabled) => ({
655
+ background: disabled ? "#f1f5f9" : primaryColor,
656
+ border: "none",
657
+ borderRadius: 10,
658
+ width: 42,
659
+ height: 42,
660
+ fontSize: 16,
661
+ fontWeight: 700,
662
+ color: disabled ? "#94a3b8" : "white",
663
+ cursor: disabled ? "not-allowed" : "pointer",
664
+ display: "flex",
665
+ alignItems: "center",
666
+ justifyContent: "center",
667
+ opacity: disabled ? 0.5 : 1,
668
+ ...styles.controlButton
669
+ });
670
+ const valueDisplayStyle = {
671
+ minWidth: 70,
672
+ textAlign: "center",
673
+ fontWeight: 700,
674
+ color: "#334155",
675
+ fontSize: 14,
676
+ fontFamily: "ui-monospace, monospace",
677
+ background: "#f8fafc",
678
+ padding: "8px 12px",
679
+ borderRadius: 8
680
+ };
681
+ const toggleTrackStyle = (checked) => ({
682
+ position: "relative",
683
+ width: 56,
684
+ height: 30,
685
+ flexShrink: 0,
686
+ display: "inline-block",
687
+ cursor: "pointer"
688
+ });
689
+ const toggleSliderStyle = (checked) => ({
690
+ position: "absolute",
691
+ cursor: "pointer",
692
+ top: 0,
693
+ left: 0,
694
+ right: 0,
695
+ bottom: 0,
696
+ backgroundColor: checked ? primaryColor : "#e2e8f0",
697
+ borderRadius: 30,
698
+ ...styles.toggleTrack
699
+ });
700
+ const toggleKnobStyle = (checked) => ({
701
+ position: "absolute",
702
+ height: 24,
703
+ width: 24,
704
+ left: checked ? 28 : 3,
705
+ bottom: 3,
706
+ backgroundColor: "white",
707
+ borderRadius: "50%",
708
+ boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.1)",
709
+ ...styles.toggleThumb
710
+ });
711
+ const dividerStyle = {
712
+ height: 1,
713
+ background: "#e2e8f0",
714
+ margin: "20px 0"
715
+ };
716
+ const sectionLabelStyle = {
717
+ fontSize: 11,
718
+ fontWeight: 700,
719
+ textTransform: "uppercase",
720
+ letterSpacing: "0.1em",
721
+ color: "#94a3b8",
722
+ marginBottom: 12,
723
+ marginTop: 4,
724
+ paddingLeft: 4
725
+ };
726
+ const resetButtonStyle = {
727
+ width: "100%",
728
+ padding: "16px 20px",
729
+ background: "#fef2f2",
730
+ border: "1px solid #fecaca",
731
+ borderRadius: 14,
732
+ color: "#dc2626",
733
+ fontWeight: 700,
734
+ fontSize: 15,
735
+ cursor: "pointer",
736
+ display: "flex",
737
+ alignItems: "center",
738
+ justifyContent: "center",
739
+ gap: 10,
740
+ marginTop: 16,
741
+ ...styles.resetButton
742
+ };
743
+ const panelId = `a11y-panel-${uniqueId}`;
744
+ if (!portalContainer) {
745
+ return null;
746
+ }
747
+ const renderToggleItem = (key, icon, label) => /* @__PURE__ */ jsxs(
748
+ "div",
749
+ {
750
+ style: getSettingItemStyle(true),
751
+ className: classNames.settingItem,
752
+ children: [
753
+ /* @__PURE__ */ jsxs("div", { style: itemHeaderStyle(true), children: [
754
+ /* @__PURE__ */ jsx2("div", { style: iconContainerStyle, children: /* @__PURE__ */ jsx2("span", { style: iconStyle, children: icon }) }),
755
+ /* @__PURE__ */ jsx2("span", { style: labelStyle, children: label })
756
+ ] }),
757
+ /* @__PURE__ */ jsxs("label", { style: toggleTrackStyle(settings[key]), children: [
758
+ /* @__PURE__ */ jsx2(
759
+ "input",
760
+ {
761
+ type: "checkbox",
762
+ id: `${key}-${uniqueId}`,
763
+ checked: settings[key],
764
+ onChange: () => toggleSetting(key),
765
+ style: { opacity: 0, width: 0, height: 0, position: "absolute" },
766
+ "aria-label": label,
767
+ role: "switch",
768
+ "aria-checked": settings[key]
769
+ }
770
+ ),
771
+ /* @__PURE__ */ jsx2("span", { style: toggleSliderStyle(settings[key]), "aria-hidden": "true", children: /* @__PURE__ */ jsx2("span", { style: toggleKnobStyle(settings[key]) }) })
772
+ ] })
773
+ ]
774
+ }
775
+ );
776
+ const renderSliderItem = (key, icon, label, decrementLabel = "\u2212", incrementLabel = "+") => /* @__PURE__ */ jsxs(
777
+ "div",
778
+ {
779
+ style: getSettingItemStyle(false),
780
+ className: classNames.settingItem,
781
+ children: [
782
+ /* @__PURE__ */ jsxs("div", { style: itemHeaderStyle(false), children: [
783
+ /* @__PURE__ */ jsx2("div", { style: iconContainerStyle, children: /* @__PURE__ */ jsx2("span", { style: iconStyle, children: icon }) }),
784
+ /* @__PURE__ */ jsx2("span", { style: labelStyle, children: label })
785
+ ] }),
786
+ /* @__PURE__ */ jsxs("div", { style: controlContainerStyle, role: "group", "aria-label": label, children: [
787
+ /* @__PURE__ */ jsx2(
788
+ "button",
789
+ {
790
+ type: "button",
791
+ onClick: () => decrementSetting(key),
792
+ disabled: settings[key] === -2,
793
+ style: controlButtonStyle(settings[key] === -2),
794
+ "aria-label": `Decrease ${label}`,
795
+ children: decrementLabel
796
+ }
797
+ ),
798
+ /* @__PURE__ */ jsx2("span", { style: valueDisplayStyle, "aria-live": "polite", children: settings[key] === 0 ? translations.normal : settings[key] > 0 ? `+${settings[key]}` : settings[key] }),
799
+ /* @__PURE__ */ jsx2(
800
+ "button",
801
+ {
802
+ type: "button",
803
+ onClick: () => incrementSetting(key),
804
+ disabled: settings[key] === 2,
805
+ style: controlButtonStyle(settings[key] === 2),
806
+ "aria-label": `Increase ${label}`,
807
+ children: incrementLabel
808
+ }
809
+ )
810
+ ] })
811
+ ]
812
+ }
813
+ );
814
+ return createPortal(
815
+ /* @__PURE__ */ jsxs(Fragment, { children: [
816
+ /* @__PURE__ */ jsx2(
817
+ "button",
818
+ {
819
+ ref: buttonRef,
820
+ type: "button",
821
+ className: `a11y-widget-button ${classNames.button || ""}`,
822
+ style: buttonStyle,
823
+ onClick: () => isOpen ? handleClose() : handleOpen(),
824
+ "aria-label": buttonAriaLabel || translations.title,
825
+ "aria-expanded": isOpen,
826
+ "aria-controls": panelId,
827
+ "aria-haspopup": "dialog",
828
+ children: buttonIcon || /* @__PURE__ */ jsx2(AccessibilityIcon, { size: 32 })
829
+ }
830
+ ),
831
+ isOpen && /* @__PURE__ */ jsxs(Fragment, { children: [
832
+ /* @__PURE__ */ jsx2(
833
+ "div",
834
+ {
835
+ className: `a11y-widget-overlay ${classNames.overlay || ""}`,
836
+ style: overlayStyle,
837
+ onClick: handleClose,
838
+ "aria-hidden": "true"
839
+ }
840
+ ),
841
+ /* @__PURE__ */ jsxs(
842
+ "div",
843
+ {
844
+ ref: panelRef,
845
+ id: panelId,
846
+ role: "dialog",
847
+ "aria-modal": "true",
848
+ "aria-label": translations.title,
849
+ className: `a11y-widget-panel ${classNames.panel || ""}`,
850
+ style: panelStyle,
851
+ children: [
852
+ /* @__PURE__ */ jsxs("div", { className: classNames.panelHeader, style: headerStyle, children: [
853
+ /* @__PURE__ */ jsx2("h2", { style: headerTitleStyle, children: translations.title }),
854
+ /* @__PURE__ */ jsx2(
855
+ "button",
856
+ {
857
+ type: "button",
858
+ style: closeButtonStyle,
859
+ onClick: handleClose,
860
+ "aria-label": translations.close,
861
+ children: /* @__PURE__ */ jsx2(CloseIcon, { size: 20 })
862
+ }
863
+ )
864
+ ] }),
865
+ /* @__PURE__ */ jsxs("div", { className: classNames.panelContent, style: contentStyle, children: [
866
+ /* @__PURE__ */ jsx2("div", { style: sectionLabelStyle, children: translations.textAdjustments || "Text Adjustments" }),
867
+ renderSliderItem("textSize", /* @__PURE__ */ jsx2(TextSizeIcon, {}), translations.textSize, "A\u2212", "A+"),
868
+ renderSliderItem("lineHeight", /* @__PURE__ */ jsx2(LineHeightIcon, {}), translations.lineSpacing),
869
+ renderSliderItem("letterSpacing", /* @__PURE__ */ jsx2(LetterSpacingIcon, {}), translations.letterSpacing),
870
+ /* @__PURE__ */ jsx2("div", { style: dividerStyle, role: "separator", "aria-hidden": "true" }),
871
+ /* @__PURE__ */ jsx2("div", { style: sectionLabelStyle, children: translations.visualAdjustments || "Visual Adjustments" }),
872
+ renderToggleItem("invertColors", /* @__PURE__ */ jsx2(InvertIcon, {}), translations.invertColors),
873
+ renderToggleItem("grayscale", /* @__PURE__ */ jsx2(GrayscaleIcon, {}), translations.grayscale),
874
+ renderToggleItem("hideImages", /* @__PURE__ */ jsx2(ImageIcon, {}), translations.hideImages),
875
+ /* @__PURE__ */ jsx2("div", { style: dividerStyle, role: "separator", "aria-hidden": "true" }),
876
+ /* @__PURE__ */ jsx2("div", { style: sectionLabelStyle, children: translations.navigationAids || "Navigation Aids" }),
877
+ renderToggleItem("underlineLinks", /* @__PURE__ */ jsx2(LinkIcon, {}), translations.underlineLinks),
878
+ renderToggleItem("bigCursor", /* @__PURE__ */ jsx2(CursorIcon, {}), translations.bigCursor),
879
+ renderToggleItem("readingGuide", /* @__PURE__ */ jsx2(ReadingGuideIcon, {}), translations.readingGuide),
880
+ /* @__PURE__ */ jsxs(
881
+ "button",
882
+ {
883
+ type: "button",
884
+ style: resetButtonStyle,
885
+ onClick: resetSettings,
886
+ className: classNames.resetButton,
887
+ children: [
888
+ /* @__PURE__ */ jsx2(ResetIcon, { size: 20 }),
889
+ translations.reset
890
+ ]
891
+ }
892
+ )
893
+ ] })
894
+ ]
895
+ }
896
+ )
897
+ ] })
898
+ ] }),
899
+ portalContainer
900
+ );
901
+ };
902
+
903
+ // src/translations/en.ts
904
+ var en = {
905
+ title: "Accessibility",
906
+ textSize: "Text Size",
907
+ lineSpacing: "Line Spacing",
908
+ letterSpacing: "Letter Spacing",
909
+ invertColors: "Invert Colors",
910
+ grayscale: "Grayscale",
911
+ underlineLinks: "Underline Links",
912
+ bigCursor: "Big Cursor",
913
+ readingGuide: "Reading Guide",
914
+ hideImages: "Hide Images",
915
+ reset: "Reset All",
916
+ normal: "Normal",
917
+ close: "Close accessibility panel",
918
+ textAdjustments: "Text Adjustments",
919
+ visualAdjustments: "Visual Adjustments",
920
+ navigationAids: "Navigation Aids"
921
+ };
922
+
923
+ // src/translations/ar.ts
924
+ var ar = {
925
+ title: "\u0625\u0645\u0643\u0627\u0646\u064A\u0629 \u0627\u0644\u0648\u0635\u0648\u0644",
926
+ textSize: "\u062D\u062C\u0645 \u0627\u0644\u0646\u0635",
927
+ lineSpacing: "\u062A\u0628\u0627\u0639\u062F \u0627\u0644\u0623\u0633\u0637\u0631",
928
+ letterSpacing: "\u062A\u0628\u0627\u0639\u062F \u0627\u0644\u0623\u062D\u0631\u0641",
929
+ invertColors: "\u0639\u0643\u0633 \u0627\u0644\u0623\u0644\u0648\u0627\u0646",
930
+ grayscale: "\u062A\u062F\u0631\u062C \u0631\u0645\u0627\u062F\u064A",
931
+ underlineLinks: "\u062A\u0633\u0637\u064A\u0631 \u0627\u0644\u0631\u0648\u0627\u0628\u0637",
932
+ bigCursor: "\u0645\u0624\u0634\u0631 \u0643\u0628\u064A\u0631",
933
+ readingGuide: "\u062F\u0644\u064A\u0644 \u0627\u0644\u0642\u0631\u0627\u0621\u0629",
934
+ hideImages: "\u0625\u062E\u0641\u0627\u0621 \u0627\u0644\u0635\u0648\u0631",
935
+ reset: "\u0625\u0639\u0627\u062F\u0629 \u062A\u0639\u064A\u064A\u0646",
936
+ normal: "\u0639\u0627\u062F\u064A",
937
+ close: "\u0625\u063A\u0644\u0627\u0642 \u0644\u0648\u062D\u0629 \u0625\u0645\u0643\u0627\u0646\u064A\u0629 \u0627\u0644\u0648\u0635\u0648\u0644",
938
+ textAdjustments: "\u062A\u0639\u062F\u064A\u0644\u0627\u062A \u0627\u0644\u0646\u0635",
939
+ visualAdjustments: "\u062A\u0639\u062F\u064A\u0644\u0627\u062A \u0628\u0635\u0631\u064A\u0629",
940
+ navigationAids: "\u0645\u0633\u0627\u0639\u062F\u0627\u062A \u0627\u0644\u062A\u0646\u0642\u0644"
941
+ };
942
+
943
+ // src/styles.ts
944
+ function injectAccessibilityStyles() {
945
+ if (typeof document === "undefined") return;
946
+ const styleId = "a11y-widget-global-styles";
947
+ if (document.getElementById(styleId)) return;
948
+ const style = document.createElement("style");
949
+ style.id = styleId;
950
+ style.textContent = `
951
+ /* Accessibility Widget Global Styles */
952
+
953
+ /* Text scaling - only when class is active */
954
+ body.a11y-text-scaled *:not([class*="a11y-widget"]) {
955
+ font-size: calc(1em * var(--a11y-text-scale, 1)) !important;
956
+ }
957
+
958
+ /* Line height - only when class is active */
959
+ body.a11y-line-height-active *:not([class*="a11y-widget"]) {
960
+ line-height: var(--a11y-line-height, 1.5) !important;
961
+ }
962
+
963
+ /* Letter spacing - only when class is active */
964
+ body.a11y-letter-spacing-active *:not([class*="a11y-widget"]) {
965
+ letter-spacing: var(--a11y-letter-spacing, normal) !important;
966
+ }
967
+
968
+ /* Invert colors - applied to content wrapper */
969
+ #a11y-content-wrapper.a11y-invert {
970
+ filter: invert(1) hue-rotate(180deg);
971
+ }
972
+
973
+ #a11y-content-wrapper.a11y-invert img:not(.a11y-widget-icon),
974
+ #a11y-content-wrapper.a11y-invert video,
975
+ #a11y-content-wrapper.a11y-invert [style*="background-image"],
976
+ #a11y-content-wrapper.a11y-invert canvas,
977
+ #a11y-content-wrapper.a11y-invert svg:not(.a11y-widget-icon) {
978
+ filter: invert(1) hue-rotate(180deg);
979
+ }
980
+
981
+ /* Grayscale - applied to content wrapper */
982
+ #a11y-content-wrapper.a11y-grayscale {
983
+ filter: grayscale(100%);
984
+ }
985
+
986
+ /* Underline links */
987
+ body.a11y-underline-links a {
988
+ text-decoration: underline !important;
989
+ text-decoration-thickness: 2px !important;
990
+ text-underline-offset: 3px !important;
991
+ }
992
+
993
+ /* Big cursor */
994
+ body.a11y-big-cursor,
995
+ body.a11y-big-cursor * {
996
+ cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40"><path fill="%232d2d2d" stroke="white" stroke-width="2" d="M10 3l20 15-8 2-4 9-5-3 4-8-7-2z"/></svg>') 8 8, auto !important;
997
+ }
998
+
999
+ /* Hide images */
1000
+ body.a11y-hide-images img,
1001
+ body.a11y-hide-images [role="img"],
1002
+ body.a11y-hide-images svg:not([class*="a11y"]) {
1003
+ opacity: 0 !important;
1004
+ pointer-events: none !important;
1005
+ }
1006
+
1007
+ /* Reading guide line is created dynamically by the hook */
1008
+ `;
1009
+ document.head.appendChild(style);
1010
+ }
1011
+ function removeAccessibilityStyles() {
1012
+ if (typeof document === "undefined") return;
1013
+ const style = document.getElementById("a11y-widget-global-styles");
1014
+ if (style) {
1015
+ style.remove();
1016
+ }
1017
+ }
1018
+ var accessibilityStylesCSS = `
1019
+ /* Accessibility Widget Global Styles */
1020
+
1021
+ /* Text scaling - only when class is active */
1022
+ body.a11y-text-scaled *:not([class*="a11y-widget"]) {
1023
+ font-size: calc(1em * var(--a11y-text-scale, 1)) !important;
1024
+ }
1025
+
1026
+ /* Line height - only when class is active */
1027
+ body.a11y-line-height-active *:not([class*="a11y-widget"]) {
1028
+ line-height: var(--a11y-line-height, 1.5) !important;
1029
+ }
1030
+
1031
+ /* Letter spacing - only when class is active */
1032
+ body.a11y-letter-spacing-active *:not([class*="a11y-widget"]) {
1033
+ letter-spacing: var(--a11y-letter-spacing, normal) !important;
1034
+ }
1035
+
1036
+ /* Invert colors - applied to content wrapper */
1037
+ #a11y-content-wrapper.a11y-invert {
1038
+ filter: invert(1) hue-rotate(180deg);
1039
+ }
1040
+
1041
+ #a11y-content-wrapper.a11y-invert img:not(.a11y-widget-icon),
1042
+ #a11y-content-wrapper.a11y-invert video,
1043
+ #a11y-content-wrapper.a11y-invert [style*="background-image"],
1044
+ #a11y-content-wrapper.a11y-invert canvas,
1045
+ #a11y-content-wrapper.a11y-invert svg:not(.a11y-widget-icon) {
1046
+ filter: invert(1) hue-rotate(180deg);
1047
+ }
1048
+
1049
+ /* Grayscale - applied to content wrapper */
1050
+ #a11y-content-wrapper.a11y-grayscale {
1051
+ filter: grayscale(100%);
1052
+ }
1053
+
1054
+ /* Underline links */
1055
+ body.a11y-underline-links a {
1056
+ text-decoration: underline !important;
1057
+ text-decoration-thickness: 2px !important;
1058
+ text-underline-offset: 3px !important;
1059
+ }
1060
+
1061
+ /* Big cursor */
1062
+ body.a11y-big-cursor,
1063
+ body.a11y-big-cursor * {
1064
+ cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40"><path fill="%232d2d2d" stroke="white" stroke-width="2" d="M10 3l20 15-8 2-4 9-5-3 4-8-7-2z"/></svg>') 8 8, auto !important;
1065
+ }
1066
+
1067
+ /* Hide images */
1068
+ body.a11y-hide-images img,
1069
+ body.a11y-hide-images [role="img"],
1070
+ body.a11y-hide-images svg:not([class*="a11y"]) {
1071
+ opacity: 0 !important;
1072
+ pointer-events: none !important;
1073
+ }
1074
+ `;
1075
+ export {
1076
+ AccessibilityIcon,
1077
+ AccessibilityWidget,
1078
+ CloseIcon,
1079
+ CursorIcon,
1080
+ GrayscaleIcon,
1081
+ ImageIcon,
1082
+ InvertIcon,
1083
+ LetterSpacingIcon,
1084
+ LineHeightIcon,
1085
+ LinkIcon,
1086
+ ReadingGuideIcon,
1087
+ ResetIcon,
1088
+ TextSizeIcon,
1089
+ accessibilityStylesCSS,
1090
+ ar,
1091
+ en,
1092
+ injectAccessibilityStyles,
1093
+ removeAccessibilityStyles,
1094
+ useAccessibilitySettings,
1095
+ useBackgroundContrast,
1096
+ useReadingGuide
1097
+ };