Run this list on every widget in the library and anything you build from it.
- It's a real element. Buttons are
<button>, links are<a href>. - It works with the keyboard. Tab reaches it, Enter or Space activates it, Escape closes it.
- Focus is visible. Never
outline: nonewithout a replacement. - It has a name. Icon-only controls get
aria-label. - State is announced. Toggles use
aria-pressedoraria-expanded; live updates go in anaria-liveregion. - Contrast holds at 4.5:1 for text in both themes.
- Touch targets are at least 40×40px.
- Motion respects
prefers-reduced-motion. - Nothing depends on hover to reveal essential content.
- User text is set with
textContent, neverinnerHTML.