Skip to content
This repository was archived by the owner on Nov 1, 2019. It is now read-only.

Commit 3d73136

Browse files
Stefan Wullemshongaar
authored andcommitted
feat: add flexibility to modal (#178)
* more flexible title and extract overlay out of modal * heading as default * cleanup * feat: all parts of the modal are now optional Furthermore, if a custom component is passed in the title prop, it's no longer wrapped in a Heading component.
1 parent d84944a commit 3d73136

File tree

6 files changed

+63
-30
lines changed

6 files changed

+63
-30
lines changed

src/Modal/Modal.stories.tsx

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,39 @@
11
import React from 'react'
22
import Faker from 'faker'
3-
3+
import { MdClose, MdCheck } from 'react-icons/md'
44
import { storiesOf } from '@storybook/react'
5-
import { Modal } from './'
6-
import { Button } from '../Button'
5+
6+
import { Modal, Button, Paragraph, Icon } from '..'
7+
import { Heading } from '../Heading'
78

89
storiesOf('molecules|Modal', module)
910
.add('default', () => {
1011
return (
1112
<Modal
1213
title='Disclaimer'
1314
buttons={[
14-
<Button onClick={() => { return }}>Whatsup</Button>,
15-
<Button danger onClick={() => { return }}>Delete</Button>
16-
]
17-
}> {Faker.lorem.paragraph(30)}</Modal >
15+
<Button success>
16+
<Icon>
17+
<MdCheck />
18+
</Icon>{' '}
19+
Acknowledge
20+
</Button>,
21+
<Button secondary>
22+
<Icon>
23+
<MdClose />
24+
</Icon>{' '}
25+
Close
26+
</Button>
27+
]}
28+
>
29+
<Paragraph>{Faker.lorem.paragraph(8)}</Paragraph>
30+
</Modal>
31+
)
32+
})
33+
.add('custom title', () => {
34+
return (
35+
<Modal title={<Heading type='section'>Custom title component</Heading>}>
36+
<Paragraph>{Faker.lorem.paragraph(8)}</Paragraph>
37+
</Modal>
1838
)
1939
})

src/Modal/Modal.tsx

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,8 @@
1-
import React, { FC } from 'react'
1+
import React, { FC, ReactNode, Children, cloneElement } from 'react'
22
import styled from 'styled-components'
33

44
import { fromTheme } from '../utils/styled'
5-
import { Button } from '../Button'
6-
import { Heading } from '../Heading'
7-
8-
const Overlay = styled.div`
9-
width: 100vw;
10-
height: 100vh;
11-
background-color: rgba(0,0,0,0.1);
12-
position: absolute;
13-
z-index: ${fromTheme(theme => theme.global.zPriority.foreground)};
14-
`
5+
import { Overlay, Button, Heading } from '..'
156

167
const ModalWrapper = styled.div`
178
position: absolute;
@@ -28,8 +19,8 @@ const Header = styled.div`
2819
const Body = styled.div`
2920
padding: ${fromTheme(theme => theme.global.baseSpacing * 1.5)}em;
3021
max-height: 400px;
31-
border-top: solid 1px ${fromTheme(theme => theme.colors.gray)};
32-
border-bottom: solid 1px ${fromTheme(theme => theme.colors.gray)};
22+
border-top: solid 1px ${fromTheme(theme => theme.colors.lightGray)};
23+
border-bottom: solid 1px ${fromTheme(theme => theme.colors.lightGray)};
3324
overflow-y: auto;
3425
`
3526

@@ -44,20 +35,19 @@ const Footer = styled.div`
4435
`
4536

4637
interface ModalProps {
47-
title: string
48-
children: React.ReactNode
49-
buttons: JSX.Element[]
38+
title?: ReactNode
39+
children?: ReactNode
40+
buttons?: JSX.Element[]
5041
}
5142

52-
export const Modal: FC<ModalProps> = ({ title, children, buttons = [], ...rest }) => (
43+
export const Modal: FC<ModalProps> = ({ title, children, buttons, ...rest }) => (
5344
<Overlay {...rest}>
5445
<ModalWrapper>
55-
<Header>
56-
<Heading>{title}</Heading>
57-
</Header>
58-
<Body>{children}</Body>
59-
<Footer>{React.Children.map(buttons,
60-
(child, index) => React.cloneElement(child, { ...child.props, key: index }))}</Footer>
46+
{title && <Header>{typeof title === 'string' ? <Heading>{title}</Heading> : title}</Header>}
47+
{children && <Body>{children}</Body>}
48+
{buttons && (
49+
<Footer>{Children.map(buttons, (child, index) => cloneElement(child, { ...child.props, key: index }))}</Footer>
50+
)}
6151
</ModalWrapper>
6252
</Overlay>
6353
)

src/Overlay/Overlay.stories.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import React from 'react'
2+
import { storiesOf } from '@storybook/react'
3+
4+
import { Overlay } from './Overlay'
5+
6+
export default storiesOf('atoms/Overlay', module)
7+
.add('default', () => (
8+
<Overlay />
9+
))

src/Overlay/Overlay.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import styled from 'styled-components'
2+
3+
import { Block } from '../Block'
4+
import { fromTheme } from '../utils'
5+
6+
export const Overlay = styled(Block)`
7+
width: 100vw;
8+
height: 100vh;
9+
background-color: rgba(0,0,0,0.1);
10+
position: absolute;
11+
z-index: ${fromTheme(theme => theme.global.zPriority.foreground)};
12+
`

src/Overlay/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { Overlay } from './Overlay'

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export * from './ListFocus'
2525
export * from './ListItem'
2626
export * from './Markdown'
2727
export * from './Modal'
28+
export * from './Overlay'
2829
export * from './Paragraph'
2930
export * from './Radio'
3031
export * from './Searchbar'

0 commit comments

Comments
 (0)