Skip to content

FluentMenu fails when first rendered with Open=true #5078

Description

Bug Report

A FluentMenu cannot be conditionally added to a page and opened in the same render. Rendering it for the first time with Open="true" races its asynchronous JavaScript initialization.

Observed downstream in the Aspire Dashboard with Microsoft.FluentUI.AspNetCore.Components 4.14.4.

Repro

<FluentButton Id="menu-anchor" @onclick="OpenMenu">
    Actions
</FluentButton>

@if (_renderMenu)
{
    <FluentMenu Anchor="menu-anchor" Open="true">
        <FluentMenuItem>Action</FluentMenuItem>
    </FluentMenu>
}

@code {
    private bool _renderMenu;

    private void OpenMenu()
    {
        _renderMenu = true;
    }
}

Current behavior

The menu is displayed while its JavaScript modules are still initializing, resulting in a JS interop error:

AnchoredRegion module is required for keyboard navigation

FluentMenu.razor.js throws this when initialize receives menuOpen=true before the anchored-region module is available.

Expected behavior

A FluentMenu should support being added to the render tree for the first time with Open="true". It should finish initialization before displaying the menu and initializing keyboard navigation.

This pattern is useful when a page contains many menu buttons. Consumers can avoid constructing every menu and paying their JavaScript import/initialization costs during the initial page render, then create only the menu that the user opens.

Aspire workaround

AspireMenuButton currently:

  1. Starts observing the anchor before rendering FluentMenu.
  2. Renders the menu closed.
  3. Uses FluentMenu's first aria-expanded write as a readiness signal that its JavaScript modules have initialized.
  4. Sets Open=true only after that signal.

Workaround source:

This works, but it relies on observing an implementation detail and requires downstream JavaScript solely to coordinate FluentMenu initialization.

Possible solutions

  • Make FluentMenu wait for all required modules to finish loading before processing an initial Open=true value.
  • Defer FluentMenu module imports and calls such as initialize until the menu is first opened. That would make a closed FluentMenu inexpensive and remove the need for consumers to conditionally render it solely for performance.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions