import { type HFunction, type JSXElement, type RenderNode, type UiActionProps, type UiDisclosureProps, type UiPromptSlotProps, type VNode, } from "@commonfabric/api"; import { isCell } from "../cell.ts"; import { KeepAsCell } from "../link-utils.ts"; import { getCellOrThrow, isCellResult } from "../query-result-proxy.ts"; /** * Fragment element name used for JSX fragments. */ const FRAGMENT_ELEMENT = "cf-fragment"; type LinkableCell = { getAsLink(options?: unknown): unknown; }; const isDeferredLinkContextError = (error: unknown): boolean => error instanceof Error && error.message.startsWith("Cannot create cell link - "); function bindingTargetLink(value: unknown): unknown { if (isCell(value)) { try { return (value as unknown as LinkableCell).getAsLink({ includeSchema: true, keepAsCell: KeepAsCell.All, }); } catch (error) { if (isDeferredLinkContextError(error)) return value; throw error; } } if (isCellResult(value)) { try { return (getCellOrThrow(value) as unknown as LinkableCell).getAsLink({ includeSchema: true, keepAsCell: KeepAsCell.All, }); } catch (error) { if (isDeferredLinkContextError(error)) return value; throw error; } } return value; } /** * JSX factory function for creating virtual DOM nodes. * @param name - The element name or component function * @param props - Element properties * @param children - Child elements * @returns A virtual DOM node or JSX element (for component functions) */ export const h: HFunction = Object.assign( function h( name: string | ((...args: any[]) => JSXElement), props: { [key: string]: any } | null, ...children: RenderNode[] ): JSXElement { // Implementation uses broader types than overloads - assertion needed for // TS compatibility. if (typeof name === "function") { return name({ ...(props ?? {}), children: children.flat(), }); } else { props ??= {}; Object.keys(props).filter((key) => key.startsWith("$")).forEach((key) => { const value = props![key]; if (typeof value !== "object") { throw new Error( `Bidirectionally bound property ${key} is not reactive\n` + "If invoking from within computed(), consider moving the component into a pattern: E.g.\n" + "```\n" + (key === "$checked" ? "const Item = pattern<{ item: Item }>(({item}) =>