diff --git a/packages/dnb-ui-lib/src/components/modal/Example.js b/packages/dnb-ui-lib/src/components/modal/Example.js
index c2b9c70ceb2..4496ecc91cd 100644
--- a/packages/dnb-ui-lib/src/components/modal/Example.js
+++ b/packages/dnb-ui-lib/src/components/modal/Example.js
@@ -48,6 +48,22 @@ class Example extends PureComponent {
Focus me with Tab key
+
+ `}
+
+
+ {/* @jsx */ `
+ {
+ setTimeout(close, 3e3)
+ }}
+>
+
+ This Modal will close in 3 seconds.
+
`}
diff --git a/packages/dnb-ui-lib/src/components/modal/Modal.js b/packages/dnb-ui-lib/src/components/modal/Modal.js
index a0790462241..75ff2eef3fc 100644
--- a/packages/dnb-ui-lib/src/components/modal/Modal.js
+++ b/packages/dnb-ui-lib/src/components/modal/Modal.js
@@ -27,6 +27,8 @@ const renderProps = {
on_open: null,
on_close: null,
on_close_prevent: null,
+ open_modal: null,
+ close_modal: null,
modal_content: null
}
@@ -46,6 +48,7 @@ export const propTypes = {
PropTypes.bool
]),
prevent_close: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
+ open_state: PropTypes.oneOf(['opened', 'closed']),
class: PropTypes.string,
// React props
@@ -56,11 +59,15 @@ export const propTypes = {
PropTypes.func
]),
- // Web Component props
- preventSetTriggerRef: PropTypes.bool,
+ // Events and functions
on_open: PropTypes.func,
on_close: PropTypes.func,
on_close_prevent: PropTypes.func,
+ open_modal: PropTypes.func,
+ close_modal: PropTypes.func,
+
+ // Web Component props
+ preventSetTriggerRef: PropTypes.bool,
modal_content: PropTypes.oneOfType([
PropTypes.string,
PropTypes.node,
@@ -126,7 +133,23 @@ export default class Modal extends PureComponent {
}
}
+ static getDerivedStateFromProps(props, state) {
+ if (state._listenForPropChanges) {
+ switch (props.open_state) {
+ case 'opened':
+ state.modalActive = true
+ break
+ case 'closed':
+ state.modalActive = false
+ break
+ }
+ }
+ state._listenForPropChanges = true
+ return state
+ }
+
state = {
+ _listenForPropChanges: true,
modalActive: false
}
@@ -153,19 +176,38 @@ export default class Modal extends PureComponent {
}
}
+ componentDidMount() {
+ const { open_modal, open_state } = this.props
+ if (typeof open_modal === 'function') {
+ open_modal(() => {
+ this.toggleOpenClose(null, true)
+ }, this)
+ }
+ if (open_state) {
+ this.handleSideEffects(this.state.modalActive)
+ }
+ }
+ componentWillUnmount() {
+ this.toggleOpenClose(null, false)
+ }
+
toggleOpenClose = (event = null, showModal = null) => {
if (event && event.preventDefault) {
event.preventDefault()
}
- Modal.insertModalRoot()
-
const modalActive =
showModal !== null ? showModal : !this.state.modalActive
this.setState({
- modalActive
+ modalActive,
+ _listenForPropChanges: false
})
+ this.handleSideEffects(modalActive)
+ }
+ handleSideEffects = modalActive => {
+ Modal.insertModalRoot()
+
// prevent scrolling on the background
try {
document.body.setAttribute(
@@ -179,6 +221,15 @@ export default class Modal extends PureComponent {
)
}
+ 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) {
dispatchCustomElementEvent(this, 'on_open', { id })
@@ -214,9 +265,6 @@ export default class Modal extends PureComponent {
this.toggleOpenClose(e, false)
}
}
- componentWillUnmount() {
- this.toggleOpenClose(null, false)
- }
render() {
const {
id, // eslint-disable-line
diff --git a/packages/dnb-ui-lib/src/components/modal/__tests__/__snapshots__/Modal.test.js.snap b/packages/dnb-ui-lib/src/components/modal/__tests__/__snapshots__/Modal.test.js.snap
index 1701cf671db..4e46d6c3be9 100644
--- a/packages/dnb-ui-lib/src/components/modal/__tests__/__snapshots__/Modal.test.js.snap
+++ b/packages/dnb-ui-lib/src/components/modal/__tests__/__snapshots__/Modal.test.js.snap
@@ -9,6 +9,7 @@ exports[`Modal component have to match snapshot 1`] = `
"children": "children",
"class": "class",
"className": "className",
+ "close_modal": [Function],
"close_title": "close_title",
"content_id": "content_id",
"hide_close_button": "hide_close_button",
@@ -18,6 +19,8 @@ exports[`Modal component have to match snapshot 1`] = `
"on_close": [Function],
"on_close_prevent": [Function],
"on_open": [Function],
+ "open_modal": [Function],
+ "open_state": "'opened'",
"preventSetTriggerRef": true,
"prevent_close": "prevent_close",
"title": "title",
@@ -67,6 +70,7 @@ exports[`Modal component have to match snapshot 1`] = `
}
class={null}
className={null}
+ close_modal={null}
close_title="close_title"
content_id="modal_content_id"
hide_close_button={false}
@@ -76,6 +80,7 @@ exports[`Modal component have to match snapshot 1`] = `
on_close={null}
on_close_prevent={null}
on_open={null}
+ open_modal={null}
preventSetTriggerRef={true}
prevent_close={false}
title="modal_title"
@@ -191,6 +196,7 @@ exports[`Modal component have to match snapshot 1`] = `
"children": "children",
"class": "class",
"className": "className",
+ "close_modal": [Function],
"close_title": "close_title",
"content_id": "content_id",
"hide_close_button": "hide_close_button",
@@ -200,6 +206,8 @@ exports[`Modal component have to match snapshot 1`] = `
"on_close": [Function],
"on_close_prevent": [Function],
"on_open": [Function],
+ "open_modal": [Function],
+ "open_state": "'opened'",
"preventSetTriggerRef": true,
"prevent_close": "prevent_close",
"title": "title",
@@ -250,6 +258,7 @@ exports[`Modal component have to match snapshot 1`] = `
class={null}
className={null}
closeModal={[Function]}
+ close_modal={null}
close_title="close_title"
content_id="modal_content_id"
hide_close_button={false}
@@ -258,6 +267,7 @@ exports[`Modal component have to match snapshot 1`] = `
on_close={null}
on_close_prevent={null}
on_open={null}
+ open_modal={null}
prevent_close={false}
title="modal_title"
toggleOpenClose={[Function]}
@@ -270,6 +280,7 @@ exports[`Modal component have to match snapshot 1`] = `
"children": "children",
"class": "class",
"className": "className",
+ "close_modal": [Function],
"close_title": "close_title",
"content_id": "content_id",
"hide_close_button": "hide_close_button",
@@ -279,6 +290,8 @@ exports[`Modal component have to match snapshot 1`] = `
"on_close": [Function],
"on_close_prevent": [Function],
"on_open": [Function],
+ "open_modal": [Function],
+ "open_state": "'opened'",
"preventSetTriggerRef": true,
"prevent_close": "prevent_close",
"title": "title",
@@ -329,6 +342,7 @@ exports[`Modal component have to match snapshot 1`] = `
class={null}
className={null}
closeModal={[Function]}
+ close_modal={null}
close_title="close_title"
content_id="modal_content_id"
hide_close_button={false}
@@ -337,6 +351,7 @@ exports[`Modal component have to match snapshot 1`] = `
on_close={null}
on_close_prevent={null}
on_open={null}
+ open_modal={null}
prevent_close={false}
title="modal_title"
toggleOpenClose={[Function]}
diff --git a/packages/dnb-ui-lib/src/components/modal/details.md b/packages/dnb-ui-lib/src/components/modal/details.md
index 056af558670..2056a16495b 100644
--- a/packages/dnb-ui-lib/src/components/modal/details.md
+++ b/packages/dnb-ui-lib/src/components/modal/details.md
@@ -10,6 +10,9 @@
| `close_title` | _(optional)_ the title of the close button. Defaults to _Close Modal Window_ |
| `hide_close_button` | _(optional)_ if set to true, the close button will now be shown |
| `prevent_close` | _(optional)_ if set to `true` (boolean or string), then the user can't close the modal. |
+| `open_state` | _(optional)_ use this prop to control the open/close state by setting either: `opened` or `closed` |
+| `open_modal` | _(optional)_ set a function to call the callback function, once the modal should open: `open_modal={(open) => open()}` |
+| `close_modal` | _(optional)_ set a function to call the callback function, once the modal should close: `close_modal={(close) => close()}` |
| Events | Description |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
diff --git a/packages/dnb-ui-lib/stories/componentsStories.js b/packages/dnb-ui-lib/stories/componentsStories.js
index 2cf2387cdf6..d6f9c9b1f6b 100644
--- a/packages/dnb-ui-lib/stories/componentsStories.js
+++ b/packages/dnb-ui-lib/stories/componentsStories.js
@@ -255,11 +255,40 @@ stories.push([
)
])
-stories.push([
- 'Modal',
- () => (
-
-
+class ModalCloseExample extends React.PureComponent {
+ state = {
+ open_state: null
+ }
+
+ // constructor(props) {
+ // super(props)
+ //
+ // setTimeout(() => {
+ // this.setState({
+ // open_state: 'opened'
+ // })
+ // setTimeout(() => {
+ // this.setState({
+ // open_state: 'closed'
+ // })
+ // }, 3e3)
+ // }, 1e3)
+ // }
+
+ render() {
+ return (
+ {
+ // setTimeout(open, 3e3)
+ // }}
+ close_modal={close => {
+ console.log('Modal was opened')
+ setTimeout(close, 3e3)
+ }}
+ >
Some content
@@ -271,6 +300,31 @@ stories.push([
+ )
+ }
+}
+
+stories.push([
+ 'Modal',
+ () => (
+
+
+
+
+
+ Some content
+ Focus me with Tab key
+
+
+
+
+
+
+
+
+
+
+
)
])