UNPKG

@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
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; }