Skip to content

Commit

Permalink
fix(Popup|Portal): do not close when mouse click was occurred inside (#…
Browse files Browse the repository at this point in the history
…3575)

* Fix

* Rework.

* Rework of rework.

* Fix typo.

* fix path to PopupOffsetExample

* fix path to PopupExampleHideOnScroll

* naming update, set `null` instead of `delete`
  • Loading branch information
mihai-dinculescu authored and layershifter committed May 5, 2019
1 parent c9a3418 commit d6751d0
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 4 deletions.
4 changes: 2 additions & 2 deletions docs/src/examples/modules/Popup/Usage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const PopupUsageExamples = () => (
<ComponentExample
title='Offset'
description='A popup position can be offset from its position.'
examplePath='modules/Popup/Variations/PopupExampleOffset'
examplePath='modules/Popup/Usage/PopupExampleOffset'
>
<Message info>
<p>
Expand Down Expand Up @@ -71,7 +71,7 @@ const PopupUsageExamples = () => (
<ComponentExample
title='Hide on scroll'
description='A popup can be hidden on a scroll event.'
examplePath='modules/Popup/Variations/PopupExampleHideOnScroll'
examplePath='modules/Popup/Usage/PopupExampleHideOnScroll'
/>
<ComponentExample
title='Default Open'
Expand Down
10 changes: 10 additions & 0 deletions src/addons/Portal/Portal.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class Portal extends Component {

contentRef = createRef()
triggerRef = createRef()
latestDocumentMouseDownEvent = null

componentWillUnmount() {
// Clean up timers
Expand All @@ -140,12 +141,20 @@ class Portal extends Component {
// Document Event Handlers
// ----------------------------------------

handleDocumentMouseDown = (e) => {
this.latestDocumentMouseDownEvent = e
}

handleDocumentClick = (e) => {
const { closeOnDocumentClick } = this.props
const currentMouseDownEvent = this.latestDocumentMouseDownEvent
this.latestDocumentMouseDownEvent = null

if (
!this.contentRef.current || // no portal
doesNodeContainClick(this.triggerRef.current, e) || // event happened in trigger (delegate to trigger handlers)
(currentMouseDownEvent &&
doesNodeContainClick(this.contentRef.current, currentMouseDownEvent)) || // event originated in the portal but was ended outside
doesNodeContainClick(this.contentRef.current, e) // event happened in the portal
) {
return
Expand Down Expand Up @@ -352,6 +361,7 @@ class Portal extends Component {
pool={eventPool}
target={this.contentRef}
/>
<EventStack name='mousedown' on={this.handleDocumentMouseDown} pool={eventPool} />
<EventStack name='click' on={this.handleDocumentClick} pool={eventPool} />
<EventStack name='keydown' on={this.handleEscape} pool={eventPool} />
</Fragment>
Expand Down
18 changes: 16 additions & 2 deletions test/specs/addons/Portal/Portal-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import PortalInner from 'src/addons/Portal/PortalInner'

let wrapper

const createHandlingComponent = eventName =>
const createHandlingComponent = (eventName) =>
class HandlingComponent extends Component {
static propTypes = {
handler: PropTypes.func,
}

handleEvent = e => this.props.handler(e, this.props)
handleEvent = (e) => this.props.handler(e, this.props)

render() {
const buttonProps = { [eventName]: this.handleEvent }
Expand Down Expand Up @@ -600,6 +600,20 @@ describe('Portal', () => {
wrapper.update()
wrapper.should.have.descendants(PortalInner)
})

it('does not close on mousedown inside and mouseup outside', () => {
wrapperMount(
<Portal closeOnDocumentClick defaultOpen>
<p id='inner' />
</Portal>,
)
wrapper.should.have.descendants(PortalInner)

domEvent.mouseDown('#inner')
domEvent.click(document)
wrapper.update()
wrapper.should.have.descendants(PortalInner)
})
})

// Heads Up!
Expand Down

0 comments on commit d6751d0

Please sign in to comment.