import { Document as NDocument, HTMLElement as NHTMLElement, Node as NNode } from 'nodom' type Assign = Pick> & K type ElementProperties = Assign, { class?: T['className'], style?: Partial, children?: any, }> type AnyProperties = {[key: string]: any} type CreateElement = typeof createElement declare global { // eslint-disable-next-line @typescript-eslint/no-namespace namespace JSX { type IntrinsicElements = { [K in keyof HTMLElementTagNameMap]: ElementProperties } type ElementChildrenAttribute = { children: any, } const createElement: CreateElement } } const document = new NDocument() // Mimics React.createElement function. export function createElement ( factory: (props: AnyProperties) => R, props: AnyProperties, ...children: any[] ): R export function createElement ( type: K, props: JSX.IntrinsicElements[K], ...children: any[] ): NHTMLElement export function createElement ( type: string | ((props: AnyProperties) => NHTMLElement), props: AnyProperties, ...children: any[] ): NHTMLElement { if (typeof type === 'function') { return type({ ...props, children }) } const el = document.createElement(type) for (const [key, val] of Object.entries(props || {})) { if (!val) { continue } else if (key === 'class' || key === 'className') { el.className = String(val) } else { el.setAttribute(key, String(val)) } } for (const child of children) { if (!child) { continue } else if (child instanceof NNode) { el.appendChild(child) } else if (typeof child === 'object' && '__html' in child) { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access el.innerHTML = child.__html as string } else { el.appendChild(document.createTextNode(String(child))) } } return el } // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access (global as any).JSX = { createElement, }