diff --git a/addon/components/ember-popover.js b/addon/components/ember-popover.js index 526b23e8..5e939d76 100644 --- a/addon/components/ember-popover.js +++ b/addon/components/ember-popover.js @@ -57,8 +57,8 @@ export default EmberTooltipBase.extend({ this.set('_isMouseInside', false); }); - this._addEventListener('focusout', () => { - if (!this.get('_isMouseInside') && this.get('hideOn') !== 'none') { + this._addEventListener('focusout', (event) => { + if (!this.get('_isMouseInside') && this.get('hideOn') !== 'none' && !this._isTargetReceivingFocusInsidePopover(event)) { this.hide(); } }); @@ -88,8 +88,8 @@ export default EmberTooltipBase.extend({ } }, popover); - this._addEventListener('focusout', () => { - if (!this.get('_isMouseInside') && this.get('isShown') && this.get('hideOn') !== 'none') { + this._addEventListener('focusout', (event) => { + if (!this.get('_isMouseInside') && this.get('isShown') && this.get('hideOn') !== 'none' && !this._isTargetReceivingFocusInsidePopover(event)) { this.hide(); } }, popover); diff --git a/addon/components/ember-tooltip-base.js b/addon/components/ember-tooltip-base.js index bf448c4a..51116c7f 100644 --- a/addon/components/ember-tooltip-base.js +++ b/addon/components/ember-tooltip-base.js @@ -221,6 +221,17 @@ export default Component.extend({ return inTestingMode ? 0 : this.animationDuration; }), + + /** + * Check if the EventTarget receiving focus is inside the popover (e.g. by keyboard navigation) + * @param {FocusEvent} event - event.relatedTarget is an EventTarget receiving focus (if any) + * @returns {boolean} true if the focus shifts to an element that is contained within the popover + */ + + _isTargetReceivingFocusInsidePopover(event) { + return !!this.get('_tooltip.popperInstance.popper')?.contains(event.relatedTarget) + }, + init() { this._super(...arguments); this.set('_tooltipEvents', []); @@ -326,8 +337,10 @@ export default Component.extend({ }); } - this._addEventListener('focusout', () => { - this.hide(); + this._addEventListener('focusout', (event) => { + if (!this._isTargetReceivingFocusInsidePopover(event)) { + this.hide(); + } }); }