diff --git a/CHANGELOG.md b/CHANGELOG.md index e99a468223..7167379a9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Handle `onClick` and `onFocus` on ListItems correctly @layershifter ([#779](https://github.com/stardust-ui/react/pull/779)) - Remove popup trigger button default role @jurokapsiar ([#806](https://github.com/stardust-ui/react/pull/806)) - Improve `Dropdown` component styles @Bugaa92 ([#786](https://github.com/stardust-ui/react/pull/786)) +- Preserve outside click subscription on `Popup` and `MenuItem` component updates @kuzhelov ([#803](https://github.com/stardust-ui/react/pull/803)) ## [v0.19.1](https://github.com/stardust-ui/react/tree/v0.19.1) (2019-01-29) diff --git a/src/components/Menu/MenuItem.tsx b/src/components/Menu/MenuItem.tsx index 2d66275b5b..211f69c037 100644 --- a/src/components/Menu/MenuItem.tsx +++ b/src/components/Menu/MenuItem.tsx @@ -278,12 +278,12 @@ class MenuItem extends AutoControlledComponent, MenuIt } private updateOutsideClickSubscription() { - this.outsideClickSubscription.unsubscribe() - - if (this.props.menu && this.state.menuOpen) { + if (this.props.menu && this.state.menuOpen && this.outsideClickSubscription.isEmpty) { setTimeout(() => { this.outsideClickSubscription = EventStack.subscribe('click', this.outsideClickHandler) }) + } else { + this.outsideClickSubscription.unsubscribe() } } diff --git a/src/components/Popup/Popup.tsx b/src/components/Popup/Popup.tsx index e0bff90544..bddf5b6657 100644 --- a/src/components/Popup/Popup.tsx +++ b/src/components/Popup/Popup.tsx @@ -226,9 +226,7 @@ export default class Popup extends AutoControlledComponent { this.outsideClickSubscription = EventStack.subscribe( 'click', @@ -247,6 +245,8 @@ export default class Popup extends AutoControlledComponent {}, true) } - public constructor(private _unsubscribe: Function, public readonly isEmpty: boolean = false) {} + public get isEmpty(): boolean { + return this._isEmpty + } + + public constructor(private _unsubscribe: Function, private _isEmpty: boolean = false) {} public unsubscribe(): void { this._unsubscribe() + this._isEmpty = true } } diff --git a/test/specs/lib/eventStack/eventStack-test.ts b/test/specs/lib/eventStack/eventStack-test.ts index dfb43df2e9..d5b74ca0c9 100644 --- a/test/specs/lib/eventStack/eventStack-test.ts +++ b/test/specs/lib/eventStack/eventStack-test.ts @@ -3,6 +3,11 @@ import { domEvent } from 'test/utils' describe('eventStack', () => { describe('sub', () => { + test('makes subscription to be non-empty', () => { + const clickSubscription = EventStack.subscribe('click', jest.fn()) + expect(clickSubscription.isEmpty).toBe(false) + }) + test('subscribes for single target', () => { const handler = jest.fn() @@ -47,6 +52,13 @@ describe('eventStack', () => { }) describe('unsub', () => { + test('makes subscription to be empty', () => { + const clickSubscription = EventStack.subscribe('click', jest.fn()) + clickSubscription.unsubscribe() + + expect(clickSubscription.isEmpty).toBe(true) + }) + test('unsubscribes and destroys eventTarget if it is empty', () => { const handler = jest.fn()