Custom Elements#
Use registerElement and createComponent to turn any C# VisualElement subclass into a React component.
Import#
import { registerElement, createComponent } from "onejs-react"Defining a Custom Element#
Create a C# class that inherits from VisualElement:
using UnityEngine.UIElements;
public class RadialProgress : VisualElement {
public float progress { get; set; }
public string trackColor { get; set; }
public float lineWidth { get; set; } = 4f;
}Registration#
Register the element once at the top of your entry file. The first argument is a name for the element. The second is the C# constructor via the CS proxy.
registerElement("radial-progress", CS.RadialProgress)For types inside a namespace:
registerElement("health-bar", CS.MyGame.UI.HealthBar)Creating a Component#
Use createComponent to get a typed React component:
import type { BaseProps } from "onejs-react"
interface RadialProgressProps extends BaseProps {
progress?: number
trackColor?: string
lineWidth?: number
}
const RadialProgress = createComponent<RadialProgressProps>("radial-progress")Then use it like any built-in component:
<RadialProgress
progress={0.75}
trackColor="#3498db"
lineWidth={6}
style={{ width: 100, height: 100 }}
className="my-progress"
/>How Props Work#
Standard React props are handled by the reconciler automatically. Everything else is forwarded directly to the C# element as property assignments.
| Prop Type | Handled By | Example |
|---|---|---|
style | Reconciler | style={{ width: 100 }} |
className | Reconciler | className="my-class" |
| Events | Reconciler | onClick={handler} |
ref | Reconciler | ref={myRef} |
| Custom props | C# element | progress={0.75} |
Events#
Event handlers work the same as built-in components:
<RadialProgress
progress={0.5}
onClick={(e) => console.log("Clicked at", e.x, e.y)}
onPointerEnter={() => console.log("Hover")}
/>See Events for the full list of supported event props.
Refs#
Refs point to the underlying C# element:
import { useRef, useEffect } from "react"
function MyComponent() {
const ref = useRef(null)
useEffect(() => {
if (ref.current) {
console.log(ref.current.GetType().Name) // "RadialProgress"
ref.current.MarkDirtyRepaint()
}
}, [])
return <RadialProgress ref={ref} progress={0.5} />
}See Refs for more on working with element references.
Complete Example#
Putting it all together:
import { registerElement, createComponent, render, View, Label } from "onejs-react"
import type { BaseProps } from "onejs-react"
import { useState } from "react"
// Define props
interface HealthBarProps extends BaseProps {
current?: number
max?: number
barColor?: string
}
// Register and create component
registerElement("health-bar", CS.MyGame.UI.HealthBar)
const HealthBar = createComponent<HealthBarProps>("health-bar")
// Use in your app
function PlayerHUD() {
const [hp, setHp] = useState(80)
return (
<View style={{ padding: 16 }}>
<Label text={`HP: ${hp}/100`} />
<HealthBar
current={hp}
max={100}
barColor="#e74c3c"
style={{ width: 200, height: 20 }}
/>
</View>
)
}
render(<PlayerHUD />, __root)