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

ButtonTheme.of().colorScheme defers to Theme (#22880)

ButtonThemeData no longer requires a colorScheme. If colorScheme is null, ButtonTheme.of() will initialize it from the current Theme.
parent 0ff9e8a9
......@@ -129,7 +129,6 @@ class TravelDestinationItem extends StatelessWidget {
),
// share, explore buttons
ButtonTheme.bar(
colorScheme: theme.colorScheme,
child: ButtonBar(
alignment: MainAxisAlignment.start,
children: <Widget>[
......
......@@ -80,7 +80,7 @@ class ButtonTheme extends InheritedWidget {
Color disabledColor,
Color highlightColor,
Color splashColor,
ColorScheme colorScheme = const ColorScheme.light(),
ColorScheme colorScheme,
MaterialTapTargetSize materialTapTargetSize,
Widget child,
}) : assert(textTheme != null),
......@@ -88,7 +88,6 @@ class ButtonTheme extends InheritedWidget {
assert(height != null && height >= 0.0),
assert(alignedDropdown != null),
assert(layoutBehavior != null),
assert(colorScheme != null),
data = ButtonThemeData(
textTheme: textTheme,
minWidth: minWidth,
......@@ -142,14 +141,13 @@ class ButtonTheme extends InheritedWidget {
Color disabledColor,
Color highlightColor,
Color splashColor,
ColorScheme colorScheme = const ColorScheme.light(),
ColorScheme colorScheme,
Widget child,
ButtonBarLayoutBehavior layoutBehavior = ButtonBarLayoutBehavior.padded,
}) : assert(textTheme != null),
assert(minWidth != null && minWidth >= 0.0),
assert(height != null && height >= 0.0),
assert(alignedDropdown != null),
assert(colorScheme != null),
data = ButtonThemeData(
textTheme: textTheme,
minWidth: minWidth,
......@@ -177,8 +175,19 @@ class ButtonTheme extends InheritedWidget {
/// ButtonThemeData theme = ButtonTheme.of(context);
/// ```
static ButtonThemeData of(BuildContext context) {
final ButtonTheme result = context.inheritFromWidgetOfExactType(ButtonTheme);
return result?.data ?? Theme.of(context).buttonTheme;
final ButtonTheme inheritedButtonTheme = context.inheritFromWidgetOfExactType(ButtonTheme);
ButtonThemeData buttonTheme = inheritedButtonTheme?.data;
if (buttonTheme?.colorScheme == null) { // if buttonTheme or buttonTheme.colorScheme is null
final ThemeData theme = Theme.of(context);
buttonTheme ??= theme.buttonTheme;
if (buttonTheme.colorScheme == null) {
buttonTheme = buttonTheme.copyWith(
colorScheme: theme.buttonTheme.colorScheme ?? theme.colorScheme,
);
assert(buttonTheme.colorScheme != null);
}
}
return buttonTheme;
}
@override
......@@ -194,7 +203,9 @@ class ButtonThemeData extends Diagnosticable {
/// Create a button theme object that can be used with [ButtonTheme]
/// or [ThemeData].
///
/// The [textTheme], [minWidth], and [height] parameters must not be null.
/// The [textTheme], [minWidth], [height], [alignedDropDown], and
/// [layoutBehavior] parameters must not be null. The [minWidth] and
/// [height] parameters must greater than or equal to zero.
///
/// The ButtonTheme's methods that have a [MaterialButton] parameter and
/// have a name with a `get` prefix are used by [RaisedButton],
......@@ -211,14 +222,13 @@ class ButtonThemeData extends Diagnosticable {
Color disabledColor,
Color highlightColor,
Color splashColor,
this.colorScheme = const ColorScheme.light(),
this.colorScheme,
MaterialTapTargetSize materialTapTargetSize,
}) : assert(textTheme != null),
assert(minWidth != null && minWidth >= 0.0),
assert(height != null && height >= 0.0),
assert(alignedDropdown != null),
assert(layoutBehavior != null),
assert(colorScheme != null),
_buttonColor = buttonColor,
_disabledColor = disabledColor,
_highlightColor = highlightColor,
......@@ -719,6 +729,7 @@ class ButtonThemeData extends Diagnosticable {
/// replaced with the non-null parameter values.
ButtonThemeData copyWith({
ButtonTextTheme textTheme,
ButtonBarLayoutBehavior layoutBehavior,
double minWidth,
double height,
EdgeInsetsGeometry padding,
......@@ -733,6 +744,7 @@ class ButtonThemeData extends Diagnosticable {
}) {
return ButtonThemeData(
textTheme: textTheme ?? this.textTheme,
layoutBehavior: layoutBehavior ?? this.layoutBehavior,
minWidth: minWidth ?? this.minWidth,
height: height ?? this.height,
padding: padding ?? this.padding,
......
......@@ -952,7 +952,6 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
),
);
final Widget actions = ButtonTheme.bar(
colorScheme: theme.buttonTheme.colorScheme,
child: ButtonBar(
children: <Widget>[
FlatButton(
......
......@@ -274,7 +274,6 @@ class AlertDialog extends StatelessWidget {
if (actions != null) {
children.add(ButtonTheme.bar(
colorScheme: Theme.of(context).colorScheme,
child: ButtonBar(
children: actions,
),
......
......@@ -400,7 +400,6 @@ class PaginatedDataTableState extends State<PaginatedDataTable> {
opacity: 0.54
),
child: ButtonTheme.bar(
colorScheme: themeData.colorScheme,
child: Ink(
height: 64.0,
color: _selectedRowCount > 0 ? themeData.secondaryHeaderColor : null,
......
......@@ -1605,7 +1605,6 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin {
),
child: SafeArea(
child: ButtonTheme.bar(
colorScheme: themeData.colorScheme,
child: SafeArea(
top: false,
child: ButtonBar(
......
......@@ -213,7 +213,6 @@ class SnackBar extends StatelessWidget {
];
if (action != null) {
children.add(ButtonTheme.bar(
colorScheme: theme.colorScheme,
padding: const EdgeInsets.symmetric(horizontal: _kSnackBarPadding),
textTheme: ButtonTextTheme.accent,
child: action,
......
......@@ -1541,7 +1541,6 @@ class _TimePickerDialogState extends State<_TimePickerDialog> {
);
final Widget actions = ButtonTheme.bar(
colorScheme: theme.colorScheme,
child: ButtonBar(
children: <Widget>[
FlatButton(
......
......@@ -64,4 +64,56 @@ void main() {
final Finder buttonBar = find.byType(ButtonBar);
expect(tester.getBottomRight(buttonBar).dy - tester.getTopRight(buttonBar).dy, 26.0);
});
testWidgets('ButtonBar FlatButton inherits Theme accentColor', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/22789
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(accentColor: const Color(1)),
home: Builder(
builder: (BuildContext context) {
return Center(
child: ButtonTheme.bar(
child: ButtonBar(
children: <Widget>[
FlatButton(
child: const Text('button'),
onPressed: () {
showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog( // puts its actions in a ButtonBar
actions: <Widget>[
FlatButton(
onPressed: () { },
child: const Text('enabled'),
),
],
);
},
);
},
),
],
),
),
);
},
),
),
);
expect(tester.widget<RawMaterialButton>(find.byType(RawMaterialButton)).textStyle.color, const Color(1));
// Show the dialog
await tester.tap(find.text('button'));
await tester.pumpAndSettle();
final Finder dialogButton = find.ancestor(
of: find.text('enabled'),
matching: find.byType(RawMaterialButton),
);
expect(tester.widget<RawMaterialButton>(dialogButton).textStyle.color, const Color(1));
});
}
......@@ -36,9 +36,12 @@ void main() {
testWidgets('ButtonTheme defaults', (WidgetTester tester) async {
ButtonTextTheme textTheme;
ButtonBarLayoutBehavior layoutBehavior;
BoxConstraints constraints;
EdgeInsets padding;
ShapeBorder shape;
bool alignedDropdown;
ColorScheme colorScheme;
await tester.pumpWidget(
ButtonTheme(
......@@ -49,13 +52,16 @@ void main() {
constraints = theme.constraints;
padding = theme.padding;
shape = theme.shape;
layoutBehavior = theme.layoutBehavior;
colorScheme = theme.colorScheme;
alignedDropdown = theme.alignedDropdown;
return Container(
alignment: Alignment.topLeft,
child: const Directionality(
child: Directionality(
textDirection: TextDirection.ltr,
child: FlatButton(
onPressed: null,
child: Text('b'), // intrinsic width < minimum width
onPressed: () { },
child: const Text('b'), // intrinsic width < minimum width
),
),
);
......@@ -65,12 +71,14 @@ void main() {
);
expect(textTheme, ButtonTextTheme.normal);
expect(layoutBehavior, ButtonBarLayoutBehavior.padded);
expect(constraints, const BoxConstraints(minWidth: 88.0, minHeight: 36.0));
expect(padding, const EdgeInsets.symmetric(horizontal: 16.0));
expect(shape, const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(2.0)),
));
expect(alignedDropdown, false);
expect(colorScheme, ThemeData.light().colorScheme);
expect(tester.widget<Material>(find.byType(Material)).shape, shape);
expect(tester.getSize(find.byType(Material)), const Size(88.0, 36.0));
});
......@@ -78,26 +86,33 @@ void main() {
test('ButtonThemeData.copyWith', () {
ButtonThemeData theme = const ButtonThemeData().copyWith();
expect(theme.textTheme, ButtonTextTheme.normal);
expect(theme.layoutBehavior, ButtonBarLayoutBehavior.padded);
expect(theme.constraints, const BoxConstraints(minWidth: 88.0, minHeight: 36.0));
expect(theme.padding, const EdgeInsets.symmetric(horizontal: 16.0));
expect(theme.shape, const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(2.0)),
));
expect(theme.alignedDropdown, false);
expect(theme.colorScheme, null);
theme = const ButtonThemeData().copyWith(
textTheme: ButtonTextTheme.primary,
layoutBehavior: ButtonBarLayoutBehavior.constrained,
minWidth: 100.0,
height: 200.0,
padding: EdgeInsets.zero,
shape: const StadiumBorder(),
alignedDropdown: true,
colorScheme: const ColorScheme.dark(),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
);
expect(theme.textTheme, ButtonTextTheme.primary);
expect(theme.layoutBehavior, ButtonBarLayoutBehavior.constrained);
expect(theme.constraints, const BoxConstraints(minWidth: 100.0, minHeight: 200.0));
expect(theme.padding, EdgeInsets.zero);
expect(theme.shape, const StadiumBorder());
expect(theme.alignedDropdown, true);
expect(theme.colorScheme, const ColorScheme.dark());
});
testWidgets('Theme buttonTheme defaults', (WidgetTester tester) async {
......
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