import React, { useState } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Minus, X } from 'lucide-react'; import { Button } from './shadcn/button'; interface SidePanelProps { isOpen: boolean; onClose: () => void; children: React.ReactNode; title?: React.ReactNode; panelWidth?: number; backdrop?: boolean; side?: 'left' | 'right'; resizable?: boolean; className?: string; contentClassName?: string; } export function SidePanel({ isOpen, title, onClose, children, panelWidth = 768, backdrop = false, side = 'right', resizable = true, className, contentClassName }: SidePanelProps) { const [_panelWidth, setPanelWidth] = useState(panelWidth); const handleDragStart = (e: React.MouseEvent) => { e.preventDefault(); let isDragging = true; const startX = e.pageX; const startWidth = _panelWidth; const handleMouseMove = (e: MouseEvent) => { if (isDragging) { const deltaX = startX - e.pageX; const newWidth = Math.max(startWidth + deltaX, 480); setPanelWidth(newWidth); } }; const handleMouseUp = () => { isDragging = false; document.removeEventListener('mousemove', handleMouseMove); document.removeEventListener('mouseup', handleMouseUp); }; document.addEventListener('mousemove', handleMouseMove); document.addEventListener('mouseup', handleMouseUp); }; const isLeft = side === 'left'; const positionClass = isLeft ? 'left-0' : 'right-0'; const paddingClass = isLeft ? 'pr-10 sm:pr-16' : 'pl-10 sm:pl-16'; const borderClass = isLeft ? 'border-r' : 'border-l'; const dragHandleClass = isLeft ? '-right-1' : '-left-1'; const initialX = isLeft ? "-100%" : "100%"; return ( {isOpen && ( {/* Backdrop */} {backdrop && ( )} {/* Drag Handle */} {resizable && ( )} {/* Sticky header */} {title && ( {title ?? ""} )} {/* Scrollable content */} {children} )} ); } function CloseButton({ onClose }: { onClose: () => void }) { return ( ) }