or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

activity-events.mdassets.mdcode-generation.mdcomponent-metadata.mddrag-drop.mdeditor-config.mdindex.mdmodels.mdplugins.mdschemas.mdshell-api.mdshell-enums.mdvalue-types.md
tile.json

drag-drop.mddocs/

Drag and Drop System

Comprehensive drag and drop functionality for the low-code editor, providing type-safe interfaces for dragging components, nodes, and custom objects.

Capabilities

Drag Object Types

Core types for objects that can be dragged in the editor.

/**
 * Union type for all draggable objects
 */
type IPublicTypeDragObject = 
  | IPublicTypeDragNodeObject 
  | IPublicTypeDragNodeDataObject 
  | IPublicTypeDragAnyObject;

/**
 * Drag object containing actual node instances
 */
interface IPublicTypeDragNodeObject {
  /** Type indicator for node objects */
  type: IPublicEnumDragObjectType.Node;
  /** Array of node instances being dragged */
  nodes: IPublicModelNode[];
}

/**
 * Drag object containing node schema data
 */
interface IPublicTypeDragNodeDataObject {
  /** Type indicator for node data objects */
  type: IPublicEnumDragObjectType.NodeData;
  /** Node schema data being dragged */
  data: IPublicTypeNodeSchema | IPublicTypeNodeSchema[];
  /** Optional thumbnail image */
  thumbnail?: string;
  /** Optional description text */
  description?: string;
  /** Additional custom properties */
  [extra: string]: any;
}

/**
 * Generic drag object for custom drag types
 */
interface IPublicTypeDragAnyObject {
  /** Custom type identifier */
  type: string;
  /** Additional custom properties */
  [key: string]: any;
}

Usage Examples:

import { 
  IPublicTypeDragObject,
  IPublicTypeDragNodeDataObject,
  IPublicEnumDragObjectType 
} from "@alilc/lowcode-types";

// Create drag object for component from material
const componentDragObject: IPublicTypeDragNodeDataObject = {
  type: IPublicEnumDragObjectType.NodeData,
  data: {
    componentName: "Button",
    props: {
      type: "primary",
      children: "Click me"
    }
  },
  thumbnail: "/assets/button-thumbnail.png",
  description: "Primary button component"
};

// Create drag object for existing nodes
const nodeDragObject: IPublicTypeDragNodeObject = {
  type: IPublicEnumDragObjectType.Node,
  nodes: [selectedNode1, selectedNode2]
};

// Create custom drag object
const customDragObject: IPublicTypeDragAnyObject = {
  type: "custom-widget",
  widgetId: "widget-123",
  config: { color: "blue" }
};

Dragon Model Integration

The Dragon model provides the core drag and drop engine functionality.

/**
 * Dragon model interface for drag and drop operations
 */
interface IPublicModelDragon {
  /** Whether currently dragging */
  readonly dragging: boolean;
  
  /** Listen for drag start events */
  onDragstart(func: (e: IPublicModelLocateEvent) => any): IPublicTypeDisposable;
  
  /** Listen for drag events */
  onDrag(func: (e: IPublicModelLocateEvent) => any): IPublicTypeDisposable;
  
  /** Listen for drag end events */
  onDragend(func: (o: { dragObject: IPublicModelDragObject; copy?: boolean }) => any): IPublicTypeDisposable;
  
  /** Set drag monitoring shell and boost function */
  from(shell: Element, boost: (e: MouseEvent) => IPublicTypeDragNodeDataObject | null): any;
  
  /** Boost drag object for dragging */
  boost(dragObject: IPublicTypeDragObject, boostEvent: MouseEvent | DragEvent, fromRglNode?: IPublicModelNode): void;
  
  /** Add sensor area */
  addSensor(sensor: IPublicModelSensor): void;
  
  /** Remove sensor area */
  removeSensor(sensor: IPublicModelSensor): void;
}

Usage Examples:

import { IPublicModelDragon } from "@alilc/lowcode-types";

// Setup drag and drop system
function setupDragDrop(dragon: IPublicModelDragon) {
  // Listen for drag start
  dragon.onDragstart((e) => {
    console.log("Drag started at:", e.clientX, e.clientY);
    // Prepare drag state
    showDragPreview();
  });
  
  // Listen for drag events
  dragon.onDrag((e) => {
    // Update drag preview position
    updateDragPreview(e.clientX, e.clientY);
  });
  
  // Listen for drag end
  dragon.onDragend(({ dragObject, copy }) => {
    console.log("Drag ended:", dragObject.type);
    if (copy) {
      console.log("Copy operation performed");
    }
    hideDragPreview();
  });
  
  // Setup drag source
  const materialPanel = document.getElementById('material-panel');
  if (materialPanel) {
    dragon.from(materialPanel, (e: MouseEvent) => {
      const target = e.target as Element;
      const componentName = target.getAttribute('data-component');
      
      if (componentName) {
        return {
          type: IPublicEnumDragObjectType.NodeData,
          data: {
            componentName,
            props: getDefaultProps(componentName)
          }
        };
      }
      return null;
    });
  }
}

Sensor System

