@gtkx/react 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -28
- package/dist/codegen/jsx-generator.d.ts +15 -9
- package/dist/codegen/jsx-generator.js +215 -94
- package/dist/factory.js +5 -0
- package/dist/generated/internal.js +9291 -3379
- package/dist/generated/jsx.d.ts +12954 -4396
- package/dist/generated/jsx.js +3672 -171
- package/dist/node.js +25 -7
- package/dist/nodes/header-bar.d.ts +19 -0
- package/dist/nodes/header-bar.js +45 -0
- package/dist/nodes/toolbar-view.d.ts +19 -0
- package/dist/nodes/toolbar-view.js +81 -0
- package/dist/nodes/window.js +11 -2
- package/dist/portal.d.ts +1 -1
- package/dist/portal.js +1 -1
- package/dist/predicates.d.ts +7 -0
- package/dist/predicates.js +4 -0
- package/dist/reconciler.js +1 -1
- package/package.json +3 -3
package/dist/node.js
CHANGED
|
@@ -1,8 +1,27 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Adw from "@gtkx/ffi/adw";
|
|
2
2
|
import * as GObject from "@gtkx/ffi/gobject";
|
|
3
3
|
import * as Gtk from "@gtkx/ffi/gtk";
|
|
4
|
+
import * as GtkSource from "@gtkx/ffi/gtksource";
|
|
5
|
+
import * as Vte from "@gtkx/ffi/vte";
|
|
6
|
+
import * as WebKit from "@gtkx/ffi/webkit";
|
|
4
7
|
import { CONSTRUCTOR_PARAMS, PROP_SETTERS, SETTER_GETTERS } from "./generated/internal.js";
|
|
5
|
-
import { isAppendable, isRemovable, isSingleChild } from "./predicates.js";
|
|
8
|
+
import { isAddable, isAppendable, isRemovable, isSingleChild } from "./predicates.js";
|
|
9
|
+
const NAMESPACE_REGISTRY = [
|
|
10
|
+
["GtkSource", GtkSource],
|
|
11
|
+
["WebKit", WebKit],
|
|
12
|
+
["Adw", Adw],
|
|
13
|
+
["Vte", Vte],
|
|
14
|
+
];
|
|
15
|
+
const resolveWidgetClass = (type) => {
|
|
16
|
+
for (const [prefix, namespace] of NAMESPACE_REGISTRY) {
|
|
17
|
+
if (type.startsWith(prefix)) {
|
|
18
|
+
const className = type.slice(prefix.length);
|
|
19
|
+
return namespace[className];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// biome-ignore lint/performance/noDynamicNamespaceImportAccess: dynamic widget resolution by name
|
|
23
|
+
return Gtk[type];
|
|
24
|
+
};
|
|
6
25
|
const extractConstructorArgs = (type, props) => {
|
|
7
26
|
const params = CONSTRUCTOR_PARAMS[type];
|
|
8
27
|
if (!params)
|
|
@@ -49,14 +68,10 @@ export class Node {
|
|
|
49
68
|
}
|
|
50
69
|
createWidget(type, props) {
|
|
51
70
|
const normalizedType = type.split(".")[0] || type;
|
|
52
|
-
|
|
53
|
-
const WidgetClass = Gtk[normalizedType];
|
|
71
|
+
const WidgetClass = resolveWidgetClass(normalizedType);
|
|
54
72
|
if (!WidgetClass) {
|
|
55
73
|
throw new Error(`Unknown GTK widget type: ${normalizedType}`);
|
|
56
74
|
}
|
|
57
|
-
if (WidgetClass === Gtk.ApplicationWindow) {
|
|
58
|
-
return new WidgetClass(getCurrentApp());
|
|
59
|
-
}
|
|
60
75
|
return new WidgetClass(...extractConstructorArgs(normalizedType, props));
|
|
61
76
|
}
|
|
62
77
|
getWidget() {
|
|
@@ -79,6 +94,9 @@ export class Node {
|
|
|
79
94
|
if (isAppendable(parentWidget)) {
|
|
80
95
|
widget.insertBefore(parentWidget, null);
|
|
81
96
|
}
|
|
97
|
+
else if (isAddable(parentWidget)) {
|
|
98
|
+
parentWidget.add(widget);
|
|
99
|
+
}
|
|
82
100
|
else if (isSingleChild(parentWidget)) {
|
|
83
101
|
parentWidget.setChild(widget);
|
|
84
102
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type * as Adw from "@gtkx/ffi/adw";
|
|
2
|
+
import type * as Gtk from "@gtkx/ffi/gtk";
|
|
3
|
+
import { Node } from "../node.js";
|
|
4
|
+
/**
|
|
5
|
+
* Node for AdwHeaderBar that uses packStart for non-slot children.
|
|
6
|
+
*/
|
|
7
|
+
export declare class AdwHeaderBarNode extends Node<Adw.HeaderBar> {
|
|
8
|
+
static matches(type: string): boolean;
|
|
9
|
+
appendChild(child: Node): void;
|
|
10
|
+
removeChild(child: Node): void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Node for Gtk.HeaderBar that uses packStart for children.
|
|
14
|
+
*/
|
|
15
|
+
export declare class HeaderBarNode extends Node<Gtk.HeaderBar> {
|
|
16
|
+
static matches(type: string): boolean;
|
|
17
|
+
appendChild(child: Node): void;
|
|
18
|
+
removeChild(child: Node): void;
|
|
19
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Node } from "../node.js";
|
|
2
|
+
/**
|
|
3
|
+
* Node for AdwHeaderBar that uses packStart for non-slot children.
|
|
4
|
+
*/
|
|
5
|
+
export class AdwHeaderBarNode extends Node {
|
|
6
|
+
static matches(type) {
|
|
7
|
+
return type === "AdwHeaderBar" || type === "AdwHeaderBar.Root";
|
|
8
|
+
}
|
|
9
|
+
appendChild(child) {
|
|
10
|
+
const childWidget = child.getWidget();
|
|
11
|
+
if (!childWidget) {
|
|
12
|
+
child.attachToParent(this);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
this.widget.packStart(childWidget);
|
|
16
|
+
}
|
|
17
|
+
removeChild(child) {
|
|
18
|
+
const childWidget = child.getWidget();
|
|
19
|
+
if (childWidget) {
|
|
20
|
+
this.widget.remove(childWidget);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Node for Gtk.HeaderBar that uses packStart for children.
|
|
26
|
+
*/
|
|
27
|
+
export class HeaderBarNode extends Node {
|
|
28
|
+
static matches(type) {
|
|
29
|
+
return type === "HeaderBar";
|
|
30
|
+
}
|
|
31
|
+
appendChild(child) {
|
|
32
|
+
const childWidget = child.getWidget();
|
|
33
|
+
if (!childWidget) {
|
|
34
|
+
child.attachToParent(this);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
this.widget.packStart(childWidget);
|
|
38
|
+
}
|
|
39
|
+
removeChild(child) {
|
|
40
|
+
const childWidget = child.getWidget();
|
|
41
|
+
if (childWidget) {
|
|
42
|
+
this.widget.remove(childWidget);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Node } from "../node.js";
|
|
2
|
+
/**
|
|
3
|
+
* Virtual node for AdwToolbarView Top and Bottom slots.
|
|
4
|
+
* These slots use addTopBar/addBottomBar instead of setChild.
|
|
5
|
+
*/
|
|
6
|
+
export declare class ToolbarViewSlotNode extends Node<never> {
|
|
7
|
+
static matches(type: string): boolean;
|
|
8
|
+
protected isVirtual(): boolean;
|
|
9
|
+
private slotType;
|
|
10
|
+
private parentNode;
|
|
11
|
+
private children;
|
|
12
|
+
constructor(type: string);
|
|
13
|
+
appendChild(child: Node): void;
|
|
14
|
+
removeChild(child: Node): void;
|
|
15
|
+
attachToParent(parent: Node): void;
|
|
16
|
+
detachFromParent(_parent: Node): void;
|
|
17
|
+
private addBarToParent;
|
|
18
|
+
private removeBarFromParent;
|
|
19
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Node } from "../node.js";
|
|
2
|
+
/**
|
|
3
|
+
* Virtual node for AdwToolbarView Top and Bottom slots.
|
|
4
|
+
* These slots use addTopBar/addBottomBar instead of setChild.
|
|
5
|
+
*/
|
|
6
|
+
export class ToolbarViewSlotNode extends Node {
|
|
7
|
+
static matches(type) {
|
|
8
|
+
if (!type.startsWith("AdwToolbarView."))
|
|
9
|
+
return false;
|
|
10
|
+
const slot = type.split(".")[1];
|
|
11
|
+
return slot === "Top" || slot === "Bottom";
|
|
12
|
+
}
|
|
13
|
+
isVirtual() {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
slotType;
|
|
17
|
+
parentNode = null;
|
|
18
|
+
children = [];
|
|
19
|
+
constructor(type) {
|
|
20
|
+
super(type);
|
|
21
|
+
const slot = type.split(".")[1];
|
|
22
|
+
if (slot !== "Top" && slot !== "Bottom") {
|
|
23
|
+
throw new Error(`Invalid toolbar view slot type: ${type}`);
|
|
24
|
+
}
|
|
25
|
+
this.slotType = slot;
|
|
26
|
+
}
|
|
27
|
+
appendChild(child) {
|
|
28
|
+
const childWidget = child.getWidget();
|
|
29
|
+
if (!childWidget)
|
|
30
|
+
return;
|
|
31
|
+
this.children.push(child);
|
|
32
|
+
if (this.parentNode) {
|
|
33
|
+
this.addBarToParent(childWidget);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
removeChild(child) {
|
|
37
|
+
const index = this.children.indexOf(child);
|
|
38
|
+
if (index !== -1) {
|
|
39
|
+
this.children.splice(index, 1);
|
|
40
|
+
}
|
|
41
|
+
const childWidget = child.getWidget();
|
|
42
|
+
if (this.parentNode && childWidget) {
|
|
43
|
+
this.removeBarFromParent(childWidget);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
attachToParent(parent) {
|
|
47
|
+
this.parentNode = parent;
|
|
48
|
+
for (const child of this.children) {
|
|
49
|
+
const childWidget = child.getWidget();
|
|
50
|
+
if (childWidget) {
|
|
51
|
+
this.addBarToParent(childWidget);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
detachFromParent(_parent) {
|
|
56
|
+
for (const child of this.children) {
|
|
57
|
+
const childWidget = child.getWidget();
|
|
58
|
+
if (childWidget) {
|
|
59
|
+
this.removeBarFromParent(childWidget);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
this.parentNode = null;
|
|
63
|
+
}
|
|
64
|
+
addBarToParent(childWidget) {
|
|
65
|
+
const parentWidget = this.parentNode?.getWidget();
|
|
66
|
+
if (!parentWidget)
|
|
67
|
+
return;
|
|
68
|
+
if (this.slotType === "Top") {
|
|
69
|
+
parentWidget.addTopBar(childWidget);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
parentWidget.addBottomBar(childWidget);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
removeBarFromParent(childWidget) {
|
|
76
|
+
const parentWidget = this.parentNode?.getWidget();
|
|
77
|
+
if (!parentWidget)
|
|
78
|
+
return;
|
|
79
|
+
parentWidget.remove(childWidget);
|
|
80
|
+
}
|
|
81
|
+
}
|
package/dist/nodes/window.js
CHANGED
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
import { getCurrentApp } from "@gtkx/ffi";
|
|
2
|
+
import * as Adw from "@gtkx/ffi/adw";
|
|
2
3
|
import * as Gtk from "@gtkx/ffi/gtk";
|
|
3
4
|
import { Node } from "../node.js";
|
|
4
5
|
import { getNumberProp } from "../props.js";
|
|
6
|
+
const WINDOW_TYPES = new Set(["Window", "ApplicationWindow", "AdwWindow", "AdwApplicationWindow"]);
|
|
5
7
|
export class WindowNode extends Node {
|
|
6
8
|
static matches(type) {
|
|
7
|
-
return type
|
|
9
|
+
return WINDOW_TYPES.has(type.split(".")[0] || type);
|
|
8
10
|
}
|
|
9
11
|
createWidget(type, _props) {
|
|
10
|
-
|
|
12
|
+
const normalizedType = type.split(".")[0] || type;
|
|
13
|
+
if (normalizedType === "ApplicationWindow") {
|
|
11
14
|
return new Gtk.ApplicationWindow(getCurrentApp());
|
|
12
15
|
}
|
|
16
|
+
if (normalizedType === "AdwApplicationWindow") {
|
|
17
|
+
return new Adw.ApplicationWindow(getCurrentApp());
|
|
18
|
+
}
|
|
19
|
+
if (normalizedType === "AdwWindow") {
|
|
20
|
+
return new Adw.Window();
|
|
21
|
+
}
|
|
13
22
|
return new Gtk.Window();
|
|
14
23
|
}
|
|
15
24
|
detachFromParent(_parent) {
|
package/dist/portal.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ import type { ReactNode, ReactPortal } from "react";
|
|
|
17
17
|
* {createPortal(<AboutDialog programName="My App" />)}
|
|
18
18
|
*
|
|
19
19
|
* // Render into a specific container
|
|
20
|
-
* {createPortal(<Label
|
|
20
|
+
* {createPortal(<Label label="This is in the Box" />, boxRef.current)}
|
|
21
21
|
* ```
|
|
22
22
|
*/
|
|
23
23
|
export declare const createPortal: (children: ReactNode, container?: unknown, key?: string | null) => ReactPortal;
|
package/dist/portal.js
CHANGED
|
@@ -17,7 +17,7 @@ import { ROOT_NODE_CONTAINER } from "./factory.js";
|
|
|
17
17
|
* {createPortal(<AboutDialog programName="My App" />)}
|
|
18
18
|
*
|
|
19
19
|
* // Render into a specific container
|
|
20
|
-
* {createPortal(<Label
|
|
20
|
+
* {createPortal(<Label label="This is in the Box" />, boxRef.current)}
|
|
21
21
|
* ```
|
|
22
22
|
*/
|
|
23
23
|
export const createPortal = (children, container, key) => {
|
package/dist/predicates.d.ts
CHANGED
|
@@ -2,6 +2,9 @@ import type * as Gtk from "@gtkx/ffi/gtk";
|
|
|
2
2
|
interface Appendable extends Gtk.Widget {
|
|
3
3
|
append(child: unknown): void;
|
|
4
4
|
}
|
|
5
|
+
interface Addable extends Gtk.Widget {
|
|
6
|
+
add(child: unknown): void;
|
|
7
|
+
}
|
|
5
8
|
interface SingleChild extends Gtk.Widget {
|
|
6
9
|
setChild(child: unknown): void;
|
|
7
10
|
}
|
|
@@ -12,6 +15,10 @@ interface Removable extends Gtk.Widget {
|
|
|
12
15
|
* Type guard that checks if a GTK widget supports appending children via an append method.
|
|
13
16
|
*/
|
|
14
17
|
export declare const isAppendable: (widget: Gtk.Widget) => widget is Appendable;
|
|
18
|
+
/**
|
|
19
|
+
* Type guard that checks if a GTK widget supports adding children via an add method.
|
|
20
|
+
*/
|
|
21
|
+
export declare const isAddable: (widget: Gtk.Widget) => widget is Addable;
|
|
15
22
|
/**
|
|
16
23
|
* Type guard that checks if a GTK widget supports a single child via setChild method.
|
|
17
24
|
*/
|
package/dist/predicates.js
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
* Type guard that checks if a GTK widget supports appending children via an append method.
|
|
3
3
|
*/
|
|
4
4
|
export const isAppendable = (widget) => "append" in widget && typeof widget.append === "function";
|
|
5
|
+
/**
|
|
6
|
+
* Type guard that checks if a GTK widget supports adding children via an add method.
|
|
7
|
+
*/
|
|
8
|
+
export const isAddable = (widget) => "add" in widget && typeof widget.add === "function";
|
|
5
9
|
/**
|
|
6
10
|
* Type guard that checks if a GTK widget supports a single child via setChild method.
|
|
7
11
|
*/
|
package/dist/reconciler.js
CHANGED
|
@@ -32,7 +32,7 @@ class Reconciler {
|
|
|
32
32
|
createInstance: (type, props) => {
|
|
33
33
|
return createNode(type, props);
|
|
34
34
|
},
|
|
35
|
-
createTextInstance: (text) => createNode("Label
|
|
35
|
+
createTextInstance: (text) => createNode("Label", { label: text }),
|
|
36
36
|
appendInitialChild: (parent, child) => parent.appendChild(child),
|
|
37
37
|
finalizeInitialChildren: () => true,
|
|
38
38
|
commitUpdate: (instance, _type, oldProps, newProps) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gtkx/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Build GTK4 desktop applications with React and TypeScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"gtk",
|
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"react-reconciler": "0.33.0",
|
|
39
|
-
"@gtkx/ffi": "0.
|
|
39
|
+
"@gtkx/ffi": "0.6.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@gtkx/gir": "0.
|
|
42
|
+
"@gtkx/gir": "0.6.0"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"react": "^19"
|