Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
b1146549
Unverified
Commit
b1146549
authored
Mar 04, 2023
by
Qun Cheng
Committed by
GitHub
Mar 04, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add `IconButton.filled`, `IconButton.filledTonal`, `IconButton.outlined` (#121884)
parent
7979d8eb
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1511 additions
and
249 deletions
+1511
-249
gen_defaults.dart
dev/tools/gen_defaults/bin/gen_defaults.dart
+4
-1
icon_button_template.dart
dev/tools/gen_defaults/lib/icon_button_template.dart
+229
-46
icon_button.2.dart
examples/api/lib/material/icon_button/icon_button.2.dart
+6
-49
icon_button.3.dart
examples/api/lib/material/icon_button/icon_button.3.dart
+96
-144
icon_button.dart
packages/flutter/lib/src/material/icon_button.dart
+573
-9
icon_button_test.dart
packages/flutter/test/material/icon_button_test.dart
+603
-0
No files found.
dev/tools/gen_defaults/bin/gen_defaults.dart
View file @
b1146549
...
@@ -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
();
...
...
dev/tools/gen_defaults/lib/icon_button_template.dart
View file @
b1146549
...
@@ -5,75 +5,259 @@
...
@@ -5,75 +5,259 @@
import
'template.dart'
;
import
'template.dart'
;
class
IconButtonTemplate
extends
TokenTemplate
{
class
IconButtonTemplate
extends
TokenTemplate
{
const
IconButtonTemplate
(
super
.
blockName
,
super
.
fileName
,
super
.
tokens
,
{
const
IconButtonTemplate
(
this
.
tokenGroup
,
super
.
blockName
,
super
.
fileName
,
super
.
tokens
,
{
super
.
colorSchemePrefix
=
'_colors.'
,
super
.
colorSchemePrefix
=
'_colors.'
,
});
});
final
String
tokenGroup
;
String
_elevationColor
(
String
token
)
{
String
_backgroundColor
()
{
if
(
tokens
.
containsKey
(
token
))
{
switch
(
tokenGroup
)
{
return
'MaterialStatePropertyAll<Color>(
${color(token)}
)'
;
case
'md.comp.filled-icon-button'
:
}
else
{
case
'md.comp.filled-tonal-icon-button'
:
return
'const MaterialStatePropertyAll<Color>(Colors.transparent)'
;
return
'''
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return
${componentColor('$tokenGroup.disabled.container')}
;
}
if (states.contains(MaterialState.selected)) {
return
${componentColor('$tokenGroup.selected.container')}
;
}
}
if (toggleable) { // toggleable but unselected case
return
${componentColor('$tokenGroup.unselected.container')}
;
}
}
return
${componentColor('$tokenGroup.container')}
;
})'''
;
case
'md.comp.outlined-icon-button'
:
return
'''
@override
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
String
generate
()
=>
'''
if (states.contains(MaterialState.disabled)) {
class _
${blockName}
DefaultsM3 extends ButtonStyle {
if (states.contains(MaterialState.selected)) {
_
${blockName}
DefaultsM3(this.context)
return
${componentColor('$tokenGroup.disabled.selected.container')}
;
: super(
}
animationDuration: kThemeChangeDuration,
return Colors.transparent;
enableFeedback: true,
}
alignment: Alignment.center,
if (states.contains(MaterialState.selected)) {
);
return
${componentColor('$tokenGroup.selected.container')}
;
}
return Colors.transparent;
})'''
;
}
return
'''
final BuildContext context
;
const MaterialStatePropertyAll<Color?>(Colors.transparent)'''
;
late final ColorScheme _colors = Theme.of(context).colorScheme;
}
// No default text style
String
_foregroundColor
()
{
switch
(
tokenGroup
)
{
case
'md.comp.filled-icon-button'
:
case
'md.comp.filled-tonal-icon-button'
:
return
'''
@override
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
MaterialStateProperty<Color?>? get backgroundColor =>
if (states.contains(MaterialState.disabled)) {
const MaterialStatePropertyAll<Color?>(Colors.transparent);
return
${componentColor('$tokenGroup.disabled.icon')}
;
}
if (states.contains(MaterialState.selected)) {
return
${componentColor('$tokenGroup.toggle.selected.icon')}
;
}
if (toggleable) { // toggleable but unselected case
return
${componentColor('$tokenGroup.toggle.unselected.icon')}
;
}
return
${componentColor('$tokenGroup.icon')}
;
})'''
;
case
'md.comp.outlined-icon-button'
:
case
'md.comp.icon-button'
:
return
'''
@override
MaterialStateProperty<Color?>? get foregroundColor =>
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
if (states.contains(MaterialState.disabled)) {
return
${componentColor('
md.comp.icon-button
.disabled.icon')}
;
return
${componentColor('
$tokenGroup
.disabled.icon')}
;
}
}
if (states.contains(MaterialState.selected)) {
if (states.contains(MaterialState.selected)) {
return
${componentColor('
md.comp.icon-button
.selected.icon')}
;
return
${componentColor('
$tokenGroup
.selected.icon')}
;
}
}
return
${componentColor('md.comp.icon-button.unselected.icon')}
;
return
${componentColor('$tokenGroup.unselected.icon')}
;
});
})'''
;
}
return
'''
@override
const MaterialStatePropertyAll<Color?>(Colors.transparent)'''
;
MaterialStateProperty<Color?>? get overlayColor =>
}
String
_overlayColor
()
{
switch
(
tokenGroup
)
{
case
'md.comp.filled-icon-button'
:
case
'md.comp.filled-tonal-icon-button'
:
return
'''
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
if (states.contains(MaterialState.hovered)) {
return
${componentColor('$tokenGroup.toggle.selected.hover.state-layer')}
.withOpacity(
${opacity('$tokenGroup.hover.state-layer.opacity')}
);
}
if (states.contains(MaterialState.focused)) {
return
${componentColor('$tokenGroup.toggle.selected.focus.state-layer')}
.withOpacity(
${opacity('$tokenGroup.focus.state-layer.opacity')}
);
}
if (states.contains(MaterialState.pressed)) {
return
${componentColor('$tokenGroup.toggle.selected.pressed.state-layer')}
.withOpacity(
${opacity('$tokenGroup.pressed.state-layer.opacity')}
);
}
}
if (toggleable) { // toggleable but unselected case
if (states.contains(MaterialState.hovered)) {
return
${componentColor('$tokenGroup.toggle.unselected.hover.state-layer')}
.withOpacity(
${opacity('$tokenGroup.hover.state-layer.opacity')}
);
}
if (states.contains(MaterialState.focused)) {
return
${componentColor('$tokenGroup.toggle.unselected.focus.state-layer')}
.withOpacity(
${opacity('$tokenGroup.focus.state-layer.opacity')}
);
}
if (states.contains(MaterialState.pressed)) {
return
${componentColor('$tokenGroup.toggle.unselected.pressed.state-layer')}
.withOpacity(
${opacity('$tokenGroup.pressed.state-layer.opacity')}
);
}
}
if (states.contains(MaterialState.hovered)) {
return
${componentColor('$tokenGroup.hover.state-layer')}
;
}
if (states.contains(MaterialState.focused)) {
return
${componentColor('$tokenGroup.focus.state-layer')}
;
}
if (states.contains(MaterialState.pressed)) {
return
${componentColor('$tokenGroup.pressed.state-layer')}
;
}
return Colors.transparent;
})'''
;
case
'md.comp.outlined-icon-button'
:
return
'''
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
if (states.contains(MaterialState.selected)) {
if (states.contains(MaterialState.hovered)) {
if (states.contains(MaterialState.hovered)) {
return
${componentColor('
md.comp.icon-button.selected.hover.state-layer')}
;
return
${componentColor('
$tokenGroup.selected.hover.state-layer')}
.withOpacity(
${opacity('$tokenGroup.hover.state-layer.opacity')}
)
;
}
}
if (states.contains(MaterialState.focused)) {
if (states.contains(MaterialState.focused)) {
return
${componentColor('
md.comp.icon-button.selected.focus.state-layer')}
;
return
${componentColor('
$tokenGroup.selected.focus.state-layer')}
.withOpacity(
${opacity('$tokenGroup.focus.state-layer.opacity')}
)
;
}
}
if (states.contains(MaterialState.pressed)) {
if (states.contains(MaterialState.pressed)) {
return
${componentColor('
md.comp.icon-button.selected.pressed.state-layer')}
;
return
${componentColor('
$tokenGroup.selected.pressed.state-layer')}
.withOpacity(
${opacity('$tokenGroup.pressed.state-layer.opacity')}
)
;
}
}
}
}
if (states.contains(MaterialState.hovered)) {
if (states.contains(MaterialState.hovered)) {
return
${componentColor('
md.comp.icon-button.unselected.hover.state-layer')}
;
return
${componentColor('
$tokenGroup.unselected.hover.state-layer')}
.withOpacity(
${opacity('$tokenGroup.hover.state-layer.opacity')}
)
;
}
}
if (states.contains(MaterialState.focused)) {
if (states.contains(MaterialState.focused)) {
return
${componentColor('
md.comp.icon-button.unselected.focus.state-layer')}
;
return
${componentColor('
$tokenGroup.unselected.focus.state-layer')}
.withOpacity(
${opacity('$tokenGroup.focus.state-layer.opacity')}
)
;
}
}
if (states.contains(MaterialState.pressed)) {
if (states.contains(MaterialState.pressed)) {
return
${componentColor('
md.comp.icon-button.unselected.pressed.state-layer')}
;
return
${componentColor('
$tokenGroup.unselected.pressed.state-layer')}
.withOpacity(
${opacity('$tokenGroup.pressed.state-layer.opacity')}
)
;
}
}
return Colors.transparent;
})'''
;
case
'md.comp.icon-button'
:
return
'''
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
if (states.contains(MaterialState.hovered)) {
return
${componentColor('$tokenGroup.selected.hover.state-layer')}
;
}
if (states.contains(MaterialState.focused)) {
return
${componentColor('$tokenGroup.selected.focus.state-layer')}
;
}
if (states.contains(MaterialState.pressed)) {
return
${componentColor('$tokenGroup.selected.pressed.state-layer')}
;
}
}
if (states.contains(MaterialState.hovered)) {
return
${componentColor('$tokenGroup.unselected.hover.state-layer')}
;
}
if (states.contains(MaterialState.focused)) {
return
${componentColor('$tokenGroup.unselected.focus.state-layer')}
;
}
if (states.contains(MaterialState.pressed)) {
return
${componentColor('$tokenGroup.unselected.pressed.state-layer')}
;
}
return Colors.transparent;
})'''
;
}
return
'''
const MaterialStatePropertyAll<Color?>(Colors.transparent)'''
;
}
String
_minimumSize
()
{
if
(
tokens
.
containsKey
(
'
$tokenGroup
.container.size'
))
{
return
'''
const MaterialStatePropertyAll<Size>(Size(
${tokens['$tokenGroup.container.size']}
,
${tokens['$tokenGroup.container.size']}
))'''
;
}
else
{
return
'''
const MaterialStatePropertyAll<Size>(Size(
${tokens['$tokenGroup.state-layer.size']}
,
${tokens['$tokenGroup.state-layer.size']}
))'''
;
}
}
String
_shape
()
{
if
(
tokens
.
containsKey
(
'
$tokenGroup
.container.shape'
))
{
return
'''
const MaterialStatePropertyAll<OutlinedBorder>(
${shape("$tokenGroup.container", "")}
)'''
;
}
else
{
return
'''
const MaterialStatePropertyAll<OutlinedBorder>(
${shape("$tokenGroup.state-layer", "")}
)'''
;
}
}
String
_side
()
{
if
(
tokens
.
containsKey
(
'
$tokenGroup
.unselected.outline.color'
))
{
return
'''
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
return null;
return null;
});
} else {
if (states.contains(MaterialState.disabled)) {
return BorderSide(color:
${componentColor('$tokenGroup.disabled.unselected.outline')}
);
}
return BorderSide(color:
${componentColor('$tokenGroup.unselected.outline')}
);
}
})'''
;
}
return
''' null'''
;
}
String
_elevationColor
(
String
token
)
{
if
(
tokens
.
containsKey
(
token
))
{
return
'MaterialStatePropertyAll<Color>(
${color(token)}
)'
;
}
else
{
return
'const MaterialStatePropertyAll<Color>(Colors.transparent)'
;
}
}
@override
String
generate
()
=>
'''
class _
${blockName}
DefaultsM3 extends ButtonStyle {
_
${blockName}
DefaultsM3(this.context, this.toggleable)
: super(
animationDuration: kThemeChangeDuration,
enableFeedback: true,
alignment: Alignment.center,
);
final BuildContext context;
final bool toggleable;
late final ColorScheme _colors = Theme.of(context).colorScheme;
// No default text style
@override
MaterialStateProperty<Color?>? get backgroundColor =>
${_backgroundColor()}
;
@override
MaterialStateProperty<Color?>? get foregroundColor =>
${_foregroundColor()}
;
@override
MaterialStateProperty<Color?>? get overlayColor =>
${_overlayColor()}
;
@override
@override
MaterialStateProperty<double>? get elevation =>
MaterialStateProperty<double>? get elevation =>
...
@@ -81,19 +265,18 @@ class _${blockName}DefaultsM3 extends ButtonStyle {
...
@@ -81,19 +265,18 @@ class _${blockName}DefaultsM3 extends ButtonStyle {
@override
@override
MaterialStateProperty<Color>? get shadowColor =>
MaterialStateProperty<Color>? get shadowColor =>
${_elevationColor("
md.comp.icon-button
.container.shadow-color")}
;
${_elevationColor("
$tokenGroup
.container.shadow-color")}
;
@override
@override
MaterialStateProperty<Color>? get surfaceTintColor =>
MaterialStateProperty<Color>? get surfaceTintColor =>
${_elevationColor("
md.comp.icon-button
.container.surface-tint-layer.color")}
;
${_elevationColor("
$tokenGroup
.container.surface-tint-layer.color")}
;
@override
@override
MaterialStateProperty<EdgeInsetsGeometry>? get padding =>
MaterialStateProperty<EdgeInsetsGeometry>? get padding =>
const MaterialStatePropertyAll<EdgeInsetsGeometry>(EdgeInsets.all(8.0));
const MaterialStatePropertyAll<EdgeInsetsGeometry>(EdgeInsets.all(8.0));
@override
@override
MaterialStateProperty<Size>? get minimumSize =>
MaterialStateProperty<Size>? get minimumSize =>
${_minimumSize()}
;
const MaterialStatePropertyAll<Size>(Size(
${tokens["md.comp.icon-button.state-layer.size"]}
,
${tokens["md.comp.icon-button.state-layer.size"]}
));
// No default fixedSize
// No default fixedSize
...
@@ -103,13 +286,13 @@ class _${blockName}DefaultsM3 extends ButtonStyle {
...
@@ -103,13 +286,13 @@ class _${blockName}DefaultsM3 extends ButtonStyle {
@override
@override
MaterialStateProperty<double>? get iconSize =>
MaterialStateProperty<double>? get iconSize =>
const MaterialStatePropertyAll<double>(
${tokens["
md.comp.icon-button
.icon.size"]}
);
const MaterialStatePropertyAll<double>(
${tokens["
$tokenGroup
.icon.size"]}
);
// No default side
@override
MaterialStateProperty<BorderSide?>? get side =>
${_side()}
;
@override
@override
MaterialStateProperty<OutlinedBorder>? get shape =>
MaterialStateProperty<OutlinedBorder>? get shape =>
${_shape()}
;
const MaterialStatePropertyAll<OutlinedBorder>(
${shape("md.comp.icon-button.state-layer", "")}
);
@override
@override
MaterialStateProperty<MouseCursor?>? get mouseCursor =>
MaterialStateProperty<MouseCursor?>? get mouseCursor =>
...
...
examples/api/lib/material/icon_button/icon_button.2.dart
View file @
b1146549
...
@@ -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
;
}),
),
),
],
],
),
),
);
);
...
...
examples/api/lib/material/icon_button/icon_button.3.dart
View file @
b1146549
...
@@ -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
>
{
bool
standardSelected
=
false
;
bool
filledSelected
=
false
;
bool
tonalSelected
=
false
;
bool
outlinedSelected
=
false
;
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
const
Padding
(
return
Column
(
padding:
EdgeInsets
.
all
(
8.0
),
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
spaceEvenly
,
mainAxisAlignment:
MainAxisAlignment
.
spaceEvenly
,
children:
<
Widget
>[
children:
<
Widget
>[
Row
(
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
// Standard IconButton
children:
<
Widget
>[
children:
<
Widget
>[
DemoIconToggleButton
(
isEnabled:
true
),
IconButton
(
SizedBox
(
width:
10
),
isSelected:
standardSelected
,
DemoIconToggleButton
(
isEnabled:
false
),
icon:
const
Icon
(
Icons
.
settings_outlined
),
]
selectedIcon:
const
Icon
(
Icons
.
settings
),
onPressed:
()
{
setState
(()
{
standardSelected
=
!
standardSelected
;
});
},
),
const
SizedBox
(
width:
10
),
IconButton
(
isSelected:
standardSelected
,
icon:
const
Icon
(
Icons
.
settings_outlined
),
selectedIcon:
const
Icon
(
Icons
.
settings
),
onPressed:
null
,
),
],
),
),
Row
(
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
<
Widget
>[
children:
<
Widget
>[
// Filled IconButton
IconButton
.
filled
(
DemoIconToggleButton
(
isEnabled:
true
,
getDefaultStyle:
enabledFilledButtonStyle
,),
isSelected:
filledSelected
,
SizedBox
(
width:
10
),
icon:
const
Icon
(
Icons
.
settings_outlined
),
DemoIconToggleButton
(
isEnabled:
false
,
getDefaultStyle:
disabledFilledButtonStyle
,)
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
(
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
<
Widget
>[
children:
<
Widget
>[
// Filled Tonal IconButton
IconButton
.
filledTonal
(
DemoIconToggleButton
(
isEnabled:
true
,
getDefaultStyle:
enabledFilledTonalButtonStyle
,),
isSelected:
tonalSelected
,
SizedBox
(
width:
10
),
icon:
const
Icon
(
Icons
.
settings_outlined
),
DemoIconToggleButton
(
isEnabled:
false
,
getDefaultStyle:
disabledFilledTonalButtonStyle
,),
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
(
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
<
Widget
>[
children:
<
Widget
>[
// Outlined IconButton
IconButton
.
outlined
(
DemoIconToggleButton
(
isEnabled:
true
,
getDefaultStyle:
enabledOutlinedButtonStyle
,),
isSelected:
outlinedSelected
,
SizedBox
(
width:
10
),
icon:
const
Icon
(
Icons
.
settings_outlined
),
DemoIconToggleButton
(
isEnabled:
false
,
getDefaultStyle:
disabledOutlinedButtonStyle
,),
selectedIcon:
const
Icon
(
Icons
.
settings
),
]
onPressed:
()
{
),
]
),
);
}
}
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
Widget
build
(
BuildContext
context
)
{
final
ColorScheme
colors
=
Theme
.
of
(
context
).
colorScheme
;
final
VoidCallback
?
onPressed
=
widget
.
isEnabled
?
()
{
setState
(()
{
setState
(()
{
selected
=
!
s
elected
;
outlinedSelected
=
!
outlinedS
elected
;
});
});
}
},
:
null
;
),
ButtonStyle
?
style
;
const
SizedBox
(
width:
10
),
if
(
widget
.
getDefaultStyle
!=
null
)
{
IconButton
.
outlined
(
style
=
widget
.
getDefaultStyle
!(
selected
,
colors
);
isSelected:
outlinedSelected
,
}
return
IconButton
(
isSelected:
selected
,
icon:
const
Icon
(
Icons
.
settings_outlined
),
icon:
const
Icon
(
Icons
.
settings_outlined
),
selectedIcon:
const
Icon
(
Icons
.
settings
),
selectedIcon:
const
Icon
(
Icons
.
settings
),
onPressed:
onPressed
,
onPressed:
null
,
style:
style
,
),
);
],
}
),
}
]
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
)),
);
}
}
packages/flutter/lib/src/material/icon_button.dart
View file @
b1146549
...
@@ -30,6 +30,8 @@ import 'tooltip.dart';
...
@@ -30,6 +30,8 @@ import 'tooltip.dart';
// See: <https://material.io/design/usability/accessibility.html#layout-typography>.
// See: <https://material.io/design/usability/accessibility.html#layout-typography>.
const
double
_kMinButtonSize
=
kMinInteractiveDimension
;
const
double
_kMinButtonSize
=
kMinInteractiveDimension
;
enum
_IconButtonVariant
{
standard
,
filled
,
filledTonal
,
outlined
}
/// A Material Design icon button.
/// A Material Design icon button.
///
///
/// An icon button is a picture printed on a [Material] widget that reacts to
/// An icon button is a picture printed on a [Material] widget that reacts to
...
@@ -115,8 +117,9 @@ const double _kMinButtonSize = kMinInteractiveDimension;
...
@@ -115,8 +117,9 @@ const double _kMinButtonSize = kMinInteractiveDimension;
/// {@end-tool}
/// {@end-tool}
///
///
/// Material Design 3 introduced new types (standard and contained) of [IconButton]s.
/// Material Design 3 introduced new types (standard and contained) of [IconButton]s.
/// The default [IconButton] is the standard type, and contained icon buttons can be produced
/// The default [IconButton] is the standard type. To create a filled icon button,
/// by configuring the [IconButton] widget's properties.
/// use [IconButton.filled]; to create a filled tonal icon button, use [IconButton.filledTonal];
/// to create a outlined icon button, use [IconButton.outlined].
///
///
/// Material Design 3 also treats [IconButton]s as toggle buttons. In order
/// Material Design 3 also treats [IconButton]s as toggle buttons. In order
/// to not break existing apps, the toggle feature can be optionally controlled
/// to not break existing apps, the toggle feature can be optionally controlled
...
@@ -198,7 +201,104 @@ class IconButton extends StatelessWidget {
...
@@ -198,7 +201,104 @@ class IconButton extends StatelessWidget {
this
.
isSelected
,
this
.
isSelected
,
this
.
selectedIcon
,
this
.
selectedIcon
,
required
this
.
icon
,
required
this
.
icon
,
})
:
assert
(
splashRadius
==
null
||
splashRadius
>
0
);
})
:
assert
(
splashRadius
==
null
||
splashRadius
>
0
),
_variant
=
_IconButtonVariant
.
standard
;
/// Create a filled variant of IconButton.
///
/// Filled icon buttons have higher visual impact and should be used for
/// high emphasis actions, such as turning off a microphone or camera.
const
IconButton
.
filled
({
super
.
key
,
this
.
iconSize
,
this
.
visualDensity
,
this
.
padding
,
this
.
alignment
,
this
.
splashRadius
,
this
.
color
,
this
.
focusColor
,
this
.
hoverColor
,
this
.
highlightColor
,
this
.
splashColor
,
this
.
disabledColor
,
required
this
.
onPressed
,
this
.
mouseCursor
,
this
.
focusNode
,
this
.
autofocus
=
false
,
this
.
tooltip
,
this
.
enableFeedback
,
this
.
constraints
,
this
.
style
,
this
.
isSelected
,
this
.
selectedIcon
,
required
this
.
icon
,
})
:
assert
(
splashRadius
==
null
||
splashRadius
>
0
),
_variant
=
_IconButtonVariant
.
filled
;
/// Create a filled tonal variant of IconButton.
///
/// Filled tonal icon buttons are a middle ground between filled and outlined
/// icon buttons. They’re useful in contexts where the button requires slightly
/// more emphasis than an outline would give, such as a secondary action paired
/// with a high emphasis action.
const
IconButton
.
filledTonal
({
super
.
key
,
this
.
iconSize
,
this
.
visualDensity
,
this
.
padding
,
this
.
alignment
,
this
.
splashRadius
,
this
.
color
,
this
.
focusColor
,
this
.
hoverColor
,
this
.
highlightColor
,
this
.
splashColor
,
this
.
disabledColor
,
required
this
.
onPressed
,
this
.
mouseCursor
,
this
.
focusNode
,
this
.
autofocus
=
false
,
this
.
tooltip
,
this
.
enableFeedback
,
this
.
constraints
,
this
.
style
,
this
.
isSelected
,
this
.
selectedIcon
,
required
this
.
icon
,
})
:
assert
(
splashRadius
==
null
||
splashRadius
>
0
),
_variant
=
_IconButtonVariant
.
filledTonal
;
/// Create a filled tonal variant of IconButton.
///
/// Outlined icon buttons are medium-emphasis buttons. They’re useful when an
/// icon button needs more emphasis than a standard icon button but less than
/// a filled or filled tonal icon button.
const
IconButton
.
outlined
({
super
.
key
,
this
.
iconSize
,
this
.
visualDensity
,
this
.
padding
,
this
.
alignment
,
this
.
splashRadius
,
this
.
color
,
this
.
focusColor
,
this
.
hoverColor
,
this
.
highlightColor
,
this
.
splashColor
,
this
.
disabledColor
,
required
this
.
onPressed
,
this
.
mouseCursor
,
this
.
focusNode
,
this
.
autofocus
=
false
,
this
.
tooltip
,
this
.
enableFeedback
,
this
.
constraints
,
this
.
style
,
this
.
isSelected
,
this
.
selectedIcon
,
required
this
.
icon
,
})
:
assert
(
splashRadius
==
null
||
splashRadius
>
0
),
_variant
=
_IconButtonVariant
.
outlined
;
/// The size of the icon inside the button.
/// The size of the icon inside the button.
///
///
...
@@ -465,6 +565,8 @@ class IconButton extends StatelessWidget {
...
@@ -465,6 +565,8 @@ class IconButton extends StatelessWidget {
/// * [ImageIcon], for showing icons from [AssetImage]s or other [ImageProvider]s.
/// * [ImageIcon], for showing icons from [AssetImage]s or other [ImageProvider]s.
final
Widget
?
selectedIcon
;
final
Widget
?
selectedIcon
;
final
_IconButtonVariant
_variant
;
/// A static convenience method that constructs an icon button
/// A static convenience method that constructs an icon button
/// [ButtonStyle] given simple values. This method is only used for Material 3.
/// [ButtonStyle] given simple values. This method is only used for Material 3.
///
///
...
@@ -615,6 +717,7 @@ class IconButton extends StatelessWidget {
...
@@ -615,6 +717,7 @@ class IconButton extends StatelessWidget {
autofocus:
autofocus
,
autofocus:
autofocus
,
focusNode:
focusNode
,
focusNode:
focusNode
,
isSelected:
isSelected
,
isSelected:
isSelected
,
variant:
_variant
,
child:
iconButton
,
child:
iconButton
,
);
);
}
}
...
@@ -714,6 +817,7 @@ class _SelectableIconButton extends StatefulWidget {
...
@@ -714,6 +817,7 @@ class _SelectableIconButton extends StatefulWidget {
this
.
isSelected
,
this
.
isSelected
,
this
.
style
,
this
.
style
,
this
.
focusNode
,
this
.
focusNode
,
required
this
.
variant
,
required
this
.
autofocus
,
required
this
.
autofocus
,
required
this
.
onPressed
,
required
this
.
onPressed
,
required
this
.
child
,
required
this
.
child
,
...
@@ -722,6 +826,7 @@ class _SelectableIconButton extends StatefulWidget {
...
@@ -722,6 +826,7 @@ class _SelectableIconButton extends StatefulWidget {
final
bool
?
isSelected
;
final
bool
?
isSelected
;
final
ButtonStyle
?
style
;
final
ButtonStyle
?
style
;
final
FocusNode
?
focusNode
;
final
FocusNode
?
focusNode
;
final
_IconButtonVariant
variant
;
final
bool
autofocus
;
final
bool
autofocus
;
final
VoidCallback
?
onPressed
;
final
VoidCallback
?
onPressed
;
final
Widget
child
;
final
Widget
child
;
...
@@ -761,12 +866,16 @@ class _SelectableIconButtonState extends State<_SelectableIconButton> {
...
@@ -761,12 +866,16 @@ class _SelectableIconButtonState extends State<_SelectableIconButton> {
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
final
bool
toggleable
=
widget
.
isSelected
!=
null
;
return
_IconButtonM3
(
return
_IconButtonM3
(
statesController:
statesController
,
statesController:
statesController
,
style:
widget
.
style
,
style:
widget
.
style
,
autofocus:
widget
.
autofocus
,
autofocus:
widget
.
autofocus
,
focusNode:
widget
.
focusNode
,
focusNode:
widget
.
focusNode
,
onPressed:
widget
.
onPressed
,
onPressed:
widget
.
onPressed
,
variant:
widget
.
variant
,
toggleable:
toggleable
,
child:
widget
.
child
,
child:
widget
.
child
,
);
);
}
}
...
@@ -779,6 +888,8 @@ class _IconButtonM3 extends ButtonStyleButton {
...
@@ -779,6 +888,8 @@ class _IconButtonM3 extends ButtonStyleButton {
super
.
focusNode
,
super
.
focusNode
,
super
.
autofocus
=
false
,
super
.
autofocus
=
false
,
super
.
statesController
,
super
.
statesController
,
required
this
.
variant
,
required
this
.
toggleable
,
required
Widget
super
.
child
,
required
Widget
super
.
child
,
})
:
super
(
})
:
super
(
onLongPress:
null
,
onLongPress:
null
,
...
@@ -786,6 +897,9 @@ class _IconButtonM3 extends ButtonStyleButton {
...
@@ -786,6 +897,9 @@ class _IconButtonM3 extends ButtonStyleButton {
onFocusChange:
null
,
onFocusChange:
null
,
clipBehavior:
Clip
.
none
);
clipBehavior:
Clip
.
none
);
final
_IconButtonVariant
variant
;
final
bool
toggleable
;
/// ## Material 3 defaults
/// ## Material 3 defaults
///
///
/// If [ThemeData.useMaterial3] is set to true the following defaults will
/// If [ThemeData.useMaterial3] is set to true the following defaults will
...
@@ -825,7 +939,16 @@ class _IconButtonM3 extends ButtonStyleButton {
...
@@ -825,7 +939,16 @@ class _IconButtonM3 extends ButtonStyleButton {
/// * `splashFactory` - Theme.splashFactory
/// * `splashFactory` - Theme.splashFactory
@override
@override
ButtonStyle
defaultStyleOf
(
BuildContext
context
)
{
ButtonStyle
defaultStyleOf
(
BuildContext
context
)
{
return
_IconButtonDefaultsM3
(
context
);
switch
(
variant
)
{
case
_IconButtonVariant
.
filled
:
return
_FilledIconButtonDefaultsM3
(
context
,
toggleable
);
case
_IconButtonVariant
.
filledTonal
:
return
_FilledTonalIconButtonDefaultsM3
(
context
,
toggleable
);
case
_IconButtonVariant
.
outlined
:
return
_OutlinedIconButtonDefaultsM3
(
context
,
toggleable
);
case
_IconButtonVariant
.
standard
:
return
_IconButtonDefaultsM3
(
context
,
toggleable
);
}
}
}
/// Returns the [IconButtonThemeData.style] of the closest [IconButtonTheme] ancestor.
/// Returns the [IconButtonThemeData.style] of the closest [IconButtonTheme] ancestor.
...
@@ -963,7 +1086,7 @@ class _IconButtonDefaultMouseCursor extends MaterialStateProperty<MouseCursor> w
...
@@ -963,7 +1086,7 @@ class _IconButtonDefaultMouseCursor extends MaterialStateProperty<MouseCursor> w
// Token database version: v0_158
// Token database version: v0_158
class
_IconButtonDefaultsM3
extends
ButtonStyle
{
class
_IconButtonDefaultsM3
extends
ButtonStyle
{
_IconButtonDefaultsM3
(
this
.
context
)
_IconButtonDefaultsM3
(
this
.
context
,
this
.
toggleable
)
:
super
(
:
super
(
animationDuration:
kThemeChangeDuration
,
animationDuration:
kThemeChangeDuration
,
enableFeedback:
true
,
enableFeedback:
true
,
...
@@ -971,6 +1094,7 @@ class _IconButtonDefaultsM3 extends ButtonStyle {
...
@@ -971,6 +1094,7 @@ class _IconButtonDefaultsM3 extends ButtonStyle {
);
);
final
BuildContext
context
;
final
BuildContext
context
;
final
bool
toggleable
;
late
final
ColorScheme
_colors
=
Theme
.
of
(
context
).
colorScheme
;
late
final
ColorScheme
_colors
=
Theme
.
of
(
context
).
colorScheme
;
// No default text style
// No default text style
...
@@ -1014,7 +1138,7 @@ class _IconButtonDefaultsM3 extends ButtonStyle {
...
@@ -1014,7 +1138,7 @@ class _IconButtonDefaultsM3 extends ButtonStyle {
if
(
states
.
contains
(
MaterialState
.
pressed
))
{
if
(
states
.
contains
(
MaterialState
.
pressed
))
{
return
_colors
.
onSurfaceVariant
.
withOpacity
(
0.12
);
return
_colors
.
onSurfaceVariant
.
withOpacity
(
0.12
);
}
}
return
null
;
return
Colors
.
transparent
;
});
});
@override
@override
...
@@ -1047,7 +1171,8 @@ class _IconButtonDefaultsM3 extends ButtonStyle {
...
@@ -1047,7 +1171,8 @@ class _IconButtonDefaultsM3 extends ButtonStyle {
MaterialStateProperty
<
double
>?
get
iconSize
=>
MaterialStateProperty
<
double
>?
get
iconSize
=>
const
MaterialStatePropertyAll
<
double
>(
24.0
);
const
MaterialStatePropertyAll
<
double
>(
24.0
);
// No default side
@override
MaterialStateProperty
<
BorderSide
?>?
get
side
=>
null
;
@override
@override
MaterialStateProperty
<
OutlinedBorder
>?
get
shape
=>
MaterialStateProperty
<
OutlinedBorder
>?
get
shape
=>
...
@@ -1073,3 +1198,442 @@ class _IconButtonDefaultsM3 extends ButtonStyle {
...
@@ -1073,3 +1198,442 @@ class _IconButtonDefaultsM3 extends ButtonStyle {
}
}
// END GENERATED TOKEN PROPERTIES - IconButton
// END GENERATED TOKEN PROPERTIES - IconButton
// BEGIN GENERATED TOKEN PROPERTIES - FilledIconButton
// Do not edit by hand. The code between the "BEGIN GENERATED" and
// "END GENERATED" comments are generated from data in the Material
// Design token database by the script:
// dev/tools/gen_defaults/bin/gen_defaults.dart.
// Token database version: v0_158
class
_FilledIconButtonDefaultsM3
extends
ButtonStyle
{
_FilledIconButtonDefaultsM3
(
this
.
context
,
this
.
toggleable
)
:
super
(
animationDuration:
kThemeChangeDuration
,
enableFeedback:
true
,
alignment:
Alignment
.
center
,
);
final
BuildContext
context
;
final
bool
toggleable
;
late
final
ColorScheme
_colors
=
Theme
.
of
(
context
).
colorScheme
;
// No default text style
@override
MaterialStateProperty
<
Color
?>?
get
backgroundColor
=>
MaterialStateProperty
.
resolveWith
((
Set
<
MaterialState
>
states
)
{
if
(
states
.
contains
(
MaterialState
.
disabled
))
{
return
_colors
.
onSurface
.
withOpacity
(
0.12
);
}
if
(
states
.
contains
(
MaterialState
.
selected
))
{
return
_colors
.
primary
;
}
if
(
toggleable
)
{
// toggleable but unselected case
return
_colors
.
surfaceVariant
;
}
return
_colors
.
primary
;
});
@override
MaterialStateProperty
<
Color
?>?
get
foregroundColor
=>
MaterialStateProperty
.
resolveWith
((
Set
<
MaterialState
>
states
)
{
if
(
states
.
contains
(
MaterialState
.
disabled
))
{
return
_colors
.
onSurface
.
withOpacity
(
0.38
);
}
if
(
states
.
contains
(
MaterialState
.
selected
))
{
return
_colors
.
onPrimary
;
}
if
(
toggleable
)
{
// toggleable but unselected case
return
_colors
.
primary
;
}
return
_colors
.
onPrimary
;
});
@override
MaterialStateProperty
<
Color
?>?
get
overlayColor
=>
MaterialStateProperty
.
resolveWith
((
Set
<
MaterialState
>
states
)
{
if
(
states
.
contains
(
MaterialState
.
selected
))
{
if
(
states
.
contains
(
MaterialState
.
hovered
))
{
return
_colors
.
onPrimary
.
withOpacity
(
0.08
);
}
if
(
states
.
contains
(
MaterialState
.
focused
))
{
return
_colors
.
onPrimary
.
withOpacity
(
0.12
);
}
if
(
states
.
contains
(
MaterialState
.
pressed
))
{
return
_colors
.
onPrimary
.
withOpacity
(
0.12
);
}
}
if
(
toggleable
)
{
// toggleable but unselected case
if
(
states
.
contains
(
MaterialState
.
hovered
))
{
return
_colors
.
primary
.
withOpacity
(
0.08
);
}
if
(
states
.
contains
(
MaterialState
.
focused
))
{
return
_colors
.
primary
.
withOpacity
(
0.12
);
}
if
(
states
.
contains
(
MaterialState
.
pressed
))
{
return
_colors
.
primary
.
withOpacity
(
0.12
);
}
}
if
(
states
.
contains
(
MaterialState
.
hovered
))
{
return
_colors
.
onPrimary
.
withOpacity
(
0.08
);
}
if
(
states
.
contains
(
MaterialState
.
focused
))
{
return
_colors
.
onPrimary
.
withOpacity
(
0.12
);
}
if
(
states
.
contains
(
MaterialState
.
pressed
))
{
return
_colors
.
onPrimary
.
withOpacity
(
0.12
);
}
return
Colors
.
transparent
;
});
@override
MaterialStateProperty
<
double
>?
get
elevation
=>
const
MaterialStatePropertyAll
<
double
>(
0.0
);
@override
MaterialStateProperty
<
Color
>?
get
shadowColor
=>
const
MaterialStatePropertyAll
<
Color
>(
Colors
.
transparent
);
@override
MaterialStateProperty
<
Color
>?
get
surfaceTintColor
=>
const
MaterialStatePropertyAll
<
Color
>(
Colors
.
transparent
);
@override
MaterialStateProperty
<
EdgeInsetsGeometry
>?
get
padding
=>
const
MaterialStatePropertyAll
<
EdgeInsetsGeometry
>(
EdgeInsets
.
all
(
8.0
));
@override
MaterialStateProperty
<
Size
>?
get
minimumSize
=>
const
MaterialStatePropertyAll
<
Size
>(
Size
(
40.0
,
40.0
));
// No default fixedSize
@override
MaterialStateProperty
<
Size
>?
get
maximumSize
=>
const
MaterialStatePropertyAll
<
Size
>(
Size
.
infinite
);
@override
MaterialStateProperty
<
double
>?
get
iconSize
=>
const
MaterialStatePropertyAll
<
double
>(
24.0
);
@override
MaterialStateProperty
<
BorderSide
?>?
get
side
=>
null
;
@override
MaterialStateProperty
<
OutlinedBorder
>?
get
shape
=>
const
MaterialStatePropertyAll
<
OutlinedBorder
>(
StadiumBorder
());
@override
MaterialStateProperty
<
MouseCursor
?>?
get
mouseCursor
=>
MaterialStateProperty
.
resolveWith
((
Set
<
MaterialState
>
states
)
{
if
(
states
.
contains
(
MaterialState
.
disabled
))
{
return
SystemMouseCursors
.
basic
;
}
return
SystemMouseCursors
.
click
;
});
@override
VisualDensity
?
get
visualDensity
=>
VisualDensity
.
standard
;
@override
MaterialTapTargetSize
?
get
tapTargetSize
=>
Theme
.
of
(
context
).
materialTapTargetSize
;
@override
InteractiveInkFeatureFactory
?
get
splashFactory
=>
Theme
.
of
(
context
).
splashFactory
;
}
// END GENERATED TOKEN PROPERTIES - FilledIconButton
// BEGIN GENERATED TOKEN PROPERTIES - FilledTonalIconButton
// Do not edit by hand. The code between the "BEGIN GENERATED" and
// "END GENERATED" comments are generated from data in the Material
// Design token database by the script:
// dev/tools/gen_defaults/bin/gen_defaults.dart.
// Token database version: v0_158
class
_FilledTonalIconButtonDefaultsM3
extends
ButtonStyle
{
_FilledTonalIconButtonDefaultsM3
(
this
.
context
,
this
.
toggleable
)
:
super
(
animationDuration:
kThemeChangeDuration
,
enableFeedback:
true
,
alignment:
Alignment
.
center
,
);
final
BuildContext
context
;
final
bool
toggleable
;
late
final
ColorScheme
_colors
=
Theme
.
of
(
context
).
colorScheme
;
// No default text style
@override
MaterialStateProperty
<
Color
?>?
get
backgroundColor
=>
MaterialStateProperty
.
resolveWith
((
Set
<
MaterialState
>
states
)
{
if
(
states
.
contains
(
MaterialState
.
disabled
))
{
return
_colors
.
onSurface
.
withOpacity
(
0.12
);
}
if
(
states
.
contains
(
MaterialState
.
selected
))
{
return
_colors
.
secondaryContainer
;
}
if
(
toggleable
)
{
// toggleable but unselected case
return
_colors
.
surfaceVariant
;
}
return
_colors
.
secondaryContainer
;
});
@override
MaterialStateProperty
<
Color
?>?
get
foregroundColor
=>
MaterialStateProperty
.
resolveWith
((
Set
<
MaterialState
>
states
)
{
if
(
states
.
contains
(
MaterialState
.
disabled
))
{
return
_colors
.
onSurface
.
withOpacity
(
0.38
);
}
if
(
states
.
contains
(
MaterialState
.
selected
))
{
return
_colors
.
onSecondaryContainer
;
}
if
(
toggleable
)
{
// toggleable but unselected case
return
_colors
.
onSurfaceVariant
;
}
return
_colors
.
onSecondaryContainer
;
});
@override
MaterialStateProperty
<
Color
?>?
get
overlayColor
=>
MaterialStateProperty
.
resolveWith
((
Set
<
MaterialState
>
states
)
{
if
(
states
.
contains
(
MaterialState
.
selected
))
{
if
(
states
.
contains
(
MaterialState
.
hovered
))
{
return
_colors
.
onSecondaryContainer
.
withOpacity
(
0.08
);
}
if
(
states
.
contains
(
MaterialState
.
focused
))
{
return
_colors
.
onSecondaryContainer
.
withOpacity
(
0.12
);
}
if
(
states
.
contains
(
MaterialState
.
pressed
))
{
return
_colors
.
onSecondaryContainer
.
withOpacity
(
0.12
);
}
}
if
(
toggleable
)
{
// toggleable but unselected case
if
(
states
.
contains
(
MaterialState
.
hovered
))
{
return
_colors
.
onSurfaceVariant
.
withOpacity
(
0.08
);
}
if
(
states
.
contains
(
MaterialState
.
focused
))
{
return
_colors
.
onSurfaceVariant
.
withOpacity
(
0.12
);
}
if
(
states
.
contains
(
MaterialState
.
pressed
))
{
return
_colors
.
onSurfaceVariant
.
withOpacity
(
0.12
);
}
}
if
(
states
.
contains
(
MaterialState
.
hovered
))
{
return
_colors
.
onSecondaryContainer
.
withOpacity
(
0.08
);
}
if
(
states
.
contains
(
MaterialState
.
focused
))
{
return
_colors
.
onSecondaryContainer
.
withOpacity
(
0.12
);
}
if
(
states
.
contains
(
MaterialState
.
pressed
))
{
return
_colors
.
onSecondaryContainer
.
withOpacity
(
0.12
);
}
return
Colors
.
transparent
;
});
@override
MaterialStateProperty
<
double
>?
get
elevation
=>
const
MaterialStatePropertyAll
<
double
>(
0.0
);
@override
MaterialStateProperty
<
Color
>?
get
shadowColor
=>
const
MaterialStatePropertyAll
<
Color
>(
Colors
.
transparent
);
@override
MaterialStateProperty
<
Color
>?
get
surfaceTintColor
=>
const
MaterialStatePropertyAll
<
Color
>(
Colors
.
transparent
);
@override
MaterialStateProperty
<
EdgeInsetsGeometry
>?
get
padding
=>
const
MaterialStatePropertyAll
<
EdgeInsetsGeometry
>(
EdgeInsets
.
all
(
8.0
));
@override
MaterialStateProperty
<
Size
>?
get
minimumSize
=>
const
MaterialStatePropertyAll
<
Size
>(
Size
(
40.0
,
40.0
));
// No default fixedSize
@override
MaterialStateProperty
<
Size
>?
get
maximumSize
=>
const
MaterialStatePropertyAll
<
Size
>(
Size
.
infinite
);
@override
MaterialStateProperty
<
double
>?
get
iconSize
=>
const
MaterialStatePropertyAll
<
double
>(
24.0
);
@override
MaterialStateProperty
<
BorderSide
?>?
get
side
=>
null
;
@override
MaterialStateProperty
<
OutlinedBorder
>?
get
shape
=>
const
MaterialStatePropertyAll
<
OutlinedBorder
>(
StadiumBorder
());
@override
MaterialStateProperty
<
MouseCursor
?>?
get
mouseCursor
=>
MaterialStateProperty
.
resolveWith
((
Set
<
MaterialState
>
states
)
{
if
(
states
.
contains
(
MaterialState
.
disabled
))
{
return
SystemMouseCursors
.
basic
;
}
return
SystemMouseCursors
.
click
;
});
@override
VisualDensity
?
get
visualDensity
=>
VisualDensity
.
standard
;
@override
MaterialTapTargetSize
?
get
tapTargetSize
=>
Theme
.
of
(
context
).
materialTapTargetSize
;
@override
InteractiveInkFeatureFactory
?
get
splashFactory
=>
Theme
.
of
(
context
).
splashFactory
;
}
// END GENERATED TOKEN PROPERTIES - FilledTonalIconButton
// BEGIN GENERATED TOKEN PROPERTIES - OutlinedIconButton
// Do not edit by hand. The code between the "BEGIN GENERATED" and
// "END GENERATED" comments are generated from data in the Material
// Design token database by the script:
// dev/tools/gen_defaults/bin/gen_defaults.dart.
// Token database version: v0_158
class
_OutlinedIconButtonDefaultsM3
extends
ButtonStyle
{
_OutlinedIconButtonDefaultsM3
(
this
.
context
,
this
.
toggleable
)
:
super
(
animationDuration:
kThemeChangeDuration
,
enableFeedback:
true
,
alignment:
Alignment
.
center
,
);
final
BuildContext
context
;
final
bool
toggleable
;
late
final
ColorScheme
_colors
=
Theme
.
of
(
context
).
colorScheme
;
// No default text style
@override
MaterialStateProperty
<
Color
?>?
get
backgroundColor
=>
MaterialStateProperty
.
resolveWith
((
Set
<
MaterialState
>
states
)
{
if
(
states
.
contains
(
MaterialState
.
disabled
))
{
if
(
states
.
contains
(
MaterialState
.
selected
))
{
return
_colors
.
onSurface
.
withOpacity
(
0.12
);
}
return
Colors
.
transparent
;
}
if
(
states
.
contains
(
MaterialState
.
selected
))
{
return
_colors
.
inverseSurface
;
}
return
Colors
.
transparent
;
});
@override
MaterialStateProperty
<
Color
?>?
get
foregroundColor
=>
MaterialStateProperty
.
resolveWith
((
Set
<
MaterialState
>
states
)
{
if
(
states
.
contains
(
MaterialState
.
disabled
))
{
return
_colors
.
onSurface
.
withOpacity
(
0.38
);
}
if
(
states
.
contains
(
MaterialState
.
selected
))
{
return
_colors
.
onInverseSurface
;
}
return
_colors
.
onSurfaceVariant
;
});
@override
MaterialStateProperty
<
Color
?>?
get
overlayColor
=>
MaterialStateProperty
.
resolveWith
((
Set
<
MaterialState
>
states
)
{
if
(
states
.
contains
(
MaterialState
.
selected
))
{
if
(
states
.
contains
(
MaterialState
.
hovered
))
{
return
_colors
.
onInverseSurface
.
withOpacity
(
0.08
);
}
if
(
states
.
contains
(
MaterialState
.
focused
))
{
return
_colors
.
onInverseSurface
.
withOpacity
(
0.08
);
}
if
(
states
.
contains
(
MaterialState
.
pressed
))
{
return
_colors
.
onInverseSurface
.
withOpacity
(
0.12
);
}
}
if
(
states
.
contains
(
MaterialState
.
hovered
))
{
return
_colors
.
onSurfaceVariant
.
withOpacity
(
0.08
);
}
if
(
states
.
contains
(
MaterialState
.
focused
))
{
return
_colors
.
onSurfaceVariant
.
withOpacity
(
0.08
);
}
if
(
states
.
contains
(
MaterialState
.
pressed
))
{
return
_colors
.
onSurface
.
withOpacity
(
0.12
);
}
return
Colors
.
transparent
;
});
@override
MaterialStateProperty
<
double
>?
get
elevation
=>
const
MaterialStatePropertyAll
<
double
>(
0.0
);
@override
MaterialStateProperty
<
Color
>?
get
shadowColor
=>
const
MaterialStatePropertyAll
<
Color
>(
Colors
.
transparent
);
@override
MaterialStateProperty
<
Color
>?
get
surfaceTintColor
=>
const
MaterialStatePropertyAll
<
Color
>(
Colors
.
transparent
);
@override
MaterialStateProperty
<
EdgeInsetsGeometry
>?
get
padding
=>
const
MaterialStatePropertyAll
<
EdgeInsetsGeometry
>(
EdgeInsets
.
all
(
8.0
));
@override
MaterialStateProperty
<
Size
>?
get
minimumSize
=>
const
MaterialStatePropertyAll
<
Size
>(
Size
(
40.0
,
40.0
));
// No default fixedSize
@override
MaterialStateProperty
<
Size
>?
get
maximumSize
=>
const
MaterialStatePropertyAll
<
Size
>(
Size
.
infinite
);
@override
MaterialStateProperty
<
double
>?
get
iconSize
=>
const
MaterialStatePropertyAll
<
double
>(
24.0
);
@override
MaterialStateProperty
<
BorderSide
?>?
get
side
=>
MaterialStateProperty
.
resolveWith
((
Set
<
MaterialState
>
states
)
{
if
(
states
.
contains
(
MaterialState
.
selected
))
{
return
null
;
}
else
{
if
(
states
.
contains
(
MaterialState
.
disabled
))
{
return
BorderSide
(
color:
_colors
.
onSurface
.
withOpacity
(
0.12
));
}
return
BorderSide
(
color:
_colors
.
outline
);
}
});
@override
MaterialStateProperty
<
OutlinedBorder
>?
get
shape
=>
const
MaterialStatePropertyAll
<
OutlinedBorder
>(
StadiumBorder
());
@override
MaterialStateProperty
<
MouseCursor
?>?
get
mouseCursor
=>
MaterialStateProperty
.
resolveWith
((
Set
<
MaterialState
>
states
)
{
if
(
states
.
contains
(
MaterialState
.
disabled
))
{
return
SystemMouseCursors
.
basic
;
}
return
SystemMouseCursors
.
click
;
});
@override
VisualDensity
?
get
visualDensity
=>
VisualDensity
.
standard
;
@override
MaterialTapTargetSize
?
get
tapTargetSize
=>
Theme
.
of
(
context
).
materialTapTargetSize
;
@override
InteractiveInkFeatureFactory
?
get
splashFactory
=>
Theme
.
of
(
context
).
splashFactory
;
}
// END GENERATED TOKEN PROPERTIES - OutlinedIconButton
packages/flutter/test/material/icon_button_test.dart
View file @
b1146549
...
@@ -1133,6 +1133,609 @@ void main() {
...
@@ -1133,6 +1133,609 @@ void main() {
expect
(
material
.
type
,
MaterialType
.
button
);
expect
(
material
.
type
,
MaterialType
.
button
);
});
});
testWidgets
(
'IconButton.fill defaults - M3'
,
(
WidgetTester
tester
)
async
{
final
ThemeData
themeM3
=
ThemeData
.
from
(
colorScheme:
colorScheme
,
useMaterial3:
true
);
// Enabled IconButton
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
themeM3
,
home:
Center
(
child:
IconButton
.
filled
(
onPressed:
()
{
},
icon:
const
Icon
(
Icons
.
ac_unit
),
),
),
),
);
final
Finder
buttonMaterial
=
find
.
descendant
(
of:
find
.
byType
(
IconButton
),
matching:
find
.
byType
(
Material
),
);
Color
?
iconColor
()
=>
_iconStyle
(
tester
,
Icons
.
ac_unit
)?.
color
;
expect
(
iconColor
(),
colorScheme
.
onPrimary
);
Material
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
colorScheme
.
primary
);
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
const
StadiumBorder
());
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
final
Align
align
=
tester
.
firstWidget
<
Align
>(
find
.
ancestor
(
of:
find
.
byIcon
(
Icons
.
ac_unit
),
matching:
find
.
byType
(
Align
)));
expect
(
align
.
alignment
,
Alignment
.
center
);
expect
(
tester
.
getSize
(
find
.
byIcon
(
Icons
.
ac_unit
)),
const
Size
(
24.0
,
24.0
));
final
Offset
center
=
tester
.
getCenter
(
find
.
byType
(
IconButton
));
final
TestGesture
gesture
=
await
tester
.
startGesture
(
center
);
await
tester
.
pump
();
// start the splash animation
await
tester
.
pump
(
const
Duration
(
milliseconds:
100
));
// splash is underway
await
gesture
.
up
();
await
tester
.
pumpAndSettle
();
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
// No change vs enabled and not pressed.
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
colorScheme
.
primary
);
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
const
StadiumBorder
());
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
// Disabled IconButton
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
themeM3
,
home:
const
Center
(
child:
IconButton
.
filled
(
onPressed:
null
,
icon:
Icon
(
Icons
.
ac_unit
),
),
),
),
);
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
colorScheme
.
onSurface
.
withOpacity
(
0.12
));
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
const
StadiumBorder
());
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
expect
(
iconColor
(),
colorScheme
.
onSurface
.
withOpacity
(
0.38
));
});
testWidgets
(
'Toggleable IconButton.fill defaults - M3'
,
(
WidgetTester
tester
)
async
{
final
ThemeData
themeM3
=
ThemeData
.
from
(
colorScheme:
colorScheme
,
useMaterial3:
true
);
// Enabled selected IconButton
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
themeM3
,
home:
Center
(
child:
IconButton
.
filled
(
isSelected:
true
,
onPressed:
()
{
},
icon:
const
Icon
(
Icons
.
ac_unit
),
),
),
),
);
final
Finder
buttonMaterial
=
find
.
descendant
(
of:
find
.
byType
(
IconButton
),
matching:
find
.
byType
(
Material
),
);
Color
?
iconColor
()
=>
_iconStyle
(
tester
,
Icons
.
ac_unit
)?.
color
;
expect
(
iconColor
(),
colorScheme
.
onPrimary
);
Material
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
colorScheme
.
primary
);
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
const
StadiumBorder
());
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
final
Align
align
=
tester
.
firstWidget
<
Align
>(
find
.
ancestor
(
of:
find
.
byIcon
(
Icons
.
ac_unit
),
matching:
find
.
byType
(
Align
)));
expect
(
align
.
alignment
,
Alignment
.
center
);
expect
(
tester
.
getSize
(
find
.
byIcon
(
Icons
.
ac_unit
)),
const
Size
(
24.0
,
24.0
));
final
Offset
center
=
tester
.
getCenter
(
find
.
byType
(
IconButton
));
final
TestGesture
gesture
=
await
tester
.
startGesture
(
center
);
await
tester
.
pump
();
// start the splash animation
await
tester
.
pump
(
const
Duration
(
milliseconds:
100
));
// splash is underway
await
gesture
.
up
();
await
tester
.
pumpAndSettle
();
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
// No change vs enabled and not pressed.
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
colorScheme
.
primary
);
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
const
StadiumBorder
());
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
// Enabled unselected IconButton
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
themeM3
,
home:
Center
(
child:
IconButton
.
filled
(
isSelected:
false
,
onPressed:
()
{
},
icon:
const
Icon
(
Icons
.
ac_unit
),
),
),
),
);
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
colorScheme
.
surfaceVariant
);
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
const
StadiumBorder
());
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
expect
(
iconColor
(),
colorScheme
.
primary
);
// Disabled IconButton
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
themeM3
,
home:
const
Center
(
child:
IconButton
.
filled
(
isSelected:
true
,
onPressed:
null
,
icon:
Icon
(
Icons
.
ac_unit
),
),
),
),
);
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
colorScheme
.
onSurface
.
withOpacity
(
0.12
));
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
const
StadiumBorder
());
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
expect
(
iconColor
(),
colorScheme
.
onSurface
.
withOpacity
(
0.38
));
});
testWidgets
(
'IconButton.filledTonal defaults - M3'
,
(
WidgetTester
tester
)
async
{
final
ThemeData
themeM3
=
ThemeData
.
from
(
colorScheme:
colorScheme
,
useMaterial3:
true
);
// Enabled IconButton.tonal
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
themeM3
,
home:
Center
(
child:
IconButton
.
filledTonal
(
onPressed:
()
{
},
icon:
const
Icon
(
Icons
.
ac_unit
),
),
),
),
);
final
Finder
buttonMaterial
=
find
.
descendant
(
of:
find
.
byType
(
IconButton
),
matching:
find
.
byType
(
Material
),
);
Color
?
iconColor
()
=>
_iconStyle
(
tester
,
Icons
.
ac_unit
)?.
color
;
expect
(
iconColor
(),
colorScheme
.
onSecondaryContainer
);
Material
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
colorScheme
.
secondaryContainer
);
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
const
StadiumBorder
());
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
final
Align
align
=
tester
.
firstWidget
<
Align
>(
find
.
ancestor
(
of:
find
.
byIcon
(
Icons
.
ac_unit
),
matching:
find
.
byType
(
Align
)));
expect
(
align
.
alignment
,
Alignment
.
center
);
expect
(
tester
.
getSize
(
find
.
byIcon
(
Icons
.
ac_unit
)),
const
Size
(
24.0
,
24.0
));
final
Offset
center
=
tester
.
getCenter
(
find
.
byType
(
IconButton
));
final
TestGesture
gesture
=
await
tester
.
startGesture
(
center
);
await
tester
.
pump
();
// start the splash animation
await
tester
.
pump
(
const
Duration
(
milliseconds:
100
));
// splash is underway
await
gesture
.
up
();
await
tester
.
pumpAndSettle
();
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
// No change vs enabled and not pressed.
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
colorScheme
.
secondaryContainer
);
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
const
StadiumBorder
());
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
// Disabled IconButton
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
themeM3
,
home:
const
Center
(
child:
IconButton
.
filledTonal
(
onPressed:
null
,
icon:
Icon
(
Icons
.
ac_unit
),
),
),
),
);
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
colorScheme
.
onSurface
.
withOpacity
(
0.12
));
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
const
StadiumBorder
());
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
expect
(
iconColor
(),
colorScheme
.
onSurface
.
withOpacity
(
0.38
));
});
testWidgets
(
'Toggleable IconButton.filledTonal defaults - M3'
,
(
WidgetTester
tester
)
async
{
final
ThemeData
themeM3
=
ThemeData
.
from
(
colorScheme:
colorScheme
,
useMaterial3:
true
);
// Enabled selected IconButton
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
themeM3
,
home:
Center
(
child:
IconButton
.
filledTonal
(
isSelected:
true
,
onPressed:
()
{
},
icon:
const
Icon
(
Icons
.
ac_unit
),
),
),
),
);
final
Finder
buttonMaterial
=
find
.
descendant
(
of:
find
.
byType
(
IconButton
),
matching:
find
.
byType
(
Material
),
);
Color
?
iconColor
()
=>
_iconStyle
(
tester
,
Icons
.
ac_unit
)?.
color
;
expect
(
iconColor
(),
colorScheme
.
onSecondaryContainer
);
Material
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
colorScheme
.
secondaryContainer
);
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
const
StadiumBorder
());
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
final
Align
align
=
tester
.
firstWidget
<
Align
>(
find
.
ancestor
(
of:
find
.
byIcon
(
Icons
.
ac_unit
),
matching:
find
.
byType
(
Align
)));
expect
(
align
.
alignment
,
Alignment
.
center
);
expect
(
tester
.
getSize
(
find
.
byIcon
(
Icons
.
ac_unit
)),
const
Size
(
24.0
,
24.0
));
final
Offset
center
=
tester
.
getCenter
(
find
.
byType
(
IconButton
));
final
TestGesture
gesture
=
await
tester
.
startGesture
(
center
);
await
tester
.
pump
();
// start the splash animation
await
tester
.
pump
(
const
Duration
(
milliseconds:
100
));
// splash is underway
await
gesture
.
up
();
await
tester
.
pumpAndSettle
();
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
// No change vs enabled and not pressed.
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
colorScheme
.
secondaryContainer
);
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
const
StadiumBorder
());
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
// Enabled unselected IconButton
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
themeM3
,
home:
Center
(
child:
IconButton
.
filledTonal
(
isSelected:
false
,
onPressed:
()
{
},
icon:
const
Icon
(
Icons
.
ac_unit
),
),
),
),
);
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
colorScheme
.
surfaceVariant
);
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
const
StadiumBorder
());
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
expect
(
iconColor
(),
colorScheme
.
onSurfaceVariant
);
// Disabled IconButton
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
themeM3
,
home:
const
Center
(
child:
IconButton
.
filledTonal
(
isSelected:
true
,
onPressed:
null
,
icon:
Icon
(
Icons
.
ac_unit
),
),
),
),
);
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
colorScheme
.
onSurface
.
withOpacity
(
0.12
));
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
const
StadiumBorder
());
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
expect
(
iconColor
(),
colorScheme
.
onSurface
.
withOpacity
(
0.38
));
});
testWidgets
(
'IconButton.outlined defaults - M3'
,
(
WidgetTester
tester
)
async
{
final
ThemeData
themeM3
=
ThemeData
.
from
(
colorScheme:
colorScheme
,
useMaterial3:
true
);
// Enabled IconButton.tonal
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
themeM3
,
home:
Center
(
child:
IconButton
.
outlined
(
onPressed:
()
{
},
icon:
const
Icon
(
Icons
.
ac_unit
),
),
),
),
);
final
Finder
buttonMaterial
=
find
.
descendant
(
of:
find
.
byType
(
IconButton
),
matching:
find
.
byType
(
Material
),
);
Color
?
iconColor
()
=>
_iconStyle
(
tester
,
Icons
.
ac_unit
)?.
color
;
expect
(
iconColor
(),
colorScheme
.
onSurfaceVariant
);
Material
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
Colors
.
transparent
);
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
StadiumBorder
(
side:
BorderSide
(
color:
colorScheme
.
outline
)));
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
final
Align
align
=
tester
.
firstWidget
<
Align
>(
find
.
ancestor
(
of:
find
.
byIcon
(
Icons
.
ac_unit
),
matching:
find
.
byType
(
Align
)));
expect
(
align
.
alignment
,
Alignment
.
center
);
expect
(
tester
.
getSize
(
find
.
byIcon
(
Icons
.
ac_unit
)),
const
Size
(
24.0
,
24.0
));
final
Offset
center
=
tester
.
getCenter
(
find
.
byType
(
IconButton
));
final
TestGesture
gesture
=
await
tester
.
startGesture
(
center
);
await
tester
.
pump
();
// start the splash animation
await
tester
.
pump
(
const
Duration
(
milliseconds:
100
));
// splash is underway
await
gesture
.
up
();
await
tester
.
pumpAndSettle
();
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
// No change vs enabled and not pressed.
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
Colors
.
transparent
);
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
StadiumBorder
(
side:
BorderSide
(
color:
colorScheme
.
outline
)));
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
// Disabled IconButton
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
themeM3
,
home:
const
Center
(
child:
IconButton
.
outlined
(
onPressed:
null
,
icon:
Icon
(
Icons
.
ac_unit
),
),
),
),
);
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
Colors
.
transparent
);
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
StadiumBorder
(
side:
BorderSide
(
color:
colorScheme
.
onSurface
.
withOpacity
(
0.12
))));
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
expect
(
iconColor
(),
colorScheme
.
onSurface
.
withOpacity
(
0.38
));
});
testWidgets
(
'Toggleable IconButton.outlined defaults - M3'
,
(
WidgetTester
tester
)
async
{
final
ThemeData
themeM3
=
ThemeData
.
from
(
colorScheme:
colorScheme
,
useMaterial3:
true
);
// Enabled selected IconButton
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
themeM3
,
home:
Center
(
child:
IconButton
.
outlined
(
isSelected:
true
,
onPressed:
()
{
},
icon:
const
Icon
(
Icons
.
ac_unit
),
),
),
),
);
final
Finder
buttonMaterial
=
find
.
descendant
(
of:
find
.
byType
(
IconButton
),
matching:
find
.
byType
(
Material
),
);
Color
?
iconColor
()
=>
_iconStyle
(
tester
,
Icons
.
ac_unit
)?.
color
;
expect
(
iconColor
(),
colorScheme
.
onInverseSurface
);
Material
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
colorScheme
.
inverseSurface
);
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
const
StadiumBorder
());
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
final
Align
align
=
tester
.
firstWidget
<
Align
>(
find
.
ancestor
(
of:
find
.
byIcon
(
Icons
.
ac_unit
),
matching:
find
.
byType
(
Align
)));
expect
(
align
.
alignment
,
Alignment
.
center
);
expect
(
tester
.
getSize
(
find
.
byIcon
(
Icons
.
ac_unit
)),
const
Size
(
24.0
,
24.0
));
final
Offset
center
=
tester
.
getCenter
(
find
.
byType
(
IconButton
));
final
TestGesture
gesture
=
await
tester
.
startGesture
(
center
);
await
tester
.
pump
();
// start the splash animation
await
tester
.
pump
(
const
Duration
(
milliseconds:
100
));
// splash is underway
await
gesture
.
up
();
await
tester
.
pumpAndSettle
();
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
// No change vs enabled and not pressed.
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
colorScheme
.
inverseSurface
);
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
const
StadiumBorder
());
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
// Enabled unselected IconButton
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
themeM3
,
home:
Center
(
child:
IconButton
.
outlined
(
isSelected:
false
,
onPressed:
()
{
},
icon:
const
Icon
(
Icons
.
ac_unit
),
),
),
),
);
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
Colors
.
transparent
);
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
StadiumBorder
(
side:
BorderSide
(
color:
colorScheme
.
outline
)));
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
expect
(
iconColor
(),
colorScheme
.
onSurfaceVariant
);
// Disabled IconButton
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
themeM3
,
home:
const
Center
(
child:
IconButton
.
outlined
(
isSelected:
true
,
onPressed:
null
,
icon:
Icon
(
Icons
.
ac_unit
),
),
),
),
);
material
=
tester
.
widget
<
Material
>(
buttonMaterial
);
expect
(
material
.
animationDuration
,
const
Duration
(
milliseconds:
200
));
expect
(
material
.
borderOnForeground
,
true
);
expect
(
material
.
borderRadius
,
null
);
expect
(
material
.
clipBehavior
,
Clip
.
none
);
expect
(
material
.
color
,
colorScheme
.
onSurface
.
withOpacity
(
0.12
));
expect
(
material
.
elevation
,
0.0
);
expect
(
material
.
shadowColor
,
Colors
.
transparent
);
expect
(
material
.
shape
,
const
StadiumBorder
());
expect
(
material
.
textStyle
,
null
);
expect
(
material
.
type
,
MaterialType
.
button
);
expect
(
iconColor
(),
colorScheme
.
onSurface
.
withOpacity
(
0.38
));
});
testWidgets
(
'Default IconButton meets a11y contrast guidelines - M3'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'Default IconButton meets a11y contrast guidelines - M3'
,
(
WidgetTester
tester
)
async
{
final
FocusNode
focusNode
=
FocusNode
();
final
FocusNode
focusNode
=
FocusNode
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment