Severian's picture
initial commit
a8b3f00
raw
history blame
2.76 kB
import { Fragment, useCallback } from 'react'
import type { ElementType, ReactNode } from 'react'
import { Dialog, Transition } from '@headlessui/react'
import classNames from '@/utils/classnames'
// https://headlessui.com/react/dialog
type DialogProps = {
className?: string
titleClassName?: string
bodyClassName?: string
footerClassName?: string
titleAs?: ElementType
title?: ReactNode
children: ReactNode
footer?: ReactNode
show: boolean
onClose?: () => void
}
const CustomDialog = ({
className,
titleClassName,
bodyClassName,
footerClassName,
titleAs,
title,
children,
footer,
show,
onClose,
}: DialogProps) => {
const close = useCallback(() => onClose?.(), [onClose])
return (
<Transition appear show={show} as={Fragment}>
<Dialog as="div" className="relative z-40" onClose={close}>
<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 bg-opacity-25" />
</Transition.Child>
<div className="fixed inset-0 overflow-y-auto">
<div className="flex items-center justify-center min-h-full p-4 text-center">
<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={classNames('w-full max-w-[800px] p-0 overflow-hidden text-left text-gray-900 align-middle transition-all transform bg-white shadow-xl rounded-2xl', className)}>
{Boolean(title) && (
<Dialog.Title
as={titleAs || 'h3'}
className={classNames('px-8 py-6 text-lg font-medium leading-6 text-gray-900', titleClassName)}
>
{title}
</Dialog.Title>
)}
<div className={classNames('px-8 text-lg font-medium leading-6', bodyClassName)}>
{children}
</div>
{Boolean(footer) && (
<div className={classNames('flex items-center justify-end gap-2 px-8 py-6', footerClassName)}>
{footer}
</div>
)}
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition >
)
}
export default CustomDialog