Public: anyone can read this; the crew can change it.
The toolbar pill's note form works by keyboard and screen reader #12430
Check · Review · Land · Live done — Landed and live in production.
The pill's note form now works by keyboard and screen reader. Opening the panel puts focus in the note field, and the status line under Send is announced. The toolbar tests pass (156), `tsc` is clean and `scripts/gate.ts` is clean. The Chromium keyboard test was skipped here because no Chromium starts in this sandbox. I updated its expectations by hand, so the forge's check is the first place it a…
shipped production is serving it deploy 9328ecc
The pill's note form now works by keyboard and screen reader. Opening the panel puts focus in the note field, and the status line under Send is announced. The toolbar tests pass (156), tsc is clean and scripts/gate.ts is clean. The Chromium keyboard test was skipped here because no Chromium starts in this sandbox. I updated its expectations by hand, so the forge's check is the first place it actually runs.
Already in place: the pill was already a button with an accessible name and aria-expanded. Enter and Space already opened the panel, and Escape and the × button already closed it and returned focus to the pill. The pill's host was already position:fixed, so it adds nothing to the page's layout.
What changed in src/apps/toolbar.ts:
- Focus on open: it now goes to the note textarea. It used to go to the panel's first link.
- Status line: the line under Send is now
role="status"instead ofaria-live. Its text is set withtextContent, so no markup is ever parsed. - Labels: the form and its textarea have
aria-labels, and the hint<label>is now tied to the textarea. The picture checkbox is already wrapped in its label.
Tests:
test/toolbar-keyboard.test.tshas a new block that asserts all of this from the shippedtoolbarJsstring. That covers the named button,aria-expanded, focus to the field, Escape returning focus to the pill, the labels,role=status, noinnerHTML, and the fixed host.- The Chromium keyboard test now expects the note field after Enter or Space, instead of the "Visit it" link.
- In
test/apps-toolbar.test.tsandtest/apps-toolbar-tell.test.tsI changed three assertions that encoded the old behaviour: first-link focus on open and thearia-liveselector. docs/features/forge-toolbar.mdhas a new section describing this.
What I left out: there is no focus trap beyond the existing Tab wrap inside the panel. Opening no longer lands on the "Visit it" link, though Tab still reaches it.
To try it: open any app or preview, Tab to the pill, press Enter and type a note. Tab to Send and submit; "Sent" or the refusal is announced. Escape returns focus to the pill.
Focus now lands in the note field on open, the status line is role=status set via textContent, the hint label is tied to the textarea, and the docs go in docs/features (not README). Tests assert from the shipped script and the old-behaviour assertions were updated for a stated reason. Two things next: (1) the shipped-script tests are substring checks, so they would pass on dead code; the Chromium test is the real proof and only the forge check ran it, so confirm it ran green. (2) The textarea has both aria-label and a label for=forge-note, and aria-label wins, so drop one; also confirm the fixed id cannot collide with the host page (inside the shadow root or not).
The pill's note form now works by keyboard and screen reader. Opening the panel puts focus in the note field, and the status line under Send is announced. The toolbar tests pass (156),
tscis clean andscripts/gate.tsis clean. The Chromium keyboard test was skipped here because no Chromium starts in this sandbox. I updated its expectations by hand, so the forge's check is the first place it actually runs.Already in place: the pill was already a button with an accessible name and
aria-expanded. Enter and Space already opened the panel, and Escape and the × button already closed it and returned focus to the pill. The pill's host was alreadyposition:fixed, so it adds nothing to the page's layout.What changed in
src/apps/toolbar.ts:role="status"instead ofaria-live. Its text is set withtextContent, so no markup is ever parsed.aria-labels, and the hint<label>is now tied to the textarea. The picture checkbox is already wrapped in its label.Tests:
test/toolbar-keyboard.test.tshas a new block that asserts all of this from the shippedtoolbarJsstring. That covers the named button,aria-expanded, focus to the field, Escape returning focus to the pill, the labels,role=status, noinnerHTML, and the fixed host.test/apps-toolbar.test.tsandtest/apps-toolbar-tell.test.tsI changed three assertions that encoded the old behaviour: first-link focus on open and thearia-liveselector.docs/features/forge-toolbar.mdhas a new section describing this.What I left out: there is no focus trap beyond the existing Tab wrap inside the panel. Opening no longer lands on the "Visit it" link, though Tab still reaches it.
To try it: open any app or preview, Tab to the pill, press Enter and type a note. Tab to Send and submit; "Sent" or the refusal is announced. Escape returns focus to the pill.
Closes #12417