-
Notifications
You must be signed in to change notification settings - Fork 123
Expand file tree
/
Copy pathToolBarLogic.js
More file actions
87 lines (81 loc) · 2.82 KB
/
Copy pathToolBarLogic.js
File metadata and controls
87 lines (81 loc) · 2.82 KB
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
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { defineComponent } from 'vue'
export default defineComponent({
data() {
return {
/** Current menu entry that has focus */
activeMenuEntry: 0,
entries: [],
}
},
computed: {
visibleEntries() {
return this.entries
},
},
watch: {
visibleEntries() {
this.$nextTick(() => {
if (this.activeMenuEntry > this.visibleEntries.length || this.visibleEntries[this.activeMenuEntry]?.disabled) {
this.setNextMenuEntry()
}
})
},
},
methods: {
/**
* Update the disabled state of an menu entry
* @param {string} menuKey The key of the menu entry that changed
* @param {boolean} state The new disabled state
*/
disableMenuEntry(menuKey, state) {
const index = this.visibleEntries.findIndex(({ key }) => key === menuKey)
this.visibleEntries[index].disabled = state
if (state === false && this.activeMenuEntry === index) {
this.$nextTick(() => this.setNextMenuEntry())
}
},
/**
* Set the active menu entry to the next one (or reset to first)
*/
setNextMenuEntry() {
// refs is not reactive so we must check this every time
const modulo = this.visibleEntries.length + (this.$refs.remainingEntries ? 1 : 0)
do {
this.activeMenuEntry = (this.activeMenuEntry + 1) % modulo
} while (this.activeMenuEntry < this.visibleEntries.length && this.visibleEntries[this.activeMenuEntry].disabled)
},
/**
* Set the active menu entry to the previous one (or reset to last entry (remaining actions))
*/
setPreviousMenuEntry() {
// refs is not reactive so we must check this every time
const modulo = this.visibleEntries.length + (this.$refs.remainingEntries ? 1 : 0)
do {
const index = this.activeMenuEntry - 1
this.activeMenuEntry = ((index % modulo) + modulo) % modulo // needed as JS does not work with negative modulos
} while (this.activeMenuEntry < this.visibleEntries.length && this.visibleEntries[this.activeMenuEntry].disabled)
},
/**
* Handle navigation in toolbar
* @param {KeyboardEvent} event The keyup event
*/
handleToolbarNavigation(event) {
if (event.key === 'ArrowRight') {
this.setNextMenuEntry()
} else if (event.key === 'ArrowLeft') {
this.setPreviousMenuEntry()
}
if (this.activeMenuEntry === this.visibleEntries.length) {
this.$refs.remainingEntries?.focusButton?.()
} else {
// The ref is in no order (ordered by the time they needed to mount), so we need to order them like they are shown on the menu
const entries = [...this.$refs.menuEntries].sort((a, b) => this.visibleEntries.findIndex(({ key }) => key === a.$vnode.data.key) - this.visibleEntries.findIndex(({ key }) => key === b.$vnode.data.key))
entries[this.activeMenuEntry].focusButton()
}
},
},
})