Skip to content

Conversation

@adamint
Copy link
Member

@adamint adamint commented Aug 29, 2025

Pull Request

📖 Description

I really like this component, but it's currently unusable in Aspire because it's not keyboard-accessible. To make it accessible, the menu button needs to properly handle tab (tab on button menu is open focuses first menu item, tab when focus is on a menu item will focus the next focusable dom element outside the menu + close the menu), and shift+tab (shift+tab when focus is on the button will close the menu if open, or otherwise will focus the button if a menu item is focused).

Additionally, the button content was not customizable (no render fragment could be provided).

This PR fixes both problems. I added a new parameter ButtonContent that can be provided instead of Text.

The accessibility changes were implemented client-side because of the focusing logic requiring DOM access. I also had to fix the FluentAnchoredRegion's FocusableElement.findNextFocusableElement function to support focusing fluent components that have focusable children (since they themselves are not focusable), which I reused in the FluentMenuButton. Please refer to this before and after:

Before (see keys pressed on screen for context)

Grabacion.de.pantalla.2025-08-28.a.la.s.8.29.16.p.m.mov

After

Grabacion.de.pantalla.2025-08-28.a.la.s.8.30.51.p.m.mov

🎫 Issues

Fixes #4090

👩‍💻 Reviewer Notes

N/A

📑 Test Plan

I added a couple tests for the ButtonContent parameter, but as most of the accessibility changes are in the component JS, you will need to test manually using the MenuButton sample page.

✅ Checklist

General

  • I have added tests for my changes.
  • I have tested my changes.
  • I have updated the project documentation to reflect my changes.
  • I have read the CONTRIBUTING documentation and followed the standards for this project.

Component-specific

  • I have added a new component
  • I have added Unit Tests for my new component
  • I have modified an existing component
  • I have validated the Unit Tests for an existing component

⏭ Next Steps


protected override void OnParametersSet()
{
if (Text is not null && ButtonContent is not null)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need to test this. But you must add to the Text property that this property will be ignored if ButtonContent is defined.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You cannot force the developer to have a content. The dev can create a MenuButton without content.
So, just add in the Text property comment: this property will be ignored if ButtonContent is defined

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not correct with the new comment. You must remove this test: the dev can set a value in Text and ButtonContent. And the component will render only the ButtonContent (ignoring the Text prarameter).

@adamint adamint requested a review from dvoituron August 29, 2025 21:21
@vnbaaij
Copy link
Collaborator

vnbaaij commented Sep 8, 2025

@adamint Can you please finish this PR and fix the comments. Thanks.

@adamint adamint requested a review from dvoituron September 9, 2025 19:36
…sible-no-require-icon' into adamint/fluent-menu-button-accessible-no-require-icon
@adamint
Copy link
Member Author

adamint commented Sep 9, 2025

@vnbaaij updated based on comments.

@adamint adamint changed the title Fix: make fluent menu accessible, allow custom button content Fix: make fluent menu button accessible, allow custom button content Sep 9, 2025
@adamint adamint marked this pull request as draft September 9, 2025 20:51
@adamint adamint changed the title Fix: make fluent menu button accessible, allow custom button content Fix: make fluent menu accessible, allow custom button content Sep 9, 2025
@adamint adamint marked this pull request as ready for review September 9, 2025 21:36
@adamint
Copy link
Member Author

adamint commented Sep 9, 2025

Ok, I realized that this issue is not unique to just menu buttons and was happening to all menus. I have reverted the focus changes to the FluentMenuButton, and instead implemented them in FluentMenu so that we properly handle tab and escape in the FluentDataGrid and other uses of FluentMenu as well. I added an example of a fluent data grid that uses menus in its cell headers, which I used to help test the changes in this PR and which used to fail.

Grabacion.de.pantalla.2025-09-09.a.la.s.5.37.40.p.m.mov

…sible-no-require-icon' into adamint/fluent-menu-button-accessible-no-require-icon
@vnbaaij vnbaaij changed the title Fix: make fluent menu accessible, allow custom button content [MenuButton] Accessibility fixes and allow custom button content Sep 11, 2025
@vnbaaij vnbaaij added this to the v4.12.2 milestone Sep 12, 2025

protected override void OnParametersSet()
{
if (Text is not null && ButtonContent is not null)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You cannot force the developer to have a content. The dev can create a MenuButton without content.
So, just add in the Text property comment: this property will be ignored if ButtonContent is defined

@vnbaaij
Copy link
Collaborator

vnbaaij commented Sep 29, 2025

Hi @adamint . Can we work to get this merged in. Please look at the latest open remarks. Thanks.

@adamint adamint requested a review from dvoituron September 29, 2025 20:10
@vnbaaij vnbaaij enabled auto-merge (squash) September 30, 2025 12:49

protected override void OnParametersSet()
{
if (Text is not null && ButtonContent is not null)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not correct with the new comment. You must remove this test: the dev can set a value in Text and ButtonContent. And the component will render only the ButtonContent (ignoring the Text prarameter).

@vnbaaij
Copy link
Collaborator

vnbaaij commented Oct 2, 2025

@adamint, just one more small change requested...

Copy link
Collaborator

@dvoituron dvoituron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vnbaaij will update the PR comments in another PR.

@vnbaaij vnbaaij disabled auto-merge October 7, 2025 13:46
@vnbaaij vnbaaij merged commit 4933136 into microsoft:dev Oct 7, 2025
2 checks passed
dvoituron pushed a commit that referenced this pull request Oct 7, 2025
…4093) (#4221)

* Remove check on Text and ButtonContent being provided, change xml doc wording,

* Remove redundant test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: tab/shift-tab does not work as expected in MenuButton

3 participants