@theaccessibleteam/a11y-feedback
v2.0.1
Published
Production-grade accessibility feedback engine for the web. Unified screen reader announcements, focus management, and WCAG-compliant notifications.
Downloads
531
Maintainers
Readme
Why This Library?
aria-live alone is not enough.
Most web apps implement feedback using ad-hoc live regions, visual toast libraries, and manual focus hacks. This leads to:
- ❌ Duplicate or missing screen reader announcements
- ❌ Focus being stolen incorrectly
- ❌ Over-announcement and cognitive overload
- ❌ Unintentional WCAG violations
a11y-feedback provides a centralized, accessibility-first feedback layer that is:
- ✅ Safe by default — Correct ARIA semantics enforced
- ✅ Hard to misuse — Focus rules prevent common mistakes
- ✅ Predictable — Consistent across all screen readers
- ✅ Framework-agnostic — Works with React, Vue, Svelte, or vanilla JS
Installation
npm install @theaccessibleteam/a11y-feedback# Yarn
yarn add @theaccessibleteam/a11y-feedback
# pnpm
pnpm add @theaccessibleteam/a11y-feedbackCDN Usage
<script src="https://unpkg.com/@theaccessibleteam/a11y-feedback/dist/a11y-feedback.umd.js"></script>
<script>
const { notify } = window.A11yFeedback
notify.success('Hello from CDN!')
</script>Quick Start
import { notify } from '@theaccessibleteam/a11y-feedback'
// Sugar helpers for common patterns
notify.success('Profile updated successfully')
notify.error('Invalid email address')
notify.warning('Session expires in 5 minutes')
notify.info('New features available')
notify.loading('Saving changes...')Error with Focus Management
notify.error('Please enter a valid email', {
focus: '#email',
explainFocus: true
})
// Screen reader: "Please enter a valid email. Focus moved to Email field."Loading → Success Pattern
// Start loading
notify.loading('Saving...', { id: 'save-op' })
// Replace with success (same ID)
notify.success('Saved!', { id: 'save-op' })Enable Visual Toasts
import { configureFeedback } from '@theaccessibleteam/a11y-feedback'
configureFeedback({
visual: true,
visualPosition: 'top-right',
maxVisualItems: 5
})Semantic Mappings (Enforced)
| Type | ARIA Role | aria-live | Can Move Focus | Auto-Dismiss |
|----------|-----------|-------------|----------------|--------------|
| success | status | polite | ❌ No | ✅ Yes |
| info | status | polite | ❌ No | ✅ Yes |
| loading | status | polite | ❌ No | ❌ No |
| warning | alert | assertive | ✅ Yes | ✅ Yes |
| error | alert | assertive | ✅ Yes | ❌ No |
These mappings are non-configurable to prevent accessibility misuse.
API Reference
notify
// Base function
notify({
message: 'Hello',
type: 'info',
options: { id: 'my-notification' }
})
// Sugar helpers (recommended)
notify.success(message, options?)
notify.error(message, options?)
notify.warning(message, options?)
notify.info(message, options?)
notify.loading(message, options?)Options
interface FeedbackOptions {
id?: string // Unique ID for deduplication/replacement
focus?: string // CSS selector for focus target (error/warning only)
explainFocus?: boolean // Announce focus movement
force?: boolean // Force re-announcement of identical messages
timeout?: number // Auto-dismiss timeout in ms
className?: string // Custom CSS class for visual feedback
onDismiss?: () => void // Callback when dismissed
}configureFeedback
import { configureFeedback } from '@theaccessibleteam/a11y-feedback'
configureFeedback({
visual: true, // Enable visual toasts
defaultTimeout: 5000, // Default auto-dismiss (ms)
visualPosition: 'top-right',
maxVisualItems: 5,
debug: false
})Debug & Telemetry
import {
enableFeedbackDebug,
getFeedbackLog,
getFeedbackStats
} from '@theaccessibleteam/a11y-feedback'
enableFeedbackDebug()
const log = getFeedbackLog()
const stats = getFeedbackStats()Features
Focus Safety Rules
| Rule | Enforced | |------|----------| | Success must not move focus | ✅ | | Info must not move focus | ✅ | | Loading must not move focus | ✅ | | Warning may move focus | ✅ | | Error may move focus | ✅ |
Content Deduplication
Rapid duplicate messages are automatically skipped:
notify.info('Loading data')
notify.info('Loading data') // Skipped (within 500ms)Re-announcement Engine
Screen readers may ignore repeated identical text. We guarantee announcements using:
- Content clearing
- Microtask delay
- Zero-width character injection
WCAG 2.2 Compliance
- ✅ No critical message auto-dismisses
- ✅ Configurable timeouts for non-critical feedback
- ✅ Users can dismiss visual feedback
- ✅ Respects
prefers-reduced-motion - ✅ Prevents WCAG 2.2.1 violations
Browser Support
| Browser | Version | |---------|---------| | Chrome | 90+ | | Firefox | 88+ | | Safari | 14+ | | Edge | 90+ |
Bundle Size
- ESM: ~23KB (minified)
- CJS: ~19KB (minified)
- UMD: ~19KB (minified)
- Zero dependencies
TypeScript Support
Full TypeScript support with exported types:
import type {
FeedbackType,
FeedbackOptions,
FeedbackEvent,
FeedbackConfig,
FeedbackLogEntry
} from '@theaccessibleteam/a11y-feedback'Contributing
We welcome contributions! See our Contributing Guide for details.
# Clone and install
git clone https://github.com/WOLFIEEEE/a11y-feedback.git
cd a11y-feedback
npm install
# Development commands
npm run build # Build the library
npm run test # Run tests
npm run lint # Lint codeLicense
MIT © The Accessible Team
