Skip to content

a11y(4.1.2): fix nested interactive elements in Copyable component#3558

Merged
ardiewen merged 2 commits into
mainfrom
wcag/4.1.2-copyable-nested-interactive
Jul 13, 2026
Merged

a11y(4.1.2): fix nested interactive elements in Copyable component#3558
ardiewen merged 2 commits into
mainfrom
wcag/4.1.2-copyable-nested-interactive

Conversation

@rosanusi

Copy link
Copy Markdown
Contributor

Summary

  • Replaces outer <button> wrapper in clickAllToCopy mode with a <div class="group">, moving the click-to-copy action into an inner <button> sibling of CopyButton
  • Eliminates nested interactive elements (button inside button), which violates WCAG 2.2 SC 4.1.2 (Name, Role, Value)
  • The inner button gets aria-label={\Copy ${content}`}` so screen readers announce it meaningfully
  • The group class stays on the <div>, so group-hover:visible / group-focus-within:visible Tailwind utilities continue to work for the CopyButton reveal
  • No consumer changes required — the fix is entirely within the primitive

Test plan

  • Verify clickAllToCopy mode renders <div> wrapping two sibling buttons (no button-in-button)
  • Tab to the inner copy button and confirm screen reader announces "Copy [content]"
  • Hover over the component and confirm CopyButton becomes visible via group-hover:visible
  • Focus the inner button and confirm CopyButton stays visible via group-focus-within:visible
  • Click the inner button and confirm content is copied to clipboard

A11y-Audit-Ref: 4.1.2-copyable-nested-interactive

🤖 Generated with Claude Code

Replaces outer <button> wrapper in clickAllToCopy mode with a <div>,
moving click-to-copy into an inner <button> sibling of CopyButton.
Eliminates WCAG 2.2 SC 4.1.2 violation (button inside button).

A11y-Audit-Ref: 4.1.2-copyable-nested-interactive

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
holocene Ready Ready Preview, Comment Jul 13, 2026 4:27pm

Request Review

@rosanusi rosanusi marked this pull request as ready for review June 12, 2026 15:34
@rosanusi rosanusi requested a review from a team as a code owner June 12, 2026 15:34
@ardiewen ardiewen changed the title [a11y] Fix nested interactive elements in Copyable component (WCAG 4.1.2) a11y(4.1.2): fix nested interactive elements in Copyable component Jul 6, 2026
@github-actions github-actions Bot added a11y Accessibility audit PR a11y:bucket-3 Bucket 3: engineer required a11y:sc-4.1.2 labels Jul 6, 2026
- Only apply the `Copy ${content}` aria-label for the default slot.
  With a custom slot (e.g. cloud-ui api-key-details renders "ID: {id}"
  while content is just the id), the hardcoded label dropped the visible
  text and broke SC 2.5.3 Label in Name. Falling back to undefined lets
  the slot text name the button, as it did before this PR.
- Hoist the shared <div> wrapper and <CopyButton> out of the if/else;
  both branches were identical apart from the slot wrapping.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ardiewen

Copy link
Copy Markdown
Contributor

Reviewed + verified in-browser (workflow header, long ID). Confirmed via the a11y tree that the button-in-button is gone and the copy button is properly named. Truncation is unchanged before/after (no regression). Pushed two follow-ups:

  • aria-label guard for custom slotsaria-label={$$slots.default ? undefined : \Copy ${content}`}. The hardcoded label broke SC 2.5.3 for custom slots (e.g. cloud-ui api-key-detailsshows "ID: {id}" whilecontent` is just the id); now the slot text names the button, as before.
  • Dedupe — hoisted the shared <div> wrapper and <CopyButton> out of the if/else.

Separately filed DT-4259: copy-success isn't announced reliably (no aria-live region — it relies on the CopyButton's icon <title> flipping, which is VoiceOver-only and silent for the content button). Pre-existing in the primitive, out of scope here.

@ardiewen ardiewen merged commit 8b384a4 into main Jul 13, 2026
17 checks passed
@ardiewen ardiewen deleted the wcag/4.1.2-copyable-nested-interactive branch July 13, 2026 16:49
rossedfort added a commit that referenced this pull request Jul 13, 2026
Auto-generated version bump from 2.52.0 to 2.52.1

Bump type: patch

Changes included:
- [`3be0df00`](3be0df0) fix(schedules): default absent second/minute/hour to 0 when editing (#3653)
- [`508b65b7`](508b65b) fix(schedules): default emptied second/minute/hour to 0 on submit (#3655)
- [`1f0e149c`](1f0e149) fix(workers): reject $LATEST qualifier in Lambda ARN validation (#3657)
- [`b42b0776`](b42b077) a11y(2.4.3): inert-based focus containment + restore; drop trap from native dialogs (#3598)
- [`cc491a29`](cc491a2) a11y(2.4.3): keep toast live region announcing during a focus trap [DT-4252] (#3654)
- [`ddc7f8e2`](ddc7f8e) a11y(2.4.11): add scroll-padding so sticky overlays don't obscure focused elements (#3532)
- [`b7e3a472`](b7e3a47) FilterBar icon update (#3660)
- [`09318ec6`](09318ec) Add danger PR comment for api version bump (#3662)
- [`273cc4be`](273cc4b) a11y(4.1.2): add label prop to Button primitive and enforce accessible names (#3556)
- [`4507115f`](4507115) Use an editable combobox for the Cloud Run region field (DT-4232) (#3636)
- [`694a7471`](694a747) a11y(1.4.13): migrate saved-query nav tooltips to Tooltip primitive (#3607)
- [`8b384a40`](8b384a4) a11y(4.1.2): fix nested interactive elements in Copyable component (#3558)
- [`1bfd2750`](1bfd275) fix describe SANO API requests to include runId parameter (#3661)
- [`ba18b43e`](ba18b43) a11y(4.1.2): require label on CodeBlock primitive; add aria-readonly for read-only mode (#3557)
- [`6e2290f1`](6e2290f) feat(deployments): make compute provider picker configurable (#3659)
- [`4470b76a`](4470b76) fix(workers): persist WDV compute-config edits via update mask; revert $LATEST validation (#3658)
- [`17fd591b`](17fd591) fix(nexus-operations): make start standalone nexus operation timeouts optional (#3656)

Co-authored-by: rossedfort <11775628+rossedfort@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a11y:bucket-3 Bucket 3: engineer required a11y:sc-4.1.2 a11y Accessibility audit PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants