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

[Material] Time picker semantics updates (#67562)

parent ee08c227
......@@ -4,6 +4,7 @@
import 'dart:async';
import 'dart:math' as math;
import 'dart:ui' as ui;
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
......@@ -355,8 +356,7 @@ class _HourControl extends StatelessWidget {
);
return Semantics(
hint: localizations.timePickerHourModeAnnouncement,
value: formattedHour,
value: '${localizations.timePickerHourModeAnnouncement} $formattedHour',
excludeSemantics: true,
increasedValue: formattedNextHour,
onIncrease: () {
......@@ -445,8 +445,7 @@ class _MinuteControl extends StatelessWidget {
return Semantics(
excludeSemantics: true,
hint: localizations.timePickerMinuteModeAnnouncement,
value: formattedMinute,
value: '${localizations.timePickerMinuteModeAnnouncement} $formattedMinute',
increasedValue: formattedNextMinute,
onIncrease: () {
fragmentContext.onTimeChange(nextMinute);
......@@ -571,7 +570,8 @@ class _DayPeriodControl extends StatelessWidget {
child: InkWell(
onTap: Feedback.wrapForTap(() => _setAm(context), context),
child: Semantics(
selected: amSelected,
checked: amSelected,
inMutuallyExclusiveGroup: true,
button: true,
child: Center(
child: Text(
......@@ -589,7 +589,8 @@ class _DayPeriodControl extends StatelessWidget {
child: InkWell(
onTap: Feedback.wrapForTap(() => _setPm(context), context),
child: Semantics(
selected: pmSelected,
checked: pmSelected,
inMutuallyExclusiveGroup: true,
button: true,
child: Center(
child: Text(
......@@ -1673,7 +1674,10 @@ class _HourMinuteTextFieldState extends State<_HourMinuteTextField> {
// If screen reader is in use, make the hint text say hours/minutes.
// Otherwise, remove the hint text when focused because the centered cursor
// 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
: (focusNode.hasFocus ? null : _formattedValue);
inputDecoration = inputDecoration.copyWith(
......
......@@ -329,7 +329,13 @@ void _tests() {
includesNodeWith(
label: 'AM',
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(
......@@ -337,7 +343,12 @@ void _tests() {
includesNodeWith(
label: 'PM',
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() {
await mediaQueryBoilerplate(tester, true);
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');
expect(semantics.nodesWith(value: '07'), hasLength(1),
expect(semantics.nodesWith(value: 'Select hours 07'), hasLength(1),
reason: '07 appears once in the header');
expect(semantics, includesNodeWith(label: 'CANCEL'));
expect(semantics, includesNodeWith(label: 'OK'));
......@@ -394,7 +405,7 @@ void _tests() {
Future<void> actAndExpect({ String initialValue, SemanticsAction action, String finalValue }) async {
final SemanticsNode elevenHours = semantics.nodesWith(
value: initialValue,
value: 'Select hours $initialValue',
ancestor: tester.renderObject(_hourControl).debugSemantics,
).single;
tester.binding.pipelineOwner.semanticsOwner.performAction(elevenHours.id, action);
......@@ -460,7 +471,7 @@ void _tests() {
Future<void> actAndExpect({ String initialValue, SemanticsAction action, String finalValue }) async {
final SemanticsNode elevenHours = semantics.nodesWith(
value: initialValue,
value: 'Select minutes $initialValue',
ancestor: tester.renderObject(_minuteControl).debugSemantics,
).single;
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