@lyonbot/interactive-blocks
Version:
Make interactive selectable, drag-and-drop, copy-and-paste ready, Block and Slot components easily! Works with Vue, React and any MV* framework.
99 lines (98 loc) • 4.02 kB
TypeScript
import { BlockDOMEventHandlers, BlockHandler } from "./BlockHandler";
import { SlotDOMEventHandlers, SlotHandler } from "./SlotHandler";
import { BlockContext } from "./BlockContext";
import { FirstParameter } from "./utils";
import { EventEmitter } from "./EventEmitter";
import { IBMoveBetweenSlotsAction, IBMoveInSlotAction, IBSlotBeforeDropAction } from "./action";
import { IBBlockDragStartAction } from "./action";
export interface DraggingContextEvents {
/** fires when one of `hoveringSlot`, `hoveringBlock` or `isHovering` changes */
hoverChanged(ctx: BlockContext): void;
/** fires when start dragging a block */
blockDragStart(action: IBBlockDragStartAction): void;
slotBeforeDrop(action: IBSlotBeforeDropAction): void;
}
export interface ComputeIndexToDropRequest {
clientX: number;
clientY: number;
offsetX: number;
offsetY: number;
currentTarget: HTMLElement;
ctx: BlockContext;
slot: SlotHandler;
isDraggingFromCurrentCtx: boolean;
/** if drag source is from current BlockContext, this will be the array of current dragging blocks */
draggingBlocks?: readonly BlockHandler[];
/** the original dataTransfer object from DragEvent */
dataTransfer: DataTransfer | null;
dropEffect: "none" | "copy" | "link" | "move";
}
declare module "./SlotHandler" {
interface SlotInfo {
/**
* for drag-n-drop
*/
onMoveInSlot?(action: IBMoveInSlotAction): void;
/**
* for drag-n-drop
*/
onMoveToThisSlot?(action: IBMoveBetweenSlotsAction): void;
/**
* for drag-n-drop
*
* fires when `isDragHovering` or `indexToDrop` change
*/
onDragHoverStatusChange?(ctx: BlockContext): void;
/**
* for drag-n-drop
*
* check if this slot is droppable and compute the insert position.
*
* returns:
*
* - `false` to prevent dropping,
* - `undefined` to use auto-computed position (which might not accurate),
* - index number
*/
computeIndexToDrop?(req: ComputeIndexToDropRequest): number | false | void;
}
interface SlotHandler {
isDragHovering?: boolean;
/** the position to drop. only available when `isDragHovering` */
indexToDrop?: number | undefined;
}
}
declare module "./BlockHandler" {
interface BlockInfo {
onDragStart?(action: IBBlockDragStartAction): void;
}
}
export declare class DraggingContext extends EventEmitter<DraggingContextEvents> {
ctx: BlockContext;
draggingBlocks: Array<BlockHandler> | undefined;
slotOfDraggingBlocks: SlotHandler | undefined;
isHovering: boolean;
hoveringSlot: SlotHandler | undefined;
hoveringBlock: BlockHandler | undefined;
/** available when isHovering */
dropEffect?: "none" | "copy" | "link" | "move";
constructor(ctx: BlockContext);
dispose(): void;
private setHoveringSlot;
private _originalSetHoveringSlot;
getBlockDOMEventHandlers(block: BlockHandler): Partial<BlockDOMEventHandlers>;
handleBlockDragStart(block: BlockHandler, ev: FirstParameter<BlockDOMEventHandlers["dragStart"]>): void;
handleBlockDragEnd(): void;
handleBlockDragOver(block: BlockHandler): void;
handleBlockDragLeave(block: BlockHandler): void;
getSlotDOMEventHandlers(slot: SlotHandler): Partial<SlotDOMEventHandlers>;
handleSlotDragOver(slot: SlotHandler, ev: FirstParameter<SlotDOMEventHandlers["dragOver"]>): boolean;
handleSlotDrop(slot: SlotHandler, ev: FirstParameter<SlotDOMEventHandlers["dragOver"]>): void;
handleSlotDragLeave(slot: SlotHandler): void;
/**
* side effect: update this.dropEffect
*
* @return false means not droppable. otherwise a number is returned.
*/
computeIndexToDrop(slot: SlotHandler, ev: DragEvent): false | number;
}