Skip to content

Commit 7754009

Browse files
Merge pull request #1464 from flutter-form-builder-ecosystem/bugfix/#1455-enabled-decoration
feat: #1455 improve input decoration enabled property
2 parents ec7543b + 284faa1 commit 7754009

File tree

2 files changed

+197
-3
lines changed

2 files changed

+197
-3
lines changed

lib/src/form_builder_field_decoration.dart

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import 'package:flutter_form_builder/flutter_form_builder.dart';
66
///
77
/// This class override `decoration.enable` with [enable] value
88
class FormBuilderFieldDecoration<T> extends FormBuilderField<T> {
9-
const FormBuilderFieldDecoration({
9+
FormBuilderFieldDecoration({
1010
super.key,
1111
super.onSaved,
1212
super.initialValue,
@@ -21,7 +21,12 @@ class FormBuilderFieldDecoration<T> extends FormBuilderField<T> {
2121
super.focusNode,
2222
required super.builder,
2323
this.decoration = const InputDecoration(),
24-
});
24+
}) : assert(
25+
decoration.enabled == enabled ||
26+
(enabled == false && decoration.enabled),
27+
'''decoration.enabled will be used instead of enabled FormBuilderField property.
28+
This will create conflicts and unexpected behaviors on focus, errorText, and other properties.
29+
Please, to enable or disable the field, use the enabled property of FormBuilderField.''');
2530
final InputDecoration decoration;
2631

2732
@override
@@ -40,7 +45,9 @@ class FormBuilderFieldDecorationState<F extends FormBuilderFieldDecoration<T>,
4045
errorText: widget.enabled || readOnly
4146
? widget.decoration.errorText ?? errorText
4247
: null,
43-
enabled: widget.enabled,
48+
enabled: widget.decoration.enabled
49+
? widget.enabled
50+
: widget.decoration.enabled,
4451
);
4552

4653
@override
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
import 'package:flutter_test/flutter_test.dart';
2+
import 'package:flutter/material.dart';
3+
import 'package:flutter_form_builder/flutter_form_builder.dart';
4+
5+
import '../form_builder_tester.dart';
6+
7+
void main() {
8+
group('FormBuilderFieldDecoration -', () {
9+
testWidgets('when change the error text then the field should be invalid',
10+
(WidgetTester tester) async {
11+
final decorationFieldKey = GlobalKey<FormBuilderFieldDecorationState>();
12+
const name = 'testField';
13+
const errorTextField = 'error text field';
14+
final widget = FormBuilderFieldDecoration<String>(
15+
key: decorationFieldKey,
16+
name: name,
17+
builder: (FormFieldState<String?> field) {
18+
return InputDecorator(
19+
decoration: (field as FormBuilderFieldDecorationState).decoration,
20+
child: TextField(
21+
onChanged: (value) {
22+
field.didChange(value);
23+
},
24+
),
25+
);
26+
},
27+
);
28+
29+
await tester.pumpWidget(buildTestableFieldWidget(widget));
30+
31+
// Initially, the field should be valid
32+
expect(decorationFieldKey.currentState?.isValid, isTrue);
33+
34+
decorationFieldKey.currentState?.invalidate(errorTextField);
35+
36+
// The field should be invalid
37+
expect(decorationFieldKey.currentState?.isValid, isFalse);
38+
39+
// Clear the error
40+
decorationFieldKey.currentState?.reset();
41+
42+
// The field should be valid again
43+
expect(decorationFieldKey.currentState?.isValid, isTrue);
44+
});
45+
group('decoration enabled -', () {
46+
testWidgets('when change the error text then the field should be invalid',
47+
(WidgetTester tester) async {
48+
final decorationFieldKey = GlobalKey<FormBuilderFieldDecorationState>();
49+
const name = 'testField';
50+
const errorTextField = 'error text field';
51+
final widget = FormBuilderFieldDecoration<String>(
52+
key: decorationFieldKey,
53+
name: name,
54+
builder: (FormFieldState<String?> field) {
55+
return InputDecorator(
56+
decoration: (field as FormBuilderFieldDecorationState).decoration,
57+
child: TextField(
58+
onChanged: (value) {
59+
field.didChange(value);
60+
},
61+
),
62+
);
63+
},
64+
);
65+
66+
await tester.pumpWidget(buildTestableFieldWidget(widget));
67+
68+
// Initially, the field should be valid
69+
expect(decorationFieldKey.currentState?.isValid, isTrue);
70+
71+
decorationFieldKey.currentState?.invalidate(errorTextField);
72+
73+
// The field should be invalid
74+
expect(decorationFieldKey.currentState?.isValid, isFalse);
75+
76+
// Clear the error
77+
decorationFieldKey.currentState?.reset();
78+
79+
// The field should be valid again
80+
expect(decorationFieldKey.currentState?.isValid, isTrue);
81+
});
82+
test(
83+
'when enable property on decoration is false and enabled true, then throw an assert',
84+
() async {
85+
final decorationFieldKey = GlobalKey<FormBuilderFieldDecorationState>();
86+
const name = 'testField';
87+
88+
expect(
89+
() => FormBuilderFieldDecoration<String>(
90+
key: decorationFieldKey,
91+
name: name,
92+
decoration: const InputDecoration(enabled: false),
93+
builder: (FormFieldState<String?> field) {
94+
return InputDecorator(
95+
decoration:
96+
(field as FormBuilderFieldDecorationState).decoration,
97+
child: TextField(
98+
onChanged: (value) {
99+
field.didChange(value);
100+
},
101+
),
102+
);
103+
},
104+
),
105+
throwsAssertionError,
106+
);
107+
});
108+
test(
109+
'when enable property on decoration is false and enable is false, then build normally',
110+
() async {
111+
final decorationFieldKey = GlobalKey<FormBuilderFieldDecorationState>();
112+
const name = 'testField';
113+
114+
expect(
115+
() => FormBuilderFieldDecoration<String>(
116+
key: decorationFieldKey,
117+
name: name,
118+
decoration: const InputDecoration(enabled: false),
119+
enabled: false,
120+
builder: (FormFieldState<String?> field) {
121+
return InputDecorator(
122+
decoration:
123+
(field as FormBuilderFieldDecorationState).decoration,
124+
child: TextField(
125+
onChanged: (value) {
126+
field.didChange(value);
127+
},
128+
),
129+
);
130+
},
131+
),
132+
returnsNormally,
133+
);
134+
});
135+
test('when decoration is default (enabled: true), then build normally',
136+
() async {
137+
final decorationFieldKey = GlobalKey<FormBuilderFieldDecorationState>();
138+
const name = 'testField';
139+
140+
expect(
141+
() => FormBuilderFieldDecoration<String>(
142+
key: decorationFieldKey,
143+
name: name,
144+
builder: (FormFieldState<String?> field) {
145+
return InputDecorator(
146+
decoration:
147+
(field as FormBuilderFieldDecorationState).decoration,
148+
child: TextField(
149+
onChanged: (value) {
150+
field.didChange(value);
151+
},
152+
),
153+
);
154+
},
155+
),
156+
returnsNormally,
157+
);
158+
});
159+
test(
160+
'when decoration is default (enabled: true) and enable false, then build normally',
161+
() async {
162+
final decorationFieldKey = GlobalKey<FormBuilderFieldDecorationState>();
163+
const name = 'testField';
164+
165+
expect(
166+
() => FormBuilderFieldDecoration<String>(
167+
key: decorationFieldKey,
168+
name: name,
169+
enabled: false,
170+
builder: (FormFieldState<String?> field) {
171+
return InputDecorator(
172+
decoration:
173+
(field as FormBuilderFieldDecorationState).decoration,
174+
child: TextField(
175+
onChanged: (value) {
176+
field.didChange(value);
177+
},
178+
),
179+
);
180+
},
181+
),
182+
returnsNormally,
183+
);
184+
});
185+
});
186+
});
187+
}

0 commit comments

Comments
 (0)