superdesk/superdesk-client-core

View on GitHub
scripts/extensions/sams/src/ui/modal/Modal.tsx

Summary

Maintainability
A
30 mins
Test Coverage
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>
        );
    }
}