-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathKeyboardMenu.js
90 lines (79 loc) · 3.34 KB
/
KeyboardMenu.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
class KeyboardMenu {
constructor(config={}) {
this.options = [] //set by updater method
this.up = null
this.down = null
this.prevFocus = null
this.descriptionContainer = config.descriptionContainer || null
}
setOptions(options) {
this.options = options
this.element.innerHTML = this.options.map((option,index) => {
const disabledAttr = option.disabled ? "disabled" : ""
return (`
<div class="option">
<button ${disabledAttr} data-button="${index}" data-description="${option.description}">
${option.label}
</button>
<span class="right">${option.right ? option.right() : ""}</span>
</div>
`)
}).join("")
this.element.querySelectorAll("button").forEach(button => {
button.addEventListener("click", () => {
const chosenOption = this.options[Number(button.dataset.button)]
chosenOption.handler()
})
button.addEventListener("mouseenter", () => {
button.focus()
})
button.addEventListener("focus", () => {
this.prevFocus = button
this.descriptionElementText.innerText = button.dataset.description
})
})
setTimeout(() => {
this.element.querySelector("button[data-button]:not([disabled])").focus()
}, 10)
}
createElement() {
this.element = document.createElement("div")
this.element.classList.add("KeyboardMenu")
this.descriptionElement = document.createElement("div")
this.descriptionElement.classList.add("DescriptionBox")
this.descriptionElement.innerHTML = (`<p>I will provide information!</p>`)
this.descriptionElementText = this.descriptionElement.querySelector("p")
}
end() {
//Remove menu element and description element
this.element.remove()
this.descriptionElement.remove()
//Clean up bindings
this.up.unbind()
this.down.unbind()
}
init(container){
this.createElement()
// (this.descriptionContainer || container).appendChild(this.descriptionElement)
if (this.descriptionContainer){
this.descriptionContainer.appendChild(this.descriptionElement)
} else {
container.appendChild(this.descriptionElement)
}
container.appendChild(this.element)
this.up = new KeyPressListener("ArrowUp", () => {
const current = Number(this.prevFocus.getAttribute("data-button"))
const prevButton = Array.from(this.element.querySelectorAll("button[data-button]")).reverse().find(el => {
return el.dataset.button < current && !el.disabled
})
prevButton?.focus()
})
this.down = new KeyPressListener("ArrowDown", () => {
const current = Number(this.prevFocus.getAttribute("data-button"))
const nextButton = Array.from(this.element.querySelectorAll("button[data-button]")).find(el => {
return el.dataset.button > current && !el.disabled
})
nextButton?.focus()
})
}
}