mirror of
https://github.com/basketikun/infinite-canvas.git
synced 2026-08-05 00:34:22 +08:00
feat(canvas): add group node support with drag-and-drop functionality
This commit is contained in:
@@ -235,7 +235,6 @@ function InfiniteCanvasPage() {
|
||||
const historyPausedRef = useRef(false);
|
||||
const didInitialCenterRef = useRef(false);
|
||||
const rafRef = useRef<number | null>(null);
|
||||
const toolbarHideTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
const nodeDraggingRef = useRef(false);
|
||||
const dragRef = useRef<{
|
||||
isDraggingNode: boolean;
|
||||
@@ -547,25 +546,12 @@ function InfiniteCanvasPage() {
|
||||
}
|
||||
}, []);
|
||||
|
||||
const keepNodeToolbar = useCallback(
|
||||
(nodeId: string) => {
|
||||
if (nodeDraggingRef.current || nodeImageSettingsOpen) return;
|
||||
if (toolbarHideTimerRef.current) {
|
||||
clearTimeout(toolbarHideTimerRef.current);
|
||||
toolbarHideTimerRef.current = null;
|
||||
}
|
||||
setToolbarNodeId(nodeId);
|
||||
},
|
||||
[nodeImageSettingsOpen],
|
||||
);
|
||||
const keepNodeToolbar = useCallback((nodeId: string) => {
|
||||
if (nodeDraggingRef.current || nodeImageSettingsOpen || !selectedNodeIdsRef.current.has(nodeId)) return;
|
||||
setToolbarNodeId(nodeId);
|
||||
}, [nodeImageSettingsOpen]);
|
||||
|
||||
const hideNodeToolbar = useCallback(() => {
|
||||
if (toolbarHideTimerRef.current) clearTimeout(toolbarHideTimerRef.current);
|
||||
toolbarHideTimerRef.current = setTimeout(() => {
|
||||
setToolbarNodeId(null);
|
||||
toolbarHideTimerRef.current = null;
|
||||
}, 120);
|
||||
}, []);
|
||||
const hideNodeToolbar = useCallback(() => {}, []);
|
||||
|
||||
const connectNodes = useCallback(
|
||||
(current: ConnectionHandle, targetNodeId: string) => {
|
||||
@@ -1106,6 +1092,7 @@ function InfiniteCanvasPage() {
|
||||
}
|
||||
|
||||
setSelectedNodeIds(nextSelected);
|
||||
setToolbarNodeId(nextSelected.size === 1 && nextSelected.has(nodeId) ? nodeId : null);
|
||||
const dragIds = new Set(nextSelected);
|
||||
currentNodes.forEach((node) => {
|
||||
if (!nextSelected.has(node.id)) return;
|
||||
@@ -1502,6 +1489,10 @@ function InfiniteCanvasPage() {
|
||||
setNodes((prev) => prev.map((node) => (node.id === nodeId ? { ...node, metadata: { ...node.metadata, content } } : node)));
|
||||
}, []);
|
||||
|
||||
const handleNodeTitleChange = useCallback((nodeId: string, title: string) => {
|
||||
setNodes((prev) => prev.map((node) => (node.id === nodeId ? { ...node, title } : node)));
|
||||
}, []);
|
||||
|
||||
const toggleBatchExpanded = useCallback((nodeId: string) => {
|
||||
const isExpanded = Boolean(nodesRef.current.find((node) => node.id === nodeId)?.metadata?.imageBatchExpanded);
|
||||
if (isExpanded) {
|
||||
@@ -2658,15 +2649,14 @@ function InfiniteCanvasPage() {
|
||||
onHoverStart={(nodeId) => {
|
||||
if (nodeDraggingRef.current) return;
|
||||
setHoveredNodeId(nodeId);
|
||||
keepNodeToolbar(nodeId);
|
||||
}}
|
||||
onHoverEnd={(nodeId) => {
|
||||
setHoveredNodeId((current) => (current === nodeId ? null : current));
|
||||
hideNodeToolbar();
|
||||
}}
|
||||
onConnectStart={handleConnectStart}
|
||||
onResize={handleNodeResize}
|
||||
onContentChange={handleNodeContentChange}
|
||||
onTitleChange={handleNodeTitleChange}
|
||||
onToggleBatch={toggleBatchExpanded}
|
||||
onSetBatchPrimary={setBatchPrimary}
|
||||
onRetry={(node) => void handleRetryNode(node)}
|
||||
|
||||
Reference in New Issue
Block a user