Unverified Commit e972d5a3 authored by Fré Dumazy's avatar Fré Dumazy Committed by GitHub

Add hasInteractedByUser getter in FormField (#131539)

Adds a getter to access the value of the private `RestorableBool _hasInteractedByUser`.

*List which issues are fixed by this PR. You must list at least one issue.*
Fixes #131538
parent 685141bf
...@@ -423,6 +423,12 @@ class FormFieldState<T> extends State<FormField<T>> with RestorationMixin { ...@@ -423,6 +423,12 @@ class FormFieldState<T> extends State<FormField<T>> with RestorationMixin {
/// True if this field has any validation errors. /// True if this field has any validation errors.
bool get hasError => _errorText.value != null; bool get hasError => _errorText.value != null;
/// Returns true if the user has modified the value of this field.
///
/// This only updates to true once [didChange] has been called and resets to
/// false when [reset] is called.
bool get hasInteractedByUser => _hasInteractedByUser.value;
/// True if the current value is valid. /// True if the current value is valid.
/// ///
/// This will not set [errorText] or [hasError] and it will not update /// This will not set [errorText] or [hasError] and it will not update
......
...@@ -854,4 +854,90 @@ void main() { ...@@ -854,4 +854,90 @@ void main() {
expect(fieldValue, '123456'); expect(fieldValue, '123456');
expect(formKey.currentState!.validate(), isFalse); expect(formKey.currentState!.validate(), isFalse);
}); });
testWidgets('hasInteractedByUser returns false when the input has not changed', (WidgetTester tester) async {
final GlobalKey<FormFieldState<String>> fieldKey = GlobalKey<FormFieldState<String>>();
final Widget widget = MaterialApp(
home: MediaQuery(
data: const MediaQueryData(),
child: Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: Material(
child: TextFormField(
key: fieldKey,
),
),
),
),
),
);
await tester.pumpWidget(widget);
expect(fieldKey.currentState!.hasInteractedByUser, isFalse);
});
testWidgets('hasInteractedByUser returns true after the input has changed', (WidgetTester tester) async {
final GlobalKey<FormFieldState<String>> fieldKey = GlobalKey<FormFieldState<String>>();
final Widget widget = MaterialApp(
home: MediaQuery(
data: const MediaQueryData(),
child: Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: Material(
child: TextFormField(
key: fieldKey,
),
),
),
),
),
);
await tester.pumpWidget(widget);
// initially, the field has not been interacted with
expect(fieldKey.currentState!.hasInteractedByUser, isFalse);
// after entering text, the field has been interacted with
await tester.enterText(find.byType(TextFormField), 'foo');
expect(fieldKey.currentState!.hasInteractedByUser, isTrue);
});
testWidgets('hasInteractedByUser returns false after the field is reset', (WidgetTester tester) async {
final GlobalKey<FormFieldState<String>> fieldKey = GlobalKey<FormFieldState<String>>();
final Widget widget = MaterialApp(
home: MediaQuery(
data: const MediaQueryData(),
child: Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: Material(
child: TextFormField(
key: fieldKey,
),
),
),
),
),
);
await tester.pumpWidget(widget);
// initially, the field has not been interacted with
expect(fieldKey.currentState!.hasInteractedByUser, isFalse);
// after entering text, the field has been interacted with
await tester.enterText(find.byType(TextFormField), 'foo');
expect(fieldKey.currentState!.hasInteractedByUser, isTrue);
// after resetting the field, it has not been interacted with again
fieldKey.currentState!.reset();
expect(fieldKey.currentState!.hasInteractedByUser, isFalse);
});
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment