Badge puts role="status" on its root, so every badge on a page is an ARIA live region.
src/ui/badge/Badge.stx renders unconditionally:
<span class="" role="status">role="status" is an implicit aria-live="polite" region. A badge is almost always a static label on a row or a card, not a status message, and making each one a live region has two consequences:
- Any text change inside a badge is announced, even when the user's attention is elsewhere. A list that re-renders announces every badge in it.
- Live regions are meant to be few and deliberate. One page in our estate (statushq) has 126 badge-shaped elements; if those were all
<Badge>, the page would carry 126 polite live regions. Screen readers do not degrade gracefully here — the queue becomes unusable noise.
A badge that genuinely reports changing status does exist, which is why the role should be opt-in rather than removed outright.
Suggested fix
Add a live (or announce) prop, default false, and emit role="status" only when set:
<span class="" >Callers that want the announcement ask for it; the ordinary labelling case stays silent.
Found on @stacksjs/components 0.2.382. Context: we are adopting this family across six apps and Badge is otherwise ready — it is fully role-token based, 0 hard-coded palette values, and it already went through the #1993 token pass.