Skip to content

Instantly share code, notes, and snippets.

@webinista
Last active October 4, 2018 20:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save webinista/c6a871139b4e64844e5cbc0b2da7b6e2 to your computer and use it in GitHub Desktop.
Save webinista/c6a871139b4e64844e5cbc0b2da7b6e2 to your computer and use it in GitHub Desktop.
A work-in-progress React component for modals. Uses the <dialog> element.
/*
DialogModal. Depends on the presence of dialog-polyfill.js
and dialog-polyfill.css with the page in non-Chrome browsers.
https://github.com/GoogleChrome/dialog-polyfill
MIT licensed.
*/
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
export default class DialogModal extends React.Component {
constructor( _props ) {
super( _props );
this.dialog = null;
this.closeModal = this.closeModal.bind(this);
this.closeButton = this.closeButton.bind(this);
this.makeTitle = this.makeTitle.bind(this);
}
/* Only necessary for the polyfill. Once <dialog> is more widely supported, we can remove this. */
componentDidMount() {
this.dialog = document.querySelector(`#${this.props.id}`);
window.dialogPolyfill.registerDialog(this.dialog);
}
componentDidUpdate(previousProps) {
if(this.props.open) {
this.dialog.showModal();
}
}
closeModal(domEvent) {
domEvent.stopPropagation();
const node = domEvent.target.nodeName;
if((node === 'DIALOG') || (node === 'BUTTON')){
this.dialog.close();
this.props.closeHandler();
}
}
makeTitle() {
if(this.props.title) {
return <h2>{this.props.title}</h2>;
} else {
return null;
}
}
closeButton() {
return (
<button type="button" className="dialog__body__close" onClick={this.closeModal}>
<svg viewBox="0 0 300 300" version="1.1" xmlns="http://www.w3.org/2000/svg">
<title>Close this modal</title>
<polygon id="×" fill="#CBCBCB" points="1.61065574 242.514344 93.8196721 150.305328 1 57.7909836 57.7909836 1 150.610656 93.5143443 242.819672 1.30532787 298.084016 56.875 205.875 149.084016 299 242.209016 242.209016 299 149.084016 205.875 56.875 298.084016"></polygon>
</svg>
</button>
);
}
render() {
let cssClasses = classNames(
this.props.cssClass,
{
'dialog__body' : true
}
);
return (
<dialog id={this.props.id} className="dialog__wrapper" onClick={this.closeModal}>
<div className={cssClasses}>
{this.makeTitle()}
{this.closeButton()}
{this.props.body}
</div>
</dialog>
)
}
}
DialogModal.defaultProps = {
closeHandler: ()=>{},
showModal: ()=>{},
open: false,
body: {},
id: ''
};
DialogModal.propTypes = {
closeHandler: PropTypes.func.isRequired,
showModal: PropTypes.func,
open: PropTypes.bool.isRequired,
body: PropTypes.object.isRequired,
id: PropTypes.string.isRequired
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment