diff --git a/packages/example/src/TestUi1Component.tsx b/packages/example/src/TestUi1Component.tsx
index 0ce2432..fc5dc3a 100644
--- a/packages/example/src/TestUi1Component.tsx
+++ b/packages/example/src/TestUi1Component.tsx
@@ -1,13 +1,37 @@
-import Godot from "godot"
+import Godot, { Vector2 } from "godot"
+import { useEffect } from "react"
import { Component } from "react-godot-renderer"
-const Control = Component.make(Godot.Control)
+const HFlowContainer = Component.make(Godot.HFlowContainer)
const Label = Component.make(Godot.Label)
+const TextEdit = Component.make(Godot.TextEdit)
+const Button = Component.make(Godot.Button)
export function TestUi1Component() {
+ const textEditRef = TextEdit.useUnsafeRef()
+ const buttonRef = Button.useUnsafeRef()
+
+ useEffect(() => {
+ const onTextChanged = Godot.Callable.create(() => {
+ console.log(textEditRef.current.text)
+ })
+
+ textEditRef.current.text_changed.connect(onTextChanged)
+ return () => { textEditRef.current.text_changed.disconnect(onTextChanged) }
+ }, [textEditRef.current])
+
+ useEffect(() => {
+ const onPressed = Godot.Callable.create(() => {
+ console.log("Pressed!")
+ })
+
+ buttonRef.current.pressed.connect(onPressed)
+ return () => { buttonRef.current.pressed.disconnect(onPressed) }
+ }, [buttonRef.current])
+
return (
-
-
-
+
+
+
+
)
}
diff --git a/packages/react-godot-renderer/src/Component.ts b/packages/react-godot-renderer/src/Component.ts
index 6397c37..2dacedf 100644
--- a/packages/react-godot-renderer/src/Component.ts
+++ b/packages/react-godot-renderer/src/Component.ts
@@ -2,21 +2,37 @@ import type * as Godot from "godot"
import * as React from "react"
-export type Component> = React.FunctionComponent>
+export interface Component>
+extends React.FunctionComponent>, Prototype {}
+
export type Props> = {
+ readonly ref?: React.RefObject
+} & {
// biome-ignore lint/complexity/noBannedTypes: using Function here is completely fine
[K in keyof T as T[K] extends Function ? never : K]?: T[K]
}
-export interface InstrinsicAttributes {
+export interface Prototype> {
+ useRef(): React.RefObject
+ useUnsafeRef(): React.RefObject
+}
+
+export interface InstrinsicAttributes extends React.Attributes {
readonly children?: React.ReactNode
readonly name?: string
}
+export const Prototype: Prototype = {
+ useRef() { return React.useRef(null) },
+ useUnsafeRef() { return React.useRef(null) },
+}
+
export const make = >(
class_: new (...args: any[]) => T
-): Component => {
- const f = (props: Props) => React.createElement("element", { ...props, class: class_ })
- f.displayName = class_.name
- return f
-}
+): Component => Object.setPrototypeOf(
+ Object.assign(
+ (props: Props) => React.createElement("element", { ...props, class: class_ }),
+ { displayName: class_.name },
+ ),
+ Prototype,
+)
diff --git a/packages/react-godot-renderer/src/Renderer.ts b/packages/react-godot-renderer/src/Renderer.ts
index aa7bf0c..76248f4 100644
--- a/packages/react-godot-renderer/src/Renderer.ts
+++ b/packages/react-godot-renderer/src/Renderer.ts
@@ -19,7 +19,7 @@ export const renderComponent: {
} = (
container: Node,
component: React.FC<{}>,
- props?: React.Attributes,
+ props?: Record,
): void => {
const reconciler = Reconciler.make()