Sensors detect and handle drop operations in specific areas.

/**
 * Sensor interface for handling drop operations
 */
interface IPublicModelSensor {
  /** Sensor active state */
  active: boolean;
  
  /** Enter sensor area */
  enter(dragObject: IPublicModelDragObject): boolean;
  
  /** Leave sensor area */
  leave(dragObject: IPublicModelDragObject): void;
  
  /** Check if can drop */
  canDrop(dragObject: IPublicModelDragObject): boolean;
  
  /** Handle drop operation */
  drop(dragObject: IPublicModelDragObject, dropLocation: IPublicModelDropLocation): void;
}

/**
 * Drop location interface
 */
interface IPublicModelDropLocation {
  /** Target node for drop */
  target: IPublicModelNode;
  /** Drop index within target */
  index: number;
  /** Drop edge position */
  edge: 'before' | 'after' | 'inside';
}

Usage Examples:

import { IPublicModelSensor, IPublicModelDragObject } from "@alilc/lowcode-types";

// Create custom sensor for canvas area
class CanvasSensor implements IPublicModelSensor {
  active = true;
  
  enter(dragObject: IPublicModelDragObject): boolean {
    // Check if drag object can be dropped on canvas
    if (dragObject.type === IPublicEnumDragObjectType.NodeData) {
      return true;
    }
    return false;
  }
  
  leave(dragObject: IPublicModelDragObject): void {
    // Clean up drop indicators
    this.clearDropIndicators();
  }
  
  canDrop(dragObject: IPublicModelDragObject): boolean {
    // Validate drop operation
    return this.validateDrop(dragObject);
  }
  
  drop(dragObject: IPublicModelDragObject, dropLocation: IPublicModelDropLocation): void {
    // Handle the drop operation
    if (dragObject.type === IPublicEnumDragObjectType.NodeData) {
      const nodeData = (dragObject as IPublicTypeDragNodeDataObject).data;
      this.insertNode(nodeData, dropLocation);
    }
  }
  
  private clearDropIndicators(): void {
    // Implementation
  }
  
  private validateDrop(dragObject: IPublicModelDragObject): boolean {
    // Implementation
    return true;
  }
  
  private insertNode(nodeData: any, location: IPublicModelDropLocation): void {
    // Implementation
  }
}

// Register sensor with dragon
function registerCanvasSensor(dragon: IPublicModelDragon) {
  const sensor = new CanvasSensor();
  dragon.addSensor(sensor);
  
  return () => {
    dragon.removeSensor(sensor);
  };
}

Drag Events and Location

Location events provide detailed information about drag operations.

/**
 * Locate event interface for drag operations
 */
interface IPublicModelLocateEvent {
  /** Event type */
  type: string;
  
  /** Target element */
  target: Element;
  
  /** Client coordinates */
  clientX: number;
  clientY: number;
  
  /** Global coordinates */
  globalX: number;
  globalY: number;
  
  /** Original DOM event */
  originalEvent: Event;
  
  /** Prevent default behavior */
  preventDefault(): void;
  
  /** Stop event propagation */
  stopPropagation(): void;
}

Import Statement

import { 
  IPublicTypeDragObject,
  IPublicTypeDragNodeObject,
  IPublicTypeDragNodeDataObject,
  IPublicTypeDragAnyObject,
  IPublicModelDragon,
  IPublicModelSensor,
  IPublicModelDropLocation,
  IPublicModelLocateEvent,
  IPublicEnumDragObjectType
} from "@alilc/lowcode-types";

Complete Example

import { 
  IPublicModelDragon, 
  IPublicEnumDragObjectType,
  IPublicTypeDragNodeDataObject 
} from "@alilc/lowcode-types";

// Complete drag and drop setup
class DragDropManager {
  private dragon: IPublicModelDragon;
  
  constructor(dragon: IPublicModelDragon) {
    this.dragon = dragon;
    this.setupDragSources();
    this.setupDropTargets();
  }
  
  private setupDragSources(): void {
    // Setup material panel as drag source
    const materialPanel = document.getElementById('materials');
    if (materialPanel) {
      this.dragon.from(materialPanel, (e: MouseEvent) => {
        const component = this.getComponentFromEvent(e);
        if (component) {
          return {
            type: IPublicEnumDragObjectType.NodeData,
            data: {
              componentName: component.name,
              props: component.defaultProps
            },
            thumbnail: component.thumbnail,
            description: component.description
          } as IPublicTypeDragNodeDataObject;
        }
        return null;
      });
    }
  }
  
  private setupDropTargets(): void {
    // Add canvas sensor
    const canvasSensor = new CanvasSensor();
    this.dragon.addSensor(canvasSensor);
    
    // Setup event listeners
    this.dragon.onDragstart(() => {
      document.body.classList.add('dragging');
    });
    
    this.dragon.onDragend(() => {
      document.body.classList.remove('dragging');
    });
  }
  
  private getComponentFromEvent(e: MouseEvent): any {
    // Implementation to extract component info from mouse event
    return null;
  }
}

This drag and drop system provides comprehensive support for all dragging scenarios in the low-code editor.