Skip to content

Commit

Permalink
fix(vmenu): ignore key presses when disable-keys is true
Browse files Browse the repository at this point in the history
  • Loading branch information
tc-kelpiffner committed Jan 17, 2023
1 parent 86b0ffb commit 01c7ea5
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 @@ -454,6 +454,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 01c7ea5

Please sign in to comment.