React Components

@visual-json/react provides a complete set of React components for building visual JSON editors. All components are designed to work together inside a VisualJson provider.

npm install @visual-json/react @visual-json/core

VisualJson

The root provider that manages tree state, selection, expansion, undo/redo, search, and schema. All other components must be rendered inside this provider.

import { VisualJson } from "@visual-json/react";

<VisualJson value={json} onChange={setJson} schema={schema}>
  {/* child components */}
</VisualJson>
PropTypeDescription
valueJsonValueThe JSON data to edit
onChange(value: JsonValue) => voidCalled when the data changes
schemaJsonSchema | nullOptional JSON Schema for validation and form hints
childrenReactNodeChild components

TreeView

Hierarchical tree with expand/collapse, drag-and-drop, keyboard navigation, and right-click context menus.

import { TreeView } from "@visual-json/react";

<TreeView className="h-full" />

Utility

getVisibleNodes(root: TreeNode, expandedIds: Set<string>): TreeNode[] returns the flat list of nodes currently visible in the tree.

FormView

Schema-aware form editor. Renders fields with descriptions, required indicators, and enum dropdowns when a schema is provided.

import { FormView } from "@visual-json/react";

<FormView className="p-4" />

DiffView

Side-by-side comparison of two JSON values with color-coded additions, removals, and changes.

import { DiffView } from "@visual-json/react";

<DiffView originalJson={original} currentJson={current} />
PropTypeDescription
originalJsonunknownThe original JSON value
currentJsonunknownThe current/modified JSON value
classNamestringOptional CSS class

Breadcrumbs

Displays the path to the currently selected node as clickable breadcrumbs.

import { Breadcrumbs } from "@visual-json/react";

<Breadcrumbs className="px-2 py-1" />

SearchBar

Search input with next/previous navigation. Supports Cmd/Ctrl+F to focus.

import { SearchBar } from "@visual-json/react";

<SearchBar className="w-full" />

ContextMenu

Rendered by TreeView on right-click. Can also be used standalone.

import { ContextMenu } from "@visual-json/react";

<ContextMenu
  x={100}
  y={200}
  items={[
    { label: "Copy", action: handleCopy },
    { separator: true },
    { label: "Delete", action: handleDelete },
  ]}
  onClose={handleClose}
/>

useStudio Hook

Access the full studio state and actions from any component inside VisualJson.

import { useStudio } from "@visual-json/react";

function MyComponent() {
  const { state, actions } = useStudio();

  return (
    <button onClick={() => actions.undo()} disabled={!actions.canUndo}>
      Undo
    </button>
  );
}

State

FieldTypeDescription
treeTreeStateCurrent tree state
focusedNodeIdstring | nullNode with keyboard focus
selectedNodeIdsSet<string>Set of selected node IDs
anchorNodeIdstring | nullAnchor node for range selection
drillDownNodeIdstring | nullNode shown as root in the form view
expandedNodeIdsSet<string>Set of expanded node IDs
schemaJsonSchema | nullActive JSON Schema
searchQuerystringCurrent search query
searchMatchesSearchMatch[]Search results
searchMatchIndexnumberIndex of the active match
searchMatchNodeIdsSet<string>Node IDs with matches

Actions

ActionDescription
setTree(state)Replace the tree state
selectNode(id)Select a single node (clears multi-selection)
toggleNodeSelection(id)Toggle a node in the selection set
selectNodeRange(id)Extend selection from anchor to the given node
setSelection(focusedId, selectedIds, anchorId)Set focus, selection, and anchor in one call
setVisibleNodesOverride(nodes)Override visible nodes used for range selection (set null to clear)
drillDown(id)Set the form view display root
toggleExpand(id)Toggle node expansion
expandNode(id)Expand a node
collapseNode(id)Collapse a node
expandAll()Expand all nodes
collapseAll()Collapse all nodes
undo()Undo last change
redo()Redo last undone change
canUndoWhether undo is available
canRedoWhether redo is available
setSearchQuery(q)Update search query
nextSearchMatch()Jump to next match
prevSearchMatch()Jump to previous match