Skip to main content
Data form components display values that originate from a document’s extracted data — the data objects and attributes produced by the taxonomy and extraction pipeline. At render time, the form renderer assembles these into a DataContextV2 object and injects it via Vue’s provide/inject mechanism so every component in the tree can access it as ctx.

Context Variables

Binding expressions receive a ctx object with the following properties:
VariableTypeDescription
ctx.dataObjectsany[]All data objects in the current scope
ctx.$itemanyCurrent item when inside a for loop
ctx.$indexnumberCurrent index when inside a for loop
ctx.$parentDataContextV2Parent data context (for nested scopes such as groupTaxon)
ctx.$rootDataContextV2Root data context, always the top-level context
ctx.tagMetadataMapMap<string, any>Taxonomy metadata definitions keyed by tag path
ctx.formValuesRecord<string, string>Shared record for cross-field value exchange
The full TypeScript interface:
interface DataContextV2 {
  dataObjects?: any[];
  $item?: any;
  $index?: number;
  $parent?: DataContextV2;
  $root?: DataContextV2;
  tagMetadataMap?: Map<string, any>;
  formValues?: Record<string, string>;
  [key: string]: any;
}

Props vs Bindings

Every UINode can set values on its component through two mechanisms:
  • props — static values set at definition time. They do not change unless the form definition itself changes.
  • bindings — JavaScript expressions evaluated against ctx at render time. They re-evaluate automatically whenever the underlying data context changes.
When both props and bindings define the same key, the binding result takes precedence.
{
  "component": "card:label",
  "props": {
    "label": "Invoice"
  }
}
{
  "component": "card:label",
  "bindings": {
    "label": "ctx.dataObjects[0]?.attributes?.find(a => a.path === 'invoice/vendor')?.value || 'Untitled'"
  }
}
The first example always displays “Invoice”. The second evaluates against live data and updates when the data objects change. See the V2 Data Binding guide for full expression syntax and the reactivity model.

Tag Metadata

Components such as v2:attributeEditor use a tagPath prop to look up the corresponding taxonomy definition from ctx.tagMetadataMap. The metadata tells the component the attribute’s data type (string, number, date, SELECTION), the available options for selection fields, the display label, and any validation or formatting rules defined in the taxonomy. This removes the need to duplicate type information in the form definition itself.

Cross-Field Linking with valueFrom

The valueFrom prop on v2:attributeEditor displays a value sourced from a different attribute instead of its own:
  • Set valueFrom to the tag path of the source attribute.
  • The field becomes read-only automatically.
  • The renderer checks ctx.formValues first, then falls back to searching ctx.dataObjects for a matching attribute path.
This is useful for showing a computed or linked value — for example, displaying a total calculated elsewhere, or mirroring a value from a related data object.
{
  "component": "v2:attributeEditor",
  "props": {
    "tagPath": "invoice/computedTotal",
    "label": "Computed Total",
    "valueFrom": "invoice/lineItemSum"
  }
}
Here the editor at invoice/computedTotal displays the value from invoice/lineItemSum and prevents direct editing.

Scoped Contexts with groupTaxon

When a v2:panel sets the groupTaxon prop, it scopes the data context for its children:
  1. The panel filters ctx.dataObjects for objects whose path matches the groupTaxon value.
  2. If multiple matching objects exist, the panel renders a tab for each instance.
  3. Children receive a scoped DataContextV2 containing only the active data object and all of its descendants (collected recursively by parentId).
  4. Nested groupTaxon panels work within the already-scoped parent context, enabling hierarchies such as line items within a shipment.
{
  "component": "v2:panel",
  "props": {
    "title": "Shipments",
    "groupTaxon": "shipments"
  },
  "children": [
    {
      "component": "v2:attributeEditor",
      "props": {
        "tagPath": "shipments/trackingNumber",
        "label": "Tracking Number"
      }
    },
    {
      "component": "v2:panel",
      "props": {
        "title": "Line Items",
        "groupTaxon": "shipments/lineItems"
      },
      "children": [
        {
          "component": "v2:attributeEditor",
          "props": {
            "tagPath": "shipments/lineItems/description",
            "label": "Description"
          }
        }
      ]
    }
  ]
}
If a document contains three shipment data objects, the outer panel renders three tabs. Selecting a tab scopes all child components — including the nested line items panel — to that shipment’s data. The inner panel then further scopes to the line items belonging to the selected shipment.

Next Steps

Layout Components

Panels, tabs, rows, columns, and alerts

Data Components

Attribute editors, tables, grids, and more

Extraction

Direct extract and AI-powered data extraction

Events & Scripting

Event handlers, QuickJS runtime, and document API