Unverified Commit 2b16202e authored by Josh Burton's avatar Josh Burton Committed by GitHub

Adds shadowColor property to the Card widget (#47273)

parent c03fbada
......@@ -5,6 +5,7 @@
import 'package:flutter/widgets.dart';
import 'card_theme.dart';
import 'colors.dart';
import 'material.dart';
import 'theme.dart';
......@@ -101,6 +102,7 @@ class Card extends StatelessWidget {
const Card({
Key key,
this.color,
this.shadowColor,
this.elevation,
this.shape,
this.borderOnForeground = true,
......@@ -120,6 +122,12 @@ class Card extends StatelessWidget {
/// if that's null then [ThemeData.cardColor] is used.
final Color color;
/// The color to paint the shadow below the card.
///
/// If null then the ambient [CardTheme]'s shadowColor is used.
/// If that's null too, then the default is fully opaque black.
final Color shadowColor;
/// The z-coordinate at which to place this card. This controls the size of
/// the shadow below the card.
///
......@@ -189,6 +197,7 @@ class Card extends StatelessWidget {
margin: margin ?? cardTheme.margin ?? const EdgeInsets.all(4.0),
child: Material(
type: MaterialType.card,
shadowColor: shadowColor ?? cardTheme.shadowColor ?? Colors.black,
color: color ?? cardTheme.color ?? Theme.of(context).cardColor,
elevation: elevation ?? cardTheme.elevation ?? _defaultElevation,
shape: shape ?? cardTheme.shape ?? const RoundedRectangleBorder(
......
......@@ -34,6 +34,7 @@ class CardTheme extends Diagnosticable {
const CardTheme({
this.clipBehavior,
this.color,
this.shadowColor,
this.elevation,
this.margin,
this.shape,
......@@ -49,6 +50,11 @@ class CardTheme extends Diagnosticable {
/// If null, [Card] uses [ThemeData.cardColor].
final Color color;
/// Default value for [Card.shadowColor].
///
/// If null, [Card] defaults to fully opaque black.
final Color shadowColor;
/// Default value for [Card.elevation].
///
/// If null, [Card] uses a default of 1.0.
......@@ -71,6 +77,7 @@ class CardTheme extends Diagnosticable {
CardTheme copyWith({
Clip clipBehavior,
Color color,
Color shadowColor,
double elevation,
EdgeInsetsGeometry margin,
ShapeBorder shape,
......@@ -78,6 +85,7 @@ class CardTheme extends Diagnosticable {
return CardTheme(
clipBehavior: clipBehavior ?? this.clipBehavior,
color: color ?? this.color,
shadowColor: shadowColor ?? this.shadowColor,
elevation: elevation ?? this.elevation,
margin: margin ?? this.margin,
shape: shape ?? this.shape,
......@@ -99,6 +107,7 @@ class CardTheme extends Diagnosticable {
return CardTheme(
clipBehavior: t < 0.5 ? a?.clipBehavior : b?.clipBehavior,
color: Color.lerp(a?.color, b?.color, t),
shadowColor: Color.lerp(a?.shadowColor, b?.shadowColor, t),
elevation: lerpDouble(a?.elevation, b?.elevation, t),
margin: EdgeInsetsGeometry.lerp(a?.margin, b?.margin, t),
shape: ShapeBorder.lerp(a?.shape, b?.shape, t),
......@@ -110,6 +119,7 @@ class CardTheme extends Diagnosticable {
return hashValues(
clipBehavior,
color,
shadowColor,
elevation,
margin,
shape,
......@@ -125,6 +135,7 @@ class CardTheme extends Diagnosticable {
return other is CardTheme
&& other.clipBehavior == clipBehavior
&& other.color == color
&& other.shadowColor == shadowColor
&& other.elevation == elevation
&& other.margin == margin
&& other.shape == shape;
......@@ -135,6 +146,7 @@ class CardTheme extends Diagnosticable {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Clip>('clipBehavior', clipBehavior, defaultValue: null));
properties.add(ColorProperty('color', color, defaultValue: null));
properties.add(ColorProperty('shadowColor', shadowColor, defaultValue: null));
properties.add(DiagnosticsProperty<double>('elevation', elevation, defaultValue: null));
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('margin', margin, defaultValue: null));
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
......
......@@ -188,4 +188,37 @@ void main() {
}));
expect(tester.widget<Material>(find.byType(Material)).clipBehavior, Clip.antiAliasWithSaveLayer);
});
}
testWidgets('Card shadowColor', (WidgetTester tester) async {
Material _getCardMaterial(WidgetTester tester) {
return tester.widget<Material>(
find.descendant(
of: find.byType(Card),
matching: find.byType(Material),
),
);
}
Card _getCard(WidgetTester tester) {
return tester.widget<Card>(
find.byType(Card)
);
}
await tester.pumpWidget(
const Card(),
);
expect(_getCard(tester).shadowColor, null);
expect(_getCardMaterial(tester).shadowColor, const Color(0xFF000000));
await tester.pumpWidget(
const Card(
shadowColor: Colors.red,
),
);
expect(_getCardMaterial(tester).shadowColor, _getCard(tester).shadowColor);
expect(_getCardMaterial(tester).shadowColor, Colors.red);
});
}
\ No newline at end of file
......@@ -46,6 +46,7 @@ void main() {
expect(material.clipBehavior, cardTheme.clipBehavior);
expect(material.color, cardTheme.color);
expect(material.shadowColor, cardTheme.shadowColor);
expect(material.elevation, cardTheme.elevation);
expect(container.margin, cardTheme.margin);
expect(material.shape, cardTheme.shape);
......@@ -146,6 +147,7 @@ CardTheme _cardTheme() {
return const CardTheme(
clipBehavior: Clip.antiAlias,
color: Colors.green,
shadowColor: Colors.red,
elevation: 6.0,
margin: EdgeInsets.all(7.0),
shape: RoundedRectangleBorder(
......
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