diff --git a/src/components/NcActions/NcActions.vue b/src/components/NcActions/NcActions.vue index fa650b4baa..2405952be2 100644 --- a/src/components/NcActions/NcActions.vue +++ b/src/components/NcActions/NcActions.vue @@ -1448,7 +1448,7 @@ export default { container: this.container, popoverBaseClass: 'action-item__popper', popupRole, - setReturnFocus: this.withFocusTrap ? this.$refs.menuButton?.$el : null, + noAutoReturnFocus: !this.withFocusTrap, focusTrap: this.withFocusTrap, }, // For some reason the popover component diff --git a/src/components/NcColorPicker/NcColorPicker.vue b/src/components/NcColorPicker/NcColorPicker.vue index 021d46c501..1e9df8d2c1 100644 --- a/src/components/NcColorPicker/NcColorPicker.vue +++ b/src/components/NcColorPicker/NcColorPicker.vue @@ -89,8 +89,8 @@ export default { diff --git a/src/components/NcPopover/NcPopover.vue b/src/components/NcPopover/NcPopover.vue index d3004776c5..591c6c8942 100644 --- a/src/components/NcPopover/NcPopover.vue +++ b/src/components/NcPopover/NcPopover.vue @@ -186,6 +186,8 @@ import { createFocusTrap } from 'focus-trap' import { getTrapStack } from '../../utils/focusTrap.js' import NcPopoverTriggerProvider from './NcPopoverTriggerProvider.vue' +const buttonSelector = 'button, [role="button"], input[type="button"]' + export default { name: 'NcPopover', @@ -236,6 +238,15 @@ export default { default: undefined, type: [HTMLElement, SVGElement, String, Boolean], }, + + /** + * When there is no setReturnFocus, NcPopover will try to return focus to the trigger button. + * Use this prop to disable this behavior. + */ + noAutoReturnFocus: { + type: Boolean, + default: false, + }, }, emits: [ @@ -279,11 +290,8 @@ export default { */ checkTriggerA11y() { if (window.OC?.debug) { - // TODO: Vue 3: should be - // this.$refs.popover.$refs.popper.$refs.reference - const triggerContainer = this.$refs.popover.$refs.reference - const requiredTriggerButton = triggerContainer.querySelector('[aria-expanded][aria-haspopup]') - if (!requiredTriggerButton) { + const triggerButton = this.getPopoverTriggerButtonElement() + if (!triggerButton || !triggerButton.hasAttributes('aria-expanded', 'aria-haspopup')) { Vue.util.warn('It looks like you are using a custom button as a or other popover #trigger. If you are not using as a trigger, you need to bind attrs from the #trigger slot props to your custom button. See docs for an example.') } } @@ -296,6 +304,23 @@ export default { return this.$refs.popover?.$refs.popperContent?.$el }, + /** + * @return {HTMLElement|undefined} + */ + getPopoverTriggerElement() { + // TODO: Vue 3: should be + // this.$refs.popover.$refs.popper.$refs.reference + return this.$refs.popover.$refs.reference + }, + + /** + * @return {HTMLElement|undefined} + */ + getPopoverTriggerButtonElement() { + const triggerContainer = this.getPopoverTriggerElement() + return triggerContainer?.querySelector(buttonSelector) + }, + /** * Add focus trap for accessibility. */ @@ -318,7 +343,7 @@ export default { // Focus will be release when popover be hide escapeDeactivates: false, allowOutsideClick: true, - setReturnFocus: this.setReturnFocus, + setReturnFocus: this.setReturnFocus || (!this.noAutoReturnFocus && this.getPopoverTriggerButtonElement()), trapStack: getTrapStack(), }) this.$focusTrap.activate()