Skip to content

Commit

Permalink
fix(VMenu): ignore key presses when disable-keys is true (#16464)
Browse files Browse the repository at this point in the history
fixes #12998
  • Loading branch information
kevin-ireland-tc authored and KaelWD committed Jul 5, 2023
1 parent 734bff1 commit 922e05a
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 0 deletions.
2 changes: 2 additions & 0 deletions packages/vuetify/src/components/VMenu/VMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,8 @@ export default baseMixins.extend({
if (tile.tabIndex === -1) this.nextTile()
},
onKeyDown (e: KeyboardEvent) {
if (this.disableKeys) return

if (e.keyCode === keyCodes.esc) {
// Wait for dependent elements to close first
setTimeout(() => { this.isActive = false })
Expand Down
130 changes: 130 additions & 0 deletions packages/vuetify/src/components/VMenu/__tests__/VMenu.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,37 @@ describe('VMenu.ts', () => {
expect('Unable to locate target [data-app]').toHaveBeenTipped()
})

it('should be able to navigate the menu list with up and down keys', async () => {
const event = (keyCode: number) => new KeyboardEvent('keydown', { keyCode })
const wrapper = mountFunction({
propsData: { eager: true },
scopedSlots: {
default () {
return this.$createElement('div', [
this.$createElement(VListItem, { props: { link: true } }),
this.$createElement(VListItem, { props: { link: true } }),
])
},
},
})

wrapper.setData({ isActive: true })

wrapper.vm.onKeyDown(event(keyCodes.down))

await wrapper.vm.$nextTick()

expect(wrapper.vm.listIndex).toBe(0)

wrapper.vm.onKeyDown(event(keyCodes.up))

await wrapper.vm.$nextTick()

expect(wrapper.vm.listIndex).toBe(1)

expect('Unable to locate target [data-app]').toHaveBeenTipped()
})

it('should select first or last item when pressing home or end on active menu', async () => {
const event = (keyCode: number) => new KeyboardEvent('keydown', { keyCode })
const wrapper = mountFunction({
Expand Down Expand Up @@ -291,4 +322,103 @@ describe('VMenu.ts', () => {

expect('Unable to locate target [data-app]').toHaveBeenTipped()
})

it('should deactivate when escape is pressed', async () => {
jest.useFakeTimers()
const event = (keyCode: number) => new KeyboardEvent('keydown', { keyCode })
const wrapper = mountFunction({
propsData: { eager: true },
})

wrapper.setData({ isActive: true })

wrapper.vm.onKeyDown(event(keyCodes.esc))

await wrapper.vm.$nextTick()
jest.runAllTimers()

expect(wrapper.vm.isActive).toBe(false)

expect('Unable to locate target [data-app]').toHaveBeenTipped()
jest.useRealTimers()
})

it('should disable escape key when disableKeys is true', async () => {
const event = (keyCode: number) => new KeyboardEvent('keydown', { keyCode })
const wrapper = mountFunction({
propsData: {
eager: true,
disableKeys: true,
},
})

wrapper.setData({ isActive: true })

wrapper.vm.onKeyDown(event(keyCodes.esc))

await wrapper.vm.$nextTick()

expect(wrapper.vm.isActive).toBe(true)

expect('Unable to locate target [data-app]').toHaveBeenTipped()
})

it('should disable navigation keys when disableKeys is true', async () => {
const event = (keyCode: number) => new KeyboardEvent('keydown', { keyCode })
const wrapper = mountFunction({
propsData: {
eager: true,
disableKeys: true,
},
scopedSlots: {
default () {
return this.$createElement('div', [
this.$createElement(VListItem, { props: { link: true } }),
])
},
},
})

wrapper.setData({ isActive: true })

wrapper.vm.onKeyDown(event(keyCodes.up))
await wrapper.vm.$nextTick()
expect(wrapper.vm.listIndex).toBe(-1)

wrapper.vm.onKeyDown(event(keyCodes.down))
await wrapper.vm.$nextTick()
expect(wrapper.vm.listIndex).toBe(-1)

wrapper.vm.onKeyDown(event(keyCodes.end))
await wrapper.vm.$nextTick()
expect(wrapper.vm.listIndex).toBe(-1)

wrapper.vm.onKeyDown(event(keyCodes.home))
await wrapper.vm.$nextTick()
expect(wrapper.vm.listIndex).toBe(-1)

expect('Unable to locate target [data-app]').toHaveBeenTipped()
})

it('should not open menu on up or down press when disableKeys is true', async () => {
const event = (keyCode: number) => new KeyboardEvent('keydown', { keyCode })
const wrapper = mountFunction({
propsData: {
eager: true,
disableKeys: true,
},
})

wrapper.vm.onKeyDown(event(keyCodes.up))
await wrapper.vm.$nextTick()
expect(wrapper.vm.isActive).toBe(false)
expect(wrapper.vm.listIndex).toBe(-1)

wrapper.vm.onKeyDown(event(keyCodes.down))
await wrapper.vm.$nextTick()
expect(wrapper.vm.isActive).toBe(false)
expect(wrapper.vm.listIndex).toBe(-1)

expect('Unable to locate target [data-app]').toHaveBeenTipped()
})
})

0 comments on commit 922e05a

Please sign in to comment.