Tree keyboard navigation
This commit is contained in:
parent
82f09dcb1d
commit
d5ffd4fb0a
1 changed files with 101 additions and 55 deletions
|
@ -185,74 +185,27 @@ class Tree extends Component {
|
|||
|
||||
async keyHandler(event) {//{{{
|
||||
let handled = true
|
||||
let nodeExpanded = false
|
||||
let siblingBefore = null
|
||||
let siblingExpanded = false
|
||||
let parent = null
|
||||
const n = this.selectedNode
|
||||
|
||||
switch (event.key) {
|
||||
case 'j':
|
||||
case 'ArrowDown':
|
||||
nodeExpanded = this.getNodeExpanded(n.UUID)
|
||||
|
||||
// Last node, not expanded, so it matters not whether it has children or not.
|
||||
// Traverse upward to nearest parent with next sibling.
|
||||
if (!nodeExpanded && n.isLastSibling()) {
|
||||
const wantedNode = this.getParentNodeWithNextSibling(n)
|
||||
if (wantedNode?.UUID === ROOT_NODE)
|
||||
break
|
||||
await _notes2.current.goToNode(wantedNode?.UUID, true, true)
|
||||
break
|
||||
}
|
||||
|
||||
if (nodeExpanded && n.isLastSibling() && !n.hasChildren()) {
|
||||
const wantedNode = this.getParentNodeWithNextSibling(n)
|
||||
await _notes2.current.goToNode(wantedNode?.UUID, true, true)
|
||||
break
|
||||
}
|
||||
// Node not expanded. Go to this node's next sibling.
|
||||
// GoToNode will abort if given null.
|
||||
if (!nodeExpanded || !n.hasChildren()) {
|
||||
await _notes2.current.goToNode(n.getSiblingAfter()?.UUID, true, true)
|
||||
break
|
||||
}
|
||||
|
||||
// Node is expanded.
|
||||
// Children will be visually beneath this node, if any.
|
||||
if (nodeExpanded && n.hasChildren()) {
|
||||
await _notes2.current.goToNode(n.Children[0].UUID, true, true)
|
||||
break
|
||||
}
|
||||
await this.navigateDown(this.selectedNode)
|
||||
break
|
||||
|
||||
case 'k':
|
||||
case 'ArrowUp':
|
||||
siblingBefore = n.getSiblingBefore()
|
||||
if (siblingBefore !== null)
|
||||
siblingExpanded = this.getNodeExpanded(siblingBefore.UUID)
|
||||
|
||||
if (n.isFirstSibling()) {
|
||||
parent = n.getParent()
|
||||
if (parent?.UUID === ROOT_NODE)
|
||||
break
|
||||
await _notes2.current.goToNode(parent?.UUID, true, true)
|
||||
break
|
||||
}
|
||||
|
||||
if (siblingBefore !== null && siblingExpanded && siblingBefore.hasChildren()) {
|
||||
await _notes2.current.goToNode(siblingBefore.Children[siblingBefore.Children.length - 1]?.UUID, true, true)
|
||||
break
|
||||
}
|
||||
|
||||
if (siblingBefore) {
|
||||
await _notes2.current.goToNode(siblingBefore.UUID, true, true)
|
||||
break
|
||||
}
|
||||
await this.navigateUp(this.selectedNode)
|
||||
break
|
||||
|
||||
case 'h':
|
||||
case 'ArrowLeft':
|
||||
await this.navigateLeft(this.selectedNode)
|
||||
break
|
||||
|
||||
case 'l':
|
||||
case 'ArrowRight':
|
||||
await this.navigateRight(this.selectedNode)
|
||||
break
|
||||
|
||||
default:
|
||||
|
@ -264,6 +217,99 @@ class Tree extends Component {
|
|||
event.stopPropagation()
|
||||
}
|
||||
}//}}}
|
||||
async navigateLeft(n) {//{{{
|
||||
const expanded = this.getNodeExpanded(n.UUID)
|
||||
if (expanded && n.hasChildren()) {
|
||||
this.setNodeExpanded(n.UUID, false)
|
||||
return
|
||||
}
|
||||
|
||||
if (n.isFirstSibling() && n.getParent().UUID !== ROOT_NODE) {
|
||||
await _notes2.current.goToNode(n.getParent()?.UUID, true, true)
|
||||
return
|
||||
}
|
||||
|
||||
await _notes2.current.goToNode(n.getSiblingBefore()?.UUID, true, true)
|
||||
}//}}}
|
||||
async navigateRight(n) {//{{{
|
||||
const siblingAfter = n.getSiblingAfter()
|
||||
const expanded = this.getNodeExpanded(n.UUID)
|
||||
|
||||
if (!expanded && n.hasChildren()) {
|
||||
this.setNodeExpanded(n.UUID, true)
|
||||
return
|
||||
}
|
||||
|
||||
if (expanded && n.hasChildren()) {
|
||||
await _notes2.current.goToNode(n.Children[0]?.UUID, true, true)
|
||||
return
|
||||
}
|
||||
|
||||
if (n.isLastSibling()) {
|
||||
const nextNode = this.getParentNodeWithNextSibling(n)
|
||||
await _notes2.current.goToNode(nextNode?.UUID, true, true)
|
||||
return
|
||||
}
|
||||
|
||||
await _notes2.current.goToNode(n.getSiblingAfter()?.UUID, true, true)
|
||||
}//}}}
|
||||
async navigateUp(n) {//{{{
|
||||
let parent = null
|
||||
const siblingBefore = n.getSiblingBefore()
|
||||
let siblingExpanded = false
|
||||
if (siblingBefore !== null)
|
||||
siblingExpanded = this.getNodeExpanded(siblingBefore.UUID)
|
||||
|
||||
if (n.isFirstSibling()) {
|
||||
parent = n.getParent()
|
||||
if (parent?.UUID === ROOT_NODE)
|
||||
return
|
||||
await _notes2.current.goToNode(parent?.UUID, true, true)
|
||||
return
|
||||
}
|
||||
|
||||
if (siblingBefore !== null && siblingExpanded && siblingBefore.hasChildren()) {
|
||||
await _notes2.current.goToNode(siblingBefore.Children[siblingBefore.Children.length - 1]?.UUID, true, true)
|
||||
return
|
||||
}
|
||||
|
||||
if (siblingBefore) {
|
||||
await _notes2.current.goToNode(siblingBefore.UUID, true, true)
|
||||
return
|
||||
}
|
||||
}//}}}
|
||||
async navigateDown(n) {//{{{
|
||||
const nodeExpanded = this.getNodeExpanded(n.UUID)
|
||||
|
||||
// Last node, not expanded, so it matters not whether it has children or not.
|
||||
// Traverse upward to nearest parent with next sibling.
|
||||
if (!nodeExpanded && n.isLastSibling()) {
|
||||
const wantedNode = this.getParentNodeWithNextSibling(n)
|
||||
if (wantedNode?.UUID === ROOT_NODE)
|
||||
return
|
||||
await _notes2.current.goToNode(wantedNode?.UUID, true, true)
|
||||
return
|
||||
}
|
||||
|
||||
if (nodeExpanded && n.isLastSibling() && !n.hasChildren()) {
|
||||
const wantedNode = this.getParentNodeWithNextSibling(n)
|
||||
await _notes2.current.goToNode(wantedNode?.UUID, true, true)
|
||||
return
|
||||
}
|
||||
// Node not expanded. Go to this node's next sibling.
|
||||
// GoToNode will abort if given null.
|
||||
if (!nodeExpanded || !n.hasChildren()) {
|
||||
await _notes2.current.goToNode(n.getSiblingAfter()?.UUID, true, true)
|
||||
return
|
||||
}
|
||||
|
||||
// Node is expanded.
|
||||
// Children will be visually beneath this node, if any.
|
||||
if (nodeExpanded && n.hasChildren()) {
|
||||
await _notes2.current.goToNode(n.Children[0].UUID, true, true)
|
||||
return
|
||||
}
|
||||
}//}}}
|
||||
}
|
||||
|
||||
class TreeNode extends Component {
|
||||
|
|
Loading…
Add table
Reference in a new issue