React Aria (Adobe) accessible component patterns for building WCAG-compliant interactive UI with hooks. Use when implementing buttons, dialogs, comboboxes, menus, and other accessible components in React applications.
View on GitHubyonatangross/orchestkit
ork
January 25, 2026
Select agents to install to:
npx add-skill https://github.com/yonatangross/orchestkit/blob/main/plugins/ork/skills/react-aria-patterns/SKILL.md -a claude-code --skill react-aria-patternsInstallation paths:
.claude/skills/react-aria-patterns/# React Aria Patterns
Build accessible UI components using Adobe's React Aria hooks library with React 19 patterns.
## Overview
- Building accessible buttons, links, and toggles with keyboard/screen reader support
- Implementing modal dialogs with proper focus management and trapping
- Creating autocomplete/combobox components with filtering and selection
- Building menu systems with roving tabindex and proper ARIA roles
- Implementing accessible tables, listboxes, and selection patterns
## Quick Reference
### useButton - Accessible Button Component
```tsx
import { useRef } from 'react';
import { useButton, useFocusRing, mergeProps } from 'react-aria';
import type { AriaButtonProps } from 'react-aria';
function Button(props: AriaButtonProps & { className?: string }) {
const ref = useRef<HTMLButtonElement>(null);
const { focusProps, isFocusVisible } = useFocusRing();
const { buttonProps } = useButton(props, ref);
return (
<button
{...mergeProps(buttonProps, focusProps)}
ref={ref}
className={`${props.className ?? ''} ${isFocusVisible ? 'ring-2 ring-blue-500' : ''}`}
>
{props.children}
</button>
);
}
```
### useDialog - Modal Dialog with Focus Management
```tsx
import { useRef } from 'react';
import { useDialog, useModalOverlay, FocusScope, mergeProps } from 'react-aria';
import { useOverlayTriggerState } from 'react-stately';
function Modal({ state, title, children }) {
const ref = useRef<HTMLDivElement>(null);
const { modalProps, underlayProps } = useModalOverlay({}, state, ref);
const { dialogProps, titleProps } = useDialog({ 'aria-label': title }, ref);
return (
<div {...underlayProps} className="fixed inset-0 z-50 bg-black/50 flex items-center justify-center">
<FocusScope contain restoreFocus autoFocus>
<div {...mergeProps(modalProps, dialogProps)} ref={ref} className="bg-white rounded-lg p-6">
<h2 {...titleProps} className="text-xl font-semibold mb-4">{title}</h2>