Data components display and edit extracted document data within V2 data forms. Each component binds to the data context via taxonomy tag paths, rendering the appropriate editor or display based on the taxon type defined in your taxonomy.
v2:attributeEditor
The core editing component. It resolves a taxonomy tag path to a data object attribute and renders the correct editor (text input, dropdown, date picker, etc.) based on the taxon type.
Props
| Prop | Type | Default | Description |
|---|
| tagPath | string | required | Taxonomy path to bind to |
| label | string | — | Display label (auto-derived from the last segment of the tag path if omitted) |
| colSpan | number | — | Column span in grid layout (1-12) |
| readonly | boolean | false | Disable editing |
| valueFrom | string | — | Tag path to mirror value from (makes field read-only, see Data Binding) |
| editorOptions | AttributeEditorOptions | — | Advanced editor configuration (see below) |
When valueFrom is set, the editor becomes a read-only input that displays the value from the referenced tag path. It checks shared formValues first, then falls back to searching data object attributes.
Editor Options
The editorOptions object provides fine-grained control over editor behavior and appearance.
| Option | Type | Description |
|---|
| placeholder | string | Placeholder text when empty |
| cellMode | boolean | Excel-like flat appearance for grid cells — no border/shadow by default, border appears on hover/focus |
| cellBackground | string | Cell background color (e.g., '#f0fdf4') |
| cellColor | string | Cell text color (e.g., '#166534') |
| cellTestId | string | Custom data-testid for testing |
| displayAsRadio | boolean | Render SELECTION taxons as radio buttons instead of a dropdown |
| radioOrientation | "horizontal" | "vertical" | Layout for radio options when displayAsRadio is true. "horizontal" (default) wraps options across the row, each option sharing the available width; "vertical" stacks one option per line at full width. Ignored unless displayAsRadio is true. |
| isCheckbox | boolean | Render as a checkbox |
| onCheckValue | string | Value to set when checkbox is checked |
| showCalendarPopup | boolean | Show a calendar picker for date fields |
| sourceDateFormat | string | Source date format for parsing |
| maskDateFormat | string | Display date format |
| isMaskedText | boolean | Use masked text display |
| maskedText | string | Mask pattern |
| hideExceptionPopup | boolean | Hide the validation exception popup |
| showPreview | boolean | Show value preview |
| hideAttributeMenu | boolean | Hide the attribute context menu (defaults to false) |
| hideInsertActions | boolean | Hide insert actions |
| allowDirectExtract | boolean | Enable direct text extraction from the document (see Extraction) |
| aiExtraction | AIExtractionConfig | AI-powered extraction configuration (see Extraction) |
| showAddFromSelection | boolean | Show a ”+” button on text selection (implied when aiExtraction is configured) |
allowDirectExtract and aiExtraction are mutually exclusive. Use allowDirectExtract for fields where the value can be copied verbatim from the document. Use aiExtraction when an LLM should interpret and extract the value.
When aiExtraction is configured without an explicit placeholder, the editor auto-sets the placeholder to “Select text in document, then click to extract”. When allowDirectExtract is configured without a placeholder, it auto-sets to “Select text in document to copy value”.
Examples
Basic attribute editor:
{
"component": "v2:attributeEditor",
"props": {
"tagPath": "invoice/invoiceNumber",
"label": "Invoice Number"
}
}
Read-only editor with value mirrored from another field:
{
"component": "v2:attributeEditor",
"props": {
"tagPath": "invoice/displayTotal",
"label": "Total",
"readonly": true,
"valueFrom": "invoice/calculatedTotal"
}
}
Checkbox editor:
{
"component": "v2:attributeEditor",
"props": {
"tagPath": "invoice/approved",
"label": "Approved",
"editorOptions": {
"isCheckbox": true,
"onCheckValue": "true"
}
}
}
SELECTION field rendered as stacked radio buttons:
{
"component": "v2:attributeEditor",
"props": {
"tagPath": "invoice/approvalStatus",
"label": "Approval Status",
"editorOptions": {
"displayAsRadio": true,
"radioOrientation": "vertical"
}
}
}
v2:label
A read-only text display component. Use it for static headings, section titles, or descriptive text within a form.
Props
| Prop | Type | Default | Description |
|---|
| text | string | required | The text content to display |
| class | string | text-sm font-medium text-foreground | CSS class string for styling |
Example
{
"component": "v2:label",
"props": {
"text": "Shipping Details",
"class": "text-base font-bold text-foreground mb-2"
}
}
Labels support dynamic text via bindings:
{
"component": "v2:label",
"bindings": {
"text": "`Total items: ${ctx.dataObjects?.length ?? 0}`"
}
}
v2:table
A row-based data display and editing component. It scopes rows by the parent taxonomy path of the first column’s tag metadata, then renders each matching data object as a table row with inline attribute editors.
Props
| Prop | Type | Default | Description |
|---|
| tagPathPrefix | string | — | Taxonomy path prefix for scoping rows |
| columns | Array | required | Column definitions |
Each entry in columns has the following shape:
| Field | Type | Required | Description |
|---|
| tagPath | string | yes | Taxonomy path for the column’s attribute |
| label | string | yes | Column header text |
| width | string | no | CSS width (e.g., '200px', '30%') |
Example
A three-column table for invoice line items:
{
"component": "v2:table",
"props": {
"tagPathPrefix": "invoice/lineItems",
"columns": [
{ "tagPath": "invoice/lineItems/description", "label": "Description", "width": "50%" },
{ "tagPath": "invoice/lineItems/quantity", "label": "Qty", "width": "25%" },
{ "tagPath": "invoice/lineItems/amount", "label": "Amount", "width": "25%" }
]
}
}
When no matching data objects are found, the table displays a “No line items found” placeholder.
v2:grid
An enhanced data grid backed by the KodexaDataObjectGrid component (ag-Grid). It provides sorting, filtering, grouping, and inline editing for repeating data objects.
Props
| Prop | Type | Default | Description |
|---|
| groupTaxon | string | required | Taxonomy path of the group taxon whose children define columns |
| groupable | boolean | false | Enable row grouping |
| showColumnMenu | boolean | false | Show column menu for visibility and ordering |
| aiExtraction | AIGridExtractionConfig | — | AI-powered row extraction (see Extraction) |
| columns | V2GridColumnConfig[] | — | Custom per-row columns that render arbitrary V2 components instead of taxon-driven attribute editors (see below) |
| height | number | — | Pixel height of the grid. When omitted, the grid sizes itself with calc(100vh - 19rem). An explicit value always wins, including when the grid runs inside a parent data-object scope. |
| editorOptions | AttributeEditorOptions | — | Default editor options applied to every taxon-driven cell. Useful for toggling allowDirectExtract off (defaults to true for grid cells). |
| limitColumns | string[] | — | Restrict the taxon-driven columns to this tag-path subset, in order |
| pagination | boolean | false | Enable ag-Grid pagination. Defaults to false on v2:grid so reviewer grids show all rows in a bounded, scrollable grid. Set true to page the grid. |
| sort | V2GridSortEntry[] | — | Default sort applied when the grid loads. An array of entries; the first entry is the primary sort, additional entries produce a multi-column sort in order. Each entry is { tagPath?, header?, direction }. |
The grid automatically builds its column definitions from the children of the specified groupTaxon in the taxonomy. All data objects in the current data context are passed to the grid, which filters them internally by path and parent ID.
Each entry in sort is a V2GridSortEntry:
| Field | Type | Required | Description |
|---|
| tagPath | string | no | Matches a taxon-driven column by its tag path |
| header | string | no | Matches a custom column by its header text (case-insensitive) |
| direction | "asc" | "desc" | yes | Sort direction |
Provide exactly one of tagPath or header per entry to select the column to sort on. For example, a default ascending sort on a line-item amount column: { "tagPath": "invoice/lineItems/amount", "direction": "asc" }.
Custom columns
Each entry in columns mounts a registered V2 component as the cell renderer for that column, alongside the taxon-driven attribute columns. Use this for columns that don’t map to a single taxon attribute — source-document badges, copy buttons, per-row delete affordances.
| Field | Type | Required | Description |
|---|
| header | string | yes | Column header label |
| component | string | yes | V2 component type name without the v2: prefix (e.g. "attributeSourceBadge", "attributeCopyButton", "attributeRowPromote", "attributeRowDeleteButton") |
| props | Record<string, unknown> | no | Props forwarded to the cell component on every render |
| width | number | no | Pixel width (defaults to 220) |
| position | "start" | "end" | no | Place left of ("start") or right of ("end", default) the taxon columns |
| pinned | "left" | "right" | no | Pin the column to the grid edge |
| sortable | boolean | no | Opt this custom column into sort interaction. The sort proxy is the first matching attribute’s tagId (resolved from the column’s props.tagPath), which orders rows by document page — a stable approximation of source-document order in multi-doc packs. Reference the column in the form’s sort array by its header. |
A sortable custom column paired with a matching sort entry — the grid loads with the “Source” column sorted ascending:
{
"component": "v2:grid",
"props": {
"groupTaxon": "invoice/lineItems",
"sort": [
{ "header": "Source", "direction": "asc" }
],
"columns": [
{
"header": "Source",
"component": "attributeSourceBadge",
"sortable": true,
"props": { "tagPath": "invoice/lineItems/amount" }
}
]
}
}
Example
A grid for financial line items:
{
"component": "v2:grid",
"props": {
"groupTaxon": "financialStatement/lineItems",
"groupable": true,
"showColumnMenu": true
}
}
Grid with AI extraction:
{
"component": "v2:grid",
"props": {
"groupTaxon": "invoice/lineItems",
"aiExtraction": {
"promptRef": "my-org/extract-line-items",
"modelType": "LARGE"
}
}
}
When aiExtraction is configured, an “AI Extract” button appears in the grid toolbar. Target fields are automatically derived from the group taxon’s children unless explicitly overridden via targetPaths.
v2:dataTable
A read-only data grid for rendering arbitrary JSON data, powered by AG Grid. Unlike v2:table (which binds to taxonomy tag paths and renders inline attribute editors), v2:dataTable takes a plain array of objects and renders them in a fully-featured grid with sorting, filtering, and column resizing. It is typically used as a child of v2:serviceBridgeView to display bridge responses, but can be used anywhere with binding expressions.
The grid automatically uses the platform’s AG Grid theme, matching light/dark mode.
Props
| Prop | Type | Default | Description |
|---|
| rows | array | — | Array of objects to render as rows |
| columns | Array | — | Column definitions (inferred from first row if omitted) |
| emptyMessage | string | "No data" | Message shown when there are no rows |
| filterable | boolean | true | Show a quick-filter search box above the grid that filters across all columns. Set to false to hide it. |
| pageSize | number | 10 | Number of rows per page. The grid always shows a pagination footer with row counts and page navigation. Adjust this to control how many rows are visible per page. |
Each entry in columns:
| Field | Type | Required | Description |
|---|
| field | string | yes | Property name to read from each row object |
| title | string | no | Column header text (defaults to the field name) |
| width | number | no | Column width in pixels. Columns without a width flex to fill available space. |
| type | string | no | Column type: "string" (default) or "boolean" (renders checkmark/cross icon) |
Built-in Features
Because v2:dataTable uses AG Grid under the hood, you get these features automatically:
- Quick filter — a search box above the grid filters across all columns as you type (enabled by default, disable with
filterable: false)
- Pagination — a footer showing row counts (e.g. “1 to 10 of 25”) with page navigation controls. Defaults to 10 rows per page, configurable via
pageSize.
- Sorting — click any column header to sort ascending/descending
- Column filtering — each column header shows a filter icon with type-appropriate filtering (text search for strings, set filter for booleans)
- Column resizing — drag column borders to resize
- Theme integration — automatically follows the platform’s light/dark mode
Examples
With explicit columns (quick filter and pagination are enabled by default):
{
"component": "v2:dataTable",
"bindings": {
"rows": "ctx.$bridgeResult"
},
"props": {
"columns": [
{ "field": "carrier", "title": "Carrier" },
{ "field": "rate", "title": "Rate", "width": 120 },
{ "field": "transit", "title": "Transit Days", "width": 120 }
]
}
}
Custom page size with quick filter disabled:
{
"component": "v2:dataTable",
"bindings": {
"rows": "ctx.$bridgeResult"
},
"props": {
"filterable": false,
"pageSize": 25,
"columns": [
{ "field": "carrier", "title": "Carrier" },
{ "field": "rate", "title": "Rate", "width": 120 },
{ "field": "transit", "title": "Transit Days", "width": 120 }
]
}
}
Boolean column with checkmark rendering:
{
"component": "v2:dataTable",
"bindings": {
"rows": "ctx.$bridgeResult"
},
"props": {
"filterable": true,
"columns": [
{ "field": "name", "title": "Bill To Name" },
{ "field": "isValid", "title": "Valid", "type": "boolean", "width": 100 }
]
}
}
With auto-inferred columns (column headers derived from property names):
{
"component": "v2:dataTable",
"bindings": {
"rows": "ctx.$bridgeResult?.items"
}
}
Static data via props (no bridge required):
{
"component": "v2:dataTable",
"props": {
"rows": [
{ "code": "USD", "name": "US Dollar" },
{ "code": "EUR", "name": "Euro" },
{ "code": "GBP", "name": "British Pound" }
],
"columns": [
{ "field": "code", "title": "Currency Code" },
{ "field": "name", "title": "Currency Name" }
]
}
}
v2:markdown
Renders markdown content as formatted HTML using the platform’s KodexaMarkdown renderer. Supports headings, lists, tables, code blocks, and all standard markdown syntax. Typically used as a child of v2:serviceBridgeView to display formatted text from bridge responses.
Props
| Prop | Type | Default | Description |
|---|
| content | string | — | Markdown content to render |
| size | string | "medium" | Size variant ("small", "medium", "large") |
Examples
Static markdown:
{
"component": "v2:markdown",
"props": {
"content": "### Instructions\n\nReview the extracted values and correct any errors before approving."
}
}
Dynamic content from a bridge response:
{
"component": "v2:markdown",
"bindings": {
"content": "ctx.$bridgeResult?.analysisReport"
}
}
Markdown with size variant:
{
"component": "v2:markdown",
"bindings": {
"content": "ctx.$bridgeResult?.summary"
},
"props": {
"size": "small"
}
}
v2:knowledgeSection
Displays knowledge base content within a form. It looks up a knowledge item by type from the workspace’s document families, loads the item’s markdown content, and renders it in a collapsible section.
Props
| Prop | Type | Default | Description |
|---|
| knowledgeItemType | string | required | The knowledge item type identifier to look up |
The component handles three states: loading (with a spinner), not found (with an italicized message), and loaded (with an expandable section showing the title and rendered markdown).
Example
{
"component": "v2:knowledgeSection",
"props": {
"knowledgeItemType": "processing-instructions"
}
}
The component searches across all document families in the current workspace for a knowledge item matching the specified type. The item’s instructionMarkdown property is rendered as formatted HTML with support for headings, lists, tables, and code blocks.
v2:exceptions
Displays validation exceptions for data objects in the current scope. It aggregates exceptions from all data objects, filters by status and tag paths, and renders each exception as a compact card.
Props
| Prop | Type | Default | Description |
|---|
| title | string | — | Optional heading above the exceptions list |
| showResolved | boolean | false | Include resolved exceptions (by default only open exceptions are shown) |
| filterPaths | string[] | — | Only show exceptions for these tag paths (shows all if omitted) |
The component listens for workspace:dataExceptionsUpdated events and refreshes automatically when exceptions change.
Example
{
"component": "v2:exceptions",
"props": {
"title": "Validation Issues",
"filterPaths": ["Invoice/InvoiceNumber", "Invoice/InvoiceDate"]
}
}
v2:attributeSourceBadge
A grid cell renderer that surfaces the source document(s) an attribute was extracted or promoted from, as one or more colored, clickable pills. For each attribute on the row at tagPath, it walks the attribute’s spatial anchor (tagId) to the containing page, reads the preprocessor-set document_type + group sequence, and renders one badge per distinct (document_type, group) tuple.
Clicking a badge dispatches workspace.focusTag(tagId, viewId), highlighting the source content in the document viewer.
Props
| Prop | Type | Default | Description |
|---|
| tagPath | string | required | Path of the row attribute whose spatial anchor identifies the source document |
Use the badge as a custom column on a v2:grid — its instance numbering ("Bill of Lading #1, #2, …") is scoped per document type, so a form rendering multiple BoLs alongside multiple Invoices shows the right number for each pill regardless of how the underlying preprocessor sequences them.
Example
{
"component": "v2:grid",
"props": {
"groupTaxon": "shipments/additionaldocumentnumbers",
"columns": [
{
"header": "Source",
"component": "attributeSourceBadge",
"width": 180,
"props": {
"tagPath": "shipments/additionaldocumentnumbers/docvalue"
}
}
]
}
}
A grid cell renderer that promotes the row’s attribute at sourceTagPath up to an ancestor scalar at targetTagPath. The source attribute’s tagId is carried onto the target so click-to-source navigation in the document viewer keeps working after the copy.
Click semantics: overwrites the destination silently and idempotently. If the target already has an attribute for that tag, it is updated in place (preserving its id so downstream watchers see a value change, not a delete + add). Duplicate target attributes left over from prior sessions are pruned automatically.
Props
| Prop | Type | Default | Description |
|---|
| sourceTagPath | string | required | Path of the row attribute whose value will be copied |
| targetTagPath | string | required | Path of the ancestor scalar (e.g. shipments/sidnumber) that receives the value. The button walks up the row’s parent chain until it finds the ancestor whose path matches the prefix of targetTagPath. |
| tooltip | string | "Copy to <targetTagPath>" | Button tooltip text |
| relatedCopies | {sourceTagPath, targetTagPath}[] | — | Additional copy pairs executed in the same click after the primary copy. Use when promoting a value only makes sense alongside sibling fields — e.g. promoting a weight value requires the matching UOM. |
Examples
Single-field promotion:
{
"component": "v2:grid",
"props": {
"groupTaxon": "shipments/additionaldocumentnumbers",
"columns": [
{
"header": "",
"component": "attributeCopyButton",
"width": 60,
"props": {
"sourceTagPath": "shipments/additionaldocumentnumbers/docvalue",
"targetTagPath": "shipments/sidnumber",
"tooltip": "Copy to SID/DOC Number"
}
}
]
}
}
Multi-field promotion with relatedCopies — promotes weight and its UOM together:
{
"component": "attributeCopyButton",
"props": {
"sourceTagPath": "shipments/candidateweights/weightvalue",
"targetTagPath": "shipments/shipweight",
"tooltip": "Promote weight + UOM",
"relatedCopies": [
{
"sourceTagPath": "shipments/candidateweights/weightuom",
"targetTagPath": "shipments/shipweightuom"
}
]
}
}
v2:attributeCopyAction
A scalar sibling-copy inline icon button for form layouts (not grid cells). Clicking it reads the value at sourceTagPath and writes it to a sibling scalar at targetTagPath on the same parent data object.
Where v2:attributeCopyButton is a grid cell renderer that promotes a row attribute up to an ancestor scalar by walking the ag-grid row’s parent chain, v2:attributeCopyAction resolves both paths at the form / data-context level — there is no grid row involved. Source and target must therefore live on the same parent taxonomy path (they are siblings). It sits alongside v2:attributeRowPromote (a row-level promote variant); use v2:attributeCopyAction for the form-layout, sibling-to-sibling case.
Props
| Prop | Type | Default | Description |
|---|
| sourceTagPath | string | required | Scalar path to read the value from |
| targetTagPath | string | required | Sibling scalar path to overwrite |
| tooltip | string | "Copy to <last segment of targetTagPath>" | Button tooltip and aria-label |
| relatedCopies | {sourceTagPath, targetTagPath}[] | — | Extra sibling copy pairs run in the same click — e.g. copy a charge amount and its paired currency or unit scalar together |
Behavior
- Value resolution prefers
dataContext.formValues, then the stored attribute (decimalValue, then stringValue), then a display-only formula-engine fallback for FORMULA taxons that have not persisted a value yet (the formula source is evaluated through the formula engine so the button works on stale-at-init documents). The fallback is never written back.
- The write always sets
stringValue, value, and decimalValue so number-typed targets (NUMBER, CURRENCY, DECIMAL, INTEGER, PERCENTAGE) re-render immediately rather than showing the stale prior string.
- The source attribute’s
tagId is carried onto the target so click-to-source navigation keeps working.
- The button is disabled while the source resolves to empty, zero, or non-numeric, and shows a brief green checkmark on success.
- An existing target attribute is updated in place (its id is preserved) and duplicate targets are pruned.
Example
In a plain form layout (not inside v2:grid columns), copy a computed line-items total into an editable total field, carrying the currency scalar along with it:
{
"component": "v2:attributeCopyAction",
"props": {
"sourceTagPath": "invoice/lineItemsTotal",
"targetTagPath": "invoice/total",
"tooltip": "Copy to Total",
"relatedCopies": [
{
"sourceTagPath": "invoice/lineItemsCurrency",
"targetTagPath": "invoice/currency"
}
]
}
}
A grid cell renderer (a custom column on v2:grid) that surfaces N promote destinations as a single “Promote to…” dropdown per row. It replaces the older pattern of one v2:attributeCopyButton chevron column per destination.
How it differs from its siblings: v2:attributeCopyButton is one chevron button per single destination column; v2:attributeRowPromote collapses multiple destinations into one dropdown driven by a targets array, and adds an optional per-target sourceTagPath override. (v2:attributeCopyAction is the scalar form-button variant for non-grid layouts.)
Props
| Prop | Type | Default | Description |
|---|
| sourceTagPath | string | required | Path of the row attribute promoted. Used as the default source for every target unless a target overrides it. |
| targets | PromoteTarget[] | required | The dropdown destinations (at least one entry) |
| label | string | "Promote to…" | Trigger button text |
The grid injects the cell context automatically, so authors do not set a params prop.
Each entry in targets is a PromoteTarget:
| Field | Type | Required | Description |
|---|
| label | string | yes | Dropdown item text, also shown in the green "✓ <label>" success state |
| targetTagPath | string | yes | Ancestor scalar that receives the value, resolved by walking the row’s parent chain up to the matching path prefix |
| sourceTagPath | string | no | Per-target override of the component-level sourceTagPath, resolved via the same ancestor traversal so a source on the row or on any ancestor works. Falls back to the component-level sourceTagPath when omitted. |
| relatedCopies | {sourceTagPath, targetTagPath}[] | no | Sibling copy pairs run in the same selection — e.g. a unit-of-measure promoted alongside a numeric value |
Behavior
The promote is idempotent — it follows the same resolve / update / dedupe path as v2:attributeCopyButton, updating an existing target attribute in place (preserving its id), creating one if absent, and pruning duplicates. The source tagId is carried onto the target so click-to-source navigation keeps working. It writes decimalValue so number-typed targets (NUMBER, CURRENCY, DECIMAL, INTEGER, PERCENTAGE) render immediately without tabbing away. The dropdown is disabled when the row has no source value or while a promote is in flight, and shows a transient green checkmark confirmation on success.
Example
Place it as a custom column inside v2:grid. Here a per-row weight promotes to two ancestor scalars — one target overrides the source to a parent-level scalar, and each carries its unit-of-measure along:
{
"component": "v2:grid",
"props": {
"groupTaxon": "shipment/stops",
"columns": [
{
"header": "",
"component": "attributeRowPromote",
"width": 150,
"props": {
"sourceTagPath": "shipment/stops/weight",
"label": "Promote to…",
"targets": [
{
"label": "Gross Weight",
"targetTagPath": "shipment/grossWeight",
"relatedCopies": [
{
"sourceTagPath": "shipment/stops/weightUom",
"targetTagPath": "shipment/grossWeightUom"
}
]
},
{
"label": "Billed Weight",
"sourceTagPath": "shipment/computedWeight",
"targetTagPath": "shipment/billedWeight",
"relatedCopies": [
{
"sourceTagPath": "shipment/stops/weightUom",
"targetTagPath": "shipment/billedWeightUom"
}
]
}
]
}
}
]
}
}
A grid cell renderer that deletes the row’s data object inline, with no confirmation prompt. Surfaces the same behavior as the 3-dots actions menu’s “Delete Row” item as an always-visible button so reviewers don’t have to open a menu per row when scrubbing extraction noise from tables that frequently pick up junk rows (freight classes, accessorials).
For bulk operations across multiple rows, use v2:gridDeleteBySource — that component confirms before deleting.
Props
| Prop | Type | Default | Description |
|---|
| tooltip | string | "Delete row" | Button tooltip text |
Example
{
"component": "v2:grid",
"props": {
"groupTaxon": "shipments/freightclasses",
"columns": [
{
"header": "",
"component": "attributeRowDeleteButton",
"width": 50,
"position": "end"
}
]
}
}
v2:gridDeleteBySource
A toolbar component that sits above a v2:grid and surfaces one Remove all <source> rows button per distinct source document detected on the configured tagPath. “Source” is the same (document_type, group) tuple v2:attributeSourceBadge shows, so reviewers see consistent source identity between the badge in the grid and the buttons above it.
Each button deletes every row in the group taxon whose configured-path attribute resolves to that source, after a single confirmation prompt. Designed for tables that frequently pick up rows from the wrong document — freight class line items pulled from the invoice instead of the BoL, or accessorials extracted from a manifest the reviewer wants to discard.
Props
| Prop | Type | Default | Description |
|---|
| groupTaxon | string | required | Same group-taxon path used by the sibling v2:grid. The toolbar deletes rows whose path matches this taxon. |
| tagPath | string | required | Path of the row attribute whose spatial anchor identifies the source. Should match the tagPath used by the grid’s attributeSourceBadge column so the buttons and badges agree on source identity. |
The toolbar renders nothing when no source can be resolved (empty grid, unloaded document), so it doesn’t reserve dead vertical space.
Example
Place the toolbar in the same parent layout as the grid:
[
{
"component": "v2:gridDeleteBySource",
"props": {
"groupTaxon": "shipments/freightclasses",
"tagPath": "shipments/freightclasses/freightclasscode"
}
},
{
"component": "v2:grid",
"props": {
"groupTaxon": "shipments/freightclasses",
"columns": [
{
"header": "Source",
"component": "attributeSourceBadge",
"props": { "tagPath": "shipments/freightclasses/freightclasscode" }
}
]
}
}
]
v2:routeTimeline
Renders a group taxon’s rows as a numbered vertical timeline of draggable stop cards for ordered lists (e.g. a multi-stop shipment route). Drag-reorder rewrites a per-row sequence attribute to the new 1-based order.
Props
| Prop | Type | Default | Description |
|---|
| groupTaxon | string | required | Path of the group taxon whose rows feed the timeline — one card per row / data object |
| sequenceTag | string | "stopSequence" | Tag name of the sequence attribute. Drag-reorder rewrites this attribute on every row to its new 1-based position. Rows missing this attribute are seeded (the attribute is created) on reorder so they can take a dropped position. |
| typeTag | string | "stopType" | Tag name of the stop-type SELECTION attribute that drives the colored pill (matched case-insensitively) |
| addressGroupTaxon | string | "<groupTaxon>/address" | Path of the optional child sub-group (one row per parent) supplying the name / address lines rendered on each card. One level of nesting only. |
| allowAdd | boolean | false | Show a ”+ Add stop” toolbar button |
| aiExtraction | AIGridExtractionConfig | — | Show an “AI extract stop” toolbar button driven by the configured prompt (see below) |
| viewId | string | — | Override which document-view store provides selection, page text, and WASM access. Falls back to the workspace’s active selection view. |
| expandable | boolean | false | Give each card a chevron toggle that reveals an inline edit panel |
| stopDetailTags | string[] | — | Direct-child taxon names rendered in the expanded panel. A domain-specific default exists; override it per form. |
| addressDetailTags | string[] | — | Sub-object child taxon names rendered in the expanded panel’s sub-panel. A domain-specific default exists; override it per form. |
| readonly | boolean | false | Render-only: disables drag-reorder and both toolbar buttons, and hides the drag handle, delete, and expand affordances |
| orientation | "vertical" | "horizontal" | "vertical" | Card layout. vertical stacks cards top-to-bottom with a left-rail connector; horizontal lays them left-to-right in a wrapping row with a chevron between adjacent cards. |
| show | "all" | "firstLast" | "all" | firstLast shows only the first and last card with a “+N more” pill to reveal the hidden middle cards inline |
Drag-reorder renumbers every row’s sequenceTag attribute to its new 1-based position; rows that are missing the sequence attribute are seeded (the attribute is created) so they can take a dropped position.
The ”+ Add stop” toolbar button is gated by allowAdd. It creates a parent row plus an empty child sub-object and seeds the sequence at the end of the list.
The “AI extract stop” toolbar button is gated by aiExtraction. It runs a single-record, selection-anchored LLM extraction: anchored on the user’s highlighted / selected text plus the line-numbered page text, it fills one parent record plus one level of nested sub-object (e.g. the address), writes per-attribute document highlights, and seeds the sequence at the end of the list. The config object mirrors the aiExtraction used by v2:grid: modelType is SMALL (default) or LARGE, and the prompt is supplied via promptRef (a stored prompt reference) or an inline prompt string.
Per card (subject to readonly and slice gating): a type pill driven by typeTag (pickup, intermediate, and delivery values render distinct colors; anything else is a neutral pill); an optional location-code badge; the name and address summary; a find-in-document button (visible only when a navigable source anchor exists) that scrolls to and highlights the source content; an expand chevron when expandable is set; and a per-row delete (no confirmation).
When expandable is true, the inline edit panel edits the row’s direct-child scalars (stopDetailTags) and its nested sub-object group (addressDetailTags). The sequence is never editable from the panel — drag order owns it. The panel is suppressed when readonly is set.
With show: "firstLast" and more than 2 rows, the timeline collapses to the first and last card and disables drag and hides the toolbar (Add / AI). At 2 or fewer rows it falls back to "all" behavior.
Example
A vertical timeline for a multi-stop shipment route, with add and AI extraction enabled and an expandable edit panel. The detail-tag defaults are overridden with neutral per-form tags:
{
"component": "v2:routeTimeline",
"props": {
"groupTaxon": "shipments/stops",
"sequenceTag": "stopSequence",
"typeTag": "stopType",
"addressGroupTaxon": "shipments/stops/address",
"allowAdd": true,
"expandable": true,
"orientation": "vertical",
"show": "all",
"stopDetailTags": ["stopType", "weight"],
"addressDetailTags": ["name", "addressLine1", "city", "region", "postalCode"],
"aiExtraction": {
"promptRef": "my-org/extract-stop",
"modelType": "SMALL"
}
}
}