Unverified Commit b227df30 authored by hangyu's avatar hangyu Committed by GitHub

Hint text semantics to be excluded in a11y read out if hintText is not visible. (#119198)

* Update input_decorator.dart

* Update text_field_test.dart

* Update time_picker.dart

Update time_picker.dart
parent 6c12e399
...@@ -2193,7 +2193,6 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat ...@@ -2193,7 +2193,6 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
opacity: (isEmpty && !_hasInlineLabel) ? 1.0 : 0.0, opacity: (isEmpty && !_hasInlineLabel) ? 1.0 : 0.0,
duration: _kTransitionDuration, duration: _kTransitionDuration,
curve: _kTransitionCurve, curve: _kTransitionCurve,
alwaysIncludeSemantics: isEmpty || (decoration.labelText == null && decoration.label == null),
child: Text( child: Text(
hintText, hintText,
style: hintStyle, style: hintStyle,
......
...@@ -2050,12 +2050,9 @@ class _HourMinuteTextFieldState extends State<_HourMinuteTextField> with Restora ...@@ -2050,12 +2050,9 @@ class _HourMinuteTextFieldState extends State<_HourMinuteTextField> with Restora
final InputDecorationTheme inputDecorationTheme = timePickerTheme.inputDecorationTheme ?? defaultTheme.inputDecorationTheme; final InputDecorationTheme inputDecorationTheme = timePickerTheme.inputDecorationTheme ?? defaultTheme.inputDecorationTheme;
InputDecoration inputDecoration = const InputDecoration().applyDefaults(inputDecorationTheme); InputDecoration inputDecoration = const InputDecoration().applyDefaults(inputDecorationTheme);
// If screen reader is in use, make the hint text say hours/minutes. // Remove the hint text when focused because the centered cursor
// Otherwise, remove the hint text when focused because the centered cursor
// appears odd above the hint text. // appears odd above the hint text.
final String? hintText = MediaQuery.accessibleNavigationOf(context) || View.of(context).platformDispatcher.semanticsEnabled final String? hintText = focusNode.hasFocus ? null : _formattedValue;
? widget.semanticHintText
: (focusNode.hasFocus ? null : _formattedValue);
// Because the fill color is specified in both the inputDecorationTheme and // Because the fill color is specified in both the inputDecorationTheme and
// the TimePickerTheme, if there's one in the user's input decoration theme, // the TimePickerTheme, if there's one in the user's input decoration theme,
...@@ -2102,6 +2099,8 @@ class _HourMinuteTextFieldState extends State<_HourMinuteTextField> with Restora ...@@ -2102,6 +2099,8 @@ class _HourMinuteTextFieldState extends State<_HourMinuteTextField> with Restora
data: MediaQuery.of(context).copyWith(textScaleFactor: 1), data: MediaQuery.of(context).copyWith(textScaleFactor: 1),
child: UnmanagedRestorationScope( child: UnmanagedRestorationScope(
bucket: bucket, bucket: bucket,
child: Semantics(
label: widget.semanticHintText,
child: TextFormField( child: TextFormField(
restorationId: 'hour_minute_text_form_field', restorationId: 'hour_minute_text_form_field',
autofocus: widget.autofocus ?? false, autofocus: widget.autofocus ?? false,
...@@ -2125,6 +2124,7 @@ class _HourMinuteTextFieldState extends State<_HourMinuteTextField> with Restora ...@@ -2125,6 +2124,7 @@ class _HourMinuteTextFieldState extends State<_HourMinuteTextField> with Restora
), ),
), ),
), ),
),
); );
} }
} }
......
...@@ -6862,7 +6862,7 @@ void main() { ...@@ -6862,7 +6862,7 @@ void main() {
await tester.tap(find.byKey(key)); await tester.tap(find.byKey(key));
await tester.pump(); await tester.pump();
expect(node.label, 'label\nhint'); expect(node.label, 'label');
expect(node.value, ''); expect(node.value, '');
semantics.dispose(); semantics.dispose();
}); });
...@@ -6930,7 +6930,7 @@ void main() { ...@@ -6930,7 +6930,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('TextField semantics always include hint when no label is given', (WidgetTester tester) async { testWidgets('TextField semantics only include hint when it is visible', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
final TextEditingController controller = TextEditingController(text: 'value'); final TextEditingController controller = TextEditingController(text: 'value');
final Key key = UniqueKey(); final Key key = UniqueKey();
...@@ -6949,15 +6949,23 @@ void main() { ...@@ -6949,15 +6949,23 @@ void main() {
final SemanticsNode node = tester.getSemantics(find.byKey(key)); final SemanticsNode node = tester.getSemantics(find.byKey(key));
expect(node.label, 'hint'); expect(node.label, '');
expect(node.value, 'value'); expect(node.value, 'value');
// Focus text field. // Focus text field.
await tester.tap(find.byKey(key)); await tester.tap(find.byKey(key));
await tester.pump(); await tester.pump();
expect(node.label, 'hint'); expect(node.label, '');
expect(node.value, 'value'); expect(node.value, 'value');
// Clear the Text.
await tester.enterText(find.byType(TextField), '');
await tester.pumpAndSettle();
expect(node.value, '');
expect(node.label, 'hint');
semantics.dispose(); semantics.dispose();
}); });
...@@ -7698,7 +7706,7 @@ void main() { ...@@ -7698,7 +7706,7 @@ void main() {
expect(semantics, hasSemantics(TestSemantics.root( expect(semantics, hasSemantics(TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
TestSemantics.rootChild( TestSemantics.rootChild(
label: 'label\nhint', label: 'label',
id: 1, id: 1,
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
textSelection: const TextSelection(baseOffset: 0, extentOffset: 0), textSelection: const TextSelection(baseOffset: 0, extentOffset: 0),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment