Normalize Card theme (#151914)
This PR is to make preparations to make `CardTheme` conform to Flutter's conventions for component themes: * Added a `CardThemeData` class which defines overrides for the defaults for `Card` properties. * Added 2 `CardTheme` constructor parameters: `CardThemeData? data` and `Widget? child`. This is now the preferred way to configure a `CardTheme`: ```dart CardTheme( data: CardThemeData(color: xxx, elevation: xxx, ...), child: Card(...) ) ``` These two properties are made nullable to not break existing apps which has customized `ThemeData.cardTheme`. * Changed the type of theme defaults from `CardTheme` to `CardThemeData`. TODO: * Fix internal failures that may have breakages. * Change the type of `ThemeData.cardTheme` from `CardTheme` to `CardThemeData`. This may cause breaking changes, a migration guide will be created. Addresses the "theme normalization" sub project within https://github.com/flutter/flutter/issues/91772
This commit is contained in:
parent
804cca62de
commit
2e7fa83f67
@ -26,7 +26,7 @@ class CardTemplate extends TokenTemplate {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String generate() => '''
|
String generate() => '''
|
||||||
class _${blockName}DefaultsM3 extends CardTheme {
|
class _${blockName}DefaultsM3 extends CardThemeData {
|
||||||
_${blockName}DefaultsM3(this.context)
|
_${blockName}DefaultsM3(this.context)
|
||||||
: super(
|
: super(
|
||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
|
@ -216,7 +216,7 @@ class Card extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final CardTheme cardTheme = CardTheme.of(context);
|
final CardTheme cardTheme = CardTheme.of(context);
|
||||||
final CardTheme defaults;
|
final CardThemeData defaults;
|
||||||
if (Theme.of(context).useMaterial3) {
|
if (Theme.of(context).useMaterial3) {
|
||||||
defaults = switch (_variant) {
|
defaults = switch (_variant) {
|
||||||
_CardVariant.elevated => _CardDefaultsM3(context),
|
_CardVariant.elevated => _CardDefaultsM3(context),
|
||||||
@ -251,7 +251,7 @@ class Card extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hand coded defaults based on Material Design 2.
|
// Hand coded defaults based on Material Design 2.
|
||||||
class _CardDefaultsM2 extends CardTheme {
|
class _CardDefaultsM2 extends CardThemeData {
|
||||||
const _CardDefaultsM2(this.context)
|
const _CardDefaultsM2(this.context)
|
||||||
: super(
|
: super(
|
||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
@ -278,7 +278,7 @@ class _CardDefaultsM2 extends CardTheme {
|
|||||||
// Design token database by the script:
|
// Design token database by the script:
|
||||||
// dev/tools/gen_defaults/bin/gen_defaults.dart.
|
// dev/tools/gen_defaults/bin/gen_defaults.dart.
|
||||||
|
|
||||||
class _CardDefaultsM3 extends CardTheme {
|
class _CardDefaultsM3 extends CardThemeData {
|
||||||
_CardDefaultsM3(this.context)
|
_CardDefaultsM3(this.context)
|
||||||
: super(
|
: super(
|
||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
@ -311,7 +311,7 @@ class _CardDefaultsM3 extends CardTheme {
|
|||||||
// Design token database by the script:
|
// Design token database by the script:
|
||||||
// dev/tools/gen_defaults/bin/gen_defaults.dart.
|
// dev/tools/gen_defaults/bin/gen_defaults.dart.
|
||||||
|
|
||||||
class _FilledCardDefaultsM3 extends CardTheme {
|
class _FilledCardDefaultsM3 extends CardThemeData {
|
||||||
_FilledCardDefaultsM3(this.context)
|
_FilledCardDefaultsM3(this.context)
|
||||||
: super(
|
: super(
|
||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
@ -344,7 +344,7 @@ class _FilledCardDefaultsM3 extends CardTheme {
|
|||||||
// Design token database by the script:
|
// Design token database by the script:
|
||||||
// dev/tools/gen_defaults/bin/gen_defaults.dart.
|
// dev/tools/gen_defaults/bin/gen_defaults.dart.
|
||||||
|
|
||||||
class _OutlinedCardDefaultsM3 extends CardTheme {
|
class _OutlinedCardDefaultsM3 extends CardThemeData {
|
||||||
_OutlinedCardDefaultsM3(this.context)
|
_OutlinedCardDefaultsM3(this.context)
|
||||||
: super(
|
: super(
|
||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
|
@ -30,64 +30,111 @@ import 'theme.dart';
|
|||||||
///
|
///
|
||||||
/// * [ThemeData], which describes the overall theme information for the
|
/// * [ThemeData], which describes the overall theme information for the
|
||||||
/// application.
|
/// application.
|
||||||
@immutable
|
class CardTheme extends InheritedWidget with Diagnosticable {
|
||||||
class CardTheme with Diagnosticable {
|
|
||||||
|
|
||||||
/// Creates a theme that can be used for [ThemeData.cardTheme].
|
/// Creates a theme that can be used for [ThemeData.cardTheme].
|
||||||
///
|
///
|
||||||
/// The [elevation] must be null or non-negative.
|
/// The [elevation] must be null or non-negative.
|
||||||
const CardTheme({
|
const CardTheme({
|
||||||
this.clipBehavior,
|
super.key,
|
||||||
this.color,
|
Clip? clipBehavior,
|
||||||
this.shadowColor,
|
Color? color,
|
||||||
this.surfaceTintColor,
|
Color? surfaceTintColor,
|
||||||
this.elevation,
|
Color? shadowColor,
|
||||||
this.margin,
|
double? elevation,
|
||||||
this.shape,
|
EdgeInsetsGeometry? margin,
|
||||||
}) : assert(elevation == null || elevation >= 0.0);
|
ShapeBorder? shape,
|
||||||
|
CardThemeData? data,
|
||||||
|
Widget? child,
|
||||||
|
}) : assert(
|
||||||
|
data == null ||
|
||||||
|
(clipBehavior ??
|
||||||
|
color ??
|
||||||
|
surfaceTintColor ??
|
||||||
|
shadowColor ??
|
||||||
|
elevation ??
|
||||||
|
margin ??
|
||||||
|
shape) == null),
|
||||||
|
assert(elevation == null || elevation >= 0.0),
|
||||||
|
_data = data,
|
||||||
|
_clipBehavior = clipBehavior,
|
||||||
|
_color = color,
|
||||||
|
_surfaceTintColor = surfaceTintColor,
|
||||||
|
_shadowColor = shadowColor,
|
||||||
|
_elevation = elevation,
|
||||||
|
_margin = margin,
|
||||||
|
_shape = shape,
|
||||||
|
super(child: child ?? const SizedBox());
|
||||||
|
|
||||||
|
final CardThemeData? _data;
|
||||||
|
final Clip? _clipBehavior;
|
||||||
|
final Color? _color;
|
||||||
|
final Color? _surfaceTintColor;
|
||||||
|
final Color? _shadowColor;
|
||||||
|
final double? _elevation;
|
||||||
|
final EdgeInsetsGeometry? _margin;
|
||||||
|
final ShapeBorder? _shape;
|
||||||
|
|
||||||
/// Overrides the default value for [Card.clipBehavior].
|
/// Overrides the default value for [Card.clipBehavior].
|
||||||
///
|
///
|
||||||
/// If null, [Card] uses [Clip.none].
|
/// This property is obsolete and will be deprecated in a future release:
|
||||||
final Clip? clipBehavior;
|
/// please use the [CardThemeData.clipBehavior] property in [data] instead.
|
||||||
|
Clip? get clipBehavior => _data != null ? _data.clipBehavior : _clipBehavior;
|
||||||
|
|
||||||
/// Overrides the default value for [Card.color].
|
/// Overrides the default value for [Card.color].
|
||||||
///
|
///
|
||||||
/// If null, [Card] uses [ThemeData.cardColor].
|
/// This property is obsolete and will be deprecated in a future release:
|
||||||
final Color? color;
|
/// please use the [CardThemeData.color] property in [data] instead.
|
||||||
|
Color? get color => _data != null ? _data.color : _color;
|
||||||
/// Overrides the default value for [Card.shadowColor].
|
|
||||||
///
|
|
||||||
/// If null, [Card] defaults to fully opaque black.
|
|
||||||
final Color? shadowColor;
|
|
||||||
|
|
||||||
/// Overrides the default value for [Card.surfaceTintColor].
|
/// Overrides the default value for [Card.surfaceTintColor].
|
||||||
///
|
///
|
||||||
/// If null, [Card] will not display an overlay color.
|
/// This property is obsolete and will be deprecated in a future release:
|
||||||
|
/// please use the [CardThemeData.surfaceTintColor] property in [data] instead.
|
||||||
|
Color? get surfaceTintColor => _data != null ? _data.surfaceTintColor : _surfaceTintColor;
|
||||||
|
|
||||||
|
/// Overrides the default value for [Card.shadowColor].
|
||||||
///
|
///
|
||||||
/// See [Material.surfaceTintColor] for more details.
|
/// This property is obsolete and will be deprecated in a future release:
|
||||||
final Color? surfaceTintColor;
|
/// please use the [CardThemeData.shadowColor] property in [data] instead.
|
||||||
|
Color? get shadowColor => _data != null ? _data.shadowColor : _shadowColor;
|
||||||
|
|
||||||
/// Overrides the default value for [Card.elevation].
|
/// Overrides the default value for [Card.elevation].
|
||||||
///
|
///
|
||||||
/// If null, [Card] uses a default of 1.0.
|
/// This property is obsolete and will be deprecated in a future release:
|
||||||
final double? elevation;
|
/// please use the [CardThemeData.elevation] property in [data] instead.
|
||||||
|
double? get elevation => _data != null ? _data.elevation : _elevation;
|
||||||
|
|
||||||
/// Overrides the default value for [Card.margin].
|
/// Overrides the default value for [Card.margin].
|
||||||
///
|
///
|
||||||
/// If null, [Card] uses a default margin of 4.0 logical pixels on all sides:
|
/// This property is obsolete and will be deprecated in a future release:
|
||||||
/// `EdgeInsets.all(4.0)`.
|
/// please use the [CardThemeData.margin] property in [data] instead.
|
||||||
final EdgeInsetsGeometry? margin;
|
EdgeInsetsGeometry? get margin => _data != null ? _data.margin : _margin;
|
||||||
|
|
||||||
/// Overrides the default value for [Card.shape].
|
/// Overrides the default value for [Card.shape].
|
||||||
///
|
///
|
||||||
/// If null, [Card] then uses a [RoundedRectangleBorder] with a circular
|
/// This property is obsolete and will be deprecated in a future release:
|
||||||
/// corner radius of 12.0 and if [ThemeData.useMaterial3] is false,
|
/// please use the [CardThemeData.shape] property in [data] instead.
|
||||||
/// then the circular corner radius will be 4.0.
|
ShapeBorder? get shape => _data != null ? _data.shape : _shape;
|
||||||
final ShapeBorder? shape;
|
|
||||||
|
/// The properties used for all descendant [Card] widgets.
|
||||||
|
CardThemeData get data {
|
||||||
|
return _data ?? CardThemeData(
|
||||||
|
clipBehavior: _clipBehavior,
|
||||||
|
color: _color,
|
||||||
|
surfaceTintColor: _surfaceTintColor,
|
||||||
|
shadowColor: _shadowColor,
|
||||||
|
elevation: _elevation,
|
||||||
|
margin: _margin,
|
||||||
|
shape: _shape,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a copy of this object with the given fields replaced with the
|
/// Creates a copy of this object with the given fields replaced with the
|
||||||
/// new values.
|
/// new values.
|
||||||
|
///
|
||||||
|
/// This method is obsolete and will be deprecated in a future release:
|
||||||
|
/// please use the [CardThemeData.copyWith] instead.
|
||||||
CardTheme copyWith({
|
CardTheme copyWith({
|
||||||
Clip? clipBehavior,
|
Clip? clipBehavior,
|
||||||
Color? color,
|
Color? color,
|
||||||
@ -110,12 +157,19 @@ class CardTheme with Diagnosticable {
|
|||||||
|
|
||||||
/// The [ThemeData.cardTheme] property of the ambient [Theme].
|
/// The [ThemeData.cardTheme] property of the ambient [Theme].
|
||||||
static CardTheme of(BuildContext context) {
|
static CardTheme of(BuildContext context) {
|
||||||
return Theme.of(context).cardTheme;
|
final CardTheme? cardTheme = context.dependOnInheritedWidgetOfExactType<CardTheme>();
|
||||||
|
return cardTheme ?? Theme.of(context).cardTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool updateShouldNotify(CardTheme oldWidget) => data != oldWidget.data;
|
||||||
|
|
||||||
/// Linearly interpolate between two Card themes.
|
/// Linearly interpolate between two Card themes.
|
||||||
///
|
///
|
||||||
/// {@macro dart.ui.shadow.lerp}
|
/// {@macro dart.ui.shadow.lerp}
|
||||||
|
///
|
||||||
|
/// This method is obsolete and will be deprecated in a future release:
|
||||||
|
/// please use the [CardThemeData.lerp] instead.
|
||||||
static CardTheme lerp(CardTheme? a, CardTheme? b, double t) {
|
static CardTheme lerp(CardTheme? a, CardTheme? b, double t) {
|
||||||
if (identical(a, b) && a != null) {
|
if (identical(a, b) && a != null) {
|
||||||
return a;
|
return a;
|
||||||
@ -131,6 +185,112 @@ class CardTheme with Diagnosticable {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
|
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(ColorProperty('surfaceTintColor', surfaceTintColor, 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Defines default property values for descendant [Card] widgets.
|
||||||
|
///
|
||||||
|
/// Descendant widgets obtain the current [CardThemeData] object using
|
||||||
|
/// `CardTheme.of(context)`. Instances of [CardThemeData] can be
|
||||||
|
/// customized with [CardThemeData.copyWith].
|
||||||
|
///
|
||||||
|
/// Typically a [CardThemeData] is specified as part of the overall [Theme]
|
||||||
|
/// with [ThemeData.cardTheme].
|
||||||
|
///
|
||||||
|
/// All [CardThemeData] properties are `null` by default. When null, the [Card]
|
||||||
|
/// will use the values from [ThemeData] if they exist, otherwise it will
|
||||||
|
/// provide its own defaults. See the individual [Card] properties for details.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [ThemeData], which describes the overall theme information for the
|
||||||
|
/// application.
|
||||||
|
@immutable
|
||||||
|
class CardThemeData with Diagnosticable {
|
||||||
|
/// Creates a theme that can be used for [ThemeData.cardTheme].
|
||||||
|
///
|
||||||
|
/// The [elevation] must be null or non-negative.
|
||||||
|
const CardThemeData({
|
||||||
|
this.clipBehavior,
|
||||||
|
this.color,
|
||||||
|
this.shadowColor,
|
||||||
|
this.surfaceTintColor,
|
||||||
|
this.elevation,
|
||||||
|
this.margin,
|
||||||
|
this.shape,
|
||||||
|
}) : assert(elevation == null || elevation >= 0.0);
|
||||||
|
|
||||||
|
/// Overrides the default value for [Card.clipBehavior].
|
||||||
|
final Clip? clipBehavior;
|
||||||
|
|
||||||
|
/// Overrides the default value for [Card.color].
|
||||||
|
final Color? color;
|
||||||
|
|
||||||
|
/// Overrides the default value for [Card.shadowColor].
|
||||||
|
final Color? shadowColor;
|
||||||
|
|
||||||
|
/// Overrides the default value for [Card.surfaceTintColor].
|
||||||
|
final Color? surfaceTintColor;
|
||||||
|
|
||||||
|
/// Overrides the default value for [Card.elevation].
|
||||||
|
final double? elevation;
|
||||||
|
|
||||||
|
/// Overrides the default value for [Card.margin].
|
||||||
|
final EdgeInsetsGeometry? margin;
|
||||||
|
|
||||||
|
/// Overrides the default value for [Card.shape].
|
||||||
|
final ShapeBorder? shape;
|
||||||
|
|
||||||
|
/// Creates a copy of this object with the given fields replaced with the
|
||||||
|
/// new values.
|
||||||
|
CardThemeData copyWith({
|
||||||
|
Clip? clipBehavior,
|
||||||
|
Color? color,
|
||||||
|
Color? shadowColor,
|
||||||
|
Color? surfaceTintColor,
|
||||||
|
double? elevation,
|
||||||
|
EdgeInsetsGeometry? margin,
|
||||||
|
ShapeBorder? shape,
|
||||||
|
}) {
|
||||||
|
return CardThemeData(
|
||||||
|
clipBehavior: clipBehavior ?? this.clipBehavior,
|
||||||
|
color: color ?? this.color,
|
||||||
|
shadowColor: shadowColor ?? this.shadowColor,
|
||||||
|
surfaceTintColor: surfaceTintColor ?? this.surfaceTintColor,
|
||||||
|
elevation: elevation ?? this.elevation,
|
||||||
|
margin: margin ?? this.margin,
|
||||||
|
shape: shape ?? this.shape,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Linearly interpolate between two Card themes.
|
||||||
|
///
|
||||||
|
/// {@macro dart.ui.shadow.lerp}
|
||||||
|
static CardThemeData lerp(CardThemeData? a, CardThemeData? b, double t) {
|
||||||
|
if (identical(a, b) && a != null) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
return CardThemeData(
|
||||||
|
clipBehavior: t < 0.5 ? a?.clipBehavior : b?.clipBehavior,
|
||||||
|
color: Color.lerp(a?.color, b?.color, t),
|
||||||
|
shadowColor: Color.lerp(a?.shadowColor, b?.shadowColor, t),
|
||||||
|
surfaceTintColor: Color.lerp(a?.surfaceTintColor, b?.surfaceTintColor, t),
|
||||||
|
elevation: lerpDouble(a?.elevation, b?.elevation, t),
|
||||||
|
margin: EdgeInsetsGeometry.lerp(a?.margin, b?.margin, t),
|
||||||
|
shape: ShapeBorder.lerp(a?.shape, b?.shape, t),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(
|
||||||
clipBehavior,
|
clipBehavior,
|
||||||
@ -150,14 +310,14 @@ class CardTheme with Diagnosticable {
|
|||||||
if (other.runtimeType != runtimeType) {
|
if (other.runtimeType != runtimeType) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return other is CardTheme
|
return other is CardThemeData
|
||||||
&& other.clipBehavior == clipBehavior
|
&& other.clipBehavior == clipBehavior
|
||||||
&& other.color == color
|
&& other.color == color
|
||||||
&& other.shadowColor == shadowColor
|
&& other.shadowColor == shadowColor
|
||||||
&& other.surfaceTintColor == surfaceTintColor
|
&& other.surfaceTintColor == surfaceTintColor
|
||||||
&& other.elevation == elevation
|
&& other.elevation == elevation
|
||||||
&& other.margin == margin
|
&& other.margin == margin
|
||||||
&& other.shape == shape;
|
&& other.shape == shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -7,19 +7,79 @@
|
|||||||
@Tags(<String>['reduced-test-set'])
|
@Tags(<String>['reduced-test-set'])
|
||||||
library;
|
library;
|
||||||
|
|
||||||
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
test('CardTheme copyWith, ==, hashCode basics', () {
|
test('CardThemeData copyWith, ==, hashCode basics', () {
|
||||||
expect(const CardTheme(), const CardTheme().copyWith());
|
expect(const CardThemeData(), const CardThemeData().copyWith());
|
||||||
expect(const CardTheme().hashCode, const CardTheme().copyWith().hashCode);
|
expect(const CardThemeData().hashCode, const CardThemeData().copyWith().hashCode);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('CardTheme lerp special cases', () {
|
test('CardThemeData lerp special cases', () {
|
||||||
expect(CardTheme.lerp(null, null, 0), const CardTheme());
|
expect(CardThemeData.lerp(null, null, 0), const CardThemeData());
|
||||||
const CardTheme theme = CardTheme();
|
const CardThemeData theme = CardThemeData();
|
||||||
expect(identical(CardTheme.lerp(theme, theme, 0.5), theme), true);
|
expect(identical(CardThemeData.lerp(theme, theme, 0.5), theme), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('CardThemeData defaults', () {
|
||||||
|
const CardThemeData cardThemeData = CardThemeData();
|
||||||
|
|
||||||
|
expect(cardThemeData.clipBehavior, null);
|
||||||
|
expect(cardThemeData.color, null);
|
||||||
|
expect(cardThemeData.elevation, null);
|
||||||
|
expect(cardThemeData.margin, null);
|
||||||
|
expect(cardThemeData.shadowColor, null);
|
||||||
|
expect(cardThemeData.shape, null);
|
||||||
|
expect(cardThemeData.surfaceTintColor, null);
|
||||||
|
|
||||||
|
const CardTheme cardTheme = CardTheme(data: CardThemeData(), child: SizedBox());
|
||||||
|
expect(cardTheme.clipBehavior, null);
|
||||||
|
expect(cardTheme.color, null);
|
||||||
|
expect(cardTheme.elevation, null);
|
||||||
|
expect(cardTheme.margin, null);
|
||||||
|
expect(cardTheme.shadowColor, null);
|
||||||
|
expect(cardTheme.shape, null);
|
||||||
|
expect(cardTheme.surfaceTintColor, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Default CardThemeData debugFillProperties', (WidgetTester tester) async {
|
||||||
|
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
||||||
|
const CardThemeData().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('CardThemeData implements debugFillProperties', (WidgetTester tester) async {
|
||||||
|
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
||||||
|
const CardThemeData(
|
||||||
|
clipBehavior: Clip.antiAlias,
|
||||||
|
color: Colors.amber,
|
||||||
|
elevation: 10.5,
|
||||||
|
margin: EdgeInsets.all(20.5),
|
||||||
|
shadowColor: Colors.green,
|
||||||
|
surfaceTintColor: Colors.purple,
|
||||||
|
shape: BeveledRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(20.5))),
|
||||||
|
).debugFillProperties(builder);
|
||||||
|
|
||||||
|
final List<String> description = builder.properties
|
||||||
|
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
|
||||||
|
.map((DiagnosticsNode node) => node.toString())
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
expect(description[0], 'clipBehavior: Clip.antiAlias');
|
||||||
|
expect(description[1], 'color: MaterialColor(primary value: Color(0xffffc107))');
|
||||||
|
expect(description[2], 'shadowColor: MaterialColor(primary value: Color(0xff4caf50))');
|
||||||
|
expect(description[3], 'surfaceTintColor: MaterialColor(primary value: Color(0xff9c27b0))');
|
||||||
|
expect(description[4], 'elevation: 10.5');
|
||||||
|
expect(description[5], 'margin: EdgeInsets.all(20.5)');
|
||||||
|
expect(description[6], 'shape: BeveledRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.circular(20.5))');
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Material3 - Passing no CardTheme returns defaults', (WidgetTester tester) async {
|
testWidgets('Material3 - Passing no CardTheme returns defaults', (WidgetTester tester) async {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user