Fix handling of iconSize
and iconColor
defaults for ButtonStyleButton
subclasses. (#143501)
## Description Adds defaults that use tokens to define default `iconSize` and `iconColor` values. Previously, the Material 3 token values for button icon sizes and colors were not being used as defaults when the `ButtonStyleButton.defaultStyleOf` function returned the default values. Adds tests to make sure appropriate `ButtonStyle` fields are populated when defaultStyle is called on buttons. Updated documentation for `defaultStyleOf` to indicated that not _all_ fields need to be non-null, since some fields make sense to be null (e.g. `fixedSize`) because they would otherwise override the behavior of other fields in the same `ButtonStyle`. ## Tests - Added tests to make sure that the appropriate fields are non-null in the default button styles for each type of button.
This commit is contained in:
parent
97996b07a2
commit
51ed348f3b
@ -145,6 +145,13 @@ md.comp.elevated-button.label-text.text-style,
|
||||
md.comp.elevated-button.pressed.container.elevation,
|
||||
md.comp.elevated-button.pressed.state-layer.color,
|
||||
md.comp.elevated-button.pressed.state-layer.opacity,
|
||||
md.comp.elevated-button.with-icon.disabled.icon.color,
|
||||
md.comp.elevated-button.with-icon.disabled.icon.opacity,
|
||||
md.comp.elevated-button.with-icon.focus.icon.color,
|
||||
md.comp.elevated-button.with-icon.hover.icon.color,
|
||||
md.comp.elevated-button.with-icon.icon.color,
|
||||
md.comp.elevated-button.with-icon.icon.size,
|
||||
md.comp.elevated-button.with-icon.pressed.icon.color,
|
||||
md.comp.elevated-card.container.color,
|
||||
md.comp.elevated-card.container.elevation,
|
||||
md.comp.elevated-card.container.shadow-color,
|
||||
@ -198,6 +205,13 @@ md.comp.filled-button.label-text.text-style,
|
||||
md.comp.filled-button.pressed.container.elevation,
|
||||
md.comp.filled-button.pressed.state-layer.color,
|
||||
md.comp.filled-button.pressed.state-layer.opacity,
|
||||
md.comp.filled-button.with-icon.disabled.icon.color,
|
||||
md.comp.filled-button.with-icon.disabled.icon.opacity,
|
||||
md.comp.filled-button.with-icon.focus.icon.color,
|
||||
md.comp.filled-button.with-icon.hover.icon.color,
|
||||
md.comp.filled-button.with-icon.icon.color,
|
||||
md.comp.filled-button.with-icon.icon.size,
|
||||
md.comp.filled-button.with-icon.pressed.icon.color,
|
||||
md.comp.filled-card.container.color,
|
||||
md.comp.filled-card.container.elevation,
|
||||
md.comp.filled-card.container.shadow-color,
|
||||
@ -296,6 +310,13 @@ md.comp.filled-tonal-button.label-text.text-style,
|
||||
md.comp.filled-tonal-button.pressed.container.elevation,
|
||||
md.comp.filled-tonal-button.pressed.state-layer.color,
|
||||
md.comp.filled-tonal-button.pressed.state-layer.opacity,
|
||||
md.comp.filled-tonal-button.with-icon.disabled.icon.color,
|
||||
md.comp.filled-tonal-button.with-icon.disabled.icon.opacity,
|
||||
md.comp.filled-tonal-button.with-icon.focus.icon.color,
|
||||
md.comp.filled-tonal-button.with-icon.hover.icon.color,
|
||||
md.comp.filled-tonal-button.with-icon.icon.color,
|
||||
md.comp.filled-tonal-button.with-icon.icon.size,
|
||||
md.comp.filled-tonal-button.with-icon.pressed.icon.color,
|
||||
md.comp.filled-tonal-icon-button.container.color,
|
||||
md.comp.filled-tonal-icon-button.container.height,
|
||||
md.comp.filled-tonal-icon-button.container.shape,
|
||||
@ -405,6 +426,7 @@ md.comp.list.list-item.hover.state-layer.opacity,
|
||||
md.comp.list.list-item.label-text.color,
|
||||
md.comp.list.list-item.label-text.text-style,
|
||||
md.comp.list.list-item.leading-icon.color,
|
||||
md.comp.list.list-item.leading-icon.size,
|
||||
md.comp.list.list-item.pressed.label-text.color,
|
||||
md.comp.list.list-item.pressed.leading-icon.icon.color,
|
||||
md.comp.list.list-item.pressed.state-layer.color,
|
||||
@ -470,6 +492,13 @@ md.comp.outlined-button.outline.color,
|
||||
md.comp.outlined-button.outline.width,
|
||||
md.comp.outlined-button.pressed.state-layer.color,
|
||||
md.comp.outlined-button.pressed.state-layer.opacity,
|
||||
md.comp.outlined-button.with-icon.disabled.icon.color,
|
||||
md.comp.outlined-button.with-icon.disabled.icon.opacity,
|
||||
md.comp.outlined-button.with-icon.focus.icon.color,
|
||||
md.comp.outlined-button.with-icon.hover.icon.color,
|
||||
md.comp.outlined-button.with-icon.icon.color,
|
||||
md.comp.outlined-button.with-icon.icon.size,
|
||||
md.comp.outlined-button.with-icon.pressed.icon.color,
|
||||
md.comp.outlined-card.container.color,
|
||||
md.comp.outlined-card.container.elevation,
|
||||
md.comp.outlined-card.container.shadow-color,
|
||||
@ -703,6 +732,13 @@ md.comp.text-button.label-text.color,
|
||||
md.comp.text-button.label-text.text-style,
|
||||
md.comp.text-button.pressed.state-layer.color,
|
||||
md.comp.text-button.pressed.state-layer.opacity,
|
||||
md.comp.text-button.with-icon.disabled.icon.color,
|
||||
md.comp.text-button.with-icon.disabled.icon.opacity,
|
||||
md.comp.text-button.with-icon.focus.icon.color,
|
||||
md.comp.text-button.with-icon.hover.icon.color,
|
||||
md.comp.text-button.with-icon.icon.color,
|
||||
md.comp.text-button.with-icon.icon.size,
|
||||
md.comp.text-button.with-icon.pressed.icon.color,
|
||||
md.comp.time-picker.clock-dial.color,
|
||||
md.comp.time-picker.clock-dial.container.size,
|
||||
md.comp.time-picker.clock-dial.label-text.text-style,
|
||||
|
|
@ -125,6 +125,29 @@ class _${blockName}DefaultsM3 extends ButtonStyle {
|
||||
|
||||
// No default fixedSize
|
||||
|
||||
@override
|
||||
MaterialStateProperty<double>? get iconSize =>
|
||||
const MaterialStatePropertyAll<double>(${getToken("$tokenGroup.with-icon.icon.size")});
|
||||
|
||||
@override
|
||||
MaterialStateProperty<Color>? get iconColor {
|
||||
return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.disabled)) {
|
||||
return ${color('$tokenGroup.with-icon.disabled.icon.color')}.withOpacity(${opacity("$tokenGroup.with-icon.disabled.icon.opacity")});
|
||||
}
|
||||
if (states.contains(MaterialState.pressed)) {
|
||||
return ${color('$tokenGroup.with-icon.pressed.icon.color')};
|
||||
}
|
||||
if (states.contains(MaterialState.hovered)) {
|
||||
return ${color('$tokenGroup.with-icon.hover.icon.color')};
|
||||
}
|
||||
if (states.contains(MaterialState.focused)) {
|
||||
return ${color('$tokenGroup.with-icon.focus.icon.color')};
|
||||
}
|
||||
return ${color('$tokenGroup.with-icon.icon.color')};
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
MaterialStateProperty<Size>? get maximumSize =>
|
||||
const MaterialStatePropertyAll<Size>(Size.infinite);
|
||||
|
@ -121,6 +121,11 @@ class _MenuButtonDefaultsM3 extends ButtonStyle {
|
||||
|
||||
// No default fixedSize
|
||||
|
||||
@override
|
||||
MaterialStateProperty<double>? get iconSize {
|
||||
return const MaterialStatePropertyAll<double>(${getToken("md.comp.list.list-item.leading-icon.size")});
|
||||
}
|
||||
|
||||
@override
|
||||
MaterialStateProperty<Size>? get maximumSize {
|
||||
return ButtonStyleButton.allOrNull<Size>(Size.infinite);
|
||||
|
@ -162,22 +162,39 @@ abstract class ButtonStyleButton extends StatefulWidget {
|
||||
/// {@macro flutter.material.ButtonStyleButton.iconAlignment}
|
||||
final IconAlignment iconAlignment;
|
||||
|
||||
/// Returns a non-null [ButtonStyle] that's based primarily on the [Theme]'s
|
||||
/// [ThemeData.textTheme] and [ThemeData.colorScheme].
|
||||
/// Returns a [ButtonStyle] that's based primarily on the [Theme]'s
|
||||
/// [ThemeData.textTheme] and [ThemeData.colorScheme], but has most values
|
||||
/// filled out (non-null).
|
||||
///
|
||||
/// The returned style can be overridden by the [style] parameter and
|
||||
/// by the style returned by [themeStyleOf]. For example the default
|
||||
/// style of the [TextButton] subclass can be overridden with its
|
||||
/// [TextButton.style] constructor parameter, or with a
|
||||
/// [TextButtonTheme].
|
||||
/// The returned style can be overridden by the [style] parameter and by the
|
||||
/// style returned by [themeStyleOf] that some button-specific themes like
|
||||
/// [TextButtonTheme] or [ElevatedButtonTheme] override. For example the
|
||||
/// default style of the [TextButton] subclass can be overridden with its
|
||||
/// [TextButton.style] constructor parameter, or with a [TextButtonTheme].
|
||||
///
|
||||
/// Concrete button subclasses should return a ButtonStyle that
|
||||
/// has no null properties, and where all of the [WidgetStateProperty]
|
||||
/// properties resolve to non-null values.
|
||||
/// Concrete button subclasses should return a [ButtonStyle] with as many
|
||||
/// non-null properties as possible, where all of the non-null
|
||||
/// [WidgetStateProperty] properties resolve to non-null values.
|
||||
///
|
||||
/// ## Properties that can be null
|
||||
///
|
||||
/// Some properties, like [ButtonStyle.fixedSize] would override other values
|
||||
/// in the same [ButtonStyle] if set, so they are allowed to be null. Here is
|
||||
/// a summary of properties that are allowed to be null when returned in the
|
||||
/// [ButtonStyle] returned by this function, an why:
|
||||
///
|
||||
/// - [ButtonStyle.fixedSize] because it would override other values in the
|
||||
/// same [ButtonStyle], like [ButtonStyle.maximumSize].
|
||||
/// - [ButtonStyle.side] because null is a valid value for a button that has
|
||||
/// no side. [OutlinedButton] returns a non-null default for this, however.
|
||||
/// - [ButtonStyle.backgroundBuilder] and [ButtonStyle.foregroundBuilder]
|
||||
/// because they would override the [ButtonStyle.foregroundColor] and
|
||||
/// [ButtonStyle.backgroundColor] of the same [ButtonStyle].
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [themeStyleOf], Returns the ButtonStyle of this button's component theme.
|
||||
/// * [themeStyleOf], returns the ButtonStyle of this button's component
|
||||
/// theme.
|
||||
@protected
|
||||
ButtonStyle defaultStyleOf(BuildContext context);
|
||||
|
||||
@ -479,7 +496,10 @@ class _ButtonStyleState extends State<ButtonStyleButton> with TickerProviderStat
|
||||
customBorder: resolvedShape.copyWith(side: resolvedSide),
|
||||
statesController: statesController,
|
||||
child: IconTheme.merge(
|
||||
data: IconThemeData(color: resolvedIconColor ?? resolvedForegroundColor, size: resolvedIconSize),
|
||||
data: IconThemeData(
|
||||
color: resolvedIconColor ?? resolvedForegroundColor,
|
||||
size: resolvedIconSize,
|
||||
),
|
||||
child: effectiveChild,
|
||||
),
|
||||
),
|
||||
|
@ -698,6 +698,29 @@ class _ElevatedButtonDefaultsM3 extends ButtonStyle {
|
||||
|
||||
// No default fixedSize
|
||||
|
||||
@override
|
||||
MaterialStateProperty<double>? get iconSize =>
|
||||
const MaterialStatePropertyAll<double>(18.0);
|
||||
|
||||
@override
|
||||
MaterialStateProperty<Color>? get iconColor {
|
||||
return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.disabled)) {
|
||||
return _colors.onSurface.withOpacity(0.38);
|
||||
}
|
||||
if (states.contains(MaterialState.pressed)) {
|
||||
return _colors.primary;
|
||||
}
|
||||
if (states.contains(MaterialState.hovered)) {
|
||||
return _colors.primary;
|
||||
}
|
||||
if (states.contains(MaterialState.focused)) {
|
||||
return _colors.primary;
|
||||
}
|
||||
return _colors.primary;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
MaterialStateProperty<Size>? get maximumSize =>
|
||||
const MaterialStatePropertyAll<Size>(Size.infinite);
|
||||
|
@ -730,6 +730,29 @@ class _FilledButtonDefaultsM3 extends ButtonStyle {
|
||||
|
||||
// No default fixedSize
|
||||
|
||||
@override
|
||||
MaterialStateProperty<double>? get iconSize =>
|
||||
const MaterialStatePropertyAll<double>(18.0);
|
||||
|
||||
@override
|
||||
MaterialStateProperty<Color>? get iconColor {
|
||||
return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.disabled)) {
|
||||
return _colors.onSurface.withOpacity(0.38);
|
||||
}
|
||||
if (states.contains(MaterialState.pressed)) {
|
||||
return _colors.onPrimary;
|
||||
}
|
||||
if (states.contains(MaterialState.hovered)) {
|
||||
return _colors.onPrimary;
|
||||
}
|
||||
if (states.contains(MaterialState.focused)) {
|
||||
return _colors.onPrimary;
|
||||
}
|
||||
return _colors.onPrimary;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
MaterialStateProperty<Size>? get maximumSize =>
|
||||
const MaterialStatePropertyAll<Size>(Size.infinite);
|
||||
@ -852,6 +875,29 @@ class _FilledTonalButtonDefaultsM3 extends ButtonStyle {
|
||||
|
||||
// No default fixedSize
|
||||
|
||||
@override
|
||||
MaterialStateProperty<double>? get iconSize =>
|
||||
const MaterialStatePropertyAll<double>(18.0);
|
||||
|
||||
@override
|
||||
MaterialStateProperty<Color>? get iconColor {
|
||||
return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.disabled)) {
|
||||
return _colors.onSurface.withOpacity(0.38);
|
||||
}
|
||||
if (states.contains(MaterialState.pressed)) {
|
||||
return _colors.onSecondaryContainer;
|
||||
}
|
||||
if (states.contains(MaterialState.hovered)) {
|
||||
return _colors.onSecondaryContainer;
|
||||
}
|
||||
if (states.contains(MaterialState.focused)) {
|
||||
return _colors.onSecondaryContainer;
|
||||
}
|
||||
return _colors.onSecondaryContainer;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
MaterialStateProperty<Size>? get maximumSize =>
|
||||
const MaterialStatePropertyAll<Size>(Size.infinite);
|
||||
|
@ -3800,6 +3800,11 @@ class _MenuButtonDefaultsM3 extends ButtonStyle {
|
||||
|
||||
// No default fixedSize
|
||||
|
||||
@override
|
||||
MaterialStateProperty<double>? get iconSize {
|
||||
return const MaterialStatePropertyAll<double>(24.0);
|
||||
}
|
||||
|
||||
@override
|
||||
MaterialStateProperty<Size>? get maximumSize {
|
||||
return ButtonStyleButton.allOrNull<Size>(Size.infinite);
|
||||
|
@ -606,6 +606,29 @@ class _OutlinedButtonDefaultsM3 extends ButtonStyle {
|
||||
|
||||
// No default fixedSize
|
||||
|
||||
@override
|
||||
MaterialStateProperty<double>? get iconSize =>
|
||||
const MaterialStatePropertyAll<double>(18.0);
|
||||
|
||||
@override
|
||||
MaterialStateProperty<Color>? get iconColor {
|
||||
return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.disabled)) {
|
||||
return _colors.onSurface.withOpacity(0.38);
|
||||
}
|
||||
if (states.contains(MaterialState.pressed)) {
|
||||
return _colors.primary;
|
||||
}
|
||||
if (states.contains(MaterialState.hovered)) {
|
||||
return _colors.primary;
|
||||
}
|
||||
if (states.contains(MaterialState.focused)) {
|
||||
return _colors.primary;
|
||||
}
|
||||
return _colors.primary;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
MaterialStateProperty<Size>? get maximumSize =>
|
||||
const MaterialStatePropertyAll<Size>(Size.infinite);
|
||||
|
@ -639,6 +639,29 @@ class _TextButtonDefaultsM3 extends ButtonStyle {
|
||||
|
||||
// No default fixedSize
|
||||
|
||||
@override
|
||||
MaterialStateProperty<double>? get iconSize =>
|
||||
const MaterialStatePropertyAll<double>(18.0);
|
||||
|
||||
@override
|
||||
MaterialStateProperty<Color>? get iconColor {
|
||||
return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.disabled)) {
|
||||
return _colors.onSurface.withOpacity(0.38);
|
||||
}
|
||||
if (states.contains(MaterialState.pressed)) {
|
||||
return _colors.primary;
|
||||
}
|
||||
if (states.contains(MaterialState.hovered)) {
|
||||
return _colors.primary;
|
||||
}
|
||||
if (states.contains(MaterialState.focused)) {
|
||||
return _colors.primary;
|
||||
}
|
||||
return _colors.primary;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
MaterialStateProperty<Size>? get maximumSize =>
|
||||
const MaterialStatePropertyAll<Size>(Size.infinite);
|
||||
|
@ -775,6 +775,8 @@ class ToggleButtons extends StatelessWidget {
|
||||
style: ButtonStyle(
|
||||
backgroundColor: MaterialStatePropertyAll<Color?>(effectiveFillColor),
|
||||
foregroundColor: MaterialStatePropertyAll<Color?>(currentColor),
|
||||
iconSize: const MaterialStatePropertyAll<double>(24.0),
|
||||
iconColor: MaterialStatePropertyAll<Color?>(currentColor),
|
||||
overlayColor: _ToggleButtonDefaultOverlay(
|
||||
selected: onPressed != null && isSelected[index],
|
||||
unselected: onPressed != null && !isSelected[index],
|
||||
|
@ -22,26 +22,30 @@ void main() {
|
||||
|
||||
test('ButtonStyle defaults', () {
|
||||
const ButtonStyle style = ButtonStyle();
|
||||
expect(style.textStyle, null);
|
||||
expect(style.backgroundColor, null);
|
||||
expect(style.foregroundColor, null);
|
||||
expect(style.overlayColor, null);
|
||||
expect(style.shadowColor, null);
|
||||
expect(style.surfaceTintColor, null);
|
||||
expect(style.elevation, null);
|
||||
expect(style.padding, null);
|
||||
expect(style.minimumSize, null);
|
||||
expect(style.fixedSize, null);
|
||||
expect(style.maximumSize, null);
|
||||
expect(style.iconColor, null);
|
||||
expect(style.iconSize, null);
|
||||
expect(style.side, null);
|
||||
expect(style.shape, null);
|
||||
expect(style.mouseCursor, null);
|
||||
expect(style.visualDensity, null);
|
||||
expect(style.tapTargetSize, null);
|
||||
expect(style.animationDuration, null);
|
||||
expect(style.enableFeedback, null);
|
||||
expect(style.textStyle, isNull);
|
||||
expect(style.backgroundColor, isNull);
|
||||
expect(style.foregroundColor, isNull);
|
||||
expect(style.overlayColor, isNull);
|
||||
expect(style.shadowColor, isNull);
|
||||
expect(style.surfaceTintColor, isNull);
|
||||
expect(style.elevation, isNull);
|
||||
expect(style.padding, isNull);
|
||||
expect(style.minimumSize, isNull);
|
||||
expect(style.fixedSize, isNull);
|
||||
expect(style.maximumSize, isNull);
|
||||
expect(style.iconColor, isNull);
|
||||
expect(style.iconSize, isNull);
|
||||
expect(style.side, isNull);
|
||||
expect(style.shape, isNull);
|
||||
expect(style.mouseCursor, isNull);
|
||||
expect(style.visualDensity, isNull);
|
||||
expect(style.tapTargetSize, isNull);
|
||||
expect(style.animationDuration, isNull);
|
||||
expect(style.enableFeedback, isNull);
|
||||
expect(style.alignment, isNull);
|
||||
expect(style.splashFactory, isNull);
|
||||
expect(style.backgroundBuilder, isNull);
|
||||
expect(style.foregroundBuilder, isNull);
|
||||
});
|
||||
|
||||
testWidgets('Default ButtonStyle debugFillProperties', (WidgetTester tester) async {
|
||||
|
@ -159,6 +159,114 @@ void main() {
|
||||
expect(material.type, MaterialType.button);
|
||||
});
|
||||
|
||||
testWidgets('ElevatedButton.defaultStyle produces a ButtonStyle with appropriate non-null values', (WidgetTester tester) async {
|
||||
const ColorScheme colorScheme = ColorScheme.light();
|
||||
final ThemeData theme = ThemeData.from(colorScheme: colorScheme);
|
||||
|
||||
final ElevatedButton button = ElevatedButton(
|
||||
onPressed: () { },
|
||||
child: const Text('button'),
|
||||
);
|
||||
BuildContext? capturedContext;
|
||||
// Enabled ElevatedButton
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme,
|
||||
home: Center(
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
capturedContext = context;
|
||||
return button;
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
final ButtonStyle style = button.defaultStyleOf(capturedContext!);
|
||||
|
||||
// Properties that must be non-null.
|
||||
expect(style.textStyle, isNotNull, reason: 'textStyle style');
|
||||
expect(style.backgroundColor, isNotNull, reason: 'backgroundColor style');
|
||||
expect(style.foregroundColor, isNotNull, reason: 'foregroundColor style');
|
||||
expect(style.overlayColor, isNotNull, reason: 'overlayColor style');
|
||||
expect(style.shadowColor, isNotNull, reason: 'shadowColor style');
|
||||
expect(style.surfaceTintColor, isNotNull, reason: 'surfaceTintColor style');
|
||||
expect(style.elevation, isNotNull, reason: 'elevation style');
|
||||
expect(style.padding, isNotNull, reason: 'padding style');
|
||||
expect(style.minimumSize, isNotNull, reason: 'minimumSize style');
|
||||
expect(style.maximumSize, isNotNull, reason: 'maximumSize style');
|
||||
expect(style.iconColor, isNotNull, reason: 'iconColor style');
|
||||
expect(style.iconSize, isNotNull, reason: 'iconSize style');
|
||||
expect(style.shape, isNotNull, reason: 'shape style');
|
||||
expect(style.mouseCursor, isNotNull, reason: 'mouseCursor style');
|
||||
expect(style.visualDensity, isNotNull, reason: 'visualDensity style');
|
||||
expect(style.tapTargetSize, isNotNull, reason: 'tapTargetSize style');
|
||||
expect(style.animationDuration, isNotNull, reason: 'animationDuration style');
|
||||
expect(style.enableFeedback, isNotNull, reason: 'enableFeedback style');
|
||||
expect(style.alignment, isNotNull, reason: 'alignment style');
|
||||
expect(style.splashFactory, isNotNull, reason: 'splashFactory style');
|
||||
|
||||
// Properties that are expected to be null.
|
||||
expect(style.fixedSize, isNull, reason: 'fixedSize style');
|
||||
expect(style.side, isNull, reason: 'side style');
|
||||
expect(style.backgroundBuilder, isNull, reason: 'backgroundBuilder style');
|
||||
expect(style.foregroundBuilder, isNull, reason: 'foregroundBuilder style');
|
||||
});
|
||||
|
||||
testWidgets('ElevatedButton.defaultStyle with an icon produces a ButtonStyle with appropriate non-null values', (WidgetTester tester) async {
|
||||
const ColorScheme colorScheme = ColorScheme.light();
|
||||
final ThemeData theme = ThemeData.from(colorScheme: colorScheme);
|
||||
|
||||
final ElevatedButton button = ElevatedButton.icon(
|
||||
onPressed: () { },
|
||||
icon: const SizedBox(),
|
||||
label: const Text('button'),
|
||||
);
|
||||
BuildContext? capturedContext;
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme,
|
||||
home: Center(
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
capturedContext = context;
|
||||
return button;
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
final ButtonStyle style = button.defaultStyleOf(capturedContext!);
|
||||
|
||||
// Properties that must be non-null.
|
||||
expect(style.textStyle, isNotNull, reason: 'textStyle style');
|
||||
expect(style.backgroundColor, isNotNull, reason: 'backgroundColor style');
|
||||
expect(style.foregroundColor, isNotNull, reason: 'foregroundColor style');
|
||||
expect(style.overlayColor, isNotNull, reason: 'overlayColor style');
|
||||
expect(style.shadowColor, isNotNull, reason: 'shadowColor style');
|
||||
expect(style.surfaceTintColor, isNotNull, reason: 'surfaceTintColor style');
|
||||
expect(style.elevation, isNotNull, reason: 'elevation style');
|
||||
expect(style.padding, isNotNull, reason: 'padding style');
|
||||
expect(style.minimumSize, isNotNull, reason: 'minimumSize style');
|
||||
expect(style.maximumSize, isNotNull, reason: 'maximumSize style');
|
||||
expect(style.iconColor, isNotNull, reason: 'iconColor style');
|
||||
expect(style.iconSize, isNotNull, reason: 'iconSize style');
|
||||
expect(style.shape, isNotNull, reason: 'shape style');
|
||||
expect(style.mouseCursor, isNotNull, reason: 'mouseCursor style');
|
||||
expect(style.visualDensity, isNotNull, reason: 'visualDensity style');
|
||||
expect(style.tapTargetSize, isNotNull, reason: 'tapTargetSize style');
|
||||
expect(style.animationDuration, isNotNull, reason: 'animationDuration style');
|
||||
expect(style.enableFeedback, isNotNull, reason: 'enableFeedback style');
|
||||
expect(style.alignment, isNotNull, reason: 'alignment style');
|
||||
expect(style.splashFactory, isNotNull, reason: 'splashFactory style');
|
||||
|
||||
// Properties that are expected to be null.
|
||||
expect(style.fixedSize, isNull, reason: 'fixedSize style');
|
||||
expect(style.side, isNull, reason: 'side style');
|
||||
expect(style.backgroundBuilder, isNull, reason: 'backgroundBuilder style');
|
||||
expect(style.foregroundBuilder, isNull, reason: 'foregroundBuilder style');
|
||||
});
|
||||
|
||||
testWidgets('ElevatedButton.icon produces the correct widgets if icon is null', (WidgetTester tester) async {
|
||||
const ColorScheme colorScheme = ColorScheme.light();
|
||||
final ThemeData theme = ThemeData.from(colorScheme: colorScheme);
|
||||
@ -409,6 +517,7 @@ void main() {
|
||||
data: ElevatedButtonThemeData(
|
||||
style: ButtonStyle(
|
||||
foregroundColor: MaterialStateProperty.resolveWith<Color>(getTextColor),
|
||||
iconColor: MaterialStateProperty.resolveWith<Color>(getTextColor),
|
||||
),
|
||||
),
|
||||
child: Builder(
|
||||
@ -995,8 +1104,8 @@ void main() {
|
||||
expect(paddingRect.left, iconRect.left - 16);
|
||||
// Use the taller widget to check the top and bottom padding.
|
||||
final Rect tallerWidget = iconRect.height > labelRect.height ? iconRect : labelRect;
|
||||
expect(paddingRect.top, tallerWidget.top - 5);
|
||||
expect(paddingRect.bottom, tallerWidget.bottom + 12);
|
||||
expect(paddingRect.top, closeTo(tallerWidget.top - 6.5, .01));
|
||||
expect(paddingRect.bottom, closeTo(tallerWidget.bottom + 13.5, .01));
|
||||
});
|
||||
|
||||
group('Default ElevatedButton padding for textScaleFactor, textDirection', () {
|
||||
|
@ -127,6 +127,114 @@ void main() {
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('FilledButton.defaultStyle produces a ButtonStyle with appropriate non-null values', (WidgetTester tester) async {
|
||||
const ColorScheme colorScheme = ColorScheme.light();
|
||||
final ThemeData theme = ThemeData.from(colorScheme: colorScheme);
|
||||
|
||||
final FilledButton button = FilledButton(
|
||||
onPressed: () { },
|
||||
child: const Text('button'),
|
||||
);
|
||||
BuildContext? capturedContext;
|
||||
// Enabled FilledButton
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme,
|
||||
home: Center(
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
capturedContext = context;
|
||||
return button;
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
final ButtonStyle style = button.defaultStyleOf(capturedContext!);
|
||||
|
||||
// Properties that must be non-null.
|
||||
expect(style.textStyle, isNotNull, reason: 'textStyle style');
|
||||
expect(style.backgroundColor, isNotNull, reason: 'backgroundColor style');
|
||||
expect(style.foregroundColor, isNotNull, reason: 'foregroundColor style');
|
||||
expect(style.overlayColor, isNotNull, reason: 'overlayColor style');
|
||||
expect(style.shadowColor, isNotNull, reason: 'shadowColor style');
|
||||
expect(style.surfaceTintColor, isNotNull, reason: 'surfaceTintColor style');
|
||||
expect(style.elevation, isNotNull, reason: 'elevation style');
|
||||
expect(style.padding, isNotNull, reason: 'padding style');
|
||||
expect(style.minimumSize, isNotNull, reason: 'minimumSize style');
|
||||
expect(style.maximumSize, isNotNull, reason: 'maximumSize style');
|
||||
expect(style.iconColor, isNotNull, reason: 'iconColor style');
|
||||
expect(style.iconSize, isNotNull, reason: 'iconSize style');
|
||||
expect(style.shape, isNotNull, reason: 'shape style');
|
||||
expect(style.mouseCursor, isNotNull, reason: 'mouseCursor style');
|
||||
expect(style.visualDensity, isNotNull, reason: 'visualDensity style');
|
||||
expect(style.tapTargetSize, isNotNull, reason: 'tapTargetSize style');
|
||||
expect(style.animationDuration, isNotNull, reason: 'animationDuration style');
|
||||
expect(style.enableFeedback, isNotNull, reason: 'enableFeedback style');
|
||||
expect(style.alignment, isNotNull, reason: 'alignment style');
|
||||
expect(style.splashFactory, isNotNull, reason: 'splashFactory style');
|
||||
|
||||
// Properties that are expected to be null.
|
||||
expect(style.fixedSize, isNull, reason: 'fixedSize style');
|
||||
expect(style.side, isNull, reason: 'side style');
|
||||
expect(style.backgroundBuilder, isNull, reason: 'backgroundBuilder style');
|
||||
expect(style.foregroundBuilder, isNull, reason: 'foregroundBuilder style');
|
||||
});
|
||||
|
||||
testWidgets('FilledButton.defaultStyle with an icon produces a ButtonStyle with appropriate non-null values', (WidgetTester tester) async {
|
||||
const ColorScheme colorScheme = ColorScheme.light();
|
||||
final ThemeData theme = ThemeData.from(colorScheme: colorScheme);
|
||||
|
||||
final FilledButton button = FilledButton.icon(
|
||||
onPressed: () { },
|
||||
icon: const SizedBox(),
|
||||
label: const Text('button'),
|
||||
);
|
||||
BuildContext? capturedContext;
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme,
|
||||
home: Center(
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
capturedContext = context;
|
||||
return button;
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
final ButtonStyle style = button.defaultStyleOf(capturedContext!);
|
||||
|
||||
// Properties that must be non-null.
|
||||
expect(style.textStyle, isNotNull, reason: 'textStyle style');
|
||||
expect(style.backgroundColor, isNotNull, reason: 'backgroundColor style');
|
||||
expect(style.foregroundColor, isNotNull, reason: 'foregroundColor style');
|
||||
expect(style.overlayColor, isNotNull, reason: 'overlayColor style');
|
||||
expect(style.shadowColor, isNotNull, reason: 'shadowColor style');
|
||||
expect(style.surfaceTintColor, isNotNull, reason: 'surfaceTintColor style');
|
||||
expect(style.elevation, isNotNull, reason: 'elevation style');
|
||||
expect(style.padding, isNotNull, reason: 'padding style');
|
||||
expect(style.minimumSize, isNotNull, reason: 'minimumSize style');
|
||||
expect(style.maximumSize, isNotNull, reason: 'maximumSize style');
|
||||
expect(style.iconColor, isNotNull, reason: 'iconColor style');
|
||||
expect(style.iconSize, isNotNull, reason: 'iconSize style');
|
||||
expect(style.shape, isNotNull, reason: 'shape style');
|
||||
expect(style.mouseCursor, isNotNull, reason: 'mouseCursor style');
|
||||
expect(style.visualDensity, isNotNull, reason: 'visualDensity style');
|
||||
expect(style.tapTargetSize, isNotNull, reason: 'tapTargetSize style');
|
||||
expect(style.animationDuration, isNotNull, reason: 'animationDuration style');
|
||||
expect(style.enableFeedback, isNotNull, reason: 'enableFeedback style');
|
||||
expect(style.alignment, isNotNull, reason: 'alignment style');
|
||||
expect(style.splashFactory, isNotNull, reason: 'splashFactory style');
|
||||
|
||||
// Properties that are expected to be null.
|
||||
expect(style.fixedSize, isNull, reason: 'fixedSize style');
|
||||
expect(style.side, isNull, reason: 'side style');
|
||||
expect(style.backgroundBuilder, isNull, reason: 'backgroundBuilder style');
|
||||
expect(style.foregroundBuilder, isNull, reason: 'foregroundBuilder style');
|
||||
});
|
||||
|
||||
testWidgets('FilledButton.icon produces the correct widgets if icon is null', (WidgetTester tester) async {
|
||||
const ColorScheme colorScheme = ColorScheme.light();
|
||||
final ThemeData theme = ThemeData.from(colorScheme: colorScheme);
|
||||
@ -601,6 +709,7 @@ void main() {
|
||||
data: FilledButtonThemeData(
|
||||
style: ButtonStyle(
|
||||
foregroundColor: MaterialStateProperty.resolveWith<Color>(getTextColor),
|
||||
iconColor: MaterialStateProperty.resolveWith<Color>(getTextColor),
|
||||
),
|
||||
),
|
||||
child: Builder(
|
||||
@ -1174,14 +1283,18 @@ void main() {
|
||||
final Rect labelRect = tester.getRect(find.byKey(labelKey));
|
||||
final Rect iconRect = tester.getRect(find.byType(Icon));
|
||||
|
||||
Matcher closeOnWeb(num value) {
|
||||
return kIsWeb ? closeTo(value, 1e-2) : equals(value);
|
||||
}
|
||||
|
||||
// The right padding should be applied on the right of the label, whereas the
|
||||
// left padding should be applied on the left side of the icon.
|
||||
expect(paddingRect.right, labelRect.right + 10);
|
||||
expect(paddingRect.left, iconRect.left - 16);
|
||||
expect(paddingRect.right, equals(labelRect.right + 10));
|
||||
expect(paddingRect.left, equals(iconRect.left - 16));
|
||||
// Use the taller widget to check the top and bottom padding.
|
||||
final Rect tallerWidget = iconRect.height > labelRect.height ? iconRect : labelRect;
|
||||
expect(paddingRect.top, tallerWidget.top - 5);
|
||||
expect(paddingRect.bottom, tallerWidget.bottom + 12);
|
||||
expect(paddingRect.top, closeOnWeb(tallerWidget.top - 6.5));
|
||||
expect(paddingRect.bottom, closeOnWeb(tallerWidget.bottom + 13.5));
|
||||
});
|
||||
|
||||
group('Default FilledButton padding for textScaleFactor, textDirection', () {
|
||||
|
@ -174,6 +174,114 @@ void main() {
|
||||
expect(material.type, MaterialType.button);
|
||||
});
|
||||
|
||||
testWidgets('OutlinedButton.defaultStyle produces a ButtonStyle with appropriate non-null values', (WidgetTester tester) async {
|
||||
const ColorScheme colorScheme = ColorScheme.light();
|
||||
final ThemeData theme = ThemeData.from(colorScheme: colorScheme);
|
||||
|
||||
final OutlinedButton button = OutlinedButton(
|
||||
onPressed: () { },
|
||||
child: const Text('button'),
|
||||
);
|
||||
BuildContext? capturedContext;
|
||||
// Enabled OutlinedButton
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme,
|
||||
home: Center(
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
capturedContext = context;
|
||||
return button;
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
final ButtonStyle style = button.defaultStyleOf(capturedContext!);
|
||||
|
||||
// Properties that must be non-null.
|
||||
expect(style.textStyle, isNotNull, reason: 'textStyle style');
|
||||
expect(style.backgroundColor, isNotNull, reason: 'backgroundColor style');
|
||||
expect(style.foregroundColor, isNotNull, reason: 'foregroundColor style');
|
||||
expect(style.overlayColor, isNotNull, reason: 'overlayColor style');
|
||||
expect(style.shadowColor, isNotNull, reason: 'shadowColor style');
|
||||
expect(style.surfaceTintColor, isNotNull, reason: 'surfaceTintColor style');
|
||||
expect(style.elevation, isNotNull, reason: 'elevation style');
|
||||
expect(style.padding, isNotNull, reason: 'padding style');
|
||||
expect(style.minimumSize, isNotNull, reason: 'minimumSize style');
|
||||
expect(style.maximumSize, isNotNull, reason: 'maximumSize style');
|
||||
expect(style.iconColor, isNotNull, reason: 'iconColor style');
|
||||
expect(style.iconSize, isNotNull, reason: 'iconSize style');
|
||||
expect(style.shape, isNotNull, reason: 'shape style');
|
||||
expect(style.mouseCursor, isNotNull, reason: 'mouseCursor style');
|
||||
expect(style.visualDensity, isNotNull, reason: 'visualDensity style');
|
||||
expect(style.tapTargetSize, isNotNull, reason: 'tapTargetSize style');
|
||||
expect(style.animationDuration, isNotNull, reason: 'animationDuration style');
|
||||
expect(style.enableFeedback, isNotNull, reason: 'enableFeedback style');
|
||||
expect(style.alignment, isNotNull, reason: 'alignment style');
|
||||
expect(style.splashFactory, isNotNull, reason: 'splashFactory style');
|
||||
expect(style.side, isNotNull, reason: 'side style');
|
||||
|
||||
// Properties that are expected to be null.
|
||||
expect(style.fixedSize, isNull, reason: 'fixedSize style');
|
||||
expect(style.backgroundBuilder, isNull, reason: 'backgroundBuilder style');
|
||||
expect(style.foregroundBuilder, isNull, reason: 'foregroundBuilder style');
|
||||
});
|
||||
|
||||
testWidgets('OutlinedButton.defaultStyle with an icon produces a ButtonStyle with appropriate non-null values', (WidgetTester tester) async {
|
||||
const ColorScheme colorScheme = ColorScheme.light();
|
||||
final ThemeData theme = ThemeData.from(colorScheme: colorScheme);
|
||||
|
||||
final OutlinedButton button = OutlinedButton.icon(
|
||||
onPressed: () { },
|
||||
icon: const SizedBox(),
|
||||
label: const Text('button'),
|
||||
);
|
||||
BuildContext? capturedContext;
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme,
|
||||
home: Center(
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
capturedContext = context;
|
||||
return button;
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
final ButtonStyle style = button.defaultStyleOf(capturedContext!);
|
||||
|
||||
// Properties that must be non-null.
|
||||
expect(style.textStyle, isNotNull, reason: 'textStyle style');
|
||||
expect(style.backgroundColor, isNotNull, reason: 'backgroundColor style');
|
||||
expect(style.foregroundColor, isNotNull, reason: 'foregroundColor style');
|
||||
expect(style.overlayColor, isNotNull, reason: 'overlayColor style');
|
||||
expect(style.shadowColor, isNotNull, reason: 'shadowColor style');
|
||||
expect(style.surfaceTintColor, isNotNull, reason: 'surfaceTintColor style');
|
||||
expect(style.elevation, isNotNull, reason: 'elevation style');
|
||||
expect(style.padding, isNotNull, reason: 'padding style');
|
||||
expect(style.minimumSize, isNotNull, reason: 'minimumSize style');
|
||||
expect(style.maximumSize, isNotNull, reason: 'maximumSize style');
|
||||
expect(style.iconColor, isNotNull, reason: 'iconColor style');
|
||||
expect(style.iconSize, isNotNull, reason: 'iconSize style');
|
||||
expect(style.shape, isNotNull, reason: 'shape style');
|
||||
expect(style.mouseCursor, isNotNull, reason: 'mouseCursor style');
|
||||
expect(style.visualDensity, isNotNull, reason: 'visualDensity style');
|
||||
expect(style.tapTargetSize, isNotNull, reason: 'tapTargetSize style');
|
||||
expect(style.animationDuration, isNotNull, reason: 'animationDuration style');
|
||||
expect(style.enableFeedback, isNotNull, reason: 'enableFeedback style');
|
||||
expect(style.alignment, isNotNull, reason: 'alignment style');
|
||||
expect(style.splashFactory, isNotNull, reason: 'splashFactory style');
|
||||
expect(style.side, isNotNull, reason: 'side style');
|
||||
|
||||
// Properties that are expected to be null.
|
||||
expect(style.fixedSize, isNull, reason: 'fixedSize style');
|
||||
expect(style.backgroundBuilder, isNull, reason: 'backgroundBuilder style');
|
||||
expect(style.foregroundBuilder, isNull, reason: 'foregroundBuilder style');
|
||||
});
|
||||
|
||||
testWidgets('OutlinedButton.icon produces the correct widgets if icon is null', (WidgetTester tester) async {
|
||||
const ColorScheme colorScheme = ColorScheme.light();
|
||||
final ThemeData theme = ThemeData.from(colorScheme: colorScheme);
|
||||
@ -600,7 +708,7 @@ void main() {
|
||||
child: OutlinedButton.icon(
|
||||
key: buttonKey,
|
||||
style: ButtonStyle(
|
||||
foregroundColor: MaterialStateProperty.resolveWith<Color>(getIconColor),
|
||||
iconColor: MaterialStateProperty.resolveWith<Color>(getIconColor),
|
||||
),
|
||||
icon: const Icon(Icons.add),
|
||||
label: const Text('OutlinedButton'),
|
||||
|
@ -154,6 +154,114 @@ void main() {
|
||||
expect(material.type, MaterialType.button);
|
||||
});
|
||||
|
||||
testWidgets('TextButton.defaultStyle produces a ButtonStyle with appropriate non-null values', (WidgetTester tester) async {
|
||||
const ColorScheme colorScheme = ColorScheme.light();
|
||||
final ThemeData theme = ThemeData.from(colorScheme: colorScheme);
|
||||
|
||||
final TextButton button = TextButton(
|
||||
onPressed: () { },
|
||||
child: const Text('button'),
|
||||
);
|
||||
BuildContext? capturedContext;
|
||||
// Enabled TextButton
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme,
|
||||
home: Center(
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
capturedContext = context;
|
||||
return button;
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
final ButtonStyle style = button.defaultStyleOf(capturedContext!);
|
||||
|
||||
// Properties that must be non-null.
|
||||
expect(style.textStyle, isNotNull, reason: 'textStyle style');
|
||||
expect(style.backgroundColor, isNotNull, reason: 'backgroundColor style');
|
||||
expect(style.foregroundColor, isNotNull, reason: 'foregroundColor style');
|
||||
expect(style.overlayColor, isNotNull, reason: 'overlayColor style');
|
||||
expect(style.shadowColor, isNotNull, reason: 'shadowColor style');
|
||||
expect(style.surfaceTintColor, isNotNull, reason: 'surfaceTintColor style');
|
||||
expect(style.elevation, isNotNull, reason: 'elevation style');
|
||||
expect(style.padding, isNotNull, reason: 'padding style');
|
||||
expect(style.minimumSize, isNotNull, reason: 'minimumSize style');
|
||||
expect(style.maximumSize, isNotNull, reason: 'maximumSize style');
|
||||
expect(style.iconColor, isNotNull, reason: 'iconColor style');
|
||||
expect(style.iconSize, isNotNull, reason: 'iconSize style');
|
||||
expect(style.shape, isNotNull, reason: 'shape style');
|
||||
expect(style.mouseCursor, isNotNull, reason: 'mouseCursor style');
|
||||
expect(style.visualDensity, isNotNull, reason: 'visualDensity style');
|
||||
expect(style.tapTargetSize, isNotNull, reason: 'tapTargetSize style');
|
||||
expect(style.animationDuration, isNotNull, reason: 'animationDuration style');
|
||||
expect(style.enableFeedback, isNotNull, reason: 'enableFeedback style');
|
||||
expect(style.alignment, isNotNull, reason: 'alignment style');
|
||||
expect(style.splashFactory, isNotNull, reason: 'splashFactory style');
|
||||
|
||||
// Properties that are expected to be null.
|
||||
expect(style.fixedSize, isNull, reason: 'fixedSize style');
|
||||
expect(style.side, isNull, reason: 'side style');
|
||||
expect(style.backgroundBuilder, isNull, reason: 'backgroundBuilder style');
|
||||
expect(style.foregroundBuilder, isNull, reason: 'foregroundBuilder style');
|
||||
});
|
||||
|
||||
testWidgets('TextButton.defaultStyle with an icon produces a ButtonStyle with appropriate non-null values', (WidgetTester tester) async {
|
||||
const ColorScheme colorScheme = ColorScheme.light();
|
||||
final ThemeData theme = ThemeData.from(colorScheme: colorScheme);
|
||||
|
||||
final TextButton button = TextButton.icon(
|
||||
onPressed: () { },
|
||||
icon: const SizedBox(),
|
||||
label: const Text('button'),
|
||||
);
|
||||
BuildContext? capturedContext;
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme,
|
||||
home: Center(
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
capturedContext = context;
|
||||
return button;
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
final ButtonStyle style = button.defaultStyleOf(capturedContext!);
|
||||
|
||||
// Properties that must be non-null.
|
||||
expect(style.textStyle, isNotNull, reason: 'textStyle style');
|
||||
expect(style.backgroundColor, isNotNull, reason: 'backgroundColor style');
|
||||
expect(style.foregroundColor, isNotNull, reason: 'foregroundColor style');
|
||||
expect(style.overlayColor, isNotNull, reason: 'overlayColor style');
|
||||
expect(style.shadowColor, isNotNull, reason: 'shadowColor style');
|
||||
expect(style.surfaceTintColor, isNotNull, reason: 'surfaceTintColor style');
|
||||
expect(style.elevation, isNotNull, reason: 'elevation style');
|
||||
expect(style.padding, isNotNull, reason: 'padding style');
|
||||
expect(style.minimumSize, isNotNull, reason: 'minimumSize style');
|
||||
expect(style.maximumSize, isNotNull, reason: 'maximumSize style');
|
||||
expect(style.iconColor, isNotNull, reason: 'iconColor style');
|
||||
expect(style.iconSize, isNotNull, reason: 'iconSize style');
|
||||
expect(style.shape, isNotNull, reason: 'shape style');
|
||||
expect(style.mouseCursor, isNotNull, reason: 'mouseCursor style');
|
||||
expect(style.visualDensity, isNotNull, reason: 'visualDensity style');
|
||||
expect(style.tapTargetSize, isNotNull, reason: 'tapTargetSize style');
|
||||
expect(style.animationDuration, isNotNull, reason: 'animationDuration style');
|
||||
expect(style.enableFeedback, isNotNull, reason: 'enableFeedback style');
|
||||
expect(style.alignment, isNotNull, reason: 'alignment style');
|
||||
expect(style.splashFactory, isNotNull, reason: 'splashFactory style');
|
||||
|
||||
// Properties that are expected to be null.
|
||||
expect(style.fixedSize, isNull, reason: 'fixedSize style');
|
||||
expect(style.side, isNull, reason: 'side style');
|
||||
expect(style.backgroundBuilder, isNull, reason: 'backgroundBuilder style');
|
||||
expect(style.foregroundBuilder, isNull, reason: 'foregroundBuilder style');
|
||||
});
|
||||
|
||||
testWidgets('TextButton.icon produces the correct widgets when icon is null', (WidgetTester tester) async {
|
||||
const ColorScheme colorScheme = ColorScheme.light();
|
||||
final ThemeData theme = ThemeData.from(colorScheme: colorScheme);
|
||||
@ -463,6 +571,7 @@ void main() {
|
||||
child: TextButton.icon(
|
||||
style: ButtonStyle(
|
||||
foregroundColor: MaterialStateProperty.resolveWith<Color>(getTextColor),
|
||||
iconColor: MaterialStateProperty.resolveWith<Color>(getTextColor),
|
||||
),
|
||||
key: buttonKey,
|
||||
icon: const Icon(Icons.add),
|
||||
|
Loading…
x
Reference in New Issue
Block a user