marge example into monorepo
This commit is contained in:
parent
90dff70165
commit
e925f1a2c2
23 changed files with 489 additions and 98 deletions
23
packages/greact/lib/index.ts
Normal file
23
packages/greact/lib/index.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import type { JSX } from "@lib/jsx/jsx-runtime";
|
||||
import GLib20 from "gi://GLib";
|
||||
import Gtk40 from "gi://Gtk?version=4.0";
|
||||
|
||||
export * from "./jsx/jsx-runtime";
|
||||
|
||||
export const createRoot = () => {
|
||||
Gtk40.init();
|
||||
const render = (element: JSX.Element) => {
|
||||
const loop = GLib20.MainLoop.new(null, false);
|
||||
|
||||
if (element instanceof Gtk40.Window) {
|
||||
element.connect("close-request", () => loop.quit());
|
||||
element.present();
|
||||
}
|
||||
|
||||
loop.run();
|
||||
};
|
||||
|
||||
return {
|
||||
render: render,
|
||||
};
|
||||
};
|
||||
1
packages/greact/lib/jsx/jsx-dev-runtime.ts
Normal file
1
packages/greact/lib/jsx/jsx-dev-runtime.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from "./jsx-runtime";
|
||||
22
packages/greact/lib/jsx/jsx-runtime.ts
Normal file
22
packages/greact/lib/jsx/jsx-runtime.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { renderJSX } from "./render";
|
||||
import type { GtkElements, GtkTag, JSXChildren } from "./types";
|
||||
import type GObject20 from "gi://GObject?version=2.0";
|
||||
|
||||
namespace JSX {
|
||||
// Allow any html tag
|
||||
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 = GObject20.Object & {};
|
||||
}
|
||||
|
||||
// Expose the main namespace
|
||||
export type { JSX };
|
||||
|
||||
// Expose factories
|
||||
export const jsx = renderJSX;
|
||||
export const jsxs = renderJSX;
|
||||
export const jsxDEV = renderJSX;
|
||||
44
packages/greact/lib/jsx/render.ts
Normal file
44
packages/greact/lib/jsx/render.ts
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import Gtk40 from "gi://Gtk?version=4.0";
|
||||
import type { JSX } from "./jsx-runtime";
|
||||
import {
|
||||
type FunctionComponent,
|
||||
GtkClasses,
|
||||
type GtkElements,
|
||||
type GtkTag,
|
||||
type JSXNode,
|
||||
} from "./types";
|
||||
|
||||
import type GObject from "gi://GObject";
|
||||
|
||||
function renderChildren(children: JSXNode | JSXNode[]): GObject.Object[] {
|
||||
if (Array.isArray(children)) {
|
||||
return children.flatMap(renderChildren);
|
||||
}
|
||||
if (typeof children === "string") {
|
||||
return [new Gtk40.Label({ name: children })];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
function renderTag<T extends GtkTag>(
|
||||
tag: T,
|
||||
attributes: GtkElements[T],
|
||||
children: GObject.Object[],
|
||||
) {
|
||||
const node = new GtkClasses[tag]({ ...attributes });
|
||||
return node;
|
||||
}
|
||||
|
||||
export function renderJSX<T extends GtkTag>(
|
||||
tag: T | FunctionComponent | undefined,
|
||||
props: JSX.IntrinsicElements[T],
|
||||
) {
|
||||
if (typeof tag === "function") {
|
||||
return tag(props as Record<string, unknown>);
|
||||
}
|
||||
if (typeof tag === "undefined") {
|
||||
return {};
|
||||
}
|
||||
const { children, ...rest } = props;
|
||||
return renderTag(tag, rest as GtkElements[T], renderChildren(children));
|
||||
}
|
||||
11
packages/greact/lib/jsx/types/gtk.ts
Normal file
11
packages/greact/lib/jsx/types/gtk.ts
Normal file
|
|
@ -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;
|
||||
2
packages/greact/lib/jsx/types/index.ts
Normal file
2
packages/greact/lib/jsx/types/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./gtk";
|
||||
export * from "./jsx";
|
||||
21
packages/greact/lib/jsx/types/jsx.ts
Normal file
21
packages/greact/lib/jsx/types/jsx.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import type { JSX } from "@lib/jsx/jsx-runtime";
|
||||
|
||||
export type RenderedNode = JSX.Element;
|
||||
|
||||
export type JSXNode =
|
||||
| RenderedNode
|
||||
| (() => JSXNode)
|
||||
| boolean
|
||||
| number
|
||||
| bigint
|
||||
| string
|
||||
| null
|
||||
| undefined;
|
||||
|
||||
export interface JSXChildren {
|
||||
children?: JSXNode | JSXNode[] | undefined;
|
||||
}
|
||||
|
||||
export type FunctionComponent = (
|
||||
props?: Record<string, unknown>,
|
||||
) => RenderedNode;
|
||||
50
packages/greact/package.json
Normal file
50
packages/greact/package.json
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"name": "@baobeld/greact",
|
||||
"type": "module",
|
||||
"version": "1.0.0",
|
||||
"types": "dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"require": "./dist/index.cjs",
|
||||
"import": "./dist/index.js"
|
||||
},
|
||||
"./jsx-runtime": {
|
||||
"types": "./dist/jsx/jsx-runtime.d.ts",
|
||||
"require": "./dist/jsx/jsx-runtime.cjs",
|
||||
"import": "./dist/jsx/jsx-runtime.js"
|
||||
},
|
||||
"./jsx-dev-runtime": {
|
||||
"types": "./dist/jsx/jsx-dev-runtime.d.ts"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"!dist/**/*.spec.*",
|
||||
"!dist/**/*.test.*",
|
||||
"!dist/**/*.stories.*",
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"dev": "",
|
||||
"build": "vite build",
|
||||
"check": "biome check --write **/*",
|
||||
"format": "biome format --write **/*",
|
||||
"lint": "biome lint --write **/*",
|
||||
"test": "vitest",
|
||||
"prepublish": "bun run check"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@types/bun": "latest",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^6.2.6",
|
||||
"vite-plugin-dts": "^4.5.3",
|
||||
"vite-tsconfig-paths": "^5.1.4",
|
||||
"vitest": "^3.1.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@girs/gio-2.0": "^2.84.0-4.0.0-beta.23",
|
||||
"@girs/gjs": "^4.0.0-beta.23",
|
||||
"@girs/glib-2.0": "^2.84.0-4.0.0-beta.23",
|
||||
"@girs/gtk-4.0": "^4.18.3-4.0.0-beta.23"
|
||||
}
|
||||
}
|
||||
50
packages/greact/tsconfig.json
Normal file
50
packages/greact/tsconfig.json
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
// Enable latest features
|
||||
"lib": ["ESNext"],
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"allowJs": true,
|
||||
|
||||
"types": [
|
||||
"vitest/globals",
|
||||
"@girs/gjs",
|
||||
"@girs/gtk-4.0",
|
||||
"@girs/gio-2.0",
|
||||
"@girs/glib-2.0"
|
||||
],
|
||||
// JSX
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "@lib/jsx",
|
||||
|
||||
// Build
|
||||
"outDir": "dist",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
|
||||
// Aliases
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@lib": ["./lib/"],
|
||||
"@lib/*": ["./lib/*"]
|
||||
},
|
||||
|
||||
// Bundler mode
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"noEmit": true,
|
||||
|
||||
// Best practices
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
|
||||
// Some stricter flags (disabled by default)
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noPropertyAccessFromIndexSignature": false
|
||||
},
|
||||
"include": ["lib", "test"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
49
packages/greact/vite.config.ts
Normal file
49
packages/greact/vite.config.ts
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/// <reference types="vitest" />
|
||||
import { resolve } from "node:path";
|
||||
import { defineConfig } from "vite";
|
||||
import tsconfigpaths from "vite-tsconfig-paths";
|
||||
import dts from "vite-plugin-dts";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
tsconfigpaths(),
|
||||
dts({
|
||||
insertTypesEntry: true,
|
||||
exclude: ["test"],
|
||||
}),
|
||||
],
|
||||
build: {
|
||||
// target: "firefox60", // Since GJS 1.53.90
|
||||
// target: "firefox68", // Since GJS 1.63.90
|
||||
// target: "firefox78", // Since GJS 1.65.90
|
||||
// target: "firefox91", // Since GJS 1.71.1
|
||||
// target: "firefox102", // Since GJS 1.73.2
|
||||
target: "firefox115", // Since GJS 1.77.2
|
||||
lib: {
|
||||
entry: resolve(__dirname, "lib", "index.ts"),
|
||||
formats: ["es", "cjs"],
|
||||
fileName: (module, filename) => {
|
||||
const extension = module === "es" ? "js" : module;
|
||||
return `${filename}.${extension}`;
|
||||
},
|
||||
},
|
||||
rollupOptions: {
|
||||
external: [
|
||||
/^gi:\/\/*/i,
|
||||
/^resource:\/\/*/i,
|
||||
"gettext",
|
||||
"system",
|
||||
"cairo",
|
||||
],
|
||||
output: {
|
||||
preserveModules: true,
|
||||
},
|
||||
},
|
||||
minify: false,
|
||||
cssMinify: false,
|
||||
},
|
||||
test: {
|
||||
globals: true,
|
||||
watch: false,
|
||||
},
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue