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
b4058b95
Unverified
Commit
b4058b95
authored
Oct 24, 2022
by
Taha Tesser
Committed by
GitHub
Oct 24, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update Popup Menu to support Material 3 (#103606)
parent
700b449d
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
636 additions
and
141 deletions
+636
-141
gen_defaults.dart
dev/tools/gen_defaults/bin/gen_defaults.dart
+2
-0
popup_menu_template.dart
dev/tools/gen_defaults/lib/popup_menu_template.dart
+46
-0
popup_menu.dart
packages/flutter/lib/src/material/popup_menu.dart
+119
-7
popup_menu_theme.dart
packages/flutter/lib/src/material/popup_menu_theme.dart
+32
-1
popup_menu_theme_test.dart
packages/flutter/test/material/popup_menu_theme_test.dart
+437
-133
No files found.
dev/tools/gen_defaults/bin/gen_defaults.dart
View file @
b4058b95
...
...
@@ -33,6 +33,7 @@ import 'package:gen_defaults/input_chip_template.dart';
import
'package:gen_defaults/input_decorator_template.dart'
;
import
'package:gen_defaults/navigation_bar_template.dart'
;
import
'package:gen_defaults/navigation_rail_template.dart'
;
import
'package:gen_defaults/popup_menu_template.dart'
;
import
'package:gen_defaults/progress_indicator_template.dart'
;
import
'package:gen_defaults/radio_template.dart'
;
import
'package:gen_defaults/surface_tint.dart'
;
...
...
@@ -136,6 +137,7 @@ Future<void> main(List<String> args) async {
InputDecoratorTemplate
(
'InputDecorator'
,
'
$materialLib
/input_decorator.dart'
,
tokens
).
updateFile
();
NavigationBarTemplate
(
'NavigationBar'
,
'
$materialLib
/navigation_bar.dart'
,
tokens
).
updateFile
();
NavigationRailTemplate
(
'NavigationRail'
,
'
$materialLib
/navigation_rail.dart'
,
tokens
).
updateFile
();
PopupMenuTemplate
(
'PopupMenu'
,
'
$materialLib
/popup_menu.dart'
,
tokens
).
updateFile
();
ProgressIndicatorTemplate
(
'ProgressIndicator'
,
'
$materialLib
/progress_indicator.dart'
,
tokens
).
updateFile
();
RadioTemplate
(
'Radio<T>'
,
'
$materialLib
/radio.dart'
,
tokens
).
updateFile
();
SurfaceTintTemplate
(
'SurfaceTint'
,
'
$materialLib
/elevation_overlay.dart'
,
tokens
).
updateFile
();
...
...
dev/tools/gen_defaults/lib/popup_menu_template.dart
0 → 100644
View file @
b4058b95
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'template.dart'
;
class
PopupMenuTemplate
extends
TokenTemplate
{
const
PopupMenuTemplate
(
super
.
blockName
,
super
.
fileName
,
super
.
tokens
,
{
super
.
colorSchemePrefix
=
'_colors.'
,
super
.
textThemePrefix
=
'_textTheme.'
,
});
@override
String
generate
()
=>
'''
class _
${blockName}
DefaultsM3 extends PopupMenuThemeData {
_
${blockName}
DefaultsM3(this.context)
: super(elevation:
${elevation('md.comp.menu.container')}
);
final BuildContext context;
late final ThemeData _theme = Theme.of(context);
late final ColorScheme _colors = _theme.colorScheme;
late final TextTheme _textTheme = _theme.textTheme;
@override MaterialStateProperty<TextStyle?>? get labelTextStyle {
return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
final TextStyle style = _textTheme.labelLarge!;
if (states.contains(MaterialState.disabled)) {
return style.apply(color:
${componentColor('md.comp.menu.list-item.disabled.label-text')}
);
}
return style.apply(color:
${componentColor('md.comp.menu.list-item.label-text')}
);
});
}
@override
Color? get color =>
${componentColor('md.comp.menu.container')}
;
@override
Color? get shadowColor =>
${color("md.comp.menu.container.shadow-color")}
;
@override
Color? get surfaceTintColor =>
${color("md.comp.menu.container.surface-tint-layer.color")}
;
@override
ShapeBorder? get shape =>
${shape("md.comp.menu.container")}
;
}'''
;
}
packages/flutter/lib/src/material/popup_menu.dart
View file @
b4058b95
...
...
@@ -6,6 +6,7 @@ import 'package:flutter/foundation.dart';
import
'package:flutter/rendering.dart'
;
import
'package:flutter/widgets.dart'
;
import
'color_scheme.dart'
;
import
'constants.dart'
;
import
'debug.dart'
;
import
'divider.dart'
;
...
...
@@ -17,6 +18,7 @@ import 'material.dart';
import
'material_localizations.dart'
;
import
'material_state.dart'
;
import
'popup_menu_theme.dart'
;
import
'text_theme.dart'
;
import
'theme.dart'
;
import
'tooltip.dart'
;
...
...
@@ -224,6 +226,7 @@ class PopupMenuItem<T> extends PopupMenuEntry<T> {
this
.
height
=
kMinInteractiveDimension
,
this
.
padding
,
this
.
textStyle
,
this
.
labelTextStyle
,
this
.
mouseCursor
,
required
this
.
child
,
})
:
assert
(
enabled
!=
null
),
...
...
@@ -263,6 +266,16 @@ class PopupMenuItem<T> extends PopupMenuEntry<T> {
/// of [ThemeData.textTheme] is used.
final
TextStyle
?
textStyle
;
/// The label style of the popup menu item.
///
/// When [ThemeData.useMaterial3] is true, this styles the text of the popup menu item.
///
/// If this property is null, then [PopupMenuThemeData.labelTextStyle] is used.
/// If [PopupMenuThemeData.labelTextStyle] is also null, then [TextTheme.labelLarge]
/// is used with the [ColorScheme.onSurface] color when popup menu item is enabled and
/// the [ColorScheme.onSurface] color with 0.38 opacity when the popup menu item is disabled.
final
MaterialStateProperty
<
TextStyle
?>?
labelTextStyle
;
/// {@template flutter.material.popupmenu.mouseCursor}
/// The cursor for a mouse pointer when it enters or is hovering over the
/// widget.
...
...
@@ -336,9 +349,20 @@ class PopupMenuItemState<T, W extends PopupMenuItem<T>> extends State<W> {
Widget
build
(
BuildContext
context
)
{
final
ThemeData
theme
=
Theme
.
of
(
context
);
final
PopupMenuThemeData
popupMenuTheme
=
PopupMenuTheme
.
of
(
context
);
TextStyle
style
=
widget
.
textStyle
??
popupMenuTheme
.
textStyle
??
theme
.
textTheme
.
titleMedium
!;
if
(!
widget
.
enabled
)
{
final
PopupMenuThemeData
defaults
=
theme
.
useMaterial3
?
_PopupMenuDefaultsM3
(
context
)
:
_PopupMenuDefaultsM2
(
context
);
final
Set
<
MaterialState
>
states
=
<
MaterialState
>{
if
(!
widget
.
enabled
)
MaterialState
.
disabled
,
};
TextStyle
style
=
theme
.
useMaterial3
?
(
widget
.
labelTextStyle
?.
resolve
(
states
)
??
popupMenuTheme
.
labelTextStyle
?.
resolve
(
states
)!
??
defaults
.
labelTextStyle
!.
resolve
(
states
)!)
:
(
widget
.
textStyle
??
popupMenuTheme
.
textStyle
??
defaults
.
textStyle
!);
if
(!
widget
.
enabled
&&
!
theme
.
useMaterial3
)
{
style
=
style
.
copyWith
(
color:
theme
.
disabledColor
);
}
...
...
@@ -537,7 +561,9 @@ class _PopupMenu<T> extends StatelessWidget {
Widget
build
(
BuildContext
context
)
{
final
double
unit
=
1.0
/
(
route
.
items
.
length
+
1.5
);
// 1.0 for the width and 0.5 for the last item's fade.
final
List
<
Widget
>
children
=
<
Widget
>[];
final
ThemeData
theme
=
Theme
.
of
(
context
);
final
PopupMenuThemeData
popupMenuTheme
=
PopupMenuTheme
.
of
(
context
);
final
PopupMenuThemeData
defaults
=
theme
.
useMaterial3
?
_PopupMenuDefaultsM3
(
context
)
:
_PopupMenuDefaultsM2
(
context
);
for
(
int
i
=
0
;
i
<
route
.
items
.
length
;
i
+=
1
)
{
final
double
start
=
(
i
+
1
)
*
unit
;
...
...
@@ -598,11 +624,13 @@ class _PopupMenu<T> extends StatelessWidget {
return
FadeTransition
(
opacity:
opacity
.
animate
(
route
.
animation
!),
child:
Material
(
shape:
route
.
shape
??
popupMenuTheme
.
shape
,
color:
route
.
color
??
popupMenuTheme
.
color
,
shape:
route
.
shape
??
popupMenuTheme
.
shape
??
defaults
.
shape
,
color:
route
.
color
??
popupMenuTheme
.
color
??
defaults
.
color
,
clipBehavior:
clipBehavior
,
type:
MaterialType
.
card
,
elevation:
route
.
elevation
??
popupMenuTheme
.
elevation
??
8.0
,
elevation:
route
.
elevation
??
popupMenuTheme
.
elevation
??
defaults
.
elevation
!,
shadowColor:
route
.
shadowColor
??
popupMenuTheme
.
shadowColor
??
defaults
.
shadowColor
,
surfaceTintColor:
route
.
surfaceTintColor
??
popupMenuTheme
.
surfaceTintColor
??
defaults
.
surfaceTintColor
,
child:
Align
(
alignment:
AlignmentDirectional
.
topEnd
,
widthFactor:
width
.
evaluate
(
route
.
animation
!),
...
...
@@ -757,6 +785,8 @@ class _PopupMenuRoute<T> extends PopupRoute<T> {
required
this
.
items
,
this
.
initialValue
,
this
.
elevation
,
this
.
surfaceTintColor
,
this
.
shadowColor
,
required
this
.
barrierLabel
,
this
.
semanticLabel
,
this
.
shape
,
...
...
@@ -771,6 +801,8 @@ class _PopupMenuRoute<T> extends PopupRoute<T> {
final
List
<
Size
?>
itemSizes
;
final
T
?
initialValue
;
final
double
?
elevation
;
final
Color
?
surfaceTintColor
;
final
Color
?
shadowColor
;
final
String
?
semanticLabel
;
final
ShapeBorder
?
shape
;
final
Color
?
color
;
...
...
@@ -911,6 +943,8 @@ Future<T?> showMenu<T>({
required
List
<
PopupMenuEntry
<
T
>>
items
,
T
?
initialValue
,
double
?
elevation
,
Color
?
shadowColor
,
Color
?
surfaceTintColor
,
String
?
semanticLabel
,
ShapeBorder
?
shape
,
Color
?
color
,
...
...
@@ -941,6 +975,8 @@ Future<T?> showMenu<T>({
items:
items
,
initialValue:
initialValue
,
elevation:
elevation
,
shadowColor:
shadowColor
,
surfaceTintColor:
surfaceTintColor
,
semanticLabel:
semanticLabel
,
barrierLabel:
MaterialLocalizations
.
of
(
context
).
modalBarrierDismissLabel
,
shape:
shape
,
...
...
@@ -1006,6 +1042,8 @@ class PopupMenuButton<T> extends StatefulWidget {
this
.
onCanceled
,
this
.
tooltip
,
this
.
elevation
,
this
.
shadowColor
,
this
.
surfaceTintColor
,
this
.
padding
=
const
EdgeInsets
.
all
(
8.0
),
this
.
child
,
this
.
splashRadius
,
...
...
@@ -1058,6 +1096,22 @@ class PopupMenuButton<T> extends StatefulWidget {
/// Defaults to 8, the appropriate elevation for popup menus.
final
double
?
elevation
;
/// The color used to paint the shadow below the menu.
///
/// If null then the ambient [PopupMenuThemeData.shadowColor] is used.
/// If that is null too, then the overall theme's [ThemeData.shadowColor]
/// (default black) is used.
final
Color
?
shadowColor
;
/// The color used as an overlay on [color] to indicate elevation.
///
/// If null, [PopupMenuThemeData.surfaceTintColor] is used. If that
/// is also null, the default value is [ColorScheme.surfaceTint].
///
/// See [Material.surfaceTintColor] for more details on how this
/// overlay is applied.
final
Color
?
surfaceTintColor
;
/// Matches IconButton's 8 dps padding by default. In some cases, notably where
/// this button appears as the trailing element of a list item, it's useful to be able
/// to set the padding to zero.
...
...
@@ -1207,6 +1261,8 @@ class PopupMenuButtonState<T> extends State<PopupMenuButton<T>> {
showMenu
<
T
?>(
context:
context
,
elevation:
widget
.
elevation
??
popupMenuTheme
.
elevation
,
shadowColor:
widget
.
shadowColor
??
popupMenuTheme
.
shadowColor
,
surfaceTintColor:
widget
.
surfaceTintColor
??
popupMenuTheme
.
surfaceTintColor
,
items:
items
,
initialValue:
widget
.
initialValue
,
position:
position
,
...
...
@@ -1240,6 +1296,7 @@ class PopupMenuButtonState<T> extends State<PopupMenuButton<T>> {
@override
Widget
build
(
BuildContext
context
)
{
final
IconThemeData
iconTheme
=
IconTheme
.
of
(
context
);
final
bool
enableFeedback
=
widget
.
enableFeedback
??
PopupMenuTheme
.
of
(
context
).
enableFeedback
??
true
;
...
...
@@ -1263,7 +1320,8 @@ class PopupMenuButtonState<T> extends State<PopupMenuButton<T>> {
icon:
widget
.
icon
??
Icon
(
Icons
.
adaptive
.
more
),
padding:
widget
.
padding
,
splashRadius:
widget
.
splashRadius
,
iconSize:
widget
.
iconSize
,
iconSize:
widget
.
iconSize
??
iconTheme
.
size
,
color:
widget
.
color
??
iconTheme
.
color
,
tooltip:
widget
.
tooltip
??
MaterialLocalizations
.
of
(
context
).
showMenuTooltip
,
onPressed:
widget
.
enabled
?
showButtonMenu
:
null
,
enableFeedback:
enableFeedback
,
...
...
@@ -1290,3 +1348,57 @@ class _EffectiveMouseCursor extends MaterialStateMouseCursor {
@override
String
get
debugDescription
=>
'MaterialStateMouseCursor(PopupMenuItemState)'
;
}
class
_PopupMenuDefaultsM2
extends
PopupMenuThemeData
{
_PopupMenuDefaultsM2
(
this
.
context
)
:
super
(
elevation:
8.0
);
final
BuildContext
context
;
late
final
ThemeData
_theme
=
Theme
.
of
(
context
);
late
final
TextTheme
_textTheme
=
_theme
.
textTheme
;
@override
TextStyle
?
get
textStyle
=>
_textTheme
.
subtitle1
;
}
// BEGIN GENERATED TOKEN PROPERTIES - PopupMenu
// 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_132
class
_PopupMenuDefaultsM3
extends
PopupMenuThemeData
{
_PopupMenuDefaultsM3
(
this
.
context
)
:
super
(
elevation:
3.0
);
final
BuildContext
context
;
late
final
ThemeData
_theme
=
Theme
.
of
(
context
);
late
final
ColorScheme
_colors
=
_theme
.
colorScheme
;
late
final
TextTheme
_textTheme
=
_theme
.
textTheme
;
@override
MaterialStateProperty
<
TextStyle
?>?
get
labelTextStyle
{
return
MaterialStateProperty
.
resolveWith
((
Set
<
MaterialState
>
states
)
{
final
TextStyle
style
=
_textTheme
.
labelLarge
!;
if
(
states
.
contains
(
MaterialState
.
disabled
))
{
return
style
.
apply
(
color:
_colors
.
onSurface
.
withOpacity
(
0.38
));
}
return
style
.
apply
(
color:
_colors
.
onSurface
);
});
}
@override
Color
?
get
color
=>
_colors
.
surface
;
@override
Color
?
get
shadowColor
=>
_colors
.
shadow
;
@override
Color
?
get
surfaceTintColor
=>
_colors
.
surfaceTint
;
@override
ShapeBorder
?
get
shape
=>
const
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
all
(
Radius
.
circular
(
4.0
)));
}
// END GENERATED TOKEN PROPERTIES - PopupMenu
packages/flutter/lib/src/material/popup_menu_theme.dart
View file @
b4058b95
...
...
@@ -48,7 +48,10 @@ class PopupMenuThemeData with Diagnosticable {
this
.
color
,
this
.
shape
,
this
.
elevation
,
this
.
shadowColor
,
this
.
surfaceTintColor
,
this
.
textStyle
,
this
.
labelTextStyle
,
this
.
enableFeedback
,
this
.
mouseCursor
,
this
.
position
,
...
...
@@ -63,9 +66,19 @@ class PopupMenuThemeData with Diagnosticable {
/// The elevation of the popup menu.
final
double
?
elevation
;
/// The color used to paint shadow below the popup menu.
final
Color
?
shadowColor
;
/// The color used as an overlay on [color] of the popup menu.
final
Color
?
surfaceTintColor
;
/// The text style of items in the popup menu.
final
TextStyle
?
textStyle
;
/// You can use this to specify a different style of the label
/// when the popup menu item is enabled and disabled.
final
MaterialStateProperty
<
TextStyle
?>?
labelTextStyle
;
/// If specified, defines the feedback property for [PopupMenuButton].
///
/// If [PopupMenuButton.enableFeedback] is provided, [enableFeedback] is ignored.
...
...
@@ -88,7 +101,10 @@ class PopupMenuThemeData with Diagnosticable {
Color
?
color
,
ShapeBorder
?
shape
,
double
?
elevation
,
Color
?
shadowColor
,
Color
?
surfaceTintColor
,
TextStyle
?
textStyle
,
MaterialStateProperty
<
TextStyle
?>?
labelTextStyle
,
bool
?
enableFeedback
,
MaterialStateProperty
<
MouseCursor
?>?
mouseCursor
,
PopupMenuPosition
?
position
,
...
...
@@ -97,7 +113,10 @@ class PopupMenuThemeData with Diagnosticable {
color:
color
??
this
.
color
,
shape:
shape
??
this
.
shape
,
elevation:
elevation
??
this
.
elevation
,
shadowColor:
shadowColor
??
this
.
shadowColor
,
surfaceTintColor:
surfaceTintColor
??
this
.
surfaceTintColor
,
textStyle:
textStyle
??
this
.
textStyle
,
labelTextStyle:
labelTextStyle
??
this
.
labelTextStyle
,
enableFeedback:
enableFeedback
??
this
.
enableFeedback
,
mouseCursor:
mouseCursor
??
this
.
mouseCursor
,
position:
position
??
this
.
position
,
...
...
@@ -118,7 +137,10 @@ class PopupMenuThemeData with Diagnosticable {
color:
Color
.
lerp
(
a
?.
color
,
b
?.
color
,
t
),
shape:
ShapeBorder
.
lerp
(
a
?.
shape
,
b
?.
shape
,
t
),
elevation:
lerpDouble
(
a
?.
elevation
,
b
?.
elevation
,
t
),
shadowColor:
Color
.
lerp
(
a
?.
shadowColor
,
b
?.
shadowColor
,
t
),
surfaceTintColor:
Color
.
lerp
(
a
?.
surfaceTintColor
,
b
?.
surfaceTintColor
,
t
),
textStyle:
TextStyle
.
lerp
(
a
?.
textStyle
,
b
?.
textStyle
,
t
),
labelTextStyle:
MaterialStateProperty
.
lerp
<
TextStyle
?>(
a
?.
labelTextStyle
,
b
?.
labelTextStyle
,
t
,
TextStyle
.
lerp
),
enableFeedback:
t
<
0.5
?
a
?.
enableFeedback
:
b
?.
enableFeedback
,
mouseCursor:
t
<
0.5
?
a
?.
mouseCursor
:
b
?.
mouseCursor
,
position:
t
<
0.5
?
a
?.
position
:
b
?.
position
,
...
...
@@ -130,7 +152,10 @@ class PopupMenuThemeData with Diagnosticable {
color
,
shape
,
elevation
,
shadowColor
,
surfaceTintColor
,
textStyle
,
labelTextStyle
,
enableFeedback
,
mouseCursor
,
position
,
...
...
@@ -145,10 +170,13 @@ class PopupMenuThemeData with Diagnosticable {
return
false
;
}
return
other
is
PopupMenuThemeData
&&
other
.
elevation
==
elevation
&&
other
.
color
==
color
&&
other
.
shape
==
shape
&&
other
.
elevation
==
elevation
&&
other
.
shadowColor
==
shadowColor
&&
other
.
surfaceTintColor
==
surfaceTintColor
&&
other
.
textStyle
==
textStyle
&&
other
.
labelTextStyle
==
labelTextStyle
&&
other
.
enableFeedback
==
enableFeedback
&&
other
.
mouseCursor
==
mouseCursor
&&
other
.
position
==
position
;
...
...
@@ -160,7 +188,10 @@ class PopupMenuThemeData with Diagnosticable {
properties
.
add
(
ColorProperty
(
'color'
,
color
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
ShapeBorder
>(
'shape'
,
shape
,
defaultValue:
null
));
properties
.
add
(
DoubleProperty
(
'elevation'
,
elevation
,
defaultValue:
null
));
properties
.
add
(
ColorProperty
(
'shadowColor'
,
shadowColor
,
defaultValue:
null
));
properties
.
add
(
ColorProperty
(
'surfaceTintColor'
,
surfaceTintColor
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
TextStyle
>(
'text style'
,
textStyle
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
MaterialStateProperty
<
TextStyle
?>>(
'labelTextStyle'
,
labelTextStyle
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
bool
>(
'enableFeedback'
,
enableFeedback
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
MaterialStateProperty
<
MouseCursor
?>>(
'mouseCursor'
,
mouseCursor
,
defaultValue:
null
));
properties
.
add
(
EnumProperty
<
PopupMenuPosition
?>(
'position'
,
position
,
defaultValue:
null
));
...
...
packages/flutter/test/material/popup_menu_theme_test.dart
View file @
b4058b95
This diff is collapsed.
Click to expand it.
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