Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Usage Modes

The DataLogicEditor has no mode enum. The props you pass determine its behavior. The same component is a read-only viewer, a live debugger, a visual editor, or any combination of those, depending on data, editable, and templating.

Behavior Overview

BehaviorEnabled byDescriptionRequires data
Read-only(none)Static diagram visualizationNo
DebuggerdataStep-through execution trace with a step timeline and failure highlightingYes
EditingeditableVisual builder: node selection, properties panel, context menus, undo/redoNo
TemplatingtemplatingMulti-key objects and arrays become output-shaping templatesNo
Engine settingsconfigEvaluation semantics: presets, NaN and division-by-zero handling, truthiness, coercion, recursion cap, operation budgetNo
Custom operatorscustomOperatorsExtra operators registered on the engineNo

You can combine these. Setting editable and providing data at the same time gives you live debugging while you edit.

Read-only (Default)

With only a value, the editor renders a static flow diagram of the JSONLogic expression.

<DataLogicEditor value={expression} />

Use cases:

  • Documentation and explanation
  • Code review and understanding
  • Static representation in reports

Features:

  • Interactive pan and zoom
  • Node highlighting on hover
  • Tree-based automatic layout
  • Nodes coloured by the type of value they produce (boolean, number, string, collection, data, temporal, null), with a category icon in the header
  • A Flow/Hierarchy toolbar toggle: Flow (default) puts sources on the left and the result on the right, Hierarchy puts the root on the left in JSON nesting order. The editor reflects the choice as data-direction on the .logic-editor root

Debugging

Provide a data prop and the editor evaluates the expression with the engine’s tracing API and exposes debugger controls for stepping through the execution.

<DataLogicEditor
  value={expression}
  data={contextData}
/>

Use cases:

  • Understanding evaluation flow
  • Debugging unexpected results
  • Testing expressions with different inputs
  • Learning JSONLogic

Features:

  • All read-only features, plus:
  • Play/pause, step forward and back, and jump to first/last (Space, arrow keys, Home/End)
  • A step timeline listing every recorded step with its node, iteration index and result (or error); click a row to jump to that step
  • A bubble on the current node showing the context it evaluated against and the value it produced
  • A highlighted execution path, so you can see which branch ran
  • Failure reporting: the editor marks the node on the engine’s failure breadcrumb (node_ids in the structured error) with the error, and a rule that fails to compile reports the error in a banner above the diagram
  • An engine banner: if the WASM engine fails to load, a banner above the diagram gives the load error and the diagram stays static

Nodes show values only on the current step, not at rest.

With data, the component calls the engine’s evaluateWithTrace, which records the result of each sub-expression, the order of evaluation, the context at each step, and the final result. The engine also returns, for each node, the JSON Pointer into the rule that the node was compiled from, and the debugger uses those pointers to place each step on the node you wrote, aliases such as ?: included.

Editing

Set editable to turn on the full visual builder.

<DataLogicEditor
  value={expression}
  onChange={setExpression}
  editable
/>

Features:

  • Node selection
  • Properties panel for the selected node, with per-operator help and a link to that operator’s documentation page
  • Context menus (right-click a node or the canvas)
  • An Insert toolbar button (Cmd/Ctrl+K) that adds an argument to the selection, wraps it, or targets the root
  • Undo/redo (up to 50 steps), from the toolbar or the keyboard
  • Keyboard shortcuts: copy/paste (Cmd/Ctrl+C / V), duplicate (Cmd/Ctrl+D), select all (Cmd/Ctrl+A), undo/redo (Cmd/Ctrl+Z, Shift+Cmd/Ctrl+Z or Cmd/Ctrl+Y), delete (Backspace/Delete), deselect (Escape)

Shortcuts, the debugger’s included, apply only while focus is inside the editor; clicking anywhere in it gives it focus. A page with several editors, or with shortcuts of its own, keeps its keys. Text fields keep their editing keys, and buttons and links keep Space and Enter.

When editable is set, onChange is active: the editor debounces edits (about 300ms) and passes back the rebuilt JSONLogic expression so you can keep your own state in sync. Feeding that value back through value keeps the selection, the open properties panel, and the pan and zoom. Any other new value object from your code counts as a new rule: the canvas remounts and fits the view to it.

Editing with Live Debugging

Combine editable with data to edit and debug in the same view: the trace re-runs as you build, so you can step through the expression you are editing.

<DataLogicEditor
  value={expression}
  onChange={setExpression}
  data={contextData}
  editable
/>

Templating

Set templating so that multi-key objects and arrays in the compiled rule become output-shaping templates with embedded JSONLogic, rather than being rejected as invalid JSONLogic. This matches the v5 core API (Engine::builder().with_templating(true)). Passing onTemplatingChange adds a Templating checkbox to the toolbar; with templating alone the mode is fixed and no checkbox renders.

<DataLogicEditor
  value={expression}
  templating={templating}
  onTemplatingChange={setTemplating}
/>

Engine Settings and Custom Operators

config changes evaluation semantics for both the result and the trace, and customOperators registers extra operators on the engine:

<DataLogicEditor
  value={expression}
  data={contextData}
  config={{ preset: 'safe_arithmetic', truthy_evaluator: 'python' }}
  customOperators={{ double: (args) => Number(args[0]) * 2 }}
/>

The toolbar shows a summary whenever settings differ from the engine defaults. The editor rebuilds the engine, resetting selection, undo history and the debugger position, only when the settings in config or the set of customOperators names change. Inline object literals are fine: an equal config or a new function under an existing name keeps the engine. See Props & API for every key.

Behavior Comparison

AspectRead-onlyDebugger (data)Editing (editable)
Node displayStructure onlyStructure, plus values on the current stepEditable nodes
InteractivityPan/zoomPan/zoom + steppingFull editing
data requiredNoYesNo
OutputStaticStatic + traceTwo-way bound via onChange

Performance Considerations

  • Read-only is fastest: no evaluation overhead.
  • Debugger re-runs the trace when the content of data changes. A new object with the same content does not re-run it.
  • Editing rebuilds the expression on each change (debounced before onChange fires).

For large expressions or frequent data updates, defer the data you pass in:

import { useDeferredValue } from 'react';

function DebugWithDeferred({ expression, data }) {
  const deferredData = useDeferredValue(data);

  return (
    <DataLogicEditor
      value={expression}
      data={deferredData}
    />
  );
}

Toggling Behavior at Runtime

Because behavior is prop-driven, you toggle it by toggling props. For example, to switch between plain visualization and debugging, conditionally pass data:

function DebugToggle() {
  const [debug, setDebug] = useState(false);

  return (
    <div>
      <button onClick={() => setDebug((d) => !d)}>
        {debug ? 'Stop debugging' : 'Debug'}
      </button>

      <DataLogicEditor
        value={expression}
        data={debug ? data : undefined}
      />
    </div>
  );
}

Next Steps