Giter VIP home page Giter VIP logo

blazorcontextmenu's Introduction

Blazor Context Menu

Build status Nuget (with prereleases) Nuget Donate

A context menu component for Blazor!

demo-img

Samples / Demo

You can find a live demo here.

Installation

1. Add the nuget package in your Blazor project

> dotnet add package Blazor.ContextMenu

OR

PM> Install-Package Blazor.ContextMenu

Nuget package page can be found here.

2. Add the following line in your Blazor project's startup class

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddBlazorContextMenu();
    }
}

3. Add the following line in your _Imports.razor

@using BlazorContextMenu

4. Reference the static files

Add the following static file references in your _Host.cshtml (server-side blazor) or in your index.html (client-side blazor). Make sure that there is a call to app.UseStaticFiles(); in your server project's Startup.cs.

<link href="_content/Blazor.ContextMenu/blazorContextMenu.min.css" rel="stylesheet" />
<script src="_content/Blazor.ContextMenu/blazorContextMenu.min.js"></script>

Basic usage

<ContextMenu Id="myMenu">
    <Item OnClick="@OnClick">Item 1</Item>
    <Item OnClick="@OnClick">Item 2</Item>
    <Item OnClick="@OnClick" Enabled="false">Item 3 (disabled)</Item>
    <Seperator />
    <Item>Submenu
        <SubMenu>
            <Item OnClick="@OnClick">Submenu Item 1</Item>
            <Item OnClick="@OnClick">Submenu Item 2</Item>
        </SubMenu>
    </Item>
</ContextMenu>

<ContextMenuTrigger MenuId="myMenu">
    <p>Right-click on me to show the context menu !!</p>
</ContextMenuTrigger>

@code{
    void OnClick(ItemClickEventArgs e)
    {
        Console.WriteLine($"Item Clicked => Menu: {e.ContextMenuId}, MenuTarget: {e.ContextMenuTargetId}, IsCanceled: {e.IsCanceled}, MenuItem: {e.MenuItemElement}, MouseEvent: {e.MouseEvent}");
    }
}

Customization

Templates

You can create templates in the configuration that you can then apply to context menus.

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddBlazorContextMenu(options =>
        {
            options.ConfigureTemplate("myTemplate", template =>
            {
                template.MenuCssClass = "my-menu";
                template.MenuItemCssClass = "my-menu-item";
                //...
            });
        });
    }
}
<style>
    .my-menu { color: darkblue; }
    
    /* using css specificity to override default background-color */
    .my-menu .my-menu-item { background-color: #ffb3b3;}
    .my-menu .my-menu-item:hover { background-color: #c11515;} 
</style>

<ContextMenu Id="myMenu" Template="myTemplate">
    <Item>Item 1</Item>
    <Item>Item 2</Item>
</ContextMenu>

You can also change the default template that will apply to all context menus (unless specified otherwise).

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddBlazorContextMenu(options =>
        {
            //Configures the default template
            options.ConfigureTemplate(defaultTemplate =>
            {
                defaultTemplate.MenuCssClass = "my-default-menu";
                defaultTemplate.MenuItemCssClass = "my-default-menu-item";
                //...
            });

            options.ConfigureTemplate("myTemplate", template =>
            {
                template.MenuCssClass = "my-menu";
                template.MenuItemCssClass = "my-menu-item";
                //...
            });
        });
    }
}

Explicit customization

All components expose CssClass parameters that you can use to add css classes. These take precedence over any template configuration.

<ContextMenu Id="myMenu" CssClass="my-menu">
    <Item CssClass="red-menuitem">Red looking Item</Item>
    <Item>Default looking item</Item>
</ContextMenu>

Overriding default css

You can override the default css classes completely in the following ways (not recommended unless you want to achieve advanced customization).

Override default css using templates

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddBlazorContextMenu(options =>
        {
            //This will override the default css classes for the default template
            options.ConfigureTemplate(defaultTemplate =>
            {
                defaultTemplate.DefaultCssOverrides.MenuCssClass  = "custom-menu";
                defaultTemplate.DefaultCssOverrides.MenuItemCssClass= "custom-menu-item";
                defaultTemplate.DefaultCssOverrides.MenuItemDisabledCssClass = "custom-menu-item--disabled";
                //...
            });
        });
    }
}

Using the OverrideDefaultXXX parameters on components. These take precedence over the template overrides.

<ContextMenu Id="myMenu" OverrideDefaultCssClass="custom-menu">
    <Item OverrideDefaultCssClass="custom-menu-item" OverrideDefaultDisabledCssClass="custom-menu-item--disabled">Item 1</Item>
    <Item OverrideDefaultCssClass="custom-menu-item" OverrideDefaultDisabledCssClass="custom-menu-item--disabled">Item 2</Item>
</ContextMenu>

⚠️ Breaking changes ⚠️

Upgrading from 1.9.0 to 1.10.0
  • The default auto-hide event is now on "mousedown". If you want the old behaviour, you can use the new AutoHideEvent parameter on the ContextMenu component to change it back to "mouseup".
Upgrading from 0.19 to 0.20
  • Replaced the ContextMenuTriggerId in events with the reference to the actual ContextMenuTrigger
Upgrading from 0.16 to 0.17
  • Removed the deprecated automatic embed of resources in blazor client-side. You must reference the static files as described in the "Installation" section.
  • The static resources path has changed in preview 7 from _content/blazorcontextmenu/ to _content/Blazor.ContextMenu/
Upgrading from 0.15 to 0.16
  • Only for Blazor Server-Side projects: You must reference the static files as described in the "Installation" section.
Upgrading from 0.12 to 0.13
  • Remove the @addTagHelper *, BlazorContextMenu as it is no longer needed.
Upgrading from 0.11 to 0.12
  • The following handlers are removed as they are no longer needed: ClickAsync, EnabledHandlerAsync, VisibleHandlerAsync.
  • The Click handler has been renamed to OnClick to keep consistency with the framework/suggested event names.
  • The MenuItemClickEventArgs class has been renamed to the more appropriate ItemClickEventArgs.
  • The EnabledHandler and VisibleHandler parameters have been removed and replaced with the new OnAppearing event handler.
  • The MenuItemEnabledHandlerArgs and MenuItemVisibleHandlerArgs classes have been removed and replaced with the new ItemAppearingEventArgs.
Upgrading from 0.10 to 0.11
  • The CssOverrides API is removed and override configuration is moved into templates. The DefaultCssOverrides of the ConfigureTemplate API must be used.
Upgrading from 0.5 to 0.6
  • You must add in Startup.ConfigureServices of your Blazor client side project the following line services.AddBlazorContextMenu();
  • The BlazorContextMenu.BlazorContextMenuDefaults API is removed. Use the API provided in the service configuration.
Upgrading from 0.1 to 0.2
  • Rename "MenuItem" to "Item".
  • Rename "MenuSeperator" to "Seperator".
  • Replace "MenuItemWithSubmenu" with a regular "Item" component.

Release Notes

2.1
2.0
  • Upgrade to dotnet 8.0
1.17
  • Upgraded asp .net packages dependencies to 6.0.25 due to security concerns.
1.16
  • Fixes issue with opening a contextual menu on the far right side of the window for the first time not properly offsetting. Contributed by matt-virtualitics.
1.15
  • Add IsMenuShown to BlazorContextMenuService. Contributed by Adam Ashton.
1.14
1.13
1.12
1.11
  • Upgraded to dotnet 6.0
1.10.1
1.10
  • Changed default auto hide event to "mousedown". Old behaviour ("mouseup") is available by using the AutoHideEvent parameter on the ContextMenu component. Contributed by KristofferStrube.
1.9
  • Added ZIndex support in ContextMenu component (default 1000). Contributed by grishat.
  • Added autohide support in ContextMenu when window is resizing. Contributed by grishat.
1.8
  • Added StopPropagation parameter on ContextMenuTrigger (default true).
1.7
1.6
  • Added contextual render fragment for ContextMenu, exposing a @context variable that simplifies advanced scenarios.
1.5
  • Fixed a bug when opening multiple menus with different ids.
1.4
  • Updated to 3.1 release.
  • Fix for #72.
1.3
  • Added menu OnHiding event #68.
