From ad5c81cebf82f6430564562ccb3c16ad6aabed59 Mon Sep 17 00:00:00 2001 From: Egor Pogadaev Date: Thu, 28 Mar 2019 16:46:18 +0500 Subject: [PATCH 1/5] test(Tooltip): test onCloseRequest call on clickOutside --- .../Tooltip/__tests__/Tooltip-test.tsx | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/packages/retail-ui/components/Tooltip/__tests__/Tooltip-test.tsx b/packages/retail-ui/components/Tooltip/__tests__/Tooltip-test.tsx index 21478e705ae..fc1f0f779d0 100644 --- a/packages/retail-ui/components/Tooltip/__tests__/Tooltip-test.tsx +++ b/packages/retail-ui/components/Tooltip/__tests__/Tooltip-test.tsx @@ -1,8 +1,15 @@ // tslint:disable:jsx-no-lambda -import { mount } from 'enzyme'; +import { mount, ReactWrapper } from 'enzyme'; import * as React from 'react'; import Button from '../../Button'; -import Tooltip, { TooltipProps } from '../Tooltip'; +import Tooltip, { TooltipProps, TooltipState } from '../Tooltip'; + +function clickOutside() { + const event = document.createEvent('HTMLEvents'); + event.initEvent('mousedown', true, true); + + document.body.dispatchEvent(event); +} describe('Tooltip', () => { const render = () => ''; @@ -118,4 +125,40 @@ describe('Tooltip', () => { wrapper.setProps({ trigger: 'hover' }); expect(wrapper.find(Content).length).toBe(0); }); + + describe('calls onCloseRequest on clickOutside when tooltip is opened', () => { + const Content = () =>
; + const onCloseRequest = jest.fn(); + let wrapper: ReactWrapper; + + beforeEach(() => { + onCloseRequest.mockClear(); + wrapper = mount( + } onCloseRequest={onCloseRequest}> + + , + ); + }); + + it('with "click" trigger', () => { + wrapper.setProps({ trigger: 'click' }); + wrapper.setState({ opened: true }); + wrapper.update(); + expect(wrapper.find(Content).length).toBe(1); + + clickOutside(); + + expect(onCloseRequest).toHaveBeenCalledTimes(1); + }); + + it('with "opened" trigger', () => { + wrapper.setProps({ trigger: 'opened' }); + wrapper.update(); + expect(wrapper.find(Content).length).toBe(1); + + clickOutside(); + + expect(onCloseRequest).toHaveBeenCalledTimes(1); + }); + }); }); From 08189733a5b4d0c8ad3f48aacfe70e3b62f90b79 Mon Sep 17 00:00:00 2001 From: Egor Pogadaev Date: Fri, 29 Mar 2019 13:04:50 +0500 Subject: [PATCH 2/5] fix(Tooltip): deactivate RenderLayer by default fix #1304 --- packages/retail-ui/components/Tooltip/Tooltip.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/retail-ui/components/Tooltip/Tooltip.tsx b/packages/retail-ui/components/Tooltip/Tooltip.tsx index 96605cee90b..1e46a607500 100644 --- a/packages/retail-ui/components/Tooltip/Tooltip.tsx +++ b/packages/retail-ui/components/Tooltip/Tooltip.tsx @@ -181,7 +181,7 @@ class Tooltip extends React.Component { public render() { const props = this.props; const content = this.renderContent(); - const { popupProps, layerProps = {} } = this.getProps(); + const { popupProps, layerProps = { active: false } } = this.getProps(); const anchorElement = props.children || props.anchorElement; const popup = this.renderPopup(anchorElement, popupProps, content); From 8e492e85c0547d1043ab6df041c4f30e4efcb31d Mon Sep 17 00:00:00 2001 From: Egor Pogadaev Date: Fri, 29 Mar 2019 13:27:23 +0500 Subject: [PATCH 3/5] revert(RenderLayer): "perf(RenderLayer): less event subscriptions" Perf optimization didn't take into account that callbacks may change independently from the "active" prop. #1304 --- .../retail-ui/components/RenderLayer/RenderLayer.tsx | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/retail-ui/components/RenderLayer/RenderLayer.tsx b/packages/retail-ui/components/RenderLayer/RenderLayer.tsx index 94e7c5e73c9..ea2e353fb0d 100644 --- a/packages/retail-ui/components/RenderLayer/RenderLayer.tsx +++ b/packages/retail-ui/components/RenderLayer/RenderLayer.tsx @@ -44,14 +44,9 @@ class RenderLayer extends React.Component { } private attachListeners() { - if (this.props.onFocusOutside) { - this.focusOutsideListenerToken = listenFocusOutside(() => [this.getDomNode()], this.handleFocusOutside); - window.addEventListener('blur', this.handleFocusOutside); - } - - if (this.props.onClickOutside) { - document.addEventListener('mousedown', this.handleNativeDocClick); - } + this.focusOutsideListenerToken = listenFocusOutside(() => [this.getDomNode()], this.handleFocusOutside); + window.addEventListener('blur', this.handleFocusOutside); + document.addEventListener('mousedown', this.handleNativeDocClick); } private detachListeners() { From 1e400fd4fc3b2011119ee8cfea014cfcf67275b6 Mon Sep 17 00:00:00 2001 From: Egor Pogadaev Date: Fri, 29 Mar 2019 13:37:27 +0500 Subject: [PATCH 4/5] chore(RenderLayer): add warning for not specified callback --- .../retail-ui/components/RenderLayer/RenderLayer.tsx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/retail-ui/components/RenderLayer/RenderLayer.tsx b/packages/retail-ui/components/RenderLayer/RenderLayer.tsx index ea2e353fb0d..c1efe69c1e5 100644 --- a/packages/retail-ui/components/RenderLayer/RenderLayer.tsx +++ b/packages/retail-ui/components/RenderLayer/RenderLayer.tsx @@ -10,6 +10,17 @@ export interface RenderLayerProps { } class RenderLayer extends React.Component { + public static propTypes = { + active(props: RenderLayerProps, propName: keyof RenderLayerProps, componentName: string) { + const { active, onClickOutside, onFocusOutside } = props; + if (active && !(onClickOutside || onFocusOutside)) { + return new Error( + `[${componentName}]: using active ${componentName} without specifing either 'onClickOutside' or 'onFocusOutside' callback is incorrect.`, + ); + } + }, + }; + public static defaultProps = { active: true, }; From 56df93da7308304698344a8e79fd4791837e03ab Mon Sep 17 00:00:00 2001 From: Egor Pogadaev Date: Fri, 29 Mar 2019 18:41:56 +0500 Subject: [PATCH 5/5] chore(RenderLayer): change propType's warning message --- packages/retail-ui/components/RenderLayer/RenderLayer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/retail-ui/components/RenderLayer/RenderLayer.tsx b/packages/retail-ui/components/RenderLayer/RenderLayer.tsx index c1efe69c1e5..c0955137725 100644 --- a/packages/retail-ui/components/RenderLayer/RenderLayer.tsx +++ b/packages/retail-ui/components/RenderLayer/RenderLayer.tsx @@ -15,7 +15,7 @@ class RenderLayer extends React.Component { const { active, onClickOutside, onFocusOutside } = props; if (active && !(onClickOutside || onFocusOutside)) { return new Error( - `[${componentName}]: using active ${componentName} without specifing either 'onClickOutside' or 'onFocusOutside' callback is incorrect.`, + `[${componentName}]: using the component without either 'onClickOutside' or 'onFocusOutside' callback is pointless.`, ); } },