Skip to content

[material_ui] Improve a11y_assessments use-case semantics for drawer, text fields, radio group, and checkbox - #13177

Open
kevmoo wants to merge 2 commits into
flutter:mainfrom
kevmoo:material-ui-a11y-assessments-use-cases
Open

kevmoo wants to merge 2 commits into
flutter:mainfrom
kevmoo:material-ui-a11y-assessments-use-cases

Conversation

@kevmoo

@kevmoo kevmoo commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Rationale

Six routes in the packages/material_ui/test_apps/a11y_assessments verification app had app-level widget configuration gaps that caused accessibility audits to report missing selection state, heading levels, input purpose (autocomplete), radio group labels, or coupled disabled checkbox state.

Summary of Changes

  • test_apps/a11y_assessments/lib/use_cases/drawer.dart:
    • Tracks _selectedIndex across the Drawer ListTile items and passes selected: _selectedIndex == 0|1|2 so the active item exposes selected state semantics (aria-current="true" / aria-selected="true").
  • test_apps/a11y_assessments/lib/use_cases/navigation_drawer.dart:
    • Wraps the NavigationDrawer 'Header' text in Semantics(container: true, headingLevel: 2) so it forms an explicit <h2> heading node inside the drawer's ListView.
  • test_apps/a11y_assessments/lib/use_cases/text_field.dart:
    • Adds keyboardType: TextInputType.emailAddress and autofillHints: const <String>[AutofillHints.email] to the @gmail.com suffix TextFields while preserving multi-line reflow (maxLines: null) when MediaQuery.textScalerOf(context).scale(1.0) > 1.0.
  • test_apps/a11y_assessments/lib/use_cases/text_field_password.dart:
    • Adds autofillHints: const <String>[AutofillHints.password] to the enabled and disabled password TextFields (WCAG 1.3.5).
  • test_apps/a11y_assessments/lib/use_cases/radio_list_tile.dart:
    • Migrates from deprecated per-tile groupValue/onChanged to RadioGroup<SingingCharacter> wrapped in Semantics(label: 'Singing character') (role="radiogroup" with group label and roving arrow-key navigation).
  • test_apps/a11y_assessments/lib/use_cases/check_box_list_tile.dart:
    • Decouples the disabled CheckboxListTile (value: false, onChanged: null) from the enabled checkbox's _checked state so toggling the enabled tile does not mutate the disabled tile's checked state.
  • test_apps/a11y_assessments/test/:
    • Adds widget test assertions in check_box_list_tile_test.dart, drawer_test.dart, navigation_drawer_test.dart, radio_list_tile_test.dart, text_field_test.dart, and text_field_password_test.dart.

Verification

  • Executed flutter test across all modified use-case test suites in packages/material_ui/test_apps/a11y_assessments/test/ (20 tests passed, 0 failures).
  • Verified live DOM and AXTree semantics across all 8 routes in headless Chrome via a11y_web_probe.py.

Pre-Adoption Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene page, which explains my responsibilities.
  • I read and followed the relevant style guides and ran the auto-formatter.
  • I signed the CLA.
  • The title of the PR starts with the name of the package surrounded by square brackets, e.g. [shared_preferences]
  • I updated pubspec.yaml with an appropriate new version according to the pub versioning philosophy, or I have added a pending_changelogs/ YAML file.
  • I updated CHANGELOG.md to add a description of the change, following repositoryCHANGELOG style, or I have added a pending_changelogs/ YAML file.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is test-exempt.
  • All existing and new tests are passing.

… text fields, radio group, and checkbox

- Track selected state on Drawer ListTile items in drawer.dart.
- Add container: true to Semantics(headingLevel: 2) on NavigationDrawer 'Header' in navigation_drawer.dart.
- Add AutofillHints.email and AutofillHints.password to text_field.dart and text_field_password.dart.
- Migrate radio_list_tile.dart to RadioGroup with Semantics group label.
- Decouple disabled CheckboxListTile state in check_box_list_tile.dart.
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Oct 9, 2026
@github-actions github-actions Bot added p: material_ui triage-design Should be looked at in design triage labels Oct 9, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request improves accessibility semantics and configuration across several use cases in the a11y_assessments test application, including CheckboxListTile, Drawer, NavigationDrawer, RadioListTile, TextField, and TextFieldPassword, along with updating their corresponding tests. Feedback on the changes suggests removing TextInputType.visiblePassword from the password text fields where obscureText is true, as using it is contradictory and the default keyboard type should be used instead to ensure secure input handling.

Comment on lines +38 to +39
keyboardType: TextInputType.visiblePassword,
autofillHints: <String>[AutofillHints.password],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

Using TextInputType.visiblePassword when obscureText is true is contradictory. TextInputType.visiblePassword is intended for passwords that are meant to be visible (i.e., when obscureText is false). When obscureText is true, the default keyboard type (TextInputType.text) should be used to ensure that the system keyboard correctly treats the input as a secure password field (e.g., disabling suggestions, learning, and clipboard history).

Suggested change
keyboardType: TextInputType.visiblePassword,
autofillHints: <String>[AutofillHints.password],
autofillHints: <String>[AutofillHints.password],

Comment on lines +45 to +46
keyboardType: TextInputType.visiblePassword,
autofillHints: <String>[AutofillHints.password],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

Using TextInputType.visiblePassword when obscureText is true is contradictory. TextInputType.visiblePassword is intended for passwords that are meant to be visible (i.e., when obscureText is false). When obscureText is true, the default keyboard type (TextInputType.text) should be used to ensure that the system keyboard correctly treats the input as a secure password field (e.g., disabling suggestions, learning, and clipboard history).

Suggested change
keyboardType: TextInputType.visiblePassword,
autofillHints: <String>[AutofillHints.password],
autofillHints: <String>[AutofillHints.password],

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD p: material_ui triage-design Should be looked at in design triage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant