Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modal #123

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open

Modal #123

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions demo/content/Modal/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,29 @@ export default class DemoContentModal extends Component {
{'Pass a function that will fire when Modal window is closed'}
</td>
</tr>
<tr>
<td><b>overlayBackground</b></td>
<td>string</td>
<td>
<code>-</code>
</td>
<td>
Enter a value to overide the default OIO Modal background overlay.
You can enter a value that would be equivalent to one that can be
passed to the css <code>background</code> property
</td>
</tr>
<tr>
<td><b>overlayOpacity</b></td>
<td>Number</td>
<td>
<code>0.97</code>
</td>
<td>
Set a number for the opacity of the Modal component&apos;s
overlay background
</td>
</tr>
<tr>
<td><b>width</b></td>
<td>String</td>
Expand Down
86 changes: 70 additions & 16 deletions src/components/Modal/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import PropTypes from 'prop-types'
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import { Link } from 'react-router-dom'
import classNames from 'classnames'
import { getWindowSize, getAttributeForCurrentSize } from '../../utils/size'
import Icon from '../Icon'
import View from '../View'
import style from './style.less'

export default class Modal extends Component {
Expand All @@ -14,6 +16,8 @@ export default class Modal extends Component {
closeURL: PropTypes.string,
mode: PropTypes.string,
onClose: PropTypes.func,
overlayBackground: PropTypes.string,
overlayOpacity: PropTypes.number.isRequired,
width: PropTypes.string,
windowClassName: PropTypes.string,
windowMargin: PropTypes.string,
Expand All @@ -26,6 +30,7 @@ export default class Modal extends Component {
mode: 'fixed',
width: '600px',
height: '600px',
overlayOpacity: 0.97,
windowMargin: '0px',
zIndex: '900'
}
Expand All @@ -37,6 +42,18 @@ export default class Modal extends Component {
position: 'middleCenter',
size: getWindowSize()
}

const oioContainer = document.getElementById('oio-container')
this.modalContainer = document.getElementById('modal-container')

if (!this.modalContainer) {
this.modalContainer = document.createElement('div')
this.modalContainer.setAttribute('id', 'modal-container')
oioContainer.appendChild(this.modalContainer)
}

this.modalElement = document.createElement('div')
this.modalContainer.appendChild(this.modalElement)
}

componentDidMount() {
Expand All @@ -46,6 +63,7 @@ export default class Modal extends Component {

componentWillUnmount() {
window.removeEventListener('resize', this.windowSizeUpdated)
this.modalContainer.removeChild(this.modalElement)
}

windowSizeUpdated = () => {
Expand All @@ -62,45 +80,62 @@ export default class Modal extends Component {
}

hideModal = (event) => {
if (this.props.onClose && this.node === event.target) {
if (this.props.onClose &&
(event.target === this.overlay || event.target === this.closeButton)) {
this.props.onClose()
}
// TODO: Below will be used once we figure out how to get history as
// browserHistory working correctly
// Presumeable, the developer can also pass an onClose function as well
// if (this.node === event.target) {
// if (this.overlay === event.target) {
// browserHistory.push(this.props.closeURL)
// }
}

render() {
const { animation, children, closeURL, zIndex, windowClassName } = this.props
const { animation, children, closeURL, onClose,
overlayBackground, overlayOpacity, zIndex, windowClassName } = this.props
const size = this.state.size
const width = parseFloat(getAttributeForCurrentSize(size, this.props.width))
const height = parseFloat(getAttributeForCurrentSize(size, this.props.height))
const width = getAttributeForCurrentSize(size, this.props.width)
const height = getAttributeForCurrentSize(size, this.props.height)
const mode = getAttributeForCurrentSize(size, this.props.mode)
const modalWindowMargin = getAttributeForCurrentSize(size, this.props.windowMargin)
const modalWindowStyle = {}

const modalOverlayStyle = {
backgroundColor: `rgba(12,15,20,${overlayOpacity})`,
padding: modalWindowMargin,
zIndex
}

// If overlayBackground is supplied through props, override default backgroundColor
if (overlayBackground) {
modalOverlayStyle.background = overlayBackground
}

const modalWindowClasses = [
style.modalWindow,
style[animation],
windowClassName
]

if (mode === 'fixed') {
modalWindowStyle.width = `${width}px`
modalWindowStyle.height = `${height}px`
modalWindowStyle.width = width
modalWindowStyle.height = height

if (this.state.position === 'middleCenter') {
if (width.endsWith('%')) {
modalWindowStyle.left = `${((100 - parseFloat(width)) / 2)}%`
} else {
modalWindowStyle.marginLeft = `${(parseFloat(width) / 2) * -1}px`
}

if (height.endsWith('%')) {
modalWindowStyle.top = `${((100 - parseFloat(height)) / 2)}%`
} else {
modalWindowStyle.marginTop = `${(parseFloat(height) / 2) * -1}px`
}
modalWindowClasses.push(style.positionAtMiddleAndCenter)
modalWindowStyle.marginTop = `${(height / 2) * -1}px`
modalWindowStyle.marginLeft = `${(width / 2) * -1}px`
} else if (this.state.position === 'topCenter') {
modalWindowClasses.push(style.positionAtTopCenter)
}
Expand All @@ -112,9 +147,26 @@ export default class Modal extends Component {
modalWindowStyle.bottom = modalWindowMargin
}

return (
const closeButtonIcon = (
<View
position="top right"
padding="0px[a-c] 6px[d] 24px[e]"
className={style.closeButtonContainer}
style={{ cursor: 'pointer', zIndex: zIndex + 1 }}>
<div className={style.closeButtonIcon}>
<Icon name="ion-ios-close-empty" />
<div
onClick={onClose}
ref={(closeButton) => { this.closeButton = closeButton }}
className={style.hitArea}
/>
</div>
</View>
)

return ReactDOM.createPortal(
<div
ref={node => (this.node = node)}
ref={(overlay) => { this.overlay = overlay }}
onClick={this.hideModal}
className={style.modalOverlay}
style={modalOverlayStyle}>
Expand All @@ -123,10 +175,12 @@ export default class Modal extends Component {
style={modalWindowStyle}>
{children}
</div>
<Link to={closeURL}>
<Icon name="ion-ios-close-empty" className={style.closeButton} />
</Link>
</div>
)
{onClose && closeButtonIcon}
{!onClose && closeURL && (
<Link to={closeURL}>{closeButtonIcon}</Link>
)}
</div>,
this.modalElement
)
}
}
27 changes: 18 additions & 9 deletions src/components/Modal/style.less
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
left: 0px;
right: 0px;
bottom: 0px;
background: rgba(12,15,20,0.97);
animation-duration: 400ms;
animation-name: showOverlay;
animation-timing-function: ease-out;
Expand Down Expand Up @@ -74,21 +73,31 @@
// Close Button
// =====================================================

.closeButton {
position: fixed;
top: 30px;
right: 30px;
font-size: 60px;
line-height: 60px;
.closeButtonContainer {
position: fixed !important;
}

.closeButtonIcon {
float: left;
position: relative;
font-size: 48px;
line-height: 48px;
width: 60px;
height: 60px;
border-radius: 50%;
padding: 6px 0px;
text-align: center;
color: #666;
transition: 300ms;

.hitArea {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}

&:hover {
color: #fff;
background: #222;
}
}
1 change: 1 addition & 0 deletions src/components/OIO/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default class OIO extends Component {

return (
<div
id="oio-container"
className={classNames(style.OIO, this.props.className)}
style={OIOStyles}>
{this.props.children}
Expand Down