@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.
163 lines (162 loc) • 5.98 kB
TypeScript
import { EventEmitter } from "./EventEmitter";
import { IBPasteAction, IBCutAction, IBClipboardData, IBMoveInSlotAction, IBMoveBetweenSlotsAction } from "./action";
import { BlockHandler, BlockInfo } from "./BlockHandler";
import { DraggingContext } from "./DraggingContext";
import { SlotHandler, SlotInfo } from "./SlotHandler";
import { MultipleSelectType } from "./MultipleSelectType";
export interface BlockContextEvents {
activeElementChanged(ctx: BlockContext): void;
focus(ctx: BlockContext): void;
blur(ctx: BlockContext): void;
paste(action: IBPasteAction): void;
cut(action: IBCutAction): void;
moveInSlot(action: IBMoveInSlotAction): void;
moveBetweenSlots(action: IBMoveBetweenSlotsAction): void;
}
export interface BlockContextOptions {
/**
* optional, a string to distinguish BlockContexts of different scenario usage.
*
* for example: "files", "workflow", "tasks", "dependencies"
*
* between BlockContexts with different brand, data cannot be pasted / dragged
*/
brand?: string;
/**
* whether unset all active blocks & slot's `active` state when click nothing on the page
*
* default is true
*/
deactivateHandlersWhenBlur?: boolean;
/**
* whether navigate with arrow keys when focused.
*
* default is true.
*
* Note: to add your own keyboard logic, `blockContext.hiddenInput.addEventListener("keydown", ...)`
*/
navigateWithArrowKeys?: boolean;
/**
* when user press delete key, whether perform cut action without updating clipboard.
*
* default is true.
*
* Note: to add your own keyboard logic, `blockContext.hiddenInput.addEventListener("keydown", ...)`
*/
handleDeleteKey?: boolean;
/**
* default is true
*/
multipleSelect?: boolean;
/**
* default is `JSON.stringify(data)`
*
* @see {@link unserializeForClipboard}
*/
serializeForClipboard?: (data: any) => string;
/**
* default is `JSON.parse(text)`
*
* @see {@link serializeForClipboard}
*/
unserializeForClipboard?: (text: string) => any;
}
export declare class BlockContext extends EventEmitter<BlockContextEvents> {
hiddenInput: HTMLTextAreaElement;
private _lastActiveElement;
hasFocus: boolean;
options: Required<BlockContextOptions>;
brand: string;
uuid: string;
dragging: DraggingContext;
constructor(options?: BlockContextOptions);
focus(): void;
/**
* dump all active blocks' data, then you can transfer it via file / clipboard etc,
* and use it with {@link pasteWithData}
*
* this will NOT delete the selected blocks. if you want to, call {@link deleteActiveBlocks}
*
* @see {@link pasteWithData}
* @returns `undefined` if cannot copy. otherwise returns text
*/
dumpSelectedData(): IBClipboardData | undefined;
/**
* Focus the hidden input and write selected blocks' data to the clipboard.
*/
copy(): void;
/**
* do a "pasting" action with the data exported by {@link dumpSelectedData}
*
* @param data
* @param targetIndex - the insert point. if not specified, will be before the active block, of the end of current active slot.
* @see {@link dumpSelectedData}
*/
pasteWithData(data: any, targetIndex?: number): void;
/**
* Make a Cut Action and send to activeSlot.
*
* `cut` event will be emitted on the slot and this context.
*
* clipboard not affected. Call `copy` before this, if needed.
*
* @return `true` if action is handled and not `preventDefault`-ed
*/
deleteActiveBlocks(): boolean;
/**
* Focus the hidden input and select next n-th block.
*
* @param n the relative number to current block. could be negative
*/
activeNextBlock(n: number, multipleSelectMode?: boolean): void;
/**
* Focus the hidden input and select parent block of current block.
*/
activeParentBlock(): void;
/**
* Focus the hidden input and select current block's first slot and its children.
*/
activeChildrenBlocks(): void;
/**
* the current active blocks.
*
* WARN:
* 1. they must be in the same slot!
* 2. always invoke `syncActiveElementStatus` after mutating this.
*/
activeBlocks: Set<BlockHandler>;
slotOfActiveBlocks: SlotHandler | null;
/**
* the current active slot.
*
* WARN:
* 1. this is NOT ALWAYS related to `activeBlocks`. See `slotOfActiveBlocks` if needed.
* 2. always invoke `syncActiveElementStatus` after mutating this.
*/
activeSlot: SlotHandler | null;
private lastActiveSlot;
private lastActiveBlocks?;
/**
* invoke this when `activeSlot` or `activeBlocks` are mutated!
*/
syncActiveElementStatus(): void;
isFocusingBlock?: BlockHandler;
isFocusingSlot?: SlotHandler;
focusingElement?: HTMLElement;
/**
* clear selection
*/
clearSelection(): void;
/**
* select a block or add it to selection ( if multipleSelect is not `none`)
*
* note: if in multipleSelect mode, `activeSlot` will be affected
*/
addBlockToSelection(currBlock: BlockHandler, multipleSelect?: MultipleSelectType): void;
handleSlotPointerUp: (slot: SlotHandler, ev?: Pick<PointerEvent, "eventPhase" | "currentTarget"> | undefined) => void;
handleBlockPointerUp: (block: BlockHandler, ev?: Pick<PointerEvent, "eventPhase" | "currentTarget"> | undefined) => void;
handleGlobalPointerUp: (ev: PointerEvent) => void;
dispose(): void;
createBlock(info: BlockInfo, ownerSlot?: SlotHandler | null): BlockHandler;
createSlot(info: SlotInfo, ownerBlock?: BlockHandler | null): SlotHandler;
}