Documents
Documents
Welcome
Why Misaki Studio
Compare
Start Here
Concepts
Guides
Boilerplates
Design
Animate
Logic
Debug
Responsive
Publish
AI Agents
Account
Reference
Troubleshooting
Examples

Add logic

How a component comes to do something: inputs it exposes, state it owns, events that change the state, conditions and repeats that shape what renders, and real data behind all of it. Everything here is wired visually and exports as ordinary React.

Where logic runs: the design canvas renders your tree without executing logic — you wire everything in the panels, then open a preview to see it live. When wiring feels inert, that is why. The preview also carries a full debugger.

1. Properties

Properties are the component's typed inputs — the parts a caller may set. Declare them in the DATA STRUCTURE panel with a type (strings, numbers, booleans, colors, images, objects and object arrays, a page, even a reference to an element) and a default.

Bind a property anywhere a value goes: into text, an image source, a style value, a condition. The type survives export as the component's Props.

A component previewed on its own renders its properties as undefined — the most common reason data-driven logic "does nothing" on first try. Save a test case (a named set of property values) and preview with that, or preview a parent that passes real props.

2. States

States are values the component owns — whether the menu is open, what the field holds. Declare them like properties, with a default. Properties come from outside; states live and change inside. They export as useState.

3. Events and actions

Elements raise fifteen event kinds — click, double click, mouse down/up/enter/leave, key down/up, change, scroll, focus, blur, mount, outside-click on a popup, and a child component's state change. On Mount is the initialize hook: logic that runs when the element first renders.

An event's payload is readable in the actions it triggers: event.text carries an input's new value on Change, event.code the key pressed, event.element the element itself.

Each event runs a list of actions:

  • Set — write a state, plain = or compound +=, -=, *=, /=.

  • Push / Push at / Remove at / Remove all — mutate an array state without code.

  • Emit — fire an event the component declared, up to its parent.

  • Go to page / Go to URL — navigate, to another page file or out to the web.

  • Scroll — scroll a named container so a target element lands at an edge, with an offset, smoothly.

  • Focus / Blur — move focus to a named element.

Actions can be conditional, and a single event can run several.

4. Conditions

A condition compares an expression against a value with one of twelve operators — equality, the four comparisons, includes/not-includes (arrays), and is valid / is not valid, which tests against a regex: "disable Submit until this matches an email pattern" is one condition, no code.

Conditions are not limited to showing and hiding. Any logic slot can be made conditional — a bind, a variant, a tooltip, an API mount, a timeline command — and a slot can hold branches: if / else-if / else, first passing branch wins.

Two operator honesty notes: includes works on arrays, not on substrings of text; and the and/or toggle between condition rows currently behaves as and in the canvas preview even though the exported code honors or — verify or-logic in the exported app.

5. Repeats

A repeat renders an element once per item of whatever it is bound to — an array, an object (key and value), a string (per character), or a numeric range, counting up or down.

Inside the repeat, bind to item, step (the index), key/value, character, and isLastStep — enough for zebra stripes, separators-between, and rank numbers. Repeats nest, and each depth gets its own scope.

6. Listeners

A listener watches one or more expressions and runs actions when any of them change — the visual counterpart of an effect. Options cover debounce and delay in milliseconds, and run on init for logic that should also fire once at mount. Search-as-you-type is a listener on the query state with a debounce.

7. Validation

The Validator declares named field rules — each field its own condition branches — and exposes validator.<field>.isValid plus validator.isAllValid to every expression. Disable the submit button on isAllValid, show each message under its field, and the form's validation exports with the component.

8. Real data

Everything above also binds to data that lives outside the component:

  • APIs — mount an endpoint from an API file; its response.body, loading and response.error become bindable, so a spinner is a condition. Each mount can override the request, so one endpoint definition serves /posts/1 here and /posts/2 there. The canvas preview really fetches.

  • Storage — shared state across components, with per-schema persistence. A write in one component updates every component that mounts the store.

  • CMS — content rows mount and repeat like an API response.

  • Database views — mount a view and repeat over live rows, behind the access rules described in File sections.

  • Environment — values from the project's environments resolve into any expression as environment.*.

9. Components talking to each other
  • Events up: a component declares its own events; inner logic emits one; the parent wires On Component Event and reacts. Exports as events?.onSubmit?.() — exactly what a hand-written component would offer.

  • State watch: a parent can also react to a child's state changing, without the child declaring anything.

  • Variants down: a parent can set a child's variant from a condition, and a component can drive its own variant while a condition holds — a loading state that styles itself, no parent involved.

10. Small surfaces with big uses
  • Tooltips — render a component or a whole screen as a tooltip, opened on hover, click, or while a boolean expression is true, in thirteen placements.

  • Follow-cursor — the same idea, pinned to the pointer.

  • Popups — an element opens another screen as a popup, aligned and offset; the outside-click event closes it.

  • Enter/exit render control — delay an element's removal so it can animate out. Give the node its condition on the same element; render control without a condition exports a type error.

  • Attributes — set data-* attributes from expressions, for your own CSS hooks or test selectors.

11. What it exports as

Properties become the typed Props; states become useState; events become handlers; conditions become ternaries and guards; validators become the form's validation object; listeners become effects; storage becomes one shared store; navigation becomes the router call. What you wired is what you read in the diff — see How export works.

Navigation ties the export to Next.js routing (next/router) — the same pages-router note as in Export your code.

Where next
On this page
Add logic
1. Properties
2. States
3. Events and actions
4. Conditions
5. Repeats
6. Listeners
7. Validation
8. Real data
9. Components talking to each other
10. Small surfaces with big uses
11. What it exports as
Where next