accessibility-widgets 2.0.12 → 2.0.14
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/README.md +57 -38
- package/package.json +1 -1
- package/widget.js +61 -1
package/README.md
CHANGED
|
@@ -2,34 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/accessibility-widgets)
|
|
4
4
|
[](https://opensource.org/licenses/GPL-3.0)
|
|
5
|
-
[](https://www.jsdelivr.com/package/npm/accessibility-widgets)
|
|
6
6
|
|
|
7
7
|
<a href="https://github.com/sponsors/sinanisler">
|
|
8
8
|
<img src="https://img.shields.io/badge/Consider_Supporting_My_Projects_❤-GitHub-d46" width="300" height="auto" />
|
|
9
9
|
</a>
|
|
10
10
|
<br><br>
|
|
11
11
|
|
|
12
|
-
A comprehensive, zero-dependency accessibility widget that enhances web accessibility for all users. This lightweight, single-file JavaScript solution provides
|
|
12
|
+
A comprehensive, zero-dependency accessibility widget that enhances web accessibility for all users. This lightweight, single-file JavaScript solution provides 16+ accessibility features to make your website instantly more inclusive and compliant with WCAG 2.1 AA, Section 508, and EN 301 549 standards.
|
|
13
13
|
<br><br>
|
|
14
14
|
|
|
15
15
|
> **Note**: This widget helps meet accessibility criteria but does not guarantee full compliance. Complete WCAG/Section 508 compliance requires proper HTML semantics, ARIA attributes, manual testing, and user validation.
|
|
16
16
|
<br><br>
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
<img width="1793" height="auto" alt="image" src="https://github.com/user-attachments/assets/610138f5-e60d-4297-b5e3-ea040f361209" />
|
|
20
19
|
|
|
21
|
-
##
|
|
20
|
+
## ⚡ Quick Easy Install
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
Add widget script close to the ```</body>``` - That's it!
|
|
24
23
|
|
|
24
|
+
```html
|
|
25
25
|
|
|
26
|
+
<script src="https://cdn.jsdelivr.net/npm/accessibility-widgets@latest/widget.js"></script>
|
|
27
|
+
```
|
|
26
28
|
|
|
27
|
-
## ⚡ Quick Start
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
<img width="1793" height="auto" alt="image" src="https://github.com/user-attachments/assets/610138f5-e60d-4297-b5e3-ea040f361209" />
|
|
31
|
+
|
|
32
|
+
## Supported Language List
|
|
33
|
+
|
|
34
|
+
English, Deutsch, Español, Italiano, Français, Русский, Türkçe, العربية, हिन्दी, 简体中文, 日本語, Português, বাংলা, 한국어, Tiếng Việt, Bahasa Indonesia, ไทย, Polski, Nederlands, Ελληνικά, Svenska, Norsk, Dansk, Suomi, Čeština, Magyar, Română, עברית, فارسی, اردو, ਪੰਜਾਬੀ, मराठी, తెలుగు, தமிழ், Bahasa Melayu, Filipino
|
|
35
|
+
|
|
33
36
|
|
|
34
37
|
Or install via NPM:
|
|
35
38
|
|
|
@@ -50,39 +53,41 @@ require('accessibility-widgets');
|
|
|
50
53
|
- **High Contrast Mode** - 3 levels (Medium 1.3x, High 1.5x, Ultra 2.0x) for improved visibility
|
|
51
54
|
- **Text Size Control** - 4 size options (Default, Medium 20px, Large 24px, X-Large 28px)
|
|
52
55
|
- **Line Height Adjustment** - 3 spacing levels (2em, 3em, 4em) for better readability
|
|
53
|
-
- **Text Spacing** -
|
|
56
|
+
- **Text Spacing** - 3 levels (Light 0.1em/0.5em, Medium 0.15em/1em, Heavy 0.25em/2em letter/word spacing)
|
|
54
57
|
- **Text Alignment** - Left, Center, or Right alignment options
|
|
55
|
-
- **Bigger Cursor** - High-contrast
|
|
58
|
+
- **Bigger Cursor** - High-contrast ~29×44px SVG cursor for better visibility
|
|
56
59
|
- **Hide Images** - Text-only mode for focused reading or bandwidth saving
|
|
60
|
+
- **Saturation Control** - 3 levels (Low 0.5x, High 10x, None/grayscale) for color intensity adjustment
|
|
57
61
|
|
|
58
62
|
### 🧠 Cognitive Support
|
|
59
63
|
- **Dyslexia-Friendly Font** - Comic Sans MS and other dyslexia-optimized fonts
|
|
60
64
|
- **Font Selection** - Choose between Arial, Times New Roman, or Verdana
|
|
61
|
-
- **Animation Control** - Pause all animations and
|
|
62
|
-
- **Reduced Motion** - Motion sensitivity support for vestibular disorders
|
|
65
|
+
- **Animation Control** - Pause all animations, transitions, and reduced motion (bundled feature for vestibular disorders)
|
|
63
66
|
|
|
64
67
|
### ♿ Assistive Technology
|
|
65
68
|
- **Screen Reader** - Built-in text-to-speech using Web Speech API
|
|
66
|
-
- **Voice Control** - Hands-free navigation with
|
|
69
|
+
- **Voice Control** - Hands-free navigation with 16 voice commands
|
|
67
70
|
- **Color Blindness Filters** - Protanopia, Deuteranopia, Tritanopia, and Grayscale modes
|
|
68
71
|
- **Keyboard Navigation** - Full Tab/Arrow key support with proper focus indicators
|
|
69
72
|
|
|
70
73
|
## 📊 Compliance & Standards
|
|
71
74
|
|
|
72
|
-
### WCAG 2.1 AA Coverage
|
|
75
|
+
### WCAG 2.1 AA & AAA Coverage
|
|
76
|
+
|
|
77
|
+
*Note: Some criteria below are AAA-level (1.4.6, 1.4.8, 2.3.3, 2.5.5). The core widget targets AA conformance.*
|
|
73
78
|
|
|
74
79
|
| Feature | WCAG Criteria | EU EN 301 549 | US Section 508 |
|
|
75
80
|
|---------|---------------|---------------|----------------|
|
|
76
|
-
| High Contrast Mode | ✅ 1.4.3, 1.4.6 | ✅ | ✅ |
|
|
81
|
+
| High Contrast Mode | ✅ 1.4.3, 1.4.6 (AAA) | ✅ | ✅ |
|
|
77
82
|
| Text Size Adjustment | ✅ 1.4.4 | ✅ | ✅ |
|
|
78
83
|
| Text Spacing | ✅ 1.4.12 | ✅ | ✅ |
|
|
79
84
|
| Line Height Adjustment | ✅ 1.4.12 | ✅ | ✅ |
|
|
80
|
-
| Text Alignment | ✅ 1.4.8 | ✅ | ✅ |
|
|
81
|
-
| Cursor Enhancement | ✅ 2.5.5 | ✅ | ✅ |
|
|
82
|
-
| Pause Animations | ✅ 2.2.2, 2.3.3 | ✅ | ✅ |
|
|
83
|
-
|
|
|
85
|
+
| Text Alignment | ✅ 1.4.8 (AAA) | ✅ | ✅ |
|
|
86
|
+
| Cursor Enhancement | ✅ 2.5.5 (AAA) | ✅ | ✅ |
|
|
87
|
+
| Pause Animations | ✅ 2.2.2, 2.3.3 (AAA) | ✅ | ✅ |
|
|
88
|
+
| Saturation Control | ✅ 1.4.1 | ✅ | ✅ |
|
|
84
89
|
| Hide Images | ✅ 1.1.1 | ✅ | ✅ |
|
|
85
|
-
| Dyslexia-Friendly Font | ✅ 1.4.8 | ✅ | ✅ |
|
|
90
|
+
| Dyslexia-Friendly Font | ✅ 1.4.8 (AAA) | ✅ | ✅ |
|
|
86
91
|
| Screen Reader | ✅ 4.1.3 | ✅ | ✅ |
|
|
87
92
|
| Voice Control | ⚠️ Browser API | ⚠️ | ⚠️ |
|
|
88
93
|
| Color Filters | ✅ 1.4.1 | ✅ | ✅ |
|
|
@@ -95,11 +100,9 @@ require('accessibility-widgets');
|
|
|
95
100
|
|
|
96
101
|
### CDN (Fastest)
|
|
97
102
|
```html
|
|
98
|
-
<!-- unpkg CDN -->
|
|
99
|
-
<script src="https://unpkg.com/accessibility-widgets@latest/widget.js"></script>
|
|
100
|
-
|
|
101
103
|
<!-- jsdelivr CDN -->
|
|
102
104
|
<script src="https://cdn.jsdelivr.net/npm/accessibility-widgets@latest/widget.js"></script>
|
|
105
|
+
|
|
103
106
|
```
|
|
104
107
|
|
|
105
108
|
### NPM
|
|
@@ -128,7 +131,7 @@ require('accessibility-widgets/widget.js');
|
|
|
128
131
|
The widget works out of the box with zero configuration:
|
|
129
132
|
|
|
130
133
|
```html
|
|
131
|
-
<script src="https://
|
|
134
|
+
<script src="https://cdn.jsdelivr.net/npm/accessibility-widgets@latest/widget.js"></script>
|
|
132
135
|
```
|
|
133
136
|
|
|
134
137
|
### Custom Configuration
|
|
@@ -156,7 +159,7 @@ window.ACCESSIBILITY_WIDGET_CONFIG = {
|
|
|
156
159
|
}
|
|
157
160
|
};
|
|
158
161
|
</script>
|
|
159
|
-
<script src="https://
|
|
162
|
+
<script src="https://cdn.jsdelivr.net/npm/accessibility-widgets@latest/widget.js"></script>
|
|
160
163
|
```
|
|
161
164
|
|
|
162
165
|
### Full Configuration Options
|
|
@@ -312,14 +315,16 @@ window.ACCESSIBILITY_WIDGET_CONFIG = {
|
|
|
312
315
|
resetAllSettings: 'Restablecer Todo'
|
|
313
316
|
},
|
|
314
317
|
voiceCommands: {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
318
|
+
es: {
|
|
319
|
+
showMenu: ['mostrar menú', 'abrir menú'],
|
|
320
|
+
highContrast: ['alto contraste'],
|
|
321
|
+
biggerText: ['texto grande', 'texto más grande'],
|
|
322
|
+
resetAll: ['reiniciar todo']
|
|
323
|
+
}
|
|
319
324
|
}
|
|
320
325
|
};
|
|
321
326
|
</script>
|
|
322
|
-
<script src="https://
|
|
327
|
+
<script src="https://cdn.jsdelivr.net/npm/accessibility-widgets@latest/widget.js"></script>
|
|
323
328
|
```
|
|
324
329
|
|
|
325
330
|
## 🎤 Voice Commands
|
|
@@ -337,7 +342,12 @@ When voice control is enabled (Chrome/Edge only), use these commands:
|
|
|
337
342
|
| "dyslexia font" | Activates dyslexia-friendly font |
|
|
338
343
|
| "bigger cursor" | Enlarges cursor |
|
|
339
344
|
| "line height" | Adjusts line spacing |
|
|
345
|
+
| "text align" | Cycles text alignment (left/center/right) |
|
|
346
|
+
| "saturation" | Cycles saturation (low/high/none) |
|
|
347
|
+
| "font selection" / "change font" | Cycles font family |
|
|
348
|
+
| "color filter" | Cycles color blindness filters |
|
|
340
349
|
| "screen reader" | Activates text-to-speech |
|
|
350
|
+
| "voice command" / "voice control" | Toggles voice control on/off |
|
|
341
351
|
| "reset all" | Resets all settings |
|
|
342
352
|
|
|
343
353
|
*All commands are fully customizable via `voiceCommands` configuration*## 📚 Feature Details
|
|
@@ -352,13 +362,16 @@ Three contrast enhancement levels:
|
|
|
352
362
|
Four size options (Default, Medium 20px, Large 24px, X-Large 28px) with smart widget exclusion to maintain UI consistency.
|
|
353
363
|
|
|
354
364
|
### Text Spacing
|
|
355
|
-
|
|
365
|
+
Three spacing levels for improved readability, especially helpful for dyslexia:
|
|
366
|
+
- **Light**: letter-spacing 0.1em, word-spacing 0.5em
|
|
367
|
+
- **Medium**: letter-spacing 0.15em, word-spacing 1em
|
|
368
|
+
- **Heavy**: letter-spacing 0.25em, word-spacing 2em
|
|
356
369
|
|
|
357
370
|
### Line Height Adjustment
|
|
358
371
|
Three spacing levels (2em, 3em, 4em) to reduce visual crowding and improve reading flow.
|
|
359
372
|
|
|
360
373
|
### Animation Control
|
|
361
|
-
Completely disables CSS animations and transitions - critical for users with vestibular disorders or ADHD.
|
|
374
|
+
Completely disables CSS animations and transitions (including `::before`/`::after` pseudo-elements). Also provides reduced motion support — critical for users with vestibular disorders or ADHD.
|
|
362
375
|
|
|
363
376
|
### Image Hiding
|
|
364
377
|
Text-only mode with smart caching (5-second intervals) to catch dynamically loaded images.
|
|
@@ -367,17 +380,23 @@ Text-only mode with smart caching (5-second intervals) to catch dynamically load
|
|
|
367
380
|
Uses Comic Sans MS and fallback fonts optimized for dyslexia (Chalkboard SE, Bradley Hand, Brush Script MT).
|
|
368
381
|
|
|
369
382
|
### Cursor Enhancement
|
|
370
|
-
Custom
|
|
383
|
+
Custom ~29×44px SVG cursor with high-contrast black fill and white stroke for better visibility.
|
|
371
384
|
|
|
372
385
|
### Screen Reader (Text-to-Speech)
|
|
373
386
|
Built-in TTS using Web Speech API - reads focused element text, alt attributes, and titles.
|
|
374
387
|
|
|
375
388
|
### Voice Control
|
|
376
|
-
Hands-free operation with Web Speech Recognition API. Supports
|
|
389
|
+
Hands-free operation with Web Speech Recognition API. Supports 16 customizable commands.
|
|
377
390
|
|
|
378
391
|
### Color Blindness Filters
|
|
379
392
|
SVG-based filters for Protanopia (red-blind), Deuteranopia (green-blind), Tritanopia (blue-blind), and Grayscale modes.
|
|
380
393
|
|
|
394
|
+
### Saturation Control
|
|
395
|
+
Three saturation levels for color intensity adjustment:
|
|
396
|
+
- **Low**: 0.5x saturation for reduced color intensity
|
|
397
|
+
- **High**: 10x saturation for boosted color vibrancy
|
|
398
|
+
- **None**: Full grayscale (desaturated) display
|
|
399
|
+
|
|
381
400
|
### Font Selection
|
|
382
401
|
Cycle through Arial (modern sans-serif), Times New Roman (traditional serif), and Verdana (screen-optimized).
|
|
383
402
|
|
|
@@ -422,7 +441,7 @@ Cycle through Arial (modern sans-serif), Times New Roman (traditional serif), an
|
|
|
422
441
|
<p>This site is fully accessible.</p>
|
|
423
442
|
|
|
424
443
|
<!-- Add widget - automatically initializes -->
|
|
425
|
-
<script src="https://
|
|
444
|
+
<script src="https://cdn.jsdelivr.net/npm/accessibility-widgets@latest/widget.js"></script>
|
|
426
445
|
</body>
|
|
427
446
|
</html>
|
|
428
447
|
```
|
|
@@ -454,7 +473,7 @@ Cycle through Arial (modern sans-serif), Times New Roman (traditional serif), an
|
|
|
454
473
|
}
|
|
455
474
|
};
|
|
456
475
|
</script>
|
|
457
|
-
<script src="https://
|
|
476
|
+
<script src="https://cdn.jsdelivr.net/npm/accessibility-widgets@latest/widget.js"></script>
|
|
458
477
|
</body>
|
|
459
478
|
</html>
|
|
460
479
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "accessibility-widgets",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.14",
|
|
4
4
|
"description": "A comprehensive, lightweight accessibility widget that enhances web accessibility for all users. Provides multiple accessibility features including screen reader support, voice control, high contrast mode, and more.",
|
|
5
5
|
"main": "widget.js",
|
|
6
6
|
"scripts": {
|
package/widget.js
CHANGED
|
@@ -1133,7 +1133,20 @@ function setLanguage(lang) {
|
|
|
1133
1133
|
}
|
|
1134
1134
|
|
|
1135
1135
|
function getTranslation(key) {
|
|
1136
|
-
|
|
1136
|
+
// Check current language translations first
|
|
1137
|
+
if (TRANSLATIONS[currentLanguage] && TRANSLATIONS[currentLanguage][key]) {
|
|
1138
|
+
return TRANSLATIONS[currentLanguage][key];
|
|
1139
|
+
}
|
|
1140
|
+
// Fallback to user-configured lang overrides
|
|
1141
|
+
if (WIDGET_CONFIG.lang && WIDGET_CONFIG.lang[key]) {
|
|
1142
|
+
return WIDGET_CONFIG.lang[key];
|
|
1143
|
+
}
|
|
1144
|
+
// Fallback to English translations
|
|
1145
|
+
if (TRANSLATIONS['en'] && TRANSLATIONS['en'][key]) {
|
|
1146
|
+
return TRANSLATIONS['en'][key];
|
|
1147
|
+
}
|
|
1148
|
+
// Last resort: return the key itself
|
|
1149
|
+
return key;
|
|
1137
1150
|
}
|
|
1138
1151
|
|
|
1139
1152
|
// Initialize language from localStorage or detect from browser
|
|
@@ -2211,6 +2224,19 @@ const widgetStyles = `
|
|
|
2211
2224
|
word-spacing: 2px !important;
|
|
2212
2225
|
text-align: left;
|
|
2213
2226
|
}
|
|
2227
|
+
|
|
2228
|
+
/* Screen-reader-only utility for live announcements */
|
|
2229
|
+
.snn-sr-only {
|
|
2230
|
+
position: absolute;
|
|
2231
|
+
width: 1px;
|
|
2232
|
+
height: 1px;
|
|
2233
|
+
padding: 0;
|
|
2234
|
+
margin: -1px;
|
|
2235
|
+
overflow: hidden;
|
|
2236
|
+
clip: rect(0, 0, 0, 0);
|
|
2237
|
+
white-space: nowrap;
|
|
2238
|
+
border-width: 0;
|
|
2239
|
+
}
|
|
2214
2240
|
`;
|
|
2215
2241
|
|
|
2216
2242
|
// Page accessibility styles (will go in main document - these affect the page, NOT the widget)
|
|
@@ -2470,6 +2496,14 @@ function createShadowContainer() {
|
|
|
2470
2496
|
styleElement.textContent = widgetStyles;
|
|
2471
2497
|
shadowRoot.appendChild(styleElement);
|
|
2472
2498
|
|
|
2499
|
+
// Create aria-live region for screen reader announcements
|
|
2500
|
+
const liveRegion = document.createElement('div');
|
|
2501
|
+
liveRegion.id = 'snn-live-region';
|
|
2502
|
+
liveRegion.setAttribute('aria-live', 'polite');
|
|
2503
|
+
liveRegion.setAttribute('aria-atomic', 'true');
|
|
2504
|
+
liveRegion.classList.add('snn-sr-only');
|
|
2505
|
+
shadowRoot.appendChild(liveRegion);
|
|
2506
|
+
|
|
2473
2507
|
return shadowRoot;
|
|
2474
2508
|
}
|
|
2475
2509
|
|
|
@@ -2477,6 +2511,19 @@ function createShadowContainer() {
|
|
|
2477
2511
|
// CORE UTILITY FUNCTIONS
|
|
2478
2512
|
// ===========================================
|
|
2479
2513
|
|
|
2514
|
+
// Announce a change to screen reader users via the live region
|
|
2515
|
+
function announceChange(message) {
|
|
2516
|
+
if (!shadowRoot) return;
|
|
2517
|
+
const liveRegion = shadowRoot.getElementById('snn-live-region');
|
|
2518
|
+
if (!liveRegion) return;
|
|
2519
|
+
// Clear then set to ensure announcement even for repeated messages
|
|
2520
|
+
liveRegion.textContent = '';
|
|
2521
|
+
// Use requestAnimationFrame to ensure DOM update before setting new text
|
|
2522
|
+
requestAnimationFrame(() => {
|
|
2523
|
+
liveRegion.textContent = message;
|
|
2524
|
+
});
|
|
2525
|
+
}
|
|
2526
|
+
|
|
2480
2527
|
// Cache for DOM elements to improve performance
|
|
2481
2528
|
const domCache = {
|
|
2482
2529
|
get body() {
|
|
@@ -2800,6 +2847,9 @@ function resetAccessibilitySettings() {
|
|
|
2800
2847
|
const steps = button.querySelectorAll('.snn-option-step');
|
|
2801
2848
|
steps.forEach(step => step.classList.remove('active'));
|
|
2802
2849
|
});
|
|
2850
|
+
|
|
2851
|
+
// Announce reset to screen reader users
|
|
2852
|
+
announceChange(getTranslation('resetAllSettings'));
|
|
2803
2853
|
}
|
|
2804
2854
|
|
|
2805
2855
|
// Create toggle buttons for accessibility options
|
|
@@ -2877,6 +2927,9 @@ function createToggleButton(
|
|
|
2877
2927
|
targetElement.classList.remove(className);
|
|
2878
2928
|
}
|
|
2879
2929
|
}
|
|
2930
|
+
|
|
2931
|
+
// Announce change to screen reader users
|
|
2932
|
+
announceChange(buttonText);
|
|
2880
2933
|
}
|
|
2881
2934
|
|
|
2882
2935
|
return button;
|
|
@@ -2916,6 +2969,7 @@ function createActionButton(buttonText, actionFunction, iconSVG, optionsConfig =
|
|
|
2916
2969
|
const result = actionFunction();
|
|
2917
2970
|
if (result) {
|
|
2918
2971
|
updateActionButtonStatus(button, optionId, optionsConfig);
|
|
2972
|
+
announceChange(buttonText + ': ' + result);
|
|
2919
2973
|
}
|
|
2920
2974
|
});
|
|
2921
2975
|
|
|
@@ -2925,6 +2979,7 @@ function createActionButton(buttonText, actionFunction, iconSVG, optionsConfig =
|
|
|
2925
2979
|
const result = actionFunction();
|
|
2926
2980
|
if (result) {
|
|
2927
2981
|
updateActionButtonStatus(button, optionId, optionsConfig);
|
|
2982
|
+
announceChange(buttonText + ': ' + result);
|
|
2928
2983
|
}
|
|
2929
2984
|
}
|
|
2930
2985
|
});
|
|
@@ -3383,6 +3438,11 @@ const voiceControl = {
|
|
|
3383
3438
|
}
|
|
3384
3439
|
|
|
3385
3440
|
try {
|
|
3441
|
+
// Abort any existing recognition instance before creating a new one
|
|
3442
|
+
if (voiceControl.recognition) {
|
|
3443
|
+
try { voiceControl.recognition.abort(); } catch (e) { /* ignore */ }
|
|
3444
|
+
voiceControl.recognition = null;
|
|
3445
|
+
}
|
|
3386
3446
|
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
3387
3447
|
voiceControl.recognition = new SpeechRecognition();
|
|
3388
3448
|
voiceControl.recognition.interimResults = false;
|