MudMenu: Replace IActivatable with MenuContext#12145
Conversation
- Created MenuContext class to encapsulate menu activation logic - Updated MudMenu to use MenuContext instead of IActivatable - Added MenuContext as cascading parameter in MudBaseButton - Updated test to use MenuContext - All 3936 tests passing (61 menu tests, 0 failures) Co-authored-by: danielchalmers <7112040+danielchalmers@users.noreply.github.com>
Co-authored-by: danielchalmers <7112040+danielchalmers@users.noreply.github.com>
|
Donating this. I don't know enough about it to do any more work |
|
Never use Goal Replace the old non-async, tightly coupled, component-specific, cascading This new API must: Provide an elegant
Replace the activator pattern with a strongly typed context API: Replace: public RenderFragment? ActivatorContent { get; set; }with: public RenderFragment<MenuContext>? ActivatorContent { get; set; }Replace the old activator render code: <CascadingValue Value="@((IActivatable)this)" IsFixed="true">
<div @onclick="ToggleMenuAsync" disabled="@Disabled" class="@ActivatorClassname">
@ActivatorContent
</div>
</CascadingValue>with: <div disabled="@Disabled" class="@ActivatorClassname">
@ActivatorContent(new MenuContext(this))
</div>Enable all components, HTML, custom components, anything — to trigger menu actions: Activators must now be written like this (just one of the example): <MudMenu FullWidth="true" PopoverClass="menu-popover-class">
<ActivatorContent>
<MudButton Variant="Variant.Filled"
OnClick="@(() => context.OpenMenuAsync())"
Color="Color.Primary">
Activator Content Standard
</MudButton>
</ActivatorContent>
<ChildContent>
<MudMenuItem Class="test-class">1</MudMenuItem>
<MudMenuItem Href="https://www.test.com">2</MudMenuItem>
<MudMenuItem Href="https://www.test.com" Target="_blank">3</MudMenuItem>
</ChildContent>
</MudMenu>Where the consumer always interacts with the menu using the passed Remove the obsolete API entirely:
Update all documentation & tests:
Required Copilot must NOT reuse old code. /// <summary>
/// Exposes async operations for managing a <see cref="MudMenu"/> instance,
/// including opening, closing, toggling, and closing parent menus.
/// </summary>
public sealed class MenuContext
{
private readonly MudMenu _menu;
/// <summary>
/// Creates a new <see cref="MenuContext"/> for the specified <see cref="MudMenu"/>.
/// </summary>
public MenuContext(MudMenu menu)
{
_menu = menu;
}
/// <summary>
/// Opens the menu. If <see cref="MudMenu.PositionAtCursor"/> is enabled,
/// the menu is positioned using the supplied event arguments.
/// </summary>
public Task OpenMenuAsync(EventArgs? args = null)
=> _menu.OpenMenuAsync(args);
/// <summary>Closes the menu.</summary>
public Task CloseMenuAsync()
=> _menu.CloseMenuAsync();
/// <summary>Toggles the menu's visibility.</summary>
public Task ToggleMenuAsync(EventArgs? args = null)
=> _menu.ToggleMenuAsync(args);
/// <summary>Closes all parent menus in the hierarchy.</summary>
public Task CloseAllMenusAsync()
=> _menu.CloseAllMenusAsync();
}Copilot may improve naming, add more XML doc details, or expand operations if needed. Copilot MUST update all relevant tests and docs. Things Copilot Must NOT Do:
|
- Create new MenuContext with async methods (OpenMenuAsync, CloseMenuAsync, ToggleMenuAsync, CloseAllMenusAsync) - Change ActivatorContent from RenderFragment? to RenderFragment<MenuContext>? - Remove CascadingValue pattern - context is passed directly to RenderFragment - Remove IActivatable dependency from MudMenu (kept for MudFileUpload) - Revert MudBaseButton changes - IActivatable remains for FileUpload - Update all doc examples and test components to use context.ToggleMenuAsync - Update tests to work with new context-based pattern Co-authored-by: ScarletKuro <19953225+ScarletKuro@users.noreply.github.com>
- Restore @OnClick handler on activator div for backward compatibility - Add ArgumentNullException.ThrowIfNull validation in MenuContext constructor Co-authored-by: ScarletKuro <19953225+ScarletKuro@users.noreply.github.com>
Implemented the clean async MenuContext API as requested in commit Changes made:
No |
|
Well that looks much better than the previous version... At least it looks more realistic and workable |
|
Doesn't look too bad, but api wise personally I prefer shorter names like |
Fair |
It's ready. If someone wishing to do a
Don't think I understood. |
-<div @onclick="@context.ToggleAsync" style="cursor: pointer">
+<div @onclick="@context.ToggleAsync" style="cursor: pointer" class="mud-target-boundary">just for the sake of identifying it |
I mean, I can ask copilot to add it, but I slightly don't see the point if this is basically examples & user area, why we need to "identify" them? <div class="mud-target-boundary">
@ActivatorContent(_menuContext)
</div> |
We've used that pattern before but I do not think it applies here, and applying MudTarget or anything similar would just be another IActivatable type reference though more abstract. I think it's good like it is and we can add or change it down the line if we feel the need. Especially once IActivatable is gone gone. |
|
Ok, I will @danielchalmers let hit the merge button, if he thinks something is missing/needs to be updated, feel free to directly change it in the PR or poke copilot |
Replaces the generic
IActivatableinterface with a dedicated asyncMenuContextclass for MudMenu activation, providing a clean, modern, component-agnostic API.Changes:
MenuContextclass - Clean async API withOpenAsync,CloseAsync,ToggleAsync, andCloseAllAsyncmethods. Fully XML-documented with proper null validation.ActivatorContentsignature changed - FromRenderFragment?toRenderFragment<MenuContext>?allowing context to be passed directly to custom activatorsMudMenurefactored - RemovedIActivatableinterface and CascadingValue pattern. Context passed directly to RenderFragment and cached in constructor for performance.IActivatablepreserved forMudFileUpload- Kept inMudBaseButtonfor backward compatibility with file upload componentcontext.ToggleAsync()callsNew MenuContext API:
New usage pattern:
Key improvements:
async voidor.CatchAndLog()Taskwith proper async patternsToggleAsyncinstead ofToggleMenuAsync)Breaking change:
ActivatorContentnow requires explicit context usage (e.g.,context.ToggleAsync()). Users must explicitly wire up click/contextmenu handlers in their ActivatorContent.Checklist:
Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.