diff --git a/dev/manual_tests/lib/menu_anchor.dart b/dev/manual_tests/lib/menu_anchor.dart
new file mode 100644
index 0000000..5d0c8de
--- /dev/null
+++ b/dev/manual_tests/lib/menu_anchor.dart
@@ -0,0 +1,667 @@
+// 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 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+
+void main() {
+  runApp(
+    const MaterialApp(
+      title: 'Menu Tester',
+      home: Material(
+        child: Home(),
+      ),
+    ),
+  );
+}
+
+class Home extends StatefulWidget {
+  const Home({super.key});
+
+  @override
+  State<Home> createState() => _HomeState();
+}
+
+class _HomeState extends State<Home> {
+  final MenuController _controller = MenuController();
+  VisualDensity _density = VisualDensity.standard;
+  TextDirection _textDirection = TextDirection.ltr;
+  double _extraPadding = 0;
+  bool _addItem = false;
+  bool _transparent = false;
+  bool _funkyTheme = false;
+
+  @override
+  Widget build(BuildContext context) {
+    final ThemeData theme = Theme.of(context);
+    MenuThemeData menuTheme = MenuTheme.of(context);
+    MenuBarThemeData menuBarTheme = MenuBarTheme.of(context);
+    MenuButtonThemeData menuButtonTheme = MenuButtonTheme.of(context);
+    if (_funkyTheme) {
+      menuTheme = const MenuThemeData(
+        style: MenuStyle(
+          shape: MaterialStatePropertyAll<OutlinedBorder>(
+            RoundedRectangleBorder(
+              borderRadius: BorderRadius.all(
+                Radius.circular(10),
+              ),
+            ),
+          ),
+          backgroundColor: MaterialStatePropertyAll<Color?>(Colors.blue),
+          elevation: MaterialStatePropertyAll<double?>(10),
+          padding: MaterialStatePropertyAll<EdgeInsetsDirectional>(
+            EdgeInsetsDirectional.all(20),
+          ),
+        ),
+      );
+      menuButtonTheme = const MenuButtonThemeData(
+        style: ButtonStyle(
+          shape: MaterialStatePropertyAll<OutlinedBorder>(StadiumBorder()),
+          backgroundColor: MaterialStatePropertyAll<Color?>(Colors.green),
+          foregroundColor: MaterialStatePropertyAll<Color?>(Colors.white),
+        ),
+      );
+      menuBarTheme = const MenuBarThemeData(
+        style: MenuStyle(
+          shape: MaterialStatePropertyAll<OutlinedBorder>(RoundedRectangleBorder()),
+          backgroundColor: MaterialStatePropertyAll<Color?>(Colors.blue),
+          elevation: MaterialStatePropertyAll<double?>(10),
+          padding: MaterialStatePropertyAll<EdgeInsetsDirectional>(
+            EdgeInsetsDirectional.all(20),
+          ),
+        ),
+      );
+    }
+    return SafeArea(
+      child: Padding(
+        padding: EdgeInsets.all(_extraPadding),
+        child: Directionality(
+          textDirection: _textDirection,
+          child: Theme(
+            data: theme.copyWith(
+              visualDensity: _density,
+              menuTheme: _transparent
+                  ? MenuThemeData(
+                      style: MenuStyle(
+                        backgroundColor: MaterialStatePropertyAll<Color>(
+                          Colors.blue.withOpacity(0.12),
+                        ),
+                        elevation: const MaterialStatePropertyAll<double>(0),
+                      ),
+                    )
+                  : menuTheme,
+              menuBarTheme: menuBarTheme,
+              menuButtonTheme: menuButtonTheme,
+            ),
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: <Widget>[
+                _TestMenus(
+                  menuController: _controller,
+                  addItem: _addItem,
+                ),
+                Expanded(
+                  child: SingleChildScrollView(
+                    child: _Controls(
+                      menuController: _controller,
+                      density: _density,
+                      addItem: _addItem,
+                      transparent: _transparent,
+                      funkyTheme: _funkyTheme,
+                      extraPadding: _extraPadding,
+                      textDirection: _textDirection,
+                      onDensityChanged: (VisualDensity value) {
+                        setState(() {
+                          _density = value;
+                        });
+                      },
+                      onTextDirectionChanged: (TextDirection value) {
+                        setState(() {
+                          _textDirection = value;
+                        });
+                      },
+                      onExtraPaddingChanged: (double value) {
+                        setState(() {
+                          _extraPadding = value;
+                        });
+                      },
+                      onAddItemChanged: (bool value) {
+                        setState(() {
+                          _addItem = value;
+                        });
+                      },
+                      onTransparentChanged: (bool value) {
+                        setState(() {
+                          _transparent = value;
+                        });
+                      },
+                      onFunkyThemeChanged: (bool value) {
+                        setState(() {
+                          _funkyTheme = value;
+                        });
+                      },
+                    ),
+                  ),
+                ),
+              ],
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+}
+
+class _Controls extends StatefulWidget {
+  const _Controls({
+    required this.density,
+    required this.textDirection,
+    required this.extraPadding,
+    this.addItem = false,
+    this.transparent = false,
+    this.funkyTheme = false,
+    required this.onDensityChanged,
+    required this.onTextDirectionChanged,
+    required this.onExtraPaddingChanged,
+    required this.onAddItemChanged,
+    required this.onTransparentChanged,
+    required this.onFunkyThemeChanged,
+    required this.menuController,
+  });
+
+  final VisualDensity density;
+  final TextDirection textDirection;
+  final double extraPadding;
+  final bool addItem;
+  final bool transparent;
+  final bool funkyTheme;
+  final ValueChanged<VisualDensity> onDensityChanged;
+  final ValueChanged<TextDirection> onTextDirectionChanged;
+  final ValueChanged<double> onExtraPaddingChanged;
+  final ValueChanged<bool> onAddItemChanged;
+  final ValueChanged<bool> onTransparentChanged;
+  final ValueChanged<bool> onFunkyThemeChanged;
+  final MenuController menuController;
+
+  @override
+  State<_Controls> createState() => _ControlsState();
+}
+
+class _ControlsState extends State<_Controls> {
+  final FocusNode _focusNode = FocusNode(debugLabel: 'Floating');
+
+  @override
+  void dispose() {
+    _focusNode.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      color: Colors.lightBlueAccent,
+      alignment: Alignment.center,
+      child: Column(
+        mainAxisAlignment: MainAxisAlignment.center,
+        children: <Widget>[
+          MenuAnchor(
+            childFocusNode: _focusNode,
+            style: const MenuStyle(alignment: AlignmentDirectional.topEnd),
+            alignmentOffset: const Offset(100, -8),
+            menuChildren: <Widget>[
+              MenuItemButton(
+                shortcut: const SingleActivator(
+                  LogicalKeyboardKey.keyB,
+                  control: true,
+                ),
+                onPressed: () {
+                  _itemSelected(TestMenu.standaloneMenu1);
+                },
+                child: Text(TestMenu.standaloneMenu1.label),
+              ),
+              MenuItemButton(
+                leadingIcon: const Icon(Icons.send),
+                trailingIcon: const Icon(Icons.mail),
+                onPressed: () {
+                  _itemSelected(TestMenu.standaloneMenu2);
+                },
+                child: Text(TestMenu.standaloneMenu2.label),
+              ),
+            ],
+            builder: (BuildContext context, MenuController controller, Widget? child) {
+              return TextButton(
+                focusNode: _focusNode,
+                onPressed: () {
+                  if (controller.isOpen) {
+                    controller.close();
+                  } else {
+                    controller.open();
+                  }
+                },
+                child: child!,
+              );
+            },
+            child: const Text('Open Menu'),
+          ),
+          ConstrainedBox(
+            constraints: const BoxConstraints(maxWidth: 400),
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.stretch,
+              children: <Widget>[
+                _ControlSlider(
+                  label: 'Extra Padding: ${widget.extraPadding.toStringAsFixed(1)}',
+                  value: widget.extraPadding,
+                  max: 40,
+                  divisions: 20,
+                  onChanged: (double value) {
+                    widget.onExtraPaddingChanged(value);
+                  },
+                ),
+                _ControlSlider(
+                  label: 'Horizontal Density: ${widget.density.horizontal.toStringAsFixed(1)}',
+                  value: widget.density.horizontal,
+                  max: 4,
+                  min: -4,
+                  divisions: 12,
+                  onChanged: (double value) {
+                    widget.onDensityChanged(
+                      VisualDensity(
+                        horizontal: value,
+                        vertical: widget.density.vertical,
+                      ),
+                    );
+                  },
+                ),
+                _ControlSlider(
+                  label: 'Vertical Density: ${widget.density.vertical.toStringAsFixed(1)}',
+                  value: widget.density.vertical,
+                  max: 4,
+                  min: -4,
+                  divisions: 12,
+                  onChanged: (double value) {
+                    widget.onDensityChanged(
+                      VisualDensity(
+                        horizontal: widget.density.horizontal,
+                        vertical: value,
+                      ),
+                    );
+                  },
+                ),
+              ],
+            ),
+          ),
+          Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: <Widget>[
+              Row(
+                mainAxisSize: MainAxisSize.min,
+                children: <Widget>[
+                  Checkbox(
+                    value: widget.textDirection == TextDirection.rtl,
+                    onChanged: (bool? value) {
+                      if (value ?? false) {
+                        widget.onTextDirectionChanged(TextDirection.rtl);
+                      } else {
+                        widget.onTextDirectionChanged(TextDirection.ltr);
+                      }
+                    },
+                  ),
+                  const Text('RTL Text')
+                ],
+              ),
+              Row(
+                mainAxisSize: MainAxisSize.min,
+                children: <Widget>[
+                  Checkbox(
+                    value: widget.addItem,
+                    onChanged: (bool? value) {
+                      if (value ?? false) {
+                        widget.onAddItemChanged(true);
+                      } else {
+                        widget.onAddItemChanged(false);
+                      }
+                    },
+                  ),
+                  const Text('Add Item')
+                ],
+              ),
+              Row(
+                mainAxisSize: MainAxisSize.min,
+                children: <Widget>[
+                  Checkbox(
+                    value: widget.transparent,
+                    onChanged: (bool? value) {
+                      if (value ?? false) {
+                        widget.onTransparentChanged(true);
+                      } else {
+                        widget.onTransparentChanged(false);
+                      }
+                    },
+                  ),
+                  const Text('Transparent')
+                ],
+              ),
+              Row(
+                mainAxisSize: MainAxisSize.min,
+                children: <Widget>[
+                  Checkbox(
+                    value: widget.funkyTheme,
+                    onChanged: (bool? value) {
+                      if (value ?? false) {
+                        widget.onFunkyThemeChanged(true);
+                      } else {
+                        widget.onFunkyThemeChanged(false);
+                      }
+                    },
+                  ),
+                  const Text('Funky Theme')
+                ],
+              ),
+            ],
+          ),
+        ],
+      ),
+    );
+  }
+
+  void _itemSelected(TestMenu item) {
+    debugPrint('App: Selected item ${item.label}');
+  }
+}
+
+class _ControlSlider extends StatelessWidget {
+  const _ControlSlider({
+    required this.label,
+    required this.value,
+    required this.onChanged,
+    this.min = 0,
+    this.max = 1,
+    this.divisions,
+  });
+
+  final String label;
+  final double value;
+  final ValueChanged<double> onChanged;
+  final double min;
+  final double max;
+  final int? divisions;
+
+  @override
+  Widget build(BuildContext context) {
+    return Row(
+      mainAxisAlignment: MainAxisAlignment.end,
+      children: <Widget>[
+        Container(
+          alignment: AlignmentDirectional.centerEnd,
+          constraints: const BoxConstraints(minWidth: 150),
+          child: Text(label),
+        ),
+        Expanded(
+          child: Slider(
+            value: value,
+            min: min,
+            max: max,
+            divisions: divisions,
+            onChanged: onChanged,
+          ),
+        ),
+      ],
+    );
+  }
+}
+
+class _TestMenus extends StatefulWidget {
+  const _TestMenus({
+    required this.menuController,
+    this.addItem = false,
+  });
+
+  final MenuController menuController;
+  final bool addItem;
+
+  @override
+  State<_TestMenus> createState() => _TestMenusState();
+}
+
+class _TestMenusState extends State<_TestMenus> {
+  final TextEditingController textController = TextEditingController();
+
+  void _itemSelected(TestMenu item) {
+    debugPrint('App: Selected item ${item.label}');
+  }
+
+  void _openItem(TestMenu item) {
+    debugPrint('App: Opened item ${item.label}');
+  }
+
+  void _closeItem(TestMenu item) {
+    debugPrint('App: Closed item ${item.label}');
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Row(
+      children: <Widget>[
+        Expanded(
+          child: MenuBar(
+            controller: widget.menuController,
+            children: <Widget>[
+              SubmenuButton(
+                onOpen: () {
+                  _openItem(TestMenu.mainMenu1);
+                },
+                onClose: () {
+                  _closeItem(TestMenu.mainMenu1);
+                },
+                menuChildren: <Widget>[
+                  MenuItemButton(
+                    shortcut: const SingleActivator(
+                      LogicalKeyboardKey.keyB,
+                      control: true,
+                    ),
+                    leadingIcon:
+                        widget.addItem ? const Icon(Icons.check_box) : const Icon(Icons.check_box_outline_blank),
+                    trailingIcon: const Icon(Icons.assessment),
+                    onPressed: () {
+                      _itemSelected(TestMenu.subMenu1);
+                    },
+                    child: Text(TestMenu.subMenu1.label),
+                  ),
+                  MenuItemButton(
+                    leadingIcon: const Icon(Icons.send),
+                    trailingIcon: const Icon(Icons.mail),
+                    onPressed: () {
+                      _itemSelected(TestMenu.subMenu2);
+                    },
+                    child: Text(TestMenu.subMenu2.label),
+                  ),
+                ],
+                child: Text(TestMenu.mainMenu1.label),
+              ),
+              SubmenuButton(
+                onOpen: () {
+                  _openItem(TestMenu.mainMenu2);
+                },
+                onClose: () {
+                  _closeItem(TestMenu.mainMenu2);
+                },
+                menuChildren: <Widget>[
+                  TextButton(
+                    child: const Text('TEST'),
+                    onPressed: () {
+                      _itemSelected(TestMenu.testButton);
+                      widget.menuController.close();
+                    },
+                  ),
+                  MenuItemButton(
+                    shortcut: const SingleActivator(
+                      LogicalKeyboardKey.enter,
+                      control: true,
+                    ),
+                    onPressed: () {
+                      _itemSelected(TestMenu.subMenu3);
+                    },
+                    child: Text(TestMenu.subMenu3.label),
+                  ),
+                ],
+                child: Text(TestMenu.mainMenu2.label),
+              ),
+              SubmenuButton(
+                onOpen: () {
+                  _openItem(TestMenu.mainMenu3);
+                },
+                onClose: () {
+                  _closeItem(TestMenu.mainMenu3);
+                },
+                menuChildren: <Widget>[
+                  MenuItemButton(
+                    child: Text(TestMenu.subMenu8.label),
+                    onPressed: () {
+                      _itemSelected(TestMenu.subMenu8);
+                    },
+                  ),
+                ],
+                child: Text(TestMenu.mainMenu3.label),
+              ),
+              SubmenuButton(
+                onOpen: () {
+                  _openItem(TestMenu.mainMenu4);
+                },
+                onClose: () {
+                  _closeItem(TestMenu.mainMenu4);
+                },
+                menuChildren: <Widget>[
+                  Actions(
+                    actions: <Type, Action<Intent>>{
+                      ActivateIntent: CallbackAction<ActivateIntent>(
+                        onInvoke: (ActivateIntent? intent) {
+                          debugPrint('Activated!');
+                          return;
+                        },
+                      )
+                    },
+                    child: MenuItemButton(
+                      shortcut: const SingleActivator(
+                        LogicalKeyboardKey.keyA,
+                        control: true,
+                      ),
+                      onPressed: () {
+                        debugPrint('Activated text input item with ${textController.text} as a value.');
+                      },
+                      child: SizedBox(
+                        width: 200,
+                        child: TextField(
+                          controller: textController,
+                          onSubmitted: (String value) {
+                            debugPrint('String $value submitted.');
+                          },
+                        ),
+                      ),
+                    ),
+                  ),
+                  SubmenuButton(
+                    onOpen: () {
+                      _openItem(TestMenu.subMenu5);
+                    },
+                    onClose: () {
+                      _closeItem(TestMenu.subMenu5);
+                    },
+                    menuChildren: <Widget>[
+                      MenuItemButton(
+                        shortcut: widget.addItem
+                            ? const SingleActivator(
+                                LogicalKeyboardKey.f11,
+                                control: true,
+                              )
+                            : const SingleActivator(
+                                LogicalKeyboardKey.f10,
+                                control: true,
+                              ),
+                        onPressed: () {
+                          _itemSelected(TestMenu.subSubMenu1);
+                        },
+                        child: Text(TestMenu.subSubMenu1.label),
+                      ),
+                      MenuItemButton(
+                        child: Text(TestMenu.subSubMenu2.label),
+                        onPressed: () {
+                          _itemSelected(TestMenu.subSubMenu2);
+                        },
+                      ),
+                      if (widget.addItem)
+                        SubmenuButton(
+                          menuChildren: <Widget>[
+                            MenuItemButton(
+                              child: Text(TestMenu.subSubSubMenu1.label),
+                              onPressed: () {
+                                _itemSelected(TestMenu.subSubSubMenu1);
+                              },
+                            ),
+                          ],
+                          child: Text(TestMenu.subSubMenu3.label),
+                        ),
+                    ],
+                    child: Text(TestMenu.subMenu5.label),
+                  ),
+                  MenuItemButton(
+                    // Disabled button
+                    shortcut: const SingleActivator(
+                      LogicalKeyboardKey.tab,
+                      control: true,
+                    ),
+                    child: Text(TestMenu.subMenu6.label),
+                  ),
+                  MenuItemButton(
+                    child: Text(TestMenu.subMenu7.label),
+                    onPressed: () {
+                      _itemSelected(TestMenu.subMenu7);
+                    },
+                  ),
+                  MenuItemButton(
+                    child: Text(TestMenu.subMenu7.label),
+                    onPressed: () {
+                      _itemSelected(TestMenu.subMenu7);
+                    },
+                  ),
+                  MenuItemButton(
+                    child: Text(TestMenu.subMenu8.label),
+                    onPressed: () {
+                      _itemSelected(TestMenu.subMenu8);
+                    },
+                  ),
+                ],
+                child: Text(TestMenu.mainMenu4.label),
+              ),
+            ],
+          ),
+        ),
+      ],
+    );
+  }
+}
+
+enum TestMenu {
+  mainMenu1('Menu 1'),
+  mainMenu2('Menu 2'),
+  mainMenu3('Menu 3'),
+  mainMenu4('Menu 4'),
+  subMenu1('Sub Menu 1'),
+  subMenu2('Sub Menu 2'),
+  subMenu3('Sub Menu 3'),
+  subMenu4('Sub Menu 4'),
+  subMenu5('Sub Menu 5'),
+  subMenu6('Sub Menu 6'),
+  subMenu7('Sub Menu 7'),
+  subMenu8('Sub Menu 8'),
+  subSubMenu1('Sub Sub Menu 1'),
+  subSubMenu2('Sub Sub Menu 2'),
+  subSubMenu3('Sub Sub Menu 3'),
+  subSubSubMenu1('Sub Sub Sub Menu 1'),
+  testButton('TEST button'),
+  standaloneMenu1('Standalone Menu 1'),
+  standaloneMenu2('Standalone Menu 2');
+
+  const TestMenu(this.label);
+  final String label;
+}
diff --git a/examples/api/lib/material/menu_anchor/menu_anchor.0.dart b/examples/api/lib/material/menu_anchor/menu_anchor.0.dart
new file mode 100644
index 0000000..b613e14
--- /dev/null
+++ b/examples/api/lib/material/menu_anchor/menu_anchor.0.dart
@@ -0,0 +1,212 @@
+// 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.
+
+/// Flutter code sample for [MenuAnchor].
+
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+
+void main() => runApp(const MenuApp());
+
+/// An enhanced enum to define the available menus and their shortcuts.
+///
+/// Using an enum for menu definition is not required, but this illustrates how
+/// they could be used for simple menu systems.
+enum MenuEntry {
+  about('About'),
+  showMessage('Show Message', SingleActivator(LogicalKeyboardKey.keyS, control: true)),
+  hideMessage('Hide Message', SingleActivator(LogicalKeyboardKey.keyS, control: true)),
+  colorMenu('Color Menu'),
+  colorRed('Red Background', SingleActivator(LogicalKeyboardKey.keyR, control: true)),
+  colorGreen('Green Background', SingleActivator(LogicalKeyboardKey.keyG, control: true)),
+  colorBlue('Blue Background', SingleActivator(LogicalKeyboardKey.keyB, control: true));
+
+  const MenuEntry(this.label, [this.shortcut]);
+  final String label;
+  final MenuSerializableShortcut? shortcut;
+}
+
+class MyCascadingMenu extends StatefulWidget {
+  const MyCascadingMenu({super.key, required this.message});
+
+  final String message;
+
+  @override
+  State<MyCascadingMenu> createState() => _MyCascadingMenuState();
+}
+
+class _MyCascadingMenuState extends State<MyCascadingMenu> {
+  MenuEntry? _lastSelection;
+  final FocusNode _buttonFocusNode = FocusNode(debugLabel: 'Menu Button');
+  ShortcutRegistryEntry? _shortcutsEntry;
+
+  Color get backgroundColor => _backgroundColor;
+  Color _backgroundColor = Colors.red;
+  set backgroundColor(Color value) {
+    if (_backgroundColor != value) {
+      setState(() {
+        _backgroundColor = value;
+      });
+    }
+  }
+
+  bool get showingMessage => _showingMessage;
+  bool _showingMessage = false;
+  set showingMessage(bool value) {
+    if (_showingMessage != value) {
+      setState(() {
+        _showingMessage = value;
+      });
+    }
+  }
+
+  @override
+  void didChangeDependencies() {
+    super.didChangeDependencies();
+    // Dispose of any previously registered shortcuts, since they are about to
+    // be replaced.
+    _shortcutsEntry?.dispose();
+    // Collect the shortcuts from the different menu selections so that they can
+    // be registered to apply to the entire app. Menus don't register their
+    // shortcuts, they only display the shortcut hint text.
+    final Map<ShortcutActivator, Intent> shortcuts = <ShortcutActivator, Intent>{
+      for (final MenuEntry item in MenuEntry.values)
+        if (item.shortcut != null) item.shortcut!: VoidCallbackIntent(() => _activate(item)),
+    };
+    // Register the shortcuts with the ShortcutRegistry so that they are
+    // available to the entire application.
+    _shortcutsEntry = ShortcutRegistry.of(context).addAll(shortcuts);
+  }
+
+  @override
+  void dispose() {
+    _shortcutsEntry?.dispose();
+    _buttonFocusNode.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.start,
+      children: <Widget>[
+        MenuAnchor(
+          childFocusNode: _buttonFocusNode,
+          menuChildren: <Widget>[
+            MenuItemButton(
+              child: Text(MenuEntry.about.label),
+              onPressed: () => _activate(MenuEntry.about),
+            ),
+            if (_showingMessage) MenuItemButton(
+              onPressed: () => _activate(MenuEntry.hideMessage),
+              shortcut: MenuEntry.hideMessage.shortcut,
+              child: Text(MenuEntry.hideMessage.label),
+            ),
+            if (!_showingMessage) MenuItemButton(
+              onPressed: () => _activate(MenuEntry.showMessage),
+              shortcut: MenuEntry.showMessage.shortcut,
+              child: Text(MenuEntry.showMessage.label),
+            ),
+            SubmenuButton(
+              menuChildren: <Widget>[
+                MenuItemButton(
+                  onPressed: () => _activate(MenuEntry.colorRed),
+                  shortcut: MenuEntry.colorRed.shortcut,
+                  child: Text(MenuEntry.colorRed.label),
+                ),
+                MenuItemButton(
+                  onPressed: () => _activate(MenuEntry.colorGreen),
+                  shortcut: MenuEntry.colorGreen.shortcut,
+                  child: Text(MenuEntry.colorGreen.label),
+                ),
+                MenuItemButton(
+                  onPressed: () => _activate(MenuEntry.colorBlue),
+                  shortcut: MenuEntry.colorBlue.shortcut,
+                  child: Text(MenuEntry.colorBlue.label),
+                ),
+              ],
+              child: const Text('Background Color'),
+            ),
+          ],
+          builder: (BuildContext context, MenuController controller, Widget? child) {
+            return TextButton(
+              focusNode: _buttonFocusNode,
+              onPressed: () {
+                if (controller.isOpen) {
+                  controller.close();
+                } else {
+                  controller.open();
+                }
+              },
+              child: const Text('OPEN MENU'),
+            );
+          },
+        ),
+        Expanded(
+          child: Container(
+            alignment: Alignment.center,
+            color: backgroundColor,
+            child: Column(
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: <Widget>[
+                Padding(
+                  padding: const EdgeInsets.all(12.0),
+                  child: Text(
+                    showingMessage ? widget.message : '',
+                    style: Theme.of(context).textTheme.headlineSmall,
+                  ),
+                ),
+                Text(_lastSelection != null ? 'Last Selected: ${_lastSelection!.label}' : ''),
+              ],
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+
+  void _activate(MenuEntry selection) {
+    setState(() {
+      _lastSelection = selection;
+    });
+
+    switch (selection) {
+      case MenuEntry.about:
+        showAboutDialog(
+          context: context,
+          applicationName: 'MenuBar Sample',
+          applicationVersion: '1.0.0',
+        );
+        break;
+      case MenuEntry.hideMessage:
+      case MenuEntry.showMessage:
+        showingMessage = !showingMessage;
+        break;
+      case MenuEntry.colorMenu:
+        break;
+      case MenuEntry.colorRed:
+        backgroundColor = Colors.red;
+        break;
+      case MenuEntry.colorGreen:
+        backgroundColor = Colors.green;
+        break;
+      case MenuEntry.colorBlue:
+        backgroundColor = Colors.blue;
+        break;
+    }
+  }
+}
+
+class MenuApp extends StatelessWidget {
+  const MenuApp({super.key});
+
+  static const String kMessage = '"Talk less. Smile more." - A. Burr';
+
+  @override
+  Widget build(BuildContext context) {
+    return const MaterialApp(
+      home: Scaffold(body: MyCascadingMenu(message: kMessage)),
+    );
+  }
+}
diff --git a/examples/api/lib/material/menu_anchor/menu_anchor.1.dart b/examples/api/lib/material/menu_anchor/menu_anchor.1.dart
new file mode 100644
index 0000000..da12e0b
--- /dev/null
+++ b/examples/api/lib/material/menu_anchor/menu_anchor.1.dart
@@ -0,0 +1,211 @@
+// 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.
+
+/// Flutter code sample for [MenuAnchor].
+
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+
+void main() => runApp(const ContextMenuApp());
+
+/// An enhanced enum to define the available menus and their shortcuts.
+///
+/// Using an enum for menu definition is not required, but this illustrates how
+/// they could be used for simple menu systems.
+enum MenuEntry {
+  about('About'),
+  showMessage('Show Message', SingleActivator(LogicalKeyboardKey.keyS, control: true)),
+  hideMessage('Hide Message', SingleActivator(LogicalKeyboardKey.keyS, control: true)),
+  colorMenu('Color Menu'),
+  colorRed('Red Background', SingleActivator(LogicalKeyboardKey.keyR, control: true)),
+  colorGreen('Green Background', SingleActivator(LogicalKeyboardKey.keyG, control: true)),
+  colorBlue('Blue Background', SingleActivator(LogicalKeyboardKey.keyB, control: true));
+
+  const MenuEntry(this.label, [this.shortcut]);
+  final String label;
+  final MenuSerializableShortcut? shortcut;
+}
+
+class MyContextMenu extends StatefulWidget {
+  const MyContextMenu({super.key, required this.message});
+
+  final String message;
+
+  @override
+  State<MyContextMenu> createState() => _MyContextMenuState();
+}
+
+class _MyContextMenuState extends State<MyContextMenu> {
+  MenuEntry? _lastSelection;
+  final FocusNode _buttonFocusNode = FocusNode(debugLabel: 'Menu Button');
+  final MenuController _menuController = MenuController();
+  ShortcutRegistryEntry? _shortcutsEntry;
+
+  Color get backgroundColor => _backgroundColor;
+  Color _backgroundColor = Colors.red;
+  set backgroundColor(Color value) {
+    if (_backgroundColor != value) {
+      setState(() {
+        _backgroundColor = value;
+      });
+    }
+  }
+
+  bool get showingMessage => _showingMessage;
+  bool _showingMessage = false;
+  set showingMessage(bool value) {
+    if (_showingMessage != value) {
+      setState(() {
+        _showingMessage = value;
+      });
+    }
+  }
+
+  @override
+  void didChangeDependencies() {
+    super.didChangeDependencies();
+    // Dispose of any previously registered shortcuts, since they are about to
+    // be replaced.
+    _shortcutsEntry?.dispose();
+    // Collect the shortcuts from the different menu selections so that they can
+    // be registered to apply to the entire app. Menus don't register their
+    // shortcuts, they only display the shortcut hint text.
+    final Map<ShortcutActivator, Intent> shortcuts = <ShortcutActivator, Intent>{
+      for (final MenuEntry item in MenuEntry.values)
+        if (item.shortcut != null) item.shortcut!: VoidCallbackIntent(() => _activate(item)),
+    };
+    // Register the shortcuts with the ShortcutRegistry so that they are
+    // available to the entire application.
+    _shortcutsEntry = ShortcutRegistry.of(context).addAll(shortcuts);
+  }
+
+  @override
+  void dispose() {
+    _shortcutsEntry?.dispose();
+    _buttonFocusNode.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Padding(
+      padding: const EdgeInsets.all(50),
+      child: GestureDetector(
+        onTapDown: _handleTapDown,
+        child: MenuAnchor(
+          controller: _menuController,
+          anchorTapClosesMenu: true,
+          menuChildren: <Widget>[
+            MenuItemButton(
+              child: Text(MenuEntry.about.label),
+              onPressed: () => _activate(MenuEntry.about),
+            ),
+            if (_showingMessage) MenuItemButton(
+              onPressed: () => _activate(MenuEntry.hideMessage),
+              shortcut: MenuEntry.hideMessage.shortcut,
+              child: Text(MenuEntry.hideMessage.label),
+            ),
+            if (!_showingMessage) MenuItemButton(
+              onPressed: () => _activate(MenuEntry.showMessage),
+              shortcut: MenuEntry.showMessage.shortcut,
+              child: Text(MenuEntry.showMessage.label),
+            ),
+            SubmenuButton(
+              menuChildren: <Widget>[
+                MenuItemButton(
+                  onPressed: () => _activate(MenuEntry.colorRed),
+                  shortcut: MenuEntry.colorRed.shortcut,
+                  child: Text(MenuEntry.colorRed.label),
+                ),
+                MenuItemButton(
+                  onPressed: () => _activate(MenuEntry.colorGreen),
+                  shortcut: MenuEntry.colorGreen.shortcut,
+                  child: Text(MenuEntry.colorGreen.label),
+                ),
+                MenuItemButton(
+                  onPressed: () => _activate(MenuEntry.colorBlue),
+                  shortcut: MenuEntry.colorBlue.shortcut,
+                  child: Text(MenuEntry.colorBlue.label),
+                ),
+              ],
+              child: const Text('Background Color'),
+            ),
+          ],
+          child: Container(
+            alignment: Alignment.center,
+            color: backgroundColor,
+            child: Column(
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: <Widget>[
+                const Padding(
+                  padding: EdgeInsets.all(8.0),
+                  child: Text('Ctrl-click anywhere on the background to show the menu.'),
+                ),
+                Padding(
+                  padding: const EdgeInsets.all(12.0),
+                  child: Text(
+                    showingMessage ? widget.message : '',
+                    style: Theme.of(context).textTheme.headlineSmall,
+                  ),
+                ),
+                Text(_lastSelection != null ? 'Last Selected: ${_lastSelection!.label}' : ''),
+              ],
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+
+  void _activate(MenuEntry selection) {
+    setState(() {
+      _lastSelection = selection;
+    });
+    switch (selection) {
+      case MenuEntry.about:
+        showAboutDialog(
+          context: context,
+          applicationName: 'MenuBar Sample',
+          applicationVersion: '1.0.0',
+        );
+        break;
+      case MenuEntry.showMessage:
+      case MenuEntry.hideMessage:
+        showingMessage = !showingMessage;
+        break;
+      case MenuEntry.colorMenu:
+        break;
+      case MenuEntry.colorRed:
+        backgroundColor = Colors.red;
+        break;
+      case MenuEntry.colorGreen:
+        backgroundColor = Colors.green;
+        break;
+      case MenuEntry.colorBlue:
+        backgroundColor = Colors.blue;
+        break;
+    }
+  }
+
+  void _handleTapDown(TapDownDetails details) {
+    if (!HardwareKeyboard.instance.logicalKeysPressed.contains(LogicalKeyboardKey.controlLeft) &&
+        !HardwareKeyboard.instance.logicalKeysPressed.contains(LogicalKeyboardKey.controlRight)) {
+      return;
+    }
+    _menuController.open(position: details.localPosition);
+  }
+}
+
+class ContextMenuApp extends StatelessWidget {
+  const ContextMenuApp({super.key});
+
+  static const String kMessage = '"Talk less. Smile more." - A. Burr';
+
+  @override
+  Widget build(BuildContext context) {
+    return const MaterialApp(
+      home: Scaffold(body: MyContextMenu(message: kMessage)),
+    );
+  }
+}
diff --git a/examples/api/lib/material/menu_anchor/menu_bar.0.dart b/examples/api/lib/material/menu_anchor/menu_bar.0.dart
new file mode 100644
index 0000000..eb68121
--- /dev/null
+++ b/examples/api/lib/material/menu_anchor/menu_bar.0.dart
@@ -0,0 +1,236 @@
+// 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.
+
+/// Flutter code sample for [MenuBar]
+
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+
+void main() => runApp(const MenuBarApp());
+
+/// A class for consolidating the definition of menu entries.
+///
+/// This sort of class is not required, but illustrates one way that defining
+/// menus could be done.
+class MenuEntry {
+  const MenuEntry({required this.label, this.shortcut, this.onPressed, this.menuChildren})
+      : assert(menuChildren == null || onPressed == null, 'onPressed is ignored if menuChildren are provided');
+  final String label;
+
+  final MenuSerializableShortcut? shortcut;
+  final VoidCallback? onPressed;
+  final List<MenuEntry>? menuChildren;
+
+  static List<Widget> build(List<MenuEntry> selections) {
+    Widget buildSelection(MenuEntry selection) {
+      if (selection.menuChildren != null) {
+        return SubmenuButton(
+          menuChildren: MenuEntry.build(selection.menuChildren!),
+          child: Text(selection.label),
+        );
+      }
+      return MenuItemButton(
+        shortcut: selection.shortcut,
+        onPressed: selection.onPressed,
+        child: Text(selection.label),
+      );
+    }
+
+    return selections.map<Widget>(buildSelection).toList();
+  }
+
+  static Map<MenuSerializableShortcut, Intent> shortcuts(List<MenuEntry> selections) {
+    final Map<MenuSerializableShortcut, Intent> result = <MenuSerializableShortcut, Intent>{};
+    for (final MenuEntry selection in selections) {
+      if (selection.menuChildren != null) {
+        result.addAll(MenuEntry.shortcuts(selection.menuChildren!));
+      } else {
+        if (selection.shortcut != null && selection.onPressed != null) {
+          result[selection.shortcut!] = VoidCallbackIntent(selection.onPressed!);
+        }
+      }
+    }
+    return result;
+  }
+}
+
+class MyMenuBar extends StatefulWidget {
+  const MyMenuBar({
+    super.key,
+    required this.message,
+  });
+
+  final String message;
+
+  @override
+  State<MyMenuBar> createState() => _MyMenuBarState();
+}
+
+class _MyMenuBarState extends State<MyMenuBar> {
+  ShortcutRegistryEntry? _shortcutsEntry;
+  String? _lastSelection;
+
+  Color get backgroundColor => _backgroundColor;
+  Color _backgroundColor = Colors.red;
+  set backgroundColor(Color value) {
+    if (_backgroundColor != value) {
+      setState(() {
+        _backgroundColor = value;
+      });
+    }
+  }
+
+  bool get showingMessage => _showMessage;
+  bool _showMessage = false;
+  set showingMessage(bool value) {
+    if (_showMessage != value) {
+      setState(() {
+        _showMessage = value;
+      });
+    }
+  }
+
+  @override
+  void dispose() {
+    _shortcutsEntry?.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: <Widget>[
+        Row(
+          mainAxisSize: MainAxisSize.min,
+          children: <Widget>[
+            Expanded(
+              child: MenuBar(
+                children: MenuEntry.build(_getMenus()),
+              ),
+            ),
+          ],
+        ),
+        Expanded(
+          child: Container(
+            alignment: Alignment.center,
+            color: backgroundColor,
+            child: Column(
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: <Widget>[
+                Padding(
+                  padding: const EdgeInsets.all(12.0),
+                  child: Text(
+                    showingMessage ? widget.message : '',
+                    style: Theme.of(context).textTheme.headlineSmall,
+                  ),
+                ),
+                Text(_lastSelection != null ? 'Last Selected: $_lastSelection' : ''),
+              ],
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+
+  List<MenuEntry> _getMenus() {
+    final List<MenuEntry> result = <MenuEntry>[
+      MenuEntry(
+        label: 'Menu Demo',
+        menuChildren: <MenuEntry>[
+          MenuEntry(
+            label: 'About',
+            onPressed: () {
+              showAboutDialog(
+                context: context,
+                applicationName: 'MenuBar Sample',
+                applicationVersion: '1.0.0',
+              );
+              setState(() {
+                _lastSelection = 'About';
+              });
+            },
+          ),
+          MenuEntry(
+            label: showingMessage ? 'Hide Message' : 'Show Message',
+            onPressed: () {
+              setState(() {
+                _lastSelection = showingMessage ? 'Hide Message' : 'Show Message';
+                showingMessage = !showingMessage;
+              });
+            },
+            shortcut: const SingleActivator(LogicalKeyboardKey.keyS, control: true),
+          ),
+          // Hides the message, but is only enabled if the message isn't
+          // already hidden.
+          MenuEntry(
+            label: 'Reset Message',
+            onPressed: showingMessage
+                ? () {
+                    setState(() {
+                      _lastSelection = 'Reset Message';
+                      showingMessage = false;
+                    });
+                  }
+                : null,
+            shortcut: const SingleActivator(LogicalKeyboardKey.escape),
+          ),
+          MenuEntry(
+            label: 'Background Color',
+            menuChildren: <MenuEntry>[
+              MenuEntry(
+                label: 'Red Background',
+                onPressed: () {
+                  setState(() {
+                    _lastSelection = 'Red Background';
+                    backgroundColor = Colors.red;
+                  });
+                },
+                shortcut: const SingleActivator(LogicalKeyboardKey.keyR, control: true),
+              ),
+              MenuEntry(
+                label: 'Green Background',
+                onPressed: () {
+                  setState(() {
+                    _lastSelection = 'Green Background';
+                    backgroundColor = Colors.green;
+                  });
+                },
+                shortcut: const SingleActivator(LogicalKeyboardKey.keyG, control: true),
+              ),
+              MenuEntry(
+                label: 'Blue Background',
+                onPressed: () {
+                  setState(() {
+                    _lastSelection = 'Blue Background';
+                    backgroundColor = Colors.blue;
+                  });
+                },
+                shortcut: const SingleActivator(LogicalKeyboardKey.keyB, control: true),
+              ),
+            ],
+          ),
+        ],
+      ),
+    ];
+    // (Re-)register the shortcuts with the ShortcutRegistry so that they are
+    // available to the entire application, and update them if they've changed.
+    _shortcutsEntry?.dispose();
+    _shortcutsEntry = ShortcutRegistry.of(context).addAll(MenuEntry.shortcuts(result));
+    return result;
+  }
+}
+
+class MenuBarApp extends StatelessWidget {
+  const MenuBarApp({super.key});
+
+  static const String kMessage = '"Talk less. Smile more." - A. Burr';
+
+  @override
+  Widget build(BuildContext context) {
+    return const MaterialApp(
+      home: Scaffold(body: MyMenuBar(message: kMessage)),
+    );
+  }
+}
diff --git a/examples/api/test/material/menu_anchor/menu_anchor.0_test.dart b/examples/api/test/material/menu_anchor/menu_anchor.0_test.dart
new file mode 100644
index 0000000..54016dc
--- /dev/null
+++ b/examples/api/test/material/menu_anchor/menu_anchor.0_test.dart
@@ -0,0 +1,107 @@
+// 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 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_api_samples/material/menu_anchor/menu_anchor.0.dart' as example;
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+  testWidgets('Can open menu', (WidgetTester tester) async {
+    await tester.pumpWidget(
+      const example.MenuApp(),
+    );
+
+    await tester.tap(find.byType(TextButton));
+    await tester.pump();
+
+    expect(find.text(example.MenuEntry.about.label), findsOneWidget);
+    expect(find.text(example.MenuEntry.showMessage.label), findsOneWidget);
+    expect(find.text(example.MenuEntry.hideMessage.label), findsNothing);
+    expect(find.text('Background Color'), findsOneWidget);
+    expect(find.text(example.MenuEntry.colorRed.label), findsNothing);
+    expect(find.text(example.MenuEntry.colorGreen.label), findsNothing);
+    expect(find.text(example.MenuEntry.colorBlue.label), findsNothing);
+    expect(find.text(example.MenuApp.kMessage), findsNothing);
+
+    await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+    await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+    await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+    await tester.pump();
+
+    expect(find.text('Background Color'), findsOneWidget);
+
+    await tester.tap(find.text('Background Color'));
+    await tester.pump();
+
+    expect(find.text(example.MenuEntry.colorRed.label), findsOneWidget);
+    expect(find.text(example.MenuEntry.colorGreen.label), findsOneWidget);
+    expect(find.text(example.MenuEntry.colorBlue.label), findsOneWidget);
+
+    await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
+    await tester.sendKeyEvent(LogicalKeyboardKey.enter);
+    await tester.pump();
+
+    expect(find.text(example.MenuApp.kMessage), findsOneWidget);
+    expect(find.text('Last Selected: ${example.MenuEntry.showMessage.label}'), findsOneWidget);
+  });
+
+  testWidgets('Shortcuts work', (WidgetTester tester) async {
+    await tester.pumpWidget(
+      const example.MenuApp(),
+    );
+
+    // Open the menu so we can watch state changes resulting from the shortcuts
+    // firing.
+    await tester.tap(find.byType(TextButton));
+    await tester.pump();
+
+    expect(find.text(example.MenuEntry.showMessage.label), findsOneWidget);
+    expect(find.text(example.MenuEntry.hideMessage.label), findsNothing);
+    expect(find.text(example.MenuApp.kMessage), findsNothing);
+
+    await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
+    await tester.sendKeyEvent(LogicalKeyboardKey.keyS);
+    await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
+    await tester.pump();
+    // Need to pump twice because of the one frame delay in the notification to
+    // update the overlay entry.
+    await tester.pump();
+
+    expect(find.text(example.MenuEntry.showMessage.label), findsNothing);
+    expect(find.text(example.MenuEntry.hideMessage.label), findsOneWidget);
+    expect(find.text(example.MenuApp.kMessage), findsOneWidget);
+
+    await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
+    await tester.sendKeyEvent(LogicalKeyboardKey.keyS);
+    await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
+    await tester.pump();
+    await tester.pump();
+
+    expect(find.text(example.MenuEntry.showMessage.label), findsOneWidget);
+    expect(find.text(example.MenuEntry.hideMessage.label), findsNothing);
+    expect(find.text(example.MenuApp.kMessage), findsNothing);
+
+    await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
+    await tester.sendKeyEvent(LogicalKeyboardKey.keyR);
+    await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
+    await tester.pump();
+
+    expect(find.text('Last Selected: ${example.MenuEntry.colorRed.label}'), findsOneWidget);
+
+    await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
+    await tester.sendKeyEvent(LogicalKeyboardKey.keyG);
+    await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
+    await tester.pump();
+
+    expect(find.text('Last Selected: ${example.MenuEntry.colorGreen.label}'), findsOneWidget);
+
+    await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
+    await tester.sendKeyEvent(LogicalKeyboardKey.keyB);
+    await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
+    await tester.pump();
+
+    expect(find.text('Last Selected: ${example.MenuEntry.colorBlue.label}'), findsOneWidget);
+  });
+}
diff --git a/examples/api/test/material/menu_anchor/menu_anchor.1_test.dart b/examples/api/test/material/menu_anchor/menu_anchor.1_test.dart
new file mode 100644
index 0000000..dbe3547
--- /dev/null
+++ b/examples/api/test/material/menu_anchor/menu_anchor.1_test.dart
@@ -0,0 +1,121 @@
+// 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 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_api_samples/material/menu_anchor/menu_anchor.1.dart' as example;
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+  testWidgets('Can open menu', (WidgetTester tester) async {
+    Finder findMenu() {
+      return find.ancestor(
+        of: find.text(example.MenuEntry.about.label),
+        matching: find.byType(FocusScope),
+      ).first;
+    }
+
+    await tester.pumpWidget(const example.ContextMenuApp());
+
+    await tester.sendKeyDownEvent(LogicalKeyboardKey.controlRight);
+    await tester.tapAt(const Offset(100, 200));
+    await tester.pump();
+    expect(tester.getRect(findMenu()), equals(const Rect.fromLTRB(100.0, 200.0, 404.0, 352.0)));
+
+    // Make sure tapping in a different place causes the menu to move.
+    await tester.tapAt(const Offset(200, 100));
+    await tester.pump();
+    await tester.sendKeyUpEvent(LogicalKeyboardKey.controlRight);
+
+    expect(tester.getRect(findMenu()), equals(const Rect.fromLTRB(200.0, 100.0, 504.0, 252.0)));
+
+    expect(find.text(example.MenuEntry.about.label), findsOneWidget);
+    expect(find.text(example.MenuEntry.showMessage.label), findsOneWidget);
+    expect(find.text(example.MenuEntry.hideMessage.label), findsNothing);
+    expect(find.text('Background Color'), findsOneWidget);
+    expect(find.text(example.MenuEntry.colorRed.label), findsNothing);
+    expect(find.text(example.MenuEntry.colorGreen.label), findsNothing);
+    expect(find.text(example.MenuEntry.colorBlue.label), findsNothing);
+    expect(find.text(example.ContextMenuApp.kMessage), findsNothing);
+
+    await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+    await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+    await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+    await tester.pump();
+
+    expect(find.text('Background Color'), findsOneWidget);
+
+    await tester.tap(find.text('Background Color'));
+    await tester.pump();
+
+    expect(find.text(example.MenuEntry.colorRed.label), findsOneWidget);
+    expect(find.text(example.MenuEntry.colorGreen.label), findsOneWidget);
+    expect(find.text(example.MenuEntry.colorBlue.label), findsOneWidget);
+
+    await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
+    await tester.sendKeyEvent(LogicalKeyboardKey.enter);
+    await tester.pump();
+
+    expect(find.text(example.ContextMenuApp.kMessage), findsOneWidget);
+    expect(find.text('Last Selected: ${example.MenuEntry.showMessage.label}'), findsOneWidget);
+  });
+
+  testWidgets('Shortcuts work', (WidgetTester tester) async {
+    await tester.pumpWidget(
+      const example.ContextMenuApp(),
+    );
+
+    // Open the menu so we can look for state changes reflected in the menu.
+    await tester.sendKeyDownEvent(LogicalKeyboardKey.controlRight);
+    await tester.tapAt(const Offset(100, 200));
+    await tester.pump();
+
+    expect(find.text(example.MenuEntry.showMessage.label), findsOneWidget);
+    expect(find.text(example.MenuEntry.hideMessage.label), findsNothing);
+    expect(find.text(example.ContextMenuApp.kMessage), findsNothing);
+
+    await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
+    await tester.sendKeyEvent(LogicalKeyboardKey.keyS);
+    await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
+    await tester.pump();
+    // Need to pump twice because of the one frame delay in the notification to
+    // update the overlay entry.
+    await tester.pump();
+
+    expect(find.text(example.MenuEntry.showMessage.label), findsNothing);
+    expect(find.text(example.MenuEntry.hideMessage.label), findsOneWidget);
+    expect(find.text(example.ContextMenuApp.kMessage), findsOneWidget);
+
+    await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
+    await tester.sendKeyEvent(LogicalKeyboardKey.keyS);
+    await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
+    await tester.pump();
+    await tester.pump();
+
+    expect(find.text(example.MenuEntry.showMessage.label), findsOneWidget);
+    expect(find.text(example.MenuEntry.hideMessage.label), findsNothing);
+    expect(find.text(example.ContextMenuApp.kMessage), findsNothing);
+
+    await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
+    await tester.sendKeyEvent(LogicalKeyboardKey.keyR);
+    await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
+    await tester.pump();
+
+    expect(find.text('Last Selected: ${example.MenuEntry.colorRed.label}'), findsOneWidget);
+
+    await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
+    await tester.sendKeyEvent(LogicalKeyboardKey.keyG);
+    await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
+    await tester.pump();
+
+    expect(find.text('Last Selected: ${example.MenuEntry.colorGreen.label}'), findsOneWidget);
+
+    await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
+    await tester.sendKeyEvent(LogicalKeyboardKey.keyB);
+    await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
+    await tester.pump();
+
+    expect(find.text('Last Selected: ${example.MenuEntry.colorBlue.label}'), findsOneWidget);
+  });
+}
diff --git a/examples/api/test/material/menu_anchor/menu_bar.0_test.dart b/examples/api/test/material/menu_anchor/menu_bar.0_test.dart
new file mode 100644
index 0000000..b508ba4
--- /dev/null
+++ b/examples/api/test/material/menu_anchor/menu_bar.0_test.dart
@@ -0,0 +1,94 @@
+// 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 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_api_samples/material/menu_anchor/menu_bar.0.dart' as example;
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+  testWidgets('Can open menu', (WidgetTester tester) async {
+    await tester.pumpWidget(
+      const example.MenuBarApp(),
+    );
+
+    final Finder menuBarFinder = find.byType(MenuBar);
+    final MenuBar menuBar = tester.widget<MenuBar>(menuBarFinder);
+    expect(menuBar.children, isNotEmpty);
+    expect(menuBar.children.length, equals(1));
+
+    final Finder menuButtonFinder = find.byType(SubmenuButton).first;
+    await tester.tap(menuButtonFinder);
+    await tester.pump();
+
+    expect(find.text('About'), findsOneWidget);
+    expect(find.text('Show Message'), findsOneWidget);
+    expect(find.text('Reset Message'), findsOneWidget);
+    expect(find.text('Background Color'), findsOneWidget);
+    expect(find.text('Red Background'), findsNothing);
+    expect(find.text('Green Background'), findsNothing);
+    expect(find.text('Blue Background'), findsNothing);
+    expect(find.text(example.MenuBarApp.kMessage), findsNothing);
+
+    await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+    await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+    await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+    await tester.pump();
+
+    expect(find.text('About'), findsOneWidget);
+    expect(find.text('Show Message'), findsOneWidget);
+    expect(find.text('Reset Message'), findsOneWidget);
+    expect(find.text('Background Color'), findsOneWidget);
+    expect(find.text('Red Background'), findsOneWidget);
+    expect(find.text('Green Background'), findsOneWidget);
+    expect(find.text('Blue Background'), findsOneWidget);
+
+    await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
+    await tester.sendKeyEvent(LogicalKeyboardKey.enter);
+    await tester.pump();
+
+    expect(find.text(example.MenuBarApp.kMessage), findsOneWidget);
+    expect(find.text('Last Selected: Show Message'), findsOneWidget);
+  });
+  testWidgets('Shortcuts work', (WidgetTester tester) async {
+    await tester.pumpWidget(
+      const example.MenuBarApp(),
+    );
+
+    expect(find.text(example.MenuBarApp.kMessage), findsNothing);
+
+    await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
+    await tester.sendKeyEvent(LogicalKeyboardKey.keyS);
+    await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
+    await tester.pump();
+
+    expect(find.text(example.MenuBarApp.kMessage), findsOneWidget);
+    await tester.sendKeyEvent(LogicalKeyboardKey.escape);
+    await tester.pump();
+
+    expect(find.text(example.MenuBarApp.kMessage), findsNothing);
+    expect(find.text('Last Selected: Reset Message'), findsOneWidget);
+
+    await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
+    await tester.sendKeyEvent(LogicalKeyboardKey.keyR);
+    await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
+    await tester.pump();
+
+    expect(find.text('Last Selected: Red Background'), findsOneWidget);
+
+    await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
+    await tester.sendKeyEvent(LogicalKeyboardKey.keyG);
+    await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
+    await tester.pump();
+
+    expect(find.text('Last Selected: Green Background'), findsOneWidget);
+
+    await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
+    await tester.sendKeyEvent(LogicalKeyboardKey.keyB);
+    await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
+    await tester.pump();
+
+    expect(find.text('Last Selected: Blue Background'), findsOneWidget);
+  });
+}
diff --git a/packages/flutter/lib/material.dart b/packages/flutter/lib/material.dart
index 5e84a60..33e77f8 100644
--- a/packages/flutter/lib/material.dart
+++ b/packages/flutter/lib/material.dart
@@ -111,6 +111,11 @@
 export 'src/material/material_localizations.dart';
 export 'src/material/material_state.dart';
 export 'src/material/material_state_mixin.dart';
+export 'src/material/menu_anchor.dart';
+export 'src/material/menu_bar_theme.dart';
+export 'src/material/menu_button_theme.dart';
+export 'src/material/menu_style.dart';
+export 'src/material/menu_theme.dart';
 export 'src/material/mergeable_material.dart';
 export 'src/material/navigation_bar.dart';
 export 'src/material/navigation_bar_theme.dart';
diff --git a/packages/flutter/lib/src/material/menu_anchor.dart b/packages/flutter/lib/src/material/menu_anchor.dart
new file mode 100644
index 0000000..3167117
--- /dev/null
+++ b/packages/flutter/lib/src/material/menu_anchor.dart
@@ -0,0 +1,2846 @@
+// 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 'dart:math' as math;
+
+import 'package:flutter/foundation.dart';
+import 'package:flutter/rendering.dart';
+import 'package:flutter/scheduler.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter/widgets.dart';
+
+import 'button_style.dart';
+import 'button_style_button.dart';
+import 'color_scheme.dart';
+import 'colors.dart';
+import 'constants.dart';
+import 'icons.dart';
+import 'ink_well.dart';
+import 'material.dart';
+import 'material_localizations.dart';
+import 'material_state.dart';
+import 'menu_bar_theme.dart';
+import 'menu_button_theme.dart';
+import 'menu_style.dart';
+import 'menu_theme.dart';
+import 'text_button.dart';
+import 'theme.dart';
+import 'theme_data.dart';
+
+// Enable if you want verbose logging about menu changes.
+const bool _kDebugMenus = false;
+
+// The default size of the arrow in _MenuItemLabel that indicates that a menu
+// has a submenu.
+const double _kDefaultSubmenuIconSize = 24;
+
+// The default spacing between the the leading icon, label, trailing icon, and
+// shortcut label in a _MenuItemLabel.
+const double _kLabelItemDefaultSpacing = 18;
+
+// The minimum spacing between the the leading icon, label, trailing icon, and
+// shortcut label in a _MenuItemLabel.
+const double _kLabelItemMinSpacing = 4;
+
+// Navigation shortcuts that we need to make sure are active when menus are
+// open.
+const Map<ShortcutActivator, Intent> _kMenuTraversalShortcuts = <ShortcutActivator, Intent>{
+  SingleActivator(LogicalKeyboardKey.gameButtonA): ActivateIntent(),
+  SingleActivator(LogicalKeyboardKey.escape): DismissIntent(),
+  SingleActivator(LogicalKeyboardKey.tab): NextFocusIntent(),
+  SingleActivator(LogicalKeyboardKey.tab, shift: true): PreviousFocusIntent(),
+  SingleActivator(LogicalKeyboardKey.arrowDown): DirectionalFocusIntent(TraversalDirection.down),
+  SingleActivator(LogicalKeyboardKey.arrowUp): DirectionalFocusIntent(TraversalDirection.up),
+  SingleActivator(LogicalKeyboardKey.arrowLeft): DirectionalFocusIntent(TraversalDirection.left),
+  SingleActivator(LogicalKeyboardKey.arrowRight): DirectionalFocusIntent(TraversalDirection.right),
+};
+
+// The minimum vertical spacing on the outside of menus.
+const double _kMenuVerticalMinPadding = 4;
+
+// How close to the edge of the safe area the menu will be placed.
+const double _kMenuViewPadding = 8;
+
+// The minimum horizontal spacing on the outside of the top level menu.
+const double _kTopLevelMenuHorizontalMinPadding = 4;
+
+/// The type of builder function used by [MenuAnchor.builder] to build the
+/// widget that the [MenuAnchor] surrounds.
+///
+/// The `context` is the context that the widget is being built in.
+///
+/// The `controller` is the [MenuController] that can be used to open and close
+/// the menu with.
+///
+/// The `child` is an optional child supplied as the [MenuAnchor.child]
+/// attribute. The child is intended to be incorporated in the result of the
+/// function.
+typedef MenuAnchorChildBuilder = Widget Function(
+  BuildContext context,
+  MenuController controller,
+  Widget? child,
+);
+
+/// A widget used to mark the "anchor" for a set of submenus, defining the
+/// rectangle used to position the menu, which can be done either with an
+/// explicit location, or with an alignment.
+///
+/// When creating a menu with [MenuBar] or a [SubmenuButton], a [MenuAnchor] is
+/// not needed, since they provide their own internally.
+///
+/// The [MenuAnchor] is meant to be a slightly lower level interface than
+/// [MenuBar], used in situations where a [MenuBar] isn't appropriate, or to
+/// construct widgets or screen regions that have submenus.
+///
+/// {@tool dartpad}
+/// This example shows how to use a [MenuAnchor] to wrap a button and open a
+/// cascading menu from the button.
+///
+/// ** See code in examples/api/lib/material/menu_anchor/menu_anchor.0.dart **
+/// {@end-tool}
+///
+/// {@tool dartpad}
+/// This example shows how to use a [MenuAnchor] to create a cascading context
+/// menu in a region of the view, positioned where the user clicks the mouse
+/// with Ctrl pressed. The [anchorTapClosesMenu] attribute is set to true so
+/// that clicks on the [MenuAnchor] area will cause the menus to be closed.
+///
+/// ** See code in examples/api/lib/material/menu_anchor/menu_anchor.1.dart **
+/// {@end-tool}
+class MenuAnchor extends StatefulWidget {
+  /// Creates a const [MenuAnchor].
+  ///
+  /// The [menuChildren] argument is required.
+  const MenuAnchor({
+    super.key,
+    this.controller,
+    this.childFocusNode,
+    this.style,
+    this.alignmentOffset = Offset.zero,
+    this.clipBehavior = Clip.none,
+    this.anchorTapClosesMenu = false,
+    this.onOpen,
+    this.onClose,
+    required this.menuChildren,
+    this.builder,
+    this.child,
+  });
+
+  /// An optional controller that allows opening and closing of the menu from
+  /// other widgets.
+  final MenuController? controller;
+
+  /// The [childFocusNode] attribute is the optional [FocusNode] also associated
+  /// the [child] or [builder] widget that opens the menu.
+  ///
+  /// The focus node should be attached to the widget that should receive focus
+  /// if keyboard focus traversal moves the focus off of the submenu with the
+  /// arrow keys.
+  ///
+  /// If not supplied, then keyboard traversal from the menu back to the
+  /// controlling button when the menu is open is disabled.
+  final FocusNode? childFocusNode;
+
+  /// The [MenuStyle] that defines the visual attributes of the menu bar.
+  ///
+  /// Colors and sizing of the menus is controllable via the [MenuStyle].
+  ///
+  /// Defaults to the ambient [MenuThemeData.style].
+  final MenuStyle? style;
+
+  /// The offset of the menu relative to the alignment origin determined by
+  /// [MenuStyle.alignment] on the [style] attribute and the ambient
+  /// [Directionality].
+  ///
+  /// Use this for adjustments of the menu placement.
+  ///
+  /// Increasing [Offset.dy] values of [alignmentOffset] move the menu position
+  /// down.
+  ///
+  /// If the [MenuStyle.alignment] from [style] is not an [AlignmentDirectional]
+  /// (e.g. [Alignment]), then increasing [Offset.dx] values of
+  /// [alignmentOffset] move the menu position to the right.
+  ///
+  /// If the [MenuStyle.alignment] from [style] is an [AlignmentDirectional],
+  /// then in a [TextDirection.ltr] [Directionality], increasing [Offset.dx]
+  /// values of [alignmentOffset] move the menu position to the right. In a
+  /// [TextDirection.rtl] directionality, increasing [Offset.dx] values of
+  /// [alignmentOffset] move the menu position to the left.
+  ///
+  /// Defaults to [Offset.zero].
+  final Offset? alignmentOffset;
+
+  /// {@macro flutter.material.Material.clipBehavior}
+  ///
+  /// Defaults to [Clip.none].
+  final Clip clipBehavior;
+
+  /// Whether the menus will be closed if the anchor area is tapped.
+  ///
+  /// For menus opened by buttons that toggle the menu, if the button is tapped
+  /// when the menu is open, the button should close the menu. But if
+  /// [anchorTapClosesMenu] is true, then the menu will close, and
+  /// (surprisingly) immediately re-open. This is because tapping on the button
+  /// closes the menu before the `onPressed` or `onTap` handler is called
+  /// because of it being considered to be "outside" the menu system, and then
+  /// the button (seeing that the menu is closed) immediately reopens the menu.
+  /// The result is that the user thinks that tapping on the button does
+  /// nothing. So, for button-initiated menus, this value is typically false so
+  /// that the menu anchor area is considered "inside" of the menu system and
+  /// doesn't cause it to close unless [MenuController.close] is called.
+  ///
+  /// For menus that are positioned using [MenuController.open]'s `position`
+  /// parameter, it is often desirable that clicking on the anchor always closes
+  /// the menu since the anchor area isn't usually considered part of the menu
+  /// system by the user. In this case [anchorTapClosesMenu] should be true.
+  ///
+  /// Defaults to false.
+  final bool anchorTapClosesMenu;
+
+  /// A callback that is invoked when the menu is opened.
+  final VoidCallback? onOpen;
+
+  /// A callback that is invoked when the menu is closed.
+  final VoidCallback? onClose;
+
+  /// A list of children containing the menu items that are the contents of the
+  /// menu surrounded by this [MenuAnchor].
+  ///
+  /// {@macro flutter.material.menu_bar.shortcuts_note}
+  final List<Widget> menuChildren;
+
+  /// The widget that this [MenuAnchor] surrounds.
+  ///
+  /// Typically this is a button used to open the menu by calling
+  /// [MenuController.open] on the `controller` passed to the builder.
+  ///
+  /// If not supplied, then the [MenuAnchor] will be the size that its parent
+  /// allocates for it.
+  final MenuAnchorChildBuilder? builder;
+
+  /// The optional child to be passed to the [builder].
+  ///
+  /// Supply this child if there is a portion of the widget tree built in
+  /// [builder] that doesn't depend on the `controller` or `context` supplied to
+  /// the [builder]. It will be more efficient, since Flutter doesn't then need
+  /// to rebuild this child when those change.
+  final Widget? child;
+
+  @override
+  State<MenuAnchor> createState() => _MenuAnchorState();
+
+  @override
+  List<DiagnosticsNode> debugDescribeChildren() {
+    return menuChildren.map<DiagnosticsNode>((Widget child) => child.toDiagnosticsNode()).toList();
+  }
+
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(FlagProperty('anchorTapClosesMenu', value: anchorTapClosesMenu, ifTrue: 'AUTO-CLOSE'));
+    properties.add(DiagnosticsProperty<FocusNode?>('focusNode', childFocusNode));
+    properties.add(DiagnosticsProperty<MenuStyle?>('style', style));
+    properties.add(EnumProperty<Clip>('clipBehavior', clipBehavior));
+    properties.add(DiagnosticsProperty<Offset?>('alignmentOffset', alignmentOffset));
+    properties.add(StringProperty('child', child.toString()));
+  }
+}
+
+class _MenuAnchorState extends State<MenuAnchor> {
+  // This is the global key that is used later to determine the bounding rect
+  // for the anchor's region that the CustomSingleChildLayout's delegate
+  // uses to determine where to place the menu on the screen and to avoid the
+  // view's edges.
+  final GlobalKey _anchorKey = GlobalKey(debugLabel: kReleaseMode ? null : 'MenuAnchor');
+  _MenuAnchorState? _parent;
+  bool _childIsOpen = false;
+  final FocusScopeNode _menuScopeNode = FocusScopeNode(debugLabel: kReleaseMode ? null : 'MenuAnchor sub menu');
+  MenuController? _internalMenuController;
+  final List<_MenuAnchorState> _anchorChildren = <_MenuAnchorState>[];
+  ScrollPosition? _position;
+  Size? _viewSize;
+  OverlayEntry? _overlayEntry;
+  Axis get _orientation => Axis.vertical;
+  bool get _isOpen => _overlayEntry != null;
+  bool get _isRoot => _parent == null;
+  bool get _isTopLevel => _parent?._isRoot ?? false;
+  MenuController get _menuController => widget.controller ?? _internalMenuController!;
+
+  @override
+  void initState() {
+    super.initState();
+    if (widget.controller == null) {
+      _internalMenuController = MenuController();
+    }
+    _menuController._attach(this);
+  }
+
+  @override
+  void dispose() {
+    assert(_debugMenuInfo('Disposing of $this'));
+    if (_isOpen) {
+      _close(inDispose: true);
+      _parent?._removeChild(this);
+    }
+    _anchorChildren.clear();
+    _menuController._detach(this);
+    _internalMenuController = null;
+    super.dispose();
+  }
+
+  @override
+  void didChangeDependencies() {
+    super.didChangeDependencies();
+    _parent?._removeChild(this);
+    _parent = _MenuAnchorState._maybeOf(context);
+    _parent?._addChild(this);
+    _position?.isScrollingNotifier.removeListener(_handleScroll);
+    _position = Scrollable.of(context)?.position;
+    _position?.isScrollingNotifier.addListener(_handleScroll);
+    final Size newSize = MediaQuery.of(context).size;
+    if (_viewSize != null && newSize != _viewSize) {
+      // Close the menus if the view changes size.
+      _root._close();
+    }
+    _viewSize = newSize;
+  }
+
+  @override
+  void didUpdateWidget(MenuAnchor oldWidget) {
+    super.didUpdateWidget(oldWidget);
+    if (oldWidget.controller != widget.controller) {
+      oldWidget.controller?._detach(this);
+      if (widget.controller != null) {
+        _internalMenuController?._detach(this);
+        _internalMenuController = null;
+        widget.controller?._attach(this);
+      } else {
+        assert(_internalMenuController == null);
+        _internalMenuController = MenuController().._attach(this);
+      }
+    }
+    assert(_menuController._anchor == this);
+    if (_overlayEntry != null) {
+      // Needs to update the overlay entry on the next frame, since it's in the
+      // overlay.
+      SchedulerBinding.instance.addPostFrameCallback((Duration _) {
+        _overlayEntry!.markNeedsBuild();
+      });
+    }
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    Widget child = _buildContents(context);
+
+    if (!widget.anchorTapClosesMenu) {
+      child = TapRegion(
+        groupId: _root,
+        onTapOutside: (PointerDownEvent event) {
+          assert(_debugMenuInfo('Tapped Outside ${widget.controller}'));
+          _closeChildren();
+        },
+        child: child,
+      );
+    }
+
+    return _MenuAnchorMarker(
+      anchorKey: _anchorKey,
+      anchor: this,
+      child: child,
+    );
+  }
+
+  Widget _buildContents(BuildContext context) {
+    return Builder(
+      key: _anchorKey,
+      builder: (BuildContext context) {
+        if (widget.builder == null) {
+          return widget.child ?? const SizedBox();
+        }
+        return widget.builder!(
+          context,
+          _menuController,
+          widget.child,
+        );
+      },
+    );
+  }
+
+  // Returns the first focusable item in the submenu, where "first" is
+  // determined by the focus traversal policy.
+  FocusNode? get _firstItemFocusNode {
+    if (_menuScopeNode.context == null) {
+      return null;
+    }
+    final FocusTraversalPolicy policy =
+        FocusTraversalGroup.maybeOf(_menuScopeNode.context!) ?? ReadingOrderTraversalPolicy();
+    return policy.findFirstFocus(_menuScopeNode, ignoreCurrentFocus: true);
+  }
+
+  void _addChild(_MenuAnchorState child) {
+    assert(_isRoot || _debugMenuInfo('Added root child: $child'));
+    assert(!_anchorChildren.contains(child));
+    _anchorChildren.add(child);
+    assert(_debugMenuInfo('Tree:\n${widget.toStringDeep()}'));
+  }
+
+  void _removeChild(_MenuAnchorState child) {
+    assert(_isRoot || _debugMenuInfo('Removed root child: $child'));
+    assert(_anchorChildren.contains(child));
+    _anchorChildren.remove(child);
+    assert(_debugMenuInfo('Tree:\n${widget.toStringDeep()}'));
+  }
+
+  _MenuAnchorState? get _nextSibling {
+    final int index = _parent!._anchorChildren.indexOf(this);
+    assert(index != -1, 'Unable to find this widget $this in parent $_parent');
+    if (index < _parent!._anchorChildren.length - 1) {
+      return _parent!._anchorChildren[index + 1];
+    }
+    return null;
+  }
+
+  _MenuAnchorState? get _previousSibling {
+    final int index = _parent!._anchorChildren.indexOf(this);
+    assert(index != -1, 'Unable to find this widget $this in parent $_parent');
+    if (index > 0) {
+      return _parent!._anchorChildren[index - 1];
+    }
+    return null;
+  }
+
+  _MenuAnchorState get _root {
+    _MenuAnchorState anchor = this;
+    while (anchor._parent != null) {
+      anchor = anchor._parent!;
+    }
+    return anchor;
+  }
+
+  _MenuAnchorState get _topLevel {
+    _MenuAnchorState handle = this;
+    while (handle._parent!._isTopLevel) {
+      handle = handle._parent!;
+    }
+    return handle;
+  }
+
+  void _childChangedOpenState(bool value) {
+    if (_childIsOpen != value) {
+      _parent?._childChangedOpenState(_childIsOpen || _isOpen);
+      if (mounted) {
+        setState(() {
+          _childIsOpen = value;
+        });
+      }
+    }
+  }
+
+  void _focusButton() {
+    if (widget.childFocusNode == null) {
+      return;
+    }
+    assert(_debugMenuInfo('Requesting focus for ${widget.childFocusNode}'));
+    widget.childFocusNode!.requestFocus();
+  }
+
+  void _handleScroll() {
+    // If an ancestor scrolls, and we're a top level or root anchor, then close
+    // the menus. Don't just close it on *any* scroll, since we want to be able
+    // to scroll menus themselves if they're too big for the view.
+    if (_isTopLevel || _isRoot) {
+      _root._close();
+    }
+  }
+
+  /// Open the menu, optionally at a position relative to the [MenuAnchor].
+  ///
+  /// Call this when the menu should be shown to the user.
+  ///
+  /// The optional `position` argument will specify the location of the menu in
+  /// the local coordinates of the [MenuAnchor], ignoring any
+  /// [MenuStyle.alignment] and/or [MenuAnchor.alignmentOffset] that were
+  /// specified.
+  void _open({Offset? position}) {
+    assert(_menuController._anchor == this);
+    if (_isOpen && position == null) {
+      assert(_debugMenuInfo("Not opening $this because it's already open"));
+      return;
+    }
+    if (_isOpen && position != null) {
+      // The menu is already open, but we need to move to another location, so
+      // close it first.
+      _close();
+    }
+    assert(_debugMenuInfo('Opening ${this} at ${position ?? Offset.zero} with alignment offset ${widget.alignmentOffset ?? Offset.zero}'));
+    _parent?._closeChildren(); // Close all siblings.
+    assert(_overlayEntry == null);
+
+    final BuildContext outerContext = context;
+    setState(() {
+      _parent?._childChangedOpenState(true);
+      _overlayEntry = OverlayEntry(
+        builder: (BuildContext context) {
+          final OverlayState overlay = Overlay.of(outerContext);
+          return Positioned.directional(
+            textDirection: Directionality.of(outerContext),
+            top: 0,
+            start: 0,
+            child: Directionality(
+              textDirection: Directionality.of(outerContext),
+              child: InheritedTheme.captureAll(
+                // Copy all the themes from the supplied outer context to the
+                // overlay.
+                outerContext,
+                _MenuAnchorMarker(
+                  // Re-advertize the anchor here in the overlay, since
+                  // otherwise a search for the anchor by descendants won't find
+                  // it.
+                  anchorKey: _anchorKey,
+                  anchor: this,
+                  child: _Submenu(
+                    anchor: this,
+                    menuStyle: widget.style,
+                    alignmentOffset: widget.alignmentOffset ?? Offset.zero,
+                    menuPosition: position,
+                    clipBehavior: widget.clipBehavior,
+                    menuChildren: widget.menuChildren,
+                  ),
+                ),
+                to: overlay.context,
+              ),
+            ),
+          );
+        },
+      );
+    });
+
+    Overlay.of(context).insert(_overlayEntry!);
+    widget.onOpen?.call();
+  }
+
+  /// Close the menu.
+  ///
+  /// Call this when the menu should be closed. Has no effect if the menu is
+  /// already closed.
+  void _close({bool inDispose = false}) {
+    assert(_debugMenuInfo('Closing $this'));
+    if (!_isOpen) {
+      return;
+    }
+    _closeChildren(inDispose: inDispose);
+    _overlayEntry?.remove();
+    _overlayEntry = null;
+    if (!inDispose && mounted) {
+      setState(() {
+        // Notify that _isOpen may have changed state, but only if not currently
+        // disposing or unmounted.
+        _parent?._childChangedOpenState(false);
+      });
+    }
+    widget.onClose?.call();
+  }
+
+  void _closeChildren({bool inDispose = false}) {
+    assert(_debugMenuInfo('Closing children of ${this}${inDispose ? ' (dispose)' : ''}'));
+    for (final _MenuAnchorState child in List<_MenuAnchorState>.from(_anchorChildren)) {
+      child._close(inDispose: inDispose);
+    }
+  }
+
+  // Returns the active anchor in the given context, if any, and creates a
+  // dependency relationship that will rebuild the context when the node
+  // changes.
+  static _MenuAnchorState? _maybeOf(BuildContext context) {
+    return context.dependOnInheritedWidgetOfExactType<_MenuAnchorMarker>()?.anchor;
+  }
+}
+
+/// A controller to manage a menu created by a [MenuBar] or [MenuAnchor].
+///
+/// A [MenuController] is used to control and interrogate a menu after it has
+/// been created, with methods such as [open] and [close], and state accessors
+/// like [isOpen].
+///
+/// See also:
+///
+/// * [MenuAnchor], a widget that defines a region that has submenu.
+/// * [MenuBar], a widget that creates a menu bar, that can take an optional
+///   [MenuController].
+/// * [SubmenuButton], a widget that has a button that manages a submenu.
+class MenuController {
+  /// The anchor that this controller controls.
+  ///
+  /// This is set automatically when a [MenuController] is given to the anchor
+  /// it controls.
+  _MenuAnchorState? _anchor;
+
+  /// Whether or not the associated menu is currently open.
+  bool get isOpen {
+    assert(_anchor != null);
+    return _anchor!._isOpen;
+  }
+
+  /// Close the menu that this menu controller is associated with.
+  ///
+  /// Associating with a menu is done by passing a [MenuController] to a
+  /// [MenuAnchor]. A [MenuController] is also be received by the
+  /// [MenuAnchor.builder] when invoked.
+  ///
+  /// If the menu's anchor point (either a [MenuBar] or a [MenuAnchor]) is
+  /// scrolled by an ancestor, or the view changes size, then any open menu will
+  /// automatically close.
+  void close() {
+    assert(_anchor != null);
+    _anchor!._close();
+  }
+
+  /// Opens the menu that this menu controller is associated with.
+  ///
+  /// If `position` is given, then the menu will open at the position given, in
+  /// the coordinate space of the [MenuAnchor] this controller is attached to.
+  ///
+  /// If given, the `position` will override the [MenuAnchor.alignmentOffset]
+  /// given to the [MenuAnchor].
+  ///
+  /// If the menu's anchor point (either a [MenuBar] or a [MenuAnchor]) is
+  /// scrolled by an ancestor, or the view changes size, then any open menu will
+  /// automatically close.
+  void open({Offset? position}) {
+    assert(_anchor != null);
+    _anchor!._open(position: position);
+  }
+
+  // ignore: use_setters_to_change_properties
+  void _attach(_MenuAnchorState anchor) {
+    _anchor = anchor;
+  }
+
+  void _detach(_MenuAnchorState anchor) {
+    if (_anchor == anchor) {
+      _anchor = null;
+    }
+  }
+}
+
+/// A menu bar that manages cascading child menus.
+///
+/// This is a Material Design menu bar that typically resides above the main
+/// body of an application (but can go anywhere) that defines a menu system for
+/// invoking callbacks in response to user selection of a menu item.
+///
+/// The menus can be opened with a click or tap. Once a menu is opened, it can
+/// be navigated by using the arrow and tab keys or via mouse hover. Selecting a
+/// menu item can be done by pressing enter, or by clicking or tapping on the
+/// menu item. Clicking or tapping on any part of the user interface that isn't
+/// part of the menu system controlled by the same controller will cause all of
+/// the menus controlled by that controller to close, as will pressing the
+/// escape key.
+///
+/// When a menu item with a submenu is clicked on, it toggles the visibility of
+/// the submenu. When the menu item is hovered over, the submenu will open, and
+/// hovering over other items will close the previous menu and open the newly
+/// hovered one. When those open/close transitions occur, [SubmenuButton.onOpen],
+/// and [SubmenuButton.onClose] are called on the corresponding [SubmenuButton] child
+/// of the menu bar.
+///
+/// {@template flutter.material.menu_bar.shortcuts_note}
+/// Menus using [MenuItemButton] can have a [SingleActivator] or
+/// [CharacterActivator] assigned to them as their [MenuItemButton.shortcut],
+/// which will display an appropriate shortcut hint. Even though the shortcut
+/// labels are displayed in the menu, shortcuts are not automatically handled.
+/// They must be available in whatever context they are appropriate, and handled
+/// via another mechanism.
+///
+/// If shortcuts should be generally enabled, but are not easily defined in a
+/// context surrounding the menu bar, consider registering them with a
+/// [ShortcutRegistry] (one is already included in the [WidgetsApp], and thus
+/// also [MaterialApp] and [CupertinoApp]), as shown in the example below. To be
+/// sure that selecting a menu item and triggering the shortcut do the same
+/// thing, it is recommended that they call the same callback.
+///
+/// {@tool dartpad}
+/// This example shows a [MenuBar] that contains a single top level menu,
+/// containing three items: "About", a checkbox menu item for showing a
+/// message, and "Quit". The items are identified with an enum value, and the
+/// shortcuts are registered globally with the [ShortcutRegistry].
+///
+/// ** See code in examples/api/lib/material/menu_anchor/menu_bar.0.dart **
+/// {@end-tool}
+/// {@endtemplate}
+///
+/// See also:
+///
+/// * [MenuAnchor], a widget that creates a region with a submenu and shows it
+///   when requested.
+/// * [SubmenuButton], a menu item which manages a submenu.
+/// * [MenuItemButton], a leaf menu item which displays the label, an optional
+///   shortcut label, and optional leading and trailing icons.
+/// * [PlatformMenuBar], which creates a menu bar that is rendered by the host
+///   platform instead of by Flutter (on macOS, for example).
+/// * [ShortcutRegistry], a registry of shortcuts that apply for the entire
+///   application.
+/// * [VoidCallbackIntent] to define intents that will call a [VoidCallback] and
+///   work with the [Actions] and [Shortcuts] system.
+/// * [CallbackShortcuts] to define shortcuts that simply call a callback and
+///   don't involve using [Actions].
+class MenuBar extends StatelessWidget {
+  /// Creates a const [MenuBar].
+  ///
+  /// The [children] argument is required.
+  const MenuBar({
+    super.key,
+    this.style,
+    this.clipBehavior = Clip.none,
+    this.controller,
+    required this.children,
+  });
+
+  /// The [MenuStyle] that defines the visual attributes of the menu bar.
+  ///
+  /// Colors and sizing of the menus is controllable via the [MenuStyle].
+  ///
+  /// Defaults to the ambient [MenuThemeData.style].
+  final MenuStyle? style;
+
+  /// {@macro flutter.material.Material.clipBehavior}
+  ///
+  /// Defaults to [Clip.none].
+  final Clip clipBehavior;
+
+  /// The [MenuController] to use for this menu bar.
+  final MenuController? controller;
+
+  /// The list of menu items that are the top level children of the [MenuBar].
+  ///
+  /// A Widget in Flutter is immutable, so directly modifying the [children]
+  /// with [List] APIs such as `someMenuBarWidget.menus.add(...)` will result in
+  /// incorrect behaviors. Whenever the menus list is modified, a new list
+  /// object must be provided.
+  ///
+  /// {@macro flutter.material.menu_bar.shortcuts_note}
+  final List<Widget> children;
+
+  @override
+  Widget build(BuildContext context) {
+    assert(debugCheckHasOverlay(context));
+    return _MenuBarAnchor(
+      controller: controller,
+      clipBehavior: clipBehavior,
+      style: style,
+      menuChildren: children,
+    );
+  }
+
+  @override
+  List<DiagnosticsNode> debugDescribeChildren() {
+    return <DiagnosticsNode>[
+      ...children.map<DiagnosticsNode>(
+            (Widget item) => item.toDiagnosticsNode(),
+      ),
+    ];
+  }
+
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(DiagnosticsProperty<MenuStyle?>('style', style, defaultValue: null));
+    properties.add(DiagnosticsProperty<Clip>('clipBehavior', clipBehavior, defaultValue: null));
+  }
+}
+
+/// A button for use in a [MenuBar], in a menu created with [MenuAnchor], or on
+/// its own, that can be activated by click or keyboard navigation.
+///
+/// This widget represents a leaf entry in a menu hierarchy that is typically
+/// part of a [MenuBar], but may be used independently, or as part of a menu
+/// created with a [MenuAnchor].
+///
+/// {@macro flutter.material.menu_bar.shortcuts_note}
+///
+/// See also:
+///
+/// * [MenuBar], a class that creates a top level menu bar in a Material Design
+///   style.
+/// * [MenuAnchor], a widget that creates a region with a submenu and shows it
+///   when requested.
+/// * [SubmenuButton], a menu item similar to this one which manages a submenu.
+/// * [PlatformMenuBar], which creates a menu bar that is rendered by the host
+///   platform instead of by Flutter (on macOS, for example).
+/// * [ShortcutRegistry], a registry of shortcuts that apply for the entire
+///   application.
+/// * [VoidCallbackIntent] to define intents that will call a [VoidCallback] and
+///   work with the [Actions] and [Shortcuts] system.
+/// * [CallbackShortcuts] to define shortcuts that simply call a callback and
+///   don't involve using [Actions].
+class MenuItemButton extends StatefulWidget {
+  /// Creates a const [MenuItemButton].
+  ///
+  /// The [child] attribute is required.
+  const MenuItemButton({
+    super.key,
+    this.onPressed,
+    this.onHover,
+    this.onFocusChange,
+    this.focusNode,
+    this.shortcut,
+    this.style,
+    this.statesController,
+    this.clipBehavior = Clip.none,
+    this.leadingIcon,
+    this.trailingIcon,
+    required this.child,
+  });
+
+  /// Called when the button is tapped or otherwise activated.
+  ///
+  /// If this callback is null, then the button will be disabled.
+  ///
+  /// See also:
+  ///
+  ///  * [enabled], which is true if the button is enabled.
+  final VoidCallback? onPressed;
+
+  /// Called when a pointer enters or exits the button response area.
+  ///
+  /// The value passed to the callback is true if a pointer has entered button
+  /// area and false if a pointer has exited.
+  final ValueChanged<bool>? onHover;
+
+  /// Handler called when the focus changes.
+  ///
+  /// Called with true if this widget's node gains focus, and false if it loses
+  /// focus.
+  final ValueChanged<bool>? onFocusChange;
+
+  /// {@macro flutter.widgets.Focus.focusNode}
+  final FocusNode? focusNode;
+
+  /// The optional shortcut that selects this [MenuItemButton].
+  ///
+  /// {@macro flutter.material.menu_bar.shortcuts_note}
+  final MenuSerializableShortcut? shortcut;
+
+  /// Customizes this button's appearance.
+  ///
+  /// Non-null properties of this style override the corresponding properties in
+  /// [themeStyleOf] and [defaultStyleOf]. [MaterialStateProperty]s that resolve
+  /// to non-null values will similarly override the corresponding
+  /// [MaterialStateProperty]s in [themeStyleOf] and [defaultStyleOf].
+  ///
+  /// Null by default.
+  final ButtonStyle? style;
+
+  /// {@macro flutter.material.inkwell.statesController}
+  final MaterialStatesController? statesController;
+
+  /// {@macro flutter.material.Material.clipBehavior}
+  ///
+  /// Defaults to [Clip.none].
+  final Clip clipBehavior;
+
+  /// An optional icon to display before the [child] label.
+  final Widget? leadingIcon;
+
+  /// An optional icon to display after the [child] label.
+  final Widget? trailingIcon;
+
+  /// The widget displayed in the center of this button.
+  ///
+  /// Typically this is the button's label, using a [Text] widget.
+  ///
+  /// {@macro flutter.widgets.ProxyWidget.child}
+  final Widget? child;
+
+  /// Whether the button is enabled or disabled.
+  ///
+  /// To enable a button, set its [onPressed] property to a non-null value.
+  bool get enabled => onPressed != null;
+
+  @override
+  State<MenuItemButton> createState() => _MenuItemButtonState();
+
+  /// Defines the button's default appearance.
+  ///
+  /// {@macro flutter.material.text_button.default_style_of}
+  ///
+  /// {@macro flutter.material.text_button.material3_defaults}
+  ButtonStyle defaultStyleOf(BuildContext context) {
+    return _MenuButtonDefaultsM3(context);
+  }
+
+  /// Returns the [MenuButtonThemeData.style] of the closest
+  /// [MenuButtonTheme] ancestor.
+  ButtonStyle? themeStyleOf(BuildContext context) {
+    return MenuButtonTheme.of(context).style;
+  }
+
+  /// A static convenience method that constructs a [MenuItemButton]'s
+  /// [ButtonStyle] given simple values.
+  ///
+  /// The [foregroundColor] color is used to create a [MaterialStateProperty]
+  /// [ButtonStyle.foregroundColor] value. Specify a value for [foregroundColor]
+  /// to specify the color of the button's icons. Use [backgroundColor] for the
+  /// button's background fill color. Use [disabledForegroundColor] and
+  /// [disabledBackgroundColor] to specify the button's disabled icon and fill
+  /// color.
+  ///
+  /// All of the other parameters are either used directly or used to create a
+  /// [MaterialStateProperty] with a single value for all states.
+  ///
+  /// All parameters default to null, by default this method returns a
+  /// [ButtonStyle] that doesn't override anything.
+  ///
+  /// For example, to override the default foreground color for a
+  /// [MenuItemButton], as well as its overlay color, with all of the standard
+  /// opacity adjustments for the pressed, focused, and hovered states, one
+  /// could write:
+  ///
+  /// ```dart
+  /// MenuItemButton(
+  ///   leadingIcon: const Icon(Icons.pets),
+  ///   style: MenuItemButton.styleFrom(foregroundColor: Colors.green),
+  ///   onPressed: () {
+  ///     // ...
+  ///   },
+  ///   child: const Text('Button Label'),
+  /// ),
+  /// ```
+  static ButtonStyle styleFrom({
+    Color? foregroundColor,
+    Color? backgroundColor,
+    Color? disabledForegroundColor,
+    Color? disabledBackgroundColor,
+    Color? shadowColor,
+    Color? surfaceTintColor,
+    TextStyle? textStyle,
+    double? elevation,
+    EdgeInsetsGeometry? padding,
+    Size? minimumSize,
+    Size? fixedSize,
+    Size? maximumSize,
+    MouseCursor? enabledMouseCursor,
+    MouseCursor? disabledMouseCursor,
+    BorderSide? side,
+    OutlinedBorder? shape,
+    VisualDensity? visualDensity,
+    MaterialTapTargetSize? tapTargetSize,
+    Duration? animationDuration,
+    bool? enableFeedback,
+    AlignmentGeometry? alignment,
+    InteractiveInkFeatureFactory? splashFactory,
+  }) {
+    return TextButton.styleFrom(
+      foregroundColor: foregroundColor,
+      backgroundColor: backgroundColor,
+      disabledBackgroundColor: disabledBackgroundColor,
+      disabledForegroundColor: disabledForegroundColor,
+      shadowColor: shadowColor,
+      surfaceTintColor: surfaceTintColor,
+      textStyle: textStyle,
+      elevation: elevation,
+      padding: padding,
+      minimumSize: minimumSize,
+      fixedSize: fixedSize,
+      maximumSize: maximumSize,
+      enabledMouseCursor: enabledMouseCursor,
+      disabledMouseCursor: disabledMouseCursor,
+      side: side,
+      shape: shape,
+      visualDensity: visualDensity,
+      tapTargetSize: tapTargetSize,
+      animationDuration: animationDuration,
+      enableFeedback: enableFeedback,
+      alignment: alignment,
+      splashFactory: splashFactory,
+    );
+  }
+
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(FlagProperty('enabled', value: onPressed != null, ifFalse: 'DISABLED'));
+    properties.add(DiagnosticsProperty<String>('child', child.toString()));
+    properties.add(DiagnosticsProperty<ButtonStyle?>('style', style, defaultValue: null));
+    properties.add(DiagnosticsProperty<MenuSerializableShortcut?>('shortcut', shortcut, defaultValue: null));
+    properties.add(DiagnosticsProperty<Widget?>('leadingIcon', leadingIcon, defaultValue: null));
+    properties.add(DiagnosticsProperty<Widget?>('trailingIcon', trailingIcon, defaultValue: null));
+    properties.add(DiagnosticsProperty<FocusNode?>('focusNode', focusNode, defaultValue: null));
+    properties.add(EnumProperty<Clip>('clipBehavior', clipBehavior, defaultValue: Clip.none));
+    properties.add(DiagnosticsProperty<MaterialStatesController?>('statesController', statesController, defaultValue: null));
+  }
+}
+
+class _MenuItemButtonState extends State<MenuItemButton> {
+  // If a focus node isn't given to the widget, then we have to manage our own.
+  FocusNode? _internalFocusNode;
+  FocusNode get _focusNode => widget.focusNode ?? _internalFocusNode!;
+
+  @override
+  void initState() {
+    super.initState();
+    _createInternalFocusNodeIfNeeded();
+    _focusNode.addListener(_handleFocusChange);
+  }
+
+  @override
+  void dispose() {
+    _focusNode.removeListener(_handleFocusChange);
+    _internalFocusNode?.dispose();
+    _internalFocusNode = null;
+    super.dispose();
+  }
+
+  @override
+  void didUpdateWidget(MenuItemButton oldWidget) {
+    if (widget.focusNode != oldWidget.focusNode) {
+      _focusNode.removeListener(_handleFocusChange);
+      if (widget.focusNode != null) {
+        _internalFocusNode?.dispose();
+        _internalFocusNode = null;
+      }
+      _createInternalFocusNodeIfNeeded();
+      _focusNode.addListener(_handleFocusChange);
+    }
+    super.didUpdateWidget(oldWidget);
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    // Since we don't want to use the theme style or default style from the
+    // TextButton, we merge the styles, merging them in the right order when
+    // each type of style exists. Each "*StyleOf" function is only called once.
+    final ButtonStyle mergedStyle =
+        widget.style?.merge(widget.themeStyleOf(context)?.merge(widget.defaultStyleOf(context))) ??
+            widget.themeStyleOf(context)?.merge(widget.defaultStyleOf(context)) ??
+            widget.defaultStyleOf(context);
+
+    return TextButton(
+      onPressed: widget.enabled ? _handleSelect : null,
+      onHover: widget.enabled ? _handleHover : null,
+      onFocusChange: widget.enabled ? widget.onFocusChange : null,
+      focusNode: _focusNode,
+      style: mergedStyle,
+      statesController: widget.statesController,
+      clipBehavior: widget.clipBehavior,
+      child: _MenuItemLabel(
+        leadingIcon: widget.leadingIcon,
+        shortcut: widget.shortcut,
+        trailingIcon: widget.trailingIcon,
+        hasSubmenu: false,
+        child: widget.child!,
+      ),
+    );
+  }
+
+  void _handleFocusChange() {
+    if (!_focusNode.hasPrimaryFocus) {
+      // Close any child menus of this button's menu.
+      _MenuAnchorState._maybeOf(context)?._closeChildren();
+    }
+  }
+
+  void _handleHover(bool hovering) {
+    widget.onHover?.call(hovering);
+    if (hovering) {
+      assert(_debugMenuInfo('Requesting focus for $_focusNode from hover'));
+      _focusNode.requestFocus();
+    }
+  }
+
+  void _handleSelect() {
+    assert(_debugMenuInfo('Selected ${widget.child} menu'));
+    widget.onPressed?.call();
+    _MenuAnchorState._maybeOf(context)?._root._close();
+  }
+
+  void _createInternalFocusNodeIfNeeded() {
+    if (widget.focusNode == null) {
+      _internalFocusNode = FocusNode();
+      assert(() {
+        if (_internalFocusNode != null) {
+          _internalFocusNode!.debugLabel = '$MenuItemButton(${widget.child})';
+        }
+        return true;
+      }());
+    }
+  }
+}
+
+/// A menu button that displays a cascading menu.
+///
+/// It can be used as part of a [MenuBar], or as a standalone widget.
+///
+/// This widget represents a menu item that has a submenu. Like the leaf
+/// [MenuItemButton], it shows a label with an optional leading or trailing
+/// icon, but additionally shows an arrow icon showing that it has a submenu.
+///
+/// By default the submenu will appear to the side of the controlling button.
+/// The alignment and offset of the submenu can be controlled by setting
+/// [MenuStyle.alignment] on the [style] and the [alignmentOffset] argument,
+/// respectively.
+///
+/// When activated (by being clicked, through keyboard navigation, or via
+/// hovering with a mouse), it will open a submenu containing the
+/// [menuChildren].
+///
+/// If [menuChildren] is empty, then this menu item will appear disabled.
+///
+/// See also:
+///
+/// * [MenuItemButton], a widget that represents a leaf menu item that does not
+///   host a submenu.
+/// * [MenuBar], a widget that renders menu items in a row in a Material Design
+///   style.
+/// * [MenuAnchor], a widget that creates a region with a submenu and shows it
+///   when requested.
+/// * [PlatformMenuBar], a widget that renders similar menu bar items from a
+///   [PlatformMenuItem] using platform-native APIs instead of Flutter.
+class SubmenuButton extends StatefulWidget {
+  /// Creates a const [SubmenuButton].
+  ///
+  /// The [child] and [menuChildren] attributes are required.
+  const SubmenuButton({
+    super.key,
+    this.onHover,
+    this.onFocusChange,
+    this.onOpen,
+    this.onClose,
+    this.style,
+    this.menuStyle,
+    this.alignmentOffset,
+    this.clipBehavior = Clip.none,
+    this.focusNode,
+    this.statesController,
+    this.leadingIcon,
+    this.trailingIcon,
+    required this.menuChildren,
+    required this.child,
+  });
+
+  /// Called when a pointer enters or exits the button response area.
+  ///
+  /// The value passed to the callback is true if a pointer has entered this
+  /// part of the button and false if a pointer has exited.
+  final ValueChanged<bool>? onHover;
+
+  /// Handler called when the focus changes.
+  ///
+  /// Called with true if this widget's [focusNode] gains focus, and false if it
+  /// loses focus.
+  final ValueChanged<bool>? onFocusChange;
+
+  /// A callback that is invoked when the menu is opened.
+  final VoidCallback? onOpen;
+
+  /// A callback that is invoked when the menu is closed.
+  final VoidCallback? onClose;
+
+  /// Customizes this button's appearance.
+  ///
+  /// Non-null properties of this style override the corresponding properties in
+  /// [themeStyleOf] and [defaultStyleOf]. [MaterialStateProperty]s that resolve
+  /// to non-null values will similarly override the corresponding
+  /// [MaterialStateProperty]s in [themeStyleOf] and [defaultStyleOf].
+  ///
+  /// Null by default.
+  final ButtonStyle? style;
+
+  /// The [MenuStyle] of the menu specified by [menuChildren].
+  ///
+  /// Defaults to the value of [MenuThemeData.style] of the ambient [MenuTheme].
+  final MenuStyle? menuStyle;
+
+  /// The offset of the menu relative to the alignment origin determined by
+  /// [MenuStyle.alignment] on the [style] attribute.
+  ///
+  /// Use this for fine adjustments of the menu placement.
+  ///
+  /// Defaults to an offset that takes into account the padding of the menu so
+  /// that the top starting corner of the first menu item is aligned with the
+  /// top of the [MenuAnchor] region.
+  final Offset? alignmentOffset;
+
+  /// {@macro flutter.material.Material.clipBehavior}
+  ///
+  /// Defaults to [Clip.none].
+  final Clip clipBehavior;
+
+  /// {@macro flutter.widgets.Focus.focusNode}
+  final FocusNode? focusNode;
+
+  /// {@macro flutter.material.inkwell.statesController}
+  final MaterialStatesController? statesController;
+
+  /// An optional icon to display before the [child].
+  final Widget? leadingIcon;
+
+  /// An optional icon to display after the [child].
+  final Widget? trailingIcon;
+
+  /// The list of widgets that appear in the menu when it is opened.
+  ///
+  /// These can be any widget, but are typically either [MenuItemButton] or
+  /// [SubmenuButton] widgets.
+  ///
+  /// If [menuChildren] is empty, then the button for this menu item will be
+  /// disabled.
+  final List<Widget> menuChildren;
+
+  /// The widget displayed in the middle portion of this button.
+  ///
+  /// Typically this is the button's label, using a [Text] widget.
+  ///
+  /// {@macro flutter.widgets.ProxyWidget.child}
+  final Widget? child;
+
+  @override
+  State<SubmenuButton> createState() => _SubmenuButtonState();
+
+  /// Defines the button's default appearance.
+  ///
+  /// {@macro flutter.material.text_button.default_style_of}
+  ///
+  /// {@macro flutter.material.text_button.material3_defaults}
+  ButtonStyle defaultStyleOf(BuildContext context) {
+    return _MenuButtonDefaultsM3(context);
+  }
+
+  /// Returns the [MenuButtonThemeData.style] of the closest [MenuButtonTheme]
+  /// ancestor.
+  ButtonStyle? themeStyleOf(BuildContext context) {
+    return MenuButtonTheme.of(context).style;
+  }
+
+  /// A static convenience method that constructs a [SubmenuButton]'s
+  /// [ButtonStyle] given simple values.
+  ///
+  /// The [foregroundColor] color is used to create a [MaterialStateProperty]
+  /// [ButtonStyle.foregroundColor] value. Specify a value for [foregroundColor]
+  /// to specify the color of the button's icons. Use [backgroundColor] for the
+  /// button's background fill color. Use [disabledForegroundColor] and
+  /// [disabledBackgroundColor] to specify the button's disabled icon and fill
+  /// color.
+  ///
+  /// All of the other parameters are either used directly or used to create a
+  /// [MaterialStateProperty] with a single value for all states.
+  ///
+  /// All parameters default to null, by default this method returns a
+  /// [ButtonStyle] that doesn't override anything.
+  ///
+  /// For example, to override the default foreground color for a
+  /// [SubmenuButton], as well as its overlay color, with all of the standard
+  /// opacity adjustments for the pressed, focused, and hovered states, one
+  /// could write:
+  ///
+  /// ```dart
+  /// SubmenuButton(
+  ///   leadingIcon: const Icon(Icons.pets),
+  ///   style: SubmenuButton.styleFrom(foregroundColor: Colors.green),
+  ///   menuChildren: const <Widget>[ /* ... */ ],
+  ///   child: const Text('Button Label'),
+  /// ),
+  /// ```
+  static ButtonStyle styleFrom({
+    Color? foregroundColor,
+    Color? backgroundColor,
+    Color? disabledForegroundColor,
+    Color? disabledBackgroundColor,
+    Color? shadowColor,
+    Color? surfaceTintColor,
+    TextStyle? textStyle,
+    double? elevation,
+    EdgeInsetsGeometry? padding,
+    Size? minimumSize,
+    Size? fixedSize,
+    Size? maximumSize,
+    MouseCursor? enabledMouseCursor,
+    MouseCursor? disabledMouseCursor,
+    BorderSide? side,
+    OutlinedBorder? shape,
+    VisualDensity? visualDensity,
+    MaterialTapTargetSize? tapTargetSize,
+    Duration? animationDuration,
+    bool? enableFeedback,
+    AlignmentGeometry? alignment,
+    InteractiveInkFeatureFactory? splashFactory,
+  }) {
+    return TextButton.styleFrom(
+      foregroundColor: foregroundColor,
+      backgroundColor: backgroundColor,
+      disabledBackgroundColor: disabledBackgroundColor,
+      disabledForegroundColor: disabledForegroundColor,
+      shadowColor: shadowColor,
+      surfaceTintColor: surfaceTintColor,
+      textStyle: textStyle,
+      elevation: elevation,
+      padding: padding,
+      minimumSize: minimumSize,
+      fixedSize: fixedSize,
+      maximumSize: maximumSize,
+      enabledMouseCursor: enabledMouseCursor,
+      disabledMouseCursor: disabledMouseCursor,
+      side: side,
+      shape: shape,
+      visualDensity: visualDensity,
+      tapTargetSize: tapTargetSize,
+      animationDuration: animationDuration,
+      enableFeedback: enableFeedback,
+      alignment: alignment,
+      splashFactory: splashFactory,
+    );
+  }
+
+  @override
+  List<DiagnosticsNode> debugDescribeChildren() {
+    return <DiagnosticsNode>[
+      ...menuChildren.map<DiagnosticsNode>((Widget child) {
+        return child.toDiagnosticsNode();
+      })
+    ];
+  }
+
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(DiagnosticsProperty<Widget>('leadingIcon', leadingIcon, defaultValue: null));
+    properties.add(DiagnosticsProperty<String>('child', child.toString()));
+    properties.add(DiagnosticsProperty<Widget>('trailingIcon', trailingIcon, defaultValue: null));
+    properties.add(DiagnosticsProperty<FocusNode?>('focusNode', focusNode));
+    properties.add(DiagnosticsProperty<MenuStyle>('menuStyle', menuStyle, defaultValue: null));
+    properties.add(DiagnosticsProperty<Offset>('alignmentOffset', alignmentOffset));
+    properties.add(EnumProperty<Clip>('clipBehavior', clipBehavior));
+  }
+}
+
+class _SubmenuButtonState extends State<SubmenuButton> {
+  FocusNode? _internalFocusNode;
+  bool _waitingToFocusMenu = false;
+  final MenuController _menuController = MenuController();
+  _MenuAnchorState? get _anchor => _MenuAnchorState._maybeOf(context);
+  FocusNode get _buttonFocusNode => widget.focusNode ?? _internalFocusNode!;
+  bool get _enabled => widget.menuChildren.isNotEmpty;
+
+  @override
+  void initState() {
+    super.initState();
+    if (widget.focusNode == null) {
+      _internalFocusNode = FocusNode();
+      assert(() {
+        if (_internalFocusNode != null) {
+          _internalFocusNode!.debugLabel = '$SubmenuButton(${widget.child})';
+        }
+        return true;
+      }());
+    }
+    _buttonFocusNode.addListener(_handleFocusChange);
+  }
+
+  @override
+  void dispose() {
+    _internalFocusNode?.removeListener(_handleFocusChange);
+    _internalFocusNode?.dispose();
+    _internalFocusNode = null;
+    super.dispose();
+  }
+
+  @override
+  void didUpdateWidget(SubmenuButton oldWidget) {
+    super.didUpdateWidget(oldWidget);
+    if (widget.focusNode != oldWidget.focusNode) {
+      if (oldWidget.focusNode == null) {
+        _internalFocusNode?.removeListener(_handleFocusChange);
+        _internalFocusNode?.dispose();
+        _internalFocusNode = null;
+      } else {
+        oldWidget.focusNode!.removeListener(_handleFocusChange);
+      }
+      if (widget.focusNode == null) {
+        _internalFocusNode ??= FocusNode();
+        assert(() {
+          if (_internalFocusNode != null) {
+            _internalFocusNode!.debugLabel = '$SubmenuButton(${widget.child})';
+          }
+          return true;
+        }());
+      }
+      _buttonFocusNode.addListener(_handleFocusChange);
+    }
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    final Offset menuPaddingOffset;
+    final EdgeInsets menuPadding = _computeMenuPadding(context);
+    switch (_anchor?._root._orientation ?? Axis.vertical) {
+      case Axis.horizontal:
+        switch (Directionality.of(context)) {
+          case TextDirection.rtl:
+            menuPaddingOffset = widget.alignmentOffset ?? Offset(-menuPadding.right, 0);
+            break;
+          case TextDirection.ltr:
+            menuPaddingOffset = widget.alignmentOffset ?? Offset(-menuPadding.left, 0);
+            break;
+        }
+        break;
+      case Axis.vertical:
+        menuPaddingOffset = widget.alignmentOffset ?? Offset(0, -menuPadding.top);
+        break;
+    }
+
+    return MenuAnchor(
+      controller: _menuController,
+      childFocusNode: _buttonFocusNode,
+      alignmentOffset: menuPaddingOffset,
+      clipBehavior: widget.clipBehavior,
+      onClose: widget.onClose,
+      onOpen: widget.onOpen,
+      style: widget.menuStyle,
+      builder: (BuildContext context, MenuController controller, Widget? child) {
+        // Since we don't want to use the theme style or default style from the
+        // TextButton, we merge the styles, merging them in the right order when
+        // each type of style exists. Each "*StyleOf" function is only called
+        // once.
+        final ButtonStyle mergedStyle =
+            widget.style?.merge(widget.themeStyleOf(context)?.merge(widget.defaultStyleOf(context))) ??
+                widget.themeStyleOf(context)?.merge(widget.defaultStyleOf(context)) ??
+                widget.defaultStyleOf(context);
+
+        void toggleShowMenu(BuildContext context) {
+          if (controller.isOpen) {
+            controller.close();
+          } else {
+            controller.open();
+            if (!_waitingToFocusMenu) {
+              // Only schedule this if it's not already scheduled.
+              SchedulerBinding.instance.addPostFrameCallback((Duration _) {
+                // This has to happen in the next frame because the menu bar is
+                // not focusable until the first menu is open.
+                controller._anchor?._focusButton();
+                _waitingToFocusMenu = false;
+              });
+              _waitingToFocusMenu = true;
+            }
+          }
+        }
+
+        // Called when the pointer is hovering over the menu button.
+        void handleHover(bool hovering, BuildContext context) {
+          widget.onHover?.call(hovering);
+          // Don't open the root menu bar menus on hover unless something else
+          // is already open. This means that the user has to first click to
+          // open a menu on the menu bar before hovering allows them to traverse
+          // it.
+          if (controller._anchor!._root._orientation == Axis.horizontal && !controller._anchor!._root._childIsOpen) {
+            return;
+          }
+
+          if (hovering) {
+            controller.open();
+            controller._anchor!._focusButton();
+          }
+        }
+
+        return TextButton(
+          style: mergedStyle,
+          focusNode: _buttonFocusNode,
+          onHover: _enabled ? (bool hovering) => handleHover(hovering, context) : null,
+          onPressed: _enabled ? () => toggleShowMenu(context) : null,
+          child: _MenuItemLabel(
+            leadingIcon: widget.leadingIcon,
+            trailingIcon: widget.trailingIcon,
+            hasSubmenu: true,
+            showDecoration: (controller._anchor!._parent?._orientation ?? Axis.horizontal) == Axis.vertical,
+            child: child ?? const SizedBox(),
+          ),
+        );
+      },
+      menuChildren: widget.menuChildren,
+      child: widget.child,
+    );
+  }
+
+  EdgeInsets _computeMenuPadding(BuildContext context) {
+    final MenuStyle? themeStyle = MenuTheme.of(context).style;
+    final MenuStyle defaultStyle = _MenuDefaultsM3(context);
+
+    T? effectiveValue<T>(T? Function(MenuStyle? style) getProperty) {
+      return getProperty(widget.menuStyle) ?? getProperty(themeStyle) ?? getProperty(defaultStyle);
+    }
+
+    T? resolve<T>(MaterialStateProperty<T>? Function(MenuStyle? style) getProperty) {
+      return effectiveValue(
+            (MenuStyle? style) {
+          return getProperty(style)?.resolve(widget.statesController?.value ?? const <MaterialState>{});
+        },
+      );
+    }
+
+    return resolve<EdgeInsetsGeometry?>(
+          (MenuStyle? style) => style?.padding,
+    )?.resolve(
+      Directionality.of(context),
+    ) ??
+        EdgeInsets.zero;
+  }
+
+  void _handleFocusChange() {
+    if (_buttonFocusNode.hasPrimaryFocus) {
+      if (!_menuController.isOpen) {
+        _menuController.open();
+      }
+    } else {
+      if (!_menuController._anchor!._menuScopeNode.hasFocus && _menuController.isOpen) {
+        _menuController.close();
+      }
+    }
+  }
+}
+
+/// An action that closes all the menus associated with the given
+/// [MenuController].
+///
+/// See also:
+///
+///  * [MenuAnchor], a widget that hosts a cascading submenu.
+///  * [MenuBar], a widget that defines a menu bar with cascading submenus.
+class DismissMenuAction extends DismissAction {
+  /// Creates a [DismissMenuAction].
+  DismissMenuAction({required this.controller});
+
+  /// The [MenuController] associated with the menus that should be closed.
+  final MenuController controller;
+
+  @override
+  void invoke(DismissIntent intent) {
+    assert(_debugMenuInfo('$runtimeType: Dismissing all open menus.'));
+    controller._anchor!._root._close();
+  }
+
+  @override
+  bool isEnabled(DismissIntent intent) {
+    return controller.isOpen;
+  }
+}
+
+/// A helper class used to generate shortcut labels for a
+/// [MenuSerializableShortcut] (a subset of the subclasses of
+/// [ShortcutActivator]).
+///
+/// This helper class is typically used by the [MenuItemButton] and
+/// [SubmenuButton] classes to display a label for their assigned shortcuts.
+///
+/// Call [getShortcutLabel] with the [MenuSerializableShortcut] to get a label
+/// for it.
+///
+/// For instance, calling [getShortcutLabel] with `SingleActivator(trigger:
+/// LogicalKeyboardKey.keyA, control: true)` would return "⌃ A" on macOS, "Ctrl
+/// A" in an US English locale, and "Strg A" in a German locale.
+class _LocalizedShortcutLabeler {
+  _LocalizedShortcutLabeler._();
+
+  static _LocalizedShortcutLabeler? _instance;
+
+  static final Map<LogicalKeyboardKey, String> _shortcutGraphicEquivalents = <LogicalKeyboardKey, String>{
+    LogicalKeyboardKey.arrowLeft: '←',
+    LogicalKeyboardKey.arrowRight: '→',
+    LogicalKeyboardKey.arrowUp: '↑',
+    LogicalKeyboardKey.arrowDown: '↓',
+    LogicalKeyboardKey.enter: '↵',
+    LogicalKeyboardKey.shift: '⇧',
+    LogicalKeyboardKey.shiftLeft: '⇧',
+    LogicalKeyboardKey.shiftRight: '⇧',
+  };
+
+  static final Set<LogicalKeyboardKey> _modifiers = <LogicalKeyboardKey>{
+    LogicalKeyboardKey.alt,
+    LogicalKeyboardKey.control,
+    LogicalKeyboardKey.meta,
+    LogicalKeyboardKey.shift,
+    LogicalKeyboardKey.altLeft,
+    LogicalKeyboardKey.controlLeft,
+    LogicalKeyboardKey.metaLeft,
+    LogicalKeyboardKey.shiftLeft,
+    LogicalKeyboardKey.altRight,
+    LogicalKeyboardKey.controlRight,
+    LogicalKeyboardKey.metaRight,
+    LogicalKeyboardKey.shiftRight,
+  };
+
+  /// Return the instance for this singleton.
+  static _LocalizedShortcutLabeler get instance {
+    return _instance ??= _LocalizedShortcutLabeler._();
+  }
+
+  // Caches the created shortcut key maps so that creating one of these isn't
+  // expensive after the first time for each unique localizations object.
+  final Map<MaterialLocalizations, Map<LogicalKeyboardKey, String>> _cachedShortcutKeys =
+      <MaterialLocalizations, Map<LogicalKeyboardKey, String>>{};
+
+  /// Returns the label to be shown to the user in the UI when a
+  /// [MenuSerializableShortcut] is used as a keyboard shortcut.
+  ///
+  /// To keep the representation short, this will return graphical key
+  /// representations when it can. For instance, the default
+  /// [LogicalKeyboardKey.shift] will return '⇧', and the arrow keys will return
+  /// arrows. When [defaultTargetPlatform] is [TargetPlatform.macOS] or
+  /// [TargetPlatform.iOS], the key [LogicalKeyboardKey.meta] will show as '⌘',
+  /// [LogicalKeyboardKey.control] will show as '˄', and
+  /// [LogicalKeyboardKey.alt] will show as '⌥'.
+  String getShortcutLabel(MenuSerializableShortcut shortcut, MaterialLocalizations localizations) {
+    final ShortcutSerialization serialized = shortcut.serializeForMenu();
+    if (serialized.trigger != null) {
+      final List<String> modifiers = <String>[];
+      final LogicalKeyboardKey trigger = serialized.trigger!;
+      // These should be in this order, to match the LogicalKeySet version.
+      if (serialized.alt!) {
+        modifiers.add(_getModifierLabel(LogicalKeyboardKey.alt, localizations));
+      }
+      if (serialized.control!) {
+        modifiers.add(_getModifierLabel(LogicalKeyboardKey.control, localizations));
+      }
+      if (serialized.meta!) {
+        modifiers.add(_getModifierLabel(LogicalKeyboardKey.meta, localizations));
+      }
+      if (serialized.shift!) {
+        modifiers.add(_getModifierLabel(LogicalKeyboardKey.shift, localizations));
+      }
+      String? shortcutTrigger;
+      final int logicalKeyId = trigger.keyId;
+      if (_shortcutGraphicEquivalents.containsKey(trigger)) {
+        shortcutTrigger = _shortcutGraphicEquivalents[trigger];
+      } else {
+        // Otherwise, look it up, and if we don't have a translation for it,
+        // then fall back to the key label.
+        shortcutTrigger = _getLocalizedName(trigger, localizations);
+        if (shortcutTrigger == null && logicalKeyId & LogicalKeyboardKey.planeMask == 0x0) {
+          // If the trigger is a Unicode-character-producing key, then use the
+          // character.
+          shortcutTrigger = String.fromCharCode(logicalKeyId & LogicalKeyboardKey.valueMask).toUpperCase();
+        }
+        // Fall back to the key label if all else fails.
+        shortcutTrigger ??= trigger.keyLabel;
+      }
+      return <String>[
+        ...modifiers,
+        if (shortcutTrigger != null && shortcutTrigger.isNotEmpty) shortcutTrigger,
+      ].join(' ');
+    } else if (serialized.character != null) {
+      return serialized.character!;
+    }
+    throw UnimplementedError('Shortcut labels for ShortcutActivators that do not implement '
+        'MenuSerializableShortcut (e.g. ShortcutActivators other than SingleActivator or '
+        'CharacterActivator) are not supported.');
+  }
+
+  // Tries to look up the key in an internal table, and if it can't find it,
+  // then fall back to the key's keyLabel.
+  String? _getLocalizedName(LogicalKeyboardKey key, MaterialLocalizations localizations) {
+    // Since this is an expensive table to build, we cache it based on the
+    // localization object. There's currently no way to clear the cache, but
+    // it's unlikely that more than one or two will be cached for each run, and
+    // they're not huge.
+    _cachedShortcutKeys[localizations] ??= <LogicalKeyboardKey, String>{
+      LogicalKeyboardKey.altGraph: localizations.keyboardKeyAltGraph,
+      LogicalKeyboardKey.backspace: localizations.keyboardKeyBackspace,
+      LogicalKeyboardKey.capsLock: localizations.keyboardKeyCapsLock,
+      LogicalKeyboardKey.channelDown: localizations.keyboardKeyChannelDown,
+      LogicalKeyboardKey.channelUp: localizations.keyboardKeyChannelUp,
+      LogicalKeyboardKey.delete: localizations.keyboardKeyDelete,
+      LogicalKeyboardKey.eject: localizations.keyboardKeyEject,
+      LogicalKeyboardKey.end: localizations.keyboardKeyEnd,
+      LogicalKeyboardKey.escape: localizations.keyboardKeyEscape,
+      LogicalKeyboardKey.fn: localizations.keyboardKeyFn,
+      LogicalKeyboardKey.home: localizations.keyboardKeyHome,
+      LogicalKeyboardKey.insert: localizations.keyboardKeyInsert,
+      LogicalKeyboardKey.numLock: localizations.keyboardKeyNumLock,
+      LogicalKeyboardKey.numpad1: localizations.keyboardKeyNumpad1,
+      LogicalKeyboardKey.numpad2: localizations.keyboardKeyNumpad2,
+      LogicalKeyboardKey.numpad3: localizations.keyboardKeyNumpad3,
+      LogicalKeyboardKey.numpad4: localizations.keyboardKeyNumpad4,
+      LogicalKeyboardKey.numpad5: localizations.keyboardKeyNumpad5,
+      LogicalKeyboardKey.numpad6: localizations.keyboardKeyNumpad6,
+      LogicalKeyboardKey.numpad7: localizations.keyboardKeyNumpad7,
+      LogicalKeyboardKey.numpad8: localizations.keyboardKeyNumpad8,
+      LogicalKeyboardKey.numpad9: localizations.keyboardKeyNumpad9,
+      LogicalKeyboardKey.numpad0: localizations.keyboardKeyNumpad0,
+      LogicalKeyboardKey.numpadAdd: localizations.keyboardKeyNumpadAdd,
+      LogicalKeyboardKey.numpadComma: localizations.keyboardKeyNumpadComma,
+      LogicalKeyboardKey.numpadDecimal: localizations.keyboardKeyNumpadDecimal,
+      LogicalKeyboardKey.numpadDivide: localizations.keyboardKeyNumpadDivide,
+      LogicalKeyboardKey.numpadEnter: localizations.keyboardKeyNumpadEnter,
+      LogicalKeyboardKey.numpadEqual: localizations.keyboardKeyNumpadEqual,
+      LogicalKeyboardKey.numpadMultiply: localizations.keyboardKeyNumpadMultiply,
+      LogicalKeyboardKey.numpadParenLeft: localizations.keyboardKeyNumpadParenLeft,
+      LogicalKeyboardKey.numpadParenRight: localizations.keyboardKeyNumpadParenRight,
+      LogicalKeyboardKey.numpadSubtract: localizations.keyboardKeyNumpadSubtract,
+      LogicalKeyboardKey.pageDown: localizations.keyboardKeyPageDown,
+      LogicalKeyboardKey.pageUp: localizations.keyboardKeyPageUp,
+      LogicalKeyboardKey.power: localizations.keyboardKeyPower,
+      LogicalKeyboardKey.powerOff: localizations.keyboardKeyPowerOff,
+      LogicalKeyboardKey.printScreen: localizations.keyboardKeyPrintScreen,
+      LogicalKeyboardKey.scrollLock: localizations.keyboardKeyScrollLock,
+      LogicalKeyboardKey.select: localizations.keyboardKeySelect,
+      LogicalKeyboardKey.space: localizations.keyboardKeySpace,
+    };
+    return _cachedShortcutKeys[localizations]![key];
+  }
+
+  String _getModifierLabel(LogicalKeyboardKey modifier, MaterialLocalizations localizations) {
+    assert(_modifiers.contains(modifier), '${modifier.keyLabel} is not a modifier key');
+    if (modifier == LogicalKeyboardKey.meta ||
+        modifier == LogicalKeyboardKey.metaLeft ||
+        modifier == LogicalKeyboardKey.metaRight) {
+      switch (defaultTargetPlatform) {
+        case TargetPlatform.android:
+        case TargetPlatform.fuchsia:
+        case TargetPlatform.linux:
+          return localizations.keyboardKeyMeta;
+        case TargetPlatform.windows:
+          return localizations.keyboardKeyMetaWindows;
+        case TargetPlatform.iOS:
+        case TargetPlatform.macOS:
+          return '⌘';
+      }
+    }
+    if (modifier == LogicalKeyboardKey.alt ||
+        modifier == LogicalKeyboardKey.altLeft ||
+        modifier == LogicalKeyboardKey.altRight) {
+      switch (defaultTargetPlatform) {
+        case TargetPlatform.android:
+        case TargetPlatform.fuchsia:
+        case TargetPlatform.linux:
+        case TargetPlatform.windows:
+          return localizations.keyboardKeyAlt;
+        case TargetPlatform.iOS:
+        case TargetPlatform.macOS:
+          return '⌥';
+      }
+    }
+    if (modifier == LogicalKeyboardKey.control ||
+        modifier == LogicalKeyboardKey.controlLeft ||
+        modifier == LogicalKeyboardKey.controlRight) {
+      // '⎈' (a boat helm wheel, not an asterisk) is apparently the standard
+      // icon for "control", but only seems to appear on the French Canadian
+      // keyboard. A '✲' (an open center asterisk) appears on some Microsoft
+      // keyboards. For all but macOS (which has standardized on "⌃", it seems),
+      // we just return the local translation of "Ctrl".
+      switch (defaultTargetPlatform) {
+        case TargetPlatform.android:
+        case TargetPlatform.fuchsia:
+        case TargetPlatform.linux:
+        case TargetPlatform.windows:
+          return localizations.keyboardKeyControl;
+        case TargetPlatform.iOS:
+        case TargetPlatform.macOS:
+          return '⌃';
+      }
+    }
+    if (modifier == LogicalKeyboardKey.shift ||
+        modifier == LogicalKeyboardKey.shiftLeft ||
+        modifier == LogicalKeyboardKey.shiftRight) {
+      return _shortcutGraphicEquivalents[LogicalKeyboardKey.shift]!;
+    }
+    throw ArgumentError('Keyboard key ${modifier.keyLabel} is not a modifier.');
+  }
+}
+
+class _MenuAnchorMarker extends InheritedWidget {
+  const _MenuAnchorMarker({
+    required super.child,
+    required this.anchorKey,
+    required this.anchor,
+  });
+
+  final GlobalKey anchorKey;
+  final _MenuAnchorState anchor;
+
+  @override
+  bool updateShouldNotify(_MenuAnchorMarker oldWidget) {
+    return anchorKey != oldWidget.anchorKey || anchor != anchor;
+  }
+}
+
+/// MenuBar-specific private specialization of [MenuAnchor] so that it can act
+/// differently in regards to orientation, how open works, and what gets built.
+class _MenuBarAnchor extends MenuAnchor {
+  const _MenuBarAnchor({
+    required super.menuChildren,
+    super.controller,
+    super.clipBehavior,
+    super.style,
+  });
+
+  @override
+  State<MenuAnchor> createState() => _MenuBarAnchorState();
+}
+
+class _MenuBarAnchorState extends _MenuAnchorState {
+  @override
+  bool get _isOpen {
+    // If it's a bar, then it's "open" if any of its children are open.
+    return _childIsOpen;
+  }
+
+  @override
+  Axis get _orientation => Axis.horizontal;
+
+  @override
+  Widget _buildContents(BuildContext context) {
+    return FocusScope(
+      node: _menuScopeNode,
+      skipTraversal: !_isOpen,
+      canRequestFocus: _isOpen,
+      child: ExcludeFocus(
+        excluding: !_isOpen,
+        child: Shortcuts(
+          shortcuts: _kMenuTraversalShortcuts,
+          child: Actions(
+            actions: <Type, Action<Intent>>{
+              DirectionalFocusIntent: _MenuDirectionalFocusAction(),
+              DismissIntent: DismissMenuAction(controller: _menuController),
+            },
+            child: Builder(builder: (BuildContext context) {
+              return _MenuPanel(
+                menuStyle: widget.style,
+                clipBehavior: widget.clipBehavior,
+                orientation: Axis.horizontal,
+                children: widget.menuChildren,
+              );
+            }),
+          ),
+        ),
+      ),
+    );
+  }
+
+  @override
+  void _open({Offset? position}) {
+    assert(_menuController._anchor == this);
+    // Menu bars can't be opened, because they're already always open.
+    return;
+  }
+}
+
+class _MenuDirectionalFocusAction extends DirectionalFocusAction {
+  /// Creates a [DirectionalFocusAction].
+  _MenuDirectionalFocusAction();
+
+  @override
+  void invoke(DirectionalFocusIntent intent) {
+    assert(_debugMenuInfo('_MenuDirectionalFocusAction invoked with $intent'));
+    final BuildContext? context = FocusManager.instance.primaryFocus?.context;
+    if (context == null) {
+      super.invoke(intent);
+      return;
+    }
+    final _MenuAnchorState? anchor = _MenuAnchorState._maybeOf(context);
+    if (anchor == null || !anchor._root._isOpen) {
+      super.invoke(intent);
+      return;
+    }
+    final bool buttonIsFocused = anchor.widget.childFocusNode?.hasPrimaryFocus ?? false;
+    Axis orientation;
+    if (buttonIsFocused) {
+      orientation = anchor._parent!._orientation;
+    } else {
+      orientation = anchor._orientation;
+    }
+    final bool firstItemIsFocused = anchor._firstItemFocusNode?.hasPrimaryFocus ?? false;
+    assert(_debugMenuInfo('In _MenuDirectionalFocusAction, current node is ${anchor.widget.childFocusNode?.debugLabel}, '
+        'button is${buttonIsFocused ? '' : ' not'} focused. Assuming ${orientation.name} orientation.'));
+
+    switch (intent.direction) {
+      case TraversalDirection.up:
+        switch (orientation) {
+          case Axis.horizontal:
+            if (_moveToParent(anchor)) {
+              return;
+            }
+            break;
+          case Axis.vertical:
+            if (firstItemIsFocused) {
+              if (_moveToParent(anchor)) {
+                return;
+              }
+            }
+            if (_moveToPrevious(anchor)) {
+              return;
+            }
+            break;
+        }
+        break;
+      case TraversalDirection.down:
+        switch (orientation) {
+          case Axis.horizontal:
+            if (_moveToSubmenu(anchor)) {
+              return;
+            }
+            break;
+          case Axis.vertical:
+            if (_moveToNext(anchor)) {
+              return;
+            }
+            break;
+        }
+        break;
+      case TraversalDirection.left:
+        switch (orientation) {
+          case Axis.horizontal:
+            switch (Directionality.of(context)) {
+              case TextDirection.rtl:
+                if (_moveToNext(anchor)) {
+                  return;
+                }
+                break;
+              case TextDirection.ltr:
+                if (_moveToPrevious(anchor)) {
+                  return;
+                }
+                break;
+            }
+            break;
+          case Axis.vertical:
+            switch (Directionality.of(context)) {
+              case TextDirection.rtl:
+                if (buttonIsFocused) {
+                  if (_moveToSubmenu(anchor)) {
+                    return;
+                  }
+                } else {
+                  if (_moveToNextTopLevel(anchor)) {
+                    return;
+                  }
+                }
+                break;
+              case TextDirection.ltr:
+                switch (anchor._parent!._orientation) {
+                  case Axis.horizontal:
+                    if (_moveToPreviousTopLevel(anchor)) {
+                      return;
+                    }
+                    break;
+                  case Axis.vertical:
+                    if (buttonIsFocused) {
+                      if (_moveToPreviousTopLevel(anchor)) {
+                        return;
+                      }
+                    } else {
+                      if (_moveToParent(anchor)) {
+                        return;
+                      }
+                    }
+                    break;
+                }
+                break;
+            }
+            break;
+        }
+        break;
+      case TraversalDirection.right:
+        switch (orientation) {
+          case Axis.horizontal:
+            switch (Directionality.of(context)) {
+              case TextDirection.rtl:
+                if (_moveToPrevious(anchor)) {
+                  return;
+                }
+                break;
+              case TextDirection.ltr:
+                if (_moveToNext(anchor)) {
+                  return;
+                }
+                break;
+            }
+            break;
+          case Axis.vertical:
+            switch (Directionality.of(context)) {
+              case TextDirection.rtl:
+                switch (anchor._parent!._orientation) {
+                  case Axis.horizontal:
+                    if (_moveToPreviousTopLevel(anchor)) {
+                      return;
+                    }
+                    break;
+                  case Axis.vertical:
+                    if (_moveToParent(anchor)) {
+                      return;
+                    }
+                    break;
+                }
+                break;
+              case TextDirection.ltr:
+                if (buttonIsFocused) {
+                  if (_moveToSubmenu(anchor)) {
+                    return;
+                  }
+                } else {
+                  if (_moveToNextTopLevel(anchor)) {
+                    return;
+                  }
+                }
+                break;
+            }
+            break;
+        }
+        break;
+    }
+    super.invoke(intent);
+  }
+
+  bool _moveToNext(_MenuAnchorState currentMenu) {
+    assert(_debugMenuInfo('Moving focus to next item in menu'));
+    // Need to invalidate the scope data because we're switching scopes, and
+    // otherwise the anti-hysteresis code will interfere with moving to the
+    // correct node.
+    if (currentMenu.widget.childFocusNode != null) {
+      final FocusTraversalPolicy? policy = FocusTraversalGroup.maybeOf(primaryFocus!.context!);
+      policy?.invalidateScopeData(currentMenu.widget.childFocusNode!.nearestScope!);
+    }
+    return false;
+  }
+
+  bool _moveToNextTopLevel(_MenuAnchorState currentMenu) {
+    final _MenuAnchorState? sibling = currentMenu._topLevel._nextSibling;
+    if (sibling == null) {
+      // Wrap around to the first top level.
+      currentMenu._topLevel._parent!._anchorChildren.first._focusButton();
+    } else {
+      sibling._focusButton();
+    }
+    return true;
+  }
+
+  bool _moveToParent(_MenuAnchorState currentMenu) {
+    assert(_debugMenuInfo('Moving focus to parent menu button'));
+    if (!(currentMenu.widget.childFocusNode?.hasPrimaryFocus ?? true)) {
+      currentMenu._focusButton();
+    }
+    return true;
+  }
+
+  bool _moveToPrevious(_MenuAnchorState currentMenu) {
+    assert(_debugMenuInfo('Moving focus to previous item in menu'));
+    // Need to invalidate the scope data because we're switching scopes, and
+    // otherwise the anti-hysteresis code will interfere with moving to the
+    // correct node.
+    if (currentMenu.widget.childFocusNode != null) {
+      final FocusTraversalPolicy? policy = FocusTraversalGroup.maybeOf(primaryFocus!.context!);
+      policy?.invalidateScopeData(currentMenu.widget.childFocusNode!.nearestScope!);
+    }
+    return false;
+  }
+
+  bool _moveToPreviousTopLevel(_MenuAnchorState currentMenu) {
+    final _MenuAnchorState? sibling = currentMenu._topLevel._previousSibling;
+    if (sibling == null) {
+      // Already on the first one, wrap around to the last one.
+      currentMenu._topLevel._parent!._anchorChildren.last._focusButton();
+    } else {
+      sibling._focusButton();
+    }
+    return true;
+  }
+
+  bool _moveToSubmenu(_MenuAnchorState currentMenu) {
+    assert(_debugMenuInfo('Opening submenu'));
+    if (!currentMenu._isOpen) {
+      // If no submenu is open, then an arrow opens the submenu.
+      currentMenu._open();
+      return true;
+    } else {
+      final FocusNode? firstNode = currentMenu._firstItemFocusNode;
+      if (firstNode != null && firstNode.nearestScope != firstNode) {
+        // Don't request focus if the "first" found node is a focus scope, since
+        // that means that nothing else in the submenu is focusable.
+        firstNode.requestFocus();
+      }
+      return true;
+    }
+  }
+}
+
+/// A label widget that is used as the label for a [MenuItemButton] or
+/// [SubmenuButton].
+///
+/// It not only shows the [SubmenuButton.child] or [MenuItemButton.child], but if
+/// there is a shortcut associated with the [MenuItemButton], it will display a
+/// mnemonic for the shortcut. For [SubmenuButton]s, it will display a visual
+/// indicator that there is a submenu.
+class _MenuItemLabel extends StatelessWidget {
+  /// Creates a const [_MenuItemLabel].
+  ///
+  /// The [child] and [hasSubmenu] arguments are required.
+  const _MenuItemLabel({
+    required this.hasSubmenu,
+    this.showDecoration = true,
+    this.leadingIcon,
+    this.trailingIcon,
+    this.shortcut,
+    required this.child,
+  });
+
+  /// Whether or not this menu has a submenu.
+  ///
+  /// Determines whether the submenu arrow is shown or not.
+  final bool hasSubmenu;
+
+  /// Whether or not this item should show decorations like shortcut labels or
+  /// submenu arrows. Items in a [MenuBar] don't show these decorations when
+  /// they are laid out horizontally.
+  final bool showDecoration;
+
+  /// The optional icon that comes before the [child].
+  final Widget? leadingIcon;
+
+  /// The optional icon that comes after the [child].
+  final Widget? trailingIcon;
+
+  /// The shortcut for this label, so that it can generate a string describing
+  /// the shortcut.
+  final MenuSerializableShortcut? shortcut;
+
+  /// The required label child widget.
+  final Widget child;
+
+  @override
+  Widget build(BuildContext context) {
+    final VisualDensity density = Theme.of(context).visualDensity;
+    final double horizontalPadding = math.max(
+      _kLabelItemMinSpacing,
+      _kLabelItemDefaultSpacing + density.horizontal * 2,
+    );
+    return Row(
+      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+      children: <Widget>[
+        Row(
+          mainAxisSize: MainAxisSize.min,
+          children: <Widget>[
+            if (leadingIcon != null) leadingIcon!,
+            Padding(
+              padding: leadingIcon != null ? EdgeInsetsDirectional.only(start: horizontalPadding) : EdgeInsets.zero,
+              child: child,
+            ),
+            if (trailingIcon != null)
+              Padding(
+                padding: EdgeInsetsDirectional.only(start: horizontalPadding),
+                child: trailingIcon,
+              ),
+          ],
+        ),
+        if (showDecoration && (shortcut != null || hasSubmenu)) SizedBox(width: horizontalPadding),
+        if (showDecoration && shortcut != null)
+          Padding(
+            padding: EdgeInsetsDirectional.only(start: horizontalPadding),
+            child: Text(
+              _LocalizedShortcutLabeler.instance.getShortcutLabel(
+                shortcut!,
+                MaterialLocalizations.of(context),
+              ),
+            ),
+          ),
+        if (showDecoration && hasSubmenu)
+          Padding(
+            padding: EdgeInsetsDirectional.only(start: horizontalPadding),
+            child: const Icon(
+              Icons.arrow_right, // Automatically switches with text direction.
+              size: _kDefaultSubmenuIconSize,
+            ),
+          ),
+      ],
+    );
+  }
+
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(DiagnosticsProperty<String>('child', child.toString()));
+    properties.add(DiagnosticsProperty<MenuSerializableShortcut>('shortcut', shortcut, defaultValue: null));
+    properties.add(DiagnosticsProperty<bool>('hasSubmenu', hasSubmenu));
+    properties.add(DiagnosticsProperty<bool>('showDecoration', showDecoration));
+  }
+}
+
+// Positions the menu in the view while trying to keep as much as possible
+// visible in the view.
+class _MenuLayout extends SingleChildLayoutDelegate {
+  const _MenuLayout({
+    required this.anchorRect,
+    required this.textDirection,
+    required this.alignment,
+    required this.alignmentOffset,
+    required this.menuPosition,
+    required this.menuPadding,
+    required this.avoidBounds,
+    required this.orientation,
+    required this.parentOrientation,
+  });
+
+  // Rectangle of underlying button, relative to the overlay's dimensions.
+  final Rect anchorRect;
+
+  // Whether to prefer going to the left or to the right.
+  final TextDirection textDirection;
+
+  // The alignment to use when finding the ideal location for the menu.
+  final AlignmentGeometry alignment;
+
+  // The offset from the alignment position to find the ideal location for the
+  // menu.
+  final Offset alignmentOffset;
+
+  // The position passed to the open method, if any.
+  final Offset? menuPosition;
+
+  // The padding on the inside of the menu, so it can be accounted for when
+  // positioning.
+  final EdgeInsetsGeometry menuPadding;
+
+  // List of rectangles that we should avoid overlapping. Unusable screen area.
+  final Set<Rect> avoidBounds;
+
+  // The orientation of this menu
+  final Axis orientation;
+
+  // The orientation of this menu's parent.
+  final Axis parentOrientation;
+
+  @override
+  BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
+    // The menu can be at most the size of the overlay minus _kMenuViewPadding
+    // pixels in each direction.
+    return BoxConstraints.loose(constraints.biggest).deflate(
+      const EdgeInsets.all(_kMenuViewPadding),
+    );
+  }
+
+  @override
+  Offset getPositionForChild(Size size, Size childSize) {
+    // size: The size of the overlay.
+    // childSize: The size of the menu, when fully open, as determined by
+    // getConstraintsForChild.
+    final Rect overlayRect = Offset.zero & size;
+    double x;
+    double y;
+    if (menuPosition == null) {
+      Offset desiredPosition = alignment.resolve(textDirection).withinRect(anchorRect);
+      final Offset directionalOffset;
+      if (alignment is AlignmentDirectional) {
+        switch (textDirection) {
+          case TextDirection.rtl:
+            directionalOffset = Offset(-alignmentOffset.dx, alignmentOffset.dy);
+            break;
+          case TextDirection.ltr:
+            directionalOffset = alignmentOffset;
+            break;
+        }
+      } else {
+        directionalOffset = alignmentOffset;
+      }
+      desiredPosition += directionalOffset;
+      x = desiredPosition.dx;
+      y = desiredPosition.dy;
+      switch (textDirection) {
+        case TextDirection.rtl:
+          x -= childSize.width;
+          break;
+        case TextDirection.ltr:
+          break;
+      }
+    } else {
+      final Offset adjustedPosition = menuPosition! + anchorRect.topLeft;
+      x = adjustedPosition.dx;
+      y = adjustedPosition.dy;
+    }
+
+    final Iterable<Rect> subScreens = DisplayFeatureSubScreen.subScreensInBounds(overlayRect, avoidBounds);
+    final Rect allowedRect = _closestScreen(subScreens, anchorRect.center);
+    bool offLeftSide(double x) => x < allowedRect.left;
+    bool offRightSide(double x) => x + childSize.width > allowedRect.right;
+    bool offTop(double y) => y < allowedRect.top;
+    bool offBottom(double y) => y + childSize.height > allowedRect.bottom;
+    // Avoid going outside an area defined as the rectangle offset from the
+    // edge of the screen by the button padding. If the menu is off of the screen,
+    // move the menu to the other side of the button first, and then if it
+    // doesn't fit there, then just move it over as much as needed to make it
+    // fit.
+    if (childSize.width >= allowedRect.width) {
+      // It just doesn't fit, so put as much on the screen as possible.
+      x = allowedRect.left;
+    } else {
+      if (offLeftSide(x)) {
+        // If the parent is a different orientation than the current one, then
+        // just push it over instead of trying the other side.
+        if (parentOrientation != orientation) {
+          x = allowedRect.left;
+        } else {
+          final double newX = anchorRect.right;
+          if (!offRightSide(newX)) {
+            x = newX;
+          } else {
+            x = allowedRect.left;
+          }
+        }
+      } else if (offRightSide(x)) {
+        if (parentOrientation != orientation) {
+          x = allowedRect.right - childSize.width;
+        } else {
+          final double newX = anchorRect.left - childSize.width;
+          if (!offLeftSide(newX)) {
+            x = newX;
+          } else {
+            x = allowedRect.right - childSize.width;
+          }
+        }
+      }
+    }
+    if (childSize.height >= allowedRect.height) {
+      // Too tall to fit, fit as much on as possible.
+      y = allowedRect.top;
+    } else {
+      if (offTop(y)) {
+        final double newY = anchorRect.bottom;
+        if (!offBottom(newY)) {
+          y = newY;
+        } else {
+          y = allowedRect.top;
+        }
+      } else if (offBottom(y)) {
+        final double newY = anchorRect.top - childSize.height;
+        if (!offTop(newY)) {
+          y = newY;
+        } else {
+          y = allowedRect.bottom - childSize.height;
+        }
+      }
+    }
+    return Offset(x, y);
+  }
+
+  @override
+  bool shouldRelayout(_MenuLayout oldDelegate) {
+    return anchorRect != oldDelegate.anchorRect ||
+        textDirection != oldDelegate.textDirection ||
+        alignment != oldDelegate.alignment ||
+        alignmentOffset != oldDelegate.alignmentOffset ||
+        menuPosition != oldDelegate.menuPosition ||
+        orientation != oldDelegate.orientation ||
+        parentOrientation != oldDelegate.parentOrientation ||
+        !setEquals(avoidBounds, oldDelegate.avoidBounds);
+  }
+
+  Rect _closestScreen(Iterable<Rect> screens, Offset point) {
+    Rect closest = screens.first;
+    for (final Rect screen in screens) {
+      if ((screen.center - point).distance < (closest.center - point).distance) {
+        closest = screen;
+      }
+    }
+    return closest;
+  }
+}
+
+/// A widget that manages a list of menu buttons in a menu.
+///
+/// It sizes itself to the widest/tallest item it contains, and then sizes all
+/// the other entries to match.
+class _MenuPanel extends StatefulWidget {
+  const _MenuPanel({
+    required this.menuStyle,
+    this.clipBehavior = Clip.none,
+    required this.orientation,
+    required this.children,
+  });
+
+  /// The menu style that has all the attributes for this menu panel.
+  final MenuStyle? menuStyle;
+
+  /// {@macro flutter.material.Material.clipBehavior}
+  ///
+  /// Defaults to [Clip.none].
+  final Clip clipBehavior;
+
+  /// The layout orientation of this panel.
+  final Axis orientation;
+
+  /// The list of widgets to use as children of this menu bar.
+  ///
+  /// These are the top level [SubmenuButton]s.
+  final List<Widget> children;
+
+  @override
+  State<_MenuPanel> createState() => _MenuPanelState();
+}
+
+class _MenuPanelState extends State<_MenuPanel> {
+  @override
+  Widget build(BuildContext context) {
+    final MenuStyle? themeStyle;
+    final MenuStyle defaultStyle;
+    switch (widget.orientation) {
+      case Axis.horizontal:
+        themeStyle = MenuBarTheme.of(context).style;
+        defaultStyle = _MenuBarDefaultsM3(context);
+        break;
+      case Axis.vertical:
+        themeStyle = MenuTheme.of(context).style;
+        defaultStyle = _MenuDefaultsM3(context);
+        break;
+    }
+    final MenuStyle? widgetStyle = widget.menuStyle;
+
+    T? effectiveValue<T>(T? Function(MenuStyle? style) getProperty) {
+      return getProperty(widgetStyle) ?? getProperty(themeStyle) ?? getProperty(defaultStyle);
+    }
+
+    T? resolve<T>(MaterialStateProperty<T>? Function(MenuStyle? style) getProperty) {
+      return effectiveValue(
+        (MenuStyle? style) {
+          return getProperty(style)?.resolve(<MaterialState>{});
+        },
+      );
+    }
+
+    final Color? backgroundColor = resolve<Color?>((MenuStyle? style) => style?.backgroundColor);
+    final Color? shadowColor = resolve<Color?>((MenuStyle? style) => style?.shadowColor);
+    final Color? surfaceTintColor = resolve<Color?>((MenuStyle? style) => style?.surfaceTintColor);
+    final double elevation = resolve<double?>((MenuStyle? style) => style?.elevation) ?? 0;
+    final Size? minimumSize = resolve<Size?>((MenuStyle? style) => style?.minimumSize);
+    final Size? fixedSize = resolve<Size?>((MenuStyle? style) => style?.fixedSize);
+    final Size? maximumSize = resolve<Size?>((MenuStyle? style) => style?.maximumSize);
+    final BorderSide? side = resolve<BorderSide?>((MenuStyle? style) => style?.side);
+    final OutlinedBorder shape = resolve<OutlinedBorder?>((MenuStyle? style) => style?.shape)!.copyWith(side: side);
+    final VisualDensity visualDensity =
+        effectiveValue((MenuStyle? style) => style?.visualDensity) ?? VisualDensity.standard;
+    final EdgeInsetsGeometry padding =
+        resolve<EdgeInsetsGeometry?>((MenuStyle? style) => style?.padding) ?? EdgeInsets.zero;
+    final Offset densityAdjustment = visualDensity.baseSizeAdjustment;
+    // Per the Material Design team: don't allow the VisualDensity
+    // adjustment to reduce the width of the left/right padding. If we
+    // did, VisualDensity.compact, the default for desktop/web, would
+    // reduce the horizontal padding to zero.
+    final double dy = densityAdjustment.dy;
+    final double dx = math.max(0, densityAdjustment.dx);
+    final EdgeInsetsGeometry resolvedPadding = padding
+        .add(EdgeInsets.fromLTRB(dx, dy, dx, dy))
+        .clamp(EdgeInsets.zero, EdgeInsetsGeometry.infinity); // ignore_clamp_double_lint
+
+    BoxConstraints effectiveConstraints = visualDensity.effectiveConstraints(
+      BoxConstraints(
+        minWidth: minimumSize?.width ?? 0,
+        minHeight: minimumSize?.height ?? 0,
+        maxWidth: maximumSize?.width ?? double.infinity,
+        maxHeight: maximumSize?.height ?? double.infinity,
+      ),
+    );
+    if (fixedSize != null) {
+      final Size size = effectiveConstraints.constrain(fixedSize);
+      if (size.width.isFinite) {
+        effectiveConstraints = effectiveConstraints.copyWith(
+          minWidth: size.width,
+          maxWidth: size.width,
+        );
+      }
+      if (size.height.isFinite) {
+        effectiveConstraints = effectiveConstraints.copyWith(
+          minHeight: size.height,
+          maxHeight: size.height,
+        );
+      }
+    }
+    return ConstrainedBox(
+      constraints: effectiveConstraints,
+      child: UnconstrainedBox(
+        constrainedAxis: widget.orientation,
+        clipBehavior: Clip.hardEdge,
+        alignment: AlignmentDirectional.centerStart,
+      child: _intrinsicCrossSize(
+        child: Material(
+          elevation: elevation,
+          shape: shape,
+          color: backgroundColor,
+          shadowColor: shadowColor,
+          surfaceTintColor: surfaceTintColor,
+          type: backgroundColor == null ? MaterialType.transparency : MaterialType.canvas,
+            clipBehavior: Clip.hardEdge,
+          child: Padding(
+            padding: resolvedPadding,
+            child: SingleChildScrollView(
+              scrollDirection: widget.orientation,
+              child: Flex(
+                crossAxisAlignment: CrossAxisAlignment.start,
+                textDirection: Directionality.of(context),
+                direction: widget.orientation,
+                mainAxisSize: MainAxisSize.min,
+                children: widget.children,
+                ),
+              ),
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+
+  Widget _intrinsicCrossSize({required Widget child}) {
+    switch (widget.orientation) {
+      case Axis.horizontal:
+        return IntrinsicHeight(child: child);
+      case Axis.vertical:
+        return IntrinsicWidth(child: child);
+    }
+  }
+}
+
+// A widget that defines the menu drawn inside of the overlay entry.
+class _Submenu extends StatelessWidget {
+  const _Submenu({
+    required this.anchor,
+    required this.menuStyle,
+    required this.menuPosition,
+    required this.alignmentOffset,
+    required this.clipBehavior,
+    required this.menuChildren,
+  });
+
+  final _MenuAnchorState anchor;
+  final MenuStyle? menuStyle;
+  final Offset? menuPosition;
+  final Offset alignmentOffset;
+  final Clip clipBehavior;
+  final List<Widget> menuChildren;
+
+  @override
+  Widget build(BuildContext context) {
+    // Use the text direction of the context where the button is.
+    final TextDirection textDirection = Directionality.of(context);
+    final MenuStyle? themeStyle;
+    final MenuStyle defaultStyle;
+    switch (anchor._parent?._orientation ?? Axis.horizontal) {
+      case Axis.horizontal:
+        themeStyle = MenuBarTheme.of(context).style;
+        defaultStyle = _MenuBarDefaultsM3(context);
+        break;
+      case Axis.vertical:
+        themeStyle = MenuTheme.of(context).style;
+        defaultStyle = _MenuDefaultsM3(context);
+        break;
+    }
+    T? effectiveValue<T>(T? Function(MenuStyle? style) getProperty) {
+      return getProperty(menuStyle) ?? getProperty(themeStyle) ?? getProperty(defaultStyle);
+    }
+    T? resolve<T>(MaterialStateProperty<T>? Function(MenuStyle? style) getProperty) {
+      return effectiveValue(
+        (MenuStyle? style) {
+          return getProperty(style)?.resolve(<MaterialState>{});
+        },
+      );
+    }
+
+    final MaterialStateMouseCursor mouseCursor = _MouseCursor(
+      (Set<MaterialState> states) => effectiveValue((MenuStyle? style) => style?.mouseCursor?.resolve(states)),
+    );
+
+    final VisualDensity visualDensity =
+        effectiveValue((MenuStyle? style) => style?.visualDensity) ?? VisualDensity.standard;
+    final AlignmentGeometry alignment = effectiveValue((MenuStyle? style) => style?.alignment)!;
+    final BuildContext anchorContext = anchor._anchorKey.currentContext!;
+    final RenderBox overlay = Overlay.of(anchorContext).context.findRenderObject()! as RenderBox;
+    final RenderBox anchorBox = anchorContext.findRenderObject()! as RenderBox;
+    final Offset upperLeft = anchorBox.localToGlobal(Offset.zero, ancestor: overlay);
+    final Offset bottomRight = anchorBox.localToGlobal(anchorBox.paintBounds.bottomRight, ancestor: overlay);
+    final Rect anchorRect = Rect.fromPoints(upperLeft, bottomRight);
+    final EdgeInsetsGeometry padding =
+        resolve<EdgeInsetsGeometry?>((MenuStyle? style) => style?.padding) ?? EdgeInsets.zero;
+    final Offset densityAdjustment = visualDensity.baseSizeAdjustment;
+    // Per the Material Design team: don't allow the VisualDensity
+    // adjustment to reduce the width of the left/right padding. If we
+    // did, VisualDensity.compact, the default for desktop/web, would
+    // reduce the horizontal padding to zero.
+    final double dy = densityAdjustment.dy;
+    final double dx = math.max(0, densityAdjustment.dx);
+    final EdgeInsetsGeometry resolvedPadding = padding
+        .add(EdgeInsets.fromLTRB(dx, dy, dx, dy))
+        .clamp(EdgeInsets.zero, EdgeInsetsGeometry.infinity); // ignore_clamp_double_lint
+
+    return Theme(
+      data: Theme.of(context).copyWith(
+        visualDensity: visualDensity,
+      ),
+      child: ConstrainedBox(
+        constraints: BoxConstraints.loose(overlay.paintBounds.size),
+        child: CustomSingleChildLayout(
+          delegate: _MenuLayout(
+            anchorRect: anchorRect,
+            textDirection: textDirection,
+            avoidBounds: DisplayFeatureSubScreen.avoidBounds(MediaQuery.of(context)).toSet(),
+            menuPadding: resolvedPadding,
+            alignment: alignment,
+            alignmentOffset: alignmentOffset,
+            menuPosition: menuPosition,
+            orientation: anchor._orientation,
+            parentOrientation: anchor._parent?._orientation ?? Axis.horizontal,
+          ),
+          child: TapRegion(
+            groupId: anchor._root,
+            onTapOutside: (PointerDownEvent event) {
+              anchor._close();
+            },
+            child: MouseRegion(
+              cursor: mouseCursor,
+              hitTestBehavior: HitTestBehavior.deferToChild,
+              child: FocusScope(
+                node: anchor._menuScopeNode,
+                child: Actions(
+                  actions: <Type, Action<Intent>>{
+                    DirectionalFocusIntent: _MenuDirectionalFocusAction(),
+                    DismissIntent: DismissMenuAction(controller: anchor._menuController),
+                  },
+                  child: Shortcuts(
+                    shortcuts: _kMenuTraversalShortcuts,
+                    child: Directionality(
+                      // Copy the directionality from the button into the overlay.
+                      textDirection: textDirection,
+                      child: _MenuPanel(
+                        menuStyle: menuStyle,
+                        clipBehavior: clipBehavior,
+                        orientation: anchor._orientation,
+                        children: menuChildren,
+                      ),
+                    ),
+                  ),
+                ),
+              ),
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+}
+
+/// Wraps the [MaterialStateMouseCursor] so that it can default to
+/// [MouseCursor.uncontrolled] if none is set.
+class _MouseCursor extends MaterialStateMouseCursor {
+  const _MouseCursor(this.resolveCallback);
+
+  final MaterialPropertyResolver<MouseCursor?> resolveCallback;
+
+  @override
+  MouseCursor resolve(Set<MaterialState> states) => resolveCallback(states) ?? MouseCursor.uncontrolled;
+
+  @override
+  String get debugDescription => 'Menu_MouseCursor';
+}
+
+/// A debug print function, which should only be called within an assert, like
+/// so:
+///
+///   assert(_debugMenuInfo('Debug Message'));
+///
+/// so that the call is entirely removed in release builds.
+///
+/// Enable debug printing by setting [_kDebugMenus] to true at the top of the
+/// file.
+bool _debugMenuInfo(String message, [Iterable<String>? details]) {
+  assert(() {
+    if (_kDebugMenus) {
+      debugPrint('MENU: $message');
+      if (details != null && details.isNotEmpty) {
+        for (final String detail in details) {
+          debugPrint('    $detail');
+        }
+      }
+    }
+    return true;
+  }());
+  // Return true so that it can be easily used inside of an assert.
+  return true;
+}
+
+// This class will eventually be auto-generated, so it should remain at the end
+// of the file.
+class _MenuBarDefaultsM3 extends MenuStyle {
+  _MenuBarDefaultsM3(this.context)
+      : super(
+          elevation: const MaterialStatePropertyAll<double?>(4),
+          shape: const MaterialStatePropertyAll<OutlinedBorder>(_defaultMenuBorder),
+          alignment: AlignmentDirectional.bottomStart,
+        );
+  static const RoundedRectangleBorder _defaultMenuBorder =
+      RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.elliptical(2, 3)));
+
+  final BuildContext context;
+
+  late final ColorScheme _colors = Theme.of(context).colorScheme;
+
+  @override
+  MaterialStateProperty<Color?> get backgroundColor {
+    return MaterialStatePropertyAll<Color?>(_colors.surface);
+  }
+
+  @override
+  MaterialStateProperty<EdgeInsetsGeometry?>? get padding {
+    return MaterialStatePropertyAll<EdgeInsetsGeometry>(
+      EdgeInsetsDirectional.symmetric(
+        horizontal: math.max(
+          _kTopLevelMenuHorizontalMinPadding,
+          2 + Theme.of(context).visualDensity.baseSizeAdjustment.dx,
+        ),
+      ),
+    );
+  }
+}
+
+// This class will eventually be auto-generated, so it should remain at the end
+// of the file.
+class _MenuButtonDefaultsM3 extends ButtonStyle {
+  _MenuButtonDefaultsM3(this.context)
+      : super(
+          animationDuration: kThemeChangeDuration,
+          enableFeedback: true,
+          alignment: AlignmentDirectional.centerStart,
+        );
+  final BuildContext context;
+
+  late final ColorScheme _colors = Theme.of(context).colorScheme;
+
+  @override
+  MaterialStateProperty<Color?>? get backgroundColor {
+    return ButtonStyleButton.allOrNull<Color>(Colors.transparent);
+  }
+
+  // No default shadow color
+
+  // No default surface tint color
+
+  @override
+  MaterialStateProperty<double>? get elevation {
+    return ButtonStyleButton.allOrNull<double>(0);
+  }
+
+  @override
+  MaterialStateProperty<Color?>? get foregroundColor {
+    return MaterialStateProperty.resolveWith(
+      (Set<MaterialState> states) {
+        if (states.contains(MaterialState.disabled)) {
+          return _colors.onSurface.withOpacity(0.38);
+        }
+        return _colors.primary;
+      },
+    );
+  }
+
+  // No default fixedSize
+
+  @override
+  MaterialStateProperty<Size>? get maximumSize {
+    return ButtonStyleButton.allOrNull<Size>(Size.infinite);
+  }
+
+  @override
+  MaterialStateProperty<Size>? get minimumSize {
+    return ButtonStyleButton.allOrNull<Size>(const Size(64, 40));
+  }
+
+  @override
+  MaterialStateProperty<MouseCursor?>? get mouseCursor {
+    return MaterialStateProperty.resolveWith(
+      (Set<MaterialState> states) {
+        if (states.contains(MaterialState.disabled)) {
+          return SystemMouseCursors.basic;
+        }
+        return SystemMouseCursors.click;
+      },
+    );
+  }
+
+  @override
+  MaterialStateProperty<Color?>? get overlayColor {
+    return MaterialStateProperty.resolveWith(
+      (Set<MaterialState> states) {
+        if (states.contains(MaterialState.hovered)) {
+          return _colors.primary.withOpacity(0.08);
+        }
+        if (states.contains(MaterialState.focused)) {
+          return _colors.primary.withOpacity(0.12);
+        }
+        if (states.contains(MaterialState.pressed)) {
+          return _colors.primary.withOpacity(0.12);
+        }
+        return null;
+      },
+    );
+  }
+
+  @override
+  MaterialStateProperty<EdgeInsetsGeometry>? get padding {
+    return ButtonStyleButton.allOrNull<EdgeInsetsGeometry>(_scaledPadding(context));
+  }
+
+  // No default side
+
+  @override
+  MaterialStateProperty<OutlinedBorder>? get shape {
+    return ButtonStyleButton.allOrNull<OutlinedBorder>(const RoundedRectangleBorder());
+  }
+
+  @override
+  InteractiveInkFeatureFactory? get splashFactory => Theme.of(context).splashFactory;
+
+  @override
+  MaterialTapTargetSize? get tapTargetSize => Theme.of(context).materialTapTargetSize;
+
+  @override
+  MaterialStateProperty<TextStyle?> get textStyle {
+    return MaterialStatePropertyAll<TextStyle?>(Theme.of(context).textTheme.labelLarge);
+  }
+
+  @override
+  VisualDensity? get visualDensity => Theme.of(context).visualDensity;
+
+  EdgeInsetsGeometry _scaledPadding(BuildContext context) {
+    return ButtonStyleButton.scaledPadding(
+      const EdgeInsets.all(8),
+      const EdgeInsets.symmetric(horizontal: 8),
+      const EdgeInsets.symmetric(horizontal: 4),
+      MediaQuery.maybeOf(context)?.textScaleFactor ?? 1,
+    );
+  }
+}
+
+// This class will eventually be auto-generated, so it should remain at the end
+// of the file.
+class _MenuDefaultsM3 extends MenuStyle {
+  _MenuDefaultsM3(this.context)
+      : super(
+          elevation: const MaterialStatePropertyAll<double?>(4),
+          shape: const MaterialStatePropertyAll<OutlinedBorder>(_defaultMenuBorder),
+          alignment: AlignmentDirectional.topEnd,
+        );
+  static const RoundedRectangleBorder _defaultMenuBorder =
+      RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.elliptical(2, 3)));
+
+  final BuildContext context;
+
+  late final ColorScheme _colors = Theme.of(context).colorScheme;
+
+  @override
+  MaterialStateProperty<Color?> get backgroundColor {
+    return MaterialStatePropertyAll<Color?>(_colors.surface);
+  }
+
+  @override
+  MaterialStateProperty<EdgeInsetsGeometry?>? get padding {
+    return MaterialStatePropertyAll<EdgeInsetsGeometry>(
+      EdgeInsetsDirectional.symmetric(
+        vertical: math.max(
+          _kMenuVerticalMinPadding,
+          2 + Theme.of(context).visualDensity.baseSizeAdjustment.dy,
+        ),
+      ),
+    );
+  }
+}
diff --git a/packages/flutter/lib/src/material/menu_bar_theme.dart b/packages/flutter/lib/src/material/menu_bar_theme.dart
new file mode 100644
index 0000000..8a8299f
--- /dev/null
+++ b/packages/flutter/lib/src/material/menu_bar_theme.dart
@@ -0,0 +1,112 @@
+// 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 'package:flutter/widgets.dart';
+
+import 'menu_anchor.dart';
+import 'menu_style.dart';
+import 'menu_theme.dart';
+import 'theme.dart';
+
+// Examples can assume:
+// late Widget child;
+
+/// A data class that [MenuBarTheme] uses to define the visual properties of
+/// [MenuBar] widgets.
+///
+/// This class defines the visual properties of [MenuBar] widgets themselves,
+/// but not their submenus. Those properties are defined by [MenuThemeData] or
+/// [MenuButtonThemeData] instead.
+///
+/// Descendant widgets obtain the current [MenuBarThemeData] object using
+/// `MenuBarTheme.of(context)`.
+///
+/// Typically, a [MenuBarThemeData] is specified as part of the overall [Theme]
+/// with [ThemeData.menuBarTheme]. Otherwise, [MenuTheme] can be used to
+/// configure its own widget subtree.
+///
+/// All [MenuBarThemeData] properties are `null` by default. If any of these
+/// properties are null, the menu bar will provide its own defaults.
+///
+/// See also:
+///
+/// * [MenuThemeData], which describes the theme for the submenus of a
+///   [MenuBar].
+/// * [MenuButtonThemeData], which describes the theme for the [MenuItemButton]s
+///   in a menu.
+/// * [ThemeData], which describes the overall theme for the application.
+@immutable
+class MenuBarThemeData extends MenuThemeData {
+  /// Creates a const set of properties used to configure [MenuTheme].
+  const MenuBarThemeData({super.style});
+
+  /// Linearly interpolate between two text button themes.
+  static MenuBarThemeData? lerp(MenuBarThemeData? a, MenuBarThemeData? b, double t) {
+    return MenuBarThemeData(style: MenuStyle.lerp(a?.style, b?.style, t));
+  }
+}
+
+/// An inherited widget that defines the configuration for the [MenuBar] widgets
+/// in this widget's descendants.
+///
+/// This class defines the visual properties of [MenuBar] widgets themselves,
+/// but not their submenus. Those properties are defined by [MenuTheme] or
+/// [MenuButtonTheme] instead.
+///
+/// Values specified here are used for [MenuBar]'s properties that are not given
+/// an explicit non-null value.
+///
+/// See also:
+/// * [MenuStyle], a configuration object that holds attributes of a menu, and
+///   is used by this theme to define those attributes.
+/// * [MenuTheme], which does the same thing for the menus created by a
+///   [SubmenuButton] or [MenuAnchor].
+/// * [MenuButtonTheme], which does the same thing for the [MenuItemButton]s
+///   inside of the menus.
+/// * [SubmenuButton], a button that manages a submenu that uses these
+///   properties.
+/// * [MenuBar], a widget that creates a menu bar that can use [SubmenuButton]s.
+class MenuBarTheme extends InheritedTheme {
+  /// Creates a theme that controls the configurations for [MenuBar] and
+  /// [MenuItemButton] in its widget subtree.
+  const MenuBarTheme({
+    super.key,
+    required this.data,
+    required super.child,
+  }) : assert(data != null);
+
+  /// The properties to set for [MenuBar] in this widget's descendants.
+  final MenuBarThemeData data;
+
+  /// Returns the closest instance of this class's [data] value that encloses
+  /// the given context. If there is no ancestor, it returns
+  /// [ThemeData.menuBarTheme].
+  ///
+  /// Typical usage is as follows:
+  ///
+  /// ```dart
+  /// Widget build(BuildContext context) {
+  ///   return MenuTheme(
+  ///     data: const MenuThemeData(
+  ///       style: MenuStyle(
+  ///         backgroundColor: MaterialStatePropertyAll<Color?>(Colors.red),
+  ///       ),
+  ///     ),
+  ///     child: child,
+  ///   );
+  /// }
+  /// ```
+  static MenuBarThemeData of(BuildContext context) {
+    final MenuBarTheme? menuBarTheme = context.dependOnInheritedWidgetOfExactType<MenuBarTheme>();
+    return menuBarTheme?.data ?? Theme.of(context).menuBarTheme;
+  }
+
+  @override
+  Widget wrap(BuildContext context, Widget child) {
+    return MenuBarTheme(data: data, child: child);
+  }
+
+  @override
+  bool updateShouldNotify(MenuBarTheme oldWidget) => data != oldWidget.data;
+}
diff --git a/packages/flutter/lib/src/material/menu_button_theme.dart b/packages/flutter/lib/src/material/menu_button_theme.dart
new file mode 100644
index 0000000..f4462e1
--- /dev/null
+++ b/packages/flutter/lib/src/material/menu_button_theme.dart
@@ -0,0 +1,136 @@
+// 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 'package:flutter/foundation.dart';
+import 'package:flutter/widgets.dart';
+
+import 'button_style.dart';
+import 'material_state.dart';
+import 'menu_anchor.dart';
+import 'theme.dart';
+
+// Examples can assume:
+// late BuildContext context;
+
+/// A [ButtonStyle] theme that overrides the default appearance of
+/// [SubmenuButton]s and [MenuItemButton]s when it's used with a
+/// [MenuButtonTheme] or with the overall [Theme]'s [ThemeData.menuTheme].
+///
+/// The [style]'s properties override [MenuItemButton]'s and [SubmenuButton]'s
+/// default style, i.e. the [ButtonStyle] returned by
+/// [MenuItemButton.defaultStyleOf] and [SubmenuButton.defaultStyleOf]. Only the
+/// style's non-null property values or resolved non-null
+/// [MaterialStateProperty] values are used.
+///
+/// See also:
+///
+/// * [MenuButtonTheme], the theme which is configured with this class.
+/// * [MenuTheme], the theme used to configure the look of the menus these
+///   buttons reside in.
+/// * [MenuItemButton.defaultStyleOf] and [SubmenuButton.defaultStyleOf] which
+///   return the default [ButtonStyle]s for menu buttons.
+/// * [MenuItemButton.styleFrom] and [SubmenuButton.styleFrom], which converts
+///   simple values into a [ButtonStyle] that's consistent with their respective
+///   defaults.
+/// * [MaterialStateProperty.resolve], "resolve" a material state property to a
+///   simple value based on a set of [MaterialState]s.
+/// * [ThemeData.menuButtonTheme], which can be used to override the default
+///   [ButtonStyle] for [MenuItemButton]s and [SubmenuButton]s below the overall
+///   [Theme].
+/// * [MenuAnchor], a widget which hosts cascading menus.
+/// * [MenuBar], a widget which defines a menu bar of buttons hosting cascading
+///   menus.
+@immutable
+class MenuButtonThemeData with Diagnosticable {
+  /// Creates a [MenuButtonThemeData].
+  ///
+  /// The [style] may be null.
+  const MenuButtonThemeData({this.style});
+
+  /// Overrides for [SubmenuButton] and [MenuItemButton]'s default style.
+  ///
+  /// Non-null properties or non-null resolved [MaterialStateProperty] values
+  /// override the [ButtonStyle] returned by [SubmenuButton.defaultStyleOf] or
+  /// [MenuItemButton.defaultStyleOf].
+  ///
+  /// If [style] is null, then this theme doesn't override anything.
+  final ButtonStyle? style;
+
+  /// Linearly interpolate between two menu button themes.
+  static MenuButtonThemeData? lerp(MenuButtonThemeData? a, MenuButtonThemeData? b, double t) {
+    return MenuButtonThemeData(style: ButtonStyle.lerp(a?.style, b?.style, t));
+  }
+
+  @override
+  int get hashCode => style.hashCode;
+
+  @override
+  bool operator ==(Object other) {
+    if (identical(this, other)) {
+      return true;
+    }
+    if (other.runtimeType != runtimeType) {
+      return false;
+    }
+    return other is MenuButtonThemeData && other.style == style;
+  }
+
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(DiagnosticsProperty<ButtonStyle>('style', style, defaultValue: null));
+  }
+}
+
+/// Overrides the default [ButtonStyle] of its [MenuItemButton] and
+/// [SubmenuButton] descendants.
+///
+/// See also:
+///
+/// * [MenuButtonThemeData], which is used to configure this theme.
+/// * [MenuTheme], the theme used to configure the look of the menus themselves.
+/// * [MenuItemButton.defaultStyleOf] and [SubmenuButton.defaultStyleOf] which
+///   return the default [ButtonStyle]s for menu buttons.
+/// * [MenuItemButton.styleFrom] and [SubmenuButton.styleFrom], which converts
+///   simple values into a [ButtonStyle] that's consistent with their respective
+///   defaults.
+/// * [ThemeData.menuButtonTheme], which can be used to override the default
+///   [ButtonStyle] for [MenuItemButton]s and [SubmenuButton]s below the overall
+///   [Theme].
+class MenuButtonTheme extends InheritedTheme {
+  /// Create a [MenuButtonTheme].
+  ///
+  /// The [data] parameter must not be null.
+  const MenuButtonTheme({
+    super.key,
+    required this.data,
+    required super.child,
+  }) : assert(data != null);
+
+  /// The configuration of this theme.
+  final MenuButtonThemeData data;
+
+  /// The closest instance of this class that encloses the given context.
+  ///
+  /// If there is no enclosing [MenuButtonTheme] widget, then
+  /// [ThemeData.menuButtonTheme] is used.
+  ///
+  /// Typical usage is as follows:
+  ///
+  /// ```dart
+  /// MenuButtonThemeData theme = MenuButtonTheme.of(context);
+  /// ```
+  static MenuButtonThemeData of(BuildContext context) {
+    final MenuButtonTheme? buttonTheme = context.dependOnInheritedWidgetOfExactType<MenuButtonTheme>();
+    return buttonTheme?.data ?? Theme.of(context).menuButtonTheme;
+  }
+
+  @override
+  Widget wrap(BuildContext context, Widget child) {
+    return MenuButtonTheme(data: data, child: child);
+  }
+
+  @override
+  bool updateShouldNotify(MenuButtonTheme oldWidget) => data != oldWidget.data;
+}
diff --git a/packages/flutter/lib/src/material/menu_style.dart b/packages/flutter/lib/src/material/menu_style.dart
new file mode 100644
index 0000000..a335eee
--- /dev/null
+++ b/packages/flutter/lib/src/material/menu_style.dart
@@ -0,0 +1,371 @@
+// 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 'dart:ui' show lerpDouble;
+
+import 'package:flutter/foundation.dart';
+import 'package:flutter/widgets.dart';
+
+import 'button_style.dart';
+import 'material_state.dart';
+import 'menu_anchor.dart';
+import 'theme.dart';
+import 'theme_data.dart';
+
+// Examples can assume:
+// late Widget child;
+// late BuildContext context;
+// late MenuStyle style;
+// @immutable
+// class MyAppHome extends StatelessWidget {
+//   const MyAppHome({super.key});
+//   @override
+//   Widget build(BuildContext context) => const SizedBox();
+// }
+
+/// The visual properties that menus have in common.
+///
+/// Menus created by [MenuBar] and [MenuAnchor] and their themes have a
+/// [MenuStyle] property which defines the visual properties whose default
+/// values are to be overridden. The default values are defined by the
+/// individual menu widgets and are typically based on overall theme's
+/// [ThemeData.colorScheme] and [ThemeData.textTheme].
+///
+/// All of the [MenuStyle] properties are null by default.
+///
+/// Many of the [MenuStyle] properties are [MaterialStateProperty] objects which
+/// resolve to different values depending on the menu's state. For example the
+/// [Color] properties are defined with `MaterialStateProperty<Color>` and can
+/// resolve to different colors depending on if the menu is pressed, hovered,
+/// focused, disabled, etc.
+///
+/// These properties can override the default value for just one state or all of
+/// them. For example to create a [SubmenuButton] whose background color is the
+/// color scheme’s primary color with 50% opacity, but only when the menu is
+/// pressed, one could write:
+///
+/// ```dart
+/// SubmenuButton(
+///   menuStyle: MenuStyle(
+///     backgroundColor: MaterialStateProperty.resolveWith<Color?>(
+///       (Set<MaterialState> states) {
+///         if (states.contains(MaterialState.focused)) {
+///           return Theme.of(context).colorScheme.primary.withOpacity(0.5);
+///         }
+///         return null; // Use the component's default.
+///       },
+///     ),
+///   ),
+///   menuChildren: const <Widget>[ /* ... */ ],
+///   child: const Text('Fly me to the moon'),
+/// ),
+/// ```
+///
+/// In this case the background color for all other menu states would fall back
+/// to the [SubmenuButton]'s default values. To unconditionally set the menu's
+/// [backgroundColor] for all states one could write:
+///
+/// ```dart
+/// const SubmenuButton(
+///   menuStyle: MenuStyle(
+///     backgroundColor: MaterialStatePropertyAll<Color>(Colors.green),
+///   ),
+///   menuChildren: <Widget>[ /* ... */ ],
+///   child: Text('Let me play among the stars'),
+/// ),
+/// ```
+///
+/// To configure all of the application's menus in the same way, specify the
+/// overall theme's `menuTheme`:
+///
+/// ```dart
+/// MaterialApp(
+///   theme: ThemeData(
+///     menuTheme: const MenuThemeData(
+///       style: MenuStyle(backgroundColor: MaterialStatePropertyAll<Color>(Colors.red)),
+///     ),
+///   ),
+///   home: const MyAppHome(),
+/// ),
+/// ```
+///
+/// See also:
+///
+/// * [MenuAnchor], a widget which hosts cascading menus.
+/// * [MenuBar], a widget which defines a menu bar of buttons hosting cascading
+///   menus.
+/// * [MenuButtonTheme], the theme for [SubmenuButton]s and [MenuItemButton]s.
+/// * [ButtonStyle], a similar configuration object for button styles.
+@immutable
+class MenuStyle with Diagnosticable {
+  /// Create a [MenuStyle].
+  const MenuStyle({
+    this.backgroundColor,
+    this.shadowColor,
+    this.surfaceTintColor,
+    this.elevation,
+    this.padding,
+    this.minimumSize,
+    this.fixedSize,
+    this.maximumSize,
+    this.side,
+    this.shape,
+    this.mouseCursor,
+    this.visualDensity,
+    this.alignment,
+  });
+
+  /// The menu's background fill color.
+  final MaterialStateProperty<Color?>? backgroundColor;
+
+  /// The shadow color of the menu's [Material].
+  ///
+  /// The material's elevation shadow can be difficult to see for dark themes,
+  /// so by default the menu classes add a semi-transparent overlay to indicate
+  /// elevation. See [ThemeData.applyElevationOverlayColor].
+  final MaterialStateProperty<Color?>? shadowColor;
+
+  /// The surface tint color of the menu's [Material].
+  ///
+  /// See [Material.surfaceTintColor] for more details.
+  final MaterialStateProperty<Color?>? surfaceTintColor;
+
+  /// The elevation of the menu's [Material].
+  final MaterialStateProperty<double?>? elevation;
+
+  /// The padding between the menu's boundary and its child.
+  final MaterialStateProperty<EdgeInsetsGeometry?>? padding;
+
+  /// The minimum size of the menu itself.
+  ///
+  /// This value must be less than or equal to [maximumSize].
+  final MaterialStateProperty<Size?>? minimumSize;
+
+  /// The menu's size.
+  ///
+  /// This size is still constrained by the style's [minimumSize] and
+  /// [maximumSize]. Fixed size dimensions whose value is [double.infinity] are
+  /// ignored.
+  ///
+  /// To specify menus with a fixed width and the default height use `fixedSize:
+  /// Size.fromWidth(320)`. Similarly, to specify a fixed height and the default
+  /// width use `fixedSize: Size.fromHeight(100)`.
+  final MaterialStateProperty<Size?>? fixedSize;
+
+  /// The maximum size of the menu itself.
+  ///
+  /// A [Size.infinite] or null value for this property means that the menu's
+  /// maximum size is not constrained.
+  ///
+  /// This value must be greater than or equal to [minimumSize].
+  final MaterialStateProperty<Size?>? maximumSize;
+
+  /// The color and weight of the menu's outline.
+  ///
+  /// This value is combined with [shape] to create a shape decorated with an
+  /// outline.
+  final MaterialStateProperty<BorderSide?>? side;
+
+  /// The shape of the menu's underlying [Material].
+  ///
+  /// This shape is combined with [side] to create a shape decorated with an
+  /// outline.
+  final MaterialStateProperty<OutlinedBorder?>? shape;
+
+  /// The cursor for a mouse pointer when it enters or is hovering over this
+  /// menu's [InkWell].
+  final MaterialStateProperty<MouseCursor?>? mouseCursor;
+
+  /// Defines how compact the menu's layout will be.
+  ///
+  /// {@macro flutter.material.themedata.visualDensity}
+  ///
+  /// See also:
+  ///
+  ///  * [ThemeData.visualDensity], which specifies the [visualDensity] for all
+  ///    widgets within a [Theme].
+  final VisualDensity? visualDensity;
+
+  /// Determines the desired alignment of the submenu when opened relative to
+  /// the button that opens it.
+  ///
+  /// If there isn't sufficient space to open the menu with the given alignment,
+  /// and there's space on the other side of the button, then the alignment is
+  /// swapped to it's opposite (1 becomes -1, etc.), and the menu will try to
+  /// appear on the other side of the button. If there isn't enough space there
+  /// either, then the menu will be pushed as far over as necessary to display
+  /// as much of itself as possible, possibly overlapping the parent button.
+  final AlignmentGeometry? alignment;
+
+  @override
+  int get hashCode {
+    final List<Object?> values = <Object?>[
+      backgroundColor,
+      shadowColor,
+      surfaceTintColor,
+      elevation,
+      padding,
+      minimumSize,
+      fixedSize,
+      maximumSize,
+      side,
+      shape,
+      mouseCursor,
+      visualDensity,
+      alignment,
+    ];
+    return Object.hashAll(values);
+  }
+
+  @override
+  bool operator ==(Object other) {
+    if (identical(this, other)) {
+      return true;
+    }
+    if (other.runtimeType != runtimeType) {
+      return false;
+    }
+    return other is MenuStyle
+        && other.backgroundColor == backgroundColor
+        && other.shadowColor == shadowColor
+        && other.surfaceTintColor == surfaceTintColor
+        && other.elevation == elevation
+        && other.padding == padding
+        && other.minimumSize == minimumSize
+        && other.fixedSize == fixedSize
+        && other.maximumSize == maximumSize
+        && other.side == side
+        && other.shape == shape
+        && other.mouseCursor == mouseCursor
+        && other.visualDensity == visualDensity
+        && other.alignment == alignment;
+  }
+
+  /// Returns a copy of this MenuStyle with the given fields replaced with
+  /// the new values.
+  MenuStyle copyWith({
+    MaterialStateProperty<Color?>? backgroundColor,
+    MaterialStateProperty<Color?>? shadowColor,
+    MaterialStateProperty<Color?>? surfaceTintColor,
+    MaterialStateProperty<double?>? elevation,
+    MaterialStateProperty<EdgeInsetsGeometry?>? padding,
+    MaterialStateProperty<Size?>? minimumSize,
+    MaterialStateProperty<Size?>? fixedSize,
+    MaterialStateProperty<Size?>? maximumSize,
+    MaterialStateProperty<BorderSide?>? side,
+    MaterialStateProperty<OutlinedBorder?>? shape,
+    MaterialStateProperty<MouseCursor?>? mouseCursor,
+    VisualDensity? visualDensity,
+    AlignmentGeometry? alignment,
+  }) {
+    return MenuStyle(
+      backgroundColor: backgroundColor ?? this.backgroundColor,
+      shadowColor: shadowColor ?? this.shadowColor,
+      surfaceTintColor: surfaceTintColor ?? this.surfaceTintColor,
+      elevation: elevation ?? this.elevation,
+      padding: padding ?? this.padding,
+      minimumSize: minimumSize ?? this.minimumSize,
+      fixedSize: fixedSize ?? this.fixedSize,
+      maximumSize: maximumSize ?? this.maximumSize,
+      side: side ?? this.side,
+      shape: shape ?? this.shape,
+      mouseCursor: mouseCursor ?? this.mouseCursor,
+      visualDensity: visualDensity ?? this.visualDensity,
+      alignment: alignment ?? this.alignment,
+    );
+  }
+
+  /// Returns a copy of this MenuStyle where the non-null fields in [style]
+  /// have replaced the corresponding null fields in this MenuStyle.
+  ///
+  /// In other words, [style] is used to fill in unspecified (null) fields
+  /// this MenuStyle.
+  MenuStyle merge(MenuStyle? style) {
+    if (style == null) {
+      return this;
+    }
+    return copyWith(
+      backgroundColor: backgroundColor ?? style.backgroundColor,
+      shadowColor: shadowColor ?? style.shadowColor,
+      surfaceTintColor: surfaceTintColor ?? style.surfaceTintColor,
+      elevation: elevation ?? style.elevation,
+      padding: padding ?? style.padding,
+      minimumSize: minimumSize ?? style.minimumSize,
+      fixedSize: fixedSize ?? style.fixedSize,
+      maximumSize: maximumSize ?? style.maximumSize,
+      side: side ?? style.side,
+      shape: shape ?? style.shape,
+      mouseCursor: mouseCursor ?? style.mouseCursor,
+      visualDensity: visualDensity ?? style.visualDensity,
+      alignment: alignment ?? style.alignment,
+    );
+  }
+
+  /// Linearly interpolate between two [MenuStyle]s.
+  static MenuStyle? lerp(MenuStyle? a, MenuStyle? b, double t) {
+    assert (t != null);
+    if (a == null && b == null) {
+      return null;
+    }
+    return MenuStyle(
+      backgroundColor: MaterialStateProperty.lerp<Color?>(a?.backgroundColor, b?.backgroundColor, t, Color.lerp),
+      shadowColor: MaterialStateProperty.lerp<Color?>(a?.shadowColor, b?.shadowColor, t, Color.lerp),
+      surfaceTintColor: MaterialStateProperty.lerp<Color?>(a?.surfaceTintColor, b?.surfaceTintColor, t, Color.lerp),
+      elevation: MaterialStateProperty.lerp<double?>(a?.elevation, b?.elevation, t, lerpDouble),
+      padding:  MaterialStateProperty.lerp<EdgeInsetsGeometry?>(a?.padding, b?.padding, t, EdgeInsetsGeometry.lerp),
+      minimumSize: MaterialStateProperty.lerp<Size?>(a?.minimumSize, b?.minimumSize, t, Size.lerp),
+      fixedSize: MaterialStateProperty.lerp<Size?>(a?.fixedSize, b?.fixedSize, t, Size.lerp),
+      maximumSize: MaterialStateProperty.lerp<Size?>(a?.maximumSize, b?.maximumSize, t, Size.lerp),
+      side: _LerpSides(a?.side, b?.side, t),
+      shape: MaterialStateProperty.lerp<OutlinedBorder?>(a?.shape, b?.shape, t, OutlinedBorder.lerp),
+      mouseCursor: t < 0.5 ? a?.mouseCursor : b?.mouseCursor,
+      visualDensity: t < 0.5 ? a?.visualDensity : b?.visualDensity,
+      alignment: AlignmentGeometry.lerp(a?.alignment, b?.alignment, t),
+    );
+  }
+
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(DiagnosticsProperty<MaterialStateProperty<Color?>>('backgroundColor', backgroundColor, defaultValue: null));
+    properties.add(DiagnosticsProperty<MaterialStateProperty<Color?>>('shadowColor', shadowColor, defaultValue: null));
+    properties.add(DiagnosticsProperty<MaterialStateProperty<Color?>>('surfaceTintColor', surfaceTintColor, defaultValue: null));
+    properties.add(DiagnosticsProperty<MaterialStateProperty<double?>>('elevation', elevation, defaultValue: null));
+    properties.add(DiagnosticsProperty<MaterialStateProperty<EdgeInsetsGeometry?>>('padding', padding, defaultValue: null));
+    properties.add(DiagnosticsProperty<MaterialStateProperty<Size?>>('minimumSize', minimumSize, defaultValue: null));
+    properties.add(DiagnosticsProperty<MaterialStateProperty<Size?>>('fixedSize', fixedSize, defaultValue: null));
+    properties.add(DiagnosticsProperty<MaterialStateProperty<Size?>>('maximumSize', maximumSize, defaultValue: null));
+    properties.add(DiagnosticsProperty<MaterialStateProperty<BorderSide?>>('side', side, defaultValue: null));
+    properties.add(DiagnosticsProperty<MaterialStateProperty<OutlinedBorder?>>('shape', shape, defaultValue: null));
+    properties.add(DiagnosticsProperty<MaterialStateProperty<MouseCursor?>>('mouseCursor', mouseCursor, defaultValue: null));
+    properties.add(DiagnosticsProperty<VisualDensity>('visualDensity', visualDensity, defaultValue: null));
+    properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment, defaultValue: null));
+  }
+}
+
+/// A required helper class because [BorderSide.lerp] doesn't support passing or
+/// returning null values.
+class _LerpSides implements MaterialStateProperty<BorderSide?> {
+  const _LerpSides(this.a, this.b, this.t);
+
+  final MaterialStateProperty<BorderSide?>? a;
+  final MaterialStateProperty<BorderSide?>? b;
+  final double t;
+
+  @override
+  BorderSide? resolve(Set<MaterialState> states) {
+    final BorderSide? resolvedA = a?.resolve(states);
+    final BorderSide? resolvedB = b?.resolve(states);
+    if (resolvedA == null && resolvedB == null) {
+      return null;
+    }
+    if (resolvedA == null) {
+      return BorderSide.lerp(BorderSide(width: 0, color: resolvedB!.color.withAlpha(0)), resolvedB, t);
+    }
+    if (resolvedB == null) {
+      return BorderSide.lerp(resolvedA, BorderSide(width: 0, color: resolvedA.color.withAlpha(0)), t);
+    }
+    return BorderSide.lerp(resolvedA, resolvedB, t);
+  }
+}
diff --git a/packages/flutter/lib/src/material/menu_theme.dart b/packages/flutter/lib/src/material/menu_theme.dart
new file mode 100644
index 0000000..b1c098b
--- /dev/null
+++ b/packages/flutter/lib/src/material/menu_theme.dart
@@ -0,0 +1,130 @@
+// 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 'package:flutter/foundation.dart';
+import 'package:flutter/widgets.dart';
+
+import 'menu_anchor.dart';
+import 'menu_style.dart';
+import 'theme.dart';
+
+// Examples can assume:
+// late Widget child;
+
+/// Defines the configuration of the submenus created by the [SubmenuButton],
+/// [MenuBar], or [MenuAnchor] widgets.
+///
+/// Descendant widgets obtain the current [MenuThemeData] object using
+/// `MenuTheme.of(context)`.
+///
+/// Typically, a [MenuThemeData] is specified as part of the overall [Theme]
+/// with [ThemeData.menuTheme]. Otherwise, [MenuTheme] can be used to configure
+/// its own widget subtree.
+///
+/// All [MenuThemeData] properties are `null` by default. If any of these
+/// properties are null, the menu bar will provide its own defaults.
+///
+/// See also:
+///
+/// * [ThemeData], which describes the overall theme for the application.
+/// * [MenuBarThemeData], which describes the theme for the menu bar itself in a
+///   [MenuBar] widget.
+@immutable
+class MenuThemeData with Diagnosticable {
+  /// Creates a const set of properties used to configure [MenuTheme].
+  const MenuThemeData({this.style});
+
+  /// The [MenuStyle] of a [SubmenuButton] menu.
+  ///
+  /// Any values not set in the [MenuStyle] will use the menu default for that
+  /// property.
+  final MenuStyle? style;
+
+  /// Linearly interpolate between two menu button themes.
+  static MenuThemeData? lerp(MenuThemeData? a, MenuThemeData? b, double t) {
+    return MenuThemeData(style: MenuStyle.lerp(a?.style, b?.style, t));
+  }
+
+  @override
+  int get hashCode => style.hashCode;
+
+  @override
+  bool operator ==(Object other) {
+    if (identical(this, other)) {
+      return true;
+    }
+    if (other.runtimeType != runtimeType) {
+      return false;
+    }
+    return other is MenuThemeData && other.style == style;
+  }
+
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(DiagnosticsProperty<MenuStyle>('style', style, defaultValue: null));
+  }
+}
+
+/// An inherited widget that defines the configuration in this widget's
+/// descendants for menus created by the [SubmenuButton], [MenuBar], or
+/// [MenuAnchor] widgets.
+///
+/// Values specified here are used for [SubmenuButton]'s menu properties that
+/// are not given an explicit non-null value.
+///
+/// See also:
+///
+/// * [MenuThemeData], a configuration object that holds attributes of a menu
+///   used by this theme.
+/// * [MenuBarTheme], which does the same thing for the [MenuBar] widget.
+/// * [MenuBar], a widget that manages [MenuItemButton]s.
+/// * [MenuAnchor], a widget that creates a region that has a submenu.
+/// * [MenuItemButton], a widget that is a selectable item in a menu bar menu.
+/// * [SubmenuButton], a widget that specifies an item with a cascading submenu
+///   in a [MenuBar] menu.
+class MenuTheme extends InheritedTheme {
+  /// Creates a const theme that controls the configurations for the menus
+  /// created by the [SubmenuButton] or [MenuAnchor] widgets.
+  const MenuTheme({
+    super.key,
+    required this.data,
+    required super.child,
+  }) : assert(data != null);
+
+  /// The properties for [MenuBar] and [MenuItemButton] in this widget's
+  /// descendants.
+  final MenuThemeData data;
+
+  /// Returns the closest instance of this class's [data] value that encloses
+  /// the given context. If there is no ancestor, it returns
+  /// [ThemeData.menuTheme].
+  ///
+  /// Typical usage is as follows:
+  ///
+  /// ```dart
+  /// Widget build(BuildContext context) {
+  ///   return MenuTheme(
+  ///     data: const MenuThemeData(
+  ///       style: MenuStyle(
+  ///         backgroundColor: MaterialStatePropertyAll<Color>(Colors.red),
+  ///       ),
+  ///     ),
+  ///     child: child,
+  ///   );
+  /// }
+  /// ```
+  static MenuThemeData of(BuildContext context) {
+    final MenuTheme? menuTheme = context.dependOnInheritedWidgetOfExactType<MenuTheme>();
+    return menuTheme?.data ?? Theme.of(context).menuTheme;
+  }
+
+  @override
+  Widget wrap(BuildContext context, Widget child) {
+    return MenuTheme(data: data, child: child);
+  }
+
+  @override
+  bool updateShouldNotify(MenuTheme oldWidget) => data != oldWidget.data;
+}
diff --git a/packages/flutter/lib/src/material/text_button.dart b/packages/flutter/lib/src/material/text_button.dart
index 9be4e53..b3dc1b5 100644
--- a/packages/flutter/lib/src/material/text_button.dart
+++ b/packages/flutter/lib/src/material/text_button.dart
@@ -222,13 +222,14 @@
 
   /// Defines the button's default appearance.
   ///
+  /// {@template flutter.material.text_button.default_style_of}
   /// The button [child]'s [Text] and [Icon] widgets are rendered with
   /// the [ButtonStyle]'s foreground color. The button's [InkWell] adds
   /// the style's overlay color when the button is focused, hovered
   /// or pressed. The button's background color becomes its [Material]
   /// color and is transparent by default.
   ///
-  /// All of the ButtonStyle's defaults appear below.
+  /// All of the [ButtonStyle]'s defaults appear below.
   ///
   /// In this list "Theme.foo" is shorthand for
   /// `Theme.of(context).foo`. Color scheme values like
@@ -245,6 +246,7 @@
   ///
   /// The color of the [ButtonStyle.textStyle] is not used, the
   /// [ButtonStyle.foregroundColor] color is used instead.
+  /// {@endtemplate}
   ///
   /// ## Material 2 defaults
   ///
@@ -295,6 +297,7 @@
   /// If [ThemeData.useMaterial3] is set to true the following defaults will
   /// be used:
   ///
+  /// {@template flutter.material.text_button.material3_defaults}
   /// * `textStyle` - Theme.textTheme.labelLarge
   /// * `backgroundColor` - transparent
   /// * `foregroundColor`
@@ -326,6 +329,7 @@
   /// * `enableFeedback` - true
   /// * `alignment` - Alignment.center
   /// * `splashFactory` - Theme.splashFactory
+  /// {@endtemplate}
   @override
   ButtonStyle defaultStyleOf(BuildContext context) {
     final ThemeData theme = Theme.of(context);
diff --git a/packages/flutter/lib/src/material/theme_data.dart b/packages/flutter/lib/src/material/theme_data.dart
index 30cd867..3b1e90c 100644
--- a/packages/flutter/lib/src/material/theme_data.dart
+++ b/packages/flutter/lib/src/material/theme_data.dart
@@ -36,6 +36,9 @@
 import 'input_decorator.dart';
 import 'list_tile.dart';
 import 'list_tile_theme.dart';
+import 'menu_bar_theme.dart';
+import 'menu_button_theme.dart';
+import 'menu_theme.dart';
 import 'navigation_bar_theme.dart';
 import 'navigation_rail_theme.dart';
 import 'outlined_button_theme.dart';
@@ -345,6 +348,9 @@
     FloatingActionButtonThemeData? floatingActionButtonTheme,
     IconButtonThemeData? iconButtonTheme,
     ListTileThemeData? listTileTheme,
+    MenuBarThemeData? menuBarTheme,
+    MenuButtonThemeData? menuButtonTheme,
+    MenuThemeData? menuTheme,
     NavigationBarThemeData? navigationBarTheme,
     NavigationRailThemeData? navigationRailTheme,
     OutlinedButtonThemeData? outlinedButtonTheme,
@@ -568,17 +574,21 @@
     bottomSheetTheme ??= const BottomSheetThemeData();
     buttonBarTheme ??= const ButtonBarThemeData();
     cardTheme ??= const CardTheme();
-    chipTheme ??= const ChipThemeData();
     checkboxTheme ??= const CheckboxThemeData();
+    chipTheme ??= const ChipThemeData();
     dataTableTheme ??= const DataTableThemeData();
     dialogTheme ??= const DialogTheme();
     dividerTheme ??= const DividerThemeData();
     drawerTheme ??= const DrawerThemeData();
     elevatedButtonTheme ??= const ElevatedButtonThemeData();
+    expansionTileTheme ??= const ExpansionTileThemeData();
     filledButtonTheme ??= const FilledButtonThemeData();
     floatingActionButtonTheme ??= const FloatingActionButtonThemeData();
     iconButtonTheme ??= const IconButtonThemeData();
     listTileTheme ??= const ListTileThemeData();
+    menuBarTheme ??= const MenuBarThemeData();
+    menuButtonTheme ??= const MenuButtonThemeData();
+    menuTheme ??= const MenuThemeData();
     navigationBarTheme ??= const NavigationBarThemeData();
     navigationRailTheme ??= const NavigationRailThemeData();
     outlinedButtonTheme ??= const OutlinedButtonThemeData();
@@ -594,7 +604,6 @@
     timePickerTheme ??= const TimePickerThemeData();
     toggleButtonsTheme ??= const ToggleButtonsThemeData();
     tooltipTheme ??= const TooltipThemeData();
-    expansionTileTheme ??= const ExpansionTileThemeData();
 
     // DEPRECATED (newest deprecations at the bottom)
     accentTextTheme = defaultAccentTextTheme.merge(accentTextTheme);
@@ -671,6 +680,9 @@
       floatingActionButtonTheme: floatingActionButtonTheme,
       iconButtonTheme: iconButtonTheme,
       listTileTheme: listTileTheme,
+      menuBarTheme: menuBarTheme,
+      menuButtonTheme: menuButtonTheme,
+      menuTheme: menuTheme,
       navigationBarTheme: navigationBarTheme,
       navigationRailTheme: navigationRailTheme,
       outlinedButtonTheme: outlinedButtonTheme,
@@ -778,6 +790,9 @@
     required this.floatingActionButtonTheme,
     required this.iconButtonTheme,
     required this.listTileTheme,
+    required this.menuBarTheme,
+    required this.menuButtonTheme,
+    required this.menuTheme,
     required this.navigationBarTheme,
     required this.navigationRailTheme,
     required this.outlinedButtonTheme,
@@ -943,6 +958,9 @@
        assert(floatingActionButtonTheme != null),
        assert(iconButtonTheme != null),
        assert(listTileTheme != null),
+       assert(menuBarTheme != null),
+       assert(menuButtonTheme != null),
+       assert(menuTheme != null),
        assert(navigationBarTheme != null),
        assert(navigationRailTheme != null),
        assert(outlinedButtonTheme != null),
@@ -1520,6 +1538,18 @@
   /// A theme for customizing the appearance of [ListTile] widgets.
   final ListTileThemeData listTileTheme;
 
+  /// A theme for customizing the color, shape, elevation, and other [MenuStyle]
+  /// aspects of the menu bar created by the [MenuBar] widget.
+  final MenuBarThemeData menuBarTheme;
+
+  /// A theme for customizing the color, shape, elevation, and text style of
+  /// cascading menu buttons created by [SubmenuButton] or [MenuItemButton].
+  final MenuButtonThemeData menuButtonTheme;
+
+  /// A theme for customizing the color, shape, elevation, and other [MenuStyle]
+  /// attributes of menus created by the [SubmenuButton] widget.
+  final MenuThemeData menuTheme;
+
   /// A theme for customizing the background color, text style, and icon themes
   /// of a [NavigationBar].
   final NavigationBarThemeData navigationBarTheme;
@@ -1814,6 +1844,9 @@
     FloatingActionButtonThemeData? floatingActionButtonTheme,
     IconButtonThemeData? iconButtonTheme,
     ListTileThemeData? listTileTheme,
+    MenuBarThemeData? menuBarTheme,
+    MenuButtonThemeData? menuButtonTheme,
+    MenuThemeData? menuTheme,
     NavigationBarThemeData? navigationBarTheme,
     NavigationRailThemeData? navigationRailTheme,
     OutlinedButtonThemeData? outlinedButtonTheme,
@@ -1972,6 +2005,9 @@
       floatingActionButtonTheme: floatingActionButtonTheme ?? this.floatingActionButtonTheme,
       iconButtonTheme: iconButtonTheme ?? this.iconButtonTheme,
       listTileTheme: listTileTheme ?? this.listTileTheme,
+      menuBarTheme: menuBarTheme ?? this.menuBarTheme,
+      menuButtonTheme: menuButtonTheme ?? this.menuButtonTheme,
+      menuTheme: menuTheme ?? this.menuTheme,
       navigationBarTheme: navigationBarTheme ?? this.navigationBarTheme,
       navigationRailTheme: navigationRailTheme ?? this.navigationRailTheme,
       outlinedButtonTheme: outlinedButtonTheme ?? this.outlinedButtonTheme,
@@ -2172,6 +2208,9 @@
       floatingActionButtonTheme: FloatingActionButtonThemeData.lerp(a.floatingActionButtonTheme, b.floatingActionButtonTheme, t)!,
       iconButtonTheme: IconButtonThemeData.lerp(a.iconButtonTheme, b.iconButtonTheme, t)!,
       listTileTheme: ListTileThemeData.lerp(a.listTileTheme, b.listTileTheme, t)!,
+      menuBarTheme: MenuBarThemeData.lerp(a.menuBarTheme, b.menuBarTheme, t)!,
+      menuButtonTheme: MenuButtonThemeData.lerp(a.menuButtonTheme, b.menuButtonTheme, t)!,
+      menuTheme: MenuThemeData.lerp(a.menuTheme, b.menuTheme, t)!,
       navigationBarTheme: NavigationBarThemeData.lerp(a.navigationBarTheme, b.navigationBarTheme, t)!,
       navigationRailTheme: NavigationRailThemeData.lerp(a.navigationRailTheme, b.navigationRailTheme, t)!,
       outlinedButtonTheme: OutlinedButtonThemeData.lerp(a.outlinedButtonTheme, b.outlinedButtonTheme, t)!,
@@ -2274,6 +2313,9 @@
         other.floatingActionButtonTheme == floatingActionButtonTheme &&
         other.iconButtonTheme == iconButtonTheme &&
         other.listTileTheme == listTileTheme &&
+        other.menuBarTheme == menuBarTheme &&
+        other.menuButtonTheme == menuButtonTheme &&
+        other.menuTheme == menuTheme &&
         other.navigationBarTheme == navigationBarTheme &&
         other.navigationRailTheme == navigationRailTheme &&
         other.outlinedButtonTheme == outlinedButtonTheme &&
@@ -2373,6 +2415,9 @@
       floatingActionButtonTheme,
       iconButtonTheme,
       listTileTheme,
+      menuBarTheme,
+      menuButtonTheme,
+      menuTheme,
       navigationBarTheme,
       navigationRailTheme,
       outlinedButtonTheme,
@@ -2474,6 +2519,9 @@
     properties.add(DiagnosticsProperty<FloatingActionButtonThemeData>('floatingActionButtonTheme', floatingActionButtonTheme, defaultValue: defaultData.floatingActionButtonTheme, level: DiagnosticLevel.debug));
     properties.add(DiagnosticsProperty<IconButtonThemeData>('iconButtonTheme', iconButtonTheme, defaultValue: defaultData.iconButtonTheme, level: DiagnosticLevel.debug));
     properties.add(DiagnosticsProperty<ListTileThemeData>('listTileTheme', listTileTheme, defaultValue: defaultData.listTileTheme, level: DiagnosticLevel.debug));
+    properties.add(DiagnosticsProperty<MenuBarThemeData>('menuBarTheme', menuBarTheme, defaultValue: defaultData.menuBarTheme, level: DiagnosticLevel.debug));
+    properties.add(DiagnosticsProperty<MenuButtonThemeData>('menuButtonTheme', menuButtonTheme, defaultValue: defaultData.menuButtonTheme, level: DiagnosticLevel.debug));
+    properties.add(DiagnosticsProperty<MenuThemeData>('menuTheme', menuTheme, defaultValue: defaultData.menuTheme, level: DiagnosticLevel.debug));
     properties.add(DiagnosticsProperty<NavigationBarThemeData>('navigationBarTheme', navigationBarTheme, defaultValue: defaultData.navigationBarTheme, level: DiagnosticLevel.debug));
     properties.add(DiagnosticsProperty<NavigationRailThemeData>('navigationRailTheme', navigationRailTheme, defaultValue: defaultData.navigationRailTheme, level: DiagnosticLevel.debug));
     properties.add(DiagnosticsProperty<OutlinedButtonThemeData>('outlinedButtonTheme', outlinedButtonTheme, defaultValue: defaultData.outlinedButtonTheme, level: DiagnosticLevel.debug));
@@ -2839,7 +2887,7 @@
   Offset get baseSizeAdjustment {
     // The number of logical pixels represented by an increase or decrease in
     // density by one. The Material Design guidelines say to increment/decrement
-    // sized in terms of four pixel increments.
+    // sizes in terms of four pixel increments.
     const double interval = 4.0;
 
     return Offset(horizontal, vertical) * interval;
diff --git a/packages/flutter/lib/src/rendering/layer.dart b/packages/flutter/lib/src/rendering/layer.dart
index b1cf4ee..a298d50 100644
--- a/packages/flutter/lib/src/rendering/layer.dart
+++ b/packages/flutter/lib/src/rendering/layer.dart
@@ -2419,7 +2419,9 @@
   Size? leaderSize;
 
   @override
-  String toString() => '${describeIdentity(this)}(${ _leader != null ? "<linked>" : "<dangling>" })';
+  String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
+    return '${describeIdentity(this)}(${ _leader != null ? "<linked>" : "<dangling>" })';
+  }
 }
 
 /// A composited layer that can be followed by a [FollowerLayer].
diff --git a/packages/flutter/lib/src/rendering/proxy_box.dart b/packages/flutter/lib/src/rendering/proxy_box.dart
index 6465d88..074711c 100644
--- a/packages/flutter/lib/src/rendering/proxy_box.dart
+++ b/packages/flutter/lib/src/rendering/proxy_box.dart
@@ -4996,7 +4996,7 @@
   void paint(PaintingContext context, Offset offset) {
     final Size? leaderSize = link.leaderSize;
     assert(
-      link.leaderSize != null || (link.leader == null || leaderAnchor == Alignment.topLeft),
+      link.leaderSize != null || link.leader == null || leaderAnchor == Alignment.topLeft,
       '$link: layer is linked to ${link.leader} but a valid leaderSize is not set. '
       'leaderSize is required when leaderAnchor is not Alignment.topLeft '
       '(current value is $leaderAnchor).',
diff --git a/packages/flutter/lib/src/widgets/basic.dart b/packages/flutter/lib/src/widgets/basic.dart
index 6fe55c0..8c86b27 100644
--- a/packages/flutter/lib/src/widgets/basic.dart
+++ b/packages/flutter/lib/src/widgets/basic.dart
@@ -85,7 +85,7 @@
 /// infrequently change. This provides a performance tradeoff where building
 /// the [Widget]s is faster but performing updates is slower.
 ///
-/// |                     | _UbiquitiousInheritedElement | InheritedElement |
+/// |                     | _UbiquitousInheritedElement | InheritedElement |
 /// |---------------------|------------------------------|------------------|
 /// | insert (best case)  | O(1)                         | O(1)             |
 /// | insert (worst case) | O(1)                         | O(n)             |
diff --git a/packages/flutter/test/material/menu_anchor_test.dart b/packages/flutter/test/material/menu_anchor_test.dart
new file mode 100644
index 0000000..c8249b0
--- /dev/null
+++ b/packages/flutter/test/material/menu_anchor_test.dart
@@ -0,0 +1,1793 @@
+// 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 'package:flutter/foundation.dart';
+import 'package:flutter/gestures.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/rendering.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+  late MenuController controller;
+  String? focusedMenu;
+  final List<TestMenu> selected = <TestMenu>[];
+  final List<TestMenu> opened = <TestMenu>[];
+  final List<TestMenu> closed = <TestMenu>[];
+  final GlobalKey menuItemKey = GlobalKey();
+
+  void onPressed(TestMenu item) {
+    selected.add(item);
+  }
+
+  void onOpen(TestMenu item) {
+    opened.add(item);
+  }
+
+  void onClose(TestMenu item) {
+    closed.add(item);
+  }
+
+  void handleFocusChange() {
+    focusedMenu = primaryFocus?.debugLabel ?? primaryFocus?.toString();
+  }
+
+  setUp(() {
+    focusedMenu = null;
+    selected.clear();
+    opened.clear();
+    closed.clear();
+    controller = MenuController();
+    focusedMenu = null;
+  });
+
+  void listenForFocusChanges() {
+    FocusManager.instance.addListener(handleFocusChange);
+    addTearDown(() => FocusManager.instance.removeListener(handleFocusChange));
+  }
+
+  Finder findMenuPanels() {
+    return find.byWidgetPredicate((Widget widget) => widget.runtimeType.toString() == '_MenuPanel');
+  }
+
+  Finder findMenuBarItemLabels() {
+    return find.byWidgetPredicate((Widget widget) => widget.runtimeType.toString() == '_MenuItemLabel');
+  }
+
+  // Finds the mnemonic associated with the menu item that has the given label.
+  Finder findMnemonic(String label) {
+    return find
+        .descendant(
+          of: find.ancestor(of: find.text(label), matching: findMenuBarItemLabels()),
+          matching: find.byType(Text),
+        )
+        .last;
+  }
+
+  Widget buildTestApp({
+    AlignmentGeometry? alignment,
+    Offset alignmentOffset = Offset.zero,
+    TextDirection textDirection = TextDirection.ltr,
+  }) {
+    final FocusNode focusNode = FocusNode();
+    return MaterialApp(
+      home: Material(
+        child: Directionality(
+          textDirection: textDirection,
+          child: Center(
+            child: MenuAnchor(
+              childFocusNode: focusNode,
+              controller: controller,
+              alignmentOffset: alignmentOffset,
+              style: MenuStyle(alignment: alignment),
+              menuChildren: <Widget>[
+                MenuItemButton(
+                  key: menuItemKey,
+                  shortcut: const SingleActivator(
+                    LogicalKeyboardKey.keyB,
+                    control: true,
+                  ),
+                  onPressed: () {},
+                  child: Text(TestMenu.subMenu00.label),
+                ),
+                MenuItemButton(
+                  leadingIcon: const Icon(Icons.send),
+                  trailingIcon: const Icon(Icons.mail),
+                  onPressed: () {},
+                  child: Text(TestMenu.subMenu01.label),
+                ),
+              ],
+              builder: (BuildContext context, MenuController controller, Widget? child) {
+                return ElevatedButton(
+                  focusNode: focusNode,
+                  onPressed: () {
+                    if (controller.isOpen) {
+                      controller.close();
+                    } else {
+                      controller.open();
+                    }
+                  },
+                  child: child,
+                );
+              },
+              child: const Text('Press Me'),
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+
+  Future<TestGesture> hoverOver(WidgetTester tester, Finder finder) async {
+    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
+    await gesture.moveTo(tester.getCenter(finder));
+    await tester.pumpAndSettle();
+    return gesture;
+  }
+
+  Material getMenuBarMaterial(WidgetTester tester) {
+    return tester.widget<Material>(
+      find.descendant(of: findMenuPanels(), matching: find.byType(Material)).first,
+    );
+  }
+
+  group('Menu functions', () {
+    testWidgets('basic menu structure', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: MenuBar(
+              controller: controller,
+              children: createTestMenus(
+                onPressed: onPressed,
+                onOpen: onOpen,
+                onClose: onClose,
+              ),
+            ),
+          ),
+        ),
+      );
+
+      expect(find.text(TestMenu.mainMenu0.label), findsOneWidget);
+      expect(find.text(TestMenu.mainMenu1.label), findsOneWidget);
+      expect(find.text(TestMenu.mainMenu2.label), findsOneWidget);
+      expect(find.text(TestMenu.subMenu10.label), findsNothing);
+      expect(find.text(TestMenu.subSubMenu110.label), findsNothing);
+      expect(opened, isEmpty);
+
+      await tester.tap(find.text(TestMenu.mainMenu1.label));
+      await tester.pump();
+
+      expect(find.text(TestMenu.mainMenu0.label), findsOneWidget);
+      expect(find.text(TestMenu.mainMenu1.label), findsOneWidget);
+      expect(find.text(TestMenu.mainMenu2.label), findsOneWidget);
+      expect(find.text(TestMenu.subMenu10.label), findsOneWidget);
+      expect(find.text(TestMenu.subMenu11.label), findsOneWidget);
+      expect(find.text(TestMenu.subMenu12.label), findsOneWidget);
+      expect(find.text(TestMenu.subSubMenu110.label), findsNothing);
+      expect(find.text(TestMenu.subSubMenu111.label), findsNothing);
+      expect(find.text(TestMenu.subSubMenu112.label), findsNothing);
+      expect(opened.last, equals(TestMenu.mainMenu1));
+      opened.clear();
+
+      await tester.tap(find.text(TestMenu.subMenu11.label));
+      await tester.pump();
+
+      expect(find.text(TestMenu.mainMenu0.label), findsOneWidget);
+      expect(find.text(TestMenu.mainMenu1.label), findsOneWidget);
+      expect(find.text(TestMenu.mainMenu2.label), findsOneWidget);
+      expect(find.text(TestMenu.subMenu10.label), findsOneWidget);
+      expect(find.text(TestMenu.subMenu11.label), findsOneWidget);
+      expect(find.text(TestMenu.subMenu12.label), findsOneWidget);
+      expect(find.text(TestMenu.subSubMenu110.label), findsOneWidget);
+      expect(find.text(TestMenu.subSubMenu111.label), findsOneWidget);
+      expect(find.text(TestMenu.subSubMenu112.label), findsOneWidget);
+      expect(opened.last, equals(TestMenu.subMenu11));
+    });
+
+    testWidgets('geometry', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: Column(
+              children: <Widget>[
+                Row(
+                  children: <Widget>[
+                    Expanded(
+                      child: MenuBar(
+                        children: createTestMenus(onPressed: onPressed),
+                      ),
+                    ),
+                  ],
+                ),
+                const Expanded(child: Placeholder()),
+              ],
+            ),
+          ),
+        ),
+      );
+      await tester.pump();
+
+      expect(tester.getRect(find.byType(MenuBar)), equals(const Rect.fromLTRB(0, 0, 800, 48)));
+
+      // Open and make sure things are the right size.
+      await tester.tap(find.text(TestMenu.mainMenu1.label));
+      await tester.pump();
+
+      expect(tester.getRect(find.byType(MenuBar)), equals(const Rect.fromLTRB(0, 0, 800, 48)));
+      expect(
+        tester.getRect(find.text(TestMenu.subMenu10.label)),
+        equals(const Rect.fromLTRB(112.0, 69.0, 266.0, 83.0)),
+      );
+      expect(
+        tester.getRect(
+          find.ancestor(of: find.text(TestMenu.subMenu10.label), matching: find.byType(Material)).at(1),
+        ),
+        equals(const Rect.fromLTRB(104.0, 48.0, 334.0, 200.0)),
+      );
+    });
+
+    testWidgets('geometry with RTL direction', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: Directionality(
+              textDirection: TextDirection.rtl,
+              child: Column(
+                children: <Widget>[
+                  Row(
+                    children: <Widget>[
+                      Expanded(
+                        child: MenuBar(
+                          children: createTestMenus(onPressed: onPressed),
+                        ),
+                      ),
+                    ],
+                  ),
+                  const Expanded(child: Placeholder()),
+                ],
+              ),
+            ),
+          ),
+        ),
+      );
+      await tester.pump();
+
+      expect(tester.getRect(find.byType(MenuBar)), equals(const Rect.fromLTRB(0, 0, 800, 48)));
+
+      // Open and make sure things are the right size.
+      await tester.tap(find.text(TestMenu.mainMenu1.label));
+      await tester.pump();
+
+      expect(tester.getRect(find.byType(MenuBar)), equals(const Rect.fromLTRB(0, 0, 800, 48)));
+      expect(
+        tester.getRect(find.text(TestMenu.subMenu10.label)),
+        equals(const Rect.fromLTRB(534.0, 69.0, 688.0, 83.0)),
+      );
+      expect(
+        tester.getRect(
+          find.ancestor(of: find.text(TestMenu.subMenu10.label), matching: find.byType(Material)).at(1),
+        ),
+        equals(const Rect.fromLTRB(466.0, 48.0, 696.0, 200.0)),
+      );
+
+      // Close and make sure it goes back where it was.
+      await tester.tap(find.text(TestMenu.mainMenu1.label));
+      await tester.pump();
+
+      expect(tester.getRect(find.byType(MenuBar)), equals(const Rect.fromLTRB(0, 0, 800, 48)));
+
+      // Test menu bar size when not expanded.
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: Column(
+              children: <Widget>[
+                MenuBar(
+                  children: createTestMenus(onPressed: onPressed),
+                ),
+                const Expanded(child: Placeholder()),
+              ],
+            ),
+          ),
+        ),
+      );
+      await tester.pump();
+
+      expect(
+        tester.getRect(find.byType(MenuBar)),
+        equals(const Rect.fromLTRB(246.0, 0.0, 554.0, 48.0)),
+      );
+    });
+
+    testWidgets('menu alignment and offset in LTR', (WidgetTester tester) async {
+      await tester.pumpWidget(buildTestApp());
+
+      final Rect buttonRect = tester.getRect(find.byType(ElevatedButton));
+      expect(buttonRect, equals(const Rect.fromLTRB(328.0, 276.0, 472.0, 324.0)));
+
+      final Finder findMenuScope = find.ancestor(of: find.byKey(menuItemKey), matching: find.byType(FocusScope)).first;
+
+      // Open the menu and make sure things are the right size, in the right place.
+      await tester.tap(find.text('Press Me'));
+      await tester.pump();
+      expect(tester.getRect(findMenuScope), equals(const Rect.fromLTRB(328.0, 324.0, 618.0, 428.0)));
+
+      await tester.pumpWidget(buildTestApp(alignment: AlignmentDirectional.topStart));
+      await tester.pump();
+      expect(tester.getRect(findMenuScope), equals(const Rect.fromLTRB(328.0, 276.0, 618.0, 380.0)));
+
+      await tester.pumpWidget(buildTestApp(alignment: AlignmentDirectional.center));
+      await tester.pump();
+      expect(tester.getRect(findMenuScope), equals(const Rect.fromLTRB(400.0, 300.0, 690.0, 404.0)));
+
+      await tester.pumpWidget(buildTestApp(alignment: AlignmentDirectional.bottomEnd));
+      await tester.pump();
+      expect(tester.getRect(findMenuScope), equals(const Rect.fromLTRB(472.0, 324.0, 762.0, 428.0)));
+
+      await tester.pumpWidget(buildTestApp(alignment: AlignmentDirectional.topStart));
+      await tester.pump();
+
+      final Rect menuRect = tester.getRect(findMenuScope);
+      await tester.pumpWidget(
+        buildTestApp(
+          alignment: AlignmentDirectional.topStart,
+          alignmentOffset: const Offset(10, 20),
+        ),
+      );
+      await tester.pump();
+      final Rect offsetMenuRect = tester.getRect(findMenuScope);
+      expect(
+        offsetMenuRect.topLeft - menuRect.topLeft,
+        equals(const Offset(10, 20)),
+      );
+    });
+
+    testWidgets('menu alignment and offset in RTL', (WidgetTester tester) async {
+      await tester.pumpWidget(buildTestApp(textDirection: TextDirection.rtl));
+
+      final Rect buttonRect = tester.getRect(find.byType(ElevatedButton));
+      expect(buttonRect, equals(const Rect.fromLTRB(328.0, 276.0, 472.0, 324.0)));
+
+      final Finder findMenuScope =
+          find.ancestor(of: find.text(TestMenu.subMenu00.label), matching: find.byType(FocusScope)).first;
+
+      // Open the menu and make sure things are the right size, in the right place.
+      await tester.tap(find.text('Press Me'));
+      await tester.pump();
+      expect(tester.getRect(findMenuScope), equals(const Rect.fromLTRB(182.0, 324.0, 472.0, 428.0)));
+
+      await tester.pumpWidget(buildTestApp(textDirection: TextDirection.rtl, alignment: AlignmentDirectional.topStart));
+      await tester.pump();
+      expect(tester.getRect(findMenuScope), equals(const Rect.fromLTRB(182.0, 276.0, 472.0, 380.0)));
+
+      await tester.pumpWidget(buildTestApp(textDirection: TextDirection.rtl, alignment: AlignmentDirectional.center));
+      await tester.pump();
+      expect(tester.getRect(findMenuScope), equals(const Rect.fromLTRB(110.0, 300.0, 400.0, 404.0)));
+
+      await tester
+          .pumpWidget(buildTestApp(textDirection: TextDirection.rtl, alignment: AlignmentDirectional.bottomEnd));
+      await tester.pump();
+      expect(tester.getRect(findMenuScope), equals(const Rect.fromLTRB(38.0, 324.0, 328.0, 428.0)));
+
+      await tester.pumpWidget(buildTestApp(textDirection: TextDirection.rtl, alignment: AlignmentDirectional.topStart));
+      await tester.pump();
+
+      final Rect menuRect = tester.getRect(findMenuScope);
+      await tester.pumpWidget(
+        buildTestApp(
+          textDirection: TextDirection.rtl,
+          alignment: AlignmentDirectional.topStart,
+          alignmentOffset: const Offset(10, 20),
+        ),
+      );
+      await tester.pump();
+      expect(tester.getRect(findMenuScope).topLeft - menuRect.topLeft, equals(const Offset(-10, 20)));
+    });
+
+    testWidgets('menu position in LTR', (WidgetTester tester) async {
+      await tester.pumpWidget(buildTestApp(alignmentOffset: const Offset(100, 50)));
+
+      final Rect buttonRect = tester.getRect(find.byType(ElevatedButton));
+      expect(buttonRect, equals(const Rect.fromLTRB(328.0, 276.0, 472.0, 324.0)));
+
+      final Finder findMenuScope =
+          find.ancestor(of: find.text(TestMenu.subMenu00.label), matching: find.byType(FocusScope)).first;
+
+      // Open the menu and make sure things are the right size, in the right place.
+      await tester.tap(find.text('Press Me'));
+      await tester.pump();
+      expect(tester.getRect(findMenuScope), equals(const Rect.fromLTRB(428.0, 374.0, 718.0, 478.0)));
+
+      // Now move the menu by calling open() again with a local position on the
+      // anchor.
+      controller.open(position: const Offset(200, 200));
+      await tester.pump();
+      expect(tester.getRect(findMenuScope), equals(const Rect.fromLTRB(510.0, 476.0, 800.0, 580.0)));
+    });
+
+    testWidgets('menu position in RTL', (WidgetTester tester) async {
+      await tester.pumpWidget(buildTestApp(
+        alignmentOffset: const Offset(100, 50),
+        textDirection: TextDirection.rtl,
+      ));
+
+      final Rect buttonRect = tester.getRect(find.byType(ElevatedButton));
+      expect(buttonRect, equals(const Rect.fromLTRB(328.0, 276.0, 472.0, 324.0)));
+      expect(buttonRect, equals(const Rect.fromLTRB(328.0, 276.0, 472.0, 324.0)));
+
+      final Finder findMenuScope =
+          find.ancestor(of: find.text(TestMenu.subMenu00.label), matching: find.byType(FocusScope)).first;
+
+      // Open the menu and make sure things are the right size, in the right place.
+      await tester.tap(find.text('Press Me'));
+      await tester.pump();
+      expect(tester.getRect(findMenuScope), equals(const Rect.fromLTRB(82.0, 374.0, 372.0, 478.0)));
+
+      // Now move the menu by calling open() again with a local position on the
+      // anchor.
+      controller.open(position: const Offset(400, 200));
+      await tester.pump();
+      expect(tester.getRect(findMenuScope), equals(const Rect.fromLTRB(510.0, 476.0, 800.0, 580.0)));
+    });
+
+    testWidgets('works with Padding around menu and overlay', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        Padding(
+          padding: const EdgeInsets.all(10.0),
+          child: MaterialApp(
+            home: Material(
+              child: Column(
+                children: <Widget>[
+                  Padding(
+                    padding: const EdgeInsets.all(12.0),
+                    child: Row(
+                      children: <Widget>[
+                        Expanded(
+                          child: MenuBar(
+                            children: createTestMenus(onPressed: onPressed),
+                          ),
+                        ),
+                      ],
+                    ),
+                  ),
+                  const Expanded(child: Placeholder()),
+                ],
+              ),
+            ),
+          ),
+        ),
+      );
+      await tester.pump();
+
+      expect(tester.getRect(find.byType(MenuBar)), equals(const Rect.fromLTRB(22.0, 22.0, 778.0, 70.0)));
+
+      // Open and make sure things are the right size.
+      await tester.tap(find.text(TestMenu.mainMenu1.label));
+      await tester.pump();
+
+      expect(tester.getRect(find.byType(MenuBar)), equals(const Rect.fromLTRB(22.0, 22.0, 778.0, 70.0)));
+      expect(
+        tester.getRect(find.text(TestMenu.subMenu10.label)),
+        equals(const Rect.fromLTRB(134.0, 91.0, 288.0, 105.0)),
+      );
+      expect(
+        tester.getRect(find.ancestor(of: find.text(TestMenu.subMenu10.label), matching: find.byType(Material)).at(1)),
+        equals(const Rect.fromLTRB(126.0, 70.0, 356.0, 222.0)),
+      );
+
+      // Close and make sure it goes back where it was.
+      await tester.tap(find.text(TestMenu.mainMenu1.label));
+      await tester.pump();
+
+      expect(tester.getRect(find.byType(MenuBar)), equals(const Rect.fromLTRB(22.0, 22.0, 778.0, 70.0)));
+    });
+
+    testWidgets('works with Padding around menu and overlay with RTL direction', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        Padding(
+          padding: const EdgeInsets.all(10.0),
+          child: MaterialApp(
+            home: Material(
+              child: Directionality(
+                textDirection: TextDirection.rtl,
+                child: Column(
+                  children: <Widget>[
+                    Padding(
+                      padding: const EdgeInsets.all(12.0),
+                      child: Row(
+                        children: <Widget>[
+                          Expanded(
+                            child: MenuBar(
+                              children: createTestMenus(onPressed: onPressed),
+                            ),
+                          ),
+                        ],
+                      ),
+                    ),
+                    const Expanded(child: Placeholder()),
+                  ],
+                ),
+              ),
+            ),
+          ),
+        ),
+      );
+      await tester.pump();
+
+      expect(tester.getRect(find.byType(MenuBar)), equals(const Rect.fromLTRB(22.0, 22.0, 778.0, 70.0)));
+
+      // Open and make sure things are the right size.
+      await tester.tap(find.text(TestMenu.mainMenu1.label));
+      await tester.pump();
+
+      expect(tester.getRect(find.byType(MenuBar)), equals(const Rect.fromLTRB(22.0, 22.0, 778.0, 70.0)));
+      expect(
+        tester.getRect(find.text(TestMenu.subMenu10.label)),
+        equals(const Rect.fromLTRB(512.0, 91.0, 666.0, 105.0)),
+      );
+      expect(
+        tester.getRect(find.ancestor(of: find.text(TestMenu.subMenu10.label), matching: find.byType(Material)).at(1)),
+        equals(const Rect.fromLTRB(444.0, 70.0, 674.0, 222.0)),
+      );
+
+      // Close and make sure it goes back where it was.
+      await tester.tap(find.text(TestMenu.mainMenu1.label));
+      await tester.pump();
+
+      expect(tester.getRect(find.byType(MenuBar)), equals(const Rect.fromLTRB(22.0, 22.0, 778.0, 70.0)));
+    });
+
+    testWidgets('visual attributes can be set', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: Column(
+              children: <Widget>[
+                Row(
+                  children: <Widget>[
+                    Expanded(
+                      child: MenuBar(
+                        style: MenuStyle(
+                          elevation: MaterialStateProperty.all<double?>(10),
+                          backgroundColor: const MaterialStatePropertyAll<Color>(Colors.red),
+                        ),
+                        children: createTestMenus(onPressed: onPressed),
+                      ),
+                    ),
+                  ],
+                ),
+                const Expanded(child: Placeholder()),
+              ],
+            ),
+          ),
+        ),
+      );
+      expect(tester.getRect(findMenuPanels()), equals(const Rect.fromLTRB(0.0, 0.0, 800.0, 48.0)));
+      final Material material = getMenuBarMaterial(tester);
+      expect(material.elevation, equals(10));
+      expect(material.color, equals(Colors.red));
+    });
+
+    testWidgets('open and close works', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: MenuBar(
+              controller: controller,
+              children: createTestMenus(
+                onPressed: onPressed,
+                onOpen: onOpen,
+                onClose: onClose,
+              ),
+            ),
+          ),
+        ),
+      );
+
+      expect(opened, isEmpty);
+      expect(closed, isEmpty);
+
+      await tester.tap(find.text(TestMenu.mainMenu1.label));
+      await tester.pump();
+      expect(opened, equals(<TestMenu>[TestMenu.mainMenu1]));
+      expect(closed, isEmpty);
+      opened.clear();
+      closed.clear();
+
+      await tester.tap(find.text(TestMenu.subMenu11.label));
+      await tester.pump();
+
+      expect(opened, equals(<TestMenu>[TestMenu.subMenu11]));
+      expect(closed, isEmpty);
+      opened.clear();
+      closed.clear();
+
+      await tester.tap(find.text(TestMenu.subMenu11.label));
+      await tester.pump();
+
+      expect(opened, isEmpty);
+      expect(closed, equals(<TestMenu>[TestMenu.subMenu11]));
+      opened.clear();
+      closed.clear();
+
+      await tester.tap(find.text(TestMenu.mainMenu0.label));
+      await tester.pump();
+
+      expect(opened, equals(<TestMenu>[TestMenu.mainMenu0]));
+      expect(closed, equals(<TestMenu>[TestMenu.mainMenu1]));
+    });
+
+    testWidgets('select works', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: MenuBar(
+              controller: controller,
+              children: createTestMenus(
+                onPressed: onPressed,
+                onOpen: onOpen,
+                onClose: onClose,
+              ),
+            ),
+          ),
+        ),
+      );
+
+      await tester.tap(find.text(TestMenu.mainMenu1.label));
+      await tester.pump();
+
+      await tester.tap(find.text(TestMenu.subMenu11.label));
+      await tester.pump();
+
+      expect(opened, equals(<TestMenu>[TestMenu.mainMenu1, TestMenu.subMenu11]));
+      opened.clear();
+      await tester.tap(find.text(TestMenu.subSubMenu110.label));
+      await tester.pump();
+
+      expect(selected, equals(<TestMenu>[TestMenu.subSubMenu110]));
+
+      // Selecting a non-submenu item should close all the menus.
+      expect(opened, isEmpty);
+      expect(find.text(TestMenu.subSubMenu110.label), findsNothing);
+      expect(find.text(TestMenu.subMenu11.label), findsNothing);
+    });
+
+    testWidgets('diagnostics', (WidgetTester tester) async {
+      const MenuItemButton item = MenuItemButton(
+        shortcut: SingleActivator(LogicalKeyboardKey.keyA),
+        child: Text('label2'),
+      );
+      final MenuBar menuBar = MenuBar(
+        controller: controller,
+        style: const MenuStyle(
+          backgroundColor: MaterialStatePropertyAll<Color>(Colors.red),
+          elevation: MaterialStatePropertyAll<double?>(10.0),
+        ),
+        children: const <Widget>[item],
+      );
+
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: menuBar,
+          ),
+        ),
+      );
+      await tester.pump();
+
+      final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
+      menuBar.debugFillProperties(builder);
+
+      final List<String> description = builder.properties
+          .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
+          .map((DiagnosticsNode node) => node.toString())
+          .toList();
+
+      expect(
+        description.join('\n'),
+        equalsIgnoringHashCodes(
+            'style: MenuStyle#00000(backgroundColor: MaterialStatePropertyAll(MaterialColor(primary value: Color(0xfff44336))), elevation: MaterialStatePropertyAll(10.0))\n'
+            'clipBehavior: Clip.none'),
+      );
+    });
+
+    testWidgets('keyboard tab traversal works', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: Column(
+              children: <Widget>[
+                MenuBar(
+                  controller: controller,
+                  children: createTestMenus(
+                    onPressed: onPressed,
+                    onOpen: onOpen,
+                    onClose: onClose,
+                  ),
+                ),
+                const Expanded(child: Placeholder()),
+              ],
+            ),
+          ),
+        ),
+      );
+
+      listenForFocusChanges();
+
+      // Have to open a menu initially to start things going.
+      await tester.tap(find.text(TestMenu.mainMenu0.label));
+      await tester.pumpAndSettle();
+
+      expect(focusedMenu, equals('SubmenuButton(Text("Menu 0"))'));
+      await tester.sendKeyEvent(LogicalKeyboardKey.tab);
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Menu 1"))'));
+      await tester.sendKeyEvent(LogicalKeyboardKey.tab);
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Menu 2"))'));
+      await tester.sendKeyEvent(LogicalKeyboardKey.tab);
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Menu 0"))'));
+
+      await tester.sendKeyDownEvent(LogicalKeyboardKey.shiftLeft);
+      await tester.sendKeyEvent(LogicalKeyboardKey.tab);
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Menu 2"))'));
+      await tester.sendKeyEvent(LogicalKeyboardKey.tab);
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Menu 1"))'));
+      await tester.sendKeyEvent(LogicalKeyboardKey.tab);
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Menu 0"))'));
+      await tester.sendKeyUpEvent(LogicalKeyboardKey.shiftLeft);
+      opened.clear();
+      closed.clear();
+
+      // Test closing a menu with enter.
+      await tester.sendKeyEvent(LogicalKeyboardKey.enter);
+      await tester.pump();
+      expect(opened, isEmpty);
+      expect(closed, <TestMenu>[TestMenu.mainMenu0]);
+    });
+
+    testWidgets('keyboard directional traversal works', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: MenuBar(
+              controller: controller,
+              children: createTestMenus(
+                onPressed: onPressed,
+                onOpen: onOpen,
+                onClose: onClose,
+              ),
+            ),
+          ),
+        ),
+      );
+
+      listenForFocusChanges();
+
+      // Have to open a menu initially to start things going.
+      await tester.tap(find.text(TestMenu.mainMenu0.label));
+      await tester.pumpAndSettle();
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Menu 1"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Menu 10"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+      expect(focusedMenu, equals('SubmenuButton(Text("Sub Menu 11"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Menu 12"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Menu 12"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Sub Menu 11"))'));
+
+      // Open the next submenu
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
+      await tester.pump();
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Sub Menu 110"))'));
+
+      // Go back, close the submenu.
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Sub Menu 11"))'));
+
+      // Move up, should close the submenu.
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
+      await tester.pump();
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Menu 10"))'));
+
+      // Move down, should reopen the submenu.
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Sub Menu 11"))'));
+
+      // Open the next submenu again.
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
+      await tester.pump();
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Sub Menu 110"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Sub Menu 111"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Sub Menu 112"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Sub Menu 113"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Sub Menu 113"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Menu 2"))'));
+    });
+
+    testWidgets('keyboard directional traversal works in RTL mode', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Directionality(
+            textDirection: TextDirection.rtl,
+            child: Material(
+              child: MenuBar(
+                controller: controller,
+                children: createTestMenus(
+                  onPressed: onPressed,
+                  onOpen: onOpen,
+                  onClose: onClose,
+                ),
+              ),
+            ),
+          ),
+        ),
+      );
+
+      listenForFocusChanges();
+
+      // Have to open a menu initially to start things going.
+      await tester.tap(find.text(TestMenu.mainMenu0.label));
+      await tester.pump();
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
+      expect(focusedMenu, equals('SubmenuButton(Text("Menu 1"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Menu 1"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Menu 10"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+      expect(focusedMenu, equals('SubmenuButton(Text("Sub Menu 11"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Menu 12"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Menu 12"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Sub Menu 11"))'));
+
+      // Open the next submenu
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
+      await tester.pump();
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Sub Menu 110"))'));
+
+      // Go back, close the submenu.
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Sub Menu 11"))'));
+
+      // Move up, should close the submenu.
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
+      await tester.pump();
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Menu 10"))'));
+
+      // Move down, should reopen the submenu.
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Sub Menu 11"))'));
+
+      // Open the next submenu again.
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
+      await tester.pump();
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Sub Menu 110"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Sub Menu 111"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Sub Menu 112"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Sub Menu 113"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Sub Menu 113"))'));
+
+      await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Menu 2"))'));
+    });
+
+    testWidgets('hover traversal works', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: MenuBar(
+              controller: controller,
+              children: createTestMenus(
+                onPressed: onPressed,
+                onOpen: onOpen,
+                onClose: onClose,
+              ),
+            ),
+          ),
+        ),
+      );
+
+      listenForFocusChanges();
+
+      // Hovering when the menu is not yet open does nothing.
+      await hoverOver(tester, find.text(TestMenu.mainMenu0.label));
+      await tester.pump();
+      expect(focusedMenu, isNull);
+
+      // Have to open a menu initially to start things going.
+      await tester.tap(find.text(TestMenu.mainMenu0.label));
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Menu 0"))'));
+
+      // Hovering when the menu is already  open does nothing.
+      await hoverOver(tester, find.text(TestMenu.mainMenu0.label));
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Menu 0"))'));
+
+      // Hovering over the other main menu items opens them now.
+      await hoverOver(tester, find.text(TestMenu.mainMenu2.label));
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Menu 2"))'));
+
+      await hoverOver(tester, find.text(TestMenu.mainMenu1.label));
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Menu 1"))'));
+
+      // Hovering over the menu items focuses them.
+      await hoverOver(tester, find.text(TestMenu.subMenu10.label));
+      await tester.pump();
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Menu 10"))'));
+
+      await hoverOver(tester, find.text(TestMenu.subMenu11.label));
+      await tester.pump();
+      expect(focusedMenu, equals('SubmenuButton(Text("Sub Menu 11"))'));
+
+      await hoverOver(tester, find.text(TestMenu.subSubMenu110.label));
+      await tester.pump();
+      expect(focusedMenu, equals('MenuItemButton(Text("Sub Sub Menu 110"))'));
+    });
+
+    testWidgets('menus close on ancestor scroll', (WidgetTester tester) async {
+      final ScrollController scrollController = ScrollController();
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: SingleChildScrollView(
+              controller: scrollController,
+              child: Container(
+                height: 1000,
+                alignment: Alignment.center,
+                child: MenuBar(
+                  controller: controller,
+                  children: createTestMenus(
+                    onPressed: onPressed,
+                    onOpen: onOpen,
+                    onClose: onClose,
+                  ),
+                ),
+              ),
+            ),
+          ),
+        ),
+      );
+
+      await tester.tap(find.text(TestMenu.mainMenu0.label));
+      await tester.pump();
+
+      expect(opened, isNotEmpty);
+      expect(closed, isEmpty);
+      opened.clear();
+
+      scrollController.jumpTo(1000);
+      await tester.pump();
+
+      expect(opened, isEmpty);
+      expect(closed, isNotEmpty);
+    });
+
+    testWidgets('menus close on view size change', (WidgetTester tester) async {
+      final ScrollController scrollController = ScrollController();
+      final MediaQueryData mediaQueryData = MediaQueryData.fromWindow(tester.binding.window);
+
+      Widget build(Size size) {
+        return MaterialApp(
+          home: Material(
+            child: MediaQuery(
+              data: mediaQueryData.copyWith(size: size),
+              child: SingleChildScrollView(
+                controller: scrollController,
+                child: Container(
+                  height: 1000,
+                  alignment: Alignment.center,
+                  child: MenuBar(
+                    controller: controller,
+                    children: createTestMenus(
+                      onPressed: onPressed,
+                      onOpen: onOpen,
+                      onClose: onClose,
+                    ),
+                  ),
+                ),
+              ),
+            ),
+          ),
+        );
+      }
+
+      await tester.pumpWidget(build(mediaQueryData.size));
+
+      await tester.tap(find.text(TestMenu.mainMenu0.label));
+      await tester.pump();
+
+      expect(opened, isNotEmpty);
+      expect(closed, isEmpty);
+      opened.clear();
+
+      const Size smallSize = Size(200, 200);
+      await tester.binding.setSurfaceSize(smallSize);
+
+      await tester.pumpWidget(build(smallSize));
+      await tester.pump();
+
+      expect(opened, isEmpty);
+      expect(closed, isNotEmpty);
+
+      // Reset binding when done.
+      await tester.binding.setSurfaceSize(mediaQueryData.size);
+    });
+  });
+
+  group('MenuController', () {
+    testWidgets('Moving a controller to a new instance works', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: MenuBar(
+              key: UniqueKey(),
+              controller: controller,
+              children: createTestMenus(),
+            ),
+          ),
+        ),
+      );
+
+      // Open a menu initially.
+      await tester.tap(find.text(TestMenu.mainMenu1.label));
+      await tester.pump();
+
+      await tester.tap(find.text(TestMenu.subMenu11.label));
+      await tester.pump();
+
+      // Now pump a new menu with a different UniqueKey to dispose of the opened
+      // menu's node, but keep the existing controller.
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: MenuBar(
+              key: UniqueKey(),
+              controller: controller,
+              children: createTestMenus(
+                includeExtraGroups: true,
+              ),
+            ),
+          ),
+        ),
+      );
+      await tester.pumpAndSettle();
+    });
+
+    testWidgets('closing via controller works', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: MenuBar(
+              controller: controller,
+              children: createTestMenus(
+                onPressed: onPressed,
+                onOpen: onOpen,
+                onClose: onClose,
+                shortcuts: <TestMenu, MenuSerializableShortcut>{
+                  TestMenu.subSubMenu110: const SingleActivator(
+                    LogicalKeyboardKey.keyA,
+                    control: true,
+                  )
+                },
+              ),
+            ),
+          ),
+        ),
+      );
+
+      // Open a menu initially.
+      await tester.tap(find.text(TestMenu.mainMenu1.label));
+      await tester.pump();
+
+      await tester.tap(find.text(TestMenu.subMenu11.label));
+      await tester.pump();
+      expect(opened, unorderedEquals(<TestMenu>[TestMenu.mainMenu1, TestMenu.subMenu11]));
+      opened.clear();
+      closed.clear();
+
+      // Close menus using the controller
+      controller.close();
+      await tester.pump();
+
+      // The menu should go away,
+      expect(closed, unorderedEquals(<TestMenu>[TestMenu.mainMenu1, TestMenu.subMenu11]));
+      expect(opened, isEmpty);
+    });
+  });
+
+  group('MenuItemButton', () {
+    testWidgets('Shortcut mnemonics are displayed', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: MenuBar(
+              controller: controller,
+              children: createTestMenus(
+                shortcuts: <TestMenu, MenuSerializableShortcut>{
+                  TestMenu.subSubMenu110: const SingleActivator(LogicalKeyboardKey.keyA, control: true),
+                  TestMenu.subSubMenu111: const SingleActivator(LogicalKeyboardKey.keyB, shift: true),
+                  TestMenu.subSubMenu112: const SingleActivator(LogicalKeyboardKey.keyC, alt: true),
+                  TestMenu.subSubMenu113: const SingleActivator(LogicalKeyboardKey.keyD, meta: true),
+                },
+              ),
+            ),
+          ),
+        ),
+      );
+
+      // Open a menu initially.
+      await tester.tap(find.text(TestMenu.mainMenu1.label));
+      await tester.pump();
+
+      await tester.tap(find.text(TestMenu.subMenu11.label));
+      await tester.pump();
+
+      Text mnemonic0;
+      Text mnemonic1;
+      Text mnemonic2;
+      Text mnemonic3;
+
+      switch (defaultTargetPlatform) {
+        case TargetPlatform.android:
+        case TargetPlatform.fuchsia:
+        case TargetPlatform.linux:
+          mnemonic0 = tester.widget(findMnemonic(TestMenu.subSubMenu110.label));
+          expect(mnemonic0.data, equals('Ctrl A'));
+          mnemonic1 = tester.widget(findMnemonic(TestMenu.subSubMenu111.label));
+          expect(mnemonic1.data, equals('⇧ B'));
+          mnemonic2 = tester.widget(findMnemonic(TestMenu.subSubMenu112.label));
+          expect(mnemonic2.data, equals('Alt C'));
+          mnemonic3 = tester.widget(findMnemonic(TestMenu.subSubMenu113.label));
+          expect(mnemonic3.data, equals('Meta D'));
+          break;
+        case TargetPlatform.windows:
+          mnemonic0 = tester.widget(findMnemonic(TestMenu.subSubMenu110.label));
+          expect(mnemonic0.data, equals('Ctrl A'));
+          mnemonic1 = tester.widget(findMnemonic(TestMenu.subSubMenu111.label));
+          expect(mnemonic1.data, equals('⇧ B'));
+          mnemonic2 = tester.widget(findMnemonic(TestMenu.subSubMenu112.label));
+          expect(mnemonic2.data, equals('Alt C'));
+          mnemonic3 = tester.widget(findMnemonic(TestMenu.subSubMenu113.label));
+          expect(mnemonic3.data, equals('Win D'));
+          break;
+        case TargetPlatform.iOS:
+        case TargetPlatform.macOS:
+          mnemonic0 = tester.widget(findMnemonic(TestMenu.subSubMenu110.label));
+          expect(mnemonic0.data, equals('⌃ A'));
+          mnemonic1 = tester.widget(findMnemonic(TestMenu.subSubMenu111.label));
+          expect(mnemonic1.data, equals('⇧ B'));
+          mnemonic2 = tester.widget(findMnemonic(TestMenu.subSubMenu112.label));
+          expect(mnemonic2.data, equals('⌥ C'));
+          mnemonic3 = tester.widget(findMnemonic(TestMenu.subSubMenu113.label));
+          expect(mnemonic3.data, equals('⌘ D'));
+          break;
+      }
+
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: MenuBar(
+              controller: controller,
+              children: createTestMenus(
+                includeExtraGroups: true,
+                shortcuts: <TestMenu, MenuSerializableShortcut>{
+                  TestMenu.subSubMenu110: const SingleActivator(LogicalKeyboardKey.arrowRight),
+                  TestMenu.subSubMenu111: const SingleActivator(LogicalKeyboardKey.arrowLeft),
+                  TestMenu.subSubMenu112: const SingleActivator(LogicalKeyboardKey.arrowUp),
+                  TestMenu.subSubMenu113: const SingleActivator(LogicalKeyboardKey.arrowDown),
+                },
+              ),
+            ),
+          ),
+        ),
+      );
+      await tester.pumpAndSettle();
+
+      mnemonic0 = tester.widget(findMnemonic(TestMenu.subSubMenu110.label));
+      expect(mnemonic0.data, equals('→'));
+      mnemonic1 = tester.widget(findMnemonic(TestMenu.subSubMenu111.label));
+      expect(mnemonic1.data, equals('←'));
+      mnemonic2 = tester.widget(findMnemonic(TestMenu.subSubMenu112.label));
+      expect(mnemonic2.data, equals('↑'));
+      mnemonic3 = tester.widget(findMnemonic(TestMenu.subSubMenu113.label));
+      expect(mnemonic3.data, equals('↓'));
+
+      // Try some weirder ones.
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: MenuBar(
+              controller: controller,
+              children: createTestMenus(
+                shortcuts: <TestMenu, MenuSerializableShortcut>{
+                  TestMenu.subSubMenu110: const SingleActivator(LogicalKeyboardKey.escape),
+                  TestMenu.subSubMenu111: const SingleActivator(LogicalKeyboardKey.fn),
+                  TestMenu.subSubMenu112: const SingleActivator(LogicalKeyboardKey.enter),
+                },
+              ),
+            ),
+          ),
+        ),
+      );
+      await tester.pumpAndSettle();
+
+      mnemonic0 = tester.widget(findMnemonic(TestMenu.subSubMenu110.label));
+      expect(mnemonic0.data, equals('Esc'));
+      mnemonic1 = tester.widget(findMnemonic(TestMenu.subSubMenu111.label));
+      expect(mnemonic1.data, equals('Fn'));
+      mnemonic2 = tester.widget(findMnemonic(TestMenu.subSubMenu112.label));
+      expect(mnemonic2.data, equals('↵'));
+    }, variant: TargetPlatformVariant.all());
+
+    testWidgets('leadingIcon is used when set', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: MenuBar(
+              controller: controller,
+              children: <Widget>[
+                SubmenuButton(
+                  menuChildren: <Widget>[
+                    MenuItemButton(
+                      leadingIcon: const Text('leadingIcon'),
+                      child: Text(TestMenu.subMenu00.label),
+                    ),
+                  ],
+                  child: Text(TestMenu.mainMenu0.label),
+                ),
+              ],
+            ),
+          ),
+        ),
+      );
+
+      await tester.tap(find.text(TestMenu.mainMenu0.label));
+      await tester.pump();
+
+      expect(find.text('leadingIcon'), findsOneWidget);
+    });
+
+    testWidgets('trailingIcon is used when set', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: MenuBar(
+              controller: controller,
+              children: <Widget>[
+                SubmenuButton(
+                  menuChildren: <Widget>[
+                    MenuItemButton(
+                      trailingIcon: const Text('trailingIcon'),
+                      child: Text(TestMenu.subMenu00.label),
+                    ),
+                  ],
+                  child: Text(TestMenu.mainMenu0.label),
+                ),
+              ],
+            ),
+          ),
+        ),
+      );
+
+      await tester.tap(find.text(TestMenu.mainMenu0.label));
+      await tester.pump();
+
+      expect(find.text('trailingIcon'), findsOneWidget);
+    });
+
+    testWidgets('diagnostics', (WidgetTester tester) async {
+      final ButtonStyle style = ButtonStyle(
+        shape: MaterialStateProperty.all<OutlinedBorder?>(const StadiumBorder()),
+        elevation: MaterialStateProperty.all<double?>(10.0),
+        backgroundColor: const MaterialStatePropertyAll<Color>(Colors.red),
+      );
+      final MenuStyle menuStyle = MenuStyle(
+        shape: MaterialStateProperty.all<OutlinedBorder?>(const RoundedRectangleBorder()),
+        elevation: MaterialStateProperty.all<double?>(20.0),
+        backgroundColor: const MaterialStatePropertyAll<Color>(Colors.green),
+      );
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: MenuBar(
+              controller: controller,
+              children: <Widget>[
+                SubmenuButton(
+                  style: style,
+                  menuStyle: menuStyle,
+                  menuChildren: <Widget>[
+                    MenuItemButton(
+                      style: style,
+                      child: Text(TestMenu.subMenu00.label),
+                    ),
+                  ],
+                  child: Text(TestMenu.mainMenu0.label),
+                ),
+              ],
+            ),
+          ),
+        ),
+      );
+
+      await tester.tap(find.text(TestMenu.mainMenu0.label));
+      await tester.pump();
+
+      final SubmenuButton submenu = tester.widget(find.byType(SubmenuButton));
+      final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
+      submenu.debugFillProperties(builder);
+
+      final List<String> description = builder.properties
+          .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
+          .map((DiagnosticsNode node) => node.toString())
+          .toList();
+
+      expect(
+        description,
+        equalsIgnoringHashCodes(
+          <String>[
+            'child: Text("Menu 0")',
+            'focusNode: null',
+            'menuStyle: MenuStyle#00000(backgroundColor: MaterialStatePropertyAll(MaterialColor(primary value: Color(0xff4caf50))), elevation: MaterialStatePropertyAll(20.0), shape: MaterialStatePropertyAll(RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.zero)))',
+            'alignmentOffset: null',
+            'clipBehavior: none',
+          ],
+        ),
+      );
+    });
+  });
+
+  group('Layout', () {
+    List<Rect> collectMenuRects() {
+      final List<Rect> menuRects = <Rect>[];
+      final List<Element> candidates = find.byType(SubmenuButton).evaluate().toList();
+      for (final Element candidate in candidates) {
+        final RenderBox box = candidate.renderObject! as RenderBox;
+        final Offset topLeft = box.localToGlobal(box.size.topLeft(Offset.zero));
+        final Offset bottomRight = box.localToGlobal(box.size.bottomRight(Offset.zero));
+        menuRects.add(Rect.fromPoints(topLeft, bottomRight));
+      }
+      return menuRects;
+    }
+
+    testWidgets('unconstrained menus show up in the right place in LTR', (WidgetTester tester) async {
+      await tester.binding.setSurfaceSize(const Size(800, 600));
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: Column(
+              children: <Widget>[
+                Row(
+                  children: <Widget>[
+                    Expanded(
+                      child: MenuBar(
+                        children: createTestMenus(onPressed: onPressed),
+                      ),
+                    ),
+                  ],
+                ),
+                const Expanded(child: Placeholder()),
+              ],
+            ),
+          ),
+        ),
+      );
+      await tester.pump();
+
+      await tester.tap(find.text(TestMenu.mainMenu1.label));
+      await tester.pump();
+      await tester.tap(find.text(TestMenu.subMenu11.label));
+      await tester.pump();
+
+      expect(find.byType(MenuItemButton), findsNWidgets(6));
+      expect(find.byType(SubmenuButton), findsNWidgets(4));
+      final List<Rect> menuRects = collectMenuRects();
+      expect(menuRects[0], equals(const Rect.fromLTRB(4.0, 0.0, 104.0, 48.0)));
+      expect(menuRects[1], equals(const Rect.fromLTRB(104.0, 0.0, 204.0, 48.0)));
+      expect(menuRects[2], equals(const Rect.fromLTRB(204.0, 0.0, 304.0, 48.0)));
+      expect(menuRects[3], equals(const Rect.fromLTRB(104.0, 100.0, 334.0, 148.0)));
+    });
+
+    testWidgets('unconstrained menus show up in the right place in RTL', (WidgetTester tester) async {
+      await tester.binding.setSurfaceSize(const Size(800, 600));
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Directionality(
+            textDirection: TextDirection.rtl,
+            child: Material(
+              child: Column(
+                children: <Widget>[
+                  Row(
+                    children: <Widget>[
+                      Expanded(
+                        child: MenuBar(
+                          children: createTestMenus(onPressed: onPressed),
+                        ),
+                      ),
+                    ],
+                  ),
+                  const Expanded(child: Placeholder()),
+                ],
+              ),
+            ),
+          ),
+        ),
+      );
+      await tester.pump();
+
+      await tester.tap(find.text(TestMenu.mainMenu1.label));
+      await tester.pump();
+      await tester.tap(find.text(TestMenu.subMenu11.label));
+      await tester.pump();
+
+      expect(find.byType(MenuItemButton), findsNWidgets(6));
+      expect(find.byType(SubmenuButton), findsNWidgets(4));
+      final List<Rect> menuRects = collectMenuRects();
+      expect(menuRects[0], equals(const Rect.fromLTRB(696.0, 0.0, 796.0, 48.0)));
+      expect(menuRects[1], equals(const Rect.fromLTRB(596.0, 0.0, 696.0, 48.0)));
+      expect(menuRects[2], equals(const Rect.fromLTRB(496.0, 0.0, 596.0, 48.0)));
+      expect(menuRects[3], equals(const Rect.fromLTRB(466.0, 100.0, 696.0, 148.0)));
+    });
+
+    testWidgets('constrained menus show up in the right place in LTR', (WidgetTester tester) async {
+      await tester.binding.setSurfaceSize(const Size(300, 300));
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Builder(
+            builder: (BuildContext context) {
+              return Directionality(
+                textDirection: TextDirection.ltr,
+                child: Material(
+                  child: Column(
+                    children: <Widget>[
+                      MenuBar(
+                        children: createTestMenus(onPressed: onPressed),
+                      ),
+                      const Expanded(child: Placeholder()),
+                    ],
+                  ),
+                ),
+              );
+            },
+          ),
+        ),
+      );
+      await tester.pump();
+
+      await tester.tap(find.text(TestMenu.mainMenu1.label));
+      await tester.pump();
+      await tester.tap(find.text(TestMenu.subMenu11.label));
+      await tester.pump();
+
+      expect(find.byType(MenuItemButton), findsNWidgets(6));
+      expect(find.byType(SubmenuButton), findsNWidgets(4));
+      final List<Rect> menuRects = collectMenuRects();
+      expect(menuRects[0], equals(const Rect.fromLTRB(4.0, 0.0, 104.0, 48.0)));
+      expect(menuRects[1], equals(const Rect.fromLTRB(104.0, 0.0, 204.0, 48.0)));
+      expect(menuRects[2], equals(const Rect.fromLTRB(204.0, 0.0, 304.0, 48.0)));
+      expect(menuRects[3], equals(const Rect.fromLTRB(70.0, 100.0, 300.0, 148.0)));
+    });
+
+    testWidgets('constrained menus show up in the right place in RTL', (WidgetTester tester) async {
+      await tester.binding.setSurfaceSize(const Size(300, 300));
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Builder(
+            builder: (BuildContext context) {
+              return Directionality(
+                textDirection: TextDirection.rtl,
+                child: Material(
+                  child: Column(
+                    children: <Widget>[
+                      MenuBar(
+                        children: createTestMenus(onPressed: onPressed),
+                      ),
+                      const Expanded(child: Placeholder()),
+                    ],
+                  ),
+                ),
+              );
+            },
+          ),
+        ),
+      );
+      await tester.pump();
+
+      await tester.tap(find.text(TestMenu.mainMenu1.label));
+      await tester.pump();
+      await tester.tap(find.text(TestMenu.subMenu11.label));
+      await tester.pump();
+
+      expect(find.byType(MenuItemButton), findsNWidgets(6));
+      expect(find.byType(SubmenuButton), findsNWidgets(4));
+      final List<Rect> menuRects = collectMenuRects();
+      expect(menuRects[0], equals(const Rect.fromLTRB(196.0, 0.0, 296.0, 48.0)));
+      expect(menuRects[1], equals(const Rect.fromLTRB(96.0, 0.0, 196.0, 48.0)));
+      expect(menuRects[2], equals(const Rect.fromLTRB(-4.0, 0.0, 96.0, 48.0)));
+      expect(menuRects[3], equals(const Rect.fromLTRB(0.0, 100.0, 230.0, 148.0)));
+    });
+  });
+
+  group('LocalizedShortcutLabeler', () {
+    testWidgets('getShortcutLabel returns the right labels', (WidgetTester tester) async {
+      String expectedMeta;
+      String expectedCtrl;
+      String expectedAlt;
+      switch (defaultTargetPlatform) {
+        case TargetPlatform.android:
+        case TargetPlatform.fuchsia:
+        case TargetPlatform.linux:
+          expectedCtrl = 'Ctrl';
+          expectedMeta = 'Meta';
+          expectedAlt = 'Alt';
+          break;
+        case TargetPlatform.windows:
+          expectedCtrl = 'Ctrl';
+          expectedMeta = 'Win';
+          expectedAlt = 'Alt';
+          break;
+        case TargetPlatform.iOS:
+        case TargetPlatform.macOS:
+          expectedCtrl = '⌃';
+          expectedMeta = '⌘';
+          expectedAlt = '⌥';
+          break;
+      }
+
+      const SingleActivator allModifiers = SingleActivator(
+        LogicalKeyboardKey.keyA,
+        control: true,
+        meta: true,
+        shift: true,
+        alt: true,
+      );
+      final String allExpected = '$expectedAlt $expectedCtrl $expectedMeta ⇧ A';
+      const CharacterActivator charShortcuts = CharacterActivator('ñ');
+      const String charExpected = 'ñ';
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: MenuBar(
+              controller: controller,
+              children: <Widget>[
+                SubmenuButton(
+                  menuChildren: <Widget>[
+                    MenuItemButton(
+                      shortcut: allModifiers,
+                      child: Text(TestMenu.subMenu10.label),
+                    ),
+                    MenuItemButton(
+                      shortcut: charShortcuts,
+                      child: Text(TestMenu.subMenu11.label),
+                    ),
+                  ],
+                  child: Text(TestMenu.mainMenu0.label),
+                ),
+              ],
+            ),
+          ),
+        ),
+      );
+      await tester.tap(find.text(TestMenu.mainMenu0.label));
+      await tester.pump();
+
+      expect(find.text(allExpected), findsOneWidget);
+      expect(find.text(charExpected), findsOneWidget);
+    }, variant: TargetPlatformVariant.all());
+  });
+}
+
+List<Widget> createTestMenus({
+  void Function(TestMenu)? onPressed,
+  void Function(TestMenu)? onOpen,
+  void Function(TestMenu)? onClose,
+  Map<TestMenu, MenuSerializableShortcut> shortcuts = const <TestMenu, MenuSerializableShortcut>{},
+  bool includeStandard = false,
+  bool includeExtraGroups = false,
+}) {
+  final List<Widget> result = <Widget>[
+    SubmenuButton(
+      onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu0) : null,
+      onClose: onClose != null ? () => onClose(TestMenu.mainMenu0) : null,
+      menuChildren: <Widget>[
+        MenuItemButton(
+          onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu00) : null,
+          shortcut: shortcuts[TestMenu.subMenu00],
+          child: Text(TestMenu.subMenu00.label),
+        ),
+        MenuItemButton(
+          onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu01) : null,
+          shortcut: shortcuts[TestMenu.subMenu01],
+          child: Text(TestMenu.subMenu01.label),
+        ),
+        MenuItemButton(
+          onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu02) : null,
+          shortcut: shortcuts[TestMenu.subMenu02],
+          child: Text(TestMenu.subMenu02.label),
+        ),
+      ],
+      child: Text(TestMenu.mainMenu0.label),
+    ),
+    SubmenuButton(
+      onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu1) : null,
+      onClose: onClose != null ? () => onClose(TestMenu.mainMenu1) : null,
+      menuChildren: <Widget>[
+        MenuItemButton(
+          onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu10) : null,
+          shortcut: shortcuts[TestMenu.subMenu10],
+          child: Text(TestMenu.subMenu10.label),
+        ),
+        SubmenuButton(
+          onOpen: onOpen != null ? () => onOpen(TestMenu.subMenu11) : null,
+          onClose: onClose != null ? () => onClose(TestMenu.subMenu11) : null,
+          menuChildren: <Widget>[
+            MenuItemButton(
+              key: UniqueKey(),
+              onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu110) : null,
+              shortcut: shortcuts[TestMenu.subSubMenu110],
+              child: Text(TestMenu.subSubMenu110.label),
+            ),
+            MenuItemButton(
+              onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu111) : null,
+              shortcut: shortcuts[TestMenu.subSubMenu111],
+              child: Text(TestMenu.subSubMenu111.label),
+            ),
+            MenuItemButton(
+              onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu112) : null,
+              shortcut: shortcuts[TestMenu.subSubMenu112],
+              child: Text(TestMenu.subSubMenu112.label),
+            ),
+            MenuItemButton(
+              onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu113) : null,
+              shortcut: shortcuts[TestMenu.subSubMenu113],
+              child: Text(TestMenu.subSubMenu113.label),
+            ),
+          ],
+          child: Text(TestMenu.subMenu11.label),
+        ),
+        MenuItemButton(
+          onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu12) : null,
+          shortcut: shortcuts[TestMenu.subMenu12],
+          child: Text(TestMenu.subMenu12.label),
+        ),
+      ],
+      child: Text(TestMenu.mainMenu1.label),
+    ),
+    SubmenuButton(
+      onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu2) : null,
+      onClose: onClose != null ? () => onClose(TestMenu.mainMenu2) : null,
+      menuChildren: <Widget>[
+        MenuItemButton(
+          // Always disabled.
+          shortcut: shortcuts[TestMenu.subMenu20],
+          child: Text(TestMenu.subMenu20.label),
+        ),
+      ],
+      child: Text(TestMenu.mainMenu2.label),
+    ),
+    if (includeExtraGroups)
+      SubmenuButton(
+        onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu3) : null,
+        onClose: onClose != null ? () => onClose(TestMenu.mainMenu3) : null,
+        menuChildren: <Widget>[
+          MenuItemButton(
+            // Always disabled.
+            shortcut: shortcuts[TestMenu.subMenu30],
+            // Always disabled.
+            child: Text(TestMenu.subMenu30.label),
+          ),
+        ],
+        child: Text(TestMenu.mainMenu3.label),
+      ),
+    if (includeExtraGroups)
+      SubmenuButton(
+        onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu4) : null,
+        onClose: onClose != null ? () => onClose(TestMenu.mainMenu4) : null,
+        menuChildren: <Widget>[
+          MenuItemButton(
+            // Always disabled.
+            shortcut: shortcuts[TestMenu.subMenu40],
+            // Always disabled.
+            child: Text(TestMenu.subMenu40.label),
+          ),
+          MenuItemButton(
+            // Always disabled.
+            shortcut: shortcuts[TestMenu.subMenu41],
+            // Always disabled.
+            child: Text(TestMenu.subMenu41.label),
+          ),
+          MenuItemButton(
+            // Always disabled.
+            shortcut: shortcuts[TestMenu.subMenu42],
+            // Always disabled.
+            child: Text(TestMenu.subMenu42.label),
+          ),
+        ],
+        child: Text(TestMenu.mainMenu4.label),
+      ),
+  ];
+  return result;
+}
+
+enum TestMenu {
+  mainMenu0('Menu 0'),
+  mainMenu1('Menu 1'),
+  mainMenu2('Menu 2'),
+  mainMenu3('Menu 3'),
+  mainMenu4('Menu 4'),
+  subMenu00('Sub Menu 00'),
+  subMenu01('Sub Menu 01'),
+  subMenu02('Sub Menu 02'),
+  subMenu10('Sub Menu 10'),
+  subMenu11('Sub Menu 11'),
+  subMenu12('Sub Menu 12'),
+  subMenu20('Sub Menu 20'),
+  subMenu30('Sub Menu 30'),
+  subMenu40('Sub Menu 40'),
+  subMenu41('Sub Menu 41'),
+  subMenu42('Sub Menu 42'),
+  subSubMenu110('Sub Sub Menu 110'),
+  subSubMenu111('Sub Sub Menu 111'),
+  subSubMenu112('Sub Sub Menu 112'),
+  subSubMenu113('Sub Sub Menu 113');
+
+  const TestMenu(this.label);
+  final String label;
+}
diff --git a/packages/flutter/test/material/menu_bar_theme_test.dart b/packages/flutter/test/material/menu_bar_theme_test.dart
new file mode 100644
index 0000000..b705d10
--- /dev/null
+++ b/packages/flutter/test/material/menu_bar_theme_test.dart
@@ -0,0 +1,315 @@
+// 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 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+  void onPressed(TestMenu item) {}
+
+  Finder findMenuPanels(Axis orientation) {
+    return find.byWidgetPredicate((Widget widget) {
+      // ignore: avoid_dynamic_calls
+      return widget.runtimeType.toString() == '_MenuPanel' && (widget as dynamic).orientation == orientation;
+    });
+  }
+
+  Finder findMenuBarPanel() {
+    return findMenuPanels(Axis.horizontal);
+  }
+
+  Finder findSubmenuPanel() {
+    return findMenuPanels(Axis.vertical);
+  }
+
+  Finder findSubMenuItem() {
+    return find.descendant(of: findSubmenuPanel().last, matching: find.byType(MenuItemButton));
+  }
+
+  Material getMenuBarPanelMaterial(WidgetTester tester) {
+    return tester.widget<Material>(find.descendant(of: findMenuBarPanel(), matching: find.byType(Material)).first);
+  }
+
+  Material getSubmenuPanelMaterial(WidgetTester tester) {
+    return tester.widget<Material>(find.descendant(of: findSubmenuPanel(), matching: find.byType(Material)).first);
+  }
+
+  DefaultTextStyle getLabelStyle(WidgetTester tester, String labelText) {
+    return tester.widget<DefaultTextStyle>(
+      find
+          .ancestor(
+            of: find.text(labelText),
+            matching: find.byType(DefaultTextStyle),
+          )
+          .first,
+    );
+  }
+
+  testWidgets('theme is honored', (WidgetTester tester) async {
+    await tester.pumpWidget(
+      MaterialApp(
+        home: Material(
+          child: Builder(builder: (BuildContext context) {
+            return MenuTheme(
+              data: const MenuThemeData(
+                style: MenuStyle(
+                  backgroundColor: MaterialStatePropertyAll<Color?>(Colors.green),
+                  elevation: MaterialStatePropertyAll<double?>(20.0),
+                ),
+              ),
+              child: MenuBarTheme(
+                data: const MenuBarThemeData(
+                  style: MenuStyle(
+                    backgroundColor: MaterialStatePropertyAll<Color?>(Colors.red),
+                    elevation: MaterialStatePropertyAll<double?>(15.0),
+                    shape: MaterialStatePropertyAll<OutlinedBorder?>(StadiumBorder()),
+                    padding: MaterialStatePropertyAll<EdgeInsetsGeometry>(
+                      EdgeInsetsDirectional.all(10.0),
+                    ),
+                  ),
+                ),
+                child: Column(
+                  children: <Widget>[
+                    MenuBar(
+                      children: createTestMenus(onPressed: onPressed),
+                    ),
+                    const Expanded(child: Placeholder()),
+                  ],
+                ),
+              ),
+            );
+          }),
+        ),
+      ),
+    );
+
+    // Open a test menu.
+    await tester.tap(find.text(TestMenu.mainMenu1.label));
+    await tester.pump();
+    expect(tester.getRect(findMenuBarPanel().first), equals(const Rect.fromLTRB(240.0, 0.0, 560.0, 68.0)));
+    final Material menuBarMaterial = getMenuBarPanelMaterial(tester);
+    expect(menuBarMaterial.elevation, equals(15));
+    expect(menuBarMaterial.color, equals(Colors.red));
+
+    final Material subMenuMaterial = getSubmenuPanelMaterial(tester);
+    expect(tester.getRect(findSubmenuPanel()), equals(const Rect.fromLTRB(350.0, 58.0, 580.0, 210.0)));
+    expect(subMenuMaterial.elevation, equals(20));
+    expect(subMenuMaterial.color, equals(Colors.green));
+  });
+
+  testWidgets('Constructor parameters override theme parameters', (WidgetTester tester) async {
+    await tester.pumpWidget(
+      MaterialApp(
+        home: Material(
+          child: Builder(
+            builder: (BuildContext context) {
+              return MenuTheme(
+                data: const MenuThemeData(
+                  style: MenuStyle(
+                    backgroundColor: MaterialStatePropertyAll<Color?>(Colors.green),
+                    elevation: MaterialStatePropertyAll<double?>(20.0),
+                  ),
+                ),
+                child: MenuBarTheme(
+                  data: const MenuBarThemeData(
+                    style: MenuStyle(
+                      backgroundColor: MaterialStatePropertyAll<Color?>(Colors.red),
+                      elevation: MaterialStatePropertyAll<double?>(15.0),
+                      shape: MaterialStatePropertyAll<OutlinedBorder?>(StadiumBorder()),
+                      padding: MaterialStatePropertyAll<EdgeInsetsGeometry>(
+                        EdgeInsetsDirectional.all(10.0),
+                      ),
+                    ),
+                  ),
+                  child: Column(
+                    children: <Widget>[
+                      MenuBar(
+                        style: const MenuStyle(
+                          backgroundColor: MaterialStatePropertyAll<Color?>(Colors.blue),
+                          elevation: MaterialStatePropertyAll<double?>(10.0),
+                          padding: MaterialStatePropertyAll<EdgeInsetsGeometry>(
+                            EdgeInsetsDirectional.all(12.0),
+                          ),
+                        ),
+                        children: createTestMenus(
+                          onPressed: onPressed,
+                          menuBackground: Colors.cyan,
+                          menuElevation: 18.0,
+                          menuPadding: const EdgeInsetsDirectional.all(14.0),
+                          menuShape: const BeveledRectangleBorder(),
+                          itemBackground: Colors.amber,
+                          itemForeground: Colors.grey,
+                          itemOverlay: Colors.blueGrey,
+                          itemPadding: const EdgeInsetsDirectional.all(11.0),
+                          itemShape: const StadiumBorder(),
+                        ),
+                      ),
+                      const Expanded(child: Placeholder()),
+                    ],
+                  ),
+                ),
+              );
+            },
+          ),
+        ),
+      ),
+    );
+
+    // Open a test menu.
+    await tester.tap(find.text(TestMenu.mainMenu1.label));
+    await tester.pump();
+
+    expect(tester.getRect(findMenuBarPanel().first), equals(const Rect.fromLTRB(238.0, 0.0, 562.0, 72.0)));
+    final Material menuBarMaterial = getMenuBarPanelMaterial(tester);
+    expect(menuBarMaterial.elevation, equals(10.0));
+    expect(menuBarMaterial.color, equals(Colors.blue));
+
+    final Material subMenuMaterial = getSubmenuPanelMaterial(tester);
+    expect(tester.getRect(findSubmenuPanel()), equals(const Rect.fromLTRB(336.0, 60.0, 594.0, 232.0)));
+    expect(subMenuMaterial.elevation, equals(18));
+    expect(subMenuMaterial.color, equals(Colors.cyan));
+    expect(subMenuMaterial.shape, equals(const BeveledRectangleBorder()));
+
+    final Finder menuItem = findSubMenuItem();
+    expect(tester.getRect(menuItem.first), equals(const Rect.fromLTRB(350.0, 74.0, 580.0, 122.0)));
+    final Material menuItemMaterial = tester.widget<Material>(
+        find.ancestor(of: find.text(TestMenu.subMenu10.label), matching: find.byType(Material)).first);
+    expect(menuItemMaterial.color, equals(Colors.amber));
+    expect(menuItemMaterial.elevation, equals(0.0));
+    expect(menuItemMaterial.shape, equals(const StadiumBorder()));
+    expect(getLabelStyle(tester, TestMenu.subMenu10.label).style.color, equals(Colors.grey));
+    final ButtonStyle? textButtonStyle = tester
+        .widget<TextButton>(find
+            .ancestor(
+              of: find.text(TestMenu.subMenu10.label),
+              matching: find.byType(TextButton),
+            )
+            .first)
+        .style;
+    expect(textButtonStyle?.overlayColor?.resolve(<MaterialState>{MaterialState.hovered}), equals(Colors.blueGrey));
+  });
+}
+
+List<Widget> createTestMenus({
+  void Function(TestMenu)? onPressed,
+  void Function(TestMenu)? onOpen,
+  void Function(TestMenu)? onClose,
+  Map<TestMenu, MenuSerializableShortcut> shortcuts = const <TestMenu, MenuSerializableShortcut>{},
+  bool includeStandard = false,
+  Color? itemOverlay,
+  Color? itemBackground,
+  Color? itemForeground,
+  EdgeInsetsDirectional? itemPadding,
+  Color? menuBackground,
+  EdgeInsetsDirectional? menuPadding,
+  OutlinedBorder? menuShape,
+  double? menuElevation,
+  OutlinedBorder? itemShape,
+}) {
+  final MenuStyle menuStyle = MenuStyle(
+    padding: menuPadding != null ? MaterialStatePropertyAll<EdgeInsetsGeometry>(menuPadding) : null,
+    backgroundColor: menuBackground != null ? MaterialStatePropertyAll<Color>(menuBackground) : null,
+    elevation: menuElevation != null ? MaterialStatePropertyAll<double>(menuElevation) : null,
+    shape: menuShape != null ? MaterialStatePropertyAll<OutlinedBorder>(menuShape) : null,
+  );
+  final ButtonStyle itemStyle = ButtonStyle(
+    padding: itemPadding != null ? MaterialStatePropertyAll<EdgeInsetsGeometry>(itemPadding) : null,
+    shape: itemShape != null ? MaterialStatePropertyAll<OutlinedBorder>(itemShape) : null,
+    foregroundColor: itemForeground != null ? MaterialStatePropertyAll<Color>(itemForeground) : null,
+    backgroundColor: itemBackground != null ? MaterialStatePropertyAll<Color>(itemBackground) : null,
+    overlayColor: itemOverlay != null ? MaterialStatePropertyAll<Color>(itemOverlay) : null,
+  );
+  final List<Widget> result = <Widget>[
+    SubmenuButton(
+      onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu0) : null,
+      onClose: onClose != null ? () => onClose(TestMenu.mainMenu0) : null,
+      menuChildren: <Widget>[
+        MenuItemButton(
+          onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu00) : null,
+          shortcut: shortcuts[TestMenu.subMenu00],
+          child: Text(TestMenu.subMenu00.label),
+        ),
+      ],
+      child: Text(TestMenu.mainMenu0.label),
+    ),
+    SubmenuButton(
+      onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu1) : null,
+      onClose: onClose != null ? () => onClose(TestMenu.mainMenu1) : null,
+      menuStyle: menuStyle,
+      menuChildren: <Widget>[
+        MenuItemButton(
+          onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu10) : null,
+          shortcut: shortcuts[TestMenu.subMenu10],
+          style: itemStyle,
+          child: Text(TestMenu.subMenu10.label),
+        ),
+        SubmenuButton(
+          onOpen: onOpen != null ? () => onOpen(TestMenu.subMenu11) : null,
+          onClose: onClose != null ? () => onClose(TestMenu.subMenu11) : null,
+          menuChildren: <Widget>[
+            MenuItemButton(
+              onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu110) : null,
+              shortcut: shortcuts[TestMenu.subSubMenu110],
+              child: Text(TestMenu.subSubMenu110.label),
+            ),
+            MenuItemButton(
+              onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu111) : null,
+              shortcut: shortcuts[TestMenu.subSubMenu111],
+              child: Text(TestMenu.subSubMenu111.label),
+            ),
+            MenuItemButton(
+              onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu112) : null,
+              shortcut: shortcuts[TestMenu.subSubMenu112],
+              child: Text(TestMenu.subSubMenu112.label),
+            ),
+            MenuItemButton(
+              onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu113) : null,
+              shortcut: shortcuts[TestMenu.subSubMenu113],
+              child: Text(TestMenu.subSubMenu113.label),
+            ),
+          ],
+          child: Text(TestMenu.subMenu11.label),
+        ),
+        MenuItemButton(
+          onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu12) : null,
+          shortcut: shortcuts[TestMenu.subMenu12],
+          child: Text(TestMenu.subMenu12.label),
+        ),
+      ],
+      child: Text(TestMenu.mainMenu1.label),
+    ),
+    SubmenuButton(
+      onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu2) : null,
+      onClose: onClose != null ? () => onClose(TestMenu.mainMenu2) : null,
+      menuChildren: <Widget>[
+        MenuItemButton(
+          // Always disabled.
+          shortcut: shortcuts[TestMenu.subMenu20],
+          // Always disabled.
+          child: Text(TestMenu.subMenu20.label),
+        ),
+      ],
+      child: Text(TestMenu.mainMenu2.label),
+    ),
+  ];
+  return result;
+}
+
+enum TestMenu {
+  mainMenu0('Menu 0'),
+  mainMenu1('Menu 1'),
+  mainMenu2('Menu 2'),
+  subMenu00('Sub Menu 00'),
+  subMenu10('Sub Menu 10'),
+  subMenu11('Sub Menu 11'),
+  subMenu12('Sub Menu 12'),
+  subMenu20('Sub Menu 20'),
+  subSubMenu110('Sub Sub Menu 110'),
+  subSubMenu111('Sub Sub Menu 111'),
+  subSubMenu112('Sub Sub Menu 112'),
+  subSubMenu113('Sub Sub Menu 113');
+
+  const TestMenu(this.label);
+  final String label;
+}
diff --git a/packages/flutter/test/material/menu_style_test.dart b/packages/flutter/test/material/menu_style_test.dart
new file mode 100644
index 0000000..66412d0
--- /dev/null
+++ b/packages/flutter/test/material/menu_style_test.dart
@@ -0,0 +1,439 @@
+// 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 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+  Finder findMenuPanels() {
+    return find.byWidgetPredicate((Widget widget) => widget.runtimeType.toString() == '_MenuPanel');
+  }
+
+  Material getMenuBarMaterial(WidgetTester tester) {
+    return tester.widget<Material>(
+      find.descendant(of: findMenuPanels(), matching: find.byType(Material)).first,
+    );
+  }
+
+  Padding getMenuBarPadding(WidgetTester tester) {
+    return tester.widget<Padding>(
+      find.descendant(of: findMenuPanels(), matching: find.byType(Padding)).first,
+    );
+  }
+
+  Material getMenuMaterial(WidgetTester tester) {
+    return tester.widget<Material>(
+      find.descendant(of: findMenuPanels().at(1), matching: find.byType(Material)).first,
+    );
+  }
+
+  Padding getMenuPadding(WidgetTester tester) {
+    return tester.widget<Padding>(
+      find.descendant(of: findMenuPanels().at(1), matching: find.byType(Padding)).first,
+    );
+  }
+
+  group('MenuStyle', () {
+    testWidgets('fixedSize affects geometry', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: Column(
+              children: <Widget>[
+                MenuBarTheme(
+                  data: const MenuBarThemeData(
+                    style: MenuStyle(
+                      fixedSize: MaterialStatePropertyAll<Size>(Size(600, 60)),
+                    ),
+                  ),
+                  child: MenuTheme(
+                    data: const MenuThemeData(
+                      style: MenuStyle(
+                        fixedSize: MaterialStatePropertyAll<Size>(Size(100, 100)),
+                      ),
+                    ),
+                    child: MenuBar(
+                      children: createTestMenus(onPressed: (TestMenu menu) {}),
+                    ),
+                  ),
+                ),
+                const Expanded(child: Placeholder()),
+              ],
+            ),
+          ),
+        ),
+      );
+
+      // Have to open a menu initially to start things going.
+      await tester.tap(find.text(TestMenu.mainMenu0.label));
+      await tester.pump();
+
+      // MenuBarTheme affects MenuBar.
+      expect(tester.getRect(findMenuPanels().first), equals(const Rect.fromLTRB(100.0, 0.0, 700.0, 60.0)));
+      expect(tester.getRect(findMenuPanels().first).size, equals(const Size(600.0, 60.0)));
+
+      // MenuTheme affects menus.
+      expect(tester.getRect(findMenuPanels().at(1)), equals(const Rect.fromLTRB(104.0, 54.0, 204.0, 154.0)));
+      expect(tester.getRect(findMenuPanels().at(1)).size, equals(const Size(100.0, 100.0)));
+    });
+
+    testWidgets('maximumSize affects geometry', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: Column(
+              children: <Widget>[
+                MenuBarTheme(
+                  data: const MenuBarThemeData(
+                    style: MenuStyle(
+                      maximumSize: MaterialStatePropertyAll<Size>(Size(250, 40)),
+                    ),
+                  ),
+                  child: MenuTheme(
+                    data: const MenuThemeData(
+                      style: MenuStyle(
+                        maximumSize: MaterialStatePropertyAll<Size>(Size(100, 100)),
+                      ),
+                    ),
+                    child: MenuBar(
+                      children: createTestMenus(onPressed: (TestMenu menu) {}),
+                    ),
+                  ),
+                ),
+                const Expanded(child: Placeholder()),
+              ],
+            ),
+          ),
+        ),
+      );
+
+      // Have to open a menu initially to start things going.
+      await tester.tap(find.text(TestMenu.mainMenu0.label));
+      await tester.pump();
+
+      // MenuBarTheme affects MenuBar.
+      expect(tester.getRect(findMenuPanels().first), equals(const Rect.fromLTRB(275.0, 0.0, 525.0, 40.0)));
+      expect(tester.getRect(findMenuPanels().first).size, equals(const Size(250.0, 40.0)));
+
+      // MenuTheme affects menus.
+      expect(tester.getRect(findMenuPanels().at(1)), equals(const Rect.fromLTRB(279.0, 44.0, 379.0, 144.0)));
+      expect(tester.getRect(findMenuPanels().at(1)).size, equals(const Size(100.0, 100.0)));
+    });
+
+    testWidgets('minimumSize affects geometry', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: Column(
+              children: <Widget>[
+                MenuBarTheme(
+                  data: const MenuBarThemeData(
+                    style: MenuStyle(
+                      minimumSize: MaterialStatePropertyAll<Size>(Size(400, 60)),
+                    ),
+                  ),
+                  child: MenuTheme(
+                    data: const MenuThemeData(
+                      style: MenuStyle(
+                        minimumSize: MaterialStatePropertyAll<Size>(Size(300, 300)),
+                      ),
+                    ),
+                    child: MenuBar(
+                      children: createTestMenus(onPressed: (TestMenu menu) {}),
+                    ),
+                  ),
+                ),
+                const Expanded(child: Placeholder()),
+              ],
+            ),
+          ),
+        ),
+      );
+
+      // Have to open a menu initially to start things going.
+      await tester.tap(find.text(TestMenu.mainMenu0.label));
+      await tester.pump();
+
+      // MenuBarTheme affects MenuBar.
+      expect(tester.getRect(findMenuPanels().first), equals(const Rect.fromLTRB(200.0, 0.0, 600.0, 60.0)));
+      expect(tester.getRect(findMenuPanels().first).size, equals(const Size(400.0, 60.0)));
+
+      // MenuTheme affects menus.
+      expect(tester.getRect(findMenuPanels().at(1)), equals(const Rect.fromLTRB(204.0, 54.0, 504.0, 354.0)));
+      expect(tester.getRect(findMenuPanels().at(1)).size, equals(const Size(300.0, 300.0)));
+    });
+
+    testWidgets('Material parameters are honored', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: Column(
+              children: <Widget>[
+                MenuBarTheme(
+                  data: const MenuBarThemeData(
+                    style: MenuStyle(
+                      backgroundColor: MaterialStatePropertyAll<Color>(Colors.red),
+                      shadowColor: MaterialStatePropertyAll<Color>(Colors.green),
+                      surfaceTintColor: MaterialStatePropertyAll<Color>(Colors.blue),
+                      padding: MaterialStatePropertyAll<EdgeInsetsGeometry>(EdgeInsets.all(10)),
+                      elevation: MaterialStatePropertyAll<double>(10),
+                      side: MaterialStatePropertyAll<BorderSide>(BorderSide(color: Colors.redAccent)),
+                      shape: MaterialStatePropertyAll<OutlinedBorder>(StadiumBorder()),
+                    ),
+                  ),
+                  child: MenuTheme(
+                    data: const MenuThemeData(
+                      style: MenuStyle(
+                        backgroundColor: MaterialStatePropertyAll<Color>(Colors.cyan),
+                        shadowColor: MaterialStatePropertyAll<Color>(Colors.purple),
+                        surfaceTintColor: MaterialStatePropertyAll<Color>(Colors.yellow),
+                        padding: MaterialStatePropertyAll<EdgeInsetsGeometry>(EdgeInsets.all(20)),
+                        elevation: MaterialStatePropertyAll<double>(20),
+                        side: MaterialStatePropertyAll<BorderSide>(BorderSide(color: Colors.cyanAccent)),
+                        shape: MaterialStatePropertyAll<OutlinedBorder>(StarBorder()),
+                      ),
+                    ),
+                    child: MenuBar(
+                      children: createTestMenus(onPressed: (TestMenu menu) {}),
+                    ),
+                  ),
+                ),
+                const Expanded(child: Placeholder()),
+              ],
+            ),
+          ),
+        ),
+      );
+
+      // Have to open a menu initially to start things going.
+      await tester.tap(find.text(TestMenu.mainMenu0.label));
+      await tester.pump();
+
+      final Material menuBarMaterial = getMenuBarMaterial(tester);
+      final Padding menuBarPadding = getMenuBarPadding(tester);
+      final Material panelMaterial = getMenuMaterial(tester);
+      final Padding panelPadding = getMenuPadding(tester);
+
+      // MenuBarTheme affects MenuBar.
+      expect(menuBarMaterial.color, equals(Colors.red));
+      expect(menuBarMaterial.shadowColor, equals(Colors.green));
+      expect(menuBarMaterial.surfaceTintColor, equals(Colors.blue));
+      expect(menuBarMaterial.shape, equals(const StadiumBorder(side: BorderSide(color: Colors.redAccent))));
+      expect(menuBarPadding.padding, equals(const EdgeInsets.all(10)));
+
+      // MenuBarTheme affects menus.
+      expect(panelMaterial.color, equals(Colors.cyan));
+      expect(panelMaterial.shadowColor, equals(Colors.purple));
+      expect(panelMaterial.surfaceTintColor, equals(Colors.yellow));
+      expect(panelMaterial.shape, equals(const StarBorder(side: BorderSide(color: Colors.cyanAccent))));
+      expect(panelPadding.padding, equals(const EdgeInsets.all(20)));
+    });
+
+    testWidgets('visual density', (WidgetTester tester) async {
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Material(
+            child: Column(
+              children: <Widget>[
+                MenuBarTheme(
+                  data: const MenuBarThemeData(
+                    style: MenuStyle(
+                      visualDensity: VisualDensity(horizontal: 1.5, vertical: -1.5),
+                    ),
+                  ),
+                  child: MenuTheme(
+                    data: const MenuThemeData(
+                      style: MenuStyle(
+                        visualDensity: VisualDensity(horizontal: 0.5, vertical: -0.5),
+                      ),
+                    ),
+                    child: MenuBar(
+                      children: createTestMenus(onPressed: (TestMenu menu) {}),
+                    ),
+                  ),
+                ),
+                const Expanded(child: Placeholder()),
+              ],
+            ),
+          ),
+        ),
+      );
+      await tester.pump();
+
+      expect(tester.getRect(find.byType(MenuBar)), equals(const Rect.fromLTRB(240.0, 0.0, 560.0, 48.0)));
+
+      // Open and make sure things are the right size.
+      await tester.tap(find.text(TestMenu.mainMenu1.label));
+      await tester.pump();
+
+      expect(tester.getRect(find.byType(MenuBar)), equals(const Rect.fromLTRB(240.0, 0.0, 560.0, 48.0)));
+      expect(
+        tester.getRect(find.text(TestMenu.subMenu10.label)),
+        equals(const Rect.fromLTRB(366.0, 64.0, 520.0, 78.0)),
+      );
+      expect(
+        tester.getRect(find.ancestor(of: find.text(TestMenu.subMenu10.label), matching: find.byType(Material)).at(1)),
+        equals(const Rect.fromLTRB(350.0, 48.0, 602.0, 178.0)),
+      );
+    });
+  });
+}
+
+List<Widget> createTestMenus({
+  void Function(TestMenu)? onPressed,
+  void Function(TestMenu)? onOpen,
+  void Function(TestMenu)? onClose,
+  Map<TestMenu, MenuSerializableShortcut> shortcuts = const <TestMenu, MenuSerializableShortcut>{},
+  bool includeStandard = false,
+  bool includeExtraGroups = false,
+}) {
+  final List<Widget> result = <Widget>[
+    SubmenuButton(
+      onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu0) : null,
+      onClose: onClose != null ? () => onClose(TestMenu.mainMenu0) : null,
+      menuChildren: <Widget>[
+        MenuItemButton(
+          onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu00) : null,
+          shortcut: shortcuts[TestMenu.subMenu00],
+          child: Text(TestMenu.subMenu00.label),
+        ),
+        MenuItemButton(
+          onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu01) : null,
+          shortcut: shortcuts[TestMenu.subMenu01],
+          child: Text(TestMenu.subMenu01.label),
+        ),
+        MenuItemButton(
+          onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu02) : null,
+          shortcut: shortcuts[TestMenu.subMenu02],
+          child: Text(TestMenu.subMenu02.label),
+        ),
+      ],
+      child: Text(TestMenu.mainMenu0.label),
+    ),
+    SubmenuButton(
+      onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu1) : null,
+      onClose: onClose != null ? () => onClose(TestMenu.mainMenu1) : null,
+      menuChildren: <Widget>[
+        MenuItemButton(
+          onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu10) : null,
+          shortcut: shortcuts[TestMenu.subMenu10],
+          child: Text(TestMenu.subMenu10.label),
+        ),
+        SubmenuButton(
+          onOpen: onOpen != null ? () => onOpen(TestMenu.subMenu11) : null,
+          onClose: onClose != null ? () => onClose(TestMenu.subMenu11) : null,
+          menuChildren: <Widget>[
+            MenuItemButton(
+              key: UniqueKey(),
+              onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu110) : null,
+              shortcut: shortcuts[TestMenu.subSubMenu110],
+              child: Text(TestMenu.subSubMenu110.label),
+            ),
+            MenuItemButton(
+              onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu111) : null,
+              shortcut: shortcuts[TestMenu.subSubMenu111],
+              child: Text(TestMenu.subSubMenu111.label),
+            ),
+            MenuItemButton(
+              onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu112) : null,
+              shortcut: shortcuts[TestMenu.subSubMenu112],
+              child: Text(TestMenu.subSubMenu112.label),
+            ),
+            MenuItemButton(
+              onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu113) : null,
+              shortcut: shortcuts[TestMenu.subSubMenu113],
+              child: Text(TestMenu.subSubMenu113.label),
+            ),
+          ],
+          child: Text(TestMenu.subMenu11.label),
+        ),
+        MenuItemButton(
+          onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu12) : null,
+          shortcut: shortcuts[TestMenu.subMenu12],
+          child: Text(TestMenu.subMenu12.label),
+        ),
+      ],
+      child: Text(TestMenu.mainMenu1.label),
+    ),
+    SubmenuButton(
+      onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu2) : null,
+      onClose: onClose != null ? () => onClose(TestMenu.mainMenu2) : null,
+      menuChildren: <Widget>[
+        MenuItemButton(
+          // Always disabled.
+          shortcut: shortcuts[TestMenu.subMenu20],
+          child: Text(TestMenu.subMenu20.label),
+        ),
+      ],
+      child: Text(TestMenu.mainMenu2.label),
+    ),
+    if (includeExtraGroups)
+      SubmenuButton(
+        onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu3) : null,
+        onClose: onClose != null ? () => onClose(TestMenu.mainMenu3) : null,
+        menuChildren: <Widget>[
+          MenuItemButton(
+            // Always disabled.
+            shortcut: shortcuts[TestMenu.subMenu30],
+            // Always disabled.
+            child: Text(TestMenu.subMenu30.label),
+          ),
+        ],
+        child: Text(TestMenu.mainMenu3.label),
+      ),
+    if (includeExtraGroups)
+      SubmenuButton(
+        onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu4) : null,
+        onClose: onClose != null ? () => onClose(TestMenu.mainMenu4) : null,
+        menuChildren: <Widget>[
+          MenuItemButton(
+            // Always disabled.
+            shortcut: shortcuts[TestMenu.subMenu40],
+            // Always disabled.
+            child: Text(TestMenu.subMenu40.label),
+          ),
+          MenuItemButton(
+            // Always disabled.
+            shortcut: shortcuts[TestMenu.subMenu41],
+            // Always disabled.
+            child: Text(TestMenu.subMenu41.label),
+          ),
+          MenuItemButton(
+            // Always disabled.
+            shortcut: shortcuts[TestMenu.subMenu42],
+            // Always disabled.
+            child: Text(TestMenu.subMenu42.label),
+          ),
+        ],
+        child: Text(TestMenu.mainMenu4.label),
+      ),
+  ];
+  return result;
+}
+
+enum TestMenu {
+  mainMenu0('Menu 0'),
+  mainMenu1('Menu 1'),
+  mainMenu2('Menu 2'),
+  mainMenu3('Menu 3'),
+  mainMenu4('Menu 4'),
+  subMenu00('Sub Menu 00'),
+  subMenu01('Sub Menu 01'),
+  subMenu02('Sub Menu 02'),
+  subMenu10('Sub Menu 10'),
+  subMenu11('Sub Menu 11'),
+  subMenu12('Sub Menu 12'),
+  subMenu20('Sub Menu 20'),
+  subMenu30('Sub Menu 30'),
+  subMenu40('Sub Menu 40'),
+  subMenu41('Sub Menu 41'),
+  subMenu42('Sub Menu 42'),
+  subSubMenu110('Sub Sub Menu 110'),
+  subSubMenu111('Sub Sub Menu 111'),
+  subSubMenu112('Sub Sub Menu 112'),
+  subSubMenu113('Sub Sub Menu 113');
+
+  const TestMenu(this.label);
+  final String label;
+}
diff --git a/packages/flutter/test/material/menu_theme_test.dart b/packages/flutter/test/material/menu_theme_test.dart
new file mode 100644
index 0000000..d0459bc
--- /dev/null
+++ b/packages/flutter/test/material/menu_theme_test.dart
@@ -0,0 +1,315 @@
+// 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 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+  void onPressed(TestMenu item) {}
+
+  Finder findMenuPanels(Axis orientation) {
+    return find.byWidgetPredicate((Widget widget) {
+      // ignore: avoid_dynamic_calls
+      return widget.runtimeType.toString() == '_MenuPanel' && (widget as dynamic).orientation == orientation;
+    });
+  }
+
+  Finder findMenuBarPanel() {
+    return findMenuPanels(Axis.horizontal);
+  }
+
+  Finder findSubmenuPanel() {
+    return findMenuPanels(Axis.vertical);
+  }
+
+  Finder findSubMenuItem() {
+    return find.descendant(of: findSubmenuPanel().last, matching: find.byType(MenuItemButton));
+  }
+
+  Material getMenuBarPanelMaterial(WidgetTester tester) {
+    return tester.widget<Material>(find.descendant(of: findMenuBarPanel(), matching: find.byType(Material)).first);
+  }
+
+  Material getSubmenuPanelMaterial(WidgetTester tester) {
+    return tester.widget<Material>(find.descendant(of: findSubmenuPanel(), matching: find.byType(Material)).first);
+  }
+
+  DefaultTextStyle getLabelStyle(WidgetTester tester, String labelText) {
+    return tester.widget<DefaultTextStyle>(
+      find
+          .ancestor(
+            of: find.text(labelText),
+            matching: find.byType(DefaultTextStyle),
+          )
+          .first,
+    );
+  }
+
+  testWidgets('theme is honored', (WidgetTester tester) async {
+    await tester.pumpWidget(
+      MaterialApp(
+        home: Material(
+          child: Builder(builder: (BuildContext context) {
+            return MenuBarTheme(
+              data: const MenuBarThemeData(
+                style: MenuStyle(
+                  backgroundColor: MaterialStatePropertyAll<Color?>(Colors.green),
+                  elevation: MaterialStatePropertyAll<double?>(20.0),
+                ),
+              ),
+              child: MenuTheme(
+                data: const MenuThemeData(
+                  style: MenuStyle(
+                    backgroundColor: MaterialStatePropertyAll<Color?>(Colors.red),
+                    elevation: MaterialStatePropertyAll<double?>(15.0),
+                    shape: MaterialStatePropertyAll<OutlinedBorder?>(StadiumBorder()),
+                    padding: MaterialStatePropertyAll<EdgeInsetsGeometry>(
+                      EdgeInsetsDirectional.all(10.0),
+                    ),
+                  ),
+                ),
+                child: Column(
+                  children: <Widget>[
+                    MenuBar(
+                      children: createTestMenus(onPressed: onPressed),
+                    ),
+                    const Expanded(child: Placeholder()),
+                  ],
+                ),
+              ),
+            );
+          }),
+        ),
+      ),
+    );
+
+    // Open a test menu.
+    await tester.tap(find.text(TestMenu.mainMenu1.label));
+    await tester.pump();
+    expect(tester.getRect(findMenuBarPanel().first), equals(const Rect.fromLTRB(246.0, 0.0, 554.0, 48.0)));
+    final Material menuBarMaterial = getMenuBarPanelMaterial(tester);
+    expect(menuBarMaterial.elevation, equals(20));
+    expect(menuBarMaterial.color, equals(Colors.green));
+
+    final Material subMenuMaterial = getSubmenuPanelMaterial(tester);
+    expect(tester.getRect(findSubmenuPanel()), equals(const Rect.fromLTRB(340.0, 48.0, 590.0, 212.0)));
+    expect(subMenuMaterial.elevation, equals(15));
+    expect(subMenuMaterial.color, equals(Colors.red));
+  });
+
+  testWidgets('Constructor parameters override theme parameters', (WidgetTester tester) async {
+    await tester.pumpWidget(
+      MaterialApp(
+        home: Material(
+          child: Builder(
+            builder: (BuildContext context) {
+              return MenuBarTheme(
+                data: const MenuBarThemeData(
+                  style: MenuStyle(
+                    backgroundColor: MaterialStatePropertyAll<Color?>(Colors.green),
+                    elevation: MaterialStatePropertyAll<double?>(20.0),
+                  ),
+                ),
+                child: MenuTheme(
+                  data: const MenuThemeData(
+                    style: MenuStyle(
+                      backgroundColor: MaterialStatePropertyAll<Color?>(Colors.red),
+                      elevation: MaterialStatePropertyAll<double?>(15.0),
+                      shape: MaterialStatePropertyAll<OutlinedBorder?>(StadiumBorder()),
+                      padding: MaterialStatePropertyAll<EdgeInsetsGeometry>(
+                        EdgeInsetsDirectional.all(10.0),
+                      ),
+                    ),
+                  ),
+                  child: Column(
+                    children: <Widget>[
+                      MenuBar(
+                        style: const MenuStyle(
+                          backgroundColor: MaterialStatePropertyAll<Color?>(Colors.blue),
+                          elevation: MaterialStatePropertyAll<double?>(10.0),
+                          padding: MaterialStatePropertyAll<EdgeInsetsGeometry>(
+                            EdgeInsetsDirectional.all(12.0),
+                          ),
+                        ),
+                        children: createTestMenus(
+                          onPressed: onPressed,
+                          menuBackground: Colors.cyan,
+                          menuElevation: 18.0,
+                          menuPadding: const EdgeInsetsDirectional.all(14.0),
+                          menuShape: const BeveledRectangleBorder(),
+                          itemBackground: Colors.amber,
+                          itemForeground: Colors.grey,
+                          itemOverlay: Colors.blueGrey,
+                          itemPadding: const EdgeInsetsDirectional.all(11.0),
+                          itemShape: const StadiumBorder(),
+                        ),
+                      ),
+                      const Expanded(child: Placeholder()),
+                    ],
+                  ),
+                ),
+              );
+            },
+          ),
+        ),
+      ),
+    );
+
+    // Open a test menu.
+    await tester.tap(find.text(TestMenu.mainMenu1.label));
+    await tester.pump();
+
+    expect(tester.getRect(findMenuBarPanel().first), equals(const Rect.fromLTRB(238.0, 0.0, 562.0, 72.0)));
+    final Material menuBarMaterial = getMenuBarPanelMaterial(tester);
+    expect(menuBarMaterial.elevation, equals(10.0));
+    expect(menuBarMaterial.color, equals(Colors.blue));
+
+    final Material subMenuMaterial = getSubmenuPanelMaterial(tester);
+    expect(tester.getRect(findSubmenuPanel()), equals(const Rect.fromLTRB(336.0, 60.0, 594.0, 232.0)));
+    expect(subMenuMaterial.elevation, equals(18));
+    expect(subMenuMaterial.color, equals(Colors.cyan));
+    expect(subMenuMaterial.shape, equals(const BeveledRectangleBorder()));
+
+    final Finder menuItem = findSubMenuItem();
+    expect(tester.getRect(menuItem.first), equals(const Rect.fromLTRB(350.0, 74.0, 580.0, 122.0)));
+    final Material menuItemMaterial = tester.widget<Material>(
+        find.ancestor(of: find.text(TestMenu.subMenu10.label), matching: find.byType(Material)).first);
+    expect(menuItemMaterial.color, equals(Colors.amber));
+    expect(menuItemMaterial.elevation, equals(0.0));
+    expect(menuItemMaterial.shape, equals(const StadiumBorder()));
+    expect(getLabelStyle(tester, TestMenu.subMenu10.label).style.color, equals(Colors.grey));
+    final ButtonStyle? textButtonStyle = tester
+        .widget<TextButton>(find
+            .ancestor(
+              of: find.text(TestMenu.subMenu10.label),
+              matching: find.byType(TextButton),
+            )
+            .first)
+        .style;
+    expect(textButtonStyle?.overlayColor?.resolve(<MaterialState>{MaterialState.hovered}), equals(Colors.blueGrey));
+  });
+}
+
+List<Widget> createTestMenus({
+  void Function(TestMenu)? onPressed,
+  void Function(TestMenu)? onOpen,
+  void Function(TestMenu)? onClose,
+  Map<TestMenu, MenuSerializableShortcut> shortcuts = const <TestMenu, MenuSerializableShortcut>{},
+  bool includeStandard = false,
+  Color? itemOverlay,
+  Color? itemBackground,
+  Color? itemForeground,
+  EdgeInsetsDirectional? itemPadding,
+  Color? menuBackground,
+  EdgeInsetsDirectional? menuPadding,
+  OutlinedBorder? menuShape,
+  double? menuElevation,
+  OutlinedBorder? itemShape,
+}) {
+  final MenuStyle menuStyle = MenuStyle(
+    padding: menuPadding != null ? MaterialStatePropertyAll<EdgeInsetsGeometry>(menuPadding) : null,
+    backgroundColor: menuBackground != null ? MaterialStatePropertyAll<Color>(menuBackground) : null,
+    elevation: menuElevation != null ? MaterialStatePropertyAll<double>(menuElevation) : null,
+    shape: menuShape != null ? MaterialStatePropertyAll<OutlinedBorder>(menuShape) : null,
+  );
+  final ButtonStyle itemStyle = ButtonStyle(
+    padding: itemPadding != null ? MaterialStatePropertyAll<EdgeInsetsGeometry>(itemPadding) : null,
+    shape: itemShape != null ? MaterialStatePropertyAll<OutlinedBorder>(itemShape) : null,
+    foregroundColor: itemForeground != null ? MaterialStatePropertyAll<Color>(itemForeground) : null,
+    backgroundColor: itemBackground != null ? MaterialStatePropertyAll<Color>(itemBackground) : null,
+    overlayColor: itemOverlay != null ? MaterialStatePropertyAll<Color>(itemOverlay) : null,
+  );
+  final List<Widget> result = <Widget>[
+    SubmenuButton(
+      onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu0) : null,
+      onClose: onClose != null ? () => onClose(TestMenu.mainMenu0) : null,
+      menuChildren: <Widget>[
+        MenuItemButton(
+          onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu00) : null,
+          shortcut: shortcuts[TestMenu.subMenu00],
+          child: Text(TestMenu.subMenu00.label),
+        ),
+      ],
+      child: Text(TestMenu.mainMenu0.label),
+    ),
+    SubmenuButton(
+      onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu1) : null,
+      onClose: onClose != null ? () => onClose(TestMenu.mainMenu1) : null,
+      menuStyle: menuStyle,
+      menuChildren: <Widget>[
+        MenuItemButton(
+          onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu10) : null,
+          shortcut: shortcuts[TestMenu.subMenu10],
+          style: itemStyle,
+          child: Text(TestMenu.subMenu10.label),
+        ),
+        SubmenuButton(
+          onOpen: onOpen != null ? () => onOpen(TestMenu.subMenu11) : null,
+          onClose: onClose != null ? () => onClose(TestMenu.subMenu11) : null,
+          menuChildren: <Widget>[
+            MenuItemButton(
+              onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu110) : null,
+              shortcut: shortcuts[TestMenu.subSubMenu110],
+              child: Text(TestMenu.subSubMenu110.label),
+            ),
+            MenuItemButton(
+              onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu111) : null,
+              shortcut: shortcuts[TestMenu.subSubMenu111],
+              child: Text(TestMenu.subSubMenu111.label),
+            ),
+            MenuItemButton(
+              onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu112) : null,
+              shortcut: shortcuts[TestMenu.subSubMenu112],
+              child: Text(TestMenu.subSubMenu112.label),
+            ),
+            MenuItemButton(
+              onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu113) : null,
+              shortcut: shortcuts[TestMenu.subSubMenu113],
+              child: Text(TestMenu.subSubMenu113.label),
+            ),
+          ],
+          child: Text(TestMenu.subMenu11.label),
+        ),
+        MenuItemButton(
+          onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu12) : null,
+          shortcut: shortcuts[TestMenu.subMenu12],
+          child: Text(TestMenu.subMenu12.label),
+        ),
+      ],
+      child: Text(TestMenu.mainMenu1.label),
+    ),
+    SubmenuButton(
+      onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu2) : null,
+      onClose: onClose != null ? () => onClose(TestMenu.mainMenu2) : null,
+      menuChildren: <Widget>[
+        MenuItemButton(
+          // Always disabled.
+          shortcut: shortcuts[TestMenu.subMenu20],
+          // Always disabled.
+          child: Text(TestMenu.subMenu20.label),
+        ),
+      ],
+      child: Text(TestMenu.mainMenu2.label),
+    ),
+  ];
+  return result;
+}
+
+enum TestMenu {
+  mainMenu0('Menu 0'),
+  mainMenu1('Menu 1'),
+  mainMenu2('Menu 2'),
+  subMenu00('Sub Menu 00'),
+  subMenu10('Sub Menu 10'),
+  subMenu11('Sub Menu 11'),
+  subMenu12('Sub Menu 12'),
+  subMenu20('Sub Menu 20'),
+  subSubMenu110('Sub Sub Menu 110'),
+  subSubMenu111('Sub Sub Menu 111'),
+  subSubMenu112('Sub Sub Menu 112'),
+  subSubMenu113('Sub Sub Menu 113');
+
+  const TestMenu(this.label);
+  final String label;
+}
diff --git a/packages/flutter/test/material/theme_data_test.dart b/packages/flutter/test/material/theme_data_test.dart
index 5e2e0fb..e0e4a71 100644
--- a/packages/flutter/test/material/theme_data_test.dart
+++ b/packages/flutter/test/material/theme_data_test.dart
@@ -6,62 +6,6 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_test/flutter_test.dart';
 
-@immutable
-class MyThemeExtensionA extends ThemeExtension<MyThemeExtensionA> {
-  const MyThemeExtensionA({
-    required this.color1,
-    required this.color2,
-  });
-
-  final Color? color1;
-  final Color? color2;
-
-  @override
-  MyThemeExtensionA copyWith({Color? color1, Color? color2}) {
-    return MyThemeExtensionA(
-      color1: color1 ?? this.color1,
-      color2: color2 ?? this.color2,
-    );
-  }
-
-  @override
-  MyThemeExtensionA lerp(MyThemeExtensionA? other, double t) {
-    if (other is! MyThemeExtensionA) {
-      return this;
-    }
-    return MyThemeExtensionA(
-      color1: Color.lerp(color1, other.color1, t),
-      color2: Color.lerp(color2, other.color2, t),
-    );
-  }
-}
-
-@immutable
-class MyThemeExtensionB extends ThemeExtension<MyThemeExtensionB> {
-  const MyThemeExtensionB({
-    required this.textStyle,
-  });
-
-  final TextStyle? textStyle;
-
-  @override
-  MyThemeExtensionB copyWith({Color? color, TextStyle? textStyle}) {
-    return MyThemeExtensionB(
-      textStyle: textStyle ?? this.textStyle,
-    );
-  }
-
-  @override
-  MyThemeExtensionB lerp(MyThemeExtensionB? other, double t) {
-    if (other is! MyThemeExtensionB) {
-      return this;
-    }
-    return MyThemeExtensionB(
-      textStyle: TextStyle.lerp(textStyle, other.textStyle, t),
-    );
-  }
-}
-
 void main() {
   test('Theme data control test', () {
     final ThemeData dark = ThemeData.dark();
@@ -696,6 +640,9 @@
       floatingActionButtonTheme: const FloatingActionButtonThemeData(backgroundColor: Colors.black),
       iconButtonTheme: IconButtonThemeData(style: IconButton.styleFrom(foregroundColor: Colors.pink)),
       listTileTheme: const ListTileThemeData(),
+      menuBarTheme: const MenuBarThemeData(style: MenuStyle(backgroundColor: MaterialStatePropertyAll<Color>(Colors.black))),
+      menuButtonTheme: MenuButtonThemeData(style: MenuItemButton.styleFrom(backgroundColor: Colors.black)),
+      menuTheme: const MenuThemeData(style: MenuStyle(backgroundColor: MaterialStatePropertyAll<Color>(Colors.black))),
       navigationBarTheme: const NavigationBarThemeData(backgroundColor: Colors.black),
       navigationRailTheme: const NavigationRailThemeData(backgroundColor: Colors.black),
       outlinedButtonTheme: OutlinedButtonThemeData(style: OutlinedButton.styleFrom(foregroundColor: Colors.blue)),
@@ -810,6 +757,9 @@
       floatingActionButtonTheme: const FloatingActionButtonThemeData(backgroundColor: Colors.white),
       iconButtonTheme: const IconButtonThemeData(),
       listTileTheme: const ListTileThemeData(),
+      menuBarTheme: const MenuBarThemeData(style: MenuStyle(backgroundColor: MaterialStatePropertyAll<Color>(Colors.white))),
+      menuButtonTheme: MenuButtonThemeData(style: MenuItemButton.styleFrom(backgroundColor: Colors.black)),
+      menuTheme: const MenuThemeData(style: MenuStyle(backgroundColor: MaterialStatePropertyAll<Color>(Colors.white))),
       navigationBarTheme: const NavigationBarThemeData(backgroundColor: Colors.white),
       navigationRailTheme: const NavigationRailThemeData(backgroundColor: Colors.white),
       outlinedButtonTheme: const OutlinedButtonThemeData(),
@@ -910,6 +860,9 @@
       floatingActionButtonTheme: otherTheme.floatingActionButtonTheme,
       iconButtonTheme: otherTheme.iconButtonTheme,
       listTileTheme: otherTheme.listTileTheme,
+      menuBarTheme: otherTheme.menuBarTheme,
+      menuButtonTheme: otherTheme.menuButtonTheme,
+      menuTheme: otherTheme.menuTheme,
       navigationBarTheme: otherTheme.navigationBarTheme,
       navigationRailTheme: otherTheme.navigationRailTheme,
       outlinedButtonTheme: otherTheme.outlinedButtonTheme,
@@ -1009,6 +962,9 @@
     expect(themeDataCopy.floatingActionButtonTheme, equals(otherTheme.floatingActionButtonTheme));
     expect(themeDataCopy.iconButtonTheme, equals(otherTheme.iconButtonTheme));
     expect(themeDataCopy.listTileTheme, equals(otherTheme.listTileTheme));
+    expect(themeDataCopy.menuBarTheme, equals(otherTheme.menuBarTheme));
+    expect(themeDataCopy.menuButtonTheme, equals(otherTheme.menuButtonTheme));
+    expect(themeDataCopy.menuTheme, equals(otherTheme.menuTheme));
     expect(themeDataCopy.navigationBarTheme, equals(otherTheme.navigationBarTheme));
     expect(themeDataCopy.navigationRailTheme, equals(otherTheme.navigationRailTheme));
     expect(themeDataCopy.outlinedButtonTheme, equals(otherTheme.outlinedButtonTheme));
@@ -1023,8 +979,6 @@
     expect(themeDataCopy.textSelectionTheme, equals(otherTheme.textSelectionTheme));
     expect(themeDataCopy.textSelectionTheme.selectionColor, equals(otherTheme.textSelectionTheme.selectionColor));
     expect(themeDataCopy.textSelectionTheme.cursorColor, equals(otherTheme.textSelectionTheme.cursorColor));
-    expect(themeDataCopy.textSelectionTheme.selectionColor, equals(otherTheme.textSelectionTheme.selectionColor));
-    expect(themeDataCopy.textSelectionTheme.cursorColor, equals(otherTheme.textSelectionTheme.cursorColor));
     expect(themeDataCopy.textSelectionTheme.selectionHandleColor, equals(otherTheme.textSelectionTheme.selectionHandleColor));
     expect(themeDataCopy.timePickerTheme, equals(otherTheme.timePickerTheme));
     expect(themeDataCopy.toggleButtonsTheme, equals(otherTheme.toggleButtonsTheme));
@@ -1141,10 +1095,14 @@
       'dividerTheme',
       'drawerTheme',
       'elevatedButtonTheme',
+      'expansionTileTheme',
       'filledButtonTheme',
       'floatingActionButtonTheme',
       'iconButtonTheme',
       'listTileTheme',
+      'menuBarTheme',
+      'menuButtonTheme',
+      'menuTheme',
       'navigationBarTheme',
       'navigationRailTheme',
       'outlinedButtonTheme',
@@ -1160,7 +1118,6 @@
       'timePickerTheme',
       'toggleButtonsTheme',
       'tooltipTheme',
-      'expansionTileTheme',
       // DEPRECATED (newest deprecations at the bottom)
       'accentColor',
       'accentColorBrightness',
@@ -1192,3 +1149,59 @@
     expect(propertyNames, expectedPropertyNames);
   });
 }
+
+@immutable
+class MyThemeExtensionA extends ThemeExtension<MyThemeExtensionA> {
+  const MyThemeExtensionA({
+    required this.color1,
+    required this.color2,
+  });
+
+  final Color? color1;
+  final Color? color2;
+
+  @override
+  MyThemeExtensionA copyWith({Color? color1, Color? color2}) {
+    return MyThemeExtensionA(
+      color1: color1 ?? this.color1,
+      color2: color2 ?? this.color2,
+    );
+  }
+
+  @override
+  MyThemeExtensionA lerp(MyThemeExtensionA? other, double t) {
+    if (other is! MyThemeExtensionA) {
+      return this;
+    }
+    return MyThemeExtensionA(
+      color1: Color.lerp(color1, other.color1, t),
+      color2: Color.lerp(color2, other.color2, t),
+    );
+  }
+}
+
+@immutable
+class MyThemeExtensionB extends ThemeExtension<MyThemeExtensionB> {
+  const MyThemeExtensionB({
+    required this.textStyle,
+  });
+
+  final TextStyle? textStyle;
+
+  @override
+  MyThemeExtensionB copyWith({Color? color, TextStyle? textStyle}) {
+    return MyThemeExtensionB(
+      textStyle: textStyle ?? this.textStyle,
+    );
+  }
+
+  @override
+  MyThemeExtensionB lerp(MyThemeExtensionB? other, double t) {
+    if (other is! MyThemeExtensionB) {
+      return this;
+    }
+    return MyThemeExtensionB(
+      textStyle: TextStyle.lerp(textStyle, other.textStyle, t),
+    );
+  }
+}
