@waysnx/ui-accessibility
v0.1.4
Published
Enterprise-grade accessibility control center for WaysNX UI Kit — centralized settings management with real-time application across all components
Maintainers
Readme
@waysnx/ui-accessibility
🤖 AI agents & LLMs: See LLM.md (shipped with this package) for a structured integration guide — AccessibilityProvider, preset profiles, and granular hooks.
Enterprise-grade accessibility control center for WaysNX UI Kit.
A React library that provides a centralized accessibility settings hub with real-time application across all UI components. Users can customize their experience and settings persist across sessions — with zero changes needed to existing components.
How it works
When a user changes a setting (e.g. increases text size), the library updates CSS custom properties on :root. Since every WaysNX UI Kit component already uses --wx-* tokens, they all respond automatically:
User changes setting
↓
AccessibilityProvider updates :root CSS variables
↓
--wx-font-size-md: 22.5px (was 15px)
--wx-color-text: #000000 (high contrast)
↓
Every ui-core, ui-layout, ui-navigation, ui-feedback,
ui-dashboard, ui-visualization component updates instantlyInstallation
npm install @waysnx/ui-accessibilityImport styles in your app entry:
import '@waysnx/ui-accessibility/dist/index.css';Quick Start
import {
AccessibilityProvider,
AccessibilityCenter,
SkipLinks,
} from '@waysnx/ui-accessibility';
import '@waysnx/ui-accessibility/dist/index.css';
function App() {
return (
<AccessibilityProvider>
{/* Skip links — place as first child for keyboard/screen reader users */}
<SkipLinks />
<YourApp />
{/* Floating accessibility button — bottom right corner */}
<AccessibilityCenter
position="bottom-right"
variant="floating-button"
/>
</AccessibilityProvider>
);
}Components
| Component | Description |
|---|---|
| AccessibilityProvider | Context provider — wraps your app, manages all settings and CSS updates |
| AccessibilityCenter | Settings UI — floating button, drawer, modal, or panel variants |
| FloatingButton | Standalone trigger button for the accessibility center |
| ReadingGuide | Visual reading line overlay that follows cursor position |
| Magnifier | Screen magnifier that activates for low vision profiles |
| SkipLinks | Visually hidden skip-navigation links for keyboard/screen reader users |
Hooks
| Hook | Description |
|---|---|
| useAccessibility | Core hook — read and update any setting, apply profiles |
| useAccessibilityProfile | Read and apply preset profiles by name or id |
| useContrast | Read/toggle contrast mode |
| useFontScale | Read/step text size up or down |
| useFocus | Read/toggle focus mode |
| useMotion | Read/toggle reduced motion — respects OS preference |
| useSpeech | Web Speech API wrapper for text-to-speech |
| useAccessibilityChange | Listen to settings changes |
| useAccessibilityAnalytics | Stream analytics events to your backend |
Preset Profiles (10)
| Profile | Key settings | |---|---| | Low Vision | X-large text, high contrast, reading guide, highlight links | | Dyslexia Friendly | OpenDyslexic font, extra-loose spacing, reading guide | | ADHD Optimized | Reduced motion, high contrast, high-visibility focus | | Motor Disabilities | Large text, large targets, reduced motion, screen reader | | Blind | Screen reader optimized, keyboard shortcuts | | Color Blind (Deuteranopia) | Red-green filter, high contrast | | Color Blind (Protanopia) | Green-red filter, high contrast | | Color Blind (Tritanopia) | Blue-yellow filter, high contrast | | Elderly | X-large text, high contrast, reading guide | | Seizure Safe | Reduced motion, no flashing |
Settings Reference
interface AccessibilitySettings {
textSize: 'normal' | 'large' | 'x-large' | 'xx-large';
textSpacing: 'normal' | 'loose' | 'extra-loose';
font: 'default' | 'dyslexia-friendly';
contrast: 'normal' | 'high' | 'yellow-black';
colorFilters: 'none' | 'grayscale' | 'deuteranopia' | 'protanopia' | 'tritanopia';
focusMode: 'standard' | 'high-visibility' | 'box-outline';
readingGuide: boolean;
highlightLinks: boolean;
reducedMotion: boolean;
screenReaderOptimization: boolean;
keyboardShortcuts: boolean;
}AccessibilityProvider Props
<AccessibilityProvider
storageKey="my-app-a11y" // localStorage key (default: 'waysnx-accessibility-settings')
persistSettings={true} // save/restore on page reload (default: true)
defaultSettings={{ textSize: 'large' }} // initial settings override
onSettingsChange={(settings) => {}} // fires on every change
onEvent={(event) => { // analytics events
fetch('/api/accessibility-events', {
method: 'POST',
body: JSON.stringify(event),
});
}}
customProfiles={[myCustomProfile]} // add your own profiles
>
<App />
</AccessibilityProvider>AccessibilityCenter Props
<AccessibilityCenter
position="bottom-right" // 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'
variant="floating-button" // 'floating-button' | 'drawer' | 'modal' | 'panel'
showProfile={true} // show current profile name
showAccessibilityScore={true} // show score widget
showQuickActions={true} // show profile quick-apply buttons
showSettings={true} // show individual settings panel
onSettingsChange={(s) => {}}
onProfileChange={(p) => {}}
customProfiles={[]}
/>Granular Hooks
import { useContrast, useFontScale, useFocus, useMotion } from '@waysnx/ui-accessibility';
function MyToolbar() {
const { contrast, toggleHighContrast } = useContrast();
const { textSize, increaseSize, decreaseSize, scale } = useFontScale();
const { focusMode, toggleHighVisibility } = useFocus();
const { reducedMotion, toggleReducedMotion, prefersReducedMotion } = useMotion();
return (
<div>
<button onClick={toggleHighContrast}>
{contrast === 'high' ? 'Disable' : 'Enable'} High Contrast
</button>
<button onClick={decreaseSize}>A−</button>
<button onClick={increaseSize}>A+</button>
</div>
);
}SkipLinks
import { SkipLinks } from '@waysnx/ui-accessibility';
// Place as first child of App — appears on keyboard Tab
<SkipLinks links={[
{ targetId: 'main-content', label: 'Skip to main content' },
{ targetId: 'main-nav', label: 'Skip to navigation' },
{ targetId: 'search', label: 'Skip to search' },
]} />
// Target elements need matching IDs
<main id="main-content">...</main>Analytics Integration
import { useAccessibilityAnalytics } from '@waysnx/ui-accessibility';
function AnalyticsWrapper() {
useAccessibilityAnalytics((event) => {
// event = { eventType, timestamp, profile, setting, previousValue, newValue, sessionId }
fetch('/api/accessibility-events', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(event),
});
});
return null;
}CSS Variables Updated
When settings change, these --wx-* tokens update automatically:
/* Text size x-large */
--wx-font-size-xs: 18px;
--wx-font-size-sm: 21px;
--wx-font-size-md: 22.5px;
--wx-font-size-lg: 27px;
/* High contrast */
--wx-color-text: #000000;
--wx-color-surface: #ffffff;
--wx-color-border: #000000;
/* Yellow-black contrast */
--wx-color-text: #ffff00;
--wx-color-surface: #000000;All WaysNX UI Kit components that use these tokens update instantly — no code changes required.
Services
import {
announcementService, // ARIA live region announcements for screen readers
focusManager, // Focus trapping, restoration, visibility
keyboardManager, // Register/manage global keyboard shortcuts
} from '@waysnx/ui-accessibility';
// Announce to screen readers
announcementService.announce('Settings saved', 'polite');
announcementService.announceSuccess('Profile applied');
// Trap focus in a modal
const release = focusManager.trapFocus(modalElement);
// Call release() to restore focus
// Register keyboard shortcut
keyboardManager.registerShortcut({
key: 'a',
modifiers: ['alt'],
handler: () => openAccessibilityCenter(),
description: 'Open accessibility settings',
});i18n
All UI strings are translatable via @waysnx/ui-i18n:
import { TranslationProvider, esMessages } from '@waysnx/ui-i18n';
<TranslationProvider locale="es" messages={esMessages}>
<App /> {/* AccessibilityCenter now renders in Spanish */}
</TranslationProvider>Built-in locales: English (default), Spanish, French, Arabic (RTL)
WCAG Compliance
- WCAG 2.2 AA compliant
- Full keyboard navigation
- All interactive elements have ARIA labels
- Focus indicators visible on all controls
- Screen reader announcements for setting changes
- Respects
prefers-reduced-motionOS preference
License
Apache License 2.0 © WaysNX Technologies Private Limited
