fix(a11y): give every wa-dialog an accessible name
Eleven dialogs passed a `label` that never reached the accessibility
tree: Web Awesome renders it into an <h2 id="title"> in the same shadow
root as the native <dialog> and never points aria-labelledby at it, so
getByRole('dialog', {name}) matched nothing and a screen reader
announced an unnamed dialog. a11y.md lists all of them under "what is
already correct".
utils/name-dialog.ts sets the IDREF, with aria-label as the fallback for
without-header (first-run-wizard), called from each host's updated().
aria-labelledby rather than aria-label because three call sites compute
their label at render time, and the heading re-renders anyway. It waits
for the dialog's own first update: wa-dialog populates its shadow root
in its own update, so a query at the host's firstUpdated names nothing.
Reaching into another library's open shadow root is deliberate and the
failure is bounded — if the structure moves, the query misses and the
dialog is as unnamed as it was.
This commit is contained in:
@@ -21,6 +21,7 @@ import { customElement, query, state } from 'lit/decorators.js';
|
||||
import '@awesome.me/webawesome/dist/components/dialog/dialog.js';
|
||||
|
||||
import { designTokens } from '../../styles/tokens.css';
|
||||
import { nameDialogsIn } from '../../utils/name-dialog';
|
||||
import {
|
||||
SHORTCUT_CATEGORIES,
|
||||
SHORTCUT_META,
|
||||
@@ -158,6 +159,15 @@ export class ShortcutsOverlay extends LitElement {
|
||||
this.isOpen = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Web Awesome renders `label` into a heading it never points the
|
||||
* `<dialog>` at, so the dialog has no accessible name until
|
||||
* something sets one. See `utils/name-dialog.ts`.
|
||||
*/
|
||||
override updated() {
|
||||
nameDialogsIn(this.shadowRoot);
|
||||
}
|
||||
|
||||
override render() {
|
||||
if (!this.isOpen) return nothing;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user