toggle-corp/react-store

View on GitHub
components/View/LoadingAnimation/index.js

Summary

Maintainability
A
0 mins
Test Coverage
import PropTypes from 'prop-types';
import React from 'react';

import { typeOf, _cs } from '@togglecorp/fujs';

import Message from '../Message';
import Spinner from '../../../v2/View/Spinner';

import styles from './styles.scss';

const propTypes = {
    className: PropTypes.string,
    message: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.node,
    ]),
    delay: PropTypes.number,
    spinnerClassName: PropTypes.string,
};

const defaultProps = {
    className: '',
    message: undefined,
    spinnerClassName: undefined,
    delay: 0,
};

export default class LoadingAnimation extends React.PureComponent {
    static propTypes = propTypes;

    static defaultProps = defaultProps;

    constructor(props) {
        super(props);
        this.state = {
            showMessage: false,
            sizeCategory: 'medium',
        };
    }

    componentDidMount() {
        const { delay } = this.props;

        this.timeout = setTimeout(() => {
            this.setState({ showMessage: true });
        }, delay);
    }

    componentWillUnmount() {
        clearTimeout(this.timeout);
    }

    handleSizeCategorization = (sizeCategory) => {
        this.setState({ sizeCategory });
    }

    renderMessage = () => {
        const { message } = this.props;

        const isNode = typeOf(message) === 'object';

        if (isNode) {
            return message;
        }

        return (
            <span className={styles.message}>
                {message}
            </span>
        );
    }

    render() {
        const {
            className: classNameFromProps,
            delay, // eslint-disable-line no-unused-vars, @typescript-eslint/no-unused-vars
            message,
            spinnerClassName,
            ...otherProps
        } = this.props;

        const {
            showMessage,
            sizeCategory,
        } = this.state;

        const LoadingMessage = this.renderMessage;

        return (
            <Message
                onSizeCategorization={this.handleSizeCategorization}
                className={_cs(styles.loadingAnimation, classNameFromProps)}
                {...otherProps}
            >
                <Spinner
                    className={spinnerClassName}
                    size={sizeCategory}
                />
                { message && showMessage && <LoadingMessage />}
            </Message>
        );
    }
}