100 lines
2.1 KiB
TypeScript
100 lines
2.1 KiB
TypeScript
import React, { useEffect } from 'react';
|
|
|
|
interface DialogProps {
|
|
open: boolean;
|
|
onOpenChange: (open: boolean) => void;
|
|
children: React.ReactNode;
|
|
}
|
|
|
|
export function Dialog({ open, onOpenChange, children }: DialogProps) {
|
|
useEffect(() => {
|
|
if (open) {
|
|
document.body.style.overflow = 'hidden';
|
|
} else {
|
|
document.body.style.overflow = 'unset';
|
|
}
|
|
|
|
return () => {
|
|
document.body.style.overflow = 'unset';
|
|
};
|
|
}, [open]);
|
|
|
|
if (!open) return null;
|
|
|
|
return (
|
|
<div className="fixed inset-0 z-50 flex items-center justify-center">
|
|
<div
|
|
className="fixed inset-0 bg-black bg-opacity-50"
|
|
onClick={() => onOpenChange(false)}
|
|
/>
|
|
<div className="relative bg-white rounded-lg shadow-xl max-w-md w-full mx-4">
|
|
{children}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface DialogContentProps {
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
}
|
|
|
|
export function DialogContent({ children, className = '' }: DialogContentProps) {
|
|
return (
|
|
<div className={`p-6 ${className}`}>
|
|
{children}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface DialogHeaderProps {
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
}
|
|
|
|
export function DialogHeader({ children, className = '' }: DialogHeaderProps) {
|
|
return (
|
|
<div className={`mb-4 ${className}`}>
|
|
{children}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface DialogTitleProps {
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
}
|
|
|
|
export function DialogTitle({ children, className = '' }: DialogTitleProps) {
|
|
return (
|
|
<h2 className={`text-lg font-semibold text-gray-900 ${className}`}>
|
|
{children}
|
|
</h2>
|
|
);
|
|
}
|
|
|
|
interface DialogDescriptionProps {
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
}
|
|
|
|
export function DialogDescription({ children, className = '' }: DialogDescriptionProps) {
|
|
return (
|
|
<p className={`text-sm text-gray-600 mt-1 ${className}`}>
|
|
{children}
|
|
</p>
|
|
);
|
|
}
|
|
|
|
interface DialogFooterProps {
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
}
|
|
|
|
export function DialogFooter({ children, className = '' }: DialogFooterProps) {
|
|
return (
|
|
<div className={`flex justify-end space-x-2 mt-6 ${className}`}>
|
|
{children}
|
|
</div>
|
|
);
|
|
}
|