@ringozz/react-godot 1.0.0-7 → 1.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 CHANGED
@@ -153,6 +153,16 @@ useSignal(root.windowInput, (event) => {
153
153
  });
154
154
  ```
155
155
 
156
+ Signal **JSX props** (`pressed`, `toggled`, `valueChanged`, `textSubmitted`, ...) are typed as the signal's callback — pass a plain function, no cast needed:
157
+
158
+ ```tsx
159
+ <Button text="Play" pressed={() => start()} />
160
+ <CheckButton text="Debug" toggled={(on) => setDebug(on)} />
161
+ <HSlider value={round} valueChanged={(v) => setRound(v)} />
162
+ ```
163
+
164
+ `ComponentProps` only exposes writable members: read-only props (e.g. `Node.multiplayer`) and methods are not settable props.
165
+
156
166
  ## Full Example
157
167
 
158
168
  Below is a complete interactive 3D physics scene with custom camera controls and physics bodies:
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ringozz/react-godot",
3
3
  "author": "Vladimir Davidovich",
4
- "version": "1.0.0-7",
4
+ "version": "1.0.0-8",
5
5
  "description": "A React renderer for Godot Engine via @ringozz/godot",
6
6
  "keywords": [
7
7
  "react",
@@ -1,39 +1,52 @@
1
- /**********************************************************************
2
- Copyright (c) Vladimir Davidovich. All rights reserved.
3
- ***********************************************************************/
4
-
5
- import type React from 'react';
6
- import type { Object } from '@ringozz/godot/Object';
7
- import type { ValueTypes } from '@ringozz/godot';
8
- import type { PackedScene } from '@ringozz/godot/PackedScene';
9
-
10
- type FunctionKeys<T> = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T];
11
- type Properties<T> = Omit<T, FunctionKeys<T>>;
12
- type Overwrite<P, O> = Properties<P> & O;
13
- type Mutable<P> = { [K in keyof P]: P[K] | Readonly<P[K]> };
14
- type ConstructorRepresentation<T = any> = new (...args: any[]) => T;
15
-
16
- export type Instance = Object;
17
-
18
- export type GodotConstructor<T extends Instance = Instance> = ConstructorRepresentation<T> & Function;
19
-
20
- export type InstanceProps<T extends Instance = Instance> = {
21
- /** An existing instance to render instead of creating a new one. */
22
- object?: T | PackedScene;
23
- /** Attaches the element to a named property of the parent instead of adding it as a child. */
24
- attach?: string;
25
- };
26
-
27
- type ReactProps<P> = React.PropsWithChildren<React.RefAttributes<P>>;
28
-
29
- type WidenVT<T> = {
30
- [K in keyof T]: T[K] extends ValueTypes ? T[K] | number[] : T[K];
31
- };
32
-
33
- type ElementProps<T extends GodotConstructor, P = InstanceType<T>> = Partial<
34
- Overwrite<WidenVT<P>, ReactProps<P>>
35
- >;
36
-
37
- export type ComponentProps<T extends GodotConstructor> = Mutable<
38
- Overwrite<ElementProps<T>, InstanceProps<InstanceType<T>>>
39
- >;
1
+ /**********************************************************************
2
+ Copyright (c) Vladimir Davidovich. All rights reserved.
3
+ ***********************************************************************/
4
+
5
+ import type React from 'react';
6
+ import type { Object } from '@ringozz/godot/Object';
7
+ import type { Signal, ValueTypes } from '@ringozz/godot';
8
+ import type { PackedScene } from '@ringozz/godot/PackedScene';
9
+
10
+ // Identity check sensitive to readonly (deferred-conditional trick; the
11
+ // comparison lives in return-type position, so it is independent of
12
+ // strictFunctionTypes).
13
+ type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends
14
+ (<T>() => T extends Y ? 1 : 2) ? true : false;
15
+
16
+ type ConstructorRepresentation<T = any> = new (...args: any[]) => T;
17
+
18
+ export type Instance = Object;
19
+
20
+ export type GodotConstructor<T extends Instance = Instance> = ConstructorRepresentation<T> & Function;
21
+
22
+ export type InstanceProps<T extends Instance = Instance> = {
23
+ /** An existing instance to render instead of creating a new one. */
24
+ object?: T | PackedScene;
25
+ /** Attaches the element to a named property of the parent instead of adding it as a child. */
26
+ attach?: string;
27
+ };
28
+
29
+ type ReactProps<P> = React.PropsWithChildren<React.RefAttributes<P>>;
30
+
31
+ // Settable, non-method keys. `Pick<T, K>` preserves the readonly modifier, so
32
+ // getter-only (read-only) props, e.g. Node.multiplayer, compare unequal to
33
+ // their `-readonly` copy and drop out; write-only accessors pass through with
34
+ // their setter parameter type.
35
+ type SettableKey<T, K extends keyof T> =
36
+ Equal<Pick<T, K>, { -readonly [P in K]: T[K] }> extends true
37
+ ? (T[K] extends Function ? never : K)
38
+ : never;
39
+
40
+ // JSX props are settable instance members, typed as the setter accepts them:
41
+ // ValueTypes also accept JSX arrays, and signals (getter `Signal<CB>`, setter
42
+ // `CB | null`) take the callback directly. Maps over `keyof T` (homomorphic)
43
+ // so optional/readonly modifiers survive.
44
+ type Properties<T> = {
45
+ [K in keyof T as SettableKey<T, K>]:
46
+ T[K] extends ValueTypes ? T[K] | number[]
47
+ : T[K] extends Signal<infer CB> ? CB | null
48
+ : T[K];
49
+ };
50
+
51
+ export type ComponentProps<T extends GodotConstructor, P extends Instance = InstanceType<T>> =
52
+ Partial<Properties<P> & ReactProps<P>> & InstanceProps<P>;