<!-- Source: https://jsonview.svelte.page/examples/accessibility -->

# ARIA Treeview

> Inspect how @humanspeak/svelte-json-view-lite renders accessible JSON trees with labelled controls, expanded state, and keyboard focus.

**Source:** [https://jsonview.svelte.page/examples/accessibility](https://jsonview.svelte.page/examples/accessibility)

**Markdown mirror:** [https://jsonview.svelte.page/examples/accessibility.md](https://jsonview.svelte.page/examples/accessibility.md)

---

This mirror preserves the prose, implementation notes, and runnable Svelte source behind the live example page.

## FIG-001: aria treeview.

Inspect how the viewer exposes tree roles, expansion state, labelled controls, and keyboard-ready focus behavior.

**Metadata:** tag: `A11Y` | role: `tree` | focus: `roving`

### Notes

- Containers render as `role="tree"` / `role="group"` nodes with `aria-expanded` and `aria-controls` wiring each disclosure to its children.
- Arrow keys walk the tree and `Enter` / `Space` toggle a node — the same keyboard model ships in the packaged component.
- A roving `tabindex` keeps a single tab stop for the whole tree so focus never gets trapped inside deep nesting.

### Source

#### AccessibilityTree.svelte

Source file: [src/lib/examples/accessibility/demos/AccessibilityTree.svelte](https://github.com/humanspeak/svelte-json-view-lite/blob/main/docs/src/lib/examples/accessibility/demos/AccessibilityTree.svelte)

```svelte
<script lang="ts">
    import { JsonView, allExpanded } from '@humanspeak/svelte-json-view-lite'
    import { docsDarkJsonViewStyles, docsDefaultJsonViewStyles } from '$lib/json-view-docs-style'
    import { mode } from 'mode-watcher'

    const payload = {
        tree: {
            role: 'tree',
            keyboard: ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Enter', 'Space'],
            nodes: [
                {
                    label: 'request',
                    expanded: true,
                    controls: 'request-panel',
                    children: ['headers', 'body', 'metadata']
                },
                {
                    label: 'response',
                    expanded: true,
                    controls: 'response-panel',
                    children: ['status', 'headers', 'body']
                }
            ]
        },
        aria: {
            labelledBy: 'json-tree-label',
            expandedState: 'mirrors disclosure state',
            focus: 'roving tabindex inside the viewer'
        }
    }

    const style = $derived(
        mode.current === 'light' ? docsDefaultJsonViewStyles : docsDarkJsonViewStyles
    )
</script>

<div class="json-demo grid">
    <aside class="json-demo-rail">
        <p class="json-demo-k">Accessibility contract</p>
        <h3>Keyboard-ready JSON trees</h3>
        <p>
            The viewer renders nested objects and arrays as an ARIA tree, with disclosure state,
            labels, and scoped keyboard navigation handled by the component.
        </p>
        <ul class="json-demo-list">
            <li>role="tree"</li>
            <li>aria-expanded on branch nodes</li>
            <li>aria-controls from generated ids</li>
            <li>roving tabindex for node controls</li>
        </ul>
    </aside>

    <div class="json-demo-body">
        <JsonView data={payload} {style} shouldExpandNode={allExpanded} />
    </div>
</div>
```
