Custom components
Add your own React component and use it in schemas by name.
registerComponent
Any React component can be used in schemas: registerComponent("Stat", Stat) and then { type: "Stat", props: { ... } }. Its props come from the node's props.
A container ({ container: true }) receives node and renderNodes; draw the children with renderNodes(node.children) — fields inside keep working.
A field ({ field: true }) must forwardRef to an input that holds its value and call onChange when it changes; then required, values, onChange actions and onSubmit work like built-in fields.
Register once, at the top of a file that runs before the form (e.g. a components.js you import in the page). The Components tab has the code.
Try it
Code
Copy Full page.js into app/your-page/page.js of a Next.js app (withrcube-html, react-bootstrap and Bootstrap's CSS installed) — it runs as is. Or copy only the schema and keep your own page.
[
{
"type": "row",
"id": "row-stats",
"props": {
"className": "g-3"
},
"children": [
{
"type": "column",
"id": "c-s1",
"props": {
"className": "col-6 col-md-4"
},
"children": [
{
"type": "Stat",
"id": "stat-users",
"props": {
"label": "Users",
"value": "1,284",
"trend": "+12%"
}
}
]
},
{
"type": "column",
"id": "c-s2",
"props": {
"className": "col-6 col-md-4"
},
"children": [
{
"type": "Stat",
"id": "stat-orders",
"props": {
"label": "Orders",
"value": "342",
"trend": "-3%"
}
}
]
},
{
"type": "column",
"id": "c-s3",
"props": {
"className": "col-12 col-md-4"
},
"children": [
{
"type": "Stat",
"id": "stat-revenue",
"props": {
"label": "Revenue",
"value": "$18.2K",
"trend": "+8%"
}
}
]
}
]
},
{
"type": "row",
"id": "row-panel",
"children": [
{
"type": "column",
"id": "c-panel",
"children": [
{
"type": "Panel",
"id": "feedback",
"props": {
"title": "Feedback (a custom container)"
},
"children": [
{
"type": "RatingField",
"id": "rating",
"props": {
"name": "rating",
"label": "How did we do?",
"required": true,
"onChange": "ratingChanged()"
}
},
{
"type": "TextareaField",
"id": "comment",
"props": {
"name": "comment",
"label": "Comment",
"rows": 2
}
}
]
},
{
"type": "ButtonField",
"id": "send",
"props": {
"type": "submit",
"text": "Send",
"onClick": "runValidation()"
}
},
{
"type": "ButtonField",
"id": "bump",
"props": {
"text": "Update a Stat from code",
"variant": "outline-secondary",
"className": "ms-2",
"onClick": "bumpUsers()"
}
}
]
}
]
}
]Options used here
| Option | What it does |
|---|---|
registerComponent(name, Component) | Use Component as { type: name }. |
{ container: true } | Receives node, nodeId, items, renderNodes, actions. |
{ field: true } | forwardRef to the value input; receives name, label, error, onChange, required, ... |
Events
| Event | When it runs | Your action receives |
|---|---|---|
onChange (custom field) | Your field calls onChange. | (event, { name, value }) |
onSubmit | Valid submit — the rating is required. | [{ rating: "4", comment: "..." }] |