import { ReactNode, useEffect } from 'react' import { X } from 'lucide-react' import clsx from 'clsx' type DrawerPlacement = 'left' | 'right' | 'top' | 'bottom' interface DrawerProps { open: boolean onClose: () => void title?: string children: ReactNode footer?: ReactNode placement?: DrawerPlacement width?: string height?: string closable?: boolean } const placementStyles = { left: 'left-0 top-0 bottom-0 animate-slide-in-left', right: 'right-0 top-0 bottom-0 animate-slide-in-right', top: 'top-0 left-0 right-0 animate-slide-in-top', bottom: 'bottom-0 left-0 right-0 animate-slide-in-bottom', } export function Drawer({ open, onClose, title, children, footer, placement = 'right', width = '400px', height = '300px', closable = true, }: DrawerProps) { useEffect(() => { if (open) { document.body.style.overflow = 'hidden' } else { document.body.style.overflow = '' } return () => { document.body.style.overflow = '' } }, [open]) if (!open) return null const isHorizontal = placement === 'left' || placement === 'right' const size = isHorizontal ? { width } : { height } return (
{/* 遮罩层 */}
{/* 抽屉内容 */}
e.stopPropagation()} > {/* 标题栏 */} {(title || closable) && (
{title && (

{title}

)} {closable && ( )}
)} {/* 内容区 */}
{children}
{/* 底部按钮 */} {footer && (
{footer}
)}
) }