55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
'use client'
|
|
|
|
import { Dialog, Transition } from '@headlessui/react'
|
|
import { Fragment } from 'react'
|
|
import { X } from 'lucide-react'
|
|
|
|
type ModalProps = {
|
|
isOpen: boolean
|
|
onClose: () => void
|
|
children: React.ReactNode
|
|
}
|
|
|
|
export function Modal({ isOpen, onClose, children }: ModalProps) {
|
|
return (
|
|
<Transition show={isOpen} as={Fragment}>
|
|
<Dialog onClose={onClose} className="relative z-50">
|
|
<Transition.Child
|
|
as={Fragment}
|
|
enter="ease-out duration-300"
|
|
enterFrom="opacity-0"
|
|
enterTo="opacity-100"
|
|
leave="ease-in duration-200"
|
|
leaveFrom="opacity-100"
|
|
leaveTo="opacity-0"
|
|
>
|
|
<div className="fixed inset-0 bg-black/30" />
|
|
</Transition.Child>
|
|
|
|
<div className="fixed inset-0 overflow-y-auto">
|
|
<div className="flex min-h-full items-center justify-center p-4">
|
|
<Transition.Child
|
|
as={Fragment}
|
|
enter="ease-out duration-300"
|
|
enterFrom="opacity-0 scale-95"
|
|
enterTo="opacity-100 scale-100"
|
|
leave="ease-in duration-200"
|
|
leaveFrom="opacity-100 scale-100"
|
|
leaveTo="opacity-0 scale-95"
|
|
>
|
|
<Dialog.Panel className="w-full max-w-2xl transform overflow-hidden rounded-xl bg-white shadow-xl transition-all">
|
|
<button
|
|
onClick={onClose}
|
|
className="absolute right-4 top-4 text-gray-500 hover:text-gray-700"
|
|
>
|
|
<X className="w-6 h-6" />
|
|
</button>
|
|
{children}
|
|
</Dialog.Panel>
|
|
</Transition.Child>
|
|
</div>
|
|
</div>
|
|
</Dialog>
|
|
</Transition>
|
|
)
|
|
}
|