Skip to content

Commit

Permalink
Add helperMaxLines to InputDecoration and InputDecorationTheme (flutt…
Browse files Browse the repository at this point in the history
…er#39433)

Similar to errorMaxLines
  • Loading branch information
letsar authored and justinmc committed Oct 8, 2019
1 parent ed1d5a8 commit 0ddcd70
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 0 deletions.
52 changes: 52 additions & 0 deletions packages/flutter/lib/src/material/input_decorator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ class _HelperError extends StatefulWidget {
this.textAlign,
this.helperText,
this.helperStyle,
this.helperMaxLines,
this.errorText,
this.errorStyle,
this.errorMaxLines,
Expand All @@ -291,6 +292,7 @@ class _HelperError extends StatefulWidget {
final TextAlign textAlign;
final String helperText;
final TextStyle helperStyle;
final int helperMaxLines;
final String errorText;
final TextStyle errorStyle;
final int errorMaxLines;
Expand Down Expand Up @@ -372,6 +374,7 @@ class _HelperErrorState extends State<_HelperError> with SingleTickerProviderSta
style: widget.helperStyle,
textAlign: widget.textAlign,
overflow: TextOverflow.ellipsis,
maxLines: widget.helperMaxLines,
),
),
);
Expand Down Expand Up @@ -2184,6 +2187,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
textAlign: textAlign,
helperText: decoration.helperText,
helperStyle: _getHelperStyle(themeData),
helperMaxLines: decoration.helperMaxLines,
errorText: decoration.errorText,
errorStyle: _getErrorStyle(themeData),
errorMaxLines: decoration.errorMaxLines,
Expand Down Expand Up @@ -2304,6 +2308,7 @@ class InputDecoration {
this.labelStyle,
this.helperText,
this.helperStyle,
this.helperMaxLines,
this.hintText,
this.hintStyle,
this.hintMaxLines,
Expand Down Expand Up @@ -2363,6 +2368,7 @@ class InputDecoration {
labelStyle = null,
helperText = null,
helperStyle = null,
helperMaxLines = null,
hintMaxLines = null,
errorText = null,
errorStyle = null,
Expand Down Expand Up @@ -2436,6 +2442,19 @@ class InputDecoration {
/// The style to use for the [helperText].
final TextStyle helperStyle;

/// The maximum number of lines the [helperText] can occupy.
///
/// Defaults to null, which means that the [helperText] will be limited
/// to a single line with [TextOverflow.ellipsis].
///
/// This value is passed along to the [Text.maxLines] attribute
/// of the [Text] widget used to display the helper.
///
/// See also:
///
/// * [errorMaxLines], the equivalent but for the [errorText].
final int helperMaxLines;

/// Text that suggests what sort of input the field accepts.
///
/// Displayed on top of the input [child] (i.e., at the same location on the
Expand Down Expand Up @@ -2485,6 +2504,10 @@ class InputDecoration {
///
/// This value is passed along to the [Text.maxLines] attribute
/// of the [Text] widget used to display the error.
///
/// See also:
///
/// * [helperMaxLines], the equivalent but for the [helperText].
final int errorMaxLines;

/// Whether the label floats on focus.
Expand Down Expand Up @@ -2939,6 +2962,7 @@ class InputDecoration {
TextStyle labelStyle,
String helperText,
TextStyle helperStyle,
int helperMaxLines,
String hintText,
TextStyle hintStyle,
int hintMaxLines,
Expand Down Expand Up @@ -2979,6 +3003,7 @@ class InputDecoration {
labelStyle: labelStyle ?? this.labelStyle,
helperText: helperText ?? this.helperText,
helperStyle: helperStyle ?? this.helperStyle,
helperMaxLines : helperMaxLines ?? this.helperMaxLines,
hintText: hintText ?? this.hintText,
hintStyle: hintStyle ?? this.hintStyle,
hintMaxLines: hintMaxLines ?? this.hintMaxLines,
Expand Down Expand Up @@ -3024,6 +3049,7 @@ class InputDecoration {
return copyWith(
labelStyle: labelStyle ?? theme.labelStyle,
helperStyle: helperStyle ?? theme.helperStyle,
helperMaxLines : helperMaxLines ?? theme.helperMaxLines,
hintStyle: hintStyle ?? theme.hintStyle,
errorStyle: errorStyle ?? theme.errorStyle,
errorMaxLines: errorMaxLines ?? theme.errorMaxLines,
Expand Down Expand Up @@ -3059,6 +3085,7 @@ class InputDecoration {
&& typedOther.labelStyle == labelStyle
&& typedOther.helperText == helperText
&& typedOther.helperStyle == helperStyle
&& typedOther.helperMaxLines == helperMaxLines
&& typedOther.hintText == hintText
&& typedOther.hintStyle == hintStyle
&& typedOther.hintMaxLines == hintMaxLines
Expand Down Expand Up @@ -3103,6 +3130,7 @@ class InputDecoration {
labelStyle,
helperText,
helperStyle,
helperMaxLines,
hintText,
hintStyle,
hintMaxLines,
Expand Down Expand Up @@ -3149,6 +3177,7 @@ class InputDecoration {
if (icon != null) 'icon: $icon',
if (labelText != null) 'labelText: "$labelText"',
if (helperText != null) 'helperText: "$helperText"',
if (helperMaxLines != null) 'helperMaxLines: "$helperMaxLines"',
if (hintText != null) 'hintText: "$hintText"',
if (hintMaxLines != null) 'hintMaxLines: "$hintMaxLines"',
if (errorText != null) 'errorText: "$errorText"',
Expand Down Expand Up @@ -3206,6 +3235,7 @@ class InputDecorationTheme extends Diagnosticable {
const InputDecorationTheme({
this.labelStyle,
this.helperStyle,
this.helperMaxLines,
this.hintStyle,
this.errorStyle,
this.errorMaxLines,
Expand Down Expand Up @@ -3245,6 +3275,19 @@ class InputDecorationTheme extends Diagnosticable {
/// The style to use for [InputDecoration.helperText].
final TextStyle helperStyle;

/// The maximum number of lines the [helperText] can occupy.
///
/// Defaults to null, which means that the [helperText] will be limited
/// to a single line with [TextOverflow.ellipsis].
///
/// This value is passed along to the [Text.maxLines] attribute
/// of the [Text] widget used to display the helper.
///
/// See also:
///
/// * [errorMaxLines], the equivalent but for the [errorText].
final int helperMaxLines;

/// The style to use for the [InputDecoration.hintText].
///
/// Also used for the [labelText] when the [labelText] is displayed on
Expand All @@ -3268,6 +3311,10 @@ class InputDecorationTheme extends Diagnosticable {
///
/// This value is passed along to the [Text.maxLines] attribute
/// of the [Text] widget used to display the error.
///
/// See also:
///
/// * [helperMaxLines], the equivalent but for the [helperText].
final int errorMaxLines;

/// Whether the placeholder text floats to become a label on focus.
Expand Down Expand Up @@ -3522,6 +3569,7 @@ class InputDecorationTheme extends Diagnosticable {
InputDecorationTheme copyWith({
TextStyle labelStyle,
TextStyle helperStyle,
int helperMaxLines,
TextStyle hintStyle,
TextStyle errorStyle,
int errorMaxLines,
Expand All @@ -3547,6 +3595,7 @@ class InputDecorationTheme extends Diagnosticable {
return InputDecorationTheme(
labelStyle: labelStyle ?? this.labelStyle,
helperStyle: helperStyle ?? this.helperStyle,
helperMaxLines: helperMaxLines ?? this.helperMaxLines,
hintStyle: hintStyle ?? this.hintStyle,
errorStyle: errorStyle ?? this.errorStyle,
errorMaxLines: errorMaxLines ?? this.errorMaxLines,
Expand Down Expand Up @@ -3576,6 +3625,7 @@ class InputDecorationTheme extends Diagnosticable {
return hashList(<dynamic>[
labelStyle,
helperStyle,
helperMaxLines,
hintStyle,
errorStyle,
errorMaxLines,
Expand Down Expand Up @@ -3609,6 +3659,7 @@ class InputDecorationTheme extends Diagnosticable {
final InputDecorationTheme typedOther = other;
return typedOther.labelStyle == labelStyle
&& typedOther.helperStyle == helperStyle
&& typedOther.helperMaxLines == helperMaxLines
&& typedOther.hintStyle == hintStyle
&& typedOther.errorStyle == errorStyle
&& typedOther.errorMaxLines == errorMaxLines
Expand Down Expand Up @@ -3638,6 +3689,7 @@ class InputDecorationTheme extends Diagnosticable {
const InputDecorationTheme defaultTheme = InputDecorationTheme();
properties.add(DiagnosticsProperty<TextStyle>('labelStyle', labelStyle, defaultValue: defaultTheme.labelStyle));
properties.add(DiagnosticsProperty<TextStyle>('helperStyle', helperStyle, defaultValue: defaultTheme.helperStyle));
properties.add(IntProperty('helperMaxLines', helperMaxLines, defaultValue: defaultTheme.helperMaxLines));
properties.add(DiagnosticsProperty<TextStyle>('hintStyle', hintStyle, defaultValue: defaultTheme.hintStyle));
properties.add(DiagnosticsProperty<TextStyle>('errorStyle', errorStyle, defaultValue: defaultTheme.errorStyle));
properties.add(IntProperty('errorMaxLines', errorMaxLines, defaultValue: defaultTheme.errorMaxLines));
Expand Down
102 changes: 102 additions & 0 deletions packages/flutter/test/material/input_decorator_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1026,6 +1026,103 @@ void main() {
expect(tester.getBottomLeft(find.text(kError1)), const Offset(12.0, 76.0));
});

testWidgets('InputDecoration helperMaxLines', (WidgetTester tester) async {
const String kHelper1 = 'e0';
const String kHelper2 = 'e0\ne1';
const String kHelper3 = 'e0\ne1\ne2';

await tester.pumpWidget(
buildInputDecorator(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
labelText: 'label',
helperText: kHelper3,
helperMaxLines: 3,
errorText: null,
filled: true,
),
),
);

// Overall height for this InputDecorator is 100dps:
//
// 12 - top padding
// 12 - floating label (ahem font size 16dps * 0.75 = 12)
// 4 - floating label / input text gap
// 16 - input text (ahem font size 16dps)
// 12 - bottom padding
// 8 - below the border padding
// 36 - helper text (3 lines, ahem font size 12dps)

expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 100.0));
expect(tester.getTopLeft(find.text(kHelper3)), const Offset(12.0, 64.0));
expect(tester.getBottomLeft(find.text(kHelper3)), const Offset(12.0, 100.0));

// Overall height for this InputDecorator is 12 less than the first
// one, 88dps, because helperText only occupies two lines.

await tester.pumpWidget(
buildInputDecorator(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
labelText: 'label',
helperText: kHelper3,
helperMaxLines: 2,
errorText: null,
filled: true,
),
),
);

expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 88.0));
expect(tester.getTopLeft(find.text(kHelper3)), const Offset(12.0, 64.0));
expect(tester.getBottomLeft(find.text(kHelper3)), const Offset(12.0, 88.0));

// Overall height for this InputDecorator is 12 less than the first
// one, 88dps, because helperText only occupies two lines.

await tester.pumpWidget(
buildInputDecorator(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
labelText: 'label',
helperText: kHelper2,
helperMaxLines: 3,
errorText: null,
filled: true,
),
),
);

expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 88.0));
expect(tester.getTopLeft(find.text(kHelper2)), const Offset(12.0, 64.0));
expect(tester.getBottomLeft(find.text(kHelper2)), const Offset(12.0, 88.0));

// Overall height for this InputDecorator is 24 less than the first
// one, 88dps, because helperText only occupies one line.

await tester.pumpWidget(
buildInputDecorator(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
labelText: 'label',
helperText: kHelper1,
helperMaxLines: 3,
errorText: null,
filled: true,
),
),
);

expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0));
expect(tester.getTopLeft(find.text(kHelper1)), const Offset(12.0, 64.0));
expect(tester.getBottomLeft(find.text(kHelper1)), const Offset(12.0, 76.0));
});

testWidgets('InputDecorator prefix/suffix texts', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
Expand Down Expand Up @@ -2703,6 +2800,7 @@ void main() {
const InputDecorationTheme(
labelStyle: themeStyle,
helperStyle: themeStyle,
helperMaxLines: 5,
hintStyle: themeStyle,
errorStyle: themeStyle,
errorMaxLines: 4,
Expand All @@ -2721,6 +2819,7 @@ void main() {

expect(decoration.labelStyle, decorationStyle);
expect(decoration.helperStyle, decorationStyle);
expect(decoration.helperMaxLines, 5);
expect(decoration.hintStyle, decorationStyle);
expect(decoration.errorStyle, decorationStyle);
expect(decoration.errorMaxLines, 4);
Expand Down Expand Up @@ -3024,6 +3123,7 @@ void main() {
final String debugString = const InputDecorationTheme(
labelStyle: TextStyle(height: 1.0),
helperStyle: TextStyle(height: 2.0),
helperMaxLines: 5,
hintStyle: TextStyle(height: 3.0),
errorStyle: TextStyle(height: 4.0),
errorMaxLines: 5,
Expand Down Expand Up @@ -3412,6 +3512,7 @@ void main() {
const InputDecorationTheme(
labelStyle: TextStyle(),
helperStyle: TextStyle(),
helperMaxLines: 6,
hintStyle: TextStyle(),
errorMaxLines: 5,
hasFloatingPlaceholder: false,
Expand All @@ -3436,6 +3537,7 @@ void main() {
expect(description, <String>[
'labelStyle: TextStyle(<all styles inherited>)',
'helperStyle: TextStyle(<all styles inherited>)',
'helperMaxLines: 6',
'hintStyle: TextStyle(<all styles inherited>)',
'errorMaxLines: 5',
'hasFloatingPlaceholder: false',
Expand Down

0 comments on commit 0ddcd70

Please sign in to comment.