Allow dropdown_menu to accept any EdgeInsetsGeometry (#153053)

Allow dropdown_menu to accept any EdgeInsetsGeometry instead of just strictly EdgeInsets.

This follows normal Flutter widget practices when accepting a padding parameter, like Container: https://github.com/flutter/flutter/blob/main/packages/flutter/lib/src/widgets/container.dart#L307C9-L307C27

Fixes https://github.com/flutter/flutter/issues/151769
This commit is contained in:
Tyler Holland 2024-08-07 14:38:34 -07:00 committed by GitHub
parent 715e476545
commit 88fa6210ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 84 additions and 3 deletions

View File

@ -397,7 +397,7 @@ class DropdownMenu<T> extends StatefulWidget {
/// properties are used.
///
/// Defaults to null.
final EdgeInsets? expandedInsets;
final EdgeInsetsGeometry? expandedInsets;
/// When [DropdownMenu.enableFilter] is true, this callback is used to
/// compute the list of filtered items.
@ -884,9 +884,20 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
},
);
if (widget.expandedInsets case final EdgeInsets padding) {
if (widget.expandedInsets case final EdgeInsetsGeometry padding) {
menuAnchor = Padding(
padding: padding.copyWith(top: 0.0, bottom: 0.0),
// Clamp the top and bottom padding to 0.
padding: padding.clamp(
EdgeInsets.zero,
const EdgeInsets.only(
left: double.infinity,
right: double.infinity,
).add(const EdgeInsetsDirectional.only(
end: double.infinity,
start: double.infinity,
),
),
),
child: Align(
alignment: AlignmentDirectional.topStart,
child: menuAnchor,

View File

@ -352,6 +352,76 @@ void main() {
expect(buttonSize.width, parentWidth - 35.0 - 20.0);
});
// Regression test for https://github.com/flutter/flutter/issues/151769
testWidgets('expandedInsets can use EdgeInsets or EdgeInsetsDirectional', (WidgetTester tester) async {
const double parentWidth = 500.0;
final List<DropdownMenuEntry<ShortMenu>> shortMenuItems = <DropdownMenuEntry<ShortMenu>>[];
for (final ShortMenu value in ShortMenu.values) {
final DropdownMenuEntry<ShortMenu> entry = DropdownMenuEntry<ShortMenu>(value: value, label: value.label);
shortMenuItems.add(entry);
}
Widget buildMenuAnchor({EdgeInsetsGeometry? expandedInsets}) {
return MaterialApp(
home: Scaffold(
body: SizedBox(
width: parentWidth,
height: parentWidth,
child: DropdownMenu<ShortMenu>(
expandedInsets: expandedInsets,
dropdownMenuEntries: shortMenuItems,
),
),
),
);
}
// By default, the width of the text field is determined by the menu children.
await tester.pumpWidget(buildMenuAnchor());
RenderBox box = tester.firstRenderObject(find.byType(TextField));
expect(box.size.width, 136.0);
await tester.tap(find.byType(TextField));
await tester.pumpAndSettle();
Size buttonSize = tester.getSize(find.widgetWithText(MenuItemButton, 'I0').hitTestable());
expect(buttonSize.width, 136.0);
// If expandedInsets is not zero, the width of the text field should be adjusted
// based on the EdgeInsets.left and EdgeInsets.right. The top and bottom values
// will be ignored.
await tester.pumpWidget(Container());
await tester.pumpWidget(buildMenuAnchor(expandedInsets: const EdgeInsets.only(left: 35.0, top: 50.0, right: 20.0)));
box = tester.firstRenderObject(find.byType(TextField));
expect(box.size.width, parentWidth - 35.0 - 20.0);
Rect containerRect = tester.getRect(find.byType(SizedBox).first);
Rect dropdownMenuRect = tester.getRect(find.byType(TextField));
expect(dropdownMenuRect.top, containerRect.top);
await tester.tap(find.byType(TextField));
await tester.pumpAndSettle();
buttonSize = tester.getSize(find.widgetWithText(MenuItemButton, 'I0'));
expect(buttonSize.width, parentWidth - 35.0 - 20.0);
// Regression test for https://github.com/flutter/flutter/issues/151769.
// If expandedInsets is not zero, the width of the text field should be adjusted
// based on the EdgeInsets.end and EdgeInsets.start. The top and bottom values
// will be ignored.
await tester.pumpWidget(Container());
await tester.pumpWidget(buildMenuAnchor(expandedInsets: const EdgeInsetsDirectional.only(start: 35.0, top: 50.0, end: 20.0)));
box = tester.firstRenderObject(find.byType(TextField));
expect(box.size.width, parentWidth - 35.0 - 20.0);
containerRect = tester.getRect(find.byType(SizedBox).first);
dropdownMenuRect = tester.getRect(find.byType(TextField));
expect(dropdownMenuRect.top, containerRect.top);
await tester.tap(find.byType(TextField));
await tester.pumpAndSettle();
buttonSize = tester.getSize(find.widgetWithText(MenuItemButton, 'I0'));
expect(buttonSize.width, parentWidth - 35.0 - 20.0);
});
testWidgets('Material2 - The menuHeight property can be used to show a shorter scrollable menu list instead of the complete list',
(WidgetTester tester) async {
final ThemeData themeData = ThemeData(useMaterial3: false);