Tree Simple
SimpleTreeView examples: itemId/label items, checkbox multi-select, per-item disabled flags, custom icons, and the iconContainer expansion trigger.
Overview
SimpleTreeView examples: itemId/label items, checkbox multi-select, per-item disabled flags, custom icons, and the iconContainer expansion trigger.
SimpleTreeView
SimpleTreeView is the lightweight, JSX-driven tree in dash-mui-charts (Community license — no key needed). Unlike the data-driven TreeView (a RichTreeView wrapper with an MUI store), SimpleTreeView renders its items as TreeItem JSX children — a lighter alternative that suits navigation sidebars and small static trees. This documentation site dogfoods it: the site's own sidebar navigation is a SimpleTreeView (NAV_ITEMS in app.py).
Item shape — itemId, not id
items = [
{"itemId": "1", "label": "Applications", "children": [
{"itemId": "1.1", "label": "Calendar"},
{"itemId": "1.2", "label": "Chrome"},
]},
]
Items also support per-item flags directly on the dict:
disabled: True— item is greyed out and inert.disableSelection: True— item renders normally but cannot be selected.icon— an MUI icon name, resolved through the library's icon resolver.
Basic usage
from dash_mui_charts import SimpleTreeView
SimpleTreeView(
id="nav",
items=items,
defaultExpandedItems=["1"],
)
Key props
multiSelect=True+checkboxSelection=True— checkbox multi-select.expandIcon/collapseIcon/endIcon— MUI icon names, e.g.
expandIcon="ChevronRight", collapseIcon="ExpandMore", endIcon="Description".
expansionTrigger="iconContainer"— only clicking the expand/collapse
icon toggles the node (default "content" toggles on the whole row).
Outputs (use as callback Inputs)
selectedItems— the current selection (string or list with multiSelect).
@callback(Output("out", "children"), Input("nav", "selectedItems"))
def show_selection(sel):
return json.dumps(sel) if sel else "Select an item..."
Related pages
- /tree-basic — TreeView, the data-driven RichTreeView wrapper
- /tree-selection — selection modes on TreeView
- /tree-expansion — expansion triggers and controlled expand/collapse
- /tree-editing — inline label editing
- /tree-icons — icons, indentation, height and sx styling
- /tree-disabled — disabled items and focusability
- /tree-pro — TreeViewPro: drag-reorder, lazy loading, per-item controls
The docs sidebar, dogfooded
Before the boilerplate migration this site's navigation WAS a SimpleTreeView. The tree below is generated from the site's real navigation map (components/navbar.py), and clicking a leaf genuinely navigates — the component driving its own documentation, as it always did.
# File: docs/tree_simple/sidebar_example.py
"""The dogfooding demo: this documentation's own sidebar as a SimpleTreeView.
Before the boilerplate migration, this site's navigation WAS a
SimpleTreeView — the component navigating its own docs. The shell now uses
the network-standard navbar, so the dogfooding story lives here instead:
the tree below is built from the SAME source the real sidebar reads, so it
can never drift from the actual nav, and selecting a leaf genuinely
navigates, exactly as the old sidebar did.
That source moved with sync item 16. The sidebar used to come from a
hand-written FAMILIES map in `components/navbar.py`; it now comes from each
page's own frontmatter (`category:` + `order:`) ordered by
`lib.constants.CATEGORY_ORDER`. This module reads the frontmatter directly
rather than the page registry, because a docs demo is executed WHILE the
registry is still being built — the file on disk is the one source that is
complete at any moment.
"""
import re
from pathlib import Path
from dash import Input, Output, clientside_callback, html
from dash_mui_charts import SimpleTreeView
from lib.constants import CATEGORY_ORDER
_DOCS = Path(__file__).resolve().parent.parent
_ICON_BY_FAMILY = {
"SparklineChart": "Timeline",
"PieChart": "PieChart",
"BarChart": "BarChart",
"Heatmap": "GridOn",
"ScatterChart": "ScatterPlot",
"LineChart": "ShowChart",
"CandlestickChart": "CandlestickChart",
"LiveTradingChart": "TrendingUp",
"CompositeChart": "Layers",
"TreeView": "AccountTree",
"Date & Time Pickers": "Schedule",
"Reference": "MenuBook",
}
def _frontmatter(md):
out = {}
for key in ("name", "endpoint", "category", "order"):
m = re.search(rf"^{key}:\s*(.+?)\s*$", md, re.M)
if m:
out[key] = m.group(1)
return out
def _families():
"""``[(category, [(endpoint, name), ...]), ...]`` in sidebar order."""
by_cat = {}
for f in sorted(_DOCS.glob("**/*.md")):
fm = _frontmatter(f.read_text())
if not fm.get("endpoint") or not fm.get("category"):
continue
try:
order = int(fm.get("order", 1000))
except ValueError:
order = 1000
by_cat.setdefault(fm["category"], []).append(
(order, fm["name"], fm["endpoint"]))
known = [c for c in CATEGORY_ORDER if c in by_cat]
extra = sorted(c for c in by_cat if c not in CATEGORY_ORDER)
return [(c, [(e, n) for _o, n, e in sorted(by_cat[c])])
for c in known + extra]
items = [
{"itemId": "/", "label": "Home", "icon": "Home"},
{"itemId": "/changelog", "label": "Changelog", "icon": "History"},
] + [
{
"itemId": f"group-{family}",
"label": family,
"icon": _ICON_BY_FAMILY.get(family, "Folder"),
"children": [
{"itemId": path, "label": name, "icon": "PlayArrow"}
for path, name in entries
],
}
for family, entries in _families()
]
component = html.Div(
[
html.P(
"Click a leaf to navigate these docs — the tree is generated "
"from the site's real navigation map.",
style={"color": "var(--mantine-color-dimmed)",
"fontSize": "14px"},
),
SimpleTreeView(
id="tree-simple-sidebar-demo",
items=items,
defaultExpandedItems=["group-TreeView"],
itemChildrenIndentation="8px",
sx={
"& .MuiTreeItem-label": {"fontSize": "14px",
"lineHeight": "1.6"},
"& .MuiTreeItem-content": {"padding": "4px 10px",
"borderRadius": "6px",
"minHeight": "34px"},
},
),
],
style={"maxWidth": "320px"},
)
# The old shell's navigation callback, verbatim in spirit: leaf selection
# drives the URL. Groups (non-path ids) are ignored.
clientside_callback(
"""
(selected) => {
if (selected && typeof selected === 'string' && selected.startsWith('/')) {
if (window.location.pathname !== selected) {
return selected;
}
}
return window.dash_clientside.no_update;
}
""",
Output("url", "href", allow_duplicate=True),
Input("tree-simple-sidebar-demo", "selectedItems"),
prevent_initial_call=True,
)
:defaultExpanded: false :withExpandedButton: true
Live examples
# File: docs/tree_simple/demo.py
"""Tree Simple demo — rendered on /tree-simple via `.. exec::`.
Ported verbatim from the pre-migration pages/tree_simple.py (same ids, same callbacks).
"""
import json
from dash import html, callback, Input, Output
from dash_mui_charts import SimpleTreeView
# SimpleTreeView uses itemId (not id) and label
SIMPLE_ITEMS = [
{"itemId": "1", "label": "Applications", "children": [
{"itemId": "1.1", "label": "Calendar"},
{"itemId": "1.2", "label": "Chrome"},
{"itemId": "1.3", "label": "Webstorm"},
]},
{"itemId": "2", "label": "Documents", "children": [
{"itemId": "2.1", "label": "OSS", "children": [
{"itemId": "2.1.1", "label": "MUI", "children": [
{"itemId": "2.1.1.1", "label": "index.js"},
]},
]},
{"itemId": "2.2", "label": "Personal", "children": [
{"itemId": "2.2.1", "label": "resume.pdf"},
]},
]},
{"itemId": "3", "label": "Bookmarks", "children": [
{"itemId": "3.1", "label": "GitHub"},
{"itemId": "3.2", "label": "Stack Overflow"},
]},
]
# Per-item disabled/disableSelection example
DISABLED_ITEMS = [
{"itemId": "d1", "label": "Available", "children": [
{"itemId": "d1.1", "label": "Item A"},
{"itemId": "d1.2", "label": "Item B (disabled)", "disabled": True},
{"itemId": "d1.3", "label": "Item C"},
]},
{"itemId": "d2", "label": "Mixed", "children": [
{"itemId": "d2.1", "label": "Selectable"},
{"itemId": "d2.2", "label": "Not selectable", "disableSelection": True},
{"itemId": "d2.3", "label": "Disabled", "disabled": True},
]},
]
section_style = {'marginBottom': '40px'}
output_style = {
'fontSize': '12px', 'margin': 0,
'padding': '10px 14px', 'borderRadius': '6px',
'backgroundColor': '#f5f5f5',
'border': '1px solid #ddd',
'whiteSpace': 'pre-wrap',
'maxHeight': '200px',
'overflow': 'auto',
}
component = html.Div([
# --- 1. Basic ---
html.Div([
html.H3("1. Basic SimpleTreeView"),
html.P("Nested items with itemId and label fields.", style={'color': '#666'}),
SimpleTreeView(
id="tree-simple-basic",
items=SIMPLE_ITEMS,
defaultExpandedItems=["1", "2"],
),
], style=section_style),
# --- 2. Selection ---
html.Div([
html.H3("2. Selection with Click Tracking"),
html.P("Single selection with click output.", style={'color': '#666'}),
SimpleTreeView(
id="tree-simple-select",
items=SIMPLE_ITEMS,
defaultExpandedItems=["1", "2", "3"],
),
html.Pre(id="tree-simple-select-out", children="Select an item...", style=output_style),
], style=section_style),
# --- 3. Multi-select with checkboxes ---
html.Div([
html.H3("3. Checkbox Multi-Select"),
html.P("multiSelect + checkboxSelection on SimpleTreeView.", style={'color': '#666'}),
SimpleTreeView(
id="tree-simple-checkbox",
items=SIMPLE_ITEMS,
defaultExpandedItems=["1", "2", "3"],
multiSelect=True,
checkboxSelection=True,
),
html.Pre(id="tree-simple-checkbox-out", children="Check items...", style=output_style),
], style=section_style),
# --- 4. Per-item disabled/disableSelection ---
html.Div([
html.H3("4. Per-Item Disabled & disableSelection"),
html.P(
"SimpleTreeView supports per-item disabled and disableSelection flags directly on items.",
style={'color': '#666'},
),
SimpleTreeView(
id="tree-simple-disabled",
items=DISABLED_ITEMS,
defaultExpandedItems=["d1", "d2"],
),
], style=section_style),
# --- 5. Custom icons ---
html.Div([
html.H3("5. Custom Icons"),
html.P('expandIcon="Add", collapseIcon="Remove", endIcon="Description"', style={'color': '#666'}),
SimpleTreeView(
id="tree-simple-icons",
items=SIMPLE_ITEMS,
defaultExpandedItems=["1"],
expandIcon="Add",
collapseIcon="Remove",
endIcon="Description",
),
], style=section_style),
# --- 6. Icon container expansion ---
html.Div([
html.H3("6. Icon Container Expansion Trigger"),
html.P('expansionTrigger="iconContainer" — only icon click expands.', style={'color': '#666'}),
SimpleTreeView(
id="tree-simple-icon-trigger",
items=SIMPLE_ITEMS,
defaultExpandedItems=["2"],
expansionTrigger="iconContainer",
expandIcon="ChevronRight",
collapseIcon="ExpandMore",
),
], style=section_style),
])
@callback(
Output("tree-simple-select-out", "children"),
Input("tree-simple-select", "selectedItems"),
prevent_initial_call=True,
)
def show_simple_select(sel):
return json.dumps(sel, indent=2) if sel else "Select an item..."
@callback(
Output("tree-simple-checkbox-out", "children"),
Input("tree-simple-checkbox", "selectedItems"),
prevent_initial_call=True,
)
def show_simple_checkbox(sel):
return json.dumps(sel, indent=2) if sel else "Check items..."
:defaultExpanded: false :withExpandedButton: true
Source: /tree-simple
Note for AI agents: This is the static, prerendered view of an interactive Dash application served because we detected a non-JS user agent. Full prose docs:
- /tree-simple/llms.txt — LLM-friendly documentation
- /sitemap.xml
- /robots.txt