Skip to content

Commit

Permalink
fix: fix #modal event dispatch handling on opening the modal by using…
Browse files Browse the repository at this point in the history
… `open_state`
  • Loading branch information
tujoworker committed Sep 11, 2019
1 parent 3455a8a commit f26abf7
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 73 deletions.
101 changes: 57 additions & 44 deletions packages/dnb-ui-lib/src/components/modal/Modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ export default class Modal extends PureComponent {

state = {
_listenForPropChanges: true,
currentActiveState: false,
modalActive: false
}

Expand All @@ -186,14 +187,12 @@ export default class Modal extends PureComponent {
}

componentDidMount() {
const { open_modal, open_state } = this.props
if (open_state) {
this.handleSideEffects(this.state.modalActive)
}
const { open_modal } = this.props

if (typeof open_modal === 'function') {
// open_modal(() => {
// this.toggleOpenClose(null, true)
// }, this)
open_modal(() => {
this.toggleOpenClose(null, true)
}, this)
}
}
componentWillUnmount() {
Expand All @@ -211,55 +210,63 @@ export default class Modal extends PureComponent {
modalActive,
_listenForPropChanges: false
})

this.handleSideEffects(modalActive)
}
handleSideEffects = modalActive => {
handleSideEffects = () => {
if (!isTrue(this.props.direct_dom_return)) {
Modal.insertModalRoot()
}

// prevent scrolling on the background
if (typeof document !== 'undefined') {
try {
document.body.setAttribute(
'data-dnb-modal-active',
modalActive ? 'true' : 'false'
)
} catch (e) {
console.warn(
'Modal: Error on set "data-dnb-modal-active" by using element.setAttribute()',
e
)
const modalActive = this.state.modalActive
const currentActiveState = modalActive

const runSideEffect = () => {
// prevent scrolling on the background
if (typeof document !== 'undefined') {
try {
document.body.setAttribute(
'data-dnb-modal-active',
modalActive ? 'true' : 'false'
)
} catch (e) {
console.warn(
'Modal: Error on set "data-dnb-modal-active" by using element.setAttribute()',
e
)
}
}
}

if (modalActive) {
if (typeof this.props.close_modal === 'function') {
this.props.close_modal(() => {
this.isClosing = false
this.toggleOpenClose(null, false)
}, this)
if (modalActive) {
if (typeof this.props.close_modal === 'function') {
this.props.close_modal(() => {
this.isClosing = false
this.toggleOpenClose(null, false)
}, this)
}
}
}

const id = this._id
if (modalActive) {
// to make sure we are after the render cyclus
// this way have the content insted by the time we call this event
this.delayEventDispatch = setTimeout(() => {
const id = this._id
if (modalActive) {
dispatchCustomElementEvent(this, 'on_open', { id })
}, 10)
} else if (this.wasActive) {
dispatchCustomElementEvent(this, 'on_close', { id })
}
this.wasActive = modalActive
} else if (this.wasActive) {
dispatchCustomElementEvent(this, 'on_close', { id })
}

this.wasActive = modalActive

if (modalActive === false) {
if (this._triggerRef && this._triggerRef.current) {
this._triggerRef.current.focus()
if (modalActive === false) {
if (this._triggerRef && this._triggerRef.current) {
this._triggerRef.current.focus()
}
}
}

this.setState(
{
currentActiveState,
_listenForPropChanges: false
},
runSideEffect
)
}
open = e => {
this.toggleOpenClose(e, true)
Expand Down Expand Up @@ -306,9 +313,15 @@ export default class Modal extends PureComponent {
...rest
} = props

const { modalActive } = this.state
const { modalActive, currentActiveState } = this.state
const modal_content = Modal.getContent(this.props)

if (modalActive !== currentActiveState) {
setTimeout(this.handleSideEffects, 1)
// delay the dispatch to make sure we are after the render cyclus
// this way have the content insted by the time we call this event
}

return (
<div className="dnb-modal">
{!isTrue(trigger_hidden) && (
Expand Down
18 changes: 17 additions & 1 deletion packages/dnb-ui-lib/src/components/modal/__tests__/Modal.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,30 @@ describe('Modal component', () => {
)
Comp.find('button').simulate('click')

await wait(11) // wait for the render to be finished
await wait(15) // wait for the event to be called

Comp.find('div.dnb-modal__content__inner').simulate('keyDown', {
key: 'Esc',
keyCode: 27
})

await wait(15) // wait for the event to be called

expect(on_open).toHaveBeenCalled()
expect(on_close).toHaveBeenCalled()
})
it('has working open event and close event on changing the "open_state"', async () => {
const on_close = jest.fn()
const on_open = jest.fn()
const Comp = mount(
<Component {...props} on_close={on_close} on_open={on_open} />
)
Comp.setProps({ open_state: 'opened' })
await wait(10) // wait for the render to be finished
expect(on_open).toHaveBeenCalled()

Comp.setProps({ open_state: 'closed' })
await wait(10) // wait for the render to be finished
expect(on_close).toHaveBeenCalled()
})
it('runs expected side effects', async () => {
Expand Down
75 changes: 47 additions & 28 deletions packages/dnb-ui-lib/stories/components/Modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
*/

import React /* , { useState, useEffect } */ from 'react'
import React, { useState, useEffect } from 'react'
import { Wrapper, Box } from '../helpers'
// import styled from '@emotion/styled'

Expand Down Expand Up @@ -38,6 +38,9 @@ export default [
trigger_text="Open Modal"
title="Modal Title"
className="dnb-core-style"
on_close={e => {
console.log('on_close', e)
}}
>
<Hr />
<Box>
Expand Down Expand Up @@ -68,6 +71,12 @@ export default [
open_state="opened"
labelled_by="custom-triggerer"
className="dnb-core-style"
on_open={e => {
console.log('on_open', e)
}}
on_close={e => {
console.log('on_close', e)
}}
>
<p className="dnb-p">
This Modal was opened by a custom trigger button.
Expand Down Expand Up @@ -155,45 +164,55 @@ let dropdownData = [
}
]

class ModalCloseExample extends React.PureComponent {
state = {
open_state: null
}
const ModalCloseExample = () => {
const [open_state, setOpenState] = useState(null)
const [count, setCount] = useState(0)

// constructor(props) {
// super(props)
//
// setTimeout(() => {
// this.setState({
// open_state: 'opened'
// })
// setTimeout(() => {
// this.setState({
// open_state: 'closed'
// })
// }, 3e3)
// }, 1e3)
// }
useEffect(() => {
if (open_state === 'opened') {
// setTimeout(() => {
setTimeout(() => {
console.log('count:', count)
setCount(count + 1)
}, 1e3)
// setOpenState('opened')
// setTimeout(() => {
// setOpenState('closed')
// }, 3e3)
// }, 1e3)
}
})

render() {
return (
return (
<>
<Button text="Open" on_click={() => setOpenState('opened')} />
<Modal
className="dnb-core-style"
trigger_text="Open Modal and auto close"
title="Modal Title"
// open_state={this.state.open_state}
open_state={open_state}
// open_modal={open => {
// setTimeout(open, 3e3)
// }}
hide_close_button
// hide_close_button
close_modal={close => {
console.log('Modal was opened')
setTimeout(close, 3e3)
if (open_state !== 'opened') {
console.log('Modal was opened')
setTimeout(close, 1e3)
}
}}
on_open={e => {
console.log('on_open', e)
}}
on_close={e => {
console.log('on_close', e)
// clearTimeout(timeoutId)
setOpenState('closed')
}}
>
<Hr />
<Box>
<H2>Some content</H2>
<H2>Some content {count}</H2>
<Input>Focus me with Tab key</Input>
</Box>
<Box>
Expand All @@ -202,6 +221,6 @@ class ModalCloseExample extends React.PureComponent {
</P>
</Box>
</Modal>
)
}
</>
)
}

0 comments on commit f26abf7

Please sign in to comment.