All Downloads are FREE. Search and download functionalities are using the official Maven repository.

package.src.jsx.ts Maven / Gradle / Ivy

Go to download

A virtual DOM library with focus on simplicity, modularity, powerful features and performance.

The newest version!
/* eslint-disable @typescript-eslint/no-namespace, import/export */
import { vnode, VNode, VNodeData } from "./vnode";
import { h, ArrayOrElement } from "./h";

// See https://www.typescriptlang.org/docs/handbook/jsx.html#type-checking
namespace JSXInternal {
  export type Element = VNode;
  export interface IntrinsicElements {
    [elemName: string]: VNodeData;
  }
}

// for conditional rendering we support boolean child element e.g cond && 
export type JsxVNodeChild =
  | VNode
  | string
  | number
  | boolean
  | undefined
  | null;
export type JsxVNodeChildren = ArrayOrElement;

export type FunctionComponent = (
  props: { [prop: string]: any } | null,
  children?: VNode[]
) => VNode;

function flattenAndFilter(
  children: JsxVNodeChildren[],
  flattened: VNode[]
): VNode[] {
  for (const child of children) {
    // filter out falsey children, except 0 since zero can be a valid value e.g inside a chart
    if (
      child !== undefined &&
      child !== null &&
      child !== false &&
      child !== ""
    ) {
      if (Array.isArray(child)) {
        flattenAndFilter(child, flattened);
      } else if (
        typeof child === "string" ||
        typeof child === "number" ||
        typeof child === "boolean"
      ) {
        flattened.push(
          vnode(undefined, undefined, undefined, String(child), undefined)
        );
      } else {
        flattened.push(child);
      }
    }
  }
  return flattened;
}

/**
 * jsx/tsx compatible factory function
 * see: https://www.typescriptlang.org/docs/handbook/jsx.html#factory-functions
 */
export function jsx(
  tag: string | FunctionComponent,
  data: VNodeData | null,
  ...children: JsxVNodeChildren[]
): VNode {
  const flatChildren = flattenAndFilter(children, []);
  if (typeof tag === "function") {
    // tag is a function component
    return tag(data, flatChildren);
  } else {
    if (
      flatChildren.length === 1 &&
      !flatChildren[0].sel &&
      flatChildren[0].text
    ) {
      // only child is a simple text node, pass as text for a simpler vtree
      return h(tag, data, flatChildren[0].text);
    } else {
      return h(tag, data, flatChildren);
    }
  }
}

export namespace jsx {
  export import JSX = JSXInternal; // eslint-disable-line @typescript-eslint/no-unused-vars
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy