import * as Dialog from '@radix-ui/react-dialog'; import { X } from 'lucide-react'; import type { ReactNode } from 'react'; import { cn } from '@/src/lib/utils'; export const AdminDialogRoot = Dialog.Root; export const AdminDialogTrigger = Dialog.Trigger; export const AdminDialogPortal = Dialog.Portal; export const AdminDialogOverlay = Dialog.Overlay; export const AdminDialogContent = Dialog.Content; export const AdminDialogTitle = Dialog.Title; export const AdminDialogDescription = Dialog.Description; export const AdminDialogClose = Dialog.Close; type AdminDialogLayout = 'center' | 'side-panel'; type AdminDialogAccent = 'default' | 'warning' | 'danger' | 'success'; type AdminDialogProps = { open: boolean; title: ReactNode; description?: ReactNode; icon?: ReactNode; layout?: AdminDialogLayout; mode?: AdminDialogLayout; size?: string; accent?: AdminDialogAccent; dismissible?: boolean; showCloseButton?: boolean; footer?: ReactNode; children: ReactNode; onOpenChange: (open: boolean) => void; className?: string; overlayClassName?: string; panelClassName?: string; headerClassName?: string; bodyClassName?: string; footerClassName?: string; titleClassName?: string; descriptionClassName?: string; closeLabel?: string; }; const accentClasses: Record = { default: 'border-blue-500/20 bg-blue-500/10 text-blue-400', warning: 'border-amber-500/20 bg-amber-500/10 text-amber-400', danger: 'border-red-500/20 bg-red-500/10 text-red-400', success: 'border-green-500/20 bg-green-500/10 text-green-400', }; export function AdminDialog({ open, title, description, icon, layout, mode, size, accent = 'default', dismissible = true, showCloseButton = true, footer, children, onOpenChange, className, overlayClassName, panelClassName, headerClassName, bodyClassName, footerClassName, titleClassName, descriptionClassName, closeLabel = '关闭对话框', }: AdminDialogProps) { const resolvedLayout = layout ?? mode ?? (size === 'side-panel' ? 'side-panel' : 'center'); const isSidePanel = resolvedLayout === 'side-panel'; const sizeClasses = size === 'sm' ? 'max-w-[min(96vw,28rem)]' : size === 'md' ? 'max-w-[min(96vw,36rem)]' : size === 'xl' ? 'max-w-[min(96vw,56rem)]' : size === '2xl' ? 'max-w-[min(96vw,72rem)]' : size === 'full' ? 'max-w-[calc(100vw-2rem)]' : 'max-w-[min(96vw,48rem)]'; const shellClasses = cn( 'glass-panel-no-hover relative flex min-h-0 w-full flex-col overflow-hidden text-gray-900 dark:text-gray-100', isSidePanel ? 'h-[100dvh] max-w-[min(100vw,40rem)] rounded-none border-l border-white/10 shadow-[0_30px_120px_rgba(0,0,0,0.55)]' : cn('max-h-[min(calc(100dvh-3rem),48rem)] rounded-3xl border border-white/10 shadow-[0_30px_120px_rgba(0,0,0,0.55)]', sizeClasses), panelClassName, ); return ( { if (!dismissible) { event.preventDefault(); } }} onPointerDownOutside={(event) => { if (!dismissible) { event.preventDefault(); } }} onInteractOutside={(event) => { if (!dismissible) { event.preventDefault(); } }} >
{icon ? (
{icon}
) : null}
{title} {description ? ( {description} ) : null}
{showCloseButton ? ( ) : null}
{children}
{footer ? (
{footer}
) : null}
); }