diff --git a/packages/flutter/lib/src/material/input_decorator.dart b/packages/flutter/lib/src/material/input_decorator.dart index 04163b2561d12..3f449e28a72fc 100644 --- a/packages/flutter/lib/src/material/input_decorator.dart +++ b/packages/flutter/lib/src/material/input_decorator.dart @@ -2164,6 +2164,7 @@ class _InputDecoratorState extends State with TickerProviderStat child: Text( decoration!.hintText!, style: hintStyle, + textDirection: decoration!.hintTextDirection, overflow: TextOverflow.ellipsis, textAlign: textAlign, maxLines: decoration!.hintMaxLines, @@ -2509,6 +2510,7 @@ class InputDecoration { this.helperMaxLines, this.hintText, this.hintStyle, + this.hintTextDirection, this.hintMaxLines, this.errorText, this.errorStyle, @@ -2566,6 +2568,7 @@ class InputDecoration { this.hasFloatingPlaceholder = true, this.floatingLabelBehavior, this.hintStyle, + this.hintTextDirection, this.filled = false, this.fillColor, this.focusColor, @@ -2687,6 +2690,12 @@ class InputDecoration { /// input field and the current [Theme]. final TextStyle? hintStyle; + /// The direction to use for the [hintText]. + /// + /// If null, defaults to a value derived from [Directionality] for the + /// input field and the current context. + final TextDirection? hintTextDirection; + /// The maximum number of lines the [hintText] can occupy. /// /// Defaults to the value of [TextField.maxLines] attribute. @@ -3307,6 +3316,7 @@ class InputDecoration { int? helperMaxLines, String? hintText, TextStyle? hintStyle, + TextDirection? hintTextDirection, int? hintMaxLines, String? errorText, TextStyle? errorStyle, @@ -3352,6 +3362,7 @@ class InputDecoration { helperMaxLines : helperMaxLines ?? this.helperMaxLines, hintText: hintText ?? this.hintText, hintStyle: hintStyle ?? this.hintStyle, + hintTextDirection: hintTextDirection ?? this.hintTextDirection, hintMaxLines: hintMaxLines ?? this.hintMaxLines, errorText: errorText ?? this.errorText, errorStyle: errorStyle ?? this.errorStyle, @@ -3440,6 +3451,7 @@ class InputDecoration { && other.helperMaxLines == helperMaxLines && other.hintText == hintText && other.hintStyle == hintStyle + && other.hintTextDirection == hintTextDirection && other.hintMaxLines == hintMaxLines && other.errorText == errorText && other.errorStyle == errorStyle @@ -3488,6 +3500,7 @@ class InputDecoration { helperMaxLines, hintText, hintStyle, + hintTextDirection, hintMaxLines, errorText, errorStyle, diff --git a/packages/flutter/test/material/text_form_field_test.dart b/packages/flutter/test/material/text_form_field_test.dart index c2e12a0c72f96..f3f9a77629466 100644 --- a/packages/flutter/test/material/text_form_field_test.dart +++ b/packages/flutter/test/material/text_form_field_test.dart @@ -581,4 +581,46 @@ void main() { final TextField widget = tester.widget(find.byType(TextField)); expect(widget.selectionControls, equals(materialTextSelectionControls)); }); + + testWidgets('TextFormField respects hintTextDirection', (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp( + home: Material( + child: Directionality( + textDirection: TextDirection.rtl, + child: TextFormField( + decoration: const InputDecoration( + border: OutlineInputBorder(), + labelText: 'Some Label', + hintText: 'Some Hint', + hintTextDirection: TextDirection.ltr, + ), + ), + ), + ), + )); + + final Finder hintTextFinder = find.text('Some Hint'); + + final Text hintText = tester.firstWidget(hintTextFinder); + expect(hintText.textDirection, TextDirection.ltr); + + await tester.pumpWidget(MaterialApp( + home: Material( + child: Directionality( + textDirection: TextDirection.rtl, + child: TextFormField( + decoration: const InputDecoration( + border: OutlineInputBorder(), + labelText: 'Some Label', + hintText: 'Some Hint', + ), + ), + ), + ), + )); + + final BuildContext context = tester.element(hintTextFinder); + final TextDirection textDirection = Directionality.of(context); + expect(textDirection, TextDirection.rtl); + }); }