Skip to content

Commit

Permalink
Merge pull request #1464 from flutter-form-builder-ecosystem/bugfix/#…
Browse files Browse the repository at this point in the history
…1455-enabled-decoration

feat: #1455 improve input decoration enabled property
  • Loading branch information
deandreamatias authored Jan 14, 2025
2 parents ec7543b + 284faa1 commit 7754009
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 3 deletions.
13 changes: 10 additions & 3 deletions lib/src/form_builder_field_decoration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import 'package:flutter_form_builder/flutter_form_builder.dart';
///
/// This class override `decoration.enable` with [enable] value
class FormBuilderFieldDecoration<T> extends FormBuilderField<T> {
const FormBuilderFieldDecoration({
FormBuilderFieldDecoration({
super.key,
super.onSaved,
super.initialValue,
Expand All @@ -21,7 +21,12 @@ class FormBuilderFieldDecoration<T> extends FormBuilderField<T> {
super.focusNode,
required super.builder,
this.decoration = const InputDecoration(),
});
}) : assert(
decoration.enabled == enabled ||
(enabled == false && decoration.enabled),
'''decoration.enabled will be used instead of enabled FormBuilderField property.
This will create conflicts and unexpected behaviors on focus, errorText, and other properties.
Please, to enable or disable the field, use the enabled property of FormBuilderField.''');
final InputDecoration decoration;

@override
Expand All @@ -40,7 +45,9 @@ class FormBuilderFieldDecorationState<F extends FormBuilderFieldDecoration<T>,
errorText: widget.enabled || readOnly
? widget.decoration.errorText ?? errorText
: null,
enabled: widget.enabled,
enabled: widget.decoration.enabled
? widget.enabled
: widget.decoration.enabled,
);

@override
Expand Down
187 changes: 187 additions & 0 deletions test/src/form_builder_field_decoration_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';

import '../form_builder_tester.dart';

void main() {
group('FormBuilderFieldDecoration -', () {
testWidgets('when change the error text then the field should be invalid',
(WidgetTester tester) async {
final decorationFieldKey = GlobalKey<FormBuilderFieldDecorationState>();
const name = 'testField';
const errorTextField = 'error text field';
final widget = FormBuilderFieldDecoration<String>(
key: decorationFieldKey,
name: name,
builder: (FormFieldState<String?> field) {
return InputDecorator(
decoration: (field as FormBuilderFieldDecorationState).decoration,
child: TextField(
onChanged: (value) {
field.didChange(value);
},
),
);
},
);

await tester.pumpWidget(buildTestableFieldWidget(widget));

// Initially, the field should be valid
expect(decorationFieldKey.currentState?.isValid, isTrue);

decorationFieldKey.currentState?.invalidate(errorTextField);

// The field should be invalid
expect(decorationFieldKey.currentState?.isValid, isFalse);

// Clear the error
decorationFieldKey.currentState?.reset();

// The field should be valid again
expect(decorationFieldKey.currentState?.isValid, isTrue);
});
group('decoration enabled -', () {
testWidgets('when change the error text then the field should be invalid',
(WidgetTester tester) async {
final decorationFieldKey = GlobalKey<FormBuilderFieldDecorationState>();
const name = 'testField';
const errorTextField = 'error text field';
final widget = FormBuilderFieldDecoration<String>(
key: decorationFieldKey,
name: name,
builder: (FormFieldState<String?> field) {
return InputDecorator(
decoration: (field as FormBuilderFieldDecorationState).decoration,
child: TextField(
onChanged: (value) {
field.didChange(value);
},
),
);
},
);

await tester.pumpWidget(buildTestableFieldWidget(widget));

// Initially, the field should be valid
expect(decorationFieldKey.currentState?.isValid, isTrue);

decorationFieldKey.currentState?.invalidate(errorTextField);

// The field should be invalid
expect(decorationFieldKey.currentState?.isValid, isFalse);

// Clear the error
decorationFieldKey.currentState?.reset();

// The field should be valid again
expect(decorationFieldKey.currentState?.isValid, isTrue);
});
test(
'when enable property on decoration is false and enabled true, then throw an assert',
() async {
final decorationFieldKey = GlobalKey<FormBuilderFieldDecorationState>();
const name = 'testField';

expect(
() => FormBuilderFieldDecoration<String>(
key: decorationFieldKey,
name: name,
decoration: const InputDecoration(enabled: false),
builder: (FormFieldState<String?> field) {
return InputDecorator(
decoration:
(field as FormBuilderFieldDecorationState).decoration,
child: TextField(
onChanged: (value) {
field.didChange(value);
},
),
);
},
),
throwsAssertionError,
);
});
test(
'when enable property on decoration is false and enable is false, then build normally',
() async {
final decorationFieldKey = GlobalKey<FormBuilderFieldDecorationState>();
const name = 'testField';

expect(
() => FormBuilderFieldDecoration<String>(
key: decorationFieldKey,
name: name,
decoration: const InputDecoration(enabled: false),
enabled: false,
builder: (FormFieldState<String?> field) {
return InputDecorator(
decoration:
(field as FormBuilderFieldDecorationState).decoration,
child: TextField(
onChanged: (value) {
field.didChange(value);
},
),
);
},
),
returnsNormally,
);
});
test('when decoration is default (enabled: true), then build normally',
() async {
final decorationFieldKey = GlobalKey<FormBuilderFieldDecorationState>();
const name = 'testField';

expect(
() => FormBuilderFieldDecoration<String>(
key: decorationFieldKey,
name: name,
builder: (FormFieldState<String?> field) {
return InputDecorator(
decoration:
(field as FormBuilderFieldDecorationState).decoration,
child: TextField(
onChanged: (value) {
field.didChange(value);
},
),
);
},
),
returnsNormally,
);
});
test(
'when decoration is default (enabled: true) and enable false, then build normally',
() async {
final decorationFieldKey = GlobalKey<FormBuilderFieldDecorationState>();
const name = 'testField';

expect(
() => FormBuilderFieldDecoration<String>(
key: decorationFieldKey,
name: name,
enabled: false,
builder: (FormFieldState<String?> field) {
return InputDecorator(
decoration:
(field as FormBuilderFieldDecorationState).decoration,
child: TextField(
onChanged: (value) {
field.didChange(value);
},
),
);
},
),
returnsNormally,
);
});
});
});
}

0 comments on commit 7754009

Please sign in to comment.