Commit a665393a authored by creativecreatorormaybenot's avatar creativecreatorormaybenot Committed by Shi-Hao Hong

Fix Tooltip implementation of PopupMenuButton (#42613)

* Fix tooltip not showing when PopupMenuButton.child was non-null
parent b9817b4f
......@@ -19,6 +19,7 @@ import 'material.dart';
import 'material_localizations.dart';
import 'popup_menu_theme.dart';
import 'theme.dart';
import 'tooltip.dart';
// Examples can assume:
// enum Commands { heroAndScholar, hurricaneCame }
......@@ -939,7 +940,8 @@ class PopupMenuButton<T> extends StatefulWidget {
assert(offset != null),
assert(enabled != null),
assert(captureInheritedThemes != null),
assert(!(child != null && icon != null)), // fails if passed both parameters
assert(!(child != null && icon != null),
'You can only pass [child] or [icon], not both.'),
super(key: key);
/// Called when the button is pressed to create the items to show in the menu.
......@@ -1080,16 +1082,21 @@ class _PopupMenuButtonState<T> extends State<PopupMenuButton<T>> {
@override
Widget build(BuildContext context) {
assert(debugCheckHasMaterialLocalizations(context));
return widget.child != null
? InkWell(
if (widget.child != null)
return Tooltip(
message: widget.tooltip ?? MaterialLocalizations.of(context).showMenuTooltip,
child: InkWell(
onTap: widget.enabled ? showButtonMenu : null,
child: widget.child,
)
: IconButton(
icon: widget.icon ?? _getIcon(Theme.of(context).platform),
padding: widget.padding,
tooltip: widget.tooltip ?? MaterialLocalizations.of(context).showMenuTooltip,
onPressed: widget.enabled ? showButtonMenu : null,
);
),
);
return IconButton(
icon: widget.icon ?? _getIcon(Theme.of(context).platform),
padding: widget.padding,
tooltip: widget.tooltip ?? MaterialLocalizations.of(context).showMenuTooltip,
onPressed: widget.enabled ? showButtonMenu : null,
);
}
}
......@@ -851,6 +851,129 @@ void main() {
expect(tester.getTopLeft(find.text('Item 0')).dx, 72);
expect(tester.getTopLeft(find.text('Item 1')).dx, 72);
});
test("PopupMenuButton's child and icon properties cannot be simultaneously defined", () {
expect(() {
PopupMenuButton<int>(
itemBuilder: (BuildContext context) => <PopupMenuItem<int>>[],
child: Container(),
icon: const Icon(Icons.error),
);
}, throwsAssertionError);
});
testWidgets('PopupMenuButton default tooltip', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
home: Material(
child: Column(
children: <Widget>[
// Default Tooltip should be present when [PopupMenuButton.icon]
// and [PopupMenuButton.child] are undefined.
PopupMenuButton<int>(
itemBuilder: (BuildContext context) {
return <PopupMenuEntry<int>>[
const PopupMenuItem<int>(
value: 1,
child: Text('Tap me please!'),
),
];
},
),
// Default Tooltip should be present when
// [PopupMenuButton.child] is defined.
PopupMenuButton<int>(
itemBuilder: (BuildContext context) {
return <PopupMenuEntry<int>>[
const PopupMenuItem<int>(
value: 1,
child: Text('Tap me please!'),
),
];
},
child: const Text('Test text'),
),
// Default Tooltip should be present when
// [PopupMenuButton.icon] is defined.
PopupMenuButton<int>(
itemBuilder: (BuildContext context) {
return <PopupMenuEntry<int>>[
const PopupMenuItem<int>(
value: 1,
child: Text('Tap me please!'),
),
];
},
icon: const Icon(Icons.check),
),
],
),
),
),
);
// The default tooltip is defined as [MaterialLocalizations.showMenuTooltip]
// and it is used when no tooltip is provided.
expect(find.byType(Tooltip), findsNWidgets(3));
expect(find.byTooltip(const DefaultMaterialLocalizations().showMenuTooltip), findsNWidgets(3));
});
testWidgets('PopupMenuButton custom tooltip', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
home: Material(
child: Column(
children: <Widget>[
// Tooltip should work when [PopupMenuButton.icon]
// and [PopupMenuButton.child] are undefined.
PopupMenuButton<int>(
itemBuilder: (BuildContext context) {
return <PopupMenuEntry<int>>[
const PopupMenuItem<int>(
value: 1,
child: Text('Tap me please!'),
),
];
},
tooltip: 'Test tooltip',
),
// Tooltip should work when
// [PopupMenuButton.child] is defined.
PopupMenuButton<int>(
itemBuilder: (BuildContext context) {
return <PopupMenuEntry<int>>[
const PopupMenuItem<int>(
value: 1,
child: Text('Tap me please!'),
),
];
},
tooltip: 'Test tooltip',
child: const Text('Test text'),
),
// Tooltip should work when
// [PopupMenuButton.icon] is defined.
PopupMenuButton<int>(
itemBuilder: (BuildContext context) {
return <PopupMenuEntry<int>>[
const PopupMenuItem<int>(
value: 1,
child: Text('Tap me please!'),
),
];
},
tooltip: 'Test tooltip',
icon: const Icon(Icons.check),
),
],
),
),
),
);
expect(find.byType(Tooltip), findsNWidgets(3));
expect(find.byTooltip('Test tooltip',), findsNWidgets(3));
});
}
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