From 3f42182fb139d3ca693a74de4848a1a1844c70ab Mon Sep 17 00:00:00 2001 From: Benjamin Palko Date: Sun, 13 Apr 2025 20:28:06 -0400 Subject: [PATCH] add gtk typings and renderer for window --- lib/jsx/jsx-runtime.ts | 10 ++++++---- lib/jsx/render.ts | 19 ++++++++++++++----- lib/jsx/types/gtk.ts | 11 +++++++++++ lib/jsx/types/index.ts | 2 ++ lib/jsx/{types.ts => types/jsx.ts} | 4 +++- 5 files changed, 36 insertions(+), 10 deletions(-) create mode 100644 lib/jsx/types/gtk.ts create mode 100644 lib/jsx/types/index.ts rename lib/jsx/{types.ts => types/jsx.ts} (76%) diff --git a/lib/jsx/jsx-runtime.ts b/lib/jsx/jsx-runtime.ts index 1e3ffb1..7fee7ab 100644 --- a/lib/jsx/jsx-runtime.ts +++ b/lib/jsx/jsx-runtime.ts @@ -1,14 +1,16 @@ import { renderJSX } from "./render"; -import type { JSXChildren, RenderedNode } from "./types"; +import type { GtkElements, GtkTag, JSXChildren } from "./types"; +import type GObject20 from "gi://GObject?version=2.0"; namespace JSX { - export type Attributes = Record & JSXChildren; // Allow any html tag - export type IntrinsicElements = Record; + export type IntrinsicElements = { + [T in GtkTag]: GtkElements[T] & JSXChildren; + }; // Declare the shape of JSX rendering result // This is required so the return types of components can be inferred - export type Element = RenderedNode; + export type Element = GObject20.Object & {}; } // Expose the main namespace diff --git a/lib/jsx/render.ts b/lib/jsx/render.ts index c21aa4c..7512603 100644 --- a/lib/jsx/render.ts +++ b/lib/jsx/render.ts @@ -1,16 +1,25 @@ import type { JSX } from "./jsx-runtime"; -import type { FunctionComponent } from "./types"; +import { + GtkClasses, + type FunctionComponent, + type GtkElements, + type GtkTag, +} from "./types"; -export function renderJSX( - tag: string | FunctionComponent | undefined, +function renderTag(tag: T, attributes: GtkElements[T]) { + return new GtkClasses[tag]({ ...attributes }); +} + +export function renderJSX( + tag: T | FunctionComponent | undefined, props: JSX.IntrinsicElements[T], ) { if (typeof tag === "function") { - return tag(props); + return tag(props as Record); } if (typeof tag === "undefined") { return {}; } const { children, ...rest } = props; - return { [tag]: { ...rest } }; + return renderTag(tag, rest as GtkElements[T]); } diff --git a/lib/jsx/types/gtk.ts b/lib/jsx/types/gtk.ts new file mode 100644 index 0000000..4df00c7 --- /dev/null +++ b/lib/jsx/types/gtk.ts @@ -0,0 +1,11 @@ +import Gtk40 from "gi://Gtk?version=4.0"; + +export const GtkClasses = { + window: Gtk40.Window, +}; +export type GtkElements = { + [K in keyof typeof GtkClasses]: ConstructorParameters< + (typeof GtkClasses)[K] + >[0]; +}; +export type GtkTag = keyof typeof GtkClasses; diff --git a/lib/jsx/types/index.ts b/lib/jsx/types/index.ts new file mode 100644 index 0000000..c5d1995 --- /dev/null +++ b/lib/jsx/types/index.ts @@ -0,0 +1,2 @@ +export * from "./gtk"; +export * from "./jsx"; diff --git a/lib/jsx/types.ts b/lib/jsx/types/jsx.ts similarity index 76% rename from lib/jsx/types.ts rename to lib/jsx/types/jsx.ts index 7714ad6..a53ec3c 100644 --- a/lib/jsx/types.ts +++ b/lib/jsx/types/jsx.ts @@ -1,4 +1,6 @@ -export type RenderedNode = object; +import type { JSX } from "@lib/jsx/jsx-runtime"; + +export type RenderedNode = JSX.Element; export type JSXNode = | RenderedNode