How do I catch Escape key and prevent dialog from closing?

So far I have this

if (e.key === "Escape") {
    console.log("ESCAPE")

    e.preventDefault()
    e.stopPropagation()
}

I get ESCAPE logged to console, but dialog still closes. Is there a way to prevent this?

So I found that dialogs cancel event can be caught, but it still does not work. Is this a lack of feature in UXP?

Example solution
And cancel event docs

Does the cancel event get logged? I assume it’s not implemented like some other events too (scroll, I think).
So even if you capture the keyboard event, that one is probably not the one that causes the dialog cancel internally.

Yes, it does get logged

Alright, I can confirm the same behavior. Most likely, window/dialog closing happens on Photoshop UI level and not panel/plugin level.
Also, you should reconsider if that’s the best thing to do in the first place. What’s your use case to block the Escape key from closing the dialog? In my opinion that’s bad UX. Imagine you could overwrite the “X”-behavior and prevent users from closing your plugin panel :smiley:

I have an absolutely placed sp-menu under the sp-textfield replicating autocomplete select. When this menu is open, I have a lot of events bound to it and document. When menu closes, events are unbound and everything works as usual. I want escape to close that menu while it’s open. Second escape would close the dialog without any issue

Ah, got it. In this case it makes somewhat sense then. I guess, only Adobe staff can answer this question then, but if I were you I wouldn’t have much hope that this will be implemented :confused:

I don’t, TBH :smiley: There’re lots of CSS/JS features I miss, that I doubt would be implemented

To be fair, it’s quite a specific use case. I’d try to make the menu UX as convenient as possible by closing it on click outside and so on (maybe that’s even default? I don’t remember). No keyboard interaction unfortunately, but better than nothing.

I already did this :slight_smile: But still, I’m so used to closing such menus with Escape, I always manage to close the dialog itself

Just noticed, <sp-picker><sp-menu /></sp-picker> does exactly what I want - prevents dialog close on Escape while picker is open. Wonder if there’s a way to achieve that with custom sp-menu :thinking: Maybe @kerrishotts would be so kind to provide some insight (now I have some hope :sweat_smile:)

During todays dev session @kerrishotts mentioned it’s by design, so that users would be able to close dialog with ESC :thinking: Wonder why [x] in the dialog corner is not enough if for whatever reason developer forgets to add a Close button and overrides ESC key event

I should note that not all dialogs have chrome that includes the option to close a dialog. (This is true for XD in particular, but you can get dialogs in PS w/o this as well.) ESC is always the escape hatch for closing a dialog w/o any other affordance for closing.

For the sp-menu use case, if it’s embedded in an sp-popover and the user has opened the popover, ESC will only close the popover.

Example:

<sp-overlay>
  <sp-action-button slot="trigger">Click</sp-action-button>
  <sp-popover offset="0" placement="below" alignment="left" appearance="none" slot="click">
    <sp-menu style="width:100px">
       <sp-menu-item>Chicago</sp-menu-item>
       <sp-menu-item>Chicago</sp-menu-item>
       <sp-menu-item>Chicago</sp-menu-item>
       <sp-menu-item>Chicago</sp-menu-item>
    </sp-menu>
  </sp-popover>
</sp-overlay>

But popovers will wreak havoc with focus, so while you can force the popover to appear outside of a user interaction (like clicking on this button) as part of an autocomplete control, the popover will steal focus… so may not work in this particular case.

Is it this overlay? I can’t find <sp-overlay/> docs