diff --git a/src/components/ActionButton/ActionButton.vue b/src/components/ActionButton/ActionButton.vue index 037bb8ebee..96ccb6a03f 100644 --- a/src/components/ActionButton/ActionButton.vue +++ b/src/components/ActionButton/ActionButton.vue @@ -26,38 +26,52 @@ This component is made to be used inside of the [Actions](#Actions) component sl ```vue diff --git a/src/components/Actions/Actions.vue b/src/components/Actions/Actions.vue index 764bad69ae..c290e2d694 100644 --- a/src/components/Actions/Actions.vue +++ b/src/components/Actions/Actions.vue @@ -559,13 +559,15 @@ export default { */ this.$emit('open') }, - closeMenu(e) { + closeMenu(returnFocus = true) { if (!this.opened) { return } this.opened = false + this.$refs.popover.clearFocusTrap({ returnFocus }) + /** * Event emitted when the popover menu open state is changed * @@ -639,7 +641,7 @@ export default { } // Esc if (event.keyCode === 27) { - this.closeMenu(event) + this.closeMenu() event.preventDefault() } }, @@ -811,6 +813,7 @@ export default { [ h('Popover', { + ref: 'popover', props: { delay: 0, handleResize: true, diff --git a/src/components/Popover/Popover.vue b/src/components/Popover/Popover.vue index 39d65544c1..fe90a2ff4b 100644 --- a/src/components/Popover/Popover.vue +++ b/src/components/Popover/Popover.vue @@ -112,9 +112,12 @@ export default { type: String, default: '', }, + /** + * Enable popover focus trap + */ focusTrap: { type: Boolean, - default: false, + default: true, }, }, @@ -142,10 +145,47 @@ export default { }, beforeDestroy() { - this.afterHide() + this.clearFocusTrap() }, methods: { + /** + * Add focus trap for accessibility. + */ + async useFocusTrap() { + await this.$nextTick() + + if (!this.focusTrap) { + return + } + + const el = this.$refs.popover?.$refs.popperContent?.$el + + if (!el) { + return + } + + this.$focusTrap = createFocusTrap(el, { + // Prevents to lose focus using esc key + // Focus will be release when popover be hide + escapeDeactivates: false, + allowOutsideClick: true, + }) + this.$focusTrap.activate() + }, + /** + * Remove focus trap + * + * @param {object} options The configuration options for focusTrap + */ + clearFocusTrap(options = {}) { + try { + this.$focusTrap?.deactivate(options) + this.$focusTrap = null + } catch (err) { + console.warn(err) + } + }, afterShow() { /** * Triggered after the tooltip was visually displayed. @@ -155,41 +195,14 @@ export default { * tooltip is already visible and in the DOM. */ this.$emit('after-show') - - /** - * Add focus trap for accessibility. - */ - this.$nextTick(() => { - if (!this.focusTrap) { - return - } - - const el = this.$refs.popover?.$refs.popperContent?.$el - - if (!el) { - return - } - - this.$focusTrap = createFocusTrap(el, { - // Prevents to lose focus using esc key - // Focus will be release when popover be hide - escapeDeactivates: false, - allowOutsideClick: true, - }) - this.$focusTrap.activate() - }) + this.useFocusTrap() }, afterHide() { /** * Triggered after the tooltip was visually hidden. */ this.$emit('after-hide') - - /** - * Remove focus trap - */ - this.$focusTrap?.deactivate() - this.$focusTrap = null + this.clearFocusTrap() }, }, } diff --git a/src/mixins/actionText.js b/src/mixins/actionText.js index 72c2686500..9ceecb6002 100644 --- a/src/mixins/actionText.js +++ b/src/mixins/actionText.js @@ -82,7 +82,7 @@ export default { if (this.closeAfterClick) { const parent = GetParent(this, 'Actions') if (parent && parent.closeMenu) { - parent.closeMenu() + parent.closeMenu(false) } } },