ngx-json-render UI
Renders dashboards, forms and tables inline in the chat as Angular Material components (MCP App).
Should I use this
Quality & Safety
Findings (1)
- LOWin render-ui
Based on automated analysis of tool definitions and protocol compliance.
Context Cost
This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.
Install
One-Click Install
Add this to your `claude_desktop_config.json` file:
{
"mcpServers": {
"ngx-json-render-ui": {
"url": "https://ngx-json-render.vercel.app/mcp"
}
}
}Remote endpoints
https://ngx-json-render.vercel.app/mcpstreamable-httpWhat it can do
Tool inventory
Tools (1)
🟢render-ui(spec)
Render an interactive Angular Material UI inline in the chat. Pass `spec`: one complete json-render spec object (not JSON Patch lines). The input schema lists every component, its props and allowed values, and every action; use only those. - `root` is the key of the top element. `elements` is a flat map of key → { type, props, children: [child keys] }; every child key must exist in `elements`. - `state` holds the data. Read it with {"$state":"/path"} rather than repeating values in props. Data-backed UI always needs `state`; use realistic sample data. - A prop can be dynamic: {"$state":"/p"} reads, {"$bindState":"/p"} binds a form field both ways, {"$template":"Hi ${/name}"} interpolates, {"$cond":{"$state":"/p"},"$then":a,"$else":b} picks. - Lists: on a container, "repeat":{"statePath":"/items","key":"id"}; its children render once per item and read {"$item":"field"}, or ${field} inside a $template. - `visible` and `on` sit next to `props`, never inside: "visible":{"$state":"/tab","eq":"home"}, "on":{"press":{"action":"setState","params":{"statePath":"/tab","value":"home"}}}. - Forms: give inputs props.validation {"checks":[{"type":"required","message":"..."}]} and submit with submitForm, which runs its inner action only when every field is valid. - To continue the conversation from a button, use sendMessage: {"action":"sendMessage","params":{"text":"Approve release 2.4.0","data":{"$state":"/release"}}}. The host puts `text` (and `data` as JSON) in the chat as the user's message, so write it in their voice. For a form: {"action":"submitForm","params":{"action":"sendMessage","params":{"text":"Sign me up","data":{"$state":"/form"}}}}.
Input Schema
{
"type": "object",
"properties": {
"spec": {
"type": "object",
"properties": {
"root": {
"type": "string",
"description": "Key of the top element in `elements`."
},
"elements": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"oneOf": [
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Stack"
},
"props": {
"type": "object",
"properties": {
"direction": {
"anyOf": [
{
"type": "string",
"enum": [
"vertical",
"horizontal"
]
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"gap": {
"anyOf": [
{
"type": "number"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"padding": {
"anyOf": [
{
"type": "number"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"align": {
"anyOf": [
{
"type": "string",
"enum": [
"start",
"center",
"end",
"stretch"
]
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"justify": {
"anyOf": [
{
"type": "string",
"enum": [
"start",
"center",
"between",
"end"
]
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"wrap": {
"anyOf": [
{
"type": "boolean"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Stack: Layout container that stacks children vertically or horizontally. The primary building block — use it for every group of elements."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Grid"
},
"props": {
"type": "object",
"properties": {
"columns": {
"anyOf": [
{
"type": "number",
"minimum": 1,
"maximum": 6
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"gap": {
"anyOf": [
{
"type": "number"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Grid: Responsive grid that places children in equal columns, collapsing to one column on narrow screens. Use for dashboards and card galleries."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Card"
},
"props": {
"type": "object",
"properties": {
"title": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"subtitle": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"appearance": {
"anyOf": [
{
"type": "string",
"enum": [
"outlined",
"raised",
"filled"
]
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Card: Material card with an optional title/subtitle header and an \"actions\" slot rendered as a footer button row."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Toolbar"
},
"props": {
"type": "object",
"properties": {
"title": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"color": {
"anyOf": [
{
"type": "string",
"enum": [
"primary",
"accent",
"warn"
]
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Toolbar: Material toolbar for a page or section header. Children are placed at the trailing edge."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "ExpansionPanel"
},
"props": {
"type": "object",
"properties": {
"title": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"expanded": {
"anyOf": [
{
"type": "boolean"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"required": [
"title"
],
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "ExpansionPanel: Collapsible Material panel. Use for secondary detail that should not compete with the main content."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Tabs"
},
"props": {
"type": "object",
"properties": {},
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Tabs: Material tab group. Children MUST all be Tab components; each Tab supplies one tab and its body."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Tab"
},
"props": {
"type": "object",
"properties": {
"label": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"required": [
"label"
],
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Tab: A single tab inside a Tabs component. Valid only as a direct child of Tabs."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Divider"
},
"props": {
"type": "object",
"properties": {},
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Divider: Horizontal Material divider."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Heading"
},
"props": {
"type": "object",
"properties": {
"content": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"level": {
"anyOf": [
{
"type": "number",
"minimum": 1,
"maximum": 3
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"required": [
"content"
],
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Heading: Section heading (level 1–3) using the Material type scale."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Text"
},
"props": {
"type": "object",
"properties": {
"content": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"tone": {
"anyOf": [
{
"type": "string",
"enum": [
"default",
"muted",
"strong"
]
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"required": [
"content"
],
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Text: A paragraph of body text; \"\\n\" in content starts a new line."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Icon"
},
"props": {
"type": "object",
"properties": {
"name": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"color": {
"anyOf": [
{
"type": "string",
"enum": [
"primary",
"accent",
"warn"
]
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"required": [
"name"
],
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Icon: Material Symbols icon. `name` is the ligature, e.g. \"home\", \"check_circle\", \"warning\"."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Metric"
},
"props": {
"type": "object",
"properties": {
"label": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"value": {
"anyOf": [
{
"type": [
"string",
"number"
]
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"delta": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"trend": {
"anyOf": [
{
"type": "string",
"enum": [
"up",
"down",
"flat"
]
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"required": [
"label",
"value"
],
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Metric: Key metric tile with an optional delta and trend direction. Use inside a Grid for dashboard summaries."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Chip"
},
"props": {
"type": "object",
"properties": {
"label": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"color": {
"anyOf": [
{
"type": "string",
"enum": [
"primary",
"accent",
"warn"
]
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"icon": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"required": [
"label"
],
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Chip: Material chip, for tags and status labels."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "List"
},
"props": {
"type": "object",
"properties": {},
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "List: Material list container. Children MUST all be ListItem components."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "ListItem"
},
"props": {
"type": "object",
"properties": {
"title": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"icon": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"required": [
"title"
],
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "ListItem: Row inside a List. Emits a 'press' event when clicked. Valid only as a direct child of List."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Table"
},
"props": {
"type": "object",
"properties": {
"columns": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"properties": {
"field": {
"type": "string"
},
"header": {
"type": "string"
},
"align": {
"type": "string",
"enum": [
"start",
"end"
]
}
},
"required": [
"field",
"header"
]
}
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"rows": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"required": [
"columns",
"rows"
],
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Table: Material table. `columns` describes the header; `rows` is an array of objects keyed by each column's `field`. Bind `rows` to a state array with {\"$state\":\"/path\"} rather than using repeat."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Button"
},
"props": {
"type": "object",
"properties": {
"label": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"variant": {
"anyOf": [
{
"type": "string",
"enum": [
"text",
"filled",
"elevated",
"outlined",
"tonal"
]
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"color": {
"anyOf": [
{
"type": "string",
"enum": [
"primary",
"accent",
"warn"
]
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"icon": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"disabled": {
"anyOf": [
{
"type": "boolean"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"required": [
"label"
],
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Button: Material button that emits a 'press' event. `variant` follows the Material 3 button appearances; use \"filled\" for the primary action on a screen and \"text\" for secondary ones. Put the action in the element's `on.press`, never in props."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "IconButton"
},
"props": {
"type": "object",
"properties": {
"icon": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"label": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"color": {
"anyOf": [
{
"type": "string",
"enum": [
"primary",
"accent",
"warn"
]
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"disabled": {
"anyOf": [
{
"type": "boolean"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"required": [
"icon",
"label"
],
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "IconButton: Icon-only Material button that emits a 'press' event. `label` is the accessible name and is required; it is also shown as a tooltip on hover and focus."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Input"
},
"props": {
"type": "object",
"properties": {
"label": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"value": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"placeholder": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"hint": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"type": {
"anyOf": [
{
"type": "string",
"enum": [
"text",
"number",
"email",
"password"
]
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"required": {
"anyOf": [
{
"type": "boolean"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"disabled": {
"anyOf": [
{
"type": "boolean"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"validation": {
"anyOf": [
{
"type": "object",
"properties": {
"checks": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"args": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"type": "string"
},
{
"type": "number"
},
{
"type": "boolean"
},
{
"type": "null"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
}
},
"message": {
"type": "string"
}
},
"required": [
"type",
"message"
]
}
},
"validateOn": {
"type": "string",
"enum": [
"change",
"blur",
"submit"
]
},
"enabled": {
"allOf": [
{
"$ref": "#/definitions/__schema0"
}
]
}
}
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Input: Material text field. Bind `value` with {\"$bindState\":\"/path\"} for two-way binding; emits 'submit' on Enter. `required` only draws the asterisk — enforcement comes from `validation`. Validate it with `validation`: {\"checks\":[{\"type\":\"required\",\"message\":\"...\"}],\"validateOn\":\"blur\"}. Check types: required, requiredIf, email, url, numeric, minLength, maxLength, pattern, min, max, matches, equalTo, lessThan, greaterThan. Args go in `args` (e.g. {\"type\":\"minLength\",\"args\":{\"min\":8},\"message\":\"...\"}). Validation needs a bound value. The built-in validateForm action checks every bound field at once, and submitForm checks them and then dispatches your submit action only if they all pass."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Textarea"
},
"props": {
"type": "object",
"properties": {
"label": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"value": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"placeholder": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"rows": {
"anyOf": [
{
"type": "number"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"disabled": {
"anyOf": [
{
"type": "boolean"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"validation": {
"anyOf": [
{
"type": "object",
"properties": {
"checks": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"args": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"type": "string"
},
{
"type": "number"
},
{
"type": "boolean"
},
{
"type": "null"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
}
},
"message": {
"type": "string"
}
},
"required": [
"type",
"message"
]
}
},
"validateOn": {
"type": "string",
"enum": [
"change",
"blur",
"submit"
]
},
"enabled": {
"allOf": [
{
"$ref": "#/definitions/__schema0"
}
]
}
}
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Textarea: Multi-line Material text field. Bind `value` with {\"$bindState\":\"/path\"}. Validate it with `validation`: {\"checks\":[{\"type\":\"required\",\"message\":\"...\"}],\"validateOn\":\"blur\"}. Check types: required, requiredIf, email, url, numeric, minLength, maxLength, pattern, min, max, matches, equalTo, lessThan, greaterThan. Args go in `args` (e.g. {\"type\":\"minLength\",\"args\":{\"min\":8},\"message\":\"...\"}). Validation needs a bound value. The built-in validateForm action checks every bound field at once, and submitForm checks them and then dispatches your submit action only if they all pass."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Select"
},
"props": {
"type": "object",
"properties": {
"label": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"value": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"options": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"properties": {
"value": {
"type": "string"
},
"label": {
"type": "string"
}
},
"required": [
"value",
"label"
]
}
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"disabled": {
"anyOf": [
{
"type": "boolean"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"validation": {
"anyOf": [
{
"type": "object",
"properties": {
"checks": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"args": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"type": "string"
},
{
"type": "number"
},
{
"type": "boolean"
},
{
"type": "null"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
}
},
"message": {
"type": "string"
}
},
"required": [
"type",
"message"
]
}
},
"validateOn": {
"type": "string",
"enum": [
"change",
"blur",
"submit"
]
},
"enabled": {
"allOf": [
{
"$ref": "#/definitions/__schema0"
}
]
}
}
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"required": [
"options"
],
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Select: Material select. Bind `value` with {\"$bindState\":\"/path\"}; `options` is an explicit list. Validate it with `validation`: {\"checks\":[{\"type\":\"required\",\"message\":\"...\"}],\"validateOn\":\"blur\"}. Check types: required, requiredIf, email, url, numeric, minLength, maxLength, pattern, min, max, matches, equalTo, lessThan, greaterThan. Args go in `args` (e.g. {\"type\":\"minLength\",\"args\":{\"min\":8},\"message\":\"...\"}). Validation needs a bound value. The built-in validateForm action checks every bound field at once, and submitForm checks them and then dispatches your submit action only if they all pass."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Checkbox"
},
"props": {
"type": "object",
"properties": {
"label": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"checked": {
"anyOf": [
{
"type": "boolean"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"disabled": {
"anyOf": [
{
"type": "boolean"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"validation": {
"anyOf": [
{
"type": "object",
"properties": {
"checks": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"args": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"type": "string"
},
{
"type": "number"
},
{
"type": "boolean"
},
{
"type": "null"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
}
},
"message": {
"type": "string"
}
},
"required": [
"type",
"message"
]
}
},
"validateOn": {
"type": "string",
"enum": [
"change",
"blur",
"submit"
]
},
"enabled": {
"allOf": [
{
"$ref": "#/definitions/__schema0"
}
]
}
}
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"required": [
"label"
],
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Checkbox: Material checkbox. Bind `checked` with {\"$bindState\":\"/path\"} or {\"$bindItem\":\"field\"} inside a repeat. Validate it with `validation`: {\"checks\":[{\"type\":\"required\",\"message\":\"...\"}],\"validateOn\":\"blur\"}. Check types: required, requiredIf, email, url, numeric, minLength, maxLength, pattern, min, max, matches, equalTo, lessThan, greaterThan. Args go in `args` (e.g. {\"type\":\"minLength\",\"args\":{\"min\":8},\"message\":\"...\"}). Validation needs a bound value. The built-in validateForm action checks every bound field at once, and submitForm checks them and then dispatches your submit action only if they all pass."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "RadioGroup"
},
"props": {
"type": "object",
"properties": {
"label": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"value": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"options": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"properties": {
"value": {
"type": "string"
},
"label": {
"type": "string"
}
},
"required": [
"value",
"label"
]
}
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"direction": {
"anyOf": [
{
"type": "string",
"enum": [
"vertical",
"horizontal"
]
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"validation": {
"anyOf": [
{
"type": "object",
"properties": {
"checks": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"args": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"type": "string"
},
{
"type": "number"
},
{
"type": "boolean"
},
{
"type": "null"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
}
},
"message": {
"type": "string"
}
},
"required": [
"type",
"message"
]
}
},
"validateOn": {
"type": "string",
"enum": [
"change",
"blur",
"submit"
]
},
"enabled": {
"allOf": [
{
"$ref": "#/definitions/__schema0"
}
]
}
}
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"required": [
"options"
],
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "RadioGroup: Material radio group. Bind `value` with {\"$bindState\":\"/path\"}. Validate it with `validation`: {\"checks\":[{\"type\":\"required\",\"message\":\"...\"}],\"validateOn\":\"blur\"}. Check types: required, requiredIf, email, url, numeric, minLength, maxLength, pattern, min, max, matches, equalTo, lessThan, greaterThan. Args go in `args` (e.g. {\"type\":\"minLength\",\"args\":{\"min\":8},\"message\":\"...\"}). Validation needs a bound value. The built-in validateForm action checks every bound field at once, and submitForm checks them and then dispatches your submit action only if they all pass."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "SlideToggle"
},
"props": {
"type": "object",
"properties": {
"label": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"checked": {
"anyOf": [
{
"type": "boolean"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"disabled": {
"anyOf": [
{
"type": "boolean"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"required": [
"label"
],
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "SlideToggle: Material slide toggle for on/off settings. Bind `checked` with {\"$bindState\":\"/path\"}."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Slider"
},
"props": {
"type": "object",
"properties": {
"label": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"value": {
"anyOf": [
{
"type": "number"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"min": {
"anyOf": [
{
"type": "number"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"max": {
"anyOf": [
{
"type": "number"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"step": {
"anyOf": [
{
"type": "number"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Slider: Material slider for a numeric range. Bind `value` with {\"$bindState\":\"/path\"}."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "ProgressBar"
},
"props": {
"type": "object",
"properties": {
"value": {
"anyOf": [
{
"type": "number"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"mode": {
"anyOf": [
{
"type": "string",
"enum": [
"determinate",
"indeterminate"
]
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"color": {
"anyOf": [
{
"type": "string",
"enum": [
"primary",
"accent",
"warn"
]
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "ProgressBar: Material progress bar (0–100). Use mode \"indeterminate\" when the amount of work is unknown."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Spinner"
},
"props": {
"type": "object",
"properties": {
"diameter": {
"anyOf": [
{
"type": "number"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"color": {
"anyOf": [
{
"type": "string",
"enum": [
"primary",
"accent",
"warn"
]
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Spinner: Material indeterminate progress spinner, for loading states."
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "Callout"
},
"props": {
"type": "object",
"properties": {
"title": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"content": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"severity": {
"anyOf": [
{
"type": "string",
"enum": [
"info",
"success",
"warning",
"error"
]
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"required": [
"content"
],
"additionalProperties": false
},
"children": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"visible": {
"allOf": [
{
"$ref": "#/definitions/Visibility"
}
]
},
"repeat": {
"allOf": [
{
"$ref": "#/definitions/Repeat"
}
]
},
"on": {
"allOf": [
{
"$ref": "#/definitions/Events"
}
]
},
"watch": {
"allOf": [
{
"$ref": "#/definitions/Watchers"
}
]
}
},
"required": [
"type",
"props"
],
"additionalProperties": false,
"description": "Callout: Inline message block for informational, success, warning, or error text."
}
]
}
},
"state": {
"description": "Initial state model; bindings read it with {\"$state\": \"/path\"}.",
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
},
"required": [
"root",
"elements"
],
"additionalProperties": false
}
},
"required": [
"spec"
],
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"DynamicValue": {
"type": "object",
"properties": {},
"additionalProperties": {},
"description": "Dynamic value: {\"$state\"}, {\"$bindState\"}, {\"$bindItem\"}, {\"$item\"}, {\"$index\"}, {\"$template\"} or {\"$cond\",\"$then\",\"$else\"}."
},
"Visibility": {
"description": "Show the element only when this holds: {\"$state\":\"/p\",\"eq\":v} (or neq, gt, gte, lt, lte, not), an array of conditions (all), {\"$or\":[...]}, true or false."
},
"Repeat": {
"type": "object",
"properties": {
"statePath": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"key": {
"type": "string"
}
},
"required": [
"statePath"
],
"additionalProperties": false,
"description": "Render the children once per item of the state array at statePath; they read {\"$item\":\"field\"} and {\"$index\":true}."
},
"Events": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"$ref": "#/definitions/ActionBinding"
},
{
"type": "array",
"items": {
"$ref": "#/definitions/ActionBinding"
}
}
]
},
"description": "Event name (such as \"press\", \"change\" or \"submit\") → action binding."
},
"ActionBinding": {
"oneOf": [
{
"type": "object",
"properties": {
"action": {
"type": "string",
"const": "sendMessage"
},
"params": {
"type": "object",
"properties": {
"text": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/DynamicValue"
}
]
},
"data": {
"anyOf": [
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
{
"$ref": "#/definitions/DynamicValue"
}
]
}
},
"required": [
"text"
],
"additionalProperties": false
},
"confirm": {},
"onSuccess": {},
"onError": {},
"preventDefault": {
"type": "boolean"
}
},
"required": [
"action",
"params"
],
"additionalProperties": false,
"description": "sendMessage: Send a message to you, the assistant, as the user, so the conversation continues from the UI. Params: { \"text\": \"what the user chose or asks for\", \"data\"?: { \"$state\": \"/path\" } }. `data` is optional and is attached as JSON; make it a single reference to a state object, because references nested inside `data` are not resolved. Use it for choices and follow-ups (\"Approve\", \"Show more\", a picked option). To send a form, gate it with submitForm: { \"action\": \"submitForm\", \"params\": { \"action\": \"sendMessage\", \"params\": { \"text\": \"Submit the sign-up form\", \"data\": { \"$state\": \"/form\" } } } }. The host puts the message in the chat as the user's (Claude lets the user review it and send it), so write `text` in their voice."
},
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"setState",
"pushState",
"removeState",
"validateForm",
"submitForm"
]
},
"params": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"confirm": {},
"onSuccess": {},
"onError": {},
"preventDefault": {
"type": "boolean"
}
},
"required": [
"action"
],
"additionalProperties": false,
"description": "setState: Update a value in the state model at the given statePath. Params: { statePath: string, value: any }\npushState: Append an item to an array in state. Params: { statePath: string, value: any, clearStatePath?: string }. Value can contain {\"$state\":\"/path\"} refs and \"$id\" for auto IDs.\nremoveState: Remove an item from an array in state by index. Params: { statePath: string, index: number }\nvalidateForm: Validate all registered form fields and write the result to state. Params: { statePath?: string }. Defaults to /formValidation. Result: { valid: boolean, errors: Record<string, string[]> }.\nsubmitForm: Validate all registered form fields and, only if every one passes, dispatch another action. Params: { action: string, params?: object, statePath?: string }. Writes the same { valid, errors } result as validateForm. Use this on a form's submit button: it is validateForm and the submit in one binding, and the submit is skipped when the form is invalid."
}
]
},
"Watchers": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"$ref": "#/definitions/ActionBinding"
},
{
"type": "array",
"items": {
"$ref": "#/definitions/ActionBinding"
}
}
]
},
"description": "State path → action binding, run when the value at that path changes."
},
"__schema0": {
"anyOf": [
{
"type": "boolean"
},
{
"anyOf": [
{
"type": "object",
"properties": {
"$state": {
"type": "string"
},
"eq": {},
"neq": {},
"gt": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"gte": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"lt": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"lte": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"not": {
"type": "boolean",
"const": true
}
},
"required": [
"$state"
]
},
{
"type": "object",
"properties": {
"$item": {
"type": "string"
},
"eq": {},
"neq": {},
"gt": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"gte": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"lt": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"lte": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"not": {
"type": "boolean",
"const": true
}
},
"required": [
"$item"
]
},
{
"type": "object",
"properties": {
"$index": {
"type": "boolean",
"const": true
},
"eq": {},
"neq": {},
"gt": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"gte": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"lt": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"lte": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"not": {
"type": "boolean",
"const": true
}
},
"required": [
"$index"
]
}
]
},
{
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"properties": {
"$state": {
"type": "string"
},
"eq": {},
"neq": {},
"gt": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"gte": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"lt": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"lte": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"not": {
"type": "boolean",
"const": true
}
},
"required": [
"$state"
]
},
{
"type": "object",
"properties": {
"$item": {
"type": "string"
},
"eq": {},
"neq": {},
"gt": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"gte": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"lt": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"lte": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"not": {
"type": "boolean",
"const": true
}
},
"required": [
"$item"
]
},
{
"type": "object",
"properties": {
"$index": {
"type": "boolean",
"const": true
},
"eq": {},
"neq": {},
"gt": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"gte": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"lt": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"lte": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"$state": {
"type": "string"
}
},
"required": [
"$state"
]
}
]
},
"not": {
"type": "boolean",
"const": true
}
},
"required": [
"$index"
]
}
]
}
},
{
"type": "object",
"properties": {
"$and": {
"type": "array",
"items": {
"$ref": "#/definitions/__schema0"
}
}
},
"required": [
"$and"
]
},
{
"type": "object",
"properties": {
"$or": {
"type": "array",
"items": {
"$ref": "#/definitions/__schema0"
}
}
},
"required": [
"$or"
]
}
]
}
}
}Community
Evidence