Skip to content

Use CloseWatcher API when available#1074

Draft
noahm wants to merge 3 commits intoreactjs:masterfrom
noahm:closewatcher
Draft

Use CloseWatcher API when available#1074
noahm wants to merge 3 commits intoreactjs:masterfrom
noahm:closewatcher

Conversation

@noahm
Copy link

@noahm noahm commented Feb 6, 2026

This issue was first raised years ago in #875 when CloseWatcher was just a proposal. Now it is part of the official HTML spec. Chrome has been shipping this since v126 (June 2024) and Firefox has an implementation behind a feature flag.

This PR takes a progressive enhancement approach. If the API is available it is used instead of ordinary Escape keydown events for closing.

However, there's a big potential pitfall with this naive approach: when a CloseWatcher emits a close event, it will be destroyed and no further events emitted. This library's design is at odds with this, where consumers control the open state, and can choose not to respond to a requested close.

The correct behavior from the CloseWatcher's perspective is to also listen to cancel events, and call preventDefault on those. This PR attempts to do that as long as shouldCloseOnEsc is false, but there's nothing requiring consumers to pass that instead of simply deciding not to respond to a onRequestClose callback. If consumers don't idiomatically pass shouldCloseOnEsc and instead just ignore onRequestClose, the Escape/back key will not be able to close the modal after the first attempt, as the CloseWatcher would have been destroyed at that point.

I believe strongly in adding support for CloseWatcher to this package now, in spite of this pitfall. Perhaps we could introduce an additional shouldCloseByCloseWatcher prop, to let consumers opt-in to the progressive enhancement of CloseWatcher? By starting with an opt-in approach, consumers can adjust their usage to always respect a onRequestClose callback.

Acceptance Checklist:

  • Tests
    • This is a bit tricky. In order to fully test CloseWatcher we need a way to trigger trusted keypress events in the browser, rather than merely sending synthetic events via React Test Library. I'm not very familiar with mocha/karma but I poked around didn't see an easy way to do this.
  • Documentation and examples (if needed)
    • This doesn't change the API at all, but we could add additional clarification that shouldCloseOnEsc={false} now also prevents closing with Android's back button.

noahm added 3 commits February 5, 2026 12:10
to properly test this we need a way to trigger trusted keydown events in the browser
by simply not responding to onclose the CloseWatcher would be destroyed and not respond to future close attempts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant