Skip to content
Forms, switch product

States

States are named boolean expressions evaluated against the live form data. They let you describe complex conditional behavior once and reuse it across many widgets — without scattering inline conditionals throughout your form definition.

A state is a key-value pair: the key is the name you reference from include / exclude rules, prop overrides, and event handlers; the value is an expression string that reads from $form.<path>.

const states = {
hasDiscount: '$form.hasDiscountCode === true',
isAdult: '$form.driverAge >= 18',
};
{
"states": {
"hasDiscount": "$form.hasDiscountCode === true",
"isAdult": "$form.driverAge >= 18"
},
"form": [
/* ... */
]
}

In the Programmatic API, states live inside formConfig.states. The form component reads them through formConfig, so the engine sees the same $form data the form itself binds to.

import { gui } from '@golemui/gui-shared';
import { GuiForm } from '@golemui/gui-react';
const config = {
formDef: [
gui.inputs.booleanInput('hasDiscountCode', { label: 'I have a discount code' }),
gui.inputs.numberInput('driverAge', { label: 'Driver age' }),
gui.inputs.textInput('discountCode', {
label: 'Discount code',
include: { in: ['hasDiscount'] },
}),
],
formConfig: {
states: {
hasDiscount: '$form.hasDiscountCode === true',
isAdult: '$form.driverAge >= 18',
},
},
};
export function MyForm() {
return <GuiForm config={config} />;
}

In the JSON path, states are declared inside the form payload itself under the top-level "states" key. There is no formConfig wrapper — the engine reads "states" directly off the parsed JSON.

{
"states": {
"hasDiscount": "$form.hasDiscountCode === true",
"isAdult": "$form.driverAge >= 18"
},
"form": [
{
"kind": "input",
"type": "checkbox",
"path": "hasDiscountCode",
"label": "I have a discount code"
},
{
"kind": "input",
"type": "number",
"path": "driverAge",
"label": "Driver age"
},
{
"kind": "input",
"type": "textinput",
"path": "discountCode",
"label": "Discount code",
"include": { "in": ["hasDiscount"] }
}
]
}

Wire the parsed JSON into your form component the same way as any other JSON formDef — no extra prop is needed for states:

import { GuiForm } from '@golemui/gui-react';
import formDef from './my-form.json';
export function MyForm() {
return <GuiForm config={{ formDef }} />;
}

Once a state is named, you reference it in three places:

  1. include / exclude — gate whether a widget renders.
  2. Per-state prop overrides — change a widget’s label, disabled flag, items list, etc. when the state is active.
  3. Inline when — a one-shot expression that doesn’t get a name.

See the sub-pages for each pattern.