Skip to content

Commit

Permalink
fix(Popover): do not trigger toggle on popover click
Browse files Browse the repository at this point in the history
Closes #594
  • Loading branch information
TheSharpieOne committed Sep 28, 2017
1 parent 3e9bf9e commit 50a8fd4
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 5 deletions.
9 changes: 7 additions & 2 deletions src/Popover.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class Popover extends React.Component {
this.addTargetEvents = this.addTargetEvents.bind(this);
this.handleDocumentClick = this.handleDocumentClick.bind(this);
this.removeTargetEvents = this.removeTargetEvents.bind(this);
this.getRef = this.getRef.bind(this);
this.toggle = this.toggle.bind(this);
this.show = this.show.bind(this);
this.hide = this.hide.bind(this);
Expand All @@ -70,6 +71,10 @@ class Popover extends React.Component {
this.removeTargetEvents();
}

getRef(ref) {
this._popover = ref;
}

getDelay(key) {
const { delay } = this.props;
if (typeof delay === 'object') {
Expand Down Expand Up @@ -115,7 +120,7 @@ class Popover extends React.Component {
}

handleDocumentClick(e) {
if (e.target !== this._target && !this._target.contains(e.target)) {
if (e.target !== this._target && !this._target.contains(e.target) && e.target !== this._popover && !(this._popover && this._popover.contains(e.target))) {
if (this._hideTimeout) {
this.clearHideTimeout();
}
Expand Down Expand Up @@ -172,7 +177,7 @@ class Popover extends React.Component {
placementPrefix={this.props.placementPrefix}
container={this.props.container}
>
<div {...attributes} className={classes} />
<div {...attributes} className={classes} ref={this.getRef} />
</PopperContent>
);
}
Expand Down
42 changes: 39 additions & 3 deletions src/__tests__/Popover.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ describe('Popover', () => {
container = document.createElement('div');
element.innerHTML = '<p id="outerTarget">This is the popover <span id="innerTarget">target</span>.</p>';
container.setAttribute('id', 'container');
outerTarget = document.getElementById('outerTarget');
innerTarget = document.getElementById('innerTarget');
element.appendChild(container);
document.body.appendChild(element);
outerTarget = document.getElementById('outerTarget');
innerTarget = document.getElementById('innerTarget');
isOpen = false;
toggle = () => { isOpen = !isOpen; };
placement = 'top';
Expand Down Expand Up @@ -221,7 +221,7 @@ describe('Popover', () => {
wrapper.detach();
});

it('should NOT handle inner target clicks', () => {
it('should NOT handle inner target clicks when isOpen is false (user is responsible)', () => {
const wrapper = mount(
<Popover target="innerTarget" isOpen={isOpen} toggle={toggle}>
Popover Content
Expand All @@ -238,6 +238,42 @@ describe('Popover', () => {
wrapper.detach();
});

it('should NOT handle inner target clicks when isOpen is true (user is responsible)', () => {
isOpen = true;
const wrapper = mount(
<Popover target="innerTarget" isOpen={isOpen} toggle={toggle}>
Popover Content
</Popover>,
{ attachTo: container }
);
const instance = wrapper.instance();

expect(isOpen).toBe(true);
instance.handleDocumentClick({ target: innerTarget });
jest.runTimersToTime(0); // toggle is still async
expect(isOpen).toBe(true);

wrapper.detach();
});

it('should NOT handle popover target clicks', () => {
isOpen = true;
const wrapper = mount(
<Popover target="innerTarget" isOpen={isOpen} toggle={toggle}>
Popover Content
</Popover>,
{ attachTo: container }
);
const instance = wrapper.instance();

expect(isOpen).toBe(true);
instance.handleDocumentClick({ target: instance._popover });
jest.runTimersToTime(0); // toggle is still async
expect(isOpen).toBe(true);

wrapper.detach();
});

it('should not do anything when document click outside of target', () => {
const wrapper = mount(
<Popover target="innerTarget" isOpen={isOpen} toggle={toggle}>
Expand Down

0 comments on commit 50a8fd4

Please sign in to comment.