Atlas Forms
Combining Both Systems
A control is visible only when BOTH modeVisibilitySettings and visibilityRule say it is visible. This AND logic lets you create controls that are conditional on field values and restricted to specific modes simultaneously.
AND Logic
// A control is shown only when:
isVisible(control, currentMode, values) =
modeVisibilitySettings[currentMode] !== false
AND
(visibilityRule === undefined OR evaluateExpression(visibilityRule, values) === truthy)
Example 1 — Admin-Only Conditional Field
Show an internal fraud-risk note only in admin mode AND only when the risk score exceeds 80:
{
"id": "fraud-risk-note",
"type": "textarea",
"label": "Internal Fraud Note",
"modeVisibilitySettings": {
"edit": false,
"view": false,
"admin": true, // ← only in admin mode
"design": false,
"preview": false
},
"visibilityRule": "values['risk-score'] > 80" // ← only when risk is high
}
// In edit mode: hidden (modeVisibilitySettings blocks it)
// In admin mode, risk = 60: hidden (visibilityRule blocks it)
// In admin mode, risk = 95: VISIBLE (both conditions pass)
Example 2 — Preview-Safe Conditional
Show the VAT number field when country is in the EU, but always hide in preview mode (clean preview layout):
{
"id": "vat-number",
"type": "text",
"label": "VAT Number",
"modeVisibilitySettings": {
"preview": false // hidden in preview regardless of country selection
},
"visibilityRule": "['DE','FR','NL','IT','ES','BE','AT'].includes(values['country'])"
// In edit mode with country = 'DE': VISIBLE
// In edit mode with country = 'US': hidden (visibilityRule)
// In preview mode with country = 'DE': hidden (modeVisibilitySettings)
}
Evaluation Order
The engine evaluates modeVisibilitySettings first (it is a simple lookup), then only evaluates the visibilityRule expression if the mode check passes. This avoids unnecessary expression evaluation for hidden-by-mode controls:
// Internal evaluation order:
// Step 1: mode check (cheap — no expression evaluation)
const modeVisible = (control.modeVisibilitySettings?.[currentMode] ?? true);
if (!modeVisible) return false; // short-circuit — skip expression evaluation
// Step 2: expression check (only reached if mode check passes)
if (!control.visibilityRule) return true;
return evaluateExpression(control.visibilityRule, values);
Decision Guide
| Requirement | Use |
|---|---|
| Always visible | Omit both properties |
| Visible in some modes only | modeVisibilitySettings only |
| Visible when a field has a specific value | visibilityRule only |
| Visible in a specific mode AND when a condition is true | Both properties combined |
Independent Systems — No Shared State
The two systems are completely independent.
modeVisibilitySettings never reads field values, and visibilityRule never checks the current mode. This separation keeps each system simple and predictable — you can reason about them independently and compose them without side effects.