docs(a11y): a11y migration docs for button#6177
Conversation
|
5t3ph
left a comment
There was a problem hiding this comment.
Overall, excellent as usual!
Please review in tandem to the a11y callouts in my PR, which I have updated slightly based on your document here.
|
|
||
| ## Overview | ||
|
|
||
| This doc describes how **`swc-button`** and a dedicated **`swc-link-button`** (or equivalent) should behave for **accessibility** in 2nd-gen, targeting **WCAG 2.2 Level AA**. It separates **actions** (`<button>` semantics) from **navigation** (`<a href>` semantics), avoids the 1st-gen **proxy-click** pattern on a synthetic link, and aligns **pending / loading** treatment with Spectrum loading guidance ([Figma — Loading animation discovery](https://www.figma.com/design/42VzvpW262EAUbYsadO4e8/Loading-animation-discovery)) and internal **general / accessibility guidance** for loading indicators (delay before show, determinate vs indeterminate, placement, status announcements, and motion). |
There was a problem hiding this comment.
Are we ready to make a call to only use the class-based, semantic <a>, or are you still proposing creating swc-link-button?
It feels a little bit like this doc is emphasizing that distinction more than we need to since link semantics are already deprecated as of S1, so in reading this, it is a little hard to distinguish the purely button recommendations. Could we instead simply note that the decision to deprecate link semantics is firm?
We should continue to have documentation in Storybook to inform consumers that the button is not capable/suited to being a link, but as far as migrating the component, I think the intertwined concerns make it a bit difficult to understand this plan is for swc-button only.
There was a problem hiding this comment.
Are we ready to make a call to only use the class-based, semantic , or are you still proposing creating swc-link-button?
Let's table the swc-link-button. I removed it and all references to it from the scope of this doc. If we need it later, we can always make an epic and a doc for it.
|
|
||
| **`swc-button`** and **`swc-link-button`** hosts should **not** expose **`role="button"`** / **`role="link"`** while the real control is **`aria-hidden`** or unfocusable—1st-gen hid the anchor and set **`role="link"`** on the host, which breaks native link behavior; avoid the same for **`<button>`**. | ||
|
|
||
| ### Form-associated buttons (`submit` / `reset`) |
There was a problem hiding this comment.
Should we defer handling these button types for the button migration MVP to avoid bringing over the current S1 stop-gap proxy behavior?
There was a problem hiding this comment.
Yes. I updated this doc accordingly.
|
|
||
| **Pending state** | ||
|
|
||
| - Tree shows **button** or **link** still (unless replaced by different control); pending is **visual** + **name** / **live region**, not a nested **progressbar** masquerading as the control. |
There was a problem hiding this comment.
Should pending use aria-disabled="true" while still remaining focusable? That was some of the guidance from SWC-459 and also matches React's behavior
| | **`aria-disabled` on `<button>`** | Only when intentionally using **disabled semantics** that still allow **focus** (rare); prefer native **`disabled`** when the control should not be in tab order. Document differences in Storybook. | | ||
| | **Links and “disabled”** | Do **not** document **`aria-disabled`** on links as “disabled link”—**links are not semantically disabled**. Use a **button**, remove **`href`**, or change copy. | | ||
| | **Pending / loading (visual)** | Use an **animated progress icon** (e.g. looping SVG) **without** **`role="progressbar"`** on that graphic unless it truly represents **measurable** progress. **Do not** embed **`swc-progress-circle`** for button pending—that component is for **progressbar** semantics ([progress circle a11y doc](../progress-circle/accessibility-migration-analysis.md)). | | ||
| | **Pending / loading (name)** | Keep the control **named**: update **visible** label (“Saving…”), **`aria-label`**, or **`aria-labelledby`** so the **accessible name** reflects **in-progress** when helpful. Prefer **specific** strings (“Uploading document…”) over generic “Loading” when context allows (per loading a11y guidance). | |
There was a problem hiding this comment.
Should aria-labelledby be removed from this guidance due to cross-root issues?
There was a problem hiding this comment.
Yes. It should be removed now.
|
|
||
| **`swc-button`** | ||
|
|
||
| - Role: **button**; name from subtree, **`aria-label`**, or **`aria-labelledby`**. |
There was a problem hiding this comment.
Remove aria-labelledby here too?
| - [ ] **No proxy** `anchorElement.click()` from a **custom element** that is not the focused **link**; **hosts** do **not** use **`role="button"`** / **`role="link"`**; **focus** targets **native** `<button>` / `<a>` (delegation). | ||
| - [ ] **Link** docs state **no semantic disabled**; patterns for “unavailable navigation” documented without **`aria-disabled`** on `<a>`. | ||
| - [ ] **Pending** uses **animated icon**, not **`swc-progress-circle`**; announcements follow **polite** / **status** guidance; **no assertive** live region for default loading. | ||
| - [ ] **Initiating button** guidance: pending UX does **not** rely on **`aria-disabled="true"`** on the trigger if that would **block** understanding of in-flight work (align with design guidance). |
There was a problem hiding this comment.
Looking at the design guidance, I think there's a typo and this should be in reference to not using disabled as you have noted as well for "Initiating control during load"
…web-components into nikkimk/button-migration
📚 Branch Preview Links🔍 First Generation Visual Regression Test ResultsWhen a visual regression test fails (or has previously failed while working on this branch), its results can be found in the following URLs:
Deployed to Azure Blob Storage: If the changes are expected, update the |
5t3ph
left a comment
There was a problem hiding this comment.
LGTM! I'll work on updating the migration plan 👍
cdransf
left a comment
There was a problem hiding this comment.
A few comments and notes, but looks great! ✨
|
|
||
| --- | ||
|
|
||
| ## 1st-gen implementation notes (avoid in 2nd-gen) |
There was a problem hiding this comment.
Should this be a subsection inside of recommendations? ✨
| ## Related rules and skills | ||
|
|
||
| - **contributor-doc-update.md** — when to run `update-nav.js` after heading or structure changes. | ||
| - **contributor-doc-update.mdc** — when to run `update-nav.js` after heading or structure changes. |
There was a problem hiding this comment.
| - **contributor-doc-update.mdc** — when to run `update-nav.js` after heading or structure changes. | |
| - **contributor-doc-update.md** — when to run `update-nav.js` after heading or structure changes. |
| - **contributor-doc-update.mdc** — when to run `update-nav.js` after heading or structure changes. | ||
| - **component-migration-analysis** skill — for `rendering-and-styling-migration-analysis.md`, not this file. | ||
| - **stories-documentation.md** / **stories-format.md** — Storybook docs, separate from this contributor planning doc. | ||
| - **stories-documentation.mdc** / **stories-format.mdc** — Storybook docs, separate from this contributor planning doc. |
There was a problem hiding this comment.
| - **stories-documentation.mdc** / **stories-format.mdc** — Storybook docs, separate from this contributor planning doc. | |
| - **stories-documentation.md** / **stories-format.mdc** — Storybook docs, separate from this contributor planning doc. |
| - **Never** recommend **`aria-live="assertive"`** for loading or routine progress. | ||
| - Treat **`aria-live="polite"`** as **rare**: polite regions still **queue** speech, and **several** components or regions updating together becomes **noisy** (bursts, backlog). Prefer **native role semantics** (e.g. **`progressbar`**) and **one** primary message for related loaders when possible. |
There was a problem hiding this comment.
I think we can remove these since we have comparable recommendations under Live regions and announcements. ✨
|
|
||
| - Verify behavior and ARIA in **2nd-gen source** before stating what the component exposes — do not document ARIA the code does not set | ||
| - Ask clarifying questions for uncertain mappings instead of guessing | ||
| - When the doc covers **progress**, **loading**, **busy**, or **spinner** UX, align guidance with Adobe’s Figma file **Loading animation discovery** ([Loading animation discovery](https://www.figma.com/design/42VzvpW262EAUbYsadO4e8/Loading-animation-discovery)); if you cite or rely on it in the doc body, **also** list that link under **`## References`** |
There was a problem hiding this comment.
The Figma docs'll be behind SSO, so we may want to move this guidance into the related ticket (I'm not sure how we'd best surface them to the assigned dev or distill it down for the agent?). ✨
Description
In spectrum-web-components/CONTRIBUTOR-DOCS/03_project-planning/03_components/button/accessibility-migration-analysis.md:
Motivation and context
The ticket requests accessibility recommendations for tabs as part of its migration from 1st-gen to 2nd-gen. The recommendations should produce a comprehensive set of accessibility requirements that the engineering team will use as the specification for the 2nd-gen implementation.
The 2nd-gen migration is an opportunity to address known accessibility gaps, align with the latest WAI-ARIA Authoring Practices, and ensure the component meets WCAG 2.2 AA compliance.
Related issue(s)
Screenshots (if appropriate)
Author's checklist
Reviewer's checklist
patch,minor, ormajorfeaturesManual review test cases
Review the Button accessibility migration analysis