Unverified Commit b1146549 authored by Qun Cheng's avatar Qun Cheng Committed by GitHub

Add `IconButton.filled`, `IconButton.filledTonal`, `IconButton.outlined` (#121884)

parent 7979d8eb
...@@ -158,7 +158,10 @@ Future<void> main(List<String> args) async { ...@@ -158,7 +158,10 @@ Future<void> main(List<String> args) async {
FABTemplate('FAB', '$materialLib/floating_action_button.dart', tokens).updateFile(); FABTemplate('FAB', '$materialLib/floating_action_button.dart', tokens).updateFile();
FilterChipTemplate('ChoiceChip', '$materialLib/choice_chip.dart', tokens).updateFile(); FilterChipTemplate('ChoiceChip', '$materialLib/choice_chip.dart', tokens).updateFile();
FilterChipTemplate('FilterChip', '$materialLib/filter_chip.dart', tokens).updateFile(); FilterChipTemplate('FilterChip', '$materialLib/filter_chip.dart', tokens).updateFile();
IconButtonTemplate('IconButton', '$materialLib/icon_button.dart', tokens).updateFile(); IconButtonTemplate('md.comp.icon-button', 'IconButton', '$materialLib/icon_button.dart', tokens).updateFile();
IconButtonTemplate('md.comp.filled-icon-button', 'FilledIconButton', '$materialLib/icon_button.dart', tokens).updateFile();
IconButtonTemplate('md.comp.filled-tonal-icon-button', 'FilledTonalIconButton', '$materialLib/icon_button.dart', tokens).updateFile();
IconButtonTemplate('md.comp.outlined-icon-button', 'OutlinedIconButton', '$materialLib/icon_button.dart', tokens).updateFile();
InputChipTemplate('InputChip', '$materialLib/input_chip.dart', tokens).updateFile(); InputChipTemplate('InputChip', '$materialLib/input_chip.dart', tokens).updateFile();
ListTileTemplate('LisTile', '$materialLib/list_tile.dart', tokens).updateFile(); ListTileTemplate('LisTile', '$materialLib/list_tile.dart', tokens).updateFile();
InputDecoratorTemplate('InputDecorator', '$materialLib/input_decorator.dart', tokens).updateFile(); InputDecoratorTemplate('InputDecorator', '$materialLib/input_decorator.dart', tokens).updateFile();
......
...@@ -52,7 +52,6 @@ class ButtonTypesGroup extends StatelessWidget { ...@@ -52,7 +52,6 @@ class ButtonTypesGroup extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final VoidCallback? onPressed = enabled ? () {} : null; final VoidCallback? onPressed = enabled ? () {} : null;
final ColorScheme colors = Theme.of(context).colorScheme;
return Padding( return Padding(
padding: const EdgeInsets.all(4.0), padding: const EdgeInsets.all(4.0),
...@@ -61,56 +60,14 @@ class ButtonTypesGroup extends StatelessWidget { ...@@ -61,56 +60,14 @@ class ButtonTypesGroup extends StatelessWidget {
children: <Widget>[ children: <Widget>[
IconButton(icon: const Icon(Icons.filter_drama), onPressed: onPressed), IconButton(icon: const Icon(Icons.filter_drama), onPressed: onPressed),
// Use a standard IconButton with specific style to implement the // Filled icon button
// 'Filled' type. IconButton.filled(onPressed: onPressed, icon: const Icon(Icons.filter_drama)),
IconButton(
icon: const Icon(Icons.filter_drama),
onPressed: onPressed,
style: IconButton.styleFrom(
foregroundColor: colors.onPrimary,
backgroundColor: colors.primary,
disabledBackgroundColor: colors.onSurface.withOpacity(0.12),
hoverColor: colors.onPrimary.withOpacity(0.08),
focusColor: colors.onPrimary.withOpacity(0.12),
highlightColor: colors.onPrimary.withOpacity(0.12),
)
),
// Use a standard IconButton with specific style to implement the // Filled tonal icon button
// 'Filled Tonal' type. IconButton.filledTonal(onPressed: onPressed, icon: const Icon(Icons.filter_drama)),
IconButton(
icon: const Icon(Icons.filter_drama),
onPressed: onPressed,
style: IconButton.styleFrom(
foregroundColor: colors.onSecondaryContainer,
backgroundColor: colors.secondaryContainer,
disabledBackgroundColor: colors.onSurface.withOpacity(0.12),
hoverColor: colors.onSecondaryContainer.withOpacity(0.08),
focusColor: colors.onSecondaryContainer.withOpacity(0.12),
highlightColor: colors.onSecondaryContainer.withOpacity(0.12),
),
),
// Use a standard IconButton with specific style to implement the // Outlined icon button
// 'Outlined' type. IconButton.outlined(onPressed: onPressed, icon: const Icon(Icons.filter_drama)),
IconButton(
icon: const Icon(Icons.filter_drama),
onPressed: onPressed,
style: IconButton.styleFrom(
focusColor: colors.onSurfaceVariant.withOpacity(0.12),
highlightColor: colors.onSurface.withOpacity(0.12),
side: onPressed == null
? BorderSide(color: Theme.of(context).colorScheme.onSurface.withOpacity(0.12))
: BorderSide(color: colors.outline),
).copyWith(
foregroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.pressed)) {
return colors.onSurface;
}
return null;
}),
),
),
], ],
), ),
); );
......
...@@ -36,153 +36,105 @@ class DemoIconToggleButtons extends StatefulWidget { ...@@ -36,153 +36,105 @@ class DemoIconToggleButtons extends StatefulWidget {
} }
class _DemoIconToggleButtonsState extends State<DemoIconToggleButtons> { class _DemoIconToggleButtonsState extends State<DemoIconToggleButtons> {
@override bool standardSelected = false;
Widget build(BuildContext context) { bool filledSelected = false;
return const Padding( bool tonalSelected = false;
padding: EdgeInsets.all(8.0), bool outlinedSelected = false;
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
// Standard IconButton
children: <Widget>[
DemoIconToggleButton(isEnabled: true),
SizedBox(width: 10),
DemoIconToggleButton(isEnabled: false),
]
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// Filled IconButton
DemoIconToggleButton(isEnabled: true, getDefaultStyle: enabledFilledButtonStyle,),
SizedBox(width: 10),
DemoIconToggleButton(isEnabled: false, getDefaultStyle: disabledFilledButtonStyle,)
]
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// Filled Tonal IconButton
DemoIconToggleButton(isEnabled: true, getDefaultStyle: enabledFilledTonalButtonStyle,),
SizedBox(width: 10),
DemoIconToggleButton(isEnabled: false, getDefaultStyle: disabledFilledTonalButtonStyle,),
]
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// Outlined IconButton
DemoIconToggleButton(isEnabled: true, getDefaultStyle: enabledOutlinedButtonStyle,),
SizedBox(width: 10),
DemoIconToggleButton(isEnabled: false, getDefaultStyle: disabledOutlinedButtonStyle,),
]
),
]
),
);
}
}
class DemoIconToggleButton extends StatefulWidget {
const DemoIconToggleButton({required this.isEnabled, this.getDefaultStyle, super.key});
final bool isEnabled;
final ButtonStyle? Function(bool, ColorScheme)? getDefaultStyle;
@override
State<DemoIconToggleButton> createState() => _DemoIconToggleButtonState();
}
class _DemoIconToggleButtonState extends State<DemoIconToggleButton> {
bool selected = false;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ColorScheme colors = Theme.of(context).colorScheme; return Column(
final VoidCallback? onPressed = widget.isEnabled mainAxisAlignment: MainAxisAlignment.spaceEvenly,
? () { children: <Widget>[
setState(() { Row(
selected = !selected; mainAxisAlignment: MainAxisAlignment.center,
}); children: <Widget>[
} IconButton(
: null; isSelected: standardSelected,
ButtonStyle? style; icon: const Icon(Icons.settings_outlined),
if (widget.getDefaultStyle != null) { selectedIcon: const Icon(Icons.settings),
style = widget.getDefaultStyle!(selected, colors); onPressed: () {
} setState(() {
standardSelected = !standardSelected;
return IconButton( });
isSelected: selected, },
icon: const Icon(Icons.settings_outlined), ),
selectedIcon: const Icon(Icons.settings), const SizedBox(width: 10),
onPressed: onPressed, IconButton(
style: style, isSelected: standardSelected,
icon: const Icon(Icons.settings_outlined),
selectedIcon: const Icon(Icons.settings),
onPressed: null,
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
IconButton.filled(
isSelected: filledSelected,
icon: const Icon(Icons.settings_outlined),
selectedIcon: const Icon(Icons.settings),
onPressed: () {
setState(() {
filledSelected = !filledSelected;
});
},
),
const SizedBox(width: 10),
IconButton.filled(
isSelected: filledSelected,
icon: const Icon(Icons.settings_outlined),
selectedIcon: const Icon(Icons.settings),
onPressed: null,
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
IconButton.filledTonal(
isSelected: tonalSelected,
icon: const Icon(Icons.settings_outlined),
selectedIcon: const Icon(Icons.settings),
onPressed: () {
setState(() {
tonalSelected = !tonalSelected;
});
},
),
const SizedBox(width: 10),
IconButton.filledTonal(
isSelected: tonalSelected,
icon: const Icon(Icons.settings_outlined),
selectedIcon: const Icon(Icons.settings),
onPressed: null,
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
IconButton.outlined(
isSelected: outlinedSelected,
icon: const Icon(Icons.settings_outlined),
selectedIcon: const Icon(Icons.settings),
onPressed: () {
setState(() {
outlinedSelected = !outlinedSelected;
});
},
),
const SizedBox(width: 10),
IconButton.outlined(
isSelected: outlinedSelected,
icon: const Icon(Icons.settings_outlined),
selectedIcon: const Icon(Icons.settings),
onPressed: null,
),
],
),
]
); );
} }
} }
ButtonStyle enabledFilledButtonStyle(bool selected, ColorScheme colors) {
return IconButton.styleFrom(
foregroundColor: selected ? colors.onPrimary : colors.primary,
backgroundColor: selected ? colors.primary : colors.surfaceVariant,
disabledForegroundColor: colors.onSurface.withOpacity(0.38),
disabledBackgroundColor: colors.onSurface.withOpacity(0.12),
hoverColor: selected ? colors.onPrimary.withOpacity(0.08) : colors.primary.withOpacity(0.08),
focusColor: selected ? colors.onPrimary.withOpacity(0.12) : colors.primary.withOpacity(0.12),
highlightColor: selected ? colors.onPrimary.withOpacity(0.12) : colors.primary.withOpacity(0.12),
);
}
ButtonStyle disabledFilledButtonStyle(bool selected, ColorScheme colors) {
return IconButton.styleFrom(
disabledForegroundColor: colors.onSurface.withOpacity(0.38),
disabledBackgroundColor: colors.onSurface.withOpacity(0.12),
);
}
ButtonStyle enabledFilledTonalButtonStyle(bool selected, ColorScheme colors) {
return IconButton.styleFrom(
foregroundColor: selected ? colors.onSecondaryContainer : colors.onSurfaceVariant,
backgroundColor: selected ? colors.secondaryContainer : colors.surfaceVariant,
hoverColor: selected ? colors.onSecondaryContainer.withOpacity(0.08) : colors.onSurfaceVariant.withOpacity(0.08),
focusColor: selected ? colors.onSecondaryContainer.withOpacity(0.12) : colors.onSurfaceVariant.withOpacity(0.12),
highlightColor: selected ? colors.onSecondaryContainer.withOpacity(0.12) : colors.onSurfaceVariant.withOpacity(0.12),
);
}
ButtonStyle disabledFilledTonalButtonStyle(bool selected, ColorScheme colors) {
return IconButton.styleFrom(
disabledForegroundColor: colors.onSurface.withOpacity(0.38),
disabledBackgroundColor: colors.onSurface.withOpacity(0.12),
);
}
ButtonStyle enabledOutlinedButtonStyle(bool selected, ColorScheme colors) {
return IconButton.styleFrom(
backgroundColor: selected ? colors.inverseSurface : null,
hoverColor: selected ? colors.onInverseSurface.withOpacity(0.08) : colors.onSurfaceVariant.withOpacity(0.08),
focusColor: selected ? colors.onInverseSurface.withOpacity(0.12) : colors.onSurfaceVariant.withOpacity(0.12),
highlightColor: selected ? colors.onInverseSurface.withOpacity(0.12) : colors.onSurface.withOpacity(0.12),
side: BorderSide(color: colors.outline),
).copyWith(
foregroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
return colors.onInverseSurface;
}
if (states.contains(MaterialState.pressed)) {
return colors.onSurface;
}
return null;
}),
);
}
ButtonStyle disabledOutlinedButtonStyle(bool selected, ColorScheme colors) {
return IconButton.styleFrom(
disabledForegroundColor: colors.onSurface.withOpacity(0.38),
disabledBackgroundColor: selected ? colors.onSurface.withOpacity(0.12) : null,
side: selected ? null : BorderSide(color: colors.outline.withOpacity(0.12)),
);
}
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