From c616baf1b2ecc9fc0d69357b76a31d084d862e62 Mon Sep 17 00:00:00 2001 From: Chandler Prall Date: Thu, 19 Jul 2018 14:26:21 -0600 Subject: [PATCH 1/2] Fix EuiOutsideClickDetector to work when its nested inside itself --- .../outside_click_detector.js | 12 ++++-- .../outside_click_detector.test.js | 43 ++++++++++++++++++- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/components/outside_click_detector/outside_click_detector.js b/src/components/outside_click_detector/outside_click_detector.js index 0af6ed9275f..390cba0f010 100644 --- a/src/components/outside_click_detector/outside_click_detector.js +++ b/src/components/outside_click_detector/outside_click_detector.js @@ -32,7 +32,7 @@ export class EuiOutsideClickDetector extends Component { // virtual DOM and executes EuiClickDetector's onClick handler, // stamping the id even though the event originates outside // this component's reified DOM tree. - this.id = htmlIdGenerator(); + this.id = htmlIdGenerator()(); } onClickOutside = event => { @@ -45,7 +45,7 @@ export class EuiOutsideClickDetector extends Component { return; } - if (event.euiGeneratedBy === this.id) { + if (event.euiGeneratedBy && event.euiGeneratedBy.includes(this.id)) { return; } @@ -61,7 +61,13 @@ export class EuiOutsideClickDetector extends Component { } onChildClick = event => { - event.nativeEvent.euiGeneratedBy = this.id; + // to support nested click detectors, build an array + // of detector ids that have been encountered + if (event.nativeEvent.hasOwnProperty('euiGeneratedBy')) { + event.nativeEvent.euiGeneratedBy.push(this.id); + } else { + event.nativeEvent.euiGeneratedBy = [this.id]; + } if (this.props.onClick) this.props.onClick(event); } diff --git a/src/components/outside_click_detector/outside_click_detector.test.js b/src/components/outside_click_detector/outside_click_detector.test.js index 076f0661930..86254ef9f4c 100644 --- a/src/components/outside_click_detector/outside_click_detector.test.js +++ b/src/components/outside_click_detector/outside_click_detector.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { render } from 'enzyme'; +import { render, mount } from 'enzyme'; import { EuiOutsideClickDetector } from './outside_click_detector'; @@ -14,4 +14,45 @@ describe('EuiOutsideClickDetector', () => { expect(component) .toMatchSnapshot(); }); + + describe('behavior', () => { + test('nested detectors', () => { + const unrelatedDetector = jest.fn(); + const parentDetector = jest.fn(); + const childDetector = jest.fn(); + + // enzyme doesn't mount the components into the global jsdom `document` + // but that's where the click detector listener is, + // pass the top-level mounted component's click event on to document + const triggerDocumentClick = e => { + const event = new Event('click'); + event.euiGeneratedBy = e.nativeEvent.euiGeneratedBy; + document.dispatchEvent(event); + }; + + const component = mount( +
+
+ +
+ +
+ +
+
+
+ + +
+ +
+ ); + + component.find('[data-test-subj="target"]').simulate('click'); + + expect(unrelatedDetector).toHaveBeenCalledTimes(1); + expect(parentDetector).toHaveBeenCalledTimes(0); + expect(childDetector).toHaveBeenCalledTimes(0); + }); + }); }); From d1fb57d6fb516b9822e92f5bafcdecaddca149c2 Mon Sep 17 00:00:00 2001 From: Chandler Prall Date: Thu, 19 Jul 2018 14:30:48 -0600 Subject: [PATCH 2/2] changelog --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 898223a67ec..a720eb89798 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ ## [`master`](https://github.com/elastic/eui/tree/master) -No public interface changes since `3.1.0`. +**Bug fixes** + +- `EuiOutsideClickDetector` can support nested detectors in the DOM tree ([#1039](https://github.com/elastic/eui/pull/1039)) ## [`3.1.0`](https://github.com/elastic/eui/tree/v3.1.0)