UNPKG

web-atoms-core

Version:
187 lines (164 loc) • 5.58 kB
import Bind from "./Bind"; import { IClassOf } from "./types"; export interface IAttributes { [key: string]: string | number | null | any; } export class RootObject { public get vsProps(): { [k in keyof this]?: this[k] | Bind } | { [k: string]: any } | {} { return undefined; } } // tslint:disable-next-line: no-namespace declare global { namespace JSX { // tslint:disable-next-line: interface-name interface ElementAttributesProperty { vsProps; } type HtmlPartial<T> = { [k in keyof T]?: { [tx in keyof T[k]]?: T[k][tx] | any; } | { eventClick?: any; eventBlur?: any; eventFocus?: any; text?: string | any; [key: string]: any } }; type IAllHtmlElements = HtmlPartial<HTMLElementTagNameMap>; // tslint:disable-next-line interface IntrinsicElements extends IAllHtmlElements { } } } export type IMergedControl<T, T1> = { [P in keyof (T & T1)]?: (T & T1)[P]; } & { vsProps: { [P in keyof (T & T1)]?: (T & T1)[P]; } }; export type NodeFactory = (a?: any, ... nodes: XNode[]) => XNode; export type AttachedNode = (n: any) => { [key: string]: any}; export default class XNode { public static attach<T, T1 extends HTMLElementTagNameMap, K extends keyof T1>( n: IClassOf<T>, tag: K): new (... a: any[]) => IMergedControl<T, T1[K]> ; public static attach<T, T1>( n: IClassOf<T>, tag: (a?: Partial<T1>, ... nodes: XNode[]) => XNode): new (... a: any[]) => IMergedControl<T, T1> ; public static attach( n: any, tag: any): any { return { factory: (attributes: any, ... nodes: XNode[] ) => new XNode(n, attributes ? { ... attributes, for: tag } : { for: tag}, nodes) }; } public static prepare<T>( n: any, isProperty?: boolean, isTemplate?: boolean): ((attributes: Partial<T>, ... nodes: XNode[]) => XNode) { return { factory(a: any, ... nodes: any[]) { return new XNode(n, a, nodes, isProperty , isTemplate); }, toString() { return n; } } as any; } public static template(): NodeFactory { return { factory: true, isTemplate: true, } as any; } /** * This is only for intellisense... */ public static attached(): AttachedNode { return { attached: true } as any; } public static property(): NodeFactory { return { factory: true } as any; } /** * Declares Root Namespace and Assembly. You can use return function to * to declare the type * @param ns Root Namespace */ public static namespace(ns: string, assemblyName: string) { return (type: string, isTemplate?: boolean) => { return (c) => { for (const key in c) { if (c.hasOwnProperty(key)) { const element = c[key]; if (element) { const n = ns + "." + type + ":" + key + ";" + assemblyName; const af: any = (a) => { const r = { [n]: a }; Object.defineProperty(r, "toString", { value: () => n, enumerable: false, configurable: false }); return r; }; af.factory = (a?: any, ... nodes: any[]) => new XNode(n, a, nodes, true, element.isTemplate ); af.toString = () => n; c[key] = af; } } } const tn = ns + "." + type + ";" + assemblyName; c.factory = (a?: any, ... nodes: XNode[]) => { return new XNode(tn, a, nodes, false, isTemplate); }; c.toString = () => tn; }; }; } public static create( // tslint:disable-next-line: ban-types name: string | Function, attributes: IAttributes, ... children: Array<XNode | XNode[] | any>): XNode { if ((name as any).factory) { return ((name as any).factory)(attributes, ... children); } if ((name as any).isControl) { return new XNode(name as any, attributes, children); } if (typeof name === "object") { name = (name as any).toString(); } return new XNode(name as any, attributes, children); } constructor( // tslint:disable-next-line: ban-types public name: string | Function, public attributes: IAttributes, public children: XNode[] | XNode[][] | any[], public isProperty?: boolean, public isTemplate?: boolean) { } public toString(): string { if (typeof this.name === "string") { return `name is of type string and value is ${this.name}`; } return `name is of type ${typeof this.name}`; } }