From de7174319f1c4e34e4226251c13ecfd9b9a1919a Mon Sep 17 00:00:00 2001 From: Matias de Andrea Date: Sat, 17 Sep 2022 18:36:11 +0200 Subject: [PATCH 01/10] chore: Add issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 53 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/documentation.md | 18 ++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 18 ++++++++ .github/ISSUE_TEMPLATE/question.md | 14 ++++++ 4 files changed, 103 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/documentation.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/question.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..11d127b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,53 @@ +--- +name: "\U0001F41B Bug" +about: Something is crashing or not working as intended +labels: bug + +--- + +## Environment + +**Package version:** + +
+ Flutter doctor + + +``` +``` + +
+ +
+ Code sample + + + +```dart +``` + +
+ +## Description + +**Expected behavior:** + +**Current behavior:** + +## Steps to reproduce + +1. This +2. Than that +3. Then + +## Images + +## Stacktrace/Logcat diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md new file mode 100644 index 0000000..b243d47 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/documentation.md @@ -0,0 +1,18 @@ +--- +name: "\U0001F4C3 Documentation Bug" +about: You want to report something that is wrong or missing from the documentation. +labels: documentation + +--- + +### Describe the change you would like to see + + +### How would the suggested change make the documentation more useful? + + +### Additional context + \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..a6b3c86 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,18 @@ +--- +name: "\U0001F680 Feature request" +about: Suggest new feature or request for this project +labels: enhancement + +--- + +## Environment + +**Package version:** + +## Description + +**What you'd like to happen:** + +**Alternatives you've considered:** + +**Images:** diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md new file mode 100644 index 0000000..0e9a57f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.md @@ -0,0 +1,14 @@ +--- +name: "\U0001F914 Questions and Help" +about: You have a quetion or need help using this packages +labels: question + +--- + +## Environment + +**Package version:** + +## Describe your question + \ No newline at end of file From 1714319f94c8a67b64e509273627b83f18787ea4 Mon Sep 17 00:00:00 2001 From: Joan Pablo Date: Fri, 29 Mar 2024 10:26:31 -0400 Subject: [PATCH 02/10] Update cli with Flutter 3.16.0 --- .github/workflows/reactive_forms.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/reactive_forms.yaml b/.github/workflows/reactive_forms.yaml index a99023f..838c900 100644 --- a/.github/workflows/reactive_forms.yaml +++ b/.github/workflows/reactive_forms.yaml @@ -23,7 +23,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2 with: - flutter-version: "3.10.0" + flutter-version: "3.16.0" channel: "stable" - run: flutter pub get - run: flutter test --no-pub --coverage @@ -36,7 +36,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2 with: - flutter-version: "3.10.0" + flutter-version: "3.16.0" channel: "stable" - run: flutter pub get - name: Analyze lib @@ -51,7 +51,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2 with: - flutter-version: "3.10.0" + flutter-version: "3.16.0" channel: "stable" - run: flutter pub get - name: Format lib From 552a7acdc32d9ed514489a398b48ce99fc2567b4 Mon Sep 17 00:00:00 2001 From: Joan Pablo Date: Fri, 29 Mar 2024 12:02:24 -0400 Subject: [PATCH 03/10] Update Flutter dependencies - Update Reactive Forms version to 17.0 - Update Flutter version >=3.16.0 - Update Dart version >=3.2.4 <4.0.0 - Replace deprecated WillPopScope with PopScope - Fix the use super parameters --- example/lib/sample_screen.dart | 3 +- .../samples/add_dynamic_controls_sample.dart | 4 +- example/pubspec.yaml | 14 ++--- lib/src/models/models.dart | 51 +++++++------------ lib/src/widgets/inherited_streamer.dart | 4 +- lib/src/widgets/reactive_checkbox.dart | 12 ++--- .../widgets/reactive_checkbox_list_tile.dart | 12 ++--- lib/src/widgets/reactive_date_picker.dart | 9 ++-- lib/src/widgets/reactive_dropdown_field.dart | 18 +++---- lib/src/widgets/reactive_form.dart | 13 ++--- lib/src/widgets/reactive_form_array.dart | 5 +- lib/src/widgets/reactive_form_builder.dart | 4 +- lib/src/widgets/reactive_form_config.dart | 6 +-- lib/src/widgets/reactive_form_consumer.dart | 4 +- lib/src/widgets/reactive_form_field.dart | 5 +- lib/src/widgets/reactive_form_pop_scope.dart | 30 ----------- lib/src/widgets/reactive_radio.dart | 12 ++--- lib/src/widgets/reactive_radio_list_tile.dart | 12 ++--- lib/src/widgets/reactive_slider.dart | 12 ++--- .../reactive_status_listenable_builder.dart | 5 +- lib/src/widgets/reactive_switch.dart | 24 +++------ .../widgets/reactive_switch_list_tile.dart | 24 +++------ lib/src/widgets/reactive_text_field.dart | 21 +++----- lib/src/widgets/reactive_time_picker.dart | 9 ++-- .../reactive_value_listenable_builder.dart | 5 +- pubspec.yaml | 9 ++-- ...ive_checkbox_list_tile_testing_widget.dart | 4 +- .../reactive_checkbox_testing_widget.dart | 4 +- .../reactive_date_picker_testing_widget.dart | 4 +- .../reactive_dropdown_testing_widget.dart | 4 +- .../reactive_form_array_testing_widget.dart | 4 +- .../reactive_form_builder_testing_widget.dart | 4 +- ...reactive_form_consumer_testing_widget.dart | 4 +- ...active_radio_list_tile_testing_widget.dart | 4 +- .../reactive_radio_testing_widget.dart | 4 +- .../reactive_slider_testing_widget.dart | 4 +- ...tus_listenable_builder_testing_widget.dart | 4 +- ...ctive_switch_list_tile_testing_widget.dart | 4 +- .../reactive_switch_testing_widget.dart | 4 +- .../reactive_text_field_testing_widget.dart | 4 +- .../reactive_time_picker_testing_widget.dart | 4 +- ...lue_listenable_builder_testing_widget.dart | 4 +- 42 files changed, 140 insertions(+), 251 deletions(-) delete mode 100644 lib/src/widgets/reactive_form_pop_scope.dart diff --git a/example/lib/sample_screen.dart b/example/lib/sample_screen.dart index 8aff487..a168e88 100644 --- a/example/lib/sample_screen.dart +++ b/example/lib/sample_screen.dart @@ -5,8 +5,7 @@ class SampleScreen extends StatelessWidget { final Widget body; final Widget? title; - const SampleScreen({Key? key, required this.body, this.title}) - : super(key: key); + const SampleScreen({super.key, required this.body, this.title}); @override Widget build(BuildContext context) { diff --git a/example/lib/samples/add_dynamic_controls_sample.dart b/example/lib/samples/add_dynamic_controls_sample.dart index fc34097..48ed0ae 100644 --- a/example/lib/samples/add_dynamic_controls_sample.dart +++ b/example/lib/samples/add_dynamic_controls_sample.dart @@ -7,8 +7,8 @@ class ViewModelProvider extends InheritedWidget { ViewModelProvider({ required this.viewModel, - required Widget child, - }) : super(child: child); + required super.child, + }); static NewContactViewModel? of(BuildContext context) => context.findAncestorWidgetOfExactType()?.viewModel; diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 9dcfa6c..1718e6f 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -18,34 +18,30 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ">=2.17.0 <3.0.0" - flutter: ">=3.0.0" + sdk: ">=3.2.4 <4.0.0" + flutter: ">=3.16.0" dependencies: flutter: sdk: flutter - intl: ^0.18.0 + intl: ^0.19.0 reactive_forms: path: ../ #reactive_forms_widgets: ^0.3.1 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^1.0.5 + cupertino_icons: ^1.0.6 #reactive_dropdown_search: ^0.9.0 #reactive_touch_spin: ^0.6.0 #reactive_segmented_control: ^0.4.0 #reactive_date_time_picker: ^0.4.0 dev_dependencies: - lints: ^2.0.0 + flutter_lints: ^3.0.2 flutter_test: sdk: flutter -dependency_overrides: - reactive_forms: - path: ../ - # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/lib/src/models/models.dart b/lib/src/models/models.dart index 0040ea7..9d809f3 100644 --- a/lib/src/models/models.dart +++ b/lib/src/models/models.dart @@ -833,18 +833,12 @@ class FormControl extends AbstractControl { /// FormControl({ T? value, - List> validators = const [], - List> asyncValidators = const [], - int asyncValidatorsDebounceTime = 250, - bool touched = false, - bool disabled = false, - }) : super( - validators: validators, - asyncValidators: asyncValidators, - asyncValidatorsDebounceTime: asyncValidatorsDebounceTime, - disabled: disabled, - touched: touched, - ) { + super.validators, + super.asyncValidators, + super.asyncValidatorsDebounceTime, + super.touched, + super.disabled, + }) { if (value != null) { this.value = value; } else { @@ -1039,16 +1033,11 @@ class FormControl extends AbstractControl { /// that emits events each time you add or remove a control to the collection. abstract class FormControlCollection extends AbstractControl { FormControlCollection({ - List> validators = const [], - List> asyncValidators = const [], - int asyncValidatorsDebounceTime = 250, - bool disabled = false, - }) : super( - validators: validators, - asyncValidators: asyncValidators, - asyncValidatorsDebounceTime: asyncValidatorsDebounceTime, - disabled: disabled, - ); + super.validators, + super.asyncValidators, + super.asyncValidatorsDebounceTime, + super.disabled, + }); final _collectionChanges = StreamController>>.broadcast(); @@ -1156,17 +1145,14 @@ class FormGroup extends FormControlCollection> { /// See also [AbstractControl.validators] FormGroup( Map> controls, { - List> validators = const [], - List> asyncValidators = const [], - int asyncValidatorsDebounceTime = 250, + super.validators, + super.asyncValidators, + super.asyncValidatorsDebounceTime, bool disabled = false, }) : assert( !controls.keys.any((name) => name.contains(_controlNameDelimiter)), 'Control name should not contain dot($_controlNameDelimiter)'), super( - validators: validators, - asyncValidators: asyncValidators, - asyncValidatorsDebounceTime: asyncValidatorsDebounceTime, disabled: disabled, ) { addAll(controls); @@ -1670,14 +1656,11 @@ class FormArray extends FormControlCollection> { /// See also [AbstractControl.validators] FormArray( List> controls, { - List> validators = const [], - List> asyncValidators = const [], - int asyncValidatorsDebounceTime = 250, + super.validators, + super.asyncValidators, + super.asyncValidatorsDebounceTime, bool disabled = false, }) : super( - validators: validators, - asyncValidators: asyncValidators, - asyncValidatorsDebounceTime: asyncValidatorsDebounceTime, disabled: disabled, ) { addAll(controls); diff --git a/lib/src/widgets/inherited_streamer.dart b/lib/src/widgets/inherited_streamer.dart index 7203a7e..15f2736 100644 --- a/lib/src/widgets/inherited_streamer.dart +++ b/lib/src/widgets/inherited_streamer.dart @@ -7,8 +7,8 @@ import 'dart:async'; import 'package:flutter/material.dart'; abstract class InheritedStreamer extends InheritedWidget { - const InheritedStreamer(this.stream, Widget child, {Key? key}) - : super(key: key, child: child); + const InheritedStreamer(this.stream, Widget child, {super.key}) + : super(child: child); final Stream stream; diff --git a/lib/src/widgets/reactive_checkbox.dart b/lib/src/widgets/reactive_checkbox.dart index 42cc054..b47ad73 100644 --- a/lib/src/widgets/reactive_checkbox.dart +++ b/lib/src/widgets/reactive_checkbox.dart @@ -21,9 +21,9 @@ class ReactiveCheckbox extends ReactiveFocusableFormField { /// For documentation about the various parameters, see the [Checkbox] class /// and the [Checkbox] constructor. ReactiveCheckbox({ - Key? key, - String? formControlName, - FormControl? formControl, + super.key, + super.formControlName, + super.formControl, bool tristate = false, Color? activeColor, Color? checkColor, @@ -36,16 +36,12 @@ class ReactiveCheckbox extends ReactiveFocusableFormField { MaterialStateProperty? fillColor, MaterialStateProperty? overlayColor, double? splashRadius, - FocusNode? focusNode, + super.focusNode, OutlinedBorder? shape, BorderSide? side, ReactiveFormFieldCallback? onChanged, ShowErrorsFunction? showErrors, }) : super( - key: key, - formControl: formControl, - formControlName: formControlName, - focusNode: focusNode, showErrors: showErrors ?? (control) => control.invalid && (control.dirty || control.touched), diff --git a/lib/src/widgets/reactive_checkbox_list_tile.dart b/lib/src/widgets/reactive_checkbox_list_tile.dart index 3417d22..a350de7 100644 --- a/lib/src/widgets/reactive_checkbox_list_tile.dart +++ b/lib/src/widgets/reactive_checkbox_list_tile.dart @@ -21,9 +21,9 @@ class ReactiveCheckboxListTile extends ReactiveFocusableFormField { /// For documentation about the various parameters, see the [CheckboxListTile] /// class and the [CheckboxListTile] constructor. ReactiveCheckboxListTile({ - Key? key, - String? formControlName, - FormControl? formControl, + super.key, + super.formControlName, + super.formControl, Color? activeColor, Color? checkColor, Widget? title, @@ -40,7 +40,7 @@ class ReactiveCheckboxListTile extends ReactiveFocusableFormField { Color? tileColor, ShapeBorder? shape, VisualDensity? visualDensity, - FocusNode? focusNode, + super.focusNode, bool? enableFeedback, OutlinedBorder? checkboxShape, BorderSide? side, @@ -54,10 +54,6 @@ class ReactiveCheckboxListTile extends ReactiveFocusableFormField { ValueChanged? onFocusChange, ShowErrorsFunction? showErrors, }) : super( - key: key, - formControl: formControl, - formControlName: formControlName, - focusNode: focusNode, showErrors: showErrors ?? (control) => control.invalid && (control.dirty || control.touched), diff --git a/lib/src/widgets/reactive_date_picker.dart b/lib/src/widgets/reactive_date_picker.dart index 318e090..644cf67 100644 --- a/lib/src/widgets/reactive_date_picker.dart +++ b/lib/src/widgets/reactive_date_picker.dart @@ -55,9 +55,9 @@ class ReactiveDatePicker extends ReactiveFormField { /// For documentation about the various parameters, see the [showTimePicker] /// function parameters. ReactiveDatePicker({ - Key? key, - String? formControlName, - FormControl? formControl, + super.key, + super.formControlName, + super.formControl, required ReactiveDatePickerBuilder builder, required DateTime firstDate, required DateTime lastDate, @@ -82,9 +82,6 @@ class ReactiveDatePicker extends ReactiveFormField { TextInputType? keyboardType, Offset? anchorPoint, }) : super( - key: key, - formControl: formControl, - formControlName: formControlName, builder: (ReactiveFormFieldState field) { return builder( field.context, diff --git a/lib/src/widgets/reactive_dropdown_field.dart b/lib/src/widgets/reactive_dropdown_field.dart index 353a37e..cab9f76 100644 --- a/lib/src/widgets/reactive_dropdown_field.dart +++ b/lib/src/widgets/reactive_dropdown_field.dart @@ -25,13 +25,13 @@ class ReactiveDropdownField extends ReactiveFocusableFormField { /// For more information about all various parameters, /// see [DropdownButtonFormField] constructor. ReactiveDropdownField({ - Key? key, - String? formControlName, - FormControl? formControl, - FocusNode? focusNode, + super.key, + super.formControlName, + super.formControl, + super.focusNode, required List> items, - Map? validationMessages, - ShowErrorsFunction? showErrors, + super.validationMessages, + super.showErrors, DropdownButtonBuilder? selectedItemBuilder, Widget? hint, InputDecoration decoration = const InputDecoration(), @@ -58,12 +58,6 @@ class ReactiveDropdownField extends ReactiveFocusableFormField { ReactiveFormFieldCallback? onChanged, }) : assert(itemHeight == null || itemHeight > 0), super( - key: key, - formControl: formControl, - formControlName: formControlName, - validationMessages: validationMessages, - showErrors: showErrors, - focusNode: focusNode, builder: (ReactiveFormFieldState field) { final effectiveDecoration = decoration.applyDefaults( Theme.of(field.context).inputDecorationTheme, diff --git a/lib/src/widgets/reactive_form.dart b/lib/src/widgets/reactive_form.dart index 979f3a2..7ac2508 100644 --- a/lib/src/widgets/reactive_form.dart +++ b/lib/src/widgets/reactive_form.dart @@ -5,7 +5,6 @@ import 'package:flutter/material.dart'; import 'package:reactive_forms/reactive_forms.dart'; import 'package:reactive_forms/src/widgets/form_control_inherited_notifier.dart'; -import 'package:reactive_forms/src/widgets/reactive_form_pop_scope.dart'; /// This class is responsible for create a [FormControlInheritedStreamer] for /// exposing a [FormGroup] to all descendants widgets. @@ -29,12 +28,12 @@ class ReactiveForm extends StatelessWidget { /// /// The [formGroup] and [child] arguments are required. const ReactiveForm({ - Key? key, + super.key, required this.formGroup, required this.child, this.canPop, this.onPopInvoked, - }) : super(key: key); + }); /// Returns the nearest model up its widget tree. /// @@ -64,9 +63,11 @@ class ReactiveForm extends StatelessWidget { control: formGroup, stream: formGroup.statusChanged, child: canPop != null || onPopInvoked != null - ? ReactiveFormPopScope( - canPop: canPop, - onPopInvoked: onPopInvoked, + ? PopScope( + canPop: canPop != null ? canPop!(formGroup) : true, + onPopInvoked: onPopInvoked != null + ? (didPop) => onPopInvoked!(formGroup, didPop) + : null, child: child, ) : child, diff --git a/lib/src/widgets/reactive_form_array.dart b/lib/src/widgets/reactive_form_array.dart index 3f5de0b..0ccf2f7 100644 --- a/lib/src/widgets/reactive_form_array.dart +++ b/lib/src/widgets/reactive_form_array.dart @@ -33,7 +33,7 @@ class ReactiveFormArray extends StatefulWidget { /// subtree does not depend on the value of the [FormArray] that is bind /// with this widget. const ReactiveFormArray({ - Key? key, + super.key, required this.builder, this.formArrayName, this.formArray, @@ -41,8 +41,7 @@ class ReactiveFormArray extends StatefulWidget { }) : assert( (formArrayName != null && formArray == null) || (formArrayName == null && formArray != null), - 'Must provide a formArrayName or a formArray, but not both at the same time.'), - super(key: key); + 'Must provide a formArrayName or a formArray, but not both at the same time.'); @override ReactiveFormArrayState createState() => ReactiveFormArrayState(); diff --git a/lib/src/widgets/reactive_form_builder.dart b/lib/src/widgets/reactive_form_builder.dart index d191387..ee9988e 100644 --- a/lib/src/widgets/reactive_form_builder.dart +++ b/lib/src/widgets/reactive_form_builder.dart @@ -51,13 +51,13 @@ class ReactiveFormBuilder extends StatefulWidget { /// } /// ``` const ReactiveFormBuilder({ - Key? key, + super.key, required this.form, required this.builder, this.canPop, this.onPopInvoked, this.child, - }) : super(key: key); + }); @override ReactiveFormBuilderState createState() => ReactiveFormBuilderState(); diff --git a/lib/src/widgets/reactive_form_config.dart b/lib/src/widgets/reactive_form_config.dart index f90ea38..fc4028f 100644 --- a/lib/src/widgets/reactive_form_config.dart +++ b/lib/src/widgets/reactive_form_config.dart @@ -33,10 +33,10 @@ class ReactiveFormConfig extends InheritedWidget { /// ); /// ``` const ReactiveFormConfig({ - required Widget child, + required super.child, required this.validationMessages, - Key? key, - }) : super(child: child, key: key); + super.key, + }); @override bool updateShouldNotify(covariant ReactiveFormConfig oldWidget) { diff --git a/lib/src/widgets/reactive_form_consumer.dart b/lib/src/widgets/reactive_form_consumer.dart index e0e5130..f915996 100644 --- a/lib/src/widgets/reactive_form_consumer.dart +++ b/lib/src/widgets/reactive_form_consumer.dart @@ -36,10 +36,10 @@ class ReactiveFormConsumer extends StatelessWidget { /// subtree does not depend on the value of the [FormGroup] that is bind /// with this widget. const ReactiveFormConsumer({ - Key? key, + super.key, required this.builder, this.child, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/src/widgets/reactive_form_field.dart b/lib/src/widgets/reactive_form_field.dart index 8a0db6f..35b7366 100644 --- a/lib/src/widgets/reactive_form_field.dart +++ b/lib/src/widgets/reactive_form_field.dart @@ -61,7 +61,7 @@ class ReactiveFormField extends StatefulWidget { /// /// The [builder] arguments are required. ReactiveFormField({ - Key? key, + super.key, this.formControl, this.formControlName, this.valueAccessor, @@ -73,8 +73,7 @@ class ReactiveFormField extends StatefulWidget { (formControlName != null && formControl == null) || (formControlName == null && formControl != null), 'Must provide a formControlName or a formControl, but not both at the same time.'), - _builder = builder, - super(key: key); + _builder = builder; @override ReactiveFormFieldState createState() => diff --git a/lib/src/widgets/reactive_form_pop_scope.dart b/lib/src/widgets/reactive_form_pop_scope.dart deleted file mode 100644 index 51f9b1c..0000000 --- a/lib/src/widgets/reactive_form_pop_scope.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:reactive_forms/reactive_forms.dart'; - -class ReactiveFormPopScope extends StatelessWidget { - final bool Function(FormGroup formGroup)? canPop; - final void Function(FormGroup formGroup, bool didPop)? onPopInvoked; - final Widget child; - - const ReactiveFormPopScope({ - super.key, - this.canPop, - this.onPopInvoked, - required this.child, - }); - - @override - Widget build(BuildContext context) { - return ReactiveFormConsumer( - builder: (context, formGroup, _) { - return PopScope( - canPop: canPop != null ? canPop!(formGroup) : true, - onPopInvoked: onPopInvoked != null - ? (didPop) => onPopInvoked!(formGroup, didPop) - : null, - child: child, - ); - }, - ); - } -} diff --git a/lib/src/widgets/reactive_radio.dart b/lib/src/widgets/reactive_radio.dart index 38bb7e0..7afdbd9 100644 --- a/lib/src/widgets/reactive_radio.dart +++ b/lib/src/widgets/reactive_radio.dart @@ -29,9 +29,9 @@ class ReactiveRadio extends ReactiveFocusableFormField { /// For documentation about the various parameters, see the [Radio] class /// and [Radio], the constructor. ReactiveRadio({ - Key? key, - String? formControlName, - FormControl? formControl, + super.key, + super.formControlName, + super.formControl, required T value, Color? activeColor, Color? focusColor, @@ -44,13 +44,9 @@ class ReactiveRadio extends ReactiveFocusableFormField { double? splashRadius, bool autofocus = false, bool toggleable = false, - FocusNode? focusNode, + super.focusNode, ReactiveFormFieldCallback? onChanged, }) : super( - key: key, - formControl: formControl, - formControlName: formControlName, - focusNode: focusNode, builder: (field) { return Radio( value: value, diff --git a/lib/src/widgets/reactive_radio_list_tile.dart b/lib/src/widgets/reactive_radio_list_tile.dart index 35603d2..f21f961 100644 --- a/lib/src/widgets/reactive_radio_list_tile.dart +++ b/lib/src/widgets/reactive_radio_list_tile.dart @@ -26,9 +26,9 @@ class ReactiveRadioListTile extends ReactiveFocusableFormField { /// /// See also [RadioListTile] ReactiveRadioListTile({ - Key? key, - String? formControlName, - FormControl? formControl, + super.key, + super.formControlName, + super.formControl, required T value, Color? activeColor, Color? selectedTileColor, @@ -45,7 +45,7 @@ class ReactiveRadioListTile extends ReactiveFocusableFormField { bool autofocus = false, bool selected = false, VisualDensity? visualDensity, - FocusNode? focusNode, + super.focusNode, bool? enableFeedback, ReactiveFormFieldCallback? onChanged, MouseCursor? mouseCursor, @@ -56,10 +56,6 @@ class ReactiveRadioListTile extends ReactiveFocusableFormField { MaterialTapTargetSize? materialTapTargetSize, ValueChanged? onFocusChange, }) : super( - key: key, - formControl: formControl, - formControlName: formControlName, - focusNode: focusNode, builder: (field) { return RadioListTile( value: value, diff --git a/lib/src/widgets/reactive_slider.dart b/lib/src/widgets/reactive_slider.dart index f5d413e..d7ff950 100644 --- a/lib/src/widgets/reactive_slider.dart +++ b/lib/src/widgets/reactive_slider.dart @@ -31,9 +31,9 @@ class ReactiveSlider extends ReactiveFocusableFormField { /// The [labelBuilder] is called each time the [FormControl] changes its value /// so you can supply a label to the Slider. ReactiveSlider( - {Key? key, - String? formControlName, - FormControl? formControl, + {super.key, + super.formControlName, + super.formControl, double min = 0.0, double max = 1.0, int? divisions, @@ -44,7 +44,7 @@ class ReactiveSlider extends ReactiveFocusableFormField { SemanticFormatterCallback? semanticFormatterCallback, bool autofocus = false, MouseCursor? mouseCursor, - FocusNode? focusNode, + super.focusNode, ReactiveFormFieldCallback? onChangeEnd, ReactiveFormFieldCallback? onChangeStart, ReactiveFormFieldCallback? onChanged, @@ -52,10 +52,6 @@ class ReactiveSlider extends ReactiveFocusableFormField { Color? secondaryActiveColor, MaterialStateProperty? overlayColor}) : super( - key: key, - formControl: formControl, - formControlName: formControlName, - focusNode: focusNode, builder: (field) { var value = field.value; if (value == null) { diff --git a/lib/src/widgets/reactive_status_listenable_builder.dart b/lib/src/widgets/reactive_status_listenable_builder.dart index 540305d..7a37da1 100644 --- a/lib/src/widgets/reactive_status_listenable_builder.dart +++ b/lib/src/widgets/reactive_status_listenable_builder.dart @@ -32,7 +32,7 @@ class ReactiveStatusListenableBuilder extends StatelessWidget { /// at the same time. /// const ReactiveStatusListenableBuilder({ - Key? key, + super.key, this.formControlName, this.formControl, required this.builder, @@ -40,8 +40,7 @@ class ReactiveStatusListenableBuilder extends StatelessWidget { }) : assert( (formControlName != null && formControl == null) || (formControlName == null && formControl != null), - 'Must provide a formControlName or a formControl, but not both at the same time.'), - super(key: key); + 'Must provide a formControlName or a formControl, but not both at the same time.'); @override Widget build(BuildContext context) { diff --git a/lib/src/widgets/reactive_switch.dart b/lib/src/widgets/reactive_switch.dart index a9d6986..92028b9 100644 --- a/lib/src/widgets/reactive_switch.dart +++ b/lib/src/widgets/reactive_switch.dart @@ -33,10 +33,10 @@ class ReactiveSwitch extends ReactiveFocusableFormField { /// For documentation about the various parameters, see the [Switch] class /// and [Switch], the constructor. ReactiveSwitch({ - Key? key, - String? formControlName, - FormControl? formControl, - FocusNode? focusNode, + super.key, + super.formControlName, + super.formControl, + super.focusNode, Color? activeColor, Color? activeTrackColor, Color? inactiveThumbColor, @@ -60,10 +60,6 @@ class ReactiveSwitch extends ReactiveFocusableFormField { MaterialStateProperty? thumbIcon, ValueChanged? onFocusChange, }) : super( - key: key, - formControl: formControl, - formControlName: formControlName, - focusNode: focusNode, builder: (field) { return Switch( value: field.value ?? false, @@ -120,10 +116,10 @@ class ReactiveSwitch extends ReactiveFocusableFormField { /// For documentation about the various parameters, see the [Switch.adaptive] /// constructor. ReactiveSwitch.adaptive({ - Key? key, - String? formControlName, - FormControl? formControl, - FocusNode? focusNode, + super.key, + super.formControlName, + super.formControl, + super.focusNode, Color? activeColor, Color? activeTrackColor, Color? inactiveThumbColor, @@ -144,10 +140,6 @@ class ReactiveSwitch extends ReactiveFocusableFormField { double? splashRadius, ReactiveFormFieldCallback? onChanged, }) : super( - key: key, - formControl: formControl, - formControlName: formControlName, - focusNode: focusNode, builder: (field) { return Switch.adaptive( value: field.value ?? false, diff --git a/lib/src/widgets/reactive_switch_list_tile.dart b/lib/src/widgets/reactive_switch_list_tile.dart index fd230ce..66c970f 100644 --- a/lib/src/widgets/reactive_switch_list_tile.dart +++ b/lib/src/widgets/reactive_switch_list_tile.dart @@ -26,9 +26,9 @@ class ReactiveSwitchListTile extends ReactiveFocusableFormField { /// /// See also [CheckboxListTile] ReactiveSwitchListTile({ - Key? key, - String? formControlName, - FormControl? formControl, + super.key, + super.formControlName, + super.formControl, Color? tileColor, Color? activeColor, Color? activeTrackColor, @@ -50,7 +50,7 @@ class ReactiveSwitchListTile extends ReactiveFocusableFormField { Color? selectedTileColor, VisualDensity? visualDensity, bool? enableFeedback, - FocusNode? focusNode, + super.focusNode, ReactiveFormFieldCallback? onChanged, ImageErrorListener? onActiveThumbImageError, ImageErrorListener? onInactiveThumbImageError, @@ -65,10 +65,6 @@ class ReactiveSwitchListTile extends ReactiveFocusableFormField { double? splashRadius, ValueChanged? onFocusChange, }) : super( - key: key, - formControl: formControl, - formControlName: formControlName, - focusNode: focusNode, builder: (field) { return SwitchListTile( value: field.value ?? false, @@ -132,9 +128,9 @@ class ReactiveSwitchListTile extends ReactiveFocusableFormField { /// For documentation about the various parameters, see the /// [SwitchListTile.adaptive] constructor. ReactiveSwitchListTile.adaptative({ - Key? key, - String? formControlName, - FormControl? formControl, + super.key, + super.formControlName, + super.formControl, Color? activeColor, Color? activeTrackColor, Color? inactiveThumbColor, @@ -158,7 +154,7 @@ class ReactiveSwitchListTile extends ReactiveFocusableFormField { ListTileControlAffinity controlAffinity = ListTileControlAffinity.platform, bool? dense, bool? enableFeedback, - FocusNode? focusNode, + super.focusNode, ValueChanged? onFocusChange, Color? hoverColor, bool isThreeLine = false, @@ -172,10 +168,6 @@ class ReactiveSwitchListTile extends ReactiveFocusableFormField { VisualDensity? visualDensity, ReactiveFormFieldCallback? onChanged, }) : super( - key: key, - formControl: formControl, - formControlName: formControlName, - focusNode: focusNode, builder: (field) { return SwitchListTile.adaptive( value: field.value ?? false, diff --git a/lib/src/widgets/reactive_text_field.dart b/lib/src/widgets/reactive_text_field.dart index 89fac18..b0cf148 100644 --- a/lib/src/widgets/reactive_text_field.dart +++ b/lib/src/widgets/reactive_text_field.dart @@ -90,13 +90,13 @@ class ReactiveTextField extends ReactiveFormField { /// For documentation about the various parameters, see the [TextField] class /// and [TextField], the constructor. ReactiveTextField({ - Key? key, - String? formControlName, - FormControl? formControl, - Map? validationMessages, - ControlValueAccessor? valueAccessor, - ShowErrorsFunction? showErrors, - FocusNode? focusNode, + super.key, + super.formControlName, + super.formControl, + super.validationMessages, + super.valueAccessor, + super.showErrors, + super.focusNode, InputDecoration decoration = const InputDecoration(), TextInputType? keyboardType, TextCapitalization textCapitalization = TextCapitalization.none, @@ -158,13 +158,6 @@ class ReactiveTextField extends ReactiveFormField { TextMagnifierConfiguration? magnifierConfiguration, }) : _textController = controller, super( - key: key, - formControl: formControl, - formControlName: formControlName, - valueAccessor: valueAccessor, - validationMessages: validationMessages, - showErrors: showErrors, - focusNode: focusNode, builder: (ReactiveFormFieldState field) { final state = field as _ReactiveTextFieldState; final effectiveDecoration = decoration diff --git a/lib/src/widgets/reactive_time_picker.dart b/lib/src/widgets/reactive_time_picker.dart index 22a25d5..501bf97 100644 --- a/lib/src/widgets/reactive_time_picker.dart +++ b/lib/src/widgets/reactive_time_picker.dart @@ -60,9 +60,9 @@ class ReactiveTimePicker extends ReactiveFormField { /// For documentation about the various parameters, see the [showTimePicker] /// function parameters. ReactiveTimePicker({ - Key? key, - String? formControlName, - FormControl? formControl, + super.key, + super.formControlName, + super.formControl, required ReactiveTimePickerBuilder builder, TransitionBuilder? transitionBuilder, bool useRootNavigator = true, @@ -78,9 +78,6 @@ class ReactiveTimePicker extends ReactiveFormField { EntryModeChangeCallback? onEntryModeChanged, Offset? anchorPoint, }) : super( - key: key, - formControl: formControl, - formControlName: formControlName, builder: (ReactiveFormFieldState field) { return builder( field.context, diff --git a/lib/src/widgets/reactive_value_listenable_builder.dart b/lib/src/widgets/reactive_value_listenable_builder.dart index 09a19ae..8223817 100644 --- a/lib/src/widgets/reactive_value_listenable_builder.dart +++ b/lib/src/widgets/reactive_value_listenable_builder.dart @@ -38,7 +38,7 @@ class ReactiveValueListenableBuilder extends StatelessWidget { /// subtree does not depend on the value of the [FormControl] that is bind /// with this widget. const ReactiveValueListenableBuilder({ - Key? key, + super.key, required this.builder, this.formControlName, this.formControl, @@ -46,8 +46,7 @@ class ReactiveValueListenableBuilder extends StatelessWidget { }) : assert( (formControlName != null && formControl == null) || (formControlName == null && formControl != null), - 'Must provide a formControlName or a formControl, but not both at the same time.'), - super(key: key); + 'Must provide a formControlName or a formControl, but not both at the same time.'); @override Widget build(BuildContext context) { diff --git a/pubspec.yaml b/pubspec.yaml index 550638e..e7478d7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,17 +4,16 @@ version: 17.0.0 homepage: "https://github.com/joanpablo/reactive_forms" environment: - sdk: ">=3.0.0 <4.0.0" - flutter: ">=3.10.0" + sdk: ">=3.2.4 <4.0.0" + flutter: ">=3.16.0" dependencies: flutter: sdk: flutter - # when using flutter 3.10, flutter_localizations depends on intl 0.18.0 - intl: ">=0.18.0 <1.0.0" + intl: ">=0.19.0 <1.0.0" dev_dependencies: - lints: ^2.1.0 + flutter_lints: ^3.0.2 flutter_test: sdk: flutter diff --git a/test/src/widgets/reactive_checkbox_list_tile_testing_widget.dart b/test/src/widgets/reactive_checkbox_list_tile_testing_widget.dart index f49abc4..73418b5 100644 --- a/test/src/widgets/reactive_checkbox_list_tile_testing_widget.dart +++ b/test/src/widgets/reactive_checkbox_list_tile_testing_widget.dart @@ -10,12 +10,12 @@ class ReactiveCheckboxListTileTestingWidget extends StatelessWidget { final ReactiveFormFieldCallback? onChanged; const ReactiveCheckboxListTileTestingWidget({ - Key? key, + super.key, required this.form, this.tristate = false, this.focusNode, this.onChanged, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/test/src/widgets/reactive_checkbox_testing_widget.dart b/test/src/widgets/reactive_checkbox_testing_widget.dart index 2f12079..d72dca6 100644 --- a/test/src/widgets/reactive_checkbox_testing_widget.dart +++ b/test/src/widgets/reactive_checkbox_testing_widget.dart @@ -10,12 +10,12 @@ class ReactiveCheckboxTestingWidget extends StatelessWidget { final ReactiveFormFieldCallback? onChanged; const ReactiveCheckboxTestingWidget({ - Key? key, + super.key, required this.form, this.tristate = false, this.focusNode, this.onChanged, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/test/src/widgets/reactive_date_picker_testing_widget.dart b/test/src/widgets/reactive_date_picker_testing_widget.dart index 510badc..db5386c 100644 --- a/test/src/widgets/reactive_date_picker_testing_widget.dart +++ b/test/src/widgets/reactive_date_picker_testing_widget.dart @@ -8,12 +8,12 @@ class ReactiveDatePickerTestingWidget extends StatelessWidget { final DateTime? initialDate; const ReactiveDatePickerTestingWidget({ - Key? key, + super.key, required this.form, this.lastDate, this.firstDate, this.initialDate, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/test/src/widgets/reactive_dropdown_testing_widget.dart b/test/src/widgets/reactive_dropdown_testing_widget.dart index 74ecd13..bd2c464 100644 --- a/test/src/widgets/reactive_dropdown_testing_widget.dart +++ b/test/src/widgets/reactive_dropdown_testing_widget.dart @@ -11,7 +11,7 @@ class ReactiveDropdownTestingWidget extends StatelessWidget { final DropdownButtonBuilder? selectedItemBuilder; const ReactiveDropdownTestingWidget({ - Key? key, + super.key, required this.form, required this.items, this.onChanged, @@ -19,7 +19,7 @@ class ReactiveDropdownTestingWidget extends StatelessWidget { this.readOnly = false, this.disabledHint, this.selectedItemBuilder, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/test/src/widgets/reactive_form_array_testing_widget.dart b/test/src/widgets/reactive_form_array_testing_widget.dart index 6173a00..dede3ea 100644 --- a/test/src/widgets/reactive_form_array_testing_widget.dart +++ b/test/src/widgets/reactive_form_array_testing_widget.dart @@ -5,9 +5,9 @@ class ReactiveFormArrayTestingWidget extends StatelessWidget { final FormGroup form; const ReactiveFormArrayTestingWidget({ - Key? key, + super.key, required this.form, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/test/src/widgets/reactive_form_builder_testing_widget.dart b/test/src/widgets/reactive_form_builder_testing_widget.dart index b62b454..748b183 100644 --- a/test/src/widgets/reactive_form_builder_testing_widget.dart +++ b/test/src/widgets/reactive_form_builder_testing_widget.dart @@ -7,13 +7,13 @@ class ReactiveFormBuilderTestingWidget extends StatelessWidget { final Map bindings; const ReactiveFormBuilderTestingWidget({ - Key? key, + super.key, required this.form, this.validationMessages, this.bindings = const { 'textField': 'name', }, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/test/src/widgets/reactive_form_consumer_testing_widget.dart b/test/src/widgets/reactive_form_consumer_testing_widget.dart index c950417..a714958 100644 --- a/test/src/widgets/reactive_form_consumer_testing_widget.dart +++ b/test/src/widgets/reactive_form_consumer_testing_widget.dart @@ -5,9 +5,9 @@ class ReactiveFormConsumerTestingWidget extends StatelessWidget { final FormGroup form; const ReactiveFormConsumerTestingWidget({ - Key? key, + super.key, required this.form, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/test/src/widgets/reactive_radio_list_tile_testing_widget.dart b/test/src/widgets/reactive_radio_list_tile_testing_widget.dart index 8f03442..953ec2b 100644 --- a/test/src/widgets/reactive_radio_list_tile_testing_widget.dart +++ b/test/src/widgets/reactive_radio_list_tile_testing_widget.dart @@ -9,11 +9,11 @@ class ReactiveRadioListTileTestingWidget extends StatelessWidget { final ReactiveFormFieldCallback? onChanged; const ReactiveRadioListTileTestingWidget({ - Key? key, + super.key, required this.form, this.focusNode, this.onChanged, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/test/src/widgets/reactive_radio_testing_widget.dart b/test/src/widgets/reactive_radio_testing_widget.dart index b7cc83e..74e6382 100644 --- a/test/src/widgets/reactive_radio_testing_widget.dart +++ b/test/src/widgets/reactive_radio_testing_widget.dart @@ -9,11 +9,11 @@ class ReactiveRadioTestingWidget extends StatelessWidget { final ReactiveFormFieldCallback? onChanged; const ReactiveRadioTestingWidget({ - Key? key, + super.key, required this.form, this.focusNode, this.onChanged, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/test/src/widgets/reactive_slider_testing_widget.dart b/test/src/widgets/reactive_slider_testing_widget.dart index fd58804..b6e5d90 100644 --- a/test/src/widgets/reactive_slider_testing_widget.dart +++ b/test/src/widgets/reactive_slider_testing_widget.dart @@ -12,14 +12,14 @@ class ReactiveSliderTestingWidget extends StatelessWidget { final ReactiveFormFieldCallback? onChanged; const ReactiveSliderTestingWidget({ - Key? key, + super.key, required this.form, this.focusNode, this.labelBuilder, this.onChanged, this.onChangeStart, this.onChangeEnd, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/test/src/widgets/reactive_status_listenable_builder_testing_widget.dart b/test/src/widgets/reactive_status_listenable_builder_testing_widget.dart index f3ba460..666e2b3 100644 --- a/test/src/widgets/reactive_status_listenable_builder_testing_widget.dart +++ b/test/src/widgets/reactive_status_listenable_builder_testing_widget.dart @@ -5,9 +5,9 @@ class ReactiveStatusListenableTestingWidget extends StatelessWidget { final FormGroup form; const ReactiveStatusListenableTestingWidget({ - Key? key, + super.key, required this.form, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/test/src/widgets/reactive_switch_list_tile_testing_widget.dart b/test/src/widgets/reactive_switch_list_tile_testing_widget.dart index 9da1ba3..b30b729 100644 --- a/test/src/widgets/reactive_switch_list_tile_testing_widget.dart +++ b/test/src/widgets/reactive_switch_list_tile_testing_widget.dart @@ -12,14 +12,14 @@ class ReactiveSwitchListTileTestingWidget extends StatelessWidget { final bool renderAdaptative; const ReactiveSwitchListTileTestingWidget({ - Key? key, + super.key, required this.form, this.renderAdaptative = true, this.focusNode, this.adaptativeFocusNode, this.onChanged, this.adaptativeOnChanged, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/test/src/widgets/reactive_switch_testing_widget.dart b/test/src/widgets/reactive_switch_testing_widget.dart index 48da166..47e6d3f 100644 --- a/test/src/widgets/reactive_switch_testing_widget.dart +++ b/test/src/widgets/reactive_switch_testing_widget.dart @@ -10,12 +10,12 @@ class ReactiveSwitchTestingWidget extends StatelessWidget { final ReactiveFormFieldCallback? adaptativeOnChanged; const ReactiveSwitchTestingWidget({ - Key? key, + super.key, required this.form, this.focusNode, this.onChanged, this.adaptativeOnChanged, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/test/src/widgets/reactive_text_field_testing_widget.dart b/test/src/widgets/reactive_text_field_testing_widget.dart index 3cc11a1..e3210db 100644 --- a/test/src/widgets/reactive_text_field_testing_widget.dart +++ b/test/src/widgets/reactive_text_field_testing_widget.dart @@ -13,7 +13,7 @@ class ReactiveTextFieldTestingWidget extends StatelessWidget { final ReactiveFormFieldCallback? onEditingComplete; const ReactiveTextFieldTestingWidget({ - Key? key, + super.key, required this.form, this.validationMessages, this.showErrors, @@ -25,7 +25,7 @@ class ReactiveTextFieldTestingWidget extends StatelessWidget { this.onTap, this.onSubmitted, this.onEditingComplete, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/test/src/widgets/reactive_time_picker_testing_widget.dart b/test/src/widgets/reactive_time_picker_testing_widget.dart index abda518..97d1c59 100644 --- a/test/src/widgets/reactive_time_picker_testing_widget.dart +++ b/test/src/widgets/reactive_time_picker_testing_widget.dart @@ -5,9 +5,9 @@ class ReactiveTimePickerTestingWidget extends StatelessWidget { final FormGroup form; const ReactiveTimePickerTestingWidget({ - Key? key, + super.key, required this.form, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/test/src/widgets/reactive_value_listenable_builder_testing_widget.dart b/test/src/widgets/reactive_value_listenable_builder_testing_widget.dart index d0b006c..0eb6a57 100644 --- a/test/src/widgets/reactive_value_listenable_builder_testing_widget.dart +++ b/test/src/widgets/reactive_value_listenable_builder_testing_widget.dart @@ -5,9 +5,9 @@ class ReactiveValueListenableTestingWidget extends StatelessWidget { final FormGroup form; const ReactiveValueListenableTestingWidget({ - Key? key, + super.key, required this.form, - }) : super(key: key); + }); @override Widget build(BuildContext context) { From b5189b0bdc43f82f9d05ba6646bebf6c2a07a1ab Mon Sep 17 00:00:00 2001 From: Joan Pablo Date: Fri, 29 Mar 2024 12:14:11 -0400 Subject: [PATCH 04/10] Update Flutter dependencies - Update Reactive Forms version to 17.0 - Update Flutter version >=3.16.0 - Update Dart version >=3.2.4 <4.0.0 - Replace deprecated WillPopScope with PopScope - Fix the use super parameters --- example/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 1718e6f..850092e 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ">=3.2.4 <4.0.0" + sdk: ">=3.2.0 <4.0.0" flutter: ">=3.16.0" dependencies: diff --git a/pubspec.yaml b/pubspec.yaml index e7478d7..61eef46 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ version: 17.0.0 homepage: "https://github.com/joanpablo/reactive_forms" environment: - sdk: ">=3.2.4 <4.0.0" + sdk: ">=3.2.0 <4.0.0" flutter: ">=3.16.0" dependencies: From 99c7ecd9dfb0d44c3c49f01d28275b53a617b126 Mon Sep 17 00:00:00 2001 From: Joan Pablo Date: Fri, 29 Mar 2024 12:14:11 -0400 Subject: [PATCH 05/10] Update Flutter dependencies - Update Reactive Forms version to 17.0 - Update Flutter version >=3.16.0 - Update Dart version >=3.2.4 <4.0.0 - Replace deprecated WillPopScope with PopScope - Fix the use super parameters --- example/pubspec.yaml | 2 +- lib/src/widgets/reactive_form_array.dart | 2 +- lib/src/widgets/reactive_status_listenable_builder.dart | 2 +- lib/src/widgets/reactive_value_listenable_builder.dart | 2 +- pubspec.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 1718e6f..850092e 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ">=3.2.4 <4.0.0" + sdk: ">=3.2.0 <4.0.0" flutter: ">=3.16.0" dependencies: diff --git a/lib/src/widgets/reactive_form_array.dart b/lib/src/widgets/reactive_form_array.dart index 0ccf2f7..48f40ef 100644 --- a/lib/src/widgets/reactive_form_array.dart +++ b/lib/src/widgets/reactive_form_array.dart @@ -38,7 +38,7 @@ class ReactiveFormArray extends StatefulWidget { this.formArrayName, this.formArray, this.child, - }) : assert( + }) : assert( (formArrayName != null && formArray == null) || (formArrayName == null && formArray != null), 'Must provide a formArrayName or a formArray, but not both at the same time.'); diff --git a/lib/src/widgets/reactive_status_listenable_builder.dart b/lib/src/widgets/reactive_status_listenable_builder.dart index 7a37da1..1268d2e 100644 --- a/lib/src/widgets/reactive_status_listenable_builder.dart +++ b/lib/src/widgets/reactive_status_listenable_builder.dart @@ -37,7 +37,7 @@ class ReactiveStatusListenableBuilder extends StatelessWidget { this.formControl, required this.builder, this.child, - }) : assert( + }) : assert( (formControlName != null && formControl == null) || (formControlName == null && formControl != null), 'Must provide a formControlName or a formControl, but not both at the same time.'); diff --git a/lib/src/widgets/reactive_value_listenable_builder.dart b/lib/src/widgets/reactive_value_listenable_builder.dart index 8223817..af355f4 100644 --- a/lib/src/widgets/reactive_value_listenable_builder.dart +++ b/lib/src/widgets/reactive_value_listenable_builder.dart @@ -43,7 +43,7 @@ class ReactiveValueListenableBuilder extends StatelessWidget { this.formControlName, this.formControl, this.child, - }) : assert( + }) : assert( (formControlName != null && formControl == null) || (formControlName == null && formControl != null), 'Must provide a formControlName or a formControl, but not both at the same time.'); diff --git a/pubspec.yaml b/pubspec.yaml index e7478d7..61eef46 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ version: 17.0.0 homepage: "https://github.com/joanpablo/reactive_forms" environment: - sdk: ">=3.2.4 <4.0.0" + sdk: ">=3.2.0 <4.0.0" flutter: ">=3.16.0" dependencies: From f839d7d9f07b232f442f115c10410755e908a180 Mon Sep 17 00:00:00 2001 From: Joan Pablo Date: Fri, 29 Mar 2024 15:06:37 -0400 Subject: [PATCH 06/10] Update Flutter dependencies - Replace deprecated WillPopScope with PopScope --- example/android/app/build.gradle | 2 +- lib/src/widgets/reactive_form.dart | 19 +++---- lib/src/widgets/reactive_form_builder.dart | 19 ++++++- lib/src/widgets/reactive_form_pop_scope.dart | 52 ++++++++++++++++++++ 4 files changed, 79 insertions(+), 13 deletions(-) create mode 100644 lib/src/widgets/reactive_form_pop_scope.dart diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index f852a55..6a21e16 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -39,7 +39,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.reactive_forms_example" - minSdkVersion 16 + minSdkVersion flutter.minSdkVersion targetSdkVersion 29 versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/lib/src/widgets/reactive_form.dart b/lib/src/widgets/reactive_form.dart index 7ac2508..d99aeaa 100644 --- a/lib/src/widgets/reactive_form.dart +++ b/lib/src/widgets/reactive_form.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'package:reactive_forms/reactive_forms.dart'; import 'package:reactive_forms/src/widgets/form_control_inherited_notifier.dart'; +import 'package:reactive_forms/src/widgets/reactive_form_pop_scope.dart'; /// This class is responsible for create a [FormControlInheritedStreamer] for /// exposing a [FormGroup] to all descendants widgets. @@ -19,10 +20,10 @@ class ReactiveForm extends StatelessWidget { final FormGroup formGroup; /// Determine whether a route can popped. See [PopScope] for more details. - final bool Function(FormGroup formGroup)? canPop; + final ReactiveFormCanPopCallback? canPop; /// A callback invoked when a route is popped. See [PopScope] for more details. - final void Function(FormGroup formGroup, bool didPop)? onPopInvoked; + final ReactiveFormPopInvokedCallback? onPopInvoked; /// Creates and instance of [ReactiveForm]. /// @@ -62,15 +63,11 @@ class ReactiveForm extends StatelessWidget { return FormControlInheritedStreamer( control: formGroup, stream: formGroup.statusChanged, - child: canPop != null || onPopInvoked != null - ? PopScope( - canPop: canPop != null ? canPop!(formGroup) : true, - onPopInvoked: onPopInvoked != null - ? (didPop) => onPopInvoked!(formGroup, didPop) - : null, - child: child, - ) - : child, + child: ReactiveFormPopScope( + canPop: canPop, + onPopInvoked: onPopInvoked, + child: child, + ), ); } } diff --git a/lib/src/widgets/reactive_form_builder.dart b/lib/src/widgets/reactive_form_builder.dart index ee9988e..03c6095 100644 --- a/lib/src/widgets/reactive_form_builder.dart +++ b/lib/src/widgets/reactive_form_builder.dart @@ -21,7 +21,7 @@ class ReactiveFormBuilder extends StatefulWidget { /// Called to create the FormGroup that will be bind to this widget. final ReactiveFormBuilderCreator form; - /// Determine whether a route can popped. See [PopScope] for more details. + /// Determine whether a route can be popped. See [PopScope] for more details. final bool Function(FormGroup formGroup)? canPop; /// A callback invoked when a route is popped. See [PopScope] for more details. @@ -50,6 +50,23 @@ class ReactiveFormBuilder extends StatefulWidget { /// } /// } /// ``` + /// ### Example: Allows the route to be popped only if the form is valid. + /// ```dart + /// class MyWidget extends StatelessWidget { + /// @override + /// Widget build(BuildContext context) { + /// return ReactiveFormBuilder( + /// form: (context) => FormGroup({'name': FormControl()}), + /// canPop: (formGroup) => formGroup.valid + /// builder: (context, form, child) { + /// return ReactiveTextField( + /// formControlName: 'name', + /// ); + /// }, + /// ); + /// } + /// } + /// ``` const ReactiveFormBuilder({ super.key, required this.form, diff --git a/lib/src/widgets/reactive_form_pop_scope.dart b/lib/src/widgets/reactive_form_pop_scope.dart new file mode 100644 index 0000000..932f617 --- /dev/null +++ b/lib/src/widgets/reactive_form_pop_scope.dart @@ -0,0 +1,52 @@ +// Copyright 2020 Joan Pablo Jimenez Milian. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:reactive_forms/reactive_forms.dart'; + +/// This is the signature to determine whether a route can popped. +/// See [PopScope] for more details. +typedef ReactiveFormCanPopCallback = bool Function(FormGroup formGroup); + +/// This is the signature of the callback invoked when a route is popped. +/// See [PopScope] for more details. +typedef ReactiveFormPopInvokedCallback = void Function( + FormGroup formGroup, bool didPop); + +class ReactiveFormPopScope extends StatelessWidget { + /// The widget below this widget in the tree. + final Widget child; + + /// Determine whether a route can popped. See [PopScope] for more details. + final ReactiveFormCanPopCallback? canPop; + + /// A callback invoked when a route is popped. See [PopScope] for more details. + final ReactiveFormPopInvokedCallback? onPopInvoked; + + const ReactiveFormPopScope({ + super.key, + this.canPop, + this.onPopInvoked, + required this.child, + }); + + @override + Widget build(BuildContext context) { + if (canPop == null && onPopInvoked == null) { + return child; + } + + return ReactiveFormConsumer( + builder: (context, formGroup, _) { + return PopScope( + canPop: canPop?.call(formGroup) ?? true, + onPopInvoked: onPopInvoked != null + ? (didPop) => onPopInvoked!(formGroup, didPop) + : null, + child: child, + ); + }, + ); + } +} From 1524eeb3d92a2867ae76085b21980441d3a8d04a Mon Sep 17 00:00:00 2001 From: Joan Pablo Date: Fri, 29 Mar 2024 15:10:58 -0400 Subject: [PATCH 07/10] Update Flutter dependencies - Dispose inner TextEditingController --- lib/src/widgets/reactive_text_field.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/widgets/reactive_text_field.dart b/lib/src/widgets/reactive_text_field.dart index 9b89367..08f4989 100644 --- a/lib/src/widgets/reactive_text_field.dart +++ b/lib/src/widgets/reactive_text_field.dart @@ -297,7 +297,7 @@ class _ReactiveTextFieldState void dispose() { if (widget.textController == null) { _textController.dispose(); - } + } super.dispose(); } } From 60e80193c27071d68175698c525e58564b220b19 Mon Sep 17 00:00:00 2001 From: Joan Pablo Date: Fri, 29 Mar 2024 15:17:19 -0400 Subject: [PATCH 08/10] Update Flutter dependencies - Dispose inner TextEditingController --- lib/src/widgets/reactive_text_field.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/widgets/reactive_text_field.dart b/lib/src/widgets/reactive_text_field.dart index 08f4989..40cda1b 100644 --- a/lib/src/widgets/reactive_text_field.dart +++ b/lib/src/widgets/reactive_text_field.dart @@ -295,7 +295,8 @@ class _ReactiveTextFieldState @override void dispose() { - if (widget.textController == null) { + final currentWidget = widget as ReactiveTextField; + if (currentWidget._textController == null) { _textController.dispose(); } super.dispose(); From ba472bb615ffd646381c28beb57329d674fbd44f Mon Sep 17 00:00:00 2001 From: Joan Pablo Date: Fri, 29 Mar 2024 20:54:45 -0400 Subject: [PATCH 09/10] Modify Validators.number - Validators.number now validate negative numbers - Validators.number now validates decimal numbers --- CHANGELOG.md | 5 +- lib/src/validators/credit_card_validator.dart | 4 +- lib/src/validators/number_validator.dart | 90 +++++++++++++++++-- .../validators/number_validator_error.dart | 6 ++ lib/src/validators/validators.dart | 46 ++++++---- .../validators/compose_validators_test.dart | 2 +- .../src/validators/number_validator_test.dart | 51 ++++++++++- 7 files changed, 175 insertions(+), 29 deletions(-) create mode 100644 lib/src/validators/number_validator_error.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 0beb7c1..a731f1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,10 @@ ## Breaking changes -- Remove `onWillPop` from `ReactiveForm` and `ReactiveFormBuilder` widgets. +- Removed deprecated `onWillPop` from `ReactiveForm` and `ReactiveFormBuilder` widgets. +It was replaced with the `PopScope` widget. +- `Validators.number` allows now to define negative numbers and decimal numbers with the addition +of two optional arguments `allowNegatives` and `allowedDecimals`. ## Features diff --git a/lib/src/validators/credit_card_validator.dart b/lib/src/validators/credit_card_validator.dart index 4d6c788..a77ef80 100644 --- a/lib/src/validators/credit_card_validator.dart +++ b/lib/src/validators/credit_card_validator.dart @@ -7,6 +7,8 @@ import 'package:reactive_forms/reactive_forms.dart'; /// A credit card validator that validates that the control's value is a valid /// credit card. class CreditCardValidator extends Validator { + static final RegExp onlyNumbersRegex = RegExp(r'^[0-9]+$'); + const CreditCardValidator() : super(); @override @@ -18,7 +20,7 @@ class CreditCardValidator extends Validator { } final cardNumber = control.value.toString().replaceAll(' ', ''); - final isNumber = NumberValidator.numberRegex.hasMatch(cardNumber); + final isNumber = onlyNumbersRegex.hasMatch(cardNumber); return isNumber && cardNumber.length >= 13 && diff --git a/lib/src/validators/number_validator.dart b/lib/src/validators/number_validator.dart index 0332a30..2dd322d 100644 --- a/lib/src/validators/number_validator.dart +++ b/lib/src/validators/number_validator.dart @@ -3,19 +3,97 @@ // found in the LICENSE file. import 'package:reactive_forms/reactive_forms.dart'; +import 'package:reactive_forms/src/validators/number_validator_error.dart'; /// Validator that validates if control's value is a numeric value. class NumberValidator extends Validator { /// The regex expression of a numeric string value. - static final RegExp numberRegex = RegExp(r'^-?[0-9]+$'); + static final RegExp notNumbersRegex = RegExp(r'[^0-9.]'); - const NumberValidator() : super(); + /// The allowed number of decimal places in the validated string. + /// + /// This value specifies the maximum number of digits allowed after the + /// decimal point in the validated string. Defaults to 0 (no decimals). + final int allowedDecimals; + + /// Whether the validator allows negative numbers. + /// + /// If set to `true`, the validator will accept strings representing + /// negative numbers (prefixed with a '-'). Defaults to `true`. + final bool allowNegatives; + + /// Creates a new NumberValidator instance to validate strings representing numbers. + /// + /// [allowedDecimals] (optional): The allowed number of decimal places. Defaults to 0. + /// [allowNegatives] (optional): Whether to allow negative numbers. Defaults to true. + const NumberValidator({ + this.allowedDecimals = 0, + this.allowNegatives = true, + }) : super(); @override Map? validate(AbstractControl control) { - return (control.value == null) || - !numberRegex.hasMatch(control.value.toString()) - ? {ValidationMessage.number: true} - : null; + if (control.value == null) { + return { + ValidationMessage.number: NumberValidatorError.nullValue, + }; + } + + // Check for leading/trailing spaces + final numberString = control.value.toString().trim(); + + // Check for empty string + if (numberString.isEmpty) { + return { + ValidationMessage.number: NumberValidatorError.invalidNumber, + }; + } + + // Check for negative sign, if allowed + final hasNegativeSign = numberString.startsWith('-'); + if (hasNegativeSign && !allowNegatives) { + return { + ValidationMessage.number: NumberValidatorError.unsignedNumber, + }; + } + + // Remove the negative sign, if present, for further validation + final unsignedNumberString = + hasNegativeSign ? numberString.substring(1) : numberString; + + // Check for valid decimal positions + if (!_validateNumberDecimals(allowedDecimals, unsignedNumberString)) { + return { + ValidationMessage.number: NumberValidatorError.invalidDecimals, + }; + } + + // Check for valid numeric characters using a regular expression + if (unsignedNumberString.contains(notNumbersRegex)) { + return { + ValidationMessage.number: NumberValidatorError.invalidNumber, + }; + } + + // No errors, the control value is a valid number + return null; + } + + bool _validateNumberDecimals(int allowedDecimals, String numberString) { + // Split the number string at the decimal point + final parts = numberString.split('.'); + + if (parts.length > 2) { + // More than one decimal point, invalid format + return false; + } + + if (parts.length == 1) { + // No decimal part, validate it has 0 decimals + return allowedDecimals == 0; + } + + // Check if the decimal part length is equal to the allowed decimals + return parts[1].length == allowedDecimals; } } diff --git a/lib/src/validators/number_validator_error.dart b/lib/src/validators/number_validator_error.dart new file mode 100644 index 0000000..5d75643 --- /dev/null +++ b/lib/src/validators/number_validator_error.dart @@ -0,0 +1,6 @@ +class NumberValidatorError { + static const String nullValue = 'nullValue'; + static const String invalidDecimals = 'invalidDecimals'; + static const String unsignedNumber = 'unsignedNumber'; + static const String invalidNumber = 'invalidNumber'; +} diff --git a/lib/src/validators/validators.dart b/lib/src/validators/validators.dart index 49a918c..e587b4b 100644 --- a/lib/src/validators/validators.dart +++ b/lib/src/validators/validators.dart @@ -7,71 +7,81 @@ import 'package:reactive_forms/reactive_forms.dart'; /// Provides a set of built-in validators that can be used by form controls, /// form groups, and form arrays. class Validators { - /// Gets a validator that delegates the validation to the external [validator] + /// Creates a validator that delegates the validation to the external [validator] /// function. static Validator delegate(ValidatorFunction validator) => DelegateValidator(validator); - /// Gets a validator that delegates the validation to the external + /// Creates a validator that delegates the validation to the external /// asynchronous [validator] function. static AsyncValidator delegateAsync( AsyncValidatorFunction validator) => DelegateAsyncValidator(validator); - /// Gets a validator that requires the control have a non-empty value. + /// Creates a validator that requires the control have a non-empty value. static Validator get required => const RequiredValidator(); - /// Gets a validator that requires the control's value be true. + /// Creates a validator that requires the control's value be true. /// This validator is commonly used for required checkboxes. static Validator get requiredTrue => const EqualsValidator( true, validationMessage: ValidationMessage.requiredTrue, ); - /// Gets a validator that requires the control's value pass an email + /// Creates a validator that requires the control's value pass an email /// validation test. static Validator get email => const EmailValidator(); - /// Gets a validator that validates if control's value is a numeric value. - static Validator get number => const NumberValidator(); + /// Creates a validator function that checks if a control's value is a valid number. + /// + /// [allowedDecimals] (optional): The allowed number of decimal places. Defaults to 0. + /// [allowNegatives] (optional): Whether to allow negative numbers. Defaults to true. + static Validator number({ + int allowedDecimals = 0, + bool allowNegatives = true, + }) => + NumberValidator( + allowedDecimals: allowedDecimals, + allowNegatives: allowNegatives, + ); - /// Gets a validator that validates if the control's value is a valid + /// Creates a validator that validates if the control's value is a valid /// credit card number. static Validator get creditCard => const CreditCardValidator(); - /// Gets a validator that requires the control's value to be equals to + /// Creates a validator that requires the control's value to be equals to /// argument [value]. /// /// The argument [value] must not be null. static Validator equals(T value) => EqualsValidator(value); - /// Gets a validator that requires the control's value to be greater than + /// Creates a validator that requires the control's value to be greater than /// or equal to [min] value. /// /// The argument [min] must not be null. static Validator min(T min) => MinValidator(min); - /// Gets a validator that requires the control's value to be less than + /// Creates a validator that requires the control's value to be less than /// or equal to [max] value. /// /// The argument [max] must not be null. static Validator max(T max) => MaxValidator(max); - /// Gets a validator that requires the length of the control's value to be + /// Creates a validator that requires the length of the control's value to be /// greater than or equal to the provided [minLength]. /// /// The argument [minLength] argument must not be null. static Validator minLength(int minLength) => MinLengthValidator(minLength); - /// Gets a validator that requires the length of the control's value to be + /// Creates a validator that requires the length of the control's value to be /// less than or equal to the provided [maxLength]. /// /// The argument [maxLength] must not be null. static Validator maxLength(int maxLength) => MaxLengthValidator(maxLength); - /// Gets a validator that requires the control's value to match a + /// Creates a validator that requires the control's value to match a /// regex [pattern]. /// /// The argument [pattern] must not be null. @@ -145,7 +155,7 @@ class Validators { return PatternValidator(evaluator, validationMessage: validationMessage); } - /// Gets a [FormGroup] validator that checks the controls [controlName] and + /// Creates a [FormGroup] validator that checks the controls [controlName] and /// [matchingControlName] have the same values. /// /// The arguments [controlName] and [matchingControlName] must not be null. @@ -208,7 +218,7 @@ class Validators { return MustMatchValidator(controlName, matchingControlName, markAsDirty); } - /// Gets a [FormGroup] validator that compares two controls in the group. + /// Creates a [FormGroup] validator that compares two controls in the group. /// /// The arguments [controlName], [compareControlName] and [compareOption] /// must not be null. @@ -251,7 +261,7 @@ class Validators { return ComposeOrValidator(validators); } - /// Gets a validator that requires the control's value contains all the + /// Creates a validator that requires the control's value contains all the /// values specified in [values]. /// /// The argument [values] must not be null. @@ -277,7 +287,7 @@ class Validators { return ContainsValidator(values); } - /// Gets a validator that requires any element of the control's iterable value + /// Creates a validator that requires any element of the control's iterable value /// satisfies [test]. /// /// Checks every element in control's value in iteration order, and marks diff --git a/test/src/validators/compose_validators_test.dart b/test/src/validators/compose_validators_test.dart index 77ae254..0d4c3bd 100644 --- a/test/src/validators/compose_validators_test.dart +++ b/test/src/validators/compose_validators_test.dart @@ -114,7 +114,7 @@ void main() { Validators.compose([ Validators.minLength(10), Validators.maxLength(10), - Validators.number, + Validators.number(), ]), ]), ], diff --git a/test/src/validators/number_validator_test.dart b/test/src/validators/number_validator_test.dart index f699915..d6354dd 100644 --- a/test/src/validators/number_validator_test.dart +++ b/test/src/validators/number_validator_test.dart @@ -1,10 +1,11 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:reactive_forms/reactive_forms.dart'; +import 'package:reactive_forms/src/validators/number_validator_error.dart'; void main() { group('Number Validator Tests', () { test('FormControl invalid if not a number', () { - final control = FormControl(validators: [Validators.number]); + final control = FormControl(validators: [Validators.number()]); control.value = 'hello'; @@ -13,11 +14,57 @@ void main() { }); test('FormControl valid if a number', () { - final control = FormControl(validators: [Validators.number]); + final control = FormControl(validators: [Validators.number()]); control.value = '10'; expect(control.valid, true); }); + + test('FormControl negative number', () { + final control = FormControl(validators: [Validators.number()]); + + control.value = '-10'; + + expect(control.valid, true); + }); + + test('FormControl decimal numbers', () { + final control = FormControl( + validators: [Validators.number(allowedDecimals: 3)], + ); + + control.value = '10.123'; + + expect(control.valid, true); + }); + + test('FormControl invalid decimal number with default allowedDecimals', () { + final control = FormControl( + validators: [Validators.number()], + ); + + control.value = '10.123'; + + expect(control.valid, false); + expect( + control.errors[ValidationMessage.number], + NumberValidatorError.invalidDecimals, + ); + }); + + test('FormControl invalid decimal numbers', () { + final control = FormControl( + validators: [Validators.number(allowedDecimals: 2)], + ); + + control.value = '10.123'; + + expect(control.valid, false); + expect( + control.errors[ValidationMessage.number], + NumberValidatorError.invalidDecimals, + ); + }); }); } From c5f3b8f10603ac7cdd184c8192c7225d50de6067 Mon Sep 17 00:00:00 2001 From: Joan Pablo Date: Fri, 29 Mar 2024 21:07:51 -0400 Subject: [PATCH 10/10] Release 17.0.0 --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 631cb8a..b9eaa6a 100644 --- a/README.md +++ b/README.md @@ -64,8 +64,8 @@ samples, guidance on mobile development, and a full API reference. ## Minimum Requirements -- Dart SDK: >=3.0.0 <4.0.0 -- Flutter: >=3.10.0 +- Dart SDK: >=3.2.0 <4.0.0 +- Flutter: >=3.16.0 > For using **Reactive Forms** in projects below Flutter 2.8.0 please use the version <= 10.7.0 of > **Reactive Forms**. @@ -88,7 +88,7 @@ dependencies: flutter: sdk: flutter - reactive_forms: ^16.1.1 + reactive_forms: ^17.0.0 ``` Then run the command `flutter packages get` on the console.