@gtkx/react 0.9.4 → 0.10.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 +55 -67
- package/dist/errors.d.ts +3 -3
- package/dist/errors.js +8 -8
- package/dist/factory.d.ts +3 -5
- package/dist/factory.js +18 -71
- package/dist/fiber-root.d.ts +1 -1
- package/dist/fiber-root.js +1 -2
- package/dist/generated/internal.d.ts +3 -6
- package/dist/generated/internal.js +10386 -13577
- package/dist/generated/jsx.d.ts +914 -808
- package/dist/generated/jsx.js +123 -358
- package/dist/generated/registry.d.ts +4 -0
- package/dist/generated/registry.js +13 -0
- package/dist/host-config.d.ts +7 -4
- package/dist/host-config.js +53 -18
- package/dist/index.d.ts +2 -22
- package/dist/index.js +2 -40
- package/dist/jsx.d.ts +719 -0
- package/dist/jsx.js +392 -0
- package/dist/node.d.ts +15 -32
- package/dist/node.js +20 -240
- package/dist/nodes/action-row-child.d.ts +21 -0
- package/dist/nodes/action-row-child.js +69 -0
- package/dist/nodes/action-row.js +33 -0
- package/dist/nodes/application.d.ts +1 -0
- package/dist/nodes/application.js +38 -0
- package/dist/nodes/autowrapped.d.ts +1 -0
- package/dist/nodes/autowrapped.js +109 -0
- package/dist/nodes/column-view-column.d.ts +16 -0
- package/dist/nodes/column-view-column.js +54 -0
- package/dist/nodes/column-view.d.ts +0 -59
- package/dist/nodes/column-view.js +107 -226
- package/dist/nodes/fixed-child.d.ts +1 -0
- package/dist/nodes/fixed-child.js +45 -0
- package/dist/nodes/grid-child.d.ts +1 -0
- package/dist/nodes/grid-child.js +54 -0
- package/dist/nodes/index.d.ts +34 -0
- package/dist/nodes/index.js +34 -0
- package/dist/nodes/internal/list-item-renderer.d.ts +18 -0
- package/dist/nodes/internal/list-item-renderer.js +67 -0
- package/dist/nodes/internal/list-store.d.ts +16 -0
- package/dist/nodes/internal/list-store.js +69 -0
- package/dist/nodes/internal/predicates.d.ts +26 -0
- package/dist/nodes/internal/predicates.js +36 -0
- package/dist/nodes/internal/signal-store.d.ts +9 -0
- package/dist/nodes/internal/signal-store.js +54 -0
- package/dist/nodes/internal/simple-list-store.d.ts +14 -0
- package/dist/nodes/internal/simple-list-store.js +60 -0
- package/dist/nodes/internal/tree-list-item-renderer.d.ts +18 -0
- package/dist/nodes/internal/tree-list-item-renderer.js +90 -0
- package/dist/nodes/internal/tree-store.d.ts +28 -0
- package/dist/nodes/internal/tree-store.js +153 -0
- package/dist/nodes/internal/utils.d.ts +3 -0
- package/dist/nodes/internal/utils.js +20 -0
- package/dist/nodes/list-item.d.ts +12 -0
- package/dist/nodes/list-item.js +24 -0
- package/dist/nodes/list-view.d.ts +0 -22
- package/dist/nodes/list-view.js +45 -38
- package/dist/nodes/menu.d.ts +6 -106
- package/dist/nodes/menu.js +16 -268
- package/dist/nodes/models/list.d.ts +24 -0
- package/dist/nodes/models/list.js +102 -0
- package/dist/nodes/models/menu.d.ts +45 -0
- package/dist/nodes/models/menu.js +265 -0
- package/dist/nodes/models/tree-list.d.ts +28 -0
- package/dist/nodes/models/tree-list.js +141 -0
- package/dist/nodes/navigation-page.d.ts +21 -0
- package/dist/nodes/navigation-page.js +95 -0
- package/dist/nodes/navigation-view.d.ts +1 -0
- package/dist/nodes/navigation-view.js +29 -0
- package/dist/nodes/notebook-page-tab.d.ts +15 -0
- package/dist/nodes/notebook-page-tab.js +42 -0
- package/dist/nodes/notebook-page.d.ts +23 -0
- package/dist/nodes/notebook-page.js +106 -0
- package/dist/nodes/notebook.d.ts +0 -32
- package/dist/nodes/notebook.js +20 -113
- package/dist/nodes/overlay-child.d.ts +1 -0
- package/dist/nodes/overlay-child.js +30 -0
- package/dist/nodes/pack-child.d.ts +21 -0
- package/dist/nodes/pack-child.js +68 -0
- package/dist/nodes/pack.d.ts +1 -0
- package/dist/nodes/pack.js +33 -0
- package/dist/nodes/popover-menu.d.ts +1 -0
- package/dist/nodes/popover-menu.js +58 -0
- package/dist/nodes/simple-list-item.d.ts +9 -0
- package/dist/nodes/simple-list-item.js +9 -0
- package/dist/nodes/simple-list-view.d.ts +1 -0
- package/dist/nodes/simple-list-view.js +75 -0
- package/dist/nodes/slot.d.ts +18 -10
- package/dist/nodes/slot.js +83 -51
- package/dist/nodes/stack-page.d.ts +1 -0
- package/dist/nodes/stack-page.js +80 -0
- package/dist/nodes/stack.d.ts +1 -22
- package/dist/nodes/stack.js +21 -60
- package/dist/nodes/toast-overlay.d.ts +1 -0
- package/dist/nodes/toast-overlay.js +35 -0
- package/dist/nodes/toast.d.ts +17 -0
- package/dist/nodes/toast.js +77 -0
- package/dist/nodes/toolbar-child.d.ts +9 -0
- package/dist/nodes/toolbar-child.js +33 -0
- package/dist/nodes/toolbar.d.ts +1 -0
- package/dist/nodes/toolbar.js +42 -0
- package/dist/nodes/tree-list-item.d.ts +20 -0
- package/dist/nodes/tree-list-item.js +102 -0
- package/dist/nodes/tree-list-view.d.ts +1 -0
- package/dist/nodes/tree-list-view.js +57 -0
- package/dist/nodes/virtual.d.ts +13 -0
- package/dist/nodes/virtual.js +21 -0
- package/dist/nodes/widget.d.ts +17 -3
- package/dist/nodes/widget.js +258 -2
- package/dist/nodes/window.d.ts +1 -12
- package/dist/nodes/window.js +66 -27
- package/dist/portal.d.ts +18 -13
- package/dist/portal.js +17 -14
- package/dist/reconciler.d.ts +0 -4
- package/dist/reconciler.js +1 -9
- package/dist/registry.d.ts +8 -0
- package/dist/registry.js +5 -0
- package/dist/render.d.ts +108 -12
- package/dist/render.js +140 -16
- package/dist/scheduler.d.ts +4 -0
- package/dist/scheduler.js +10 -0
- package/dist/types.d.ts +3 -136
- package/package.json +6 -6
- package/dist/batch.d.ts +0 -5
- package/dist/batch.js +0 -31
- package/dist/codegen/jsx-generator.d.ts +0 -56
- package/dist/codegen/jsx-generator.js +0 -959
- package/dist/containers.d.ts +0 -58
- package/dist/nodes/about-dialog.d.ts +0 -8
- package/dist/nodes/about-dialog.js +0 -16
- package/dist/nodes/action-bar.d.ts +0 -5
- package/dist/nodes/action-bar.js +0 -6
- package/dist/nodes/combo-row.d.ts +0 -5
- package/dist/nodes/combo-row.js +0 -6
- package/dist/nodes/drop-down.d.ts +0 -9
- package/dist/nodes/drop-down.js +0 -12
- package/dist/nodes/flow-box.d.ts +0 -10
- package/dist/nodes/flow-box.js +0 -41
- package/dist/nodes/grid.d.ts +0 -30
- package/dist/nodes/grid.js +0 -84
- package/dist/nodes/header-bar.d.ts +0 -43
- package/dist/nodes/header-bar.js +0 -116
- package/dist/nodes/indexed-child-container.d.ts +0 -16
- package/dist/nodes/indexed-child-container.js +0 -22
- package/dist/nodes/list-box.d.ts +0 -10
- package/dist/nodes/list-box.js +0 -48
- package/dist/nodes/list-item-factory.d.ts +0 -19
- package/dist/nodes/list-item-factory.js +0 -58
- package/dist/nodes/overlay.d.ts +0 -11
- package/dist/nodes/overlay.js +0 -50
- package/dist/nodes/paged-stack.d.ts +0 -31
- package/dist/nodes/paged-stack.js +0 -95
- package/dist/nodes/root.d.ts +0 -8
- package/dist/nodes/root.js +0 -13
- package/dist/nodes/selectable-list.d.ts +0 -45
- package/dist/nodes/selectable-list.js +0 -260
- package/dist/nodes/stack-page-props.d.ts +0 -11
- package/dist/nodes/stack-page-props.js +0 -23
- package/dist/nodes/string-list-container.d.ts +0 -34
- package/dist/nodes/string-list-container.js +0 -118
- package/dist/nodes/string-list-item.d.ts +0 -19
- package/dist/nodes/string-list-item.js +0 -50
- package/dist/nodes/string-list-store.d.ts +0 -13
- package/dist/nodes/string-list-store.js +0 -44
- package/dist/nodes/text-view.d.ts +0 -8
- package/dist/nodes/text-view.js +0 -16
- package/dist/nodes/toggle-button.d.ts +0 -14
- package/dist/nodes/toggle-button.js +0 -39
- package/dist/nodes/toolbar-view.d.ts +0 -14
- package/dist/nodes/toolbar-view.js +0 -78
- package/dist/nodes/view-stack.d.ts +0 -9
- package/dist/nodes/view-stack.js +0 -28
- package/dist/nodes/virtual-item.d.ts +0 -19
- package/dist/nodes/virtual-item.js +0 -48
- package/dist/nodes/virtual-slot.d.ts +0 -25
- package/dist/nodes/virtual-slot.js +0 -57
- package/dist/predicates.d.ts +0 -29
- package/dist/predicates.js +0 -37
- package/dist/props.d.ts +0 -7
- package/dist/props.js +0 -12
- /package/dist/{containers.js → nodes/action-row.d.ts} +0 -0
package/dist/portal.js
CHANGED
|
@@ -1,23 +1,26 @@
|
|
|
1
|
-
import { ROOT_NODE_CONTAINER } from "./factory.js";
|
|
2
1
|
/**
|
|
3
|
-
* Creates a portal
|
|
2
|
+
* Creates a React portal for rendering children into a different part of the widget tree.
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Portals are useful for rendering dialogs, tooltips, or other floating content
|
|
5
|
+
* that should visually appear outside its parent component's boundaries.
|
|
7
6
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* the internal representation required by custom reconcilers.
|
|
7
|
+
* @param children - The React elements to render in the portal
|
|
8
|
+
* @param container - The target container widget to render into
|
|
9
|
+
* @param key - Optional key for the portal element
|
|
10
|
+
* @returns A ReactPortal element
|
|
13
11
|
*
|
|
14
12
|
* @example
|
|
15
13
|
* ```tsx
|
|
16
|
-
*
|
|
17
|
-
* {createPortal(<AboutDialog programName="My App" />)}
|
|
14
|
+
* import { createPortal } from "@gtkx/react";
|
|
18
15
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
16
|
+
* const Modal = ({ container, children }) => {
|
|
17
|
+
* return createPortal(
|
|
18
|
+
* <GtkWindow modal>
|
|
19
|
+
* {children}
|
|
20
|
+
* </GtkWindow>,
|
|
21
|
+
* container
|
|
22
|
+
* );
|
|
23
|
+
* };
|
|
21
24
|
* ```
|
|
22
25
|
*/
|
|
23
26
|
export const createPortal = (children, container, key) => {
|
|
@@ -25,7 +28,7 @@ export const createPortal = (children, container, key) => {
|
|
|
25
28
|
$$typeof: Symbol.for("react.portal"),
|
|
26
29
|
key: key ?? null,
|
|
27
30
|
children,
|
|
28
|
-
containerInfo: container
|
|
31
|
+
containerInfo: container,
|
|
29
32
|
implementation: null,
|
|
30
33
|
};
|
|
31
34
|
};
|
package/dist/reconciler.d.ts
CHANGED
|
@@ -5,9 +5,5 @@ declare class Reconciler {
|
|
|
5
5
|
getInstance(): ReconcilerInstance;
|
|
6
6
|
private injectDevTools;
|
|
7
7
|
}
|
|
8
|
-
/**
|
|
9
|
-
* The singleton GTKX React reconciler instance.
|
|
10
|
-
* @private This is an internal API used only by @gtkx/testing. Do not use directly.
|
|
11
|
-
*/
|
|
12
8
|
export declare const reconciler: Reconciler;
|
|
13
9
|
export {};
|
package/dist/reconciler.js
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
import ReactReconciler from "react-reconciler";
|
|
2
2
|
import packageJson from "../package.json" with { type: "json" };
|
|
3
|
-
import { createNode } from "./factory.js";
|
|
4
3
|
import { createHostConfig } from "./host-config.js";
|
|
5
4
|
class Reconciler {
|
|
6
5
|
instance;
|
|
7
6
|
constructor() {
|
|
8
|
-
|
|
9
|
-
return createNode(container.constructor.name, {}, container);
|
|
10
|
-
};
|
|
11
|
-
this.instance = ReactReconciler(createHostConfig(createNodeFromContainer));
|
|
7
|
+
this.instance = ReactReconciler(createHostConfig());
|
|
12
8
|
this.injectDevTools();
|
|
13
9
|
}
|
|
14
10
|
getInstance() {
|
|
@@ -24,8 +20,4 @@ class Reconciler {
|
|
|
24
20
|
});
|
|
25
21
|
}
|
|
26
22
|
}
|
|
27
|
-
/**
|
|
28
|
-
* The singleton GTKX React reconciler instance.
|
|
29
|
-
* @private This is an internal API used only by @gtkx/testing. Do not use directly.
|
|
30
|
-
*/
|
|
31
23
|
export const reconciler = new Reconciler();
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Node } from "./node.js";
|
|
2
|
+
import type { Container, Props } from "./types.js";
|
|
3
|
+
type NodeClass<T = unknown, P = Props> = {
|
|
4
|
+
new (typeName: string, props: P, container: T, rootContainer?: Container): Node<T, P>;
|
|
5
|
+
} & Omit<typeof Node, "prototype">;
|
|
6
|
+
export declare const NODE_CLASSES: NodeClass[];
|
|
7
|
+
export declare const registerNodeClass: <T, P>(nodeClass: NodeClass<T, P>) => void;
|
|
8
|
+
export {};
|
package/dist/registry.js
ADDED
package/dist/render.d.ts
CHANGED
|
@@ -1,22 +1,118 @@
|
|
|
1
1
|
import type * as Gio from "@gtkx/ffi/gio";
|
|
2
|
-
import type
|
|
3
|
-
|
|
2
|
+
import type * as Gtk from "@gtkx/ffi/gtk";
|
|
3
|
+
import { type ReactNode } from "react";
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* React Context providing access to the GTK Application instance.
|
|
6
|
+
*
|
|
7
|
+
* Use {@link useApplication} to access the application in components.
|
|
7
8
|
*
|
|
8
9
|
* @example
|
|
9
10
|
* ```tsx
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
11
|
+
* const App = () => {
|
|
12
|
+
* const app = useApplication();
|
|
13
|
+
* console.log(app.applicationId);
|
|
14
|
+
* return <GtkLabel label="Hello" />;
|
|
15
|
+
* };
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare const ApplicationContext: React.Context<Gtk.Application | null>;
|
|
19
|
+
/**
|
|
20
|
+
* Hook to access the GTK Application instance.
|
|
21
|
+
*
|
|
22
|
+
* Must be called within a component rendered by {@link render}.
|
|
23
|
+
* Throws an error if called outside the application context.
|
|
24
|
+
*
|
|
25
|
+
* @returns The GTK Application instance
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```tsx
|
|
29
|
+
* const MyComponent = () => {
|
|
30
|
+
* const app = useApplication();
|
|
31
|
+
* return <GtkLabel label={app.applicationId} />;
|
|
32
|
+
* };
|
|
16
33
|
* ```
|
|
17
34
|
*
|
|
35
|
+
* @see {@link ApplicationContext} for the underlying context
|
|
36
|
+
*/
|
|
37
|
+
export declare const useApplication: () => Gtk.Application;
|
|
38
|
+
/**
|
|
39
|
+
* Sets the hot reloading state.
|
|
40
|
+
*
|
|
41
|
+
* Used internally by the dev server to prevent quit() from closing
|
|
42
|
+
* the application during HMR updates.
|
|
43
|
+
*
|
|
44
|
+
* @internal
|
|
45
|
+
*/
|
|
46
|
+
export declare const setHotReloading: (value: boolean) => void;
|
|
47
|
+
/**
|
|
48
|
+
* Renders a React element tree into a GTK4 application window.
|
|
49
|
+
*
|
|
50
|
+
* This is the main entry point for GTKX applications. It initializes the GTK4
|
|
51
|
+
* runtime, creates an application container, and begins the React reconciliation
|
|
52
|
+
* process.
|
|
53
|
+
*
|
|
18
54
|
* @param element - The root React element to render
|
|
19
|
-
* @param appId -
|
|
20
|
-
* @param flags - Optional GIO application flags
|
|
55
|
+
* @param appId - Application ID in reverse domain notation (e.g., "com.example.myapp")
|
|
56
|
+
* @param flags - Optional GIO application flags for customizing behavior
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```tsx
|
|
60
|
+
* import { render, quit } from "@gtkx/react";
|
|
61
|
+
*
|
|
62
|
+
* const App = () => (
|
|
63
|
+
* <GtkApplicationWindow title="My App" onCloseRequest={quit}>
|
|
64
|
+
* <GtkLabel label="Hello, GTKX!" />
|
|
65
|
+
* </GtkApplicationWindow>
|
|
66
|
+
* );
|
|
67
|
+
*
|
|
68
|
+
* render(<App />, "com.example.myapp");
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @see {@link quit} for shutting down the application
|
|
72
|
+
* @see {@link update} for hot-reloading the rendered tree
|
|
21
73
|
*/
|
|
22
74
|
export declare const render: (element: ReactNode, appId: string, flags?: Gio.ApplicationFlags) => void;
|
|
75
|
+
/**
|
|
76
|
+
* Updates the rendered React element tree.
|
|
77
|
+
*
|
|
78
|
+
* Used primarily for hot module replacement (HMR) during development.
|
|
79
|
+
* Replaces the current component tree with a new element without
|
|
80
|
+
* reinitializing the GTK application.
|
|
81
|
+
*
|
|
82
|
+
* @param element - The new root React element to render
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```tsx
|
|
86
|
+
* // In HMR handler
|
|
87
|
+
* if (import.meta.hot) {
|
|
88
|
+
* import.meta.hot.accept(() => {
|
|
89
|
+
* update(<App />);
|
|
90
|
+
* });
|
|
91
|
+
* }
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* @see {@link render} for initial rendering
|
|
95
|
+
*/
|
|
96
|
+
export declare const update: (element: ReactNode) => Promise<void>;
|
|
97
|
+
/**
|
|
98
|
+
* Gracefully shuts down the GTK application.
|
|
99
|
+
*
|
|
100
|
+
* Unmounts the React component tree and stops the GTK main loop.
|
|
101
|
+
* Typically used as the `onCloseRequest` handler for the application window.
|
|
102
|
+
*
|
|
103
|
+
* @returns `false` to allow GTK to close the window
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```tsx
|
|
107
|
+
* import { quit } from "@gtkx/react";
|
|
108
|
+
*
|
|
109
|
+
* const App = () => (
|
|
110
|
+
* <GtkApplicationWindow title="My App" onCloseRequest={quit}>
|
|
111
|
+
* <GtkButton label="Quit" onClicked={quit} />
|
|
112
|
+
* </GtkApplicationWindow>
|
|
113
|
+
* );
|
|
114
|
+
* ```
|
|
115
|
+
*
|
|
116
|
+
* @see {@link render} for starting the application
|
|
117
|
+
*/
|
|
118
|
+
export declare const quit: () => boolean;
|
package/dist/render.js
CHANGED
|
@@ -1,35 +1,159 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { discardAllBatches, start, stop } from "@gtkx/ffi";
|
|
3
|
+
import { createContext, useContext } from "react";
|
|
2
4
|
import { formatBoundaryError, formatRenderError } from "./errors.js";
|
|
3
|
-
import { ROOT_NODE_CONTAINER } from "./factory.js";
|
|
4
5
|
import { reconciler } from "./reconciler.js";
|
|
6
|
+
/**
|
|
7
|
+
* React Context providing access to the GTK Application instance.
|
|
8
|
+
*
|
|
9
|
+
* Use {@link useApplication} to access the application in components.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* const App = () => {
|
|
14
|
+
* const app = useApplication();
|
|
15
|
+
* console.log(app.applicationId);
|
|
16
|
+
* return <GtkLabel label="Hello" />;
|
|
17
|
+
* };
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export const ApplicationContext = createContext(null);
|
|
21
|
+
/**
|
|
22
|
+
* Hook to access the GTK Application instance.
|
|
23
|
+
*
|
|
24
|
+
* Must be called within a component rendered by {@link render}.
|
|
25
|
+
* Throws an error if called outside the application context.
|
|
26
|
+
*
|
|
27
|
+
* @returns The GTK Application instance
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* const MyComponent = () => {
|
|
32
|
+
* const app = useApplication();
|
|
33
|
+
* return <GtkLabel label={app.applicationId} />;
|
|
34
|
+
* };
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @see {@link ApplicationContext} for the underlying context
|
|
38
|
+
*/
|
|
39
|
+
export const useApplication = () => {
|
|
40
|
+
const context = useContext(ApplicationContext);
|
|
41
|
+
if (!context) {
|
|
42
|
+
throw new Error("Expected ApplicationContext: useApplication must be called within Application");
|
|
43
|
+
}
|
|
44
|
+
return context;
|
|
45
|
+
};
|
|
5
46
|
let container = null;
|
|
6
|
-
|
|
47
|
+
let app = null;
|
|
48
|
+
let isHotReloading = false;
|
|
49
|
+
/**
|
|
50
|
+
* Sets the hot reloading state.
|
|
51
|
+
*
|
|
52
|
+
* Used internally by the dev server to prevent quit() from closing
|
|
53
|
+
* the application during HMR updates.
|
|
54
|
+
*
|
|
55
|
+
* @internal
|
|
56
|
+
*/
|
|
57
|
+
export const setHotReloading = (value) => {
|
|
58
|
+
isHotReloading = value;
|
|
59
|
+
};
|
|
7
60
|
/**
|
|
8
|
-
* Renders a React element tree
|
|
9
|
-
*
|
|
61
|
+
* Renders a React element tree into a GTK4 application window.
|
|
62
|
+
*
|
|
63
|
+
* This is the main entry point for GTKX applications. It initializes the GTK4
|
|
64
|
+
* runtime, creates an application container, and begins the React reconciliation
|
|
65
|
+
* process.
|
|
66
|
+
*
|
|
67
|
+
* @param element - The root React element to render
|
|
68
|
+
* @param appId - Application ID in reverse domain notation (e.g., "com.example.myapp")
|
|
69
|
+
* @param flags - Optional GIO application flags for customizing behavior
|
|
10
70
|
*
|
|
11
71
|
* @example
|
|
12
72
|
* ```tsx
|
|
13
|
-
* render
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
73
|
+
* import { render, quit } from "@gtkx/react";
|
|
74
|
+
*
|
|
75
|
+
* const App = () => (
|
|
76
|
+
* <GtkApplicationWindow title="My App" onCloseRequest={quit}>
|
|
77
|
+
* <GtkLabel label="Hello, GTKX!" />
|
|
78
|
+
* </GtkApplicationWindow>
|
|
18
79
|
* );
|
|
80
|
+
*
|
|
81
|
+
* render(<App />, "com.example.myapp");
|
|
19
82
|
* ```
|
|
20
83
|
*
|
|
21
|
-
* @
|
|
22
|
-
* @
|
|
23
|
-
* @param flags - Optional GIO application flags
|
|
84
|
+
* @see {@link quit} for shutting down the application
|
|
85
|
+
* @see {@link update} for hot-reloading the rendered tree
|
|
24
86
|
*/
|
|
25
87
|
export const render = (element, appId, flags) => {
|
|
26
|
-
start(appId, flags);
|
|
88
|
+
app = start(appId, flags);
|
|
27
89
|
const instance = reconciler.getInstance();
|
|
28
|
-
container = instance.createContainer(
|
|
90
|
+
container = instance.createContainer(app, 0, null, false, null, "", (error) => {
|
|
91
|
+
discardAllBatches();
|
|
29
92
|
throw formatRenderError(error);
|
|
30
93
|
}, (error) => {
|
|
94
|
+
discardAllBatches();
|
|
31
95
|
const formattedError = formatBoundaryError(error);
|
|
32
96
|
console.error(formattedError.toString());
|
|
33
97
|
}, () => { }, () => { }, null);
|
|
34
|
-
instance.updateContainer(element, container, null, () => { });
|
|
98
|
+
instance.updateContainer(_jsx(ApplicationContext.Provider, { value: app, children: element }), container, null, () => { });
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Updates the rendered React element tree.
|
|
102
|
+
*
|
|
103
|
+
* Used primarily for hot module replacement (HMR) during development.
|
|
104
|
+
* Replaces the current component tree with a new element without
|
|
105
|
+
* reinitializing the GTK application.
|
|
106
|
+
*
|
|
107
|
+
* @param element - The new root React element to render
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```tsx
|
|
111
|
+
* // In HMR handler
|
|
112
|
+
* if (import.meta.hot) {
|
|
113
|
+
* import.meta.hot.accept(() => {
|
|
114
|
+
* update(<App />);
|
|
115
|
+
* });
|
|
116
|
+
* }
|
|
117
|
+
* ```
|
|
118
|
+
*
|
|
119
|
+
* @see {@link render} for initial rendering
|
|
120
|
+
*/
|
|
121
|
+
export const update = (element) => {
|
|
122
|
+
return new Promise((resolve) => {
|
|
123
|
+
reconciler
|
|
124
|
+
.getInstance()
|
|
125
|
+
.updateContainer(_jsx(ApplicationContext.Provider, { value: app, children: element }), container, null, resolve);
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* Gracefully shuts down the GTK application.
|
|
130
|
+
*
|
|
131
|
+
* Unmounts the React component tree and stops the GTK main loop.
|
|
132
|
+
* Typically used as the `onCloseRequest` handler for the application window.
|
|
133
|
+
*
|
|
134
|
+
* @returns `false` to allow GTK to close the window
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```tsx
|
|
138
|
+
* import { quit } from "@gtkx/react";
|
|
139
|
+
*
|
|
140
|
+
* const App = () => (
|
|
141
|
+
* <GtkApplicationWindow title="My App" onCloseRequest={quit}>
|
|
142
|
+
* <GtkButton label="Quit" onClicked={quit} />
|
|
143
|
+
* </GtkApplicationWindow>
|
|
144
|
+
* );
|
|
145
|
+
* ```
|
|
146
|
+
*
|
|
147
|
+
* @see {@link render} for starting the application
|
|
148
|
+
*/
|
|
149
|
+
export const quit = () => {
|
|
150
|
+
if (isHotReloading) {
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
reconciler.getInstance().updateContainer(null, container, null, () => {
|
|
154
|
+
setTimeout(() => {
|
|
155
|
+
stop();
|
|
156
|
+
}, 0);
|
|
157
|
+
});
|
|
158
|
+
return true;
|
|
35
159
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const pendingCallbacks = [];
|
|
2
|
+
export const scheduleAfterCommit = (callback) => {
|
|
3
|
+
pendingCallbacks.push(callback);
|
|
4
|
+
};
|
|
5
|
+
export const flushAfterCommit = () => {
|
|
6
|
+
const callbacks = pendingCallbacks.splice(0);
|
|
7
|
+
for (const callback of callbacks) {
|
|
8
|
+
callback();
|
|
9
|
+
}
|
|
10
|
+
};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,137 +1,4 @@
|
|
|
1
1
|
import type * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* Used by container widgets that render child elements in designated slots.
|
|
6
|
-
*/
|
|
7
|
-
export type SlotProps = {
|
|
8
|
-
children?: ReactNode;
|
|
9
|
-
};
|
|
10
|
-
/**
|
|
11
|
-
* Props passed to list item components (ListView, GridView, ColumnView).
|
|
12
|
-
* @typeParam I - The type of the data item
|
|
13
|
-
*/
|
|
14
|
-
export type ListItemProps<I = unknown> = {
|
|
15
|
-
/** Unique identifier for this item. Used for selection. */
|
|
16
|
-
id: string;
|
|
17
|
-
/** The data item to render. */
|
|
18
|
-
item: I;
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* Props for string list items (DropDown, ComboRow).
|
|
22
|
-
* Similar to HTML select option elements.
|
|
23
|
-
*/
|
|
24
|
-
export type StringListItemProps = {
|
|
25
|
-
/** Unique identifier for this item. Used for selection. */
|
|
26
|
-
id: string;
|
|
27
|
-
/** Display text shown in the dropdown. */
|
|
28
|
-
label: string;
|
|
29
|
-
};
|
|
30
|
-
export type GridChildProps = SlotProps & {
|
|
31
|
-
column?: number;
|
|
32
|
-
row?: number;
|
|
33
|
-
columnSpan?: number;
|
|
34
|
-
rowSpan?: number;
|
|
35
|
-
};
|
|
36
|
-
/**
|
|
37
|
-
* Render function for ListView/GridView items.
|
|
38
|
-
* Called with null during setup (for loading state) and with the actual item during bind.
|
|
39
|
-
*/
|
|
40
|
-
export type RenderItemFn<T> = (item: T | null) => ReactElement;
|
|
41
|
-
/**
|
|
42
|
-
* Props for ListView and GridView components.
|
|
43
|
-
* @typeParam T - The type of the data items in the list
|
|
44
|
-
*/
|
|
45
|
-
export type ListViewRenderProps<T = unknown> = {
|
|
46
|
-
/** Render function called for each item in the list. */
|
|
47
|
-
renderItem: RenderItemFn<T>;
|
|
48
|
-
};
|
|
49
|
-
/**
|
|
50
|
-
* Props for individual columns in a ColumnView.
|
|
51
|
-
* @typeParam T - The type of the data items displayed in the column
|
|
52
|
-
*/
|
|
53
|
-
export type ColumnViewColumnProps<T = unknown> = {
|
|
54
|
-
/** The column header title. */
|
|
55
|
-
title?: string;
|
|
56
|
-
/** Whether the column should expand to fill available space. */
|
|
57
|
-
expand?: boolean;
|
|
58
|
-
/** Whether the column can be resized by the user. */
|
|
59
|
-
resizable?: boolean;
|
|
60
|
-
/** Fixed width in pixels. Overrides automatic sizing. */
|
|
61
|
-
fixedWidth?: number;
|
|
62
|
-
/** Unique identifier for the column. Used for sorting. */
|
|
63
|
-
id?: string;
|
|
64
|
-
/** Whether this column header can be clicked to trigger sorting. */
|
|
65
|
-
sortable?: boolean;
|
|
66
|
-
/**
|
|
67
|
-
* Render function for column cells.
|
|
68
|
-
* Called with null during setup (for loading state) and with the actual item during bind.
|
|
69
|
-
* Always annotate your callback parameter type to include null, e.g.: `(item: MyItem | null) => ...`
|
|
70
|
-
*/
|
|
71
|
-
renderCell: (item: T | null) => ReactElement;
|
|
72
|
-
};
|
|
73
|
-
/**
|
|
74
|
-
* Props for the ColumnView root component.
|
|
75
|
-
* Sorting is handled by the parent component - sort your items before rendering
|
|
76
|
-
* and pass them as ColumnView.Item children in the desired order.
|
|
77
|
-
* @typeParam C - The union type of column IDs
|
|
78
|
-
*/
|
|
79
|
-
export type ColumnViewRootProps<C extends string = string> = {
|
|
80
|
-
/** The ID of the currently sorted column, or null if unsorted. Controls the sort indicator UI. */
|
|
81
|
-
sortColumn?: C | null;
|
|
82
|
-
/** The current sort direction. Controls the sort indicator UI. */
|
|
83
|
-
sortOrder?: Gtk.SortType;
|
|
84
|
-
/** Callback fired when the user clicks a column header to change sort. */
|
|
85
|
-
onSortChange?: (column: C | null, order: Gtk.SortType) => void;
|
|
86
|
-
};
|
|
87
|
-
export type NotebookPageProps = SlotProps & {
|
|
88
|
-
label: string;
|
|
89
|
-
};
|
|
90
|
-
export type StackRootProps = SlotProps & {
|
|
91
|
-
visibleChildName?: string;
|
|
92
|
-
};
|
|
93
|
-
export type StackPageProps = SlotProps & {
|
|
94
|
-
name?: string;
|
|
95
|
-
title?: string;
|
|
96
|
-
iconName?: string;
|
|
97
|
-
needsAttention?: boolean;
|
|
98
|
-
visible?: boolean;
|
|
99
|
-
useUnderline?: boolean;
|
|
100
|
-
};
|
|
101
|
-
/**
|
|
102
|
-
* Props for the Menu.Root component.
|
|
103
|
-
* Root container for declarative menu structures.
|
|
104
|
-
*/
|
|
105
|
-
export type MenuRootProps = {
|
|
106
|
-
children?: ReactNode;
|
|
107
|
-
};
|
|
108
|
-
/**
|
|
109
|
-
* Props for Menu.Item components.
|
|
110
|
-
* Represents a single menu item with an action.
|
|
111
|
-
*/
|
|
112
|
-
export type MenuItemProps = {
|
|
113
|
-
/** The visible label for the menu item. */
|
|
114
|
-
label: string;
|
|
115
|
-
/** Callback invoked when the menu item is activated. */
|
|
116
|
-
onActivate?: () => void;
|
|
117
|
-
/** Keyboard accelerators for this menu item (e.g., `"<Control>q"` or `["<Control>q", "<Control>w"]`). */
|
|
118
|
-
accels?: string | string[];
|
|
119
|
-
};
|
|
120
|
-
/**
|
|
121
|
-
* Props for Menu.Section components.
|
|
122
|
-
* Groups related menu items with optional label.
|
|
123
|
-
*/
|
|
124
|
-
export type MenuSectionProps = {
|
|
125
|
-
/** Optional section label displayed as a header. */
|
|
126
|
-
label?: string;
|
|
127
|
-
children?: ReactNode;
|
|
128
|
-
};
|
|
129
|
-
/**
|
|
130
|
-
* Props for Menu.Submenu components.
|
|
131
|
-
* Creates a nested submenu with its own items.
|
|
132
|
-
*/
|
|
133
|
-
export type MenuSubmenuProps = {
|
|
134
|
-
/** The submenu label shown in parent menu. */
|
|
135
|
-
label: string;
|
|
136
|
-
children?: ReactNode;
|
|
137
|
-
};
|
|
2
|
+
export type Container = Gtk.Widget | Gtk.Application;
|
|
3
|
+
export type Props = Record<string, unknown>;
|
|
4
|
+
export type ContainerClass = typeof Gtk.Widget | typeof Gtk.Application;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gtkx/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Build GTK4 desktop applications with React and TypeScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"gtk",
|
|
@@ -36,18 +36,18 @@
|
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"react-reconciler": "^0.33.0",
|
|
39
|
-
"@gtkx/ffi": "0.
|
|
39
|
+
"@gtkx/ffi": "0.10.0",
|
|
40
|
+
"@gtkx/gir": "0.10.0"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
|
-
"@
|
|
43
|
-
"@gtkx/
|
|
43
|
+
"@types/react-reconciler": "^0.32.3",
|
|
44
|
+
"@gtkx/codegen": "0.0.0"
|
|
44
45
|
},
|
|
45
46
|
"peerDependencies": {
|
|
46
47
|
"react": "^19"
|
|
47
48
|
},
|
|
48
49
|
"scripts": {
|
|
49
50
|
"build": "tsc -b && cp ../../README.md .",
|
|
50
|
-
"codegen": "
|
|
51
|
-
"test": "../../scripts/run-tests.sh"
|
|
51
|
+
"codegen": "gtkx-codegen jsx --girs-dir ../../girs --output-dir src/generated"
|
|
52
52
|
}
|
|
53
53
|
}
|
package/dist/batch.d.ts
DELETED
package/dist/batch.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
const state = {
|
|
2
|
-
depth: 0,
|
|
3
|
-
pendingFlushes: new Set(),
|
|
4
|
-
};
|
|
5
|
-
export const beginCommit = () => {
|
|
6
|
-
state.depth++;
|
|
7
|
-
};
|
|
8
|
-
export const endCommit = () => {
|
|
9
|
-
if (state.depth <= 0) {
|
|
10
|
-
state.depth = 0;
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
state.depth--;
|
|
14
|
-
if (state.depth === 0 && state.pendingFlushes.size > 0) {
|
|
15
|
-
const callbacks = [...state.pendingFlushes];
|
|
16
|
-
state.pendingFlushes.clear();
|
|
17
|
-
queueMicrotask(() => {
|
|
18
|
-
for (const callback of callbacks) {
|
|
19
|
-
callback();
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
export const scheduleFlush = (callback) => {
|
|
25
|
-
if (state.depth > 0) {
|
|
26
|
-
state.pendingFlushes.add(callback);
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
callback();
|
|
30
|
-
}
|
|
31
|
-
};
|