A JSON viewer on the tree family's pattern: objects and arrays open and close with a height animation and a spring on the chevron, closed ones show a preview like {3 keys} or [12 items], and values are colored by type with strings, numbers, booleans and null each told apart in light and dark themes. Long arrays arrive in chunks behind a Show more row, a search field highlights matching keys and values, opens their parents and reaches into chunked arrays, and every row copies its value or its path, written the way you would in code (data.dates[2].city). Values stay selectable. The whole viewer is a WAI-ARIA tree: arrow keys walk it, Right and Left open, close and climb, `*` opens every sibling, and Cmd or Ctrl + C copies the focused value (with Shift, its path).
The import and the props worth knowing about, in one place.
import { TreeJson } from "@/components/beste/component/tree-json";
<TreeJson data={response} rootName="response" expandDepth={2} searchable />
// Controlled search and expansion, copy callback
<TreeJson
data={config}
rootName="config"
expanded={open}
onExpandedChange={setOpen}
search={query}
onSearchChange={setQuery}
chunkSize={50} // array items shown at a time
onCopy={(text, what, path) => console.log("Copied", what, path)}
tone="outline" // "ghost" (default) | "muted" | "outline"
size="sm" // "sm" | "default" | "lg"
/>Every one of these is in the component already. They are listed because a props table cannot mention a gesture, so nothing else on this page can tell you they exist.
| Arrow Up / Down | Move between visible rows; the tree is one tab stop. |
|---|---|
| Arrow Right | Open a closed object or array, or step into an open one. |
| Arrow Left | Close an open object or array, or climb to the parent. |
| Home / End | Jump to the first or last visible row. |
| Enter / Space | Open or close the row, or show the next chunk on a Show more row. |
| * | Open every object and array at the focused row's level. |
| Cmd or Ctrl + C | Copy the focused row's value; with Shift, its path. |
| Arrow Down in the search | Jump to the first match. |
Read from the component's own type, so this cannot drift from what it accepts.
| Prop | Type | Default | Description |
|---|---|---|---|
data* | unknown | — | Any JSON value: an object, an array or a single value. |
rootName | string | — | Name of the root, and the start of every copied path. |
expandDepth | number | — | Levels open on first render; 1 opens only the root. |
expanded | string[] | — | Open paths, controlled. Paths look like `data.tours[2].city`. |
defaultExpanded | string[] | — | |
onExpandedChange | (paths: string[]) => void | — | |
searchable | boolean | — | A search field above the tree that highlights matches and opens their parents. |
search | string | — | The search text, controlled. |
defaultSearch | string | — | |
onSearchChange | (search: string) => void | — | |
chunkSize | number | — | Array items shown at a time; the rest wait behind a "Show more" row. |
copyable | boolean | — | Copy value and copy path buttons on each row. |
onCopy | (text: string, what: "value" | "path", path: string) => void | — | |
tone | "muted" | "outline" | "ghost" | — | |
size | "sm" | "default" | "lg" | — | |
className | string | — | |
aria-label | string | — |