Custom scene objects
Scenes comes with extensibility in mind. In addition to the library primitives, you can build your own custom scene objects that extend the basic functionality of the library. This topic describes how to create a custom object.
Create custom scene objects
Follow these steps to create a custom scene object.
Step 1. Define the state type of the custom object
Start by defining the state type for your custom object. This interface must extend the SceneObjectState
interface:
interface CounterState extends SceneObjectState {
count: number;
}
Step 2. Implement a custom object class
Implement a class for the custom scene object. This class must extend the SceneObjectBase
class:
export class Counter extends SceneObjectBase<CounterState> {
public constructor(state?: Partial<CounterState>) {
super({ count: 0, ...state });
}
}
Step 3. Implement a custom object renderer
Implement a React component that will be shown when the custom object is used in a scene. This component must use the SceneComponentProps<T extends SceneObjectBase>
type for props:
function CounterRenderer(props: SceneComponentProps<Counter>) {
return <div>Counter</div>;
}
Set a renderer for the Counter
custom object using the static Component
property:
export class Counter extends SceneObjectBase<CounterState> {
static Component = CounterRenderer;
}
Step 4. Use a custom object state in the renderer
Use the model
property passed to the component and subscribe to its state using the model.useState()
hook. Any changes to the object state will re-render the component:
function CounterRenderer({ model }: SceneComponentProps<Counter>) {
const { count } = model.useState();
return (
<div>
<div>Counter: {count}</div>
</div>
);
}
Step 5. Modify the state of the custom object from the component
Define the state-modifying method, (onIncrement
), in the custom scene object:
export class Counter extends SceneObjectBase<CounterState> {
public static Component = CounterRenderer;
public onIncrement = () => {
this.setState({ count: this.state.count + 1 });
};
}
Use the onIncrement
method in the renderer:
function CounterRenderer({ model }: SceneComponentProps<Counter>) {
const { count } = model.useState();
return (
<div>
<div>Counter: {count}</div>
<button onClick={model.onIncrement}>Increment counter</button>
</div>
);
}
Step 6. Use the custom object in a scene
Now your custom scene object, Counter
, is ready to be used in a scene. Create a scene that uses it:
const myScene = new EmbeddedScene({
body: new SceneFlexLayout({
children: [
new SceneFlexItem({
body: new Counter(),
}),
],
}),
});