Added InputDecoration helperText, helperStyle (#10852)
This commit is contained in:
parent
b471a9cffc
commit
40db1e4bc6
@ -144,6 +144,7 @@ class TextFormFieldDemoState extends State<TextFormFieldDemo> {
|
|||||||
new TextFormField(
|
new TextFormField(
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
hintText: 'Tell us about yourself',
|
hintText: 'Tell us about yourself',
|
||||||
|
helperText: 'Keep it short, this is just a demo',
|
||||||
labelText: 'Life story',
|
labelText: 'Life story',
|
||||||
),
|
),
|
||||||
maxLines: 3,
|
maxLines: 3,
|
||||||
|
@ -31,6 +31,8 @@ class InputDecoration {
|
|||||||
this.icon,
|
this.icon,
|
||||||
this.labelText,
|
this.labelText,
|
||||||
this.labelStyle,
|
this.labelStyle,
|
||||||
|
this.helperText,
|
||||||
|
this.helperStyle,
|
||||||
this.hintText,
|
this.hintText,
|
||||||
this.hintStyle,
|
this.hintStyle,
|
||||||
this.errorText,
|
this.errorText,
|
||||||
@ -55,6 +57,8 @@ class InputDecoration {
|
|||||||
}) : icon = null,
|
}) : icon = null,
|
||||||
labelText = null,
|
labelText = null,
|
||||||
labelStyle = null,
|
labelStyle = null,
|
||||||
|
helperText = null,
|
||||||
|
helperStyle = null,
|
||||||
errorText = null,
|
errorText = null,
|
||||||
errorStyle = null,
|
errorStyle = null,
|
||||||
isDense = false,
|
isDense = false,
|
||||||
@ -93,6 +97,17 @@ class InputDecoration {
|
|||||||
/// input field and the current [Theme].
|
/// input field and the current [Theme].
|
||||||
final TextStyle labelStyle;
|
final TextStyle labelStyle;
|
||||||
|
|
||||||
|
/// Text that provides context about the field’s value, such as how the value
|
||||||
|
/// will be used.
|
||||||
|
///
|
||||||
|
/// If non-null, the text is displayed below the input field, in the same
|
||||||
|
/// location as [errorText]. If a non-null [errorText] value is specified then
|
||||||
|
/// the helper text is not shown.
|
||||||
|
final String helperText;
|
||||||
|
|
||||||
|
/// The style to use for the [helperText].
|
||||||
|
final TextStyle helperStyle;
|
||||||
|
|
||||||
/// Text that suggests what sort of input the field accepts.
|
/// Text that suggests what sort of input the field accepts.
|
||||||
///
|
///
|
||||||
/// Displayed on top of the input field (i.e., at the same location on the
|
/// Displayed on top of the input field (i.e., at the same location on the
|
||||||
@ -113,7 +128,7 @@ class InputDecoration {
|
|||||||
|
|
||||||
/// Text that appears below the input field.
|
/// Text that appears below the input field.
|
||||||
///
|
///
|
||||||
/// If non-null the divider, that appears below the input field is red.
|
/// If non-null, the divider that appears below the input field is red.
|
||||||
final String errorText;
|
final String errorText;
|
||||||
|
|
||||||
/// The style to use for the [errorText].
|
/// The style to use for the [errorText].
|
||||||
@ -171,6 +186,8 @@ class InputDecoration {
|
|||||||
Widget icon,
|
Widget icon,
|
||||||
String labelText,
|
String labelText,
|
||||||
TextStyle labelStyle,
|
TextStyle labelStyle,
|
||||||
|
String helperText,
|
||||||
|
TextStyle helperStyle,
|
||||||
String hintText,
|
String hintText,
|
||||||
TextStyle hintStyle,
|
TextStyle hintStyle,
|
||||||
String errorText,
|
String errorText,
|
||||||
@ -186,6 +203,8 @@ class InputDecoration {
|
|||||||
icon: icon ?? this.icon,
|
icon: icon ?? this.icon,
|
||||||
labelText: labelText ?? this.labelText,
|
labelText: labelText ?? this.labelText,
|
||||||
labelStyle: labelStyle ?? this.labelStyle,
|
labelStyle: labelStyle ?? this.labelStyle,
|
||||||
|
helperText: helperText ?? this.helperText,
|
||||||
|
helperStyle: helperStyle ?? this.helperStyle,
|
||||||
hintText: hintText ?? this.hintText,
|
hintText: hintText ?? this.hintText,
|
||||||
hintStyle: hintStyle ?? this.hintStyle,
|
hintStyle: hintStyle ?? this.hintStyle,
|
||||||
errorText: errorText ?? this.errorText,
|
errorText: errorText ?? this.errorText,
|
||||||
@ -209,6 +228,8 @@ class InputDecoration {
|
|||||||
return typedOther.icon == icon
|
return typedOther.icon == icon
|
||||||
&& typedOther.labelText == labelText
|
&& typedOther.labelText == labelText
|
||||||
&& typedOther.labelStyle == labelStyle
|
&& typedOther.labelStyle == labelStyle
|
||||||
|
&& typedOther.helperText == helperText
|
||||||
|
&& typedOther.helperStyle == helperStyle
|
||||||
&& typedOther.hintText == hintText
|
&& typedOther.hintText == hintText
|
||||||
&& typedOther.hintStyle == hintStyle
|
&& typedOther.hintStyle == hintStyle
|
||||||
&& typedOther.errorText == errorText
|
&& typedOther.errorText == errorText
|
||||||
@ -228,6 +249,8 @@ class InputDecoration {
|
|||||||
icon,
|
icon,
|
||||||
labelText,
|
labelText,
|
||||||
labelStyle,
|
labelStyle,
|
||||||
|
helperText,
|
||||||
|
helperStyle,
|
||||||
hintText,
|
hintText,
|
||||||
hintStyle,
|
hintStyle,
|
||||||
errorText,
|
errorText,
|
||||||
@ -249,6 +272,8 @@ class InputDecoration {
|
|||||||
description.add('icon: $icon');
|
description.add('icon: $icon');
|
||||||
if (labelText != null)
|
if (labelText != null)
|
||||||
description.add('labelText: "$labelText"');
|
description.add('labelText: "$labelText"');
|
||||||
|
if (helperText != null)
|
||||||
|
description.add('helperText: "$helperText"');
|
||||||
if (hintText != null)
|
if (hintText != null)
|
||||||
description.add('hintText: "$hintText"');
|
description.add('hintText: "$hintText"');
|
||||||
if (errorText != null)
|
if (errorText != null)
|
||||||
@ -390,6 +415,7 @@ class InputDecorator extends StatelessWidget {
|
|||||||
assert(!isDense || !isCollapsed);
|
assert(!isDense || !isCollapsed);
|
||||||
|
|
||||||
final String labelText = decoration.labelText;
|
final String labelText = decoration.labelText;
|
||||||
|
final String helperText = decoration.helperText;
|
||||||
final String hintText = decoration.hintText;
|
final String hintText = decoration.hintText;
|
||||||
final String errorText = decoration.errorText;
|
final String errorText = decoration.errorText;
|
||||||
|
|
||||||
@ -485,16 +511,20 @@ class InputDecorator extends StatelessWidget {
|
|||||||
stackChildren.add(_buildContent(borderColor, topPadding, isDense, inputChild));
|
stackChildren.add(_buildContent(borderColor, topPadding, isDense, inputChild));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isDense && errorText != null) {
|
if (!isDense && (errorText != null || helperText != null)) {
|
||||||
assert(!isCollapsed);
|
assert(!isCollapsed);
|
||||||
final TextStyle errorStyle = decoration.errorStyle ?? themeData.textTheme.caption.copyWith(color: themeData.errorColor);
|
final TextStyle captionStyle = themeData.textTheme.caption;
|
||||||
|
final TextStyle subtextStyle = errorText != null
|
||||||
|
? decoration.errorStyle ?? captionStyle.copyWith(color: themeData.errorColor)
|
||||||
|
: decoration.helperStyle ?? captionStyle.copyWith(color: themeData.hintColor);
|
||||||
|
|
||||||
stackChildren.add(new Positioned(
|
stackChildren.add(new Positioned(
|
||||||
left: 0.0,
|
left: 0.0,
|
||||||
right: 0.0,
|
right: 0.0,
|
||||||
bottom: 0.0,
|
bottom: 0.0,
|
||||||
child: new Text(
|
child: new Text(
|
||||||
errorText,
|
errorText ?? helperText,
|
||||||
style: errorStyle,
|
style: subtextStyle,
|
||||||
textAlign: textAlign,
|
textAlign: textAlign,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
|
@ -741,6 +741,75 @@ void main() {
|
|||||||
await checkText('Hello World');
|
await checkText('Hello World');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('TextField errorText trumps helperText', (WidgetTester tester) async {
|
||||||
|
Widget builder() {
|
||||||
|
return const Center(
|
||||||
|
child: const Material(
|
||||||
|
child: const TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
errorText: 'error text',
|
||||||
|
helperText: 'helper text',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await tester.pumpWidget(builder());
|
||||||
|
expect(find.text('helper text'), findsNothing);
|
||||||
|
expect(find.text('error text'), findsOneWidget);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('TextField with default helperStyle', (WidgetTester tester) async {
|
||||||
|
final ThemeData themeData = new ThemeData(
|
||||||
|
hintColor: Colors.blue[500],
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget builder() {
|
||||||
|
return new Center(
|
||||||
|
child: new Theme(
|
||||||
|
data: themeData,
|
||||||
|
child: const Material(
|
||||||
|
child: const TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
helperText: 'helper text',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await tester.pumpWidget(builder());
|
||||||
|
final Text helperText = tester.widget(find.text('helper text'));
|
||||||
|
expect(helperText.style.color, themeData.hintColor);
|
||||||
|
expect(helperText.style.fontSize, themeData.textTheme.caption.fontSize);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('TextField with specified helperStyle', (WidgetTester tester) async {
|
||||||
|
final TextStyle style = new TextStyle(
|
||||||
|
color: Colors.pink[500],
|
||||||
|
fontSize: 10.0,
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget builder() {
|
||||||
|
return new Center(
|
||||||
|
child: new Material(
|
||||||
|
child: new TextField(
|
||||||
|
decoration: new InputDecoration(
|
||||||
|
helperText: 'helper text',
|
||||||
|
helperStyle: style,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await tester.pumpWidget(builder());
|
||||||
|
final Text helperText = tester.widget(find.text('helper text'));
|
||||||
|
expect(helperText.style, style);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('TextField with default hintStyle', (WidgetTester tester) async {
|
testWidgets('TextField with default hintStyle', (WidgetTester tester) async {
|
||||||
final TextStyle style = new TextStyle(
|
final TextStyle style = new TextStyle(
|
||||||
color: Colors.pink[500],
|
color: Colors.pink[500],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user