Merge pull request #7731 from ouchihao/codex/bug-dialog-escape-stack

fix(ui): limit Escape to the most recently opened dialog
This commit is contained in:
Wesley Liddick
2026-10-08 13:49:34 +08:00
committed by GitHub
2 changed files with 31 additions and 1 deletions
@@ -111,7 +111,7 @@ const handleClose = () => {
}
const handleEscape = (event: KeyboardEvent) => {
if (props.show && props.closeOnEscape && event.key === 'Escape') {
if (props.show && props.closeOnEscape && event.key === 'Escape' && [...openDialogs].pop() === dialogId) {
emit('close')
}
}
@@ -0,0 +1,30 @@
import { afterEach, describe, expect, it } from 'vitest'
import { enableAutoUnmount, mount } from '@vue/test-utils'
import BaseDialog from '../BaseDialog.vue'
enableAutoUnmount(afterEach)
const pressEscape = () => document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' }))
describe('stacked dialog Escape handling', () => {
it('closes only the most recently opened dialog, then allows the parent to close', async () => {
const parent = mount(BaseDialog, { props: { show: true, title: 'Parent' } })
const child = mount(BaseDialog, { props: { show: true, title: 'Child' } })
pressEscape()
expect(child.emitted('close')).toHaveLength(1)
expect(parent.emitted('close')).toBeUndefined()
await child.setProps({ show: false })
pressEscape()
expect(parent.emitted('close')).toHaveLength(1)
})
it('does not dismiss a parent behind a child that disallows Escape', () => {
const parent = mount(BaseDialog, { props: { show: true, title: 'Parent' } })
const child = mount(BaseDialog, { props: { show: true, title: 'Child', closeOnEscape: false } })
pressEscape()
expect(child.emitted('close')).toBeUndefined()
expect(parent.emitted('close')).toBeUndefined()
child.unmount()
pressEscape()
expect(parent.emitted('close')).toHaveLength(1)
})
})