MenuBar Hovering dont close submenu: Bug or Feature?

Hi,

i have a menu bar with a sub menu and open on hover activated. But once i leave the menu with the mouse, the submenu does not disappear.

Any suggestion how i could archieve it?

MenuBar menuBar = new MenuBar();
        menuBar.addThemeVariants(MenuBarVariant.LUMO_SMALL);
        menuBar.setOpenOnHover(true);
        MenuItem item = menuBar.addItem(new Div(new Span("Optionen")));
        item.getStyle().setCursor("pointer");

        SubMenu subMenu = item.getSubMenu();

        Icon eye = VaadinIcon.EYE.create();
        eye.getStyle().set("width", "20px").set("margin-right", "8px");
        Span openText = new Span("Ă–ffnen");
        subMenu.addItem(new Div(eye, openText));

And also i would like to have a arrow down next to the which indicates “there is more” but when i add a Icon and i resize the browser to smartphone, the menu gets an aroow automatically .:thinking: Wouldnt it be nice to have the arrow always visible (down) or set it via an API?

image

I have this behavior since several versions. It closes if you hover on another item on the menubar, but not when leaving the submenu in any other direction.

That seems like a bug. Its unnormal behaviour which i did not aspect as a user.

I have this menubar in a grid for each row (because there is now button which options available). This makes it even harder to use

Edit: will open an issue. For now i will go with a select component

1 Like

Hey Nico, I wrote this javascript function that does an auto close after 500ms when the mouse leaves the element.
You need to execute this when the submenu is opened:

MenuItem item = menuBar.addItem(new Div(new Span("Optionen")));
item.addClickListener(cEvent -> {
     item.getElement().executeJs(/* js from below here */);
});
setTimeout(() => {
    const overlays = document.getElementsByTagName('vaadin-menu-bar-overlay')
    for (const overlay of overlays) {
        if (overlay.getAttribute("data-autoclose")) {
            continue
        }
        const target = overlay.shadowRoot?.getElementById('overlay')
        if (target) {
            let timeout;
            overlay.setAttribute('data-autoclose', "true")
            target.addEventListener('mouseleave', e => timeout = setTimeout(() => overlay.opened = false, 500))
            target.addEventListener('mouseenter', e => clearTimeout(timeout))
        }
    }
}, 100);
  • Search for all Menubar overlay. Only one should be there by Vaadin’s design.
  • Gets the most outer visible element from shadow dom
  • Add a mouseleave listener that closes the overlay after 500ms
  • Add a mouseenter listener that cancels the close when the mouse is inside the overlay within the 500ms
  • Set “data-autoclose” to prevent a doubled registration

PS: only tested in Hilla, but I think I will actually use that in my Flow project.

PPS: does not work good when multiple menuitems are in the same menubar, because the overlay is client sided re-used and then closes when switching submenus on hover :D