Skip to content

Commit c5c2b24

Browse files
authored
Fix floating behavior of long label and outline input border (flutter#68727)
Corrects the space available to the label in an outlined text field
1 parent 099ae9b commit c5c2b24

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

packages/flutter/lib/src/material/input_decorator.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -976,11 +976,15 @@ class _RenderDecoration extends RenderBox {
976976
+ contentPadding.right));
977977
// Increase the available width for the label when it is scaled down.
978978
final double invertedLabelScale = lerpDouble(1.00, 1 / _kFinalLabelScale, decoration.floatingLabelProgress)!;
979+
double suffixIconWidth = _boxSize(suffixIcon).width;
980+
if (decoration.border!.isOutline) {
981+
suffixIconWidth = lerpDouble(suffixIconWidth, 0.0, decoration.floatingLabelProgress)!;
982+
}
979983
final double labelWidth = math.max(0.0, constraints.maxWidth - (
980984
_boxSize(icon).width
981985
+ contentPadding.left
982986
+ _boxSize(prefixIcon).width
983-
+ _boxSize(suffixIcon).width
987+
+ suffixIconWidth
984988
+ contentPadding.right));
985989
boxToBaseline[label] = _layoutLineBox(
986990
label,

packages/flutter/test/material/input_decorator_test.dart

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4253,6 +4253,58 @@ void main() {
42534253
expect(getOpacity(tester, prefixText), 1.0);
42544254
});
42554255

4256+
// Related issue: https://github.com/flutter/flutter/issues/64427
4257+
testWidgets('OutlineInputBorder and InputDecorator long labels and in Floating, the width should ignore the icon width', (WidgetTester tester) async {
4258+
const String labelText = 'Flutter is Google’s UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop from a single codebase.';
4259+
4260+
Widget getLabeledInputDecorator(FloatingLabelBehavior floatingLabelBehavior) => MaterialApp(
4261+
home: Material(
4262+
child: Container(
4263+
width: 300,
4264+
child: TextField(
4265+
decoration: InputDecoration(
4266+
border: const OutlineInputBorder(
4267+
borderSide: BorderSide(color: Colors.greenAccent, width: 1.0),
4268+
),
4269+
suffixIcon: const Icon(Icons.arrow_drop_down),
4270+
floatingLabelBehavior: floatingLabelBehavior,
4271+
labelText: labelText,
4272+
),
4273+
),
4274+
),
4275+
),
4276+
);
4277+
4278+
await tester.pumpWidget(getLabeledInputDecorator(FloatingLabelBehavior.never));
4279+
4280+
final double labelWidth = getLabelRect(tester).width;
4281+
4282+
await tester.pumpWidget(getLabeledInputDecorator(FloatingLabelBehavior.always));
4283+
await tester.pumpAndSettle();
4284+
4285+
final double floatedLabelWidth = getLabelRect(tester).width;
4286+
4287+
expect(floatedLabelWidth > labelWidth, isTrue);
4288+
4289+
final Widget target = getLabeledInputDecorator(FloatingLabelBehavior.auto);
4290+
await tester.pumpWidget(target);
4291+
await tester.pumpAndSettle();
4292+
4293+
expect(getLabelRect(tester).width, labelWidth);
4294+
4295+
// Click for Focus.
4296+
await tester.tap(find.byType(TextField));
4297+
// Default animation duration is 200 millisecond.
4298+
await tester.pumpFrames(target, const Duration(milliseconds: 100));
4299+
4300+
expect(getLabelRect(tester).width > labelWidth, isTrue);
4301+
expect(getLabelRect(tester).width < floatedLabelWidth, isTrue);
4302+
4303+
await tester.pumpAndSettle();
4304+
4305+
expect(getLabelRect(tester).width, floatedLabelWidth);
4306+
});
4307+
42564308
testWidgets('given enough space, constrained and unconstrained heights result in the same size widget', (WidgetTester tester) async {
42574309
// Regression test for https://github.com/flutter/flutter/issues/65572
42584310
final UniqueKey keyUnconstrained = UniqueKey();

0 commit comments

Comments
 (0)