Unverified Commit dc31d89c authored by Hans Muller's avatar Hans Muller Committed by GitHub

New Button Universe (#59702)

parent ea777fea
......@@ -36,6 +36,8 @@ export 'src/material/bottom_sheet_theme.dart';
export 'src/material/button.dart';
export 'src/material/button_bar.dart';
export 'src/material/button_bar_theme.dart';
export 'src/material/button_style.dart';
export 'src/material/button_style_button.dart';
export 'src/material/button_theme.dart';
export 'src/material/card.dart';
export 'src/material/card_theme.dart';
......@@ -47,6 +49,8 @@ export 'src/material/circle_avatar.dart';
export 'src/material/color_scheme.dart';
export 'src/material/colors.dart';
export 'src/material/constants.dart';
export 'src/material/contained_button.dart';
export 'src/material/contained_button_theme.dart';
export 'src/material/data_table.dart';
export 'src/material/data_table_source.dart';
export 'src/material/debug.dart';
......@@ -88,6 +92,8 @@ export 'src/material/mergeable_material.dart';
export 'src/material/navigation_rail.dart';
export 'src/material/navigation_rail_theme.dart';
export 'src/material/outline_button.dart';
export 'src/material/outlined_button.dart';
export 'src/material/outlined_button_theme.dart';
export 'src/material/page.dart';
export 'src/material/page_transitions_theme.dart';
export 'src/material/paginated_data_table.dart';
......@@ -117,6 +123,8 @@ export 'src/material/tab_bar_theme.dart';
export 'src/material/tab_controller.dart';
export 'src/material/tab_indicator.dart';
export 'src/material/tabs.dart';
export 'src/material/text_button.dart';
export 'src/material/text_button_theme.dart';
export 'src/material/text_field.dart';
export 'src/material/text_form_field.dart';
export 'src/material/text_selection.dart';
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// 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.
// @dart = 2.8
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'button_style.dart';
import 'theme.dart';
/// A [ButtonStyle] that overrides the default appearance of
/// [ContainedButton]s when it's used with [ContainedButtonTheme] or with the
/// overall [Theme]'s [ThemeData.containedButtonTheme].
///
/// The [style]'s properties override [ContainedButton]'s default style,
/// i.e. the [ButtonStyle] returned by [ContainedButton.defaultStyleOf]. Only
/// the style's non-null property values or resolved non-null
/// [MaterialStateProperty] values are used.
///
/// See also:
///
/// * [ContainedButtonTheme], the theme which is configured with this class.
/// * [ContainedButton.defaultStyleOf], which returns the default [ButtonStyle]
/// for text buttons.
/// * [ContainedButton.styleOf], which converts simple values into a
/// [ButtonStyle] that's consistent with [ContainedButton]'s defaults.
/// * [MaterialStateProperty.resolve], "resolve" a material state property
/// to a simple value based on a set of [MaterialState]s.
/// * [ThemeData.containedButtonTheme], which can be used to override the default
/// [ButtonStyle] for [ContainedButton]s below the overall [Theme].
@immutable
class ContainedButtonThemeData with Diagnosticable {
/// Creates a [ContainedButtonThemeData].
///
/// The [style] may be null.
const ContainedButtonThemeData({ this.style });
/// Overrides for [ContainedButton]'s default style.
///
/// Non-null properties or non-null resolved [MaterialStateProperty]
/// values override the [ButtonStyle] returned by
/// [ContainedButton.defaultStyleOf].
///
/// If [style] is null, then this theme doesn't override anything.
final ButtonStyle style;
/// Linearly interpolate between two contained button themes.
static ContainedButtonThemeData lerp(ContainedButtonThemeData a, ContainedButtonThemeData b, double t) {
assert (t != null);
if (a == null && b == null)
return null;
return ContainedButtonThemeData(
style: ButtonStyle.lerp(a?.style, b?.style, t),
);
}
@override
int get hashCode {
return style.hashCode;
}
@override
bool operator ==(Object other) {
if (identical(this, other))
return true;
if (other.runtimeType != runtimeType)
return false;
return other is ContainedButtonThemeData && other.style == style;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<ButtonStyle>('style', style, defaultValue: null));
}
}
/// Overrides the default [ButtonStyle] of its [ContainedButton] descendants.
///
/// See also:
///
/// * [ContainedButtonThemeData], which is used to configure this theme.
/// * [ContainedButton.defaultStyleOf], which returns the default [ButtonStyle]
/// for text buttons.
/// * [ContainedButton.styleOf], which converts simple values into a
/// [ButtonStyle] that's consistent with [ContainedButton]'s defaults.
/// * [ThemeData.containedButtonTheme], which can be used to override the default
/// [ButtonStyle] for [ContainedButton]s below the overall [Theme].
class ContainedButtonTheme extends InheritedTheme {
/// Create a [ContainedButtonTheme].
///
/// The [data] parameter must not be null.
const ContainedButtonTheme({
Key key,
@required this.data,
Widget child,
}) : assert(data != null), super(key: key, child: child);
/// The configuration of this theme.
final ContainedButtonThemeData data;
/// The closest instance of this class that encloses the given context.
///
/// If there is no enclosing [ContainedButtonsTheme] widget, then
/// [ThemeData.containedButtonTheme] is used.
///
/// Typical usage is as follows:
///
/// ```dart
/// ContainedButtonTheme theme = ContainedButtonTheme.of(context);
/// ```
static ContainedButtonThemeData of(BuildContext context) {
final ContainedButtonTheme buttonTheme = context.dependOnInheritedWidgetOfExactType<ContainedButtonTheme>();
return buttonTheme?.data ?? Theme.of(context).containedButtonTheme;
}
@override
Widget wrap(BuildContext context, Widget child) {
final ContainedButtonTheme ancestorTheme = context.findAncestorWidgetOfExactType<ContainedButtonTheme>();
return identical(this, ancestorTheme) ? child : ContainedButtonTheme(data: data, child: child);
}
@override
bool updateShouldNotify(ContainedButtonTheme oldWidget) => data != oldWidget.data;
}
......@@ -362,4 +362,7 @@ class _MaterialStatePropertyAll<T> implements MaterialStateProperty<T> {
@override
T resolve(Set<MaterialState> states) => value;
@override
String toString() => 'MaterialStateProperty.all($value)';
}
This diff is collapsed.
// 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.
// @dart = 2.8
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'button_style.dart';
import 'theme.dart';
/// A [ButtonStyle] that overrides the default appearance of
/// [OutlinedButton]s when it's used with [OutlinedButtonTheme] or with the
/// overall [Theme]'s [ThemeData.outlinedButtonTheme].
///
/// The [style]'s properties override [OutlinedButton]'s default style,
/// i.e. the [ButtonStyle] returned by [OutlinedButton.defaultStyleOf]. Only
/// the style's non-null property values or resolved non-null
/// [MaterialStateProperty] values are used.
///
/// See also:
///
/// * [OutlinedButtonTheme], the theme which is configured with this class.
/// * [OutlinedButton.defaultStyleOf], which returns the default [ButtonStyle]
/// for text buttons.
/// * [OutlinedButton.styleOf], which converts simple values into a
/// [ButtonStyle] that's consistent with [OutlinedButton]'s defaults.
/// * [MaterialStateProperty.resolve], "resolve" a material state property
/// to a simple value based on a set of [MaterialState]s.
/// * [ThemeData.outlinedButtonTheme], which can be used to override the default
/// [ButtonStyle] for [OutlinedButton]s below the overall [Theme].
@immutable
class OutlinedButtonThemeData with Diagnosticable {
/// Creates a [OutlinedButtonThemeData].
///
/// The [style] may be null.
const OutlinedButtonThemeData({ this.style });
/// Overrides for [OutlinedButton]'s default style.
///
/// Non-null properties or non-null resolved [MaterialStateProperty]
/// values override the [ButtonStyle] returned by
/// [OutlinedButton.defaultStyleOf].
///
/// If [style] is null, then this theme doesn't override anything.
final ButtonStyle style;
/// Linearly interpolate between two outlined button themes.
static OutlinedButtonThemeData lerp(OutlinedButtonThemeData a, OutlinedButtonThemeData b, double t) {
assert (t != null);
if (a == null && b == null)
return null;
return OutlinedButtonThemeData(
style: ButtonStyle.lerp(a?.style, b?.style, t),
);
}
@override
int get hashCode {
return style.hashCode;
}
@override
bool operator ==(Object other) {
if (identical(this, other))
return true;
if (other.runtimeType != runtimeType)
return false;
return other is OutlinedButtonThemeData && other.style == style;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<ButtonStyle>('style', style, defaultValue: null));
}
}
/// Overrides the default [ButtonStyle] of its [OutlinedButton] descendants.
///
/// See also:
///
/// * [OutlinedButtonThemeData], which is used to configure this theme.
/// * [OutlinedButton.defaultStyleOf], which returns the default [ButtonStyle]
/// for text buttons.
/// * [OutlinedButton.styleOf], which converts simple values into a
/// [ButtonStyle] that's consistent with [OutlinedButton]'s defaults.
/// * [ThemeData.outlinedButtonTheme], which can be used to override the default
/// [ButtonStyle] for [OutlinedButton]s below the overall [Theme].
class OutlinedButtonTheme extends InheritedTheme {
/// Create a [OutlinedButtonTheme].
///
/// The [data] parameter must not be null.
const OutlinedButtonTheme({
Key key,
@required this.data,
Widget child,
}) : assert(data != null), super(key: key, child: child);
/// The configuration of this theme.
final OutlinedButtonThemeData data;
/// The closest instance of this class that encloses the given context.
///
/// If there is no enclosing [OutlinedButtonsTheme] widget, then
/// [ThemeData.outlinedButtonTheme] is used.
///
/// Typical usage is as follows:
///
/// ```dart
/// OutlinedButtonTheme theme = OutlinedButtonTheme.of(context);
/// ```
static OutlinedButtonThemeData of(BuildContext context) {
final OutlinedButtonTheme buttonTheme = context.dependOnInheritedWidgetOfExactType<OutlinedButtonTheme>();
return buttonTheme?.data ?? Theme.of(context).outlinedButtonTheme;
}
@override
Widget wrap(BuildContext context, Widget child) {
final OutlinedButtonTheme ancestorTheme = context.findAncestorWidgetOfExactType<OutlinedButtonTheme>();
return identical(this, ancestorTheme) ? child : OutlinedButtonTheme(data: data, child: child);
}
@override
bool updateShouldNotify(OutlinedButtonTheme oldWidget) => data != oldWidget.data;
}
This diff is collapsed.
// 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.
// @dart = 2.8
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'button_style.dart';
import 'theme.dart';
/// A [ButtonStyle] that overrides the default appearance of
/// [TextButton]s when it's used with [TextButtonTheme] or with the
/// overall [Theme]'s [ThemeData.textButtonTheme].
///
/// The [style]'s properties override [TextButton]'s default style,
/// i.e. the [ButtonStyle] returned by [TextButton.defaultStyleOf]. Only
/// the style's non-null property values or resolved non-null
/// [MaterialStateProperty] values are used.
///
/// See also:
///
/// * [TextButtonTheme], the theme which is configured with this class.
/// * [TextButton.defaultStyleOf], which returns the default [ButtonStyle]
/// for text buttons.
/// * [TextButton.styleOf], which converts simple values into a
/// [ButtonStyle] that's consistent with [TextButton]'s defaults.
/// * [MaterialStateProperty.resolve], "resolve" a material state property
/// to a simple value based on a set of [MaterialState]s.
/// * [ThemeData.textButtonTheme], which can be used to override the default
/// [ButtonStyle] for [TextButton]s below the overall [Theme].
@immutable
class TextButtonThemeData with Diagnosticable {
/// Creates a [TextButtonThemeData].
///
/// The [style] may be null.
const TextButtonThemeData({ this.style });
/// Overrides for [TextButton]'s default style.
///
/// Non-null properties or non-null resolved [MaterialStateProperty]
/// values override the [ButtonStyle] returned by
/// [TextButton.defaultStyleOf].
///
/// If [style] is null, then this theme doesn't override anything.
final ButtonStyle style;
/// Linearly interpolate between two text button themes.
static TextButtonThemeData lerp(TextButtonThemeData a, TextButtonThemeData b, double t) {
assert (t != null);
if (a == null && b == null)
return null;
return TextButtonThemeData(
style: ButtonStyle.lerp(a?.style, b?.style, t),
);
}
@override
int get hashCode {
return style.hashCode;
}
@override
bool operator ==(Object other) {
if (identical(this, other))
return true;
if (other.runtimeType != runtimeType)
return false;
return other is TextButtonThemeData && other.style == style;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<ButtonStyle>('style', style, defaultValue: null));
}
}
/// Overrides the default [ButtonStyle] of its [TextButton] descendants.
///
/// See also:
///
/// * [TextButtonThemeData], which is used to configure this theme.
/// * [TextButton.defaultStyleOf], which returns the default [ButtonStyle]
/// for text buttons.
/// * [TextButton.styleOf], which converts simple values into a
/// [ButtonStyle] that's consistent with [TextButton]'s defaults.
/// * [ThemeData.textButtonTheme], which can be used to override the default
/// [ButtonStyle] for [TextButton]s below the overall [Theme].
class TextButtonTheme extends InheritedTheme {
/// Create a [TextButtonTheme].
///
/// The [data] parameter must not be null.
const TextButtonTheme({
Key key,
@required this.data,
Widget child,
}) : assert(data != null), super(key: key, child: child);
/// The configuration of this theme.
final TextButtonThemeData data;
/// The closest instance of this class that encloses the given context.
///
/// If there is no enclosing [TextButtonsTheme] widget, then
/// [ThemeData.textButtonTheme] is used.
///
/// Typical usage is as follows:
///
/// ```dart
/// TextButtonTheme theme = TextButtonTheme.of(context);
/// ```
static TextButtonThemeData of(BuildContext context) {
final TextButtonTheme buttonTheme = context.dependOnInheritedWidgetOfExactType<TextButtonTheme>();
return buttonTheme?.data ?? Theme.of(context).textButtonTheme;
}
@override
Widget wrap(BuildContext context, Widget child) {
final TextButtonTheme ancestorTheme = context.findAncestorWidgetOfExactType<TextButtonTheme>();
return identical(this, ancestorTheme) ? child : TextButtonTheme(data: data, child: child);
}
@override
bool updateShouldNotify(TextButtonTheme oldWidget) => data != oldWidget.data;
}
......@@ -22,6 +22,7 @@ import 'card_theme.dart';
import 'chip_theme.dart';
import 'color_scheme.dart';
import 'colors.dart';
import 'contained_button_theme.dart';
import 'dialog_theme.dart';
import 'divider_theme.dart';
import 'floating_action_button_theme.dart';
......@@ -29,11 +30,13 @@ import 'ink_splash.dart';
import 'ink_well.dart' show InteractiveInkFeatureFactory;
import 'input_decorator.dart';
import 'navigation_rail_theme.dart';
import 'outlined_button_theme.dart';
import 'page_transitions_theme.dart';
import 'popup_menu_theme.dart';
import 'slider_theme.dart';
import 'snack_bar_theme.dart';
import 'tab_bar_theme.dart';
import 'text_button_theme.dart';
import 'text_theme.dart';
import 'time_picker_theme.dart';
import 'toggle_buttons_theme.dart';
......@@ -271,6 +274,9 @@ class ThemeData with Diagnosticable {
ButtonBarThemeData buttonBarTheme,
BottomNavigationBarThemeData bottomNavigationBarTheme,
TimePickerThemeData timePickerTheme,
TextButtonThemeData textButtonTheme,
ContainedButtonThemeData containedButtonTheme,
OutlinedButtonThemeData outlinedButtonTheme,
bool fixTextFieldOutlineLabel,
}) {
assert(colorScheme?.brightness == null || brightness == null || colorScheme.brightness == brightness);
......@@ -383,7 +389,9 @@ class ThemeData with Diagnosticable {
buttonBarTheme ??= const ButtonBarThemeData();
bottomNavigationBarTheme ??= const BottomNavigationBarThemeData();
timePickerTheme ??= const TimePickerThemeData();
textButtonTheme ??= const TextButtonThemeData();
containedButtonTheme ??= const ContainedButtonThemeData();
outlinedButtonTheme ??= const OutlinedButtonThemeData();
fixTextFieldOutlineLabel ??= false;
return ThemeData.raw(
......@@ -452,6 +460,9 @@ class ThemeData with Diagnosticable {
buttonBarTheme: buttonBarTheme,
bottomNavigationBarTheme: bottomNavigationBarTheme,
timePickerTheme: timePickerTheme,
textButtonTheme: textButtonTheme,
containedButtonTheme: containedButtonTheme,
outlinedButtonTheme: outlinedButtonTheme,
fixTextFieldOutlineLabel: fixTextFieldOutlineLabel,
);
}
......@@ -532,6 +543,9 @@ class ThemeData with Diagnosticable {
@required this.buttonBarTheme,
@required this.bottomNavigationBarTheme,
@required this.timePickerTheme,
@required this.textButtonTheme,
@required this.containedButtonTheme,
@required this.outlinedButtonTheme,
@required this.fixTextFieldOutlineLabel,
}) : assert(visualDensity != null),
assert(primaryColor != null),
......@@ -595,6 +609,9 @@ class ThemeData with Diagnosticable {
assert(buttonBarTheme != null),
assert(bottomNavigationBarTheme != null),
assert(timePickerTheme != null),
assert(textButtonTheme != null),
assert(containedButtonTheme != null),
assert(outlinedButtonTheme != null),
assert(fixTextFieldOutlineLabel != null);
/// Create a [ThemeData] based on the colors in the given [colorScheme] and
......@@ -1044,6 +1061,18 @@ class ThemeData with Diagnosticable {
/// A theme for customizing the appearance and layout of time picker widgets.
final TimePickerThemeData timePickerTheme;
/// A theme for customizing the appearance and internal layout of
/// [TextButton]s.
final TextButtonThemeData textButtonTheme;
/// A theme for customizing the appearance and internal layout of
/// [ContainedButton]s
final ContainedButtonThemeData containedButtonTheme;
/// A theme for customizing the appearance and internal layout of
/// [OutlinedButton]s.
final OutlinedButtonThemeData outlinedButtonTheme;
/// A temporary flag to allow apps to opt-in to a
/// [small fix](https://github.com/flutter/flutter/issues/54028) for the Y
/// coordinate of the floating label in a [TextField] [OutlineInputBorder].
......@@ -1126,6 +1155,9 @@ class ThemeData with Diagnosticable {
ButtonBarThemeData buttonBarTheme,
BottomNavigationBarThemeData bottomNavigationBarTheme,
TimePickerThemeData timePickerTheme,
TextButtonThemeData textButtonTheme,
ContainedButtonThemeData containedButtonTheme,
OutlinedButtonThemeData outlinedButtonTheme,
bool fixTextFieldOutlineLabel,
}) {
cupertinoOverrideTheme = cupertinoOverrideTheme?.noDefault();
......@@ -1195,6 +1227,9 @@ class ThemeData with Diagnosticable {
buttonBarTheme: buttonBarTheme ?? this.buttonBarTheme,
bottomNavigationBarTheme: bottomNavigationBarTheme ?? this.bottomNavigationBarTheme,
timePickerTheme: timePickerTheme ?? this.timePickerTheme,
textButtonTheme: textButtonTheme ?? this.textButtonTheme,
containedButtonTheme: containedButtonTheme ?? this.containedButtonTheme,
outlinedButtonTheme: outlinedButtonTheme ?? this.outlinedButtonTheme,
fixTextFieldOutlineLabel: fixTextFieldOutlineLabel ?? this.fixTextFieldOutlineLabel,
);
}
......@@ -1342,6 +1377,9 @@ class ThemeData with Diagnosticable {
buttonBarTheme: ButtonBarThemeData.lerp(a.buttonBarTheme, b.buttonBarTheme, t),
bottomNavigationBarTheme: BottomNavigationBarThemeData.lerp(a.bottomNavigationBarTheme, b.bottomNavigationBarTheme, t),
timePickerTheme: TimePickerThemeData.lerp(a.timePickerTheme, b.timePickerTheme, t),
textButtonTheme: TextButtonThemeData.lerp(a.textButtonTheme, b.textButtonTheme, t),
containedButtonTheme: ContainedButtonThemeData.lerp(a.containedButtonTheme, b.containedButtonTheme, t),
outlinedButtonTheme: OutlinedButtonThemeData.lerp(a.outlinedButtonTheme, b.outlinedButtonTheme, t),
fixTextFieldOutlineLabel: t < 0.5 ? a.fixTextFieldOutlineLabel : b.fixTextFieldOutlineLabel,
);
}
......@@ -1417,6 +1455,9 @@ class ThemeData with Diagnosticable {
&& other.buttonBarTheme == buttonBarTheme
&& other.bottomNavigationBarTheme == bottomNavigationBarTheme
&& other.timePickerTheme == timePickerTheme
&& other.textButtonTheme == textButtonTheme
&& other.containedButtonTheme == containedButtonTheme
&& other.outlinedButtonTheme == outlinedButtonTheme
&& other.fixTextFieldOutlineLabel == fixTextFieldOutlineLabel;
}
......@@ -1491,6 +1532,9 @@ class ThemeData with Diagnosticable {
buttonBarTheme,
bottomNavigationBarTheme,
timePickerTheme,
textButtonTheme,
containedButtonTheme,
outlinedButtonTheme,
fixTextFieldOutlineLabel,
];
return hashList(values);
......@@ -1562,6 +1606,9 @@ class ThemeData with Diagnosticable {
properties.add(DiagnosticsProperty<ButtonBarThemeData>('buttonBarTheme', buttonBarTheme, defaultValue: defaultData.buttonBarTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<TimePickerThemeData>('timePickerTheme', timePickerTheme, defaultValue: defaultData.timePickerTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<BottomNavigationBarThemeData>('bottomNavigationBarTheme', bottomNavigationBarTheme, defaultValue: defaultData.bottomNavigationBarTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<TextButtonThemeData>('textButtonTheme', textButtonTheme, defaultValue: defaultData.textButtonTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<ContainedButtonThemeData>('containedButtonTheme', containedButtonTheme, defaultValue: defaultData.containedButtonTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<OutlinedButtonThemeData>('outlinedButtonTheme', outlinedButtonTheme, defaultValue: defaultData.outlinedButtonTheme, level: DiagnosticLevel.debug));
}
}
......
// 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.
// @dart = 2.8
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
test('ButtonStyle copyWith, merge, ==, hashCode basics', () {
expect(const ButtonStyle(), const ButtonStyle().copyWith());
expect(const ButtonStyle().merge(const ButtonStyle()), const ButtonStyle());
expect(const ButtonStyle().hashCode, const ButtonStyle().copyWith().hashCode);
});
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.elevation, null);
expect(style.padding, null);
expect(style.minimumSize, 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);
});
testWidgets('Default ButtonStyle debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
const ButtonStyle().debugFillProperties(builder);
final List<String> description = builder.properties
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
.map((DiagnosticsNode node) => node.toString())
.toList();
expect(description, <String>[]);
});
testWidgets('ButtonStyle debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
ButtonStyle(
textStyle: MaterialStateProperty.all<TextStyle>(const TextStyle(fontSize: 10.0)),
backgroundColor: MaterialStateProperty.all<Color>(const Color(0xfffffff1)),
foregroundColor: MaterialStateProperty.all<Color>(const Color(0xfffffff2)),
overlayColor: MaterialStateProperty.all<Color>(const Color(0xfffffff3)),
elevation: MaterialStateProperty.all<double>(1.5),
padding: MaterialStateProperty.all<EdgeInsets>(const EdgeInsets.all(1.0)),
minimumSize: MaterialStateProperty.all<Size>(const Size(1.0, 2.0)),
side: MaterialStateProperty.all<BorderSide>(const BorderSide(width: 4.0, color: Color(0xfffffff4))),
shape: MaterialStateProperty.all<OutlinedBorder>(const StadiumBorder()),
mouseCursor: MaterialStateProperty.all<MouseCursor>(SystemMouseCursors.forbidden),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
animationDuration: const Duration(seconds: 1),
enableFeedback: true,
).debugFillProperties(builder);
final List<String> description = builder.properties
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
.map((DiagnosticsNode node) => node.toString())
.toList();
expect(description, <String>[
'textStyle: MaterialStateProperty.all(TextStyle(inherit: true, size: 10.0))',
'backgroundColor: MaterialStateProperty.all(Color(0xfffffff1))',
'foregroundColor: MaterialStateProperty.all(Color(0xfffffff2))',
'overlayColor: MaterialStateProperty.all(Color(0xfffffff3))',
'elevation: MaterialStateProperty.all(1.5)',
'padding: MaterialStateProperty.all(EdgeInsets.all(1.0))',
'minimumSize: MaterialStateProperty.all(Size(1.0, 2.0))',
'side: MaterialStateProperty.all(BorderSide(Color(0xfffffff4), 4.0, BorderStyle.solid))',
'shape: MaterialStateProperty.all(StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none)))',
'mouseCursor: MaterialStateProperty.all(SystemMouseCursor(forbidden))',
'tapTargetSize: shrinkWrap',
'animationDuration: 0:00:01.000000',
'enableFeedback: true',
]);
});
testWidgets('ButtonStyle copyWith, merge', (WidgetTester tester) async {
final MaterialStateProperty<TextStyle> textStyle = MaterialStateProperty.all<TextStyle>(const TextStyle(fontSize: 10));
final MaterialStateProperty<Color> backgroundColor = MaterialStateProperty.all<Color>(const Color(0xfffffff1));
final MaterialStateProperty<Color> foregroundColor = MaterialStateProperty.all<Color>(const Color(0xfffffff2));
final MaterialStateProperty<Color> overlayColor = MaterialStateProperty.all<Color>(const Color(0xfffffff3));
final MaterialStateProperty<double> elevation = MaterialStateProperty.all<double>(1);
final MaterialStateProperty<EdgeInsets> padding = MaterialStateProperty.all<EdgeInsets>(const EdgeInsets.all(1));
final MaterialStateProperty<Size> minimumSize = MaterialStateProperty.all<Size>(const Size(1, 2));
final MaterialStateProperty<BorderSide> side = MaterialStateProperty.all<BorderSide>(const BorderSide());
final MaterialStateProperty<OutlinedBorder> shape = MaterialStateProperty.all<OutlinedBorder>(const StadiumBorder());
final MaterialStateProperty<MouseCursor> mouseCursor = MaterialStateProperty.all<MouseCursor>(SystemMouseCursors.forbidden);
const VisualDensity visualDensity = VisualDensity.compact;
const MaterialTapTargetSize tapTargetSize = MaterialTapTargetSize.shrinkWrap;
const Duration animationDuration = Duration(seconds: 1);
const bool enableFeedback = true;
final ButtonStyle style = ButtonStyle(
textStyle: textStyle,
backgroundColor: backgroundColor,
foregroundColor: foregroundColor,
overlayColor: overlayColor,
elevation: elevation,
padding: padding,
minimumSize: minimumSize,
side: side,
shape: shape,
mouseCursor: mouseCursor,
visualDensity: visualDensity,
tapTargetSize: tapTargetSize,
animationDuration: animationDuration,
enableFeedback: enableFeedback,
);
expect(
style,
const ButtonStyle().copyWith(
textStyle: textStyle,
backgroundColor: backgroundColor,
foregroundColor: foregroundColor,
overlayColor: overlayColor,
elevation: elevation,
padding: padding,
minimumSize: minimumSize,
side: side,
shape: shape,
mouseCursor: mouseCursor,
visualDensity: visualDensity,
tapTargetSize: tapTargetSize,
animationDuration: animationDuration,
enableFeedback: enableFeedback,
),
);
expect(
style,
const ButtonStyle().merge(style),
);
expect(
style.copyWith(),
style.merge(const ButtonStyle())
);
});
}
This diff is collapsed.
// 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.
// @dart = 2.8
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Passing no ContainedButtonTheme returns defaults', (WidgetTester tester) async {
const ColorScheme colorScheme = ColorScheme.light();
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.from(colorScheme: colorScheme),
home: Scaffold(
body: Center(
child: ContainedButton(
onPressed: () { },
child: const Text('button'),
),
),
),
),
);
final Finder buttonMaterial = find.descendant(
of: find.byType(ContainedButton),
matching: find.byType(Material),
);
final Material material = tester.widget<Material>(buttonMaterial);
expect(material.animationDuration, const Duration(milliseconds: 200));
expect(material.borderRadius, null);
expect(material.color, colorScheme.primary);
expect(material.elevation, 2);
expect(material.shadowColor, const Color(0xff000000));
expect(material.shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(4.0)));
expect(material.textStyle.color, colorScheme.onPrimary);
expect(material.textStyle.fontFamily, 'Roboto');
expect(material.textStyle.fontSize, 14);
expect(material.textStyle.fontWeight, FontWeight.w500);
});
group('[Theme, TextTheme, ContainedButton style overrides]', () {
const Color primaryColor = Color(0xff000001);
const Color onSurfaceColor = Color(0xff000002);
const Color shadowColor = Color(0xff000004);
const Color onPrimaryColor = Color(0xff000005);
const double elevation = 1;
const TextStyle textStyle = TextStyle(fontSize: 12.0);
const EdgeInsets padding = EdgeInsets.all(3);
const Size minimumSize = Size(200, 200);
const BorderSide side = BorderSide(color: Colors.green, width: 2);
const OutlinedBorder shape = RoundedRectangleBorder(side: side, borderRadius: BorderRadius.all(Radius.circular(2)));
const MouseCursor enabledMouseCursor = SystemMouseCursors.text;
const MouseCursor disabledMouseCursor = SystemMouseCursors.grab;
const MaterialTapTargetSize tapTargetSize = MaterialTapTargetSize.shrinkWrap;
const Duration animationDuration = Duration(milliseconds: 25);
const bool enableFeedback = false;
final ButtonStyle style = ContainedButton.styleFrom(
primary: primaryColor,
onPrimary: onPrimaryColor,
onSurface: onSurfaceColor,
shadowColor: shadowColor,
elevation: elevation,
textStyle: textStyle,
padding: padding,
minimumSize: minimumSize,
side: side,
shape: shape,
enabledMouseCursor: enabledMouseCursor,
disabledMouseCursor: disabledMouseCursor,
tapTargetSize: tapTargetSize,
animationDuration: animationDuration,
enableFeedback: enableFeedback,
);
Widget buildFrame({ ButtonStyle buttonStyle, ButtonStyle themeStyle, ButtonStyle overallStyle }) {
final Widget child = Builder(
builder: (BuildContext context) {
return ContainedButton(
style: buttonStyle,
onPressed: () { },
child: const Text('button'),
);
},
);
return MaterialApp(
theme: ThemeData.from(colorScheme: const ColorScheme.light()).copyWith(
containedButtonTheme: ContainedButtonThemeData(style: overallStyle),
),
home: Scaffold(
body: Center(
// If the ContainedButtonTheme widget is present, it's used
// instead of the Theme's ThemeData.containedButtonTheme.
child: themeStyle == null ? child : ContainedButtonTheme(
data: ContainedButtonThemeData(style: themeStyle),
child: child,
),
),
),
);
}
final Finder findMaterial = find.descendant(
of: find.byType(ContainedButton),
matching: find.byType(Material),
);
final Finder findInkWell = find.descendant(
of: find.byType(ContainedButton),
matching: find.byType(InkWell),
);
const Set<MaterialState> enabled = <MaterialState>{};
const Set<MaterialState> disabled = <MaterialState>{ MaterialState.disabled };
const Set<MaterialState> hovered = <MaterialState>{ MaterialState.hovered };
const Set<MaterialState> focused = <MaterialState>{ MaterialState.focused };
const Set<MaterialState> pressed = <MaterialState>{ MaterialState.pressed };
void checkButton(WidgetTester tester) {
final Material material = tester.widget<Material>(findMaterial);
final InkWell inkWell = tester.widget<InkWell>(findInkWell);
expect(material.textStyle.color, onPrimaryColor);
expect(material.textStyle.fontSize, 12);
expect(material.color, primaryColor);
expect(material.shadowColor, shadowColor);
expect(material.elevation, elevation);
expect(MaterialStateProperty.resolveAs<MouseCursor>(inkWell.mouseCursor, enabled), enabledMouseCursor);
expect(MaterialStateProperty.resolveAs<MouseCursor>(inkWell.mouseCursor, disabled), disabledMouseCursor);
expect(inkWell.overlayColor.resolve(hovered), onPrimaryColor.withOpacity(0.08));
expect(inkWell.overlayColor.resolve(focused), onPrimaryColor.withOpacity(0.24));
expect(inkWell.overlayColor.resolve(pressed), onPrimaryColor.withOpacity(0.24));
expect(inkWell.enableFeedback, enableFeedback);
expect(material.borderRadius, null);
expect(material.shape, shape);
expect(material.animationDuration, animationDuration);
expect(tester.getSize(find.byType(ContainedButton)), const Size(200, 200));
}
testWidgets('Button style overrides defaults', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(buttonStyle: style));
await tester.pumpAndSettle(); // allow the animations to finish
checkButton(tester);
});
testWidgets('Button theme style overrides defaults', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(themeStyle: style));
await tester.pumpAndSettle();
checkButton(tester);
});
testWidgets('Overall Theme button theme style overrides defaults', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(overallStyle: style));
await tester.pumpAndSettle();
checkButton(tester);
});
// Same as the previous tests with empty ButtonStyle's instead of null.
testWidgets('Button style overrides defaults, empty theme and overall styles', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(buttonStyle: style, themeStyle: const ButtonStyle(), overallStyle: const ButtonStyle()));
await tester.pumpAndSettle(); // allow the animations to finish
checkButton(tester);
});
testWidgets('Button theme style overrides defaults, empty button and overall styles', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(buttonStyle: const ButtonStyle(), themeStyle: style, overallStyle: const ButtonStyle()));
await tester.pumpAndSettle(); // allow the animations to finish
checkButton(tester);
});
testWidgets('Overall Theme button theme style overrides defaults, null theme and empty overall style', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(buttonStyle: const ButtonStyle(), themeStyle: null, overallStyle: style));
await tester.pumpAndSettle(); // allow the animations to finish
checkButton(tester);
});
});
}
This diff is collapsed.
// 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.
// @dart = 2.8
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Passing no OutlinedButtonTheme returns defaults', (WidgetTester tester) async {
const ColorScheme colorScheme = ColorScheme.light();
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.from(colorScheme: colorScheme),
home: Scaffold(
body: Center(
child: OutlinedButton(
onPressed: () { },
child: const Text('button'),
),
),
),
),
);
final Finder buttonMaterial = find.descendant(
of: find.byType(OutlinedButton),
matching: find.byType(Material),
);
final Material material = tester.widget<Material>(buttonMaterial);
expect(material.animationDuration, const Duration(milliseconds: 200));
expect(material.borderRadius, null);
expect(material.color, Colors.transparent);
expect(material.elevation, 0.0);
expect(material.shadowColor, const Color(0xff000000));
expect(material.shape, RoundedRectangleBorder(
side: BorderSide(width: 1, color: colorScheme.onSurface.withOpacity(0.12)),
borderRadius: BorderRadius.circular(4.0),
));
expect(material.textStyle.color, colorScheme.primary);
expect(material.textStyle.fontFamily, 'Roboto');
expect(material.textStyle.fontSize, 14);
expect(material.textStyle.fontWeight, FontWeight.w500);
});
group('[Theme, TextTheme, OutlinedButton style overrides]', () {
const Color primaryColor = Color(0xff000001);
const Color onSurfaceColor = Color(0xff000002);
const Color backgroundColor = Color(0xff000003);
const Color shadowColor = Color(0xff000004);
const double elevation = 3;
const TextStyle textStyle = TextStyle(fontSize: 12.0);
const EdgeInsets padding = EdgeInsets.all(3);
const Size minimumSize = Size(200, 200);
const BorderSide side = BorderSide(color: Colors.green, width: 2);
const OutlinedBorder shape = RoundedRectangleBorder(side: side, borderRadius: BorderRadius.all(Radius.circular(2)));
const MouseCursor enabledMouseCursor = SystemMouseCursors.text;
const MouseCursor disabledMouseCursor = SystemMouseCursors.grab;
const MaterialTapTargetSize tapTargetSize = MaterialTapTargetSize.shrinkWrap;
const Duration animationDuration = Duration(milliseconds: 25);
const bool enableFeedback = false;
final ButtonStyle style = OutlinedButton.styleFrom(
primary: primaryColor,
onSurface: onSurfaceColor,
backgroundColor: backgroundColor,
shadowColor: shadowColor,
elevation: elevation,
textStyle: textStyle,
padding: padding,
minimumSize: minimumSize,
side: side,
shape: shape,
enabledMouseCursor: enabledMouseCursor,
disabledMouseCursor: disabledMouseCursor,
tapTargetSize: tapTargetSize,
animationDuration: animationDuration,
enableFeedback: enableFeedback,
);
Widget buildFrame({ ButtonStyle buttonStyle, ButtonStyle themeStyle, ButtonStyle overallStyle }) {
final Widget child = Builder(
builder: (BuildContext context) {
return OutlinedButton(
style: buttonStyle,
onPressed: () { },
child: const Text('button'),
);
},
);
return MaterialApp(
theme: ThemeData.from(colorScheme: const ColorScheme.light()).copyWith(
outlinedButtonTheme: OutlinedButtonThemeData(style: overallStyle),
),
home: Scaffold(
body: Center(
// If the OutlinedButtonTheme widget is present, it's used
// instead of the Theme's ThemeData.outlinedButtonTheme.
child: themeStyle == null ? child : OutlinedButtonTheme(
data: OutlinedButtonThemeData(style: themeStyle),
child: child,
),
),
),
);
}
final Finder findMaterial = find.descendant(
of: find.byType(OutlinedButton),
matching: find.byType(Material),
);
final Finder findInkWell = find.descendant(
of: find.byType(OutlinedButton),
matching: find.byType(InkWell),
);
const Set<MaterialState> enabled = <MaterialState>{};
const Set<MaterialState> disabled = <MaterialState>{ MaterialState.disabled };
const Set<MaterialState> hovered = <MaterialState>{ MaterialState.hovered };
const Set<MaterialState> focused = <MaterialState>{ MaterialState.focused };
void checkButton(WidgetTester tester) {
final Material material = tester.widget<Material>(findMaterial);
final InkWell inkWell = tester.widget<InkWell>(findInkWell);
expect(material.textStyle.color, primaryColor);
expect(material.textStyle.fontSize, 12);
expect(material.color, backgroundColor);
expect(material.shadowColor, shadowColor);
expect(material.elevation, elevation);
expect(MaterialStateProperty.resolveAs<MouseCursor>(inkWell.mouseCursor, enabled), enabledMouseCursor);
expect(MaterialStateProperty.resolveAs<MouseCursor>(inkWell.mouseCursor, disabled), disabledMouseCursor);
expect(inkWell.overlayColor.resolve(hovered), primaryColor.withOpacity(0.04));
expect(inkWell.overlayColor.resolve(focused), primaryColor.withOpacity(0.12));
expect(inkWell.enableFeedback, enableFeedback);
expect(material.borderRadius, null);
expect(material.shape, shape);
expect(material.animationDuration, animationDuration);
expect(tester.getSize(find.byType(OutlinedButton)), const Size(200, 200));
}
testWidgets('Button style overrides defaults', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(buttonStyle: style));
await tester.pumpAndSettle(); // allow the animations to finish
checkButton(tester);
});
testWidgets('Button theme style overrides defaults', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(themeStyle: style));
await tester.pumpAndSettle();
checkButton(tester);
});
testWidgets('Overall Theme button theme style overrides defaults', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(overallStyle: style));
await tester.pumpAndSettle();
checkButton(tester);
});
// Same as the previous tests with empty ButtonStyle's instead of null.
testWidgets('Button style overrides defaults, empty theme and overall styles', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(buttonStyle: style, themeStyle: const ButtonStyle(), overallStyle: const ButtonStyle()));
await tester.pumpAndSettle(); // allow the animations to finish
checkButton(tester);
});
testWidgets('Button theme style overrides defaults, empty button and overall styles', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(buttonStyle: const ButtonStyle(), themeStyle: style, overallStyle: const ButtonStyle()));
await tester.pumpAndSettle(); // allow the animations to finish
checkButton(tester);
});
testWidgets('Overall Theme button theme style overrides defaults, null theme and empty overall style', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(buttonStyle: const ButtonStyle(), themeStyle: null, overallStyle: style));
await tester.pumpAndSettle(); // allow the animations to finish
checkButton(tester);
});
});
}
This diff is collapsed.
// 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.
// @dart = 2.8
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Passing no TextButtonTheme returns defaults', (WidgetTester tester) async {
const ColorScheme colorScheme = ColorScheme.light();
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.from(colorScheme: colorScheme),
home: Scaffold(
body: Center(
child: TextButton(
onPressed: () { },
child: const Text('button'),
),
),
),
),
);
final Finder buttonMaterial = find.descendant(
of: find.byType(TextButton),
matching: find.byType(Material),
);
final Material material = tester.widget<Material>(buttonMaterial);
expect(material.animationDuration, const Duration(milliseconds: 200));
expect(material.borderRadius, null);
expect(material.color, Colors.transparent);
expect(material.elevation, 0.0);
expect(material.shadowColor, const Color(0xff000000));
expect(material.shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(4.0)));
expect(material.textStyle.color, colorScheme.primary);
expect(material.textStyle.fontFamily, 'Roboto');
expect(material.textStyle.fontSize, 14);
expect(material.textStyle.fontWeight, FontWeight.w500);
});
group('[Theme, TextTheme, TextButton style overrides]', () {
const Color primaryColor = Color(0xff000001);
const Color onSurfaceColor = Color(0xff000002);
const Color backgroundColor = Color(0xff000003);
const Color shadowColor = Color(0xff000004);
const double elevation = 3;
const TextStyle textStyle = TextStyle(fontSize: 12.0);
const EdgeInsets padding = EdgeInsets.all(3);
const Size minimumSize = Size(200, 200);
const BorderSide side = BorderSide(color: Colors.green, width: 2);
const OutlinedBorder shape = RoundedRectangleBorder(side: side, borderRadius: BorderRadius.all(Radius.circular(2)));
const MouseCursor enabledMouseCursor = SystemMouseCursors.text;
const MouseCursor disabledMouseCursor = SystemMouseCursors.grab;
const MaterialTapTargetSize tapTargetSize = MaterialTapTargetSize.shrinkWrap;
const Duration animationDuration = Duration(milliseconds: 25);
const bool enableFeedback = false;
final ButtonStyle style = TextButton.styleFrom(
primary: primaryColor,
onSurface: onSurfaceColor,
backgroundColor: backgroundColor,
shadowColor: shadowColor,
elevation: elevation,
textStyle: textStyle,
padding: padding,
minimumSize: minimumSize,
side: side,
shape: shape,
enabledMouseCursor: enabledMouseCursor,
disabledMouseCursor: disabledMouseCursor,
tapTargetSize: tapTargetSize,
animationDuration: animationDuration,
enableFeedback: enableFeedback,
);
Widget buildFrame({ ButtonStyle buttonStyle, ButtonStyle themeStyle, ButtonStyle overallStyle }) {
final Widget child = Builder(
builder: (BuildContext context) {
return TextButton(
style: buttonStyle,
onPressed: () { },
child: const Text('button'),
);
},
);
return MaterialApp(
theme: ThemeData.from(colorScheme: const ColorScheme.light()).copyWith(
textButtonTheme: TextButtonThemeData(style: overallStyle),
),
home: Scaffold(
body: Center(
// If the TextButtonTheme widget is present, it's used
// instead of the Theme's ThemeData.textButtonTheme.
child: themeStyle == null ? child : TextButtonTheme(
data: TextButtonThemeData(style: themeStyle),
child: child,
),
),
),
);
}
final Finder findMaterial = find.descendant(
of: find.byType(TextButton),
matching: find.byType(Material),
);
final Finder findInkWell = find.descendant(
of: find.byType(TextButton),
matching: find.byType(InkWell),
);
const Set<MaterialState> enabled = <MaterialState>{};
const Set<MaterialState> disabled = <MaterialState>{ MaterialState.disabled };
const Set<MaterialState> hovered = <MaterialState>{ MaterialState.hovered };
const Set<MaterialState> focused = <MaterialState>{ MaterialState.focused };
void checkButton(WidgetTester tester) {
final Material material = tester.widget<Material>(findMaterial);
final InkWell inkWell = tester.widget<InkWell>(findInkWell);
expect(material.textStyle.color, primaryColor);
expect(material.textStyle.fontSize, 12);
expect(material.color, backgroundColor);
expect(material.shadowColor, shadowColor);
expect(material.elevation, elevation);
expect(MaterialStateProperty.resolveAs<MouseCursor>(inkWell.mouseCursor, enabled), enabledMouseCursor);
expect(MaterialStateProperty.resolveAs<MouseCursor>(inkWell.mouseCursor, disabled), disabledMouseCursor);
expect(inkWell.overlayColor.resolve(hovered), primaryColor.withOpacity(0.04));
expect(inkWell.overlayColor.resolve(focused), primaryColor.withOpacity(0.12));
expect(inkWell.enableFeedback, enableFeedback);
expect(material.borderRadius, null);
expect(material.shape, shape);
expect(material.animationDuration, animationDuration);
expect(tester.getSize(find.byType(TextButton)), const Size(200, 200));
}
testWidgets('Button style overrides defaults', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(buttonStyle: style));
await tester.pumpAndSettle(); // allow the animations to finish
checkButton(tester);
});
testWidgets('Button theme style overrides defaults', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(themeStyle: style));
await tester.pumpAndSettle();
checkButton(tester);
});
testWidgets('Overall Theme button theme style overrides defaults', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(overallStyle: style));
await tester.pumpAndSettle();
checkButton(tester);
});
// Same as the previous tests with empty ButtonStyle's instead of null.
testWidgets('Button style overrides defaults, empty theme and overall styles', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(buttonStyle: style, themeStyle: const ButtonStyle(), overallStyle: const ButtonStyle()));
await tester.pumpAndSettle(); // allow the animations to finish
checkButton(tester);
});
testWidgets('Button theme style overrides defaults, empty button and overall styles', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(buttonStyle: const ButtonStyle(), themeStyle: style, overallStyle: const ButtonStyle()));
await tester.pumpAndSettle(); // allow the animations to finish
checkButton(tester);
});
testWidgets('Overall Theme button theme style overrides defaults, null theme and empty overall style', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(buttonStyle: const ButtonStyle(), themeStyle: null, overallStyle: style));
await tester.pumpAndSettle(); // allow the animations to finish
checkButton(tester);
});
});
}
......@@ -283,6 +283,9 @@ void main() {
buttonBarTheme: const ButtonBarThemeData(alignment: MainAxisAlignment.start),
bottomNavigationBarTheme: const BottomNavigationBarThemeData(type: BottomNavigationBarType.fixed),
timePickerTheme: const TimePickerThemeData(backgroundColor: Colors.black),
textButtonTheme: TextButtonThemeData(style: TextButton.styleFrom(primary: Colors.red)),
containedButtonTheme: ContainedButtonThemeData(style: ContainedButton.styleFrom(primary: Colors.green)),
outlinedButtonTheme: OutlinedButtonThemeData(style: OutlinedButton.styleFrom(primary: Colors.blue)),
fixTextFieldOutlineLabel: false,
);
......@@ -365,6 +368,9 @@ void main() {
buttonBarTheme: const ButtonBarThemeData(alignment: MainAxisAlignment.end),
bottomNavigationBarTheme: const BottomNavigationBarThemeData(type: BottomNavigationBarType.shifting),
timePickerTheme: const TimePickerThemeData(backgroundColor: Colors.white),
textButtonTheme: const TextButtonThemeData(),
containedButtonTheme: const ContainedButtonThemeData(),
outlinedButtonTheme: const OutlinedButtonThemeData(),
fixTextFieldOutlineLabel: true,
);
......@@ -433,6 +439,9 @@ void main() {
buttonBarTheme: otherTheme.buttonBarTheme,
bottomNavigationBarTheme: otherTheme.bottomNavigationBarTheme,
timePickerTheme: otherTheme.timePickerTheme,
textButtonTheme: otherTheme.textButtonTheme,
containedButtonTheme: otherTheme.containedButtonTheme,
outlinedButtonTheme: otherTheme.outlinedButtonTheme,
fixTextFieldOutlineLabel: otherTheme.fixTextFieldOutlineLabel,
);
......@@ -503,6 +512,9 @@ void main() {
expect(themeDataCopy.buttonBarTheme, equals(otherTheme.buttonBarTheme));
expect(themeDataCopy.bottomNavigationBarTheme, equals(otherTheme.bottomNavigationBarTheme));
expect(themeDataCopy.timePickerTheme, equals(otherTheme.timePickerTheme));
expect(themeDataCopy.textButtonTheme, equals(otherTheme.textButtonTheme));
expect(themeDataCopy.containedButtonTheme, equals(otherTheme.containedButtonTheme));
expect(themeDataCopy.outlinedButtonTheme, equals(otherTheme.outlinedButtonTheme));
expect(themeDataCopy.fixTextFieldOutlineLabel, equals(otherTheme.fixTextFieldOutlineLabel));
});
......
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