Properties, states, and events define how a Component communicates. Properties and child slots are inputs from a parent, states are values owned by the running Component, and events are callbacks the Component emits outward. Keeping those roles distinct produces a clearer visual model and a usable generated React API.
Open a visual Component and choose Logic. The file-level Data Structure can enable these current slots:
Slot: Properties · Role: Typed values supplied by the caller.
Slot: States · Role: Typed runtime values owned by the Component.
Slot: Animatable Properties · Role: Number/color channels driven on a Code Component by timelines.
Slot: Variants · Role: Named visual alternatives exposed as a typed selection.
Slot: Children · Role: Named React-node or function slots supplied to a Component instance.
Slot: External Children · Role: Page/external composition slots exposed separately from ordinary Component children.
Slot: Events · Role: Typed callbacks the Component emits to its parent.
Slot: Timeline Player · Role: Logic-facing commands for configured timelines.
Slot: API Loader · Role: Mounted API definitions available to logic.
Slot: Storage Mounter · Role: Mounted Storage definitions available to logic.
Slot: View Loader · Role: Mounted Content/database views available to logic.
Slot: Validator · Role: Named validation results.
Slot: Listeners · Role: Component-level event listeners.
Actual timeline nodes are separate from the Timeline Player slot. A Component can contain an autoplay or scroll-driven timeline even when Timeline Player is not enabled.
Use a property for a value the parent should control:
a button's label;
a card's image or description;
a form's initial configuration;
a list of typed items;
a Page or Component reference selected from the project.
Each property has a stable generated field ID, a name, datatype, optional flag, and optional default. The generated module can expose a Props type and DefaultProps value, and the Component receives values through its properties input.
Properties and states support scalar values, project references, arrays, objects, and arrays of objects according to the current datatype menu. An object field contains named child fields; an object-array field repeats that declared shape.
An element value belongs in a Children slot and a function belongs in an Events or function-capable slot. They are not valid ordinary property/state datatypes in the current MCP schema because the generator cannot express them correctly there.
A default supplies the value used when a caller omits the property. An optional type allows undefined. Those are different decisions.
Avoid marking a field optional merely because it has a default. The generated type can still become T | undefined, which makes later bindings or repetition reject a value that visually appears initialized.
Empty string is a real default for a string. Empty structured defaults can use [] or {} where the current field supports them; non-empty structured defaults are better supplied through a Component instance or test case unless the editor offers a verified value editor for the exact shape.
Use state when the Component itself owns a value:
whether a disclosure is open;
the active tab;
input text while the user types;
a loading or error condition;
the current item index;
a boolean that drives a visual variant or timeline command.
Generated visual Components can expose a States type and an onStatesChange callback. This lets a consuming parent observe state changes without turning every internal value into a controlled property.
State references use the declared name, such as states.open. Logic can compare them, assign new values, toggle booleans, bind them into content, or use them to select visual behavior.
Declare an event when the Component should notify its parent:
onSelect;
onOpenChange;
onSubmit;
onDismiss.
An Event field is a function. Nested fields describe its typed parameter shape; no nested fields means a parameterless callback.
The event has three stages:
Declare it in the Component's Events slot.
Emit it from an element action or other supported Component behavior.
React to it on a Component instance in the parent Page or Component.
Do not confuse a DOM event such as a click with the Component's public event contract. The click is an internal trigger; onSelect is the intentional output a consumer receives.
A Children slot accepts content supplied by a Component instance. For example, leftIcon lets a Button control spacing while the caller provides an icon. The source Component must both declare the slot and render it at a node; content nested under an instance without a matching rendered slot can disappear from output.
External Children is a separate generated channel used where content is injected into a Page or other supported external composition. Its generated API is not interchangeable with a Component's ordinary children object.
Component variants are a flat list of named choices. A consumer passes one or more names through the generated variant input. The base/default style has no variant ID; each non-default variant has an ID used by the style system.
Use variants for deliberate visual alternatives such as outline, destructive, sm, lg, disabled, or selected. A variant combination adds a style layer that applies only when an exact set is selected together.
Variants are not states. A state may drive a variant condition internally, but the concepts remain separate: state stores runtime information; a variant selects a visual style layer.
The Validator slot contains named validation fields. Logic can read each field through validator.values.<name> and can use validator.isAllValid to aggregate them.
A plain validator field is a boolean result. More complex return-value shapes created through editor-only configuration can change that shape, so inspect the actual structure before writing advanced logic against it.
Validation rules compare references and literal/regular-expression operands. A successful TypeScript generation is not enough proof that the chosen rule matches the intended user input; exercise valid, invalid, empty, and boundary values in preview.
A Component test case is a named set of property values used by the Overview/preview workflow. States always start from their declared defaults and cannot be set by the current test-case tools.
Test cases can address nested property paths such as:
meta.author
rows[1].id
tags[0]
A test case should represent a meaningful scenario—Empty, Loading, Long label, With avatar—not only “Case 1.” Use preview to verify the rendered result for the selected case.
Open the Component and choose Logic.
Enable Properties and add the smallest caller-controlled inputs.
Enable States for values the Component owns.
Enable Events for outcomes the parent needs to observe.
Add Children slots for caller-supplied visual regions.
Add variants for named visual alternatives.
Bind elements, conditions, instance props, and actions to those declarations.
Create named test cases with representative property values.
Preview each case and inspect the generated Component API.
Changing a field's name, datatype, optional flag, or default can affect logic references, test-case values, and Component instances. Review all consumers after a contract change.
Coverage: UI + MCP.
Select the Website project and inspect
<component path>. Read its current data structure before editing. Add a required string property namedlabelwith defaultButton, a boolean state namedpressedwith defaultfalse, and a parameterless event namedonPress. Do not bind them yet. Read the properties/states and complete data structure back, run diagnostics, and show the generated TSX contract.
The agent can use get-data-structure, get-props-states, add-props-states, add-events-slot, export-code, and get-diagnostics. It must use the returned field IDs for later edits rather than assuming names are sufficient everywhere.
Inspect the properties on
<component path>. Create and name two Component test cases:DefaultandLong label. Set only property values supported by the current declared types. Read both cases back, then capture a preview screenshot for each case. Do not change state defaults or publish anything.
The relevant operations are add-test-case, name-test-case, set-test-case-values, get-test-cases, and get-preview-screenshot. These are Component test cases, not API request test cases.
For an existing field:
Read its generated ID, datatype, default, and consumers.
Make one semantic change.
Read the data structure and affected logic back.
Run diagnostics.
Preview representative test cases.
Inspect generated output and downstream Component instances.
Removing a field does not automatically make every stored logic, instance, or timeline reference safe. For example, removing an animatable property can leave its timeline track present under a raw ID so the data is not silently destroyed. Treat diagnostics and consumer review as required cleanup steps.
Data-structure operations change Component content and should be represented in its undo history. Batch MCP operations such as setting multiple test-case values validate before writing and commit the batch as one content action where implemented.
Undoing a declaration change does not undo exported files, Git commits, or published artifacts created afterward.