Skip to content

Commit

Permalink
STSCOM-895: Make useClickOutside catch click event on capture phase (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
BogdanDenis authored and zburke committed Nov 22, 2021
1 parent eb013f2 commit ebbc7d9
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Change history for stripes-components

## IN PROGRESS

* Make `useClickOutside` click handler work on `capture` event phase. Refs STCOM-895.

## [10.0.2](https://github.com/folio-org/stripes-components/tree/v10.0.2) (2021-11-15)
[Full Changelog](https://github.com/folio-org/stripes-components/compare/v10.0.1...v10.0.2)

Expand Down
18 changes: 17 additions & 1 deletion hooks/tests/useClickOutside-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,13 @@ describe('useClickOutside', () => {

return (
<div ref={content}>
<span id="click-inside-element">Inside element</span>
<button
id="click-inside-element"
type="button"
onClick={(e) => e.target.parentNode.removeChild(e.target)}
>
Inside element
</button>
</div>
);
};
Expand Down Expand Up @@ -73,4 +79,14 @@ describe('useClickOutside', () => {
expect(onClickSpy.calledOnceWith(false)).to.be.true;
});
});

describe('when other click handler removes click target from DOM', () => {
beforeEach(async () => {
await useClickOutsideInteractor.clickInsideElement();
});

it('should still give correct results', () => {
expect(onClickSpy.calledOnceWith(false)).to.be.true;
});
});
});
7 changes: 5 additions & 2 deletions hooks/useClickOutside/useClickOutside.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ const useClickOutside = (ref, onClick) => {
onClick(e, isOutside);
};

document.addEventListener('click', handleClick);
// need to catch event in capture phase to process click event before other handlers
// this is to fix a case when other click handler might remove e.target from DOM
// and when this handler runs - `contains` will return false because e.target is no longer in DOM
document.addEventListener('click', handleClick, true);
return () => {
document.removeEventListener('click', handleClick);
document.removeEventListener('click', handleClick, true);
};
}, [ref, onClick]);
};
Expand Down

0 comments on commit ebbc7d9

Please sign in to comment.