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