Skip to content

Commit c8f72ac

Browse files
author
Hans Muller
authored
Force DatePicker value to stay within firstDate and lastDate upon year change (flutter#26239)
* Force DatePicker value to stay within firstDate and lastDate upon year change * updated per review feedback
1 parent 985ccb6 commit c8f72ac

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

packages/flutter/lib/src/material/date_picker.dart

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,13 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
902902
}
903903

904904
void _handleYearChanged(DateTime value) {
905+
if (value.isBefore(widget.firstDate))
906+
value = widget.firstDate;
907+
else if (value.isAfter(widget.lastDate))
908+
value = widget.lastDate;
909+
if (value == _selectedDate)
910+
return;
911+
905912
_vibrate();
906913
setState(() {
907914
_mode = DatePickerMode.day;
@@ -1067,9 +1074,12 @@ typedef SelectableDayPredicate = bool Function(DateTime day);
10671074
/// provided by [Directionality]. If both [locale] and [textDirection] are not
10681075
/// null, [textDirection] overrides the direction chosen for the [locale].
10691076
///
1070-
/// The `context` argument is passed to [showDialog], the documentation for
1077+
/// The [context] argument is passed to [showDialog], the documentation for
10711078
/// which discusses how it is used.
10721079
///
1080+
/// The [context], [initialDate], [firstDate], and [lastDate] parameters must
1081+
/// not be null.
1082+
///
10731083
/// See also:
10741084
///
10751085
/// * [showTimePicker], which shows a dialog that contains a material design
@@ -1090,6 +1100,9 @@ Future<DateTime> showDatePicker({
10901100
Locale locale,
10911101
TextDirection textDirection,
10921102
}) async {
1103+
assert(initialDate != null);
1104+
assert(firstDate != null);
1105+
assert(lastDate != null);
10931106
assert(!initialDate.isBefore(firstDate), 'initialDate must be on or after firstDate');
10941107
assert(!initialDate.isAfter(lastDate), 'initialDate must be on or before lastDate');
10951108
assert(!firstDate.isAfter(lastDate), 'lastDate must be on or after firstDate');

packages/flutter/test/material/date_picker_test.dart

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,39 @@ void _tests() {
279279
});
280280
});
281281

282+
testWidgets('Selecting firstDate year respects firstDate', (WidgetTester tester) async {
283+
// Regression test for https://github.com/flutter/flutter/issues/17309
284+
initialDate = DateTime(2018, DateTime.may, 4);
285+
firstDate = DateTime(2016, DateTime.june, 9);
286+
lastDate = DateTime(2019, DateTime.january, 15);
287+
await preparePicker(tester, (Future<DateTime> date) async {
288+
await tester.tap(find.text('2018'));
289+
await tester.pumpAndSettle();
290+
await tester.tap(find.text('2016'));
291+
await tester.pumpAndSettle();
292+
await tester.tap(find.text('OK'));
293+
await tester.pumpAndSettle();
294+
expect(await date, DateTime(2016, DateTime.june, 9));
295+
});
296+
});
297+
298+
testWidgets('Selecting lastDate year respects lastDate', (WidgetTester tester) async {
299+
// Regression test for https://github.com/flutter/flutter/issues/17309
300+
initialDate = DateTime(2018, DateTime.may, 4);
301+
firstDate = DateTime(2016, DateTime.june, 9);
302+
lastDate = DateTime(2019, DateTime.january, 15);
303+
await preparePicker(tester, (Future<DateTime> date) async {
304+
await tester.tap(find.text('2018'));
305+
await tester.pumpAndSettle();
306+
await tester.tap(find.text('2019'));
307+
await tester.pumpAndSettle();
308+
await tester.tap(find.text('OK'));
309+
await tester.pumpAndSettle();
310+
expect(await date, DateTime(2019, DateTime.january, 15));
311+
});
312+
});
313+
314+
282315
testWidgets('Only predicate days are selectable', (WidgetTester tester) async {
283316
initialDate = DateTime(2017, DateTime.january, 16);
284317
firstDate = DateTime(2017, DateTime.january, 10);

0 commit comments

Comments
 (0)