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

139 lines
3.9 KiB
TypeScript

import React, { memo, useMemo } from 'react';
import classNames from 'classnames';
import ClearIcon from '@material-ui/icons/Clear';
import ButtonBase from '@material-ui/core/ButtonBase';
import Dialog from '@material-ui/core/Dialog';
import Button from '@material-ui/core/Button';
import Loading from '@Components/Base/Loading';
import Styles from './index.module.css';
import { ModalProps } from './types';
function Modal(props: ModalProps): React.ReactElement {
/* Global & Local States */
const {
open,
onClose,
onConfirm,
typeSize,
typeIsLoading,
disableEscapeKeyDown,
disableBackdropClick,
disableCancelButton,
disableConfirmButton,
confirmButtonText,
cancelButtonText,
tipsText,
children,
className,
mainName,
titleClassName,
actionClassName,
title,
closeIcon = true,
disabledConfirm,
} = props;
/* Views */
const RenderSize = useMemo(() => {
switch (typeSize) {
case 'xs':
return 'xs';
case 'sm':
return 'sm';
case 'md':
return 'md';
case 'lg':
return 'lg';
case 'xl':
return 'xl';
default:
return 'sm';
}
}, [typeSize]);
const RenderCloseIcon = useMemo<React.ReactElement>(() => {
if (closeIcon) {
return (
<ButtonBase className={classNames(Styles.modalContainerRemoveIcon)} onClick={onClose}>
<ClearIcon className={classNames(Styles.modalContainerRemoveIconStyle)} fontSize="small" />
</ButtonBase>
);
}
return <></>;
}, [open, closeIcon, onClose]);
const RenderTitle = useMemo<React.ReactElement>(() => {
if (title) {
return <div className={classNames(Styles.modalContainerTitle, titleClassName)}>{title}</div>;
}
return <></>;
}, [title]);
const RenderIsLoading = useMemo<React.ReactElement>(
() => <Loading typePosition="relative" typeZIndex={10003} typeIcon="line:relative" isLoading={typeIsLoading} />,
[typeIsLoading],
);
const RenderCancelButton = useMemo<React.ReactElement>(() => {
if (!disableCancelButton) {
return (
<Button className={classNames(Styles.modalContainerActionStyle)} color="default" onClick={onClose}>
{!cancelButtonText ? '取消' : cancelButtonText}
</Button>
);
}
return <></>;
}, [disableCancelButton, cancelButtonText, onClose]);
const RenderConfirmButton = useMemo<React.ReactElement>(() => {
if (!disableConfirmButton) {
return (
<Button
className={classNames(Styles.modalContainerActionStyle)}
color="primary"
variant="contained"
onClick={onConfirm}
disabled={disabledConfirm}
>
{!confirmButtonText ? '確定' : confirmButtonText}
</Button>
);
}
return <></>;
}, [disableConfirmButton, confirmButtonText, onConfirm]);
const RenderTipsText = useMemo(() => {
if (tipsText) {
return tipsText;
}
return <></>;
}, [tipsText]);
/* Main */
return (
<Dialog
className={classNames(Styles.modalContainer, mainName)}
open={open}
onClose={onClose}
fullWidth
maxWidth={RenderSize}
disableEnforceFocus
disableEscapeKeyDown={disableEscapeKeyDown}
disableBackdropClick={disableBackdropClick}
>
<div className={classNames(className)}>
{RenderCloseIcon}
{RenderTitle}
<div className={classNames(Styles.modalContainerContent)} style={{ marginTop: title ? '18px' : '0px' }}>
{children}
</div>
<div
className={classNames(
(!disableCancelButton || !disableConfirmButton) && Styles.modalContainerAction,
actionClassName,
)}
>
{RenderTipsText}
{RenderCancelButton}
{RenderConfirmButton}
</div>
{RenderIsLoading}
</div>
</Dialog>
);
}
export default memo(Modal);