React accessibility utility functions and hooks for building accessible user interfaces. Provides a comprehensive set of ARIA prop factories and CSS utilities to help you build WCAG-compliant React applications.
- 🎯 ARIA Prop Factories - Functions to generate correct ARIA props for common patterns
- 👁️ Screen Reader Utilities - CSS styles for visually hidden but accessible content
- 🔧 TypeScript Support - Full type definitions for all ARIA attributes
- 🪶 Zero Dependencies - No external dependencies
- ♿ WCAG Compliant - Built following accessibility best practices
npm install @opensourceframework/react-a11y-utils
# or
yarn add @opensourceframework/react-a11y-utils
# or
pnpm add @opensourceframework/react-a11y-utilsimport {
srOnly,
createDisclosureProps,
createLiveRegion,
statusMessageProps,
} from '@opensourceframework/react-a11y-utils';
function Accordion({ title, children, isOpen, onToggle }) {
return (
<div>
<button
{...createDisclosureProps(isOpen, 'panel-1')}
onClick={onToggle}
>
{title}
</button>
<div id="panel-1" hidden={!isOpen}>
{children}
</div>
</div>
);
}
function StatusMessage({ message }) {
return (
<div {...statusMessageProps}>
{message}
</div>
);
}
// Screen reader only text
function SkipLink() {
return (
<a href="#main-content" style={srOnly} tabIndex={0}>
Skip to main content
</a>
);
}CSS styles for screen-reader-only content. Elements are visually hidden but accessible to screen readers.
<span style={srOnly}>This text is only visible to screen readers</span>CSS styles for elements that should become visible when focused (e.g., skip links).
<a href="#main" style={srOnlyFocusable}>Skip to main content</a>Props for decorative elements that should be hidden from screen readers.
<img src="decoration.png" alt="" {...decorative} />Props for disabled interactive elements.
<button {...disabledProps}>Disabled Button</button>Props for status messages (polite announcements).
<div {...statusMessageProps}>Changes saved successfully</div>Props for alert messages (assertive announcements).
<div {...alertMessageProps}>Error: Please correct the form</div>Creates props for live regions that announce changes to screen readers.
<div {...createLiveRegion({ atomic: true, live: 'polite' })}>
{message}
</div>Options:
| Option | Type | Default | Description |
|---|---|---|---|
atomic |
boolean |
false |
Announce entire region or just changes |
relevant |
'additions' | 'removals' | 'text' | 'all' |
'additions' |
What changes to announce |
busy |
boolean |
false |
Whether region is being updated |
live |
'polite' | 'assertive' |
'polite' |
How assertive the announcement |
Creates props for skip links.
<a {...createSkipLinkProps('main-content')}>Skip to main content</a>
<main id="main-content">...</main>Creates props for elements that expand/collapse content.
<button {...createDisclosureProps(isOpen, 'panel-id')} onClick={toggle}>
Toggle
</button>Creates props for toggle buttons with pressed state.
<button {...createPressedProps(isActive)} onClick={toggle}>
Toggle Feature
</button>Creates props for elements with selected state.
<li {...createSelectedProps(isSelected)} role="option">
Option 1
</li>Creates props for elements with checked state.
<div {...createCheckedProps(checked)} role="checkbox" tabIndex={0}>
{checked ? '✓' : ''}
</div>Creates props for dialog/modal triggers.
<button {...createDialogTriggerProps('my-dialog', isOpen)}>
Open Dialog
</button>Creates props for form fields.
<input {...createFormFieldProps(true, hasError)} />Creates props for elements described by another element.
<input {...createDescribedByProps('error-message')} />
<span id="error-message">This field is required</span>Creates props for elements labeled by another element.
<div {...createLabelledByProps('panel-title')} role="region">
<h2 id="panel-title">Panel Title</h2>
Content
</div>Combines multiple accessibility props objects.
<div {...mergeA11yProps(statusMessageProps, { 'aria-label': 'Status' })}>
{message}
</div>import { createDisclosureProps } from '@opensourceframework/react-a11y-utils';
function AccordionItem({ id, title, children, isExpanded, onToggle }) {
const panelId = `panel-${id}`;
return (
<div className="accordion-item">
<h3>
<button
{...createDisclosureProps(isExpanded, panelId)}
onClick={onToggle}
>
{title}
</button>
</h3>
<div
id={panelId}
role="region"
hidden={!isExpanded}
>
{children}
</div>
</div>
);
}import { createCheckedProps } from '@opensourceframework/react-a11y-utils';
function Checkbox({ checked, onChange, children }) {
return (
<div
{...createCheckedProps(checked)}
role="checkbox"
tabIndex={0}
onClick={() => onChange(!checked)}
onKeyDown={(e) => {
if (e.key === ' ' || e.key === 'Enter') {
onChange(!checked);
}
}}
>
{checked ? '✓' : ''}
{children}
</div>
);
}import { createLiveRegion, alertMessageProps } from '@opensourceframework/react-a11y-utils';
function Toast({ message, type = 'info' }) {
const props = type === 'error'
? alertMessageProps
: createLiveRegion({ live: 'polite' });
return (
<div {...props} className={`toast toast-${type}`}>
{message}
</div>
);
}See Contributing Guide for details.
MIT © OpenSource Framework Contributors
Maintained by @opensourceframework in the monorepo.