Skip to content

Commit

Permalink
Merge pull request #4953 from nextcloud-libraries/fix/4910/nc-popover…
Browse files Browse the repository at this point in the history
…--integrate-with-current-focus-trap

fix(NcActions): intercept into current focus trap stack
  • Loading branch information
susnux committed Jan 29, 2024
2 parents 7665b6e + 6060690 commit c39a056
Showing 1 changed file with 33 additions and 0 deletions.
33 changes: 33 additions & 0 deletions src/components/NcActions/NcActions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,7 @@ p {
import NcButton from '../NcButton/index.js'
import NcPopover from '../NcPopover/index.js'
import GenRandomId from '../../utils/GenRandomId.js'
import { getTrapStack } from '../../utils/focusTrap.js'
import { t } from '../../l10n.js'
import Vue, { computed } from 'vue'
Expand Down Expand Up @@ -1009,6 +1010,7 @@ export default {
* @type {'menu'|'navigation'|'dialog'|'tooltip'|''}
*/
actionsMenuSemanticType: '',
externalFocusTrapStack: [],
}
},
Expand All @@ -1035,6 +1037,10 @@ export default {
this.opened = state
},
opened() {
this.intersectIntoCurrentFocusTrapStack()
},
},
methods: {
Expand All @@ -1048,6 +1054,33 @@ export default {
return action?.componentOptions?.Ctor?.extendOptions?.name ?? action?.componentOptions?.tag
},
/**
* When the component has its own focus trap, then it is managed by global trap stack by focus-trap.
*
* However if the component has no focus trap and is used inside another focus trap - there is an issue.
* By default popover content is rendered in body or other container, which is likely outside the current focus trap containers.
* It results in broken behavior from focus-trap.
*
* We need to pause all the focus traps for opening popover and then unpause them back after closing.
*/
intersectIntoCurrentFocusTrapStack() {
if (this.withFocusTrap) {
return
}
if (this.opened) {
this.externalFocusTrapStack = [...getTrapStack()]
for (const trap of this.externalFocusTrapStack) {
trap.pause()
}
} else {
for (const trap of this.externalFocusTrapStack) {
trap.unpause()
}
this.externalFocusTrapStack = []
}
},
/**
* Do we have exactly one Action and
* is it allowed as a standalone element?
Expand Down

0 comments on commit c39a056

Please sign in to comment.