JSON Tree View
A component that displays JSON data in an interactive, collapsible tree structure.
Anatomy
To set up the JSON tree view correctly, you'll need to understand its anatomy and how we name its parts.
Each part includes a
data-partattribute to help identify them in the DOM.
Examples
Learn how to use the JsonTreeView component in your project. Let's take a look at the most basic example:
import { JsonTreeView } from '@ark-ui/react/json-tree-view'
import { ChevronRightIcon } from 'lucide-react'
export const Basic = () => {
return (
<JsonTreeView.Root
data={{
name: 'John Doe',
age: 30,
email: 'john.doe@example.com',
tags: ['tag1', 'tag2', 'tag3'],
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA',
zip: '12345',
},
}}
>
<JsonTreeView.Tree arrow={<ChevronRightIcon />} />
</JsonTreeView.Root>
)
}
import { JsonTreeView } from '@ark-ui/solid/json-tree-view'
import { ChevronRightIcon } from 'lucide-solid'
export const Basic = () => {
return (
<JsonTreeView.Root
data={{
name: 'John Doe',
age: 30,
email: 'john.doe@example.com',
tags: ['tag1', 'tag2', 'tag3'],
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA',
zip: '12345',
},
}}
>
<JsonTreeView.Tree arrow={<ChevronRightIcon />} />
</JsonTreeView.Root>
)
}
<script setup lang="ts">
import { JsonTreeView } from '@ark-ui/vue/json-tree-view'
import { ChevronRightIcon } from 'lucide-vue-next'
</script>
<template>
<JsonTreeView.Root
:data="{
name: 'John Doe',
age: 30,
email: 'john.doe@example.com',
tags: ['tag1', 'tag2', 'tag3'],
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA',
zip: '12345',
},
}"
>
<JsonTreeView.Tree>
<template #arrow>
<ChevronRightIcon />
</template>
</JsonTreeView.Tree>
</JsonTreeView.Root>
</template>
<script lang="ts">
import { JsonTreeView } from '@ark-ui/svelte/json-tree-view'
import { ChevronRightIcon } from 'lucide-svelte'
</script>
<JsonTreeView.Root
data={{
name: 'John Doe',
age: 30,
email: 'john.doe@example.com',
tags: ['tag1', 'tag2', 'tag3'],
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA',
zip: '12345',
},
}}
>
<JsonTreeView.Tree>
{#snippet arrow()}
<ChevronRightIcon />
{/snippet}
</JsonTreeView.Tree>
</JsonTreeView.Root>
Different Data Types
The JSON tree view can display various JavaScript data types including objects, arrays, primitives, and special values:
import { JsonTreeView } from '@ark-ui/react/json-tree-view'
import { ChevronRightIcon } from 'lucide-react'
const testArray = [1, 2, 3, 4, 5]
Object.defineProperties(testArray, {
customProperty: { value: 'custom value', enumerable: false, writable: false },
anotherProperty: { value: 42, enumerable: false, writable: false },
})
export const ArrayData = () => {
return (
<JsonTreeView.Root
data={{
normalArray: [1, 2, 3],
arrayWithNonEnumerableProperties: testArray,
sparseArray: (() => {
const sparse = []
sparse[0] = 'first'
sparse[5] = 'sixth'
return sparse
})(),
}}
>
<JsonTreeView.Tree arrow={<ChevronRightIcon />} />
</JsonTreeView.Root>
)
}
import { JsonTreeView } from '@ark-ui/solid/json-tree-view'
import { ChevronRightIcon } from 'lucide-solid'
const testArray = [1, 2, 3, 4, 5]
Object.defineProperties(testArray, {
customProperty: { value: 'custom value', enumerable: false, writable: false },
anotherProperty: { value: 42, enumerable: false, writable: false },
})
export const ArrayData = () => {
return (
<JsonTreeView.Root
data={{
normalArray: [1, 2, 3],
arrayWithNonEnumerableProperties: testArray,
sparseArray: (() => {
const sparse = []
sparse[0] = 'first'
sparse[5] = 'sixth'
return sparse
})(),
}}
>
<JsonTreeView.Tree arrow={<ChevronRightIcon />} />
</JsonTreeView.Root>
)
}
<script setup lang="ts">
import { JsonTreeView } from '@ark-ui/vue/json-tree-view'
import { ChevronRightIcon } from 'lucide-vue-next'
const testArray = [1, 2, 3, 4, 5]
Object.defineProperties(testArray, {
customProperty: { value: 'custom value', enumerable: false, writable: false },
anotherProperty: { value: 42, enumerable: false, writable: false },
})
const data = {
normalArray: [1, 2, 3],
arrayWithNonEnumerableProperties: testArray,
sparseArray: (() => {
const sparse = []
sparse[0] = 'first'
sparse[5] = 'sixth'
return sparse
})(),
}
</script>
<template>
<JsonTreeView.Root :data="data">
<JsonTreeView.Tree>
<template #arrow>
<ChevronRightIcon />
</template>
</JsonTreeView.Tree>
</JsonTreeView.Root>
</template>
<script lang="ts">
import { JsonTreeView } from '@ark-ui/svelte/json-tree-view'
import { ChevronRightIcon } from 'lucide-svelte'
const testArray = [1, 2, 3, 4, 5]
Object.defineProperties(testArray, {
customProperty: { value: 'custom value', enumerable: false, writable: false },
anotherProperty: { value: 42, enumerable: false, writable: false },
})
</script>
<JsonTreeView.Root
data={{
normalArray: [1, 2, 3],
arrayWithNonEnumerableProperties: testArray,
sparseArray: (() => {
const sparse = []
sparse[0] = 'first'
sparse[5] = 'sixth'
return sparse
})(),
}}
>
<JsonTreeView.Tree>
{#snippet arrow()}
<ChevronRightIcon />
{/snippet}
</JsonTreeView.Tree>
</JsonTreeView.Root>
Functions and Methods
Display JavaScript functions, async functions, and generators in your JSON tree:
import { JsonTreeView } from '@ark-ui/react/json-tree-view'
import { ChevronRightIcon } from 'lucide-react'
const data = [
function sum(a: number, b: number) {
return a + b
},
async (promises: Promise<any>[]) => await Promise.all(promises),
function* generator(a: number) {
while (a > 0) {
yield a - 1
}
},
]
export const Functions = () => {
return (
<JsonTreeView.Root data={data}>
<JsonTreeView.Tree arrow={<ChevronRightIcon />} />
</JsonTreeView.Root>
)
}
import { JsonTreeView } from '@ark-ui/solid/json-tree-view'
import { ChevronRightIcon } from 'lucide-solid'
const data = [
function sum(a: number, b: number) {
return a + b
},
async (promises: Promise<any>[]) => await Promise.all(promises),
function* generator(a: number) {
while (a > 0) {
yield a - 1
}
},
]
export const Functions = () => {
return (
<JsonTreeView.Root data={data}>
<JsonTreeView.Tree arrow={<ChevronRightIcon />} />
</JsonTreeView.Root>
)
}
<script setup lang="ts">
import { JsonTreeView } from '@ark-ui/vue/json-tree-view'
import { ChevronRightIcon } from 'lucide-vue-next'
const data = [
function sum(a: number, b: number) {
return a + b
},
async (promises: Promise<any>[]) => await Promise.all(promises),
function* generator(a: number) {
while (a > 0) {
yield a - 1
}
},
]
</script>
<template>
<JsonTreeView.Root :data="data">
<JsonTreeView.Tree>
<template #arrow>
<ChevronRightIcon />
</template>
</JsonTreeView.Tree>
</JsonTreeView.Root>
</template>
<script lang="ts">
import { JsonTreeView } from '@ark-ui/svelte/json-tree-view'
import { ChevronRightIcon } from 'lucide-svelte'
const data = [
function sum(a: number, b: number) {
return a + b
},
async (promises: Promise<any>[]) => await Promise.all(promises),
function* generator(a: number) {
while (a > 0) {
yield a - 1
}
},
]
</script>
<JsonTreeView.Root {data}>
<JsonTreeView.Tree>
{#snippet arrow()}
<ChevronRightIcon />
{/snippet}
</JsonTreeView.Tree>
</JsonTreeView.Root>
Regular Expressions
Regular expressions are displayed with their pattern and flags:
import { JsonTreeView } from '@ark-ui/react/json-tree-view'
import { ChevronRightIcon } from 'lucide-react'
const data = {
regex: /^[a-z0-9]+/g,
case_insensitive: /^(?:[a-z0-9]+)foo.*?/i,
}
export const Regex = () => {
return (
<JsonTreeView.Root data={data}>
<JsonTreeView.Tree arrow={<ChevronRightIcon />} />
</JsonTreeView.Root>
)
}
import { JsonTreeView } from '@ark-ui/solid/json-tree-view'
import { ChevronRightIcon } from 'lucide-solid'
const data = {
regex: /^[a-z0-9]+/g,
case_insensitive: /^(?:[a-z0-9]+)foo.*?/i,
}
export const Regex = () => {
return (
<JsonTreeView.Root data={data}>
<JsonTreeView.Tree arrow={<ChevronRightIcon />} />
</JsonTreeView.Root>
)
}
<script setup lang="ts">
import { JsonTreeView } from '@ark-ui/vue/json-tree-view'
import { ChevronRightIcon } from 'lucide-vue-next'
const data = {
regex: /^[a-z0-9]+/g,
case_insensitive: /^(?:[a-z0-9]+)foo.*?/i,
}
</script>
<template>
<JsonTreeView.Root :data="data">
<JsonTreeView.Tree>
<template #arrow>
<ChevronRightIcon />
</template>
</JsonTreeView.Tree>
</JsonTreeView.Root>
</template>
<script lang="ts">
import { JsonTreeView } from '@ark-ui/svelte/json-tree-view'
import { ChevronRightIcon } from 'lucide-svelte'
const data = {
regex: /^[a-z0-9]+/g,
case_insensitive: /^(?:[a-z0-9]+)foo.*?/i,
}
</script>
<JsonTreeView.Root {data}>
<JsonTreeView.Tree>
{#snippet arrow()}
<ChevronRightIcon />
{/snippet}
</JsonTreeView.Tree>
</JsonTreeView.Root>
Error Objects
Error objects and their stack traces can be visualized:
import { JsonTreeView } from '@ark-ui/react/json-tree-view'
import { ChevronRightIcon } from 'lucide-react'
const data = new Error('Error')
export const Errors = () => {
return (
<JsonTreeView.Root data={data}>
<JsonTreeView.Tree arrow={<ChevronRightIcon />} />
</JsonTreeView.Root>
)
}
import { JsonTreeView } from '@ark-ui/solid/json-tree-view'
import { ChevronRightIcon } from 'lucide-solid'
const data = new Error('Error')
export const Errors = () => {
return (
<JsonTreeView.Root data={data}>
<JsonTreeView.Tree arrow={<ChevronRightIcon />} />
</JsonTreeView.Root>
)
}
<script setup lang="ts">
import { JsonTreeView } from '@ark-ui/vue/json-tree-view'
import { ChevronRightIcon } from 'lucide-vue-next'
const data = new Error('Error')
</script>
<template>
<JsonTreeView.Root :data="data">
<JsonTreeView.Tree>
<template #arrow>
<ChevronRightIcon />
</template>
</JsonTreeView.Tree>
</JsonTreeView.Root>
</template>
<script lang="ts">
import { JsonTreeView } from '@ark-ui/svelte/json-tree-view'
import { ChevronRightIcon } from 'lucide-svelte'
const data = new Error('Error')
</script>
<JsonTreeView.Root {data}>
<JsonTreeView.Tree>
{#snippet arrow()}
<ChevronRightIcon />
{/snippet}
</JsonTreeView.Tree>
</JsonTreeView.Root>
Map and Set Objects
Native JavaScript Map and Set objects are supported:
import { JsonTreeView } from '@ark-ui/react/json-tree-view'
import { ChevronRightIcon } from 'lucide-react'
const data = new Map<string, any>([
['name', 'ark-ui-json-tree'],
['license', 'MIT'],
['elements', new Set(['ark-ui', 123, false, true, null, undefined, 456n])],
[
'nested',
new Map<string, any>([
[
'taglines',
new Set([
{ name: 'ark-ui', feature: 'headless components' },
{ name: 'ark-ui', feature: 'framework agnostic' },
{ name: 'ark-ui', feature: 'accessible by default' },
]),
],
]),
],
])
export const MapAndSet = () => {
return (
<JsonTreeView.Root data={data}>
<JsonTreeView.Tree arrow={<ChevronRightIcon />} />
</JsonTreeView.Root>
)
}
import { JsonTreeView } from '@ark-ui/solid/json-tree-view'
import { ChevronRightIcon } from 'lucide-solid'
const data = new Map<string, any>([
['name', 'ark-ui-json-tree'],
['license', 'MIT'],
['elements', new Set(['ark-ui', 123, false, true, null, undefined, 456n])],
[
'nested',
new Map<string, any>([
[
'taglines',
new Set([
{ name: 'ark-ui', feature: 'headless components' },
{ name: 'ark-ui', feature: 'framework agnostic' },
{ name: 'ark-ui', feature: 'accessible by default' },
]),
],
]),
],
])
export const MapAndSet = () => {
return (
<JsonTreeView.Root data={data}>
<JsonTreeView.Tree arrow={<ChevronRightIcon />} />
</JsonTreeView.Root>
)
}
<script setup lang="ts">
import { JsonTreeView } from '@ark-ui/vue/json-tree-view'
import { ChevronRightIcon } from 'lucide-vue-next'
const data = new Map<string, any>([
['name', 'ark-ui-json-tree'],
['license', 'MIT'],
['elements', new Set(['ark-ui', 123, false, true, null, undefined, 456n])],
[
'nested',
new Map<string, any>([
[
'taglines',
new Set([
{ name: 'ark-ui', feature: 'headless components' },
{ name: 'ark-ui', feature: 'framework agnostic' },
{ name: 'ark-ui', feature: 'accessible by default' },
]),
],
]),
],
])
</script>
<template>
<JsonTreeView.Root :data="data">
<JsonTreeView.Tree>
<template #arrow>
<ChevronRightIcon />
</template>
</JsonTreeView.Tree>
</JsonTreeView.Root>
</template>
<script lang="ts">
import { JsonTreeView } from '@ark-ui/svelte/json-tree-view'
import { ChevronRightIcon } from 'lucide-svelte'
const data = new Map<string, any>([
['name', 'ark-ui-json-tree'],
['license', 'MIT'],
['elements', new Set(['ark-ui', 123, false, true, null, undefined, 456n])],
[
'nested',
new Map<string, any>([
[
'taglines',
new Set([
{ name: 'ark-ui', feature: 'headless components' },
{ name: 'ark-ui', feature: 'framework agnostic' },
{ name: 'ark-ui', feature: 'accessible by default' },
]),
],
]),
],
])
</script>
<JsonTreeView.Root {data}>
<JsonTreeView.Tree>
{#snippet arrow()}
<ChevronRightIcon />
{/snippet}
</JsonTreeView.Tree>
</JsonTreeView.Root>
Controlling Expand Level
Use the defaultExpandedDepth prop to control how many levels are expanded by default:
import { JsonTreeView } from '@ark-ui/react/json-tree-view'
import { ChevronRightIcon } from 'lucide-react'
export const ExpandLevel = () => {
return (
<JsonTreeView.Root
defaultExpandedDepth={1}
data={{
name: 'John Doe',
age: 30,
email: 'john.doe@example.com',
tags: ['tag1', 'tag2', 'tag3'],
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA',
zip: '12345',
},
}}
>
<JsonTreeView.Tree arrow={<ChevronRightIcon />} />
</JsonTreeView.Root>
)
}
import { JsonTreeView } from '@ark-ui/solid/json-tree-view'
import { ChevronRightIcon } from 'lucide-solid'
export const ExpandLevel = () => {
return (
<JsonTreeView.Root
defaultExpandedDepth={1}
data={{
name: 'John Doe',
age: 30,
email: 'john.doe@example.com',
tags: ['tag1', 'tag2', 'tag3'],
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA',
zip: '12345',
},
}}
>
<JsonTreeView.Tree arrow={<ChevronRightIcon />} />
</JsonTreeView.Root>
)
}
<script setup lang="ts">
import { JsonTreeView } from '@ark-ui/vue/json-tree-view'
import { ChevronRightIcon } from 'lucide-vue-next'
</script>
<template>
<JsonTreeView.Root
:default-expanded-depth="1"
:data="{
name: 'John Doe',
age: 30,
email: 'john.doe@example.com',
tags: ['tag1', 'tag2', 'tag3'],
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA',
zip: '12345',
},
}"
>
<JsonTreeView.Tree>
<template #arrow>
<ChevronRightIcon />
</template>
</JsonTreeView.Tree>
</JsonTreeView.Root>
</template>
<script lang="ts">
import { JsonTreeView } from '@ark-ui/svelte/json-tree-view'
import { ChevronRightIcon } from 'lucide-svelte'
</script>
<JsonTreeView.Root
defaultExpandedDepth={1}
data={{
name: 'John Doe',
age: 30,
email: 'john.doe@example.com',
tags: ['tag1', 'tag2', 'tag3'],
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA',
zip: '12345',
},
}}
>
<JsonTreeView.Tree>
{#snippet arrow()}
<ChevronRightIcon />
{/snippet}
</JsonTreeView.Tree>
</JsonTreeView.Root>
Custom Value Rendering
You can customize how specific values are rendered using the renderValue prop. This example shows how to make email
addresses clickable:
import { JsonTreeView } from '@ark-ui/react/json-tree-view'
import { ChevronRightIcon } from 'lucide-react'
export const RenderValue = () => {
return (
<JsonTreeView.Root
defaultExpandedDepth={2}
data={{
name: 'John Doe',
age: 30,
number: Number.NaN,
email: 'john.doe@example.com',
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA',
zip: '12345',
},
}}
>
<JsonTreeView.Tree
arrow={<ChevronRightIcon />}
renderValue={(node) => {
if (node.type === 'text' && typeof node.value === 'string' && isEmail(node.value)) {
return (
<a href={`mailto:${node.value}`} target="_blank" rel="noreferrer">
{node.value}
</a>
)
}
}}
/>
</JsonTreeView.Root>
)
}
const isEmail = (value: string) => {
const strippedValue = value.replace(/^"(.*)"$/, '$1')
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(strippedValue)
}
import { JsonTreeView } from '@ark-ui/solid/json-tree-view'
import { ChevronRightIcon } from 'lucide-solid'
export const RenderValue = () => {
return (
<JsonTreeView.Root
defaultExpandedDepth={2}
data={{
name: 'John Doe',
age: 30,
number: Number.NaN,
email: 'john.doe@example.com',
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA',
zip: '12345',
},
}}
>
<JsonTreeView.Tree
arrow={<ChevronRightIcon />}
renderValue={(node) => {
if (node.type === 'text' && typeof node.value === 'string' && isEmail(node.value)) {
return (
<a href={`mailto:${node.value}`} target="_blank" rel="noreferrer">
{node.value}
</a>
)
}
}}
/>
</JsonTreeView.Root>
)
}
const isEmail = (value: string) => {
const strippedValue = value.replace(/^"(.*)"$/, '$1')
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(strippedValue)
}
<script setup lang="ts">
import { JsonTreeView } from '@ark-ui/vue/json-tree-view'
import { ChevronRightIcon } from 'lucide-vue-next'
const isEmail = (value: string) => {
const strippedValue = value.replace(/^"(.*)"$/, '$1')
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(strippedValue)
}
</script>
<template>
<JsonTreeView.Root
:default-expanded-depth="2"
:data="{
name: 'John Doe',
age: 30,
number: Number.NaN,
email: 'john.doe@example.com',
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA',
zip: '12345',
},
}"
>
<JsonTreeView.Tree>
<template #arrow>
<ChevronRightIcon />
</template>
<template #renderValue="{ node }">
<a
v-if="node.type === 'text' && typeof node.value === 'string' && isEmail(node.value)"
:href="`mailto:${node.value}`"
target="_blank"
rel="noreferrer"
>
{{ node.value }}
</a>
</template>
</JsonTreeView.Tree>
</JsonTreeView.Root>
</template>
<script lang="ts">
import { JsonTreeView } from '@ark-ui/svelte/json-tree-view'
import { ChevronRightIcon } from 'lucide-svelte'
const isEmail = (value: string) => {
const strippedValue = value.replace(/^"(.*)"$/, '$1')
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(strippedValue)
}
</script>
<JsonTreeView.Root
defaultExpandedDepth={2}
data={{
name: 'John Doe',
age: 30,
number: Number.NaN,
email: 'john.doe@example.com',
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA',
zip: '12345',
},
}}
>
<JsonTreeView.Tree>
{#snippet arrow()}
<ChevronRightIcon />
{/snippet}
{#snippet renderValue(node)}
{#if node.type === 'text' && typeof node.value === 'string'}
{#if isEmail(node.value)}
<a href={`mailto:${node.value}`} target="_blank" rel="noreferrer">
{node.value}
</a>
{:else}
{node.value}
{/if}
{/if}
{/snippet}
</JsonTreeView.Tree>
</JsonTreeView.Root>
Configuration Options
The JSON tree view supports several configuration options to customize the display:
<JsonTreeView.Root
data={data}
defaultExpandedDepth={2}
quotesOnKeys={true}
showNonenumerable={true}
maxPreviewItems={5}
collapseStringsAfterLength={50}
groupArraysAfterLength={100}
>
<JsonTreeView.Tree arrow={<ChevronRightIcon />} />
</JsonTreeView.Root>
Configuration Options:
quotesOnKeys: Whether to show quotes around object keysshowNonenumerable: Whether to show non-enumerable propertiesmaxPreviewItems: Maximum number of items to show in object/array previewscollapseStringsAfterLength: Collapse strings longer than this lengthgroupArraysAfterLength: Group array items when array is longer than this length
Using the Root Provider
The RootProvider component provides a context for the JSON tree view. It accepts the value of the useJsonTreeView
hook. You can leverage it to access the component state and methods from outside the JSON tree view.
import { JsonTreeView, useJsonTreeView } from '@ark-ui/react/json-tree-view'
import { ChevronRightIcon } from 'lucide-react'
export const RootProvider = () => {
const jsonTreeView = useJsonTreeView({
data: {
name: 'John Doe',
age: 30,
email: 'john.doe@example.com',
tags: ['tag1', 'tag2', 'tag3'],
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA',
zip: '12345',
},
},
})
return (
<JsonTreeView.RootProvider value={jsonTreeView}>
<JsonTreeView.Tree arrow={<ChevronRightIcon />} />
</JsonTreeView.RootProvider>
)
}
import { JsonTreeView, useJsonTreeView } from '@ark-ui/solid/json-tree-view'
import { ChevronRightIcon } from 'lucide-solid'
export const RootProvider = () => {
const jsonTreeView = useJsonTreeView({
data: {
name: 'John Doe',
age: 30,
email: 'john.doe@example.com',
tags: ['tag1', 'tag2', 'tag3'],
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA',
zip: '12345',
},
},
})
return (
<JsonTreeView.RootProvider value={jsonTreeView}>
<JsonTreeView.Tree arrow={<ChevronRightIcon />} />
</JsonTreeView.RootProvider>
)
}
<template>
<JsonTreeViewRootProvider :value="jsonTreeView">
<JsonTreeViewTree>
<template #arrow>
<ChevronRightIcon />
</template>
</JsonTreeViewTree>
</JsonTreeViewRootProvider>
</template>
<script setup lang="ts">
import { useJsonTreeView } from '@ark-ui/vue/json-tree-view'
import { JsonTreeViewRootProvider, JsonTreeViewTree } from '@ark-ui/vue/json-tree-view'
import { ChevronRightIcon } from 'lucide-vue-next'
const jsonTreeView = useJsonTreeView({
data: {
name: 'John Doe',
age: 30,
email: 'john.doe@example.com',
tags: ['tag1', 'tag2', 'tag3'],
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA',
zip: '12345',
},
},
})
</script>
<script lang="ts">
import { JsonTreeView, useJsonTreeView } from '@ark-ui/svelte/json-tree-view'
import { ChevronRight } from 'lucide-svelte'
const jsonTreeView = useJsonTreeView({
data: {
name: 'John Doe',
age: 30,
email: 'john.doe@example.com',
tags: ['tag1', 'tag2', 'tag3'],
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA',
zip: '12345',
},
},
})
</script>
<JsonTreeView.RootProvider value={jsonTreeView}>
<JsonTreeView.Tree>
{#snippet arrow()}
<ChevronRight />
{/snippet}
</JsonTreeView.Tree>
</JsonTreeView.RootProvider>If you're using the
RootProvidercomponent, you don't need to use theRootcomponent.
API Reference
JsonTreeViewRoot
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
checkedValue | string[]The controlled checked node value | |
collapseStringsAfterLength | number | |
data | {}The data to display in the tree. | |
defaultCheckedValue | string[]The initial checked node value when rendered. Use when you don't need to control the checked node value. | |
defaultExpandedDepth | numberThe default expand level. | |
defaultExpandedValue | string[]The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | |
defaultFocusedValue | stringThe initial focused node value when rendered. Use when you don't need to control the focused node value. | |
defaultSelectedValue | string[]The initial selected node value when rendered. Use when you don't need to control the selected node value. | |
expandedValue | string[]The controlled expanded node ids | |
expandOnClick | true | booleanWhether clicking on a branch should open it or not |
focusedValue | stringThe value of the focused node | |
groupArraysAfterLength | number | |
ids | Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>The ids of the tree elements. Useful for composition. | |
lazyMount | false | booleanWhether to enable lazy mounting |
loadChildren | (details: LoadChildrenDetails<JsonNode<any>>) => Promise<JsonNode<any>[]>Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | |
maxPreviewItems | number | |
onCheckedChange | (details: CheckedChangeDetails) => voidCalled when the checked value changes | |
onExpandedChange | (details: ExpandedChangeDetails<JsonNode<any>>) => voidCalled when the tree is opened or closed | |
onFocusChange | (details: FocusChangeDetails<JsonNode<any>>) => voidCalled when the focused node changes | |
onLoadChildrenComplete | (details: LoadChildrenCompleteDetails<JsonNode<any>>) => voidCalled when a node finishes loading children | |
onLoadChildrenError | (details: LoadChildrenErrorDetails<JsonNode<any>>) => voidCalled when loading children fails for one or more nodes | |
onSelectionChange | (details: SelectionChangeDetails<JsonNode<any>>) => voidCalled when the selection changes | |
quotesOnKeys | booleanWhether to show quotes on the keys. | |
selectedValue | string[]The controlled selected node value | |
selectionMode | 'single' | 'multiple' | 'single'Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected |
showNonenumerable | boolean | |
typeahead | true | booleanWhether the tree supports typeahead search |
unmountOnExit | false | booleanWhether to unmount on exit. |
JsonTreeViewRootProvider
| Prop | Default | Type |
|---|---|---|
value | UseTreeViewReturn<JsonNode<any>> | |
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
lazyMount | false | booleanWhether to enable lazy mounting |
unmountOnExit | false | booleanWhether to unmount on exit. |
JsonTreeViewTree
| Prop | Default | Type |
|---|---|---|
arrow | ReactElement<unknown, string | JSXElementConstructor<any>>The icon to use for the arrow. | |
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
indentGuide | boolean | ReactElement<unknown, string | JSXElementConstructor<any>>The indent guide to use for the tree. | |
renderValue | (node: JsonNodeHastElement) => ReactNodeThe function to render the value of the node. |
Accessibility
The JSON tree view is built on top of the Tree View component and complies with the Tree View WAI-ARIA design pattern.
Keyboard Support
| Key | Description |
|---|---|
Tab | Moves focus to the tree view, placing the first tree view item in focus. |
EnterSpace | Selects the item or branch node |
ArrowDown | Moves focus to the next node |
ArrowUp | Moves focus to the previous node |
ArrowRight | When focus is on a closed branch node, opens the branch. When focus is on an open branch node, moves focus to the first item node. |
ArrowLeft | When focus is on an open branch node, closes the node. When focus is on an item or branch node, moves focus to its parent branch node. |
Home | Moves focus to first node without opening or closing a node. |
End | Moves focus to the last node that can be focused without expanding any nodes that are closed. |
a-zA-Z | Focus moves to the next node with a name that starts with the typed character. The search logic ignores nodes that are descendants of closed branch. |
* | Expands all sibling nodes that are at the same depth as the focused node. |
Shift + ArrowDown | Moves focus to and toggles the selection state of the next node. |
Shift + ArrowUp | Moves focus to and toggles the selection state of the previous node. |
Ctrl + A | Selects all nodes in the tree. If all nodes are selected, unselects all nodes. |