Design Principle
ARIA is a semantic and interaction contract, not magic attributes for divs. Custom comboboxes, dialogs, tabs, treegrids, menus, listboxes, and similar widgets must prove their keyboard, focus, and assistive-technology model first.
Large Theory
Complex widgets often fail not because the visuals are wrong, but because roles, focus, keyboard behavior, and exposed state disagree. APG provides a pattern language: when a role applies, which states are required, which keys should work, how DOM focus or virtual focus moves, and which boundaries examples demonstrate. Agents should turn this into a component contract before implementation instead of discovering it while coding.
Small Points
- First decide whether native HTML already covers the need. If native select, button, dialog, or details works, do not add ARIA unnecessarily.
- Choose an APG pattern for each complex component: combobox, dialog, tabs, treegrid, menu button, listbox, slider, accordion, and so on.
- Extract roles, states, and properties such as
aria-expanded,aria-controls,aria-selected, andaria-activedescendant. - Convert keyboard tables into test assertions: Enter, Escape, Arrow keys, Home/End, Tab, and Shift+Tab should define entry, exit, looping, and cancellation behavior.
- Name the focus model: DOM focus enters the popup, or focus stays on the input while
aria-activedescendantidentifies the active item. Do not mix models casually. - APG examples are not full product components; local work still needs loading, empty, error, disabled, mobile, RTL, forced-colors, and form-submit boundaries.
Design Judgment
A component is ready for visual implementation when the contract can answer where focus is, what screen readers announce, which key changes which state, how state maps to DOM/ARIA, and where focus returns after close. If those answers are unclear, use Radix, React Aria, Ariakit, or native controls first.
Implementation Notes
Before generation, output an apgPatternContract: patternName, sourceHref, nativeAlternative, roles, statesProps, keyboardInteractions, focusModel, selectionModel, labelling, liveRegion, escapeBehavior, formIntegration, mobileNotes, and testAssertions. Playwright or Testing Library tests should cover keyboard paths and ARIA state, not only screenshots.
Counterexamples/Risks
A div with role=button that does not activate on Space; a combobox whose popup mixes DOM focus with aria-activedescendant incorrectly; tabs that only work with mouse; a dialog that loses focus on close; menu items that look like links but lack the menu keyboard model; and a treegrid that draws hierarchy without row and column semantics.
Case Study
The APG home page describes applying ARIA semantics to common design patterns and widgets, with design patterns, functional examples, and fundamental practices. The APG combobox pattern distinguishes listbox, grid, tree, and dialog popup keyboard behavior, and notes that some popups keep DOM focus on the combobox with aria-activedescendant, while dialog popups move DOM focus into the dialog. The reusable lesson is that one visual autocomplete can imply several focus models; choose the pattern before implementation.
Source Links
WAI-ARIA APG: https://www.w3.org/WAI/ARIA/apg/ APG Patterns: https://www.w3.org/WAI/ARIA/apg/patterns/ APG Combobox Pattern: https://www.w3.org/WAI/ARIA/apg/patterns/combobox/ W3C aria-practices repository: https://github.com/w3c/aria-practices W3C Software and Document License: https://www.w3.org/copyright/software-license/
Agent Directive
Before hand-writing complex widgets, output the APG pattern contract and test assertions; prefer native controls or mature primitives, and do not rely on role/aria attributes to rescue mouse-first components.