import { ref, Properties } from "framework-utils"; import * as React from "react"; import { renderSelf, ContainerProvider } from "croact"; import InnerMoveable from "./InnerMoveable"; import { MoveableInterface, MoveableOptions, MoveableProperties, } from "react-moveable/types"; import { camelize, getDocument, isArray } from "@daybrush/utils"; import { MoveableEventsParameters } from "./types"; import { PROPERTIES, EVENTS, METHODS } from "./consts"; import EventEmitter from "@scena/event-emitter"; /** * Moveable is Draggable! Resizable! Scalable! Rotatable! * @sort 1 * @alias Moveable * @extends EventEmitter */ @Properties(METHODS, (prototype, property) => { if (prototype[property]) { return; } prototype[property] = function(...args: any[]) { const self = this.getMoveable(); if (!self || !self[property]) { return; } return self[property](...args); }; }) @Properties(PROPERTIES, (prototype, property) => { Object.defineProperty(prototype, property, { get() { return this.getMoveable().props[property]; }, set(value) { this.setState({ [property]: value, }); }, enumerable: true, configurable: true, }); }) class MoveableManager extends EventEmitter { private innerMoveable!: InnerMoveable | null; private containerProvider: ContainerProvider | null = null; private selfElement: HTMLElement | null = null; private _warp = false; /** * */ constructor(parentElement: HTMLElement, options: MoveableOptions = {}) { super(); const nextOptions = { ...options }; const events: any = {}; EVENTS.forEach(name => { events[camelize(`on ${name}`)] = (e: any) => this.trigger(name, e); }); let selfElement!: HTMLElement; if (options.warpSelf) { delete options.warpSelf; this._warp = true; selfElement = parentElement; } else { selfElement = getDocument(parentElement).createElement("div"); parentElement.appendChild(selfElement); } this.containerProvider = renderSelf( as any, selfElement, ); this.selfElement = selfElement; const target = nextOptions.target!; if (isArray(target) && target.length > 1) { this.updateRect(); } } public setState(state: Partial, callback?: () => any) { this.innerMoveable!.setState(state, callback); } public forceUpdate(callback?: () => any) { this.innerMoveable!.forceUpdate(callback); } public dragStart(e: MouseEvent | TouchEvent, target: EventTarget | null = e.target) { const innerMoveable = this.innerMoveable; if ((innerMoveable as any).$_timer) { this.forceUpdate(); } this.getMoveable().dragStart(e, target); } public destroy() { const selfElement = this.selfElement!; renderSelf( null, selfElement!, this.containerProvider, ); if (!this._warp) { selfElement?.parentElement?.removeChild(selfElement); } this.containerProvider = null; this.off(); this.selfElement = null; this.innerMoveable = null; } private getMoveable() { return this.innerMoveable!.moveable; } } interface MoveableManager extends MoveableInterface, MoveableProperties { } export default MoveableManager;