Skip to content

Commit

Permalink
fix(NcAppSidebar): focus on open and return focus on close
Browse files Browse the repository at this point in the history
Signed-off-by: Grigorii K. Shartsev <me@shgk.me>
  • Loading branch information
ShGKme committed Feb 7, 2024
1 parent cf330f2 commit 4dd1de8
Showing 1 changed file with 42 additions and 2 deletions.
44 changes: 42 additions & 2 deletions src/components/NcAppSidebar/NcAppSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -405,11 +405,12 @@ export default {
<!-- main name -->
<h2 v-show="!nameEditable"
:id="`app-sidebar-vue-${uid}__header`"
ref="header"
v-linkify="{text: name, linkify: linkifyName}"
:aria-label="title"
:title="title"
class="app-sidebar-header__mainname"
:tabindex="nameEditable ? 0 : undefined"
:tabindex="nameEditable ? 0 : -1"
@click.self="editName">
{{ name }}
</h2>
Expand Down Expand Up @@ -665,6 +666,7 @@ export default {
favoriteTranslated: t('Favorite'),
isStarred: this.starred,
focusTrap: null,
elementToReturnFocus: null,
}
},
Expand All @@ -690,7 +692,16 @@ export default {
},
},
created() {
this.preserveElementToReturnFocus()
},
mounted() {
// Focus sidebar on open only if it was opened by a user interaction
if (this.elementToReturnFocus) {
this.focus()
}
this.toggleFocusTrap()
},
Expand All @@ -701,6 +712,23 @@ export default {
},
methods: {
preserveElementToReturnFocus() {
// Save the element that had focus before the sidebar was opened to return back on close
if (document.activeElement && document.activeElement !== document.body) {
this.elementToReturnFocus = document.activeElement
// Special case for menus (NcActions)
// If a sidebar was opened from a menu item, we want to return focus to the menu trigger instead of the item
if (this.elementToReturnFocus.getAttribute('role') === 'menuitem') {
const menu = this.elementToReturnFocus.closest('[role="menu"]')
if (menu) {
const menuTrigger = document.querySelector(`[aria-controls="${menu.id}"]`)
this.elementToReturnFocus = menuTrigger
}
}
}
},
initFocusTrap() {
if (this.focusTrap) {
return
Expand All @@ -725,7 +753,7 @@ export default {
/**
* Activate focus trap if it is currently needed, otherwise deactivate
*/
toggleFocusTrap() {
toggleFocusTrap() {
if (this.isMobile) {
this.initFocusTrap()
this.focusTrap.activate()
Expand Down Expand Up @@ -765,6 +793,10 @@ export default {
* @type {HTMLElement}
*/
this.$emit('closed', element)
// Return focus to the element that had focus before the sidebar was opened
this.elementToReturnFocus?.focus({ focusVisible: true })
this.elementToReturnFocus = null
},
/**
Expand Down Expand Up @@ -824,6 +856,14 @@ export default {
}
},
/**
* Focus the sidebar
* @public
*/
focus() {
this.$refs.header.focus()
},
/**
* Emit name change event to parent component
*
Expand Down

0 comments on commit 4dd1de8

Please sign in to comment.