52 lines
1.5 KiB
TypeScript
52 lines
1.5 KiB
TypeScript
import type { UNode, UElement, URoot, UType, UComponent, UniversalProps } from "./schema.js";
|
|
|
|
let _idCounter = 0;
|
|
|
|
export function h(type: UType, props?: UniversalProps | null, ...children: UNode[]): UElement | URoot {
|
|
const flatChildren = children.flat(Infinity as 1).filter((c: UNode) => c != null && c !== false) as UNode[];
|
|
|
|
if (type === "root") {
|
|
return {
|
|
type: "root",
|
|
props: { ...(props ?? {}) },
|
|
children: flatChildren,
|
|
} as URoot;
|
|
}
|
|
|
|
const { key, ...restProps } = props ?? {};
|
|
const resolvedProps: UniversalProps = restProps;
|
|
|
|
return {
|
|
type: type as string,
|
|
props: resolvedProps,
|
|
children: flatChildren,
|
|
...(key != null ? { key: key as string } : {}),
|
|
} as UElement;
|
|
}
|
|
|
|
export function createRoot(id: string | undefined, ...children: UNode[]): URoot {
|
|
return {
|
|
type: "root",
|
|
props: { id: id ?? `root_${++_idCounter}` },
|
|
children: children.flat(Infinity as 1).filter((c: UNode) => c != null && c !== false) as UNode[],
|
|
};
|
|
}
|
|
|
|
export function createComponent<P extends UniversalProps>(
|
|
name: string,
|
|
render: (props: P) => UNode,
|
|
targets?: string[],
|
|
): UComponent<P> {
|
|
const c = render as unknown as UComponent<P>;
|
|
c.displayName = name;
|
|
c.targets = targets;
|
|
return c;
|
|
}
|
|
|
|
export function Fragment(props: { children?: UNode[] }): UNode[] {
|
|
return ((props.children ?? []) as UNode[]).flat(Infinity as 1).filter((c: UNode) => c != null && c !== false) as UNode[];
|
|
}
|
|
|
|
export const jsx = h;
|
|
export const jsxs = h;
|
|
export const jsxDEV = h; |