diff --git a/CHANGELOG.md b/CHANGELOG.md index 32a5554..d56686a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,137 +1,130 @@ -# 3.0.6 +##3.0.1 -- Fixing issue #42 dense empty form field +* Fixing [issue #29](https://github.com/GaspardMerten/date_field/issues/29) -> adding 24h format support for material time picker dialog -# 3.0.5 +##3.0.0 -- Bumping intl to 0.18.0 +* Breaking Upgraded minimum Dart version to 2.15 for Constructor Tearoff support +* Added optional `DateTimeFieldCreator` argument to `DateTimeFormField` to allow specifying custom implementations of `DateTimeField` +* Refactored `DateTimeField` to expose `showMaterialTimePicker`, `showMaterialDatePicker`, and `showMaterialTimePicker` as separate overrideable methods +* Made `kCupertinoDatePickerHeight` and `cupertinoModeFromPickerMode` public for convenience +* Removed `DateTimeFormFieldState`, replaced by an instance of `FormFieldState` +* Fixed the behaviour of the `initialDate' parameter. -# 3.0.4 +##2.1.3 -- Updating Changelog.md +* [TheGlorySaint](https://github.com/TheGlorySaint) added the possibility to use the 24Hour Format at the Timepicker. Default it is set to false -# 3.0.3 +##2.1.2 -- Updating the README.md file. Adding more information about the package, rewriting the text to make it more appealing. -- Adding support for providing a different initial time mode for the material time picker dialog (thanks to @schalky). +* Adding the possibility to specify the initial date selected in the date picker dialog. -# 3.0.2 +##2.1.1 -Added support for clickable pointer on desktop and web. +* Formatting with Dart FM -# 3.0.1 +##2.1.0 -Fixed issue #29 by adding 24-hour format support for the material time picker dialog. +* Fixing label & hint style issues +* Moving to a more generic architecture +* Updating the analysis_options.yaml file -# 3.0.0 +##2.0.1 -Upgraded the minimum Dart version to 2.15 for constructor tear-off support, which is a breaking change. -Added an optional DateTimeFieldCreator argument to DateTimeFormField for specifying custom implementations of DateTimeField. -Refactored DateTimeField to expose showMaterialTimePicker, showMaterialDatePicker, and showMaterialTimePicker as separate overrideable methods. -Made kCupertinoDatePickerHeight and cupertinoModeFromPickerMode public for convenience. -Removed DateTimeFormFieldState and replaced it with an instance of FormFieldState. -Fixed the behavior of the initialDate parameter. +* Adding the ability to specify the entry mode for the material date picker. -# 2.1.3 +##2.0.0 -Added the possibility to use the 24-hour format for the time picker. Default is set to false. +* Migrating to null-safety -# 2.1.2 -Added the ability to specify the initial date selected in the date picker dialog. +##1.0.5 -# 2.1.1 +* Removing unused variables +* Improving description -Formatted code with Dart FM. -# 2.1.0 +##1.0.4 -Fixed label and hint style issues. -Moved to a more generic architecture. -Updated the analysis_options.yaml file. +* Fixing critical issue -# 2.0.1 +##1.0.3 -Added the ability to specify the entry mode for the material date picker. +* Improving package description -# 2.0.0 +##1.0.2 -Migrated to null-safety. +* Improving package description -# 1.0.5 +##1.0.1 -Removed unused variables and improved the description. +* Removing the ripple effect -# 1.0.4 +##1.0.0 -Fixed a critical issue. +* Full support for input decoration +* New standardized usage, many deprecations -# 1.0.3 +##0.3.3 -Improved the package description. +* Intl => any support -# 1.0.2 +Breaking change: +* Removing the label property, please consider using the InputDecoration to customize the label. -Improved the package description. +##0.3.2 -# 1.0.1 +* Formating with dartfm -Removed the ripple effect. +##0.3.1 -# 1.0.0 +* Adding the possibility to style the text with TextStyle -Added full support for input decoration. -Adopted a new standardized usage, with many deprecations. +## 0.3.0 -# 0.3.3 +Breaking changes: +* No more const constructor. -Changed support from Intl to any, which is a breaking change. -Removed the label property, and suggested using the InputDecoration to customize the label. +Deprecated: +* DateField and DateFormField are now deprecated and will be removed in the next version, please consider switching to + DateTimeField and DateTimeFormField. -# 0.3.2 +Improvements: +* Adding support for time. Now you can ask the user for a time, a date or both. +* Improving performances by setting default value in the constructor. +* Adding .time constructor for the DateField widget only. -Formatted the code with Dart FM. +## 0.2.2 -# 0.3.1 +* Auto-formatting with dart-fm to meet pub.dev requirements -Added the possibility to style the text with TextStyle. +## 0.2.1 -# 0.3.0 +* Adding support for Flutter web -Removed the const constructor, which is a breaking change. -Deprecated DateField and DateFormField, and added support for time. -Improved performance by setting the default value in the constructor. -Added a .time constructor for the DateField widget only. +## 0.2.0 -# 0.2.2 +* DateFormField now extends FormField. All issues related to this are now fiex +* The style of the DateField (and by extension the one of DateFormField) is now rigorously applying the theme or any customization. -Formatted the code with dart-fm to meet pub.dev requirements. +## 0.1.2 -# 0.2.1 +* Fixing an incorrect boolean (iOS picker was inverted with the Android one) -Added support for Flutter web. +## 0.1.1 -# 0.2.0 +* Formatting with DartFM! -Changed DateFormField to extend FormField, and rigorously applied the style to match the theme or any customization. +## 0.1.0 -# 0.1.2 +* Updating documentation! -Fixed an incorrect boolean value (the iOS picker was inverted with the Android one). +## 0.0.2 -# 0.1.1 +* Fixing README.md +* Updating package description +* Formatting with DartFM -Formatted the code with DartFM. - -# 0.1.0 - -Updated the documentation. - -# 0.0.2 - -Fixed the README.md and updated the package description. -Formatted the code with DartFM. - -# 0.0.1 +## 0.0.1 * Initial version diff --git a/README.md b/README.md index 8c10310..f5829db 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,51 @@ -# Welcome to the Date Field package! 📅 +# date_field -[![pub package](https://img.shields.io/pub/v/date_field.svg)](https://pub.dev/packages/date_field) +[![pub package](https://img.shields.io/pub/v/date_field.svg)](https://pub.dartlang.org/packages/date_field) -This package provides two widgets, DateTimeField and DateTimeFormField, which allow users to pick a date and/or time from an input field. You can customize the appearance of the widgets using the decoration argument, and specify whether to ask for a date, a time, or both using the mode parameter. -## Here's how to get started 🚀 +Contains DateTimeField and DateTimeFormField which allows the user to pick a DateTime from an input field! Depending on +the mode, it can ask the user the time, the date or both at the same time ;) ! -Add the date_field package to your project's dependencies in pubspec.yaml. + + +## Usage + +In the `pubspec.yaml` of your flutter project, add the following dependency: ```yaml dependencies: ... - date_field: ^3.0.5 + date_field: ^3.0.0 ``` - -Import the package in your Dart code. +In your library add the following import: ```dart import 'package:date_field/date_field.dart'; ``` -Use the DateTimeField or DateTimeFormField widget in your code, and customize it using the available parameters. -## Available Parameters 📝 +## Getting Started -- onSaved: a callback that is called when the form is saved. -- validator: a callback that is called to validate the value. -- initialValue: the initial value of the field. -- autovalidateMode: when to validate the field. -- enabled: whether the field is enabled or disabled. -- use24hFormat: whether to use a 24-hour format for the time picker. -- dateTextStyle: the text style for the date. -- dateFormat: the format of the date. -- firstDate: the earliest date that can be selected. -- lastDate: the latest date that can be selected. -- initialDate: the initial date that is selected. -- onDateSelected: a callback that is called when a date is selected. -- decoration: the decoration for the field. -- initialEntryMode: the initial entry mode of the date picker. -- initialDatePickerMode: the initial date picker mode. -- mode: the mode of the date and time picker. -- initialTimePickerEntryMode: the initial entry mode of the time picker. -- fieldCreator: the creator of the DateTimeField. +There are two widgets in this package: -## Example Usage 📖 +- DateTimeField +- DateTimeFormField -Here's an example usage of DateTimeFormField: +It follows the usual Flutter patterns convention, meaning the DateTimeFormField extends the FormField widget and wraps a DateTimeField widget. -```dart +You can customize both of these widgets with the decoration argument which is fully supported. + +You can also specify whether you would like to ask the user for a date, a time or both using the mode parameter. + +## Example + +The following picture illustrates some things you can do with this package. + + + + +``` dart DateTimeFormField( decoration: const InputDecoration( hintStyle: TextStyle(color: Colors.black45), @@ -63,19 +60,7 @@ DateTimeFormField( onDateSelected: (DateTime value) { print(value); }, -) +), ``` -You can find more examples and a complete example on the GitHub repository. We hope this package is helpful to you! - -## License 📜 - -This package is released under the MIT license. - -## Contributing 🤝 - -Contributions to this package are welcome! If you find a bug or have a feature request, please create an issue on the GitHub repository. If you'd like to contribute code, please create a pull request with your changes. - -Before submitting a pull request, please make sure to run the tests and ensure they all pass. Additionally, please follow the existing coding style and make sure your code is well-documented. - -Thank you for your contributions! \ No newline at end of file +You can check the GitHub repo for a complete example. \ No newline at end of file diff --git a/example/.gitignore b/example/.gitignore index a1345d0..0fa6b67 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -32,6 +32,7 @@ /build/ # Web related +lib/generated_plugin_registrant.dart # Symbolication related app.*.symbols diff --git a/example/lib/main.dart b/example/lib/main.dart index 7ceb620..5b54c39 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -65,7 +65,6 @@ class _MyHomePageState extends State { Form( child: Column( children: [ - DateTimeFormField(), DateTimeFormField( decoration: const InputDecoration( hintStyle: TextStyle(color: Colors.black45), diff --git a/lib/src/field.dart b/lib/src/field.dart index 28dff95..9d9fc55 100644 --- a/lib/src/field.dart +++ b/lib/src/field.dart @@ -1,6 +1,5 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:intl/intl.dart'; final DateTime _kDefaultFirstSelectableDate = DateTime(1900); @@ -25,7 +24,6 @@ typedef DateTimeFieldCreator = DateTimeField Function({ DateTime? lastDate, DateTimeFieldPickerMode mode, bool use24hFormat, - TimePickerEntryMode initialTimePickerEntryMode, }); /// [DateTimeField] @@ -49,7 +47,6 @@ class DateTimeField extends StatelessWidget { DateTime? firstDate, DateTime? lastDate, DateFormat? dateFormat, - this.initialTimePickerEntryMode = TimePickerEntryMode.dial, }) : dateFormat = dateFormat ?? getDateFormatFromDateFieldPickerMode(mode), firstDate = firstDate ?? _kDefaultFirstSelectableDate, lastDate = lastDate ?? _kDefaultLastSelectableDate, @@ -65,7 +62,6 @@ class DateTimeField extends StatelessWidget { this.dateTextStyle, this.use24hFormat = false, this.initialEntryMode = DatePickerEntryMode.calendar, - this.initialTimePickerEntryMode = TimePickerEntryMode.dial, DateTime? firstDate, DateTime? lastDate, }) : initialDatePickerMode = null, @@ -114,9 +110,6 @@ class DateTimeField extends StatelessWidget { /// The initial entry mode for the material date picker dialog final DatePickerEntryMode initialEntryMode; - // the initial entry mode for the material time picker dialog - final TimePickerEntryMode initialTimePickerEntryMode; - /// Shows a dialog asking the user to pick a date ! Future _selectDate(BuildContext context) async { final DateTime initialDateTime; @@ -133,20 +126,23 @@ class DateTimeField extends StatelessWidget { } if (Theme.of(context).platform == TargetPlatform.iOS) { - final DateTime? _selectedDateTime = await showCupertinoPicker(context, initialDateTime); + final DateTime? _selectedDateTime = + await showCupertinoPicker(context, initialDateTime); if (_selectedDateTime != null) { onDateSelected!(_selectedDateTime); } } else { DateTime _selectedDateTime = initialDateTime; - const List modesWithDate = [ + const List modesWithDate = + [ DateTimeFieldPickerMode.dateAndTime, DateTimeFieldPickerMode.date ]; if (modesWithDate.contains(mode)) { - final DateTime? _selectedDate = await showMaterialDatePicker(context, initialDateTime); + final DateTime? _selectedDate = + await showMaterialDatePicker(context, initialDateTime); if (_selectedDate != null) { _selectedDateTime = _selectedDate; @@ -155,14 +151,15 @@ class DateTimeField extends StatelessWidget { } } - final List modesWithTime = [ + final List modesWithTime = + [ DateTimeFieldPickerMode.dateAndTime, DateTimeFieldPickerMode.time ]; if (modesWithTime.contains(mode)) { - final TimeOfDay? _selectedTime = await showMaterialTimePicker(context, initialDateTime, - initialEntryMode: initialTimePickerEntryMode); + final TimeOfDay? _selectedTime = + await showMaterialTimePicker(context, initialDateTime); if (_selectedTime != null) { _selectedDateTime = DateTime( @@ -181,12 +178,13 @@ class DateTimeField extends StatelessWidget { /// Launches the Material time picker by invoking [showTimePicker]. /// Can be @[override]n to allow further customization of the picker options - Future showMaterialTimePicker(BuildContext context, DateTime initialDateTime, - {TimePickerEntryMode initialEntryMode = TimePickerEntryMode.dial}) async { + Future showMaterialTimePicker( + BuildContext context, + DateTime initialDateTime, + ) async { return showTimePicker( initialTime: TimeOfDay.fromDateTime(initialDateTime), context: context, - initialEntryMode: initialEntryMode, builder: (BuildContext context, Widget? child) { return MediaQuery( data: MediaQuery.of(context).copyWith( @@ -268,7 +266,8 @@ enum DateTimeFieldPickerMode { time, date, dateAndTime } /// Returns the [CupertinoDatePickerMode] corresponding to the selected /// [DateTimeFieldPickerMode]. This exists to prevent redundancy in the [DateTimeField] /// widget parameters. -CupertinoDatePickerMode cupertinoModeFromPickerMode(DateTimeFieldPickerMode mode) { +CupertinoDatePickerMode cupertinoModeFromPickerMode( + DateTimeFieldPickerMode mode) { switch (mode) { case DateTimeFieldPickerMode.time: return CupertinoDatePickerMode.time; @@ -297,7 +296,7 @@ DateFormat getDateFormatFromDateFieldPickerMode(DateTimeFieldPickerMode mode) { /// Shows a field with a dropdown arrow ! /// It does not show any popup menu, it'll just trigger onPressed whenever the /// user does click on it ! -class _InputDropdown extends StatefulWidget { +class _InputDropdown extends StatelessWidget { const _InputDropdown({ Key? key, required this.text, @@ -327,46 +326,21 @@ class _InputDropdown extends StatefulWidget { /// Defaults to false. final bool isEmpty; - @override - State<_InputDropdown> createState() => _InputDropdownState(); -} - -class _InputDropdownState extends State<_InputDropdown> { - bool focused = false; - @override Widget build(BuildContext context) { - final InputDecoration effectiveDecoration = widget.decoration ?? + final InputDecoration effectiveDecoration = decoration ?? const InputDecoration( suffixIcon: Icon(Icons.arrow_drop_down), ); - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - onTap: widget.onPressed, - child: Focus( - onFocusChange: (bool newFocus) => setState(() { - focused = newFocus; - }), - onKey: (_, RawKeyEvent key) { - if (key.isKeyPressed(LogicalKeyboardKey.space)) { - widget.onPressed?.call(); - return KeyEventResult.handled; - } - return KeyEventResult.ignored; - }, - child: InputDecorator( - isHovering: focused, - decoration: effectiveDecoration.applyDefaults( - Theme.of(context).inputDecorationTheme, - ), - isEmpty: widget.isEmpty, - child: widget.text == null - ? Text('', style: widget.textStyle) - : Text(widget.text!, style: widget.textStyle), - ), + return GestureDetector( + onTap: onPressed, + child: InputDecorator( + decoration: effectiveDecoration.applyDefaults( + Theme.of(context).inputDecorationTheme, ), + isEmpty: isEmpty, + child: text == null ? null : Text(text!, style: textStyle), ), ); } diff --git a/lib/src/form_field.dart b/lib/src/form_field.dart index 71168cc..d11a4ff 100644 --- a/lib/src/form_field.dart +++ b/lib/src/form_field.dart @@ -30,38 +30,27 @@ class DateTimeFormField extends FormField { DatePickerEntryMode initialEntryMode = DatePickerEntryMode.calendar, DatePickerMode initialDatePickerMode = DatePickerMode.day, DateTimeFieldPickerMode mode = DateTimeFieldPickerMode.dateAndTime, - TimePickerEntryMode initialTimePickerEntryMode = TimePickerEntryMode.dial, - DateTimeFormFieldController? controller, DateTimeFieldCreator fieldCreator = DateTimeField.new, }) : super( key: key, - initialValue: - initialValue == null && controller != null ? controller.selectedDate : initialValue, + initialValue: initialValue, onSaved: onSaved, validator: validator, autovalidateMode: autovalidateMode, enabled: enabled, builder: (FormFieldState field) { - if (controller != null) { - controller.addListener(() { - field.didChange(controller.selectedDate); - }); - } - // Theme defaults are applied inside the _InputDropdown widget final InputDecoration _decorationWithThemeDefaults = decoration ?? const InputDecoration(); final InputDecoration effectiveDecoration = - _decorationWithThemeDefaults.copyWith(errorText: field.errorText); + _decorationWithThemeDefaults.copyWith( + errorText: field.errorText); void onChangedHandler(DateTime value) { if (onDateSelected != null) { onDateSelected(value); } - if (controller != null) { - controller.selectedDate = value; - } field.didChange(value); } @@ -79,7 +68,6 @@ class DateTimeFormField extends FormField { mode: mode, initialEntryMode: initialEntryMode, dateTextStyle: dateTextStyle, - initialTimePickerEntryMode: initialTimePickerEntryMode, ); }, ); @@ -87,12 +75,3 @@ class DateTimeFormField extends FormField { @override FormFieldState createState() => FormFieldState(); } - -class DateTimeFormFieldController extends ChangeNotifier { - DateTime? _selectedDate; - DateTime? get selectedDate => _selectedDate; - set selectedDate(DateTime? value) { - _selectedDate = value; - notifyListeners(); - } -} diff --git a/pubspec.yaml b/pubspec.yaml index 540005e..1fc091a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: date_field description: A widget in the form of a field that lets people choose a date, a time or both. -version: 3.0.6 +version: 3.0.1 homepage: 'https://github.com/GaspardMerten/date_field' environment: @@ -10,5 +10,5 @@ dependencies: flutter: sdk: flutter - intl: ^0.18.0 + intl: ^0.17.0