110 lines
3.0 KiB
TypeScript
110 lines
3.0 KiB
TypeScript
import React, { memo, useMemo } from 'react';
|
|
import PropTypes from 'prop-types';
|
|
import classNames from 'classnames';
|
|
import LinearProgress from '@material-ui/core/LinearProgress';
|
|
import CircularProgress from '@material-ui/core/CircularProgress';
|
|
import { LoadingProps } from './types';
|
|
import Styles from './index.module.css';
|
|
|
|
function Loading(props: LoadingProps): React.ReactElement {
|
|
/* Global & Local States */
|
|
const {
|
|
typePosition, typeBackground, typeZIndex, typeIcon, isLoading, isHideText, text,
|
|
} = props;
|
|
/* Views */
|
|
const RenderPosition = useMemo(() => {
|
|
switch (typePosition) {
|
|
case 'relative':
|
|
return Styles.relateScreenLoadingContainer;
|
|
case 'absolute':
|
|
return Styles.fullScreenLoadingContainer;
|
|
default:
|
|
return Styles.fullScreenLoadingContainer;
|
|
}
|
|
}, [typePosition]);
|
|
const RenderBackground = useMemo(() => {
|
|
switch (typeBackground) {
|
|
case 'white':
|
|
return Styles.backgroundWhite;
|
|
case 'black':
|
|
return Styles.backgroundBlack;
|
|
default:
|
|
return '';
|
|
}
|
|
}, [typeBackground]);
|
|
const RenderTextColor = useMemo(() => {
|
|
switch (typeBackground) {
|
|
case 'white':
|
|
return Styles.loadingTextWhite;
|
|
case 'black':
|
|
return Styles.loadingTextBlack;
|
|
default:
|
|
return Styles.loadingTextWhite;
|
|
}
|
|
}, [typeBackground]);
|
|
const RenderText = useMemo(() => {
|
|
if (isHideText) {
|
|
return <React.Fragment />;
|
|
}
|
|
return <div className={classNames(RenderTextColor, Styles.loadingTextStyle)}>{text}</div>;
|
|
}, [isHideText, text, typeBackground]);
|
|
const RenderAnimation = useMemo(() => {
|
|
switch (typeIcon) {
|
|
case 'basic':
|
|
return (
|
|
<div className={`${Styles.loadingAreaContainer}`}>
|
|
<CircularProgress size={25} thickness={5} />
|
|
{RenderText}
|
|
</div>
|
|
);
|
|
case 'text':
|
|
return <div className={`${Styles.loadingAreaContainer}`}>{RenderText}</div>;
|
|
case 'icon':
|
|
return (
|
|
<div className={`${Styles.loadingAreaContainer}`}>
|
|
<CircularProgress size={25} thickness={5} />
|
|
</div>
|
|
);
|
|
case 'line:fix':
|
|
return <LinearProgress />;
|
|
case 'line:relative':
|
|
return <LinearProgress />;
|
|
default:
|
|
return <React.Fragment />;
|
|
}
|
|
}, [typeIcon, isHideText, text]);
|
|
return (
|
|
<>
|
|
{isLoading && (
|
|
<div
|
|
className={classNames(RenderPosition, RenderBackground, Styles.flexCentral)}
|
|
style={{ zIndex: typeZIndex }}
|
|
>
|
|
{RenderAnimation}
|
|
</div>
|
|
)}
|
|
</>
|
|
);
|
|
}
|
|
|
|
Loading.propTypes = {
|
|
typePosition: PropTypes.string,
|
|
typeBackground: PropTypes.string,
|
|
typeZIndex: PropTypes.number,
|
|
typeIcon: PropTypes.string,
|
|
isLoading: PropTypes.bool,
|
|
isHideText: PropTypes.bool,
|
|
text: PropTypes.string,
|
|
};
|
|
Loading.defaultProps = {
|
|
typePosition: 'relative',
|
|
typeBackground: '',
|
|
typeZIndex: 10000,
|
|
typeIcon: 'line:relative',
|
|
isLoading: false,
|
|
isHideText: false,
|
|
text: '',
|
|
};
|
|
|
|
export default memo(Loading);
|