mirror of https://github.com/portainer/portainer
64 lines
1.6 KiB
TypeScript
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>
|
|
);
|
|
}
|