100 lines
2.7 KiB
JavaScript
100 lines
2.7 KiB
JavaScript
import React, { Component } from "react";
|
|
import PropTypes from "prop-types";
|
|
import cx from "classnames";
|
|
import Measure from "react-measure";
|
|
|
|
export default class Modal extends Component {
|
|
static PropTypes = {
|
|
variations: PropTypes.array,
|
|
disableClose: PropTypes.bool,
|
|
handleClose: PropTypes.func,
|
|
handleSave: PropTypes.func,
|
|
title: PropTypes.string,
|
|
subtitle: PropTypes.string,
|
|
navigation: PropTypes.node,
|
|
actions: PropTypes.node,
|
|
footer: PropTypes.node
|
|
};
|
|
|
|
constructor(props) {
|
|
super(props);
|
|
|
|
this.state = {
|
|
windowHeight: {},
|
|
modalHeight: {}
|
|
};
|
|
|
|
this.updateHeights = this.updateHeights.bind(this);
|
|
}
|
|
|
|
updateHeights(contentRect) {
|
|
this.setState({ windowHeight: window.innerHeight });
|
|
this.setState({ modalHeight: contentRect.bounds.height });
|
|
}
|
|
|
|
readVariationClasses() {
|
|
if (this.props.variations) {
|
|
const { variations } = this.props;
|
|
const classes = variations.reduce(
|
|
(classes, variation) => classes + `cabana-modal--${variation} `,
|
|
""
|
|
);
|
|
return classes;
|
|
}
|
|
}
|
|
|
|
checkClosability() {
|
|
return this.props.disableClose || false;
|
|
}
|
|
|
|
checkYScrollability() {
|
|
return this.state.modalHeight > this.state.windowHeight;
|
|
}
|
|
|
|
render() {
|
|
return (
|
|
<div
|
|
className={cx("cabana-modal", this.readVariationClasses(), {
|
|
"cabana-modal--not-closable": this.checkClosability(),
|
|
"cabana-modal--scrollable-y": this.checkYScrollability()
|
|
})}
|
|
>
|
|
<Measure
|
|
bounds
|
|
onResize={contentRect => {
|
|
this.updateHeights(contentRect);
|
|
}}
|
|
>
|
|
{({ measureRef }) => (
|
|
<div ref={measureRef} className="cabana-modal-container">
|
|
<div
|
|
className="cabana-modal-close-icon"
|
|
onClick={this.props.handleClose}
|
|
/>
|
|
<div className="cabana-modal-header">
|
|
<h1>{this.props.title}</h1>
|
|
<p>{this.props.subtitle}</p>
|
|
</div>
|
|
<div className="cabana-modal-navigation">
|
|
{this.props.navigation}
|
|
</div>
|
|
<div className="cabana-modal-body">
|
|
<div className="cabana-modal-body-window">
|
|
{this.props.children}
|
|
</div>
|
|
<div className="cabana-modal-body-gradient" />
|
|
</div>
|
|
<div className="cabana-modal-actions">{this.props.actions}</div>
|
|
<div className="cabana-modal-footer">{this.props.footer}</div>
|
|
</div>
|
|
)}
|
|
</Measure>
|
|
<div
|
|
className="cabana-modal-backdrop"
|
|
onClick={this.props.handleClose}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
}
|