Skip to main content

Logic Engine

Show this section IF (State is WA OR CA) AND (Income < $50,000).
Government forms need complex conditional logic. The Logic Engine evaluates expression trees to determine which fields are visible based on current form values.

Why Expression Trees?

Simple visibility rules like “show X when Y equals Z” don’t scale. Real forms have conditions like:
  • “Show disability section if age > 65 OR has disability”
  • “Show income verification if employment = ‘self-employed’ AND income > $50k”
  • “Hide bank section if (payment method = ‘check’) OR (no bank account)”
We need composable conditions: rules that combine with AND/OR operators into arbitrarily deep trees. This tree evaluates to: (State = WA OR State = CA) AND (Income < 50000)

Data Structures

LogicRule

A single comparison:

LogicGroup

A collection of conditions combined with AND or OR:

LogicCondition

The recursive union:

Operators

The engine supports 18 operators:

Age Operators (for date fields)

Special operators that calculate age from a date:

Evaluation

The main evaluation function:

Rule Evaluation

Group Evaluation

Nested Path Support

Field IDs can reference nested data:
This allows rules like address.state = "WA".

Show vs Hide Actions

By default, logic shows fields when conditions are met. But sometimes you want the opposite:
The logicAction property inverts the logic result:
  • "show" (default): field visible when logic is true
  • "hide": field visible when logic is false

Complete Example

A form section that shows income verification for high-earning self-employed applicants in certain states:
This evaluates as:

Legacy Visibility (Deprecated)

The old visibility format is still supported for backwards compatibility:
The evaluateElementVisibility function handles both:

Helper Functions

Utilities for building logic programmatically:

Form Builder UI

The Logic Builder component (in src/components/form-builder/logic-builder.tsx) provides a visual interface: Users can:
  • Add rules that compare field values
  • Create nested groups with AND/OR
  • See live preview of which fields would show

Performance Considerations

The logic engine re-evaluates on every form value change. For most forms this is instant, but deep nesting could become slow. Optimizations applied:
  1. Short-circuit evaluation — AND stops at first false, OR stops at first true
  2. Direct property access — no recursive tree walking for simple paths
  3. Type coercion caching — number/string conversions memoized per render
Worst case: A form with 100 fields, each with 10-deep nested logic, re-evaluated 60x per second. In practice, forms have 20-50 fields with 2-3 level nesting.

Edge Cases

Empty Values

Empty inputs ("", null, undefined, []) are handled consistently:

Type Coercion

Comparisons handle type mismatches:

Invalid Dates

Age operators handle malformed dates:

Schema Design

How fields store logic conditions

Form Builder

Visual interface for building logic