@gtkx/react 0.1.17 → 0.1.19

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.
@@ -1,3 +1,4 @@
1
+ import "react";
1
2
  export const CONSTRUCTOR_PARAMS = {
2
3
  AppChooserButton: [{ name: "contentType", hasDefault: false }],
3
4
  AppChooserDialog: [
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { createRef } from "@gtkx/ffi";
2
2
  export * from "./generated/jsx.js";
3
3
  export { createPortal } from "./portal.js";
4
+ export { reconciler } from "./reconciler.js";
4
5
  export { render } from "./render.js";
5
6
  export declare const quit: () => boolean;
package/dist/index.js CHANGED
@@ -1,12 +1,13 @@
1
1
  export { createRef } from "@gtkx/ffi";
2
2
  export * from "./generated/jsx.js";
3
3
  export { createPortal } from "./portal.js";
4
+ export { reconciler } from "./reconciler.js";
4
5
  export { render } from "./render.js";
5
6
  import { stop } from "@gtkx/ffi";
6
7
  import { reconciler } from "./reconciler.js";
7
8
  import { container } from "./render.js";
8
9
  export const quit = () => {
9
- reconciler.updateContainer(null, container, null, () => {
10
+ reconciler.getInstance().updateContainer(null, container, null, () => {
10
11
  stop();
11
12
  });
12
13
  return true;
package/dist/node.d.ts CHANGED
@@ -5,8 +5,8 @@ export declare abstract class Node<T extends Gtk.Widget | undefined = Gtk.Widget
5
5
  protected signalHandlers: Map<string, number>;
6
6
  protected widget: T;
7
7
  protected isVirtual(): boolean;
8
- constructor(type: string, props: Props, currentApp?: unknown);
9
- protected createWidget(type: string, props: Props, currentApp?: unknown): T;
8
+ constructor(type: string, props: Props, app: Gtk.Application);
9
+ protected createWidget(type: string, props: Props, app: Gtk.Application): T;
10
10
  getWidget(): T;
11
11
  appendChild(child: Node): void;
12
12
  removeChild(child: Node): void;
@@ -18,6 +18,6 @@ export declare abstract class Node<T extends Gtk.Widget | undefined = Gtk.Widget
18
18
  protected setSignalProperty(widget: Gtk.Widget, key: string, handler: unknown): void;
19
19
  protected setSignalHandler(widget: Gtk.Widget, eventName: string, handler: (...args: unknown[]) => unknown): void;
20
20
  protected setProperty(widget: Gtk.Widget, key: string, value: unknown): void;
21
- mount(): void;
22
- dispose(): void;
21
+ mount(_app: Gtk.Application): void;
22
+ dispose(_app: Gtk.Application): void;
23
23
  }
package/dist/node.js CHANGED
@@ -8,7 +8,6 @@ const extractConstructorArgs = (type, props) => {
8
8
  return [];
9
9
  return params.map((p) => props[p.name]);
10
10
  };
11
- const normalizeType = (type) => (type.endsWith(".Root") ? type.slice(0, -5) : type);
12
11
  export class Node {
13
12
  static matches(_type) {
14
13
  return false;
@@ -18,21 +17,20 @@ export class Node {
18
17
  isVirtual() {
19
18
  return false;
20
19
  }
21
- constructor(type, props, currentApp) {
22
- this.widget = (this.isVirtual() ? undefined : this.createWidget(type, props, currentApp));
20
+ constructor(type, props, app) {
21
+ this.widget = (this.isVirtual() ? undefined : this.createWidget(type, props, app));
23
22
  this.updateProps({}, props);
24
23
  }
25
- createWidget(type, props, currentApp) {
26
- const normalizedType = normalizeType(type);
24
+ createWidget(type, props, app) {
25
+ const normalizedType = type.split(".")[0] || type;
27
26
  const WidgetClass = Gtk[normalizedType];
28
- if (!WidgetClass || typeof WidgetClass !== "function") {
27
+ if (!WidgetClass) {
29
28
  throw new Error(`Unknown GTK widget type: ${normalizedType}`);
30
29
  }
31
30
  if (normalizedType === "ApplicationWindow") {
32
- return new WidgetClass(currentApp);
31
+ return new WidgetClass(app);
33
32
  }
34
- const args = extractConstructorArgs(normalizedType, props);
35
- return new WidgetClass(...args);
33
+ return new WidgetClass(...extractConstructorArgs(normalizedType, props));
36
34
  }
37
35
  getWidget() {
38
36
  return this.widget;
@@ -121,6 +119,6 @@ export class Node {
121
119
  setter.call(widget, value);
122
120
  }
123
121
  }
124
- mount() { }
125
- dispose() { }
122
+ mount(_app) { }
123
+ dispose(_app) { }
126
124
  }
@@ -17,7 +17,7 @@ export declare class DropDownNode extends Node<Gtk.DropDown> {
17
17
  static matches(type: string): boolean;
18
18
  private store;
19
19
  private onSelectionChanged?;
20
- constructor(type: string, props: Props, currentApp?: unknown);
20
+ constructor(type: string, props: Props, app: Gtk.Application);
21
21
  getStore(): DropDownStore;
22
22
  protected consumedProps(): Set<string>;
23
23
  updateProps(oldProps: Props, newProps: Props): void;
@@ -26,7 +26,7 @@ export declare class DropDownItemNode extends Node<never> {
26
26
  static matches(type: string): boolean;
27
27
  protected isVirtual(): boolean;
28
28
  private item;
29
- constructor(type: string, props: Props, _currentApp?: unknown);
29
+ constructor(type: string, props: Props, app: Gtk.Application);
30
30
  getItem(): unknown;
31
31
  attachToParent(parent: Node): void;
32
32
  detachFromParent(parent: Node): void;
@@ -36,8 +36,8 @@ export class DropDownNode extends Node {
36
36
  }
37
37
  store;
38
38
  onSelectionChanged;
39
- constructor(type, props, currentApp) {
40
- super(type, props, currentApp);
39
+ constructor(type, props, app) {
40
+ super(type, props, app);
41
41
  const labelFn = props.itemLabel ?? ((item) => String(item));
42
42
  this.onSelectionChanged = props.onSelectionChanged;
43
43
  this.store = new DropDownStore(labelFn);
@@ -75,8 +75,8 @@ export class DropDownItemNode extends Node {
75
75
  return true;
76
76
  }
77
77
  item;
78
- constructor(type, props, _currentApp) {
79
- super(type, props);
78
+ constructor(type, props, app) {
79
+ super(type, props, app);
80
80
  this.item = props.item;
81
81
  }
82
82
  getItem() {
@@ -13,7 +13,7 @@ export declare class GridChildNode extends Node<never> {
13
13
  private rowSpan;
14
14
  private childWidget;
15
15
  private parentGrid;
16
- constructor(type: string, props: Props, _currentApp?: unknown);
16
+ constructor(type: string, props: Props, app: Gtk.Application);
17
17
  appendChild(child: Node): void;
18
18
  removeChild(child: Node): void;
19
19
  private attachChildToGrid;
@@ -17,8 +17,8 @@ export class GridChildNode extends Node {
17
17
  rowSpan;
18
18
  childWidget = null;
19
19
  parentGrid = null;
20
- constructor(type, props, _currentApp) {
21
- super(type, props);
20
+ constructor(type, props, app) {
21
+ super(type, props, app);
22
22
  this.column = props.column ?? 0;
23
23
  this.row = props.row ?? 0;
24
24
  this.columnSpan = props.columnSpan ?? 1;
@@ -9,18 +9,18 @@ export declare class ListViewNode extends Node<Gtk.ListView> {
9
9
  private items;
10
10
  private renderItem;
11
11
  private factorySignalHandlers;
12
- constructor(type: string, props: Props, currentApp?: unknown);
12
+ constructor(type: string, props: Props, app: Gtk.Application);
13
13
  addItem(item: unknown): void;
14
14
  removeItem(item: unknown): void;
15
15
  protected consumedProps(): Set<string>;
16
16
  updateProps(oldProps: Props, newProps: Props): void;
17
- dispose(): void;
17
+ dispose(app: Gtk.Application): void;
18
18
  }
19
19
  export declare class ListItemNode extends Node {
20
20
  static matches(type: string): boolean;
21
21
  protected isVirtual(): boolean;
22
22
  private item;
23
- constructor(type: string, props: Props, _currentApp?: unknown);
23
+ constructor(type: string, props: Props, app: Gtk.Application);
24
24
  getItem(): unknown;
25
25
  attachToParent(parent: Node): void;
26
26
  detachFromParent(parent: Node): void;
@@ -12,8 +12,8 @@ export class ListViewNode extends Node {
12
12
  items = [];
13
13
  renderItem = null;
14
14
  factorySignalHandlers = new Map();
15
- constructor(type, props, currentApp) {
16
- super(type, props, currentApp);
15
+ constructor(type, props, app) {
16
+ super(type, props, app);
17
17
  this.stringList = new Gtk.StringList([]);
18
18
  this.selectionModel = new Gtk.SingleSelection(this.stringList);
19
19
  this.factory = new Gtk.SignalListItemFactory();
@@ -61,8 +61,8 @@ export class ListViewNode extends Node {
61
61
  }
62
62
  super.updateProps(oldProps, newProps);
63
63
  }
64
- dispose() {
65
- super.dispose();
64
+ dispose(app) {
65
+ super.dispose(app);
66
66
  this.widget.setModel(undefined);
67
67
  this.widget.setFactory(undefined);
68
68
  }
@@ -80,8 +80,8 @@ export class ListItemNode extends Node {
80
80
  return true;
81
81
  }
82
82
  item;
83
- constructor(type, props, _currentApp) {
84
- super(type, props);
83
+ constructor(type, props, app) {
84
+ super(type, props, app);
85
85
  this.item = props.item;
86
86
  }
87
87
  getItem() {
@@ -1,3 +1,4 @@
1
+ import type * as Gtk from "@gtkx/ffi/gtk";
1
2
  import type { Props } from "../factory.js";
2
3
  import { Node } from "../node.js";
3
4
  export declare class SlotNode extends Node<never> {
@@ -5,7 +6,7 @@ export declare class SlotNode extends Node<never> {
5
6
  protected isVirtual(): boolean;
6
7
  private child;
7
8
  private slotName;
8
- constructor(type: string, props: Props, _currentApp?: unknown);
9
+ constructor(type: string, props: Props, app: Gtk.Application);
9
10
  appendChild(child: Node): void;
10
11
  removeChild(_child: Node): void;
11
12
  attachToParent(parent: Node): void;
@@ -14,8 +14,8 @@ export class SlotNode extends Node {
14
14
  }
15
15
  child = null;
16
16
  slotName;
17
- constructor(type, props, _currentApp) {
18
- super(type, props);
17
+ constructor(type, props, app) {
18
+ super(type, props, app);
19
19
  const dotIndex = type.indexOf(".");
20
20
  if (dotIndex === -1) {
21
21
  throw new Error(`Invalid slot type: ${type}`);
@@ -2,7 +2,7 @@ import * as Gtk from "@gtkx/ffi/gtk";
2
2
  import type { Props } from "../factory.js";
3
3
  import { Node } from "../node.js";
4
4
  export declare class WidgetWrapper extends Node<Gtk.Widget> {
5
- constructor(widget: Gtk.Widget);
5
+ constructor(widget: Gtk.Widget, app: Gtk.Application);
6
6
  protected isVirtual(): boolean;
7
7
  }
8
8
  export declare class WidgetNode extends Node<Gtk.Widget> {
@@ -11,6 +11,6 @@ export declare class WidgetNode extends Node<Gtk.Widget> {
11
11
  detachFromParent(parent: Node): void;
12
12
  protected consumedProps(): Set<string>;
13
13
  updateProps(oldProps: Props, newProps: Props): void;
14
- mount(): void;
15
- dispose(): void;
14
+ mount(app: Gtk.Application): void;
15
+ dispose(app: Gtk.Application): void;
16
16
  }
@@ -1,6 +1,5 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
2
  import { Node } from "../node.js";
3
- import { getCurrentApp } from "../reconciler.js";
4
3
  import { OverlayNode } from "./overlay.js";
5
4
  const COMBINED_PROPS = [
6
5
  {
@@ -15,8 +14,8 @@ const COMBINED_PROPS = [
15
14
  },
16
15
  ];
17
16
  export class WidgetWrapper extends Node {
18
- constructor(widget) {
19
- super("", {});
17
+ constructor(widget, app) {
18
+ super("", {}, app);
20
19
  this.widget = widget;
21
20
  }
22
21
  isVirtual() {
@@ -95,10 +94,9 @@ export class WidgetNode extends Node {
95
94
  }
96
95
  super.updateProps(oldProps, newProps);
97
96
  }
98
- mount() {
97
+ mount(app) {
99
98
  if (this.widget instanceof Gtk.AboutDialog) {
100
- const app = getCurrentApp();
101
- const activeWindow = app?.getActiveWindow();
99
+ const activeWindow = app.getActiveWindow();
102
100
  if (activeWindow) {
103
101
  this.widget.setTransientFor(activeWindow);
104
102
  }
@@ -107,8 +105,8 @@ export class WidgetNode extends Node {
107
105
  this.widget.present();
108
106
  }
109
107
  }
110
- dispose() {
111
- super.dispose();
108
+ dispose(app) {
109
+ super.dispose(app);
112
110
  if (this.widget instanceof Gtk.Window) {
113
111
  this.widget.close();
114
112
  }
package/dist/portal.d.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  import type { ReactNode, ReactPortal } from "react";
2
- export declare const ROOT_CONTAINER: unique symbol;
3
2
  export declare const createPortal: (children: ReactNode, container?: unknown, key?: string | null) => ReactPortal;
package/dist/portal.js CHANGED
@@ -1,10 +1,10 @@
1
- export const ROOT_CONTAINER = Symbol("ROOT_CONTAINER");
1
+ import * as Gtk from "@gtkx/ffi/gtk";
2
2
  export const createPortal = (children, container, key) => {
3
3
  return {
4
4
  $$typeof: Symbol.for("react.portal"),
5
5
  key: key ?? null,
6
6
  children,
7
- containerInfo: container ?? ROOT_CONTAINER,
7
+ containerInfo: container ?? Gtk.Application.getDefault(),
8
8
  implementation: null,
9
9
  };
10
10
  };
@@ -1,21 +1,22 @@
1
- import type * as Gtk from "@gtkx/ffi/gtk";
2
1
  import type { Application } from "@gtkx/ffi/gtk";
3
- import Reconciler from "react-reconciler";
2
+ import * as Gtk from "@gtkx/ffi/gtk";
3
+ import ReactReconciler from "react-reconciler";
4
4
  import type { Node } from "./node.js";
5
- import { ROOT_CONTAINER } from "./portal.js";
6
- type Container = Gtk.Widget | typeof ROOT_CONTAINER;
5
+ type Container = Gtk.Application | Gtk.Widget;
7
6
  type TextInstance = Node;
8
- export declare class GtkReconciler {
9
- private reconciler;
10
- private currentApp;
7
+ type SuspenseInstance = never;
8
+ type PublicInstance = Gtk.Widget;
9
+ type FormInstance = never;
10
+ type ReconcilerInstance = ReactReconciler.Reconciler<Container, Node, TextInstance, SuspenseInstance, FormInstance, PublicInstance>;
11
+ export declare class Reconciler {
12
+ private instance;
13
+ private app;
11
14
  constructor();
12
- setCurrentApp(app: Application): void;
13
- getCurrentApp(): Application | null;
14
- getReconciler(): typeof this.reconciler;
15
+ getApp(): Application;
16
+ setApp(app: Application): void;
17
+ getInstance(): ReconcilerInstance;
15
18
  private createHostConfig;
16
19
  private createReconcilerContext;
17
20
  }
18
- export declare const reconciler: Reconciler.Reconciler<Container, Node<Gtk.Widget | undefined>, TextInstance, never, never, Gtk.Widget>;
19
- export declare const setCurrentApp: (app: Application) => void;
20
- export declare const getCurrentApp: () => Application | null;
21
+ export declare const reconciler: Reconciler;
21
22
  export {};
@@ -1,22 +1,25 @@
1
+ import * as Gtk from "@gtkx/ffi/gtk";
1
2
  import React from "react";
2
- import Reconciler from "react-reconciler";
3
+ import ReactReconciler from "react-reconciler";
3
4
  import { createNode } from "./factory.js";
4
5
  import { WidgetWrapper } from "./nodes/widget.js";
5
- import { ROOT_CONTAINER } from "./portal.js";
6
- export class GtkReconciler {
7
- reconciler;
8
- currentApp = null;
6
+ export class Reconciler {
7
+ instance;
8
+ app = null;
9
9
  constructor() {
10
- this.reconciler = Reconciler(this.createHostConfig());
10
+ this.instance = ReactReconciler(this.createHostConfig());
11
11
  }
12
- setCurrentApp(app) {
13
- this.currentApp = app;
12
+ getApp() {
13
+ if (!this.app) {
14
+ throw new Error("Tried to get GTK Application before it was set.");
15
+ }
16
+ return this.app;
14
17
  }
15
- getCurrentApp() {
16
- return this.currentApp;
18
+ setApp(app) {
19
+ this.app = app;
17
20
  }
18
- getReconciler() {
19
- return this.reconciler;
21
+ getInstance() {
22
+ return this.instance;
20
23
  }
21
24
  createHostConfig() {
22
25
  return {
@@ -28,30 +31,33 @@ export class GtkReconciler {
28
31
  getRootHostContext: () => ({}),
29
32
  getChildHostContext: (parentHostContext) => parentHostContext,
30
33
  shouldSetTextContent: () => false,
31
- createInstance: (type, props) => createNode(type, props, this.currentApp),
32
- createTextInstance: (text) => createNode("Label.Root", { label: text }, this.currentApp),
34
+ createInstance: (type, props) => createNode(type, props, this.getApp()),
35
+ createTextInstance: (text) => createNode("Label.Root", { label: text }, this.getApp()),
33
36
  appendInitialChild: (parent, child) => parent.appendChild(child),
34
37
  finalizeInitialChildren: () => true,
35
38
  commitUpdate: (instance, _type, oldProps, newProps) => {
36
39
  instance.updateProps(oldProps, newProps);
37
40
  },
38
41
  commitMount: (instance) => {
39
- instance.mount();
42
+ instance.mount(this.getApp());
40
43
  },
41
44
  appendChild: (parent, child) => parent.appendChild(child),
42
45
  removeChild: (parent, child) => parent.removeChild(child),
43
46
  insertBefore: (parent, child, beforeChild) => parent.insertBefore(child, beforeChild),
44
47
  removeChildFromContainer: (container, child) => {
45
- if (container !== ROOT_CONTAINER)
46
- child.detachFromParent(new WidgetWrapper(container));
48
+ if (container instanceof Gtk.Widget) {
49
+ child.detachFromParent(new WidgetWrapper(container, this.getApp()));
50
+ }
47
51
  },
48
52
  appendChildToContainer: (container, child) => {
49
- if (container !== ROOT_CONTAINER)
50
- child.attachToParent(new WidgetWrapper(container));
53
+ if (container instanceof Gtk.Widget) {
54
+ child.attachToParent(new WidgetWrapper(container, this.getApp()));
55
+ }
51
56
  },
52
57
  insertInContainerBefore: (container, child, _beforeChild) => {
53
- if (container !== ROOT_CONTAINER)
54
- child.attachToParent(new WidgetWrapper(container));
58
+ if (container instanceof Gtk.Widget) {
59
+ child.attachToParent(new WidgetWrapper(container, this.getApp()));
60
+ }
55
61
  },
56
62
  prepareForCommit: () => null,
57
63
  resetAfterCommit: () => { },
@@ -79,7 +85,7 @@ export class GtkReconciler {
79
85
  prepareScopeUpdate: () => { },
80
86
  getInstanceFromScope: () => null,
81
87
  detachDeletedInstance: (instance) => {
82
- instance.dispose();
88
+ instance.dispose(this.getApp());
83
89
  },
84
90
  resetFormInstance: () => { },
85
91
  requestPostPaintCallback: () => { },
@@ -99,7 +105,4 @@ export class GtkReconciler {
99
105
  return context;
100
106
  }
101
107
  }
102
- const gtkReconciler = new GtkReconciler();
103
- export const reconciler = gtkReconciler.getReconciler();
104
- export const setCurrentApp = (app) => gtkReconciler.setCurrentApp(app);
105
- export const getCurrentApp = () => gtkReconciler.getCurrentApp();
108
+ export const reconciler = new Reconciler();
package/dist/render.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import { start } from "@gtkx/ffi";
2
- import { ROOT_CONTAINER } from "./portal.js";
3
- import { reconciler, setCurrentApp } from "./reconciler.js";
2
+ import { reconciler } from "./reconciler.js";
4
3
  export let container = null;
5
4
  export const render = (element, appId, flags) => {
6
5
  const app = start(appId, flags);
7
- setCurrentApp(app);
8
- container = reconciler.createContainer(ROOT_CONTAINER, 0, null, false, false, "", (error, info) => {
9
- console.error("React reconciler error:", error, info);
10
- }, null, null, null, null);
11
- reconciler.updateContainer(element, container, null, () => { });
6
+ const instance = reconciler.getInstance();
7
+ reconciler.setApp(app);
8
+ container = instance.createContainer(app, 0, null, false, null, "", (error, info) => {
9
+ console.error("Uncaught error in GTKX application:", error, info);
10
+ }, (_error, _info) => { }, (_error, _info) => { }, () => { }, null);
11
+ instance.updateContainer(element, container, null, () => { });
12
12
  return app;
13
13
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gtkx/react",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "description": "Build GTK4 desktop applications with React and TypeScript",
5
5
  "keywords": [
6
6
  "gtk",
@@ -28,7 +28,10 @@
28
28
  "./package.json": "./package.json",
29
29
  ".": {
30
30
  "types": "./dist/index.d.ts",
31
- "development": "./src/index.ts",
31
+ "development": {
32
+ "types": "./src/index.ts",
33
+ "default": "./src/index.ts"
34
+ },
32
35
  "default": "./dist/index.js"
33
36
  }
34
37
  },
@@ -37,13 +40,13 @@
37
40
  ],
38
41
  "dependencies": {
39
42
  "react-reconciler": "0.33.0",
40
- "@gtkx/ffi": "0.1.17"
43
+ "@gtkx/ffi": "0.1.19"
41
44
  },
42
45
  "devDependencies": {
43
- "@gtkx/gir": "0.1.17"
46
+ "@gtkx/gir": "0.1.19"
44
47
  },
45
48
  "peerDependencies": {
46
- "react": "19"
49
+ "react": "^19"
47
50
  },
48
51
  "scripts": {
49
52
  "build": "tsc -b",