Interactive Demo
Experience the library in action. Use a screen reader for the full accessibility experience.
Screen Reader Simulation
See what assistive technology users hear
Basic Notifications
Click to trigger different feedback types with correct ARIA semantics.
🔘 Action Buttons
Notifications can include interactive action buttons for user responses.
📊 Progress Notifications
Track long-running operations with real-time progress updates.
💬 Accessible Dialogs
Promise-based confirm and prompt dialogs with full keyboard navigation.
🎨 Rich Content
Include icons, HTML, and styled content in notifications.
📝 Notification Templates
Create reusable notification patterns with predefined templates.
Form Validation Demo
Complete form with accessible validation. Errors move focus to the first invalid field.
Loading → Success Pattern
Use the same ID to replace loading states with results. Watch the screen reader panel.
Deduplication & Force
Rapid duplicate messages are skipped. Use force: true to override.
What's New in v2.0
Major new features for enterprise-grade accessibility.
Action Buttons
Add interactive buttons to notifications. Support for primary, secondary, and custom actions with keyboard navigation.
Progress Notifications
Track long-running operations with visual progress bars and screen reader announcements at key milestones.
Promise-based Dialogs
Accessible confirm() and prompt() dialogs that return Promises. Full keyboard navigation and focus management.
Notification Templates
Create reusable notification patterns with predefined options. Perfect for consistent error handling and user feedback.
Rich Content
Include icons, HTML, and styled content in notifications. Full customization with accessibility preserved.
Sound & Haptics
Optional audio and haptic feedback for notifications. Web Audio API integration with user preferences respected.
Notification Center
Centralized history panel for all notifications. Users can review past notifications and mark as read.
Keyboard Navigation
Full keyboard support for all interactions. Tab navigation, Escape to dismiss, and custom shortcuts.
Screen Reader First
Automatically manages ARIA live regions with correct politeness levels. Polite for success/info, assertive for errors/warnings.
Focus Safety
Enforced rules prevent focus theft. Only errors and warnings can move focus. Success messages never steal focus.
Smart Deduplication
Rapid duplicate messages are automatically skipped. Use ID-based replacement for loading → success patterns.
WCAG 2.2 Compliant
Errors never auto-dismiss. Configurable timeouts. Respects prefers-reduced-motion. Fully keyboard accessible.
i18n & RTL Ready
Built-in support for 10+ languages. Automatic RTL detection. Custom translations for all UI strings.
Themeable
Full CSS custom properties support. Light/dark mode. Customize colors, spacing, animations.
Event System
Subscribe to feedback events for analytics and logging. Track announcements, dismissals, and focus changes.
Zero Dependencies
Lightweight (~22KB gzip). No external dependencies. Works with any framework or vanilla JavaScript.
Semantic Mappings (Enforced)
These mappings are non-configurable to prevent accessibility misuse.
| Type | ARIA Role | aria-live | Priority | Can Move Focus | Auto-Dismiss |
|---|---|---|---|---|---|
| success | status |
polite |
Low | No | Yes |
| info | status |
polite |
Low | No | Yes |
| loading | status |
polite |
Low | No | No |
| warning | alert |
assertive |
High | Yes | Yes |
| error | alert |
assertive |
High | Yes | No |
Framework Integration
First-class bindings for 5 popular frameworks, or use vanilla JavaScript.
import { notify, configureFeedback, confirm, prompt } from '@theaccessibleteam/a11y-feedback'
// Enable visual toasts with sound
configureFeedback({
visual: true,
enableSound: true
})
// Simple notifications
notify.success('Profile saved!')
notify.error('Something went wrong')
// With action buttons (v2.0)
notify.info('New message received', {
actions: [
{ label: 'View', onClick: () => openMessage() },
{ label: 'Dismiss', variant: 'secondary' }
]
})
// Progress notifications (v2.0)
notify.loading('Uploading...', {
id: 'upload',
progress: { value: 0, max: 100 }
})
// Promise-based dialogs (v2.0)
const confirmed = await confirm('Delete this item?')
const name = await prompt('Enter your name')
import { useA11yFeedback, A11yFeedbackProvider } from '@theaccessibleteam/a11y-feedback-react'
// Wrap your app with the provider
function App() {
return (
<A11yFeedbackProvider config={{ visual: true }}>
<YourApp />
</A11yFeedbackProvider>
)
}
// Use in any component
function SaveButton() {
const { success, error, loading, confirm } = useA11yFeedback()
const handleSave = async () => {
loading('Saving...', { id: 'save' })
try {
await saveData()
success('Saved!', { id: 'save' })
} catch (e) {
error('Failed to save', { id: 'save' })
}
}
return <button onClick={handleSave}>Save</button>
}
Install: npm i @theaccessibleteam/a11y-feedback-react
<script setup>
import { useA11yFeedback } from '@theaccessibleteam/a11y-feedback-vue'
const { success, error, loading, confirm } = useA11yFeedback()
async function handleSubmit() {
loading('Submitting...', { id: 'submit' })
try {
await submitForm()
success('Submitted!', { id: 'submit' })
} catch (e) {
error('Submission failed', { id: 'submit' })
}
}
async function handleDelete() {
const confirmed = await confirm('Delete this?')
if (confirmed) { /* delete */ }
}
</script>
<template>
<button @click="handleSubmit">Submit</button>
</template>
Install: npm i @theaccessibleteam/a11y-feedback-vue
<script>
import { useA11yFeedback } from '@theaccessibleteam/a11y-feedback-svelte'
const { success, error, loading, confirm } = useA11yFeedback()
async function handleSave() {
loading('Saving...', { id: 'save' })
try {
await saveData()
success('Saved!', { id: 'save' })
} catch (e) {
error('Failed', { id: 'save' })
}
}
</script>
<button on:click={handleSave}>Save</button>
Install: npm i @theaccessibleteam/a11y-feedback-svelte
import { Component, inject } from '@angular/core'
import { A11yFeedbackService } from '@theaccessibleteam/a11y-feedback-angular'
@Component({
selector: 'app-save-button',
template: `<button (click)="save()">Save</button>`
})
export class SaveButtonComponent {
private feedback = inject(A11yFeedbackService)
async save() {
this.feedback.loading('Saving...', { id: 'save' })
try {
await this.saveData()
this.feedback.success('Saved!', { id: 'save' })
} catch (e) {
this.feedback.error('Failed', { id: 'save' })
}
}
}
Install: npm i @theaccessibleteam/a11y-feedback-angular
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://unpkg.com/@theaccessibleteam/a11y-feedback@2/dist/a11y-feedback.umd.js"></script>
</head>
<body>
<button id="save-btn">Save</button>
<script>
const { notify, configureFeedback, confirm } = window.A11yFeedback
configureFeedback({ visual: true })
document.getElementById('save-btn').addEventListener('click', async () => {
const confirmed = await confirm('Save changes?')
if (confirmed) {
notify.success('Saved!')
}
})
</script>
</body>
</html>
API Playground
Experiment with the API in real-time. Edit the code and see results instantly.
Ready to make your app accessible?
Join developers building inclusive web experiences with a11y-feedback v2.0.