Custom Escape close handler for modal Popover?

I’m doing my own Combobox-like component with a TextField and an anchored Popover.
When focus is inside the popover and user presses Escape, I want the Popover to close and set input focus back to the TextField.

The Popover is modal, because I also want to keep it open both when focus is in TextField and in the Popover. That was a whole separate issue.

If I let the Popover handle Escape, with setCloseOnEsc(true) then the focus is just lost.
I have tried adding extra shortcutListener on the Popover, but it is not called.

If I call setCloseOnEsc(false), then nothing happens, and my shortcutListeners are still not called.

So I assume the overlay swallows the Escape. Any way I can get around that?

Have you tried with Popover::addOpenedChangeListener(ComponentEventListener) and then focus the text field in the handler?

Adding a shortcut listener on the popover probably won’t work because the event actually comes from the popover’s overlay, which is a separate element in the DOM. Maybe you could wrap your popover content in a div and register the listener on that.

Say I have:

  • Field A : My special field with an open Popover which has focus.
  • Field B : A regular TextField

If user clicks in Field B I want focus to end up there. I don’t want to steal it back to Field A

This seems to work as a basic example:

Input input = new Input();
add(input);

Popover popover = new Popover();
popover.setCloseOnEsc(false);
popover.setModal(true);
popover.setTarget(input);

Div content = new Div();
NativeButton button = new NativeButton("Some to focus");
content.add(button);
popover.add(content);

Shortcuts.addShortcutListener(content, () -> {
    popover.setOpened(false);
    input.focus();
}, Key.ESCAPE);

Also, when opening the popover by focusing or clicking the input, it does revert the focus back to the input on Escape press when using setCloseOnEsc(true). It only doesn’t do that when opening on hover.

That does actually work.
I had already tried it, but I had a bug in the code :grinning:

Thanks

1 Like

This should hopefully become easier in v25, where the plan is to use the native HTML popover API. That would allow us adding the overlay as a child of the popover element, so the event can be listened for on the popover itself.