Unverified Commit 8866ac65 authored by Rami's avatar Rami Committed by GitHub

[Material You] Introduce large FAB size and allow for FAB size theming (#86441)

parent df3fe587
......@@ -25,9 +25,13 @@ const BoxConstraints _kMiniSizeConstraints = BoxConstraints.tightFor(
height: 40.0,
);
const BoxConstraints _kExtendedSizeConstraints = BoxConstraints(
minHeight: 48.0,
maxHeight: 48.0,
const BoxConstraints _kLargeSizeConstraints = BoxConstraints.tightFor(
width: 96.0,
height: 96.0,
);
const BoxConstraints _kExtendedSizeConstraints = BoxConstraints.tightFor(
height: 48.0,
);
class _DefaultHeroTag {
......@@ -36,6 +40,13 @@ class _DefaultHeroTag {
String toString() => '<default FloatingActionButton tag>';
}
enum _FloatingActionButtonType {
regular,
small,
large,
extended,
}
/// A material design floating action button.
///
/// A floating action button is a circular icon button that hovers over content
......@@ -157,7 +168,101 @@ class FloatingActionButton extends StatelessWidget {
assert(clipBehavior != null),
assert(isExtended != null),
assert(autofocus != null),
_sizeConstraints = mini ? _kMiniSizeConstraints : _kSizeConstraints,
_floatingActionButtonType = mini ? _FloatingActionButtonType.small : _FloatingActionButtonType.regular,
_extendedLabel = null,
extendedIconLabelSpacing = null,
super(key: key);
/// Creates a small circular floating action button.
///
/// This constructor overrides the default size constraints of the floating
/// action button.
///
/// The [clipBehavior] and [autofocus] arguments must not be null.
/// Additionally, [elevation], [focusElevation], [hoverElevation],
/// [highlightElevation], and [disabledElevation] (if specified) must be
/// non-negative.
const FloatingActionButton.small({
Key? key,
this.child,
this.tooltip,
this.foregroundColor,
this.backgroundColor,
this.focusColor,
this.hoverColor,
this.splashColor,
this.heroTag = const _DefaultHeroTag(),
this.elevation,
this.focusElevation,
this.hoverElevation,
this.highlightElevation,
this.disabledElevation,
required this.onPressed,
this.mouseCursor,
this.shape,
this.clipBehavior = Clip.none,
this.focusNode,
this.autofocus = false,
this.materialTapTargetSize,
this.enableFeedback,
}) : assert(elevation == null || elevation >= 0.0),
assert(focusElevation == null || focusElevation >= 0.0),
assert(hoverElevation == null || hoverElevation >= 0.0),
assert(highlightElevation == null || highlightElevation >= 0.0),
assert(disabledElevation == null || disabledElevation >= 0.0),
assert(clipBehavior != null),
assert(autofocus != null),
_floatingActionButtonType = _FloatingActionButtonType.small,
mini = true,
isExtended = false,
_extendedLabel = null,
extendedIconLabelSpacing = null,
super(key: key);
/// Creates a large circular floating action button.
///
/// This constructor overrides the default size constraints of the floating
/// action button.
///
/// The [clipBehavior] and [autofocus] arguments must not be null.
/// Additionally, [elevation], [focusElevation], [hoverElevation],
/// [highlightElevation], and [disabledElevation] (if specified) must be
/// non-negative.
const FloatingActionButton.large({
Key? key,
this.child,
this.tooltip,
this.foregroundColor,
this.backgroundColor,
this.focusColor,
this.hoverColor,
this.splashColor,
this.heroTag = const _DefaultHeroTag(),
this.elevation,
this.focusElevation,
this.hoverElevation,
this.highlightElevation,
this.disabledElevation,
required this.onPressed,
this.mouseCursor,
this.shape,
this.clipBehavior = Clip.none,
this.focusNode,
this.autofocus = false,
this.materialTapTargetSize,
this.enableFeedback,
}) : assert(elevation == null || elevation >= 0.0),
assert(focusElevation == null || focusElevation >= 0.0),
assert(hoverElevation == null || hoverElevation >= 0.0),
assert(highlightElevation == null || highlightElevation >= 0.0),
assert(disabledElevation == null || disabledElevation >= 0.0),
assert(clipBehavior != null),
assert(autofocus != null),
_floatingActionButtonType = _FloatingActionButtonType.large,
mini = false,
isExtended = false,
_extendedLabel = null,
extendedIconLabelSpacing = null,
super(key: key);
/// Creates a wider [StadiumBorder]-shaped floating action button with
......@@ -166,7 +271,7 @@ class FloatingActionButton extends StatelessWidget {
/// The [label], [autofocus], and [clipBehavior] arguments must not be null.
/// Additionally, [elevation], [highlightElevation], and [disabledElevation]
/// (if specified) must be non-negative.
FloatingActionButton.extended({
const FloatingActionButton.extended({
Key? key,
this.tooltip,
this.foregroundColor,
......@@ -188,6 +293,7 @@ class FloatingActionButton extends StatelessWidget {
this.clipBehavior = Clip.none,
this.focusNode,
this.autofocus = false,
this.extendedIconLabelSpacing,
Widget? icon,
required Widget label,
this.enableFeedback,
......@@ -199,30 +305,10 @@ class FloatingActionButton extends StatelessWidget {
assert(isExtended != null),
assert(clipBehavior != null),
assert(autofocus != null),
_sizeConstraints = _kExtendedSizeConstraints,
mini = false,
child = _ChildOverflowBox(
child: Row(
mainAxisSize: MainAxisSize.min,
children: icon == null
? <Widget>[
const SizedBox(width: 20.0),
label,
const SizedBox(width: 20.0),
]
: !isExtended ? <Widget>[
const SizedBox(width: 20.0),
icon,
const SizedBox(width: 20.0),
] : <Widget>[
const SizedBox(width: 16.0),
icon,
const SizedBox(width: 8.0),
label,
const SizedBox(width: 20.0),
],
),
),
_floatingActionButtonType = _FloatingActionButtonType.extended,
child = icon,
_extendedLabel = label,
super(key: key);
/// The widget below this widget in the tree.
......@@ -424,7 +510,17 @@ class FloatingActionButton extends StatelessWidget {
/// * [Feedback] for providing platform-specific feedback to certain actions.
final bool? enableFeedback;
final BoxConstraints _sizeConstraints;
/// The spacing between the icon and the label for an extended
/// [FloatingActionButton].
///
/// If null, [FloatingActionButtonThemeData.extendedIconLabelSpacing] is used.
/// If that is also null, the default is 8.0.
final double? extendedIconLabelSpacing;
final _FloatingActionButtonType _floatingActionButtonType;
final Widget? _extendedLabel;
static const double _defaultElevation = 6;
static const double _defaultFocusElevation = 6;
......@@ -480,6 +576,41 @@ class FloatingActionButton extends StatelessWidget {
?? floatingActionButtonTheme.shape
?? (isExtended ? _defaultExtendedShape : _defaultShape);
BoxConstraints sizeConstraints;
Widget? resolvedChild = child;
switch(_floatingActionButtonType) {
case _FloatingActionButtonType.regular:
sizeConstraints = floatingActionButtonTheme.sizeConstraints ?? _kSizeConstraints;
break;
case _FloatingActionButtonType.small:
sizeConstraints = floatingActionButtonTheme.smallSizeConstraints ?? _kMiniSizeConstraints;
break;
case _FloatingActionButtonType.large:
sizeConstraints = floatingActionButtonTheme.largeSizeConstraints ?? _kLargeSizeConstraints;
// The large FAB uses a larger icon.
resolvedChild = child != null ? IconTheme.merge(
data: const IconThemeData(size: 36.0),
child: child!,
) : child;
break;
case _FloatingActionButtonType.extended:
sizeConstraints = floatingActionButtonTheme.extendedSizeConstraints ?? _kExtendedSizeConstraints;
final double iconLabelSpacing = extendedIconLabelSpacing ?? floatingActionButtonTheme.extendedIconLabelSpacing ?? 8.0;
const Widget width20 = SizedBox(width: 20.0);
const Widget width16 = SizedBox(width: 16.0);
resolvedChild = _ChildOverflowBox(
child: Row(
mainAxisSize: MainAxisSize.min,
children: child == null
? <Widget>[width20, _extendedLabel!, width20]
: isExtended
? <Widget>[width16, child!, SizedBox(width: iconLabelSpacing), _extendedLabel!, width20]
: <Widget>[width20, child!, width20],
),
);
break;
}
Widget result = RawMaterialButton(
onPressed: onPressed,
mouseCursor: mouseCursor,
......@@ -488,7 +619,7 @@ class FloatingActionButton extends StatelessWidget {
hoverElevation: hoverElevation,
highlightElevation: highlightElevation,
disabledElevation: disabledElevation,
constraints: _sizeConstraints,
constraints: sizeConstraints,
materialTapTargetSize: materialTapTargetSize,
fillColor: backgroundColor,
focusColor: focusColor,
......@@ -500,7 +631,7 @@ class FloatingActionButton extends StatelessWidget {
focusNode: focusNode,
autofocus: autofocus,
enableFeedback: enableFeedback,
child: child,
child: resolvedChild,
);
if (tooltip != null) {
......
......@@ -43,6 +43,11 @@ class FloatingActionButtonThemeData with Diagnosticable {
this.highlightElevation,
this.shape,
this.enableFeedback,
this.sizeConstraints,
this.smallSizeConstraints,
this.largeSizeConstraints,
this.extendedSizeConstraints,
this.extendedIconLabelSpacing,
});
/// Color to be used for the unselected, enabled [FloatingActionButton]'s
......@@ -96,6 +101,22 @@ class FloatingActionButtonThemeData with Diagnosticable {
/// ignored.
final bool? enableFeedback;
/// Overrides the default size constraints for the [FloatingActionButton].
final BoxConstraints? sizeConstraints;
/// Overrides the default size constraints for [FloatingActionButton.small].
final BoxConstraints? smallSizeConstraints;
/// Overrides the default size constraints for [FloatingActionButton.large].
final BoxConstraints? largeSizeConstraints;
/// Overrides the default size constraints for [FloatingActionButton.extended].
final BoxConstraints? extendedSizeConstraints;
/// The spacing between the icon and the label for an extended
/// [FloatingActionButton].
final double? extendedIconLabelSpacing;
/// Creates a copy of this object with the given fields replaced with the
/// new values.
FloatingActionButtonThemeData copyWith({
......@@ -111,6 +132,11 @@ class FloatingActionButtonThemeData with Diagnosticable {
double? highlightElevation,
ShapeBorder? shape,
bool? enableFeedback,
BoxConstraints? sizeConstraints,
BoxConstraints? smallSizeConstraints,
BoxConstraints? largeSizeConstraints,
BoxConstraints? extendedSizeConstraints,
double? extendedIconLabelSpacing,
}) {
return FloatingActionButtonThemeData(
foregroundColor: foregroundColor ?? this.foregroundColor,
......@@ -125,6 +151,11 @@ class FloatingActionButtonThemeData with Diagnosticable {
highlightElevation: highlightElevation ?? this.highlightElevation,
shape: shape ?? this.shape,
enableFeedback: enableFeedback ?? this.enableFeedback,
sizeConstraints: sizeConstraints ?? this.sizeConstraints,
smallSizeConstraints: smallSizeConstraints ?? this.smallSizeConstraints,
largeSizeConstraints: largeSizeConstraints ?? this.largeSizeConstraints,
extendedSizeConstraints: extendedSizeConstraints ?? this.extendedSizeConstraints,
extendedIconLabelSpacing: extendedIconLabelSpacing ?? this.extendedIconLabelSpacing,
);
}
......@@ -150,6 +181,11 @@ class FloatingActionButtonThemeData with Diagnosticable {
highlightElevation: lerpDouble(a?.highlightElevation, b?.highlightElevation, t),
shape: ShapeBorder.lerp(a?.shape, b?.shape, t),
enableFeedback: t < 0.5 ? a?.enableFeedback : b?.enableFeedback,
sizeConstraints: BoxConstraints.lerp(a?.sizeConstraints, b?.sizeConstraints, t),
smallSizeConstraints: BoxConstraints.lerp(a?.smallSizeConstraints, b?.smallSizeConstraints, t),
largeSizeConstraints: BoxConstraints.lerp(a?.largeSizeConstraints, b?.largeSizeConstraints, t),
extendedSizeConstraints: BoxConstraints.lerp(a?.extendedSizeConstraints, b?.extendedSizeConstraints, t),
extendedIconLabelSpacing: lerpDouble(a?.extendedIconLabelSpacing, b?.extendedIconLabelSpacing, t),
);
}
......@@ -168,6 +204,11 @@ class FloatingActionButtonThemeData with Diagnosticable {
highlightElevation,
shape,
enableFeedback,
sizeConstraints,
smallSizeConstraints,
largeSizeConstraints,
extendedSizeConstraints,
extendedIconLabelSpacing,
);
}
......@@ -189,25 +230,34 @@ class FloatingActionButtonThemeData with Diagnosticable {
&& other.disabledElevation == disabledElevation
&& other.highlightElevation == highlightElevation
&& other.shape == shape
&& other.enableFeedback == enableFeedback;
&& other.enableFeedback == enableFeedback
&& other.sizeConstraints == sizeConstraints
&& other.smallSizeConstraints == smallSizeConstraints
&& other.largeSizeConstraints == largeSizeConstraints
&& other.extendedSizeConstraints == extendedSizeConstraints
&& other.extendedIconLabelSpacing == extendedIconLabelSpacing;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
const FloatingActionButtonThemeData defaultData = FloatingActionButtonThemeData();
properties.add(ColorProperty('foregroundColor', foregroundColor, defaultValue: defaultData.foregroundColor));
properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: defaultData.backgroundColor));
properties.add(ColorProperty('focusColor', focusColor, defaultValue: defaultData.focusColor));
properties.add(ColorProperty('hoverColor', hoverColor, defaultValue: defaultData.hoverColor));
properties.add(ColorProperty('splashColor', splashColor, defaultValue: defaultData.splashColor));
properties.add(DoubleProperty('elevation', elevation, defaultValue: defaultData.elevation));
properties.add(DoubleProperty('focusElevation', focusElevation, defaultValue: defaultData.focusElevation));
properties.add(DoubleProperty('hoverElevation', hoverElevation, defaultValue: defaultData.hoverElevation));
properties.add(DoubleProperty('disabledElevation', disabledElevation, defaultValue: defaultData.disabledElevation));
properties.add(DoubleProperty('highlightElevation', highlightElevation, defaultValue: defaultData.highlightElevation));
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: defaultData.shape));
properties.add(DiagnosticsProperty<bool>('enableFeedback', enableFeedback, defaultValue: defaultData.enableFeedback));
properties.add(ColorProperty('foregroundColor', foregroundColor, defaultValue: null));
properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: null));
properties.add(ColorProperty('focusColor', focusColor, defaultValue: null));
properties.add(ColorProperty('hoverColor', hoverColor, defaultValue: null));
properties.add(ColorProperty('splashColor', splashColor, defaultValue: null));
properties.add(DoubleProperty('elevation', elevation, defaultValue: null));
properties.add(DoubleProperty('focusElevation', focusElevation, defaultValue: null));
properties.add(DoubleProperty('hoverElevation', hoverElevation, defaultValue: null));
properties.add(DoubleProperty('disabledElevation', disabledElevation, defaultValue: null));
properties.add(DoubleProperty('highlightElevation', highlightElevation, defaultValue: null));
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
properties.add(DiagnosticsProperty<bool>('enableFeedback', enableFeedback, defaultValue: null));
properties.add(DiagnosticsProperty<BoxConstraints>('sizeConstraints', sizeConstraints, defaultValue: null));
properties.add(DiagnosticsProperty<BoxConstraints>('smallSizeConstraints', smallSizeConstraints, defaultValue: null));
properties.add(DiagnosticsProperty<BoxConstraints>('largeSizeConstraints', largeSizeConstraints, defaultValue: null));
properties.add(DiagnosticsProperty<BoxConstraints>('extendedSizeConstraints', extendedSizeConstraints, defaultValue: null));
properties.add(DoubleProperty('extendedIconLabelSpacing', extendedIconLabelSpacing, defaultValue: null));
}
}
......@@ -421,14 +421,14 @@ void main() {
expect(getRawMaterialButtonWidget().shape, const CircleBorder());
await tester.pumpWidget(
MaterialApp(
const MaterialApp(
home: Scaffold(
floatingActionButton: FloatingActionButton.extended(
label: const SizedBox(
label: SizedBox(
width: 100.0,
child: Text('label'),
),
icon: const Icon(Icons.android),
icon: Icon(Icons.android),
onPressed: null,
),
),
......@@ -475,10 +475,10 @@ void main() {
}
await tester.pumpWidget(
MaterialApp(
const MaterialApp(
home: Scaffold(
floatingActionButton: FloatingActionButton.extended(
label: const SizedBox(
label: SizedBox(
width: 100.0,
child: Text('label'),
),
......@@ -965,6 +965,60 @@ void main() {
expect(find.byKey(labelKey), findsNothing);
});
testWidgets('FloatingActionButton.small configures correct size', (WidgetTester tester) async {
final Key key = UniqueKey();
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
floatingActionButton: FloatingActionButton.small(
key: key,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
onPressed: null,
),
),
),
);
expect(tester.getSize(find.byKey(key)), const Size(40.0, 40.0));
});
testWidgets('FloatingActionButton.large configures correct size', (WidgetTester tester) async {
final Key key = UniqueKey();
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
floatingActionButton: FloatingActionButton.large(
key: key,
onPressed: null,
),
),
),
);
expect(tester.getSize(find.byKey(key)), const Size(96.0, 96.0));
});
testWidgets('FloatingActionButton.extended can customize spacing between icon and label', (WidgetTester tester) async {
const Key iconKey = Key('icon');
const Key labelKey = Key('label');
const double spacing = 33.0;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
floatingActionButton: FloatingActionButton.extended(
label: const Text('', key: labelKey),
icon: const Icon(Icons.add, key: iconKey),
extendedIconLabelSpacing: spacing,
onPressed: () {},
),
),
),
);
expect(tester.getTopLeft(find.byKey(labelKey)).dx - tester.getTopRight(find.byKey(iconKey)).dx, spacing);
});
group('feedback', () {
late FeedbackTester feedback;
......
......@@ -32,6 +32,7 @@ void main() {
expect(_getRawMaterialButton(tester).highlightElevation, 12);
expect(_getRawMaterialButton(tester).shape, const CircleBorder());
expect(_getRawMaterialButton(tester).splashColor, ThemeData().splashColor);
expect(_getRawMaterialButton(tester).constraints, const BoxConstraints.tightFor(width: 56.0, height: 56.0));
});
testWidgets('FloatingActionButtonThemeData values are used when no FloatingActionButton properties are specified', (WidgetTester tester) async {
......@@ -42,6 +43,7 @@ void main() {
const double disabledElevation = 1;
const double highlightElevation = 13;
const ShapeBorder shape = StadiumBorder();
const BoxConstraints constraints = BoxConstraints.tightFor(width: 100.0, height: 100.0);
await tester.pumpWidget(MaterialApp(
theme: ThemeData().copyWith(
......@@ -53,6 +55,7 @@ void main() {
disabledElevation: disabledElevation,
highlightElevation: highlightElevation,
shape: shape,
sizeConstraints: constraints,
),
),
home: Scaffold(
......@@ -70,6 +73,7 @@ void main() {
expect(_getRawMaterialButton(tester).highlightElevation, highlightElevation);
expect(_getRawMaterialButton(tester).shape, shape);
expect(_getRawMaterialButton(tester).splashColor, splashColor);
expect(_getRawMaterialButton(tester).constraints, constraints);
});
testWidgets('FloatingActionButton values take priority over FloatingActionButtonThemeData values when both properties are specified', (WidgetTester tester) async {
......@@ -132,6 +136,96 @@ void main() {
expect(_getRawMaterialButton(tester).shape, customShape);
});
testWidgets('FloatingActionButton.small uses custom constraints when specified in the theme', (WidgetTester tester) async {
const BoxConstraints constraints = BoxConstraints.tightFor(width: 100.0, height: 100.0);
await tester.pumpWidget(MaterialApp(
theme: ThemeData().copyWith(
floatingActionButtonTheme: const FloatingActionButtonThemeData(
smallSizeConstraints: constraints,
),
),
home: Scaffold(
floatingActionButton: FloatingActionButton.small(
onPressed: () { },
child: const Icon(Icons.add),
),
),
));
expect(_getRawMaterialButton(tester).constraints, constraints);
});
testWidgets('FloatingActionButton.large uses custom constraints when specified in the theme', (WidgetTester tester) async {
const BoxConstraints constraints = BoxConstraints.tightFor(width: 100.0, height: 100.0);
await tester.pumpWidget(MaterialApp(
theme: ThemeData().copyWith(
floatingActionButtonTheme: const FloatingActionButtonThemeData(
largeSizeConstraints: constraints,
),
),
home: Scaffold(
floatingActionButton: FloatingActionButton.large(
onPressed: () { },
child: const Icon(Icons.add),
),
),
));
expect(_getRawMaterialButton(tester).constraints, constraints);
});
testWidgets('FloatingActionButton.extended uses custom constraints and spacing when specified in the theme', (WidgetTester tester) async {
const Key iconKey = Key('icon');
const Key labelKey = Key('label');
const BoxConstraints constraints = BoxConstraints.tightFor(height: 100.0);
const double spacing = 33.0;
await tester.pumpWidget(MaterialApp(
theme: ThemeData().copyWith(
floatingActionButtonTheme: const FloatingActionButtonThemeData(
extendedSizeConstraints: constraints,
extendedIconLabelSpacing: spacing,
),
),
home: Scaffold(
floatingActionButton: FloatingActionButton.extended(
onPressed: () { },
label: const Text('Extended', key: labelKey),
icon: const Icon(Icons.add, key: iconKey),
),
),
));
expect(_getRawMaterialButton(tester).constraints, constraints);
expect(tester.getTopLeft(find.byKey(labelKey)).dx - tester.getTopRight(find.byKey(iconKey)).dx, spacing);
});
testWidgets('FloatingActionButton.extended spacing takes priority over FloatingActionButtonThemeData spacing', (WidgetTester tester) async {
const Key iconKey = Key('icon');
const Key labelKey = Key('label');
const double spacing = 33.0;
await tester.pumpWidget(MaterialApp(
theme: ThemeData().copyWith(
floatingActionButtonTheme: const FloatingActionButtonThemeData(
extendedIconLabelSpacing: 25.0,
),
),
home: Scaffold(
floatingActionButton: FloatingActionButton.extended(
onPressed: () { },
label: const Text('Extended', key: labelKey),
icon: const Icon(Icons.add, key: iconKey),
extendedIconLabelSpacing: spacing,
),
),
));
expect(tester.getTopLeft(find.byKey(labelKey)).dx - tester.getTopRight(find.byKey(iconKey)).dx, spacing);
});
testWidgets('default FloatingActionButton debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
const FloatingActionButtonThemeData ().debugFillProperties(builder);
......@@ -147,12 +241,23 @@ void main() {
testWidgets('Material implements debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
const FloatingActionButtonThemeData(
backgroundColor: Color(0xCAFECAFE),
foregroundColor: Color(0xFEEDFEED),
backgroundColor: Color(0xCAFECAFE),
focusColor: Color(0xFEEDFEE1),
hoverColor: Color(0xFEEDFEE2),
splashColor: Color(0xFEEDFEE3),
elevation: 23,
focusElevation: 9,
hoverElevation: 10,
disabledElevation: 11,
highlightElevation: 43,
shape: BeveledRectangleBorder(),
enableFeedback: true,
sizeConstraints: BoxConstraints.tightFor(width: 100.0, height: 100.0),
smallSizeConstraints: BoxConstraints.tightFor(width: 101.0, height: 101.0),
largeSizeConstraints: BoxConstraints.tightFor(width: 102.0, height: 102.0),
extendedSizeConstraints: BoxConstraints(minHeight: 103.0, maxHeight: 103.0),
extendedIconLabelSpacing: 12,
).debugFillProperties(builder);
final List<String> description = builder.properties
......@@ -163,10 +268,21 @@ void main() {
expect(description, <String>[
'foregroundColor: Color(0xfeedfeed)',
'backgroundColor: Color(0xcafecafe)',
'focusColor: Color(0xfeedfee1)',
'hoverColor: Color(0xfeedfee2)',
'splashColor: Color(0xfeedfee3)',
'elevation: 23.0',
'focusElevation: 9.0',
'hoverElevation: 10.0',
'disabledElevation: 11.0',
'highlightElevation: 43.0',
'shape: BeveledRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.zero)',
'enableFeedback: true',
'sizeConstraints: BoxConstraints(w=100.0, h=100.0)',
'smallSizeConstraints: BoxConstraints(w=101.0, h=101.0)',
'largeSizeConstraints: BoxConstraints(w=102.0, h=102.0)',
'extendedSizeConstraints: BoxConstraints(0.0<=w<=Infinity, h=103.0)',
'extendedIconLabelSpacing: 12.0'
]);
});
}
......
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