Skip to content

Commit

Permalink
fix(DropdownToggle): Listen for touch events on the document to close…
Browse files Browse the repository at this point in the history
… a Toggle on mobile (#1152)

Fixes Dropdown behavior on iOS devices.
Also fixes a broken test that was never running assertions due to setTimeout.

fix #1131
  • Loading branch information
mturley authored and jschuler committed Jan 11, 2019
1 parent 534501f commit a7f3c89
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,60 @@ describe('API', () => {
expect(mockToggle.mock.calls[0][0]).toBe(false);
});

test('touch on document', () => {
const map = {};
document.addEventListener = jest.fn((event, cb) => {
map[event] = cb;
});
const mockToggle = jest.fn();
mount(
<DropdownToggle id="Dropdown Toggle" onToggle={mockToggle} isOpen parentRef={document.createElement('div')}>
Dropdown
</DropdownToggle>
);

map.touchstart({ target: document });
expect(mockToggle.mock.calls[0][0]).toBe(false);
});

test('on click outside has been removed', () => {
const map = {};
document.removeEventListener = jest.fn((event, cb) => {
document.addEventListener = jest.fn((event, cb) => {
map[event] = cb;
});
document.removeEventListener = jest.fn((event, cb) => {
if (map[event] === cb) map[event] = () => {};
});
const mockToggle = jest.fn();
const view = mount(
<DropdownToggle id="Dropdown Toggle" onToggle={mockToggle} isOpen parentRef={document.createElement('div')}>
Dropdown
</DropdownToggle>
);
view.unmount();
setTimeout(() => {
map.mousedown({ target: document });
expect(mockToggle.mock.calls).toHaveLength(0);
expect(document.removeEventListener.mock.calls).toHaveLength(1);
map.mousedown({ target: document });
expect(mockToggle.mock.calls).toHaveLength(0);
expect(document.removeEventListener).toHaveBeenCalledWith('mousedown', expect.any(Function));
});

test('on touch outside has been removed', () => {
const map = {};
document.addEventListener = jest.fn((event, cb) => {
map[event] = cb;
});
document.removeEventListener = jest.fn((event, cb) => {
if (map[event] === cb) map[event] = () => {};
});
const mockToggle = jest.fn();
const view = mount(
<DropdownToggle id="Dropdown Toggle" onToggle={mockToggle} isOpen parentRef={document.createElement('div')}>
Dropdown
</DropdownToggle>
);
view.unmount();
map.touchstart({ target: document });
expect(mockToggle.mock.calls).toHaveLength(0);
expect(document.removeEventListener).toHaveBeenCalledWith('touchstart', expect.any(Function));
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,13 @@ const defaultProps = {
class DropdownToggle extends Component {
componentDidMount = () => {
document.addEventListener('mousedown', this.onDocClick);
document.addEventListener('touchstart', this.onDocClick);
document.addEventListener('keydown', this.onEscPress);
};

componentWillUnmount = () => {
document.removeEventListener('mousedown', this.onDocClick);
document.removeEventListener('touchstart', this.onDocClick);
document.removeEventListener('keydown', this.onEscPress);
};

Expand Down

0 comments on commit a7f3c89

Please sign in to comment.