Add minimum height and width box constraints to input decoration icons (#18480)
This commit is contained in:
parent
2a19dae28b
commit
24a1f57065
@ -803,6 +803,9 @@ class _RenderDecoration extends RenderBox {
|
||||
+ aboveBaseline
|
||||
+ belowBaseline
|
||||
+ contentPadding.bottom;
|
||||
containerHeight = math.max(
|
||||
containerHeight,
|
||||
math.max(_boxSize(suffixIcon).height, _boxSize(prefixIcon).height));
|
||||
|
||||
if (label != null) {
|
||||
// floatingLabelHeight includes the vertical gap between the inline
|
||||
@ -1688,21 +1691,27 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
);
|
||||
|
||||
final Widget prefixIcon = decoration.prefixIcon == null ? null :
|
||||
IconTheme.merge(
|
||||
data: new IconThemeData(
|
||||
color: iconColor,
|
||||
size: iconSize,
|
||||
new ConstrainedBox(
|
||||
constraints: const BoxConstraints(minWidth: 48.0, minHeight: 48.0),
|
||||
child: IconTheme.merge(
|
||||
data: new IconThemeData(
|
||||
color: iconColor,
|
||||
size: iconSize,
|
||||
),
|
||||
child: decoration.prefixIcon,
|
||||
),
|
||||
child: decoration.prefixIcon,
|
||||
);
|
||||
|
||||
final Widget suffixIcon = decoration.suffixIcon == null ? null :
|
||||
IconTheme.merge(
|
||||
data: new IconThemeData(
|
||||
color: iconColor,
|
||||
size: iconSize,
|
||||
new ConstrainedBox(
|
||||
constraints: const BoxConstraints(minWidth: 48.0, minHeight: 48.0),
|
||||
child: IconTheme.merge(
|
||||
data: new IconThemeData(
|
||||
color: iconColor,
|
||||
size: iconSize,
|
||||
),
|
||||
child: decoration.suffixIcon,
|
||||
),
|
||||
child: decoration.suffixIcon,
|
||||
);
|
||||
|
||||
final Widget helperError = new _HelperError(
|
||||
@ -1728,6 +1737,8 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
|
||||
EdgeInsets contentPadding;
|
||||
double floatingLabelHeight;
|
||||
final double leftInset = decoration.prefixIcon == null ? 12.0 : 0.0;
|
||||
final double rightInset = decoration.suffixIcon == null ? 12.0 : 0.0;
|
||||
if (decoration.isCollapsed) {
|
||||
floatingLabelHeight = 0.0;
|
||||
contentPadding = decorationContentPadding ?? EdgeInsets.zero;
|
||||
@ -1736,8 +1747,8 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
floatingLabelHeight = 4.0 + 0.75 * inlineLabelStyle.fontSize;
|
||||
if (decoration.filled == true) { // filled == null same as filled == false
|
||||
contentPadding = decorationContentPadding ?? (decorationIsDense
|
||||
? const EdgeInsets.fromLTRB(12.0, 8.0, 12.0, 8.0)
|
||||
: const EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 12.0));
|
||||
? new EdgeInsets.fromLTRB(leftInset, 8.0, rightInset, 8.0)
|
||||
: new EdgeInsets.fromLTRB(leftInset, 12.0, rightInset, 12.0));
|
||||
} else {
|
||||
// Not left or right padding for underline borders that aren't filled
|
||||
// is a small concession to backwards compatibility. This eliminates
|
||||
@ -1749,8 +1760,8 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
} else {
|
||||
floatingLabelHeight = 0.0;
|
||||
contentPadding = decorationContentPadding ?? (decorationIsDense
|
||||
? const EdgeInsets.fromLTRB(12.0, 20.0, 12.0, 12.0)
|
||||
: const EdgeInsets.fromLTRB(12.0, 24.0, 12.0, 16.0));
|
||||
? new EdgeInsets.fromLTRB(leftInset, 20.0, rightInset, 12.0)
|
||||
: new EdgeInsets.fromLTRB(leftInset, 24.0, rightInset, 16.0));
|
||||
}
|
||||
|
||||
return new _Decorator(
|
||||
@ -1987,11 +1998,16 @@ class InputDecoration {
|
||||
/// [IconTheme] and therefore does not need to be explicitly given in the
|
||||
/// icon widget.
|
||||
///
|
||||
/// The prefix icon is not padded. To pad the trailing edge of the prefix icon:
|
||||
/// The prefix icon is constrained with a minimum size of 48px by 48px, but
|
||||
/// can be expanded beyond that. Anything larger than 24px will require
|
||||
/// additional padding to ensure it matches the material spec of 12px padding
|
||||
/// between the left edge of the input and leading edge of the prefix icon.
|
||||
/// To pad the leading edge of the prefix icon:
|
||||
///
|
||||
/// ```dart
|
||||
/// prefixIcon: new Padding(
|
||||
/// padding: const EdgeInsetsDirectional.only(end: 16.0),
|
||||
/// child: myIcon,
|
||||
/// padding: const EdgeInsetsDirectional.only(start: 12.0),
|
||||
/// child: myIcon, // icon is 48px widget.
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
@ -2021,11 +2037,16 @@ class InputDecoration {
|
||||
/// [IconTheme] and therefore does not need to be explicitly given in the
|
||||
/// icon widget.
|
||||
///
|
||||
/// The suffix icon is not padded. To pad the leading edge of the suffix icon:
|
||||
/// The suffix icon is constrained with a minimum size of 48px by 48px, but
|
||||
/// can be expanded beyond that. Anything larger than 24px will require
|
||||
/// additional padding to ensure it matches the material spec of 12px padding
|
||||
/// between the right edge of the input and trailing edge of the prefix icon.
|
||||
/// To pad the trailing edge of the suffix icon:
|
||||
///
|
||||
/// ```dart
|
||||
/// suffixIcon: new Padding(
|
||||
/// padding: const EdgeInsetsDirectional.only(start: 16.0),
|
||||
/// child: new Icon(Icons.search),
|
||||
/// padding: const EdgeInsetsDirectional.only(end: 12.0),
|
||||
/// child: myIcon, // icon is 48px widget.
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
|
@ -750,6 +750,42 @@ void main() {
|
||||
expect(tester.getTopRight(find.text('text')).dx, lessThanOrEqualTo(tester.getTopLeft(find.text('s')).dx));
|
||||
});
|
||||
|
||||
testWidgets('InputDecorator prefixIcon/suffixIcon', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
buildInputDecorator(
|
||||
// isEmpty: false (default)
|
||||
// isFocused: false (default)
|
||||
decoration: const InputDecoration(
|
||||
prefixIcon: const Icon(Icons.pages),
|
||||
suffixIcon: const Icon(Icons.satellite),
|
||||
filled: true,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Overall height for this InputDecorator is 48dps:
|
||||
// 12 - top padding
|
||||
// 16 - input text (ahem font size 16dps)
|
||||
// 12 - bottom padding
|
||||
// 48 - prefix icon
|
||||
// 48 - suffix icon
|
||||
|
||||
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0));
|
||||
expect(tester.getSize(find.text('text')).height, 16.0);
|
||||
expect(tester.getSize(find.byIcon(Icons.pages)).height, 48.0);
|
||||
expect(tester.getSize(find.byIcon(Icons.satellite)).height, 48.0);
|
||||
expect(tester.getTopLeft(find.text('text')).dy, 12.0);
|
||||
expect(tester.getTopLeft(find.byIcon(Icons.pages)).dy, 0.0);
|
||||
expect(tester.getTopLeft(find.byIcon(Icons.satellite)).dy, 0.0);
|
||||
expect(tester.getTopRight(find.byIcon(Icons.satellite)).dx, 800.0);
|
||||
|
||||
|
||||
// layout is a row: [icon text icon]
|
||||
expect(tester.getTopLeft(find.byIcon(Icons.pages)).dx, 0.0);
|
||||
expect(tester.getTopRight(find.byIcon(Icons.pages)).dx, lessThanOrEqualTo(tester.getTopLeft(find.text('text')).dx));
|
||||
expect(tester.getTopRight(find.text('text')).dx, lessThanOrEqualTo(tester.getTopLeft(find.byIcon(Icons.satellite)).dx));
|
||||
});
|
||||
|
||||
testWidgets('InputDecorator error/helper/counter RTL layout', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
buildInputDecorator(
|
||||
|
Loading…
x
Reference in New Issue
Block a user