Value tree
Show a JSON value a person can read and walk with the keyboard, with what a recorder left out as chips and highlights by JSON pointer.
7 min read
ValueTree shows a value the way a person reads it: each key with its value, text, numbers and constants in the colours of the code palette, lists and objects that open, a page of children at a time, and long text cut to one line until asked for. Use it for what a step received and returned, a run's input and output, the parameters of an approval, or any JSON a reader needs to look into. JsonViewer draws its trees with it.
import {
ValueTree,
formatValueInline,
pathText,
pointerOf,
summarizeValue,
summaryWords,
} from '@tale/ui/value-tree';
import { JsonViewer } from '@tale/ui/json-viewer';Read a value
Arrow keys move and open. Type a field name to jump to it.
Selected: nothing yet
Pass the value and an aria-label. The tree reads the value as JSON first: a missing key and undefined are the same, a date reads as its text. The top level shows; lists and objects below it stay closed. defaultExpandDepth opens more levels: 2 opens the containers of the top level, Infinity opens everything.
A list or an object shows its size in words, such as "a list of 3 items", and opens with its chevron, a click or the → key. A container with more than pageSize children (50) shows that many and a Show 50 more row. Text longer than maxStringChars (240) shows as one cut line with Show all 400 characters; → shows it whole and ← cuts it again.
Pass onSelectPointer to let the reader pick a place: a click or Enter calls it with the row's JSON pointer, and selectedPointer marks that row as selected. The tree opens and pages its way to the selected place, and scrolls it into view when the selection changes from outside. Without onSelectPointer, a click opens and closes a container.
Every row offers Copy value and Copy path on hover, and ⌘C or Ctrl+C copies the focused row's value, ⇧⌘C or Ctrl+Shift+C its path, such as issues[0].title. Text copies as the text itself, anything else as JSON. Set copyable={false} to leave both out. density="compact" makes 24px rows for an inspector; the default rows are 28px.
Show what a recorder left out
Arrow keys move and open. Type a field name to jump to it.
A run records values out of band: it cuts long text, drops list items past a limit, replaces values deeper than it keeps with null, and hides secrets, and it lists each place beside the value instead of writing a marker into it. Pass those lists as elided and redacted (a RecordedValue's fields), and the tree shows each place as a chip, never as a value:
elided kind | The row shows |
|---|---|
string | The text that was kept, then "+3,412 characters not kept". |
items | The list's size, then "+18 items not kept". |
depth | "Deeper levels not kept" in place of the null the recorder left. |
whole | "Too large to keep (52 KB)" in place of the value. |
A pointer in redacted shows Hidden secret in place of its value, with "Tale hides secrets in recorded values." on hover. A cut or a secret at the whole value's pointer ('') shows above the tree. A diff reads the same places as unknown rather than changed: pass them to DataDiff as unknownAt.