Unverified Commit a31e0a43 authored by Parker Stromberg's avatar Parker Stromberg Committed by GitHub

Added time picker entry mode callback and tests (#87595)

parent e7df5ec5
......@@ -1786,6 +1786,9 @@ class _HourMinuteTextFieldState extends State<_HourMinuteTextField> with Restora
}
}
/// Signature for when the time picker entry mode is changed.
typedef EntryModeChangeCallback = void Function(TimePickerEntryMode);
/// A material design time picker designed to appear inside a popup dialog.
///
/// Pass this widget to [showDialog]. The value returned by [showDialog] is the
......@@ -1807,6 +1810,7 @@ class TimePickerDialog extends StatefulWidget {
this.minuteLabelText,
this.restorationId,
this.initialEntryMode = TimePickerEntryMode.dial,
this.onEntryModeChanged,
}) : assert(initialTime != null),
super(key: key);
......@@ -1852,6 +1856,9 @@ class TimePickerDialog extends StatefulWidget {
/// Flutter.
final String? restorationId;
/// Callback called when the selected entry mode is changed.
final EntryModeChangeCallback? onEntryModeChanged;
@override
State<TimePickerDialog> createState() => _TimePickerDialogState();
}
......@@ -1947,6 +1954,8 @@ class _TimePickerDialogState extends State<TimePickerDialog> with RestorationMix
final RestorableBoolN _autofocusMinute = RestorableBoolN(null);
final RestorableBool _announcedInitialTime = RestorableBool(false);
late final VoidCallback _entryModeListener;
@override
void didChangeDependencies() {
super.didChangeDependencies();
......@@ -1955,6 +1964,13 @@ class _TimePickerDialogState extends State<TimePickerDialog> with RestorationMix
_announceModeOnce();
}
@override
void initState() {
super.initState();
_entryModeListener = () => widget.onEntryModeChanged?.call(_entryMode.value);
_entryMode.addListener(_entryModeListener);
}
@override
String? get restorationId => widget.restorationId;
......@@ -2288,6 +2304,7 @@ class _TimePickerDialogState extends State<TimePickerDialog> with RestorationMix
void dispose() {
_vibrateTimer?.cancel();
_vibrateTimer = null;
_entryMode.removeListener(_entryModeListener);
super.dispose();
}
}
......@@ -2380,6 +2397,7 @@ Future<TimeOfDay?> showTimePicker({
String? hourLabelText,
String? minuteLabelText,
RouteSettings? routeSettings,
EntryModeChangeCallback? onEntryModeChanged,
}) async {
assert(context != null);
assert(initialTime != null);
......@@ -2396,6 +2414,7 @@ Future<TimeOfDay?> showTimePicker({
errorInvalidText: errorInvalidText,
hourLabelText: hourLabelText,
minuteLabelText: minuteLabelText,
onEntryModeChanged: onEntryModeChanged,
);
return showDialog<TimeOfDay>(
context: context,
......
......@@ -903,6 +903,34 @@ void _testsInput() {
expect(find.byType(TextField), findsNothing);
});
testWidgets('Switching to dial entry mode triggers entry callback', (WidgetTester tester) async {
bool triggeredCallback = false;
await mediaQueryBoilerplate(tester, true, entryMode: TimePickerEntryMode.input, onEntryModeChange: (TimePickerEntryMode mode) {
if (mode == TimePickerEntryMode.dial) {
triggeredCallback = true;
}
});
await tester.tap(find.byIcon(Icons.access_time));
await tester.pumpAndSettle();
expect(triggeredCallback, true);
});
testWidgets('Switching to input entry mode triggers entry callback', (WidgetTester tester) async {
bool triggeredCallback = false;
await mediaQueryBoilerplate(tester, true, entryMode: TimePickerEntryMode.dial, onEntryModeChange: (TimePickerEntryMode mode) {
if (mode == TimePickerEntryMode.input) {
triggeredCallback = true;
}
});
await tester.tap(find.byIcon(Icons.keyboard));
await tester.pumpAndSettle();
expect(triggeredCallback, true);
});
testWidgets('Can double tap hours (when selected) to enter input mode', (WidgetTester tester) async {
await mediaQueryBoilerplate(tester, false, entryMode: TimePickerEntryMode.dial);
final Finder hourFinder = find.ancestor(
......@@ -1163,6 +1191,7 @@ Future<void> mediaQueryBoilerplate(
String? minuteLabelText,
String? errorInvalidText,
bool accessibleNavigation = false,
EntryModeChangeCallback? onEntryModeChange,
}) async {
await tester.pumpWidget(
Localizations(
......@@ -1192,7 +1221,8 @@ Future<void> mediaQueryBoilerplate(
helpText: helpText,
hourLabelText: hourLabelText,
minuteLabelText: minuteLabelText,
errorInvalidText: errorInvalidText
errorInvalidText: errorInvalidText,
onEntryModeChanged: onEntryModeChange,
);
},
child: const Text('X'),
......
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