@gravity-ui/graph
Version:
Modern graph editor component
103 lines (102 loc) • 3.71 kB
TypeScript
import type { Graph } from "../../graph";
import type { DragOperationCallbacks, DragOperationOptions, DragState } from "./types";
/**
* DragService manages drag operations for all draggable GraphComponents.
*
* When a user starts dragging a component:
* 1. Collects all selected draggable components from SelectionService
* 2. Manages the drag lifecycle (start, update, end) via dragListener
* 3. Handles autopanning, cursor locking, and camera-change synchronization
* 4. Delegates actual movement logic to components via handleDragStart/handleDrag/handleDragEnd
*/
export declare class DragService {
private graph;
/** Components participating in the current drag operation */
private dragComponents;
/** Starting coordinates in world space */
private startCoords;
/** Previous frame coordinates in world space */
private prevCoords;
/** Current drag listener emitter (null when not dragging) */
private currentDragEmitter;
/** Unsubscribe function for graph mousedown event */
private unsubscribeMouseDown;
/**
* Reactive signal with current drag state.
* Use this to react to drag state changes, e.g. to disable certain behaviors during multi-component drag.
*
* @example
* ```typescript
* // Check if drag is happening with multiple heterogeneous components
* if (graph.dragService.$state.value.isDragging && !graph.dragService.$state.value.isHomogeneous) {
* // Disable snap to grid
* }
* ```
*/
readonly $state: import("@preact/signals-core").Signal<DragState>;
constructor(graph: Graph);
/**
* Create idle (not dragging) state
*/
private createIdleState;
/**
* Create active drag state from components
*/
private createDragState;
/**
* Cleanup when service is destroyed
*/
destroy(): void;
/**
* Handle mousedown on graph - determine if drag should start
*/
private handleMouseDown;
/**
* Collect all components that should participate in drag operation.
* Behavior depends on canDrag setting:
* - ALL: If target is in selection, drag all selected draggable components. Otherwise drag only target.
* - ONLY_SELECTED: Only selected components can be dragged. If target is not selected, returns empty array.
*/
private collectDragComponents;
/**
* Handle drag start from dragListener
*/
private handleDragStart;
/**
* Handle drag update from dragListener
*/
private handleDragUpdate;
/**
* Handle drag end from dragListener
*/
private handleDragEnd;
/**
* Convert screen coordinates to world coordinates
*/
private getWorldCoords;
/**
* Cleanup after drag operation ends
*/
private cleanup;
/**
* Start a custom drag operation for specialized use cases like creating connections or new blocks.
* This provides a unified API for drag operations without exposing dragListener directly.
*
* @param callbacks - Lifecycle callbacks (onStart, onUpdate, onEnd)
* @param options - Drag options (document, cursor, autopanning, etc.)
*
* @example
* ```typescript
* // In ConnectionLayer
* graph.dragService.startOperation(
* {
* onStart: (event, coords) => this.onStartConnection(event, coords),
* onUpdate: (event, coords) => this.onMoveConnection(event, coords),
* onEnd: (event, coords) => this.onEndConnection(coords),
* },
* { cursor: "crosshair", autopanning: true }
* );
* ```
*/
startDrag(callbacks: DragOperationCallbacks, options?: DragOperationOptions): void;
}