diff --git a/dev/tools/localization/gen_material_localizations.dart b/dev/tools/localization/gen_material_localizations.dart index def667d8f4..e22c09fd84 100644 --- a/dev/tools/localization/gen_material_localizations.dart +++ b/dev/tools/localization/gen_material_localizations.dart @@ -41,17 +41,23 @@ ConstructorGenerator generateMaterialConstructor = (LocaleInfo locale) { const MaterialLocalization${locale.camelCase()}({ String localeName = '$localeName', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, );'''; @@ -63,15 +69,18 @@ const String materialFactoryDeclaration = ''' GlobalMaterialLocalizations getMaterialTranslation( Locale locale, intl.DateFormat fullYearFormat, + intl.DateFormat compactDateFormat, + intl.DateFormat shortDateFormat, intl.DateFormat mediumDateFormat, intl.DateFormat longDateFormat, intl.DateFormat yearMonthFormat, + intl.DateFormat shortMonthDayFormat, intl.NumberFormat decimalFormat, intl.NumberFormat twoDigitZeroPaddedFormat, ) {'''; const String materialFactoryArguments = - 'fullYearFormat: fullYearFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat'; + 'fullYearFormat: fullYearFormat, compactDateFormat: compactDateFormat, shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat'; const String materialSupportedLanguagesConstant = 'kMaterialSupportedLanguages'; diff --git a/packages/flutter/lib/material.dart b/packages/flutter/lib/material.dart index 77d594a0db..780b39795c 100644 --- a/packages/flutter/lib/material.dart +++ b/packages/flutter/lib/material.dart @@ -46,7 +46,6 @@ export 'src/material/colors.dart'; export 'src/material/constants.dart'; export 'src/material/data_table.dart'; export 'src/material/data_table_source.dart'; -export 'src/material/date_picker.dart'; export 'src/material/debug.dart'; export 'src/material/dialog.dart'; export 'src/material/dialog_theme.dart'; @@ -86,6 +85,7 @@ export 'src/material/outline_button.dart'; export 'src/material/page.dart'; export 'src/material/page_transitions_theme.dart'; export 'src/material/paginated_data_table.dart'; +export 'src/material/pickers/pickers.dart'; export 'src/material/popup_menu.dart'; export 'src/material/popup_menu_theme.dart'; export 'src/material/progress_indicator.dart'; diff --git a/packages/flutter/lib/src/material/material_localizations.dart b/packages/flutter/lib/src/material/material_localizations.dart index f15014eb79..84fb04c342 100644 --- a/packages/flutter/lib/src/material/material_localizations.dart +++ b/packages/flutter/lib/src/material/material_localizations.dart @@ -224,6 +224,29 @@ abstract class MaterialLocalizations { /// Full unabbreviated year format, e.g. 2017 rather than 17. String formatYear(DateTime date); + /// Formats the date in a compact format. + /// + /// Usually just the numeric values for the for day, month and year are used. + /// + /// Examples: + /// + /// - US English: 02/21/2019 + /// - Russian: 21.02.2019 + /// + /// See also: + /// * [parseCompactDate], which will convert a compact date string to a [DateTime]. + String formatCompactDate(DateTime date); + + /// Formats the date using a short-width format. + /// + /// Includes the abbreviation of the month, the day and year. + /// + /// Examples: + /// + /// - US English: Feb 21, 2019 + /// - Russian: 21 февр. 2019 г. + String formatShortDate(DateTime date); + /// Formats the date using a medium-width format. /// /// Abbreviates month and days of week. This appears in the header of the date @@ -252,6 +275,24 @@ abstract class MaterialLocalizations { /// in the date picker invoked using [showDatePicker]. String formatMonthYear(DateTime date); + /// Formats the month and day of the given [date]. + /// + /// Examples: + /// + /// - US English: Feb 21 + /// - Russian: 21 февр. + String formatShortMonthDay(DateTime date); + + /// Converts the given compact date formatted string into a [DateTime]. + /// + /// The format of the string must be a valid compact date format for the + /// given locale. If the text doesn't represent a valid date, `null` will be + /// returned. + /// + /// See also: + /// * [formatCompactDate], which will convert a [DateTime] into a string in the compact format. + DateTime parseCompactDate(String inputString); + /// List of week day names in narrow format, usually 1- or 2-letter /// abbreviations of full names. /// @@ -437,6 +478,23 @@ class DefaultMaterialLocalizations implements MaterialLocalizations { 'December', ]; + /// Returns the number of days in a month, according to the proleptic + /// Gregorian calendar. + /// + /// This applies the leap year logic introduced by the Gregorian reforms of + /// 1582. It will not give valid results for dates prior to that time. + int _getDaysInMonth(int year, int month) { + if (month == DateTime.february) { + final bool isLeapYear = (year % 4 == 0) && (year % 100 != 0) || + (year % 400 == 0); + if (isLeapYear) + return 29; + return 28; + } + const List daysInMonth = [31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + return daysInMonth[month - 1]; + } + @override String formatHour(TimeOfDay timeOfDay, { bool alwaysUse24HourFormat = false }) { final TimeOfDayFormat format = timeOfDayFormat(alwaysUse24HourFormat: alwaysUse24HourFormat); @@ -470,6 +528,21 @@ class DefaultMaterialLocalizations implements MaterialLocalizations { @override String formatYear(DateTime date) => date.year.toString(); + @override + String formatCompactDate(DateTime date) { + // Assumes US mm/dd/yyyy format + final String month = _formatTwoDigitZeroPad(date.month); + final String day = _formatTwoDigitZeroPad(date.day); + final String year = date.year.toString().padLeft(4, '0'); + return '$month/$day/$year'; + } + + @override + String formatShortDate(DateTime date) { + final String month = _shortMonths[date.month - DateTime.january]; + return '$month ${date.day}, ${date.year}'; + } + @override String formatMediumDate(DateTime date) { final String day = _shortWeekdays[date.weekday - DateTime.monday]; @@ -490,6 +563,37 @@ class DefaultMaterialLocalizations implements MaterialLocalizations { return '$month $year'; } + @override + String formatShortMonthDay(DateTime date) { + final String month = _shortMonths[date.month - DateTime.january]; + return '$month ${date.day}'; + } + + @override + DateTime parseCompactDate(String inputString) { + // Assumes US mm/dd/yyyy format + final List inputParts = inputString.split('/'); + if (inputParts.length != 3) { + return null; + } + + final int year = int.tryParse(inputParts[2], radix: 10); + if (year == null || year < 1) { + return null; + } + + final int month = int.tryParse(inputParts[0], radix: 10); + if (month == null || month < 1 || month > 12) { + return null; + } + + final int day = int.tryParse(inputParts[1], radix: 10); + if (day == null || day < 1 || day > _getDaysInMonth(year, month)) { + return null; + } + return DateTime(year, month, day); + } + @override List get narrowWeekdays => _narrowWeekdays; diff --git a/packages/flutter/lib/src/material/pickers/calendar_date_picker.dart b/packages/flutter/lib/src/material/pickers/calendar_date_picker.dart new file mode 100644 index 0000000000..518a6a9c0f --- /dev/null +++ b/packages/flutter/lib/src/material/pickers/calendar_date_picker.dart @@ -0,0 +1,1043 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:math' as math; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; + +import '../color_scheme.dart'; +import '../divider.dart'; +import '../icon_button.dart'; +import '../icons.dart'; +import '../ink_well.dart'; +import '../material_localizations.dart'; +import '../text_theme.dart'; +import '../theme.dart'; + +import 'date_picker_common.dart'; +import 'date_utils.dart' as utils; + +const Duration _monthScrollDuration = Duration(milliseconds: 200); + +const double _dayPickerRowHeight = 42.0; +const int _maxDayPickerRowCount = 6; // A 31 day month that starts on Saturday. +// One extra row for the day-of-week header. +const double _maxDayPickerHeight = _dayPickerRowHeight * (_maxDayPickerRowCount + 1); +const double _monthPickerHorizontalPadding = 8.0; + +const int _yearPickerColumnCount = 3; +const double _yearPickerPadding = 16.0; +const double _yearPickerRowHeight = 52.0; +const double _yearPickerRowSpacing = 8.0; + +const double _subHeaderHeight = 52.0; +const double _monthNavButtonsWidth = 108.0; + +/// Displays a grid of days for a given month and allows the user to select a date. +/// +/// Days are arranged in a rectangular grid with one column for each day of the +/// week. Controls are provided to change the year and month that the grid is +/// showing. +/// +/// The calendar picker widget is rarely used directly. Instead, consider using +/// [showDatePicker], which will create a dialog that uses this as well as provides +/// a text entry option. +/// +/// See also: +/// +/// * [showDatePicker], which creates a Dialog that contains a [CalendarDatePicker] +/// and provides an optional compact view where the user can enter a date as +/// a line of text. +/// * [showTimePicker], which shows a dialog that contains a material design +/// time picker. +/// +class CalendarDatePicker extends StatefulWidget { + /// Creates a calender date picker + /// + /// It will display a grid of days for the [initialDate]'s month. The day + /// indicated by [initialDate] will be selected. + /// + /// The optional [onDisplayedMonthChanged] callback can be used to track + /// the currently displayed month. + /// + /// The user interface provides a way to change the year of the month being + /// displayed. By default it will show the day grid, but this can be changed + /// to start in the year selection interface with [initialCalendarMode] set + /// to [DatePickerMode.year]. + /// + /// The [initialDate], [firstDate], [lastDate], [onDateChanged], and + /// [initialCalendarMode] must be non-null. + /// + /// [lastDate] must be after or equal to [firstDate]. + /// + /// [initialDate] must be between [firstDate] and [lastDate] or equal to + /// one of them. + /// + /// If [selectableDayPredicate] is non-null, it must return `true` for the + /// [initialDate]. + CalendarDatePicker({ + Key key, + @required DateTime initialDate, + @required DateTime firstDate, + @required DateTime lastDate, + @required this.onDateChanged, + this.onDisplayedMonthChanged, + this.initialCalendarMode = DatePickerMode.day, + this.selectableDayPredicate, + }) : assert(initialDate != null), + assert(firstDate != null), + assert(lastDate != null), + initialDate = utils.dateOnly(initialDate), + firstDate = utils.dateOnly(firstDate), + lastDate = utils.dateOnly(lastDate), + assert(onDateChanged != null), + assert(initialCalendarMode != null), + super(key: key) { + assert( + !this.lastDate.isBefore(this.firstDate), + 'lastDate ${this.lastDate} must be on or after firstDate ${this.firstDate}.' + ); + assert( + !this.initialDate.isBefore(this.firstDate), + 'initialDate ${this.initialDate} must be on or after firstDate ${this.firstDate}.' + ); + assert( + !this.initialDate.isAfter(this.lastDate), + 'initialDate ${this.initialDate} must be on or before lastDate ${this.lastDate}.' + ); + assert( + selectableDayPredicate == null || selectableDayPredicate(this.initialDate), + 'Provided initialDate ${this.initialDate} must satisfy provided selectableDayPredicate.' + ); + } + + /// The initially selected [DateTime] that the picker should display. + final DateTime initialDate; + + /// The earliest allowable [DateTime] that the user can select. + final DateTime firstDate; + + /// The latest allowable [DateTime] that the user can select. + final DateTime lastDate; + + /// Called when the user selects a date in the picker. + final ValueChanged onDateChanged; + + /// Called when the user navigates to a new month/year in the picker. + final ValueChanged onDisplayedMonthChanged; + + /// The initial display of the calendar picker. + final DatePickerMode initialCalendarMode; + + /// Function to provide full control over which dates in the calendar can be selected. + final SelectableDayPredicate selectableDayPredicate; + + @override + _CalendarDatePickerState createState() => _CalendarDatePickerState(); +} + +class _CalendarDatePickerState extends State { + bool _announcedInitialDate = false; + DatePickerMode _mode; + DateTime _currentDisplayedMonthDate; + DateTime _selectedDate; + final GlobalKey _monthPickerKey = GlobalKey(); + final GlobalKey _yearPickerKey = GlobalKey(); + MaterialLocalizations _localizations; + TextDirection _textDirection; + + @override + void initState() { + super.initState(); + _mode = widget.initialCalendarMode; + _currentDisplayedMonthDate = DateTime(widget.initialDate.year, widget.initialDate.month); + _selectedDate = widget.initialDate; + } + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + _localizations = MaterialLocalizations.of(context); + _textDirection = Directionality.of(context); + if (!_announcedInitialDate) { + _announcedInitialDate = true; + SemanticsService.announce( + _localizations.formatFullDate(_selectedDate), + _textDirection, + ); + } + } + + void _vibrate() { + switch (Theme.of(context).platform) { + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + HapticFeedback.vibrate(); + break; + case TargetPlatform.iOS: + case TargetPlatform.macOS: + break; + } + } + + void _handleModeChanged(DatePickerMode mode) { + _vibrate(); + setState(() { + _mode = mode; + if (_mode == DatePickerMode.day) { + SemanticsService.announce( + _localizations.formatMonthYear(_selectedDate), + _textDirection, + ); + } else { + SemanticsService.announce( + _localizations.formatYear(_selectedDate), + _textDirection, + ); + } + }); + } + + void _handleMonthChanged(DateTime date) { + setState(() { + if (_currentDisplayedMonthDate.year != date.year || _currentDisplayedMonthDate.month != date.month) { + _currentDisplayedMonthDate = DateTime(date.year, date.month); + widget.onDisplayedMonthChanged?.call(_currentDisplayedMonthDate); + } + }); + } + + void _handleYearChanged(DateTime value) { + _vibrate(); + + if (value.isBefore(widget.firstDate)) { + value = widget.firstDate; + } else if (value.isAfter(widget.lastDate)) { + value = widget.lastDate; + } + + setState(() { + _mode = DatePickerMode.day; + _handleMonthChanged(value); + }); + } + + void _handleDayChanged(DateTime value) { + _vibrate(); + setState(() { + _selectedDate = value; + widget.onDateChanged?.call(_selectedDate); + }); + } + + Widget _buildPicker() { + assert(_mode != null); + switch (_mode) { + case DatePickerMode.day: + return _MonthPicker( + key: _monthPickerKey, + initialMonth: _currentDisplayedMonthDate, + currentDate: DateTime.now(), + firstDate: widget.firstDate, + lastDate: widget.lastDate, + selectedDate: _selectedDate, + onChanged: _handleDayChanged, + onDisplayedMonthChanged: _handleMonthChanged, + selectableDayPredicate: widget.selectableDayPredicate, + ); + case DatePickerMode.year: + return Padding( + padding: const EdgeInsets.only(top: _subHeaderHeight), + child: _YearPicker( + key: _yearPickerKey, + currentDate: DateTime.now(), + firstDate: widget.firstDate, + lastDate: widget.lastDate, + initialDate: _currentDisplayedMonthDate, + selectedDate: _selectedDate, + onChanged: _handleYearChanged, + ), + ); + } + return null; + } + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + SingleChildScrollView( + child: SizedBox( + height: _maxDayPickerHeight, + child: _buildPicker(), + ), + ), + // Put the mode toggle button on top so that it won't be covered up by the _MonthPicker + _DatePickerModeToggleButton( + mode: _mode, + title: _localizations.formatMonthYear(_currentDisplayedMonthDate), + onTitlePressed: () { + // Toggle the day/year mode. + _handleModeChanged(_mode == DatePickerMode.day ? DatePickerMode.year : DatePickerMode.day); + }, + ), + ], + ); + } +} + +/// A button that used to toggle the [DatePickerMode] for a date picker. +/// +/// This appears above the calendar grid and allows the user to toggle the +/// [DatePickerMode] to display either the calendar view or the year list. +class _DatePickerModeToggleButton extends StatefulWidget { + const _DatePickerModeToggleButton({ + @required this.mode, + @required this.title, + @required this.onTitlePressed, + }); + + /// The current display of the calendar picker. + final DatePickerMode mode; + + /// The text that displays the current month/year being viewed. + final String title; + + /// The callback when the title is pressed. + final VoidCallback onTitlePressed; + + @override + _DatePickerModeToggleButtonState createState() => _DatePickerModeToggleButtonState(); +} + +class _DatePickerModeToggleButtonState extends State<_DatePickerModeToggleButton> with SingleTickerProviderStateMixin { + AnimationController _controller; + + @override + void initState() { + super.initState(); + _controller = AnimationController( + value: widget.mode == DatePickerMode.year ? 0.5 : 0, + upperBound: 0.5, + duration: const Duration(milliseconds: 200), + vsync: this, + ); + } + + @override + void didUpdateWidget(_DatePickerModeToggleButton oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.mode == widget.mode) { + return; + } + + if (widget.mode == DatePickerMode.year) { + _controller.forward(); + } else { + _controller.reverse(); + } + } + + @override + Widget build(BuildContext context) { + final ColorScheme colorScheme = Theme.of(context).colorScheme; + final TextTheme textTheme = Theme.of(context).textTheme; + final Color controlColor = colorScheme.onSurface.withOpacity(0.60); + + return Container( + padding: const EdgeInsetsDirectional.only(start: 16, end: 4), + height: _subHeaderHeight, + child: Row( + children: [ + Flexible( + child: Semantics( + // TODO(darrenaustin): localize 'Select year' + label: 'Select year', + excludeSemantics: true, + button: true, + child: Container( + height: _subHeaderHeight, + child: InkWell( + onTap: widget.onTitlePressed, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: Row( + children: [ + Flexible( + child: Text( + widget.title, + overflow: TextOverflow.ellipsis, + style: textTheme.subtitle2?.copyWith( + color: controlColor, + ), + ), + ), + RotationTransition( + turns: _controller, + child: Icon( + Icons.arrow_drop_down, + color: controlColor, + ), + ), + ], + ), + ), + ), + ), + ), + ), + if (widget.mode == DatePickerMode.day) + // Give space for the prev/next month buttons that are underneath this row + const SizedBox(width: _monthNavButtonsWidth), + ], + ), + ); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } +} + +class _MonthPicker extends StatefulWidget { + /// Creates a month picker. + _MonthPicker({ + Key key, + @required this.initialMonth, + @required this.currentDate, + @required this.firstDate, + @required this.lastDate, + @required this.selectedDate, + @required this.onChanged, + @required this.onDisplayedMonthChanged, + this.selectableDayPredicate, + }) : assert(selectedDate != null), + assert(currentDate != null), + assert(onChanged != null), + assert(firstDate != null), + assert(lastDate != null), + assert(!firstDate.isAfter(lastDate)), + assert(!selectedDate.isBefore(firstDate)), + assert(!selectedDate.isAfter(lastDate)), + super(key: key); + + /// The initial month to display + final DateTime initialMonth; + + /// The current date. + /// + /// This date is subtly highlighted in the picker. + final DateTime currentDate; + + /// The earliest date the user is permitted to pick. + /// + /// This date must be on or before the [lastDate]. + final DateTime firstDate; + + /// The latest date the user is permitted to pick. + /// + /// This date must be on or after the [firstDate]. + final DateTime lastDate; + + /// The currently selected date. + /// + /// This date is highlighted in the picker. + final DateTime selectedDate; + + /// Called when the user picks a day. + final ValueChanged onChanged; + + /// Called when the user navigates to a new month + final ValueChanged onDisplayedMonthChanged; + + /// Optional user supplied predicate function to customize selectable days. + final SelectableDayPredicate selectableDayPredicate; + + @override + State createState() => _MonthPickerState(); +} + +class _MonthPickerState extends State<_MonthPicker> { + DateTime _currentMonth; + DateTime _nextMonthDate; + DateTime _previousMonthDate; + PageController _pageController; + MaterialLocalizations _localizations; + TextDirection _textDirection; + + @override + void initState() { + super.initState(); + _currentMonth = widget.initialMonth; + _previousMonthDate = utils.addMonthsToMonthDate(_currentMonth, -1); + _nextMonthDate = utils.addMonthsToMonthDate(_currentMonth, 1); + _pageController = PageController(initialPage: utils.monthDelta(widget.firstDate, _currentMonth)); + } + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + _localizations = MaterialLocalizations.of(context); + _textDirection = Directionality.of(context); + } + + @override + void dispose() { + _pageController?.dispose(); + super.dispose(); + } + + void _handleMonthPageChanged(int monthPage) { + final DateTime monthDate = utils.addMonthsToMonthDate(widget.firstDate, monthPage); + if (_currentMonth.year != monthDate.year || _currentMonth.month != monthDate.month) { + _currentMonth = DateTime(monthDate.year, monthDate.month); + _previousMonthDate = utils.addMonthsToMonthDate(_currentMonth, -1); + _nextMonthDate = utils.addMonthsToMonthDate(_currentMonth, 1); + widget.onDisplayedMonthChanged?.call(_currentMonth); + } + } + + void _handleNextMonth() { + if (!_isDisplayingLastMonth) { + SemanticsService.announce( + _localizations.formatMonthYear(_nextMonthDate), + _textDirection, + ); + _pageController.nextPage( + duration: _monthScrollDuration, + curve: Curves.ease, + ); + } + } + + void _handlePreviousMonth() { + if (!_isDisplayingFirstMonth) { + SemanticsService.announce( + _localizations.formatMonthYear(_previousMonthDate), + _textDirection, + ); + _pageController.previousPage( + duration: _monthScrollDuration, + curve: Curves.ease, + ); + } + } + + /// True if the earliest allowable month is displayed. + bool get _isDisplayingFirstMonth { + return !_currentMonth.isAfter( + DateTime(widget.firstDate.year, widget.firstDate.month), + ); + } + + /// True if the latest allowable month is displayed. + bool get _isDisplayingLastMonth { + return !_currentMonth.isBefore( + DateTime(widget.lastDate.year, widget.lastDate.month), + ); + } + + Widget _buildItems(BuildContext context, int index) { + final DateTime month = utils.addMonthsToMonthDate(widget.firstDate, index); + return _DayPicker( + key: ValueKey(month), + selectedDate: widget.selectedDate, + currentDate: widget.currentDate, + onChanged: widget.onChanged, + firstDate: widget.firstDate, + lastDate: widget.lastDate, + displayedMonth: month, + selectableDayPredicate: widget.selectableDayPredicate, + ); + } + + @override + Widget build(BuildContext context) { + final String previousTooltipText = '${_localizations.previousMonthTooltip} ${_localizations.formatMonthYear(_previousMonthDate)}'; + final String nextTooltipText = '${_localizations.nextMonthTooltip} ${_localizations.formatMonthYear(_nextMonthDate)}'; + final Color controlColor = Theme.of(context).colorScheme.onSurface.withOpacity(0.60); + + return Semantics( + child: Column( + children: [ + Container( + padding: const EdgeInsetsDirectional.only(start: 16, end: 4), + height: _subHeaderHeight, + child: Row( + children: [ + const Spacer(), + IconButton( + icon: const Icon(Icons.chevron_left), + color: controlColor, + tooltip: _isDisplayingFirstMonth ? null : previousTooltipText, + onPressed: _isDisplayingFirstMonth ? null : _handlePreviousMonth, + ), + IconButton( + icon: const Icon(Icons.chevron_right), + color: controlColor, + tooltip: _isDisplayingLastMonth ? null : nextTooltipText, + onPressed: _isDisplayingLastMonth ? null : _handleNextMonth, + ), + ], + ), + ), + _DayHeaders(), + Expanded( + child: PageView.builder( + key: ValueKey(widget.selectedDate), + controller: _pageController, + itemBuilder: _buildItems, + itemCount: utils.monthDelta(widget.firstDate, widget.lastDate) + 1, + scrollDirection: Axis.horizontal, + onPageChanged: _handleMonthPageChanged, + ), + ), + ], + ), + ); + } +} + +/// Displays the days of a given month and allows choosing a day. +/// +/// The days are arranged in a rectangular grid with one column for each day of +/// the week. +class _DayPicker extends StatelessWidget { + /// Creates a day picker. + _DayPicker({ + Key key, + @required this.currentDate, + @required this.displayedMonth, + @required this.firstDate, + @required this.lastDate, + @required this.selectedDate, + @required this.onChanged, + this.selectableDayPredicate, + }) : assert(currentDate != null), + assert(displayedMonth != null), + assert(firstDate != null), + assert(lastDate != null), + assert(selectedDate != null), + assert(onChanged != null), + assert(!firstDate.isAfter(lastDate)), + assert(!selectedDate.isBefore(firstDate)), + assert(!selectedDate.isAfter(lastDate)), + super(key: key); + + /// The currently selected date. + /// + /// This date is highlighted in the picker. + final DateTime selectedDate; + + /// The current date at the time the picker is displayed. + final DateTime currentDate; + + /// Called when the user picks a day. + final ValueChanged onChanged; + + /// The earliest date the user is permitted to pick. + /// + /// This date must be on or before the [lastDate]. + final DateTime firstDate; + + /// The latest date the user is permitted to pick. + /// + /// This date must be on or after the [firstDate]. + final DateTime lastDate; + + /// The month whose days are displayed by this picker. + final DateTime displayedMonth; + + /// Optional user supplied predicate function to customize selectable days. + final SelectableDayPredicate selectableDayPredicate; + + @override + Widget build(BuildContext context) { + final ColorScheme colorScheme = Theme.of(context).colorScheme; + final MaterialLocalizations localizations = MaterialLocalizations.of(context); + final TextTheme textTheme = Theme.of(context).textTheme; + final TextStyle dayStyle = textTheme.caption; + final Color enabledDayColor = colorScheme.onSurface.withOpacity(0.87); + final Color disabledDayColor = colorScheme.onSurface.withOpacity(0.38); + final Color selectedDayColor = colorScheme.onPrimary; + final Color selectedDayBackground = colorScheme.primary; + final Color todayColor = colorScheme.primary; + + final int year = displayedMonth.year; + final int month = displayedMonth.month; + + final int daysInMonth = utils.getDaysInMonth(year, month); + final int dayOffset = utils.firstDayOffset(year, month, localizations); + + final List dayItems = []; + // 1-based day of month, e.g. 1-31 for January, and 1-29 for February on + // a leap year. + int day = -dayOffset; + while (day < daysInMonth) { + day++; + if (day < 1) { + dayItems.add(Container()); + } else { + final DateTime dayToBuild = DateTime(year, month, day); + final bool isDisabled = dayToBuild.isAfter(lastDate) || + dayToBuild.isBefore(firstDate) || + (selectableDayPredicate != null && !selectableDayPredicate(dayToBuild)); + + BoxDecoration decoration; + Color dayColor = enabledDayColor; + final bool isSelectedDay = utils.isSameDay(selectedDate, dayToBuild); + if (isSelectedDay) { + // The selected day gets a circle background highlight, and a + // contrasting text color. + dayColor = selectedDayColor; + decoration = BoxDecoration( + color: selectedDayBackground, + shape: BoxShape.circle, + ); + } else if (isDisabled) { + dayColor = disabledDayColor; + } else if (utils.isSameDay(currentDate, dayToBuild)) { + // The current day gets a different text color and a circle stroke + // border. + dayColor = todayColor; + decoration = BoxDecoration( + border: Border.all(color: todayColor, width: 1), + shape: BoxShape.circle, + ); + } + + Widget dayWidget = Container( + decoration: decoration, + child: Center( + child: Text(localizations.formatDecimal(day), style: dayStyle.apply(color: dayColor)), + ), + ); + + if (isDisabled) { + dayWidget = ExcludeSemantics( + child: dayWidget, + ); + } else { + dayWidget = GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () => onChanged(dayToBuild), + child: Semantics( + // We want the day of month to be spoken first irrespective of the + // locale-specific preferences or TextDirection. This is because + // an accessibility user is more likely to be interested in the + // day of month before the rest of the date, as they are looking + // for the day of month. To do that we prepend day of month to the + // formatted full date. + label: '${localizations.formatDecimal(day)}, ${localizations.formatFullDate(dayToBuild)}', + selected: isSelectedDay, + excludeSemantics: true, + child: dayWidget, + ), + ); + } + + dayItems.add(dayWidget); + } + } + + return Padding( + padding: const EdgeInsets.symmetric( + horizontal: _monthPickerHorizontalPadding, + ), + child: GridView.custom( + physics: const ClampingScrollPhysics(), + gridDelegate: _dayPickerGridDelegate, + childrenDelegate: SliverChildListDelegate( + dayItems, + addRepaintBoundaries: false, + ), + ), + ); + } +} + +class _DayPickerGridDelegate extends SliverGridDelegate { + const _DayPickerGridDelegate(); + + @override + SliverGridLayout getLayout(SliverConstraints constraints) { + const int columnCount = DateTime.daysPerWeek; + final double tileWidth = constraints.crossAxisExtent / columnCount; + final double tileHeight = math.min(_dayPickerRowHeight, + constraints.viewportMainAxisExtent / _maxDayPickerRowCount); + return SliverGridRegularTileLayout( + childCrossAxisExtent: tileWidth, + childMainAxisExtent: tileHeight, + crossAxisCount: columnCount, + crossAxisStride: tileWidth, + mainAxisStride: tileHeight, + reverseCrossAxis: axisDirectionIsReversed(constraints.crossAxisDirection), + ); + } + + @override + bool shouldRelayout(_DayPickerGridDelegate oldDelegate) => false; +} + +const _DayPickerGridDelegate _dayPickerGridDelegate = _DayPickerGridDelegate(); + +class _DayHeaders extends StatelessWidget { + /// Builds widgets showing abbreviated days of week. The first widget in the + /// returned list corresponds to the first day of week for the current locale. + /// + /// Examples: + /// + /// ``` + /// ┌ Sunday is the first day of week in the US (en_US) + /// | + /// S M T W T F S <-- the returned list contains these widgets + /// _ _ _ _ _ 1 2 + /// 3 4 5 6 7 8 9 + /// + /// ┌ But it's Monday in the UK (en_GB) + /// | + /// M T W T F S S <-- the returned list contains these widgets + /// _ _ _ _ 1 2 3 + /// 4 5 6 7 8 9 10 + /// ``` + List _getDayHeaders(TextStyle headerStyle, MaterialLocalizations localizations) { + final List result = []; + for (int i = localizations.firstDayOfWeekIndex; true; i = (i + 1) % 7) { + final String weekday = localizations.narrowWeekdays[i]; + result.add(ExcludeSemantics( + child: Center(child: Text(weekday, style: headerStyle)), + )); + if (i == (localizations.firstDayOfWeekIndex - 1) % 7) + break; + } + return result; + } + + @override + Widget build(BuildContext context) { + final ThemeData theme = Theme.of(context); + final ColorScheme colorScheme = theme.colorScheme; + final TextStyle dayHeaderStyle = theme.textTheme.caption?.apply( + color: colorScheme.onSurface.withOpacity(0.60), + ); + final MaterialLocalizations localizations = MaterialLocalizations.of(context); + final List labels = _getDayHeaders(dayHeaderStyle, localizations); + + return Padding( + padding: const EdgeInsets.symmetric( + horizontal: _monthPickerHorizontalPadding, + ), + child: GridView.custom( + shrinkWrap: true, + gridDelegate: _dayPickerGridDelegate, + childrenDelegate: SliverChildListDelegate( + labels, + addRepaintBoundaries: false, + ), + ), + ); + } +} + +/// A scrollable list of years to allow picking a year. +class _YearPicker extends StatefulWidget { + /// Creates a year picker. + /// + /// The [currentDate, [firstDate], [lastDate], [selectedDate], and [onChanged] + /// arguments must be non-null. The [lastDate] must be after the [firstDate]. + _YearPicker({ + Key key, + @required this.currentDate, + @required this.firstDate, + @required this.lastDate, + @required this.initialDate, + @required this.selectedDate, + @required this.onChanged, + }) : assert(currentDate != null), + assert(firstDate != null), + assert(lastDate != null), + assert(initialDate != null), + assert(selectedDate != null), + assert(onChanged != null), + assert(!firstDate.isAfter(lastDate)), + super(key: key); + + /// The current date. + /// + /// This date is subtly highlighted in the picker. + final DateTime currentDate; + + /// The earliest date the user is permitted to pick. + final DateTime firstDate; + + /// The latest date the user is permitted to pick. + final DateTime lastDate; + + /// The initial date to center the year display around. + final DateTime initialDate; + + /// The currently selected date. + /// + /// This date is highlighted in the picker. + final DateTime selectedDate; + + /// Called when the user picks a year. + final ValueChanged onChanged; + + @override + _YearPickerState createState() => _YearPickerState(); +} + +class _YearPickerState extends State<_YearPicker> { + ScrollController scrollController; + + // The approximate number of years necessary to fill the available space. + static const int minYears = 18; + + @override + void initState() { + super.initState(); + + // Set the scroll position to approximately center the initial year. + final int initialYearIndex = widget.selectedDate.year - widget.firstDate.year; + final int initialYearRow = initialYearIndex ~/ _yearPickerColumnCount; + // Move the offset down by 2 rows to approximately center it. + final int centeredYearRow = initialYearRow - 2; + final double scrollOffset = _itemCount < minYears ? 0 : centeredYearRow * _yearPickerRowHeight; + scrollController = ScrollController(initialScrollOffset: scrollOffset); + } + + Widget _buildYearItem(BuildContext context, int index) { + final ColorScheme colorScheme = Theme.of(context).colorScheme; + final TextTheme textTheme = Theme.of(context).textTheme; + + // Backfill the _YearPicker with disabled years if necessary. + final int offset = _itemCount < minYears ? (minYears - _itemCount) ~/ 2 : 0; + final int year = widget.firstDate.year + index - offset; + final bool isSelected = year == widget.selectedDate.year; + final bool isCurrentYear = year == widget.currentDate.year; + final bool isDisabled = year < widget.firstDate.year || year > widget.lastDate.year; + const double decorationHeight = 36.0; + const double decorationWidth = 72.0; + + Color textColor; + if (isSelected) { + textColor = colorScheme.onPrimary; + } else if (isDisabled) { + textColor = colorScheme.onSurface.withOpacity(0.38); + } else if (isCurrentYear) { + textColor = colorScheme.primary; + } else { + textColor = colorScheme.onSurface.withOpacity(0.87); + } + final TextStyle itemStyle = textTheme.bodyText1?.apply(color: textColor); + + BoxDecoration decoration; + if (isSelected) { + decoration = BoxDecoration( + color: colorScheme.primary, + borderRadius: BorderRadius.circular(decorationHeight / 2), + shape: BoxShape.rectangle, + ); + } else if (isCurrentYear && !isDisabled) { + decoration = BoxDecoration( + border: Border.all( + color: colorScheme.primary, + width: 1, + ), + borderRadius: BorderRadius.circular(decorationHeight / 2), + shape: BoxShape.rectangle, + ); + } + + Widget yearItem = Center( + child: Container( + decoration: decoration, + height: decorationHeight, + width: decorationWidth, + child: Center( + child: Semantics( + selected: isSelected, + child: Text(year.toString(), style: itemStyle), + ), + ), + ), + ); + + if (isDisabled) { + yearItem = ExcludeSemantics( + child: yearItem, + ); + } else { + yearItem = InkWell( + key: ValueKey(year), + onTap: () { + widget.onChanged( + DateTime( + year, + widget.initialDate.month, + widget.initialDate.day, + ), + ); + }, + child: yearItem, + ); + } + + return yearItem; + } + + int get _itemCount { + return widget.lastDate.year - widget.firstDate.year + 1; + } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + const Divider(), + Expanded( + child: GridView.builder( + controller: scrollController, + gridDelegate: _yearPickerGridDelegate, + itemBuilder: _buildYearItem, + itemCount: math.max(_itemCount, minYears), + padding: const EdgeInsets.symmetric(horizontal: _yearPickerPadding), + ), + ), + const Divider(), + ], + ); + } +} + +class _YearPickerGridDelegate extends SliverGridDelegate { + const _YearPickerGridDelegate(); + + @override + SliverGridLayout getLayout(SliverConstraints constraints) { + final double tileWidth = + (constraints.crossAxisExtent - (_yearPickerColumnCount - 1) * _yearPickerRowSpacing) / _yearPickerColumnCount; + return SliverGridRegularTileLayout( + childCrossAxisExtent: tileWidth, + childMainAxisExtent: _yearPickerRowHeight, + crossAxisCount: _yearPickerColumnCount, + crossAxisStride: tileWidth + _yearPickerRowSpacing, + mainAxisStride: _yearPickerRowHeight, + reverseCrossAxis: axisDirectionIsReversed(constraints.crossAxisDirection), + ); + } + + @override + bool shouldRelayout(_YearPickerGridDelegate oldDelegate) => false; +} + +const _YearPickerGridDelegate _yearPickerGridDelegate = _YearPickerGridDelegate(); diff --git a/packages/flutter/lib/src/material/pickers/date_picker_common.dart b/packages/flutter/lib/src/material/pickers/date_picker_common.dart new file mode 100644 index 0000000000..06a0015118 --- /dev/null +++ b/packages/flutter/lib/src/material/pickers/date_picker_common.dart @@ -0,0 +1,38 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/// Mode of the date picker dialog. +/// +/// Either a calendar or text input. In [calendar] mode, a calendar view is +/// displayed and the user taps the day they wish to select. In [input] mode a +/// [TextField] is displayed and the user types in the date they wish to select. +enum DatePickerEntryMode { + /// Tapping on a calendar. + calendar, + + /// Text input. + input, +} + +/// Initial display of a calendar date picker. +/// +/// Either a grid of available years or a monthly calendar. +/// +/// See also: +/// +/// * [showDatePicker], which shows a dialog that contains a material design +/// date picker. +/// * [CalendarDatePicker], widget which implements the material design date picker. +enum DatePickerMode { + /// Choosing a month and day. + day, + + /// Choosing a year. + year, +} + +/// Signature for predicating dates for enabled date selections. +/// +/// See [showDatePicker]. +typedef SelectableDayPredicate = bool Function(DateTime day); diff --git a/packages/flutter/lib/src/material/date_picker.dart b/packages/flutter/lib/src/material/pickers/date_picker_deprecated.dart similarity index 61% rename from packages/flutter/lib/src/material/date_picker.dart rename to packages/flutter/lib/src/material/pickers/date_picker_deprecated.dart index 19f8f586e4..901ac22649 100644 --- a/packages/flutter/lib/src/material/date_picker.dart +++ b/packages/flutter/lib/src/material/pickers/date_picker_deprecated.dart @@ -5,188 +5,36 @@ import 'dart:async'; import 'dart:math' as math; -import 'package:flutter/rendering.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter/widgets.dart'; import 'package:flutter/gestures.dart' show DragStartBehavior; +import 'package:flutter/rendering.dart'; +import 'package:flutter/widgets.dart'; + +import '../debug.dart'; +import '../icon_button.dart'; +import '../icons.dart'; +import '../ink_well.dart'; +import '../material.dart'; +import '../material_localizations.dart'; +import '../theme.dart'; + +import 'date_picker_common.dart'; + +// NOTE: this is the original implementation for the Material Date Picker. +// These classes are deprecated and the whole file can be removed after +// this has been on stable for long enough for people to migrate to the new +// CalendarDatePicker (if needed, as showDatePicker has already been migrated +// and it is what most apps would have used). -import 'button_bar.dart'; -import 'colors.dart'; -import 'debug.dart'; -import 'dialog.dart'; -import 'feedback.dart'; -import 'flat_button.dart'; -import 'icon_button.dart'; -import 'icons.dart'; -import 'ink_well.dart'; -import 'material.dart'; -import 'material_localizations.dart'; -import 'text_theme.dart'; -import 'theme.dart'; // Examples can assume: // BuildContext context; -/// Initial display mode of the date picker dialog. -/// -/// Date picker UI mode for either showing a list of available years or a -/// monthly calendar initially in the dialog shown by calling [showDatePicker]. -/// -/// See also: -/// -/// * [showDatePicker], which shows a dialog that contains a material design -/// date picker. -enum DatePickerMode { - /// Show a date picker UI for choosing a month and day. - day, - - /// Show a date picker UI for choosing a year. - year, -} - const Duration _kMonthScrollDuration = Duration(milliseconds: 200); const double _kDayPickerRowHeight = 42.0; const int _kMaxDayPickerRowCount = 6; // A 31 day month that starts on Saturday. // Two extra rows: one for the day-of-week header and one for the month header. const double _kMaxDayPickerHeight = _kDayPickerRowHeight * (_kMaxDayPickerRowCount + 2); -// Shows the selected date in large font and toggles between year and day mode -class _DatePickerHeader extends StatelessWidget { - const _DatePickerHeader({ - Key key, - @required this.selectedDate, - @required this.mode, - @required this.onModeChanged, - @required this.orientation, - }) : assert(selectedDate != null), - assert(mode != null), - assert(orientation != null), - super(key: key); - - final DateTime selectedDate; - final DatePickerMode mode; - final ValueChanged onModeChanged; - final Orientation orientation; - - void _handleChangeMode(DatePickerMode value) { - if (value != mode) - onModeChanged(value); - } - - @override - Widget build(BuildContext context) { - final MaterialLocalizations localizations = MaterialLocalizations.of(context); - final ThemeData themeData = Theme.of(context); - final TextTheme headerTextTheme = themeData.primaryTextTheme; - Color dayColor; - Color yearColor; - switch (themeData.primaryColorBrightness) { - case Brightness.light: - dayColor = mode == DatePickerMode.day ? Colors.black87 : Colors.black54; - yearColor = mode == DatePickerMode.year ? Colors.black87 : Colors.black54; - break; - case Brightness.dark: - dayColor = mode == DatePickerMode.day ? Colors.white : Colors.white70; - yearColor = mode == DatePickerMode.year ? Colors.white : Colors.white70; - break; - } - final TextStyle dayStyle = headerTextTheme.headline4.copyWith(color: dayColor); - final TextStyle yearStyle = headerTextTheme.subtitle1.copyWith(color: yearColor); - - Color backgroundColor; - switch (themeData.brightness) { - case Brightness.light: - backgroundColor = themeData.primaryColor; - break; - case Brightness.dark: - backgroundColor = themeData.backgroundColor; - break; - } - - EdgeInsets padding; - MainAxisAlignment mainAxisAlignment; - switch (orientation) { - case Orientation.portrait: - padding = const EdgeInsets.all(16.0); - mainAxisAlignment = MainAxisAlignment.center; - break; - case Orientation.landscape: - padding = const EdgeInsets.all(8.0); - mainAxisAlignment = MainAxisAlignment.start; - break; - } - - final Widget yearButton = IgnorePointer( - ignoring: mode != DatePickerMode.day, - ignoringSemantics: false, - child: _DateHeaderButton( - color: backgroundColor, - onTap: Feedback.wrapForTap(() => _handleChangeMode(DatePickerMode.year), context), - child: Semantics( - selected: mode == DatePickerMode.year, - child: Text(localizations.formatYear(selectedDate), style: yearStyle), - ), - ), - ); - - final Widget dayButton = IgnorePointer( - ignoring: mode == DatePickerMode.day, - ignoringSemantics: false, - child: _DateHeaderButton( - color: backgroundColor, - onTap: Feedback.wrapForTap(() => _handleChangeMode(DatePickerMode.day), context), - child: Semantics( - selected: mode == DatePickerMode.day, - child: Text(localizations.formatMediumDate(selectedDate), style: dayStyle), - ), - ), - ); - - return Container( - padding: padding, - color: backgroundColor, - child: Column( - mainAxisAlignment: mainAxisAlignment, - crossAxisAlignment: CrossAxisAlignment.start, - children: [yearButton, dayButton], - ), - ); - } -} - -class _DateHeaderButton extends StatelessWidget { - const _DateHeaderButton({ - Key key, - this.onTap, - this.color, - this.child, - }) : super(key: key); - - final VoidCallback onTap; - final Color color; - final Widget child; - - @override - Widget build(BuildContext context) { - final ThemeData theme = Theme.of(context); - - return Material( - type: MaterialType.button, - color: color, - child: InkWell( - borderRadius: kMaterialEdges[MaterialType.button], - highlightColor: theme.highlightColor, - splashColor: theme.splashColor, - onTap: onTap, - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: child, - ), - ), - ); - } -} - class _DayPickerGridDelegate extends SliverGridDelegate { const _DayPickerGridDelegate(); @@ -226,6 +74,11 @@ const _DayPickerGridDelegate _kDayPickerGridDelegate = _DayPickerGridDelegate(); /// date picker. /// * [showTimePicker], which shows a dialog that contains a material design /// time picker. +/// +@Deprecated( + 'Use CalendarDatePicker instead. ' + 'This feature was deprecated after v1.15.3.' +) class DayPicker extends StatelessWidget { /// Creates a day picker. /// @@ -503,6 +356,11 @@ class DayPicker extends StatelessWidget { /// date picker. /// * [showTimePicker], which shows a dialog that contains a material design /// time picker. +/// +@Deprecated( + 'Use CalendarDatePicker instead. ' + 'This feature was deprecated after v1.15.3.' +) class MonthPicker extends StatefulWidget { /// Creates a month picker. /// @@ -546,6 +404,7 @@ class MonthPicker extends StatefulWidget { _MonthPickerState createState() => _MonthPickerState(); } +// ignore: deprecated_member_use_from_same_package class _MonthPickerState extends State with SingleTickerProviderStateMixin { static final Animatable _chevronOpacityTween = Tween(begin: 1.0, end: 0.0) .chain(CurveTween(curve: Curves.easeInOut)); @@ -567,6 +426,7 @@ class _MonthPickerState extends State with SingleTickerProviderStat } @override + // ignore: deprecated_member_use_from_same_package void didUpdateWidget(MonthPicker oldWidget) { super.didUpdateWidget(oldWidget); if (widget.selectedDate != oldWidget.selectedDate) { @@ -617,6 +477,7 @@ class _MonthPickerState extends State with SingleTickerProviderStat Widget _buildItems(BuildContext context, int index) { final DateTime month = _addMonthsToMonthDate(widget.firstDate, index); + // ignore: deprecated_member_use_from_same_package return DayPicker( key: ValueKey(month), selectedDate: widget.selectedDate, @@ -766,6 +627,11 @@ class _MonthPickerSortKey extends OrdinalSortKey { /// date picker. /// * [showTimePicker], which shows a dialog that contains a material design /// time picker. +/// +@Deprecated( + 'Use CalendarDatePicker instead. ' + 'This feature was deprecated after v1.15.3.' +) class YearPicker extends StatefulWidget { /// Creates a year picker. /// @@ -807,6 +673,7 @@ class YearPicker extends StatefulWidget { _YearPickerState createState() => _YearPickerState(); } +// ignore: deprecated_member_use_from_same_package class _YearPickerState extends State { static const double _itemExtent = 50.0; ScrollController scrollController; @@ -852,339 +719,3 @@ class _YearPickerState extends State { ); } } - -class _DatePickerDialog extends StatefulWidget { - const _DatePickerDialog({ - Key key, - this.initialDate, - this.firstDate, - this.lastDate, - this.selectableDayPredicate, - this.initialDatePickerMode, - }) : super(key: key); - - final DateTime initialDate; - final DateTime firstDate; - final DateTime lastDate; - final SelectableDayPredicate selectableDayPredicate; - final DatePickerMode initialDatePickerMode; - - @override - _DatePickerDialogState createState() => _DatePickerDialogState(); -} - -class _DatePickerDialogState extends State<_DatePickerDialog> { - @override - void initState() { - super.initState(); - _selectedDate = widget.initialDate; - _mode = widget.initialDatePickerMode; - } - - bool _announcedInitialDate = false; - - MaterialLocalizations localizations; - TextDirection textDirection; - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - localizations = MaterialLocalizations.of(context); - textDirection = Directionality.of(context); - if (!_announcedInitialDate) { - _announcedInitialDate = true; - SemanticsService.announce( - localizations.formatFullDate(_selectedDate), - textDirection, - ); - } - } - - DateTime _selectedDate; - DatePickerMode _mode; - final GlobalKey _pickerKey = GlobalKey(); - - void _vibrate() { - switch (Theme.of(context).platform) { - case TargetPlatform.android: - case TargetPlatform.fuchsia: - case TargetPlatform.linux: - case TargetPlatform.windows: - HapticFeedback.vibrate(); - break; - case TargetPlatform.iOS: - case TargetPlatform.macOS: - break; - } - } - - void _handleModeChanged(DatePickerMode mode) { - _vibrate(); - setState(() { - _mode = mode; - if (_mode == DatePickerMode.day) { - SemanticsService.announce(localizations.formatMonthYear(_selectedDate), textDirection); - } else { - SemanticsService.announce(localizations.formatYear(_selectedDate), textDirection); - } - }); - } - - void _handleYearChanged(DateTime value) { - if (value.isBefore(widget.firstDate)) - value = widget.firstDate; - else if (value.isAfter(widget.lastDate)) - value = widget.lastDate; - if (value == _selectedDate) - return; - - _vibrate(); - setState(() { - _mode = DatePickerMode.day; - _selectedDate = value; - }); - } - - void _handleDayChanged(DateTime value) { - _vibrate(); - setState(() { - _selectedDate = value; - }); - } - - void _handleCancel() { - Navigator.pop(context); - } - - void _handleOk() { - Navigator.pop(context, _selectedDate); - } - - Widget _buildPicker() { - assert(_mode != null); - switch (_mode) { - case DatePickerMode.day: - return MonthPicker( - key: _pickerKey, - selectedDate: _selectedDate, - onChanged: _handleDayChanged, - firstDate: widget.firstDate, - lastDate: widget.lastDate, - selectableDayPredicate: widget.selectableDayPredicate, - ); - case DatePickerMode.year: - return YearPicker( - key: _pickerKey, - selectedDate: _selectedDate, - onChanged: _handleYearChanged, - firstDate: widget.firstDate, - lastDate: widget.lastDate, - ); - } - return null; - } - - @override - Widget build(BuildContext context) { - final ThemeData theme = Theme.of(context); - final Widget picker = _buildPicker(); - final Widget actions = ButtonBar( - children: [ - FlatButton( - child: Text(localizations.cancelButtonLabel), - onPressed: _handleCancel, - ), - FlatButton( - child: Text(localizations.okButtonLabel), - onPressed: _handleOk, - ), - ], - ); - - final Dialog dialog = Dialog( - child: OrientationBuilder( - builder: (BuildContext context, Orientation orientation) { - assert(orientation != null); - final Widget header = _DatePickerHeader( - selectedDate: _selectedDate, - mode: _mode, - onModeChanged: _handleModeChanged, - orientation: orientation, - ); - switch (orientation) { - case Orientation.portrait: - return Container( - color: theme.dialogBackgroundColor, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - header, - Flexible(child: picker), - actions, - ], - ), - ); - case Orientation.landscape: - return Container( - color: theme.dialogBackgroundColor, - child: Row( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Flexible(child: header), - Flexible( - flex: 2, // have the picker take up 2/3 of the dialog width - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Flexible(child: picker), - actions, - ], - ), - ), - ], - ), - ); - } - return null; - } - ), - ); - - return Theme( - data: theme.copyWith( - dialogBackgroundColor: Colors.transparent, - ), - child: dialog, - ); - } -} - -/// Signature for predicating dates for enabled date selections. -/// -/// See [showDatePicker]. -typedef SelectableDayPredicate = bool Function(DateTime day); - -/// Shows a dialog containing a material design date picker. -/// -/// The returned [Future] resolves to the date selected by the user when the -/// user closes the dialog. If the user cancels the dialog, null is returned. -/// -/// An optional [selectableDayPredicate] function can be passed in to customize -/// the days to enable for selection. If provided, only the days that -/// [selectableDayPredicate] returned true for will be selectable. -/// -/// An optional [initialDatePickerMode] argument can be used to display the -/// date picker initially in the year or month+day picker mode. It defaults -/// to month+day, and must not be null. -/// -/// An optional [locale] argument can be used to set the locale for the date -/// picker. It defaults to the ambient locale provided by [Localizations]. -/// -/// An optional [textDirection] argument can be used to set the text direction -/// (RTL or LTR) for the date picker. It defaults to the ambient text direction -/// provided by [Directionality]. If both [locale] and [textDirection] are not -/// null, [textDirection] overrides the direction chosen for the [locale]. -/// -/// The [context], [useRootNavigator] and [routeSettings] arguments are passed to -/// [showDialog], the documentation for which discusses how it is used. -/// -/// The [builder] parameter can be used to wrap the dialog widget -/// to add inherited widgets like [Theme]. -/// -/// {@animation 350 622 https://flutter.github.io/assets-for-api-docs/assets/material/show_date_picker.mp4} -/// -/// {@tool snippet} -/// Show a date picker with the dark theme. -/// -/// ```dart -/// Future selectedDate = showDatePicker( -/// context: context, -/// initialDate: DateTime.now(), -/// firstDate: DateTime(2018), -/// lastDate: DateTime(2030), -/// builder: (BuildContext context, Widget child) { -/// return Theme( -/// data: ThemeData.dark(), -/// child: child, -/// ); -/// }, -/// ); -/// ``` -/// {@end-tool} -/// -/// The [context], [initialDate], [firstDate], and [lastDate] parameters must -/// not be null. -/// -/// See also: -/// -/// * [showTimePicker], which shows a dialog that contains a material design -/// time picker. -/// * [DayPicker], which displays the days of a given month and allows -/// choosing a day. -/// * [MonthPicker], which displays a scrollable list of months to allow -/// picking a month. -/// * [YearPicker], which displays a scrollable list of years to allow picking -/// a year. -Future showDatePicker({ - @required BuildContext context, - @required DateTime initialDate, - @required DateTime firstDate, - @required DateTime lastDate, - SelectableDayPredicate selectableDayPredicate, - DatePickerMode initialDatePickerMode = DatePickerMode.day, - Locale locale, - TextDirection textDirection, - TransitionBuilder builder, - bool useRootNavigator = true, - RouteSettings routeSettings, -}) async { - assert(initialDate != null); - assert(firstDate != null); - assert(lastDate != null); - assert(useRootNavigator != null); - assert(!initialDate.isBefore(firstDate), 'initialDate must be on or after firstDate'); - assert(!initialDate.isAfter(lastDate), 'initialDate must be on or before lastDate'); - assert(!firstDate.isAfter(lastDate), 'lastDate must be on or after firstDate'); - assert( - selectableDayPredicate == null || selectableDayPredicate(initialDate), - 'Provided initialDate must satisfy provided selectableDayPredicate' - ); - assert(initialDatePickerMode != null, 'initialDatePickerMode must not be null'); - assert(context != null); - assert(debugCheckHasMaterialLocalizations(context)); - - Widget child = _DatePickerDialog( - initialDate: initialDate, - firstDate: firstDate, - lastDate: lastDate, - selectableDayPredicate: selectableDayPredicate, - initialDatePickerMode: initialDatePickerMode, - ); - - if (textDirection != null) { - child = Directionality( - textDirection: textDirection, - child: child, - ); - } - - if (locale != null) { - child = Localizations.override( - context: context, - locale: locale, - child: child, - ); - } - - return await showDialog( - context: context, - useRootNavigator: useRootNavigator, - builder: (BuildContext context) { - return builder == null ? child : builder(context, child); - }, - routeSettings: routeSettings, - ); -} diff --git a/packages/flutter/lib/src/material/pickers/date_picker_dialog.dart b/packages/flutter/lib/src/material/pickers/date_picker_dialog.dart new file mode 100644 index 0000000000..ded9a05ee1 --- /dev/null +++ b/packages/flutter/lib/src/material/pickers/date_picker_dialog.dart @@ -0,0 +1,482 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:math' as math; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; + +import '../button_bar.dart'; +import '../button_theme.dart'; +import '../color_scheme.dart'; +import '../debug.dart'; +import '../dialog.dart'; +import '../flat_button.dart'; +import '../icons.dart'; +import '../material_localizations.dart'; +import '../text_theme.dart'; +import '../theme.dart'; + +import 'calendar_date_picker.dart'; +import 'date_picker_common.dart'; +import 'date_picker_header.dart'; +import 'date_utils.dart' as utils; +import 'input_date_picker.dart'; + +const Size _calendarPortraitDialogSize = Size(330.0, 518.0); +const Size _calendarLandscapeDialogSize = Size(496.0, 346.0); +const Size _inputPortraitDialogSize = Size(330.0, 270.0); +const Size _inputLandscapeDialogSize = Size(496, 160.0); +const Duration _dialogSizeAnimationDuration = Duration(milliseconds: 200); + +/// Shows a dialog containing a Material Design date picker. +/// +/// The returned [Future] resolves to the date selected by the user when the +/// user confirms the dialog. If the user cancels the dialog, null is returned. +/// +/// When the date picker is first displayed, it will show the month of +/// [initialDate], with [initialDate] selected. +/// +/// The [firstDate] is the earliest allowable date. The [lastDate] is the latest +/// allowable date. [initialDate] must either fall between these dates, +/// or be equal to one of them. For each of these [DateTime] parameters, only +/// their dates are considered. Their time fields are ignored. They must all +/// be non-null. +/// +/// An optional [initialEntryMode] argument can be used to display the date +/// picker in the [DatePickerEntryMode.calendar] (a calendar month grid) +/// or [DatePickerEntryMode.input] (a text input field) mode. +/// It defaults to [DatePickerEntryMode.calendar] and must be non-null. +/// +/// An optional [selectableDayPredicate] function can be passed in to only allow +/// certain days for selection. If provided, only the days that +/// [selectableDayPredicate] returns true for will be selectable. For example, +/// this can be used to only allow weekdays for selection. If provided, it must +/// return true for [initialDate]. +/// +/// Optional strings for the [cancelText], [confirmText], [errorFormatText], +/// [errorInvalidText], [fieldHintText], [fieldLabelText], and [helpText] allow +/// you to override the default text used for various parts of the dialog: +/// +/// * [cancelText], label on the cancel button. +/// * [confirmText], label on the ok button. +/// * [errorFormatText], message used when the input text isn't in a proper date format. +/// * [errorInvalidText], message used when the input text isn't a selectable date. +/// * [fieldHintText], text used to prompt the user when no text has been entered in the field. +/// * [fieldLabelText], label for the date text input field. +/// * [helpText], label on the top of the dialog. +/// +/// An optional [locale] argument can be used to set the locale for the date +/// picker. It defaults to the ambient locale provided by [Localizations]. +/// +/// An optional [textDirection] argument can be used to set the text direction +/// ([TextDirection.ltr] or [TextDirection.rtl]) for the date picker. It +/// defaults to the ambient text direction provided by [Directionality]. If both +/// [locale] and [textDirection] are non-null, [textDirection] overrides the +/// direction chosen for the [locale]. +/// +/// The [context], [useRootNavigator] and [routeSettings] arguments are passed to +/// [showDialog], the documentation for which discusses how it is used. [context] +/// and [useRootNavigator] must be non-null. +/// +/// The [builder] parameter can be used to wrap the dialog widget +/// to add inherited widgets like [Theme]. +/// +/// An optional [initialDatePickerMode] argument can be used to have the +/// calendar date picker initially appear in the [DatePickerMode.year] or +/// [DatePickerMode.day] mode. It defaults to [DatePickerMode.day], and +/// must be non-null. +Future showDatePicker({ + @required BuildContext context, + @required DateTime initialDate, + @required DateTime firstDate, + @required DateTime lastDate, + DatePickerEntryMode initialEntryMode = DatePickerEntryMode.calendar, + SelectableDayPredicate selectableDayPredicate, + String helpText, + String cancelText, + String confirmText, + Locale locale, + bool useRootNavigator = true, + RouteSettings routeSettings, + TextDirection textDirection, + TransitionBuilder builder, + DatePickerMode initialDatePickerMode = DatePickerMode.day, + String errorFormatText, + String errorInvalidText, + String fieldHintText, + String fieldLabelText, +}) async { + assert(context != null); + assert(initialDate != null); + assert(firstDate != null); + assert(lastDate != null); + initialDate = utils.dateOnly(initialDate); + firstDate = utils.dateOnly(firstDate); + lastDate = utils.dateOnly(lastDate); + assert( + !lastDate.isBefore(firstDate), + 'lastDate $lastDate must be on or after firstDate $firstDate.' + ); + assert( + !initialDate.isBefore(firstDate), + 'initialDate $initialDate must be on or after firstDate $firstDate.' + ); + assert( + !initialDate.isAfter(lastDate), + 'initialDate $initialDate must be on or before lastDate $lastDate.' + ); + assert( + selectableDayPredicate == null || selectableDayPredicate(initialDate), + 'Provided initialDate $initialDate must satisfy provided selectableDayPredicate.' + ); + assert(initialEntryMode != null); + assert(useRootNavigator != null); + assert(initialDatePickerMode != null); + assert(debugCheckHasMaterialLocalizations(context)); + + Widget dialog = _DatePickerDialog( + initialDate: initialDate, + firstDate: firstDate, + lastDate: lastDate, + initialEntryMode: initialEntryMode, + selectableDayPredicate: selectableDayPredicate, + helpText: helpText, + cancelText: cancelText, + confirmText: confirmText, + initialCalendarMode: initialDatePickerMode, + errorFormatText: errorFormatText, + errorInvalidText: errorInvalidText, + fieldHintText: fieldHintText, + fieldLabelText: fieldLabelText, + ); + + if (textDirection != null) { + dialog = Directionality( + textDirection: textDirection, + child: dialog, + ); + } + + if (locale != null) { + dialog = Localizations.override( + context: context, + locale: locale, + child: dialog, + ); + } + + return showDialog( + context: context, + useRootNavigator: useRootNavigator, + routeSettings: routeSettings, + builder: (BuildContext context) { + return builder == null ? dialog : builder(context, dialog); + }, + ); +} + +class _DatePickerDialog extends StatefulWidget { + _DatePickerDialog({ + Key key, + @required DateTime initialDate, + @required DateTime firstDate, + @required DateTime lastDate, + this.initialEntryMode = DatePickerEntryMode.calendar, + this.selectableDayPredicate, + this.cancelText, + this.confirmText, + this.helpText, + this.initialCalendarMode = DatePickerMode.day, + this.errorFormatText, + this.errorInvalidText, + this.fieldHintText, + this.fieldLabelText, + }) : assert(initialDate != null), + assert(firstDate != null), + assert(lastDate != null), + initialDate = utils.dateOnly(initialDate), + firstDate = utils.dateOnly(firstDate), + lastDate = utils.dateOnly(lastDate), + assert(initialEntryMode != null), + assert(initialCalendarMode != null), + super(key: key) { + assert( + !this.lastDate.isBefore(this.firstDate), + 'lastDate ${this.lastDate} must be on or after firstDate ${this.firstDate}.' + ); + assert( + !this.initialDate.isBefore(this.firstDate), + 'initialDate ${this.initialDate} must be on or after firstDate ${this.firstDate}.' + ); + assert( + !this.initialDate.isAfter(this.lastDate), + 'initialDate ${this.initialDate} must be on or before lastDate ${this.lastDate}.' + ); + assert( + selectableDayPredicate == null || selectableDayPredicate(this.initialDate), + 'Provided initialDate ${this.initialDate} must satisfy provided selectableDayPredicate' + ); + } + + /// The initially selected [DateTime] that the picker should display. + final DateTime initialDate; + + /// The earliest allowable [DateTime] that the user can select. + final DateTime firstDate; + + /// The latest allowable [DateTime] that the user can select. + final DateTime lastDate; + + final DatePickerEntryMode initialEntryMode; + + /// Function to provide full control over which [DateTime] can be selected. + final SelectableDayPredicate selectableDayPredicate; + + /// The text that is displayed on the cancel button. + final String cancelText; + + /// The text that is displayed on the confirm button. + final String confirmText; + + /// The text that is displayed at the top of the header. + /// + /// This is used to indicate to the user what they are selecting a date for. + final String helpText; + + /// The initial display of the calendar picker. + final DatePickerMode initialCalendarMode; + + final String errorFormatText; + + final String errorInvalidText; + + final String fieldHintText; + + final String fieldLabelText; + + @override + _DatePickerDialogState createState() => _DatePickerDialogState(); +} + +class _DatePickerDialogState extends State<_DatePickerDialog> { + + DatePickerEntryMode _entryMode; + DateTime _selectedDate; + bool _autoValidate; + final GlobalKey _calendarPickerKey = GlobalKey(); + final GlobalKey _formKey = GlobalKey(); + + @override + void initState() { + super.initState(); + _entryMode = widget.initialEntryMode; + _selectedDate = widget.initialDate; + _autoValidate = false; + } + + void _handleOk() { + if (_entryMode == DatePickerEntryMode.input) { + final FormState form = _formKey.currentState; + if (!form.validate()) { + setState(() => _autoValidate = true); + return; + } + form.save(); + } + Navigator.pop(context, _selectedDate); + } + + void _handleCancel() { + Navigator.pop(context); + } + + void _handelEntryModeToggle() { + setState(() { + switch (_entryMode) { + case DatePickerEntryMode.calendar: + _entryMode = DatePickerEntryMode.input; + break; + case DatePickerEntryMode.input: + _formKey.currentState.save(); + _entryMode = DatePickerEntryMode.calendar; + break; + } + }); + } + + void _handleDateChanged(DateTime date) { + setState(() => _selectedDate = date); + } + + Size _dialogSize(BuildContext context) { + final Orientation orientation = MediaQuery.of(context).orientation; + switch (_entryMode) { + case DatePickerEntryMode.calendar: + switch (orientation) { + case Orientation.portrait: + return _calendarPortraitDialogSize; + case Orientation.landscape: + return _calendarLandscapeDialogSize; + } + break; + case DatePickerEntryMode.input: + switch (orientation) { + case Orientation.portrait: + return _inputPortraitDialogSize; + case Orientation.landscape: + return _inputLandscapeDialogSize; + } + break; + } + return null; + } + + @override + Widget build(BuildContext context) { + final ThemeData theme = Theme.of(context); + final ColorScheme colorScheme = theme.colorScheme; + final MaterialLocalizations localizations = MaterialLocalizations.of(context); + final Orientation orientation = MediaQuery.of(context).orientation; + final TextTheme textTheme = theme.textTheme; + // Constrain the textScaleFactor to the largest supported value to prevent + // layout issues. + final double textScaleFactor = math.min(MediaQuery.of(context).textScaleFactor, 1.3); + + final String dateText = _selectedDate != null + ? localizations.formatMediumDate(_selectedDate) + // TODO(darrenaustin): localize 'Date' + : 'Date'; + final Color dateColor = colorScheme.brightness == Brightness.light + ? colorScheme.onPrimary + : colorScheme.onSurface; + final TextStyle dateStyle = orientation == Orientation.landscape + ? textTheme.headline5?.copyWith(color: dateColor) + : textTheme.headline4?.copyWith(color: dateColor); + + final Widget actions = ButtonBar( + buttonTextTheme: ButtonTextTheme.primary, + layoutBehavior: ButtonBarLayoutBehavior.constrained, + children: [ + FlatButton( + child: Text(widget.cancelText ?? localizations.cancelButtonLabel), + onPressed: _handleCancel, + ), + FlatButton( + child: Text(widget.confirmText ?? localizations.okButtonLabel), + onPressed: _handleOk, + ), + ], + ); + + Widget picker; + IconData entryModeIcon; + String entryModeTooltip; + switch (_entryMode) { + case DatePickerEntryMode.calendar: + picker = CalendarDatePicker( + key: _calendarPickerKey, + initialDate: _selectedDate, + firstDate: widget.firstDate, + lastDate: widget.lastDate, + onDateChanged: _handleDateChanged, + selectableDayPredicate: widget.selectableDayPredicate, + initialCalendarMode: widget.initialCalendarMode, + ); + entryModeIcon = Icons.edit; + // TODO(darrenaustin): localize 'Switch to input' + entryModeTooltip = 'Switch to input'; + break; + + case DatePickerEntryMode.input: + picker = Form( + key: _formKey, + autovalidate: _autoValidate, + child: InputDatePickerFormField( + initialDate: _selectedDate, + firstDate: widget.firstDate, + lastDate: widget.lastDate, + onDateSubmitted: _handleDateChanged, + onDateSaved: _handleDateChanged, + selectableDayPredicate: widget.selectableDayPredicate, + errorFormatText: widget.errorFormatText, + errorInvalidText: widget.errorInvalidText, + fieldHintText: widget.fieldHintText, + fieldLabelText: widget.fieldLabelText, + autofocus: true, + ), + ); + entryModeIcon = Icons.calendar_today; + // TODO(darrenaustin): localize 'Switch to calendar' + entryModeTooltip = 'Switch to calendar'; + break; + } + + final Widget header = DatePickerHeader( + // TODO(darrenaustin): localize 'SELECT DATE' + helpText: widget.helpText ?? 'SELECT DATE', + titleText: dateText, + titleStyle: dateStyle, + orientation: orientation, + isShort: orientation == Orientation.landscape, + icon: entryModeIcon, + iconTooltip: entryModeTooltip, + onIconPressed: _handelEntryModeToggle, + ); + + final Size dialogSize = _dialogSize(context) * textScaleFactor; + return Dialog( + child: AnimatedContainer( + width: dialogSize.width, + height: dialogSize.height, + duration: _dialogSizeAnimationDuration, + curve: Curves.easeIn, + child: MediaQuery( + data: MediaQuery.of(context).copyWith( + textScaleFactor: textScaleFactor, + ), + child: Builder(builder: (BuildContext context) { + switch (orientation) { + case Orientation.portrait: + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + header, + Expanded(child: picker), + actions, + ], + ); + case Orientation.landscape: + return Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + header, + Flexible( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Expanded(child: picker), + actions, + ], + ), + ), + ], + ); + } + return null; + }), + ), + ), + insetPadding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 24.0), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(4.0)) + ), + clipBehavior: Clip.antiAlias, + elevation: 24.0, + ); + } +} diff --git a/packages/flutter/lib/src/material/pickers/date_picker_header.dart b/packages/flutter/lib/src/material/pickers/date_picker_header.dart new file mode 100644 index 0000000000..0f9272abbc --- /dev/null +++ b/packages/flutter/lib/src/material/pickers/date_picker_header.dart @@ -0,0 +1,193 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/widgets.dart'; + +import '../color_scheme.dart'; +import '../icon_button.dart'; +import '../text_theme.dart'; +import '../theme.dart'; + +// NOTE: This is an internal implementation file. Even though there are public +// classes and functions defined here, they are only meant to be used by the +// date picker implementation and are not exported as part of the Material library. +// See pickers.dart for exactly what is considered part of the public API. + +const double _datePickerHeaderLandscapeWidth = 152.0; +const double _datePickerHeaderPortraitHeight = 120.0; +const double _headerPaddingLandscape = 16.0; + +/// Re-usable widget that displays the selected date (in large font) and the +/// help text above it. +/// +/// These types include: +/// +/// * Single Date picker with calendar mode. +/// * Single Date picker with manual input mode. +/// +/// [helpText], [orientation], [icon], [onIconPressed] are required and must be +/// non-null. +class DatePickerHeader extends StatelessWidget { + /// Creates a header for use in a date picker dialog. + const DatePickerHeader({ + Key key, + @required this.helpText, + @required this.titleText, + this.titleSemanticsLabel, + @required this.titleStyle, + @required this.orientation, + this.isShort = false, + @required this.icon, + @required this.iconTooltip, + @required this.onIconPressed, + }) : assert(helpText != null), + assert(orientation != null), + assert(isShort != null), + super(key: key); + + /// The text that is displayed at the top of the header. + /// + /// This is used to indicate to the user what they are selecting a date for. + final String helpText; + + /// The text that is displayed at the center of the header. + final String titleText; + + /// The semantic label associated with the [titleText]. + final String titleSemanticsLabel; + + /// The [TextStyle] that the title text is displayed with. + final TextStyle titleStyle; + + /// The orientation is used to decide how to layout its children. + final Orientation orientation; + + /// Indicates the header is being displayed in a shorter/narrower context. + /// + /// This will be used to tighten up the space between the help text and date + /// text if `true`. Additionally, it will use a smaller typography style if + /// `true`. + /// + /// This is necessary for displaying the manual input mode in + /// landscape orientation, in order to account for the keyboard height. + final bool isShort; + + /// The mode-switching icon that will be displayed in the lower right + /// in portrait, and lower left in landscape. + /// + /// The available icons are described in [Icons]. + final IconData icon; + + /// The text that is displayed for the tooltip of the icon. + final String iconTooltip; + + /// Callback when the user taps the icon in the header. + /// + /// The picker will use this to toggle between entry modes. + final VoidCallback onIconPressed; + + @override + Widget build(BuildContext context) { + final ThemeData theme = Theme.of(context); + final ColorScheme colorScheme = theme.colorScheme; + final TextTheme textTheme = theme.textTheme; + + // The header should use the primary color in light themes and surface color in dark + final bool isDark = colorScheme.brightness == Brightness.dark; + final Color primarySurfaceColor = isDark ? colorScheme.surface : colorScheme.primary; + final Color onPrimarySurfaceColor = isDark ? colorScheme.onSurface : colorScheme.onPrimary; + + final TextStyle helpStyle = textTheme.overline?.copyWith( + color: onPrimarySurfaceColor, + ); + + final Text help = Text( + helpText, + style: helpStyle, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ); + final Text title = Text( + titleText, + semanticsLabel: titleSemanticsLabel ?? titleText, + style: titleStyle, + maxLines: (isShort || orientation == Orientation.portrait) ? 1 : 2, + overflow: TextOverflow.ellipsis, + ); + final IconButton icon = IconButton( + icon: Icon(this.icon), + color: onPrimarySurfaceColor, + tooltip: iconTooltip, + onPressed: onIconPressed, + ); + + switch (orientation) { + case Orientation.portrait: + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + height: _datePickerHeaderPortraitHeight, + color: primarySurfaceColor, + padding: const EdgeInsetsDirectional.only( + start: 24, + end: 12, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 16), + Flexible(child: help), + const SizedBox(height: 38), + Row( + children: [ + Expanded(child: title), + icon, + ], + ), + ], + ), + ), + ], + ); + case Orientation.landscape: + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: _datePickerHeaderLandscapeWidth, + color: primarySurfaceColor, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 16), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: _headerPaddingLandscape, + ), + child: help, + ), + SizedBox(height: isShort ? 16 : 56), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: _headerPaddingLandscape, + ), + child: title, + ), + const Spacer(), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 4, + ), + child: icon, + ), + ], + ), + ), + ], + ); + } + return null; + } +} diff --git a/packages/flutter/lib/src/material/pickers/date_utils.dart b/packages/flutter/lib/src/material/pickers/date_utils.dart new file mode 100644 index 0000000000..c156b05cbb --- /dev/null +++ b/packages/flutter/lib/src/material/pickers/date_utils.dart @@ -0,0 +1,122 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + + +// Common date utility functions used by the date picker implementation + +// NOTE: This is an internal implementation file. Even though there are public +// classes and functions defined here, they are only meant to be used by the +// date picker implementation and are not exported as part of the Material library. +// See pickers.dart for exactly what is considered part of the public API. + +import '../material_localizations.dart'; + +/// Returns a [DateTime] with just the date of the original, but no time set. +DateTime dateOnly(DateTime date) { + return DateTime(date.year, date.month, date.day); +} + +/// Returns true if the two [DateTime] objects have the same day, month, and +/// year. +bool isSameDay(DateTime dateA, DateTime dateB) { + return + dateA.year == dateB.year && + dateA.month == dateB.month && + dateA.day == dateB.day; +} + +/// Determines the number of months between two [DateTime] objects. +/// +/// For example: +/// ``` +/// DateTime date1 = DateTime(year: 2019, month: 6, day: 15); +/// DateTime date2 = DateTime(year: 2020, month: 1, day: 15); +/// int delta = monthDelta(date1, date2); +/// ``` +/// +/// The value for `delta` would be `7`. +int monthDelta(DateTime startDate, DateTime endDate) { + return (endDate.year - startDate.year) * 12 + endDate.month - startDate.month; +} + +/// Returns a [DateTime] with the added number of months and truncates any day +/// and time information. +/// +/// For example: +/// ``` +/// DateTime date = DateTime(year: 2019, month: 1, day: 15); +/// DateTime futureDate = _addMonthsToMonthDate(date, 3); +/// ``` +/// +/// `date` would be January 15, 2019. +/// `futureDate` would be April 1, 2019 since it adds 3 months and truncates +/// any additional date information. +DateTime addMonthsToMonthDate(DateTime monthDate, int monthsToAdd) { + return DateTime(monthDate.year, monthDate.month + monthsToAdd); +} + +/// Computes the offset from the first day of the week that the first day of +/// the [month] falls on. +/// +/// For example, September 1, 2017 falls on a Friday, which in the calendar +/// localized for United States English appears as: +/// +/// ``` +/// S M T W T F S +/// _ _ _ _ _ 1 2 +/// ``` +/// +/// The offset for the first day of the months is the number of leading blanks +/// in the calendar, i.e. 5. +/// +/// The same date localized for the Russian calendar has a different offset, +/// because the first day of week is Monday rather than Sunday: +/// +/// ``` +/// M T W T F S S +/// _ _ _ _ 1 2 3 +/// ``` +/// +/// So the offset is 4, rather than 5. +/// +/// This code consolidates the following: +/// +/// - [DateTime.weekday] provides a 1-based index into days of week, with 1 +/// falling on Monday. +/// - [MaterialLocalizations.firstDayOfWeekIndex] provides a 0-based index +/// into the [MaterialLocalizations.narrowWeekdays] list. +/// - [MaterialLocalizations.narrowWeekdays] list provides localized names of +/// days of week, always starting with Sunday and ending with Saturday. +int firstDayOffset(int year, int month, MaterialLocalizations localizations) { + // 0-based day of week for the month and year, with 0 representing Monday. + final int weekdayFromMonday = DateTime(year, month).weekday - 1; + + // 0-based start of week depending on the locale, with 0 representing Sunday. + int firstDayOfWeekIndex = localizations.firstDayOfWeekIndex; + + // firstDayOfWeekIndex recomputed to be Monday-based, in order to compare with + // weekdayFromMonday. + firstDayOfWeekIndex = (firstDayOfWeekIndex - 1) % 7; + + // Number of days between the first day of week appearing on the calendar, + // and the day corresponding to the first of the month. + return (weekdayFromMonday - firstDayOfWeekIndex) % 7; +} + +/// Returns the number of days in a month, according to the proleptic +/// Gregorian calendar. +/// +/// This applies the leap year logic introduced by the Gregorian reforms of +/// 1582. It will not give valid results for dates prior to that time. +int getDaysInMonth(int year, int month) { + if (month == DateTime.february) { + final bool isLeapYear = (year % 4 == 0) && (year % 100 != 0) || + (year % 400 == 0); + if (isLeapYear) + return 29; + return 28; + } + const List daysInMonth = [31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + return daysInMonth[month - 1]; +} diff --git a/packages/flutter/lib/src/material/pickers/input_date_picker.dart b/packages/flutter/lib/src/material/pickers/input_date_picker.dart new file mode 100644 index 0000000000..6c0af3aa64 --- /dev/null +++ b/packages/flutter/lib/src/material/pickers/input_date_picker.dart @@ -0,0 +1,281 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; + +import '../input_border.dart'; +import '../input_decorator.dart'; +import '../material_localizations.dart'; +import '../text_field.dart'; +import '../text_form_field.dart'; + +import 'date_picker_common.dart'; +import 'date_utils.dart' as utils; + +const double _inputPortraitHeight = 98.0; +const double _inputLandscapeHeight = 108.0; + +/// A [TextFormField] configured to accept and validate a date entered by the user. +/// +/// The text entered into this field will be constrained to only allow digits +/// and separators. When saved or submitted, the text will be parsed into a +/// [DateTime] according to the ambient locale. If the input text doesn't parse +/// into a date, the [errorFormatText] message will be displayed under the field. +/// +/// [firstDate], [lastDate], and [selectableDayPredicate] provide constraints on +/// what days are valid. If the input date isn't in the date range or doesn't pass +/// the given predicate, then the [errorInvalidText] message will be displayed +/// under the field. +/// +/// See also: +/// +/// * [showDatePicker], which shows a dialog that contains a material design +/// date picker which includes support for text entry of dates. +/// * [MaterialLocalizations.parseCompactDate], which is used to parse the text +/// input into a [DateTime]. +/// +class InputDatePickerFormField extends StatefulWidget { + /// Creates a [TextFormField] configured to accept and validate a date. + /// + /// If the optional [initialDate] is provided, then it will be used to populate + /// the text field. If the [fieldHintText] is provided, it will be shown. + /// + /// If [initialDate] is provided, it must not be before [firstDate] or after + /// [lastDate]. If [selectableDayPredicate] is provided, it must return `true` + /// for [initialDate]. + /// + /// [firstDate] must be on or before [lastDate]. + /// + /// [firstDate], [lastDate], and [autofocus] must be non-null. + /// + InputDatePickerFormField({ + Key key, + DateTime initialDate, + @required DateTime firstDate, + @required DateTime lastDate, + this.onDateSubmitted, + this.onDateSaved, + this.selectableDayPredicate, + this.errorFormatText, + this.errorInvalidText, + this.fieldHintText, + this.fieldLabelText, + this.autofocus = false, + }) : assert(firstDate != null), + assert(lastDate != null), + assert(autofocus != null), + initialDate = initialDate != null ? utils.dateOnly(initialDate) : null, + firstDate = utils.dateOnly(firstDate), + lastDate = utils.dateOnly(lastDate), + super(key: key) { + assert( + !this.lastDate.isBefore(this.firstDate), + 'lastDate ${this.lastDate} must be on or after firstDate ${this.firstDate}.' + ); + assert( + initialDate == null || !this.initialDate.isBefore(this.firstDate), + 'initialDate ${this.initialDate} must be on or after firstDate ${this.firstDate}.' + ); + assert( + initialDate == null || !this.initialDate.isAfter(this.lastDate), + 'initialDate ${this.initialDate} must be on or before lastDate ${this.lastDate}.' + ); + assert( + selectableDayPredicate == null || initialDate == null || selectableDayPredicate(this.initialDate), + 'Provided initialDate ${this.initialDate} must satisfy provided selectableDayPredicate.' + ); + } + + /// If provided, it will be used as the default value of the field. + final DateTime initialDate; + + /// The earliest allowable [DateTime] that the user can input. + final DateTime firstDate; + + /// The latest allowable [DateTime] that the user can input. + final DateTime lastDate; + + /// An optional method to call when the user indicates they are done editing + /// the text in the field. Will only be called if the input represents a valid + /// [DateTime]. + final ValueChanged onDateSubmitted; + + /// An optional method to call with the final date when the form is + /// saved via [FormState.save]. Will only be called if the input represents + /// a valid [DateTime]. + final ValueChanged onDateSaved; + + /// Function to provide full control over which [DateTime] can be selected. + final SelectableDayPredicate selectableDayPredicate; + + /// The error text displayed if the entered date is not in the correct format. + final String errorFormatText; + + /// The error text displayed if the date is not valid. + /// + /// A date is not valid if it is earlier than [firstDate], later than + /// [lastDate], or doesn't pass the [selectableDayPredicate]. + final String errorInvalidText; + + /// The hint text displayed in the [TextField]. + /// + /// If this is null, it will default to the date format string. For example, + /// 'mm/dd/yyyy' for en_US. + final String fieldHintText; + + /// The label text displayed in the [TextField]. + /// + /// If this is null, it will default to the words representing the date format + /// string. For example, 'Month, Day, Year' for en_US. + final String fieldLabelText; + + /// {@macro flutter.widgets.editableText.autofocus} + final bool autofocus; + + @override + _InputDatePickerFormFieldState createState() => _InputDatePickerFormFieldState(); +} + +class _InputDatePickerFormFieldState extends State { + final TextEditingController _controller = TextEditingController(); + DateTime _selectedDate; + String _inputText; + bool _autoSelected = false; + + @override + void initState() { + super.initState(); + _selectedDate = widget.initialDate; + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + if (_selectedDate != null) { + final MaterialLocalizations localizations = MaterialLocalizations.of(context); + _inputText = localizations.formatCompactDate(_selectedDate); + TextEditingValue textEditingValue = _controller.value.copyWith(text: _inputText); + // Select the new text if we are auto focused and haven't selected the text before. + if (widget.autofocus && !_autoSelected) { + textEditingValue = textEditingValue.copyWith(selection: TextSelection( + baseOffset: 0, + extentOffset: _inputText.length, + )); + _autoSelected = true; + } + _controller.value = textEditingValue; + } + } + + DateTime _parseDate(String text) { + final MaterialLocalizations localizations = MaterialLocalizations.of(context); + return localizations.parseCompactDate(text); + } + + bool _isValidAcceptableDate(DateTime date) { + return + date != null && + !date.isBefore(widget.firstDate) && + !date.isAfter(widget.lastDate) && + (widget.selectableDayPredicate == null || widget.selectableDayPredicate(date)); + } + + String _validateDate(String text) { + final DateTime date = _parseDate(text); + if (date == null) { + // TODO(darrenaustin): localize 'Invalid format.' + return widget.errorFormatText ?? 'Invalid format.'; + } else if (!_isValidAcceptableDate(date)) { + // TODO(darrenaustin): localize 'Out of range.' + return widget.errorInvalidText ?? 'Out of range.'; + } + return null; + } + + void _handleSaved(String text) { + if (widget.onDateSaved != null) { + final DateTime date = _parseDate(text); + if (_isValidAcceptableDate(date)) { + _selectedDate = date; + _inputText = text; + widget.onDateSaved(date); + } + } + } + + void _handleSubmitted(String text) { + if (widget.onDateSubmitted != null) { + final DateTime date = _parseDate(text); + if (_isValidAcceptableDate(date)) { + _selectedDate = date; + _inputText = text; + widget.onDateSubmitted(date); + } + } + } + + @override + Widget build(BuildContext context) { + return OrientationBuilder(builder: (BuildContext context, Orientation orientation) { + assert(orientation != null); + + return Container( + padding: const EdgeInsets.symmetric(horizontal: 24), + height: orientation == Orientation.portrait ? _inputPortraitHeight : _inputLandscapeHeight, + child: Column( + children: [ + const Spacer(), + TextFormField( + decoration: InputDecoration( + border: const UnderlineInputBorder(), + filled: true, + // TODO(darrenaustin): localize 'mm/dd/yyyy' and 'Enter Date' + hintText: widget.fieldHintText ?? 'mm/dd/yyyy', + labelText: widget.fieldLabelText ?? 'Enter Date', + ), + validator: _validateDate, + inputFormatters: [ + // TODO(darrenaustin): localize date separator '/' + _DateTextInputFormatter('/'), + ], + keyboardType: TextInputType.datetime, + onSaved: _handleSaved, + onFieldSubmitted: _handleSubmitted, + autofocus: widget.autofocus, + controller: _controller, + ), + const Spacer(), + ], + ), + ); + }); + } +} + +class _DateTextInputFormatter extends TextInputFormatter { + + _DateTextInputFormatter(this.separator); + + final String separator; + + final WhitelistingTextInputFormatter _filterFormatter = + // Only allow digits and separators (slash, dot, comma, hyphen, space). + WhitelistingTextInputFormatter(RegExp(r'[\d\/\.,-\s]+')); + + @override + TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) { + final TextEditingValue filteredValue = _filterFormatter.formatEditUpdate(oldValue, newValue); + return filteredValue.copyWith( + // Replace any separator character with the given separator + text: filteredValue.text.replaceAll(RegExp(r'[\D]'), separator), + ); + } +} diff --git a/packages/flutter/lib/src/material/pickers/pickers.dart b/packages/flutter/lib/src/material/pickers/pickers.dart new file mode 100644 index 0000000000..8f834046da --- /dev/null +++ b/packages/flutter/lib/src/material/pickers/pickers.dart @@ -0,0 +1,10 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Date Picker public API +export 'calendar_date_picker.dart' show CalendarDatePicker; +export 'date_picker_common.dart' show DatePickerEntryMode, DatePickerMode, SelectableDayPredicate; +export 'date_picker_deprecated.dart'; +export 'date_picker_dialog.dart' show showDatePicker; +export 'input_date_picker.dart' show InputDatePickerFormField; diff --git a/packages/flutter/test/material/date_picker_test.dart b/packages/flutter/test/material/date_picker_test.dart index 7b683c8db7..5bb8c1f9a8 100644 --- a/packages/flutter/test/material/date_picker_test.dart +++ b/packages/flutter/test/material/date_picker_test.dart @@ -2,135 +2,55 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui'; - -import 'package:flutter/rendering.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:flutter/gestures.dart' show DragStartBehavior; -import '../widgets/semantics_tester.dart'; import 'feedback_tester.dart'; void main() { - group('showDatePicker', () { - _tests(); - }); -} -void _tests() { DateTime firstDate; DateTime lastDate; DateTime initialDate; SelectableDayPredicate selectableDayPredicate; - DatePickerMode initialDatePickerMode; + DatePickerEntryMode initialEntryMode; + DatePickerMode initialCalendarMode; + + String cancelText; + String confirmText; + String errorFormatText; + String errorInvalidText; + String fieldHintText; + String fieldLabelText; + String helpText; + final Finder nextMonthIcon = find.byWidgetPredicate((Widget w) => w is IconButton && (w.tooltip?.startsWith('Next month') ?? false)); final Finder previousMonthIcon = find.byWidgetPredicate((Widget w) => w is IconButton && (w.tooltip?.startsWith('Previous month') ?? false)); + final Finder switchToInputIcon = find.byIcon(Icons.edit); + final Finder switchToCalendarIcon = find.byIcon(Icons.calendar_today); + + TextField textField(WidgetTester tester) { + return tester.widget(find.byType(TextField)); + } setUp(() { firstDate = DateTime(2001, DateTime.january, 1); lastDate = DateTime(2031, DateTime.december, 31); initialDate = DateTime(2016, DateTime.january, 15); selectableDayPredicate = null; - initialDatePickerMode = null; + initialEntryMode = DatePickerEntryMode.calendar; + initialCalendarMode = DatePickerMode.day; + + cancelText = null; + confirmText = null; + errorFormatText = null; + errorInvalidText = null; + fieldHintText = null; + fieldLabelText = null; + helpText = null; }); - testWidgets('tap-select a day', (WidgetTester tester) async { - final Key _datePickerKey = UniqueKey(); - DateTime _selectedDate = DateTime(2016, DateTime.july, 26); - - await tester.pumpWidget( - MaterialApp( - home: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return Container( - width: 400.0, - child: SingleChildScrollView( - dragStartBehavior: DragStartBehavior.down, - child: Material( - child: MonthPicker( - dragStartBehavior: DragStartBehavior.down, - firstDate: DateTime(0), - lastDate: DateTime(9999), - key: _datePickerKey, - selectedDate: _selectedDate, - onChanged: (DateTime value) { - setState(() { - _selectedDate = value; - }); - }, - ), - ), - ), - ); - }, - ), - ), - ); - - expect(_selectedDate, equals(DateTime(2016, DateTime.july, 26))); - - await tester.tapAt(const Offset(50.0, 100.0)); - await tester.pumpAndSettle(); - await tester.pump(const Duration(seconds: 2)); - - await tester.tap(find.text('1')); - await tester.pumpAndSettle(); - expect(_selectedDate, equals(DateTime(2016, DateTime.july, 1))); - - await tester.tap(nextMonthIcon); - await tester.pumpAndSettle(); - expect(_selectedDate, equals(DateTime(2016, DateTime.july, 1))); - - await tester.tap(find.text('5')); - await tester.pumpAndSettle(); - expect(_selectedDate, equals(DateTime(2016, DateTime.august, 5))); - - await tester.drag(find.byKey(_datePickerKey), const Offset(-400.0, 0.0)); - await tester.pumpAndSettle(); - expect(_selectedDate, equals(DateTime(2016, DateTime.august, 5))); - - await tester.tap(find.text('25')); - await tester.pumpAndSettle(); - expect(_selectedDate, equals(DateTime(2016, DateTime.september, 25))); - - await tester.drag(find.byKey(_datePickerKey), const Offset(800.0, 0.0)); - await tester.pumpAndSettle(); - expect(_selectedDate, equals(DateTime(2016, DateTime.september, 25))); - - await tester.tap(find.text('17')); - await tester.pumpAndSettle(); - expect(_selectedDate, equals(DateTime(2016, DateTime.august, 17))); - }); - - testWidgets('render picker with intrinsic dimensions', (WidgetTester tester) async { - await tester.pumpWidget( - MaterialApp( - home: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return IntrinsicWidth( - child: IntrinsicHeight( - child: Material( - child: SingleChildScrollView( - child: MonthPicker( - firstDate: DateTime(0), - lastDate: DateTime(9999), - onChanged: (DateTime value) { }, - selectedDate: DateTime(2000, DateTime.january, 1), - ), - ), - ), - ), - ); - }, - ), - ), - ); - await tester.pump(const Duration(seconds: 5)); - }); - - Future preparePicker(WidgetTester tester, Future callback(Future date)) async { + Future prepareDatePicker(WidgetTester tester, Future callback(Future date)) async { BuildContext buttonContext; await tester.pumpWidget(MaterialApp( home: Material( @@ -150,200 +70,466 @@ void _tests() { await tester.tap(find.text('Go')); expect(buttonContext, isNotNull); - final Future date = initialDatePickerMode == null - // Exercise the argument default for initialDatePickerMode. - ? - showDatePicker( - context: buttonContext, - initialDate: initialDate, - firstDate: firstDate, - lastDate: lastDate, - selectableDayPredicate: selectableDayPredicate, - ) - : - showDatePicker( - context: buttonContext, - initialDate: initialDate, - firstDate: firstDate, - lastDate: lastDate, - selectableDayPredicate: selectableDayPredicate, - initialDatePickerMode: initialDatePickerMode, - ); + final Future date = showDatePicker( + context: buttonContext, + initialDate: initialDate, + firstDate: firstDate, + lastDate: lastDate, + selectableDayPredicate: selectableDayPredicate, + initialDatePickerMode: initialCalendarMode, + initialEntryMode: initialEntryMode, + cancelText: cancelText, + confirmText: confirmText, + errorFormatText: errorFormatText, + errorInvalidText: errorInvalidText, + fieldHintText: fieldHintText, + fieldLabelText: fieldLabelText, + helpText: helpText, + ); await tester.pumpAndSettle(const Duration(seconds: 1)); await callback(date); } - testWidgets('Initial date is the default', (WidgetTester tester) async { - await preparePicker(tester, (Future date) async { - await tester.tap(find.text('OK')); - expect(await date, equals(DateTime(2016, DateTime.january, 15))); + group('showDatePicker Dialog', () { + testWidgets('Cancel, confirm, and help text is used', (WidgetTester tester) async { + cancelText = 'nope'; + confirmText = 'yep'; + helpText = 'help'; + await prepareDatePicker(tester, (Future date) async { + expect(find.text(cancelText), findsOneWidget); + expect(find.text(confirmText), findsOneWidget); + expect(find.text(helpText), findsOneWidget); + }); }); - }); - testWidgets('Can cancel', (WidgetTester tester) async { - await preparePicker(tester, (Future date) async { - await tester.tap(find.text('CANCEL')); - expect(await date, isNull); + testWidgets('Initial date is the default', (WidgetTester tester) async { + await prepareDatePicker(tester, (Future date) async { + await tester.tap(find.text('OK')); + expect(await date, DateTime(2016, DateTime.january, 15)); + }); }); - }); - testWidgets('Can select a day', (WidgetTester tester) async { - await preparePicker(tester, (Future date) async { - await tester.tap(find.text('12')); - await tester.tap(find.text('OK')); - expect(await date, equals(DateTime(2016, DateTime.january, 12))); + testWidgets('Can cancel', (WidgetTester tester) async { + await prepareDatePicker(tester, (Future date) async { + await tester.tap(find.text('CANCEL')); + expect(await date, isNull); + }); }); - }); - testWidgets('Can select a month', (WidgetTester tester) async { - await preparePicker(tester, (Future date) async { - await tester.tap(previousMonthIcon); - await tester.pumpAndSettle(const Duration(seconds: 1)); - await tester.tap(find.text('25')); - await tester.tap(find.text('OK')); - expect(await date, equals(DateTime(2015, DateTime.december, 25))); + testWidgets('Can toggle to input entry mode', (WidgetTester tester) async { + await prepareDatePicker(tester, (Future date) async { + expect(find.byType(TextField), findsNothing); + await tester.tap(find.byIcon(Icons.edit)); + await tester.pumpAndSettle(); + expect(find.byType(TextField), findsOneWidget); + }); }); - }); - testWidgets('Can select a year', (WidgetTester tester) async { - await preparePicker(tester, (Future date) async { - await tester.tap(find.text('2016')); - await tester.pump(); - await tester.tap(find.text('2018')); - await tester.tap(find.text('OK')); - expect(await date, equals(DateTime(2018, DateTime.january, 15))); + testWidgets('Toggle to input mode keeps selected date', (WidgetTester tester) async { + await prepareDatePicker(tester, (Future date) async { + await tester.tap(find.text('12')); + await tester.tap(find.byIcon(Icons.edit)); + await tester.pumpAndSettle(); + await tester.tap(find.text('OK')); + expect(await date, DateTime(2016, DateTime.january, 12)); + }); }); - }); - testWidgets('Can select a year and then a day', (WidgetTester tester) async { - await preparePicker(tester, (Future date) async { - await tester.tap(find.text('2016')); - await tester.pump(); - await tester.tap(find.text('2017')); - await tester.pump(); - final MaterialLocalizations localizations = MaterialLocalizations.of( - tester.element(find.byType(DayPicker)) - ); - final String dayLabel = localizations.formatMediumDate(DateTime(2017, DateTime.january, 15)); - await tester.tap(find.text(dayLabel)); - await tester.pump(); - await tester.tap(find.text('19')); - await tester.tap(find.text('OK')); - expect(await date, equals(DateTime(2017, DateTime.january, 19))); - }); - }); + testWidgets('builder parameter', (WidgetTester tester) async { + Widget buildFrame(TextDirection textDirection) { + return MaterialApp( + home: Material( + child: Center( + child: Builder( + builder: (BuildContext context) { + return RaisedButton( + child: const Text('X'), + onPressed: () { + showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime(2018), + lastDate: DateTime(2030), + builder: (BuildContext context, Widget child) { + return Directionality( + textDirection: textDirection, + child: child, + ); + }, + ); + }, + ); + }, + ), + ), + ), + ); + } - testWidgets('Current year is initially visible in year picker', (WidgetTester tester) async { - initialDate = DateTime(2000); - firstDate = DateTime(1900); - lastDate = DateTime(2100); - await preparePicker(tester, (Future date) async { - await tester.tap(find.text('2000')); - await tester.pump(); - expect(find.text('2000'), findsNWidgets(2)); - }); - }); - - testWidgets('Cannot select a day outside bounds', (WidgetTester tester) async { - initialDate = DateTime(2017, DateTime.january, 15); - firstDate = initialDate; - lastDate = initialDate; - await preparePicker(tester, (Future date) async { - await tester.tap(find.text('10')); // Earlier than firstDate. Should be ignored. - await tester.tap(find.text('20')); // Later than lastDate. Should be ignored. - await tester.tap(find.text('OK')); - // We should still be on the initial date. - expect(await date, equals(initialDate)); - }); - }); - - testWidgets('Cannot select a month past last date', (WidgetTester tester) async { - initialDate = DateTime(2017, DateTime.january, 15); - firstDate = initialDate; - lastDate = DateTime(2017, DateTime.february, 20); - await preparePicker(tester, (Future date) async { - await tester.tap(nextMonthIcon); - await tester.pumpAndSettle(const Duration(seconds: 1)); - // Shouldn't be possible to keep going into March. - expect(nextMonthIcon, findsNothing); - }); - }); - - testWidgets('Cannot select a month before first date', (WidgetTester tester) async { - initialDate = DateTime(2017, DateTime.january, 15); - firstDate = DateTime(2016, DateTime.december, 10); - lastDate = initialDate; - await preparePicker(tester, (Future date) async { - await tester.tap(previousMonthIcon); - await tester.pumpAndSettle(const Duration(seconds: 1)); - // Shouldn't be possible to keep going into November. - expect(previousMonthIcon, findsNothing); - }); - }); - - testWidgets('Selecting firstDate year respects firstDate', (WidgetTester tester) async { - // Regression test for https://github.com/flutter/flutter/issues/17309 - initialDate = DateTime(2018, DateTime.may, 4); - firstDate = DateTime(2016, DateTime.june, 9); - lastDate = DateTime(2019, DateTime.january, 15); - await preparePicker(tester, (Future date) async { - await tester.tap(find.text('2018')); + await tester.pumpWidget(buildFrame(TextDirection.ltr)); + await tester.tap(find.text('X')); await tester.pumpAndSettle(); - await tester.tap(find.text('2016')); + final double ltrOkRight = tester.getBottomRight(find.text('OK')).dx; + + await tester.tap(find.text('OK')); // Dismiss the dialog. await tester.pumpAndSettle(); - await tester.tap(find.text('OK')); + + await tester.pumpWidget(buildFrame(TextDirection.rtl)); + await tester.tap(find.text('X')); await tester.pumpAndSettle(); - expect(await date, DateTime(2016, DateTime.june, 9)); + + // Verify that the time picker is being laid out RTL. + // We expect the left edge of the 'OK' button in the RTL + // layout to match the gap between right edge of the 'OK' + // button and the right edge of the 800 wide window. + expect(tester.getBottomLeft(find.text('OK')).dx, 800 - ltrOkRight); + }); + + testWidgets('uses nested navigator if useRootNavigator is false', (WidgetTester tester) async { + final _DatePickerObserver rootObserver = _DatePickerObserver(); + final _DatePickerObserver nestedObserver = _DatePickerObserver(); + + await tester.pumpWidget(MaterialApp( + navigatorObservers: [rootObserver], + home: Navigator( + observers: [nestedObserver], + onGenerateRoute: (RouteSettings settings) { + return MaterialPageRoute( + builder: (BuildContext context) { + return RaisedButton( + onPressed: () { + showDatePicker( + context: context, + useRootNavigator: false, + initialDate: DateTime.now(), + firstDate: DateTime(2018), + lastDate: DateTime(2030), + builder: (BuildContext context, Widget child) => const SizedBox(), + ); + }, + child: const Text('Show Date Picker'), + ); + }, + ); + }, + ), + )); + + // Open the dialog. + await tester.tap(find.byType(RaisedButton)); + + expect(rootObserver.datePickerCount, 0); + expect(nestedObserver.datePickerCount, 1); + }); + + }); + + group('Calendar mode', () { + testWidgets('Can select a day', (WidgetTester tester) async { + await prepareDatePicker(tester, (Future date) async { + await tester.tap(find.text('12')); + await tester.tap(find.text('OK')); + expect(await date, equals(DateTime(2016, DateTime.january, 12))); + }); + }); + + testWidgets('Can select a month', (WidgetTester tester) async { + await prepareDatePicker(tester, (Future date) async { + await tester.tap(previousMonthIcon); + await tester.pumpAndSettle(const Duration(seconds: 1)); + await tester.tap(find.text('25')); + await tester.tap(find.text('OK')); + expect(await date, DateTime(2015, DateTime.december, 25)); + }); + }); + + testWidgets('Can select a year', (WidgetTester tester) async { + await prepareDatePicker(tester, (Future date) async { + await tester.tap(find.text('January 2016')); // Switch to year mode. + await tester.pump(); + await tester.tap(find.text('2018')); + await tester.pump(); + expect(find.text('January 2018'), findsOneWidget); + }); + }); + + testWidgets('Changing year does not change selected date', (WidgetTester tester) async { + await prepareDatePicker(tester, (Future date) async { + await tester.tap(find.text('January 2016')); + await tester.pump(); + await tester.tap(find.text('2018')); + await tester.pump(); + await tester.tap(find.text('OK')); + expect(await date, equals(DateTime(2016, DateTime.january, 15))); + }); + }); + + testWidgets('Changing year does not change the month', (WidgetTester tester) async { + await prepareDatePicker(tester, (Future date) async { + await tester.tap(nextMonthIcon); + await tester.pumpAndSettle(); + await tester.tap(nextMonthIcon); + await tester.pumpAndSettle(); + await tester.tap(find.text('March 2016')); + await tester.pumpAndSettle(); + await tester.tap(find.text('2018')); + await tester.pumpAndSettle(); + expect(find.text('March 2018'), findsOneWidget); + }); + }); + + testWidgets('Can select a year and then a day', (WidgetTester tester) async { + await prepareDatePicker(tester, (Future date) async { + await tester.tap(find.text('January 2016')); // Switch to year mode. + await tester.pump(); + await tester.tap(find.text('2017')); + await tester.pump(); + await tester.tap(find.text('19')); + await tester.tap(find.text('OK')); + expect(await date, DateTime(2017, DateTime.january, 19)); + }); + }); + + testWidgets('Current year is visible in year picker', (WidgetTester tester) async { + await prepareDatePicker(tester, (Future date) async { + await tester.tap(find.text('January 2016')); // Switch to year mode. + await tester.pump(); + expect(find.text('2016'), findsOneWidget); + }); + }); + + testWidgets('Cannot select a day outside bounds', (WidgetTester tester) async { + initialDate = DateTime(2017, DateTime.january, 15); + firstDate = initialDate; + lastDate = initialDate; + await prepareDatePicker(tester, (Future date) async { + // Earlier than firstDate. Should be ignored. + await tester.tap(find.text('10')); + // Later than lastDate. Should be ignored. + await tester.tap(find.text('20')); + await tester.tap(find.text('OK')); + // We should still be on the initial date. + expect(await date, initialDate); + }); + }); + + testWidgets('Cannot select a month past last date', (WidgetTester tester) async { + initialDate = DateTime(2017, DateTime.january, 15); + firstDate = initialDate; + lastDate = DateTime(2017, DateTime.february, 20); + await prepareDatePicker(tester, (Future date) async { + await tester.tap(nextMonthIcon); + await tester.pumpAndSettle(const Duration(seconds: 1)); + // Shouldn't be possible to keep going into March. + expect(nextMonthIcon, findsNothing); + }); + }); + + testWidgets('Cannot select a month before first date', (WidgetTester tester) async { + initialDate = DateTime(2017, DateTime.january, 15); + firstDate = DateTime(2016, DateTime.december, 10); + lastDate = initialDate; + await prepareDatePicker(tester, (Future date) async { + await tester.tap(previousMonthIcon); + await tester.pumpAndSettle(const Duration(seconds: 1)); + // Shouldn't be possible to keep going into November. + expect(previousMonthIcon, findsNothing); + }); + }); + + testWidgets('Cannot select disabled year', (WidgetTester tester) async { + initialDate = DateTime(2018, DateTime.july, 4); + firstDate = DateTime(2018, DateTime.june, 9); + lastDate = DateTime(2018, DateTime.december, 15); + await prepareDatePicker(tester, (Future date) async { + await tester.tap(find.text('July 2018')); // Switch to year mode. + await tester.pumpAndSettle(); + await tester.tap(find.text('2016')); // Disabled, doesn't change the year. + await tester.pumpAndSettle(); + await tester.tap(find.text('OK')); + await tester.pumpAndSettle(); + expect(await date, DateTime(2018, DateTime.july, 4)); + }); + }); + + testWidgets('Selecting firstDate year respects firstDate', (WidgetTester tester) async { + initialDate = DateTime(2018, DateTime.may, 4); + firstDate = DateTime(2016, DateTime.june, 9); + lastDate = DateTime(2019, DateTime.january, 15); + await prepareDatePicker(tester, (Future date) async { + await tester.tap(find.text('May 2018')); + await tester.pumpAndSettle(); + await tester.tap(find.text('2016')); + await tester.pumpAndSettle(); + // Month should be clamped to June as the range starts at June 2016 + expect(find.text('June 2016'), findsOneWidget); + }); + }); + + testWidgets('Selecting lastDate year respects lastDate', (WidgetTester tester) async { + initialDate = DateTime(2018, DateTime.may, 4); + firstDate = DateTime(2016, DateTime.june, 9); + lastDate = DateTime(2019, DateTime.january, 15); + await prepareDatePicker(tester, (Future date) async { + await tester.tap(find.text('May 2018')); + await tester.pumpAndSettle(); + await tester.tap(find.text('2019')); + await tester.pumpAndSettle(); + // Month should be clamped to January as the range ends at January 2019 + expect(find.text('January 2019'), findsOneWidget); + }); + }); + + testWidgets('Only predicate days are selectable', (WidgetTester tester) async { + initialDate = DateTime(2017, DateTime.january, 16); + firstDate = DateTime(2017, DateTime.january, 10); + lastDate = DateTime(2017, DateTime.january, 20); + selectableDayPredicate = (DateTime day) => day.day.isEven; + await prepareDatePicker(tester, (Future date) async { + await tester.tap(find.text('13')); // Odd, doesn't work. + await tester.tap(find.text('10')); // Even, works. + await tester.tap(find.text('17')); // Odd, doesn't work. + await tester.tap(find.text('OK')); + expect(await date, DateTime(2017, DateTime.january, 10)); + }); + }); + + testWidgets('Can select initial date picker mode', (WidgetTester tester) async { + initialDate = DateTime(2014, DateTime.january, 15); + initialCalendarMode = DatePickerMode.year; + await prepareDatePicker(tester, (Future date) async { + await tester.pump(); + // 2018 wouldn't be available if the year picker wasn't showing. + // The initial current year is 2014. + await tester.tap(find.text('2018')); + await tester.pump(); + expect(find.text('January 2018'), findsOneWidget); + }); + }); + + }); + + group('Input mode', () { + setUp(() { + firstDate = DateTime(2015, DateTime.january, 1); + lastDate = DateTime(2017, DateTime.december, 31); + initialDate = DateTime(2016, DateTime.january, 15); + initialEntryMode = DatePickerEntryMode.input; + }); + + testWidgets('Initial entry mode is used', (WidgetTester tester) async { + await prepareDatePicker(tester, (Future date) async { + expect(find.byType(TextField), findsOneWidget); + }); + }); + + testWidgets('Hint, label, and help text is used', (WidgetTester tester) async { + cancelText = 'nope'; + confirmText = 'yep'; + fieldHintText = 'hint'; + fieldLabelText = 'label'; + helpText = 'help'; + await prepareDatePicker(tester, (Future date) async { + expect(find.text(cancelText), findsOneWidget); + expect(find.text(confirmText), findsOneWidget); + expect(find.text(fieldHintText), findsOneWidget); + expect(find.text(fieldLabelText), findsOneWidget); + expect(find.text(helpText), findsOneWidget); + }); + }); + + testWidgets('Initial date is the default', (WidgetTester tester) async { + await prepareDatePicker(tester, (Future date) async { + await tester.tap(find.text('OK')); + expect(await date, DateTime(2016, DateTime.january, 15)); + }); + }); + + testWidgets('Can toggle to calendar entry mode', (WidgetTester tester) async { + await prepareDatePicker(tester, (Future date) async { + expect(find.byType(TextField), findsOneWidget); + await tester.tap(find.byIcon(Icons.calendar_today)); + await tester.pumpAndSettle(); + expect(find.byType(TextField), findsNothing); + }); + }); + + testWidgets('Toggle to calendar mode keeps selected date', (WidgetTester tester) async { + await prepareDatePicker(tester, (Future date) async { + final TextField field = textField(tester); + field.controller.clear(); + + await tester.enterText(find.byType(TextField), '12/25/2016'); + await tester.tap(find.byIcon(Icons.calendar_today)); + await tester.pumpAndSettle(); + await tester.tap(find.text('OK')); + expect(await date, DateTime(2016, DateTime.december, 25)); + }); + }); + + testWidgets('Entered text returns date', (WidgetTester tester) async { + await prepareDatePicker(tester, (Future date) async { + final TextField field = textField(tester); + field.controller.clear(); + + await tester.enterText(find.byType(TextField), '12/25/2016'); + await tester.tap(find.text('OK')); + expect(await date, DateTime(2016, DateTime.december, 25)); + }); + }); + + testWidgets('Too short entered text shows error', (WidgetTester tester) async { + errorFormatText = 'oops'; + await prepareDatePicker(tester, (Future date) async { + final TextField field = textField(tester); + field.controller.clear(); + + await tester.pumpAndSettle(); + await tester.enterText(find.byType(TextField), '1225'); + expect(find.text(errorFormatText), findsNothing); + + await tester.tap(find.text('OK')); + await tester.pumpAndSettle(); + expect(find.text(errorFormatText), findsOneWidget); + }); + }); + + testWidgets('Bad format entered text shows error', (WidgetTester tester) async { + errorFormatText = 'oops'; + await prepareDatePicker(tester, (Future date) async { + final TextField field = textField(tester); + field.controller.clear(); + + await tester.pumpAndSettle(); + await tester.enterText(find.byType(TextField), '20202014'); + expect(find.text(errorFormatText), findsNothing); + + await tester.tap(find.text('OK')); + await tester.pumpAndSettle(); + expect(find.text(errorFormatText), findsOneWidget); + }); + }); + + testWidgets('Invalid entered text shows error', (WidgetTester tester) async { + errorInvalidText = 'oops'; + await prepareDatePicker(tester, (Future date) async { + final TextField field = textField(tester); + field.controller.clear(); + + await tester.pumpAndSettle(); + await tester.enterText(find.byType(TextField), '08/10/1969'); + expect(find.text(errorInvalidText), findsNothing); + + await tester.tap(find.text('OK')); + await tester.pumpAndSettle(); + expect(find.text(errorInvalidText), findsOneWidget); + }); }); }); - testWidgets('Selecting lastDate year respects lastDate', (WidgetTester tester) async { - // Regression test for https://github.com/flutter/flutter/issues/17309 - initialDate = DateTime(2018, DateTime.may, 4); - firstDate = DateTime(2016, DateTime.june, 9); - lastDate = DateTime(2019, DateTime.january, 15); - await preparePicker(tester, (Future date) async { - await tester.tap(find.text('2018')); - await tester.pumpAndSettle(); - await tester.tap(find.text('2019')); - await tester.pumpAndSettle(); - await tester.tap(find.text('OK')); - await tester.pumpAndSettle(); - expect(await date, DateTime(2019, DateTime.january, 15)); - }); - }); - - - testWidgets('Only predicate days are selectable', (WidgetTester tester) async { - initialDate = DateTime(2017, DateTime.january, 16); - firstDate = DateTime(2017, DateTime.january, 10); - lastDate = DateTime(2017, DateTime.january, 20); - selectableDayPredicate = (DateTime day) => day.day.isEven; - await preparePicker(tester, (Future date) async { - await tester.tap(find.text('10')); // Even, works. - await tester.tap(find.text('13')); // Odd, doesn't work. - await tester.tap(find.text('17')); // Odd, doesn't work. - await tester.tap(find.text('OK')); - expect(await date, equals(DateTime(2017, DateTime.january, 10))); - }); - }); - - testWidgets('Can select initial date picker mode', (WidgetTester tester) async { - initialDate = DateTime(2014, DateTime.january, 15); - initialDatePickerMode = DatePickerMode.year; - await preparePicker(tester, (Future date) async { - await tester.pump(); - // 2018 wouldn't be available if the year picker wasn't showing. - // The initial current year is 2014. - await tester.tap(find.text('2018')); - await tester.tap(find.text('OK')); - expect(await date, equals(DateTime(2018, DateTime.january, 15))); - }); - }); - - group('haptic feedback', () { - const Duration kHapticFeedbackInterval = Duration(milliseconds: 10); + group('Haptic feedback', () { + const Duration hapticFeedbackInterval = Duration(milliseconds: 10); FeedbackTester feedback; setUp(() { @@ -351,6 +537,7 @@ void _tests() { initialDate = DateTime(2017, DateTime.january, 16); firstDate = DateTime(2017, DateTime.january, 10); lastDate = DateTime(2018, DateTime.january, 20); + initialCalendarMode = DatePickerMode.day; selectableDayPredicate = (DateTime date) => date.day.isEven; }); @@ -358,464 +545,358 @@ void _tests() { feedback?.dispose(); }); - testWidgets('tap-select date vibrates', (WidgetTester tester) async { - await preparePicker(tester, (Future date) async { + testWidgets('Selecting date vibrates', (WidgetTester tester) async { + await prepareDatePicker(tester, (Future date) async { await tester.tap(find.text('10')); - await tester.pump(kHapticFeedbackInterval); + await tester.pump(hapticFeedbackInterval); expect(feedback.hapticCount, 1); await tester.tap(find.text('12')); - await tester.pump(kHapticFeedbackInterval); + await tester.pump(hapticFeedbackInterval); expect(feedback.hapticCount, 2); await tester.tap(find.text('14')); - await tester.pump(kHapticFeedbackInterval); + await tester.pump(hapticFeedbackInterval); expect(feedback.hapticCount, 3); }); }); - testWidgets('tap-select unselectable date does not vibrate', (WidgetTester tester) async { - await preparePicker(tester, (Future date) async { + testWidgets('Tapping unselectable date does not vibrate', (WidgetTester tester) async { + await prepareDatePicker(tester, (Future date) async { await tester.tap(find.text('11')); - await tester.pump(kHapticFeedbackInterval); + await tester.pump(hapticFeedbackInterval); expect(feedback.hapticCount, 0); await tester.tap(find.text('13')); - await tester.pump(kHapticFeedbackInterval); + await tester.pump(hapticFeedbackInterval); expect(feedback.hapticCount, 0); await tester.tap(find.text('15')); - await tester.pump(kHapticFeedbackInterval); + await tester.pump(hapticFeedbackInterval); expect(feedback.hapticCount, 0); }); }); - testWidgets('mode, year change vibrates', (WidgetTester tester) async { - await preparePicker(tester, (Future date) async { - await tester.tap(find.text('2017')); - await tester.pump(kHapticFeedbackInterval); + testWidgets('Changing modes and year vibrates', (WidgetTester tester) async { + await prepareDatePicker(tester, (Future date) async { + await tester.tap(find.text('January 2017')); + await tester.pump(hapticFeedbackInterval); expect(feedback.hapticCount, 1); await tester.tap(find.text('2018')); - await tester.pump(kHapticFeedbackInterval); + await tester.pump(hapticFeedbackInterval); expect(feedback.hapticCount, 2); }); }); - }); - test('days in month', () { - expect(DayPicker.getDaysInMonth(2017, 10), 31); - expect(DayPicker.getDaysInMonth(2017, 6), 30); - expect(DayPicker.getDaysInMonth(2017, 2), 28); - expect(DayPicker.getDaysInMonth(2016, 2), 29); - expect(DayPicker.getDaysInMonth(2000, 2), 29); - expect(DayPicker.getDaysInMonth(1900, 2), 28); - }); + group('Semantics', () { + testWidgets('calendar day mode', (WidgetTester tester) async { + final SemanticsHandle semantics = tester.ensureSemantics(); - testWidgets('month header tap', (WidgetTester tester) async { - selectableDayPredicate = null; - await preparePicker(tester, (Future date) async { - // Switch into the year selector. - await tester.tap(find.text('January 2016')); - await tester.pump(); - expect(find.text('2020'), isNotNull); + await prepareDatePicker(tester, (Future date) async { + // Header + expect( + tester.getSemantics(find.text('SELECT DATE')), matchesSemantics( + label: 'SELECT DATE\nFri, Jan 15', + )); - await tester.tap(find.text('CANCEL')); - expect(await date, isNull); - }); - }); + // Input mode toggle button + expect(tester.getSemantics(switchToInputIcon), matchesSemantics( + label: 'Switch to input', + isButton: true, + hasTapAction: true, + isEnabled: true, + hasEnabledState: true, + isFocusable: true, + )); - testWidgets('exports semantics', (WidgetTester tester) async { - final SemanticsTester semantics = SemanticsTester(tester); - await preparePicker(tester, (Future date) async { - final TestSemantics expected = TestSemantics( - flags: [SemanticsFlag.scopesRoute], - children: [ - TestSemantics( - elevation: 24.0, - thickness: 0.0, - children: [ - TestSemantics( - flags: [SemanticsFlag.isFocusable], - actions: [SemanticsAction.tap], - label: '2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - flags: [ - SemanticsFlag.isSelected, - SemanticsFlag.isFocusable, - ], - actions: [SemanticsAction.tap], - label: 'Fri, Jan 15', - textDirection: TextDirection.ltr, - ), - TestSemantics( - children: [ - TestSemantics( - id: 55, - actions: [SemanticsAction.scrollLeft, SemanticsAction.scrollRight], - children: [ - TestSemantics( - children: [ - TestSemantics( - children: [ - TestSemantics( - id: 11, - flags: [SemanticsFlag.hasImplicitScrolling], - children: [ - // TODO(dnfield): These shouldn't be here. https://github.com/flutter/flutter/issues/34431 - TestSemantics(), - TestSemantics(), - TestSemantics(), - TestSemantics(), - TestSemantics(), - TestSemantics(), - TestSemantics(), - TestSemantics(), - TestSemantics(), - TestSemantics(), - TestSemantics(), - TestSemantics(), - TestSemantics( - actions: [SemanticsAction.tap], - label: '1, Friday, January 1, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '2, Saturday, January 2, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '3, Sunday, January 3, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '4, Monday, January 4, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '5, Tuesday, January 5, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '6, Wednesday, January 6, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '7, Thursday, January 7, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '8, Friday, January 8, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '9, Saturday, January 9, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '10, Sunday, January 10, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '11, Monday, January 11, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '12, Tuesday, January 12, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '13, Wednesday, January 13, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '14, Thursday, January 14, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - flags: [SemanticsFlag.isSelected], - actions: [SemanticsAction.tap], - label: '15, Friday, January 15, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '16, Saturday, January 16, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '17, Sunday, January 17, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '18, Monday, January 18, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '19, Tuesday, January 19, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '20, Wednesday, January 20, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '21, Thursday, January 21, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '22, Friday, January 22, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '23, Saturday, January 23, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '24, Sunday, January 24, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '25, Monday, January 25, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '26, Tuesday, January 26, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '27, Wednesday, January 27, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '28, Thursday, January 28, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '29, Friday, January 29, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '30, Saturday, January 30, 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - actions: [SemanticsAction.tap], - label: '31, Sunday, January 31, 2016', - textDirection: TextDirection.ltr, - ), - ], - ), - ], - ), - ], - ), - ], - ), - ], - ), - TestSemantics( - flags: [ - SemanticsFlag.hasEnabledState, - SemanticsFlag.isButton, - SemanticsFlag.isEnabled, - SemanticsFlag.isFocusable, - ], - actions: [SemanticsAction.tap], - label: 'Previous month December 2015', - textDirection: TextDirection.ltr, - ), - TestSemantics( - flags: [ - SemanticsFlag.hasEnabledState, - SemanticsFlag.isButton, - SemanticsFlag.isEnabled, - SemanticsFlag.isFocusable, - ], - actions: [SemanticsAction.tap], - label: 'Next month February 2016', - textDirection: TextDirection.ltr, - ), - TestSemantics( - flags: [ - SemanticsFlag.hasEnabledState, - SemanticsFlag.isButton, - SemanticsFlag.isEnabled, - SemanticsFlag.isFocusable, - ], - actions: [SemanticsAction.tap], - label: 'CANCEL', - textDirection: TextDirection.ltr, - ), - TestSemantics( - flags: [ - SemanticsFlag.hasEnabledState, - SemanticsFlag.isButton, - SemanticsFlag.isEnabled, - SemanticsFlag.isFocusable, - ], - actions: [SemanticsAction.tap], - label: 'OK', - textDirection: TextDirection.ltr, - ), - ], - ), - ], - ); + // Year mode drop down button + expect( + tester.getSemantics(find.text('January 2016')), matchesSemantics( + label: 'Select year', + isButton: true, + )); - expect(semantics, hasSemantics( - TestSemantics.root(children: [ - TestSemantics( - children: [expected], - ), - ]), - ignoreId: true, - ignoreTransform: true, - ignoreRect: true, - )); + // Prev/Next month buttons + expect(tester.getSemantics(previousMonthIcon), matchesSemantics( + label: 'Previous month December 2015', + isButton: true, + hasTapAction: true, + isEnabled: true, + hasEnabledState: true, + isFocusable: true, + )); + expect(tester.getSemantics(nextMonthIcon), matchesSemantics( + label: 'Next month February 2016', + isButton: true, + hasTapAction: true, + isEnabled: true, + hasEnabledState: true, + isFocusable: true, + )); + + // Day grid + expect(tester.getSemantics(find.text('1')), matchesSemantics( + label: '1, Friday, January 1, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('2')), matchesSemantics( + label: '2, Saturday, January 2, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('3')), matchesSemantics( + label: '3, Sunday, January 3, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('4')), matchesSemantics( + label: '4, Monday, January 4, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('5')), matchesSemantics( + label: '5, Tuesday, January 5, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('6')), matchesSemantics( + label: '6, Wednesday, January 6, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('7')), matchesSemantics( + label: '7, Thursday, January 7, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('8')), matchesSemantics( + label: '8, Friday, January 8, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('9')), matchesSemantics( + label: '9, Saturday, January 9, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('10')), matchesSemantics( + label: '10, Sunday, January 10, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('11')), matchesSemantics( + label: '11, Monday, January 11, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('12')), matchesSemantics( + label: '12, Tuesday, January 12, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('13')), matchesSemantics( + label: '13, Wednesday, January 13, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('14')), matchesSemantics( + label: '14, Thursday, January 14, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('15')), matchesSemantics( + label: '15, Friday, January 15, 2016', + hasTapAction: true, + isSelected: true, + )); + expect(tester.getSemantics(find.text('16')), matchesSemantics( + label: '16, Saturday, January 16, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('17')), matchesSemantics( + label: '17, Sunday, January 17, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('18')), matchesSemantics( + label: '18, Monday, January 18, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('19')), matchesSemantics( + label: '19, Tuesday, January 19, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('20')), matchesSemantics( + label: '20, Wednesday, January 20, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('21')), matchesSemantics( + label: '21, Thursday, January 21, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('22')), matchesSemantics( + label: '22, Friday, January 22, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('23')), matchesSemantics( + label: '23, Saturday, January 23, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('24')), matchesSemantics( + label: '24, Sunday, January 24, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('25')), matchesSemantics( + label: '25, Monday, January 25, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('26')), matchesSemantics( + label: '26, Tuesday, January 26, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('27')), matchesSemantics( + label: '27, Wednesday, January 27, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('28')), matchesSemantics( + label: '28, Thursday, January 28, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('29')), matchesSemantics( + label: '29, Friday, January 29, 2016', + hasTapAction: true, + )); + expect(tester.getSemantics(find.text('30')), matchesSemantics( + label: '30, Saturday, January 30, 2016', + hasTapAction: true, + )); + + // Ok/Cancel buttons + expect(tester.getSemantics(find.text('OK')), matchesSemantics( + label: 'OK', + isButton: true, + hasTapAction: true, + isEnabled: true, + hasEnabledState: true, + isFocusable: true, + )); + expect(tester.getSemantics(find.text('CANCEL')), matchesSemantics( + label: 'CANCEL', + isButton: true, + hasTapAction: true, + isEnabled: true, + hasEnabledState: true, + isFocusable: true, + )); + + }); + + semantics.dispose(); + }); + + testWidgets('calendar year mode', (WidgetTester tester) async { + final SemanticsHandle semantics = tester.ensureSemantics(); + + initialCalendarMode = DatePickerMode.year; + await prepareDatePicker(tester, (Future date) async { + // Header + expect(tester.getSemantics(find.text('SELECT DATE')), matchesSemantics( + label: 'SELECT DATE\nFri, Jan 15', + )); + + // Input mode toggle button + expect(tester.getSemantics(switchToInputIcon), matchesSemantics( + label: 'Switch to input', + isButton: true, + hasTapAction: true, + isEnabled: true, + hasEnabledState: true, + isFocusable: true, + )); + + // Year mode drop down button + expect(tester.getSemantics(find.text('January 2016')), matchesSemantics( + label: 'Select year', + isButton: true, + )); + + // Year grid only shows 2010 - 2024 + for (int year = 2010; year <= 2024; year++) { + expect(tester.getSemantics(find.text('$year')), matchesSemantics( + label: '$year', + hasTapAction: true, + isSelected: year == 2016, + isFocusable: true, + )); + } + + // Ok/Cancel buttons + expect(tester.getSemantics(find.text('OK')), matchesSemantics( + label: 'OK', + isButton: true, + hasTapAction: true, + isEnabled: true, + hasEnabledState: true, + isFocusable: true, + )); + expect(tester.getSemantics(find.text('CANCEL')), matchesSemantics( + label: 'CANCEL', + isButton: true, + hasTapAction: true, + isEnabled: true, + hasEnabledState: true, + isFocusable: true, + )); + + }); + + semantics.dispose(); + }); + + testWidgets('input mode', (WidgetTester tester) async { + final SemanticsHandle semantics = tester.ensureSemantics(); + + initialEntryMode = DatePickerEntryMode.input; + await prepareDatePicker(tester, (Future date) async { + // Header + expect(tester.getSemantics(find.text('SELECT DATE')), matchesSemantics( + label: 'SELECT DATE\nFri, Jan 15', + )); + + // Input mode toggle button + expect(tester.getSemantics(switchToCalendarIcon), matchesSemantics( + label: 'Switch to calendar', + isButton: true, + hasTapAction: true, + isEnabled: true, + hasEnabledState: true, + isFocusable: true, + )); + + // Text field + expect(tester.getSemantics(find.byType(EditableText)), matchesSemantics( + label: 'Enter Date\nmm/dd/yyyy', + isTextField: true, + isFocused: true, + value: '01/15/2016', + hasTapAction: true, + hasSetSelectionAction: true, + hasCopyAction: true, + hasCutAction: true, + hasPasteAction: true, + hasMoveCursorBackwardByCharacterAction: true, + hasMoveCursorBackwardByWordAction: true, + )); + + // Ok/Cancel buttons + expect(tester.getSemantics(find.text('OK')), matchesSemantics( + label: 'OK', + isButton: true, + hasTapAction: true, + isEnabled: true, + hasEnabledState: true, + isFocusable: true, + )); + expect(tester.getSemantics(find.text('CANCEL')), matchesSemantics( + label: 'CANCEL', + isButton: true, + hasTapAction: true, + isEnabled: true, + hasEnabledState: true, + isFocusable: true, + )); + + }); + + semantics.dispose(); }); - semantics.dispose(); }); - testWidgets('chervons animate when scrolling month picker', (WidgetTester tester) async { - final Key _datePickerKey = UniqueKey(); - DateTime _selectedDate = DateTime(2016, DateTime.july, 26); - - await tester.pumpWidget( - MaterialApp( - home: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return Container( - width: 400.0, - child: SingleChildScrollView( - child: Material( - child: MonthPicker( - firstDate: DateTime(0), - lastDate: DateTime(9999), - key: _datePickerKey, - selectedDate: _selectedDate, - onChanged: (DateTime value) { - setState(() { - _selectedDate = value; - }); - }, - ), - ), - ), - ); - }, - ), - ), - ); - - final Finder chevronFinder = find.byType(IconButton); - final List chevronRenderers = chevronFinder - .evaluate() - .map((Element element) => element.findAncestorRenderObjectOfType()) - .toList(); - - // Initial chevron animation state should be dismissed - // An AlwaysStoppedAnimation is also found and is ignored - for (final RenderAnimatedOpacity renderer in chevronRenderers) { - expect(renderer.opacity.value, equals(1.0)); - expect(renderer.opacity.status, equals(AnimationStatus.dismissed)); - } - - // Drag and hold the picker to test for the opacity change - final TestGesture gesture = await tester.startGesture(const Offset(100.0, 100.0)); - await gesture.moveBy(const Offset(50.0, 100.0)); - await tester.pumpAndSettle(); - for (final RenderAnimatedOpacity renderer in chevronRenderers) { - expect(renderer.opacity.value, equals(0.0)); - expect(renderer.opacity.status, equals(AnimationStatus.completed)); - } - - // Release the drag and test for the opacity to return to original value - await gesture.up(); - await tester.pumpAndSettle(); - for (final RenderAnimatedOpacity renderer in chevronRenderers) { - expect(renderer.opacity.value, equals(1.0)); - expect(renderer.opacity.status, equals(AnimationStatus.dismissed)); - } - }); - - testWidgets('builder parameter', (WidgetTester tester) async { - Widget buildFrame(TextDirection textDirection) { - return MaterialApp( - home: Material( - child: Center( - child: Builder( - builder: (BuildContext context) { - return RaisedButton( - child: const Text('X'), - onPressed: () { - showDatePicker( - context: context, - initialDate: DateTime.now(), - firstDate: DateTime(2018), - lastDate: DateTime(2030), - builder: (BuildContext context, Widget child) { - return Directionality( - textDirection: textDirection, - child: child, - ); - }, - ); - }, - ); - }, - ), - ), - ), - ); - } - - await tester.pumpWidget(buildFrame(TextDirection.ltr)); - await tester.tap(find.text('X')); - await tester.pumpAndSettle(); - final double ltrOkRight = tester.getBottomRight(find.text('OK')).dx; - - await tester.tap(find.text('OK')); // dismiss the dialog - await tester.pumpAndSettle(); - - await tester.pumpWidget(buildFrame(TextDirection.rtl)); - await tester.tap(find.text('X')); - await tester.pumpAndSettle(); - - // Verify that the time picker is being laid out RTL. - // We expect the left edge of the 'OK' button in the RTL - // layout to match the gap between right edge of the 'OK' - // button and the right edge of the 800 wide window. - expect(tester.getBottomLeft(find.text('OK')).dx, 800 - ltrOkRight); - }); - - group('screen configurations', () { + group('Screen configurations', () { // Test various combinations of screen sizes, orientations and text scales // to ensure the layout doesn't overflow and cause an exception to be thrown. @@ -834,26 +915,11 @@ void _tests() { Future _showPicker(WidgetTester tester, Size size, [double textScaleFactor = 1.0]) async { tester.binding.window.physicalSizeTestValue = size; tester.binding.window.devicePixelRatioTestValue = 1.0; - await tester.pumpWidget( - MaterialApp( - home: Builder( - builder: (BuildContext context) { - return RaisedButton( - child: const Text('X'), - onPressed: () { - showDatePicker( - context: context, - initialDate: initialDate, - firstDate: firstDate, - lastDate: lastDate, - ); - }, - ); - }, - ), - ), - ); - await tester.tap(find.text('X')); + tester.binding.window.clearPhysicalSizeTestValue(); + tester.binding.window.clearDevicePixelRatioTestValue(); + await prepareDatePicker(tester, (Future date) async { + await tester.tap(find.text('OK')); + }); await tester.pumpAndSettle(); } @@ -897,84 +963,9 @@ void _tests() { expect(tester.takeException(), isNull); }); }); - - testWidgets('uses root navigator by default', (WidgetTester tester) async { - final DatePickerObserver rootObserver = DatePickerObserver(); - final DatePickerObserver nestedObserver = DatePickerObserver(); - - await tester.pumpWidget(MaterialApp( - navigatorObservers: [rootObserver], - home: Navigator( - observers: [nestedObserver], - onGenerateRoute: (RouteSettings settings) { - return MaterialPageRoute( - builder: (BuildContext context) { - return RaisedButton( - onPressed: () { - showDatePicker( - context: context, - initialDate: DateTime.now(), - firstDate: DateTime(2018), - lastDate: DateTime(2030), - builder: (BuildContext context, Widget child) { - return const SizedBox(); - }, - ); - }, - child: const Text('Show Date Picker'), - ); - }, - ); - }, - ), - )); - - // Open the dialog. - await tester.tap(find.byType(RaisedButton)); - - expect(rootObserver.datePickerCount, 1); - expect(nestedObserver.datePickerCount, 0); - }); - - testWidgets('uses nested navigator if useRootNavigator is false', (WidgetTester tester) async { - final DatePickerObserver rootObserver = DatePickerObserver(); - final DatePickerObserver nestedObserver = DatePickerObserver(); - - await tester.pumpWidget(MaterialApp( - navigatorObservers: [rootObserver], - home: Navigator( - observers: [nestedObserver], - onGenerateRoute: (RouteSettings settings) { - return MaterialPageRoute( - builder: (BuildContext context) { - return RaisedButton( - onPressed: () { - showDatePicker( - context: context, - useRootNavigator: false, - initialDate: DateTime.now(), - firstDate: DateTime(2018), - lastDate: DateTime(2030), - builder: (BuildContext context, Widget child) => const SizedBox(), - ); - }, - child: const Text('Show Date Picker'), - ); - }, - ); - }, - ), - )); - - // Open the dialog. - await tester.tap(find.byType(RaisedButton)); - - expect(rootObserver.datePickerCount, 0); - expect(nestedObserver.datePickerCount, 1); - }); } -class DatePickerObserver extends NavigatorObserver { +class _DatePickerObserver extends NavigatorObserver { int datePickerCount = 0; @override diff --git a/packages/flutter_localizations/lib/src/l10n/generated_material_localizations.dart b/packages/flutter_localizations/lib/src/l10n/generated_material_localizations.dart index b391b47e9d..f94fb636e8 100644 --- a/packages/flutter_localizations/lib/src/l10n/generated_material_localizations.dart +++ b/packages/flutter_localizations/lib/src/l10n/generated_material_localizations.dart @@ -29,17 +29,23 @@ class MaterialLocalizationAf extends GlobalMaterialLocalizations { const MaterialLocalizationAf({ String localeName = 'af', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -236,17 +242,23 @@ class MaterialLocalizationAm extends GlobalMaterialLocalizations { const MaterialLocalizationAm({ String localeName = 'am', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -443,17 +455,23 @@ class MaterialLocalizationAr extends GlobalMaterialLocalizations { const MaterialLocalizationAr({ String localeName = 'ar', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -650,17 +668,23 @@ class MaterialLocalizationAs extends GlobalMaterialLocalizations { const MaterialLocalizationAs({ String localeName = 'as', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -857,17 +881,23 @@ class MaterialLocalizationAz extends GlobalMaterialLocalizations { const MaterialLocalizationAz({ String localeName = 'az', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -1064,17 +1094,23 @@ class MaterialLocalizationBe extends GlobalMaterialLocalizations { const MaterialLocalizationBe({ String localeName = 'be', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -1271,17 +1307,23 @@ class MaterialLocalizationBg extends GlobalMaterialLocalizations { const MaterialLocalizationBg({ String localeName = 'bg', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -1478,17 +1520,23 @@ class MaterialLocalizationBn extends GlobalMaterialLocalizations { const MaterialLocalizationBn({ String localeName = 'bn', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -1685,17 +1733,23 @@ class MaterialLocalizationBs extends GlobalMaterialLocalizations { const MaterialLocalizationBs({ String localeName = 'bs', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -1892,17 +1946,23 @@ class MaterialLocalizationCa extends GlobalMaterialLocalizations { const MaterialLocalizationCa({ String localeName = 'ca', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -2099,17 +2159,23 @@ class MaterialLocalizationCs extends GlobalMaterialLocalizations { const MaterialLocalizationCs({ String localeName = 'cs', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -2306,17 +2372,23 @@ class MaterialLocalizationDa extends GlobalMaterialLocalizations { const MaterialLocalizationDa({ String localeName = 'da', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -2513,17 +2585,23 @@ class MaterialLocalizationDe extends GlobalMaterialLocalizations { const MaterialLocalizationDe({ String localeName = 'de', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -2720,17 +2798,23 @@ class MaterialLocalizationDeCh extends MaterialLocalizationDe { const MaterialLocalizationDeCh({ String localeName = 'de_CH', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -2750,17 +2834,23 @@ class MaterialLocalizationEl extends GlobalMaterialLocalizations { const MaterialLocalizationEl({ String localeName = 'el', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -2957,17 +3047,23 @@ class MaterialLocalizationEn extends GlobalMaterialLocalizations { const MaterialLocalizationEn({ String localeName = 'en', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -3164,17 +3260,23 @@ class MaterialLocalizationEnAu extends MaterialLocalizationEn { const MaterialLocalizationEnAu({ String localeName = 'en_AU', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -3206,17 +3308,23 @@ class MaterialLocalizationEnCa extends MaterialLocalizationEn { const MaterialLocalizationEnCa({ String localeName = 'en_CA', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -3248,17 +3356,23 @@ class MaterialLocalizationEnGb extends MaterialLocalizationEn { const MaterialLocalizationEnGb({ String localeName = 'en_GB', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -3293,17 +3407,23 @@ class MaterialLocalizationEnIe extends MaterialLocalizationEn { const MaterialLocalizationEnIe({ String localeName = 'en_IE', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -3338,17 +3458,23 @@ class MaterialLocalizationEnIn extends MaterialLocalizationEn { const MaterialLocalizationEnIn({ String localeName = 'en_IN', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -3380,17 +3506,23 @@ class MaterialLocalizationEnNz extends MaterialLocalizationEn { const MaterialLocalizationEnNz({ String localeName = 'en_NZ', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -3422,17 +3554,23 @@ class MaterialLocalizationEnSg extends MaterialLocalizationEn { const MaterialLocalizationEnSg({ String localeName = 'en_SG', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -3464,17 +3602,23 @@ class MaterialLocalizationEnZa extends MaterialLocalizationEn { const MaterialLocalizationEnZa({ String localeName = 'en_ZA', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -3509,17 +3653,23 @@ class MaterialLocalizationEs extends GlobalMaterialLocalizations { const MaterialLocalizationEs({ String localeName = 'es', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -3716,17 +3866,23 @@ class MaterialLocalizationEs419 extends MaterialLocalizationEs { const MaterialLocalizationEs419({ String localeName = 'es_419', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -3797,17 +3953,23 @@ class MaterialLocalizationEsAr extends MaterialLocalizationEs { const MaterialLocalizationEsAr({ String localeName = 'es_AR', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -3878,17 +4040,23 @@ class MaterialLocalizationEsBo extends MaterialLocalizationEs { const MaterialLocalizationEsBo({ String localeName = 'es_BO', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -3959,17 +4127,23 @@ class MaterialLocalizationEsCl extends MaterialLocalizationEs { const MaterialLocalizationEsCl({ String localeName = 'es_CL', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -4040,17 +4214,23 @@ class MaterialLocalizationEsCo extends MaterialLocalizationEs { const MaterialLocalizationEsCo({ String localeName = 'es_CO', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -4121,17 +4301,23 @@ class MaterialLocalizationEsCr extends MaterialLocalizationEs { const MaterialLocalizationEsCr({ String localeName = 'es_CR', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -4202,17 +4388,23 @@ class MaterialLocalizationEsDo extends MaterialLocalizationEs { const MaterialLocalizationEsDo({ String localeName = 'es_DO', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -4283,17 +4475,23 @@ class MaterialLocalizationEsEc extends MaterialLocalizationEs { const MaterialLocalizationEsEc({ String localeName = 'es_EC', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -4364,17 +4562,23 @@ class MaterialLocalizationEsGt extends MaterialLocalizationEs { const MaterialLocalizationEsGt({ String localeName = 'es_GT', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -4445,17 +4649,23 @@ class MaterialLocalizationEsHn extends MaterialLocalizationEs { const MaterialLocalizationEsHn({ String localeName = 'es_HN', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -4526,17 +4736,23 @@ class MaterialLocalizationEsMx extends MaterialLocalizationEs { const MaterialLocalizationEsMx({ String localeName = 'es_MX', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -4607,17 +4823,23 @@ class MaterialLocalizationEsNi extends MaterialLocalizationEs { const MaterialLocalizationEsNi({ String localeName = 'es_NI', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -4688,17 +4910,23 @@ class MaterialLocalizationEsPa extends MaterialLocalizationEs { const MaterialLocalizationEsPa({ String localeName = 'es_PA', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -4769,17 +4997,23 @@ class MaterialLocalizationEsPe extends MaterialLocalizationEs { const MaterialLocalizationEsPe({ String localeName = 'es_PE', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -4850,17 +5084,23 @@ class MaterialLocalizationEsPr extends MaterialLocalizationEs { const MaterialLocalizationEsPr({ String localeName = 'es_PR', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -4931,17 +5171,23 @@ class MaterialLocalizationEsPy extends MaterialLocalizationEs { const MaterialLocalizationEsPy({ String localeName = 'es_PY', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -5012,17 +5258,23 @@ class MaterialLocalizationEsSv extends MaterialLocalizationEs { const MaterialLocalizationEsSv({ String localeName = 'es_SV', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -5093,17 +5345,23 @@ class MaterialLocalizationEsUs extends MaterialLocalizationEs { const MaterialLocalizationEsUs({ String localeName = 'es_US', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -5177,17 +5435,23 @@ class MaterialLocalizationEsUy extends MaterialLocalizationEs { const MaterialLocalizationEsUy({ String localeName = 'es_UY', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -5258,17 +5522,23 @@ class MaterialLocalizationEsVe extends MaterialLocalizationEs { const MaterialLocalizationEsVe({ String localeName = 'es_VE', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -5339,17 +5609,23 @@ class MaterialLocalizationEt extends GlobalMaterialLocalizations { const MaterialLocalizationEt({ String localeName = 'et', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -5546,17 +5822,23 @@ class MaterialLocalizationEu extends GlobalMaterialLocalizations { const MaterialLocalizationEu({ String localeName = 'eu', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -5753,17 +6035,23 @@ class MaterialLocalizationFa extends GlobalMaterialLocalizations { const MaterialLocalizationFa({ String localeName = 'fa', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -5960,17 +6248,23 @@ class MaterialLocalizationFi extends GlobalMaterialLocalizations { const MaterialLocalizationFi({ String localeName = 'fi', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -6167,17 +6461,23 @@ class MaterialLocalizationFil extends GlobalMaterialLocalizations { const MaterialLocalizationFil({ String localeName = 'fil', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -6374,17 +6674,23 @@ class MaterialLocalizationFr extends GlobalMaterialLocalizations { const MaterialLocalizationFr({ String localeName = 'fr', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -6581,17 +6887,23 @@ class MaterialLocalizationFrCa extends MaterialLocalizationFr { const MaterialLocalizationFrCa({ String localeName = 'fr_CA', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -6635,17 +6947,23 @@ class MaterialLocalizationGl extends GlobalMaterialLocalizations { const MaterialLocalizationGl({ String localeName = 'gl', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -6842,17 +7160,23 @@ class MaterialLocalizationGsw extends GlobalMaterialLocalizations { const MaterialLocalizationGsw({ String localeName = 'gsw', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -7049,17 +7373,23 @@ class MaterialLocalizationGu extends GlobalMaterialLocalizations { const MaterialLocalizationGu({ String localeName = 'gu', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -7256,17 +7586,23 @@ class MaterialLocalizationHe extends GlobalMaterialLocalizations { const MaterialLocalizationHe({ String localeName = 'he', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -7463,17 +7799,23 @@ class MaterialLocalizationHi extends GlobalMaterialLocalizations { const MaterialLocalizationHi({ String localeName = 'hi', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -7670,17 +8012,23 @@ class MaterialLocalizationHr extends GlobalMaterialLocalizations { const MaterialLocalizationHr({ String localeName = 'hr', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -7877,17 +8225,23 @@ class MaterialLocalizationHu extends GlobalMaterialLocalizations { const MaterialLocalizationHu({ String localeName = 'hu', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -8084,17 +8438,23 @@ class MaterialLocalizationHy extends GlobalMaterialLocalizations { const MaterialLocalizationHy({ String localeName = 'hy', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -8291,17 +8651,23 @@ class MaterialLocalizationId extends GlobalMaterialLocalizations { const MaterialLocalizationId({ String localeName = 'id', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -8498,17 +8864,23 @@ class MaterialLocalizationIs extends GlobalMaterialLocalizations { const MaterialLocalizationIs({ String localeName = 'is', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -8705,17 +9077,23 @@ class MaterialLocalizationIt extends GlobalMaterialLocalizations { const MaterialLocalizationIt({ String localeName = 'it', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -8912,17 +9290,23 @@ class MaterialLocalizationJa extends GlobalMaterialLocalizations { const MaterialLocalizationJa({ String localeName = 'ja', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -9119,17 +9503,23 @@ class MaterialLocalizationKa extends GlobalMaterialLocalizations { const MaterialLocalizationKa({ String localeName = 'ka', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -9326,17 +9716,23 @@ class MaterialLocalizationKk extends GlobalMaterialLocalizations { const MaterialLocalizationKk({ String localeName = 'kk', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -9533,17 +9929,23 @@ class MaterialLocalizationKm extends GlobalMaterialLocalizations { const MaterialLocalizationKm({ String localeName = 'km', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -9740,17 +10142,23 @@ class MaterialLocalizationKn extends GlobalMaterialLocalizations { const MaterialLocalizationKn({ String localeName = 'kn', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -9947,17 +10355,23 @@ class MaterialLocalizationKo extends GlobalMaterialLocalizations { const MaterialLocalizationKo({ String localeName = 'ko', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -10154,17 +10568,23 @@ class MaterialLocalizationKy extends GlobalMaterialLocalizations { const MaterialLocalizationKy({ String localeName = 'ky', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -10361,17 +10781,23 @@ class MaterialLocalizationLo extends GlobalMaterialLocalizations { const MaterialLocalizationLo({ String localeName = 'lo', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -10568,17 +10994,23 @@ class MaterialLocalizationLt extends GlobalMaterialLocalizations { const MaterialLocalizationLt({ String localeName = 'lt', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -10775,17 +11207,23 @@ class MaterialLocalizationLv extends GlobalMaterialLocalizations { const MaterialLocalizationLv({ String localeName = 'lv', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -10982,17 +11420,23 @@ class MaterialLocalizationMk extends GlobalMaterialLocalizations { const MaterialLocalizationMk({ String localeName = 'mk', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -11189,17 +11633,23 @@ class MaterialLocalizationMl extends GlobalMaterialLocalizations { const MaterialLocalizationMl({ String localeName = 'ml', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -11396,17 +11846,23 @@ class MaterialLocalizationMn extends GlobalMaterialLocalizations { const MaterialLocalizationMn({ String localeName = 'mn', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -11603,17 +12059,23 @@ class MaterialLocalizationMr extends GlobalMaterialLocalizations { const MaterialLocalizationMr({ String localeName = 'mr', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -11810,17 +12272,23 @@ class MaterialLocalizationMs extends GlobalMaterialLocalizations { const MaterialLocalizationMs({ String localeName = 'ms', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -12017,17 +12485,23 @@ class MaterialLocalizationMy extends GlobalMaterialLocalizations { const MaterialLocalizationMy({ String localeName = 'my', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -12224,17 +12698,23 @@ class MaterialLocalizationNb extends GlobalMaterialLocalizations { const MaterialLocalizationNb({ String localeName = 'nb', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -12431,17 +12911,23 @@ class MaterialLocalizationNe extends GlobalMaterialLocalizations { const MaterialLocalizationNe({ String localeName = 'ne', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -12638,17 +13124,23 @@ class MaterialLocalizationNl extends GlobalMaterialLocalizations { const MaterialLocalizationNl({ String localeName = 'nl', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -12845,17 +13337,23 @@ class MaterialLocalizationOr extends GlobalMaterialLocalizations { const MaterialLocalizationOr({ String localeName = 'or', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -13052,17 +13550,23 @@ class MaterialLocalizationPa extends GlobalMaterialLocalizations { const MaterialLocalizationPa({ String localeName = 'pa', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -13259,17 +13763,23 @@ class MaterialLocalizationPl extends GlobalMaterialLocalizations { const MaterialLocalizationPl({ String localeName = 'pl', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -13466,17 +13976,23 @@ class MaterialLocalizationPs extends GlobalMaterialLocalizations { const MaterialLocalizationPs({ String localeName = 'ps', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -13673,17 +14189,23 @@ class MaterialLocalizationPt extends GlobalMaterialLocalizations { const MaterialLocalizationPt({ String localeName = 'pt', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -13880,17 +14402,23 @@ class MaterialLocalizationPtPt extends MaterialLocalizationPt { const MaterialLocalizationPtPt({ String localeName = 'pt_PT', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -13958,17 +14486,23 @@ class MaterialLocalizationRo extends GlobalMaterialLocalizations { const MaterialLocalizationRo({ String localeName = 'ro', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -14165,17 +14699,23 @@ class MaterialLocalizationRu extends GlobalMaterialLocalizations { const MaterialLocalizationRu({ String localeName = 'ru', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -14372,17 +14912,23 @@ class MaterialLocalizationSi extends GlobalMaterialLocalizations { const MaterialLocalizationSi({ String localeName = 'si', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -14579,17 +15125,23 @@ class MaterialLocalizationSk extends GlobalMaterialLocalizations { const MaterialLocalizationSk({ String localeName = 'sk', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -14786,17 +15338,23 @@ class MaterialLocalizationSl extends GlobalMaterialLocalizations { const MaterialLocalizationSl({ String localeName = 'sl', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -14993,17 +15551,23 @@ class MaterialLocalizationSq extends GlobalMaterialLocalizations { const MaterialLocalizationSq({ String localeName = 'sq', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -15200,17 +15764,23 @@ class MaterialLocalizationSr extends GlobalMaterialLocalizations { const MaterialLocalizationSr({ String localeName = 'sr', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -15407,17 +15977,23 @@ class MaterialLocalizationSrCyrl extends MaterialLocalizationSr { const MaterialLocalizationSrCyrl({ String localeName = 'sr_Cyrl', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -15431,17 +16007,23 @@ class MaterialLocalizationSrLatn extends MaterialLocalizationSr { const MaterialLocalizationSrLatn({ String localeName = 'sr_Latn', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -15611,17 +16193,23 @@ class MaterialLocalizationSv extends GlobalMaterialLocalizations { const MaterialLocalizationSv({ String localeName = 'sv', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -15818,17 +16406,23 @@ class MaterialLocalizationSw extends GlobalMaterialLocalizations { const MaterialLocalizationSw({ String localeName = 'sw', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -16025,17 +16619,23 @@ class MaterialLocalizationTa extends GlobalMaterialLocalizations { const MaterialLocalizationTa({ String localeName = 'ta', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -16232,17 +16832,23 @@ class MaterialLocalizationTe extends GlobalMaterialLocalizations { const MaterialLocalizationTe({ String localeName = 'te', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -16439,17 +17045,23 @@ class MaterialLocalizationTh extends GlobalMaterialLocalizations { const MaterialLocalizationTh({ String localeName = 'th', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -16646,17 +17258,23 @@ class MaterialLocalizationTl extends GlobalMaterialLocalizations { const MaterialLocalizationTl({ String localeName = 'tl', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -16853,17 +17471,23 @@ class MaterialLocalizationTr extends GlobalMaterialLocalizations { const MaterialLocalizationTr({ String localeName = 'tr', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -17060,17 +17684,23 @@ class MaterialLocalizationUk extends GlobalMaterialLocalizations { const MaterialLocalizationUk({ String localeName = 'uk', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -17267,17 +17897,23 @@ class MaterialLocalizationUr extends GlobalMaterialLocalizations { const MaterialLocalizationUr({ String localeName = 'ur', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -17474,17 +18110,23 @@ class MaterialLocalizationUz extends GlobalMaterialLocalizations { const MaterialLocalizationUz({ String localeName = 'uz', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -17681,17 +18323,23 @@ class MaterialLocalizationVi extends GlobalMaterialLocalizations { const MaterialLocalizationVi({ String localeName = 'vi', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -17888,17 +18536,23 @@ class MaterialLocalizationZh extends GlobalMaterialLocalizations { const MaterialLocalizationZh({ String localeName = 'zh', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -18095,17 +18749,23 @@ class MaterialLocalizationZhHans extends MaterialLocalizationZh { const MaterialLocalizationZhHans({ String localeName = 'zh_Hans', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -18119,17 +18779,23 @@ class MaterialLocalizationZhHant extends MaterialLocalizationZh { const MaterialLocalizationZhHant({ String localeName = 'zh_Hant', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -18281,17 +18947,23 @@ class MaterialLocalizationZhHantHk extends MaterialLocalizationZhHant { const MaterialLocalizationZhHantHk({ String localeName = 'zh_Hant_HK', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -18305,17 +18977,23 @@ class MaterialLocalizationZhHantTw extends MaterialLocalizationZhHant { const MaterialLocalizationZhHantTw({ String localeName = 'zh_Hant_TW', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -18368,17 +19046,23 @@ class MaterialLocalizationZu extends GlobalMaterialLocalizations { const MaterialLocalizationZu({ String localeName = 'zu', @required intl.DateFormat fullYearFormat, + @required intl.DateFormat compactDateFormat, + @required intl.DateFormat shortDateFormat, @required intl.DateFormat mediumDateFormat, @required intl.DateFormat longDateFormat, @required intl.DateFormat yearMonthFormat, + @required intl.DateFormat shortMonthDayFormat, @required intl.NumberFormat decimalFormat, @required intl.NumberFormat twoDigitZeroPaddedFormat, }) : super( localeName: localeName, fullYearFormat: fullYearFormat, + compactDateFormat: compactDateFormat, + shortDateFormat: shortDateFormat, mediumDateFormat: mediumDateFormat, longDateFormat: longDateFormat, yearMonthFormat: yearMonthFormat, + shortMonthDayFormat: shortMonthDayFormat, decimalFormat: decimalFormat, twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat, ); @@ -18752,274 +19436,277 @@ final Set kMaterialSupportedLanguages = HashSet.from(const get narrowWeekdays { return _longDateFormat.dateSymbols.NARROWWEEKDAYS; @@ -576,24 +614,36 @@ class _MaterialLocalizationsDelegate extends LocalizationsDelegate(getMaterialTranslation( locale, fullYearFormat, + compactDateFormat, + shortDateFormat, mediumDateFormat, longDateFormat, yearMonthFormat, + shortMonthDayFormat, decimalFormat, twoDigitZeroPaddedFormat, )); diff --git a/packages/flutter_localizations/test/material/date_picker_test.dart b/packages/flutter_localizations/test/material/date_picker_test.dart index 56b45a3e8a..172ea20396 100644 --- a/packages/flutter_localizations/test/material/date_picker_test.dart +++ b/packages/flutter_localizations/test/material/date_picker_test.dart @@ -19,7 +19,7 @@ void main() { initialDate = DateTime(2016, DateTime.january, 15); }); - group(DayPicker, () { + group(CalendarDatePicker, () { final intl.NumberFormat arabicNumbers = intl.NumberFormat('0', 'ar'); final Map> testLocales = >{ // Tests the default. @@ -59,13 +59,11 @@ void main() { final TextDirection textDirection = testLocales[locale]['textDirection'] as TextDirection; final DateTime baseDate = DateTime(2017, 9, 27); - await _pumpBoilerplate(tester, DayPicker( - selectedDate: baseDate, - currentDate: baseDate, - onChanged: (DateTime newValue) { }, + await _pumpBoilerplate(tester, CalendarDatePicker( + initialDate: baseDate, firstDate: baseDate.subtract(const Duration(days: 90)), lastDate: baseDate.add(const Duration(days: 90)), - displayedMonth: baseDate, + onDateChanged: (DateTime newValue) {}, ), locale: locale, textDirection: textDirection); expect(find.text(expectedMonthYearHeader), findsOneWidget); @@ -126,14 +124,14 @@ void main() { await tester.tap(find.text('X')); await tester.pumpAndSettle(const Duration(seconds: 1)); - final Element dayPicker = tester.element(find.byType(DayPicker)); + final Element picker = tester.element(find.byType(CalendarDatePicker)); expect( - Localizations.localeOf(dayPicker), + Localizations.localeOf(picker), const Locale('fr', 'CA'), ); expect( - Directionality.of(dayPicker), + Directionality.of(picker), TextDirection.ltr, ); @@ -169,9 +167,9 @@ void main() { await tester.tap(find.text('X')); await tester.pumpAndSettle(const Duration(seconds: 1)); - final Element dayPicker = tester.element(find.byType(DayPicker)); + final Element picker = tester.element(find.byType(CalendarDatePicker)); expect( - Directionality.of(dayPicker), + Directionality.of(picker), TextDirection.rtl, ); @@ -210,14 +208,14 @@ void main() { await tester.tap(find.text('X')); await tester.pumpAndSettle(const Duration(seconds: 1)); - final Element dayPicker = tester.element(find.byType(DayPicker)); + final Element picker = tester.element(find.byType(CalendarDatePicker)); expect( - Localizations.localeOf(dayPicker), + Localizations.localeOf(picker), const Locale('fr', 'CA'), ); expect( - Directionality.of(dayPicker), + Directionality.of(picker), TextDirection.rtl, ); @@ -292,12 +290,16 @@ Future _pumpBoilerplate( Locale locale = const Locale('en', 'US'), TextDirection textDirection = TextDirection.ltr, }) async { - await tester.pumpWidget(Directionality( - textDirection: TextDirection.ltr, - child: Localizations( - locale: locale, - delegates: GlobalMaterialLocalizations.delegates, - child: child, + await tester.pumpWidget(MaterialApp( + home: Directionality( + textDirection: TextDirection.ltr, + child: Localizations( + locale: locale, + delegates: GlobalMaterialLocalizations.delegates, + child: Material( + child: child, + ), + ), ), )); } diff --git a/packages/flutter_localizations/test/override_test.dart b/packages/flutter_localizations/test/override_test.dart index 4e90abab1d..6b98fbcf9a 100644 --- a/packages/flutter_localizations/test/override_test.dart +++ b/packages/flutter_localizations/test/override_test.dart @@ -15,9 +15,12 @@ class FooMaterialLocalizations extends MaterialLocalizationEn { ) : super( localeName: localeName.toString(), fullYearFormat: intl.DateFormat.y(), + compactDateFormat: intl.DateFormat.yMd(), + shortDateFormat: intl.DateFormat.yMMMd(), mediumDateFormat: intl.DateFormat('E, MMM\u00a0d'), longDateFormat: intl.DateFormat.yMMMMEEEEd(), yearMonthFormat: intl.DateFormat.yMMMM(), + shortMonthDayFormat: intl.DateFormat.MMMd(), decimalFormat: intl.NumberFormat.decimalPattern(), twoDigitZeroPaddedFormat: intl.NumberFormat('00'), );