diff --git a/packages/flutter/lib/src/material/input_decorator.dart b/packages/flutter/lib/src/material/input_decorator.dart index 9cadc9f7b9b..c19c9b56159 100644 --- a/packages/flutter/lib/src/material/input_decorator.dart +++ b/packages/flutter/lib/src/material/input_decorator.dart @@ -17,6 +17,7 @@ import 'theme_data.dart'; const Duration _kTransitionDuration = Duration(milliseconds: 200); const Curve _kTransitionCurve = Curves.fastOutSlowIn; +const double _kFinalLabelScale = 0.75; // Defines the gap in the InputDecorator's outline border where the // floating label will appear. @@ -981,9 +982,11 @@ class _RenderDecoration extends RenderBox { + _boxSize(suffix).width + _boxSize(suffixIcon).width + contentPadding.right)); + // Increase the available width for the label when it is scaled down. + final double invertedLabelScale = lerpDouble(1.00, 1 / _kFinalLabelScale, decoration.floatingLabelProgress); boxToBaseline[label] = _layoutLineBox( label, - boxConstraints.copyWith(maxWidth: inputWidth), + boxConstraints.copyWith(maxWidth: inputWidth * invertedLabelScale), ); boxToBaseline[hint] = _layoutLineBox( hint, @@ -1452,11 +1455,10 @@ class _RenderDecoration extends RenderBox { final bool isOutlineBorder = decoration.border != null && decoration.border.isOutline; // Temporary opt-in fix for https://github.com/flutter/flutter/issues/54028 // Center the scaled label relative to the border. - const double finalLabelScale = 0.75; final double floatingY = decoration.fixTextFieldOutlineLabel - ? isOutlineBorder ? (-labelHeight * finalLabelScale) / 2.0 + borderWeight / 2.0 : contentPadding.top + ? isOutlineBorder ? (-labelHeight * _kFinalLabelScale) / 2.0 + borderWeight / 2.0 : contentPadding.top : isOutlineBorder ? -labelHeight * 0.25 : contentPadding.top; - final double scale = lerpDouble(1.0, finalLabelScale, t); + final double scale = lerpDouble(1.0, _kFinalLabelScale, t); double dx; switch (textDirection) { case TextDirection.rtl: diff --git a/packages/flutter/test/material/input_decorator_test.dart b/packages/flutter/test/material/input_decorator_test.dart index cd72e1200fe..e477153e7a6 100644 --- a/packages/flutter/test/material/input_decorator_test.dart +++ b/packages/flutter/test/material/input_decorator_test.dart @@ -4069,6 +4069,58 @@ void main() { expect(tester.getTopLeft(find.text('label')).dy, 20.0); }); + testWidgets('InputDecorator floating label width scales when focused', (WidgetTester tester) async { + final String longStringA = String.fromCharCodes(List.generate(200, (_) => 65)); + final String longStringB = String.fromCharCodes(List.generate(200, (_) => 66)); + + await tester.pumpWidget( + Center( + child: Container( + width: 100, + height: 100, + child: buildInputDecorator( + // isFocused: false (default) + isEmpty: true, + decoration: InputDecoration( + labelText: longStringA, + ), + ), + ), + ), + ); + + await tester.pumpAndSettle(); + + expect( + find.text(longStringA), + paints..clipRect(rect: const Rect.fromLTWH(0, 0, 100.0, 16.0)), + ); + + await tester.pumpWidget( + Center( + child: Container( + width: 100, + height: 100, + child: buildInputDecorator( + isFocused: true, + isEmpty: true, + decoration: InputDecoration( + labelText: longStringB, + ), + ), + ), + ), + ); + + await tester.pumpAndSettle(); + + expect( + find.text(longStringB), + // 133.3 is approximately 100 / 0.75 (_kFinalLabelScale) + paints..clipRect(rect: const Rect.fromLTWH(0, 0, 133.0, 16.0)), + ); + }, skip: isBrowser); // TODO(yjbanov): https://github.com/flutter/flutter/issues/44020 + testWidgets('textAlignVertical can be updated', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/56933 const String hintText = 'hint';