ngx-json-render UI
Server Details
Renders dashboards, forms and tables inline in the chat as Angular Material components (MCP App).
- Status
- Healthy
- Uptime
- 99.6% over 18 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- shteynu/ngx-json-render
- GitHub Stars
- 1
- Server Listing
- ngx-json-render-ui
TDQS
Scored across 1 tool
With only one tool, there is no possibility of tool overlap or misselection. An agent cannot confuse render-ui with any other operation.
The single tool follows a clear verb_noun pattern (render-ui). There are no other names to compare against, so consistency is trivially perfect.
One tool is thin for a server with this much described capability (state, actions, form validation, loops). While the rendering operation itself is singular, the lack of auxiliary tools (e.g., validation, schema introspection) makes the count borderline.
The tool covers the full rendering lifecycle including specs, state, dynamic props, lists, forms, and actions. Minor gap: no dedicated tool to validate a spec or fetch the component schema before rendering, though the description includes inline schema details.
Available Tools
1 toolrender-uiRender UIARead-onlyIdempotentInspect
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.
rootis the key of the top element.elementsis a flat map of key → { type, props, children: [child keys] }; every child key must exist inelements.stateholds the data. Read it with {"$state":"/path"} rather than repeating values in props. Data-backed UI always needsstate; 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.
visibleandonsit next toprops, 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(anddataas 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"}}}}.
| Name | Required | Description | Default |
|---|---|---|---|
| spec | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| spec | Yes | The json-render spec that was rendered. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint/idempotent/destructive=false, and the description goes beyond them by disclosing a real side effect: the host posts `text` (and `data`) into the chat as the user's message, so `text` must be written in the user's voice. It does not say whether a rendered UI persists across turns or supersedes a prior render, which is the one behavioral gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in one sentence, followed by a tight bulleted tour of exactly the constructs an agent must get right. For a DSL this large the length is justified and every bullet carries an actionable rule rather than filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need no explanation, and the description fills the remaining gap: spec shape, state, bindings, loops, visibility, events, validation and submit flow. Only the schema-defined `watch` and action modifiers (`confirm`, `onSuccess`) go unexplained, which the rich component schema covers.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Top-level schema description coverage is 0%, so the description must carry the load and it does: it defines `root`, the flat `elements` map and child-key invariant, `state` reads, `$state`/`$bindState`/`$template`/`$cond` dynamics, `repeat`, and the placement rule that `visible`/`on` sit beside `props`. This is far more than the schema's top-level text supplies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence gives a specific verb and resource — 'Render an interactive Angular Material UI inline in the chat' — so an agent knows exactly what the tool produces. It immediately narrows to the `spec` argument, and with no sibling tools there is nothing to disambiguate against.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly instructs what to pass ('one complete json-render spec object (not JSON Patch lines)') and gives situational guidance for tricky cases like data-backed UI needing `state` and forms using `submitForm`. It never states when NOT to render UI versus answering in plain text, but with no alternatives that omission is minor.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
- Changed
render-ui3 fields changed- changed
Input schema / properties / spec / properties / elements / additionalProperties / oneOfPrevious value: -[ - { - "additionalProperties": false, - "description": "Stack: Layout container that stacks children vertically or horizontally. The primary building block — use it for every group of elements.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "align": { - "anyOf": [ - { - "enum": [ - "start", - "center", - "end", - "stretch" - ], - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "direction": { - "anyOf": [ - { - "enum": [ - "vertical", - "horizontal" - ], - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "gap": { - "anyOf": [ - { - "type": "number" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "justify": { - "anyOf": [ - { - "enum": [ - "start", - "center", - "between", - "end" - ], - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "padding": { - "anyOf": [ - { - "type": "number" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "wrap": { - "anyOf": [ - { - "type": "boolean" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Stack", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "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.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "columns": { - "anyOf": [ - { - "maximum": 6, - "minimum": 1, - "type": "number" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "gap": { - "anyOf": [ - { - "type": "number" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Grid", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Card: Material card with an optional title/subtitle header and an \"actions\" slot rendered as a footer button row.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "appearance": { - "anyOf": [ - { - "enum": [ - "outlined", - "raised", - "filled" - ], - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "subtitle": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "title": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Card", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Toolbar: Material toolbar for a page or section header. Children are placed at the trailing edge.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "color": { - "anyOf": [ - { - "enum": [ - "primary", - "accent", - "warn" - ], - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "title": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Toolbar", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "ExpansionPanel: Collapsible Material panel. Use for secondary detail that should not compete with the main content.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "expanded": { - "anyOf": [ - { - "type": "boolean" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "title": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "required": [ - "title" - ], - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "ExpansionPanel", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Tabs: Material tab group. Children MUST all be Tab components; each Tab supplies one tab and its body.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": {}, - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Tabs", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Tab: A single tab inside a Tabs component. Valid only as a direct child of Tabs.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "label": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "required": [ - "label" - ], - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Tab", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Divider: Horizontal Material divider.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": {}, - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Divider", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Heading: Section heading (level 1–3) using the Material type scale.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "content": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "level": { - "anyOf": [ - { - "maximum": 3, - "minimum": 1, - "type": "number" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "required": [ - "content" - ], - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Heading", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Text: A paragraph of body text; \"\\n\" in content starts a new line.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "content": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "tone": { - "anyOf": [ - { - "enum": [ - "default", - "muted", - "strong" - ], - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "required": [ - "content" - ], - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Text", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Icon: Material Symbols icon. `name` is the ligature, e.g. \"home\", \"check_circle\", \"warning\".", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "color": { - "anyOf": [ - { - "enum": [ - "primary", - "accent", - "warn" - ], - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Icon", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Metric: Key metric tile with an optional delta and trend direction. Use inside a Grid for dashboard summaries.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "delta": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "label": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "trend": { - "anyOf": [ - { - "enum": [ - "up", - "down", - "flat" - ], - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "value": { - "anyOf": [ - { - "type": [ - "string", - "number" - ] - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "required": [ - "label", - "value" - ], - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Metric", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Chip: Material chip, for tags and status labels.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "color": { - "anyOf": [ - { - "enum": [ - "primary", - "accent", - "warn" - ], - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "icon": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "label": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "required": [ - "label" - ], - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Chip", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "List: Material list container. Children MUST all be ListItem components.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": {}, - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "List", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "ListItem: Row inside a List. Emits a 'press' event when clicked. Valid only as a direct child of List.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "icon": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "title": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "required": [ - "title" - ], - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "ListItem", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "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.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "columns": { - "anyOf": [ - { - "items": { - "properties": { - "align": { - "enum": [ - "start", - "end" - ], - "type": "string" - }, - "field": { - "type": "string" - }, - "header": { - "type": "string" - } - }, - "required": [ - "field", - "header" - ], - "type": "object" - }, - "type": "array" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "rows": { - "anyOf": [ - { - "items": { - "additionalProperties": {}, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "type": "array" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "required": [ - "columns", - "rows" - ], - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Table", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "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.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "color": { - "anyOf": [ - { - "enum": [ - "primary", - "accent", - "warn" - ], - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "icon": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "label": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "variant": { - "anyOf": [ - { - "enum": [ - "text", - "filled", - "elevated", - "outlined", - "tonal" - ], - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "required": [ - "label" - ], - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Button", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "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.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "color": { - "anyOf": [ - { - "enum": [ - "primary", - "accent", - "warn" - ], - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "icon": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "label": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "required": [ - "icon", - "label" - ], - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "IconButton", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "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.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "hint": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "label": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "placeholder": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "required": { - "anyOf": [ - { - "type": "boolean" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "type": { - "anyOf": [ - { - "enum": [ - "text", - "number", - "email", - "password" - ], - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "validation": { - "anyOf": [ - { - "properties": { - "checks": { - "items": { - "properties": { - "args": { - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "boolean" - }, - { - "type": "null" - }, - { - "properties": { - "$state": { - "type": "string" - } - }, - "required": [ - "$state" - ], - "type": "object" - } - ] - }, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "message": { - "type": "string" - }, - "type": { - "type": "string" - } - }, - "required": [ - "type", - "message" - ], - "type": "object" - }, - "type": "array" - }, - "enabled": { - "allOf": [ - { - "$ref": "#/definitions/__schema0" - } - ] - }, - "validateOn": { - "enum": [ - "change", - "blur", - "submit" - ], - "type": "string" - } - }, - "type": "object" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "value": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Input", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "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.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "label": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "placeholder": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "rows": { - "anyOf": [ - { - "type": "number" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "validation": { - "anyOf": [ - { - "properties": { - "checks": { - "items": { - "properties": { - "args": { - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "boolean" - }, - { - "type": "null" - }, - { - "properties": { - "$state": { - "type": "string" - } - }, - "required": [ - "$state" - ], - "type": "object" - } - ] - }, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "message": { - "type": "string" - }, - "type": { - "type": "string" - } - }, - "required": [ - "type", - "message" - ], - "type": "object" - }, - "type": "array" - }, - "enabled": { - "allOf": [ - { - "$ref": "#/definitions/__schema0" - } - ] - }, - "validateOn": { - "enum": [ - "change", - "blur", - "submit" - ], - "type": "string" - } - }, - "type": "object" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "value": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Textarea", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "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.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "label": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "options": { - "anyOf": [ - { - "items": { - "properties": { - "label": { - "type": "string" - }, - "value": { - "type": "string" - } - }, - "required": [ - "value", - "label" - ], - "type": "object" - }, - "type": "array" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "validation": { - "anyOf": [ - { - "properties": { - "checks": { - "items": { - "properties": { - "args": { - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "boolean" - }, - { - "type": "null" - }, - { - "properties": { - "$state": { - "type": "string" - } - }, - "required": [ - "$state" - ], - "type": "object" - } - ] - }, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "message": { - "type": "string" - }, - "type": { - "type": "string" - } - }, - "required": [ - "type", - "message" - ], - "type": "object" - }, - "type": "array" - }, - "enabled": { - "allOf": [ - { - "$ref": "#/definitions/__schema0" - } - ] - }, - "validateOn": { - "enum": [ - "change", - "blur", - "submit" - ], - "type": "string" - } - }, - "type": "object" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "value": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "required": [ - "options" - ], - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Select", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "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.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "checked": { - "anyOf": [ - { - "type": "boolean" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "label": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "validation": { - "anyOf": [ - { - "properties": { - "checks": { - "items": { - "properties": { - "args": { - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "boolean" - }, - { - "type": "null" - }, - { - "properties": { - "$state": { - "type": "string" - } - }, - "required": [ - "$state" - ], - "type": "object" - } - ] - }, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "message": { - "type": "string" - }, - "type": { - "type": "string" - } - }, - "required": [ - "type", - "message" - ], - "type": "object" - }, - "type": "array" - }, - "enabled": { - "allOf": [ - { - "$ref": "#/definitions/__schema0" - } - ] - }, - "validateOn": { - "enum": [ - "change", - "blur", - "submit" - ], - "type": "string" - } - }, - "type": "object" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "required": [ - "label" - ], - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Checkbox", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "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.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "direction": { - "anyOf": [ - { - "enum": [ - "vertical", - "horizontal" - ], - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "label": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "options": { - "anyOf": [ - { - "items": { - "properties": { - "label": { - "type": "string" - }, - "value": { - "type": "string" - } - }, - "required": [ - "value", - "label" - ], - "type": "object" - }, - "type": "array" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "validation": { - "anyOf": [ - { - "properties": { - "checks": { - "items": { - "properties": { - "args": { - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "boolean" - }, - { - "type": "null" - }, - { - "properties": { - "$state": { - "type": "string" - } - }, - "required": [ - "$state" - ], - "type": "object" - } - ] - }, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "message": { - "type": "string" - }, - "type": { - "type": "string" - } - }, - "required": [ - "type", - "message" - ], - "type": "object" - }, - "type": "array" - }, - "enabled": { - "allOf": [ - { - "$ref": "#/definitions/__schema0" - } - ] - }, - "validateOn": { - "enum": [ - "change", - "blur", - "submit" - ], - "type": "string" - } - }, - "type": "object" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "value": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "required": [ - "options" - ], - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "RadioGroup", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "SlideToggle: Material slide toggle for on/off settings. Bind `checked` with {\"$bindState\":\"/path\"}.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "checked": { - "anyOf": [ - { - "type": "boolean" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "label": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "required": [ - "label" - ], - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "SlideToggle", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Slider: Material slider for a numeric range. Bind `value` with {\"$bindState\":\"/path\"}.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "label": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "max": { - "anyOf": [ - { - "type": "number" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "min": { - "anyOf": [ - { - "type": "number" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "step": { - "anyOf": [ - { - "type": "number" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "value": { - "anyOf": [ - { - "type": "number" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Slider", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "ProgressBar: Material progress bar (0–100). Use mode \"indeterminate\" when the amount of work is unknown.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "color": { - "anyOf": [ - { - "enum": [ - "primary", - "accent", - "warn" - ], - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "mode": { - "anyOf": [ - { - "enum": [ - "determinate", - "indeterminate" - ], - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "value": { - "anyOf": [ - { - "type": "number" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "ProgressBar", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Spinner: Material indeterminate progress spinner, for loading states.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "color": { - "anyOf": [ - { - "enum": [ - "primary", - "accent", - "warn" - ], - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "diameter": { - "anyOf": [ - { - "type": "number" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Spinner", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Callout: Inline message block for informational, success, warning, or error text.", - "properties": { - "children": { - "default": [], - "items": { - "type": "string" - }, - "type": "array" - }, - "on": { - "allOf": [ - { - "$ref": "#/definitions/Events" - } - ] - }, - "props": { - "additionalProperties": false, - "properties": { - "content": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "severity": { - "anyOf": [ - { - "enum": [ - "info", - "success", - "warning", - "error" - ], - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - }, - "title": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/DynamicValue" - } - ] - } - }, - "required": [ - "content" - ], - "type": "object" - }, - "repeat": { - "allOf": [ - { - "$ref": "#/definitions/Repeat" - } - ] - }, - "type": { - "const": "Callout", - "type": "string" - }, - "visible": { - "allOf": [ - { - "$ref": "#/definitions/Visibility" - } - ] - }, - "watch": { - "allOf": [ - { - "$ref": "#/definitions/Watchers" - } - ] - } - }, - "required": [ - "type", - "props" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "description": "Stack: Layout container that stacks children vertically or horizontally. The primary building block — use it for every group of elements.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "align": { + "anyOf": [ + { + "enum": [ + "start", + "center", + "end", + "stretch" + ], + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "direction": { + "anyOf": [ + { + "enum": [ + "vertical", + "horizontal" + ], + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "gap": { + "anyOf": [ + { + "type": "number" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "justify": { + "anyOf": [ + { + "enum": [ + "start", + "center", + "between", + "end" + ], + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "padding": { + "anyOf": [ + { + "type": "number" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "wrap": { + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Stack", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "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.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "columns": { + "anyOf": [ + { + "maximum": 6, + "minimum": 1, + "type": "number" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "gap": { + "anyOf": [ + { + "type": "number" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Grid", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Card: Material card with an optional title/subtitle header and an \"actions\" slot rendered as a footer button row.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "appearance": { + "anyOf": [ + { + "enum": [ + "outlined", + "raised", + "filled" + ], + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "subtitle": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Card", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Toolbar: Material toolbar for a page or section header. Children are placed at the trailing edge.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "color": { + "anyOf": [ + { + "enum": [ + "primary", + "accent", + "warn" + ], + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Toolbar", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "ExpansionPanel: Collapsible Material panel. Use for secondary detail that should not compete with the main content.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "expanded": { + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "required": [ + "title" + ], + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "ExpansionPanel", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Tabs: Material tab group. Children MUST all be Tab components; each Tab supplies one tab and its body.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": {}, + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Tabs", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Tab: A single tab inside a Tabs component. Valid only as a direct child of Tabs.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "required": [ + "label" + ], + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Tab", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Stepper: Material stepper for a multi-step form or wizard. Children MUST all be Step components; each Step supplies one step and its body. Every step but the first gets a Back button and every step but the last a Next button (`backLabel`, `nextLabel` rename them). Next validates the bound fields inside its step and moves on only if they all pass, so put each field's `validation` on it as usual and the final submit button (submitForm) in the last Step. With `linear: true` the step headers cannot skip ahead to a step not reached yet. `selected` is the 0-based index of the open step; bind it with {\"$bindState\":\"/path\"} to read or drive it.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "backLabel": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "linear": { + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "nextLabel": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "orientation": { + "anyOf": [ + { + "enum": [ + "horizontal", + "vertical" + ], + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "selected": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Stepper", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Step: A single step inside a Stepper. Valid only as a direct child of Stepper.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "required": [ + "label" + ], + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Step", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Divider: Horizontal Material divider.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": {}, + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Divider", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Heading: Section heading (level 1–3) using the Material type scale.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "content": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "level": { + "anyOf": [ + { + "maximum": 3, + "minimum": 1, + "type": "number" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "required": [ + "content" + ], + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Heading", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Text: A paragraph of body text; \"\\n\" in content starts a new line.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "content": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "tone": { + "anyOf": [ + { + "enum": [ + "default", + "muted", + "strong" + ], + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "required": [ + "content" + ], + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Text", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Icon: Material Symbols icon. `name` is the ligature, e.g. \"home\", \"check_circle\", \"warning\".", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "color": { + "anyOf": [ + { + "enum": [ + "primary", + "accent", + "warn" + ], + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Icon", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Metric: Key metric tile with an optional delta and trend direction. Use inside a Grid for dashboard summaries.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "delta": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "trend": { + "anyOf": [ + { + "enum": [ + "up", + "down", + "flat" + ], + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "value": { + "anyOf": [ + { + "type": [ + "string", + "number" + ] + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "required": [ + "label", + "value" + ], + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Metric", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Chip: Material chip, for tags and status labels.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "color": { + "anyOf": [ + { + "enum": [ + "primary", + "accent", + "warn" + ], + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "icon": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "required": [ + "label" + ], + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Chip", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "List: Material list container. Children MUST all be ListItem components.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": {}, + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "List", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "ListItem: Row inside a List. Emits a 'press' event when clicked. Valid only as a direct child of List.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "icon": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "required": [ + "title" + ], + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "ListItem", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "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.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "columns": { + "anyOf": [ + { + "items": { + "properties": { + "align": { + "enum": [ + "start", + "end" + ], + "type": "string" + }, + "field": { + "type": "string" + }, + "header": { + "type": "string" + } + }, + "required": [ + "field", + "header" + ], + "type": "object" + }, + "type": "array" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "rows": { + "anyOf": [ + { + "items": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": "array" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "required": [ + "columns", + "rows" + ], + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Table", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "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.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "color": { + "anyOf": [ + { + "enum": [ + "primary", + "accent", + "warn" + ], + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "disabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "icon": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "variant": { + "anyOf": [ + { + "enum": [ + "text", + "filled", + "elevated", + "outlined", + "tonal" + ], + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "required": [ + "label" + ], + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Button", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "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.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "color": { + "anyOf": [ + { + "enum": [ + "primary", + "accent", + "warn" + ], + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "disabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "icon": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "required": [ + "icon", + "label" + ], + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "IconButton", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "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`. Validation: see `elements`.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "disabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "placeholder": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "required": { + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "type": { + "anyOf": [ + { + "enum": [ + "text", + "number", + "email", + "password" + ], + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "validation": { + "anyOf": [ + { + "properties": { + "checks": { + "items": { + "properties": { + "args": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "properties": { + "$state": { + "type": "string" + } + }, + "required": [ + "$state" + ], + "type": "object" + } + ] + }, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "message": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type", + "message" + ], + "type": "object" + }, + "type": "array" + }, + "enabled": { + "allOf": [ + { + "$ref": "#/definitions/__schema0" + } + ] + }, + "validateOn": { + "enum": [ + "change", + "blur", + "submit" + ], + "type": "string" + } + }, + "type": "object" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Input", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Textarea: Multi-line Material text field. Bind `value` with {\"$bindState\":\"/path\"}. Validation: see `elements`.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "disabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "placeholder": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "rows": { + "anyOf": [ + { + "type": "number" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "validation": { + "anyOf": [ + { + "properties": { + "checks": { + "items": { + "properties": { + "args": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "properties": { + "$state": { + "type": "string" + } + }, + "required": [ + "$state" + ], + "type": "object" + } + ] + }, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "message": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type", + "message" + ], + "type": "object" + }, + "type": "array" + }, + "enabled": { + "allOf": [ + { + "$ref": "#/definitions/__schema0" + } + ] + }, + "validateOn": { + "enum": [ + "change", + "blur", + "submit" + ], + "type": "string" + } + }, + "type": "object" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Textarea", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Select: Material select. Bind `value` with {\"$bindState\":\"/path\"}; `options` is an explicit list. With `multiple: true` the user can pick several options and `value` is an array of the chosen values (start it as []); a required check then fails on an empty array. Validation: see `elements`.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "disabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "multiple": { + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "options": { + "anyOf": [ + { + "items": { + "properties": { + "label": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "value", + "label" + ], + "type": "object" + }, + "type": "array" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "validation": { + "anyOf": [ + { + "properties": { + "checks": { + "items": { + "properties": { + "args": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "properties": { + "$state": { + "type": "string" + } + }, + "required": [ + "$state" + ], + "type": "object" + } + ] + }, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "message": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type", + "message" + ], + "type": "object" + }, + "type": "array" + }, + "enabled": { + "allOf": [ + { + "$ref": "#/definitions/__schema0" + } + ] + }, + "validateOn": { + "enum": [ + "change", + "blur", + "submit" + ], + "type": "string" + } + }, + "type": "object" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "value": { + "anyOf": [ + { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "required": [ + "options" + ], + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Select", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "DatePicker: Material date field with a calendar popup. Dates in `value`, `min` and `max` are \"YYYY-MM-DD\" strings. Bind `value` with {\"$bindState\":\"/path\"}; clearing the field writes \"\". `min` and `max` limit the days the calendar offers. ISO dates compare as strings, so an end date after a start date is {\"type\":\"greaterThan\",\"args\":{\"other\":{\"$state\":\"/start\"}},\"message\":\"...\"}. Validation: see `elements`.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "disabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "max": { + "anyOf": [ + { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "min": { + "anyOf": [ + { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "validation": { + "anyOf": [ + { + "properties": { + "checks": { + "items": { + "properties": { + "args": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "properties": { + "$state": { + "type": "string" + } + }, + "required": [ + "$state" + ], + "type": "object" + } + ] + }, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "message": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type", + "message" + ], + "type": "object" + }, + "type": "array" + }, + "enabled": { + "allOf": [ + { + "$ref": "#/definitions/__schema0" + } + ] + }, + "validateOn": { + "enum": [ + "change", + "blur", + "submit" + ], + "type": "string" + } + }, + "type": "object" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "value": { + "anyOf": [ + { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "DatePicker", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Checkbox: Material checkbox. Bind `checked` with {\"$bindState\":\"/path\"} or {\"$bindItem\":\"field\"} inside a repeat. Validation: see `elements`.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "checked": { + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "disabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "validation": { + "anyOf": [ + { + "properties": { + "checks": { + "items": { + "properties": { + "args": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "properties": { + "$state": { + "type": "string" + } + }, + "required": [ + "$state" + ], + "type": "object" + } + ] + }, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "message": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type", + "message" + ], + "type": "object" + }, + "type": "array" + }, + "enabled": { + "allOf": [ + { + "$ref": "#/definitions/__schema0" + } + ] + }, + "validateOn": { + "enum": [ + "change", + "blur", + "submit" + ], + "type": "string" + } + }, + "type": "object" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "required": [ + "label" + ], + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Checkbox", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "RadioGroup: Material radio group. Bind `value` with {\"$bindState\":\"/path\"}. Validation: see `elements`.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "direction": { + "anyOf": [ + { + "enum": [ + "vertical", + "horizontal" + ], + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "options": { + "anyOf": [ + { + "items": { + "properties": { + "label": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "value", + "label" + ], + "type": "object" + }, + "type": "array" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "validation": { + "anyOf": [ + { + "properties": { + "checks": { + "items": { + "properties": { + "args": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "properties": { + "$state": { + "type": "string" + } + }, + "required": [ + "$state" + ], + "type": "object" + } + ] + }, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "message": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type", + "message" + ], + "type": "object" + }, + "type": "array" + }, + "enabled": { + "allOf": [ + { + "$ref": "#/definitions/__schema0" + } + ] + }, + "validateOn": { + "enum": [ + "change", + "blur", + "submit" + ], + "type": "string" + } + }, + "type": "object" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "required": [ + "options" + ], + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "RadioGroup", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "ToggleGroup: Segmented control: a row of 2–5 buttons, one of which is chosen. Prefer it to a RadioGroup or Select for a short, frequently switched choice such as a view mode or a time range. Bind `value` with {\"$bindState\":\"/path\"}; an option may carry a Material Symbols `icon`. Validation: see `elements`.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "disabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "options": { + "anyOf": [ + { + "items": { + "properties": { + "icon": { + "type": "string" + }, + "label": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "value", + "label" + ], + "type": "object" + }, + "type": "array" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "validation": { + "anyOf": [ + { + "properties": { + "checks": { + "items": { + "properties": { + "args": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "properties": { + "$state": { + "type": "string" + } + }, + "required": [ + "$state" + ], + "type": "object" + } + ] + }, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "message": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type", + "message" + ], + "type": "object" + }, + "type": "array" + }, + "enabled": { + "allOf": [ + { + "$ref": "#/definitions/__schema0" + } + ] + }, + "validateOn": { + "enum": [ + "change", + "blur", + "submit" + ], + "type": "string" + } + }, + "type": "object" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "required": [ + "options" + ], + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "ToggleGroup", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "SlideToggle: Material slide toggle for on/off settings. Bind `checked` with {\"$bindState\":\"/path\"}.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "checked": { + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "disabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "required": [ + "label" + ], + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "SlideToggle", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Slider: Material slider for a numeric range. Bind `value` with {\"$bindState\":\"/path\"}.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "max": { + "anyOf": [ + { + "type": "number" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "min": { + "anyOf": [ + { + "type": "number" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "step": { + "anyOf": [ + { + "type": "number" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "value": { + "anyOf": [ + { + "type": "number" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Slider", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "ProgressBar: Material progress bar (0–100). Use mode \"indeterminate\" when the amount of work is unknown.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "color": { + "anyOf": [ + { + "enum": [ + "primary", + "accent", + "warn" + ], + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "mode": { + "anyOf": [ + { + "enum": [ + "determinate", + "indeterminate" + ], + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "value": { + "anyOf": [ + { + "type": "number" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "ProgressBar", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Spinner: Material indeterminate progress spinner, for loading states.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "color": { + "anyOf": [ + { + "enum": [ + "primary", + "accent", + "warn" + ], + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "diameter": { + "anyOf": [ + { + "type": "number" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Spinner", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Callout: Inline message block for informational, success, warning, or error text.", + "properties": { + "children": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "on": { + "allOf": [ + { + "$ref": "#/definitions/Events" + } + ] + }, + "props": { + "additionalProperties": false, + "properties": { + "content": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "severity": { + "anyOf": [ + { + "enum": [ + "info", + "success", + "warning", + "error" + ], + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/DynamicValue" + } + ] + } + }, + "required": [ + "content" + ], + "type": "object" + }, + "repeat": { + "allOf": [ + { + "$ref": "#/definitions/Repeat" + } + ] + }, + "type": { + "const": "Callout", + "type": "string" + }, + "visible": { + "allOf": [ + { + "$ref": "#/definitions/Visibility" + } + ] + }, + "watch": { + "allOf": [ + { + "$ref": "#/definitions/Watchers" + } + ] + } + }, + "required": [ + "type", + "props" + ], + "type": "object" + } +] - added
Input schema / properties / spec / properties / elements / descriptionAdded value: +"Elements by key. On every component that takes `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." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "spec": { + "additionalProperties": {}, + "description": "The json-render spec that was rendered.", + "properties": { + "elements": { + "additionalProperties": { + "additionalProperties": {}, + "properties": { + "children": { + "items": { + "type": "string" + }, + "type": "array" + }, + "props": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type", + "props", + "children" + ], + "type": "object" + }, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "root": { + "type": "string" + }, + "state": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + } + }, + "required": [ + "root", + "elements" + ], + "type": "object" + } + }, + "required": [ + "spec" + ], + "type": "object" +}
1 tool update
- First observed
render-ui
Related MCP Connectors
An AI concierge that turns static forms into adaptive AI conversations. From any MCP client.
Build, deploy, and operate hosted web apps on VibeKit (vibekit.bot) from any MCP client.
Build your own tools from chat: design, test and host them on a shareable MCP server URL.
Dashboards as data. Author, validate, render, and share dvt dashboards from any MCP client.
Related MCP Servers
- AlicenseAqualityBmaintenanceMCP server that lets agents create, display, and export rich UI widgets (cards, dashboards, charts, forms) inline in conversations, with interactive iframe support in MCP Apps hosts and PNG image fallback for other clients.43MIT
- AlicenseNot gradedqualityBmaintenanceEnables hosting interactive MCP apps on a dedicated /app route, rendering entity-specific layouts in iframes and relaying user actions through the MCP Apps extension.2 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables agents to serve interactive Auth0 Forms as MCP Apps in a sandboxed iframe, letting users complete sign-up, consent, profile, or payment flows while the agent only receives completion status.MIT
- AlicenseAqualityBmaintenanceHand a human a rich interactive UI by URL from any MCP client and get structured data back: forms, approvals, surveys, pickers, editable lists. Round-trip human-in-the-loop for agents.201MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.