mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
77 lines
2.0 KiB
TypeScript
77 lines
2.0 KiB
TypeScript
import { useEffect, useRef } from 'react'
|
|
|
|
import type { MouseEvent } from 'react'
|
|
|
|
const isClickInsideRectangle = (e: MouseEvent, element: HTMLElement) => {
|
|
const r = element.getBoundingClientRect()
|
|
|
|
return e.clientX > r.left && e.clientX < r.right && e.clientY > r.top && e.clientY < r.bottom
|
|
}
|
|
|
|
interface Props {
|
|
title?: string
|
|
isOpened: boolean
|
|
onClose: () => void
|
|
children: React.ReactNode
|
|
showCloseButton?: boolean
|
|
closeOnClickOutside?: boolean
|
|
className?: string
|
|
}
|
|
|
|
const DialogModal = ({
|
|
title,
|
|
isOpened,
|
|
onClose,
|
|
children,
|
|
showCloseButton = true,
|
|
closeOnClickOutside = true,
|
|
className,
|
|
}: Props) => {
|
|
const ref = useRef<HTMLDialogElement>(null)
|
|
|
|
useEffect(() => {
|
|
if (isOpened) {
|
|
ref.current?.showModal()
|
|
ref.current?.classList.remove('tw:hidden')
|
|
document.body.style.overflow = 'hidden'
|
|
} else {
|
|
ref.current?.close()
|
|
ref.current?.classList.add('tw:hidden')
|
|
document.body.style.overflow = ''
|
|
}
|
|
}, [isOpened])
|
|
|
|
if (isOpened) {
|
|
return (
|
|
<dialog
|
|
className={`${className ?? ''} tw:card tw:shadow-xl tw:absolute tw:right-0 tw:top-0 tw:bottom-0 tw:left-0 tw:m-auto tw:transition-opacity tw:duration-300 tw:p-4 tw:max-w-xl tw:bg-base-100`}
|
|
ref={ref}
|
|
onCancel={onClose}
|
|
onClick={(e) => {
|
|
if (ref.current && !isClickInsideRectangle(e, ref.current) && closeOnClickOutside) {
|
|
onClose()
|
|
}
|
|
}}
|
|
>
|
|
<div className='tw:card-body tw:p-2'>
|
|
{title && (
|
|
<h2 className='tw:text-2xl tw:font-semibold tw:mb-2 tw:text-center'>{title}</h2>
|
|
)}
|
|
|
|
{children}
|
|
{showCloseButton && (
|
|
<button
|
|
className='tw:btn tw:btn-sm tw:btn-circle tw:btn-ghost tw:absolute tw:right-2 tw:top-2'
|
|
onClick={onClose}
|
|
>
|
|
✕
|
|
</button>
|
|
)}
|
|
</div>
|
|
</dialog>
|
|
)
|
|
} else return <></>
|
|
}
|
|
|
|
export default DialogModal
|