flow-components
flow-components copied to clipboard
Add MenuBar submenu open/close listener
Describe your motivation
A PopupButton is really easy to be implemented on top of a MenuBar with single Menu Item, which opens a Component contents when clicked. It's always good to have an open/close listener for the PopupButton, to perhaps populate or update the popup contens lazily.
Describe the solution you'd like
A MenuBar MenuItem could have a submenu open/close listener which would get fired when the submenu is being shown or hidden.
Describe alternatives you've considered
No response
Additional context
No response
Workaround:
public class VovMenuBar extends MenuBar {
public static class PopupVisibilityEvent
extends ComponentEvent<MenuBar> {
private final boolean isVisible;
public PopupVisibilityEvent(MenuBar source, boolean isVisible, boolean fromClient) {
super(source, fromClient);
this.isVisible = isVisible;
}
public boolean isVisible() {
return isVisible;
}
}
@ClientCallable
private void onPopupOpened(boolean opened) {
fireEvent(new PopupVisibilityEvent(this, opened, true));
}
@NotNull
public Registration addPopupVisibilityListener(@NotNull ComponentEventListener<PopupVisibilityEvent> listener) {
return addListener(PopupVisibilityEvent.class, listener);
}
@Override
protected void onAttach(AttachEvent attachEvent) {
super.onAttach(attachEvent);
getElement().executeJs("self = this; this._subMenu.$.overlay.addEventListener('opened-changed', e => self.$server.onPopupOpened(e.detail.value));");
}
/**
* Closes the menu submenu overlay. Does nothing if the popup button is already closed.
*/
public void closeSubmenuOverlay() {
// workaround for https://github.com/vaadin/vaadin-menu-bar/issues/102
getElement().executeJs("this._subMenu.close()");
}
}