scripts/extensions/sams/src/ui/modal/Modal.tsx
import * as React from 'react';
import classNames from 'classnames';
import {Portal} from '../Portal';
export type IModalSize = 'large' | 'x-large' | 'fill' | 'fullscreen';
interface IProps {
id: string;
size?: IModalSize;
closeOnEsc?: boolean;
closeModal?(): void;
theme?: 'dark-ui';
fullHeight?: boolean;
}
export class Modal extends React.PureComponent<IProps> {
constructor(props: IProps) {
super(props);
this.handleKeydown = this.handleKeydown.bind(this);
}
handleKeydown(event: KeyboardEvent) {
if (event.code === 'Escape' && this.props.closeModal) {
event.preventDefault();
this.props.closeModal();
}
}
componentDidMount() {
if (this.props.closeOnEsc) {
document.addEventListener('keydown', this.handleKeydown);
}
}
componentWillUnmount() {
if (this.props.closeOnEsc) {
document.removeEventListener('keydown', this.handleKeydown);
}
}
render() {
const modalClass = classNames(
'modal',
{[`modal--${this.props.size}`]: this.props.size},
);
const dialogStyle = !this.props.fullHeight ? {} : {height: '100%'};
return (
<Portal id={this.props.id}>
<div className="modal__backdrop fade in" />
<div
className={modalClass}
style={{display: 'block'}}
data-theme={this.props.theme}
>
<div className="modal__dialog" style={dialogStyle}>
<div className="modal__content">
{this.props.children}
</div>
</div>
</div>
</Portal>
);
}
}