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
4125a3a8
Unverified
Commit
4125a3a8
authored
Sep 01, 2022
by
Qun Cheng
Committed by
GitHub
Sep 01, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed the leading IconButton size (#110722)
parent
69b2dd0f
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
145 additions
and
23 deletions
+145
-23
icon_button_template.dart
dev/tools/gen_defaults/lib/icon_button_template.dart
+1
-1
icon_button.3.dart
examples/api/lib/material/icon_button/icon_button.3.dart
+0
-4
app_bar.dart
packages/flutter/lib/src/material/app_bar.dart
+15
-5
icon_button.dart
packages/flutter/lib/src/material/icon_button.dart
+10
-2
theme_data.dart
packages/flutter/lib/src/material/theme_data.dart
+5
-0
app_bar_test.dart
packages/flutter/test/material/app_bar_test.dart
+48
-9
icon_button_test.dart
packages/flutter/test/material/icon_button_test.dart
+66
-2
No files found.
dev/tools/gen_defaults/lib/icon_button_template.dart
View file @
4125a3a8
...
...
@@ -108,7 +108,7 @@ class _${blockName}DefaultsM3 extends ButtonStyle {
});
@override
VisualDensity? get visualDensity =>
Theme.of(context).visualDensity
;
VisualDensity? get visualDensity =>
VisualDensity.standard
;
@override
MaterialTapTargetSize? get tapTargetSize => Theme.of(context).materialTapTargetSize;
...
...
examples/api/lib/material/icon_button/icon_button.3.dart
View file @
4125a3a8
...
...
@@ -19,10 +19,6 @@ class IconButtonToggleApp extends StatelessWidget {
theme:
ThemeData
(
colorSchemeSeed:
const
Color
(
0xff6750a4
),
useMaterial3:
true
,
// Desktop and web platforms have a compact visual density by default.
// To see buttons with circular background on desktop/web, the "visualDensity"
// needs to be set to "VisualDensity.standard".
visualDensity:
VisualDensity
.
standard
,
),
title:
'Icon Button Types'
,
home:
const
Scaffold
(
...
...
packages/flutter/lib/src/material/app_bar.dart
View file @
4125a3a8
...
...
@@ -1000,10 +1000,20 @@ class _AppBarState extends State<AppBar> {
}
}
if
(
leading
!=
null
)
{
leading
=
ConstrainedBox
(
constraints:
BoxConstraints
.
tightFor
(
width:
widget
.
leadingWidth
??
_kLeadingWidth
),
child:
leading
,
);
// Based on the Material Design 3 specs, the leading IconButton should have
// a size of 48x48, and a highlight size of 40x40. Users can also put other
// type of widgets on leading with the original config.
if
(
theme
.
useMaterial3
)
{
leading
=
ConstrainedBox
(
constraints:
BoxConstraints
.
tightFor
(
width:
widget
.
leadingWidth
??
_kLeadingWidth
),
child:
leading
is
IconButton
?
Center
(
child:
leading
)
:
leading
,
);
}
else
{
leading
=
ConstrainedBox
(
constraints:
BoxConstraints
.
tightFor
(
width:
widget
.
leadingWidth
??
_kLeadingWidth
),
child:
leading
,
);
}
}
Widget
?
title
=
widget
.
title
;
...
...
@@ -1058,7 +1068,7 @@ class _AppBarState extends State<AppBar> {
if
(
widget
.
actions
!=
null
&&
widget
.
actions
!.
isNotEmpty
)
{
actions
=
Row
(
mainAxisSize:
MainAxisSize
.
min
,
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
crossAxisAlignment:
theme
.
useMaterial3
?
CrossAxisAlignment
.
center
:
CrossAxisAlignment
.
stretch
,
children:
widget
.
actions
!,
);
}
else
if
(
hasEndDrawer
)
{
...
...
packages/flutter/lib/src/material/icon_button.dart
View file @
4125a3a8
...
...
@@ -132,6 +132,11 @@ const double _kMinButtonSize = kMinInteractiveDimension;
/// precedence: widget property, [IconButtonTheme] property, [IconTheme] property and
/// internal default property value.
///
/// In Material Design 3, the [IconButton.visualDensity] defaults to [VisualDensity.standard]
/// for all platforms; otherwise the button will have a rounded rectangle shape if
/// the [IconButton.visualDensity] is set to [VisualDensity.compact]. Users can
/// customize it by using [IconButtonTheme], [IconButton.style] or [IconButton.visualDensity].
///
/// {@tool dartpad}
/// This sample shows creation of [IconButton] widgets for standard, filled,
/// filled tonal and outlined types, as described in: https://m3.material.io/components/icon-buttons/overview
...
...
@@ -218,6 +223,9 @@ class IconButton extends StatelessWidget {
///
/// {@macro flutter.material.themedata.visualDensity}
///
/// This property can be null. If null, it defaults to [VisualDensity.standard]
/// in Material Design 3 to make sure the button will be circular on all platforms.
///
/// See also:
///
/// * [ThemeData.visualDensity], which specifies the [visualDensity] for all
...
...
@@ -811,7 +819,7 @@ class _IconButtonM3 extends ButtonStyleButton {
/// * `mouseCursor`
/// * disabled - SystemMouseCursors.basic
/// * others - SystemMouseCursors.click
/// * `visualDensity` -
theme.visualDensity
/// * `visualDensity` -
VisualDensity.standard
/// * `tapTargetSize` - theme.materialTapTargetSize
/// * `animationDuration` - kThemeChangeDuration
/// * `enableFeedback` - true
...
...
@@ -1053,7 +1061,7 @@ class _IconButtonDefaultsM3 extends ButtonStyle {
});
@override
VisualDensity
?
get
visualDensity
=>
Theme
.
of
(
context
).
visualDensity
;
VisualDensity
?
get
visualDensity
=>
VisualDensity
.
standard
;
@override
MaterialTapTargetSize
?
get
tapTargetSize
=>
Theme
.
of
(
context
).
materialTapTargetSize
;
...
...
packages/flutter/lib/src/material/theme_data.dart
View file @
4125a3a8
...
...
@@ -1267,6 +1267,11 @@ class ThemeData with Diagnosticable {
///
/// A larger value translates to a spacing increase (less dense), and a
/// smaller value translates to a spacing decrease (more dense).
///
/// In Material Design 3, the [visualDensity] does not override the value of
/// [IconButton.visualDensity] which defaults to [VisualDensity.standard]
/// for all platforms. To override the default value of [IconButton.visualDensity],
/// use [ThemeData.iconButtonTheme] instead.
/// {@endtemplate}
final
VisualDensity
visualDensity
;
...
...
packages/flutter/test/material/app_bar_test.dart
View file @
4125a3a8
...
...
@@ -693,10 +693,12 @@ void main() {
expect
(
iconColor
(),
color
);
});
testWidgets
(
'leading button extends to edge and is square'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'leading widget extends to edge and is square'
,
(
WidgetTester
tester
)
async
{
final
ThemeData
themeData
=
ThemeData
(
platform:
TargetPlatform
.
android
);
final
bool
material3
=
themeData
.
useMaterial3
;
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
ThemeData
(
platform:
TargetPlatform
.
android
)
,
theme:
themeData
,
home:
Scaffold
(
appBar:
AppBar
(
title:
const
Text
(
'X'
),
...
...
@@ -706,15 +708,52 @@ void main() {
),
);
final
Finder
hamburger
=
find
.
byTooltip
(
'Open navigation menu'
);
expect
(
tester
.
getTopLeft
(
hamburger
),
Offset
.
zero
);
expect
(
tester
.
getSize
(
hamburger
),
const
Size
(
56.0
,
56.0
));
// Default IconButton has a size of (48x48) in M3, (56x56) in M2
final
Finder
hamburger
=
find
.
byType
(
IconButton
);
expect
(
tester
.
getTopLeft
(
hamburger
),
material3
?
const
Offset
(
4.0
,
4.0
)
:
Offset
.
zero
);
expect
(
tester
.
getSize
(
hamburger
),
material3
?
const
Size
(
48.0
,
48.0
)
:
const
Size
(
56.0
,
56.0
));
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
themeData
,
home:
Scaffold
(
appBar:
AppBar
(
leading:
Container
(),
title:
const
Text
(
'X'
),
),
),
),
);
// Default leading widget has a size of (56x56) for both M2 and M3
final
Finder
leadingBox
=
find
.
byType
(
Container
);
expect
(
tester
.
getTopLeft
(
leadingBox
),
Offset
.
zero
);
expect
(
tester
.
getSize
(
leadingBox
),
const
Size
(
56.0
,
56.0
));
// The custom leading widget should still be 56x56 even if its size is smaller.
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
themeData
,
home:
Scaffold
(
appBar:
AppBar
(
leading:
const
SizedBox
(
height:
36
,
width:
36
,),
title:
const
Text
(
'X'
),
),
// Doesn't really matter. Triggers a hamburger regardless.
),
),
);
final
Finder
leading
=
find
.
byType
(
SizedBox
);
expect
(
tester
.
getTopLeft
(
leading
),
Offset
.
zero
);
expect
(
tester
.
getSize
(
leading
),
const
Size
(
56.0
,
56.0
));
});
testWidgets
(
'test action is 4dp from edge and 48dp min'
,
(
WidgetTester
tester
)
async
{
final
ThemeData
theme
=
ThemeData
(
platform:
TargetPlatform
.
android
);
final
bool
material3
=
theme
.
useMaterial3
;
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
ThemeData
(
platform:
TargetPlatform
.
android
)
,
theme:
theme
,
home:
Scaffold
(
appBar:
AppBar
(
title:
const
Text
(
'X'
),
...
...
@@ -737,14 +776,14 @@ void main() {
),
);
final
Finder
addButton
=
find
.
byTooltip
(
'Add'
);
final
Finder
addButton
=
find
.
widgetWithIcon
(
IconButton
,
Icons
.
add
);
expect
(
tester
.
getTopRight
(
addButton
),
const
Offset
(
800.0
,
0.0
));
// It's still the size it was plus the 2 * 8dp padding from IconButton.
expect
(
tester
.
getSize
(
addButton
),
const
Size
(
60.0
+
2
*
8.0
,
56.0
));
final
Finder
shareButton
=
find
.
byTooltip
(
'Share'
);
final
Finder
shareButton
=
find
.
widgetWithIcon
(
IconButton
,
Icons
.
share
);
// The 20dp icon is expanded to fill the IconButton's touch target to 48dp.
expect
(
tester
.
getSize
(
shareButton
),
const
Size
(
48.0
,
56.0
));
expect
(
tester
.
getSize
(
shareButton
),
material3
?
const
Size
(
48.0
,
48.0
)
:
const
Size
(
48.0
,
56.0
));
});
testWidgets
(
'SliverAppBar default configuration'
,
(
WidgetTester
tester
)
async
{
...
...
packages/flutter/test/material/icon_button_test.dart
View file @
4125a3a8
...
...
@@ -275,11 +275,23 @@ void main() {
testWidgets
(
'Small icons comply with VisualDensity requirements'
,
(
WidgetTester
tester
)
async
{
final
bool
material3
=
theme
.
useMaterial3
;
final
ThemeData
themeDataM2
=
ThemeData
(
useMaterial3:
material3
,
visualDensity:
const
VisualDensity
(
horizontal:
1
,
vertical:
-
1
),
);
final
ThemeData
themeDataM3
=
ThemeData
(
useMaterial3:
material3
,
iconButtonTheme:
IconButtonThemeData
(
style:
IconButton
.
styleFrom
(
visualDensity:
const
VisualDensity
(
horizontal:
1
,
vertical:
-
1
)
)
),
);
await
tester
.
pumpWidget
(
wrap
(
useMaterial3:
material3
,
child:
Theme
(
data:
ThemeData
(
visualDensity:
const
VisualDensity
(
horizontal:
1
,
vertical:
-
1
),
useMaterial3:
material3
)
,
data:
material3
?
themeDataM3
:
themeDataM2
,
child:
IconButton
(
iconSize:
10.0
,
onPressed:
mockOnPressedFunction
.
handler
,
...
...
@@ -435,6 +447,7 @@ void main() {
});
testWidgets
(
'IconButton AppBar size'
,
(
WidgetTester
tester
)
async
{
final
bool
material3
=
theme
.
useMaterial3
;
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
theme
,
...
...
@@ -454,7 +467,8 @@ void main() {
final
RenderBox
barBox
=
tester
.
renderObject
(
find
.
byType
(
AppBar
));
final
RenderBox
iconBox
=
tester
.
renderObject
(
find
.
byType
(
IconButton
));
expect
(
iconBox
.
size
.
height
,
equals
(
barBox
.
size
.
height
));
expect
(
iconBox
.
size
.
height
,
material3
?
48
:
equals
(
barBox
.
size
.
height
));
expect
(
tester
.
getCenter
(
find
.
byType
(
IconButton
)).
dy
,
28
);
});
// This test is very similar to the '...explicit splashColor and highlightColor' test
...
...
@@ -1629,6 +1643,56 @@ void main() {
expect
(
find
.
byIcon
(
Icons
.
ac_unit
),
findsOneWidget
);
});
testWidgets
(
'The visualDensity of M3 IconButton can be configured by IconButtonTheme, '
'but cannot be configured by ThemeData - M3'
,
(
WidgetTester
tester
)
async
{
Future
<
void
>
buildTest
({
VisualDensity
?
iconButtonThemeVisualDensity
,
VisualDensity
?
themeVisualDensity
})
async
{
return
tester
.
pumpWidget
(
MaterialApp
(
theme:
ThemeData
.
from
(
colorScheme:
colorScheme
,
useMaterial3:
true
).
copyWith
(
iconButtonTheme:
IconButtonThemeData
(
style:
IconButton
.
styleFrom
(
visualDensity:
iconButtonThemeVisualDensity
)
),
visualDensity:
themeVisualDensity
),
home:
Material
(
child:
Center
(
child:
IconButton
(
onPressed:
()
{},
icon:
const
Icon
(
Icons
.
play_arrow
),
),
),
),
),
);
}
await
buildTest
(
iconButtonThemeVisualDensity:
VisualDensity
.
standard
);
final
RenderBox
box
=
tester
.
renderObject
(
find
.
byType
(
IconButton
));
await
tester
.
pumpAndSettle
();
expect
(
box
.
size
,
equals
(
const
Size
(
48
,
48
)));
await
buildTest
(
iconButtonThemeVisualDensity:
VisualDensity
.
compact
);
await
tester
.
pumpAndSettle
();
expect
(
box
.
size
,
equals
(
const
Size
(
40
,
40
)));
await
buildTest
(
iconButtonThemeVisualDensity:
const
VisualDensity
(
horizontal:
3.0
,
vertical:
3.0
));
await
tester
.
pumpAndSettle
();
expect
(
box
.
size
,
equals
(
const
Size
(
64
,
64
)));
// ThemeData.visualDensity will be ignored because useMaterial3 is true
await
buildTest
(
themeVisualDensity:
VisualDensity
.
standard
);
await
tester
.
pumpAndSettle
();
expect
(
box
.
size
,
equals
(
const
Size
(
48
,
48
)));
await
buildTest
(
themeVisualDensity:
VisualDensity
.
compact
);
await
tester
.
pumpAndSettle
();
expect
(
box
.
size
,
equals
(
const
Size
(
48
,
48
)));
await
buildTest
(
themeVisualDensity:
const
VisualDensity
(
horizontal:
3.0
,
vertical:
3.0
));
await
tester
.
pumpAndSettle
();
expect
(
box
.
size
,
equals
(
const
Size
(
48
,
48
)));
});
group
(
'IconTheme tests in Material 3'
,
()
{
testWidgets
(
'IconTheme overrides default values in M3'
,
(
WidgetTester
tester
)
async
{
// Theme's IconTheme
...
...
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