mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Expose affixes icon constraints in InputDecorationTheme (#153089)
## Description This PR makes the existing `InputDecoration.prefixIconConstraints` and `InputDecoration.suffixIconConstraints` configurable from an `InputDecorationTheme`. ## Related Issue Related to https://github.com/flutter/flutter/issues/138691 (this is needed before providing a fix or a workaround for it). ## Tests Update and split one existing test into two different tests. Update the existing test related to debugFillDescription by adding all the non tested properties.
This commit is contained in:
parent
ed47c4bb1f
commit
5609019500
@ -3089,9 +3089,10 @@ class InputDecoration {
|
||||
/// This can be used to modify the [BoxConstraints] surrounding [prefixIcon].
|
||||
///
|
||||
/// This property is particularly useful for getting the decoration's height
|
||||
/// less than 48px. This can be achieved by setting [isDense] to true and
|
||||
/// setting the constraints' minimum height and width to a value lower than
|
||||
/// 48px.
|
||||
/// less than the minimum tappable height (which is 48px when the visual
|
||||
/// density is set to [VisualDensity.standard]). This can be achieved by
|
||||
/// setting [isDense] to true and setting the constraints' minimum height
|
||||
/// and width to a value lower than the minimum tappable size.
|
||||
///
|
||||
/// {@tool dartpad}
|
||||
/// This example shows the differences between two `TextField` widgets when
|
||||
@ -3263,9 +3264,10 @@ class InputDecoration {
|
||||
/// This can be used to modify the [BoxConstraints] surrounding [suffixIcon].
|
||||
///
|
||||
/// This property is particularly useful for getting the decoration's height
|
||||
/// less than 48px. This can be achieved by setting [isDense] to true and
|
||||
/// setting the constraints' minimum height and width to a value lower than
|
||||
/// 48px.
|
||||
/// less than the minimum tappable height (which is 48px when the visual
|
||||
/// density is set to [VisualDensity.standard]). This can be achieved by
|
||||
/// setting [isDense] to true and setting the constraints' minimum height
|
||||
/// and width to a value lower than the minimum tappable size.
|
||||
///
|
||||
/// If null, a [BoxConstraints] with a minimum width and height of 48px is
|
||||
/// used.
|
||||
@ -3692,8 +3694,10 @@ class InputDecoration {
|
||||
iconColor: iconColor ?? theme.iconColor,
|
||||
prefixStyle: prefixStyle ?? theme.prefixStyle,
|
||||
prefixIconColor: prefixIconColor ?? theme.prefixIconColor,
|
||||
prefixIconConstraints: prefixIconConstraints ?? theme.prefixIconConstraints,
|
||||
suffixStyle: suffixStyle ?? theme.suffixStyle,
|
||||
suffixIconColor: suffixIconColor ?? theme.suffixIconColor,
|
||||
suffixIconConstraints: suffixIconConstraints ?? theme.suffixIconConstraints,
|
||||
counterStyle: counterStyle ?? theme.counterStyle,
|
||||
filled: filled ?? theme.filled,
|
||||
fillColor: fillColor ?? theme.fillColor,
|
||||
@ -3921,8 +3925,10 @@ class InputDecorationTheme with Diagnosticable {
|
||||
this.iconColor,
|
||||
this.prefixStyle,
|
||||
this.prefixIconColor,
|
||||
this.prefixIconConstraints,
|
||||
this.suffixStyle,
|
||||
this.suffixIconColor,
|
||||
this.suffixIconConstraints,
|
||||
this.counterStyle,
|
||||
this.filled = false,
|
||||
this.fillColor,
|
||||
@ -4063,6 +4069,21 @@ class InputDecorationTheme with Diagnosticable {
|
||||
/// If null, defaults to the [ColorScheme.primary].
|
||||
final Color? prefixIconColor;
|
||||
|
||||
/// The constraints to use for [InputDecoration.prefixIconConstraints].
|
||||
///
|
||||
/// This can be used to modify the [BoxConstraints] surrounding
|
||||
/// [InputDecoration.prefixIcon].
|
||||
///
|
||||
/// This property is particularly useful for getting the decoration's height
|
||||
/// less than the minimum tappable height (which is 48px when the visual
|
||||
/// density is set to [VisualDensity.standard]). This can be achieved by
|
||||
/// setting [isDense] to true and setting the constraints' minimum height
|
||||
/// and width to a value lower than the minimum tappable size.
|
||||
///
|
||||
/// If null, [BoxConstraints] with a minimum width and height of 48px is
|
||||
/// used.
|
||||
final BoxConstraints? prefixIconConstraints;
|
||||
|
||||
/// The style to use for the [InputDecoration.suffixText].
|
||||
///
|
||||
/// If [suffixStyle] is a [WidgetStateTextStyle], then the effective
|
||||
@ -4081,6 +4102,21 @@ class InputDecorationTheme with Diagnosticable {
|
||||
/// If null, defaults to the [ColorScheme.primary].
|
||||
final Color? suffixIconColor;
|
||||
|
||||
/// The constraints to use for [InputDecoration.suffixIconConstraints].
|
||||
///
|
||||
/// This can be used to modify the [BoxConstraints] surrounding
|
||||
/// [InputDecoration.suffixIcon].
|
||||
///
|
||||
/// This property is particularly useful for getting the decoration's height
|
||||
/// less than the minimum tappable height (which is 48px when the visual
|
||||
/// density is set to [VisualDensity.standard]). This can be achieved by
|
||||
/// setting [isDense] to true and setting the constraints' minimum height
|
||||
/// and width to a value lower than the minimum tappable size.
|
||||
///
|
||||
/// If null, [BoxConstraints] with a minimum width and height of 48px is
|
||||
/// used.
|
||||
final BoxConstraints? suffixIconConstraints;
|
||||
|
||||
/// The style to use for the [InputDecoration.counterText].
|
||||
///
|
||||
/// If [counterStyle] is a [WidgetStateTextStyle], then the effective
|
||||
@ -4332,8 +4368,10 @@ class InputDecorationTheme with Diagnosticable {
|
||||
Color? iconColor,
|
||||
TextStyle? prefixStyle,
|
||||
Color? prefixIconColor,
|
||||
BoxConstraints? prefixIconConstraints,
|
||||
TextStyle? suffixStyle,
|
||||
Color? suffixIconColor,
|
||||
BoxConstraints? suffixIconConstraints,
|
||||
TextStyle? counterStyle,
|
||||
bool? filled,
|
||||
Color? fillColor,
|
||||
@ -4367,8 +4405,10 @@ class InputDecorationTheme with Diagnosticable {
|
||||
isCollapsed: isCollapsed ?? this.isCollapsed,
|
||||
prefixStyle: prefixStyle ?? this.prefixStyle,
|
||||
prefixIconColor: prefixIconColor ?? this.prefixIconColor,
|
||||
prefixIconConstraints: prefixIconConstraints ?? this.prefixIconConstraints,
|
||||
suffixStyle: suffixStyle ?? this.suffixStyle,
|
||||
suffixIconColor: suffixIconColor ?? this.suffixIconColor,
|
||||
suffixIconConstraints: suffixIconConstraints ?? this.suffixIconConstraints,
|
||||
counterStyle: counterStyle ?? this.counterStyle,
|
||||
filled: filled ?? this.filled,
|
||||
fillColor: fillColor ?? this.fillColor,
|
||||
@ -4413,8 +4453,10 @@ class InputDecorationTheme with Diagnosticable {
|
||||
iconColor: iconColor ?? inputDecorationTheme.iconColor,
|
||||
prefixStyle: prefixStyle ?? inputDecorationTheme.prefixStyle,
|
||||
prefixIconColor: prefixIconColor ?? inputDecorationTheme.prefixIconColor,
|
||||
prefixIconConstraints: prefixIconConstraints ?? inputDecorationTheme.prefixIconConstraints,
|
||||
suffixStyle: suffixStyle ?? inputDecorationTheme.suffixStyle,
|
||||
suffixIconColor: suffixIconColor ?? inputDecorationTheme.suffixIconColor,
|
||||
suffixIconConstraints: suffixIconConstraints ?? inputDecorationTheme.suffixIconConstraints,
|
||||
counterStyle: counterStyle ?? inputDecorationTheme.counterStyle,
|
||||
fillColor: fillColor ?? inputDecorationTheme.fillColor,
|
||||
activeIndicatorBorder: activeIndicatorBorder ?? inputDecorationTheme.activeIndicatorBorder,
|
||||
@ -4448,11 +4490,13 @@ class InputDecorationTheme with Diagnosticable {
|
||||
iconColor,
|
||||
prefixStyle,
|
||||
prefixIconColor,
|
||||
prefixIconConstraints,
|
||||
suffixStyle,
|
||||
suffixIconColor,
|
||||
counterStyle,
|
||||
filled,
|
||||
suffixIconConstraints,
|
||||
Object.hash(
|
||||
counterStyle,
|
||||
filled,
|
||||
fillColor,
|
||||
activeIndicatorBorder,
|
||||
outlineBorder,
|
||||
@ -4493,8 +4537,10 @@ class InputDecorationTheme with Diagnosticable {
|
||||
&& other.iconColor == iconColor
|
||||
&& other.prefixStyle == prefixStyle
|
||||
&& other.prefixIconColor == prefixIconColor
|
||||
&& other.prefixIconConstraints == prefixIconConstraints
|
||||
&& other.suffixStyle == suffixStyle
|
||||
&& other.suffixIconColor == suffixIconColor
|
||||
&& other.suffixIconConstraints == suffixIconConstraints
|
||||
&& other.counterStyle == counterStyle
|
||||
&& other.floatingLabelBehavior == floatingLabelBehavior
|
||||
&& other.floatingLabelAlignment == floatingLabelAlignment
|
||||
@ -4534,8 +4580,10 @@ class InputDecorationTheme with Diagnosticable {
|
||||
properties.add(DiagnosticsProperty<bool>('isCollapsed', isCollapsed, defaultValue: defaultTheme.isCollapsed));
|
||||
properties.add(DiagnosticsProperty<Color>('iconColor', iconColor, defaultValue: defaultTheme.iconColor));
|
||||
properties.add(DiagnosticsProperty<Color>('prefixIconColor', prefixIconColor, defaultValue: defaultTheme.prefixIconColor));
|
||||
properties.add(DiagnosticsProperty<BoxConstraints>('prefixIconConstraints', prefixIconConstraints, defaultValue: defaultTheme.prefixIconConstraints));
|
||||
properties.add(DiagnosticsProperty<TextStyle>('prefixStyle', prefixStyle, defaultValue: defaultTheme.prefixStyle));
|
||||
properties.add(DiagnosticsProperty<Color>('suffixIconColor', suffixIconColor, defaultValue: defaultTheme.suffixIconColor));
|
||||
properties.add(DiagnosticsProperty<BoxConstraints>('suffixIconConstraints', suffixIconConstraints, defaultValue: defaultTheme.suffixIconConstraints));
|
||||
properties.add(DiagnosticsProperty<TextStyle>('suffixStyle', suffixStyle, defaultValue: defaultTheme.suffixStyle));
|
||||
properties.add(DiagnosticsProperty<TextStyle>('counterStyle', counterStyle, defaultValue: defaultTheme.counterStyle));
|
||||
properties.add(DiagnosticsProperty<bool>('filled', filled, defaultValue: defaultTheme.filled));
|
||||
|
||||
@ -6777,7 +6777,7 @@ void main() {
|
||||
expect(nodeValues.length, 11);
|
||||
});
|
||||
|
||||
testWidgets('InputDecorationTheme.inputDecoration', (WidgetTester tester) async {
|
||||
testWidgets('InputDecorationTheme.applyDefaults initializes empty field', (WidgetTester tester) async {
|
||||
const TextStyle themeStyle = TextStyle(color: Color(0xFF00FFFF));
|
||||
const Color themeColor = Color(0xFF00FF00);
|
||||
const InputBorder themeInputBorder = OutlineInputBorder(
|
||||
@ -6785,16 +6785,8 @@ void main() {
|
||||
color: Color(0xFF0000FF),
|
||||
),
|
||||
);
|
||||
const TextStyle decorationStyle = TextStyle(color: Color(0xFFFFFF00));
|
||||
const Color decorationColor = Color(0xFF0000FF);
|
||||
const InputBorder decorationInputBorder = OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFFFF00FF),
|
||||
),
|
||||
);
|
||||
|
||||
// InputDecorationTheme arguments define InputDecoration properties.
|
||||
InputDecoration decoration = const InputDecoration().applyDefaults(
|
||||
final InputDecoration decoration = const InputDecoration().applyDefaults(
|
||||
const InputDecorationTheme(
|
||||
labelStyle: themeStyle,
|
||||
floatingLabelStyle: themeStyle,
|
||||
@ -6810,8 +6802,10 @@ void main() {
|
||||
iconColor: themeColor,
|
||||
prefixStyle: themeStyle,
|
||||
prefixIconColor: themeColor,
|
||||
prefixIconConstraints: BoxConstraints(minWidth: 10, maxWidth: 10, minHeight: 30, maxHeight: 30),
|
||||
suffixStyle: themeStyle,
|
||||
suffixIconColor: themeColor,
|
||||
suffixIconConstraints: BoxConstraints(minWidth: 20, maxWidth: 20, minHeight: 40, maxHeight: 40),
|
||||
counterStyle: themeStyle,
|
||||
filled: true,
|
||||
fillColor: themeColor,
|
||||
@ -6842,8 +6836,10 @@ void main() {
|
||||
expect(decoration.iconColor, themeColor);
|
||||
expect(decoration.prefixStyle, themeStyle);
|
||||
expect(decoration.prefixIconColor, themeColor);
|
||||
expect(decoration.prefixIconConstraints, const BoxConstraints(minWidth: 10, maxWidth: 10, minHeight: 30, maxHeight: 30));
|
||||
expect(decoration.suffixStyle, themeStyle);
|
||||
expect(decoration.suffixIconColor, themeColor);
|
||||
expect(decoration.suffixIconConstraints, const BoxConstraints(minWidth: 20, maxWidth: 20, minHeight: 40, maxHeight: 40));
|
||||
expect(decoration.counterStyle, themeStyle);
|
||||
expect(decoration.filled, true);
|
||||
expect(decoration.fillColor, themeColor);
|
||||
@ -6857,9 +6853,26 @@ void main() {
|
||||
expect(decoration.border, InputBorder.none);
|
||||
expect(decoration.alignLabelWithHint, true);
|
||||
expect(decoration.constraints, const BoxConstraints(minWidth: 10, maxWidth: 20, minHeight: 30, maxHeight: 40));
|
||||
});
|
||||
|
||||
// InputDecoration (baseDecoration) defines InputDecoration properties
|
||||
decoration = const InputDecoration(
|
||||
testWidgets('InputDecorationTheme.applyDefaults does not override non-null fields', (WidgetTester tester) async {
|
||||
const TextStyle themeStyle = TextStyle(color: Color(0xFF00FFFF));
|
||||
const Color themeColor = Color(0xFF00FF00);
|
||||
const InputBorder themeInputBorder = OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFF0000FF),
|
||||
),
|
||||
);
|
||||
const TextStyle decorationStyle = TextStyle(color: Color(0xFFFFFF00));
|
||||
const Color decorationColor = Color(0xFF0000FF);
|
||||
const InputBorder decorationInputBorder = OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFFFF00FF),
|
||||
),
|
||||
);
|
||||
const BoxConstraints decorationConstraints = BoxConstraints(minWidth: 40, maxWidth: 50, minHeight: 60, maxHeight: 70);
|
||||
|
||||
final InputDecoration decoration = const InputDecoration(
|
||||
labelStyle: decorationStyle,
|
||||
floatingLabelStyle: decorationStyle,
|
||||
helperStyle: decorationStyle,
|
||||
@ -6874,8 +6887,10 @@ void main() {
|
||||
iconColor: decorationColor,
|
||||
prefixStyle: decorationStyle,
|
||||
prefixIconColor: decorationColor,
|
||||
prefixIconConstraints: decorationConstraints,
|
||||
suffixStyle: decorationStyle,
|
||||
suffixIconColor: decorationColor,
|
||||
suffixIconConstraints: decorationConstraints,
|
||||
counterStyle: decorationStyle,
|
||||
filled: false,
|
||||
fillColor: decorationColor,
|
||||
@ -6888,7 +6903,7 @@ void main() {
|
||||
enabledBorder: decorationInputBorder,
|
||||
border: OutlineInputBorder(),
|
||||
alignLabelWithHint: false,
|
||||
constraints: BoxConstraints(minWidth: 40, maxWidth: 50, minHeight: 60, maxHeight: 70),
|
||||
constraints: decorationConstraints,
|
||||
).applyDefaults(
|
||||
const InputDecorationTheme(
|
||||
labelStyle: themeStyle,
|
||||
@ -6937,8 +6952,10 @@ void main() {
|
||||
expect(decoration.iconColor, decorationColor);
|
||||
expect(decoration.prefixStyle, decorationStyle);
|
||||
expect(decoration.prefixIconColor, decorationColor);
|
||||
expect(decoration.prefixIconConstraints, decorationConstraints);
|
||||
expect(decoration.suffixStyle, decorationStyle);
|
||||
expect(decoration.suffixIconColor, decorationColor);
|
||||
expect(decoration.suffixIconConstraints, decorationConstraints);
|
||||
expect(decoration.counterStyle, decorationStyle);
|
||||
expect(decoration.filled, false);
|
||||
expect(decoration.fillColor, decorationColor);
|
||||
@ -6951,7 +6968,7 @@ void main() {
|
||||
expect(decoration.enabledBorder, decorationInputBorder);
|
||||
expect(decoration.border, const OutlineInputBorder());
|
||||
expect(decoration.alignLabelWithHint, false);
|
||||
expect(decoration.constraints, const BoxConstraints(minWidth: 40, maxWidth: 50, minHeight: 60, maxHeight: 70));
|
||||
expect(decoration.constraints, decorationConstraints);
|
||||
});
|
||||
|
||||
testWidgets('InputDecorationTheme.inputDecoration with MaterialState', (WidgetTester tester) async {
|
||||
@ -7131,20 +7148,34 @@ void main() {
|
||||
|
||||
testWidgets('InputDecorationTheme implements debugFillDescription', (WidgetTester tester) async {
|
||||
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
||||
const BoxConstraints constraints = BoxConstraints(minWidth: 10, maxWidth: 10, minHeight: 30, maxHeight: 30);
|
||||
const InputDecorationTheme(
|
||||
labelStyle: TextStyle(),
|
||||
floatingLabelStyle: TextStyle(),
|
||||
helperStyle: TextStyle(),
|
||||
helperMaxLines: 6,
|
||||
hintStyle: TextStyle(),
|
||||
errorStyle: TextStyle(),
|
||||
errorMaxLines: 5,
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
floatingLabelAlignment: FloatingLabelAlignment.center,
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsetsDirectional.only(start: 40.0, top: 12.0, bottom: 12.0),
|
||||
isCollapsed: true,
|
||||
iconColor: Colors.red,
|
||||
prefixIconColor: Colors.blue,
|
||||
prefixIconConstraints: constraints,
|
||||
prefixStyle: TextStyle(),
|
||||
suffixIconColor: Colors.blue,
|
||||
suffixIconConstraints: constraints,
|
||||
suffixStyle: TextStyle(),
|
||||
counterStyle: TextStyle(),
|
||||
filled: true,
|
||||
fillColor: Colors.red,
|
||||
activeIndicatorBorder: BorderSide(),
|
||||
outlineBorder: BorderSide(),
|
||||
focusColor: Colors.blue,
|
||||
hoverColor: Colors.green,
|
||||
errorBorder: UnderlineInputBorder(),
|
||||
focusedBorder: UnderlineInputBorder(),
|
||||
focusedErrorBorder: UnderlineInputBorder(),
|
||||
@ -7152,24 +7183,38 @@ void main() {
|
||||
enabledBorder: UnderlineInputBorder(),
|
||||
border: UnderlineInputBorder(),
|
||||
alignLabelWithHint: true,
|
||||
constraints: constraints,
|
||||
).debugFillProperties(builder);
|
||||
final List<String> description = builder.properties
|
||||
.where((DiagnosticsNode n) => !n.isFiltered(DiagnosticLevel.info))
|
||||
.map((DiagnosticsNode n) => n.toString()).toList();
|
||||
expect(description, <String>[
|
||||
'labelStyle: TextStyle(<all styles inherited>)',
|
||||
'floatingLabelStyle: TextStyle(<all styles inherited>)',
|
||||
'helperStyle: TextStyle(<all styles inherited>)',
|
||||
'helperMaxLines: 6',
|
||||
'hintStyle: TextStyle(<all styles inherited>)',
|
||||
'errorStyle: TextStyle(<all styles inherited>)',
|
||||
'errorMaxLines: 5',
|
||||
'floatingLabelBehavior: FloatingLabelBehavior.never',
|
||||
'floatingLabelAlignment: FloatingLabelAlignment.center',
|
||||
'isDense: true',
|
||||
'contentPadding: EdgeInsetsDirectional(40.0, 12.0, 0.0, 12.0)',
|
||||
'isCollapsed: true',
|
||||
'iconColor: MaterialColor(primary value: Color(0xfff44336))',
|
||||
'prefixIconColor: MaterialColor(primary value: Color(0xff2196f3))',
|
||||
'prefixIconConstraints: BoxConstraints(w=10.0, h=30.0)',
|
||||
'prefixStyle: TextStyle(<all styles inherited>)',
|
||||
'suffixIconColor: MaterialColor(primary value: Color(0xff2196f3))',
|
||||
'suffixIconConstraints: BoxConstraints(w=10.0, h=30.0)',
|
||||
'suffixStyle: TextStyle(<all styles inherited>)',
|
||||
'counterStyle: TextStyle(<all styles inherited>)',
|
||||
'filled: true',
|
||||
'fillColor: MaterialColor(primary value: Color(0xfff44336))',
|
||||
'activeIndicatorBorder: BorderSide',
|
||||
'outlineBorder: BorderSide',
|
||||
'focusColor: MaterialColor(primary value: Color(0xff2196f3))',
|
||||
'hoverColor: MaterialColor(primary value: Color(0xff4caf50))',
|
||||
'errorBorder: UnderlineInputBorder()',
|
||||
'focusedBorder: UnderlineInputBorder()',
|
||||
'focusedErrorBorder: UnderlineInputBorder()',
|
||||
@ -7177,6 +7222,7 @@ void main() {
|
||||
'enabledBorder: UnderlineInputBorder()',
|
||||
'border: UnderlineInputBorder()',
|
||||
'alignLabelWithHint: true',
|
||||
'constraints: BoxConstraints(w=10.0, h=30.0)',
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user