Skip to content

Commit

Permalink
fix(Modal): make children accept function with close method in parame…
Browse files Browse the repository at this point in the history
…ters (#2015)
  • Loading branch information
tujoworker committed May 31, 2023
1 parent 06368a7 commit 8e6f247
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 314 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
| `rootId` / `root_id` | _(optional)_ The id used internal in the modal root element. Defaults to `root`, so the element id will be `dnb-modal-root`. |
| `contentId` / `content_id` | _(optional)_ Defines an unique identifier to a modal. Use it in case you have to refer in some way to the modal content. |
| `labelledBy` / `labelled_by` | _(optional)_ The ID of the trigger component, describing the modal content. Defaults to the internal `trigger`, so make sure You define the `title` in `triggerAttributes`. |
| `children` | _(optional)_ the content which will appear when triggering open the modal. |
| `children` or `function` | _(optional)_ the content which will appear when triggering open the modal. If a function is given, you get a close method `() => ({ close })` in the arguments. |
| `fullscreen` | _(optional)_ If set to `true` then the modal content will be shown as fullscreen, without showing the original content behind. Can be set to `false` to omit the auto fullscreen. Defaults to `auto`. |
| `openState` / `open_state` | _(optional)_ use this prop to control the open/close state by setting either: `opened` / `closed` or `true` / `false`. |
| `openDelay` / `open_delay` | _(optional)_ forces the modal to delay the opening. The delay is given in `ms`. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
attachToBody,
} from '../../../core/jest/jestSetup'
import * as helpers from '../../../shared/helpers'
import { render } from '@testing-library/react'
import { fireEvent, render } from '@testing-library/react'

const props = fakeProps(require.resolve('../Dialog.tsx'), {
all: true,
Expand Down Expand Up @@ -361,6 +361,30 @@ describe('Dialog', () => {
).toBe(false)
})

it('will close dialog by using callback method', () => {
const onClose = jest.fn()
const onOpen = jest.fn()

render(
<Dialog
noAnimation={true}
onOpen={onOpen}
onClose={onClose}
hideCloseButton
>
{({ close }) => (
<Button id="close-button" text="close" on_click={close} />
)}
</Dialog>
)

fireEvent.click(document.querySelector('button.dnb-modal__trigger'))
expect(onOpen).toHaveBeenCalledTimes(1)

fireEvent.click(document.querySelector('button#close-button'))
expect(onClose).toHaveBeenCalledTimes(1)
})

it('can contain dialog parts', () => {
const Comp = mount(
<Dialog noAnimation directDomReturn={false}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,30 @@ describe('Drawer', () => {
expect(scrollRef.current).toBeTruthy()
})

it('will close drawer by using callback method', () => {
const onClose = jest.fn()
const onOpen = jest.fn()

render(
<Drawer
noAnimation={true}
onOpen={onOpen}
onClose={onClose}
hideCloseButton
>
{({ close }) => (
<Button id="close-button" text="close" on_click={close} />
)}
</Drawer>
)

fireEvent.click(document.querySelector('button.dnb-modal__trigger'))
expect(onOpen).toHaveBeenCalledTimes(1)

fireEvent.click(document.querySelector('button#close-button'))
expect(onClose).toHaveBeenCalledTimes(1)
})

it('can contain drawer parts', () => {
const Comp = mount(
<Drawer noAnimation directDomReturn={false}>
Expand Down
10 changes: 8 additions & 2 deletions packages/dnb-eufemia/src/components/modal/ModalContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -361,12 +361,13 @@ export default class ModalContent extends React.PureComponent<
no_animation_on_mobile = false,
fullscreen = 'auto',
container_placement = 'right',
close, // eslint-disable-line
close,
content_class,
overlay_class,
content_id,
children, // eslint-disable-line
dialog_role = null,
...rest
} = this.props
const { color } = this.state

Expand Down Expand Up @@ -426,6 +427,11 @@ export default class ModalContent extends React.PureComponent<
onClick: this.onContentClickHandler,
}

const content =
typeof children === 'function'
? children({ ...rest, close })
: children

return (
<ModalContext.Provider
value={{
Expand Down Expand Up @@ -455,7 +461,7 @@ export default class ModalContent extends React.PureComponent<
}
{...contentParams}
>
{children}
{content}
</div>

<span
Expand Down
22 changes: 14 additions & 8 deletions packages/dnb-eufemia/src/components/modal/__tests__/Modal.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
attachToBody, // in order to use document.activeElement properly
loadScss,
} from '../../../core/jest/jestSetup'
import { render } from '@testing-library/react'
import { fireEvent, render } from '@testing-library/react'
import Input from '../../input/Input'
import Component, { OriginalComponent } from '../Modal'
import Button from '../../button/Button'
Expand Down Expand Up @@ -55,18 +55,20 @@ describe('Modal component', () => {
})

it('should add its instance to the stack', () => {
const Comp = mount(
render(
<Component {...props}>
<DialogContent />
</Component>
)

Comp.find('Modal').find('button.dnb-modal__trigger').simulate('click')
fireEvent.click(document.querySelector('button.dnb-modal__trigger'))

expect(window.__modalStack).toHaveLength(1)
expect(typeof window.__modalStack[0]).toBe('object')

Comp.find('button.dnb-modal__close-button').simulate('click')
fireEvent.click(
document.querySelector('button.dnb-modal__close-button')
)

expect(window.__modalStack).toHaveLength(0)
})
Expand Down Expand Up @@ -281,20 +283,24 @@ describe('Modal component', () => {
it('will close modal by using callback method', () => {
const on_close = jest.fn()
const on_open = jest.fn()
const Comp = mount(

render(
<Component
no_animation={true}
on_open={on_open}
on_close={on_close}
hide_close_button
>
{({ close }) => <Button text="close" on_click={close} />}
{({ close }) => {
return <Button id="close-button" text="close" on_click={close} />
}}
</Component>
)
Comp.find('button').simulate('click')

fireEvent.click(document.querySelector('button.dnb-modal__trigger'))
expect(on_open).toHaveBeenCalledTimes(1)

Comp.find('button').simulate('click')
fireEvent.click(document.querySelector('button#close-button'))
expect(on_close).toHaveBeenCalledTimes(1)
})

Expand Down
Loading

0 comments on commit 8e6f247

Please sign in to comment.