2025-02-06 20:27:56 +03:00
|
|
|
'use client';
|
|
|
|
|
|
|
|
import clsx from 'clsx';
|
|
|
|
|
2025-02-26 00:16:22 +03:00
|
|
|
import { BadgeHelp } from '@/features/help/components';
|
2025-02-12 21:36:03 +03:00
|
|
|
|
2025-03-12 11:54:32 +03:00
|
|
|
import { useEscapeKey } from '@/hooks/use-escape-key';
|
2025-02-06 20:27:56 +03:00
|
|
|
import { useDialogsStore } from '@/stores/dialogs';
|
2025-02-11 20:56:11 +03:00
|
|
|
import { prepareTooltip } from '@/utils/utils';
|
2025-02-06 20:27:56 +03:00
|
|
|
|
2025-03-12 12:04:23 +03:00
|
|
|
import { Button, MiniButton } from '../control';
|
|
|
|
import { IconClose } from '../icons';
|
2025-02-12 21:36:03 +03:00
|
|
|
|
2025-03-12 11:54:32 +03:00
|
|
|
import { ModalBackdrop } from './modal-backdrop';
|
|
|
|
import { type ModalProps } from './modal-form';
|
2025-02-06 20:27:56 +03:00
|
|
|
|
2025-03-12 23:08:01 +03:00
|
|
|
interface ModalViewProps extends ModalProps {
|
|
|
|
/** Float all UI elements on top of contents. */
|
|
|
|
fullScreen?: boolean;
|
|
|
|
}
|
2025-02-06 20:27:56 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Displays a customizable modal window with submit form.
|
|
|
|
*/
|
|
|
|
export function ModalView({
|
|
|
|
children,
|
|
|
|
className,
|
|
|
|
header,
|
|
|
|
overflowVisible,
|
|
|
|
helpTopic,
|
|
|
|
hideHelpWhen,
|
2025-03-12 23:08:01 +03:00
|
|
|
fullScreen,
|
2025-02-06 20:27:56 +03:00
|
|
|
...restProps
|
|
|
|
}: React.PropsWithChildren<ModalViewProps>) {
|
|
|
|
const hideDialog = useDialogsStore(state => state.hideDialog);
|
|
|
|
useEscapeKey(hideDialog);
|
|
|
|
|
|
|
|
return (
|
2025-03-10 16:01:40 +03:00
|
|
|
<div className='cc-modal-wrapper'>
|
2025-02-06 20:27:56 +03:00
|
|
|
<ModalBackdrop onHide={hideDialog} />
|
2025-03-11 12:56:32 +03:00
|
|
|
<div className='cc-animate-modal relative grid border rounded-xl bg-prim-100' role='dialog'>
|
2025-02-06 20:27:56 +03:00
|
|
|
{helpTopic && !hideHelpWhen?.() ? (
|
2025-03-09 21:57:21 +03:00
|
|
|
<BadgeHelp
|
|
|
|
topic={helpTopic}
|
2025-03-11 12:56:32 +03:00
|
|
|
className='absolute z-pop top-2 left-2'
|
2025-03-09 21:57:21 +03:00
|
|
|
padding='p-0'
|
|
|
|
contentClass='sm:max-w-160'
|
|
|
|
/>
|
2025-02-06 20:27:56 +03:00
|
|
|
) : null}
|
|
|
|
|
2025-03-07 16:21:18 +03:00
|
|
|
<MiniButton
|
|
|
|
noPadding
|
2025-03-09 21:57:21 +03:00
|
|
|
aria-label='Закрыть'
|
2025-03-07 16:21:18 +03:00
|
|
|
titleHtml={prepareTooltip('Закрыть диалоговое окно', 'ESC')}
|
|
|
|
icon={<IconClose size='1.25rem' />}
|
2025-03-11 12:56:32 +03:00
|
|
|
className='absolute z-pop top-2 right-2'
|
2025-03-07 16:21:18 +03:00
|
|
|
onClick={hideDialog}
|
|
|
|
/>
|
2025-02-06 20:27:56 +03:00
|
|
|
|
2025-03-12 23:08:01 +03:00
|
|
|
{header ? (
|
|
|
|
<h1
|
|
|
|
className={clsx(
|
|
|
|
'px-12 py-2 select-none',
|
|
|
|
fullScreen && 'z-pop absolute top-0 right-1/2 translate-x-1/2 cc-blur bg-prim-100/90 rounded-2xl'
|
|
|
|
)}
|
|
|
|
>
|
|
|
|
{header}
|
|
|
|
</h1>
|
|
|
|
) : null}
|
2025-02-06 20:27:56 +03:00
|
|
|
|
|
|
|
<div
|
|
|
|
className={clsx(
|
2025-03-04 12:23:23 +03:00
|
|
|
'@container/modal',
|
|
|
|
'max-h-[calc(100svh-8rem)] max-w-[100svw] xs:max-w-[calc(100svw-2rem)]',
|
|
|
|
'overscroll-contain outline-hidden',
|
2025-03-13 01:14:47 +03:00
|
|
|
overflowVisible ? 'overflow-visible' : 'overflow-auto',
|
2025-02-06 20:27:56 +03:00
|
|
|
className
|
|
|
|
)}
|
|
|
|
{...restProps}
|
|
|
|
>
|
|
|
|
{children}
|
|
|
|
</div>
|
|
|
|
|
2025-03-12 23:08:01 +03:00
|
|
|
{!fullScreen ? (
|
|
|
|
<Button
|
|
|
|
text='Закрыть'
|
|
|
|
aria-label='Закрыть'
|
|
|
|
className={clsx(
|
|
|
|
'my-2 mx-auto text-sm min-w-28',
|
|
|
|
fullScreen && 'z-pop absolute bottom-0 right-1/2 translate-x-1/2 cc-blur'
|
|
|
|
)}
|
|
|
|
onClick={hideDialog}
|
|
|
|
/>
|
|
|
|
) : (
|
|
|
|
<div className='z-pop absolute bottom-0 right-1/2 translate-x-1/2 bg-prim-100/90 cc-blur p-3 rounded-xl'>
|
|
|
|
{' '}
|
|
|
|
<Button text='Закрыть' aria-label='Закрыть' className='text-sm min-w-28' onClick={hideDialog} />
|
|
|
|
</div>
|
|
|
|
)}
|
2025-02-06 20:27:56 +03:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|