hermes

Build an accessible ARIA widget

Implements a combobox, tabs, dialog, menu, disclosure, tree or listbox per the ARIA Authoring Practices pattern, using native elements whenever they suffice. Use for custom interactive widgets.

context

The first rule of ARIA is not to use it when a native element does the job: WebAIM's yearly scans of the top million home pages keep finding more errors on pages that use ARIA than on pages that do not. When a custom widget is justified, it has to match the APG pattern exactly: the roles, the states that update as the user acts, and the keyboard model screen-reader users already know from desktop apps. Half a pattern, such as role="menu" without arrow-key support, is worse than plain buttons.

task

Build an accessible in .

Existing code or usage: (if empty, build from scratch with a minimal, typical API).

  1. Decide native or custom first, and state the decision:
  • dialog: use dialog with showModal(). It provides the top layer, an inert background and Escape for free.
  • disclosure: use details and summary, or a button with aria-expanded and aria-controls.
  • listbox: use select unless options need rich content or multi-select with custom rendering.
  • menu: role="menu" is for app-style command menus. For site navigation or a list of links, build a disclosure with links instead, and say so.
  • combobox: a text input with a custom popup. datalist is acceptable only for simple suggestions.
  • tabs and tree have no native equivalent, so build them custom.
  1. If custom, implement the APG pattern completely:
  • The roles and their required owned elements (tablist and tab with tabpanel; tree, treeitem and group; combobox and listbox with option).
  • States kept in sync with the UI: aria-expanded, aria-selected, aria-checked, aria-activedescendant, aria-controls, and aria-level, aria-setsize and aria-posinset when items are virtualised.
  • Accessible names for the widget and each item.
  • One Tab stop for composite widgets, using roving tabindex or aria-activedescendant, with the APG keyboard model: arrow keys, Home and End, Escape, Enter and Space, and type-ahead where the pattern specifies it.
  • Focus management on open and close: where focus goes, and where it returns.
  1. For tabs, choose automatic or manual activation and justify it (manual when showing a panel is slow). For combobox, implement the ARIA 1.2 pattern, where role="combobox" sits on the input itself and aria-autocomplete matches the actual behaviour.
  2. Reuse the project's existing components and styles. Make focus visible.
  3. Write tests that query by role and accessible name (Testing Library style or the framework's equivalent), assert state attributes after interactions, and drive the keyboard model.
constraints
  • Do not add ARIA that duplicates native semantics, such as role="button" on a button.
  • Do not use aria-hidden="true" on anything focusable.
  • If is the wrong pattern for the described use, say so, recommend the right one, and build that instead.
  • Read the relevant code before making a claim about it. Do not guess what a file, function or config contains.
  • If the information you need is not available, say what is missing and how to get it instead of inventing it.
output format

Native or custom

The decision and why, in two or three sentences.

Keyboard

| Key | Context | Result |

Roles states and properties

| Element | Role | Attributes and when they change |

Code

Each file in its own code block, headed by its path.

Tests

Code, then one line per test.

Manual checks

A short list to verify with NVDA plus Firefox or Chrome, and with VoiceOver plus Safari: what should be announced on focus and after each action.

1 required value still a placeholder; the assistant will ask for it.

details

kind
Prompt: a task you run by name to get one finished thing back
domain
Software engineering
category
Accessibility
level
Expert
made for
Frontend engineer, Full-stack engineer
needs
repo-read, file-write
risk
edits-files
version
v1.0.0 · incubating
reviewed
2026-10-02
works in
Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Antigravity, OpenCode, Windsurf, Zed, Continue, AGENTS.md

Edit on GitHubReport a problem

use in

Hodios CLI
npx @hermes-hq/hodios install build-aria-widget --target claude-code
Agent Skills
npx skills add hermes-hq/hodios-dist --skill build-aria-widget -a claude-code
Add the Hodios marketplace (once)
claude plugin marketplace add hermes-hq/hodios-dist
Install the software-engineering plugin
claude plugin install hodios-software-engineering@hodios

The plugin brings every entry in this domain at once.

pairs well with

All of Accessibility
PersonaAccessibility

Accessibility specialist

Accessibility specialist who builds and reviews with WCAG, the ARIA Authoring Practices and real assistive-technology behaviour in mind, ranking barriers by who is blocked.

accessibility-specialist
PromptAccessibility

Fix keyboard navigation in a component

Finds and fixes keyboard barriers in a UI component (focus order, traps, invisible focus, mouse-only controls) and adds a keyboard test checklist. Use when a widget fails without a mouse.

fix-keyboard-navigation
PromptAccessibility

Write a screen-reader test plan

Writes a manual screen-reader test script for a user flow on NVDA, JAWS, VoiceOver or TalkBack, with keystrokes and expected announcements per step. Use before releasing a key flow.

write-screen-reader-test-plan
PromptAccessibility

Audit a mobile screen for accessibility

Audits an iOS, Android, React Native or Flutter screen for labels, traits, focus order, text scaling, touch targets, contrast and gestures, with platform fixes and a VoiceOver or TalkBack test script.

audit-mobile-accessibility
PromptAccessibility

Audit web accessibility against WCAG 2.2

Audits markup or components against WCAG 2.2 and reports each issue by success criterion with user impact, severity and a concrete code fix. Use before a release or a compliance review.

audit-web-accessibility
PromptAccessibility

Build or fix an accessible form

Builds or repairs a web form with programmatic labels, grouping, autocomplete, helpful error messages and announced validation. Use for sign-up, checkout, settings or any data-entry form.

fix-form-accessibility