File size: 1,965 Bytes
212c959 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | import * as Dialog from '@radix-ui/react-dialog'
import clsx from 'clsx'
import { X } from 'lucide-react'
const sizes = {
sm: 'max-w-lg',
md: 'max-w-2xl',
lg: 'max-w-5xl',
}
export default function Modal({
open,
onOpenChange,
title,
description,
size = 'md',
children,
footer,
className,
}) {
return (
<Dialog.Root open={open} onOpenChange={onOpenChange}>
<Dialog.Portal>
<Dialog.Overlay className="fixed inset-0 z-50 bg-black/45" />
<Dialog.Content
className={clsx(
'fixed left-1/2 top-1/2 z-50 w-[calc(100%-1.5rem)] max-h-[calc(100vh-1.5rem)] -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-lg border border-border bg-card shadow-panel md:w-full',
sizes[size],
className,
)}
>
<div className="border-b border-border px-5 py-4 sm:px-6">
<div className="flex items-start justify-between gap-4">
<div>
<Dialog.Title className="font-display text-xl font-semibold text-foreground">
{title}
</Dialog.Title>
{description ? (
<Dialog.Description className="mt-1 max-w-2xl text-sm leading-6 text-muted-foreground">
{description}
</Dialog.Description>
) : null}
</div>
<Dialog.Close
className="rounded-lg p-2 text-muted-foreground transition hover:bg-secondary hover:text-foreground"
aria-label="Close dialog"
>
<X className="h-4 w-4" />
</Dialog.Close>
</div>
</div>
<div className="max-h-[calc(100vh-12rem)] overflow-y-auto px-5 py-5 sm:px-6">{children}</div>
{footer ? <div className="border-t border-border px-5 py-4 sm:px-6">{footer}</div> : null}
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
)
}
|