Skip to content

Read out text fields#2131

Open
oskardanielsson-yubico wants to merge 5 commits into
mainfrom
oskar/ID3
Open

Read out text fields#2131
oskardanielsson-yubico wants to merge 5 commits into
mainfrom
oskar/ID3

Conversation

@oskardanielsson-yubico
Copy link
Copy Markdown
Contributor

@oskardanielsson-yubico oskardanielsson-yubico commented Mar 31, 2026

Makes VoiceOver read out the text field. However this fix may not be optimal as it's not the most intuitive.
Issues:

@oskardanielsson-yubico oskardanielsson-yubico changed the title Oskar/id3 Read out text fields Mar 31, 2026
Comment thread lib/oath/views/add_account_page.dart Outdated
key: keys.issuerField,
controller: _issuerController,
autofocus: widget.credentialData == null,
//autofocus: widget.credentialData == null,
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.

I’m curious about the autofocus behaviour you're seeing. I ran a quick test with NVDA on Windows, and it successfully announced the label text upon focus. What screen reader are you using? If it’s a specific bug there, it would be nice if we can find a workaround that lets us keep autofocus enabled, for UX consistency.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Improves VoiceOver/screen reader behavior by adding explicit semantics to dialog titles and text fields so their labels/titles are announced more reliably.

Changes:

  • Wraps ResponsiveDialog titles in a Semantics widget for both fullscreen and dialog layouts.
  • Wraps AppTextField in a Semantics widget, using the input decoration’s labelText as the accessibility label.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
lib/widgets/responsive_dialog.dart Adds a helper to wrap dialog/app bar titles with Semantics to influence screen reader announcement.
lib/widgets/app_text_field.dart Wraps text fields with Semantics(label: ...) to encourage VoiceOver to announce the field label.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +67 to +68
Widget _wrapTitleWithSemantics(Widget? title) {
if (title == null) return const SizedBox.shrink();
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

_wrapTitleWithSemantics() returning a non-null widget for a null title changes behavior: AppBar/AlertDialog will now treat the title as present and can apply title padding/spacing even when the caller intended title: null (e.g., empty top padding in AlertDialog). Consider changing the helper to return Widget? and return null when title is null, and only wrap when non-null.

Suggested change
Widget _wrapTitleWithSemantics(Widget? title) {
if (title == null) return const SizedBox.shrink();
Widget? _wrapTitleWithSemantics(Widget? title) {
if (title == null) return null;

Copilot uses AI. Check for mistakes.

Widget _wrapTitleWithSemantics(Widget? title) {
if (title == null) return const SizedBox.shrink();
return Semantics(enabled: true, onTap: () {}, child: title);
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

The Semantics wrapper adds an onTap action with an empty callback. This will expose the title as an actionable element to assistive tech (often announced as a button) but tapping it does nothing, which is confusing and can fail accessibility expectations. Prefer making the title readable via semantics properties that don’t imply an action (e.g., header/focusable/label), or wire onTap to a real interaction if one exists.

Suggested change
return Semantics(enabled: true, onTap: () {}, child: title);
return Semantics(header: true, child: title);

Copilot uses AI. Check for mistakes.
Comment on lines +98 to +105
child: Semantics(
label: labelText,
enabled: true,
child: DefaultSelectionStyle(
selectionColor: decoration?.errorText != null
? Theme.of(context).colorScheme.error
: null,
child: this,
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

The Semantics wrapper forces enabled: true unconditionally. If the underlying TextField is disabled (enabled: false), screen readers will still treat it as enabled, which is incorrect. Remove enabled here or bind it to the TextField’s enabled state (and/or let TextField provide its own enabled semantics).

Copilot uses AI. Check for mistakes.
@fdennis
Copy link
Copy Markdown
Contributor

fdennis commented Apr 9, 2026

This is a bug in Flutter. See flutter/flutter#120779

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants