@gtkx/react 0.1.11

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.
Files changed (45) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +390 -0
  3. package/dist/codegen/jsx-generator.d.ts +37 -0
  4. package/dist/codegen/jsx-generator.js +554 -0
  5. package/dist/factory.d.ts +3 -0
  6. package/dist/factory.js +59 -0
  7. package/dist/generated/jsx.d.ts +1598 -0
  8. package/dist/generated/jsx.js +264 -0
  9. package/dist/index.d.ts +5 -0
  10. package/dist/index.js +14 -0
  11. package/dist/node.d.ts +13 -0
  12. package/dist/node.js +1 -0
  13. package/dist/nodes/action-bar.d.ts +27 -0
  14. package/dist/nodes/action-bar.js +88 -0
  15. package/dist/nodes/dialog.d.ts +19 -0
  16. package/dist/nodes/dialog.js +87 -0
  17. package/dist/nodes/dropdown.d.ts +41 -0
  18. package/dist/nodes/dropdown.js +163 -0
  19. package/dist/nodes/grid.d.ts +41 -0
  20. package/dist/nodes/grid.js +140 -0
  21. package/dist/nodes/list.d.ts +46 -0
  22. package/dist/nodes/list.js +165 -0
  23. package/dist/nodes/notebook.d.ts +25 -0
  24. package/dist/nodes/notebook.js +88 -0
  25. package/dist/nodes/overlay.d.ts +29 -0
  26. package/dist/nodes/overlay.js +109 -0
  27. package/dist/nodes/slot.d.ts +17 -0
  28. package/dist/nodes/slot.js +55 -0
  29. package/dist/nodes/text.d.ts +16 -0
  30. package/dist/nodes/text.js +31 -0
  31. package/dist/nodes/widget.d.ts +19 -0
  32. package/dist/nodes/widget.js +136 -0
  33. package/dist/portal.d.ts +3 -0
  34. package/dist/portal.js +11 -0
  35. package/dist/reconciler.d.ts +20 -0
  36. package/dist/reconciler.js +111 -0
  37. package/dist/render.d.ts +5 -0
  38. package/dist/render.js +12 -0
  39. package/dist/signal-utils.d.ts +4 -0
  40. package/dist/signal-utils.js +7 -0
  41. package/dist/types.d.ts +13 -0
  42. package/dist/types.js +1 -0
  43. package/dist/widget-capabilities.d.ts +46 -0
  44. package/dist/widget-capabilities.js +32 -0
  45. package/package.json +52 -0
