Unverified Commit e74b9b5b authored by hangyu's avatar hangyu Committed by GitHub

Migrate InputDecorator to Material 3 (#107943)

* Support material 3 in inputDecorator

* Format polish

* format polish

* update input_decorator_test

* revert pub

* style update

* style polish

* default before base

* resolve comments

* Update text_field.2.dart

* move text styles into M2 theme

* add error style

* fix typo

* resolve comments

* fix g3 test
parent 2f4299ad
...@@ -26,6 +26,7 @@ import 'package:gen_defaults/chip_input_template.dart'; ...@@ -26,6 +26,7 @@ import 'package:gen_defaults/chip_input_template.dart';
import 'package:gen_defaults/dialog_template.dart'; import 'package:gen_defaults/dialog_template.dart';
import 'package:gen_defaults/fab_template.dart'; import 'package:gen_defaults/fab_template.dart';
import 'package:gen_defaults/icon_button_template.dart'; import 'package:gen_defaults/icon_button_template.dart';
import 'package:gen_defaults/input_decorator_template.dart';
import 'package:gen_defaults/navigation_bar_template.dart'; import 'package:gen_defaults/navigation_bar_template.dart';
import 'package:gen_defaults/navigation_rail_template.dart'; import 'package:gen_defaults/navigation_rail_template.dart';
import 'package:gen_defaults/surface_tint.dart'; import 'package:gen_defaults/surface_tint.dart';
...@@ -111,6 +112,7 @@ Future<void> main(List<String> args) async { ...@@ -111,6 +112,7 @@ Future<void> main(List<String> args) async {
DialogTemplate('Dialog', '$materialLib/dialog.dart', tokens).updateFile(); DialogTemplate('Dialog', '$materialLib/dialog.dart', tokens).updateFile();
FABTemplate('FAB', '$materialLib/floating_action_button.dart', tokens).updateFile(); FABTemplate('FAB', '$materialLib/floating_action_button.dart', tokens).updateFile();
IconButtonTemplate('IconButton', '$materialLib/icon_button.dart', tokens).updateFile(); IconButtonTemplate('IconButton', '$materialLib/icon_button.dart', tokens).updateFile();
InputDecoratorTemplate('InputDecorator', '$materialLib/input_decorator.dart', tokens).updateFile();
NavigationBarTemplate('NavigationBar', '$materialLib/navigation_bar.dart', tokens).updateFile(); NavigationBarTemplate('NavigationBar', '$materialLib/navigation_bar.dart', tokens).updateFile();
NavigationRailTemplate('NavigationRail', '$materialLib/navigation_rail.dart', tokens).updateFile(); NavigationRailTemplate('NavigationRail', '$materialLib/navigation_rail.dart', tokens).updateFile();
SurfaceTintTemplate('SurfaceTint', '$materialLib/elevation_overlay.dart', tokens).updateFile(); SurfaceTintTemplate('SurfaceTint', '$materialLib/elevation_overlay.dart', tokens).updateFile();
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'template.dart';
class InputDecoratorTemplate extends TokenTemplate {
const InputDecoratorTemplate(super.blockName, super.fileName, super.tokens, {
super.colorSchemePrefix = '_colors.',
super.textThemePrefix = '_textTheme.'
});
@override
String generate() => '''
// Generated version ${tokens["version"]}
class _${blockName}DefaultsM3 extends InputDecorationTheme {
_${blockName}DefaultsM3(this.context)
: super();
final BuildContext context;
late final ColorScheme _colors = Theme.of(context).colorScheme;
late final TextTheme _textTheme = Theme.of(context).textTheme;
@override
TextStyle? get hintStyle => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return TextStyle(color: Theme.of(context).disabledColor);
}
return TextStyle(color: Theme.of(context).hintColor);
});
@override
Color? get fillColor => MaterialStateColor.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return ${componentColor("md.comp.filled-text-field.disabled.container")};
}
return ${componentColor("md.comp.filled-text-field.container")};
});
@override
BorderSide? get activeIndicatorBorder => MaterialStateBorderSide.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.error)) {
if (states.contains(MaterialState.hovered)) {
return ${border('md.comp.filled-text-field.error.hover.active-indicator')};
}
if (states.contains(MaterialState.focused)) {
return ${border('md.comp.filled-text-field.error.focus.active-indicator')};
}
return ${border('md.comp.filled-text-field.error.active-indicator')};
}
if (states.contains(MaterialState.hovered)) {
return ${border('md.comp.filled-text-field.hover.active-indicator')};
}
if (states.contains(MaterialState.focused)) {
return ${border('md.comp.filled-text-field.focus.active-indicator')};
}
if (states.contains(MaterialState.disabled)) {
return ${border('md.comp.filled-text-field.disabled.active-indicator')};
}
return ${border('md.comp.filled-text-field.active-indicator')};
});
@override
BorderSide? get outlineBorder => MaterialStateBorderSide.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.error)) {
if (states.contains(MaterialState.hovered)) {
return ${border('md.comp.outlined-text-field.error.hover.outline')};
}
if (states.contains(MaterialState.focused)) {
return ${border('md.comp.outlined-text-field.error.focus.outline')};
}
return ${border('md.comp.outlined-text-field.error.outline')};
}
if (states.contains(MaterialState.hovered)) {
return ${border('md.comp.outlined-text-field.hover.outline')};
}
if (states.contains(MaterialState.focused)) {
return ${border('md.comp.outlined-text-field.focus.outline')};
}
if (states.contains(MaterialState.disabled)) {
return ${border('md.comp.outlined-text-field.disabled.outline')};
}
return ${border('md.comp.outlined-text-field.outline')};
});
@override
Color? get iconColor => ${componentColor("md.comp.filled-text-field.leading-icon")};
@override
Color? get prefixIconColor => MaterialStateColor.resolveWith((Set<MaterialState> states) {
if(states.contains(MaterialState.error)) {
if (states.contains(MaterialState.hovered)) {
return ${componentColor('md.comp.filled-text-field.error.hover.leading-icon')};
}
if (states.contains(MaterialState.focused)) {
return ${componentColor('md.comp.filled-text-field.error.focus.leading-icon')};
}
return ${componentColor('md.comp.filled-text-field.error.leading-icon')};
}
if (states.contains(MaterialState.hovered)) {
return ${componentColor('md.comp.filled-text-field.hover.leading-icon')};
}
if (states.contains(MaterialState.focused)) {
return ${componentColor('md.comp.filled-text-field.focus.leading-icon')};
}
if (states.contains(MaterialState.disabled)) {
return ${componentColor('md.comp.filled-text-field.disabled.leading-icon')};
}
return ${componentColor('md.comp.filled-text-field.leading-icon')};
});
@override
Color? get suffixIconColor => MaterialStateColor.resolveWith((Set<MaterialState> states) {
if(states.contains(MaterialState.error)) {
if (states.contains(MaterialState.hovered)) {
return ${componentColor('md.comp.filled-text-field.error.hover.trailing-icon')};
}
if (states.contains(MaterialState.focused)) {
return ${componentColor('md.comp.filled-text-field.error.focus.trailing-icon')};
}
return ${componentColor('md.comp.filled-text-field.error.trailing-icon')};
}
if (states.contains(MaterialState.hovered)) {
return ${componentColor('md.comp.filled-text-field.hover.trailing-icon')};
}
if (states.contains(MaterialState.focused)) {
return ${componentColor('md.comp.filled-text-field.focus.trailing-icon')};
}
if (states.contains(MaterialState.disabled)) {
return ${componentColor('md.comp.filled-text-field.disabled.trailing-icon')};
}
return ${componentColor('md.comp.filled-text-field.trailing-icon')};
});
@override
TextStyle? get labelStyle => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
final TextStyle textStyle= ${textStyle("md.comp.filled-text-field.label-text")} ?? const TextStyle();
if(states.contains(MaterialState.error)) {
if (states.contains(MaterialState.hovered)) {
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.error.hover.label-text')});
}
if (states.contains(MaterialState.focused)) {
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.error.focus.label-text')});
}
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.error.label-text')});
}
if (states.contains(MaterialState.hovered)) {
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.hover.label-text')});
}
if (states.contains(MaterialState.focused)) {
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.focus.label-text')});
}
if (states.contains(MaterialState.disabled)) {
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.disabled.label-text')});
}
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.label-text')});
});
@override
TextStyle? get floatingLabelStyle => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
final TextStyle textStyle= ${textStyle("md.comp.filled-text-field.label-text")} ?? const TextStyle();
if(states.contains(MaterialState.error)) {
if (states.contains(MaterialState.hovered)) {
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.error.hover.label-text')});
}
if (states.contains(MaterialState.focused)) {
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.error.focus.label-text')});
}
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.error.label-text')});
}
if (states.contains(MaterialState.hovered)) {
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.hover.label-text')});
}
if (states.contains(MaterialState.focused)) {
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.focus.label-text')});
}
if (states.contains(MaterialState.disabled)) {
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.disabled.label-text')});
}
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.label-text')});
});
@override
TextStyle? get helperStyle => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
final TextStyle textStyle= ${textStyle("md.comp.filled-text-field.supporting-text")} ?? const TextStyle();
if (states.contains(MaterialState.hovered)) {
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.hover.supporting-text')});
}
if (states.contains(MaterialState.focused)) {
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.focus.supporting-text')});
}
if (states.contains(MaterialState.disabled)) {
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.disabled.supporting-text')});
}
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.supporting-text')});
});
@override
TextStyle? get errorStyle => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
final TextStyle textStyle= ${textStyle("md.comp.filled-text-field.supporting-text")} ?? const TextStyle();
if (states.contains(MaterialState.hovered)) {
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.error.hover.supporting-text')});
}
if (states.contains(MaterialState.focused)) {
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.error.focus.supporting-text')});
}
return textStyle.copyWith(color:${componentColor('md.comp.filled-text-field.error.supporting-text')});
});
}
''';
}
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flutter code sample for Material Design 3 TextFields.
import 'package:flutter/material.dart';
void main() { runApp(const TextFieldExamplesApp()); }
class TextFieldExamplesApp extends StatelessWidget {
const TextFieldExamplesApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(colorSchemeSeed: const Color(0xff6750a4), useMaterial3: true),
home: Scaffold(
appBar: AppBar(title: const Text('TextField Examples')),
body: Column(
children: const <Widget>[
Spacer(),
FilledTextFieldExample(),
OutlinedTextFieldExample(),
Spacer(),
],
),
),
);
}
}
/// An example of the filled text field type.
///
/// A filled [TextField] with default settings matching the spec:
/// https://m3.material.io/components/text-fields/specs#6d654d1d-262e-4697-858c-9a75e8e7c81d
class FilledTextFieldExample extends StatelessWidget {
const FilledTextFieldExample({ super.key });
@override
Widget build(BuildContext context) {
return const TextField(
decoration: InputDecoration(
prefixIcon: Icon(Icons.search),
suffixIcon: Icon(Icons.clear),
labelText: 'Filled',
hintText: 'hint text',
helperText: 'supporting text',
filled: true,
)
);
}
}
/// An example of the outlined text field type.
///
/// A Outlined [TextField] with default settings matching the spec:
/// https://m3.material.io/components/text-fields/specs#68b00bd6-ab40-4b4f-93d9-ed1fbbc5d06e
class OutlinedTextFieldExample extends StatelessWidget {
const OutlinedTextFieldExample({ super.key });
@override
Widget build(BuildContext context) {
return const TextField(
decoration: InputDecoration(
prefixIcon: Icon(Icons.search),
suffixIcon: Icon(Icons.clear),
labelText: 'Outlined',
hintText: 'hint text',
helperText: 'supporting text',
border: OutlineInputBorder(),
),
);
}
}
...@@ -9,10 +9,13 @@ import 'package:flutter/foundation.dart'; ...@@ -9,10 +9,13 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'color_scheme.dart';
import 'colors.dart'; import 'colors.dart';
import 'constants.dart'; import 'constants.dart';
import 'input_border.dart'; import 'input_border.dart';
import 'material.dart';
import 'material_state.dart'; import 'material_state.dart';
import 'text_theme.dart';
import 'theme.dart'; import 'theme.dart';
import 'theme_data.dart'; import 'theme_data.dart';
...@@ -1944,14 +1947,15 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat ...@@ -1944,14 +1947,15 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
} }
} }
Color _getActiveColor(ThemeData themeData) { Color _getDefaultM2BorderColor(ThemeData themeData) {
if (isFocused) { if (!decoration.enabled && !isFocused) {
return themeData.colorScheme.primary; return ((decoration.filled ?? false) && !(decoration.border?.isOutline ?? false))
? Colors.transparent
: themeData.disabledColor;
}
if (decoration.errorText != null) {
return themeData.errorColor;
} }
return themeData.hintColor;
}
Color _getDefaultBorderColor(ThemeData themeData) {
if (isFocused) { if (isFocused) {
return themeData.colorScheme.primary; return themeData.colorScheme.primary;
} }
...@@ -1966,27 +1970,14 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat ...@@ -1966,27 +1970,14 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
return enabledColor; return enabledColor;
} }
Color _getFillColor(ThemeData themeData) { Color _getFillColor(ThemeData themeData, InputDecorationTheme defaults) {
if (decoration.filled != true) { // filled == null same as filled == false if (decoration.filled != true) { // filled == null same as filled == false
return Colors.transparent; return Colors.transparent;
} }
if (decoration.fillColor != null) { if (decoration.fillColor != null) {
return MaterialStateProperty.resolveAs(decoration.fillColor!, materialState); return MaterialStateProperty.resolveAs(decoration.fillColor!, materialState);
} }
return MaterialStateProperty.resolveAs(defaults.fillColor!, materialState);
// dark theme: 10% white (enabled), 5% white (disabled)
// light theme: 4% black (enabled), 2% black (disabled)
const Color darkEnabled = Color(0x1AFFFFFF);
const Color darkDisabled = Color(0x0DFFFFFF);
const Color lightEnabled = Color(0x0A000000);
const Color lightDisabled = Color(0x05000000);
switch (themeData.brightness) {
case Brightness.dark:
return decoration.enabled ? darkEnabled : darkDisabled;
case Brightness.light:
return decoration.enabled ? lightEnabled : lightDisabled;
}
} }
Color _getHoverColor(ThemeData themeData) { Color _getHoverColor(ThemeData themeData) {
...@@ -1996,35 +1987,19 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat ...@@ -1996,35 +1987,19 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
return decoration.hoverColor ?? themeData.inputDecorationTheme.hoverColor ?? themeData.hoverColor; return decoration.hoverColor ?? themeData.inputDecorationTheme.hoverColor ?? themeData.hoverColor;
} }
Color _getIconColor(ThemeData themeData) { Color _getIconColor(ThemeData themeData, InputDecorationTheme defaults) {
Color resolveIconColor(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled) && !states.contains(MaterialState.focused)) {
return themeData.disabledColor;
}
if (states.contains(MaterialState.focused)) {
return themeData.colorScheme.primary;
}
switch (themeData.brightness) {
case Brightness.dark:
return Colors.white70;
case Brightness.light:
return Colors.black45;
}
}
return MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.iconColor, materialState) return MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.iconColor, materialState)
?? MaterialStateProperty.resolveWith(resolveIconColor).resolve(materialState); ?? MaterialStateProperty.resolveAs(defaults.iconColor!, materialState);
} }
Color _getPrefixIconColor(ThemeData themeData) { Color _getPrefixIconColor(ThemeData themeData, InputDecorationTheme defaults) {
return MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.prefixIconColor, materialState) return MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.prefixIconColor, materialState)
?? _getIconColor(themeData); ?? MaterialStateProperty.resolveAs(defaults.prefixIconColor!, materialState);
} }
Color _getSuffixIconColor(ThemeData themeData) { Color _getSuffixIconColor(ThemeData themeData, InputDecorationTheme defaults) {
return MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.suffixIconColor, materialState) return MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.suffixIconColor, materialState)
?? _getIconColor(themeData); ?? MaterialStateProperty.resolveAs(defaults.suffixIconColor!, materialState);
} }
// True if the label will be shown and the hint will not. // True if the label will be shown and the hint will not.
...@@ -2042,10 +2017,8 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat ...@@ -2042,10 +2017,8 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
// The base style for the inline label when they're displayed "inline", // The base style for the inline label when they're displayed "inline",
// i.e. when they appear in place of the empty text field. // i.e. when they appear in place of the empty text field.
TextStyle _getInlineLabelStyle(ThemeData themeData) { TextStyle _getInlineLabelStyle(ThemeData themeData, InputDecorationTheme defaults) {
final TextStyle defaultStyle = TextStyle( final TextStyle defaultStyle = MaterialStateProperty.resolveAs(defaults.labelStyle!, materialState);
color: decoration.enabled ? themeData.hintColor : themeData.disabledColor,
);
final TextStyle? style = MaterialStateProperty.resolveAs(decoration.labelStyle, materialState) final TextStyle? style = MaterialStateProperty.resolveAs(decoration.labelStyle, materialState)
?? MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.labelStyle, materialState); ?? MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.labelStyle, materialState);
...@@ -2059,10 +2032,8 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat ...@@ -2059,10 +2032,8 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
// The base style for the inline hint when they're displayed "inline", // The base style for the inline hint when they're displayed "inline",
// i.e. when they appear in place of the empty text field. // i.e. when they appear in place of the empty text field.
TextStyle _getInlineHintStyle(ThemeData themeData) { TextStyle _getInlineHintStyle(ThemeData themeData, InputDecorationTheme defaults) {
final TextStyle defaultStyle = TextStyle( final TextStyle defaultStyle = MaterialStateProperty.resolveAs(defaults.hintStyle!, materialState);
color: decoration.enabled ? themeData.hintColor : themeData.disabledColor,
);
final TextStyle? style = MaterialStateProperty.resolveAs(decoration.hintStyle, materialState) final TextStyle? style = MaterialStateProperty.resolveAs(decoration.hintStyle, materialState)
?? MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.hintStyle, materialState); ?? MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.hintStyle, materialState);
...@@ -2073,15 +2044,12 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat ...@@ -2073,15 +2044,12 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
.merge(style); .merge(style);
} }
TextStyle _getFloatingLabelStyle(ThemeData themeData) { TextStyle _getFloatingLabelStyle(ThemeData themeData, InputDecorationTheme defaults) {
TextStyle getFallbackTextStyle() { TextStyle defaultTextStyle = MaterialStateProperty.resolveAs(defaults.floatingLabelStyle!, materialState);
final Color color = decoration.errorText != null if (decoration.errorText != null && decoration.errorStyle?.color != null) {
? decoration.errorStyle?.color ?? themeData.errorColor defaultTextStyle = defaultTextStyle.copyWith(color: decoration.errorStyle?.color);
: _getActiveColor(themeData);
return TextStyle(color: decoration.enabled ? color : themeData.disabledColor)
.merge(decoration.floatingLabelStyle ?? decoration.labelStyle);
} }
defaultTextStyle = defaultTextStyle.merge(decoration.floatingLabelStyle ?? decoration.labelStyle);
final TextStyle? style = MaterialStateProperty.resolveAs(decoration.floatingLabelStyle, materialState) final TextStyle? style = MaterialStateProperty.resolveAs(decoration.floatingLabelStyle, materialState)
?? MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.floatingLabelStyle, materialState); ?? MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.floatingLabelStyle, materialState);
...@@ -2089,18 +2057,18 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat ...@@ -2089,18 +2057,18 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
return themeData.textTheme.subtitle1! return themeData.textTheme.subtitle1!
.merge(widget.baseStyle) .merge(widget.baseStyle)
.copyWith(height: 1) .copyWith(height: 1)
.merge(getFallbackTextStyle()) .merge(defaultTextStyle)
.merge(style); .merge(style);
} }
TextStyle _getHelperStyle(ThemeData themeData) { TextStyle _getHelperStyle(ThemeData themeData, InputDecorationTheme defaults) {
final Color color = decoration.enabled ? themeData.hintColor : Colors.transparent; return MaterialStateProperty.resolveAs(defaults.helperStyle!, materialState)
return themeData.textTheme.caption!.copyWith(color: color).merge(MaterialStateProperty.resolveAs(decoration.helperStyle, materialState)); .merge(MaterialStateProperty.resolveAs(decoration.helperStyle, materialState));
} }
TextStyle _getErrorStyle(ThemeData themeData) { TextStyle _getErrorStyle(ThemeData themeData, InputDecorationTheme defaults) {
final Color color = decoration.enabled ? themeData.errorColor : Colors.transparent; return MaterialStateProperty.resolveAs(defaults.errorStyle!, materialState)
return themeData.textTheme.caption!.copyWith(color: color).merge(decoration.errorStyle); .merge(decoration.errorStyle);
} }
Set<MaterialState> get materialState { Set<MaterialState> get materialState {
...@@ -2112,7 +2080,8 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat ...@@ -2112,7 +2080,8 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
}; };
} }
InputBorder _getDefaultBorder(ThemeData themeData) {
InputBorder _getDefaultBorder(ThemeData themeData, InputDecorationTheme defaults) {
final InputBorder border = MaterialStateProperty.resolveAs(decoration.border, materialState) final InputBorder border = MaterialStateProperty.resolveAs(decoration.border, materialState)
?? const UnderlineInputBorder(); ?? const UnderlineInputBorder();
...@@ -2124,34 +2093,39 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat ...@@ -2124,34 +2093,39 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
return border; return border;
} }
final Color borderColor; if (themeData.useMaterial3) {
if (decoration.enabled || isFocused) { if (decoration.filled!) {
borderColor = decoration.errorText == null return border.copyWith(
? _getDefaultBorderColor(themeData) borderSide: MaterialStateProperty.resolveAs(defaults.activeIndicatorBorder, materialState),
: themeData.errorColor; );
} else { } else {
borderColor = ((decoration.filled ?? false) && !(decoration.border?.isOutline ?? false)) return border.copyWith(
? Colors.transparent borderSide: MaterialStateProperty.resolveAs(defaults.outlineBorder, materialState),
: themeData.disabledColor; );
}
} }
else{
final double borderWeight; return border.copyWith(
if (decoration.isCollapsed || decoration.border == InputBorder.none || !decoration.enabled) { borderSide: BorderSide(
borderWeight = 0.0; color: _getDefaultM2BorderColor(themeData),
} else { width: (decoration.isCollapsed || decoration.border == InputBorder.none || !decoration.enabled)
borderWeight = isFocused ? 2.0 : 1.0; ? 0.0
: isFocused ? 2.0 : 1.0,
),
);
} }
return border.copyWith(borderSide: BorderSide(color: borderColor, width: borderWeight));
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context); final ThemeData themeData = Theme.of(context);
final TextStyle labelStyle = _getInlineLabelStyle(themeData); final InputDecorationTheme defaults =
Theme.of(context).useMaterial3 ? _InputDecoratorDefaultsM3(context) : _InputDecoratorDefaultsM2(context);
final TextStyle labelStyle = _getInlineLabelStyle(themeData, defaults);
final TextBaseline textBaseline = labelStyle.textBaseline!; final TextBaseline textBaseline = labelStyle.textBaseline!;
final TextStyle hintStyle = _getInlineHintStyle(themeData); final TextStyle hintStyle = _getInlineHintStyle(themeData, defaults);
final String? hintText = decoration.hintText; final String? hintText = decoration.hintText;
final Widget? hint = hintText == null ? null : AnimatedOpacity( final Widget? hint = hintText == null ? null : AnimatedOpacity(
opacity: (isEmpty && !_hasInlineLabel) ? 1.0 : 0.0, opacity: (isEmpty && !_hasInlineLabel) ? 1.0 : 0.0,
...@@ -2177,13 +2151,13 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat ...@@ -2177,13 +2151,13 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
} else { } else {
border = isError ? decoration.errorBorder : decoration.enabledBorder; border = isError ? decoration.errorBorder : decoration.enabledBorder;
} }
border ??= _getDefaultBorder(themeData); border ??= _getDefaultBorder(themeData, defaults);
final Widget container = _BorderContainer( final Widget container = _BorderContainer(
border: border, border: border,
gap: _borderGap, gap: _borderGap,
gapAnimation: _floatingLabelController.view, gapAnimation: _floatingLabelController.view,
fillColor: _getFillColor(themeData), fillColor: _getFillColor(themeData, defaults),
hoverColor: _getHoverColor(themeData), hoverColor: _getHoverColor(themeData),
isHovering: isHovering, isHovering: isHovering,
); );
...@@ -2198,7 +2172,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat ...@@ -2198,7 +2172,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
duration:_kTransitionDuration, duration:_kTransitionDuration,
curve: _kTransitionCurve, curve: _kTransitionCurve,
style: widget._labelShouldWithdraw style: widget._labelShouldWithdraw
? _getFloatingLabelStyle(themeData) ? _getFloatingLabelStyle(themeData, defaults)
: labelStyle, : labelStyle,
child: decoration.label ?? Text( child: decoration.label ?? Text(
decoration.labelText!, decoration.labelText!,
...@@ -2234,7 +2208,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat ...@@ -2234,7 +2208,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
padding: const EdgeInsetsDirectional.only(end: 16.0), padding: const EdgeInsetsDirectional.only(end: 16.0),
child: IconTheme.merge( child: IconTheme.merge(
data: IconThemeData( data: IconThemeData(
color: _getIconColor(themeData), color: _getIconColor(themeData, defaults),
size: iconSize, size: iconSize,
), ),
child: decoration.icon!, child: decoration.icon!,
...@@ -2254,7 +2228,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat ...@@ -2254,7 +2228,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
), ),
child: IconTheme.merge( child: IconTheme.merge(
data: IconThemeData( data: IconThemeData(
color: _getPrefixIconColor(themeData), color: _getPrefixIconColor(themeData, defaults),
size: iconSize, size: iconSize,
), ),
child: decoration.prefixIcon!, child: decoration.prefixIcon!,
...@@ -2275,7 +2249,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat ...@@ -2275,7 +2249,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
), ),
child: IconTheme.merge( child: IconTheme.merge(
data: IconThemeData( data: IconThemeData(
color: _getSuffixIconColor(themeData), color: _getSuffixIconColor(themeData, defaults),
size: iconSize, size: iconSize,
), ),
child: decoration.suffixIcon!, child: decoration.suffixIcon!,
...@@ -2286,10 +2260,10 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat ...@@ -2286,10 +2260,10 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
final Widget helperError = _HelperError( final Widget helperError = _HelperError(
textAlign: textAlign, textAlign: textAlign,
helperText: decoration.helperText, helperText: decoration.helperText,
helperStyle: _getHelperStyle(themeData), helperStyle: _getHelperStyle(themeData, defaults),
helperMaxLines: decoration.helperMaxLines, helperMaxLines: decoration.helperMaxLines,
errorText: decoration.errorText, errorText: decoration.errorText,
errorStyle: _getErrorStyle(themeData), errorStyle: _getErrorStyle(themeData, defaults),
errorMaxLines: decoration.errorMaxLines, errorMaxLines: decoration.errorMaxLines,
); );
...@@ -2302,7 +2276,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat ...@@ -2302,7 +2276,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
liveRegion: isFocused, liveRegion: isFocused,
child: Text( child: Text(
decoration.counterText!, decoration.counterText!,
style: _getHelperStyle(themeData).merge(MaterialStateProperty.resolveAs(decoration.counterStyle, materialState)), style: _getHelperStyle(themeData, defaults).merge(MaterialStateProperty.resolveAs(decoration.counterStyle, materialState)),
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
semanticsLabel: decoration.semanticCounterText, semanticsLabel: decoration.semanticCounterText,
), ),
...@@ -2325,14 +2299,18 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat ...@@ -2325,14 +2299,18 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
if (decoration.filled ?? false) { if (decoration.filled ?? false) {
contentPadding = decorationContentPadding ?? (decorationIsDense contentPadding = decorationContentPadding ?? (decorationIsDense
? const EdgeInsets.fromLTRB(12.0, 8.0, 12.0, 8.0) ? const EdgeInsets.fromLTRB(12.0, 8.0, 12.0, 8.0)
: const EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 12.0)); : themeData.useMaterial3
? const EdgeInsets.fromLTRB(12.0, 12.75, 12.0, 12.75)
: const EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 12.0));
} else { } else {
// Not left or right padding for underline borders that aren't filled // Not left or right padding for underline borders that aren't filled
// is a small concession to backwards compatibility. This eliminates // is a small concession to backwards compatibility. This eliminates
// the most noticeable layout change introduced by #13734. // the most noticeable layout change introduced by #13734.
contentPadding = decorationContentPadding ?? (decorationIsDense contentPadding = decorationContentPadding ?? (decorationIsDense
? const EdgeInsets.fromLTRB(0.0, 8.0, 0.0, 8.0) ? const EdgeInsets.fromLTRB(0.0, 8.0, 0.0, 8.0)
: const EdgeInsets.fromLTRB(0.0, 12.0, 0.0, 12.0)); : themeData.useMaterial3
? const EdgeInsets.fromLTRB(0.0, 12.75, 0.0, 12.75)
: const EdgeInsets.fromLTRB(0.0, 12.0, 0.0, 12.0));
} }
} else { } else {
floatingLabelHeight = 0.0; floatingLabelHeight = 0.0;
...@@ -3752,6 +3730,8 @@ class InputDecorationTheme with Diagnosticable { ...@@ -3752,6 +3730,8 @@ class InputDecorationTheme with Diagnosticable {
this.counterStyle, this.counterStyle,
this.filled = false, this.filled = false,
this.fillColor, this.fillColor,
this.activeIndicatorBorder,
this.outlineBorder,
this.focusColor, this.focusColor,
this.hoverColor, this.hoverColor,
this.errorBorder, this.errorBorder,
...@@ -3936,6 +3916,12 @@ class InputDecorationTheme with Diagnosticable { ...@@ -3936,6 +3916,12 @@ class InputDecorationTheme with Diagnosticable {
/// true and bordered per the [border]. /// true and bordered per the [border].
final Color? fillColor; final Color? fillColor;
/// The borderSide of the OutlineInputBorder with `color` and `weight`.
final BorderSide? outlineBorder;
/// The borderSide of the UnderlineInputBorder with `color` and `weight`.
final BorderSide? activeIndicatorBorder;
/// The color to blend with the decoration's [fillColor] with, if [filled] is /// The color to blend with the decoration's [fillColor] with, if [filled] is
/// true and the container has the input focus. /// true and the container has the input focus.
/// ///
...@@ -4155,6 +4141,8 @@ class InputDecorationTheme with Diagnosticable { ...@@ -4155,6 +4141,8 @@ class InputDecorationTheme with Diagnosticable {
TextStyle? counterStyle, TextStyle? counterStyle,
bool? filled, bool? filled,
Color? fillColor, Color? fillColor,
BorderSide? activeIndicatorBorder,
BorderSide? outlineBorder,
Color? focusColor, Color? focusColor,
Color? hoverColor, Color? hoverColor,
InputBorder? errorBorder, InputBorder? errorBorder,
...@@ -4187,6 +4175,8 @@ class InputDecorationTheme with Diagnosticable { ...@@ -4187,6 +4175,8 @@ class InputDecorationTheme with Diagnosticable {
counterStyle: counterStyle ?? this.counterStyle, counterStyle: counterStyle ?? this.counterStyle,
filled: filled ?? this.filled, filled: filled ?? this.filled,
fillColor: fillColor ?? this.fillColor, fillColor: fillColor ?? this.fillColor,
activeIndicatorBorder: activeIndicatorBorder ?? this.activeIndicatorBorder,
outlineBorder: outlineBorder ?? this.outlineBorder,
focusColor: focusColor ?? this.focusColor, focusColor: focusColor ?? this.focusColor,
hoverColor: hoverColor ?? this.hoverColor, hoverColor: hoverColor ?? this.hoverColor,
errorBorder: errorBorder ?? this.errorBorder, errorBorder: errorBorder ?? this.errorBorder,
...@@ -4223,6 +4213,8 @@ class InputDecorationTheme with Diagnosticable { ...@@ -4223,6 +4213,8 @@ class InputDecorationTheme with Diagnosticable {
filled, filled,
Object.hash( Object.hash(
fillColor, fillColor,
activeIndicatorBorder,
outlineBorder,
focusColor, focusColor,
hoverColor, hoverColor,
errorBorder, errorBorder,
...@@ -4265,6 +4257,8 @@ class InputDecorationTheme with Diagnosticable { ...@@ -4265,6 +4257,8 @@ class InputDecorationTheme with Diagnosticable {
&& other.floatingLabelAlignment == floatingLabelAlignment && other.floatingLabelAlignment == floatingLabelAlignment
&& other.filled == filled && other.filled == filled
&& other.fillColor == fillColor && other.fillColor == fillColor
&& other.activeIndicatorBorder == activeIndicatorBorder
&& other.outlineBorder == outlineBorder
&& other.focusColor == focusColor && other.focusColor == focusColor
&& other.hoverColor == hoverColor && other.hoverColor == hoverColor
&& other.errorBorder == errorBorder && other.errorBorder == errorBorder
...@@ -4302,6 +4296,8 @@ class InputDecorationTheme with Diagnosticable { ...@@ -4302,6 +4296,8 @@ class InputDecorationTheme with Diagnosticable {
properties.add(DiagnosticsProperty<TextStyle>('counterStyle', counterStyle, defaultValue: defaultTheme.counterStyle)); properties.add(DiagnosticsProperty<TextStyle>('counterStyle', counterStyle, defaultValue: defaultTheme.counterStyle));
properties.add(DiagnosticsProperty<bool>('filled', filled, defaultValue: defaultTheme.filled)); properties.add(DiagnosticsProperty<bool>('filled', filled, defaultValue: defaultTheme.filled));
properties.add(ColorProperty('fillColor', fillColor, defaultValue: defaultTheme.fillColor)); properties.add(ColorProperty('fillColor', fillColor, defaultValue: defaultTheme.fillColor));
properties.add(DiagnosticsProperty<BorderSide>('activeIndicatorBorder', activeIndicatorBorder, defaultValue: defaultTheme.activeIndicatorBorder));
properties.add(DiagnosticsProperty<BorderSide>('outlineBorder', outlineBorder, defaultValue: defaultTheme.outlineBorder));
properties.add(ColorProperty('focusColor', focusColor, defaultValue: defaultTheme.focusColor)); properties.add(ColorProperty('focusColor', focusColor, defaultValue: defaultTheme.focusColor));
properties.add(ColorProperty('hoverColor', hoverColor, defaultValue: defaultTheme.hoverColor)); properties.add(ColorProperty('hoverColor', hoverColor, defaultValue: defaultTheme.hoverColor));
properties.add(DiagnosticsProperty<InputBorder>('errorBorder', errorBorder, defaultValue: defaultTheme.errorBorder)); properties.add(DiagnosticsProperty<InputBorder>('errorBorder', errorBorder, defaultValue: defaultTheme.errorBorder));
...@@ -4314,3 +4310,335 @@ class InputDecorationTheme with Diagnosticable { ...@@ -4314,3 +4310,335 @@ class InputDecorationTheme with Diagnosticable {
properties.add(DiagnosticsProperty<BoxConstraints>('constraints', constraints, defaultValue: defaultTheme.constraints)); properties.add(DiagnosticsProperty<BoxConstraints>('constraints', constraints, defaultValue: defaultTheme.constraints));
} }
} }
class _InputDecoratorDefaultsM2 extends InputDecorationTheme {
const _InputDecoratorDefaultsM2(this.context)
: super();
final BuildContext context;
@override
TextStyle? get hintStyle => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return TextStyle(color: Theme.of(context).disabledColor);
}
return TextStyle(color: Theme.of(context).hintColor);
});
@override
TextStyle? get labelStyle => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return TextStyle(color: Theme.of(context).disabledColor);
}
return TextStyle(color: Theme.of(context).hintColor);
});
@override
TextStyle? get floatingLabelStyle => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return TextStyle(color: Theme.of(context).disabledColor);
}
if (states.contains(MaterialState.error)) {
return TextStyle(color: Theme.of(context).errorColor);
}
if (states.contains(MaterialState.focused)) {
return TextStyle(color: Theme.of(context).colorScheme.primary);
}
return TextStyle(color: Theme.of(context).hintColor);
});
@override
TextStyle? get helperStyle => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
final ThemeData themeData= Theme.of(context);
if (states.contains(MaterialState.disabled)) {
return themeData.textTheme.caption!.copyWith(color: Colors.transparent);
}
return themeData.textTheme.caption!.copyWith(color: themeData.hintColor);
});
@override
TextStyle? get errorStyle => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
final ThemeData themeData= Theme.of(context);
if (states.contains(MaterialState.disabled)) {
return themeData.textTheme.caption!.copyWith(color: Colors.transparent);
}
return themeData.textTheme.caption!.copyWith(color: themeData.errorColor);
});
@override
Color? get fillColor => MaterialStateColor.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
// dark theme: 5% white
// light theme: 2% black
switch (Theme.of(context).brightness) {
case Brightness.dark:
return const Color(0x0DFFFFFF);
case Brightness.light:
return const Color(0x05000000) ;
}
}
// dark theme: 10% white
// light theme: 4% black
switch (Theme.of(context).brightness) {
case Brightness.dark: return const Color(0x1AFFFFFF);
case Brightness.light:return const Color(0x0A000000) ;
}
});
@override
Color? get iconColor => MaterialStateColor.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled) && !states.contains(MaterialState.focused)) {
return Theme.of(context).disabledColor;
}
if (states.contains(MaterialState.focused)) {
return Theme.of(context).colorScheme.primary;
}
switch (Theme.of(context).brightness) {
case Brightness.dark:
return Colors.white70;
case Brightness.light:
return Colors.black45;
}
});
@override
Color? get prefixIconColor => MaterialStateColor.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled) && !states.contains(MaterialState.focused)) {
return Theme.of(context).disabledColor;
}
if (states.contains(MaterialState.focused)) {
return Theme.of(context).colorScheme.primary;
}
switch (Theme.of(context).brightness) {
case Brightness.dark:
return Colors.white70;
case Brightness.light:
return Colors.black45;
}
});
@override
Color? get suffixIconColor => MaterialStateColor.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled) && !states.contains(MaterialState.focused)) {
return Theme.of(context).disabledColor;
}
if (states.contains(MaterialState.focused)) {
return Theme.of(context).colorScheme.primary;
}
switch (Theme.of(context).brightness) {
case Brightness.dark:
return Colors.white70;
case Brightness.light:
return Colors.black45;
}
});
}
// BEGIN GENERATED TOKEN PROPERTIES - InputDecorator
// Do not edit by hand. The code between the "BEGIN GENERATED" and
// "END GENERATED" comments are generated from data in the Material
// Design token database by the script:
// dev/tools/gen_defaults/bin/gen_defaults.dart.
// Token database version: v0_101
// Generated version v0_101
class _InputDecoratorDefaultsM3 extends InputDecorationTheme {
_InputDecoratorDefaultsM3(this.context)
: super();
final BuildContext context;
late final ColorScheme _colors = Theme.of(context).colorScheme;
late final TextTheme _textTheme = Theme.of(context).textTheme;
@override
TextStyle? get hintStyle => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return TextStyle(color: Theme.of(context).disabledColor);
}
return TextStyle(color: Theme.of(context).hintColor);
});
@override
Color? get fillColor => MaterialStateColor.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return _colors.onSurface.withOpacity(0.04);
}
return _colors.surfaceVariant;
});
@override
BorderSide? get activeIndicatorBorder => MaterialStateBorderSide.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.error)) {
if (states.contains(MaterialState.hovered)) {
return BorderSide(color: _colors.onErrorContainer);
}
if (states.contains(MaterialState.focused)) {
return BorderSide(color: _colors.error);
}
return BorderSide(color: _colors.error);
}
if (states.contains(MaterialState.hovered)) {
return BorderSide(color: _colors.onSurface);
}
if (states.contains(MaterialState.focused)) {
return BorderSide(color: _colors.primary);
}
if (states.contains(MaterialState.disabled)) {
return BorderSide(color: _colors.onSurface.withOpacity(0.38));
}
return BorderSide(color: _colors.onSurfaceVariant);
});
@override
BorderSide? get outlineBorder => MaterialStateBorderSide.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.error)) {
if (states.contains(MaterialState.hovered)) {
return BorderSide(color: _colors.onErrorContainer);
}
if (states.contains(MaterialState.focused)) {
return BorderSide(color: _colors.error);
}
return BorderSide(color: _colors.error);
}
if (states.contains(MaterialState.hovered)) {
return BorderSide(color: _colors.onSurface);
}
if (states.contains(MaterialState.focused)) {
return BorderSide(color: _colors.primary, width: 2.0);
}
if (states.contains(MaterialState.disabled)) {
return BorderSide(color: _colors.onSurface.withOpacity(0.12));
}
return BorderSide(color: _colors.outline);
});
@override
Color? get iconColor => _colors.onSurfaceVariant;
@override
Color? get prefixIconColor => MaterialStateColor.resolveWith((Set<MaterialState> states) {
if(states.contains(MaterialState.error)) {
if (states.contains(MaterialState.hovered)) {
return _colors.onSurfaceVariant;
}
if (states.contains(MaterialState.focused)) {
return _colors.onSurfaceVariant;
}
return _colors.onSurfaceVariant;
}
if (states.contains(MaterialState.hovered)) {
return _colors.onSurfaceVariant;
}
if (states.contains(MaterialState.focused)) {
return _colors.onSurfaceVariant;
}
if (states.contains(MaterialState.disabled)) {
return _colors.onSurface.withOpacity(0.38);
}
return _colors.onSurfaceVariant;
});
@override
Color? get suffixIconColor => MaterialStateColor.resolveWith((Set<MaterialState> states) {
if(states.contains(MaterialState.error)) {
if (states.contains(MaterialState.hovered)) {
return _colors.onErrorContainer;
}
if (states.contains(MaterialState.focused)) {
return _colors.error;
}
return _colors.error;
}
if (states.contains(MaterialState.hovered)) {
return _colors.onSurfaceVariant;
}
if (states.contains(MaterialState.focused)) {
return _colors.onSurfaceVariant;
}
if (states.contains(MaterialState.disabled)) {
return _colors.onSurface.withOpacity(0.38);
}
return _colors.onSurfaceVariant;
});
@override
TextStyle? get labelStyle => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
final TextStyle textStyle= _textTheme.bodyLarge ?? const TextStyle();
if(states.contains(MaterialState.error)) {
if (states.contains(MaterialState.hovered)) {
return textStyle.copyWith(color:_colors.onErrorContainer);
}
if (states.contains(MaterialState.focused)) {
return textStyle.copyWith(color:_colors.error);
}
return textStyle.copyWith(color:_colors.error);
}
if (states.contains(MaterialState.hovered)) {
return textStyle.copyWith(color:_colors.onSurfaceVariant);
}
if (states.contains(MaterialState.focused)) {
return textStyle.copyWith(color:_colors.primary);
}
if (states.contains(MaterialState.disabled)) {
return textStyle.copyWith(color:_colors.onSurface.withOpacity(0.38));
}
return textStyle.copyWith(color:_colors.onSurfaceVariant);
});
@override
TextStyle? get floatingLabelStyle => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
final TextStyle textStyle= _textTheme.bodyLarge ?? const TextStyle();
if(states.contains(MaterialState.error)) {
if (states.contains(MaterialState.hovered)) {
return textStyle.copyWith(color:_colors.onErrorContainer);
}
if (states.contains(MaterialState.focused)) {
return textStyle.copyWith(color:_colors.error);
}
return textStyle.copyWith(color:_colors.error);
}
if (states.contains(MaterialState.hovered)) {
return textStyle.copyWith(color:_colors.onSurfaceVariant);
}
if (states.contains(MaterialState.focused)) {
return textStyle.copyWith(color:_colors.primary);
}
if (states.contains(MaterialState.disabled)) {
return textStyle.copyWith(color:_colors.onSurface.withOpacity(0.38));
}
return textStyle.copyWith(color:_colors.onSurfaceVariant);
});
@override
TextStyle? get helperStyle => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
final TextStyle textStyle= _textTheme.bodySmall ?? const TextStyle();
if (states.contains(MaterialState.hovered)) {
return textStyle.copyWith(color:_colors.onSurfaceVariant);
}
if (states.contains(MaterialState.focused)) {
return textStyle.copyWith(color:_colors.onSurfaceVariant);
}
if (states.contains(MaterialState.disabled)) {
return textStyle.copyWith(color:_colors.onSurface.withOpacity(0.38));
}
return textStyle.copyWith(color:_colors.onSurfaceVariant);
});
@override
TextStyle? get errorStyle => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
final TextStyle textStyle= _textTheme.bodySmall ?? const TextStyle();
if (states.contains(MaterialState.hovered)) {
return textStyle.copyWith(color:_colors.error);
}
if (states.contains(MaterialState.focused)) {
return textStyle.copyWith(color:_colors.error);
}
return textStyle.copyWith(color:_colors.error);
});
}
// END GENERATED TOKEN PROPERTIES - InputDecorator
...@@ -1183,6 +1183,7 @@ class ThemeData with Diagnosticable { ...@@ -1183,6 +1183,7 @@ class ThemeData with Diagnosticable {
/// * FAB: [FloatingActionButton] /// * FAB: [FloatingActionButton]
/// * Extended FAB: [FloatingActionButton.extended] /// * Extended FAB: [FloatingActionButton.extended]
/// * Cards: [Card] /// * Cards: [Card]
/// * TextFields: [TextField] together with its [InputDecoration]
/// * Chips: /// * Chips:
/// - [ActionChip] (used for Assist and Suggestion chips), /// - [ActionChip] (used for Assist and Suggestion chips),
/// - [FilterChip], [ChoiceChip] (used for single selection filter chips), /// - [FilterChip], [ChoiceChip] (used for single selection filter chips),
......
...@@ -24,6 +24,7 @@ Widget buildInputDecorator({ ...@@ -24,6 +24,7 @@ Widget buildInputDecorator({
bool isEmpty = false, bool isEmpty = false,
bool isFocused = false, bool isFocused = false,
bool isHovering = false, bool isHovering = false,
bool useMaterial3 = false,
TextStyle? baseStyle, TextStyle? baseStyle,
TextAlignVertical? textAlignVertical, TextAlignVertical? textAlignVertical,
VisualDensity? visualDensity, VisualDensity? visualDensity,
...@@ -40,6 +41,7 @@ Widget buildInputDecorator({ ...@@ -40,6 +41,7 @@ Widget buildInputDecorator({
data: (theme ?? Theme.of(context)).copyWith( data: (theme ?? Theme.of(context)).copyWith(
inputDecorationTheme: inputDecorationTheme, inputDecorationTheme: inputDecorationTheme,
visualDensity: visualDensity, visualDensity: visualDensity,
useMaterial3: useMaterial3,
), ),
child: Align( child: Align(
alignment: Alignment.topLeft, alignment: Alignment.topLeft,
...@@ -145,10 +147,12 @@ double getOpacity(WidgetTester tester, String textValue) { ...@@ -145,10 +147,12 @@ double getOpacity(WidgetTester tester, String textValue) {
} }
void main() { void main() {
for(final bool useMaterial3 in <bool>[true, false]){
testWidgets('InputDecorator input/label text layout', (WidgetTester tester) async { testWidgets('InputDecorator input/label text layout', (WidgetTester tester) async {
// The label appears above the input text // The label appears above the input text
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -166,16 +170,17 @@ void main() { ...@@ -166,16 +170,17 @@ void main() {
// 12 - bottom padding // 12 - bottom padding
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('text')).dy, 28.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 : 28.0);
expect(tester.getBottomLeft(find.text('text')).dy, 44.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
expect(tester.getTopLeft(find.text('label')).dy, 12.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
expect(tester.getBottomLeft(find.text('label')).dy, 24.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 1.0); expect(getBorderWeight(tester), 1.0);
// The label appears within the input when there is no text content // The label appears within the input when there is no text content
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -185,11 +190,12 @@ void main() { ...@@ -185,11 +190,12 @@ void main() {
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getTopLeft(find.text('label')).dy, 20.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);
// The label appears above the input text when there is no content and floatingLabelBehavior is always // The label appears above the input text when there is no content and floatingLabelBehavior is always
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -200,11 +206,12 @@ void main() { ...@@ -200,11 +206,12 @@ void main() {
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getTopLeft(find.text('label')).dy, 12.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
// The label appears within the input text when there is content and floatingLabelBehavior is never // The label appears within the input text when there is content and floatingLabelBehavior is never
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: 'label', labelText: 'label',
...@@ -214,7 +221,7 @@ void main() { ...@@ -214,7 +221,7 @@ void main() {
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getTopLeft(find.text('label')).dy, 20.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);
// Overall height for this InputDecorator is 56dps: // Overall height for this InputDecorator is 56dps:
// 12 - top padding // 12 - top padding
...@@ -223,12 +230,13 @@ void main() { ...@@ -223,12 +230,13 @@ void main() {
// 16 - input text (ahem font size 16dps) // 16 - input text (ahem font size 16dps)
// 12 - bottom padding // 12 - bottom padding
expect(tester.getTopLeft(find.text('label')).dy, 20.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);
// isFocused: true increases the border's weight from 1.0 to 2.0 // isFocused: true increases the border's weight from 1.0 to 2.0
// but does not change the overall height. // but does not change the overall height.
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
isFocused: true, isFocused: true,
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -238,16 +246,17 @@ void main() { ...@@ -238,16 +246,17 @@ void main() {
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('text')).dy, 28.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 : 28.0);
expect(tester.getBottomLeft(find.text('text')).dy, 44.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
expect(tester.getTopLeft(find.text('label')).dy, 12.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
expect(tester.getBottomLeft(find.text('label')).dy, 24.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 2.0); expect(getBorderWeight(tester), 2.0);
// isEmpty: true causes the label to be aligned with the input text // isEmpty: true causes the label to be aligned with the input text
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: 'label', labelText: 'label',
...@@ -267,16 +276,17 @@ void main() { ...@@ -267,16 +276,17 @@ void main() {
} }
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('text')).dy, 28.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 : 28.0);
expect(tester.getBottomLeft(find.text('text')).dy, 44.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
expect(tester.getTopLeft(find.text('label')).dy, 20.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);
expect(tester.getBottomLeft(find.text('label')).dy, 36.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0: 36.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 1.0); expect(getBorderWeight(tester), 1.0);
// isFocused: true causes the label to move back up above the input text. // isFocused: true causes the label to move back up above the input text.
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
isFocused: true, isFocused: true,
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -296,10 +306,10 @@ void main() { ...@@ -296,10 +306,10 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('text')).dy, 28.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 : 28.0);
expect(tester.getBottomLeft(find.text('text')).dy, 44.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
expect(tester.getTopLeft(find.text('label')).dy, 12.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
expect(tester.getBottomLeft(find.text('label')).dy, 24.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 2.0); expect(getBorderWeight(tester), 2.0);
...@@ -307,6 +317,7 @@ void main() { ...@@ -307,6 +317,7 @@ void main() {
// The widget's size and layout is the same as for enabled: true. // The widget's size and layout is the same as for enabled: true.
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: 'label', labelText: 'label',
...@@ -316,16 +327,17 @@ void main() { ...@@ -316,16 +327,17 @@ void main() {
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('text')).dy, 28.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 : 28.0);
expect(tester.getBottomLeft(find.text('text')).dy, 44.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
expect(tester.getTopLeft(find.text('label')).dy, 20.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);
expect(tester.getBottomLeft(find.text('label')).dy, 36.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0: 36.0);
expect(getBorderWeight(tester), 0.0); expect(getBorderWeight(tester), useMaterial3 ? 1.0 : 0.0);
// enabled: false produces a transparent border if filled: true. // enabled: false produces a transparent border if filled: true.
// The widget's size and layout is the same as for enabled: true. // The widget's size and layout is the same as for enabled: true.
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: 'label', labelText: 'label',
...@@ -336,16 +348,18 @@ void main() { ...@@ -336,16 +348,18 @@ void main() {
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('text')).dy, 28.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 : 28.0);
expect(tester.getBottomLeft(find.text('text')).dy, 44.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
expect(tester.getTopLeft(find.text('label')).dy, 20.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);
expect(tester.getBottomLeft(find.text('label')).dy, 36.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0: 36.0);
expect(getBorderColor(tester), Colors.transparent); final ThemeData theme = ThemeData.from(colorScheme: const ColorScheme.light());
expect(getBorderColor(tester), useMaterial3 ? theme.colorScheme.onSurface.withOpacity(0.38) : Colors.transparent);
// alignLabelWithHint: true positions the label at the text baseline, // alignLabelWithHint: true positions the label at the text baseline,
// aligned with the hint. // aligned with the hint.
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: 'label', labelText: 'label',
...@@ -356,8 +370,10 @@ void main() { ...@@ -356,8 +370,10 @@ void main() {
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('label')).dy, tester.getTopLeft(find.text('hint')).dy); if(!useMaterial3) {
expect(tester.getBottomLeft(find.text('label')).dy, tester.getBottomLeft(find.text('hint')).dy); expect(tester.getTopLeft(find.text('label')).dy, tester.getTopLeft(find.text('hint')).dy);
expect(tester.getBottomLeft(find.text('label')).dy, tester.getBottomLeft(find.text('hint')).dy);
}
}); });
testWidgets('InputDecorator input/label widget layout', (WidgetTester tester) async { testWidgets('InputDecorator input/label widget layout', (WidgetTester tester) async {
...@@ -366,6 +382,7 @@ void main() { ...@@ -366,6 +382,7 @@ void main() {
// The label appears above the input text. // The label appears above the input text.
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -394,16 +411,17 @@ void main() { ...@@ -394,16 +411,17 @@ void main() {
// 12 - bottom padding // 12 - bottom padding
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('text')).dy, 28.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 : 28.0);
expect(tester.getBottomLeft(find.text('text')).dy, 44.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
expect(tester.getTopLeft(find.byKey(key)).dy, 12.0); expect(tester.getTopLeft(find.byKey(key)).dy, useMaterial3 ? 12.75 :12.0);
expect(tester.getBottomLeft(find.byKey(key)).dy, 24.0); expect(tester.getBottomLeft(find.byKey(key)).dy, useMaterial3 ? 23.25 :24.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 1.0); expect(getBorderWeight(tester), 1.0);
// The label appears within the input when there is no text content. // The label appears within the input when there is no text content.
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -424,12 +442,13 @@ void main() { ...@@ -424,12 +442,13 @@ void main() {
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getTopLeft(find.byKey(key)).dy, 20.0); expect(tester.getTopLeft(find.byKey(key)).dy, useMaterial3 ? 21.0 :20.0);
// The label appears above the input text when there is no content and the // The label appears above the input text when there is no content and the
// floatingLabelBehavior is set to always. // floatingLabelBehavior is set to always.
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -451,12 +470,13 @@ void main() { ...@@ -451,12 +470,13 @@ void main() {
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getTopLeft(find.byKey(key)).dy, 12.0); expect(tester.getTopLeft(find.byKey(key)).dy, useMaterial3 ? 12.75 :12.0);
// The label appears within the input text when there is content and // The label appears within the input text when there is content and
// the floatingLabelBehavior is set to never. // the floatingLabelBehavior is set to never.
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
label: Text.rich( label: Text.rich(
...@@ -477,7 +497,7 @@ void main() { ...@@ -477,7 +497,7 @@ void main() {
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getTopLeft(find.byKey(key)).dy, 20.0); expect(tester.getTopLeft(find.byKey(key)).dy, useMaterial3 ? 21 :20.0);
// Overall height for this InputDecorator is 56dps: // Overall height for this InputDecorator is 56dps:
// 12 - top padding // 12 - top padding
...@@ -486,12 +506,13 @@ void main() { ...@@ -486,12 +506,13 @@ void main() {
// 16 - input text (ahem font size 16dps) // 16 - input text (ahem font size 16dps)
// 12 - bottom padding // 12 - bottom padding
expect(tester.getTopLeft(find.byKey(key)).dy, 20.0); expect(tester.getTopLeft(find.byKey(key)).dy, useMaterial3 ? 21 :20.0);
// isFocused: true increases the border's weight from 1.0 to 2.0 // isFocused: true increases the border's weight from 1.0 to 2.0
// but does not change the overall height. // but does not change the overall height.
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
isFocused: true, isFocused: true,
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -512,16 +533,17 @@ void main() { ...@@ -512,16 +533,17 @@ void main() {
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('text')).dy, 28.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 : 28.0);
expect(tester.getBottomLeft(find.text('text')).dy, 44.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
expect(tester.getTopLeft(find.byKey(key)).dy, 12.0); expect(tester.getTopLeft(find.byKey(key)).dy, useMaterial3 ? 12.75 :12.0);
expect(tester.getBottomLeft(find.byKey(key)).dy, 24.0); expect(tester.getBottomLeft(find.byKey(key)).dy, useMaterial3 ? 23.25 :24.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 2.0); expect(getBorderWeight(tester), 2.0);
// isEmpty: true causes the label to be aligned with the input text. // isEmpty: true causes the label to be aligned with the input text.
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
decoration: const InputDecoration( decoration: const InputDecoration(
label: Text.rich( label: Text.rich(
...@@ -551,16 +573,17 @@ void main() { ...@@ -551,16 +573,17 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('text')).dy, 28.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 :28.0);
expect(tester.getBottomLeft(find.text('text')).dy, 44.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 :44.0);
expect(tester.getTopLeft(find.byKey(key)).dy, 20.0); expect(tester.getTopLeft(find.byKey(key)).dy, useMaterial3 ? 21 :20.0);
expect(tester.getBottomLeft(find.byKey(key)).dy, 36.0); expect(tester.getBottomLeft(find.byKey(key)).dy, useMaterial3 ? 35 :36.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 1.0); expect(getBorderWeight(tester), 1.0);
// isFocused: true causes the label to move back up above the input text. // isFocused: true causes the label to move back up above the input text.
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
isFocused: true, isFocused: true,
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -593,10 +616,10 @@ void main() { ...@@ -593,10 +616,10 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('text')).dy, 28.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 :28.0);
expect(tester.getBottomLeft(find.text('text')).dy, 44.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 :44.0);
expect(tester.getTopLeft(find.byKey(key)).dy, 12.0); expect(tester.getTopLeft(find.byKey(key)).dy, useMaterial3 ? 12.75 :12.0);
expect(tester.getBottomLeft(find.byKey(key)).dy, 24.0); expect(tester.getBottomLeft(find.byKey(key)).dy, useMaterial3 ? 23.25 :24.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 2.0); expect(getBorderWeight(tester), 2.0);
...@@ -604,6 +627,7 @@ void main() { ...@@ -604,6 +627,7 @@ void main() {
// The widget's size and layout is the same as for enabled: true. // The widget's size and layout is the same as for enabled: true.
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
decoration: const InputDecoration( decoration: const InputDecoration(
label: Text.rich( label: Text.rich(
...@@ -624,16 +648,17 @@ void main() { ...@@ -624,16 +648,17 @@ void main() {
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('text')).dy, 28.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 :28.0);
expect(tester.getBottomLeft(find.text('text')).dy, 44.0); expect(tester.getBottomLeft(find.text('text')).dy,useMaterial3 ? 43.25 : 44.0);
expect(tester.getTopLeft(find.byKey(key)).dy, 20.0); expect(tester.getTopLeft(find.byKey(key)).dy, useMaterial3 ? 21 :20.0);
expect(tester.getBottomLeft(find.byKey(key)).dy, 36.0); expect(tester.getBottomLeft(find.byKey(key)).dy, useMaterial3 ? 35 :36.0);
expect(getBorderWeight(tester), 0.0); expect(getBorderWeight(tester),useMaterial3 ? 1.0 : 0.0);
// enabled: false produces a transparent border if filled: true. // enabled: false produces a transparent border if filled: true.
// The widget's size and layout is the same as for enabled: true. // The widget's size and layout is the same as for enabled: true.
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
decoration: const InputDecoration( decoration: const InputDecoration(
label: Text.rich( label: Text.rich(
...@@ -655,16 +680,18 @@ void main() { ...@@ -655,16 +680,18 @@ void main() {
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('text')).dy, 28.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25: 28.0);
expect(tester.getBottomLeft(find.text('text')).dy, 44.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25: 44.0);
expect(tester.getTopLeft(find.byKey(key)).dy, 20.0); expect(tester.getTopLeft(find.byKey(key)).dy, useMaterial3 ? 21: 20.0);
expect(tester.getBottomLeft(find.byKey(key)).dy, 36.0); expect(tester.getBottomLeft(find.byKey(key)).dy, useMaterial3 ? 35: 36.0);
expect(getBorderColor(tester), Colors.transparent); final ThemeData theme = ThemeData.from(colorScheme: const ColorScheme.light());
expect(getBorderColor(tester), useMaterial3 ? theme.colorScheme.onSurface.withOpacity(0.38) : Colors.transparent);
// alignLabelWithHint: true positions the label at the text baseline, // alignLabelWithHint: true positions the label at the text baseline,
// aligned with the hint. // aligned with the hint.
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
decoration: const InputDecoration( decoration: const InputDecoration(
label: Text.rich( label: Text.rich(
...@@ -686,8 +713,11 @@ void main() { ...@@ -686,8 +713,11 @@ void main() {
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.byKey(key)).dy, tester.getTopLeft(find.text('hint')).dy); if(!useMaterial3) {
expect(tester.getBottomLeft(find.byKey(key)).dy, tester.getBottomLeft(find.text('hint')).dy); expect(tester.getTopLeft(find.byKey(key)).dy, tester.getTopLeft(find.text('hint')).dy);
expect(tester.getBottomLeft(find.byKey(key)).dy, tester.getBottomLeft(find.text('hint')).dy);
}
}); });
group('alignLabelWithHint', () { group('alignLabelWithHint', () {
...@@ -909,6 +939,7 @@ void main() { ...@@ -909,6 +939,7 @@ void main() {
// The hint aligns with the input text // The hint aligns with the input text
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -932,6 +963,7 @@ void main() { ...@@ -932,6 +963,7 @@ void main() {
// Label is visible, hint is not (opacity 0.0). // Label is visible, hint is not (opacity 0.0).
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -959,10 +991,10 @@ void main() { ...@@ -959,10 +991,10 @@ void main() {
// The label is not floating so it's vertically centered. // The label is not floating so it's vertically centered.
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('text')).dy, 28.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 : 28.0);
expect(tester.getBottomLeft(find.text('text')).dy, 44.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
expect(tester.getTopLeft(find.text('label')).dy, 20.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);
expect(tester.getBottomLeft(find.text('label')).dy, 36.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0: 36.0);
expect(getOpacity(tester, 'hint'), 0.0); expect(getOpacity(tester, 'hint'), 0.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 1.0); expect(getBorderWeight(tester), 1.0);
...@@ -970,6 +1002,7 @@ void main() { ...@@ -970,6 +1002,7 @@ void main() {
// Label moves upwards, hint is visible (opacity 1.0). // Label moves upwards, hint is visible (opacity 1.0).
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
isFocused: true, isFocused: true,
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -992,18 +1025,19 @@ void main() { ...@@ -992,18 +1025,19 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('text')).dy, 28.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 :28.0);
expect(tester.getBottomLeft(find.text('text')).dy, 44.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 :44.0);
expect(tester.getTopLeft(find.text('label')).dy, 12.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
expect(tester.getBottomLeft(find.text('label')).dy, 24.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
expect(tester.getTopLeft(find.text('hint')).dy, 28.0); expect(tester.getTopLeft(find.text('hint')).dy, useMaterial3 ? 27.25 :28.0);
expect(tester.getBottomLeft(find.text('hint')).dy, 44.0); expect(tester.getBottomLeft(find.text('hint')).dy, useMaterial3 ? 43.25 :44.0);
expect(getOpacity(tester, 'hint'), 1.0); expect(getOpacity(tester, 'hint'), 1.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 2.0); expect(getBorderWeight(tester), 2.0);
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isFocused: true, isFocused: true,
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: 'label', labelText: 'label',
...@@ -1025,12 +1059,12 @@ void main() { ...@@ -1025,12 +1059,12 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('text')).dy, 28.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 :28.0);
expect(tester.getBottomLeft(find.text('text')).dy, 44.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 :44.0);
expect(tester.getTopLeft(find.text('label')).dy, 12.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
expect(tester.getBottomLeft(find.text('label')).dy, 24.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
expect(tester.getTopLeft(find.text('hint')).dy, 28.0); expect(tester.getTopLeft(find.text('hint')).dy, useMaterial3 ? 27.25 :28.0);
expect(tester.getBottomLeft(find.text('hint')).dy, 44.0); expect(tester.getBottomLeft(find.text('hint')).dy, useMaterial3 ? 43.25 :44.0);
expect(getOpacity(tester, 'hint'), 0.0); expect(getOpacity(tester, 'hint'), 0.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 2.0); expect(getBorderWeight(tester), 2.0);
...@@ -1040,6 +1074,7 @@ void main() { ...@@ -1040,6 +1074,7 @@ void main() {
// Label is visible, hint is not (opacity 0.0). // Label is visible, hint is not (opacity 0.0).
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1066,18 +1101,19 @@ void main() { ...@@ -1066,18 +1101,19 @@ void main() {
// 16 - bottom padding (empty input text still appears here) // 16 - bottom padding (empty input text still appears here)
// The label is not floating so it's vertically centered. // The label is not floating so it's vertically centered.
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0)); expect(tester.getSize(find.byType(InputDecorator)), Size(800.0, useMaterial3 ? 46.5 :48.0));
expect(tester.getTopLeft(find.text('text')).dy, 24.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 22.5 : 24.0);
expect(tester.getBottomLeft(find.text('text')).dy, 40.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 38.5 : 40.0);
expect(tester.getTopLeft(find.text('label')).dy, 16.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 16.25 : 16.0);
expect(tester.getBottomLeft(find.text('label')).dy, 32.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 30.25 : 32.0);
expect(getOpacity(tester, 'hint'), 0.0); expect(getOpacity(tester, 'hint'), 0.0);
expect(getBorderBottom(tester), 48.0); expect(getBorderBottom(tester), useMaterial3 ? 46.5 : 48.0);
expect(getBorderWeight(tester), 1.0); expect(getBorderWeight(tester), 1.0);
// Label is visible, hint is not (opacity 0.0). // Label is visible, hint is not (opacity 0.0).
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
isFocused: true, isFocused: true,
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1088,13 +1124,13 @@ void main() { ...@@ -1088,13 +1124,13 @@ void main() {
), ),
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0)); expect(tester.getSize(find.byType(InputDecorator)), Size(800.0, useMaterial3 ? 46.5 : 48.0));
expect(tester.getTopLeft(find.text('text')).dy, 24.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 22.5 : 24.0);
expect(tester.getBottomLeft(find.text('text')).dy, 40.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 38.5 : 40.0);
expect(tester.getTopLeft(find.text('label')).dy, 8.0); expect(tester.getTopLeft(find.text('label')).dy, 8.0);
expect(tester.getBottomLeft(find.text('label')).dy, 20.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 18.5 : 20.0);
expect(getOpacity(tester, 'hint'), 1.0); expect(getOpacity(tester, 'hint'), 1.0);
expect(getBorderBottom(tester), 48.0); expect(getBorderBottom(tester), useMaterial3 ? 46.5 : 48.0);
expect(getBorderWeight(tester), 2.0); expect(getBorderWeight(tester), 2.0);
}); });
...@@ -1102,6 +1138,7 @@ void main() { ...@@ -1102,6 +1138,7 @@ void main() {
// Label is visible, hint is not (opacity 0.0). // Label is visible, hint is not (opacity 0.0).
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1115,6 +1152,7 @@ void main() { ...@@ -1115,6 +1152,7 @@ void main() {
testWidgets('InputDecorator error/helper/counter layout', (WidgetTester tester) async { testWidgets('InputDecorator error/helper/counter layout', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1148,10 +1186,10 @@ void main() { ...@@ -1148,10 +1186,10 @@ void main() {
// isEmpty: true, the label is not floating // isEmpty: true, the label is not floating
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0));
expect(tester.getTopLeft(find.text('text')).dy, 28.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 : 28.0);
expect(tester.getBottomLeft(find.text('text')).dy, 44.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 :44.0);
expect(tester.getTopLeft(find.text('label')).dy, 20.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);
expect(tester.getBottomLeft(find.text('label')).dy, 36.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0: 36.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 1.0); expect(getBorderWeight(tester), 1.0);
expect(tester.getTopLeft(find.text('helper')), const Offset(12.0, 64.0)); expect(tester.getTopLeft(find.text('helper')), const Offset(12.0, 64.0));
...@@ -1160,6 +1198,7 @@ void main() { ...@@ -1160,6 +1198,7 @@ void main() {
// If errorText is specified then the helperText isn't shown // If errorText is specified then the helperText isn't shown
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1175,10 +1214,10 @@ void main() { ...@@ -1175,10 +1214,10 @@ void main() {
// isEmpty: false, the label _is_ floating // isEmpty: false, the label _is_ floating
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0));
expect(tester.getTopLeft(find.text('text')).dy, 28.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 : 28.0);
expect(tester.getBottomLeft(find.text('text')).dy, 44.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
expect(tester.getTopLeft(find.text('label')).dy, 12.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
expect(tester.getBottomLeft(find.text('label')).dy, 24.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 1.0); expect(getBorderWeight(tester), 1.0);
expect(tester.getTopLeft(find.text('error')), const Offset(12.0, 64.0)); expect(tester.getTopLeft(find.text('error')), const Offset(12.0, 64.0));
...@@ -1207,6 +1246,7 @@ void main() { ...@@ -1207,6 +1246,7 @@ void main() {
// The layout of the error/helper/counter subtext doesn't change for dense layout. // The layout of the error/helper/counter subtext doesn't change for dense layout.
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1222,18 +1262,19 @@ void main() { ...@@ -1222,18 +1262,19 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
// isEmpty: false, the label _is_ floating // isEmpty: false, the label _is_ floating
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 68.0)); expect(tester.getSize(find.byType(InputDecorator)), Size(800.0, useMaterial3 ? 66.5 : 68.0));
expect(tester.getTopLeft(find.text('text')).dy, 24.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 22.5 : 24.0);
expect(tester.getBottomLeft(find.text('text')).dy, 40.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 38.5 : 40.0);
expect(tester.getTopLeft(find.text('label')).dy, 8.0); expect(tester.getTopLeft(find.text('label')).dy, 8.0);
expect(tester.getBottomLeft(find.text('label')).dy, 20.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 18.5 : 20.0);
expect(getBorderBottom(tester), 48.0); expect(getBorderBottom(tester), useMaterial3 ? 46.5 : 48.0);
expect(getBorderWeight(tester), 1.0); expect(getBorderWeight(tester), 1.0);
expect(tester.getTopLeft(find.text('error')), const Offset(12.0, 56.0)); expect(tester.getTopLeft(find.text('error')), Offset(12.0, useMaterial3 ? 54.5 : 56.0));
expect(tester.getTopRight(find.text('counter')), const Offset(788.0, 56.0)); expect(tester.getTopRight(find.text('counter')), Offset(788.0, useMaterial3 ? 54.5 : 56.0));
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1249,15 +1290,15 @@ void main() { ...@@ -1249,15 +1290,15 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
// isEmpty: false, the label is not floating // isEmpty: false, the label is not floating
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 68.0)); expect(tester.getSize(find.byType(InputDecorator)), Size(800.0, useMaterial3 ? 66.5 : 68.0));
expect(tester.getTopLeft(find.text('text')).dy, 24.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 22.5 : 24.0);
expect(tester.getBottomLeft(find.text('text')).dy, 40.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 38.5 : 40.0);
expect(tester.getTopLeft(find.text('label')).dy, 16.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 16.25 : 16.0);
expect(tester.getBottomLeft(find.text('label')).dy, 32.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 30.25 : 32.0);
expect(getBorderBottom(tester), 48.0); expect(getBorderBottom(tester), useMaterial3 ? 46.5 : 48.0);
expect(getBorderWeight(tester), 1.0); expect(getBorderWeight(tester), 1.0);
expect(tester.getTopLeft(find.text('error')), const Offset(12.0, 56.0)); expect(tester.getTopLeft(find.text('error')), Offset(12.0, useMaterial3 ? 54.5 : 56.0));
expect(tester.getTopRight(find.text('counter')), const Offset(788.0, 56.0)); expect(tester.getTopRight(find.text('counter')), Offset(788.0, useMaterial3 ? 54.5 : 56.0));
}); });
testWidgets('InputDecorator counter text, widget, and null', (WidgetTester tester) async { testWidgets('InputDecorator counter text, widget, and null', (WidgetTester tester) async {
...@@ -1369,6 +1410,7 @@ void main() { ...@@ -1369,6 +1410,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1400,6 +1442,7 @@ void main() { ...@@ -1400,6 +1442,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1421,6 +1464,7 @@ void main() { ...@@ -1421,6 +1464,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1445,6 +1489,7 @@ void main() { ...@@ -1445,6 +1489,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1475,6 +1520,7 @@ void main() { ...@@ -1475,6 +1520,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1495,6 +1541,7 @@ void main() { ...@@ -1495,6 +1541,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1515,6 +1562,7 @@ void main() { ...@@ -1515,6 +1562,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1534,6 +1582,7 @@ void main() { ...@@ -1534,6 +1582,7 @@ void main() {
testWidgets('InputDecorator prefix/suffix texts', (WidgetTester tester) async { testWidgets('InputDecorator prefix/suffix texts', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1571,6 +1620,7 @@ void main() { ...@@ -1571,6 +1620,7 @@ void main() {
testWidgets('InputDecorator icon/prefix/suffix', (WidgetTester tester) async { testWidgets('InputDecorator icon/prefix/suffix', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1612,6 +1662,7 @@ void main() { ...@@ -1612,6 +1662,7 @@ void main() {
const Key sKey = Key('s'); const Key sKey = Key('s');
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1638,17 +1689,17 @@ void main() { ...@@ -1638,17 +1689,17 @@ void main() {
// 4 - bottom prefix/suffix padding // 4 - bottom prefix/suffix padding
// 12 - bottom padding // 12 - bottom padding
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0)); expect(tester.getSize(find.byType(InputDecorator)), Size(800.0, useMaterial3 ? 49.5 : 48.0));
expect(tester.getSize(find.text('text')).height, 16.0); expect(tester.getSize(find.text('text')).height, 16.0);
expect(tester.getSize(find.byKey(pKey)).height, 24.0); expect(tester.getSize(find.byKey(pKey)).height, 24.0);
expect(tester.getSize(find.text('p')).height, 16.0); expect(tester.getSize(find.text('p')).height, 16.0);
expect(tester.getSize(find.byKey(sKey)).height, 24.0); expect(tester.getSize(find.byKey(sKey)).height, 24.0);
expect(tester.getSize(find.text('s')).height, 16.0); expect(tester.getSize(find.text('s')).height, 16.0);
expect(tester.getTopLeft(find.text('text')).dy, 16.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 16.75 : 16.0);
expect(tester.getTopLeft(find.byKey(pKey)).dy, 12.0); expect(tester.getTopLeft(find.byKey(pKey)).dy, useMaterial3 ? 12.75 : 12.0);
expect(tester.getTopLeft(find.text('p')).dy, 16.0); expect(tester.getTopLeft(find.text('p')).dy, useMaterial3 ? 16.75 : 16.0);
expect(tester.getTopLeft(find.byKey(sKey)).dy, 12.0); expect(tester.getTopLeft(find.byKey(sKey)).dy, useMaterial3 ? 12.75 : 12.0);
expect(tester.getTopLeft(find.text('s')).dy, 16.0); expect(tester.getTopLeft(find.text('s')).dy, useMaterial3 ? 16.75 : 16.0);
expect(tester.getTopRight(find.byKey(sKey)).dx, 788.0); expect(tester.getTopRight(find.byKey(sKey)).dx, 788.0);
expect(tester.getTopRight(find.text('s')).dx, 784.0); expect(tester.getTopRight(find.text('s')).dx, 784.0);
...@@ -1662,6 +1713,7 @@ void main() { ...@@ -1662,6 +1713,7 @@ void main() {
const Key pKey = Key('p'); const Key pKey = Key('p');
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1691,11 +1743,11 @@ void main() { ...@@ -1691,11 +1743,11 @@ void main() {
// 12 - bottom padding // 12 - bottom padding
expect(tester.getSize(find.byType(InputDecorator)).width, 800.0); expect(tester.getSize(find.byType(InputDecorator)).width, 800.0);
expect(tester.getSize(find.byType(InputDecorator)).height, moreOrLessEquals(128.0, epsilon: .0001)); expect(tester.getSize(find.byType(InputDecorator)).height, moreOrLessEquals(useMaterial3 ? 129.5 : 128.0, epsilon: .0001));
expect(tester.getSize(find.text('text')).height, 20.0); expect(tester.getSize(find.text('text')).height, 20.0);
expect(tester.getSize(find.byKey(pKey)).height, 100.0); expect(tester.getSize(find.byKey(pKey)).height, 100.0);
expect(tester.getTopLeft(find.text('text')).dy, moreOrLessEquals(96, epsilon: .0001)); // 12 + 100 - 16 expect(tester.getTopLeft(find.text('text')).dy, moreOrLessEquals(useMaterial3 ? 96.75 : 96, epsilon: .0001)); // 12 + 100 - 16
expect(tester.getTopLeft(find.byKey(pKey)).dy, 12.0); expect(tester.getTopLeft(find.byKey(pKey)).dy, useMaterial3 ? 12.75 : 12.0);
// layout is a row: [prefix text suffix] // layout is a row: [prefix text suffix]
expect(tester.getTopLeft(find.byKey(pKey)).dx, 12.0); expect(tester.getTopLeft(find.byKey(pKey)).dx, 12.0);
...@@ -1706,6 +1758,7 @@ void main() { ...@@ -1706,6 +1758,7 @@ void main() {
const Key pKey = Key('p'); const Key pKey = Key('p');
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1755,6 +1808,7 @@ void main() { ...@@ -1755,6 +1808,7 @@ void main() {
testWidgets('InputDecorator prefixIcon/suffixIcon', (WidgetTester tester) async { testWidgets('InputDecorator prefixIcon/suffixIcon', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1775,7 +1829,7 @@ void main() { ...@@ -1775,7 +1829,7 @@ void main() {
expect(tester.getSize(find.text('text')).height, 16.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.pages)).height, 48.0);
expect(tester.getSize(find.byIcon(Icons.satellite)).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.text('text')).dy, useMaterial3 ? 12.75 : 12.0);
expect(tester.getTopLeft(find.byIcon(Icons.pages)).dy, 0.0); expect(tester.getTopLeft(find.byIcon(Icons.pages)).dy, 0.0);
expect(tester.getTopLeft(find.byIcon(Icons.satellite)).dy, 0.0); expect(tester.getTopLeft(find.byIcon(Icons.satellite)).dy, 0.0);
expect(tester.getTopRight(find.byIcon(Icons.satellite)).dx, 800.0); expect(tester.getTopRight(find.byIcon(Icons.satellite)).dx, 800.0);
...@@ -1790,6 +1844,7 @@ void main() { ...@@ -1790,6 +1844,7 @@ void main() {
testWidgets('InputDecorator prefixIconConstraints/suffixIconConstraints', (WidgetTester tester) async { testWidgets('InputDecorator prefixIconConstraints/suffixIconConstraints', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1828,6 +1883,7 @@ void main() { ...@@ -1828,6 +1883,7 @@ void main() {
const Key prefixKey = Key('prefix'); const Key prefixKey = Key('prefix');
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
decoration: const InputDecoration( decoration: const InputDecoration(
prefixIcon: Padding( prefixIcon: Padding(
padding: EdgeInsets.all(16.0), padding: EdgeInsets.all(16.0),
...@@ -1853,6 +1909,7 @@ void main() { ...@@ -1853,6 +1909,7 @@ void main() {
// Label is visible, hint is not (opacity 0.0). // Label is visible, hint is not (opacity 0.0).
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
visualDensity: VisualDensity.compact, visualDensity: VisualDensity.compact,
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1864,10 +1921,10 @@ void main() { ...@@ -1864,10 +1921,10 @@ void main() {
// The label is not floating so it's vertically centered. // The label is not floating so it's vertically centered.
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0));
expect(tester.getTopLeft(find.text('text')).dy, 24.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 23.25 : 24.0);
expect(tester.getBottomLeft(find.text('text')).dy, 40.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 39.25 : 40.0);
expect(tester.getTopLeft(find.text('label')).dy, 16.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 17 : 16.0);
expect(tester.getBottomLeft(find.text('label')).dy, 32.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 31.0 : 32.0);
expect(getOpacity(tester, 'hint'), 0.0); expect(getOpacity(tester, 'hint'), 0.0);
expect(getBorderBottom(tester), 48.0); expect(getBorderBottom(tester), 48.0);
expect(getBorderWeight(tester), 1.0); expect(getBorderWeight(tester), 1.0);
...@@ -1875,6 +1932,7 @@ void main() { ...@@ -1875,6 +1932,7 @@ void main() {
// Label moves upwards, hint is visible (opacity 1.0). // Label moves upwards, hint is visible (opacity 1.0).
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
isFocused: true, isFocused: true,
visualDensity: VisualDensity.compact, visualDensity: VisualDensity.compact,
...@@ -1898,18 +1956,19 @@ void main() { ...@@ -1898,18 +1956,19 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0));
expect(tester.getTopLeft(find.text('text')).dy, 24.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 23.25 : 24.0);
expect(tester.getBottomLeft(find.text('text')).dy, 40.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 39.25 : 40.0);
expect(tester.getTopLeft(find.text('label')).dy, 12.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
expect(tester.getBottomLeft(find.text('label')).dy, 24.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
expect(tester.getTopLeft(find.text('hint')).dy, 24.0); expect(tester.getTopLeft(find.text('hint')).dy, useMaterial3 ? 23.25 : 24.0);
expect(tester.getBottomLeft(find.text('hint')).dy, 40.0); expect(tester.getBottomLeft(find.text('hint')).dy, useMaterial3 ? 39.25 : 40.0);
expect(getOpacity(tester, 'hint'), 1.0); expect(getOpacity(tester, 'hint'), 1.0);
expect(getBorderBottom(tester), 48.0); expect(getBorderBottom(tester), 48.0);
expect(getBorderWeight(tester), 2.0); expect(getBorderWeight(tester), 2.0);
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isFocused: true, isFocused: true,
visualDensity: VisualDensity.compact, visualDensity: VisualDensity.compact,
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1932,12 +1991,12 @@ void main() { ...@@ -1932,12 +1991,12 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0));
expect(tester.getTopLeft(find.text('text')).dy, 24.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 23.25 : 24.0);
expect(tester.getBottomLeft(find.text('text')).dy, 40.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 39.25 : 40.0);
expect(tester.getTopLeft(find.text('label')).dy, 12.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
expect(tester.getBottomLeft(find.text('label')).dy, 24.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
expect(tester.getTopLeft(find.text('hint')).dy, 24.0); expect(tester.getTopLeft(find.text('hint')).dy, useMaterial3 ? 23.25 : 24.0);
expect(tester.getBottomLeft(find.text('hint')).dy, 40.0); expect(tester.getBottomLeft(find.text('hint')).dy, useMaterial3 ? 39.25 : 40.0);
expect(getOpacity(tester, 'hint'), 0.0); expect(getOpacity(tester, 'hint'), 0.0);
expect(getBorderBottom(tester), 48.0); expect(getBorderBottom(tester), 48.0);
expect(getBorderWeight(tester), 2.0); expect(getBorderWeight(tester), 2.0);
...@@ -1947,6 +2006,7 @@ void main() { ...@@ -1947,6 +2006,7 @@ void main() {
// Label is visible, hint is not (opacity 0.0). // Label is visible, hint is not (opacity 0.0).
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
visualDensity: const VisualDensity(horizontal: 2.0, vertical: 2.0), visualDensity: const VisualDensity(horizontal: 2.0, vertical: 2.0),
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -1958,10 +2018,10 @@ void main() { ...@@ -1958,10 +2018,10 @@ void main() {
// The label is not floating so it's vertically centered. // The label is not floating so it's vertically centered.
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 64.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 64.0));
expect(tester.getTopLeft(find.text('text')).dy, 32.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 31.25 : 32.0);
expect(tester.getBottomLeft(find.text('text')).dy, 48.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 47.25 : 48.0);
expect(tester.getTopLeft(find.text('label')).dy, 24.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 25.0 : 24.0);
expect(tester.getBottomLeft(find.text('label')).dy, 40.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 39.0 : 40.0);
expect(getOpacity(tester, 'hint'), 0.0); expect(getOpacity(tester, 'hint'), 0.0);
expect(getBorderBottom(tester), 64.0); expect(getBorderBottom(tester), 64.0);
expect(getBorderWeight(tester), 1.0); expect(getBorderWeight(tester), 1.0);
...@@ -1969,6 +2029,7 @@ void main() { ...@@ -1969,6 +2029,7 @@ void main() {
// Label moves upwards, hint is visible (opacity 1.0). // Label moves upwards, hint is visible (opacity 1.0).
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
isFocused: true, isFocused: true,
visualDensity: const VisualDensity(horizontal: 2.0, vertical: 2.0), visualDensity: const VisualDensity(horizontal: 2.0, vertical: 2.0),
...@@ -1992,18 +2053,19 @@ void main() { ...@@ -1992,18 +2053,19 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 64.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 64.0));
expect(tester.getTopLeft(find.text('text')).dy, 32.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 31.25 : 32.0);
expect(tester.getBottomLeft(find.text('text')).dy, 48.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 47.25 : 48.0);
expect(tester.getTopLeft(find.text('label')).dy, 12.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
expect(tester.getBottomLeft(find.text('label')).dy, 24.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
expect(tester.getTopLeft(find.text('hint')).dy, 32.0); expect(tester.getTopLeft(find.text('hint')).dy, useMaterial3 ? 31.25 : 32.0);
expect(tester.getBottomLeft(find.text('hint')).dy, 48.0); expect(tester.getBottomLeft(find.text('hint')).dy, useMaterial3 ? 47.25 : 48.0);
expect(getOpacity(tester, 'hint'), 1.0); expect(getOpacity(tester, 'hint'), 1.0);
expect(getBorderBottom(tester), 64.0); expect(getBorderBottom(tester), 64.0);
expect(getBorderWeight(tester), 2.0); expect(getBorderWeight(tester), 2.0);
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isFocused: true, isFocused: true,
visualDensity: const VisualDensity(horizontal: 2.0, vertical: 2.0), visualDensity: const VisualDensity(horizontal: 2.0, vertical: 2.0),
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -2026,12 +2088,12 @@ void main() { ...@@ -2026,12 +2088,12 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 64.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 64.0));
expect(tester.getTopLeft(find.text('text')).dy, 32.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 31.25 : 32.0);
expect(tester.getBottomLeft(find.text('text')).dy, 48.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 47.25 : 48.0);
expect(tester.getTopLeft(find.text('label')).dy, 12.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
expect(tester.getBottomLeft(find.text('label')).dy, 24.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
expect(tester.getTopLeft(find.text('hint')).dy, 32.0); expect(tester.getTopLeft(find.text('hint')).dy, useMaterial3 ? 31.25 : 32.0);
expect(tester.getBottomLeft(find.text('hint')).dy, 48.0); expect(tester.getBottomLeft(find.text('hint')).dy, useMaterial3 ? 47.25 : 48.0);
expect(getOpacity(tester, 'hint'), 0.0); expect(getOpacity(tester, 'hint'), 0.0);
expect(getBorderBottom(tester), 64.0); expect(getBorderBottom(tester), 64.0);
expect(getBorderWeight(tester), 2.0); expect(getBorderWeight(tester), 2.0);
...@@ -2041,6 +2103,7 @@ void main() { ...@@ -2041,6 +2103,7 @@ void main() {
const Key prefixKey = Key('prefix'); const Key prefixKey = Key('prefix');
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
decoration: const InputDecoration( decoration: const InputDecoration(
prefixIcon: SizedBox(width: 100.0, height: 100.0, key: prefixKey), prefixIcon: SizedBox(width: 100.0, height: 100.0, key: prefixKey),
filled: true, filled: true,
...@@ -2061,7 +2124,9 @@ void main() { ...@@ -2061,7 +2124,9 @@ void main() {
group('constraints', () { group('constraints', () {
testWidgets('No InputDecorator constraints', (WidgetTester tester) async { testWidgets('No InputDecorator constraints', (WidgetTester tester) async {
await tester.pumpWidget(buildInputDecorator()); await tester.pumpWidget(buildInputDecorator(
useMaterial3: useMaterial3,
));
// Should fill the screen width and be default height // Should fill the screen width and be default height
expect(tester.getSize(find.byType(InputDecorator)), const Size(800, 48)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800, 48));
...@@ -2070,6 +2135,7 @@ void main() { ...@@ -2070,6 +2135,7 @@ void main() {
testWidgets('InputDecoratorThemeData constraints', (WidgetTester tester) async { testWidgets('InputDecoratorThemeData constraints', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
theme: ThemeData( theme: ThemeData(
inputDecorationTheme: const InputDecorationTheme( inputDecorationTheme: const InputDecorationTheme(
constraints: BoxConstraints(maxWidth: 300, maxHeight: 40), constraints: BoxConstraints(maxWidth: 300, maxHeight: 40),
...@@ -2085,6 +2151,7 @@ void main() { ...@@ -2085,6 +2151,7 @@ void main() {
testWidgets('InputDecorator constraints', (WidgetTester tester) async { testWidgets('InputDecorator constraints', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
theme: ThemeData( theme: ThemeData(
inputDecorationTheme: const InputDecorationTheme( inputDecorationTheme: const InputDecorationTheme(
constraints: BoxConstraints(maxWidth: 300, maxHeight: 40), constraints: BoxConstraints(maxWidth: 300, maxHeight: 40),
...@@ -2108,6 +2175,7 @@ void main() { ...@@ -2108,6 +2175,7 @@ void main() {
const String text = 'text'; const String text = 'text';
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
expands: true, // so we have a tall input where align can vary expands: true, // so we have a tall input where align can vary
...@@ -2124,13 +2192,14 @@ void main() { ...@@ -2124,13 +2192,14 @@ void main() {
); );
// Same as the default case above. // Same as the default case above.
expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(12.0, epsilon: .0001)); expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(useMaterial3 ? 12.75 : 12.0, epsilon: .0001));
}); });
testWidgets('align center', (WidgetTester tester) async { testWidgets('align center', (WidgetTester tester) async {
const String text = 'text'; const String text = 'text';
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
expands: true, expands: true,
...@@ -2154,6 +2223,7 @@ void main() { ...@@ -2154,6 +2223,7 @@ void main() {
const String text = 'text'; const String text = 'text';
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
expands: true, expands: true,
...@@ -2170,13 +2240,14 @@ void main() { ...@@ -2170,13 +2240,14 @@ void main() {
); );
// Below the center aligned case. // Below the center aligned case.
expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(568.0, epsilon: .0001)); expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(useMaterial3 ? 567.25 : 568.0, epsilon: .0001));
}); });
testWidgets('align as a double', (WidgetTester tester) async { testWidgets('align as a double', (WidgetTester tester) async {
const String text = 'text'; const String text = 'text';
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
expands: true, expands: true,
...@@ -2193,7 +2264,7 @@ void main() { ...@@ -2193,7 +2264,7 @@ void main() {
); );
// In between the center and bottom aligned cases. // In between the center and bottom aligned cases.
expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(498.5, epsilon: .0001)); expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(useMaterial3 ? 497.9375 : 498.5, epsilon: .0001));
}); });
}); });
...@@ -2202,6 +2273,7 @@ void main() { ...@@ -2202,6 +2273,7 @@ void main() {
const String text = 'text'; const String text = 'text';
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
expands: true, // so we have a tall input where align can vary expands: true, // so we have a tall input where align can vary
...@@ -2227,6 +2299,7 @@ void main() { ...@@ -2227,6 +2299,7 @@ void main() {
const String text = 'text'; const String text = 'text';
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
expands: true, expands: true,
...@@ -2251,6 +2324,7 @@ void main() { ...@@ -2251,6 +2324,7 @@ void main() {
const String text = 'text'; const String text = 'text';
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
expands: true, expands: true,
...@@ -2278,6 +2352,7 @@ void main() { ...@@ -2278,6 +2352,7 @@ void main() {
const String text = 'text'; const String text = 'text';
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -2298,8 +2373,8 @@ void main() { ...@@ -2298,8 +2373,8 @@ void main() {
); );
// Same as the default case above. // Same as the default case above.
expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(96, epsilon: .0001)); expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(useMaterial3 ? 96.75 : 96, epsilon: .0001));
expect(tester.getTopLeft(find.byKey(pKey)).dy, 12.0); expect(tester.getTopLeft(find.byKey(pKey)).dy, useMaterial3 ? 12.75 : 12.0);
}); });
testWidgets('InputDecorator tall prefix align center', (WidgetTester tester) async { testWidgets('InputDecorator tall prefix align center', (WidgetTester tester) async {
...@@ -2307,6 +2382,7 @@ void main() { ...@@ -2307,6 +2382,7 @@ void main() {
const String text = 'text'; const String text = 'text';
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -2327,8 +2403,8 @@ void main() { ...@@ -2327,8 +2403,8 @@ void main() {
); );
// Same as the default case above. // Same as the default case above.
expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(96.0, epsilon: .0001)); expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(useMaterial3 ? 96.75 : 96.0, epsilon: .0001));
expect(tester.getTopLeft(find.byKey(pKey)).dy, 12.0); expect(tester.getTopLeft(find.byKey(pKey)).dy, useMaterial3 ? 12.75 : 12.0);
}); });
testWidgets('InputDecorator tall prefix align bottom', (WidgetTester tester) async { testWidgets('InputDecorator tall prefix align bottom', (WidgetTester tester) async {
...@@ -2336,6 +2412,7 @@ void main() { ...@@ -2336,6 +2412,7 @@ void main() {
const String text = 'text'; const String text = 'text';
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -2356,8 +2433,8 @@ void main() { ...@@ -2356,8 +2433,8 @@ void main() {
); );
// Top of the input + 100 prefix height - overlap // Top of the input + 100 prefix height - overlap
expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(96.0, epsilon: .0001)); expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(useMaterial3 ? 96.75 : 96.0, epsilon: .0001));
expect(tester.getTopLeft(find.byKey(pKey)).dy, 12.0); expect(tester.getTopLeft(find.byKey(pKey)).dy, useMaterial3 ? 12.75 : 12.0);
}); });
}); });
...@@ -2367,6 +2444,7 @@ void main() { ...@@ -2367,6 +2444,7 @@ void main() {
const String text = 'text'; const String text = 'text';
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
expands: true, expands: true,
...@@ -2398,6 +2476,7 @@ void main() { ...@@ -2398,6 +2476,7 @@ void main() {
const String text = 'text'; const String text = 'text';
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
expands: true, expands: true,
...@@ -2431,6 +2510,7 @@ void main() { ...@@ -2431,6 +2510,7 @@ void main() {
const String text = 'text'; const String text = 'text';
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
expands: true, expands: true,
...@@ -2462,6 +2542,7 @@ void main() { ...@@ -2462,6 +2542,7 @@ void main() {
const String text = 'text'; const String text = 'text';
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
expands: true, expands: true,
...@@ -2494,6 +2575,7 @@ void main() { ...@@ -2494,6 +2575,7 @@ void main() {
const String text = 'text'; const String text = 'text';
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
expands: true, // so we have a tall input where align can vary expands: true, // so we have a tall input where align can vary
...@@ -2512,13 +2594,14 @@ void main() { ...@@ -2512,13 +2594,14 @@ void main() {
// The label causes the text to start slightly lower than it would // The label causes the text to start slightly lower than it would
// otherwise. // otherwise.
expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(28.0, epsilon: .0001)); expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(useMaterial3 ? 27.25 : 28.0, epsilon: .0001));
}); });
testWidgets('align center', (WidgetTester tester) async { testWidgets('align center', (WidgetTester tester) async {
const String text = 'text'; const String text = 'text';
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
expands: true, // so we have a tall input where align can vary expands: true, // so we have a tall input where align can vary
...@@ -2537,13 +2620,14 @@ void main() { ...@@ -2537,13 +2620,14 @@ void main() {
// The label reduces the amount of space available for text, so the // The label reduces the amount of space available for text, so the
// center is slightly lower. // center is slightly lower.
expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(298.0, epsilon: .0001)); expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(useMaterial3 ? 297.25 : 298.0, epsilon: .0001));
}); });
testWidgets('align bottom', (WidgetTester tester) async { testWidgets('align bottom', (WidgetTester tester) async {
const String text = 'text'; const String text = 'text';
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
expands: true, // so we have a tall input where align can vary expands: true, // so we have a tall input where align can vary
...@@ -2562,7 +2646,7 @@ void main() { ...@@ -2562,7 +2646,7 @@ void main() {
// The label reduces the amount of space available for text, but the // The label reduces the amount of space available for text, but the
// bottom line is still in the same place. // bottom line is still in the same place.
expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(568.0, epsilon: .0001)); expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(useMaterial3 ? 567.25 : 568.0, epsilon: .0001));
}); });
}); });
}); });
...@@ -2572,6 +2656,7 @@ void main() { ...@@ -2572,6 +2656,7 @@ void main() {
testWidgets('Centers when border', (WidgetTester tester) async { testWidgets('Centers when border', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
decoration: const InputDecoration( decoration: const InputDecoration(
border: OutlineInputBorder(), border: OutlineInputBorder(),
), ),
...@@ -2588,6 +2673,7 @@ void main() { ...@@ -2588,6 +2673,7 @@ void main() {
testWidgets('Centers when border and label', (WidgetTester tester) async { testWidgets('Centers when border and label', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: 'label', labelText: 'label',
border: OutlineInputBorder(), border: OutlineInputBorder(),
...@@ -2605,6 +2691,7 @@ void main() { ...@@ -2605,6 +2691,7 @@ void main() {
testWidgets('Centers when border and contentPadding', (WidgetTester tester) async { testWidgets('Centers when border and contentPadding', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
decoration: const InputDecoration( decoration: const InputDecoration(
border: OutlineInputBorder(), border: OutlineInputBorder(),
contentPadding: EdgeInsets.fromLTRB( contentPadding: EdgeInsets.fromLTRB(
...@@ -2625,6 +2712,7 @@ void main() { ...@@ -2625,6 +2712,7 @@ void main() {
testWidgets('Centers when border and contentPadding and label', (WidgetTester tester) async { testWidgets('Centers when border and contentPadding and label', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: 'label', labelText: 'label',
border: OutlineInputBorder(), border: OutlineInputBorder(),
...@@ -2645,6 +2733,7 @@ void main() { ...@@ -2645,6 +2733,7 @@ void main() {
testWidgets('Centers when border and lopsided contentPadding and label', (WidgetTester tester) async { testWidgets('Centers when border and lopsided contentPadding and label', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: 'label', labelText: 'label',
border: OutlineInputBorder(), border: OutlineInputBorder(),
...@@ -2668,6 +2757,7 @@ void main() { ...@@ -2668,6 +2757,7 @@ void main() {
testWidgets('top align includes padding', (WidgetTester tester) async { testWidgets('top align includes padding', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
expands: true, expands: true,
textAlignVertical: TextAlignVertical.top, textAlignVertical: TextAlignVertical.top,
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -2691,6 +2781,7 @@ void main() { ...@@ -2691,6 +2781,7 @@ void main() {
testWidgets('center align ignores padding', (WidgetTester tester) async { testWidgets('center align ignores padding', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
expands: true, expands: true,
textAlignVertical: TextAlignVertical.center, textAlignVertical: TextAlignVertical.center,
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -2714,6 +2805,7 @@ void main() { ...@@ -2714,6 +2805,7 @@ void main() {
testWidgets('bottom align includes padding', (WidgetTester tester) async { testWidgets('bottom align includes padding', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
expands: true, expands: true,
textAlignVertical: TextAlignVertical.bottom, textAlignVertical: TextAlignVertical.bottom,
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -2737,6 +2829,7 @@ void main() { ...@@ -2737,6 +2829,7 @@ void main() {
testWidgets('padding exceeds middle keeps top at middle', (WidgetTester tester) async { testWidgets('padding exceeds middle keeps top at middle', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
expands: true, expands: true,
textAlignVertical: TextAlignVertical.top, textAlignVertical: TextAlignVertical.top,
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -2762,6 +2855,7 @@ void main() { ...@@ -2762,6 +2855,7 @@ void main() {
testWidgets('counter text has correct right margin - LTR, not dense', (WidgetTester tester) async { testWidgets('counter text has correct right margin - LTR, not dense', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -2781,6 +2875,7 @@ void main() { ...@@ -2781,6 +2875,7 @@ void main() {
testWidgets('counter text has correct right margin - RTL, not dense', (WidgetTester tester) async { testWidgets('counter text has correct right margin - RTL, not dense', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
textDirection: TextDirection.rtl, textDirection: TextDirection.rtl,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
...@@ -2800,6 +2895,7 @@ void main() { ...@@ -2800,6 +2895,7 @@ void main() {
testWidgets('counter text has correct right margin - LTR, dense', (WidgetTester tester) async { testWidgets('counter text has correct right margin - LTR, dense', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -2820,6 +2916,7 @@ void main() { ...@@ -2820,6 +2916,7 @@ void main() {
testWidgets('counter text has correct right margin - RTL, dense', (WidgetTester tester) async { testWidgets('counter text has correct right margin - RTL, dense', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
textDirection: TextDirection.rtl, textDirection: TextDirection.rtl,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
...@@ -2840,6 +2937,7 @@ void main() { ...@@ -2840,6 +2937,7 @@ void main() {
testWidgets('InputDecorator error/helper/counter RTL layout', (WidgetTester tester) async { testWidgets('InputDecorator error/helper/counter RTL layout', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
textDirection: TextDirection.rtl, textDirection: TextDirection.rtl,
...@@ -2862,10 +2960,10 @@ void main() { ...@@ -2862,10 +2960,10 @@ void main() {
// 12 - [counter helper/error] (ahem font size 12dps) // 12 - [counter helper/error] (ahem font size 12dps)
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0));
expect(tester.getTopLeft(find.text('text')).dy, 28.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 : 28.0);
expect(tester.getBottomLeft(find.text('text')).dy, 44.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
expect(tester.getTopLeft(find.text('label')).dy, 12.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
expect(tester.getBottomLeft(find.text('label')).dy, 24.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 1.0); expect(getBorderWeight(tester), 1.0);
expect(tester.getTopLeft(find.text('counter')), const Offset(12.0, 64.0)); expect(tester.getTopLeft(find.text('counter')), const Offset(12.0, 64.0));
...@@ -2874,6 +2972,7 @@ void main() { ...@@ -2874,6 +2972,7 @@ void main() {
// If both error and helper are specified, show the error // If both error and helper are specified, show the error
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
textDirection: TextDirection.rtl, textDirection: TextDirection.rtl,
...@@ -2895,6 +2994,7 @@ void main() { ...@@ -2895,6 +2994,7 @@ void main() {
testWidgets('InputDecorator prefix/suffix RTL', (WidgetTester tester) async { testWidgets('InputDecorator prefix/suffix RTL', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
textDirection: TextDirection.rtl, textDirection: TextDirection.rtl,
...@@ -2929,10 +3029,11 @@ void main() { ...@@ -2929,10 +3029,11 @@ void main() {
// LTR: content left edge is contentPadding.start: 40.0 // LTR: content left edge is contentPadding.start: 40.0
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: InputDecoration(
contentPadding: EdgeInsetsDirectional.only(start: 40.0, top: 12.0, bottom: 12.0), contentPadding: EdgeInsetsDirectional.only(start: 40.0, top: useMaterial3 ? 12.75 : 12.0, bottom: useMaterial3 ? 12.75 : 12.0),
labelText: 'label', labelText: 'label',
hintText: 'hint', hintText: 'hint',
filled: true, filled: true,
...@@ -2947,11 +3048,12 @@ void main() { ...@@ -2947,11 +3048,12 @@ void main() {
// RTL: content right edge is 800 - contentPadding.start: 760.0. // RTL: content right edge is 800 - contentPadding.start: 760.0.
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
isFocused: true, // label is floating, still adjusted for contentPadding isFocused: true, // label is floating, still adjusted for contentPadding
textDirection: TextDirection.rtl, textDirection: TextDirection.rtl,
decoration: const InputDecoration( decoration: InputDecoration(
contentPadding: EdgeInsetsDirectional.only(start: 40.0, top: 12.0, bottom: 12.0), contentPadding: EdgeInsetsDirectional.only(start: 40.0, top: useMaterial3 ? 12.75 : 12.0, bottom: useMaterial3 ? 12.75 : 12.0),
labelText: 'label', labelText: 'label',
hintText: 'hint', hintText: 'hint',
filled: true, filled: true,
...@@ -2975,6 +3077,7 @@ void main() { ...@@ -2975,6 +3077,7 @@ void main() {
required FloatingLabelAlignment alignment, required FloatingLabelAlignment alignment,
bool borderIsOutline = false, bool borderIsOutline = false,
}) => buildInputDecorator( }) => buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
textDirection: textDirection, textDirection: textDirection,
...@@ -3193,6 +3296,7 @@ void main() { ...@@ -3193,6 +3296,7 @@ void main() {
testWidgets('InputDecorator prefix/suffix dense layout', (WidgetTester tester) async { testWidgets('InputDecorator prefix/suffix dense layout', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
isFocused: true, isFocused: true,
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -3228,11 +3332,13 @@ void main() { ...@@ -3228,11 +3332,13 @@ void main() {
expect(tester.getTopRight(find.text('text')).dx, lessThanOrEqualTo(tester.getTopLeft(find.text('s')).dx)); expect(tester.getTopRight(find.text('text')).dx, lessThanOrEqualTo(tester.getTopLeft(find.text('s')).dx));
expect(getBorderBottom(tester), 32.0); expect(getBorderBottom(tester), 32.0);
expect(getBorderWeight(tester), 2.0); expect(getBorderWeight(tester), useMaterial3 ? 1.0 : 2.0);
}); });
testWidgets('InputDecorator with empty InputDecoration', (WidgetTester tester) async { testWidgets('InputDecorator with empty InputDecoration', (WidgetTester tester) async {
await tester.pumpWidget(buildInputDecorator()); await tester.pumpWidget(buildInputDecorator(
useMaterial3: useMaterial3,
));
// Overall height for this InputDecorator is 40dps: // Overall height for this InputDecorator is 40dps:
// 12 - top padding // 12 - top padding
...@@ -3251,6 +3357,7 @@ void main() { ...@@ -3251,6 +3357,7 @@ void main() {
const double verticalPadding = 1.0; const double verticalPadding = 1.0;
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default), // isEmpty: false (default),
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -3275,6 +3382,7 @@ void main() { ...@@ -3275,6 +3382,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default), // isEmpty: false (default),
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration.collapsed( decoration: const InputDecoration.collapsed(
...@@ -3298,6 +3406,7 @@ void main() { ...@@ -3298,6 +3406,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default), // isEmpty: false (default),
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -3322,6 +3431,7 @@ void main() { ...@@ -3322,6 +3431,7 @@ void main() {
testWidgets('InputDecorator.collapsed', (WidgetTester tester) async { testWidgets('InputDecorator.collapsed', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default), // isEmpty: false (default),
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration.collapsed( decoration: const InputDecoration.collapsed(
...@@ -3343,6 +3453,7 @@ void main() { ...@@ -3343,6 +3453,7 @@ void main() {
// The hint should appear // The hint should appear
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
isFocused: true, isFocused: true,
decoration: const InputDecoration.collapsed( decoration: const InputDecoration.collapsed(
...@@ -3366,6 +3477,7 @@ void main() { ...@@ -3366,6 +3477,7 @@ void main() {
const TextStyle style = TextStyle(fontFamily: 'Ahem', fontSize: 10.0); const TextStyle style = TextStyle(fontFamily: 'Ahem', fontSize: 10.0);
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
baseStyle: style, baseStyle: style,
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -3391,19 +3503,20 @@ void main() { ...@@ -3391,19 +3503,20 @@ void main() {
// 10 - label (ahem font size 10dps) // 10 - label (ahem font size 10dps)
// 17.75 - bottom padding (empty input text still appears here) // 17.75 - bottom padding (empty input text still appears here)
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension)); // 45.5 bumped up to minimum. expect(tester.getSize(find.byType(InputDecorator)), Size(800.0, useMaterial3 ? 50.0 : kMinInteractiveDimension)); // 45.5 bumped up to minimum.
expect(tester.getSize(find.text('hint')).height, 10.0); expect(tester.getSize(find.text('hint')).height, 10.0);
expect(tester.getSize(find.text('label')).height, 10.0); expect(tester.getSize(find.text('label')).height, useMaterial3 ? 14.0 : 10.0);
expect(tester.getSize(find.text('text')).height, 10.0); expect(tester.getSize(find.text('text')).height, 10.0);
expect(tester.getTopLeft(find.text('hint')).dy, 24.75); expect(tester.getTopLeft(find.text('hint')).dy, useMaterial3 ? 27.25 : 24.75);
expect(tester.getTopLeft(find.text('label')).dy, 19.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 18 : 19.0);
expect(tester.getTopLeft(find.text('text')).dy, 24.75); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 : 24.75);
}); });
testWidgets('InputDecorator with empty style overrides', (WidgetTester tester) async { testWidgets('InputDecorator with empty style overrides', (WidgetTester tester) async {
// Same as not specifying any style overrides // Same as not specifying any style overrides
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -3432,10 +3545,10 @@ void main() { ...@@ -3432,10 +3545,10 @@ void main() {
// Label is floating because isEmpty is false. // Label is floating because isEmpty is false.
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0));
expect(tester.getTopLeft(find.text('text')).dy, 28.0); expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 : 28.0);
expect(tester.getBottomLeft(find.text('text')).dy, 44.0); expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
expect(tester.getTopLeft(find.text('label')).dy, 12.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
expect(tester.getBottomLeft(find.text('label')).dy, 24.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 1.0); expect(getBorderWeight(tester), 1.0);
expect(tester.getTopLeft(find.text('helper')), const Offset(12.0, 64.0)); expect(tester.getTopLeft(find.text('helper')), const Offset(12.0, 64.0));
...@@ -3445,6 +3558,7 @@ void main() { ...@@ -3445,6 +3558,7 @@ void main() {
testWidgets('InputDecoration outline shape with no border and no floating placeholder', (WidgetTester tester) async { testWidgets('InputDecoration outline shape with no border and no floating placeholder', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isFocused: false (default) // isFocused: false (default)
isEmpty: true, isEmpty: true,
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -3460,8 +3574,8 @@ void main() { ...@@ -3460,8 +3574,8 @@ void main() {
// 16 - label (ahem font size 16dps) // 16 - label (ahem font size 16dps)
// 20 - bottom padding // 20 - bottom padding
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('label')).dy, 20.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);
expect(tester.getBottomLeft(find.text('label')).dy, 36.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0: 36.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 0.0); expect(getBorderWeight(tester), 0.0);
}); });
...@@ -3469,6 +3583,7 @@ void main() { ...@@ -3469,6 +3583,7 @@ void main() {
testWidgets('InputDecoration outline shape with no border and no floating placeholder not empty', (WidgetTester tester) async { testWidgets('InputDecoration outline shape with no border and no floating placeholder not empty', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -3485,8 +3600,8 @@ void main() { ...@@ -3485,8 +3600,8 @@ void main() {
// 20 - bottom padding // 20 - bottom padding
// expect(tester.widget<Text>(find.text('prefix')).style.color, prefixStyle.color); // expect(tester.widget<Text>(find.text('prefix')).style.color, prefixStyle.color);
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('label')).dy, 20.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);
expect(tester.getBottomLeft(find.text('label')).dy, 36.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0: 36.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 0.0); expect(getBorderWeight(tester), 0.0);
...@@ -3518,6 +3633,7 @@ void main() { ...@@ -3518,6 +3633,7 @@ void main() {
testWidgets('InputDecorationTheme outline border', (WidgetTester tester) async { testWidgets('InputDecorationTheme outline border', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, // label appears, vertically centered isEmpty: true, // label appears, vertically centered
// isFocused: false (default) // isFocused: false (default)
inputDecorationTheme: const InputDecorationTheme( inputDecorationTheme: const InputDecorationTheme(
...@@ -3534,8 +3650,8 @@ void main() { ...@@ -3534,8 +3650,8 @@ void main() {
// 16 - label (ahem font size 16dps) // 16 - label (ahem font size 16dps)
// 20 - bottom padding // 20 - bottom padding
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('label')).dy, 20.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);
expect(tester.getBottomLeft(find.text('label')).dy, 36.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0: 36.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 1.0); expect(getBorderWeight(tester), 1.0);
}); });
...@@ -3543,6 +3659,7 @@ void main() { ...@@ -3543,6 +3659,7 @@ void main() {
testWidgets('InputDecorationTheme outline border, dense layout', (WidgetTester tester) async { testWidgets('InputDecorationTheme outline border, dense layout', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, // label appears, vertically centered isEmpty: true, // label appears, vertically centered
// isFocused: false (default) // isFocused: false (default)
inputDecorationTheme: const InputDecorationTheme( inputDecorationTheme: const InputDecorationTheme(
...@@ -3561,18 +3678,18 @@ void main() { ...@@ -3561,18 +3678,18 @@ void main() {
// 16 - label (ahem font size 16dps) // 16 - label (ahem font size 16dps)
// 16 - bottom padding // 16 - bottom padding
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0));
expect(tester.getTopLeft(find.text('label')).dy, 16.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 17.0 : 16.0);
expect(tester.getBottomLeft(find.text('label')).dy, 32.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 31.0 : 32.0);
expect(getBorderBottom(tester), 48.0); expect(getBorderBottom(tester), 48.0);
expect(getBorderWeight(tester), 1.0); expect(getBorderWeight(tester), 1.0);
}); });
testWidgets('InputDecorationTheme style overrides', (WidgetTester tester) async { testWidgets('InputDecorationTheme style overrides', (WidgetTester tester) async {
const TextStyle style16 = TextStyle(fontFamily: 'Ahem', fontSize: 16.0); final TextStyle defaultStyle = TextStyle(fontFamily: 'Ahem', fontSize: useMaterial3 ? 14.0 : 16.0);
final TextStyle labelStyle = style16.merge(const TextStyle(color: Colors.red)); final TextStyle labelStyle = defaultStyle.merge(const TextStyle(color: Colors.red));
final TextStyle hintStyle = style16.merge(const TextStyle(color: Colors.green)); final TextStyle hintStyle = defaultStyle.merge(const TextStyle(color: Colors.green));
final TextStyle prefixStyle = style16.merge(const TextStyle(color: Colors.blue)); final TextStyle prefixStyle = defaultStyle.merge(const TextStyle(color: Colors.blue));
final TextStyle suffixStyle = style16.merge(const TextStyle(color: Colors.purple)); final TextStyle suffixStyle = defaultStyle.merge(const TextStyle(color: Colors.purple));
const TextStyle style12 = TextStyle(fontFamily: 'Ahem', fontSize: 12.0); const TextStyle style12 = TextStyle(fontFamily: 'Ahem', fontSize: 12.0);
final TextStyle helperStyle = style12.merge(const TextStyle(color: Colors.orange)); final TextStyle helperStyle = style12.merge(const TextStyle(color: Colors.orange));
...@@ -3585,6 +3702,7 @@ void main() { ...@@ -3585,6 +3702,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, // label appears, vertically centered isEmpty: true, // label appears, vertically centered
// isFocused: false (default) // isFocused: false (default)
inputDecorationTheme: InputDecorationTheme( inputDecorationTheme: InputDecorationTheme(
...@@ -3616,8 +3734,8 @@ void main() { ...@@ -3616,8 +3734,8 @@ void main() {
// 8 - below the border padding // 8 - below the border padding
// 12 - help/error/counter text (ahem font size 12dps) // 12 - help/error/counter text (ahem font size 12dps)
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0));
expect(tester.getTopLeft(find.text('label')).dy, 20.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);
expect(tester.getBottomLeft(find.text('label')).dy, 36.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0: 36.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 1.0); expect(getBorderWeight(tester), 1.0);
expect(tester.getTopLeft(find.text('helper')), const Offset(0.0, 64.0)); expect(tester.getTopLeft(find.text('helper')), const Offset(0.0, 64.0));
...@@ -3633,12 +3751,12 @@ void main() { ...@@ -3633,12 +3751,12 @@ void main() {
}); });
testWidgets('InputDecorationTheme style overrides (focused)', (WidgetTester tester) async { testWidgets('InputDecorationTheme style overrides (focused)', (WidgetTester tester) async {
const TextStyle style16 = TextStyle(fontFamily: 'Ahem', fontSize: 16.0); final TextStyle defaultStyle = TextStyle(fontFamily: 'Ahem', fontSize: useMaterial3 ? 14.0 : 16.0);
final TextStyle labelStyle = style16.merge(const TextStyle(color: Colors.red)); final TextStyle labelStyle = defaultStyle.merge(const TextStyle(color: Colors.red));
final TextStyle floatingLabelStyle = style16.merge(const TextStyle(color: Colors.indigo)); final TextStyle floatingLabelStyle = defaultStyle.merge(const TextStyle(color: Colors.indigo));
final TextStyle hintStyle = style16.merge(const TextStyle(color: Colors.green)); final TextStyle hintStyle = defaultStyle.merge(const TextStyle(color: Colors.green));
final TextStyle prefixStyle = style16.merge(const TextStyle(color: Colors.blue)); final TextStyle prefixStyle = defaultStyle.merge(const TextStyle(color: Colors.blue));
final TextStyle suffixStyle = style16.merge(const TextStyle(color: Colors.purple)); final TextStyle suffixStyle = defaultStyle.merge(const TextStyle(color: Colors.purple));
const TextStyle style12 = TextStyle(fontFamily: 'Ahem', fontSize: 12.0); const TextStyle style12 = TextStyle(fontFamily: 'Ahem', fontSize: 12.0);
final TextStyle helperStyle = style12.merge(const TextStyle(color: Colors.orange)); final TextStyle helperStyle = style12.merge(const TextStyle(color: Colors.orange));
...@@ -3651,6 +3769,7 @@ void main() { ...@@ -3651,6 +3769,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
isFocused: true, // Label appears floating above input field. isFocused: true, // Label appears floating above input field.
inputDecorationTheme: InputDecorationTheme( inputDecorationTheme: InputDecorationTheme(
...@@ -3683,8 +3802,8 @@ void main() { ...@@ -3683,8 +3802,8 @@ void main() {
// 8 - below the border padding // 8 - below the border padding
// 12 - help/error/counter text (ahem font size 12dps) // 12 - help/error/counter text (ahem font size 12dps)
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0));
expect(tester.getTopLeft(find.text('label')).dy, 12.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
expect(tester.getBottomLeft(find.text('label')).dy, 24.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 2.0); expect(getBorderWeight(tester), 2.0);
expect(tester.getTopLeft(find.text('helper')), const Offset(0.0, 64.0)); expect(tester.getTopLeft(find.text('helper')), const Offset(0.0, 64.0));
...@@ -3716,6 +3835,7 @@ void main() { ...@@ -3716,6 +3835,7 @@ void main() {
testWidgets('InputDecorator.debugDescribeChildren', (WidgetTester tester) async { testWidgets('InputDecorator.debugDescribeChildren', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
decoration: const InputDecoration( decoration: const InputDecoration(
icon: Text('icon'), icon: Text('icon'),
labelText: 'label', labelText: 'label',
...@@ -3758,6 +3878,7 @@ void main() { ...@@ -3758,6 +3878,7 @@ void main() {
// Regression test for https://github.com/flutter/flutter/issues/14165 // Regression test for https://github.com/flutter/flutter/issues/14165
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -3769,8 +3890,8 @@ void main() { ...@@ -3769,8 +3890,8 @@ void main() {
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(getBorderWeight(tester), 0.0); expect(getBorderWeight(tester), 0.0);
expect(tester.getTopLeft(find.text('label')).dy, 12.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
expect(tester.getBottomLeft(find.text('label')).dy, 24.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
}); });
testWidgets('InputDecorationTheme.inputDecoration', (WidgetTester tester) async { testWidgets('InputDecorationTheme.inputDecoration', (WidgetTester tester) async {
...@@ -3978,6 +4099,7 @@ void main() { ...@@ -3978,6 +4099,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -4016,6 +4138,7 @@ void main() { ...@@ -4016,6 +4138,7 @@ void main() {
testWidgets('InputDecorator UnderlineInputBorder fillColor is clipped by border', (WidgetTester tester) async { testWidgets('InputDecorator UnderlineInputBorder fillColor is clipped by border', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default) // isEmpty: false (default)
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -4158,10 +4281,10 @@ void main() { ...@@ -4158,10 +4281,10 @@ void main() {
); );
testWidgets('InputDecorator draws and animates hoverColor', (WidgetTester tester) async { testWidgets('InputDecorator draws and animates hoverColor', (WidgetTester tester) async {
const Color fillColor = Color(0x0A000000); final Color fillColor = useMaterial3 ? const Color(0xffffffff) : const Color(0x0A000000);
const Color hoverColor = Color(0xFF00FF00); const Color hoverColor = Color(0xFF00FF00);
const Color disabledColor = Color(0x05000000); final Color disabledColor =useMaterial3 ? const Color(0x0A000000) : const Color(0x05000000);
const Color enabledBorderColor = Color(0x61000000); final Color enabledBorderColor = useMaterial3 ? const Color(0xffffffff) : const Color(0x61000000);
Future<void> pumpDecorator({ Future<void> pumpDecorator({
required bool hovering, required bool hovering,
...@@ -4170,13 +4293,14 @@ void main() { ...@@ -4170,13 +4293,14 @@ void main() {
}) async { }) async {
return tester.pumpWidget( return tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isHovering: hovering, isHovering: hovering,
decoration: InputDecoration( decoration: InputDecoration(
enabled: enabled, enabled: enabled,
filled: filled, filled: filled,
hoverColor: hoverColor, hoverColor: hoverColor,
disabledBorder: const OutlineInputBorder(borderSide: BorderSide(color: disabledColor)), disabledBorder: OutlineInputBorder(borderSide: BorderSide(color: disabledColor)),
border: const OutlineInputBorder(borderSide: BorderSide(color: enabledBorderColor)), border: OutlineInputBorder(borderSide: BorderSide(color: enabledBorderColor)),
), ),
), ),
); );
...@@ -4209,7 +4333,7 @@ void main() { ...@@ -4209,7 +4333,7 @@ void main() {
expect(getContainerColor(tester), equals(disabledColor)); expect(getContainerColor(tester), equals(disabledColor));
// Test outline text field. // Test outline text field.
const Color blendedHoverColor = Color(0x74004400); final Color blendedHoverColor = useMaterial3 ? const Color(0xff000000) : const Color(0x74004400);
await pumpDecorator(hovering: false, filled: false); await pumpDecorator(hovering: false, filled: false);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getBorderColor(tester), equals(enabledBorderColor)); expect(getBorderColor(tester), equals(enabledBorderColor));
...@@ -4240,7 +4364,7 @@ void main() { ...@@ -4240,7 +4364,7 @@ void main() {
testWidgets('InputDecorator draws and animates focusColor', (WidgetTester tester) async { testWidgets('InputDecorator draws and animates focusColor', (WidgetTester tester) async {
const Color focusColor = Color(0xFF0000FF); const Color focusColor = Color(0xFF0000FF);
const Color disabledColor = Color(0x05000000); const Color disabledColor = Color(0x05000000);
const Color enabledBorderColor = Color(0x61000000); final Color enabledBorderColor = useMaterial3 ? const Color(0xffffffff) : const Color(0x61000000);
Future<void> pumpDecorator({ Future<void> pumpDecorator({
required bool focused, required bool focused,
...@@ -4249,6 +4373,7 @@ void main() { ...@@ -4249,6 +4373,7 @@ void main() {
}) async { }) async {
return tester.pumpWidget( return tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isFocused: focused, isFocused: focused,
decoration: InputDecoration( decoration: InputDecoration(
enabled: enabled, enabled: enabled,
...@@ -4256,7 +4381,7 @@ void main() { ...@@ -4256,7 +4381,7 @@ void main() {
focusColor: focusColor, focusColor: focusColor,
focusedBorder: const OutlineInputBorder(borderSide: BorderSide(color: focusColor)), focusedBorder: const OutlineInputBorder(borderSide: BorderSide(color: focusColor)),
disabledBorder: const OutlineInputBorder(borderSide: BorderSide(color: disabledColor)), disabledBorder: const OutlineInputBorder(borderSide: BorderSide(color: disabledColor)),
border: const OutlineInputBorder(borderSide: BorderSide(color: enabledBorderColor)), border: OutlineInputBorder(borderSide: BorderSide(color: enabledBorderColor)),
), ),
), ),
); );
...@@ -4300,6 +4425,7 @@ void main() { ...@@ -4300,6 +4425,7 @@ void main() {
}) async { }) async {
return tester.pumpWidget( return tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: empty, isEmpty: empty,
isFocused: focused, isFocused: focused,
decoration: InputDecoration( decoration: InputDecoration(
...@@ -4316,44 +4442,45 @@ void main() { ...@@ -4316,44 +4442,45 @@ void main() {
await pumpDecorator(focused: false); await pumpDecorator(focused: false);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getLabelRect(tester).topLeft, equals(const Offset(12, 20))); final Size labelSize= useMaterial3 ? const Size(70, 14) : const Size(80, 16);
expect(getLabelRect(tester).size, equals(const Size(80, 16))); expect(getLabelRect(tester).topLeft, equals(Offset(12, useMaterial3 ? 21 : 20)));
expect(getLabelRect(tester).size, equals(labelSize));
await pumpDecorator(focused: false, empty: false); await pumpDecorator(focused: false, empty: false);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getLabelRect(tester).topLeft, equals(const Offset(12, -5.5))); expect(getLabelRect(tester).topLeft, equals(Offset(12, useMaterial3 ? -4.75 : -5.5)));
expect(getLabelRect(tester).size, equals(const Size(80, 16) * 0.75)); expect(getLabelRect(tester).size, equals(labelSize * 0.75));
await pumpDecorator(focused: true); await pumpDecorator(focused: true);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getLabelRect(tester).topLeft, equals(const Offset(12, -5.5))); expect(getLabelRect(tester).topLeft, equals(Offset(12, useMaterial3 ? -4.75 : -5.5)));
expect(getLabelRect(tester).size, equals(const Size(80, 16) * 0.75)); expect(getLabelRect(tester).size, equals(labelSize * 0.75));
await pumpDecorator(focused: true, empty: false); await pumpDecorator(focused: true, empty: false);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getLabelRect(tester).topLeft, equals(const Offset(12, -5.5))); expect(getLabelRect(tester).topLeft, equals( Offset(12, useMaterial3 ? -4.75 : -5.5)));
expect(getLabelRect(tester).size, equals(const Size(80, 16) * 0.75)); expect(getLabelRect(tester).size, equals(labelSize * 0.75));
await pumpDecorator(focused: false, enabled: false); await pumpDecorator(focused: false, enabled: false);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getLabelRect(tester).topLeft, equals(const Offset(12, 20))); expect(getLabelRect(tester).topLeft, equals(Offset(12, useMaterial3 ? 21 : 20)));
expect(getLabelRect(tester).size, equals(const Size(80, 16))); expect(getLabelRect(tester).size, equals(labelSize));
await pumpDecorator(focused: false, empty: false, enabled: false); await pumpDecorator(focused: false, empty: false, enabled: false);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getLabelRect(tester).topLeft, equals(const Offset(12, -5.5))); expect(getLabelRect(tester).topLeft, equals( Offset(12, useMaterial3 ? -4.75 : -5.5)));
expect(getLabelRect(tester).size, equals(const Size(80, 16) * 0.75)); expect(getLabelRect(tester).size, equals(labelSize * 0.75));
// Focused and disabled happens with NavigationMode.directional. // Focused and disabled happens with NavigationMode.directional.
await pumpDecorator(focused: true, enabled: false); await pumpDecorator(focused: true, enabled: false);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getLabelRect(tester).topLeft, equals(const Offset(12, 20))); expect(getLabelRect(tester).topLeft, equals(Offset(12, useMaterial3 ? 21 : 20)));
expect(getLabelRect(tester).size, equals(const Size(80, 16))); expect(getLabelRect(tester).size, equals(labelSize));
await pumpDecorator(focused: true, empty: false, enabled: false); await pumpDecorator(focused: true, empty: false, enabled: false);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getLabelRect(tester).topLeft, equals(const Offset(12, -5.5))); expect(getLabelRect(tester).topLeft, equals( Offset(12, useMaterial3 ? -4.75 : -5.5)));
expect(getLabelRect(tester).size, equals(const Size(80, 16) * 0.75)); expect(getLabelRect(tester).size, equals(labelSize * 0.75));
}); });
testWidgets('InputDecorationTheme.toString()', (WidgetTester tester) async { testWidgets('InputDecorationTheme.toString()', (WidgetTester tester) async {
...@@ -4410,12 +4537,14 @@ void main() { ...@@ -4410,12 +4537,14 @@ void main() {
testWidgets('InputDecoration default border uses colorScheme', (WidgetTester tester) async { testWidgets('InputDecoration default border uses colorScheme', (WidgetTester tester) async {
final ThemeData theme = ThemeData.from(colorScheme: const ColorScheme.light()); final ThemeData theme = ThemeData.from(colorScheme: const ColorScheme.light());
final Color enabledColor = theme.colorScheme.onSurface.withOpacity(0.38); final Color enabledColor = useMaterial3 ? theme.colorScheme.onSurfaceVariant : theme.colorScheme.onSurface.withOpacity(0.38);
final Color disabledColor = useMaterial3 ? theme.colorScheme.onSurface.withOpacity(0.12) : theme.disabledColor;
final Color hoverColor = Color.alphaBlend(theme.hoverColor.withOpacity(0.12), enabledColor); final Color hoverColor = Color.alphaBlend(theme.hoverColor.withOpacity(0.12), enabledColor);
// Enabled // Enabled
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
theme: theme, theme: theme,
), ),
); );
...@@ -4425,6 +4554,7 @@ void main() { ...@@ -4425,6 +4554,7 @@ void main() {
// Filled // Filled
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
theme: theme, theme: theme,
decoration: const InputDecoration( decoration: const InputDecoration(
filled: true, filled: true,
...@@ -4432,11 +4562,12 @@ void main() { ...@@ -4432,11 +4562,12 @@ void main() {
), ),
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getBorderColor(tester), theme.hintColor); expect(getBorderColor(tester), useMaterial3 ? theme.colorScheme.onSurfaceVariant : theme.hintColor);
// Hovering // Hovering
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
theme: theme, theme: theme,
isHovering: true, isHovering: true,
), ),
...@@ -4447,6 +4578,7 @@ void main() { ...@@ -4447,6 +4578,7 @@ void main() {
// Focused // Focused
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
theme: theme, theme: theme,
isFocused: true, isFocused: true,
), ),
...@@ -4457,6 +4589,7 @@ void main() { ...@@ -4457,6 +4589,7 @@ void main() {
// Error // Error
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
theme: theme, theme: theme,
decoration: const InputDecoration( decoration: const InputDecoration(
errorText: 'Nope', errorText: 'Nope',
...@@ -4469,6 +4602,7 @@ void main() { ...@@ -4469,6 +4602,7 @@ void main() {
// Disabled // Disabled
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
theme: theme, theme: theme,
decoration: const InputDecoration( decoration: const InputDecoration(
enabled: false, enabled: false,
...@@ -4476,11 +4610,12 @@ void main() { ...@@ -4476,11 +4610,12 @@ void main() {
), ),
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getBorderColor(tester), theme.disabledColor); expect(getBorderColor(tester), disabledColor);
// Disabled, filled // Disabled, filled
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
theme: theme, theme: theme,
decoration: const InputDecoration( decoration: const InputDecoration(
enabled: false, enabled: false,
...@@ -4489,7 +4624,7 @@ void main() { ...@@ -4489,7 +4624,7 @@ void main() {
), ),
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getBorderColor(tester), Colors.transparent); expect(getBorderColor(tester), useMaterial3 ? theme.colorScheme.onSurface.withOpacity(0.38) : Colors.transparent);
}); });
testWidgets('InputDecoration borders', (WidgetTester tester) async { testWidgets('InputDecoration borders', (WidgetTester tester) async {
...@@ -4511,6 +4646,7 @@ void main() { ...@@ -4511,6 +4646,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
// errorText: null (default) // errorText: null (default)
...@@ -4527,6 +4663,7 @@ void main() { ...@@ -4527,6 +4663,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isFocused: true, isFocused: true,
decoration: const InputDecoration( decoration: const InputDecoration(
// errorText: null (default) // errorText: null (default)
...@@ -4544,6 +4681,7 @@ void main() { ...@@ -4544,6 +4681,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isFocused: true, isFocused: true,
decoration: const InputDecoration( decoration: const InputDecoration(
errorText: 'error', errorText: 'error',
...@@ -4561,6 +4699,7 @@ void main() { ...@@ -4561,6 +4699,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
errorText: 'error', errorText: 'error',
...@@ -4578,6 +4717,7 @@ void main() { ...@@ -4578,6 +4717,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
errorText: 'error', errorText: 'error',
...@@ -4595,6 +4735,7 @@ void main() { ...@@ -4595,6 +4735,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isFocused: false (default) // isFocused: false (default)
decoration: const InputDecoration( decoration: const InputDecoration(
// errorText: false (default) // errorText: false (default)
...@@ -4612,6 +4753,7 @@ void main() { ...@@ -4612,6 +4753,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isFocused: true, isFocused: true,
decoration: const InputDecoration( decoration: const InputDecoration(
// errorText: null (default) // errorText: null (default)
...@@ -4644,6 +4786,7 @@ void main() { ...@@ -4644,6 +4786,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
decoration: const InputDecoration( decoration: const InputDecoration(
filled: true, filled: true,
fillColor: Color(0xFF00FF00), fillColor: Color(0xFF00FF00),
...@@ -4748,6 +4891,7 @@ void main() { ...@@ -4748,6 +4891,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
decoration: InputDecoration( decoration: InputDecoration(
filled: true, filled: true,
fillColor: const Color(0xFF00FF00), fillColor: const Color(0xFF00FF00),
...@@ -5036,6 +5180,7 @@ void main() { ...@@ -5036,6 +5180,7 @@ void main() {
// Regression test for https://github.com/flutter/flutter/issues/54028 // Regression test for https://github.com/flutter/flutter/issues/54028
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: 'label', labelText: 'label',
...@@ -5051,12 +5196,13 @@ void main() { ...@@ -5051,12 +5196,13 @@ void main() {
// floatingLabelHeight = 12 (ahem font size 16dps * 0.75 = 12) // floatingLabelHeight = 12 (ahem font size 16dps * 0.75 = 12)
// labelY = -floatingLabelHeight/2 + borderWidth/2 // labelY = -floatingLabelHeight/2 + borderWidth/2
expect(tester.getTopLeft(find.text('label')).dy, -4.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? -3.25 : -4.0);
}); });
testWidgets('InputDecorator floating label obeys floatingLabelBehavior', (WidgetTester tester) async { testWidgets('InputDecorator floating label obeys floatingLabelBehavior', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: 'label', labelText: 'label',
floatingLabelBehavior: FloatingLabelBehavior.never, floatingLabelBehavior: FloatingLabelBehavior.never,
...@@ -5066,12 +5212,13 @@ void main() { ...@@ -5066,12 +5212,13 @@ void main() {
// Passing floating behavior never results in a dy offset of 20 // Passing floating behavior never results in a dy offset of 20
// because the label is not initially floating. // because the label is not initially floating.
expect(tester.getTopLeft(find.text('label')).dy, 20.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);
}); });
testWidgets('InputDecorator hint is displayed when floatingLabelBehavior is always', (WidgetTester tester) async { testWidgets('InputDecorator hint is displayed when floatingLabelBehavior is always', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
// isFocused: false (default) // isFocused: false (default)
isEmpty: true, isEmpty: true,
decoration: const InputDecoration( decoration: const InputDecoration(
...@@ -5096,6 +5243,7 @@ void main() { ...@@ -5096,6 +5243,7 @@ void main() {
width: 100, width: 100,
height: 100, height: 100,
child: buildInputDecorator( child: buildInputDecorator(
useMaterial3: useMaterial3,
// isFocused: false (default) // isFocused: false (default)
isEmpty: true, isEmpty: true,
decoration: InputDecoration( decoration: InputDecoration(
...@@ -5110,7 +5258,7 @@ void main() { ...@@ -5110,7 +5258,7 @@ void main() {
expect( expect(
find.text(longStringA), find.text(longStringA),
paints..clipRect(rect: const Rect.fromLTWH(0, 0, 100.0, 16.0)), paints..clipRect(rect: Rect.fromLTWH(0, 0, 100.0, useMaterial3 ? 14.0 : 16.0)),
); );
await tester.pumpWidget( await tester.pumpWidget(
...@@ -5119,6 +5267,7 @@ void main() { ...@@ -5119,6 +5267,7 @@ void main() {
width: 100, width: 100,
height: 100, height: 100,
child: buildInputDecorator( child: buildInputDecorator(
useMaterial3: useMaterial3,
isFocused: true, isFocused: true,
isEmpty: true, isEmpty: true,
decoration: InputDecoration( decoration: InputDecoration(
...@@ -5134,7 +5283,7 @@ void main() { ...@@ -5134,7 +5283,7 @@ void main() {
expect( expect(
find.text(longStringB), find.text(longStringB),
// 133.3 is approximately 100 / 0.75 (_kFinalLabelScale) // 133.3 is approximately 100 / 0.75 (_kFinalLabelScale)
paints..clipRect(rect: const Rect.fromLTWH(0, 0, 133.0, 16.0)), paints..clipRect(rect: Rect.fromLTWH(0, 0, 133.0, useMaterial3 ? 14.0 : 16.0)),
); );
}, skip: isBrowser); // TODO(yjbanov): https://github.com/flutter/flutter/issues/44020 }, skip: isBrowser); // TODO(yjbanov): https://github.com/flutter/flutter/issues/44020
...@@ -5619,6 +5768,7 @@ void main() { ...@@ -5619,6 +5768,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
isFocused: true, // Label appears floating above input field. isFocused: true, // Label appears floating above input field.
inputDecorationTheme: InputDecorationTheme( inputDecorationTheme: InputDecorationTheme(
...@@ -5640,8 +5790,8 @@ void main() { ...@@ -5640,8 +5790,8 @@ void main() {
// 16 - input text (ahem font size 16dps) // 16 - input text (ahem font size 16dps)
// 12 - bottom padding // 12 - bottom padding
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('label')).dy, 12.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
expect(tester.getBottomLeft(find.text('label')).dy, 24.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 24.75 : 24.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 2.0); expect(getBorderWeight(tester), 2.0);
...@@ -5650,8 +5800,8 @@ void main() { ...@@ -5650,8 +5800,8 @@ void main() {
}); });
testWidgets('InputDecorationTheme labelStyle overrides label widget styles when the widget is a text widget', (WidgetTester tester) async { testWidgets('InputDecorationTheme labelStyle overrides label widget styles when the widget is a text widget', (WidgetTester tester) async {
const TextStyle style16 = TextStyle(fontFamily: 'Ahem', fontSize: 16.0); final TextStyle styleDefaultSize = TextStyle(fontFamily: 'Ahem', fontSize: useMaterial3 ? 14.0 : 16.0);
final TextStyle labelStyle = style16.merge(const TextStyle(color: Colors.purple)); final TextStyle labelStyle = styleDefaultSize.merge(const TextStyle(color: Colors.purple));
// This test also verifies that the default InputDecorator provides a // This test also verifies that the default InputDecorator provides a
// "small concession to backwards compatibility" by not padding on // "small concession to backwards compatibility" by not padding on
...@@ -5660,6 +5810,7 @@ void main() { ...@@ -5660,6 +5810,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildInputDecorator( buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, // Label appears inline, on top of the input field. isEmpty: true, // Label appears inline, on top of the input field.
inputDecorationTheme: InputDecorationTheme( inputDecorationTheme: InputDecorationTheme(
labelStyle: labelStyle, labelStyle: labelStyle,
...@@ -5680,8 +5831,8 @@ void main() { ...@@ -5680,8 +5831,8 @@ void main() {
// 16 - input text (ahem font size 16dps) // 16 - input text (ahem font size 16dps)
// 12 - bottom padding // 12 - bottom padding
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0)); expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('label')).dy, 20.0); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);
expect(tester.getBottomLeft(find.text('label')).dy, 36.0); expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0 : 36.0);
expect(getBorderBottom(tester), 56.0); expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 1.0); expect(getBorderWeight(tester), 1.0);
...@@ -5692,6 +5843,7 @@ void main() { ...@@ -5692,6 +5843,7 @@ void main() {
testWidgets("InputDecorator's floating label origin no longer depends on ThemeData.fixTextFieldOutlineLabel", (WidgetTester tester) async { testWidgets("InputDecorator's floating label origin no longer depends on ThemeData.fixTextFieldOutlineLabel", (WidgetTester tester) async {
Widget buildFrame(bool fixTextFieldOutlineLabel) { Widget buildFrame(bool fixTextFieldOutlineLabel) {
return buildInputDecorator( return buildInputDecorator(
useMaterial3: useMaterial3,
isEmpty: true, isEmpty: true,
theme: ThemeData.light().copyWith( theme: ThemeData.light().copyWith(
fixTextFieldOutlineLabel: fixTextFieldOutlineLabel, fixTextFieldOutlineLabel: fixTextFieldOutlineLabel,
...@@ -5709,11 +5861,12 @@ void main() { ...@@ -5709,11 +5861,12 @@ void main() {
// floatingLabelHeight = 12 (ahem font size 16dps * 0.75 = 12) // floatingLabelHeight = 12 (ahem font size 16dps * 0.75 = 12)
// labelY = -floatingLabelHeight/2 + borderWidth/2 // labelY = -floatingLabelHeight/2 + borderWidth/2
expect(tester.getTopLeft(find.text('label')).dy, -5.5); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? -4.75 : -5.5);
await tester.pumpWidget(buildFrame(true)); await tester.pumpWidget(buildFrame(true));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getTopLeft(find.text('label')).dy, -5.5); expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? -4.75 : -5.5);
}); });
} }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment