forked from bulwark-crypto/bulwark-ui
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request bulwark-crypto#45 from dustinengle/modal
fixes bulwark-crypto#27 added modal
- Loading branch information
Showing
7 changed files
with
247 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import PropTypes from 'prop-types' | ||
import React from 'react' | ||
import {pickRest} from '../lib/utils' | ||
|
||
// Modal | ||
export const Modal = (props) => { | ||
if (!props.open) return null | ||
const [mods, {children, onCancel, ...rest}] = pickRest(props, ['open', 'overlay']) | ||
return ( | ||
<div block='modal' mods={mods} onClick={onCancel}> | ||
<div block='modal' elem='container' {...rest}> | ||
{children} | ||
</div> | ||
</div> | ||
) | ||
} | ||
|
||
Modal.propTypes = { | ||
children: PropTypes.any.isRequired, | ||
onCancel: PropTypes.func, | ||
open: PropTypes.bool, | ||
overlay: PropTypes.bool | ||
} | ||
|
||
// Actions | ||
export const ModalActions = ({children, ...rest}) => ( | ||
<div block='modal' elem='actions' {...rest}> | ||
{children} | ||
</div> | ||
) | ||
|
||
ModalActions.propTypes = { | ||
children: PropTypes.any.isRequired | ||
} | ||
|
||
// Content | ||
export const ModalContent = ({children, ...rest}) => ( | ||
<div block='modal' elem='content' {...rest}> | ||
{children} | ||
</div> | ||
) | ||
|
||
ModalContent.propTypes = { | ||
children: PropTypes.any.isRequired | ||
} | ||
|
||
// Title | ||
export const ModalTitle = ({children, ...rest}) => ( | ||
<div block='modal' elem='title' {...rest}> | ||
{children} | ||
</div> | ||
) | ||
|
||
ModalTitle.propTypes = { | ||
children: PropTypes.any.isRequired | ||
} | ||
|
||
export default {Modal, ModalActions, ModalContent, ModalTitle} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
|
||
.modal { | ||
background: transparent; | ||
bottom: 0; | ||
left: 0; | ||
margin: 0; | ||
padding: 0; | ||
position: fixed; | ||
right: 0; | ||
top: 0; | ||
z-index: 10; | ||
|
||
&--open { | ||
opacity: 1; | ||
transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; | ||
will-change: opacity; | ||
} | ||
|
||
&--overlay { | ||
background-color: rgba(0, 0, 0, 0.5); | ||
} | ||
|
||
&__actions { | ||
margin: 0; | ||
padding-top: 42px; | ||
text-align: right; | ||
|
||
.button, button { margin: 0; } | ||
|
||
.button:first-child, button:first-child { margin-right: 20px; } | ||
} | ||
|
||
&__container { | ||
background-color: $white; | ||
border-radius: 5px; | ||
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.25); | ||
left: 50%; | ||
margin: 0; | ||
padding: $modal-padding; | ||
position: fixed; | ||
top: 50%; | ||
transform: translate(-50%, -50%); | ||
} | ||
|
||
&__content { | ||
margin: 0; | ||
padding: 0; | ||
|
||
* { | ||
margin: 0; | ||
padding: 0; | ||
} | ||
} | ||
|
||
&__title { | ||
font-family: $font-secondary; | ||
font-size: 20px; | ||
font-weight: bold; | ||
height: 28px; | ||
letter-spacing: -1px; | ||
line-height: 30px; | ||
margin-bottom: 17px; | ||
|
||
* { | ||
margin: 0; | ||
padding: 0; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* global describe, it */ | ||
import React from 'react' | ||
import expect from 'must' | ||
import {shallow} from 'enzyme' | ||
import Button from '../react/Button' | ||
import {Modal, ModalActions, ModalContent, ModalTitle} from '../react/Modal' | ||
|
||
describe('<Modal />', () => { | ||
it('render as modal', () => { | ||
const wrapper = shallow(<Modal open>Test</Modal>) | ||
expect(wrapper.is('div')).to.be.true() | ||
expect(wrapper.hasClass('modal')).to.be.true() | ||
expect(wrapper.find('.modal__container')).to.have.length(1) | ||
}) | ||
|
||
it('render nothing if not open', () => { | ||
const wrapper = shallow(<Modal>Test</Modal>) | ||
expect(wrapper.html()).to.equal(null) | ||
}) | ||
|
||
it('render as modal open', () => { | ||
const wrapper = shallow(<Modal open>Test</Modal>) | ||
expect(wrapper.hasClass('modal--open')).to.be.true() | ||
}) | ||
|
||
it('render as modal overlay', () => { | ||
const wrapper = shallow(<Modal open overlay>Test</Modal>) | ||
expect(wrapper.hasClass('modal--overlay')).to.be.true() | ||
}) | ||
|
||
it('passes onCancel prop', () => { | ||
const fakeFunc = () => {} | ||
const wrapper = shallow(<Modal open onCancel={fakeFunc}>Test</Modal>) | ||
expect(wrapper.prop('onClick')).to.equal(fakeFunc) | ||
}) | ||
}) | ||
|
||
describe('<ModalActions />', () => { | ||
it('render as modal actions', () => { | ||
const wrapper = shallow(<ModalActions><Button>OK</Button></ModalActions>) | ||
expect(wrapper.is('div')).to.be.true() | ||
expect(wrapper.hasClass('modal__actions')).to.be.true() | ||
}) | ||
}) | ||
|
||
describe('<ModalContent />', () => { | ||
it('render as modal content', () => { | ||
const wrapper = shallow(<ModalContent>OK?</ModalContent>) | ||
expect(wrapper.is('div')).to.be.true() | ||
expect(wrapper.hasClass('modal__content')).to.be.true() | ||
}) | ||
|
||
it('render as modal content text', () => { | ||
const wrapper = shallow(<ModalContent>OK?</ModalContent>) | ||
expect(wrapper.is('div')).to.be.true() | ||
expect(wrapper.text()).to.equal('OK?') | ||
}) | ||
}) | ||
|
||
describe('<ModalTitle />', () => { | ||
it('render as modal title', () => { | ||
const wrapper = shallow(<ModalTitle>Test</ModalTitle>) | ||
expect(wrapper.is('div')).to.be.true() | ||
expect(wrapper.hasClass('modal__title')).to.be.true() | ||
}) | ||
|
||
it('render modal title text', () => { | ||
const wrapper = shallow(<ModalTitle>Test</ModalTitle>) | ||
expect(wrapper.text()).to.equal('Test') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import React from 'react' | ||
|
||
import Button from '../../react/Button' | ||
import {Modal, ModalActions, ModalContent, ModalTitle} from '../../react/Modal' | ||
|
||
class ModalDemo extends React.Component { | ||
state = { | ||
open: false, | ||
overlay: false | ||
} | ||
|
||
handleClick = () => { | ||
const state = {open: !this.state.open} | ||
if (this.state.overlay && !state.open) state.overlay = false | ||
this.setState(state) | ||
} | ||
|
||
handleOverlay = () => this.setState({overlay: !this.state.overlay}, this.handleClick) | ||
|
||
render () { | ||
return ( | ||
<div> | ||
<Modal onCancel={this.handleClick} open={this.state.open} overlay={this.state.overlay}> | ||
<ModalTitle>Terms of Service</ModalTitle> | ||
<ModalContent style={{width: 320}}> | ||
By clicking Sign Up, you agree to our Terms and that you | ||
have read our Data Use Policy, including our Cookie Use. | ||
</ModalContent> | ||
<ModalActions> | ||
<Button primary outline onClick={this.handleClick}>I Accept</Button> | ||
<Button outline onClick={this.handleClick}>No Thanks</Button> | ||
</ModalActions> | ||
</Modal> | ||
<h3>Modal</h3> | ||
<Button onClick={this.handleClick}>Open Modal</Button> | ||
<Button onClick={this.handleOverlay}>Open Modal with Overlay</Button> | ||
</div> | ||
) | ||
} | ||
} | ||
|
||
export default ModalDemo |