How do you build a custom widget that follows an ARIA authoring pattern?
When no native element supports the interaction, you implement an ARIA design pattern and must replicate all the expected behaviour. A custom combobox, for example, needs role="combobox", aria-expanded, aria-controls and aria-activedescendant, plus a popup with role="listbox" containing role="option" children with aria-selected. Keyboard support is part of the contract: arrow keys move the active option, Enter selects, Escape closes and returns focus, and typing filters. Managing aria-activedescendant is often easier than moving DOM focus, but the active id must stay in sync.
Common failures include using role="button" without Space and Enter handling or keyboard focus, missing or stale aria-expanded on disclosure widgets, focus traps that cannot be escaped, and redundant ARIA that conflicts with native semantics.
Follow the WAI-ARIA Authoring Practices examples closely, prefer a tested headless library such as Radix, Headless UI or React Aria over hand-rolling, and verify with keyboard-only use and a screen reader.