Allow for customizing and theming extended FAB's TextStyle (#87498)
This commit is contained in:
parent
22436cca0e
commit
37c414dd8e
@ -172,6 +172,7 @@ class FloatingActionButton extends StatelessWidget {
|
||||
_extendedLabel = null,
|
||||
extendedIconLabelSpacing = null,
|
||||
extendedPadding = null,
|
||||
extendedTextStyle = null,
|
||||
super(key: key);
|
||||
|
||||
/// Creates a small circular floating action button.
|
||||
@ -219,6 +220,7 @@ class FloatingActionButton extends StatelessWidget {
|
||||
_extendedLabel = null,
|
||||
extendedIconLabelSpacing = null,
|
||||
extendedPadding = null,
|
||||
extendedTextStyle = null,
|
||||
super(key: key);
|
||||
|
||||
/// Creates a large circular floating action button.
|
||||
@ -266,6 +268,7 @@ class FloatingActionButton extends StatelessWidget {
|
||||
_extendedLabel = null,
|
||||
extendedIconLabelSpacing = null,
|
||||
extendedPadding = null,
|
||||
extendedTextStyle = null,
|
||||
super(key: key);
|
||||
|
||||
/// Creates a wider [StadiumBorder]-shaped floating action button with
|
||||
@ -298,6 +301,7 @@ class FloatingActionButton extends StatelessWidget {
|
||||
this.autofocus = false,
|
||||
this.extendedIconLabelSpacing,
|
||||
this.extendedPadding,
|
||||
this.extendedTextStyle,
|
||||
Widget? icon,
|
||||
required Widget label,
|
||||
this.enableFeedback,
|
||||
@ -530,6 +534,13 @@ class FloatingActionButton extends StatelessWidget {
|
||||
/// provided, and `EdgeInsetsDirectional.only(start: 20.0, end: 20.0)` if not.
|
||||
final EdgeInsetsGeometry? extendedPadding;
|
||||
|
||||
/// The text style for an extended [FloatingActionButton]'s label.
|
||||
///
|
||||
/// If null, [FloatingActionButtonThemeData.extendedTextStyle] is used. If
|
||||
/// that is also null, then [TextTheme.button] with a letter spacing of 1.2
|
||||
/// is used.
|
||||
final TextStyle? extendedTextStyle;
|
||||
|
||||
final _FloatingActionButtonType _floatingActionButtonType;
|
||||
|
||||
final Widget? _extendedLabel;
|
||||
@ -580,10 +591,9 @@ class FloatingActionButton extends StatelessWidget {
|
||||
?? theme.materialTapTargetSize;
|
||||
final bool enableFeedback = this.enableFeedback
|
||||
?? floatingActionButtonTheme.enableFeedback ?? true;
|
||||
final TextStyle textStyle = theme.textTheme.button!.copyWith(
|
||||
color: foregroundColor,
|
||||
letterSpacing: 1.2,
|
||||
);
|
||||
final TextStyle extendedTextStyle = (this.extendedTextStyle
|
||||
?? floatingActionButtonTheme.extendedTextStyle
|
||||
?? theme.textTheme.button!.copyWith(letterSpacing: 1.2)).copyWith(color: foregroundColor);
|
||||
final ShapeBorder shape = this.shape
|
||||
?? floatingActionButtonTheme.shape
|
||||
?? (isExtended ? _defaultExtendedShape : _defaultShape);
|
||||
@ -644,7 +654,7 @@ class FloatingActionButton extends StatelessWidget {
|
||||
focusColor: focusColor,
|
||||
hoverColor: hoverColor,
|
||||
splashColor: splashColor,
|
||||
textStyle: textStyle,
|
||||
textStyle: extendedTextStyle,
|
||||
shape: shape,
|
||||
clipBehavior: clipBehavior,
|
||||
focusNode: focusNode,
|
||||
|
@ -49,6 +49,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
|
||||
this.extendedSizeConstraints,
|
||||
this.extendedIconLabelSpacing,
|
||||
this.extendedPadding,
|
||||
this.extendedTextStyle,
|
||||
});
|
||||
|
||||
/// Color to be used for the unselected, enabled [FloatingActionButton]'s
|
||||
@ -121,6 +122,9 @@ class FloatingActionButtonThemeData with Diagnosticable {
|
||||
/// The padding for an extended [FloatingActionButton]'s content.
|
||||
final EdgeInsetsGeometry? extendedPadding;
|
||||
|
||||
/// The text style for an extended [FloatingActionButton]'s label.
|
||||
final TextStyle? extendedTextStyle;
|
||||
|
||||
/// Creates a copy of this object with the given fields replaced with the
|
||||
/// new values.
|
||||
FloatingActionButtonThemeData copyWith({
|
||||
@ -142,6 +146,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
|
||||
BoxConstraints? extendedSizeConstraints,
|
||||
double? extendedIconLabelSpacing,
|
||||
EdgeInsetsGeometry? extendedPadding,
|
||||
TextStyle? extendedTextStyle,
|
||||
}) {
|
||||
return FloatingActionButtonThemeData(
|
||||
foregroundColor: foregroundColor ?? this.foregroundColor,
|
||||
@ -162,6 +167,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
|
||||
extendedSizeConstraints: extendedSizeConstraints ?? this.extendedSizeConstraints,
|
||||
extendedIconLabelSpacing: extendedIconLabelSpacing ?? this.extendedIconLabelSpacing,
|
||||
extendedPadding: extendedPadding ?? this.extendedPadding,
|
||||
extendedTextStyle: extendedTextStyle ?? this.extendedTextStyle,
|
||||
);
|
||||
}
|
||||
|
||||
@ -193,6 +199,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
|
||||
extendedSizeConstraints: BoxConstraints.lerp(a?.extendedSizeConstraints, b?.extendedSizeConstraints, t),
|
||||
extendedIconLabelSpacing: lerpDouble(a?.extendedIconLabelSpacing, b?.extendedIconLabelSpacing, t),
|
||||
extendedPadding: EdgeInsetsGeometry.lerp(a?.extendedPadding, b?.extendedPadding, t),
|
||||
extendedTextStyle: TextStyle.lerp(a?.extendedTextStyle, b?.extendedTextStyle, t),
|
||||
);
|
||||
}
|
||||
|
||||
@ -217,6 +224,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
|
||||
extendedSizeConstraints,
|
||||
extendedIconLabelSpacing,
|
||||
extendedPadding,
|
||||
extendedTextStyle,
|
||||
);
|
||||
}
|
||||
|
||||
@ -244,7 +252,8 @@ class FloatingActionButtonThemeData with Diagnosticable {
|
||||
&& other.largeSizeConstraints == largeSizeConstraints
|
||||
&& other.extendedSizeConstraints == extendedSizeConstraints
|
||||
&& other.extendedIconLabelSpacing == extendedIconLabelSpacing
|
||||
&& other.extendedPadding == extendedPadding;
|
||||
&& other.extendedPadding == extendedPadding
|
||||
&& other.extendedTextStyle == extendedTextStyle;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -269,5 +278,6 @@ class FloatingActionButtonThemeData with Diagnosticable {
|
||||
properties.add(DiagnosticsProperty<BoxConstraints>('extendedSizeConstraints', extendedSizeConstraints, defaultValue: null));
|
||||
properties.add(DoubleProperty('extendedIconLabelSpacing', extendedIconLabelSpacing, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('extendedPadding', extendedPadding, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<TextStyle>('extendedTextStyle', extendedTextStyle, defaultValue: null));
|
||||
}
|
||||
}
|
||||
|
@ -1023,6 +1023,33 @@ void main() {
|
||||
expect(tester.getTopRight(find.byType(FloatingActionButton)).dx - tester.getTopRight(find.byKey(labelKey)).dx, padding.end);
|
||||
});
|
||||
|
||||
testWidgets('FloatingActionButton.extended can customize text style', (WidgetTester tester) async {
|
||||
const Key labelKey = Key('label');
|
||||
const TextStyle style = TextStyle(letterSpacing: 2.0);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
label: const Text('', key: labelKey),
|
||||
icon: const Icon(Icons.add),
|
||||
extendedTextStyle: style,
|
||||
onPressed: () {},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final RawMaterialButton rawMaterialButton = tester.widget<RawMaterialButton>(
|
||||
find.descendant(
|
||||
of: find.byType(FloatingActionButton),
|
||||
matching: find.byType(RawMaterialButton),
|
||||
),
|
||||
);
|
||||
// The color comes from the default color scheme's onSecondary value.
|
||||
expect(rawMaterialButton.textStyle, style.copyWith(color: const Color(0xffffffff)));
|
||||
});
|
||||
|
||||
group('feedback', () {
|
||||
late FeedbackTester feedback;
|
||||
|
||||
|
@ -176,12 +176,13 @@ void main() {
|
||||
expect(_getRawMaterialButton(tester).constraints, constraints);
|
||||
});
|
||||
|
||||
testWidgets('FloatingActionButton.extended uses custom constraints and spacing when specified in the theme', (WidgetTester tester) async {
|
||||
testWidgets('FloatingActionButton.extended uses custom properties 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 iconLabelSpacing = 33.0;
|
||||
const EdgeInsetsDirectional padding = EdgeInsetsDirectional.only(start: 5.0, end: 6.0);
|
||||
const TextStyle textStyle = TextStyle(letterSpacing: 2.0);
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData().copyWith(
|
||||
@ -189,6 +190,7 @@ void main() {
|
||||
extendedSizeConstraints: constraints,
|
||||
extendedIconLabelSpacing: iconLabelSpacing,
|
||||
extendedPadding: padding,
|
||||
extendedTextStyle: textStyle,
|
||||
),
|
||||
),
|
||||
home: Scaffold(
|
||||
@ -204,19 +206,23 @@ void main() {
|
||||
expect(tester.getTopLeft(find.byKey(labelKey)).dx - tester.getTopRight(find.byKey(iconKey)).dx, iconLabelSpacing);
|
||||
expect(tester.getTopLeft(find.byKey(iconKey)).dx - tester.getTopLeft(find.byType(FloatingActionButton)).dx, padding.start);
|
||||
expect(tester.getTopRight(find.byType(FloatingActionButton)).dx - tester.getTopRight(find.byKey(labelKey)).dx, padding.end);
|
||||
// The color comes from the default color scheme's onSecondary value.
|
||||
expect(_getRawMaterialButton(tester).textStyle, textStyle.copyWith(color: const Color(0xffffffff)));
|
||||
});
|
||||
|
||||
testWidgets('FloatingActionButton.extended spacing takes priority over FloatingActionButtonThemeData spacing', (WidgetTester tester) async {
|
||||
testWidgets('FloatingActionButton.extended custom properties takes priority over FloatingActionButtonThemeData spacing', (WidgetTester tester) async {
|
||||
const Key iconKey = Key('icon');
|
||||
const Key labelKey = Key('label');
|
||||
const double iconLabelSpacing = 33.0;
|
||||
const EdgeInsetsDirectional padding = EdgeInsetsDirectional.only(start: 5.0, end: 6.0);
|
||||
const TextStyle textStyle = TextStyle(letterSpacing: 2.0);
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData().copyWith(
|
||||
floatingActionButtonTheme: const FloatingActionButtonThemeData(
|
||||
extendedIconLabelSpacing: 25.0,
|
||||
extendedPadding: EdgeInsetsDirectional.only(start: 7.0, end: 8.0),
|
||||
extendedTextStyle: TextStyle(letterSpacing: 3.0),
|
||||
),
|
||||
),
|
||||
home: Scaffold(
|
||||
@ -226,6 +232,7 @@ void main() {
|
||||
icon: const Icon(Icons.add, key: iconKey),
|
||||
extendedIconLabelSpacing: iconLabelSpacing,
|
||||
extendedPadding: padding,
|
||||
extendedTextStyle: textStyle,
|
||||
),
|
||||
),
|
||||
));
|
||||
@ -233,6 +240,8 @@ void main() {
|
||||
expect(tester.getTopLeft(find.byKey(labelKey)).dx - tester.getTopRight(find.byKey(iconKey)).dx, iconLabelSpacing);
|
||||
expect(tester.getTopLeft(find.byKey(iconKey)).dx - tester.getTopLeft(find.byType(FloatingActionButton)).dx, padding.start);
|
||||
expect(tester.getTopRight(find.byType(FloatingActionButton)).dx - tester.getTopRight(find.byKey(labelKey)).dx, padding.end);
|
||||
// The color comes from the default color scheme's onSecondary value.
|
||||
expect(_getRawMaterialButton(tester).textStyle, textStyle.copyWith(color: const Color(0xffffffff)));
|
||||
});
|
||||
|
||||
testWidgets('default FloatingActionButton debugFillProperties', (WidgetTester tester) async {
|
||||
@ -268,6 +277,7 @@ void main() {
|
||||
extendedSizeConstraints: BoxConstraints(minHeight: 103.0, maxHeight: 103.0),
|
||||
extendedIconLabelSpacing: 12,
|
||||
extendedPadding: EdgeInsetsDirectional.only(start: 7.0, end: 8.0),
|
||||
extendedTextStyle: TextStyle(letterSpacing: 2.0),
|
||||
).debugFillProperties(builder);
|
||||
|
||||
final List<String> description = builder.properties
|
||||
@ -294,6 +304,7 @@ void main() {
|
||||
'extendedSizeConstraints: BoxConstraints(0.0<=w<=Infinity, h=103.0)',
|
||||
'extendedIconLabelSpacing: 12.0',
|
||||
'extendedPadding: EdgeInsetsDirectional(7.0, 0.0, 8.0, 0.0)',
|
||||
'extendedTextStyle: TextStyle(inherit: true, letterSpacing: 2.0)',
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user