Unverified Commit bbf1b557 authored by Rami's avatar Rami Committed by GitHub

[Material] Time picker semantics updates (#67562)

parent ee08c227
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:math' as math; import 'dart:math' as math;
import 'dart:ui' as ui;
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
...@@ -355,8 +356,7 @@ class _HourControl extends StatelessWidget { ...@@ -355,8 +356,7 @@ class _HourControl extends StatelessWidget {
); );
return Semantics( return Semantics(
hint: localizations.timePickerHourModeAnnouncement, value: '${localizations.timePickerHourModeAnnouncement} $formattedHour',
value: formattedHour,
excludeSemantics: true, excludeSemantics: true,
increasedValue: formattedNextHour, increasedValue: formattedNextHour,
onIncrease: () { onIncrease: () {
...@@ -445,8 +445,7 @@ class _MinuteControl extends StatelessWidget { ...@@ -445,8 +445,7 @@ class _MinuteControl extends StatelessWidget {
return Semantics( return Semantics(
excludeSemantics: true, excludeSemantics: true,
hint: localizations.timePickerMinuteModeAnnouncement, value: '${localizations.timePickerMinuteModeAnnouncement} $formattedMinute',
value: formattedMinute,
increasedValue: formattedNextMinute, increasedValue: formattedNextMinute,
onIncrease: () { onIncrease: () {
fragmentContext.onTimeChange(nextMinute); fragmentContext.onTimeChange(nextMinute);
...@@ -571,7 +570,8 @@ class _DayPeriodControl extends StatelessWidget { ...@@ -571,7 +570,8 @@ class _DayPeriodControl extends StatelessWidget {
child: InkWell( child: InkWell(
onTap: Feedback.wrapForTap(() => _setAm(context), context), onTap: Feedback.wrapForTap(() => _setAm(context), context),
child: Semantics( child: Semantics(
selected: amSelected, checked: amSelected,
inMutuallyExclusiveGroup: true,
button: true, button: true,
child: Center( child: Center(
child: Text( child: Text(
...@@ -589,7 +589,8 @@ class _DayPeriodControl extends StatelessWidget { ...@@ -589,7 +589,8 @@ class _DayPeriodControl extends StatelessWidget {
child: InkWell( child: InkWell(
onTap: Feedback.wrapForTap(() => _setPm(context), context), onTap: Feedback.wrapForTap(() => _setPm(context), context),
child: Semantics( child: Semantics(
selected: pmSelected, checked: pmSelected,
inMutuallyExclusiveGroup: true,
button: true, button: true,
child: Center( child: Center(
child: Text( child: Text(
...@@ -1673,7 +1674,10 @@ class _HourMinuteTextFieldState extends State<_HourMinuteTextField> { ...@@ -1673,7 +1674,10 @@ class _HourMinuteTextFieldState extends State<_HourMinuteTextField> {
// If screen reader is in use, make the hint text say hours/minutes. // If screen reader is in use, make the hint text say hours/minutes.
// Otherwise, 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.of(context)!.accessibleNavigation //
// TODO(rami-a): Once https://github.com/flutter/flutter/issues/67571 is
// resolved, remove the window check for semantics being enabled on web.
final String? hintText = MediaQuery.of(context)!.accessibleNavigation || ui.window.semanticsEnabled
? widget.semanticHintText ? widget.semanticHintText
: (focusNode.hasFocus ? null : _formattedValue); : (focusNode.hasFocus ? null : _formattedValue);
inputDecoration = inputDecoration.copyWith( inputDecoration = inputDecoration.copyWith(
......
...@@ -329,7 +329,13 @@ void _tests() { ...@@ -329,7 +329,13 @@ void _tests() {
includesNodeWith( includesNodeWith(
label: 'AM', label: 'AM',
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap],
flags: <SemanticsFlag>[SemanticsFlag.isButton, SemanticsFlag.isSelected, SemanticsFlag.isFocusable], flags: <SemanticsFlag>[
SemanticsFlag.isButton,
SemanticsFlag.isChecked,
SemanticsFlag.isInMutuallyExclusiveGroup,
SemanticsFlag.hasCheckedState,
SemanticsFlag.isFocusable,
],
), ),
); );
expect( expect(
...@@ -337,7 +343,12 @@ void _tests() { ...@@ -337,7 +343,12 @@ void _tests() {
includesNodeWith( includesNodeWith(
label: 'PM', label: 'PM',
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap],
flags: <SemanticsFlag>[SemanticsFlag.isButton, SemanticsFlag.isFocusable], flags: <SemanticsFlag>[
SemanticsFlag.isButton,
SemanticsFlag.isInMutuallyExclusiveGroup,
SemanticsFlag.hasCheckedState,
SemanticsFlag.isFocusable,
],
), ),
); );
...@@ -349,9 +360,9 @@ void _tests() { ...@@ -349,9 +360,9 @@ void _tests() {
await mediaQueryBoilerplate(tester, true); await mediaQueryBoilerplate(tester, true);
expect(semantics, isNot(includesNodeWith(label: ':'))); expect(semantics, isNot(includesNodeWith(label: ':')));
expect(semantics.nodesWith(value: '00'), hasLength(1), expect(semantics.nodesWith(value: 'Select minutes 00'), hasLength(1),
reason: '00 appears once in the header'); reason: '00 appears once in the header');
expect(semantics.nodesWith(value: '07'), hasLength(1), expect(semantics.nodesWith(value: 'Select hours 07'), hasLength(1),
reason: '07 appears once in the header'); reason: '07 appears once in the header');
expect(semantics, includesNodeWith(label: 'CANCEL')); expect(semantics, includesNodeWith(label: 'CANCEL'));
expect(semantics, includesNodeWith(label: 'OK')); expect(semantics, includesNodeWith(label: 'OK'));
...@@ -394,7 +405,7 @@ void _tests() { ...@@ -394,7 +405,7 @@ void _tests() {
Future<void> actAndExpect({ String initialValue, SemanticsAction action, String finalValue }) async { Future<void> actAndExpect({ String initialValue, SemanticsAction action, String finalValue }) async {
final SemanticsNode elevenHours = semantics.nodesWith( final SemanticsNode elevenHours = semantics.nodesWith(
value: initialValue, value: 'Select hours $initialValue',
ancestor: tester.renderObject(_hourControl).debugSemantics, ancestor: tester.renderObject(_hourControl).debugSemantics,
).single; ).single;
tester.binding.pipelineOwner.semanticsOwner.performAction(elevenHours.id, action); tester.binding.pipelineOwner.semanticsOwner.performAction(elevenHours.id, action);
...@@ -460,7 +471,7 @@ void _tests() { ...@@ -460,7 +471,7 @@ void _tests() {
Future<void> actAndExpect({ String initialValue, SemanticsAction action, String finalValue }) async { Future<void> actAndExpect({ String initialValue, SemanticsAction action, String finalValue }) async {
final SemanticsNode elevenHours = semantics.nodesWith( final SemanticsNode elevenHours = semantics.nodesWith(
value: initialValue, value: 'Select minutes $initialValue',
ancestor: tester.renderObject(_minuteControl).debugSemantics, ancestor: tester.renderObject(_minuteControl).debugSemantics,
).single; ).single;
tester.binding.pipelineOwner.semanticsOwner.performAction(elevenHours.id, action); tester.binding.pipelineOwner.semanticsOwner.performAction(elevenHours.id, action);
......
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