Unverified Commit 859b6ecd authored by Hasnen Tai's avatar Hasnen Tai Committed by GitHub

Feat: `showDatePicker` - Exposed callback when user changes Date Picker Mode (#119116)

parent eaae56ad
...@@ -164,6 +164,7 @@ Future<DateTime?> showDatePicker({ ...@@ -164,6 +164,7 @@ Future<DateTime?> showDatePicker({
String? fieldLabelText, String? fieldLabelText,
TextInputType? keyboardType, TextInputType? keyboardType,
Offset? anchorPoint, Offset? anchorPoint,
final ValueChanged<DatePickerEntryMode>? onDatePickerModeChange
}) async { }) async {
initialDate = DateUtils.dateOnly(initialDate); initialDate = DateUtils.dateOnly(initialDate);
firstDate = DateUtils.dateOnly(firstDate); firstDate = DateUtils.dateOnly(firstDate);
...@@ -202,6 +203,7 @@ Future<DateTime?> showDatePicker({ ...@@ -202,6 +203,7 @@ Future<DateTime?> showDatePicker({
fieldHintText: fieldHintText, fieldHintText: fieldHintText,
fieldLabelText: fieldLabelText, fieldLabelText: fieldLabelText,
keyboardType: keyboardType, keyboardType: keyboardType,
onDatePickerModeChange: onDatePickerModeChange,
); );
if (textDirection != null) { if (textDirection != null) {
...@@ -259,6 +261,7 @@ class DatePickerDialog extends StatefulWidget { ...@@ -259,6 +261,7 @@ class DatePickerDialog extends StatefulWidget {
this.fieldLabelText, this.fieldLabelText,
this.keyboardType, this.keyboardType,
this.restorationId, this.restorationId,
this.onDatePickerModeChange
}) : initialDate = DateUtils.dateOnly(initialDate), }) : initialDate = DateUtils.dateOnly(initialDate),
firstDate = DateUtils.dateOnly(firstDate), firstDate = DateUtils.dateOnly(firstDate),
lastDate = DateUtils.dateOnly(lastDate), lastDate = DateUtils.dateOnly(lastDate),
...@@ -356,6 +359,15 @@ class DatePickerDialog extends StatefulWidget { ...@@ -356,6 +359,15 @@ class DatePickerDialog extends StatefulWidget {
/// Flutter. /// Flutter.
final String? restorationId; final String? restorationId;
/// Called when the [DatePickerDialog] is toggled between
/// [DatePickerEntryMode.calendar],[DatePickerEntryMode.input].
///
/// An example of how this callback might be used is an app that saves the
/// user's preferred entry mode and uses it to initialize the
/// `initialEntryMode` parameter the next time the date picker is shown.
final ValueChanged<DatePickerEntryMode>? onDatePickerModeChange;
@override @override
State<DatePickerDialog> createState() => _DatePickerDialogState(); State<DatePickerDialog> createState() => _DatePickerDialogState();
} }
...@@ -394,16 +406,24 @@ class _DatePickerDialogState extends State<DatePickerDialog> with RestorationMix ...@@ -394,16 +406,24 @@ class _DatePickerDialogState extends State<DatePickerDialog> with RestorationMix
Navigator.pop(context); Navigator.pop(context);
} }
void _handleOnDatePickerModeChange() {
if (widget.onDatePickerModeChange != null) {
widget.onDatePickerModeChange!(_entryMode.value);
}
}
void _handleEntryModeToggle() { void _handleEntryModeToggle() {
setState(() { setState(() {
switch (_entryMode.value) { switch (_entryMode.value) {
case DatePickerEntryMode.calendar: case DatePickerEntryMode.calendar:
_autovalidateMode.value = AutovalidateMode.disabled; _autovalidateMode.value = AutovalidateMode.disabled;
_entryMode.value = DatePickerEntryMode.input; _entryMode.value = DatePickerEntryMode.input;
_handleOnDatePickerModeChange();
break; break;
case DatePickerEntryMode.input: case DatePickerEntryMode.input:
_formKey.currentState!.save(); _formKey.currentState!.save();
_entryMode.value = DatePickerEntryMode.calendar; _entryMode.value = DatePickerEntryMode.calendar;
_handleOnDatePickerModeChange();
break; break;
case DatePickerEntryMode.calendarOnly: case DatePickerEntryMode.calendarOnly:
case DatePickerEntryMode.inputOnly: case DatePickerEntryMode.inputOnly:
......
...@@ -20,6 +20,7 @@ void main() { ...@@ -20,6 +20,7 @@ void main() {
late SelectableDayPredicate? selectableDayPredicate; late SelectableDayPredicate? selectableDayPredicate;
late DatePickerEntryMode initialEntryMode; late DatePickerEntryMode initialEntryMode;
late DatePickerMode initialCalendarMode; late DatePickerMode initialCalendarMode;
late DatePickerEntryMode currentMode;
String? cancelText; String? cancelText;
String? confirmText; String? confirmText;
...@@ -56,6 +57,7 @@ void main() { ...@@ -56,6 +57,7 @@ void main() {
fieldLabelText = null; fieldLabelText = null;
helpText = null; helpText = null;
keyboardType = null; keyboardType = null;
currentMode = initialEntryMode;
}); });
Future<void> prepareDatePicker( Future<void> prepareDatePicker(
...@@ -101,6 +103,9 @@ void main() { ...@@ -101,6 +103,9 @@ void main() {
fieldLabelText: fieldLabelText, fieldLabelText: fieldLabelText,
helpText: helpText, helpText: helpText,
keyboardType: keyboardType, keyboardType: keyboardType,
onDatePickerModeChange: (DatePickerEntryMode value) {
currentMode = value;
},
builder: (BuildContext context, Widget? child) { builder: (BuildContext context, Widget? child) {
return Directionality( return Directionality(
textDirection: textDirection, textDirection: textDirection,
...@@ -1369,6 +1374,19 @@ void main() { ...@@ -1369,6 +1374,19 @@ void main() {
expect(find.byType(TextField), findsNothing); expect(find.byType(TextField), findsNothing);
expect(find.byIcon(Icons.edit), findsNothing); expect(find.byIcon(Icons.edit), findsNothing);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/33615 }, skip: isBrowser); // https://github.com/flutter/flutter/issues/33615
testWidgets('Test Callback on Toggle of DatePicker Mode', (WidgetTester tester) async {
prepareDatePicker(tester, (Future<DateTime?> date) async {
await tester.tap(find.byIcon(Icons.edit));
expect(currentMode, DatePickerEntryMode.input);
await tester.pumpAndSettle();
expect(find.byType(TextField), findsOneWidget);
await tester.tap(find.byIcon(Icons.calendar_today));
expect(currentMode, DatePickerEntryMode.calendar);
await tester.pumpAndSettle();
expect(find.byType(TextField), findsNothing);
});
});
} }
class _RestorableDatePickerDialogTestWidget extends StatefulWidget { class _RestorableDatePickerDialogTestWidget extends StatefulWidget {
......
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