"use client"; import "@/app/globals.css"; import { useDraggable } from "@dnd-kit/core"; import { ReactElement, useEffect, useRef, useState } from "react"; import { nearestMultiple } from "./utils"; export default function Draggable(props: DraggablePropsType) { const targetRef = useRef(null); const [size, setSize] = useState({ width: 16, height: 16 }); const { id, component, data, x, y, width, height } = props; const { attributes, listeners, setNodeRef, transform } = useDraggable({ id, }); const style = transform ? { top: y, left: x, width: width, height: height, transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`, opacity: 0.6, } : { top: y, left: x, width: width, height: height, }; useEffect(() => { const element = targetRef.current; if (!element) return; // 创建 ResizeObserver 实例 let timer: any; const observer = new ResizeObserver( _.throttle((entries: any) => { for (const entry of entries) { const { width, height } = entry.contentRect; setSize({ width: nearestMultiple(width), height: nearestMultiple(height), }); if (timer) { clearTimeout(timer); } // setIsResize(true); timer = setTimeout(() => { entry.target.style.width = nearestMultiple(width) + "px"; entry.target.style.height = nearestMultiple(height) + "px"; // syncSize(entry.contentRect, containerRef.current); // setIsResize(false); }, 150); } }, 30), ); // 开始观察元素 observer.observe(element); // 组件卸载时断开连接 return () => { observer.disconnect(); }; }, []); // 空依赖数组确保只运行一次 const className = transform ? "shadow-xl absolute w-min min-w-[128px] min-h-[128px]" : "absolute w-min resize overflow-hidden min-w-[128px] min-h-[128px]"; return (
{component && component(data??{})}
); } export type DraggablePropsType = { id: string; component: (data: Record) => ReactElement; data?: Record; x: number; y: number; width: number; height: number; };