element-plus/packages/utils/menu/submenu.ts

65 lines
1.6 KiB
TypeScript
Raw Normal View History

import { EVENT_CODE, triggerEvent } from '../aria'
2020-07-28 17:48:40 +08:00
import MenuItem from './menu-item'
class SubMenu {
public subMenuItems: NodeList
public subIndex = 0
constructor(public parent: MenuItem, public domNode: ParentNode) {
this.subIndex = 0
this.init()
}
init(): void {
this.subMenuItems = this.domNode.querySelectorAll('li')
this.addListeners()
}
gotoSubIndex(idx: number): void {
if (idx === this.subMenuItems.length) {
idx = 0
} else if (idx < 0) {
idx = this.subMenuItems.length - 1
}
(this.subMenuItems[idx] as HTMLElement).focus()
this.subIndex = idx
}
addListeners(): void {
const parentNode = this.parent.domNode
Array.prototype.forEach.call(this.subMenuItems, (el: Element) => {
el.addEventListener('keydown', (event: KeyboardEvent) => {
let prevDef = false
switch (event.code) {
case EVENT_CODE.down: {
2020-07-28 17:48:40 +08:00
this.gotoSubIndex(this.subIndex + 1)
prevDef = true
break
}
case EVENT_CODE.up: {
2020-07-28 17:48:40 +08:00
this.gotoSubIndex(this.subIndex - 1)
prevDef = true
break
}
case EVENT_CODE.tab: {
2020-07-28 17:48:40 +08:00
triggerEvent(parentNode as HTMLElement, 'mouseleave')
break
}
case EVENT_CODE.enter:
case EVENT_CODE.space: {
2020-07-28 17:48:40 +08:00
prevDef = true
;(event.currentTarget as HTMLElement).click()
2020-07-28 17:48:40 +08:00
break
}
}
if (prevDef) {
event.preventDefault()
event.stopPropagation()
}
return false
})
})
}
}
export default SubMenu