diff --git a/administrator/components/com_media/resources/scripts/components/tree/drive.vue b/administrator/components/com_media/resources/scripts/components/tree/drive.vue index fcd0aa88ee175..96a30b01e1331 100644 --- a/administrator/components/com_media/resources/scripts/components/tree/drive.vue +++ b/administrator/components/com_media/resources/scripts/components/tree/drive.vue @@ -10,18 +10,26 @@ >
  • - + {{ drive.displayName }}
  • @@ -50,6 +58,12 @@ export default { onDriveClick() { this.navigateTo(this.drive.root); }, + moveFocusToChildElement(nextRoot) { + this.$refs[nextRoot].setFocusToFirstChild(); + }, + restoreFocus() { + this.$refs['drive-root'].focus(); + }, }, }; diff --git a/administrator/components/com_media/resources/scripts/components/tree/tree.vue b/administrator/components/com_media/resources/scripts/components/tree/tree.vue index 8432b9e014cfe..5f3555700f1af 100644 --- a/administrator/components/com_media/resources/scripts/components/tree/tree.vue +++ b/administrator/components/com_media/resources/scripts/components/tree/tree.vue @@ -4,27 +4,39 @@ role="group" >
  • + - + @click.stop.prevent="onItemClick(item)" + @keyup.up="moveFocusToPreviousElement(index)" + @keyup.down="moveFocusToNextElement(index)" + @keyup.enter="onItemClick(item)" + @keyup.right="moveFocusToChildElement(item)" + @keyup.left="moveFocusToParentElement()" + > {{ item.name }}
  • @@ -46,7 +58,12 @@ export default { type: Number, required: true, }, + parentIndex: { + type: Number, + required: true, + }, }, + emits: ['move-focus-to-parent'], computed: { /* Get the directories */ directories() { @@ -61,19 +78,19 @@ export default { return (item.path === this.$store.state.selectedDirectory); }, getTabindex(item) { - return item.isActive ? 0 : -1; + return this.isActive(item) ? 0 : -1; }, onItemClick(item) { this.navigateTo(item.path); window.parent.document.dispatchEvent( - new CustomEvent( - 'onMediaFileSelected', - { - bubbles: true, - cancelable: false, - detail: {}, - }, - ), + new CustomEvent( + 'onMediaFileSelected', + { + bubbles: true, + cancelable: false, + detail: {}, + }, + ), ); }, hasChildren(item) { @@ -89,6 +106,33 @@ export default { 'icon-folder-open': this.isOpen(item), }; }, - } + setFocusToFirstChild() { + this.$refs[`${this.root}0`][0].focus(); + }, + moveFocusToNextElement(currentIndex) { + if ((currentIndex + 1) === this.directories.length) { + return; + } + this.$refs[this.root + (currentIndex + 1)][0].focus(); + }, + moveFocusToPreviousElement(currentIndex) { + if (currentIndex === 0) { + return; + } + this.$refs[this.root + (currentIndex - 1)][0].focus(); + }, + moveFocusToChildElement(item) { + if (!this.hasChildren(item)) { + return; + } + this.$refs[item.path][0].setFocusToFirstChild(); + }, + moveFocusToParentElement() { + this.$emit('move-focus-to-parent', this.parentIndex); + }, + restoreFocus(parentIndex) { + this.$refs[this.root + parentIndex][0].focus(); + }, + }, };