UNPKG

jcore-ui

Version:

jcore-ui - components for building an interface

121 lines (99 loc) 3.6 kB
import { IObject } from "../interfaces"; import EventEmitter, { TEventEmitter } from "../utils/EventEmitter"; import { $, JDom } from "./JDom"; export interface IComponentSelector { element: string; } export interface IComponentOptions { mount?: boolean; name?: string; } export interface IComponentOn { mount?: (ctx?: Component) => void; render?: (ctx?: Component) => void; destroy?: (ctx?: Component) => void; unmount?: (ctx?: Component) => void; } export interface IComponent extends IObject { selectors?: IComponentSelector; $element?: HTMLElement | NodeListOf<HTMLElement> | string; options?: IComponentOptions; on?: IComponentOn; } export interface IComponentClass extends IComponent { Component: any; } interface Component { handlers?: IObject; $element: JDom; emitter: TEventEmitter; components: any[]; selectors: IComponentSelector; _mount: boolean; options: IComponentOptions; on: IComponentOn; } class Component { constructor(props: IComponentClass) { /** * Если пришел массив HTMLElement, * то для каждого вызываем экземпляр компонента * и записываем их в массив components */ if (Array.isArray(props.$element) || props.$element instanceof NodeList) { let array = Array.from(props.$element); if (array.length) { this.components = array.map(el => { if (this._mount || $(el).hasAttr('data-mount')) { return; }; return new props.Component(Object.assign(props, { $element: el })); }).filter(cpm => cpm); } return this; }; /** * Если не передали HTMLElement, * то делаем поиск по селектору элемента и вызываем для него экземпляр компонента */ if (!props.$element) { return new props.Component({ ...props, $element: $(props.selectors.element).element }); }; this.$element = $(props.$element); if (!this.$element) { // throw Error(`Не найден HTMLElement ${this.constructor.name}`) console.log(Error(`Не найден HTMLElement ${this.constructor.name}`)); }; this.options = { mount: true, name: this.$element.dataset.name || props.options && props.options.name || '' }; this.on = { mount: () => {}, render: () => {}, destroy: () => {}, unmount: () => {}, }; this.selectors = props.selectors; this.emitter = props.emitter || new EventEmitter(); this.options = Object.assign(this.options, props.options || {}); this.on = Object.assign(this.on, props.on || {}); } mount() { this.$element.attr('data-mount', 'true'); this._mount = true; } getByName(components: Component[], name: string): Component { return components.filter(component => component.options.name === name)[0]; } unmount() { this._mount = false; this.$element.attr('data-mount', null); } } export default Component