keycloak-demo-frontend/src/components/Base/Loading/index.tsx

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);