xLog/src/components/ui/Modal.tsx

58 lines
1.8 KiB
TypeScript

import { Dialog } from "@headlessui/react"
import { cn } from "~/lib/utils"
import React from "react"
export const Modal: React.FC<{
open: boolean
setOpen: (open: boolean) => void
children: React.ReactNode
title?: string | React.ReactNode
titleIcon?: React.ReactNode
size?: "md" | "lg" | "sm"
}> = ({ open, setOpen, children, title, titleIcon, size = "md" }) => {
return (
<Dialog
open={open}
onClose={() => setOpen(false)}
className="relative z-50"
>
{/* The backdrop, rendered as a fixed sibling to the panel container */}
<div className="fixed inset-0 bg-black/30 z-40" aria-hidden={true} />
{/* Full-screen container to center the panel */}
<div
className={cn(
`fixed inset-0 flex items-center justify-center p-4 z-40`,
)}
>
{/* The actual dialog panel */}
<Dialog.Panel
className={cn(
`mx-auto rounded-lg bg-white w-full shadow-modal max-h-full overflow-y-auto flex flex-col`,
size === "md"
? `max-w-md`
: size === "lg"
? `max-w-lg`
: `max-w-sm`,
)}
>
{title && (
<Dialog.Title className="text-lg border-b h-14 flex items-center px-5 space-x-2 py-4 relative">
{titleIcon && <span>{titleIcon}</span>}
<span className="truncate flex items-center w-full">{title}</span>
<span
className="absolute right-1 w-7 h-7 text-xl cursor-pointer bg-white flex items-center justify-center"
onClick={() => setOpen(false)}
>
<i className="i-mingcute:close-line inline-block" />
</span>
</Dialog.Title>
)}
{children}
</Dialog.Panel>
</div>
</Dialog>
)
}