Unverified Commit ccaf5156 authored by Taha Tesser's avatar Taha Tesser Committed by GitHub

Add custom size constraints parameter to `PopupMenu` (#97798)

parent ff425fc7
...@@ -529,10 +529,12 @@ class _PopupMenu<T> extends StatelessWidget { ...@@ -529,10 +529,12 @@ class _PopupMenu<T> extends StatelessWidget {
Key? key, Key? key,
required this.route, required this.route,
required this.semanticLabel, required this.semanticLabel,
this.constraints,
}) : super(key: key); }) : super(key: key);
final _PopupMenuRoute<T> route; final _PopupMenuRoute<T> route;
final String? semanticLabel; final String? semanticLabel;
final BoxConstraints? constraints;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -572,7 +574,7 @@ class _PopupMenu<T> extends StatelessWidget { ...@@ -572,7 +574,7 @@ class _PopupMenu<T> extends StatelessWidget {
final CurveTween height = CurveTween(curve: Interval(0.0, unit * route.items.length)); final CurveTween height = CurveTween(curve: Interval(0.0, unit * route.items.length));
final Widget child = ConstrainedBox( final Widget child = ConstrainedBox(
constraints: const BoxConstraints( constraints: constraints ?? const BoxConstraints(
minWidth: _kMenuMinWidth, minWidth: _kMenuMinWidth,
maxWidth: _kMenuMaxWidth, maxWidth: _kMenuMaxWidth,
), ),
...@@ -735,6 +737,7 @@ class _PopupMenuRoute<T> extends PopupRoute<T> { ...@@ -735,6 +737,7 @@ class _PopupMenuRoute<T> extends PopupRoute<T> {
this.shape, this.shape,
this.color, this.color,
required this.capturedThemes, required this.capturedThemes,
this.constraints,
}) : itemSizes = List<Size?>.filled(items.length, null); }) : itemSizes = List<Size?>.filled(items.length, null);
final RelativeRect position; final RelativeRect position;
...@@ -746,6 +749,7 @@ class _PopupMenuRoute<T> extends PopupRoute<T> { ...@@ -746,6 +749,7 @@ class _PopupMenuRoute<T> extends PopupRoute<T> {
final ShapeBorder? shape; final ShapeBorder? shape;
final Color? color; final Color? color;
final CapturedThemes capturedThemes; final CapturedThemes capturedThemes;
final BoxConstraints? constraints;
@override @override
Animation<double> createAnimation() { Animation<double> createAnimation() {
...@@ -779,7 +783,11 @@ class _PopupMenuRoute<T> extends PopupRoute<T> { ...@@ -779,7 +783,11 @@ class _PopupMenuRoute<T> extends PopupRoute<T> {
} }
} }
final Widget menu = _PopupMenu<T>(route: this, semanticLabel: semanticLabel); final Widget menu = _PopupMenu<T>(
route: this,
semanticLabel: semanticLabel,
constraints: constraints,
);
final MediaQueryData mediaQuery = MediaQuery.of(context); final MediaQueryData mediaQuery = MediaQuery.of(context);
return MediaQuery.removePadding( return MediaQuery.removePadding(
context: context, context: context,
...@@ -870,6 +878,7 @@ Future<T?> showMenu<T>({ ...@@ -870,6 +878,7 @@ Future<T?> showMenu<T>({
ShapeBorder? shape, ShapeBorder? shape,
Color? color, Color? color,
bool useRootNavigator = false, bool useRootNavigator = false,
BoxConstraints? constraints,
}) { }) {
assert(context != null); assert(context != null);
assert(position != null); assert(position != null);
...@@ -899,6 +908,7 @@ Future<T?> showMenu<T>({ ...@@ -899,6 +908,7 @@ Future<T?> showMenu<T>({
shape: shape, shape: shape,
color: color, color: color,
capturedThemes: InheritedTheme.capture(from: context, to: navigator.context), capturedThemes: InheritedTheme.capture(from: context, to: navigator.context),
constraints: constraints,
)); ));
} }
...@@ -966,6 +976,7 @@ class PopupMenuButton<T> extends StatefulWidget { ...@@ -966,6 +976,7 @@ class PopupMenuButton<T> extends StatefulWidget {
this.shape, this.shape,
this.color, this.color,
this.enableFeedback, this.enableFeedback,
this.constraints,
}) : assert(itemBuilder != null), }) : assert(itemBuilder != null),
assert(offset != null), assert(offset != null),
assert(enabled != null), assert(enabled != null),
...@@ -1072,6 +1083,22 @@ class PopupMenuButton<T> extends StatefulWidget { ...@@ -1072,6 +1083,22 @@ class PopupMenuButton<T> extends StatefulWidget {
/// If this property is null, the default size is 24.0 pixels. /// If this property is null, the default size is 24.0 pixels.
final double? iconSize; final double? iconSize;
/// Optional size constraints for the menu.
///
/// When unspecified, defaults to:
/// ```dart
/// const BoxConstraints(
/// minWidth: 2.0 * 56.0,
/// maxWidth: 5.0 * 56.0,
/// )
/// ```
///
/// The default constraints ensure that the menu width matches maximum width
/// recommended by the material design guidelines.
/// Specifying this parameter enables creation of menu wider than
/// the default maximum width.
final BoxConstraints? constraints;
@override @override
PopupMenuButtonState<T> createState() => PopupMenuButtonState<T>(); PopupMenuButtonState<T> createState() => PopupMenuButtonState<T>();
} }
...@@ -1111,6 +1138,7 @@ class PopupMenuButtonState<T> extends State<PopupMenuButton<T>> { ...@@ -1111,6 +1138,7 @@ class PopupMenuButtonState<T> extends State<PopupMenuButton<T>> {
position: position, position: position,
shape: widget.shape ?? popupMenuTheme.shape, shape: widget.shape ?? popupMenuTheme.shape,
color: widget.color ?? popupMenuTheme.color, color: widget.color ?? popupMenuTheme.color,
constraints: widget.constraints,
) )
.then<void>((T? newValue) { .then<void>((T? newValue) {
if (!mounted) if (!mounted)
......
...@@ -2536,6 +2536,39 @@ void main() { ...@@ -2536,6 +2536,39 @@ void main() {
expect(tester.widget<InkWell>(find.byType(InkWell)).radius, expect(tester.widget<InkWell>(find.byType(InkWell)).radius,
testSplashRadius); testSplashRadius);
}); });
testWidgets('Can override menu size constraints', (WidgetTester tester) async {
final Key popupMenuButtonKey = UniqueKey();
final Type menuItemType = const PopupMenuItem<String>(child: Text('item')).runtimeType;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: Center(
child: PopupMenuButton<String>(
key: popupMenuButtonKey,
constraints: const BoxConstraints(
minWidth: 500,
),
itemBuilder: (_) => <PopupMenuEntry<String>>[
const PopupMenuItem<String>(
value: 'value',
child: Text('Item 0'),
),
],
),
),
),
),
);
// Show the menu
await tester.tap(find.byKey(popupMenuButtonKey));
await tester.pumpAndSettle();
expect(tester.getSize(find.widgetWithText(menuItemType, 'Item 0')).height, 48);
expect(tester.getSize(find.widgetWithText(menuItemType, 'Item 0')).width, 500);
});
} }
class TestApp extends StatefulWidget { class TestApp extends StatefulWidget {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment