aragon/ui

Modal: EscapeOutside causing premature modal closing with internal interactions

andy-hook opened this issue · 0 comments

I've run up against an issue multiple times where EscapeOutside checks for the existence of the target element too late in the event queue, causing a premature closing of the modal.

This is common when you want to hide an interactive element after it's been clicked. For example you might store some state on whether to show or hide a button:

const [buttonVisible, setButtonVisible] = useState(true)

......
<Modal>
    {buttonVisible && <Button onClick={() => setButtonVisible(false)}/>}
</Modal>

Button is clicked (modal catches click event)
State is updated and Button is removed from DOM
EscapeOutside searches the contents of the modal for the event.target node
EscapeOutside deems this as an outside click because the Button was removed before the modal click fired.

This problem is often masked when using animations as nodes stick around long enough to be checked.

It might just be a case of using onmousedown instead of click. Another option could be to assign a handler to the background scrim that closes the modal, that way the intent is explicit and we sidestep dealing with event.target.