diff --git a/src/TooltipPopoverWrapper.js b/src/TooltipPopoverWrapper.js index 278662490..80a27f100 100644 --- a/src/TooltipPopoverWrapper.js +++ b/src/TooltipPopoverWrapper.js @@ -160,10 +160,19 @@ class TooltipPopoverWrapper extends React.Component { return delay; } + getCurrentTarget(target) { + if (!target) + return null; + const index = this._targets.indexOf(target); + if (index >= 0) + return this._targets[index]; + return this.getCurrentTarget(target.parentElement); + } + show(e) { if (!this.props.isOpen) { this.clearShowTimeout(); - this.currentTargetElement = e ? e.currentTarget || e.target : null; + this.currentTargetElement = e ? e.currentTarget || this.getCurrentTarget(e.target) : null; if (e && e.composedPath && typeof e.composedPath === 'function') { const path = e.composedPath(); this.currentTargetElement = (path && path[0]) || this.currentTargetElement; diff --git a/src/__tests__/TooltipPopoverWrapper.spec.js b/src/__tests__/TooltipPopoverWrapper.spec.js index 66e950a71..c61c6f28e 100644 --- a/src/__tests__/TooltipPopoverWrapper.spec.js +++ b/src/__tests__/TooltipPopoverWrapper.spec.js @@ -192,6 +192,24 @@ describe('Tooltip', () => { wrapper.detach(); }); + it('should handle inner target click and correct placement', () => { + const wrapper = mount( + + Tooltip Content + , + { attachTo: container } + ); + const instance = wrapper.instance(); + + expect(isOpen).toBe(false); + instance.handleDocumentClick({ target: innerTarget }); + jest.runTimersToTime(200); + expect(isOpen).toBe(true); + wrapper.setProps({ isOpen: true }); + expect(wrapper.find(PopperContent).props().target.id).toBe('target'); + wrapper.detach(); + }); + it('should not do anything when document click outside of target', () => { const wrapper = mount( @@ -380,17 +398,19 @@ describe('Tooltip', () => { }); describe('multi target', () => { - let targets, targetContainer; + let targets, innerTarget, targetContainer; beforeEach(() => { targetContainer = document.createElement('div'); - targetContainer.innerHTML = `Target 1Target 2` + targetContainer.innerHTML = `Target 1Target 2Inner target` element.appendChild(targetContainer); targets = targetContainer.querySelectorAll('.example'); + innerTarget = targetContainer.querySelector('.inner_example'); }); afterEach(() => { element.removeChild(targetContainer); targets = null; + innerTarget = null; }); it("should attach tooltip on multiple target when a target selector matches multiple elements", () => { @@ -415,6 +435,19 @@ describe('Tooltip', () => { expect(isOpen).toBe(false); wrapper.detach(); }); + + it("should attach tooltip on second target with correct placement, when inner element is clicked", () => { + const wrapper = mount( + Yo!, + { attachTo: container }); + + innerTarget.dispatchEvent(new Event('click')); + jest.runTimersToTime(0) + expect(isOpen).toBe(true); + wrapper.setProps({ isOpen: true }); + expect(wrapper.find(PopperContent).props().target.className).toBe('example second'); + wrapper.detach(); + }); }); describe('delay', () => {