Commit 114335df authored by Trevor Wang's avatar Trevor Wang Committed by xster

Support TextField multi-line hint text #20941 (#24976)

parent 65df90d8
......@@ -233,7 +233,7 @@ class TextFormFieldDemoState extends State<TextFormFieldDemo> {
TextFormField(
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'Tell us about yourself',
hintText: 'Tell us about yourself (e.g., write down what you do or what hobbies you have)',
helperText: 'Keep it short, this is just a demo.',
labelText: 'Life story',
),
......
......@@ -1719,6 +1719,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
style: hintStyle,
overflow: TextOverflow.ellipsis,
textAlign: textAlign,
maxLines: decoration.hintMaxLines,
),
);
......@@ -1944,6 +1945,7 @@ class InputDecoration {
this.helperStyle,
this.hintText,
this.hintStyle,
this.hintMaxLines,
this.errorText,
this.errorStyle,
this.errorMaxLines,
......@@ -1994,6 +1996,7 @@ class InputDecoration {
labelStyle = null,
helperText = null,
helperStyle = null,
hintMaxLines = null,
errorText = null,
errorStyle = null,
errorMaxLines = null,
......@@ -2081,6 +2084,15 @@ class InputDecoration {
/// input field and the current [Theme].
final TextStyle hintStyle;
/// The maximum number of lines the [hintText] can occupy.
///
/// Defaults to the value of [TextField.maxLines] attribute.
///
/// This value is passed along to the [Text.maxLines] attribute
/// of the [Text] widget used to display the hint text. [TextOverflow.ellipsis] is
/// used to handle the overflow when it is limited to single line.
final int hintMaxLines;
/// Text that appears below the input [child] and the border.
///
/// If non-null, the border's color animates to red and the [helperText] is
......@@ -2449,6 +2461,7 @@ class InputDecoration {
TextStyle helperStyle,
String hintText,
TextStyle hintStyle,
int hintMaxLines,
String errorText,
TextStyle errorStyle,
int errorMaxLines,
......@@ -2484,6 +2497,7 @@ class InputDecoration {
helperStyle: helperStyle ?? this.helperStyle,
hintText: hintText ?? this.hintText,
hintStyle: hintStyle ?? this.hintStyle,
hintMaxLines: hintMaxLines ?? this.hintMaxLines,
errorText: errorText ?? this.errorText,
errorStyle: errorStyle ?? this.errorStyle,
errorMaxLines: errorMaxLines ?? this.errorMaxLines,
......@@ -2556,6 +2570,7 @@ class InputDecoration {
&& typedOther.helperStyle == helperStyle
&& typedOther.hintText == hintText
&& typedOther.hintStyle == hintStyle
&& typedOther.hintMaxLines == hintMaxLines
&& typedOther.errorText == errorText
&& typedOther.errorStyle == errorStyle
&& typedOther.errorMaxLines == errorMaxLines
......@@ -2597,6 +2612,7 @@ class InputDecoration {
helperStyle,
hintText,
hintStyle,
hintMaxLines,
errorText,
errorStyle,
errorMaxLines,
......@@ -2646,6 +2662,8 @@ class InputDecoration {
description.add('helperText: "$helperText"');
if (hintText != null)
description.add('hintText: "$hintText"');
if (hintMaxLines != null)
description.add('hintMaxLines: "$hintMaxLines"');
if (errorText != null)
description.add('errorText: "$errorText"');
if (errorStyle != null)
......
......@@ -398,6 +398,7 @@ class _TextFieldState extends State<TextField> with AutomaticKeepAliveClientMixi
.applyDefaults(Theme.of(context).inputDecorationTheme)
.copyWith(
enabled: widget.enabled,
hintMaxLines: widget.decoration?.hintMaxLines ?? widget.maxLines
);
if (!needsCounter)
......
......@@ -722,6 +722,43 @@ void main() {
expect(inputBox.size, greaterThan(fourLineInputSize));
});
testWidgets('Multiline hint text will wrap up to maxLines', (WidgetTester tester) async {
final Key textFieldKey = UniqueKey();
Widget builder(int maxLines, final String hintMsg) {
return boilerplate(
child: TextField(
key: textFieldKey,
style: const TextStyle(color: Colors.black, fontSize: 34.0),
maxLines: maxLines,
decoration: InputDecoration(
hintText: hintMsg,
),
),
);
}
const String hintPlaceholder = 'Placeholder';
const String multipleLineText = 'Here\'s a text, which is more than one line, to demostrate the multiple line hint text';
await tester.pumpWidget(builder(null, hintPlaceholder));
RenderBox findHintText(String hint) => tester.renderObject(find.text(hint));
final RenderBox hintTextBox = findHintText(hintPlaceholder);
final Size oneLineHintSize = hintTextBox.size;
await tester.pumpWidget(builder(null, hintPlaceholder));
expect(findHintText(hintPlaceholder), equals(hintTextBox));
expect(hintTextBox.size, equals(oneLineHintSize));
const int maxLines = 3;
await tester.pumpWidget(builder(maxLines, multipleLineText));
final Text hintTextWidget = tester.widget(find.text(multipleLineText));
expect(hintTextWidget.maxLines, equals(maxLines));
expect(findHintText(multipleLineText).size, greaterThan(oneLineHintSize));
});
testWidgets('Can drag handles to change selection in multiline', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
......
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