@peachy/react 0.0.6 → 0.0.8
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 +27 -2
- package/dist/extra.mjs +37 -12
- package/dist/global.d.mts +8 -1
- package/dist/index.mjs +3 -1
- package/dist/utilities/children.mjs +19 -10
- package/dist/utilities/diff.mjs +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -26,7 +26,6 @@ Then setup your config file
|
|
|
26
26
|
"extends": "@peachy/react/tsconfig",
|
|
27
27
|
"include": ["@peachy/types"]
|
|
28
28
|
}
|
|
29
|
-
|
|
30
29
|
```
|
|
31
30
|
|
|
32
31
|
## Usage
|
|
@@ -73,7 +72,7 @@ app.connect("activate", () => {
|
|
|
73
72
|
|
|
74
73
|
render(
|
|
75
74
|
<Button label="Click me!" onClick={() => console.log("Button clicked")} />,
|
|
76
|
-
app_window
|
|
75
|
+
app_window,
|
|
77
76
|
);
|
|
78
77
|
|
|
79
78
|
app_window.present();
|
|
@@ -82,6 +81,32 @@ app.connect("activate", () => {
|
|
|
82
81
|
app.run([]);
|
|
83
82
|
```
|
|
84
83
|
|
|
84
|
+
### Signals
|
|
85
|
+
|
|
86
|
+
To connect signals, you can use the `on` prefix followed by the signal name and detail. For example:
|
|
87
|
+
|
|
88
|
+
> Note: For details, we use one colon (`onNotify:hasFocus`) instead of two colons as is otherwise done in GJS/GObject (`notify::has-focus`).
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
import Gtk from "gi://Gtk?version=4.0";
|
|
92
|
+
import { render } from "@peachy/react";
|
|
93
|
+
|
|
94
|
+
const Button = () => {
|
|
95
|
+
const onClicked = () => console.log("Button clicked");
|
|
96
|
+
const onFocused = () => console.log("Button focused/unfocused");
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
<Gtk.Button
|
|
100
|
+
label="Hello World"
|
|
101
|
+
onClicked={onClicked}
|
|
102
|
+
onNotify:hasFocus={onFocused}
|
|
103
|
+
/>
|
|
104
|
+
);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
app.run([]);
|
|
108
|
+
```
|
|
109
|
+
|
|
85
110
|
## References
|
|
86
111
|
|
|
87
112
|
- https://github.com/VisualElectric/pixi-react
|
package/dist/extra.mjs
CHANGED
|
@@ -3,18 +3,43 @@ import Gtk from "gi://Gtk?version=4.0";
|
|
|
3
3
|
|
|
4
4
|
//#region src/extra.ts
|
|
5
5
|
let builder;
|
|
6
|
-
const extraMap = new Map([
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
6
|
+
const extraMap = new Map([
|
|
7
|
+
[Gtk.Buildable.$gtype, { appendChild: (parentInstance, child) => {
|
|
8
|
+
builder ??= Gtk.Builder.new();
|
|
9
|
+
const metadata = getMetadata(child);
|
|
10
|
+
parentInstance.vfunc_add_child(builder, child, metadata?.childType ?? null);
|
|
11
|
+
} }],
|
|
12
|
+
[Gtk.Window.$gtype, {
|
|
13
|
+
appendChild: (parentInstance, child) => {
|
|
14
|
+
parentInstance.set_child(child);
|
|
15
|
+
},
|
|
16
|
+
removeChild: (parentInstance) => {
|
|
17
|
+
parentInstance.set_child(null);
|
|
18
|
+
}
|
|
19
|
+
}],
|
|
20
|
+
[Gtk.Overlay.$gtype, {
|
|
21
|
+
appendChild(parentInstance, child) {
|
|
22
|
+
if (getMetadata(child)?.childType === "overlay") parentInstance.add_overlay(child);
|
|
23
|
+
else parentInstance.set_child(child);
|
|
24
|
+
},
|
|
25
|
+
removeChild(parentInstance, child) {
|
|
26
|
+
if (getMetadata(child)?.childType === "overlay") parentInstance.remove_overlay(child);
|
|
27
|
+
else parentInstance.set_child(null);
|
|
28
|
+
}
|
|
29
|
+
}],
|
|
30
|
+
[Gtk.ListBox.$gtype, {
|
|
31
|
+
appendChild(parentInstance, child) {
|
|
32
|
+
parentInstance.append(child);
|
|
33
|
+
},
|
|
34
|
+
removeChild(parentInstance, child) {
|
|
35
|
+
parentInstance.remove(child);
|
|
36
|
+
},
|
|
37
|
+
insertBefore(parentInstance, child, sibling) {
|
|
38
|
+
const siblingRow = sibling instanceof Gtk.ListBoxRow ? sibling : sibling.get_ancestor(Gtk.ListBoxRow.$gtype);
|
|
39
|
+
parentInstance.insert(child, siblingRow?.get_index() ?? 0);
|
|
40
|
+
}
|
|
41
|
+
}]
|
|
42
|
+
]);
|
|
18
43
|
|
|
19
44
|
//#endregion
|
|
20
45
|
export { extraMap };
|
package/dist/global.d.mts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { Key, Ref } from "react";
|
|
2
2
|
|
|
3
3
|
//#region src/global.d.ts
|
|
4
|
+
type PascalCase<S> = S extends `${infer Head}${"-" | "_"}${infer Tail}` ? `${Capitalize<Head>}${PascalCase<Tail>}` : S extends string ? Capitalize<S> : never;
|
|
5
|
+
type SignalProps<Self extends GObject.Object> = { [S in keyof Self["$signals"] as S extends `${infer E}::${infer D}` ? // Note here that the detail `D` in ts-for-gir is a property
|
|
6
|
+
// which will most likely be incorrect for signals other that notify
|
|
7
|
+
`on${PascalCase<`${E}:${D}`>}` : S extends string ? `on${PascalCase<S>}` : never]?: GObject.SignalCallback<Self, Self["$signals"][S]> };
|
|
4
8
|
declare global {
|
|
5
9
|
namespace JSX {
|
|
6
10
|
interface IntrinsicAttributes {
|
|
@@ -8,6 +12,7 @@ declare global {
|
|
|
8
12
|
ref?: Ref<any>;
|
|
9
13
|
key?: Key | null | undefined;
|
|
10
14
|
}
|
|
15
|
+
type LibraryManagedAttributes<C, Props> = C extends typeof GObject.Object ? Props & SignalProps<InstanceType<C>> : Props;
|
|
11
16
|
}
|
|
12
17
|
}
|
|
13
18
|
declare module "gi://Gtk?version=4.0" {
|
|
@@ -33,4 +38,6 @@ declare module "gi://Gtk?version=3.0" {
|
|
|
33
38
|
}
|
|
34
39
|
}
|
|
35
40
|
}
|
|
36
|
-
}
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { PascalCase, SignalProps };
|
package/dist/index.mjs
CHANGED
|
@@ -90,7 +90,9 @@ const reconciler = Reconciler({
|
|
|
90
90
|
commitUpdate(widget, type, oldProps, newProps, internalInstanceHandle) {
|
|
91
91
|
updateWidget(widget, oldProps, newProps);
|
|
92
92
|
},
|
|
93
|
-
commitTextUpdate(textInstance, oldText, newText) {
|
|
93
|
+
commitTextUpdate(textInstance, oldText, newText) {
|
|
94
|
+
textInstance.label = newText;
|
|
95
|
+
},
|
|
94
96
|
resolveUpdatePriority: function() {
|
|
95
97
|
if (updatePriority !== NoEventPriority) return updatePriority;
|
|
96
98
|
return DefaultEventPriority;
|
|
@@ -3,26 +3,22 @@ import { getGtype } from "./type.mjs";
|
|
|
3
3
|
import GObject from "gi://GObject?version=2.0";
|
|
4
4
|
|
|
5
5
|
//#region src/utilities/children.ts
|
|
6
|
-
function
|
|
6
|
+
function appendChild(parentInstance, child) {
|
|
7
7
|
const gtype = getGtype(parentInstance);
|
|
8
8
|
for (const [type, props] of extraMap) if (GObject.type_is_a(gtype, type)) {
|
|
9
9
|
if (props.appendChild) {
|
|
10
10
|
props.appendChild(parentInstance, child);
|
|
11
|
-
return
|
|
11
|
+
return;
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
if ("child" in parentInstance) {
|
|
15
15
|
parentInstance.child = child;
|
|
16
|
-
return
|
|
16
|
+
return;
|
|
17
17
|
}
|
|
18
18
|
if ("content" in parentInstance) {
|
|
19
19
|
parentInstance.content = child;
|
|
20
|
-
return
|
|
20
|
+
return;
|
|
21
21
|
}
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
function appendChild(parentInstance, child) {
|
|
25
|
-
if (_appendChildIfPossible(parentInstance, child)) return;
|
|
26
22
|
child.set_parent(parentInstance);
|
|
27
23
|
}
|
|
28
24
|
function insertBefore(parentInstance, child, sibling) {
|
|
@@ -30,8 +26,12 @@ function insertBefore(parentInstance, child, sibling) {
|
|
|
30
26
|
for (const [type, props] of extraMap) if (GObject.type_is_a(gtype, type)) {
|
|
31
27
|
if (props.insertBefore) return props.insertBefore(parentInstance, child, sibling);
|
|
32
28
|
}
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
const children = getAllChildren(parentInstance);
|
|
30
|
+
children.forEach((child$1) => removeChild(parentInstance, child$1));
|
|
31
|
+
const childIndex = children.findIndex((c) => c === sibling);
|
|
32
|
+
if (childIndex !== -1) children.splice(childIndex, 0, child);
|
|
33
|
+
else children.push(child);
|
|
34
|
+
children.forEach((child$1) => appendChild(parentInstance, child$1));
|
|
35
35
|
}
|
|
36
36
|
function removeChild(parentInstance, child) {
|
|
37
37
|
const gtype = getGtype(parentInstance);
|
|
@@ -48,6 +48,15 @@ function removeChild(parentInstance, child) {
|
|
|
48
48
|
}
|
|
49
49
|
child.unparent();
|
|
50
50
|
}
|
|
51
|
+
function getAllChildren(parentInstance) {
|
|
52
|
+
const children = [];
|
|
53
|
+
let child = parentInstance.get_first_child();
|
|
54
|
+
while (child) {
|
|
55
|
+
children.push(child);
|
|
56
|
+
child = child.get_next_sibling();
|
|
57
|
+
}
|
|
58
|
+
return children;
|
|
59
|
+
}
|
|
51
60
|
|
|
52
61
|
//#endregion
|
|
53
62
|
export { appendChild, insertBefore, removeChild };
|
package/dist/utilities/diff.mjs
CHANGED
|
@@ -7,7 +7,7 @@ const INTERNAL_PROP_NAMES = [
|
|
|
7
7
|
"ref",
|
|
8
8
|
"key"
|
|
9
9
|
];
|
|
10
|
-
const getEventName = (event) => event.substring(2).replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "").replace(
|
|
10
|
+
const getEventName = (event) => event.substring(2).replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "").replace(/:-?/, "::");
|
|
11
11
|
const isEvent = (key) => key.startsWith("on");
|
|
12
12
|
const isProperty = (key) => key !== "children" && !isEvent(key) && !INTERNAL_PROP_NAMES.includes(key);
|
|
13
13
|
const isNew = (prev, next) => (key) => prev[key] !== next[key];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peachy/react",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "Run GJS applications with react",
|
|
5
5
|
"main": "./dist/index.mjs",
|
|
6
6
|
"exports": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"react": "^19.2.3",
|
|
21
21
|
"react-reconciler": "^0.33.0",
|
|
22
22
|
"reflect-metadata": "^0.2.2",
|
|
23
|
-
"@peachy/core": "0.0.
|
|
23
|
+
"@peachy/core": "0.0.8"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/react": "^19.2.8",
|