Add ToggleButtons.textStyle property (#38813)
* Add ToggleButtons.textStyle property
This commit is contained in:
@@ -165,6 +165,7 @@ class ToggleButtons extends StatelessWidget {
|
||||
@required this.children,
|
||||
@required this.isSelected,
|
||||
this.onPressed,
|
||||
this.textStyle,
|
||||
this.color,
|
||||
this.selectedColor,
|
||||
this.disabledColor,
|
||||
@@ -215,6 +216,13 @@ class ToggleButtons extends StatelessWidget {
|
||||
/// When the callback is null, all toggle buttons will be disabled.
|
||||
final void Function(int index) onPressed;
|
||||
|
||||
/// The [TextStyle] to apply to any text in these toggle buttons.
|
||||
///
|
||||
/// [TextStyle.color] will be ignored and substituted by [color],
|
||||
/// [selectedColor] or [disabledColor] depending on whether the buttons
|
||||
/// are active, selected, or disabled.
|
||||
final TextStyle textStyle;
|
||||
|
||||
/// The color for descendant [Text] and [Icon] widgets if the button is
|
||||
/// enabled and not selected.
|
||||
///
|
||||
@@ -569,6 +577,7 @@ class ToggleButtons extends StatelessWidget {
|
||||
|
||||
return _ToggleButton(
|
||||
selected: isSelected[index],
|
||||
textStyle: textStyle,
|
||||
color: color,
|
||||
selectedColor: selectedColor,
|
||||
disabledColor: disabledColor,
|
||||
@@ -603,6 +612,7 @@ class ToggleButtons extends StatelessWidget {
|
||||
ifTrue: 'Buttons are disabled',
|
||||
ifFalse: 'Buttons are enabled',
|
||||
));
|
||||
textStyle?.debugFillProperties(properties, prefix: 'textStyle.');
|
||||
properties.add(ColorProperty('color', color, defaultValue: null));
|
||||
properties.add(ColorProperty('selectedColor', selectedColor, defaultValue: null));
|
||||
properties.add(ColorProperty('disabledColor', disabledColor, defaultValue: null));
|
||||
@@ -634,6 +644,7 @@ class _ToggleButton extends StatelessWidget {
|
||||
const _ToggleButton({
|
||||
Key key,
|
||||
this.selected = false,
|
||||
this.textStyle,
|
||||
this.color,
|
||||
this.selectedColor,
|
||||
this.disabledColor,
|
||||
@@ -657,6 +668,9 @@ class _ToggleButton extends StatelessWidget {
|
||||
/// Determines if the button is displayed as active/selected or enabled.
|
||||
final bool selected;
|
||||
|
||||
/// The [TextStyle] to apply to any text that appears in this button.
|
||||
final TextStyle textStyle;
|
||||
|
||||
/// The color for [Text] and [Icon] widgets if the button is enabled.
|
||||
///
|
||||
/// If [selected] is false and [onPressed] is not null, this color will be used.
|
||||
@@ -769,10 +783,12 @@ class _ToggleButton extends StatelessWidget {
|
||||
currentFillColor = theme.colorScheme.surface.withOpacity(0.0);
|
||||
}
|
||||
|
||||
final TextStyle currentTextStyle = textStyle ?? toggleButtonsTheme.textStyle ?? theme.textTheme.body1;
|
||||
|
||||
final Widget result = ClipRRect(
|
||||
borderRadius: clipRadius,
|
||||
child: RawMaterialButton(
|
||||
textStyle: TextStyle(
|
||||
textStyle: currentTextStyle.copyWith(
|
||||
color: currentColor,
|
||||
),
|
||||
elevation: 0.0,
|
||||
|
||||
@@ -28,6 +28,7 @@ class ToggleButtonsThemeData extends Diagnosticable {
|
||||
/// Creates the set of color and border properties used to configure
|
||||
/// [ToggleButtons].
|
||||
const ToggleButtonsThemeData({
|
||||
this.textStyle,
|
||||
this.color,
|
||||
this.selectedColor,
|
||||
this.disabledColor,
|
||||
@@ -43,6 +44,13 @@ class ToggleButtonsThemeData extends Diagnosticable {
|
||||
this.borderWidth,
|
||||
});
|
||||
|
||||
/// The default text style for [ToggleButtons.children].
|
||||
///
|
||||
/// [TextStyle.color] will be ignored and substituted by [color],
|
||||
/// [selectedColor] or [disabledColor] depending on whether the buttons
|
||||
/// are active, selected, or disabled.
|
||||
final TextStyle textStyle;
|
||||
|
||||
/// The color for descendant [Text] and [Icon] widgets if the toggle button
|
||||
/// is enabled.
|
||||
final Color color;
|
||||
@@ -95,6 +103,7 @@ class ToggleButtonsThemeData extends Diagnosticable {
|
||||
/// Creates a copy of this object but with the given fields replaced with the
|
||||
/// new values.
|
||||
ToggleButtonsThemeData copyWith({
|
||||
TextStyle textStyle,
|
||||
Color color,
|
||||
Color selectedColor,
|
||||
Color disabledColor,
|
||||
@@ -110,6 +119,7 @@ class ToggleButtonsThemeData extends Diagnosticable {
|
||||
double borderWidth,
|
||||
}) {
|
||||
return ToggleButtonsThemeData(
|
||||
textStyle: textStyle ?? this.textStyle,
|
||||
color: color ?? this.color,
|
||||
selectedColor: selectedColor ?? this.selectedColor,
|
||||
disabledColor: disabledColor ?? this.disabledColor,
|
||||
@@ -132,6 +142,7 @@ class ToggleButtonsThemeData extends Diagnosticable {
|
||||
if (a == null && b == null)
|
||||
return null;
|
||||
return ToggleButtonsThemeData(
|
||||
textStyle: TextStyle.lerp(a?.textStyle, b?.textStyle, t),
|
||||
color: Color.lerp(a?.color, b?.color, t),
|
||||
selectedColor: Color.lerp(a?.selectedColor, b?.selectedColor, t),
|
||||
disabledColor: Color.lerp(a?.disabledColor, b?.disabledColor, t),
|
||||
@@ -151,6 +162,7 @@ class ToggleButtonsThemeData extends Diagnosticable {
|
||||
@override
|
||||
int get hashCode {
|
||||
return hashValues(
|
||||
textStyle,
|
||||
color,
|
||||
selectedColor,
|
||||
disabledColor,
|
||||
@@ -174,7 +186,8 @@ class ToggleButtonsThemeData extends Diagnosticable {
|
||||
if (other.runtimeType != runtimeType)
|
||||
return false;
|
||||
final ToggleButtonsThemeData typedOther = other;
|
||||
return typedOther.color == color
|
||||
return typedOther.textStyle == textStyle
|
||||
&& typedOther.color == color
|
||||
&& typedOther.selectedColor == selectedColor
|
||||
&& typedOther.disabledColor == disabledColor
|
||||
&& typedOther.fillColor == fillColor
|
||||
@@ -192,6 +205,7 @@ class ToggleButtonsThemeData extends Diagnosticable {
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
textStyle?.debugFillProperties(properties, prefix: 'textStyle.');
|
||||
properties.add(ColorProperty('color', color, defaultValue: null));
|
||||
properties.add(ColorProperty('selectedColor', selectedColor, defaultValue: null));
|
||||
properties.add(ColorProperty('disabledColor', disabledColor, defaultValue: null));
|
||||
|
||||
@@ -250,6 +250,78 @@ void main() {
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets('Default text style is applied', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData();
|
||||
await tester.pumpWidget(
|
||||
Material(
|
||||
child: boilerplate(
|
||||
child: ToggleButtons(
|
||||
isSelected: const <bool>[false, true],
|
||||
onPressed: (int index) {},
|
||||
children: const <Widget>[
|
||||
Text('First child'),
|
||||
Text('Second child'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
TextStyle textStyle;
|
||||
textStyle = tester.widget<DefaultTextStyle>(find.descendant(
|
||||
of: find.widgetWithText(RawMaterialButton, 'First child'),
|
||||
matching: find.byType(DefaultTextStyle),
|
||||
)).style;
|
||||
expect(textStyle.fontFamily, theme.textTheme.body1.fontFamily);
|
||||
expect(textStyle.decoration, theme.textTheme.body1.decoration);
|
||||
|
||||
textStyle = tester.widget<DefaultTextStyle>(find.descendant(
|
||||
of: find.widgetWithText(RawMaterialButton, 'Second child'),
|
||||
matching: find.byType(DefaultTextStyle),
|
||||
)).style;
|
||||
expect(textStyle.fontFamily, theme.textTheme.body1.fontFamily);
|
||||
expect(textStyle.decoration, theme.textTheme.body1.decoration);
|
||||
});
|
||||
|
||||
testWidgets('Custom text style except color is applied', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
Material(
|
||||
child: boilerplate(
|
||||
child: ToggleButtons(
|
||||
isSelected: const <bool>[false, true],
|
||||
onPressed: (int index) {},
|
||||
textStyle: const TextStyle(
|
||||
textBaseline: TextBaseline.ideographic,
|
||||
fontSize: 20.0,
|
||||
color: Colors.orange,
|
||||
),
|
||||
children: const <Widget>[
|
||||
Text('First child'),
|
||||
Text('Second child'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
TextStyle textStyle;
|
||||
textStyle = tester.widget<DefaultTextStyle>(find.descendant(
|
||||
of: find.widgetWithText(RawMaterialButton, 'First child'),
|
||||
matching: find.byType(DefaultTextStyle),
|
||||
)).style;
|
||||
expect(textStyle.textBaseline, TextBaseline.ideographic);
|
||||
expect(textStyle.fontSize, 20.0);
|
||||
expect(textStyle.color, isNot(Colors.orange));
|
||||
|
||||
textStyle = tester.widget<DefaultTextStyle>(find.descendant(
|
||||
of: find.widgetWithText(RawMaterialButton, 'Second child'),
|
||||
matching: find.byType(DefaultTextStyle),
|
||||
)).style;
|
||||
expect(textStyle.textBaseline, TextBaseline.ideographic);
|
||||
expect(textStyle.fontSize, 20.0);
|
||||
expect(textStyle.color, isNot(Colors.orange));
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'Default text/icon colors for enabled, selected and disabled states',
|
||||
(WidgetTester tester) async {
|
||||
|
||||
@@ -24,6 +24,7 @@ void main() {
|
||||
|
||||
test('ToggleButtonsThemeData defaults', () {
|
||||
const ToggleButtonsThemeData themeData = ToggleButtonsThemeData();
|
||||
expect(themeData.textStyle, null);
|
||||
expect(themeData.color, null);
|
||||
expect(themeData.selectedColor, null);
|
||||
expect(themeData.disabledColor, null);
|
||||
@@ -39,6 +40,7 @@ void main() {
|
||||
expect(themeData.borderWidth, null);
|
||||
|
||||
const ToggleButtonsTheme theme = ToggleButtonsTheme(data: ToggleButtonsThemeData());
|
||||
expect(theme.data.textStyle, null);
|
||||
expect(theme.data.color, null);
|
||||
expect(theme.data.selectedColor, null);
|
||||
expect(theme.data.disabledColor, null);
|
||||
@@ -69,6 +71,7 @@ void main() {
|
||||
testWidgets('ToggleButtonsThemeData implements debugFillProperties', (WidgetTester tester) async {
|
||||
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
||||
const ToggleButtonsThemeData(
|
||||
textStyle: TextStyle(fontSize: 10),
|
||||
color: Color(0xfffffff0),
|
||||
selectedColor: Color(0xfffffff1),
|
||||
disabledColor: Color(0xfffffff2),
|
||||
@@ -90,6 +93,8 @@ void main() {
|
||||
.toList();
|
||||
|
||||
expect(description, <String>[
|
||||
'textStyle.inherit: true',
|
||||
'textStyle.size: 10.0',
|
||||
'color: Color(0xfffffff0)',
|
||||
'selectedColor: Color(0xfffffff1)',
|
||||
'disabledColor: Color(0xfffffff2)',
|
||||
@@ -106,6 +111,49 @@ void main() {
|
||||
]);
|
||||
});
|
||||
|
||||
testWidgets('Theme text style, except color, is applied', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
Material(
|
||||
child: boilerplate(
|
||||
child: ToggleButtonsTheme(
|
||||
data: const ToggleButtonsThemeData(
|
||||
textStyle: TextStyle(
|
||||
color: Colors.orange,
|
||||
textBaseline: TextBaseline.ideographic,
|
||||
fontSize: 20.0,
|
||||
),
|
||||
),
|
||||
child: ToggleButtons(
|
||||
isSelected: const <bool>[false, true],
|
||||
onPressed: (int index) {},
|
||||
children: const <Widget>[
|
||||
Text('First child'),
|
||||
Text('Second child'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
TextStyle textStyle;
|
||||
textStyle = tester.widget<DefaultTextStyle>(find.descendant(
|
||||
of: find.widgetWithText(RawMaterialButton, 'First child'),
|
||||
matching: find.byType(DefaultTextStyle),
|
||||
)).style;
|
||||
expect(textStyle.textBaseline, TextBaseline.ideographic);
|
||||
expect(textStyle.fontSize, 20.0);
|
||||
expect(textStyle.color, isNot(Colors.orange));
|
||||
|
||||
textStyle = tester.widget<DefaultTextStyle>(find.descendant(
|
||||
of: find.widgetWithText(RawMaterialButton, 'Second child'),
|
||||
matching: find.byType(DefaultTextStyle),
|
||||
)).style;
|
||||
expect(textStyle.textBaseline, TextBaseline.ideographic);
|
||||
expect(textStyle.fontSize, 20.0);
|
||||
expect(textStyle.color, isNot(Colors.orange));
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'Theme text/icon colors for enabled, selected and disabled states',
|
||||
(WidgetTester tester) async {
|
||||
|
||||
Reference in New Issue
Block a user