computer-scienceangular-roadmapbackend-roadmapblockchain-roadmapdba-roadmapdeveloper-roadmapdevops-roadmapfrontend-roadmapgo-roadmaphactoberfestjava-roadmapjavascript-roadmapnodejs-roadmappython-roadmapqa-roadmapreact-roadmaproadmapstudy-planvue-roadmapweb3-roadmap
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
58 lines
1.3 KiB
58 lines
1.3 KiB
import { type ReactNode, useRef } from 'react'; |
|
import { useOutsideClick } from '../hooks/use-outside-click'; |
|
import { useKeydown } from '../hooks/use-keydown'; |
|
import { cn } from '../lib/classname'; |
|
|
|
type ModalProps = { |
|
onClose: () => void; |
|
children: ReactNode; |
|
overlayClassName?: string; |
|
bodyClassName?: string; |
|
wrapperClassName?: string; |
|
}; |
|
|
|
export function Modal(props: ModalProps) { |
|
const { |
|
onClose, |
|
children, |
|
bodyClassName, |
|
wrapperClassName, |
|
overlayClassName, |
|
} = props; |
|
|
|
const popupBodyEl = useRef<HTMLDivElement>(null); |
|
|
|
useKeydown('Escape', () => { |
|
onClose(); |
|
}); |
|
|
|
useOutsideClick(popupBodyEl, () => { |
|
onClose(); |
|
}); |
|
|
|
return ( |
|
<div |
|
className={cn( |
|
'popup fixed left-0 right-0 top-0 z-[99] flex h-full items-center justify-center overflow-y-auto overflow-x-hidden bg-black/50', |
|
overlayClassName, |
|
)} |
|
> |
|
<div |
|
className={cn( |
|
'relative h-full w-full max-w-md p-4 md:h-auto', |
|
wrapperClassName, |
|
)} |
|
> |
|
<div |
|
ref={popupBodyEl} |
|
className={cn( |
|
'popup-body relative h-full rounded-lg bg-white shadow', |
|
bodyClassName, |
|
)} |
|
> |
|
{children} |
|
</div> |
|
</div> |
|
</div> |
|
); |
|
}
|
|
|