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-part
attribute 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
RootProvider
component, you don't need to use theRoot
component.
API Reference
JsonTreeViewRoot
Prop | Default | Type |
---|---|---|
asChild | boolean Use 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 | |
classNames | JsonTreeViewClassNames The CSS class names for each part of the component. | |
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 | number The 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 | string The 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 | boolean Whether clicking on a branch should open it or not |
focusedValue | string The 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 | boolean Whether 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) => void Called when the checked value changes | |
onExpandedChange | (details: ExpandedChangeDetails<JsonNode<any>>) => void Called when the tree is opened or closed | |
onFocusChange | (details: FocusChangeDetails<JsonNode<any>>) => void Called when the focused node changes | |
onLoadChildrenComplete | (details: LoadChildrenCompleteDetails<JsonNode<any>>) => void Called when a node finishes loading children | |
onLoadChildrenError | (details: LoadChildrenErrorDetails<JsonNode<any>>) => void Called when loading children fails for one or more nodes | |
onSelectionChange | (details: SelectionChangeDetails<JsonNode<any>>) => void Called when the selection changes | |
quotesOnKeys | boolean Whether 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 | boolean Whether the tree supports typeahead search |
unmountOnExit | false | boolean Whether to unmount on exit. |
JsonTreeViewRootProvider
Prop | Default | Type |
---|---|---|
value | UseTreeViewReturn<JsonNode<any>> | |
asChild | boolean Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
lazyMount | false | boolean Whether to enable lazy mounting |
unmountOnExit | false | boolean Whether to unmount on exit. |
JsonTreeViewTree
Prop | Default | Type |
---|---|---|
arrow | ReactElement<unknown, string | JSXElementConstructor<any>> The icon to use for the arrow. | |
asChild | boolean Use 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) => ReactNode The 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. |