You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Tearsheet: Escape should only close the active topmost layer #989
When a Tearsheet opens another modal, such as a file-selection modal, pressing Escape closes both the modal and the underlying Tearsheet.
This suggests that the Escape-key event is being handled by multiple layers rather
than only by the active topmost layer. With stacked Tearsheets, the same behavior
could dismiss multiple workflow levels with a single keypress and unexpectedly
discard in-progress work.
Steps to reproduce
Open a Tearsheet.
Open a modal or file-selection flow from within the Tearsheet.
Press Escape.
Observe that both the nested modal and the underlying Tearsheet close.
Repeat with multiple stacked Tearsheets and verify whether one Escape
dismisses more than the active layer.
Here I hit escape to cancel out of the modal but all views are closed:
Expected behavior
Pressing Escape should dismiss only the active topmost modal or Tearsheet.
Underlying layers should remain open, and the event should not continue to
trigger their close handlers.
Hi @nickmazzi . At the moment it should be possible to tweak the Escape press behavior via the onEscapePress prop on Tearsheet/Modal, similar to our Modal with Dropdown example. in that example we're checking if the Dropdowwn is open (if it is, we can assume focus is on/in the dropdown or its toggle) and closing the MenuToggle only on Escape, otherwise we close the Modal.
Our base Modal by default uses whatever is passed to the onClose prop for its Escape key press logic, and adds an eventlistener, so that'd explain partially why Escape is closing all the modals/tearsheets.
For the Stacked Tearsheet example that was added in #954, I added the following:
And passed onEscapePress={onEscapePress} to each Tearsheet in that example and Escape only closed the immediate layer (only passed onEscapePress to the "base" or lowest level Tearsheet also worked fine since it's all being fired off the onkeydown eventlistener). Not the prettiest, but something like that should work whether you're dealing with only Tearsheets or Tearsheets and Modals like you described.
I think if we were to try and finagle the code on the PatternFly side, it'd have to be in our React repo on the Modal component, since Tearsheet is just using our Modal component.
Now it's just a question of whether we add this implementation to the <Modal/> or to the <Tearsheet/>. That, or leave it up to consumers to decide on the behaviour
Activity
thatblindgeye commentedon Oct 2, 2026
Hi @nickmazzi . At the moment it should be possible to tweak the Escape press behavior via the onEscapePress prop on Tearsheet/Modal, similar to our Modal with Dropdown example. in that example we're checking if the Dropdowwn is open (if it is, we can assume focus is on/in the dropdown or its toggle) and closing the MenuToggle only on Escape, otherwise we close the Modal.
Our base Modal by default uses whatever is passed to the onClose prop for its Escape key press logic, and adds an eventlistener, so that'd explain partially why Escape is closing all the modals/tearsheets.
For the Stacked Tearsheet example that was added in #954, I added the following:
And passed
onEscapePress={onEscapePress}to each Tearsheet in that example and Escape only closed the immediate layer (only passed onEscapePress to the "base" or lowest level Tearsheet also worked fine since it's all being fired off the onkeydown eventlistener). Not the prettiest, but something like that should work whether you're dealing with only Tearsheets or Tearsheets and Modals like you described.I think if we were to try and finagle the code on the PatternFly side, it'd have to be in our React repo on the Modal component, since Tearsheet is just using our Modal component.
GAUNSD commentedon Oct 2, 2026
Now it's just a question of whether we add this implementation to the
<Modal/>or to the<Tearsheet/>. That, or leave it up to consumers to decide on the behaviour