ConceptPortal-public/rsconcept/frontend/src/components/Common/Modal.tsx

108 lines
2.4 KiB
TypeScript
Raw Normal View History

'use client';
import clsx from 'clsx';
2023-07-25 20:27:29 +03:00
import { useRef } from 'react';
2023-12-16 19:20:26 +03:00
import { BiX } from 'react-icons/bi';
2023-07-25 20:27:29 +03:00
import useEscapeKey from '@/hooks/useEscapeKey';
2023-07-25 20:27:29 +03:00
import Button from './Button';
2023-12-04 14:19:54 +03:00
import MiniButton from './MiniButton';
import Overlay from './Overlay';
2023-07-22 12:24:14 +03:00
2023-09-11 17:56:32 +03:00
export interface ModalProps {
2023-07-22 12:24:14 +03:00
title?: string
submitText?: string
2023-08-23 01:36:17 +03:00
submitInvalidTooltip?: string
2023-08-08 23:04:21 +03:00
readonly?: boolean
2023-07-29 03:31:21 +03:00
canSubmit?: boolean
2023-07-25 22:29:33 +03:00
hideWindow: () => void
2023-08-08 23:04:21 +03:00
onSubmit?: () => void
2023-07-22 12:24:14 +03:00
onCancel?: () => void
children: React.ReactNode
2023-12-07 01:21:27 +03:00
className?: string
2023-07-22 12:24:14 +03:00
}
2023-08-23 01:36:17 +03:00
function Modal({
title, hideWindow, onSubmit,
readonly, onCancel, canSubmit,
2023-12-07 01:21:27 +03:00
submitInvalidTooltip, className,
2023-08-23 01:36:17 +03:00
children,
submitText = 'Продолжить'
}: ModalProps) {
2023-07-22 12:24:14 +03:00
const ref = useRef(null);
2023-07-25 22:29:33 +03:00
useEscapeKey(hideWindow);
2023-07-22 12:24:14 +03:00
const handleCancel = () => {
2023-07-25 22:29:33 +03:00
hideWindow();
2023-07-25 20:27:29 +03:00
if (onCancel) onCancel();
2023-07-22 12:24:14 +03:00
};
const handleSubmit = () => {
2023-07-25 22:29:33 +03:00
hideWindow();
2023-08-08 23:04:21 +03:00
if (onSubmit) onSubmit();
};
2023-12-04 14:19:54 +03:00
return (
<>
<div className={clsx(
'z-navigation',
'fixed top-0 left-0',
'w-full h-full',
'clr-modal-backdrop'
)}/>
<div ref={ref}
className={clsx(
'z-modal',
'fixed bottom-1/2 left-1/2 -translate-x-1/2 translate-y-1/2',
'border shadow-md',
'clr-app'
)}
2023-08-08 23:04:21 +03:00
>
2023-12-17 20:19:28 +03:00
<Overlay position='right-[0.3rem] top-2'>
2023-12-04 14:19:54 +03:00
<MiniButton
tooltip='Закрыть диалоговое окно [ESC]'
2023-12-16 19:20:26 +03:00
icon={<BiX size='1.25rem'/>}
2023-12-04 14:19:54 +03:00
onClick={handleCancel}
/>
</Overlay>
2023-12-04 14:19:54 +03:00
{title ? <h1 className='px-12 py-2 select-none'>{title}</h1> : null}
2023-12-04 14:19:54 +03:00
2023-12-07 01:21:27 +03:00
<div
className={clsx(
'overflow-auto',
className
)}
2023-12-07 01:21:27 +03:00
style={{
maxHeight: 'calc(100vh - 8rem)',
maxWidth: 'calc(100vw - 2rem)',
}}
>
2023-07-22 12:24:14 +03:00
{children}
</div>
2023-12-04 14:19:54 +03:00
<div className={clsx(
'z-modal-controls',
'px-6 py-3 flex gap-12 justify-center'
)}>
{!readonly ?
<Button autoFocus
2023-07-22 12:24:14 +03:00
text={submitText}
2023-08-23 01:36:17 +03:00
tooltip={!canSubmit ? submitInvalidTooltip: ''}
className='min-w-[8rem] min-h-[2.6rem]'
2023-11-05 16:31:49 +03:00
colors='clr-btn-primary'
2023-07-22 12:24:14 +03:00
disabled={!canSubmit}
onClick={handleSubmit}
/> : null}
2023-07-25 20:27:29 +03:00
<Button
2023-08-08 23:04:21 +03:00
text={readonly ? 'Закрыть' : 'Отмена'}
className='min-w-[8rem] min-h-[2.6rem]'
2023-07-22 12:24:14 +03:00
onClick={handleCancel}
/>
</div>
</div>
2023-12-02 00:15:56 +03:00
</>);
2023-07-22 12:24:14 +03:00
}
export default Modal;