@gtkx/react 0.13.2 → 0.14.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 +32 -31
- package/dist/generated/internal.js +98 -0
- package/dist/generated/jsx.d.ts +1110 -1781
- package/dist/jsx.d.ts +66 -35
- package/dist/jsx.js +17 -5
- package/dist/nodes/application.js +6 -6
- package/dist/nodes/index.d.ts +1 -0
- package/dist/nodes/index.js +1 -0
- package/dist/nodes/internal/constants.js +11 -0
- package/dist/nodes/internal/list-item-renderer.js +1 -1
- package/dist/nodes/internal/tree-list-item-renderer.js +1 -1
- package/dist/nodes/list-view.js +5 -0
- package/dist/nodes/models/list.d.ts +6 -1
- package/dist/nodes/models/list.js +21 -6
- package/dist/nodes/models/tree-list.d.ts +6 -1
- package/dist/nodes/models/tree-list.js +21 -7
- package/dist/nodes/navigation-page.d.ts +1 -6
- package/dist/nodes/navigation-page.js +21 -32
- package/dist/nodes/scrolled-window.d.ts +1 -0
- package/dist/nodes/scrolled-window.js +21 -0
- package/dist/nodes/slot.js +11 -2
- package/dist/nodes/tree-list-view.js +5 -0
- package/dist/nodes/widget.d.ts +5 -0
- package/dist/nodes/widget.js +82 -4
- package/dist/render.d.ts +14 -14
- package/dist/render.js +14 -14
- package/dist/types.d.ts +84 -1
- package/package.json +3 -3
|
@@ -59,7 +59,12 @@ class TreeListViewNode extends WidgetNode {
|
|
|
59
59
|
if (!oldProps || oldProps.estimatedItemHeight !== newProps.estimatedItemHeight) {
|
|
60
60
|
this.itemRenderer.setEstimatedItemHeight(newProps.estimatedItemHeight);
|
|
61
61
|
}
|
|
62
|
+
const previousModel = this.treeList.getSelectionModel();
|
|
62
63
|
this.treeList.updateProps(oldProps ? filterProps(oldProps, RENDERER_PROP_NAMES) : null, filterProps(newProps, RENDERER_PROP_NAMES));
|
|
64
|
+
const currentModel = this.treeList.getSelectionModel();
|
|
65
|
+
if (previousModel !== currentModel) {
|
|
66
|
+
this.container.setModel(currentModel);
|
|
67
|
+
}
|
|
63
68
|
super.updateProps(oldProps ? filterProps(oldProps, PROP_NAMES) : null, filterProps(newProps, PROP_NAMES));
|
|
64
69
|
}
|
|
65
70
|
}
|
package/dist/nodes/widget.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ export declare class WidgetNode<T extends Gtk.Widget = Gtk.Widget, P extends Pro
|
|
|
7
7
|
private clickController?;
|
|
8
8
|
private keyController?;
|
|
9
9
|
private scrollController?;
|
|
10
|
+
private dragSourceController?;
|
|
11
|
+
private dropTargetController?;
|
|
10
12
|
static matches(_type: string, containerOrClass?: Container | ContainerClass | null): boolean;
|
|
11
13
|
static createContainer(props: Props, containerClass: typeof Gtk.Widget): Container | null;
|
|
12
14
|
appendChild(child: Node): void;
|
|
@@ -15,7 +17,10 @@ export declare class WidgetNode<T extends Gtk.Widget = Gtk.Widget, P extends Pro
|
|
|
15
17
|
private insertBeforeReorderable;
|
|
16
18
|
private insertBeforeInsertable;
|
|
17
19
|
updateProps(oldProps: P | null, newProps: P): void;
|
|
20
|
+
private updateSizeRequest;
|
|
18
21
|
private updateEventControllerProp;
|
|
22
|
+
private ensureDragSource;
|
|
23
|
+
private ensureDropTarget;
|
|
19
24
|
private updateNotifyHandler;
|
|
20
25
|
private propNameToSignalName;
|
|
21
26
|
private getProperty;
|
package/dist/nodes/widget.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { batch, isObjectEqual, NativeObject } from "@gtkx/ffi";
|
|
2
|
+
import * as Gdk from "@gtkx/ffi/gdk";
|
|
2
3
|
import * as Gtk from "@gtkx/ffi/gtk";
|
|
3
4
|
import { CONSTRUCTOR_PROPS } from "../generated/internal.js";
|
|
4
5
|
import { Node } from "../node.js";
|
|
@@ -8,12 +9,15 @@ import { hasSingleContent, isAddable, isAppendable, isEditable, isInsertable, is
|
|
|
8
9
|
import { signalStore } from "./internal/signal-store.js";
|
|
9
10
|
import { filterProps, isContainerType, resolvePropMeta, resolveSignal } from "./internal/utils.js";
|
|
10
11
|
import { SlotNode } from "./slot.js";
|
|
12
|
+
const PROPS = ["children", "widthRequest", "heightRequest"];
|
|
11
13
|
export class WidgetNode extends Node {
|
|
12
14
|
static priority = 3;
|
|
13
15
|
motionController;
|
|
14
16
|
clickController;
|
|
15
17
|
keyController;
|
|
16
18
|
scrollController;
|
|
19
|
+
dragSourceController;
|
|
20
|
+
dropTargetController;
|
|
17
21
|
static matches(_type, containerOrClass) {
|
|
18
22
|
return isContainerType(Gtk.Widget, containerOrClass);
|
|
19
23
|
}
|
|
@@ -89,9 +93,10 @@ export class WidgetNode extends Node {
|
|
|
89
93
|
container.insert(child.container, position);
|
|
90
94
|
}
|
|
91
95
|
updateProps(oldProps, newProps) {
|
|
96
|
+
this.updateSizeRequest(oldProps, newProps);
|
|
92
97
|
const propNames = new Set([
|
|
93
|
-
...Object.keys(filterProps(oldProps ?? {},
|
|
94
|
-
...Object.keys(filterProps(newProps ?? {},
|
|
98
|
+
...Object.keys(filterProps(oldProps ?? {}, PROPS)),
|
|
99
|
+
...Object.keys(filterProps(newProps ?? {}, PROPS)),
|
|
95
100
|
]);
|
|
96
101
|
const pendingSignals = [];
|
|
97
102
|
for (const name of propNames) {
|
|
@@ -136,8 +141,19 @@ export class WidgetNode extends Node {
|
|
|
136
141
|
}
|
|
137
142
|
}
|
|
138
143
|
}
|
|
139
|
-
|
|
140
|
-
const
|
|
144
|
+
updateSizeRequest(oldProps, newProps) {
|
|
145
|
+
const oldWidth = oldProps?.widthRequest;
|
|
146
|
+
const oldHeight = oldProps?.heightRequest;
|
|
147
|
+
const newWidth = newProps.widthRequest;
|
|
148
|
+
const newHeight = newProps.heightRequest;
|
|
149
|
+
if (oldWidth !== newWidth || oldHeight !== newHeight) {
|
|
150
|
+
this.container.setSizeRequest(newWidth ?? -1, newHeight ?? -1);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
updateEventControllerProp(propName, handlerOrValue) {
|
|
154
|
+
const wrappedHandler = typeof handlerOrValue === "function"
|
|
155
|
+
? (_self, ...args) => handlerOrValue(...args)
|
|
156
|
+
: undefined;
|
|
141
157
|
switch (propName) {
|
|
142
158
|
case "onEnter":
|
|
143
159
|
case "onLeave":
|
|
@@ -178,7 +194,69 @@ export class WidgetNode extends Node {
|
|
|
178
194
|
signalStore.set(this, this.scrollController, "scroll", wrappedHandler);
|
|
179
195
|
break;
|
|
180
196
|
}
|
|
197
|
+
case "onDragPrepare":
|
|
198
|
+
case "onDragBegin":
|
|
199
|
+
case "onDragEnd":
|
|
200
|
+
case "onDragCancel":
|
|
201
|
+
case "dragActions": {
|
|
202
|
+
const dragSource = this.ensureDragSource();
|
|
203
|
+
if (propName === "dragActions") {
|
|
204
|
+
dragSource.setActions(handlerOrValue ?? Gdk.DragAction.COPY);
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
const signalName = propName === "onDragPrepare"
|
|
208
|
+
? "prepare"
|
|
209
|
+
: propName === "onDragBegin"
|
|
210
|
+
? "drag-begin"
|
|
211
|
+
: propName === "onDragEnd"
|
|
212
|
+
? "drag-end"
|
|
213
|
+
: "drag-cancel";
|
|
214
|
+
signalStore.set(this, dragSource, signalName, wrappedHandler);
|
|
215
|
+
}
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
case "onDrop":
|
|
219
|
+
case "onDropEnter":
|
|
220
|
+
case "onDropLeave":
|
|
221
|
+
case "onDropMotion":
|
|
222
|
+
case "dropActions":
|
|
223
|
+
case "dropTypes": {
|
|
224
|
+
const dropTarget = this.ensureDropTarget();
|
|
225
|
+
if (propName === "dropActions") {
|
|
226
|
+
dropTarget.setActions(handlerOrValue ?? Gdk.DragAction.COPY);
|
|
227
|
+
}
|
|
228
|
+
else if (propName === "dropTypes") {
|
|
229
|
+
const types = handlerOrValue ?? [];
|
|
230
|
+
dropTarget.setGtypes(types.length, types);
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
const signalName = propName === "onDrop"
|
|
234
|
+
? "drop"
|
|
235
|
+
: propName === "onDropEnter"
|
|
236
|
+
? "enter"
|
|
237
|
+
: propName === "onDropLeave"
|
|
238
|
+
? "leave"
|
|
239
|
+
: "motion";
|
|
240
|
+
signalStore.set(this, dropTarget, signalName, wrappedHandler);
|
|
241
|
+
}
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
ensureDragSource() {
|
|
247
|
+
if (!this.dragSourceController) {
|
|
248
|
+
this.dragSourceController = new Gtk.DragSource();
|
|
249
|
+
this.dragSourceController.setActions(Gdk.DragAction.COPY);
|
|
250
|
+
this.container.addController(this.dragSourceController);
|
|
251
|
+
}
|
|
252
|
+
return this.dragSourceController;
|
|
253
|
+
}
|
|
254
|
+
ensureDropTarget() {
|
|
255
|
+
if (!this.dropTargetController) {
|
|
256
|
+
this.dropTargetController = new Gtk.DropTarget(0, Gdk.DragAction.COPY);
|
|
257
|
+
this.container.addController(this.dropTargetController);
|
|
181
258
|
}
|
|
259
|
+
return this.dropTargetController;
|
|
182
260
|
}
|
|
183
261
|
updateNotifyHandler(handler) {
|
|
184
262
|
const wrappedHandler = handler
|
package/dist/render.d.ts
CHANGED
|
@@ -9,9 +9,9 @@ import { type ReactNode } from "react";
|
|
|
9
9
|
* @example
|
|
10
10
|
* ```tsx
|
|
11
11
|
* const App = () => {
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* const app = useApplication();
|
|
13
|
+
* console.log(app.applicationId);
|
|
14
|
+
* return <GtkLabel label="Hello" />;
|
|
15
15
|
* };
|
|
16
16
|
* ```
|
|
17
17
|
*/
|
|
@@ -27,8 +27,8 @@ export declare const ApplicationContext: React.Context<Gtk.Application | null>;
|
|
|
27
27
|
* @example
|
|
28
28
|
* ```tsx
|
|
29
29
|
* const MyComponent = () => {
|
|
30
|
-
*
|
|
31
|
-
*
|
|
30
|
+
* const app = useApplication();
|
|
31
|
+
* return <GtkLabel label={app.applicationId} />;
|
|
32
32
|
* };
|
|
33
33
|
* ```
|
|
34
34
|
*
|
|
@@ -69,9 +69,9 @@ export declare const setHotReloading: (value: boolean) => void;
|
|
|
69
69
|
* import { render, quit } from "@gtkx/react";
|
|
70
70
|
*
|
|
71
71
|
* const App = () => (
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
72
|
+
* <GtkApplicationWindow title="My App" onClose={quit}>
|
|
73
|
+
* <GtkLabel label="Hello, GTKX!" />
|
|
74
|
+
* </GtkApplicationWindow>
|
|
75
75
|
* );
|
|
76
76
|
*
|
|
77
77
|
* render(<App />, "com.example.myapp");
|
|
@@ -94,9 +94,9 @@ export declare const render: (element: ReactNode, appId: string, flags?: Gio.App
|
|
|
94
94
|
* ```tsx
|
|
95
95
|
* // In HMR handler
|
|
96
96
|
* if (import.meta.hot) {
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
97
|
+
* import.meta.hot.accept(() => {
|
|
98
|
+
* update(<App />);
|
|
99
|
+
* });
|
|
100
100
|
* }
|
|
101
101
|
* ```
|
|
102
102
|
*
|
|
@@ -114,9 +114,9 @@ export declare const update: (element: ReactNode) => Promise<void>;
|
|
|
114
114
|
* import { quit } from "@gtkx/react";
|
|
115
115
|
*
|
|
116
116
|
* const App = () => (
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
117
|
+
* <GtkApplicationWindow title="My App" onClose={quit}>
|
|
118
|
+
* <GtkButton label="Quit" onClicked={quit} />
|
|
119
|
+
* </GtkApplicationWindow>
|
|
120
120
|
* );
|
|
121
121
|
* ```
|
|
122
122
|
*
|
package/dist/render.js
CHANGED
|
@@ -11,9 +11,9 @@ import { reconciler } from "./reconciler.js";
|
|
|
11
11
|
* @example
|
|
12
12
|
* ```tsx
|
|
13
13
|
* const App = () => {
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* const app = useApplication();
|
|
15
|
+
* console.log(app.applicationId);
|
|
16
|
+
* return <GtkLabel label="Hello" />;
|
|
17
17
|
* };
|
|
18
18
|
* ```
|
|
19
19
|
*/
|
|
@@ -29,8 +29,8 @@ export const ApplicationContext = createContext(null);
|
|
|
29
29
|
* @example
|
|
30
30
|
* ```tsx
|
|
31
31
|
* const MyComponent = () => {
|
|
32
|
-
*
|
|
33
|
-
*
|
|
32
|
+
* const app = useApplication();
|
|
33
|
+
* return <GtkLabel label={app.applicationId} />;
|
|
34
34
|
* };
|
|
35
35
|
* ```
|
|
36
36
|
*
|
|
@@ -84,9 +84,9 @@ export const setHotReloading = (value) => {
|
|
|
84
84
|
* import { render, quit } from "@gtkx/react";
|
|
85
85
|
*
|
|
86
86
|
* const App = () => (
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
87
|
+
* <GtkApplicationWindow title="My App" onClose={quit}>
|
|
88
|
+
* <GtkLabel label="Hello, GTKX!" />
|
|
89
|
+
* </GtkApplicationWindow>
|
|
90
90
|
* );
|
|
91
91
|
*
|
|
92
92
|
* render(<App />, "com.example.myapp");
|
|
@@ -121,9 +121,9 @@ export const render = (element, appId, flags) => {
|
|
|
121
121
|
* ```tsx
|
|
122
122
|
* // In HMR handler
|
|
123
123
|
* if (import.meta.hot) {
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
124
|
+
* import.meta.hot.accept(() => {
|
|
125
|
+
* update(<App />);
|
|
126
|
+
* });
|
|
127
127
|
* }
|
|
128
128
|
* ```
|
|
129
129
|
*
|
|
@@ -147,9 +147,9 @@ export const update = (element) => {
|
|
|
147
147
|
* import { quit } from "@gtkx/react";
|
|
148
148
|
*
|
|
149
149
|
* const App = () => (
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
150
|
+
* <GtkApplicationWindow title="My App" onClose={quit}>
|
|
151
|
+
* <GtkButton label="Quit" onClicked={quit} />
|
|
152
|
+
* </GtkApplicationWindow>
|
|
153
153
|
* );
|
|
154
154
|
* ```
|
|
155
155
|
*
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type * as Gdk from "@gtkx/ffi/gdk";
|
|
2
|
+
import type * as GObject from "@gtkx/ffi/gobject";
|
|
2
3
|
import type * as Gtk from "@gtkx/ffi/gtk";
|
|
3
4
|
export type Container = Gtk.Widget | Gtk.Application;
|
|
4
5
|
export type Props = Record<string, unknown>;
|
|
@@ -7,7 +8,7 @@ export type ContainerClass = typeof Gtk.Widget | typeof Gtk.Application;
|
|
|
7
8
|
* Props for EventController-based event handlers.
|
|
8
9
|
*
|
|
9
10
|
* These props attach EventControllers to widgets for handling
|
|
10
|
-
* pointer motion, clicks,
|
|
11
|
+
* pointer motion, clicks, keyboard events, and drag-and-drop.
|
|
11
12
|
*/
|
|
12
13
|
export interface EventControllerProps {
|
|
13
14
|
/** Called when the pointer enters the widget */
|
|
@@ -27,3 +28,85 @@ export interface EventControllerProps {
|
|
|
27
28
|
/** Called when the widget is scrolled */
|
|
28
29
|
onScroll?: (dx: number, dy: number) => boolean;
|
|
29
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Props for DragSource controller.
|
|
33
|
+
*
|
|
34
|
+
* Enables dragging content from a widget. Attach a DragSource to make
|
|
35
|
+
* a widget draggable.
|
|
36
|
+
*/
|
|
37
|
+
export interface DragSourceProps {
|
|
38
|
+
/**
|
|
39
|
+
* Called when a drag is about to start. Return a ContentProvider with the data
|
|
40
|
+
* to be dragged, or null to cancel the drag.
|
|
41
|
+
* @param x - X coordinate where drag started
|
|
42
|
+
* @param y - Y coordinate where drag started
|
|
43
|
+
*/
|
|
44
|
+
onDragPrepare?: (x: number, y: number) => Gdk.ContentProvider | null;
|
|
45
|
+
/**
|
|
46
|
+
* Called when the drag operation begins.
|
|
47
|
+
* @param drag - The Gdk.Drag object representing the ongoing drag
|
|
48
|
+
*/
|
|
49
|
+
onDragBegin?: (drag: Gdk.Drag) => void;
|
|
50
|
+
/**
|
|
51
|
+
* Called when the drag operation ends.
|
|
52
|
+
* @param drag - The Gdk.Drag object
|
|
53
|
+
* @param deleteData - Whether the data should be deleted (for move operations)
|
|
54
|
+
*/
|
|
55
|
+
onDragEnd?: (drag: Gdk.Drag, deleteData: boolean) => void;
|
|
56
|
+
/**
|
|
57
|
+
* Called when the drag operation is cancelled.
|
|
58
|
+
* @param drag - The Gdk.Drag object
|
|
59
|
+
* @param reason - The reason for cancellation
|
|
60
|
+
* @returns true if the cancel was handled
|
|
61
|
+
*/
|
|
62
|
+
onDragCancel?: (drag: Gdk.Drag, reason: Gdk.DragCancelReason) => boolean;
|
|
63
|
+
/**
|
|
64
|
+
* The allowed drag actions (COPY, MOVE, LINK, ASK).
|
|
65
|
+
* Defaults to Gdk.DragAction.COPY if not specified.
|
|
66
|
+
*/
|
|
67
|
+
dragActions?: Gdk.DragAction;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Props for DropTarget controller.
|
|
71
|
+
*
|
|
72
|
+
* Enables dropping content onto a widget. Attach a DropTarget to make
|
|
73
|
+
* a widget accept drops.
|
|
74
|
+
*/
|
|
75
|
+
export interface DropTargetProps {
|
|
76
|
+
/**
|
|
77
|
+
* Called when content is dropped on the widget.
|
|
78
|
+
* @param value - The dropped value (use value.getTypeName() to check type, then extract)
|
|
79
|
+
* @param x - X coordinate of drop
|
|
80
|
+
* @param y - Y coordinate of drop
|
|
81
|
+
* @returns true if the drop was accepted
|
|
82
|
+
*/
|
|
83
|
+
onDrop?: (value: GObject.Value, x: number, y: number) => boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Called when a drag enters the widget bounds.
|
|
86
|
+
* @param x - X coordinate
|
|
87
|
+
* @param y - Y coordinate
|
|
88
|
+
* @returns The preferred action, or 0 to reject
|
|
89
|
+
*/
|
|
90
|
+
onDropEnter?: (x: number, y: number) => Gdk.DragAction;
|
|
91
|
+
/**
|
|
92
|
+
* Called when a drag leaves the widget bounds.
|
|
93
|
+
*/
|
|
94
|
+
onDropLeave?: () => void;
|
|
95
|
+
/**
|
|
96
|
+
* Called when a drag moves within the widget bounds.
|
|
97
|
+
* @param x - X coordinate
|
|
98
|
+
* @param y - Y coordinate
|
|
99
|
+
* @returns The preferred action, or 0 to reject
|
|
100
|
+
*/
|
|
101
|
+
onDropMotion?: (x: number, y: number) => Gdk.DragAction;
|
|
102
|
+
/**
|
|
103
|
+
* The allowed drop actions (COPY, MOVE, LINK, ASK).
|
|
104
|
+
* Defaults to Gdk.DragAction.COPY if not specified.
|
|
105
|
+
*/
|
|
106
|
+
dropActions?: Gdk.DragAction;
|
|
107
|
+
/**
|
|
108
|
+
* Array of GTypes that this drop target accepts.
|
|
109
|
+
* Use typeFromName() to get GType values (e.g., typeFromName("gchararray") for strings).
|
|
110
|
+
*/
|
|
111
|
+
dropTypes?: number[];
|
|
112
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gtkx/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Build GTK4 desktop applications with React and TypeScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"gtkx",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"react-reconciler": "^0.33.0",
|
|
40
|
-
"@gtkx/ffi": "0.
|
|
41
|
-
"@gtkx/gir": "0.
|
|
40
|
+
"@gtkx/ffi": "0.14.0",
|
|
41
|
+
"@gtkx/gir": "0.14.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/react-reconciler": "^0.32.3"
|