Perry uses reactive state to automatically update the UI when data changes.
Every snippet below is excerpted from
docs/examples/ui/state/snippets.ts —
CI compiles and runs it on every PR.
{{#include ../../examples/ui/state/snippets.ts:creating}}State(initialValue) creates a reactive state container.
{{#include ../../examples/ui/state/snippets.ts:read-write}}Every .set() call re-renders the widget tree with the new value.
Template literals with state.value update automatically:
{{#include ../../examples/ui/state/snippets.ts:reactive-text}}This works because Perry detects state.value reads inside template literals
and creates reactive bindings.
Input widgets expose an onChange callback. Forward that into a state's
.set(...) to keep the state in sync as the user types/toggles/drags:
{{#include ../../examples/ui/state/snippets.ts:bind-textfield}}Input control signatures:
TextField(placeholder, onChange)— text input,onChange: (value: string) => voidSecureField(placeholder, onChange)— password input,onChange: (value: string) => voidToggle(label, onChange)— boolean toggle,onChange: (value: boolean) => voidSlider(min, max, onChange)— numeric slider,onChange: (value: number) => voidPicker(onChange)— dropdown,onChange: (index: number) => void; items viapickerAddItem
For programmatic-to-UI sync (state-drives-widget) use the dedicated binders:
stateBindTextfield, stateBindSlider, stateBindToggle, stateBindTextNumeric,
stateBindVisibility.
Listen for state changes with the free-function stateOnChange:
{{#include ../../examples/ui/state/snippets.ts:on-change}}Render a list from numeric state (the index count):
{{#include ../../examples/ui/state/snippets.ts:foreach}}Note:
ForEachiterates by index over a numeric state. Keep a count state in sync with your array, then read the items viaarray.value[i]inside the closure.
ForEach re-renders the list when the count state changes:
{{#include ../../examples/ui/state/snippets.ts:foreach-mutate}}Use state to conditionally show widgets:
{{#include ../../examples/ui/state/snippets.ts:conditional}}Text can depend on multiple state values:
{{#include ../../examples/ui/state/snippets.ts:multi-state}}{{#include ../../examples/ui/state/snippets.ts:object-state}}Note: State uses identity comparison. You must create a new array/object reference for changes to be detected. Mutating in-place without calling
.set()with a new reference won't trigger updates.
{{#include ../../examples/ui/state/todo_app.ts}}This program is built and run by CI (scripts/run_doc_tests.sh), so the
snippet above always matches the compiled artifact under
docs/examples/ui/state/todo_app.ts.