1.2
1.1
  • Added the ability to show/hide a menu from code. (#63)
1.0
  • Updated to 3.0 release.
0.21
  • Updated to 3.0 preview 9.
0.20
  • Added ContextMenuTrigger data, that can be accessed from event args.
  • Replaced the ContextMenuTriggerId in event args with the reference to the actual ContextMenuTrigger
0.19
  • Fix for Blazor server-side prerendering: #53.
0.18
  • Updated to 3.0 preview 8.
  • Added attribute splatting to components.
0.17
  • Updated to 3.0 preview 7.
  • Added double click mouse trigger.
  • Removed the deprecated automatic embed of resources in blazor client-side. You now have to reference the static files just like the server-side blazor projects.
0.16
  • Updated to 3.0 preview 6.
0.15
  • Added new OnAppearing event to ContextMenu conponent, that can be used to prevent the menu from showing.
  • Added the WrapperTag parameter to the ContextMenuTrigger component, that can be used to change the ContextMenuTrigger component's element tag (default: div).
  • Added the Id parameter to the ContextMenuTrigger component.
0.14
  • Updated to 3.0 preview 5.
0.13
  • Updated to 3.0 preview 4.
0.12
  • Updated to Blazor 0.9.0.
  • Changed event handlers to the new EventCallback<>. As a consequence the following handlers are no longer needed and they are removed: ClickAsync, EnabledHandlerAsync, VisibleHandlerAsync.
  • Fixed menu display position when it doesn't fit on screen.
  • The Click handler has been renamed to OnClick to keep consistency with the framework/suggested event names.
  • The MenuItemClickEventArgs class has been renamed to the more appropriate ItemClickEventArgs.
  • The EnabledHandler and VisibleHandler parameters have been removed and replaced with the new OnAppearing event handler.
  • The MenuItemEnabledHandlerArgs and MenuItemVisibleHandlerArgs classes have been removed and replaced with the new ItemAppearingEventArgs.
0.11
  • Updated to Blazor 0.8.0.
  • Added animations.
  • Default css overrides are now part of the Templates API so that you can easily have multiple custom overriden menus.
  • Razor Components are not loading the static files included in the library => #6349. As a workaround you can download and reference directly the .css and .js from the /BlazorContextMenu/content folder until the issue is resolved.
0.10
  • Added proper support for Razor Components (aka server-side Blazor).
0.9
  • Updated to Blazor 0.7.0.
  • Removed some js interop in favor of the new Cascading Values feature.
0.8
  • Updated to Blazor 0.6.0.
0.7
  • Added left-click trigger support.
0.6
  • Updated to Blazor 0.5.1.
  • Changed configuration setup.
  • Added templates.
0.5
  • Updated to Blazor 0.5.0.
0.4
  • Added minification for included css/js.
  • Updated to Blazor 0.4.0.
0.3
  • Added dynamic EnabledHandlers for menu items.
  • Added Active and dynamic ActiveHandlers for menu items.
0.2
  • Updated to Blazor 0.3.0.
  • Renamed "MenuItem" to "Item" to avoid conflicts with the html element "menuitem".
  • Renamed "MenuSeperator" to "Seperator" for consistency.
  • Removed "MenuItemWithSubmenu" (just use a regular "Item").
0.1
  • Initial release.

Special Thanks

This project was inspired by https://github.com/fkhadra/react-contexify and https://github.com/vkbansal/react-contextmenu

blazorcontextmenu's People

Contributors

adamashton avatar dependabot[bot] avatar elanhasson avatar kristofferstrube avatar matt-virtualitics avatar sebastian-wachsmuth avatar stavroskasidis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

blazorcontextmenu's Issues

"Cannot read properties of undefined (reading 'removeEventListener')" after closing menu

Describe the bug
A second after closing the menu, I'm getting this error in the JS console:

blazorContextMenu.js:256 Uncaught TypeError: Cannot read properties of undefined (reading 'removeEventListener')
    at HTMLLIElement.closeSubMenus (blazorContextMenu.js:256:31)
closeSubMenus @ blazorContextMenu.js:256

To Reproduce
Steps to reproduce the behavior:

  1. Click submenu item (which opens a window and closes the current context menu
  2. Error in the JS console.

Expected behavior
No error

Desktop (please complete the following information):

  • OS: Windows 10
  • Browser: Chrome
  • Version 102.0.5005.62

Configurable direction of menu-open (e.g. bottom-right, top-left)

Is your feature request related to a problem? Please describe.
I'd like to configure the context menu to open to the top-left instead of to the bottom-right. Currently, the menus seem to always open to the bottom-right, although they do seem to nicely reverse direction when there's not enough room.

Describe the solution you'd like
It'd be nice if the trigger element or the menu element had another parameter property that allowed this configuration. The default could be something like MenuOpenDirection.BottomRight and in my own use-case I'd explicitly set it to MenuOpenDirection.TopLeft.

Describe alternatives you've considered
I scanned the docs & code for any ideas on how to get this to happen, but I came up empty-handed. I might try diving more deeply into the code to try to figure out what to change so I can get it to work. If I surprise myself and actually figure it out, I'll happily report back here.

Additional context
None right now.

Show/Hide the context menu from code

Hi,

I really love your component. So powerful!

I would need to show/hide a contextual menu from the code. I have the coordinates (X,Y) to position the menu dynamically.

Do you think it would be simple to implement in your component?

Can this be used in a Razor Class Library?

Hello -- excellent work on this component, very excited to integrate it with my application.

One problem I'm having is I'm not able to import the component into a Razor Class Library project.
I'm fairly green to Blazor, so it's likely not a bug but me misunderstanding something.

  1. Install NuGet package
  2. Try to add @using BlazorContextMenu to _Imports.razor,
    image

I've been able to use it within a Blazor App project, but I'd like to be able to include it in a separate Razor Class Library for reuse.

Thanks for your effort, and help!

upgrade to blazor 0.8

Hi stavroskasidis, thanks for your work on this project !
I actually need your component but i begin with the last version of blazor (0.8, including .net core 3 preview).

It's possible to upgrade your project to upgrade on this ? i already did on my computer, it's work perfectly, so if you want i can commit on your project to target to blazor 0.8/.NET CORE 3

Thanks !

Julien

.Net Core 3.0 Preview 8 + BlazorContextMenu = Error

What is the Problem? Its a Complete new Blazor Template. I dont get it. can you help me?

System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.AspNetCore.Components.Server.Circuits.RemoteJSRuntime.BeginInvokeJS(Int64 asyncHandle, String identifier, String argsJson)
at Microsoft.JSInterop.JSRuntimeBase.InvokeAsync[T](String identifier, IEnumerable1 args, CancellationToken cancellationToken) at Microsoft.JSInterop.JSRuntimeBase.InvokeWithDefaultCancellation[T](String identifier, IEnumerable1 args)
at BlazorContextMenu.ContextMenuTrigger.OnAfterRenderAsync()
at Microsoft.AspNetCore.Components.Rendering.HtmlRenderer.HandleException(Exception exception)
at Microsoft.AspNetCore.Components.Rendering.Renderer.AddToPendingTasks(Task task)
at Microsoft.AspNetCore.Components.Rendering.ComponentState.SetDirectParameters(ParameterView parameters)
at Microsoft.AspNetCore.Components.Rendering.Renderer.RenderRootComponentAsync(Int32 componentId, ParameterView initialParameters)
at Microsoft.AspNetCore.Components.Rendering.HtmlRenderer.CreateInitialRenderAsync(Type componentType, ParameterView initialParameters)
at Microsoft.AspNetCore.Components.Rendering.HtmlRenderer.RenderComponentAsync(Type componentType, ParameterView initialParameters)
at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.<>c__111.<<InvokeAsync>b__11_0>d.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Mvc.ViewFeatures.RazorComponents.StaticComponentRenderer.PrerenderComponentAsync(ParameterView parameters, HttpContext httpContext, Type componentType) at Microsoft.AspNetCore.Mvc.Rendering.HtmlHelperRazorComponentExtensions.RenderStaticComponentAsync[TComponent](IHtmlHelper htmlHelper, Object parameters) at VertreterApto.Pages.Pages__Host.<ExecuteAsync>b__10_1() in C:\Users\praktikant\source\repos\VertreterApto\VertreterApto\Pages\_Host.cshtml:line 22 at Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.SetOutputContentAsync() at VertreterApto.Pages.Pages__Host.ExecuteAsync() at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context) at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, Boolean invokeViewStarts) at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context) at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable1 statusCode)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.SetRoutingAndContinue(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Support for stopPropagation

Hello and thanks for your library, it is very useful for my project !

Sometimes, inside a container which react to a contextMenu, I need tu put some child component which also react to contextMenu (not yours, the classic html contextmenu)
In this case, i wan't to "cancel" the appearing of yours contextMenu and let my code make something else.

I was thinking with the new stopPropagation in the .net core 3.1.0 it will be OK (https://docs.microsoft.com/fr-fr/aspnet/core/blazor/components?view=aspnetcore-3.1#stop-event-propagation), but its not.

How to reproduce :

  • first of all, upgrade the projects of your solution in .net core 3.1.0 and .net standard 2.1 and with the latest nugget
  • put this piece of code somewhere in a page
@inject IJSRuntime JsRuntime
<ContextMenuTrigger MenuId="menuTestPropagation">
    <div style="width:400px; height:400px; background-color: blue">
        <div style="width:200px; height:200px; margin: auto; background-color: red" @oncontextmenu="ChildrenClick" @oncontextmenu:stopPropagation="true">
            @**@
        </div>
    </div>
</ContextMenuTrigger>
<ContextMenu Id="menuTestPropagation">
    <Item Id="menuTestPropagation-item1">Item 1</Item>
    <Item Id="menuTestPropagation-item2">Item 2</Item>
</ContextMenu>

protected async Task ChildrenClick()
    {
        await this.JsRuntime.InvokeVoidAsync("alert", "children was clicked");
    }

launch the app, if you right click on the children red square, you have the ChildrenClick called (which is OK), but also the menu appaering (which is not OK, I wan't the directive @oncontextmenu:stopPropagation="true" prevent your menu appearing)

Do you think you have time to check that ?

If needed, i can submit a PR with the upgrade of your project in .net core 3.1 + .net standard 2.1 and solve this case if you know approximatively how to solve it.

Thanks !

Julien

Scrolling menu options

I am working on a context menu for wishlisting items. The app I have will have user created wish lists and some might have a lot. Was wondering if there might be a way to implement a scroll box inside the context menu for more than x items.

Don't require constant keydown - behave more like a standard context menu

I just added this to my project, and it's awesome, thanks!

The only downside is that if you click, and then let go, the menu disappears. Standard context menus should only dismiss when I select a menu item, or click outside the menu. The current behaviour makes it a bit awkward for use with a touchpad.

Is there an option to change this behaviour?

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on Greenkeeper branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet.
We recommend using:

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please click the 'fix repo' button on account.greenkeeper.io.

Keyboard nav and focus

When a context menu opens, it is really helpful to keyboard nav ready to work which usually requires focus to be on the element. Currently the first menu item does not have focus and esc key does not work.

Would be nice if, when the menu opens, the following is true:

  • focus is on first clickable menu item
  • up/down keys work to navigate menu if it has focus and if parent/child item focused then left/right keys work too to focus relevant item
  • escape key closes menu and returns focus to element that was active at the time of menu opening (e.g. button that opened or null if none)

I've looked at other blazor components and no one seems to have this feature yet...makes me wonder if there is some reason it is not do-able?

Move css overrides into templates

Right now you can either override the default css for all context menus, or on every single instance of <ContextMenu>, which is painful if you want to have more than one overridden menu.

The CssOverrides API should move into the ConfigureTemplate API, to bind the overrides onto templates so that you can have multiple overridden menus.

Context menu does not close automatically if a dialogue menu is opened.

Describe the bug
We have users select a file when clicking a button on the context menu. After selecting a file, the context menu does not close automatically until the user clicks again.

To Reproduce
Steps to reproduce the behavior:

  1. Make a context menu with a child element that loads a file from the user's computer when clicked.

Expected behavior
The context menu should close immediately after a file is chosen, or at least there should be the option to have it close. (Closing immediately might be a breaking change.)

Desktop (please complete the following information):

  • OS: Windows 11
  • Browser: Edge
  • Version: 105.0.1343.33

Additional context
This would be easily mitigated if you made the Show/Hide functions public so that we did not have to use reflection.

Lazy Loading based on clicked item?

Hi,

I have a listbox with contextmenu on the listboxitems.
How do I dynamically load some additional data from database based on where the contextmenu is triggered.

<ContextMenu Id="myMenu"> 
    @foreach (var subitem in CurrentItemSubitems)
    {
        <Item>
            EXP-@subitem.Id
        </Item>
    }
</ContextMenu>

 <Virtualize @ref="_listbox" Items="Items">
   <ItemContent>
       <ContextMenuTrigger MenuId="myMenu" Data="???">
          @context.Title
       </ContextMenuTrigger>
    </ItemContent>
</Virtualize>

Additionally, if would be nice, if this lazy loading worked for submenus as well...

Allow Associating ContextMenuTrigger with an ID/Tag

A am adding a ContextMenuTrigger to each table row in a HTML5 table. For each row (ContextMenuTrigger) I would like to provide a tag/id that gets passed to the callback when a menu item is invoked so I know which data item the context menu was invoked for.

I was expecting to be able to do something like this
@foreach (var item in Items)
{
<ContextMenuTrigger Tag="@item.Id.ToString()" WrapperTag="tr" MenuId="tableContextMenu" MouseButtonTrigger="MouseButtonTrigger.Right">

and then be able to get the Tag value in the ItemClick handler
void OnClick(BlazorContextMenu.ItemClickEventArgs e)
{
string ItemId = e.ContextMenuTrigger.Tag;

or similar....

Javascript error, when first child-Tag of an item is a Blazor component

Describe the bug
ContextMenu Items with blazor component as child cause error:
blazorContextMenu.min.js:1

       Uncaught TypeError: r.className.split is not a function
    at e (blazorContextMenu.min.js:1:2608)
    at Object.f.OnMenuItemMouseOver (blazorContextMenu.min.js:1:2721)
    at HTMLLIElement.onmouseover (Elemente:1:19)

Causing Line: blazorContextMenu.js

To Reproduce
Steps to reproduce the behavior:

Create a contextMenu with a blazor component as first child

<BlazorContextMenu.ContextMenu Id="contextMenuId">
    <BlazorContextMenu.Item OnClick="ShowDetailsClicked">
        <FeatherEye CssClass="mr-4 inline-block" Color="currentColor" />
          Details
    </BlazorContextMenu.Item>
</BlazorContextMenu.ContextMenu I

this will generate follow markup for the Item

<li id="4f859ec6-da68-487d-ac20-1c0799695a25" 
     class="blazor-context-menu__item blazor-context-menu__item--default " 
     style="display:block;" 
     itemenabled="true" 
     onmouseover="blazorContextMenu.OnMenuItemMouseOver(event, 4, this);" 
     onmouseout="blazorContextMenu.OnMenuItemMouseOut(event);" _bl_73="">
     <!--!-->
     <!--!-->
     <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1,5" stroke-linecap="round" stroke-linejoin="round" class="feather mr-4 inline-block feather-eye"><!--!--><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg>
     <!--!-->
      Details 
</li>

Expected behavior
since the code is looking at the className property, the NodeList children can be used, since it only returns children of type element

Desktop (please complete the following information):

  • OS: Windows 11
  • Browser Edge
  • Dotnet-Version: 6.0.3

Additional context
The code uses the property childNodes, which also return text and comment Nodes (source)

IsShown Member

First of all: Thanks for your awesome work!

At the moment i am using your context menu on a table cell. Further more i use a tooltip for every cell. My problem is that the tooltip, when activated, sets itself in front of everything else. So i can't use your context menu for cells which also have a tooltip.

The easiest solution for me would be to deactivated the tooltip when activating the context menu. But i think there is no such member or event which i could use for that.

I saw the onAppearing Event, and i think i could have used that one, but then i could never comfortably activate the tooltip again.

You may have an idea how to solve my problem. Otherwise i think a good solution would be a member which tells me about the context menu status, or a onHiding event.

For some reason i cannot compile the project, otherwise i would solved this problem by myself. Sorry for that!

Trigger closing of context menu depending on position of mousedown.

Is your feature request related to a problem? Please describe.
When you click outside the context menu then the menu is first closed when onmouseup is invoked as we only subscribe to this event. This is not mimicking the behaviour of a normal mouse-based browser context menu.

Describe the solution you'd like
The solution would be to change what events we subscribe to in order to mimic normal behaviour:

  1. Subscribe on onmousedown.
  2. If your click starts outside the context menu then the menu is closed immediately.
  3. If your click starts within the context menu then the menu is not closed unless you end the click on an option (for which we need to subscribe to onmouseup still.)

For this, we also need to keep track of if the current click was started within or without a context menu when the click is ended (onmouseup)

Describe alternatives you've considered
There are definitely many ways to implement a context menu, but this seems closer to other implementations.

Additional context
I want to use this in one of my projects that can have long drag-and-drops for which you want to close other open context menus on onmousedown which is also the standard.

I can help with the implementation. Just wanted to know if you were interested in this approach before making a fork.

Error in ContextMenuTrigger AfterRenderAsync on iOS

We have been experiencing an issue on a page that uses Blazor Context Menu. If a user opens the page on linked Apple Devices (i.e. an iPad) and then opens the same page on an iPhone, the app crashes. It seems it could be related to "handoff" somehow, be we aren't entirely certain. After enabling detailed errors and hooking a phone up to a mac to gain access to a Safari developer console, we were able to see the actual error that was occurring....

Error: Microsoft.JSInterop.JSException: null is not an object (evaluating 'e.dataset')
_content/Blazor.ContextMenu/blazorContextMenu.min.js:1:3553
[native code]
_framework/Blazor.ContextMenu/blazor.server.js:8:31426
Promise@[native code]
beginInvokeJSFromDotNet@_framework/Blazor.ContextMenu/blazor.server.js:8:31401
forEach@[native code]
_framework/Blazor.ContextMenu/blazor.server.js:1:19180
_framework/Blazor.ContextMenu/blazor.server.js:1:17183
_framework/Blazor.ContextMenu/blazor.server.js:1:38100
at Microsoft.JSInterop.JSRuntime.InvokeWithDefaultCancellation[T](String identifier, Object[] args)
at BlazorContextMenu.ContextMenuTrigger.OnAfterRenderAsync(Boolean firstRender)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle)

Error: Circuit has been shut down due to error.

After I remove the Context Menu from the page, the error is unable to be reproduced.

It's obviously a bit of a perfect storm and very difficult to provide a reproduction as it only seems to happen after opening the page on multiple iOS devices and then only on the phone. I'm hoping maybe the error itself may provide a clue as to what's going on or a potential fix?

Animations

Add predefined animations for opening the menu (default: none)

Using "internal" severely limits the extensibility of the library

Hiding .GetTarget() and .Data in ContextMenuBase with internal unfortunately greatly limits the possibilities of extending the library with custom MenuItems by inheriting from MenuTreeComponent.

Would much prefer to see them public (and possibly other fields as well).

Add more showcases to demo app

Add the following to the Demo app

  • Showcase left-click/both-clicks support
  • Showcase templates
  • Showcase Enabled/Visible handlers for items
  • Add tabs that show the code in all showcases

Prevent from opening the context menu on child element of ContextMenuTrigger

Hi,
I'm not sure if this is possible or not.
Is it possible to prevent the context menu to open in a specific child component of the ContextMenuTrigger?

Something like this:

<ContextMenuTrigger MenuId="menu">
    <div>
        <p>Test</p>
            <div>Special</div>
    </div>
    <div>
        <p>If this element is clicked just ignore it... Please? :)</p>
    </div>

</ContextMenuTrigger>

Thanks in advance.

Dynamically Add Menu Items/Extra Data

I have a grid which displays a list of clients. I want to add a context menu to each row which has options such as "Create Project", "Invoice Client" etc and then when this menu item is clicked, it navigates the users to the appropriate page. For this to work though, I need to be able to build the menu items dynamically so I can add extra data (e.g. the client ID from the grid) so that it can be included in the query string to the appropriate page.

blazorContextMenu.min.css returns a 404 error after updating to version 1.11.0

Describe the bug
After updating to 1.11.0 I keep getting a 404 error when loading BlazorContextMenu 1.11.0.

To Reproduce
Update BlazorContextMenu to version 1.11.0

Expected behavior
Update should work as expected.

Desktop (please complete the following information):

  • OS: Windows 10
  • Browser Chrome
  • Version 1.11.0

Failed to load resource: the server responded with a status of 404 ()

Downgrading to the previous version and reloading the site, bypassing the cache fixes it.

SubMenu position affected by Css backdrop-filter

Hi,

I'm trying to apply a backdrop filter on a context menu but it is affecting the sub menu position.

image

The idea is to have a transparent blured efect on the context menu.

CSS based on the dark template example:

div.dark-menu {
    color: #FFFFFF;
    background-color: rgba(52, 58, 64, 0.95);
    backdrop-filter: blur(2px) contrast(.3);
    width: 200px;
    margin: 0;
    padding: 0;
}

Could you help with this?

Thanks

Invalid cast exception when used in Child Component

When a context menu is used inside a child component, that is rendered more than once, it is rendered with wrong Data, which might easily lead to runtime exception:

<Child Item="@("abc")"/>
<Child Item="@(123)"/>

child.razor

@using BlazorContextMenu
@typeparam TItem
<ContextMenu Id="myMenu">
    <Item>Hello</Item>
    @if (((TItem)context.Data) != null)  @*invalid cast exception here*@
    {
        <Item>@context.Data</Item>
    }
</ContextMenu>

<ContextMenuTrigger MenuId="myMenu" Data="Item">
    <p>Right-click on me to show the context menu !!</p>
</ContextMenuTrigger>

@code {
[Parameter]
public TItem Item {get; set;}
}

To Reproduce
Steps to reproduce the behavior:

  1. Go to https://blazorrepl.com/repl/GlYewBvl362TrE7X05
  2. Click on 'Run'
  3. Right click second paragraph - it works
  4. Right click first paragraph - see error

Expected behavior
ContextMenu should not throw exception when correct data is passed

Feature: Programatically open context menu without ContextMenuTrigger

Is your feature request related to a problem? Please describe.
I need to manually handle right click event, resp. @OnContextMenu, in order to get some other details.

Particularly in my case I have a data grid component that handles @OnContextMenu for me:

protected virtual async Task OnContextMenuHandler(RowMouseEventArgs<TRow> args)
{
    MouseEventArgs mouseArgs = args.EventArgs
    var clickedCell = _grid.GetCell(args);
    //how to show  ContextMenu with clickedCell as Data parameter?
}

Describe the solution you'd like
I would love to see more decoupling from ContextMenuTrigger and ability to show ContextMenu programatically:

await _contexMenu.Show(mouseArgs.ClientX, mouseArgs.ClientY);

would you like me to submit PR?

Change Enabled property based on Data attribute

Is your feature request related to a problem? Please describe.
I want to toggle the Enabled property based on the currently selected item's Data attribute, so I can enable the item when a certain condition is true.

 <Item OnClick="@Synchronize" Enabled="@CanSynchronize(CurrentNode)">Synchronize</Item>

Describe the solution you'd like
It would be great if the Enabled property of a ContextMenuItem could be bound to an event handler that gets a similar structure to ItemClickEventArgsso I can get the current item's data attribute.

Describe alternatives you've considered
None

Additional context
None

component stop working after 1.7 upgarde

Hello, and thanks again for your component, it is very usefull for my app.

However, since i upgrade to 1.7, it completely stop working.

Whats happen is on my grid I listen the onContextMenu on the and i programmaticaly launch the contextMenu with _blazorContextMenuService. With 1.7 version, this event is never launch.

so for make it work, i have to select my row with left click and then make a right click to have the menu appaering.

I try to understand whats happen, Nothing sure but the stopPropagation you included in Item.razor and/or in the js seem cause this. (its strange beacuse normally it's not related, but it seem the best explication)

Do you think you can expose this behavior with an option ? like a boolean stopPropagation ?

thanks !

[Regression] OnAppearing is sometimes with ContextMenuTargetId null

Hi and thanks for your work !
I have a problem with your library since last versions (i don't know exactly wich one).
I use your library with table and use the "old" system, retrieve a ContextMenuTargetId and then i retrieve my element by myself in js.
I can't use the new version where you pass data because i need have the hand on the generated, so i kept the global trigger which include the table.

Now, depend where i click on the table, but sometimes i have ContextMenuTargetId null (which for me was normally impossible). So i can't retrieve my item.

It seem the first time i click on an element, it's OK, but then if i reclick on this element, the ContextMenuTargetId become null

Do you have an explanation for that ?

You will find a repro here : https://github.com/julienGrd/BlazorAppReproBugContextMenu

  • go to the fetch data
  • right click on the first row / first cell => normally is OK, menu is shown
  • reclick on the first row / first cell => the menu not show, if you debug the OnAppearing you will see the value null.

Good luck !

Context menu won't open on Firefox

I experience an issue on Firefox v84.0.2 (64-bit) in a Blazor WebAssembly application. When i right click on the SVG element that is wrapped by the ContextMenuTrigger component no menu appears. I don't experience this issue on Google Chrome or Microsoft Edge.

Example code:

<svg width="100%" height="100%">
    <ContextMenuTrigger WrapperTag="g" MenuId="menuId">
        <rect width="100%" height="100%" fill="red"></rect>
    </ContextMenuTrigger>
</svg>

<ContextMenu Id="menuId">
    <Item><i class="fas fa-plus fa-fw"></i> Add</Item>
</ContextMenu>

Update

Firefox has no support for the 'oncontextmenu' handler on SVG elements. I fixed it this way:

Add the following script to your index.html to disable the default browser context menu.

Script

<script>
    window.attachHandlers = () => {
        var elements = document.getElementsByClassName("disable-default-context-menu");
        
        for (var i = 0; i < elements.length; i++) {
            elements[i].addEventListener('contextmenu', e => {e.preventDefault()});
        }
    };
</script>

Than you can use the contextmenu on SVG items on the following way:

Usage:

<svg width="100%" height="100%">
    <g class="disable-default-context-menu" @onmouseup="@(e => OnRightClick(e))" oncontextmenu="return false;">
        <rect width="100%" height="100%" fill="red"></rect>
    </g>
</svg>

<ContextMenu Id="menuId">
    <Item><i class="fas fa-plus fa-fw"></i> Add</Item>
</ContextMenu>

@code {
        protected override void OnAfterRender(bool firstRender)
        {
            JsRuntime.InvokeVoidAsync("attachHandlers");
        }

        private async Task OnRightClick(MouseEventArgs args)
        {
            if (args.Button == 2)
            {
                await BlazorContextMenuService.ShowMenu("menuId", (int)args.ClientX, (int)args.ClientY);
            }
        }
}

'blazorContextMenu' was undefined

I made a exact basic sample provided and I got this error on running in .Net 6. Any idea why?

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Could not find 'blazorContextMenu.SetMenuHandlerReference' ('blazorContextMenu' was undefined).
      Error: Could not find 'blazorContextMenu.SetMenuHandlerReference' ('blazorContextMenu' was undefined).
          at https://localhost:44355/_framework/blazor.webassembly.js:1:328
          at Array.forEach (<anonymous>)
          at a.findFunction (https://localhost:44355/_framework/blazor.webassembly.js:1:296)
          at _ (https://localhost:44355/_framework/blazor.webassembly.js:1:2437)
          at https://localhost:44355/_framework/blazor.webassembly.js:1:3325
          at new Promise (<anonymous>)
          at Object.beginInvokeJSFromDotNet (https://localhost:44355/_framework/blazor.webassembly.js:1:3306)
          at Object.Rt [as invokeJSFromDotNet] (https://localhost:44355/_framework/blazor.webassembly.js:1:59738)
          at _mono_wasm_invoke_js_blazor (https://localhost:44355/_framework/dotnet.6.0.1.1jrhn1vj7r.js:1:194546)
          at wasm://wasm/009705ea:wasm-function[219]:0x1a129
Microsoft.JSInterop.JSException: Could not find 'blazorContextMenu.SetMenuHandlerReference' ('blazorContextMenu' was undefined).
Error: Could not find 'blazorContextMenu.SetMenuHandlerReference' ('blazorContextMenu' was undefined).
    at https://localhost:44355/_framework/blazor.webassembly.js:1:328
    at Array.forEach (<anonymous>)
    at a.findFunction (https://localhost:44355/_framework/blazor.webassembly.js:1:296)
    at _ (https://localhost:44355/_framework/blazor.webassembly.js:1:2437)
    at https://localhost:44355/_framework/blazor.webassembly.js:1:3325
    at new Promise (<anonymous>)
    at Object.beginInvokeJSFromDotNet (https://localhost:44355/_framework/blazor.webassembly.js:1:3306)
    at Object.Rt [as invokeJSFromDotNet] (https://localhost:44355/_framework/blazor.webassembly.js:1:59738)
    at _mono_wasm_invoke_js_blazor (https://localhost:44355/_framework/dotnet.6.0.1.1jrhn1vj7r.js:1:194546)
    at wasm://wasm/009705ea:wasm-function[219]:0x1a129
   at Microsoft.JSInterop.JSRuntime.<InvokeAsync>d__16`1[[System.Object, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
   at BlazorContextMenu.ContextMenuBase.OnAfterRenderAsync(Boolean firstRender)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)

any way to have an event like "Shown" on contextMenu

Hi and thanks for your work

It could be nice to Have an event when the contextMenu appear to run some piece of code (in my case, I would like to run some code wich determinate status of my menu, visibility, disabled, etc).

You think it's possible to integrate this on your next version ?

something like that

<ContextMenu Id="tableContextMenu" OnShown="@OnShown">

If you don't have time, I think I can integrate this if you want

  • 1 parameter of type Action on ContextMenu.razor
    [Parameter]
    public Action OnShown { get; protected set; }
  • in the internal void Show(string x, string y, string targetId)
    this.OnShown?.Invoke();

thanks !

In recursive structure OnClick doesn't work

I'm using .net 5.0 so Use 1.10.1 version

I use recursive structure because treeview.

and child component OnClick is not work...

mainlayout.razor

<div class="page">
    <BlazorContextMenu.ContextMenuTrigger MenuId="EditItem" StopPropagation="true">
        <div class="sidebar">
            @foreach (Model.TreeItemModel tree in db.trees)
            {
                <Component.TreeView Collapse="" Depth="0" Item="tree" />
            }
            <span class="@Collapse()"><i class="oi @CreateItemIcon()" /><input type="text" @bind-Value="@Name" @bind-Value:event="oninput" @onkeydown="@CreateKeyDown" placeholder="@Name item" @ref="Focusing" @onblur="OnBlur" /></span>
        </div>
    </BlazorContextMenu.ContextMenuTrigger>
    @Body
</div>

<BlazorContextMenu.ContextMenu Id="EditItem">
    <BlazorContextMenu.Item OnClick="@(e => OnClickContext(true))">New Folder</BlazorContextMenu.Item>
    <BlazorContextMenu.Item OnClick="@(e => OnClickContext(false))">New File</BlazorContextMenu.Item>
</BlazorContextMenu.ContextMenu>

this item OnClick is work

Component.Treeview.razor

 <div class="@Collapse">
        <BlazorContextMenu.ContextMenuTrigger MenuId="Edit">
            <button class="btn btn-block text-left" style="@Indent()" @onclick="@(()=>Collapsed=!Collapsed)">
                <i class="oi @CollapseIcon()" />
                @Item.Name
            </button> 
            <span class="@CollapseCreate()" style="@pIndent()"><i class="oi @CreateItemIcon()" /><input type="text" @bind-Value="@Name" @bind-Value:event="oninput" placeholder="New Item" @ref="Focusing" @onblur="OnBlur" /></span>
        </BlazorContextMenu.ContextMenuTrigger>
        @foreach (Model.TreeItemModel child in Item.Childs)
        {
            <TreeView Item=child Collapse="@(this.Collapsed ? "collapse":"")" Depth="@Depth" />
        }
</div>

<BlazorContextMenu.ContextMenu Id="Edit">
    <BlazorContextMenu.Item Id="Folder" OnClick="@EditingItem">New Folder</BlazorContextMenu.Item>
    <BlazorContextMenu.Item Id="File" OnClick="@(e => OnClickContext(false))">New File</BlazorContextMenu.Item>
    <BlazorContextMenu.Item Enabled="false">ReName</BlazorContextMenu.Item>
</BlazorContextMenu.ContextMenu>

but this not work

am I must use latest version and .net 6.0? or using wrong way?

Overwrite ContextMenuTrigger for some child elements

Describe the bug
When creating a second ContextMenuTrigger, within a ContextMenuTrigger, and an element within the inner trigger is clicked both are shown and not only the inner one.

To Reproduce
Run the following code:

<ContextMenuTrigger MenuId="menu">
    <div>
        <p>Test</p>
        <ContextMenuTrigger MenuId="special">
            <div>Special</div>
        </ContextMenuTrigger>
    </div>

</ContextMenuTrigger>

<ContextMenu Id="menu">
    <Item >Item 1</Item>
    <Item> Item 2</Item>
    <Item> Item 3</Item>
</ContextMenu>

<ContextMenu Id="special">
    <Item>Special</Item>
</ContextMenu>

And click on special.

Expected behavior
It should only show one menu with the item special.

Screenshots
image

Left click

Of course, right-click to get a context menu is normal.... But left clicking to a context menu can occasionally be useful.

I'm using a Blazor grid where I want the context menu click event to do something with the selected record. However, right clicking does not select the record. Left click does select the record. So it would be nice to left click to select AND show the context menu. Otherwise, the user has to left click select and then right click to get the context menu.

Nice to have ...

Thank you for this project!

right click twice to show context menu make the contexte menu unable to disappear

Describe the bug
if you right click twice for trigger a context menu, the context menu which appear cannot be closed by left-click outside

To Reproduce

  • right click on a context menu trigger, the context menu appear, left click outside, it disappear => OK
  • right click on a context menu trigger, the context menu appear, right click again, the context menu show again, left click outside, nothing happened. to hide them, you have to right click again and then left click outside

thanks !

Julien

Support touch devices by changing to pointer events

Is your feature request related to a problem? Please describe.
When using touch devices the context menu can't be hidden/closed by pressing outside the context menu as that uses events specific to a mouse.

Describe the solution you'd like
The places that mouse events are explicitly used we can change to using pointer-events instead. pointer-events are an event type that supports both mouses, touch input, and other pointer types and should not change the existing behaviour for mouse usage.

Additional context
I would like to make a PR for this.

SubMenu component doesn't use ContextMenuBase.ZIndex

Describe the bug

Unlike the ContextMenu component, the SubMenu component doesn't use ContextMenuBase.ZIndex.

This can lead to situations where, for example, the context menu trigger is on the right side of the page, it opens up the context menu to the left, then opens up a submenu back to the right, the top-level menu text can appear on top of the submenu area. It can depend on the top-to-bottom order of the context menu items in the DOM, since z-index isn't specified for them. If the "underneath" item is after the submenu, you'll see the item's whole text on top of the submenu. If not, you'll at least see the little submenu arrow on top.

The natural way to fix this would be for the developer-user to set ZIndex on the ContextMenu as well as all SubMenus. This doesn't work because SubMenu ignores ZIndex despite having access to it.

To Reproduce

Steps to reproduce the behavior:

  1. Clone/download the repro repo here:
  2. Build & run the "bug repro" project (a Blazor WASM app).
  3. Right-click the trigger paragraph on the right side of the index page.
    • Make sure you right-click pretty close to the right edge of the paragraph, so that the submenu is forced to open to the left.
  4. Navigate to the submenu and then the sub-submenu.
  5. See the top-level menu elements appear on top of the sub-submenu area.

Expected behavior

Each submenu and all of its content should appear on top of all ancestor-ish menu content, at least as long as I'm properly setting the ZIndex property on all SubMenu components.

Screenshots

image

Desktop:

  • OS: Windows 10
  • Browser: Edge
  • Version: 100.0.1185.50 (Official build) (64-bit)

Additional context

The fix (or a workaround) appears to be as simple as adding the same z-index setting already in ContextMenu.razor to SubMenu.razor. The developer still has to arrange their own ZIndex values over the submenus, but that's probably not a big deal. Otherwise, the library itself would have to try to intelligently set the ZIndex values. Maybe that's easy? Dunno.

Not overriding browser's oncontextmenu

I may be missing something or doing it wrong, but when I right-click on an element that has the ContextMenuTrigger div surrounding it, I still get the context menu that the browser displays when I right-click anywhere on the page. I think there is supposed to be some way that the component overrides the default context menu to display the one I defined with the ContextMenu component.

Update After starting this new issue, I tried putting the ContextMenuTrigger around some other text outside the InputSelect block, and it works. Apparently, things don't work when trying to use this around the content of an option in a select.
Is this a known limitation?

When I use "Inspect", I see the divs generated by the BlazorContextMenu component, as I would expect. I just don't get the context menu I want; I still get the default one from the browser.

I'm on Windows 10 latest, with latest Edge browser. Also tried Brave browser.

Here is the relevant code in the .razor file, if it makes any difference:

<ContextMenu Id=@($"itemMenu{ColSearch.SName}")>
    <Item OnClick="@OnClickDelete">Delete</Item>
</ContextMenu>

<div class="form-group col-auto">
    <button type="button" id="Sel@(ColSearch.SName)" disabled="@(Report == null)" class="btn btn-dark" @onclick="() => OpenSearchDialog()" >@ColSearch.SName</button>
    <InputSelect @bind-Value="@SelectedItems" aria-label=@($"Select {ColSearch.SName}") size="8" class="form-control">
        @if ( ColSearch.AFiltItems.Count == 0 )
        {
            <option value="[all]" disabled selected>[all]</option>
        }
        else
        {
            foreach ( FilterSelectDialog.SelItem sel in ColSearch.AFiltItems )
            {
                <option value="@sel.sKey">
                    <ContextMenuTrigger MenuId=@($"itemMenu{ColSearch.SName}")>@sel.sValue</ContextMenuTrigger>
                </option>
            }
        }
    </InputSelect>
</div>

Support Touch and Mobile

Wondering if there are plans to support mobile browsers.
For example using Google Chrome or Firefox on iOS.

Maybe events like:
double tap/ long tap?

Checkbox functionality on menu

Is there a way to have a menu item show a check or check box. I would like to be able to turn the check on and off without actually closing the menu. This would be used for adding/removing a song on several playlists.

Long context menu items can overlap the fixed-width (200px) context menu

Is your feature request related to a problem? Please describe.
When the text contained in a menu item exceeds a certain number of characters, the text gets drawn above the 200px width menu item. Changing the width to something bigger than 200px using CSS works, however, then the position for the submenus is not correct.

Describe the solution you'd like
BlazorContextMenu should automatically adjust the width to the content of the menu item. Alternatively, it should allow for a width setting on the BlazorContextMenu tag in the razor file.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.