Keyboard navigation for Tree

pull/41/head
cagataycivici 2019-07-31 18:42:49 +03:00
parent b9c040d723
commit 58ab99c03d
1 changed files with 97 additions and 1 deletions

View File

@ -1,6 +1,6 @@
<template>
<li :class="containerClass">
<div class="p-treenode-content" tabindex="0" role="treeitem">
<div class="p-treenode-content" tabindex="0" role="treeitem" @click="onClick" @keydown="onKeyDown" :aria-expanded="expanded">
<span class="p-tree-toggler p-unselectable-text p-link" @click="toggle">
<span :class="toggleIcon"></span>
</span>
@ -15,6 +15,8 @@
</template>
<script>
import DomHandler from '../utils/DomHandler';
export default {
name: 'sub-treenode',
props: {
@ -33,6 +35,100 @@ export default {
},
onChildNodeToggle(node) {
this.$emit('toggle', node);
},
onClick() {
},
onKeyDown(event) {
const nodeElement = event.target.parentElement;
switch (event.which) {
//down arrow
case 40:
const listElement = nodeElement.children[1];
if (listElement) {
this.focusNode(listElement.children[0]);
}
else {
const nextNodeElement = nodeElement.nextElementSibling;
if (nextNodeElement) {
this.focusNode(nextNodeElement);
}
else {
let nextSiblingAncestor = this.findNextSiblingOfAncestor(nodeElement);
if (nextSiblingAncestor) {
this.focusNode(nextSiblingAncestor);
}
}
}
event.preventDefault();
break;
//up arrow
case 38:
if (nodeElement.previousElementSibling) {
this.focusNode(this.findLastVisibleDescendant(nodeElement.previousElementSibling));
}
else {
let parentNodeElement = this.getParentNodeElement(nodeElement);
if (parentNodeElement) {
this.focusNode(parentNodeElement);
}
}
event.preventDefault();
break;
//right-left arrows
case 37:
case 39:
this.$emit('toggle', this.node);
event.preventDefault();
break;
//enter
case 13:
this.onClick(event);
event.preventDefault();
break;
default:
//no op
break;
}
},
findNextSiblingOfAncestor(nodeElement) {
let parentNodeElement = this.getParentNodeElement(nodeElement);
if (parentNodeElement) {
if (parentNodeElement.nextElementSibling)
return parentNodeElement.nextElementSibling;
else
return this.findNextSiblingOfAncestor(parentNodeElement);
}
else {
return null;
}
},
findLastVisibleDescendant(nodeElement) {
const childrenListElement = nodeElement.children[1];
if (childrenListElement) {
const lastChildElement = childrenListElement.children[childrenListElement.children.length - 1];
return this.findLastVisibleDescendant(lastChildElement);
}
else {
return nodeElement;
}
},
getParentNodeElement(nodeElement) {
const parentNodeElement = nodeElement.parentElement.parentElement;
return DomHandler.hasClass(parentNodeElement, 'p-treenode') ? parentNodeElement : null;
},
focusNode(element) {
element.children[0].focus();
}
},
computed: {