import { ref, Properties } from "framework-utils"; import * as React from "react"; import { PROPERTIES, METHODS, EVENTS } from "./consts"; import { GuidesInterface, GuidesEvents, GuidesOptions } from "@scena/react-guides/declaration/types"; import InnerGuides from "./InnerGuides"; import EventEmitter from "@scena/event-emitter"; import { camelize } from "@daybrush/utils"; import { ContainerProvider, renderSelf } from "croact"; @Properties(METHODS as any, (prototype, property) => { if (prototype[property]) { return; } prototype[property] = function(...args) { const self = this.getInnerGuides(); if (!self || !self[property]) { return; } return self[property](...args); }; }) @Properties(PROPERTIES, (prototype, property) => { Object.defineProperty(prototype, property, { get() { return this.getInnerGuides().props[property]; }, set(value) { this.innerGuides.setState({ [property]: value, }); }, enumerable: true, configurable: true, }); }) /** * @sort 1 * @extends EventEmitter */ class Guides extends EventEmitter { private containerProvider: ContainerProvider | null = null; private selfElement: HTMLElement | null = null; private _warp = false; private innerGuides!: InnerGuides; /** * @sort 1 * @param - guides' container * @param {$ts:Partial} - guides' options */ constructor(container: HTMLElement, options: Partial = {}) { super(); const events: any = {}; EVENTS.forEach(name => { events[camelize(`on ${name}`)] = (e: any) => this.trigger(name as any, e); }); let selfElement!: HTMLElement; if (options.warpSelf) { delete options.warpSelf; this._warp = true; selfElement = container; } else { selfElement = document.createElement("div"); container.appendChild(selfElement); } this.containerProvider = renderSelf( , selfElement, ); } /** * @param state * @param callback */ public setState(state: Partial, callback?: () => void) { this.innerGuides.setState(state, callback); } /** * @param callback */ public forceUpdate(callback?: () => void) { this.innerGuides.forceUpdate(callback); } /** * destroy guides */ public destroy() { const selfElement = this.selfElement!; renderSelf( null, selfElement!, this.containerProvider, ); if (!this._warp) { selfElement?.parentElement?.removeChild(selfElement); } this.selfElement = null; this.innerGuides = null; } private getInnerGuides() { return this.innerGuides.guides; } } interface Guides extends GuidesInterface {} export default Guides;