Unverified Commit 983b2f6b authored by Tirth's avatar Tirth Committed by GitHub

Adds `useRootNavigator` property to `PopupMenuButton` widget. (#137453)

Adds `useRootNavigator` property to `PopupMenuButton` widget.

Fixes #95425
parent d7bf0a8f
......@@ -1128,6 +1128,7 @@ class PopupMenuButton<T> extends StatefulWidget {
this.constraints,
this.position,
this.clipBehavior = Clip.none,
this.useRootNavigator = false,
}) : assert(
!(child != null && icon != null),
'You can only pass [child] or [icon], not both.',
......@@ -1292,6 +1293,12 @@ class PopupMenuButton<T> extends StatefulWidget {
/// Defaults to [Clip.none].
final Clip clipBehavior;
/// Used to determine whether to push the menu to the [Navigator] furthest
/// from or nearest to the given `context`.
///
/// Defaults to false.
final bool useRootNavigator;
@override
PopupMenuButtonState<T> createState() => PopupMenuButtonState<T>();
}
......@@ -1348,6 +1355,7 @@ class PopupMenuButtonState<T> extends State<PopupMenuButton<T>> {
color: widget.color ?? popupMenuTheme.color,
constraints: widget.constraints,
clipBehavior: widget.clipBehavior,
useRootNavigator: widget.useRootNavigator,
)
.then<void>((T? newValue) {
if (!mounted) {
......
......@@ -3785,6 +3785,93 @@ void main() {
await tester.pumpAndSettle();
expect(count, 1);
});
testWidgetsWithLeakTracking('PopupMenuButton uses root navigator if useRootNavigator is true', (WidgetTester tester) async {
final MenuObserver rootObserver = MenuObserver();
final MenuObserver nestedObserver = MenuObserver();
await tester.pumpWidget(
MaterialApp(
navigatorObservers: <NavigatorObserver>[rootObserver],
home: Navigator(
observers: <NavigatorObserver>[nestedObserver],
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute<dynamic>(
builder: (BuildContext context) {
return Material(
child: PopupMenuButton<String>(
useRootNavigator: true,
child: const Text('button'),
itemBuilder: (BuildContext context) {
return <PopupMenuItem<String>>[
const CheckedPopupMenuItem<String>(
value: 'item1',
child: Text('item 1'),
),
const CheckedPopupMenuItem<String>(
value: 'item2',
child: Text('item 2'),
),
];
},
),
);
},
);
},
),
),
);
// Open the dialog.
await tester.tap(find.text('button'));
expect(rootObserver.menuCount, 1);
expect(nestedObserver.menuCount, 0);
});
testWidgetsWithLeakTracking('PopupMenuButton does not use root navigator if useRootNavigator is false', (WidgetTester tester) async {
final MenuObserver rootObserver = MenuObserver();
final MenuObserver nestedObserver = MenuObserver();
await tester.pumpWidget(
MaterialApp(
navigatorObservers: <NavigatorObserver>[rootObserver],
home: Navigator(
observers: <NavigatorObserver>[nestedObserver],
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute<dynamic>(
builder: (BuildContext context) {
return Material(
child: PopupMenuButton<String>(
child: const Text('button'),
itemBuilder: (BuildContext context) {
return <PopupMenuItem<String>>[
const CheckedPopupMenuItem<String>(
value: 'item1',
child: Text('item 1'),
),
const CheckedPopupMenuItem<String>(
value: 'item2',
child: Text('item 2'),
),
];
},
),
);
},
);
},
),
),
);
// Open the dialog.
await tester.tap(find.text('button'));
expect(rootObserver.menuCount, 0);
expect(nestedObserver.menuCount, 1);
});
}
class TestApp extends StatelessWidget {
......
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