diff --git a/packages/json_script_example/seed/components.json b/packages/json_script_example/seed/components.json
new file mode 100644
index 000000000..90aab622a
--- /dev/null
+++ b/packages/json_script_example/seed/components.json
@@ -0,0 +1,484 @@
+{
+ "schema_version": "2.1.0",
+ "package": "json_script_example",
+ "description": "UI component examples using JSON script",
+
+ "exports": {
+ "components": ["ExpressionDemo", "OperatorDemo", "ResultDisplay"]
+ },
+
+ "components": [
+ {
+ "id": "expression_demo",
+ "name": "ExpressionDemo",
+ "exported": true,
+ "docstring": {
+ "summary": "Interactive expression calculator component",
+ "description": "Renders a form with two number inputs and displays the results of all expression operations (sum, diff, product, max, etc.)",
+ "props": [
+ {
+ "name": "initialA",
+ "type": "number",
+ "description": "Initial value for first number",
+ "optional": true,
+ "default": 10
+ },
+ {
+ "name": "initialB",
+ "type": "number",
+ "description": "Initial value for second number",
+ "optional": true,
+ "default": 5
+ }
+ ],
+ "examples": [
+ {
+ "title": "Default values",
+ "code": ""
+ },
+ {
+ "title": "Custom initial values",
+ "code": ""
+ }
+ ],
+ "since": "1.0.0",
+ "tags": ["component", "demo", "interactive", "expressions"]
+ },
+ "props": [
+ {
+ "name": "initialA",
+ "type": "number",
+ "optional": true,
+ "default": 10
+ },
+ {
+ "name": "initialB",
+ "type": "number",
+ "optional": true,
+ "default": 5
+ }
+ ],
+ "render": {
+ "type": "component",
+ "template": {
+ "type": "div",
+ "className": "json_script_example_expression-demo",
+ "children": [
+ {
+ "type": "h2",
+ "children": "Expression Calculator"
+ },
+ {
+ "type": "div",
+ "className": "json_script_example_inputs",
+ "children": [
+ {
+ "type": "label",
+ "children": [
+ "First Number: ",
+ {
+ "type": "input",
+ "inputType": "number",
+ "value": "$ref:state.a",
+ "onChange": "$ref:handlers.setA"
+ }
+ ]
+ },
+ {
+ "type": "label",
+ "children": [
+ "Second Number: ",
+ {
+ "type": "input",
+ "inputType": "number",
+ "value": "$ref:state.b",
+ "onChange": "$ref:handlers.setB"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "type": "component",
+ "name": "ResultDisplay",
+ "props": {
+ "result": "$ref:computed.result"
+ }
+ }
+ ]
+ }
+ },
+ "state": {
+ "a": "$ref:props.initialA",
+ "b": "$ref:props.initialB"
+ },
+ "handlers": {
+ "setA": {
+ "params": ["value"],
+ "body": [
+ {
+ "type": "setState",
+ "updates": {
+ "a": "$ref:params.value"
+ }
+ }
+ ]
+ },
+ "setB": {
+ "params": ["value"],
+ "body": [
+ {
+ "type": "setState",
+ "updates": {
+ "b": "$ref:params.value"
+ }
+ }
+ ]
+ }
+ },
+ "computed": {
+ "result": {
+ "body": [
+ {
+ "type": "return",
+ "value": {
+ "type": "call_expression",
+ "callee": "$ref:imports.script.all_expressions",
+ "args": ["$ref:state.a", "$ref:state.b"]
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "id": "operator_demo",
+ "name": "OperatorDemo",
+ "exported": true,
+ "docstring": {
+ "summary": "Interactive operator demonstration component",
+ "description": "Shows all operator results in a categorized table format with real-time updates",
+ "props": [
+ {
+ "name": "x",
+ "type": "number",
+ "description": "First operand",
+ "optional": true,
+ "default": 10
+ },
+ {
+ "name": "y",
+ "type": "number",
+ "description": "Second operand",
+ "optional": true,
+ "default": 5
+ }
+ ],
+ "since": "1.0.0",
+ "tags": ["component", "demo", "operators", "table"]
+ },
+ "props": [
+ {
+ "name": "x",
+ "type": "number",
+ "optional": true,
+ "default": 10
+ },
+ {
+ "name": "y",
+ "type": "number",
+ "optional": true,
+ "default": 5
+ }
+ ],
+ "render": {
+ "type": "component",
+ "template": {
+ "type": "div",
+ "className": "json_script_example_operator-demo",
+ "children": [
+ {
+ "type": "h2",
+ "children": "Operator Demonstration"
+ },
+ {
+ "type": "p",
+ "children": {
+ "type": "template_literal",
+ "template": "x = ${x}, y = ${y}",
+ "values": {
+ "x": "$ref:props.x",
+ "y": "$ref:props.y"
+ }
+ }
+ },
+ {
+ "type": "div",
+ "className": "json_script_example_operator-grid",
+ "children": [
+ {
+ "type": "section",
+ "children": [
+ {
+ "type": "h3",
+ "children": "Arithmetic"
+ },
+ {
+ "type": "ul",
+ "children": [
+ {
+ "type": "li",
+ "children": {
+ "type": "template_literal",
+ "template": "x + y = ${result}",
+ "values": {
+ "result": {
+ "type": "member_access",
+ "object": {
+ "type": "member_access",
+ "object": "$ref:computed.operators",
+ "property": "arithmetic"
+ },
+ "property": "add"
+ }
+ }
+ }
+ },
+ {
+ "type": "li",
+ "children": {
+ "type": "template_literal",
+ "template": "x - y = ${result}",
+ "values": {
+ "result": {
+ "type": "member_access",
+ "object": {
+ "type": "member_access",
+ "object": "$ref:computed.operators",
+ "property": "arithmetic"
+ },
+ "property": "subtract"
+ }
+ }
+ }
+ },
+ {
+ "type": "li",
+ "children": {
+ "type": "template_literal",
+ "template": "x * y = ${result}",
+ "values": {
+ "result": {
+ "type": "member_access",
+ "object": {
+ "type": "member_access",
+ "object": "$ref:computed.operators",
+ "property": "arithmetic"
+ },
+ "property": "multiply"
+ }
+ }
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "type": "section",
+ "children": [
+ {
+ "type": "h3",
+ "children": "Comparison"
+ },
+ {
+ "type": "ul",
+ "children": [
+ {
+ "type": "li",
+ "children": {
+ "type": "template_literal",
+ "template": "x == y: ${result}",
+ "values": {
+ "result": {
+ "type": "member_access",
+ "object": {
+ "type": "member_access",
+ "object": "$ref:computed.operators",
+ "property": "comparison"
+ },
+ "property": "equal"
+ }
+ }
+ }
+ },
+ {
+ "type": "li",
+ "children": {
+ "type": "template_literal",
+ "template": "x > y: ${result}",
+ "values": {
+ "result": {
+ "type": "member_access",
+ "object": {
+ "type": "member_access",
+ "object": "$ref:computed.operators",
+ "property": "comparison"
+ },
+ "property": "greaterThan"
+ }
+ }
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "computed": {
+ "operators": {
+ "body": [
+ {
+ "type": "return",
+ "value": {
+ "type": "call_expression",
+ "callee": "$ref:imports.script.all_operators",
+ "args": ["$ref:props.x", "$ref:props.y"]
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "id": "result_display",
+ "name": "ResultDisplay",
+ "exported": true,
+ "docstring": {
+ "summary": "Displays expression results in a formatted card",
+ "description": "Renders the result object from all_expressions in a clean, readable format",
+ "props": [
+ {
+ "name": "result",
+ "type": "ExpressionsDemoResult",
+ "description": "Result object from all_expressions function"
+ }
+ ],
+ "since": "1.0.0",
+ "tags": ["component", "display", "results"]
+ },
+ "props": [
+ {
+ "name": "result",
+ "type": "object"
+ }
+ ],
+ "render": {
+ "type": "component",
+ "template": {
+ "type": "div",
+ "className": "json_script_example_result-display",
+ "children": [
+ {
+ "type": "h3",
+ "children": "Results"
+ },
+ {
+ "type": "dl",
+ "children": [
+ {
+ "type": "dt",
+ "children": "Sum"
+ },
+ {
+ "type": "dd",
+ "children": {
+ "type": "member_access",
+ "object": "$ref:props.result",
+ "property": "sum"
+ }
+ },
+ {
+ "type": "dt",
+ "children": "Difference"
+ },
+ {
+ "type": "dd",
+ "children": {
+ "type": "member_access",
+ "object": "$ref:props.result",
+ "property": "diff"
+ }
+ },
+ {
+ "type": "dt",
+ "children": "Product"
+ },
+ {
+ "type": "dd",
+ "children": {
+ "type": "member_access",
+ "object": "$ref:props.result",
+ "property": "product"
+ }
+ },
+ {
+ "type": "dt",
+ "children": "Maximum"
+ },
+ {
+ "type": "dd",
+ "children": {
+ "type": "member_access",
+ "object": "$ref:props.result",
+ "property": "max"
+ }
+ },
+ {
+ "type": "dt",
+ "children": "Both Positive?"
+ },
+ {
+ "type": "dd",
+ "children": {
+ "type": "conditional_expression",
+ "test": {
+ "type": "member_access",
+ "object": "$ref:props.result",
+ "property": "bothPositive"
+ },
+ "consequent": "Yes",
+ "alternate": "No"
+ }
+ },
+ {
+ "type": "dt",
+ "children": "Message"
+ },
+ {
+ "type": "dd",
+ "children": {
+ "type": "member_access",
+ "object": "$ref:props.result",
+ "property": "message"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ ],
+
+ "imports": [
+ {
+ "from": "script",
+ "import": ["all_expressions", "all_operators"]
+ }
+ ]
+}
diff --git a/packages/json_script_example/seed/metadata.json b/packages/json_script_example/seed/metadata.json
index 53eb82777..fb7f607e4 100644
--- a/packages/json_script_example/seed/metadata.json
+++ b/packages/json_script_example/seed/metadata.json
@@ -30,7 +30,11 @@
"TestResult",
"ValidationResult"
],
- "components": []
+ "components": [
+ "ExpressionDemo",
+ "OperatorDemo",
+ "ResultDisplay"
+ ]
},
"tests": {
"parameterized": [
@@ -54,6 +58,7 @@
"stories": [
{
"name": "All Expressions",
+ "type": "function",
"function": "all_expressions",
"args": [10, 5],
"argControls": {
@@ -63,11 +68,13 @@
},
{
"name": "All Statements",
+ "type": "function",
"function": "all_statements",
"args": [[1, 2, 3, 4, 5]]
},
{
"name": "All Operators",
+ "type": "function",
"function": "all_operators",
"args": [10, 5],
"argControls": {
@@ -77,6 +84,7 @@
},
{
"name": "Control Flow",
+ "type": "function",
"function": "control_flow",
"args": [42],
"argControls": {
@@ -85,8 +93,35 @@
},
{
"name": "Data Structures",
+ "type": "function",
"function": "data_structures",
"args": []
+ },
+ {
+ "name": "Expression Demo Component",
+ "type": "component",
+ "component": "ExpressionDemo",
+ "props": {
+ "initialA": 10,
+ "initialB": 5
+ },
+ "propControls": {
+ "initialA": { "type": "number", "default": 10, "min": -100, "max": 100, "step": 1 },
+ "initialB": { "type": "number", "default": 5, "min": -100, "max": 100, "step": 1 }
+ }
+ },
+ {
+ "name": "Operator Demo Component",
+ "type": "component",
+ "component": "OperatorDemo",
+ "props": {
+ "x": 10,
+ "y": 5
+ },
+ "propControls": {
+ "x": { "type": "number", "default": 10, "min": -100, "max": 100, "step": 1 },
+ "y": { "type": "number", "default": 5, "min": -100, "max": 100, "step": 1 }
+ }
}
]
},
@@ -94,7 +129,8 @@
"scripts": [
"seed/script.json",
"seed/math_utils.json",
- "seed/validation.json"
+ "seed/validation.json",
+ "seed/components.json"
],
"main": "seed/script.json",
"executor": {