disabled and readOnly flags. disabled usually blocks interaction, while readOnly allows viewing
without editing. FormEngine Core supports these flags out of the box and propagates them through the component tree so you can lock down
sections consistently without wiring every field.
In this guide, you’ll learn:
- How
disabledandreadOnlyare computed and propagated - Where to set the flags in
FormViewerand form JSON - Which components receive the flags and why
- How UI components apply the flags
Overview
disabled and readOnly are boolean flags that move down the component tree. FormEngine Core treats both as propagated state and leaves
the actual interaction behavior to the UI component, so you can define intent once and let each component decide how to react.
Where to Set the Flags
Set the flags at the highest level that matches your intent. Because the flags always propagate down, a higher-level setting affects every component beneath it.| Source | How to set | Scope |
|---|---|---|
| FormViewer props | readOnly disabled | Entire component tree |
| Screen props | readOnly disabled | Screen subtree |
| Templates / embedded forms | readOnly disabled | Template subtree |
| Container components | readOnly or disabled propsSee the API reference. | Container subtree |
| Component props | readOnly or disabled propsSee the API reference. | Component subtree |
- FormViewer props apply across the tree and are part of the public API. See FormViewerProps.
- Container components are any components that render children. If they declare these annotations, the flags apply to all descendants. Not every container exposes these flags, so check the component API reference.
- Component props are the most direct way to set flags, but not every component supports them. Check the component API reference.
- Custom prop mapping is supported. If a component maps the flag to a custom key, set that key in form JSON (for example,
isLocked).
FormViewer props examples
Read-only- Define a form with a single
MuiTextField. - Pass
readOnlytoFormViewer.
Live example
live
- Define a form with a single
MuiTextField. - Pass
disabledtoFormViewer.
Live example
live
Screen props examples
Read-only- Set
readOnlyon theScreenprops in the form JSON. - Render the form with
FormViewer.
Live example
live
- Set
disabledon theScreenprops in the form JSON. - Render the form with
FormViewer.
Live example
live
Embedded forms example
- Define a single embedded form with one
MuiTextField. - In the parent form, render two
EmbeddedFormcomponents that share the sameformName. - Add labels in the parent form and set
readOnlyon one embedded form anddisabledon the other. - Use
getFormto return the embedded form whenformNameis provided.
Live example
live
Container components example
- Wrap each
MuiTextFieldin its ownMuiBoxcontainer and add a label withMuiTypography. - Set
readOnlyon one container anddisabledon the other. - Render the form with
FormViewer.
Live example
live
Component props example
- Define two
MuiTextFieldcomponents in the form. - Set
readOnlyon one component anddisabledon the other. - Render the form with
FormViewer.
Live example
live
Propagation Rules
For each component, the core computesisDisabled and isReadOnly from three sources:
FormViewerprops- The parent component state
- The component’s own mapped flag
self refers to the component’s own flag (or mapped prop key). Propagation uses the parent component state, not raw parent props, so
descendants inherit the already computed flag. A true value at any level applies to the entire subtree. There is no override to turn a
child back on if an ancestor is disabled or read-only.
Which Components Receive the Flags
Only components that declaredisabled or readOnly in their metadata receive the computed flags as props. If a component does not opt in,
the core does not inject these flags for it.
Use the special boolean annotations when defining your component metadata:
- Declare the flag in
.props()using thereadOnlyordisabledannotation. - Map to your prop name by choosing the key that matches your component API (for example,
isLockedorisDisabled). - Remember containers: container components can also declare these annotations to propagate the flags to their children.
Example: Simple Read-Only Component
SimpleNote.tsx
Live example
live
How UI Components Apply the Flags
FormEngine Core injectsdisabled and readOnly alongside calculated values and events, but it does not block interaction on its own. Each
UI component must apply the flags, for example by mapping to native props when supported or guarding event handlers like onChange and
onClick.
Form actions and calculations can still read and update form data even when components are disabled or read-only. The flags only influence
how the UI behaves.
Summary
disabledandreadOnlyare computed fromFormViewerprops, parent state, and the component’s own mapped flag.- Only components that declare these annotations receive the flags as props.
- The core injects the flags into rendered props, while UI components decide how to enforce them.
- You can set the flags on
FormViewer, screens, embedded forms/templates, containers, or individual components.
For more information:
- Custom components: disabled and read-only
- Embedded forms and templates
- FormViewer props API
- Disabled annotation
- ReadOnly annotation
Next steps
- Conditional Logic — Control field visibility based on form state
- Validation — Validate form fields and handle errors