Skip to content

fix(a11y): Role.Button on all bare clickables, TextField label link, split-tunnel double-action#59

Merged
iampedii merged 1 commit into
WhiteDNS:mainfrom
Danialsamadi:fix/wcag-aduit
Jun 21, 2026
Merged

fix(a11y): Role.Button on all bare clickables, TextField label link, split-tunnel double-action#59
iampedii merged 1 commit into
WhiteDNS:mainfrom
Danialsamadi:fix/wcag-aduit

Conversation

@Danialsamadi

@Danialsamadi Danialsamadi commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Builds on the TalkBack foundation from #45 to close the remaining WCAG 4.1.2 (Name, Role, Value — Level A) gaps found by a full audit of WhiteDnsScreen.kt.

  • Split-tunnel app row — replaced .clickable + active Checkbox(onCheckedChange) with toggleable(role = Role.Checkbox) + Checkbox(onCheckedChange = null, clearAndSetSemantics {}), matching the ParallelTestConfigRow pattern. Previously TalkBack focused on both the row and the checkbox separately, firing onToggle() twice.

  • ConnectButton — added role = Role.Button to .semantics(mergeDescendants = true) {} so TalkBack announces "Button" on the main action element.

  • 23 bare .clickable elements — added role = Role.Button to every custom interactive element that used .clickable {} or .clickable(enabled) without a declared role. Includes: expand/collapse headers, ProfileIconButton, CompactActionButton, ResolverActionButton, LogActionButton, SectionCard toggle header, dropdown triggers, dismiss/close buttons for banners and dialogs, the footer Telegram link, copy-address row, and stat cards.

  • WhiteDnsTextField label association — wrapped the Column(FieldLabel + BasicTextField) with semantics(mergeDescendants = true) so TalkBack announces the visible field label alongside the input field (WCAG 1.3.1 / 3.3.2).

  • SectionCard non-collapsible iconcontentDescription is now null when collapsible = false, eliminating noise for screen reader users on static section headers.

WCAG criteria addressed

Criterion Level Impact
4.1.2 Name, Role, Value — missing role on 23 clickables A High
4.1.2 Name, Role, Value — split-tunnel double action A Critical
4.1.2 Name, Role, Value — ConnectButton role A High
1.3.1 Info and Relationships — TextField label link A Moderate
4.1.2 Name, Role, Value — non-collapsible icon noise A Minor

Test plan

  • TalkBack: tap each interactive element and verify it announces "Button" (or "Checkbox" / "Switch" for toggles)
  • TalkBack: verify split-tunnel app rows toggle once per tap and announce checked/unchecked state
  • TalkBack: verify ConnectButton announces "Button" alongside its status label
  • TalkBack: verify text fields announce the visible label when focused
  • TalkBack: verify non-collapsible SectionCard headers are not announced as interactive
  • Visual regression: all elements look unchanged

🤖 Generated with Claude Code

…ls, split-tunnel double-action

- Replace split-tunnel app row .clickable + active Checkbox with
  toggleable(Role.Checkbox) + Checkbox(onCheckedChange=null,
  clearAndSetSemantics{}), matching the ParallelTestConfigRow pattern
- Add role=Role.Button to ConnectButton semantics block
- Add role=Role.Button to all 23 bare .clickable elements:
  expand/collapse headers, icon buttons, action buttons, close/dismiss
  buttons, footer link, dropdown triggers, stat cards, log buttons
- Wrap WhiteDnsTextField Column with semantics(mergeDescendants=true)
  so TalkBack announces the visible FieldLabel alongside the input
- Set SectionCard icon contentDescription=null when non-collapsible
  to eliminate meaningless noise for screen reader users

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

Copy link
Copy Markdown
Collaborator

@Danialsamadi Thank you for you MR.

@iampedii iampedii merged commit d17fe35 into WhiteDNS:main Jun 21, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants