# JSON Tree View (SVELTE)



## 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:

**Example: basic**

#### React

```tsx
import { JsonTreeView } from '@ark-ui/react/json-tree-view'
import { ChevronRightIcon } from 'lucide-react'
import styles from 'styles/json-tree-view.module.css'

export const Basic = () => {
  return (
    <JsonTreeView.Root
      defaultExpandedDepth={1}
      className={styles.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 className={styles.Tree} arrow={<ChevronRightIcon />} />
    </JsonTreeView.Root>
  )
}

```

#### Solid

```tsx
import { JsonTreeView } from '@ark-ui/solid/json-tree-view'
import { ChevronRightIcon } from 'lucide-solid'
import styles from 'styles/json-tree-view.module.css'

export const Basic = () => {
  return (
    <JsonTreeView.Root
      defaultExpandedDepth={1}
      class={styles.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 class={styles.Tree} arrow={<ChevronRightIcon />} />
    </JsonTreeView.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { JsonTreeView } from '@ark-ui/vue/json-tree-view'
import { ChevronRightIcon } from 'lucide-vue-next'
import styles from 'styles/json-tree-view.module.css'

const 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>

<template>
  <JsonTreeView.Root :defaultExpandedDepth="1" :class="styles.Root" :data="data">
    <JsonTreeView.Tree :class="styles.Tree">
      <template #arrow>
        <ChevronRightIcon />
      </template>
    </JsonTreeView.Tree>
  </JsonTreeView.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { JsonTreeView } from '@ark-ui/svelte/json-tree-view'
  import { ChevronRightIcon } from 'lucide-svelte'
  import styles from 'styles/json-tree-view.module.css'
</script>

<JsonTreeView.Root
  defaultExpandedDepth={1}
  class={styles.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 class={styles.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:

**Example: array-data**

#### React

```tsx
import { JsonTreeView } from '@ark-ui/react/json-tree-view'
import { ChevronRightIcon } from 'lucide-react'
import styles from 'styles/json-tree-view.module.css'

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
      defaultExpandedDepth={1}
      className={styles.Root}
      data={{
        normalArray: [1, 2, 3],
        arrayWithNonEnumerableProperties: testArray,
        sparseArray: (() => {
          const sparse = []
          sparse[0] = 'first'
          sparse[5] = 'sixth'
          return sparse
        })(),
      }}
    >
      <JsonTreeView.Tree className={styles.Tree} arrow={<ChevronRightIcon />} />
    </JsonTreeView.Root>
  )
}

```

#### Solid

```tsx
import { JsonTreeView } from '@ark-ui/solid/json-tree-view'
import { ChevronRightIcon } from 'lucide-solid'
import styles from 'styles/json-tree-view.module.css'

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
      defaultExpandedDepth={1}
      class={styles.Root}
      data={{
        normalArray: [1, 2, 3],
        arrayWithNonEnumerableProperties: testArray,
        sparseArray: (() => {
          const sparse = []
          sparse[0] = 'first'
          sparse[5] = 'sixth'
          return sparse
        })(),
      }}
    >
      <JsonTreeView.Tree class={styles.Tree} arrow={<ChevronRightIcon />} />
    </JsonTreeView.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { JsonTreeView } from '@ark-ui/vue/json-tree-view'
import { ChevronRightIcon } from 'lucide-vue-next'
import styles from 'styles/json-tree-view.module.css'

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 :defaultExpandedDepth="1" :class="styles.Root" :data="data">
    <JsonTreeView.Tree :class="styles.Tree">
      <template #arrow>
        <ChevronRightIcon />
      </template>
    </JsonTreeView.Tree>
  </JsonTreeView.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { JsonTreeView } from '@ark-ui/svelte/json-tree-view'
  import { ChevronRightIcon } from 'lucide-svelte'
  import styles from 'styles/json-tree-view.module.css'

  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
  defaultExpandedDepth={1}
  class={styles.Root}
  data={{
    normalArray: [1, 2, 3],
    arrayWithNonEnumerableProperties: testArray,
    sparseArray: (() => {
      const sparse = []
      sparse[0] = 'first'
      sparse[5] = 'sixth'
      return sparse
    })(),
  }}
>
  <JsonTreeView.Tree class={styles.Tree}>
    {#snippet arrow()}
      <ChevronRightIcon />
    {/snippet}
  </JsonTreeView.Tree>
</JsonTreeView.Root>

```

### Functions and Methods

Display JavaScript functions, async functions, and generators in your JSON tree:

**Example: functions**

#### React

```tsx
import { JsonTreeView } from '@ark-ui/react/json-tree-view'
import { ChevronRightIcon } from 'lucide-react'
import styles from 'styles/json-tree-view.module.css'

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 defaultExpandedDepth={1} className={styles.Root} data={data}>
      <JsonTreeView.Tree className={styles.Tree} arrow={<ChevronRightIcon />} />
    </JsonTreeView.Root>
  )
}

```

#### Solid

```tsx
import { JsonTreeView } from '@ark-ui/solid/json-tree-view'
import { ChevronRightIcon } from 'lucide-solid'
import styles from 'styles/json-tree-view.module.css'

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 defaultExpandedDepth={1} class={styles.Root} data={data}>
      <JsonTreeView.Tree class={styles.Tree} arrow={<ChevronRightIcon />} />
    </JsonTreeView.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { JsonTreeView } from '@ark-ui/vue/json-tree-view'
import { ChevronRightIcon } from 'lucide-vue-next'
import styles from 'styles/json-tree-view.module.css'

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 :defaultExpandedDepth="1" :class="styles.Root" :data="data">
    <JsonTreeView.Tree :class="styles.Tree">
      <template #arrow>
        <ChevronRightIcon />
      </template>
    </JsonTreeView.Tree>
  </JsonTreeView.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { JsonTreeView } from '@ark-ui/svelte/json-tree-view'
  import { ChevronRightIcon } from 'lucide-svelte'
  import styles from 'styles/json-tree-view.module.css'

  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 defaultExpandedDepth={1} class={styles.Root} {data}>
  <JsonTreeView.Tree class={styles.Tree}>
    {#snippet arrow()}
      <ChevronRightIcon />
    {/snippet}
  </JsonTreeView.Tree>
</JsonTreeView.Root>

```

### Regular Expressions

Regular expressions are displayed with their pattern and flags:

**Example: regex**

#### React

```tsx
import { JsonTreeView } from '@ark-ui/react/json-tree-view'
import { ChevronRightIcon } from 'lucide-react'
import styles from 'styles/json-tree-view.module.css'

const data = {
  regex: /^[a-z0-9]+/g,
  case_insensitive: /^(?:[a-z0-9]+)foo.*?/i,
}

export const Regex = () => {
  return (
    <JsonTreeView.Root defaultExpandedDepth={1} className={styles.Root} data={data}>
      <JsonTreeView.Tree className={styles.Tree} arrow={<ChevronRightIcon />} />
    </JsonTreeView.Root>
  )
}

```

#### Solid

```tsx
import { JsonTreeView } from '@ark-ui/solid/json-tree-view'
import { ChevronRightIcon } from 'lucide-solid'
import styles from 'styles/json-tree-view.module.css'

const data = {
  regex: /^[a-z0-9]+/g,
  case_insensitive: /^(?:[a-z0-9]+)foo.*?/i,
}

export const Regex = () => {
  return (
    <JsonTreeView.Root defaultExpandedDepth={1} class={styles.Root} data={data}>
      <JsonTreeView.Tree class={styles.Tree} arrow={<ChevronRightIcon />} />
    </JsonTreeView.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { JsonTreeView } from '@ark-ui/vue/json-tree-view'
import { ChevronRightIcon } from 'lucide-vue-next'
import styles from 'styles/json-tree-view.module.css'

const data = {
  regex: /^[a-z0-9]+/g,
  case_insensitive: /^(?:[a-z0-9]+)foo.*?/i,
}
</script>

<template>
  <JsonTreeView.Root :defaultExpandedDepth="1" :class="styles.Root" :data="data">
    <JsonTreeView.Tree :class="styles.Tree">
      <template #arrow>
        <ChevronRightIcon />
      </template>
    </JsonTreeView.Tree>
  </JsonTreeView.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { JsonTreeView } from '@ark-ui/svelte/json-tree-view'
  import { ChevronRightIcon } from 'lucide-svelte'
  import styles from 'styles/json-tree-view.module.css'

  const data = {
    regex: /^[a-z0-9]+/g,
    case_insensitive: /^(?:[a-z0-9]+)foo.*?/i,
  }
</script>

<JsonTreeView.Root defaultExpandedDepth={1} class={styles.Root} {data}>
  <JsonTreeView.Tree class={styles.Tree}>
    {#snippet arrow()}
      <ChevronRightIcon />
    {/snippet}
  </JsonTreeView.Tree>
</JsonTreeView.Root>

```

### Error Objects

Error objects and their stack traces can be visualized:

**Example: errors**

#### React

```tsx
import { JsonTreeView } from '@ark-ui/react/json-tree-view'
import { ChevronRightIcon } from 'lucide-react'
import styles from 'styles/json-tree-view.module.css'

const data = new Error('Error')

export const Errors = () => {
  return (
    <JsonTreeView.Root className={styles.Root} data={data} defaultExpandedDepth={1}>
      <JsonTreeView.Tree className={styles.Tree} arrow={<ChevronRightIcon />} />
    </JsonTreeView.Root>
  )
}

```

#### Solid

```tsx
import { JsonTreeView } from '@ark-ui/solid/json-tree-view'
import { ChevronRightIcon } from 'lucide-solid'
import styles from 'styles/json-tree-view.module.css'

const data = new Error('Error')

export const Errors = () => {
  return (
    <JsonTreeView.Root class={styles.Root} data={data} defaultExpandedDepth={1}>
      <JsonTreeView.Tree class={styles.Tree} arrow={<ChevronRightIcon />} />
    </JsonTreeView.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { JsonTreeView } from '@ark-ui/vue/json-tree-view'
import { ChevronRightIcon } from 'lucide-vue-next'
import styles from 'styles/json-tree-view.module.css'

const data = new Error('Error')
</script>

<template>
  <JsonTreeView.Root :class="styles.Root" :data="data" :defaultExpandedDepth="1">
    <JsonTreeView.Tree :class="styles.Tree">
      <template #arrow>
        <ChevronRightIcon />
      </template>
    </JsonTreeView.Tree>
  </JsonTreeView.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { JsonTreeView } from '@ark-ui/svelte/json-tree-view'
  import { ChevronRightIcon } from 'lucide-svelte'
  import styles from 'styles/json-tree-view.module.css'

  const data = new Error('Error')
</script>

<JsonTreeView.Root class={styles.Root} {data} defaultExpandedDepth={1}>
  <JsonTreeView.Tree class={styles.Tree}>
    {#snippet arrow()}
      <ChevronRightIcon />
    {/snippet}
  </JsonTreeView.Tree>
</JsonTreeView.Root>

```

### Map and Set Objects

Native JavaScript Map and Set objects are supported:

**Example: map-and-set**

#### React

```tsx
import { JsonTreeView } from '@ark-ui/react/json-tree-view'
import { ChevronRightIcon } from 'lucide-react'
import styles from 'styles/json-tree-view.module.css'

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 defaultExpandedDepth={1} className={styles.Root} data={data}>
      <JsonTreeView.Tree className={styles.Tree} arrow={<ChevronRightIcon />} />
    </JsonTreeView.Root>
  )
}

```

#### Solid

```tsx
import { JsonTreeView } from '@ark-ui/solid/json-tree-view'
import { ChevronRightIcon } from 'lucide-solid'
import styles from 'styles/json-tree-view.module.css'

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 defaultExpandedDepth={1} class={styles.Root} data={data}>
      <JsonTreeView.Tree class={styles.Tree} arrow={<ChevronRightIcon />} />
    </JsonTreeView.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { JsonTreeView } from '@ark-ui/vue/json-tree-view'
import { ChevronRightIcon } from 'lucide-vue-next'
import styles from 'styles/json-tree-view.module.css'

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 :defaultExpandedDepth="1" :class="styles.Root" :data="data">
    <JsonTreeView.Tree :class="styles.Tree">
      <template #arrow>
        <ChevronRightIcon />
      </template>
    </JsonTreeView.Tree>
  </JsonTreeView.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { JsonTreeView } from '@ark-ui/svelte/json-tree-view'
  import { ChevronRightIcon } from 'lucide-svelte'
  import styles from 'styles/json-tree-view.module.css'

  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 defaultExpandedDepth={1} class={styles.Root} {data}>
  <JsonTreeView.Tree class={styles.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:

**Example: expand-level**

#### React

```tsx
import { JsonTreeView } from '@ark-ui/react/json-tree-view'
import { ChevronRightIcon } from 'lucide-react'
import styles from 'styles/json-tree-view.module.css'

export const ExpandLevel = () => {
  return (
    <JsonTreeView.Root
      className={styles.Root}
      defaultExpandedDepth={2}
      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 className={styles.Tree} arrow={<ChevronRightIcon />} />
    </JsonTreeView.Root>
  )
}

```

#### Solid

```tsx
import { JsonTreeView } from '@ark-ui/solid/json-tree-view'
import { ChevronRightIcon } from 'lucide-solid'
import styles from 'styles/json-tree-view.module.css'

export const ExpandLevel = () => {
  return (
    <JsonTreeView.Root
      class={styles.Root}
      defaultExpandedDepth={2}
      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 class={styles.Tree} arrow={<ChevronRightIcon />} />
    </JsonTreeView.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { JsonTreeView } from '@ark-ui/vue/json-tree-view'
import { ChevronRightIcon } from 'lucide-vue-next'
import styles from 'styles/json-tree-view.module.css'

const 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>

<template>
  <JsonTreeView.Root :class="styles.Root" :defaultExpandedDepth="2" :data="data">
    <JsonTreeView.Tree :class="styles.Tree">
      <template #arrow>
        <ChevronRightIcon />
      </template>
    </JsonTreeView.Tree>
  </JsonTreeView.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { JsonTreeView } from '@ark-ui/svelte/json-tree-view'
  import { ChevronRightIcon } from 'lucide-svelte'
  import styles from 'styles/json-tree-view.module.css'
</script>

<JsonTreeView.Root
  class={styles.Root}
  defaultExpandedDepth={2}
  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 class={styles.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:

**Example: render-value**

#### React

```tsx
import { JsonTreeView } from '@ark-ui/react/json-tree-view'
import { ChevronRightIcon } from 'lucide-react'
import styles from 'styles/json-tree-view.module.css'

export const RenderValue = () => {
  return (
    <JsonTreeView.Root
      className={styles.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
        className={styles.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)
}

```

#### Solid

```tsx
import { JsonTreeView } from '@ark-ui/solid/json-tree-view'
import { ChevronRightIcon } from 'lucide-solid'
import styles from 'styles/json-tree-view.module.css'

export const RenderValue = () => {
  return (
    <JsonTreeView.Root
      class={styles.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
        class={styles.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)
}

```

#### Vue

```vue
<script setup lang="ts">
import { JsonTreeView } from '@ark-ui/vue/json-tree-view'
import { ChevronRightIcon } from 'lucide-vue-next'
import styles from 'styles/json-tree-view.module.css'

const 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',
  },
}

const isEmail = (value: string) => {
  const strippedValue = value.replace(/^"(.*)"$/, '$1')
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(strippedValue)
}
</script>

<template>
  <JsonTreeView.Root :class="styles.Root" :defaultExpandedDepth="2" :data="data">
    <JsonTreeView.Tree :class="styles.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>

```

#### Svelte

```svelte
<script lang="ts">
  import { JsonTreeView } from '@ark-ui/svelte/json-tree-view'
  import { ChevronRightIcon } from 'lucide-svelte'
  import styles from 'styles/json-tree-view.module.css'

  const isEmail = (value: string) => {
    const strippedValue = value.replace(/^"(.*)"$/, '$1')
    return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(strippedValue)
  }
</script>

<JsonTreeView.Root
  class={styles.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 class={styles.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:

```tsx
<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 keys
- **`showNonenumerable`**: Whether to show non-enumerable properties
- **`maxPreviewItems`**: Maximum number of items to show in object/array previews
- **`collapseStringsAfterLength`**: Collapse strings longer than this length
- **`groupArraysAfterLength`**: 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.

**Example: root-provider**

#### React

```tsx
import { JsonTreeView, useJsonTreeView } from '@ark-ui/react/json-tree-view'
import { ChevronRightIcon } from 'lucide-react'
import styles from 'styles/json-tree-view.module.css'

export const RootProvider = () => {
  const jsonTreeView = useJsonTreeView({
    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',
      },
    },
  })

  return (
    <JsonTreeView.RootProvider className={styles.Root} value={jsonTreeView}>
      <JsonTreeView.Tree className={styles.Tree} arrow={<ChevronRightIcon />} />
    </JsonTreeView.RootProvider>
  )
}

```

#### Solid

```tsx
import { JsonTreeView, useJsonTreeView } from '@ark-ui/solid/json-tree-view'
import { ChevronRightIcon } from 'lucide-solid'
import styles from 'styles/json-tree-view.module.css'

export const RootProvider = () => {
  const jsonTreeView = useJsonTreeView({
    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',
      },
    },
  })

  return (
    <JsonTreeView.RootProvider class={styles.Root} value={jsonTreeView}>
      <JsonTreeView.Tree class={styles.Tree} arrow={<ChevronRightIcon />} />
    </JsonTreeView.RootProvider>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { JsonTreeView, useJsonTreeView } from '@ark-ui/vue/json-tree-view'
import { ChevronRightIcon } from 'lucide-vue-next'
import styles from 'styles/json-tree-view.module.css'

const jsonTreeView = useJsonTreeView({
  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',
    },
  },
})
</script>

<template>
  <JsonTreeView.RootProvider :class="styles.Root" :value="jsonTreeView">
    <JsonTreeView.Tree :class="styles.Tree">
      <template #arrow>
        <ChevronRightIcon />
      </template>
    </JsonTreeView.Tree>
  </JsonTreeView.RootProvider>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { JsonTreeView, useJsonTreeView } from '@ark-ui/svelte/json-tree-view'
  import { ChevronRightIcon } from 'lucide-svelte'
  import styles from 'styles/json-tree-view.module.css'

  const jsonTreeView = useJsonTreeView({
    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',
      },
    },
  })
</script>

<JsonTreeView.RootProvider class={styles.Root} value={jsonTreeView}>
  <JsonTreeView.Tree class={styles.Tree}>
    {#snippet arrow()}
      <ChevronRightIcon />
    {/snippet}
  </JsonTreeView.Tree>
</JsonTreeView.RootProvider>

```

> If you're using the `RootProvider` component, you don't need to use the `Root` component.

## API Reference

**Component API Reference**

#### React

**JsonTreeViewRoot Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `canRename` | `(node: JsonNode<any>, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed |
| `checkedValue` | `string[]` | No | The controlled checked node value |
| `collapseStringsAfterLength` | `number` | No |  |
| `data` | `{}` | No | The data to display in the tree. |
| `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered.
Use when you don't need to control the checked node value. |
| `defaultExpandedDepth` | `number` | No | The default expand level. |
| `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered.
Use when you don't need to control the expanded node value. |
| `defaultFocusedValue` | `string` | No | The initial focused node value when rendered.
Use when you don't need to control the focused node value. |
| `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered.
Use when you don't need to control the selected node value. |
| `expandedValue` | `string[]` | No | The controlled expanded node ids |
| `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not |
| `focusedValue` | `string` | No | The value of the focused node |
| `groupArraysAfterLength` | `number` | No |  |
| `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loadChildren` | `(details: LoadChildrenDetails<JsonNode<any>>) => Promise<JsonNode<any>[]>` | No | Function to load children for a node asynchronously.
When provided, branches will wait for this promise to resolve before expanding. |
| `maxPreviewItems` | `number` | No |  |
| `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. |
| `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes |
| `onExpandedChange` | `(details: ExpandedChangeDetails<JsonNode<any>>) => void` | No | Called when the tree is opened or closed |
| `onFocusChange` | `(details: FocusChangeDetails<JsonNode<any>>) => void` | No | Called when the focused node changes |
| `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails<JsonNode<any>>) => void` | No | Called when a node finishes loading children |
| `onLoadChildrenError` | `(details: LoadChildrenErrorDetails<JsonNode<any>>) => void` | No | Called when loading children fails for one or more nodes |
| `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed |
| `onRenameStart` | `(details: RenameStartDetails<JsonNode<any>>) => void` | No | Called when a node starts being renamed |
| `onSelectionChange` | `(details: SelectionChangeDetails<JsonNode<any>>) => void` | No | Called when the selection changes |
| `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. |
| `selectedValue` | `string[]` | No | The controlled selected node value |
| `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection
- "single": only one node can be selected
- "multiple": multiple nodes can be selected |
| `showNonenumerable` | `boolean` | No |  |
| `typeahead` | `boolean` | No | Whether the tree supports typeahead search |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**JsonTreeViewRootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseTreeViewReturn<JsonNode<any>>` | Yes |  |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**JsonTreeViewTree Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `arrow` | `ReactElement<unknown, string | JSXElementConstructor<any>>` | No | The icon to use for the arrow. |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `indentGuide` | `boolean | ReactElement<unknown, string | JSXElementConstructor<any>>` | No | The indent guide to use for the tree. |
| `renderValue` | `(node: JsonNodeHastElement) => ReactNode` | No | The function to render the value of the node. |


#### Solid

**JsonTreeViewRoot Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `canRename` | `(node: any, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed |
| `checkedValue` | `string[]` | No | The controlled checked node value |
| `collapseStringsAfterLength` | `number` | No |  |
| `data` | `{}` | No | The data to display in the tree. |
| `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered.
Use when you don't need to control the checked node value. |
| `defaultExpandedDepth` | `number` | No | The default expand level. |
| `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered.
Use when you don't need to control the expanded node value. |
| `defaultFocusedValue` | `string` | No | The initial focused node value when rendered.
Use when you don't need to control the focused node value. |
| `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered.
Use when you don't need to control the selected node value. |
| `expandedValue` | `string[]` | No | The controlled expanded node ids |
| `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not |
| `focusedValue` | `string` | No | The value of the focused node |
| `groupArraysAfterLength` | `number` | No |  |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loadChildren` | `(details: LoadChildrenDetails<any>) => Promise<any[]>` | No | Function to load children for a node asynchronously.
When provided, branches will wait for this promise to resolve before expanding. |
| `maxPreviewItems` | `number` | No |  |
| `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. |
| `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes |
| `onExpandedChange` | `(details: ExpandedChangeDetails<any>) => void` | No | Called when the tree is opened or closed |
| `onFocusChange` | `(details: FocusChangeDetails<any>) => void` | No | Called when the focused node changes |
| `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails<any>) => void` | No | Called when a node finishes loading children |
| `onLoadChildrenError` | `(details: LoadChildrenErrorDetails<any>) => void` | No | Called when loading children fails for one or more nodes |
| `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed |
| `onRenameStart` | `(details: RenameStartDetails<any>) => void` | No | Called when a node starts being renamed |
| `onSelectionChange` | `(details: SelectionChangeDetails<any>) => void` | No | Called when the selection changes |
| `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. |
| `selectedValue` | `string[]` | No | The controlled selected node value |
| `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection
- "single": only one node can be selected
- "multiple": multiple nodes can be selected |
| `showNonenumerable` | `boolean` | No |  |
| `typeahead` | `boolean` | No | Whether the tree supports typeahead search |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**JsonTreeViewRootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseTreeViewReturn<JsonNode<any>>` | Yes |  |
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**JsonTreeViewTree Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `arrow` | `number | boolean | Node | (string & {}) | ArrayElement` | No | The icon to use for the arrow. |
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `indentGuide` | `number | boolean | Node | (string & {}) | ArrayElement` | No | The indent guide to use for the tree. |
| `renderValue` | `(node: JsonNodeHastElement) => Element` | No | The function to render the value of the node. |


#### Vue

**JsonTreeViewRoot Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `data` | `object` | Yes | The data to display in the tree. |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `canRename` | `(node: JsonNode<any>, indexPath: number[]) => boolean` | No | Function to determine if a node can be renamed |
| `checkedValue` | `string[]` | No | The controlled checked node values |
| `collapseStringsAfterLength` | `number` | No |  |
| `defaultCheckedValue` | `string[]` | No | The initial checked node values when rendered.
Use when you don't need to control the checked node values. |
| `defaultExpandedDepth` | `number` | No | The default expand level. |
| `defaultExpandedValue` | `string[]` | No | The initial expanded node values when rendered.
Use when you don't need to control the expanded node values. |
| `defaultFocusedValue` | `string` | No | The initial focused node value when rendered.
Use when you don't need to control the focused node value. |
| `defaultSelectedValue` | `string[]` | No | The initial selected node values when rendered.
Use when you don't need to control the selected node values. |
| `expandedValue` | `string[]` | No | The controlled expanded node values |
| `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not |
| `focusedValue` | `string` | No | The id of the focused node |
| `groupArraysAfterLength` | `number` | No |  |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{ root: string; tree: string; label: string; node(value: string): string }>` | No | The ids of the tree elements. Useful for composition. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loadChildren` | `(details: LoadChildrenDetails<JsonNode<any>>) => Promise<JsonNode<any>[]>` | No | A function that loads the children of a node. |
| `maxPreviewItems` | `number` | No |  |
| `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. |
| `selectedValue` | `string[]` | No | The controlled selected node values |
| `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection
- "single": only one node can be selected
- "multiple": multiple nodes can be selected |
| `showNonenumerable` | `boolean` | No |  |
| `typeahead` | `boolean` | No | Whether the tree supports typeahead search |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**JsonTreeViewRootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `TreeViewApi<PropTypes, JsonNode<any>>` | Yes |  |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**JsonTreeViewTree Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `indentGuide` | `boolean` | No |  |


#### Svelte

**JsonTreeViewRoot Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `canRename` | `(node: JsonNode<any>, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed |
| `checkedValue` | `string[]` | No | The controlled checked node value |
| `collapseStringsAfterLength` | `number` | No |  |
| `data` | `{}` | No | The data to display in the tree. |
| `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered.
Use when you don't need to control the checked node value. |
| `defaultExpandedDepth` | `number` | No | The default expand level. |
| `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered.
Use when you don't need to control the expanded node value. |
| `defaultFocusedValue` | `string` | No | The initial focused node value when rendered.
Use when you don't need to control the focused node value. |
| `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered.
Use when you don't need to control the selected node value. |
| `expandedValue` | `string[]` | No | The controlled expanded node ids |
| `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not |
| `focusedValue` | `string` | No | The value of the focused node |
| `groupArraysAfterLength` | `number` | No |  |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loadChildren` | `(details: LoadChildrenDetails<JsonNode<any>>) => Promise<JsonNode<any>[]>` | No | Function to load children for a node asynchronously.
When provided, branches will wait for this promise to resolve before expanding. |
| `maxPreviewItems` | `number` | No |  |
| `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. |
| `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes |
| `onExpandedChange` | `(details: ExpandedChangeDetails<JsonNode<any>>) => void` | No | Called when the tree is opened or closed |
| `onFocusChange` | `(details: FocusChangeDetails<JsonNode<any>>) => void` | No | Called when the focused node changes |
| `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails<JsonNode<any>>) => void` | No | Called when a node finishes loading children |
| `onLoadChildrenError` | `(details: LoadChildrenErrorDetails<JsonNode<any>>) => void` | No | Called when loading children fails for one or more nodes |
| `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed |
| `onRenameStart` | `(details: RenameStartDetails<JsonNode<any>>) => void` | No | Called when a node starts being renamed |
| `onSelectionChange` | `(details: SelectionChangeDetails<JsonNode<any>>) => void` | No | Called when the selection changes |
| `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. |
| `ref` | `Element` | No |  |
| `selectedValue` | `string[]` | No | The controlled selected node value |
| `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection
- "single": only one node can be selected
- "multiple": multiple nodes can be selected |
| `showNonenumerable` | `boolean` | No |  |
| `typeahead` | `boolean` | No | Whether the tree supports typeahead search |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**JsonTreeViewRootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseTreeViewReturn<JsonNode<any>>` | Yes |  |
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `ref` | `Element` | No |  |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**JsonTreeViewTree Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `arrow` | `Snippet<[]>` | No | The icon to use for the arrow. |
| `asChild` | `Snippet<[PropsFn<'ul'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `indentGuide` | `boolean | Snippet<[]>` | No | The indent guide to use for the tree. |
| `ref` | `Element` | No |  |
| `renderValue` | `Snippet<[JsonNodeHastElement]>` | No | 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](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/).

### Keyboard Support

**`Tab`**
Description: Moves focus to the tree view, placing the first tree view item in focus.

**`Enter + Space`**
Description: Selects the item or branch node

**`ArrowDown`**
Description: Moves focus to the next node

**`ArrowUp`**
Description: Moves focus to the previous node

**`ArrowRight`**
Description: When focus is on a closed branch node, opens the branch.<br> When focus is on an open branch node, moves focus to the first item node.

**`ArrowLeft`**
Description: When focus is on an open branch node, closes the node.<br> When focus is on an item or branch node, moves focus to its parent branch node.

**`Home`**
Description: Moves focus to first node without opening or closing a node.

**`End`**
Description: Moves focus to the last node that can be focused without expanding any nodes that are closed.

**`a-z + A-Z`**
Description: 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.

**`*`**
Description: Expands all sibling nodes that are at the same depth as the focused node.

**`Shift + ArrowDown`**
Description: Moves focus to and toggles the selection state of the next node.

**`Shift + ArrowUp`**
Description: Moves focus to and toggles the selection state of the previous node.

**`Ctrl + A`**
Description: Selects all nodes in the tree. If all nodes are selected, unselects all nodes.