@@ -0,0 +1,109 @@
1
+ import { appendChild, disconnectSignalHandlers, isConnectable, removeChild } from "../widget-capabilities.js";
2
+ const isOverlayWidget = (widget) => "setChild" in widget &&
3
+ typeof widget.setChild === "function" &&
4
+ "addOverlay" in widget &&
5
+ typeof widget.addOverlay === "function" &&
6
+ "removeOverlay" in widget &&
7
+ typeof widget.removeOverlay === "function";
8
+ export class OverlayNode {
9
+ static needsWidget = true;
10
+ static matches(type, widget) {
11
+ if (type !== "Overlay" && type !== "Overlay.Root")
12
+ return false;
13
+ return widget !== null && isOverlayWidget(widget);
14
+ }
15
+ widget;
16
+ mainChild = null;
17
+ overlayChildren = [];
18
+ signalHandlers = new Map();
19
+ constructor(_type, widget, _props) {
20
+ if (!isOverlayWidget(widget)) {
21
+ throw new Error("OverlayNode requires an Overlay widget");
22
+ }
23
+ this.widget = widget;
24
+ }
25
+ getWidget() {
26
+ return this.widget;
27
+ }
28
+ appendChild(child) {
29
+ child.attachToParent(this);
30
+ }
31
+ removeChild(child) {
32
+ child.detachFromParent(this);
33
+ }
34
+ insertBefore(child, _before) {
35
+ this.appendChild(child);
36
+ }
37
+ attachToParent(parent) {
38
+ const parentWidget = parent.getWidget?.();
39
+ if (parentWidget) {
40
+ appendChild(parentWidget, this.widget);
41
+ }
42
+ }
43
+ detachFromParent(parent) {
44
+ const parentWidget = parent.getWidget?.();
45
+ if (parentWidget) {
46
+ removeChild(parentWidget, this.widget);
47
+ }
48
+ }
49
+ attachChild(childWidget) {
50
+ if (this.mainChild === null) {
51
+ this.mainChild = childWidget;
52
+ this.widget.setChild(childWidget.ptr);
53
+ }
54
+ else {
55
+ this.overlayChildren.push(childWidget);
56
+ this.widget.addOverlay(childWidget.ptr);
57
+ }
58
+ }
59
+ detachChild(childWidget) {
60
+ if (this.mainChild === childWidget) {
61
+ this.widget.setChild(null);
62
+ this.mainChild = null;
63
+ }
64
+ else {
65
+ const index = this.overlayChildren.indexOf(childWidget);
66
+ if (index !== -1) {
67
+ this.overlayChildren.splice(index, 1);
68
+ this.widget.removeOverlay(childWidget.ptr);
69
+ }
70
+ }
71
+ }
72
+ updateProps(oldProps, newProps) {
73
+ const consumedProps = new Set(["children"]);
74
+ const allKeys = new Set([...Object.keys(oldProps), ...Object.keys(newProps)]);
75
+ for (const key of allKeys) {
76
+ if (consumedProps.has(key))
77
+ continue;
78
+ const oldValue = oldProps[key];
79
+ const newValue = newProps[key];
80
+ if (oldValue === newValue)
81
+ continue;
82
+ if (key.startsWith("on")) {
83
+ const eventName = key
84
+ .slice(2)
85
+ .replace(/([A-Z])/g, "-$1")
86
+ .toLowerCase()
87
+ .replace(/^-/, "");
88
+ const oldHandlerId = this.signalHandlers.get(eventName);
89
+ if (oldHandlerId !== undefined && isConnectable(this.widget)) {
90
+ this.signalHandlers.delete(eventName);
91
+ }
92
+ if (typeof newValue === "function" && isConnectable(this.widget)) {
93
+ const handlerId = this.widget.connect(eventName, newValue);
94
+ this.signalHandlers.set(eventName, handlerId);
95
+ }
96
+ continue;
97
+ }
98
+ const setterName = `set${key.charAt(0).toUpperCase()}${key.slice(1)}`;
99
+ const setter = this.widget[setterName];
100
+ if (typeof setter === "function") {
101
+ setter.call(this.widget, newValue);
102
+ }
103
+ }
104
+ }
105
+ mount() { }
106
+ dispose() {
107
+ disconnectSignalHandlers(this.widget, this.signalHandlers);
108
+ }
109
+ }
@@ -0,0 +1,17 @@
1
+ import type * as Gtk from "@gtkx/ffi/gtk";
2
+ import type { Props } from "../factory.js";
3
+ import type { Node } from "../node.js";
4
+ export declare class SlotNode implements Node {
5
+ static needsWidget: boolean;
6
+ static matches(type: string, _widget: Gtk.Widget | null): _widget is Gtk.Widget;
7
+ private child;
8
+ private slotName;
9
+ constructor(type: string, _widget: Gtk.Widget, _props: Props);
10
+ appendChild(child: Node): void;
11
+ removeChild(_child: Node): void;
12
+ insertBefore(child: Node, _before: Node): void;
13
+ updateProps(_oldProps: Props, _newProps: Props): void;
14
+ mount(): void;
15
+ attachToParent(parent: Node): void;
16
+ detachFromParent(parent: Node): void;
17
+ }
@@ -0,0 +1,55 @@
1
+ export class SlotNode {
2
+ static needsWidget = false;
3
+ static matches(type, _widget) {
4
+ if (!type.includes("."))
5
+ return false;
6
+ const parts = type.split(".");
7
+ if (parts.length !== 2)
8
+ return false;
9
+ const suffix = parts[1];
10
+ return suffix !== "Item" && suffix !== "Root";
11
+ }
12
+ child = null;
13
+ slotName;
14
+ constructor(type, _widget, _props) {
15
+ const dotIndex = type.indexOf(".");
16
+ if (dotIndex === -1) {
17
+ throw new Error(`Invalid slot type: ${type}`);
18
+ }
19
+ this.slotName = type.substring(dotIndex + 1);
20
+ }
21
+ appendChild(child) {
22
+ if (child.getWidget) {
23
+ this.child = child;
24
+ }
25
+ }
26
+ removeChild(_child) {
27
+ this.child = null;
28
+ }
29
+ insertBefore(child, _before) {
30
+ this.appendChild(child);
31
+ }
32
+ updateProps(_oldProps, _newProps) { }
33
+ mount() { }
34
+ attachToParent(parent) {
35
+ const parentWidget = parent.getWidget?.();
36
+ const childWidget = this.child?.getWidget?.();
37
+ if (!parentWidget || !childWidget)
38
+ return;
39
+ const setterName = `set${this.slotName}`;
40
+ const setter = parentWidget[setterName];
41
+ if (typeof setter === "function") {
42
+ setter.call(parentWidget, childWidget.ptr);
43
+ }
44
+ }
45
+ detachFromParent(parent) {
46
+ const parentWidget = parent.getWidget?.();
47
+ if (!parentWidget)
48
+ return;
49
+ const setterName = `set${this.slotName}`;
50
+ const setter = parentWidget[setterName];
51
+ if (typeof setter === "function") {
52
+ setter.call(parentWidget, null);
53
+ }
54
+ }
55
+ }
@@ -0,0 +1,16 @@
1
+ import * as Gtk from "@gtkx/ffi/gtk";
2
+ import type { Props } from "../factory.js";
3
+ import type { Node } from "../node.js";
4
+ export declare class TextNode implements Node<Gtk.Label> {
5
+ private label;
6
+ constructor(text: string);
7
+ getWidget(): Gtk.Label;
8
+ updateText(text: string): void;
9
+ appendChild(_child: Node): void;
10
+ removeChild(_child: Node): void;
11
+ insertBefore(_child: Node, _before: Node): void;
12
+ updateProps(_oldProps: Props, _newProps: Props): void;
13
+ mount(): void;
14
+ attachToParent(parent: Node): void;
15
+ detachFromParent(parent: Node): void;
16
+ }
@@ -0,0 +1,31 @@
1
+ import * as Gtk from "@gtkx/ffi/gtk";
2
+ import { appendChild, removeChild } from "../widget-capabilities.js";
3
+ export class TextNode {
4
+ label;
5
+ constructor(text) {
6
+ this.label = new Gtk.Label(text);
7
+ }
8
+ getWidget() {
9
+ return this.label;
10
+ }
11
+ updateText(text) {
12
+ this.label.setLabel(text);
13
+ }
14
+ appendChild(_child) { }
15
+ removeChild(_child) { }
16
+ insertBefore(_child, _before) { }
17
+ updateProps(_oldProps, _newProps) { }
18
+ mount() { }
19
+ attachToParent(parent) {
20
+ const parentWidget = parent.getWidget?.();
21
+ if (parentWidget) {
22
+ appendChild(parentWidget, this.label);
23
+ }
24
+ }
25
+ detachFromParent(parent) {
26
+ const parentWidget = parent.getWidget?.();
27
+ if (parentWidget) {
28
+ removeChild(parentWidget, this.label);
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,19 @@
1
+ import type * as Gtk from "@gtkx/ffi/gtk";
2
+ import type { Props } from "../factory.js";
3
+ import type { Node } from "../node.js";
4
+ export declare class WidgetNode implements Node {
5
+ static needsWidget: boolean;
6
+ static matches(_type: string, widget: Gtk.Widget | null): widget is Gtk.Widget;
7
+ private widget;
8
+ private signalHandlers;
9
+ constructor(_type: string, widget: Gtk.Widget, _props: Props);
10
+ getWidget(): Gtk.Widget;
11
+ appendChild(child: Node): void;
12
+ removeChild(child: Node): void;
13
+ insertBefore(child: Node, _before: Node): void;
14
+ attachToParent(parent: Node): void;
15
+ detachFromParent(parent: Node): void;
16
+ updateProps(oldProps: Props, newProps: Props): void;
17
+ mount(): void;
18
+ dispose(): void;
19
+ }
@@ -0,0 +1,136 @@
1
+ import * as GObject from "@gtkx/ffi/gobject";
2
+ import { appendChild, disconnectSignalHandlers, isConnectable, isDefaultSizable, isPresentable, removeChild, } from "../widget-capabilities.js";
3
+ import { ActionBarNode } from "./action-bar.js";
4
+ import { NotebookNode } from "./notebook.js";
5
+ import { OverlayNode } from "./overlay.js";
6
+ const COMBINED_PROPS = [
7
+ {
8
+ props: ["defaultWidth", "defaultHeight"],
9
+ apply: (widget) => (values) => {
10
+ if (isDefaultSizable(widget)) {
11
+ const width = values.defaultWidth ?? -1;
12
+ const height = values.defaultHeight ?? -1;
13
+ widget.setDefaultSize(width, height);
14
+ }
15
+ },
16
+ },
17
+ ];
18
+ export class WidgetNode {
19
+ static needsWidget = true;
20
+ static matches(_type, widget) {
21
+ return widget !== null;
22
+ }
23
+ widget;
24
+ signalHandlers = new Map();
25
+ constructor(_type, widget, _props) {
26
+ this.widget = widget;
27
+ }
28
+ getWidget() {
29
+ return this.widget;
30
+ }
31
+ appendChild(child) {
32
+ child.attachToParent(this);
33
+ }
34
+ removeChild(child) {
35
+ child.detachFromParent(this);
36
+ }
37
+ insertBefore(child, _before) {
38
+ this.appendChild(child);
39
+ }
40
+ attachToParent(parent) {
41
+ if (parent instanceof NotebookNode) {
42
+ parent.attachChild(this.widget);
43
+ return;
44
+ }
45
+ if (parent instanceof OverlayNode) {
46
+ parent.attachChild(this.widget);
47
+ return;
48
+ }
49
+ if (parent instanceof ActionBarNode) {
50
+ parent.attachChild(this.widget);
51
+ return;
52
+ }
53
+ const parentWidget = parent.getWidget?.();
54
+ if (parentWidget) {
55
+ appendChild(parentWidget, this.widget);
56
+ }
57
+ }
58
+ detachFromParent(parent) {
59
+ if (parent instanceof NotebookNode) {
60
+ parent.detachChild(this.widget);
61
+ return;
62
+ }
63
+ if (parent instanceof OverlayNode) {
64
+ parent.detachChild(this.widget);
65
+ return;
66
+ }
67
+ if (parent instanceof ActionBarNode) {
68
+ parent.detachChild(this.widget);
69
+ return;
70
+ }
71
+ const parentWidget = parent.getWidget?.();
72
+ if (parentWidget) {
73
+ removeChild(parentWidget, this.widget);
74
+ }
75
+ }
76
+ updateProps(oldProps, newProps) {
77
+ const consumedProps = new Set(["children", "application"]);
78
+ for (const handler of COMBINED_PROPS) {
79
+ const hasAnyChanged = handler.props.some((prop) => oldProps[prop] !== newProps[prop]);
80
+ if (hasAnyChanged) {
81
+ const values = {};
82
+ for (const prop of handler.props) {
83
+ values[prop] = newProps[prop];
84
+ consumedProps.add(prop);
85
+ }
86
+ handler.apply(this.widget)(values);
87
+ }
88
+ else {
89
+ for (const prop of handler.props) {
90
+ consumedProps.add(prop);
91
+ }
92
+ }
93
+ }
94
+ const allKeys = new Set([...Object.keys(oldProps), ...Object.keys(newProps)]);
95
+ for (const key of allKeys) {
96
+ if (consumedProps.has(key))
97
+ continue;
98
+ const oldValue = oldProps[key];
99
+ const newValue = newProps[key];
100
+ if (oldValue === newValue)
101
+ continue;
102
+ if (key.startsWith("on")) {
103
+ const eventName = key
104
+ .slice(2)
105
+ .replace(/([A-Z])/g, "-$1")
106
+ .toLowerCase()
107
+ .replace(/^-/, "");
108
+ const oldHandlerId = this.signalHandlers.get(eventName);
109
+ if (oldHandlerId !== undefined) {
110
+ GObject.signalHandlerDisconnect(this.widget, oldHandlerId);
111
+ this.signalHandlers.delete(eventName);
112
+ }
113
+ if (typeof newValue === "function" && isConnectable(this.widget)) {
114
+ const handlerId = this.widget.connect(eventName, newValue);
115
+ this.signalHandlers.set(eventName, handlerId);
116
+ }
117
+ continue;
118
+ }
119
+ if (newValue === undefined)
120
+ continue;
121
+ const setterName = `set${key.charAt(0).toUpperCase()}${key.slice(1)}`;
122
+ const setter = this.widget[setterName];
123
+ if (typeof setter === "function") {
124
+ setter.call(this.widget, newValue);
125
+ }
126
+ }
127
+ }
128
+ mount() {
129
+ if (isPresentable(this.widget)) {
130
+ this.widget.present();
131
+ }
132
+ }
133
+ dispose() {
134
+ disconnectSignalHandlers(this.widget, this.signalHandlers);
135
+ }
136
+ }
@@ -0,0 +1,3 @@
1
+ import type { ReactNode, ReactPortal } from "react";
2
+ export declare const isRootPortalContainer: (container: unknown) => boolean;
3
+ export declare const createPortal: (children: ReactNode, container?: unknown, key?: string | null) => ReactPortal;
package/dist/portal.js ADDED
@@ -0,0 +1,11 @@
1
+ const ROOT_PORTAL_CONTAINER = Symbol("ROOT_PORTAL_CONTAINER");
2
+ export const isRootPortalContainer = (container) => container === ROOT_PORTAL_CONTAINER;
3
+ export const createPortal = (children, container, key) => {
4
+ return {
5
+ $$typeof: Symbol.for("react.portal"),
6
+ key: key ?? null,
7
+ children,
8
+ containerInfo: container ?? ROOT_PORTAL_CONTAINER,
9
+ implementation: null,
10
+ };
11
+ };
@@ -0,0 +1,20 @@
1
+ import type * as Gtk from "@gtkx/ffi/gtk";
2
+ import type { Application } from "@gtkx/ffi/gtk";
3
+ import Reconciler from "react-reconciler";
4
+ import type { Node } from "./node.js";
5
+ export declare const getCurrentApp: () => Application | null;
6
+ export declare const getActiveWindow: () => Gtk.Window | null;
7
+ export declare const disposeAllInstances: () => void;
8
+ import { TextNode } from "./nodes/text.js";
9
+ type PublicInstance = Node;
10
+ export declare class GtkReconciler {
11
+ private reconciler;
12
+ constructor();
13
+ setCurrentApp(app: Application): void;
14
+ getReconciler(): typeof this.reconciler;
15
+ private createHostConfig;
16
+ private createReconcilerContext;
17
+ }
18
+ export declare const reconciler: Reconciler.Reconciler<unknown, Node<Gtk.Widget>, TextNode, never, never, PublicInstance>;
19
+ export declare const setCurrentApp: (app: Application) => void;
20
+ export {};
@@ -0,0 +1,111 @@
1
+ import React from "react";
2
+ import Reconciler from "react-reconciler";
3
+ import { createNode } from "./factory.js";
4
+ const allInstances = new Set();
5
+ let currentApp = null;
6
+ export const getCurrentApp = () => currentApp;
7
+ export const getActiveWindow = () => currentApp?.getActiveWindow() ?? null;
8
+ export const disposeAllInstances = () => {
9
+ for (const instance of allInstances) {
10
+ instance.dispose?.();
11
+ }
12
+ allInstances.clear();
13
+ };
14
+ import { TextNode } from "./nodes/text.js";
15
+ export class GtkReconciler {
16
+ reconciler;
17
+ constructor() {
18
+ this.reconciler = Reconciler(this.createHostConfig());
19
+ }
20
+ setCurrentApp(app) {
21
+ currentApp = app;
22
+ }
23
+ getReconciler() {
24
+ return this.reconciler;
25
+ }
26
+ createHostConfig() {
27
+ return {
28
+ supportsMutation: true,
29
+ supportsPersistence: false,
30
+ supportsHydration: false,
31
+ isPrimaryRenderer: true,
32
+ noTimeout: -1,
33
+ getRootHostContext: () => ({}),
34
+ getChildHostContext: (parentHostContext) => parentHostContext,
35
+ shouldSetTextContent: () => false,
36
+ createInstance: (type, props) => {
37
+ const instance = createNode(type, props, currentApp);
38
+ allInstances.add(instance);
39
+ return instance;
40
+ },
41
+ createTextInstance: (text) => {
42
+ return new TextNode(text);
43
+ },
44
+ appendInitialChild: (parent, child) => parent.appendChild(child),
45
+ finalizeInitialChildren: () => true,
46
+ commitUpdate: (instance, _type, oldProps, newProps) => {
47
+ instance.updateProps(oldProps, newProps);
48
+ },
49
+ commitMount: (instance) => {
50
+ instance.mount();
51
+ },
52
+ appendChild: (parent, child) => parent.appendChild(child),
53
+ removeChild: (parent, child) => parent.removeChild(child),
54
+ insertBefore: (parent, child, beforeChild) => parent.insertBefore(child, beforeChild),
55
+ removeChildFromContainer: (_container, _child) => { },
56
+ appendChildToContainer: (_container, child) => {
57
+ child.mount();
58
+ },
59
+ insertInContainerBefore: (_container, child, _beforeChild) => {
60
+ child.mount();
61
+ },
62
+ prepareForCommit: () => null,
63
+ resetAfterCommit: () => { },
64
+ commitTextUpdate: (textInstance, _oldText, newText) => {
65
+ textInstance.updateText(newText);
66
+ },
67
+ clearContainer: () => { },
68
+ preparePortalMount: () => { },
69
+ scheduleTimeout: (fn, delay) => {
70
+ const timeoutId = setTimeout(fn, delay ?? 0);
71
+ return typeof timeoutId === "number" ? timeoutId : Number(timeoutId);
72
+ },
73
+ cancelTimeout: (id) => {
74
+ clearTimeout(id);
75
+ },
76
+ getPublicInstance: (instance) => instance,
77
+ getCurrentUpdatePriority: () => 2,
78
+ setCurrentUpdatePriority: () => { },
79
+ resolveUpdatePriority: () => 2,
80
+ NotPendingTransition: null,
81
+ HostTransitionContext: this.createReconcilerContext(0),
82
+ getInstanceFromNode: () => null,
83
+ beforeActiveInstanceBlur: () => { },
84
+ afterActiveInstanceBlur: () => { },
85
+ prepareScopeUpdate: () => { },
86
+ getInstanceFromScope: () => null,
87
+ detachDeletedInstance: (instance) => {
88
+ instance.dispose?.();
89
+ allInstances.delete(instance);
90
+ },
91
+ resetFormInstance: () => { },
92
+ requestPostPaintCallback: () => { },
93
+ shouldAttemptEagerTransition: () => false,
94
+ trackSchedulerEvent: () => { },
95
+ resolveEventType: () => null,
96
+ resolveEventTimeStamp: () => Date.now(),
97
+ maySuspendCommit: () => false,
98
+ preloadInstance: () => false,
99
+ startSuspendingCommit: () => { },
100
+ suspendInstance: () => { },
101
+ waitForCommitToBeReady: () => null,
102
+ };
103
+ }
104
+ createReconcilerContext(value) {
105
+ const context = React.createContext(value);
106
+ return context;
107
+ }
108
+ }
109
+ const gtkReconciler = new GtkReconciler();
110
+ export const reconciler = gtkReconciler.getReconciler();
111
+ export const setCurrentApp = (app) => gtkReconciler.setCurrentApp(app);
@@ -0,0 +1,5 @@
1
+ import type { ApplicationFlags } from "@gtkx/ffi/gio";
2
+ import type { Application } from "@gtkx/ffi/gtk";
3
+ import type { ReactNode } from "react";
4
+ export declare let container: unknown;
5
+ export declare const render: (element: ReactNode, appId: string, flags?: ApplicationFlags) => Application;
package/dist/render.js ADDED
@@ -0,0 +1,12 @@
1
+ import { start } from "@gtkx/ffi";
2
+ import { reconciler, setCurrentApp } from "./reconciler.js";
3
+ export let container = null;
4
+ export const render = (element, appId, flags) => {
5
+ const app = start(appId, flags);
6
+ setCurrentApp(app);
7
+ container = reconciler.createContainer(appId, 0, null, false, false, "", (error, info) => {
8
+ console.error("React reconciler error:", error, info);
9
+ }, null, null, null, null);
10
+ reconciler.updateContainer(element, container, null, () => { });
11
+ return app;
12
+ };
@@ -0,0 +1,4 @@
1
+ import * as GObject from "@gtkx/ffi/gobject";
2
+ type SignalHandlerMap = Map<string, number>;
3
+ export declare const disconnectSignalHandlers: (gobject: GObject.GObject, handlers: SignalHandlerMap) => void;
4
+ export {};
@@ -0,0 +1,7 @@
1
+ import * as GObject from "@gtkx/ffi/gobject";
2
+ export const disconnectSignalHandlers = (gobject, handlers) => {
3
+ for (const handlerId of handlers.values()) {
4
+ GObject.signalHandlerDisconnect(gobject, handlerId);
5
+ }
6
+ handlers.clear();
7
+ };
@@ -0,0 +1,13 @@
1
+ import type { ReactNode } from "react";
2
+ export interface SlotProps {
3
+ children?: ReactNode;
4
+ }
5
+ export interface ItemProps<T> {
6
+ item: T;
7
+ }
8
+ export interface GridChildProps extends SlotProps {
9
+ column?: number;
10
+ row?: number;
11
+ columnSpan?: number;
12
+ rowSpan?: number;
13
+ }
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,46 @@
1
+ import type * as Gtk from "@gtkx/ffi/gtk";
2
+ export interface Appendable extends Gtk.Widget {
3
+ append(child: unknown): void;
4
+ }
5
+ export interface SingleChild extends Gtk.Widget {
6
+ setChild(child: unknown): void;
7
+ }
8
+ export interface Removable extends Gtk.Widget {
9
+ remove(child: unknown): void;
10
+ }
11
+ export interface Presentable extends Gtk.Widget {
12
+ present(): void;
13
+ }
14
+ export interface Connectable extends Gtk.Widget {
15
+ connect(signal: string, handler: (...args: unknown[]) => unknown, after?: boolean): number;
16
+ }
17
+ export interface DefaultSizable extends Gtk.Widget {
18
+ setDefaultSize(width: number, height: number): void;
19
+ }
20
+ export interface ModelSettable extends Gtk.Widget {
21
+ setModel(model: unknown): void;
22
+ }
23
+ export interface Selectable extends Gtk.Widget {
24
+ getSelected(): number;
25
+ }
26
+ export interface GridAttachable extends Gtk.Widget {
27
+ attach(child: unknown, column: number, row: number, width: number, height: number): void;
28
+ }
29
+ export interface NotebookLike extends Gtk.Widget {
30
+ appendPage(child: unknown, tabLabel?: unknown): number;
31
+ pageNum(child: unknown): number;
32
+ removePage(pageNum: number): void;
33
+ }
34
+ export declare const isAppendable: (widget: Gtk.Widget) => widget is Appendable;
35
+ export declare const isSingleChild: (widget: Gtk.Widget) => widget is SingleChild;
36
+ export declare const isRemovable: (widget: Gtk.Widget) => widget is Removable;
37
+ export declare const isPresentable: (widget: Gtk.Widget) => widget is Presentable;
38
+ export declare const isConnectable: (widget: Gtk.Widget) => widget is Connectable;
39
+ export declare const isDefaultSizable: (widget: Gtk.Widget) => widget is DefaultSizable;
40
+ export declare const isModelSettable: (widget: Gtk.Widget) => widget is ModelSettable;
41
+ export declare const isSelectable: (widget: Gtk.Widget) => widget is Selectable;
42
+ export declare const isGridAttachable: (widget: Gtk.Widget) => widget is GridAttachable;
43
+ export declare const isNotebookLike: (widget: Gtk.Widget) => widget is NotebookLike;
44
+ export declare const appendChild: (parent: Gtk.Widget, child: Gtk.Widget) => void;
45
+ export declare const removeChild: (parent: Gtk.Widget, child: Gtk.Widget) => void;
46
+ export { disconnectSignalHandlers } from "./signal-utils.js";
@@ -0,0 +1,32 @@
1
+ export const isAppendable = (widget) => "append" in widget && typeof widget.append === "function";
2
+ export const isSingleChild = (widget) => "setChild" in widget && typeof widget.setChild === "function";
3
+ export const isRemovable = (widget) => "remove" in widget && typeof widget.remove === "function";
4
+ export const isPresentable = (widget) => "present" in widget && typeof widget.present === "function";
5
+ export const isConnectable = (widget) => "connect" in widget && typeof widget.connect === "function";
6
+ export const isDefaultSizable = (widget) => "setDefaultSize" in widget && typeof widget.setDefaultSize === "function";
7
+ export const isModelSettable = (widget) => "setModel" in widget && typeof widget.setModel === "function";
8
+ export const isSelectable = (widget) => "getSelected" in widget && typeof widget.getSelected === "function";
9
+ export const isGridAttachable = (widget) => "attach" in widget && typeof widget.attach === "function";
10
+ export const isNotebookLike = (widget) => "appendPage" in widget &&
11
+ typeof widget.appendPage === "function" &&
12
+ "pageNum" in widget &&
13
+ typeof widget.pageNum === "function" &&
14
+ "removePage" in widget &&
15
+ typeof widget.removePage === "function";
16
+ export const appendChild = (parent, child) => {
17
+ if (isSingleChild(parent)) {
18
+ parent.setChild(child.ptr);
19
+ }
20
+ else if (isAppendable(parent)) {
21
+ parent.append(child.ptr);
22
+ }
23
+ };
24
+ export const removeChild = (parent, child) => {
25
+ if (isRemovable(parent)) {
26
+ parent.remove(child.ptr);
27
+ }
28
+ else if (isSingleChild(parent)) {
29
+ parent.setChild(null);
30
+ }
31
+ };
32
+ export { disconnectSignalHandlers } from "./signal-utils.js";