数通智联化工云平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

111 lines
2.8 KiB

/* eslint-disable @typescript-eslint/no-namespace, import/export */
import { Key, 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 && <tag />
export type JsxVNodeChild =
| VNode
| string
| number
| boolean
| undefined
| null;
export type JsxVNodeChildren = ArrayOrElement<JsxVNodeChild>;
export type FunctionComponent = (
props: { [prop: string]: any } | null,
children?: VNode[]
) => VNode;
export function Fragment(
data: { key?: Key } | null,
...children: JsxVNodeChildren[]
): VNode {
const flatChildren = flattenAndFilter(children, []);
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 vnode(
undefined,
undefined,
undefined,
flatChildren[0].text,
undefined
);
} else {
return vnode(undefined, data ?? {}, flatChildren, undefined, undefined);
}
}
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
}