vision-accessibility 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +225 -0
  3. package/dist/components/AccessibilityPanel/AccessibilityPanel.d.ts +12 -0
  4. package/dist/components/AccessibilityPanel/AccessibilityPanel.d.ts.map +1 -0
  5. package/dist/components/AccessibilityToggle/AccessibilityToggle.d.ts +18 -0
  6. package/dist/components/AccessibilityToggle/AccessibilityToggle.d.ts.map +1 -0
  7. package/dist/components/ColorSchemeControl/ColorSchemeControl.d.ts +18 -0
  8. package/dist/components/ColorSchemeControl/ColorSchemeControl.d.ts.map +1 -0
  9. package/dist/components/FontSizeControl/FontSizeControl.d.ts +18 -0
  10. package/dist/components/FontSizeControl/FontSizeControl.d.ts.map +1 -0
  11. package/dist/components/ImageControl/ImageControl.d.ts +18 -0
  12. package/dist/components/ImageControl/ImageControl.d.ts.map +1 -0
  13. package/dist/context/AccessibilityContext.d.ts +25 -0
  14. package/dist/context/AccessibilityContext.d.ts.map +1 -0
  15. package/dist/hooks/useAccessibilitySettings.d.ts +25 -0
  16. package/dist/hooks/useAccessibilitySettings.d.ts.map +1 -0
  17. package/dist/index.d.ts +17 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.esm.js +1151 -0
  20. package/dist/index.esm.js.map +1 -0
  21. package/dist/index.umd.js +11 -0
  22. package/dist/index.umd.js.map +1 -0
  23. package/dist/lib/accessibility-storage.d.ts +23 -0
  24. package/dist/lib/accessibility-storage.d.ts.map +1 -0
  25. package/dist/lib/css-applier.d.ts +50 -0
  26. package/dist/lib/css-applier.d.ts.map +1 -0
  27. package/dist/lib/dom-manipulator.d.ts +29 -0
  28. package/dist/lib/dom-manipulator.d.ts.map +1 -0
  29. package/dist/lib/font-size-manager.d.ts +26 -0
  30. package/dist/lib/font-size-manager.d.ts.map +1 -0
  31. package/dist/style.css +1 -0
  32. package/dist/types/index.d.ts +61 -0
  33. package/dist/types/index.d.ts.map +1 -0
  34. package/package.json +58 -0
  35. package/src/components/AccessibilityPanel/AccessibilityPanel.module.scss +214 -0
  36. package/src/components/AccessibilityPanel/AccessibilityPanel.tsx +151 -0
  37. package/src/components/AccessibilityToggle/AccessibilityToggle.module.scss +158 -0
  38. package/src/components/AccessibilityToggle/AccessibilityToggle.tsx +85 -0
  39. package/src/components/ColorSchemeControl/ColorSchemeControl.module.scss +175 -0
  40. package/src/components/ColorSchemeControl/ColorSchemeControl.tsx +116 -0
  41. package/src/components/FontSizeControl/FontSizeControl.module.scss +175 -0
  42. package/src/components/FontSizeControl/FontSizeControl.tsx +116 -0
  43. package/src/components/ImageControl/ImageControl.module.scss +163 -0
  44. package/src/components/ImageControl/ImageControl.tsx +85 -0
  45. package/src/context/AccessibilityContext.tsx +54 -0
  46. package/src/hooks/useAccessibilitySettings.ts +228 -0
  47. package/src/index.ts +80 -0
  48. package/src/lib/accessibility-storage.ts +82 -0
  49. package/src/lib/css-applier.ts +168 -0
  50. package/src/lib/dom-manipulator.ts +75 -0
  51. package/src/lib/font-size-manager.ts +185 -0
  52. package/src/styles/global.scss +60 -0
  53. package/src/styles/variables.scss +80 -0
  54. package/src/types/index.ts +72 -0
  55. package/src/types/scss.d.ts +9 -0
@@ -0,0 +1,1151 @@
1
+ import require$$0, { useCallback, useState, useEffect, createContext, useContext, useRef } from "react";
2
+ const DEFAULT_ACCESSIBILITY_SETTINGS = {
3
+ isEnabled: false,
4
+ colorScheme: "standard",
5
+ fontSize: "standard",
6
+ showImages: true
7
+ };
8
+ const STORAGE_KEY = "accessibility-settings";
9
+ const saveToStorage = (settings) => {
10
+ try {
11
+ if (typeof window === "undefined") return;
12
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(settings));
13
+ } catch (error) {
14
+ console.warn("Не удалось сохранить настройки доступности:", error);
15
+ }
16
+ };
17
+ const loadFromStorage = () => {
18
+ try {
19
+ if (typeof window === "undefined") return null;
20
+ const saved = localStorage.getItem(STORAGE_KEY);
21
+ return saved ? validateSettings(JSON.parse(saved)) : null;
22
+ } catch (error) {
23
+ console.warn("Не удалось загрузить настройки доступности:", error);
24
+ return null;
25
+ }
26
+ };
27
+ const clearStorage = () => {
28
+ try {
29
+ if (typeof window === "undefined") return;
30
+ localStorage.removeItem(STORAGE_KEY);
31
+ } catch (error) {
32
+ console.warn("Не удалось очистить настройки доступности:", error);
33
+ }
34
+ };
35
+ const validateSettings = (settings) => {
36
+ if (!settings || typeof settings !== "object") {
37
+ return DEFAULT_ACCESSIBILITY_SETTINGS;
38
+ }
39
+ const s = settings;
40
+ return {
41
+ isEnabled: typeof s.isEnabled === "boolean" ? s.isEnabled : DEFAULT_ACCESSIBILITY_SETTINGS.isEnabled,
42
+ colorScheme: ["standard", "high-contrast", "grayscale"].includes(s.colorScheme) ? s.colorScheme : DEFAULT_ACCESSIBILITY_SETTINGS.colorScheme,
43
+ fontSize: ["small", "standard", "large"].includes(s.fontSize) ? s.fontSize : DEFAULT_ACCESSIBILITY_SETTINGS.fontSize,
44
+ showImages: typeof s.showImages === "boolean" ? s.showImages : DEFAULT_ACCESSIBILITY_SETTINGS.showImages
45
+ };
46
+ };
47
+ const safeLocalStorageOperation = (operation, fallback, errorMessage) => {
48
+ try {
49
+ return operation();
50
+ } catch (error) {
51
+ console.warn(errorMessage, error);
52
+ return fallback;
53
+ }
54
+ };
55
+ const TEXT_ELEMENTS_SELECTOR = "h1, h2, h3, h4, h5, h6, p, span, a, button, label, li";
56
+ const IMAGE_ELEMENTS_SELECTOR = 'img, picture, svg[role="img"]';
57
+ const getTextElements = () => {
58
+ if (typeof document === "undefined") {
59
+ return [];
60
+ }
61
+ return document.querySelectorAll(TEXT_ELEMENTS_SELECTOR);
62
+ };
63
+ const getImageElements = () => {
64
+ if (typeof document === "undefined") {
65
+ return [];
66
+ }
67
+ return document.querySelectorAll(IMAGE_ELEMENTS_SELECTOR);
68
+ };
69
+ const applyClassToElements = (elements, className) => {
70
+ elements.forEach((element) => {
71
+ if (element && element.classList) {
72
+ element.classList.add(className);
73
+ }
74
+ });
75
+ };
76
+ const removeClassFromElements = (elements, className) => {
77
+ elements.forEach((element) => {
78
+ if (element && element.classList) {
79
+ element.classList.remove(className);
80
+ }
81
+ });
82
+ };
83
+ const safeDOMOperation = (operation, errorMessage) => {
84
+ try {
85
+ if (typeof window === "undefined") return;
86
+ operation();
87
+ } catch (error) {
88
+ console.warn(errorMessage, error);
89
+ }
90
+ };
91
+ const isDOMAvailable = () => {
92
+ return typeof window !== "undefined" && typeof document !== "undefined";
93
+ };
94
+ const ORIGINAL_FONT_SIZE_ATTR = "data-original-font-size";
95
+ const FONT_SIZE_MULTIPLIERS = {
96
+ small: 0.8,
97
+ // 80% от оригинального размера
98
+ standard: 1,
99
+ // 100% - оригинальный размер
100
+ large: 1.3
101
+ // 130% от оригинального размера
102
+ };
103
+ const getComputedFontSize = (element) => {
104
+ const computedStyle = window.getComputedStyle(element);
105
+ const fontSize = computedStyle.fontSize;
106
+ return parseFloat(fontSize);
107
+ };
108
+ const saveOriginalFontSize = (element) => {
109
+ if (!element.hasAttribute(ORIGINAL_FONT_SIZE_ATTR)) {
110
+ const originalSize = getComputedFontSize(element);
111
+ element.setAttribute(ORIGINAL_FONT_SIZE_ATTR, originalSize.toString());
112
+ }
113
+ };
114
+ const getOriginalFontSize = (element) => {
115
+ const savedSize = element.getAttribute(ORIGINAL_FONT_SIZE_ATTR);
116
+ if (savedSize) {
117
+ return parseFloat(savedSize);
118
+ }
119
+ const currentSize = getComputedFontSize(element);
120
+ element.setAttribute(ORIGINAL_FONT_SIZE_ATTR, currentSize.toString());
121
+ return currentSize;
122
+ };
123
+ const applyFontSizeToElement = (element, newSize) => {
124
+ element.style.fontSize = `${newSize}px`;
125
+ };
126
+ const resetElementFontSize = (element) => {
127
+ element.style.fontSize = "";
128
+ element.removeAttribute(ORIGINAL_FONT_SIZE_ATTR);
129
+ };
130
+ const applyDynamicFontSize = (size) => {
131
+ safeDOMOperation(() => {
132
+ if (!isDOMAvailable()) return;
133
+ const elements = getTextElements();
134
+ const multiplier = FONT_SIZE_MULTIPLIERS[size];
135
+ elements.forEach((element) => {
136
+ try {
137
+ if (size === "standard") {
138
+ resetElementFontSize(element);
139
+ } else {
140
+ saveOriginalFontSize(element);
141
+ const originalSize = getOriginalFontSize(element);
142
+ const newSize = originalSize * multiplier;
143
+ applyFontSizeToElement(element, newSize);
144
+ }
145
+ } catch (error) {
146
+ console.warn("Ошибка при изменении размера шрифта элемента:", element, error);
147
+ }
148
+ });
149
+ }, `Ошибка при применении динамического размера шрифта: ${size}`);
150
+ };
151
+ const resetAllFontSizes = () => {
152
+ safeDOMOperation(() => {
153
+ if (!isDOMAvailable()) return;
154
+ const elements = getTextElements();
155
+ elements.forEach((element) => {
156
+ try {
157
+ resetElementFontSize(element);
158
+ } catch (error) {
159
+ console.warn("Ошибка при сбросе размера шрифта элемента:", element, error);
160
+ }
161
+ });
162
+ }, "Ошибка при сбросе всех размеров шрифта");
163
+ };
164
+ const updateNewElementsFontSize = (size) => {
165
+ if (size === "standard") return;
166
+ safeDOMOperation(() => {
167
+ if (!isDOMAvailable()) return;
168
+ const elements = getTextElements();
169
+ const multiplier = FONT_SIZE_MULTIPLIERS[size];
170
+ elements.forEach((element) => {
171
+ if (!element.hasAttribute(ORIGINAL_FONT_SIZE_ATTR) && !element.style.fontSize) {
172
+ try {
173
+ saveOriginalFontSize(element);
174
+ const originalSize = getOriginalFontSize(element);
175
+ const newSize = originalSize * multiplier;
176
+ applyFontSizeToElement(element, newSize);
177
+ } catch (error) {
178
+ console.warn("Ошибка при обновлении размера шрифта нового элемента:", element, error);
179
+ }
180
+ }
181
+ });
182
+ }, `Ошибка при обновлении размера шрифта новых элементов: ${size}`);
183
+ };
184
+ const isFontSizeModified = () => {
185
+ if (!isDOMAvailable()) return false;
186
+ const elements = getTextElements();
187
+ for (let i = 0; i < Math.min(elements.length, 10); i++) {
188
+ if (elements[i].hasAttribute(ORIGINAL_FONT_SIZE_ATTR)) {
189
+ return true;
190
+ }
191
+ }
192
+ return false;
193
+ };
194
+ const CSS_CLASSES = {
195
+ HIGH_CONTRAST: "accessibility-high-contrast",
196
+ FONT_SMALL: "accessibility-font-small",
197
+ FONT_LARGE: "accessibility-font-large",
198
+ HIDE_IMAGES: "accessibility-hide-images"
199
+ };
200
+ const applyColorScheme = (scheme) => {
201
+ safeDOMOperation(() => {
202
+ if (!isDOMAvailable()) return;
203
+ document.body.classList.remove(CSS_CLASSES.HIGH_CONTRAST);
204
+ document.body.style.filter = "";
205
+ switch (scheme) {
206
+ case "high-contrast":
207
+ document.body.classList.add(CSS_CLASSES.HIGH_CONTRAST);
208
+ break;
209
+ case "grayscale":
210
+ document.body.style.filter = "grayscale(100%)";
211
+ break;
212
+ case "standard":
213
+ break;
214
+ default:
215
+ console.warn(`Неизвестная цветовая схема: ${scheme}`);
216
+ break;
217
+ }
218
+ }, `Ошибка при применении цветовой схемы: ${scheme}`);
219
+ };
220
+ const applyFontSize = (size) => {
221
+ applyDynamicFontSize(size);
222
+ };
223
+ const applyImageVisibility = (showImages) => {
224
+ safeDOMOperation(() => {
225
+ if (!isDOMAvailable()) return;
226
+ const elements = getImageElements();
227
+ if (showImages) {
228
+ removeClassFromElements(elements, CSS_CLASSES.HIDE_IMAGES);
229
+ } else {
230
+ applyClassToElements(elements, CSS_CLASSES.HIDE_IMAGES);
231
+ }
232
+ }, `Ошибка при управлении отображением изображений: ${showImages}`);
233
+ };
234
+ const removeAllAccessibilityStyles = () => {
235
+ safeDOMOperation(() => {
236
+ if (!isDOMAvailable()) return;
237
+ document.body.classList.remove(CSS_CLASSES.HIGH_CONTRAST);
238
+ document.body.classList.remove(CSS_CLASSES.FONT_SMALL);
239
+ document.body.classList.remove(CSS_CLASSES.FONT_LARGE);
240
+ document.body.style.filter = "";
241
+ resetAllFontSizes();
242
+ const imageElements = getImageElements();
243
+ removeClassFromElements(imageElements, CSS_CLASSES.HIDE_IMAGES);
244
+ }, "Ошибка при удалении всех стилей доступности");
245
+ };
246
+ const applyAllSettings = (settings) => {
247
+ if (!settings.isEnabled) {
248
+ removeAllAccessibilityStyles();
249
+ return;
250
+ }
251
+ applyColorScheme(settings.colorScheme);
252
+ applyFontSize(settings.fontSize);
253
+ applyImageVisibility(settings.showImages);
254
+ };
255
+ const applySettingIfEnabled = (isEnabled, settingType, value) => {
256
+ if (!isEnabled) {
257
+ return;
258
+ }
259
+ switch (settingType) {
260
+ case "colorScheme":
261
+ applyColorScheme(value);
262
+ break;
263
+ case "fontSize":
264
+ applyFontSize(value);
265
+ break;
266
+ case "imageVisibility":
267
+ applyImageVisibility(value);
268
+ break;
269
+ default:
270
+ console.warn(`Неизвестный тип настройки: ${settingType}`);
271
+ }
272
+ };
273
+ const useAccessibilitySettings = () => {
274
+ const [settings, setSettings] = useState(DEFAULT_ACCESSIBILITY_SETTINGS);
275
+ const [isLoaded, setIsLoaded] = useState(false);
276
+ useEffect(() => {
277
+ if (typeof window === "undefined" || !isLoaded || !settings.isEnabled) return;
278
+ const observer = new MutationObserver((mutations) => {
279
+ let hasNewTextElements = false;
280
+ mutations.forEach((mutation) => {
281
+ if (mutation.type === "childList") {
282
+ mutation.addedNodes.forEach((node) => {
283
+ if (node.nodeType === Node.ELEMENT_NODE) {
284
+ const element = node;
285
+ if (element.matches("h1, h2, h3, h4, h5, h6, p, span, a, button, label, li, div") || element.querySelector("h1, h2, h3, h4, h5, h6, p, span, a, button, label, li, div")) {
286
+ hasNewTextElements = true;
287
+ }
288
+ }
289
+ });
290
+ }
291
+ });
292
+ if (hasNewTextElements && settings.fontSize !== "standard") {
293
+ setTimeout(() => {
294
+ updateNewElementsFontSize(settings.fontSize);
295
+ }, 100);
296
+ }
297
+ });
298
+ observer.observe(document.body, {
299
+ childList: true,
300
+ subtree: true
301
+ });
302
+ return () => {
303
+ observer.disconnect();
304
+ };
305
+ }, [isLoaded, settings.isEnabled, settings.fontSize]);
306
+ useEffect(() => {
307
+ if (typeof window === "undefined") {
308
+ return;
309
+ }
310
+ try {
311
+ const savedSettings = loadFromStorage();
312
+ if (savedSettings) {
313
+ setSettings(savedSettings);
314
+ if (savedSettings.isEnabled) {
315
+ applyAllSettings(savedSettings);
316
+ }
317
+ }
318
+ } catch (error) {
319
+ console.warn("Ошибка при загрузке настроек доступности:", error);
320
+ setSettings(DEFAULT_ACCESSIBILITY_SETTINGS);
321
+ } finally {
322
+ setIsLoaded(true);
323
+ }
324
+ }, []);
325
+ useEffect(() => {
326
+ if (!isLoaded) {
327
+ return;
328
+ }
329
+ try {
330
+ saveToStorage(settings);
331
+ if (settings.isEnabled) {
332
+ applyAllSettings(settings);
333
+ } else {
334
+ removeAllAccessibilityStyles();
335
+ }
336
+ } catch (error) {
337
+ console.warn("Ошибка при сохранении настроек доступности:", error);
338
+ }
339
+ }, [settings, isLoaded]);
340
+ const updateSettings = useCallback((updates) => {
341
+ setSettings((prevSettings) => {
342
+ const newSettings = { ...prevSettings, ...updates };
343
+ if (prevSettings.isEnabled && !newSettings.isEnabled) {
344
+ removeAllAccessibilityStyles();
345
+ }
346
+ return newSettings;
347
+ });
348
+ }, []);
349
+ const resetSettings = useCallback(() => {
350
+ try {
351
+ removeAllAccessibilityStyles();
352
+ setSettings(DEFAULT_ACCESSIBILITY_SETTINGS);
353
+ clearStorage();
354
+ } catch (error) {
355
+ console.warn("Ошибка при сбросе настроек доступности:", error);
356
+ }
357
+ }, []);
358
+ return {
359
+ settings,
360
+ updateSettings,
361
+ resetSettings,
362
+ isLoaded
363
+ };
364
+ };
365
+ const useAccessibilitySetting = (settingKey) => {
366
+ const { settings, updateSettings } = useAccessibilitySettings();
367
+ const setValue = useCallback((value) => {
368
+ updateSettings({ [settingKey]: value });
369
+ }, [settingKey, updateSettings]);
370
+ return [settings[settingKey], setValue];
371
+ };
372
+ const useAccessibilityToggle = () => {
373
+ const { settings, updateSettings } = useAccessibilitySettings();
374
+ const setEnabled = useCallback((enabled) => {
375
+ updateSettings({ isEnabled: enabled });
376
+ }, [updateSettings]);
377
+ return [settings.isEnabled, setEnabled];
378
+ };
379
+ var jsxRuntime = { exports: {} };
380
+ var reactJsxRuntime_production = {};
381
+ /**
382
+ * @license React
383
+ * react-jsx-runtime.production.js
384
+ *
385
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
386
+ *
387
+ * This source code is licensed under the MIT license found in the
388
+ * LICENSE file in the root directory of this source tree.
389
+ */
390
+ var hasRequiredReactJsxRuntime_production;
391
+ function requireReactJsxRuntime_production() {
392
+ if (hasRequiredReactJsxRuntime_production) return reactJsxRuntime_production;
393
+ hasRequiredReactJsxRuntime_production = 1;
394
+ var REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment");
395
+ function jsxProd(type, config, maybeKey) {
396
+ var key = null;
397
+ void 0 !== maybeKey && (key = "" + maybeKey);
398
+ void 0 !== config.key && (key = "" + config.key);
399
+ if ("key" in config) {
400
+ maybeKey = {};
401
+ for (var propName in config)
402
+ "key" !== propName && (maybeKey[propName] = config[propName]);
403
+ } else maybeKey = config;
404
+ config = maybeKey.ref;
405
+ return {
406
+ $$typeof: REACT_ELEMENT_TYPE,
407
+ type,
408
+ key,
409
+ ref: void 0 !== config ? config : null,
410
+ props: maybeKey
411
+ };
412
+ }
413
+ reactJsxRuntime_production.Fragment = REACT_FRAGMENT_TYPE;
414
+ reactJsxRuntime_production.jsx = jsxProd;
415
+ reactJsxRuntime_production.jsxs = jsxProd;
416
+ return reactJsxRuntime_production;
417
+ }
418
+ var reactJsxRuntime_development = {};
419
+ /**
420
+ * @license React
421
+ * react-jsx-runtime.development.js
422
+ *
423
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
424
+ *
425
+ * This source code is licensed under the MIT license found in the
426
+ * LICENSE file in the root directory of this source tree.
427
+ */
428
+ var hasRequiredReactJsxRuntime_development;
429
+ function requireReactJsxRuntime_development() {
430
+ if (hasRequiredReactJsxRuntime_development) return reactJsxRuntime_development;
431
+ hasRequiredReactJsxRuntime_development = 1;
432
+ "production" !== process.env.NODE_ENV && function() {
433
+ function getComponentNameFromType(type) {
434
+ if (null == type) return null;
435
+ if ("function" === typeof type)
436
+ return type.$$typeof === REACT_CLIENT_REFERENCE ? null : type.displayName || type.name || null;
437
+ if ("string" === typeof type) return type;
438
+ switch (type) {
439
+ case REACT_FRAGMENT_TYPE:
440
+ return "Fragment";
441
+ case REACT_PROFILER_TYPE:
442
+ return "Profiler";
443
+ case REACT_STRICT_MODE_TYPE:
444
+ return "StrictMode";
445
+ case REACT_SUSPENSE_TYPE:
446
+ return "Suspense";
447
+ case REACT_SUSPENSE_LIST_TYPE:
448
+ return "SuspenseList";
449
+ case REACT_ACTIVITY_TYPE:
450
+ return "Activity";
451
+ }
452
+ if ("object" === typeof type)
453
+ switch ("number" === typeof type.tag && console.error(
454
+ "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
455
+ ), type.$$typeof) {
456
+ case REACT_PORTAL_TYPE:
457
+ return "Portal";
458
+ case REACT_CONTEXT_TYPE:
459
+ return type.displayName || "Context";
460
+ case REACT_CONSUMER_TYPE:
461
+ return (type._context.displayName || "Context") + ".Consumer";
462
+ case REACT_FORWARD_REF_TYPE:
463
+ var innerType = type.render;
464
+ type = type.displayName;
465
+ type || (type = innerType.displayName || innerType.name || "", type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef");
466
+ return type;
467
+ case REACT_MEMO_TYPE:
468
+ return innerType = type.displayName || null, null !== innerType ? innerType : getComponentNameFromType(type.type) || "Memo";
469
+ case REACT_LAZY_TYPE:
470
+ innerType = type._payload;
471
+ type = type._init;
472
+ try {
473
+ return getComponentNameFromType(type(innerType));
474
+ } catch (x) {
475
+ }
476
+ }
477
+ return null;
478
+ }
479
+ function testStringCoercion(value) {
480
+ return "" + value;
481
+ }
482
+ function checkKeyStringCoercion(value) {
483
+ try {
484
+ testStringCoercion(value);
485
+ var JSCompiler_inline_result = false;
486
+ } catch (e) {
487
+ JSCompiler_inline_result = true;
488
+ }
489
+ if (JSCompiler_inline_result) {
490
+ JSCompiler_inline_result = console;
491
+ var JSCompiler_temp_const = JSCompiler_inline_result.error;
492
+ var JSCompiler_inline_result$jscomp$0 = "function" === typeof Symbol && Symbol.toStringTag && value[Symbol.toStringTag] || value.constructor.name || "Object";
493
+ JSCompiler_temp_const.call(
494
+ JSCompiler_inline_result,
495
+ "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
496
+ JSCompiler_inline_result$jscomp$0
497
+ );
498
+ return testStringCoercion(value);
499
+ }
500
+ }
501
+ function getTaskName(type) {
502
+ if (type === REACT_FRAGMENT_TYPE) return "<>";
503
+ if ("object" === typeof type && null !== type && type.$$typeof === REACT_LAZY_TYPE)
504
+ return "<...>";
505
+ try {
506
+ var name = getComponentNameFromType(type);
507
+ return name ? "<" + name + ">" : "<...>";
508
+ } catch (x) {
509
+ return "<...>";
510
+ }
511
+ }
512
+ function getOwner() {
513
+ var dispatcher = ReactSharedInternals.A;
514
+ return null === dispatcher ? null : dispatcher.getOwner();
515
+ }
516
+ function UnknownOwner() {
517
+ return Error("react-stack-top-frame");
518
+ }
519
+ function hasValidKey(config) {
520
+ if (hasOwnProperty.call(config, "key")) {
521
+ var getter = Object.getOwnPropertyDescriptor(config, "key").get;
522
+ if (getter && getter.isReactWarning) return false;
523
+ }
524
+ return void 0 !== config.key;
525
+ }
526
+ function defineKeyPropWarningGetter(props, displayName) {
527
+ function warnAboutAccessingKey() {
528
+ specialPropKeyWarningShown || (specialPropKeyWarningShown = true, console.error(
529
+ "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
530
+ displayName
531
+ ));
532
+ }
533
+ warnAboutAccessingKey.isReactWarning = true;
534
+ Object.defineProperty(props, "key", {
535
+ get: warnAboutAccessingKey,
536
+ configurable: true
537
+ });
538
+ }
539
+ function elementRefGetterWithDeprecationWarning() {
540
+ var componentName = getComponentNameFromType(this.type);
541
+ didWarnAboutElementRef[componentName] || (didWarnAboutElementRef[componentName] = true, console.error(
542
+ "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
543
+ ));
544
+ componentName = this.props.ref;
545
+ return void 0 !== componentName ? componentName : null;
546
+ }
547
+ function ReactElement(type, key, props, owner, debugStack, debugTask) {
548
+ var refProp = props.ref;
549
+ type = {
550
+ $$typeof: REACT_ELEMENT_TYPE,
551
+ type,
552
+ key,
553
+ props,
554
+ _owner: owner
555
+ };
556
+ null !== (void 0 !== refProp ? refProp : null) ? Object.defineProperty(type, "ref", {
557
+ enumerable: false,
558
+ get: elementRefGetterWithDeprecationWarning
559
+ }) : Object.defineProperty(type, "ref", { enumerable: false, value: null });
560
+ type._store = {};
561
+ Object.defineProperty(type._store, "validated", {
562
+ configurable: false,
563
+ enumerable: false,
564
+ writable: true,
565
+ value: 0
566
+ });
567
+ Object.defineProperty(type, "_debugInfo", {
568
+ configurable: false,
569
+ enumerable: false,
570
+ writable: true,
571
+ value: null
572
+ });
573
+ Object.defineProperty(type, "_debugStack", {
574
+ configurable: false,
575
+ enumerable: false,
576
+ writable: true,
577
+ value: debugStack
578
+ });
579
+ Object.defineProperty(type, "_debugTask", {
580
+ configurable: false,
581
+ enumerable: false,
582
+ writable: true,
583
+ value: debugTask
584
+ });
585
+ Object.freeze && (Object.freeze(type.props), Object.freeze(type));
586
+ return type;
587
+ }
588
+ function jsxDEVImpl(type, config, maybeKey, isStaticChildren, debugStack, debugTask) {
589
+ var children = config.children;
590
+ if (void 0 !== children)
591
+ if (isStaticChildren)
592
+ if (isArrayImpl(children)) {
593
+ for (isStaticChildren = 0; isStaticChildren < children.length; isStaticChildren++)
594
+ validateChildKeys(children[isStaticChildren]);
595
+ Object.freeze && Object.freeze(children);
596
+ } else
597
+ console.error(
598
+ "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
599
+ );
600
+ else validateChildKeys(children);
601
+ if (hasOwnProperty.call(config, "key")) {
602
+ children = getComponentNameFromType(type);
603
+ var keys = Object.keys(config).filter(function(k) {
604
+ return "key" !== k;
605
+ });
606
+ isStaticChildren = 0 < keys.length ? "{key: someKey, " + keys.join(": ..., ") + ": ...}" : "{key: someKey}";
607
+ didWarnAboutKeySpread[children + isStaticChildren] || (keys = 0 < keys.length ? "{" + keys.join(": ..., ") + ": ...}" : "{}", console.error(
608
+ 'A props object containing a "key" prop is being spread into JSX:\n let props = %s;\n <%s {...props} />\nReact keys must be passed directly to JSX without using spread:\n let props = %s;\n <%s key={someKey} {...props} />',
609
+ isStaticChildren,
610
+ children,
611
+ keys,
612
+ children
613
+ ), didWarnAboutKeySpread[children + isStaticChildren] = true);
614
+ }
615
+ children = null;
616
+ void 0 !== maybeKey && (checkKeyStringCoercion(maybeKey), children = "" + maybeKey);
617
+ hasValidKey(config) && (checkKeyStringCoercion(config.key), children = "" + config.key);
618
+ if ("key" in config) {
619
+ maybeKey = {};
620
+ for (var propName in config)
621
+ "key" !== propName && (maybeKey[propName] = config[propName]);
622
+ } else maybeKey = config;
623
+ children && defineKeyPropWarningGetter(
624
+ maybeKey,
625
+ "function" === typeof type ? type.displayName || type.name || "Unknown" : type
626
+ );
627
+ return ReactElement(
628
+ type,
629
+ children,
630
+ maybeKey,
631
+ getOwner(),
632
+ debugStack,
633
+ debugTask
634
+ );
635
+ }
636
+ function validateChildKeys(node) {
637
+ isValidElement(node) ? node._store && (node._store.validated = 1) : "object" === typeof node && null !== node && node.$$typeof === REACT_LAZY_TYPE && ("fulfilled" === node._payload.status ? isValidElement(node._payload.value) && node._payload.value._store && (node._payload.value._store.validated = 1) : node._store && (node._store.validated = 1));
638
+ }
639
+ function isValidElement(object) {
640
+ return "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE;
641
+ }
642
+ var React = require$$0, REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = Symbol.for("react.activity"), REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty = Object.prototype.hasOwnProperty, isArrayImpl = Array.isArray, createTask = console.createTask ? console.createTask : function() {
643
+ return null;
644
+ };
645
+ React = {
646
+ react_stack_bottom_frame: function(callStackForError) {
647
+ return callStackForError();
648
+ }
649
+ };
650
+ var specialPropKeyWarningShown;
651
+ var didWarnAboutElementRef = {};
652
+ var unknownOwnerDebugStack = React.react_stack_bottom_frame.bind(
653
+ React,
654
+ UnknownOwner
655
+ )();
656
+ var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
657
+ var didWarnAboutKeySpread = {};
658
+ reactJsxRuntime_development.Fragment = REACT_FRAGMENT_TYPE;
659
+ reactJsxRuntime_development.jsx = function(type, config, maybeKey) {
660
+ var trackActualOwner = 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
661
+ return jsxDEVImpl(
662
+ type,
663
+ config,
664
+ maybeKey,
665
+ false,
666
+ trackActualOwner ? Error("react-stack-top-frame") : unknownOwnerDebugStack,
667
+ trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask
668
+ );
669
+ };
670
+ reactJsxRuntime_development.jsxs = function(type, config, maybeKey) {
671
+ var trackActualOwner = 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
672
+ return jsxDEVImpl(
673
+ type,
674
+ config,
675
+ maybeKey,
676
+ true,
677
+ trackActualOwner ? Error("react-stack-top-frame") : unknownOwnerDebugStack,
678
+ trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask
679
+ );
680
+ };
681
+ }();
682
+ return reactJsxRuntime_development;
683
+ }
684
+ if (process.env.NODE_ENV === "production") {
685
+ jsxRuntime.exports = requireReactJsxRuntime_production();
686
+ } else {
687
+ jsxRuntime.exports = requireReactJsxRuntime_development();
688
+ }
689
+ var jsxRuntimeExports = jsxRuntime.exports;
690
+ const AccessibilityContext = createContext(null);
691
+ const AccessibilityProvider = ({ children }) => {
692
+ const accessibilityState = useAccessibilitySettings();
693
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(AccessibilityContext.Provider, { value: accessibilityState, children });
694
+ };
695
+ const useAccessibilityContext = () => {
696
+ const context = useContext(AccessibilityContext);
697
+ if (!context) {
698
+ throw new Error("useAccessibilityContext должен использоваться внутри AccessibilityProvider");
699
+ }
700
+ return context;
701
+ };
702
+ const accessibilityToggle = "_accessibilityToggle_jwfla_9";
703
+ const toggleContainer = "_toggleContainer_jwfla_15";
704
+ const toggleLabel = "_toggleLabel_jwfla_21";
705
+ const toggleInput = "_toggleInput_jwfla_42";
706
+ const toggleSlider = "_toggleSlider_jwfla_49";
707
+ const toggleThumb = "_toggleThumb_jwfla_55";
708
+ const toggleContent = "_toggleContent_jwfla_81";
709
+ const toggleTitle = "_toggleTitle_jwfla_88";
710
+ const toggleStatus = "_toggleStatus_jwfla_95";
711
+ const description$2 = "_description_jwfla_102";
712
+ const styles$4 = {
713
+ accessibilityToggle,
714
+ toggleContainer,
715
+ toggleLabel,
716
+ toggleInput,
717
+ toggleSlider,
718
+ toggleThumb,
719
+ toggleContent,
720
+ toggleTitle,
721
+ toggleStatus,
722
+ description: description$2
723
+ };
724
+ const AccessibilityToggle = ({
725
+ className
726
+ }) => {
727
+ const { settings, updateSettings } = useAccessibilityContext();
728
+ const isEnabled = settings.isEnabled;
729
+ const handleToggleChange = (event) => {
730
+ updateSettings({ isEnabled: event.target.checked });
731
+ };
732
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `${styles$4.accessibilityToggle} ${className || ""}`, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: styles$4.toggleContainer, children: [
733
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: styles$4.toggleLabel, children: [
734
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
735
+ "input",
736
+ {
737
+ type: "checkbox",
738
+ checked: isEnabled,
739
+ onChange: handleToggleChange,
740
+ className: styles$4.toggleInput,
741
+ "aria-describedby": "accessibility-toggle-description"
742
+ }
743
+ ),
744
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: styles$4.toggleSlider, "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: styles$4.toggleThumb }) }),
745
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: styles$4.toggleContent, children: [
746
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: styles$4.toggleTitle, children: "Режим доступности" }),
747
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: styles$4.toggleStatus, children: isEnabled ? "Включен" : "Выключен" })
748
+ ] })
749
+ ] }),
750
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
751
+ "p",
752
+ {
753
+ id: "accessibility-toggle-description",
754
+ className: styles$4.description,
755
+ children: isEnabled ? "Все настройки доступности активны. Используйте элементы управления ниже для точной настройки." : "Включите режим доступности для активации всех настроек. При выключении все изменения будут сброшены."
756
+ }
757
+ )
758
+ ] }) });
759
+ };
760
+ const colorSchemeControl = "_colorSchemeControl_tkb2w_9";
761
+ const disabled$2 = "_disabled_tkb2w_12";
762
+ const title$3 = "_title_tkb2w_12";
763
+ const optionsContainer$1 = "_optionsContainer_tkb2w_23";
764
+ const option$1 = "_option_tkb2w_23";
765
+ const selected$1 = "_selected_tkb2w_50";
766
+ const radioIndicator$1 = "_radioIndicator_tkb2w_54";
767
+ const optionDisabled$1 = "_optionDisabled_tkb2w_62";
768
+ const radioInput$1 = "_radioInput_tkb2w_72";
769
+ const optionContent$1 = "_optionContent_tkb2w_79";
770
+ const optionLabel$1 = "_optionLabel_tkb2w_91";
771
+ const optionDescription$1 = "_optionDescription_tkb2w_98";
772
+ const styles$3 = {
773
+ colorSchemeControl,
774
+ disabled: disabled$2,
775
+ title: title$3,
776
+ optionsContainer: optionsContainer$1,
777
+ option: option$1,
778
+ selected: selected$1,
779
+ radioIndicator: radioIndicator$1,
780
+ optionDisabled: optionDisabled$1,
781
+ radioInput: radioInput$1,
782
+ optionContent: optionContent$1,
783
+ optionLabel: optionLabel$1,
784
+ optionDescription: optionDescription$1
785
+ };
786
+ const COLOR_SCHEME_OPTIONS = [
787
+ {
788
+ value: "standard",
789
+ label: "Стандартный",
790
+ description: "Обычная цветовая схема сайта"
791
+ },
792
+ {
793
+ value: "high-contrast",
794
+ label: "Контрастный белый на черном",
795
+ description: "Высококонтрастная схема для лучшей читаемости"
796
+ },
797
+ {
798
+ value: "grayscale",
799
+ label: "Черно-белый",
800
+ description: "Преобразование всех цветов в оттенки серого"
801
+ }
802
+ ];
803
+ const ColorSchemeControl = ({
804
+ className
805
+ }) => {
806
+ const { settings, updateSettings } = useAccessibilityContext();
807
+ const colorScheme = settings.colorScheme;
808
+ const isEnabled = settings.isEnabled;
809
+ const handleColorSchemeChange = (event) => {
810
+ const newColorScheme = event.target.value;
811
+ updateSettings({ colorScheme: newColorScheme });
812
+ };
813
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `${styles$3.colorSchemeControl} ${className || ""} ${!isEnabled ? styles$3.disabled : ""}`, children: [
814
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: styles$3.title, children: "Цветовая схема" }),
815
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: styles$3.optionsContainer, role: "radiogroup", "aria-labelledby": "color-scheme-title", children: COLOR_SCHEME_OPTIONS.map((option2) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
816
+ "label",
817
+ {
818
+ className: `${styles$3.option} ${colorScheme === option2.value ? styles$3.selected : ""} ${!isEnabled ? styles$3.optionDisabled : ""}`,
819
+ children: [
820
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
821
+ "input",
822
+ {
823
+ type: "radio",
824
+ name: "colorScheme",
825
+ value: option2.value,
826
+ checked: colorScheme === option2.value,
827
+ onChange: handleColorSchemeChange,
828
+ className: styles$3.radioInput,
829
+ "aria-describedby": `color-scheme-${option2.value}-description`,
830
+ disabled: !isEnabled
831
+ }
832
+ ),
833
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: styles$3.optionContent, children: [
834
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: styles$3.optionLabel, children: option2.label }),
835
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
836
+ "span",
837
+ {
838
+ id: `color-scheme-${option2.value}-description`,
839
+ className: styles$3.optionDescription,
840
+ children: option2.description
841
+ }
842
+ )
843
+ ] }),
844
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: styles$3.radioIndicator, "aria-hidden": "true" })
845
+ ]
846
+ },
847
+ option2.value
848
+ )) })
849
+ ] });
850
+ };
851
+ const fontSizeControl = "_fontSizeControl_xe2rx_9";
852
+ const disabled$1 = "_disabled_xe2rx_12";
853
+ const title$2 = "_title_xe2rx_12";
854
+ const optionsContainer = "_optionsContainer_xe2rx_23";
855
+ const option = "_option_xe2rx_23";
856
+ const selected = "_selected_xe2rx_50";
857
+ const radioIndicator = "_radioIndicator_xe2rx_54";
858
+ const optionDisabled = "_optionDisabled_xe2rx_62";
859
+ const radioInput = "_radioInput_xe2rx_72";
860
+ const optionContent = "_optionContent_xe2rx_79";
861
+ const optionLabel = "_optionLabel_xe2rx_91";
862
+ const optionDescription = "_optionDescription_xe2rx_98";
863
+ const styles$2 = {
864
+ fontSizeControl,
865
+ disabled: disabled$1,
866
+ title: title$2,
867
+ optionsContainer,
868
+ option,
869
+ selected,
870
+ radioIndicator,
871
+ optionDisabled,
872
+ radioInput,
873
+ optionContent,
874
+ optionLabel,
875
+ optionDescription
876
+ };
877
+ const FONT_SIZE_OPTIONS = [
878
+ {
879
+ value: "small",
880
+ label: "Мелкий",
881
+ description: "Уменьшенный размер текста (80%)"
882
+ },
883
+ {
884
+ value: "standard",
885
+ label: "Стандартный",
886
+ description: "Обычный размер текста"
887
+ },
888
+ {
889
+ value: "large",
890
+ label: "Крупный",
891
+ description: "Увеличенный размер текста (130%)"
892
+ }
893
+ ];
894
+ const FontSizeControl = ({
895
+ className
896
+ }) => {
897
+ const { settings, updateSettings } = useAccessibilityContext();
898
+ const fontSize = settings.fontSize;
899
+ const isEnabled = settings.isEnabled;
900
+ const handleFontSizeChange = (event) => {
901
+ const newFontSize = event.target.value;
902
+ updateSettings({ fontSize: newFontSize });
903
+ };
904
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `${styles$2.fontSizeControl} ${className || ""} ${!isEnabled ? styles$2.disabled : ""}`, children: [
905
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: styles$2.title, children: "Размер шрифта" }),
906
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: styles$2.optionsContainer, role: "radiogroup", "aria-labelledby": "font-size-title", children: FONT_SIZE_OPTIONS.map((option2) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
907
+ "label",
908
+ {
909
+ className: `${styles$2.option} ${fontSize === option2.value ? styles$2.selected : ""} ${!isEnabled ? styles$2.optionDisabled : ""}`,
910
+ children: [
911
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
912
+ "input",
913
+ {
914
+ type: "radio",
915
+ name: "fontSize",
916
+ value: option2.value,
917
+ checked: fontSize === option2.value,
918
+ onChange: handleFontSizeChange,
919
+ className: styles$2.radioInput,
920
+ "aria-describedby": `font-size-${option2.value}-description`,
921
+ disabled: !isEnabled
922
+ }
923
+ ),
924
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: styles$2.optionContent, children: [
925
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: styles$2.optionLabel, children: option2.label }),
926
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
927
+ "span",
928
+ {
929
+ id: `font-size-${option2.value}-description`,
930
+ className: styles$2.optionDescription,
931
+ children: option2.description
932
+ }
933
+ )
934
+ ] }),
935
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: styles$2.radioIndicator, "aria-hidden": "true" })
936
+ ]
937
+ },
938
+ option2.value
939
+ )) })
940
+ ] });
941
+ };
942
+ const imageControl = "_imageControl_rczak_9";
943
+ const disabled = "_disabled_rczak_12";
944
+ const title$1 = "_title_rczak_12";
945
+ const switchContainer = "_switchContainer_rczak_23";
946
+ const switchLabel = "_switchLabel_rczak_29";
947
+ const switchDisabled = "_switchDisabled_rczak_49";
948
+ const switchInput = "_switchInput_rczak_59";
949
+ const switchSlider = "_switchSlider_rczak_66";
950
+ const switchThumb = "_switchThumb_rczak_72";
951
+ const switchText = "_switchText_rczak_98";
952
+ const description$1 = "_description_rczak_106";
953
+ const styles$1 = {
954
+ imageControl,
955
+ disabled,
956
+ title: title$1,
957
+ switchContainer,
958
+ switchLabel,
959
+ switchDisabled,
960
+ switchInput,
961
+ switchSlider,
962
+ switchThumb,
963
+ switchText,
964
+ description: description$1
965
+ };
966
+ const ImageControl = ({
967
+ className
968
+ }) => {
969
+ const { settings, updateSettings } = useAccessibilityContext();
970
+ const showImages = settings.showImages;
971
+ const isEnabled = settings.isEnabled;
972
+ const handleImageVisibilityChange = (event) => {
973
+ updateSettings({ showImages: event.target.checked });
974
+ };
975
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `${styles$1.imageControl} ${className || ""} ${!isEnabled ? styles$1.disabled : ""}`, children: [
976
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: styles$1.title, children: "Изображения" }),
977
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: styles$1.switchContainer, children: [
978
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: `${styles$1.switchLabel} ${!isEnabled ? styles$1.switchDisabled : ""}`, children: [
979
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
980
+ "input",
981
+ {
982
+ type: "checkbox",
983
+ checked: showImages,
984
+ onChange: handleImageVisibilityChange,
985
+ className: styles$1.switchInput,
986
+ "aria-describedby": "image-control-description",
987
+ disabled: !isEnabled
988
+ }
989
+ ),
990
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: styles$1.switchSlider, "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: styles$1.switchThumb }) }),
991
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: styles$1.switchText, children: showImages ? "Показывать изображения" : "Скрывать изображения" })
992
+ ] }),
993
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
994
+ "p",
995
+ {
996
+ id: "image-control-description",
997
+ className: styles$1.description,
998
+ children: showImages ? "Изображения отображаются на странице" : "Изображения скрыты для лучшей концентрации на тексте"
999
+ }
1000
+ )
1001
+ ] })
1002
+ ] });
1003
+ };
1004
+ const stickyContainer = "_stickyContainer_1xqyi_9";
1005
+ const panel = "_panel_1xqyi_23";
1006
+ const topRight = "_topRight_1xqyi_38";
1007
+ const topLeft = "_topLeft_1xqyi_42";
1008
+ const header = "_header_1xqyi_59";
1009
+ const title = "_title_1xqyi_68";
1010
+ const closeButton = "_closeButton_1xqyi_76";
1011
+ const description = "_description_1xqyi_107";
1012
+ const content = "_content_1xqyi_115";
1013
+ const controls = "_controls_1xqyi_135";
1014
+ const slideIn = "_slideIn_1xqyi_1";
1015
+ const styles = {
1016
+ stickyContainer,
1017
+ panel,
1018
+ topRight,
1019
+ topLeft,
1020
+ header,
1021
+ title,
1022
+ closeButton,
1023
+ description,
1024
+ content,
1025
+ controls,
1026
+ slideIn
1027
+ };
1028
+ const AccessibilityPanelInner = ({
1029
+ isOpen,
1030
+ onClose,
1031
+ position = "top-right"
1032
+ }) => {
1033
+ const panelRef = useRef(null);
1034
+ useEffect(() => {
1035
+ if (!isOpen) return;
1036
+ const handleClickOutside = (event) => {
1037
+ if (panelRef.current && !panelRef.current.contains(event.target)) {
1038
+ onClose();
1039
+ }
1040
+ };
1041
+ const timeoutId = setTimeout(() => {
1042
+ document.addEventListener("mousedown", handleClickOutside);
1043
+ }, 100);
1044
+ return () => {
1045
+ clearTimeout(timeoutId);
1046
+ document.removeEventListener("mousedown", handleClickOutside);
1047
+ };
1048
+ }, [isOpen, onClose]);
1049
+ useEffect(() => {
1050
+ if (!isOpen) return;
1051
+ const handleEscapeKey = (event) => {
1052
+ if (event.key === "Escape") {
1053
+ onClose();
1054
+ }
1055
+ };
1056
+ document.addEventListener("keydown", handleEscapeKey);
1057
+ return () => {
1058
+ document.removeEventListener("keydown", handleEscapeKey);
1059
+ };
1060
+ }, [isOpen, onClose]);
1061
+ const handleCloseClick = (event) => {
1062
+ event.preventDefault();
1063
+ event.stopPropagation();
1064
+ onClose();
1065
+ };
1066
+ if (!isOpen) {
1067
+ return null;
1068
+ }
1069
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `${styles.stickyContainer} accessibility-panel-container`, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
1070
+ "div",
1071
+ {
1072
+ ref: panelRef,
1073
+ className: `${styles.panel} ${styles[position]}`,
1074
+ role: "dialog",
1075
+ "aria-modal": "true",
1076
+ "aria-labelledby": "accessibility-panel-title",
1077
+ "aria-describedby": "accessibility-panel-description",
1078
+ children: [
1079
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: styles.header, children: [
1080
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { id: "accessibility-panel-title", className: styles.title, children: "Настройки доступности" }),
1081
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1082
+ "button",
1083
+ {
1084
+ onClick: handleCloseClick,
1085
+ className: styles.closeButton,
1086
+ "aria-label": "Закрыть панель настроек доступности",
1087
+ type: "button",
1088
+ children: "×"
1089
+ }
1090
+ )
1091
+ ] }),
1092
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1093
+ "div",
1094
+ {
1095
+ id: "accessibility-panel-description",
1096
+ className: styles.description,
1097
+ children: "Настройте отображение страницы для улучшения доступности"
1098
+ }
1099
+ ),
1100
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: styles.content, children: [
1101
+ /* @__PURE__ */ jsxRuntimeExports.jsx(AccessibilityToggle, {}),
1102
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: styles.controls, children: [
1103
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ColorSchemeControl, {}),
1104
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FontSizeControl, {}),
1105
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ImageControl, {})
1106
+ ] })
1107
+ ] })
1108
+ ]
1109
+ }
1110
+ ) });
1111
+ };
1112
+ const AccessibilityPanel = (props) => {
1113
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(AccessibilityProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(AccessibilityPanelInner, { ...props }) });
1114
+ };
1115
+ export {
1116
+ AccessibilityPanel,
1117
+ AccessibilityProvider,
1118
+ AccessibilityToggle,
1119
+ CSS_CLASSES,
1120
+ ColorSchemeControl,
1121
+ DEFAULT_ACCESSIBILITY_SETTINGS,
1122
+ FontSizeControl,
1123
+ ImageControl,
1124
+ STORAGE_KEY,
1125
+ applyAllSettings,
1126
+ applyClassToElements,
1127
+ applyColorScheme,
1128
+ applyDynamicFontSize,
1129
+ applyFontSize,
1130
+ applyImageVisibility,
1131
+ applySettingIfEnabled,
1132
+ clearStorage,
1133
+ getImageElements,
1134
+ getTextElements,
1135
+ isDOMAvailable,
1136
+ isFontSizeModified,
1137
+ loadFromStorage,
1138
+ removeAllAccessibilityStyles,
1139
+ removeClassFromElements,
1140
+ resetAllFontSizes,
1141
+ safeDOMOperation,
1142
+ safeLocalStorageOperation,
1143
+ saveToStorage,
1144
+ updateNewElementsFontSize,
1145
+ useAccessibilityContext,
1146
+ useAccessibilitySetting,
1147
+ useAccessibilitySettings,
1148
+ useAccessibilityToggle,
1149
+ validateSettings
1150
+ };
1151
+ //# sourceMappingURL=index.esm.js.map