Skip to content

Implement RawMenuAnchor#158255

Merged
auto-submit[bot] merged 100 commits intoflutter:masterfrom
davidhicks980:raw_menu_anchor
Feb 4, 2025
Merged

Implement RawMenuAnchor#158255
auto-submit[bot] merged 100 commits intoflutter:masterfrom
davidhicks980:raw_menu_anchor

Conversation

@davidhicks980
Copy link
Contributor

@davidhicks980 davidhicks980 commented Nov 6, 2024

This PR adds a RawMenuAnchor() widget to widgets.dart. The purpose of this widget is to provide a menu primitive for the Material and Cupertino libraries (and others) to build upon. Additionally, this PR makes MenuController an inherited widget to simplify nested access to the menu (e.g. if you want to launch a context menu from a deeply-nested widget).

This PR:

  • Centralizes core menu logic to a private class, _RawMenuAnchor(),
    • Provides the internals for interacting with menus:
      • TapRegion interop
      • DismissMenuAction handler
      • Close on scroll/resize
      • Focus traversal information, if applicable
      • Subclasses override _open, _close, _isOpen, _buildAnchor, and _menuScopeNode
    • State is accessible by descendents via MenuController.maybeOf(context)._anchor
  • Adds 2 public constructors, backed by a _RawMenuAnchor() that contains shared logic.
    • RawMenuAnchor()
      • Users build the overlay from scratch.
      • Provides anchor/overlay position information and TapRegionGroupId to builder
      • Does not provide FocusScope management.
    • RawMenuAnchorGroup()
      • A primitive for menus that do not have overlays (menu bars).
      • This was previously called RawMenuAnchor.node(), but @dkwingsmt made a good case for splitting out the constructor.

Documentation examples have been added, and can be viewed at https://menu-anchor.web.app/

https://github.com/user-attachments/assets/25d35f23-2aad-4d07-9172-5c3fd65d53cf

@dkwingsmt

List which issues are fixed by this PR. #143712

Some issues that need to be addressed:

Semantics:
image
I'm basing the menu semantics off of the comment here, but I'm unsure whether the route should be given a name. There is no menubar/menu/menuitem role in Flutter, so I'm assuming the menu should be composed of nested dialogs

Unlike the menubar pattern from W3C, the RawMenuAnchor

  • does not close on tab/shift-tab. I left this behavior out of the menu so that users could customize tab behavior, but I'm not opinionated either way
  • does not open on ArrowUp/ArrowDown, because this could interfere with user focus behavior in unconventional menu setups (e.g. a vertical menu).
  • does not automatically focus the first item in a menu overlay when activated via enter/spacebar, but does focus the first item when horizontal traversal opens a submenu. Automatically focusing the first item whenever an overlay opens interferes with hover traversal, and I couldn't think of a good way to only focus the first item when an overlay is triggered via enter/spacebar.
  • doesn't focus disabled items (I wasn't sure how to address this without editing MenuItemButton)

While it is possible to nest menus -- for example, a dropdown anchor within a full-app context menu area -- nested menus behave as a single group. I was considering adding an additional parameter that separates nested root menus from their parents, and am interested to hear your feedback.

If you had to change anything in the flutter/tests repo, include a link to the migration guide as per the breaking change policy.

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

d: api docs Issues with https://api.flutter.dev/ d: examples Sample code and demos f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels. will affect goldens Changes to golden files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants