portainer/app/react/components/modals/Modal/Modal.tsx

64 lines
1.6 KiB
TypeScript

import { DialogContent, DialogOverlay } from '@reach/dialog';
import clsx from 'clsx';
import { createContext, PropsWithChildren, useContext } from 'react';
import { CloseButton } from './CloseButton';
import styles from './Modal.module.css';
const Context = createContext<boolean | null>(null);
Context.displayName = 'ModalContext';
export function useModalContext() {
const context = useContext(Context);
if (!context) {
throw new Error('should be nested under Modal');
}
return context;
}
interface Props {
onDismiss?(): void;
'aria-label'?: string;
'aria-labelledby'?: string;
size?: 'md' | 'lg';
className?: string;
}
export function Modal({
children,
onDismiss,
'aria-label': ariaLabel,
'aria-labelledby': ariaLabelledBy,
size = 'md',
className,
}: PropsWithChildren<Props>) {
return (
<Context.Provider value>
<DialogOverlay
isOpen
className={clsx(
styles.overlay,
'z-50 flex items-center justify-center'
)}
onDismiss={onDismiss}
role="dialog"
>
<DialogContent
aria-label={ariaLabel}
aria-labelledby={ariaLabelledBy}
className={clsx(styles.modalDialog, 'bg-transparent p-0', {
'w-[450px]': size === 'md',
'w-[700px]': size === 'lg',
})}
>
<div className={clsx(styles.modalContent, 'relative', className)}>
{children}
{onDismiss && <CloseButton onClose={onDismiss} />}
</div>
</DialogContent>
</DialogOverlay>
</Context.Provider>
);
}