Tree
SvTree: a file explorer with cascading tri-state checkboxes and a single-select highlight; keyboard up/down move, left/right collapse/expand.
A live, editable Svelte 5 component example from the SvGrid gallery (Layout). Read the SvGrid UI component docs for the full API.
About this example
SvTree in Svelte 5 as a file explorer with cascading tri-state checkboxes, a single-select highlight and a search box that filters the tree. Up and Down move between visible nodes, Left and Right collapse and expand, and onSelect, onCheck and onToggle report selection, the checked id set and expansion changes.
SvTree - a production file explorer with cascading tri-state checkboxes and a single-select highlight. Keyboard: up/down move, left/right collapse/expand. Copy-paste ready.
Imports, features and API used
Imports: @svgrid/grid
Frequently asked questions
How do I enable checkboxes?
Set checkable and pass the checked ids; checking a folder cascades to its descendants and partial folders show the indeterminate state. onCheck receives the updated id array.
How does search work?
searchable adds an input above the tree; typing filters to nodes whose label matches and keeps their ancestors visible and expanded so the path stays readable.
How is the expanded state controlled?
expandedIds holds the open node ids and onToggle reports each change, so the parent can persist or preset which folders are open.
Related documentation
Related articles
- Saved Views - Persist Grid Layout and Filters - Give users named, switchable snapshots of column order, sorting, filters, and grouping - persisted to localStorage or a server adapter - using SvGrid's createNamedViews API.
- SvGrid UI Components Tips and Tricks: Svelte 5 Buttons, Inputs, Tree, Forms - Practical tips for the SvGrid UI component kit - SvButton states, a Cmd+K command palette, a virtualized searchable tree, schema-driven forms, a parsing date/time field, and the shared field contract - each with a code snippet.
- Inside SvGrid: Grouping, Trees, and Master-Detail - Three different ways to show hierarchy in a data grid, unified under one expansion model in SvGrid - the design decision and how each feature actually works.
Source code (321-tree.svelte)
<script lang="ts">
/**
* SvTree - a production file explorer with cascading tri-state checkboxes and a
* single-select highlight. Keyboard: up/down move, left/right collapse/expand.
* Copy-paste ready.
*/
import { SvTree } from '@svgrid/grid'
import type { SvTreeNode } from '@svgrid/grid'
const nodes: SvTreeNode[] = [
{ id: 'src', label: 'src', children: [
{ id: 'comp', label: 'components', children: [
{ id: 'grid', label: 'Grid.svelte' },
{ id: 'toolbar', label: 'Toolbar.svelte' },
] },
{ id: 'lib', label: 'lib', children: [
{ id: 'api', label: 'api.ts' },
{ id: 'utils', label: 'utils.ts' },
] },
{ id: 'main', label: 'main.ts' },
] },
{ id: 'public', label: 'public', children: [
{ id: 'logo', label: 'logo.svg' },
{ id: 'favicon', label: 'favicon.ico' },
] },
{ id: 'readme', label: 'README.md' },
]
let selected = $state<string | null>('grid')
let checked = $state<string[]>(['api'])
let expanded = $state<string[]>(['src', 'comp', 'lib'])
</script>
<div class="wrap">
<header>
<h2>Tree</h2>
<p>A hierarchical view (WAI-ARIA tree) with a built-in search box (type to filter, matches auto-expand), cascading tri-state checkboxes and keyboard nav.</p>
</header>
<div class="cols">
<div class="card">
<SvTree {nodes} {selected} checkable {checked} expandedIds={expanded} searchable searchPlaceholder="Search files..."
onSelect={(id) => (selected = id)}
onCheck={(ids) => (checked = ids)}
onToggle={(id, open) => (expanded = open ? [...expanded, id] : expanded.filter((e) => e !== id))} />
</div>
<aside class="side">
<div><span class="k">Selected</span><strong>{selected ?? '-'}</strong></div>
<div><span class="k">Checked ({checked.length})</span><strong>{checked.join(', ') || '-'}</strong></div>
</aside>
</div>
</div>
<style>
.wrap { padding: 20px; max-width: 640px; display: flex; flex-direction: column; gap: 16px; }
header h2 { margin: 0 0 4px; font-size: 20px; font-weight: 700; }
header p { margin: 0; color: var(--sg-muted, #64748b); font-size: 13.5px; line-height: 1.5; }
.cols { display: flex; gap: 24px; align-items: flex-start; flex-wrap: wrap; }
.side { flex: 1; min-width: 160px; display: flex; flex-direction: column; gap: 14px; }
.side .k { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: 0.03em; color: var(--sg-muted, #94a3b8); margin-bottom: 2px; }
.side strong { font-size: 13px; word-break: break-word; }
</style>More Layout examples
- Account & security settings console - A real SaaS settings surface composed from the UI kit: SvMenubar app bar, promise + Undo-action toasts on save, SvPopconfirm on destructive rows, SvHoverCard teammate previews, and frame input adornments (leading icons, prefix affixes, masked API key). Profile / Team / Security tabs over SvCard + SvStat.
- Invoice builder - An adornment-heavy money form: currency prefixes, % suffixes, masked tax IDs (frame adornments), line items with SvPopconfirm delete + Undo action toasts, live SvStat totals, an SvHoverCard tax hint, and a promise toast on Send. Pure UI-kit composition.
- Operations KPI dashboard - A KPI console: SvStat + SvSparkline tiles, an SvGauge SLA dial, SvHoverCard drill-down previews per service, an SvMenubar toolbar (View / Range / Actions) and a promise toast on Refresh. Pure UI-kit composition, no grid dependency.
- Form: rich field types - SvForm reaching the whole input suite from one schema - phone, country, mask, combobox, radio, slider, tags, datetime and file - plus per-field help text, a readonly field, column span, and a promise toast on submit.
- Form: cascading fields - SvForm dependent selects - a child list derives from the parent value via a function `options`, and `dependsOn` clears the child when the parent changes so a stale selection never lingers. Country -> State -> City.