Skip to content

Commit

Permalink
Merge pull request #1465 from flutter-form-builder-ecosystem/feature/#…
Browse files Browse the repository at this point in the history
…1456-remove-deprecated-code

feat: #1456-remove-deprecated-code
  • Loading branch information
deandreamatias authored Jan 15, 2025
2 parents 7754009 + 8bbfdbf commit 8c6641f
Show file tree
Hide file tree
Showing 21 changed files with 314 additions and 47 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/base.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ jobs:
- name: Install dependencies
run: flutter pub get
- name: Format code
run: dart format --set-exit-if-changed .
run: dart format --set-exit-if-changed lib/ test/ example/
- name: Analyze static code
run: flutter analyze
- name: Run tests
run: flutter test --coverage
- name: Run fixes tests
run: dart fix --compare-to-golden test_fixes/
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
Expand Down
4 changes: 4 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
include: package:flutter_lints/flutter.yaml

analyzer:
exclude:
- "test_fixes/**"
2 changes: 1 addition & 1 deletion example/lib/minimal_code_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class _ExamplePageState extends State<_ExamplePage> {
key: _formKey,
child: Column(
children: [
FormBuilderFilterChip<String>(
FormBuilderFilterChips<String>(
decoration: const InputDecoration(
labelText: 'The language of my people',
enabled: false,
Expand Down
4 changes: 2 additions & 2 deletions example/lib/sources/complete_form.dart
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ class _CompleteFormState extends State<CompleteForm> {
FormBuilderValidators.maxLength(3),
]),
),
FormBuilderFilterChip<String>(
FormBuilderFilterChips<String>(
autovalidateMode: AutovalidateMode.onUserInteraction,
decoration: const InputDecoration(
labelText: 'The language of my people'),
Expand Down Expand Up @@ -286,7 +286,7 @@ class _CompleteFormState extends State<CompleteForm> {
FormBuilderValidators.maxLength(3),
]),
),
FormBuilderChoiceChip<String>(
FormBuilderChoiceChips<String>(
autovalidateMode: AutovalidateMode.onUserInteraction,
decoration: const InputDecoration(
labelText:
Expand Down
45 changes: 45 additions & 0 deletions lib/fix_data.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
version: 1
transforms:
- title: 'Remove deprecated maxChips property on FormBuilderFilterChip'
date: 2025-01-15
element:
uris: [ 'flutter_form_builder.dart' ]
constructor: ''
inClass: 'FormBuilderFilterChip'
changes:
- kind: 'removeParameter'
name: 'maxChips'
- title: 'Remove deprecated resetIcon property on FormBuilderDateTimePicker'
date: 2025-01-15
element:
uris: [ 'flutter_form_builder.dart' ]
constructor: ''
inClass: 'FormBuilderDateTimePicker'
changes:
- kind: 'removeParameter'
name: 'resetIcon'
- title: 'Remove deprecated onPopInvoked property on FormBuilder'
date: 2025-01-15
element:
uris: [ 'flutter_form_builder.dart' ]
constructor: ''
inClass: 'FormBuilder'
changes:
- kind: 'removeParameter'
name: 'onPopInvoked'
- title: 'Rename FormBuilderChoiceChip to be plural'
date: 2025-01-15
element:
uris: [ 'flutter_form_builder.dart' ]
class: 'FormBuilderChoiceChip'
changes:
- kind: 'rename'
newName: 'FormBuilderChoiceChips'
- title: 'Rename FormBuilderFilterChip to be plural'
date: 2025-01-15
element:
uris: [ 'flutter_form_builder.dart' ]
class: 'FormBuilderFilterChip'
changes:
- kind: 'rename'
newName: 'FormBuilderFilterChips'
1 change: 1 addition & 0 deletions lib/src/extensions/generic_validator.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
extension GenericValidator<T> on T? {
/// Check if the value is empty in a generic way
bool emptyValidator() {
if (this == null) return true;
if (this is Iterable) return (this as Iterable).isEmpty;
Expand Down
8 changes: 4 additions & 4 deletions lib/src/fields/form_builder_choice_chips.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';

/// A list of `Chip`s that acts like radio buttons
class FormBuilderChoiceChip<T> extends FormBuilderFieldDecoration<T> {
class FormBuilderChoiceChips<T> extends FormBuilderFieldDecoration<T> {
/// The list of items the user can select.
final List<FormBuilderChipOption<T>> options;

Expand Down Expand Up @@ -344,7 +344,7 @@ class FormBuilderChoiceChip<T> extends FormBuilderFieldDecoration<T> {
final String? tooltip;

/// Creates a list of `Chip`s that acts like radio buttons
FormBuilderChoiceChip({
FormBuilderChoiceChips({
super.autovalidateMode = AutovalidateMode.disabled,
super.enabled,
super.focusNode,
Expand Down Expand Up @@ -457,12 +457,12 @@ class FormBuilderChoiceChip<T> extends FormBuilderFieldDecoration<T> {
});

@override
FormBuilderFieldDecorationState<FormBuilderChoiceChip<T>, T> createState() =>
FormBuilderFieldDecorationState<FormBuilderChoiceChips<T>, T> createState() =>
_FormBuilderChoiceChipState<T>();
}

class _FormBuilderChoiceChipState<T>
extends FormBuilderFieldDecorationState<FormBuilderChoiceChip<T>, T> {
extends FormBuilderFieldDecorationState<FormBuilderChoiceChips<T>, T> {
void handleFocusChange() {
setState(() {});
}
Expand Down
5 changes: 0 additions & 5 deletions lib/src/fields/form_builder_date_time_picker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ class FormBuilderDateTimePicker extends FormBuilderFieldDecoration<DateTime> {
/// to noon. Explicitly set this to `null` to use the current time.
final TimeOfDay initialTime;

@Deprecated(
'This property is no used anymore. Please use decoration.suffixIcon to set your desired icon')
final Widget? resetIcon;

/// Called when an enclosing form is saved. The value passed will be `null`
/// if [format] fails to parse the text.
// final FormFieldSetter<DateTime> onSaved;
Expand Down Expand Up @@ -146,7 +142,6 @@ class FormBuilderDateTimePicker extends FormBuilderFieldDecoration<DateTime> {
this.scrollPadding = const EdgeInsets.all(20.0),
this.cursorWidth = 2.0,
this.enableInteractiveSelection = true,
this.resetIcon = const Icon(Icons.close),
this.initialTime = const TimeOfDay(hour: 12, minute: 0),
this.keyboardType,
this.textAlign = TextAlign.start,
Expand Down
10 changes: 5 additions & 5 deletions lib/src/fields/form_builder_filter_chips.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';

/// Field with chips that acts like a list checkboxes.
class FormBuilderFilterChip<T> extends FormBuilderFieldDecoration<List<T>> {
class FormBuilderFilterChips<T> extends FormBuilderFieldDecoration<List<T>> {
//TODO: Add documentation
final Color? backgroundColor;
final Color? disabledColor;
Expand Down Expand Up @@ -35,7 +35,7 @@ class FormBuilderFilterChip<T> extends FormBuilderFieldDecoration<List<T>> {
final ShapeBorder avatarBorder;

/// Creates field with chips that acts like a list checkboxes.
FormBuilderFilterChip({
FormBuilderFilterChips({
super.autovalidateMode = AutovalidateMode.disabled,
super.enabled,
super.focusNode,
Expand All @@ -59,7 +59,7 @@ class FormBuilderFilterChip<T> extends FormBuilderFieldDecoration<List<T>> {
this.labelPadding,
this.labelStyle,
this.materialTapTargetSize,
this.maxChips,
@Deprecated('Useless property. Please remove it.') this.maxChips,
this.padding,
this.pressElevation,
this.runAlignment = WrapAlignment.start,
Expand Down Expand Up @@ -143,9 +143,9 @@ class FormBuilderFilterChip<T> extends FormBuilderFieldDecoration<List<T>> {
);

@override
FormBuilderFieldDecorationState<FormBuilderFilterChip<T>, List<T>>
FormBuilderFieldDecorationState<FormBuilderFilterChips<T>, List<T>>
createState() => _FormBuilderFilterChipState<T>();
}

class _FormBuilderFilterChipState<T> extends FormBuilderFieldDecorationState<
FormBuilderFilterChip<T>, List<T>> {}
FormBuilderFilterChips<T>, List<T>> {}
5 changes: 5 additions & 0 deletions lib/src/fields/form_builder_text_field.dart
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,11 @@ class FormBuilderTextField extends FormBuilderFieldDecoration<String> {
this.contentInsertionConfiguration,
this.spellCheckConfiguration,
this.clipBehavior = Clip.hardEdge,
@Deprecated(
'This property will be removed in the next Flutter stable versions. '
'Use FocusNode.canRequestFocus instead. '
'Ref: https://docs.flutter.dev/release/breaking-changes/can-request-focus',
)
this.canRequestFocus = true,
this.cursorErrorColor,
this.cursorOpacityAnimates,
Expand Down
29 changes: 8 additions & 21 deletions lib/src/form_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ class FormBuilder extends StatefulWidget {
/// will rebuild.
final VoidCallback? onChanged;

/// DEPRECATED: Use [onPopInvokedWithResult] instead.
final void Function(bool)? onPopInvoked;

/// {@macro flutter.widgets.navigator.onPopInvokedWithResult}
///
/// {@tool dartpad}
Expand Down Expand Up @@ -105,11 +102,6 @@ class FormBuilder extends StatefulWidget {
required this.child,
this.onChanged,
this.autovalidateMode,
@Deprecated(
'Use onPopInvokedWithResult instead. '
'This feature was deprecated after v3.22.0-12.0.pre.',
)
this.onPopInvoked,
this.onPopInvokedWithResult,
this.initialValue = const <String, dynamic>{},
this.skipDisabled = false,
Expand Down Expand Up @@ -143,6 +135,7 @@ class FormBuilderState extends State<FormBuilder> {
/// Only used to internal logic
bool get focusOnInvalid => _focusOnInvalid;

/// Get if form is enabled
bool get enabled => widget.enabled;

/// Verify if all fields on form are valid.
Expand Down Expand Up @@ -171,6 +164,7 @@ class FormBuilderState extends State<FormBuilder> {
/// Get all fields of form.
FormBuilderFields get fields => _fields;

/// Get all fields values of form.
Map<String, dynamic> get instantValue => Map<String, dynamic>.unmodifiable(
_instantValue.map(
(key, value) => MapEntry(
Expand Down Expand Up @@ -204,15 +198,18 @@ class FormBuilderState extends State<FormBuilder> {
initialValue[name];
}

/// Get a field value by name
void setInternalFieldValue<T>(String name, T? value) {
_instantValue[name] = value;
widget.onChanged?.call();
}

/// Remove a field value by name
void removeInternalFieldValue(String name) {
_instantValue.remove(name);
}

/// Register a field on form
void registerField(String name, FormBuilderFieldState field) {
// Each field must have a unique name. Ideally we could simply:
// assert(!_fields.containsKey(name));
Expand Down Expand Up @@ -242,6 +239,7 @@ class FormBuilderState extends State<FormBuilder> {
);
}

/// Unregister a field on form
void unregisterField(String name, FormBuilderFieldState field) {
assert(
_fields.containsKey(name),
Expand Down Expand Up @@ -270,23 +268,14 @@ class FormBuilderState extends State<FormBuilder> {
}
}

/// Save form values
void save() {
_formKey.currentState!.save();
// Copy values from instant to saved
_savedValue.clear();
_savedValue.addAll(_instantValue);
}

@Deprecated(
'Will be remove to avoid redundancy. Use fields[name]?.invalidate(errorText) instead')
void invalidateField({required String name, String? errorText}) =>
fields[name]?.invalidate(errorText ?? '');

@Deprecated(
'Will be remove to avoid redundancy. Use fields.first.invalidate(errorText) instead')
void invalidateFirstField({required String errorText}) =>
fields.values.first.invalidate(errorText);

/// Validate all fields of form
///
/// Focus to first invalid field when has field invalid, if [focusOnInvalid] is `true`.
Expand Down Expand Up @@ -343,7 +332,7 @@ class FormBuilderState extends State<FormBuilder> {
);
}

/// Reset form to `initialValue`
/// Reset form to `initialValue` set on FormBuilder or on each field.
void reset() {
_formKey.currentState?.reset();
}
Expand Down Expand Up @@ -376,8 +365,6 @@ class FormBuilderState extends State<FormBuilder> {
key: _formKey,
autovalidateMode: widget.autovalidateMode,
onPopInvokedWithResult: widget.onPopInvokedWithResult,
// ignore: deprecated_member_use
onPopInvoked: widget.onPopInvoked,
canPop: widget.canPop,
// `onChanged` is called during setInternalFieldValue else will be called early
child: _FormBuilderScope(
Expand Down
26 changes: 26 additions & 0 deletions lib/src/form_builder_field.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,17 @@ class FormBuilderFieldState<F extends FormBuilderField<T>, T>
FormBuilderState? _formBuilderState;
bool _touched = false;
bool _dirty = false;

/// The focus node that is used to focus this field.
late FocusNode effectiveFocusNode;

/// The focus attachment for the [effectiveFocusNode].
FocusAttachment? focusAttachment;

@override
F get widget => super.widget as F;

/// Returns the parent [FormBuilderState] if it exists.
FormBuilderState? get formState => _formBuilderState;

/// Returns the initial value, which may be declared at the field, or by the
Expand All @@ -91,18 +96,33 @@ class FormBuilderFieldState<F extends FormBuilderField<T>, T>
widget.valueTransformer == null ? value : widget.valueTransformer!(value);

@override

/// Returns the current error text,
/// which may be a validation error or a custom error text.
String? get errorText => super.errorText ?? _customErrorText;

@override

/// Returns `true` if the field has an error or has a custom error text.
bool get hasError => super.hasError || errorText != null;

@override

/// Returns `true` if the field is valid and has no custom error text.
bool get isValid => super.isValid && _customErrorText == null;

/// Returns `true` if the field is valid.
bool get valueIsValid => super.isValid;

/// Returns `true` if the field has an error.
bool get valueHasError => super.hasError;

/// Returns `true` if the field is enabled and the parent FormBuilder is enabled.
bool get enabled => widget.enabled && (_formBuilderState?.enabled ?? true);

/// Returns `true` if the field is read only.
///
/// See [FormBuilder.skipDisabled] for more information.
bool get readOnly => !(_formBuilderState?.widget.skipDisabled ?? false);

/// Will be true if the field is dirty
Expand Down Expand Up @@ -199,6 +219,10 @@ class FormBuilderFieldState<F extends FormBuilderField<T>, T>
}

@override

/// Reset field value to initial value
///
/// Also reset custom error text if exists, and set [isDirty] to `false`.
void reset() {
super.reset();
didChange(initialValue);
Expand Down Expand Up @@ -276,10 +300,12 @@ class FormBuilderFieldState<F extends FormBuilderField<T>, T>
);
}

/// Focus field
void focus() {
FocusScope.of(context).requestFocus(effectiveFocusNode);
}

/// Scroll to show field
void ensureScrollableVisibility() {
Scrollable.ensureVisible(context);
}
Expand Down
1 change: 1 addition & 0 deletions lib/src/form_builder_field_decoration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class FormBuilderFieldDecorationState<F extends FormBuilderFieldDecoration<T>,
@override
F get widget => super.widget as F;

/// Get the decoration with the current state
InputDecoration get decoration => widget.decoration.copyWith(
// Read only allow show error to support property skipDisabled
errorText: widget.enabled || readOnly
Expand Down
Loading

0 comments on commit 8c6641f

Please sign in to comment.