An anywidget wrapping react-complex-tree
Project description
anycomplextree
An anywidget that wraps react-complex-tree, giving you an interactive tree view inside Jupyter / JupyterLab / VS Code / Marimo notebooks with two-way state sync to Python.
Features
- Hierarchical tree rendering powered by
react-complex-tree - Two-way sync for selection, expansion, and focus
- Python-side validation of tree structure with clear error messages
- Single bundled ESM asset — no CDN fetches at runtime
Installation
uv add anycomplextree
Quick start
from anycomplextree import ComplexTree
tree = ComplexTree(
items={
"root": {
"isFolder": True,
"children": ["fruits", "meals"],
"data": "Root",
},
"fruits": {
"isFolder": True,
"children": ["apple", "orange", "banana"],
"data": "Fruits",
},
"apple": {"data": "Apple"},
"orange": {"data": "Orange"},
"banana": {"data": "Banana"},
"meals": {
"isFolder": True,
"children": ["pasta", "pizza"],
"data": "Meals",
},
"pasta": {"data": "Pasta"},
"pizza": {"data": "Pizza"},
},
root_item="root",
)
tree
The items model
Each entry in items represents one node. The dict key is the node's identifier — react-complex-tree calls it index. The key, the optional index field on the item, and the entries inside parent children arrays must all be the same string.
| field | type | description |
|---|---|---|
index |
str |
Unique identifier. Auto-filled from the dict key if omitted. |
data |
Any |
Per-item payload. By default used as the display title. |
isFolder |
bool |
Whether the item can have children. |
children |
list[str] |
IDs of child items (must exist as keys in items). |
Using UUIDs
Since the dict key is the identifier, just use UUID strings as keys:
import uuid
apple_id = str(uuid.uuid4())
fruits_id = str(uuid.uuid4())
tree = ComplexTree(
items={
fruits_id: {"isFolder": True, "children": [apple_id], "data": "Fruits"},
apple_id: {"data": "Apple"},
"root": {"isFolder": True, "children": [fruits_id], "data": "Root"},
},
)
tree.selected_items # -> [apple_id] after you click Apple
Traits
All traits are two-way synced between Python and the browser.
| trait | type | description |
|---|---|---|
items |
dict |
The tree contents (see above). |
root_item |
str |
Key of the root node. Defaults to "root". |
selected_items |
list[str] |
Currently selected item IDs. |
expanded_items |
list[str] |
Currently expanded folder IDs. |
focused_item |
str | None |
Currently focused item ID. |
Read, write, or observe them like any traitlet:
tree.expanded_items = ["root", "fruits"]
tree.selected_items = ["apple"]
tree.focused_item = "apple"
tree.observe(lambda change: print("selection:", change["new"]), names="selected_items")
Note: traitlets only fires change events when the trait is reassigned, not when mutated in place. Use
tree.selected_items = [...], nottree.selected_items.append(...).
Validation
items and root_item are validated on assignment. You'll get a TraitError with a clear message for:
- A dict key that doesn't match an explicit
indexfield - A
childrenentry that doesn't exist initems - A
root_itemthat isn't a key initems
Development
The widget bundle lives in js/ and builds to anycomplextree/static/.
# one-time install
cd js && npm install
# rebuild after JS changes
npm run build
# watch mode during development
npm run dev
On the Python side:
uv sync
uv run jupyter lab
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file anycomplextree-0.1.0.tar.gz.
File metadata
- Download URL: anycomplextree-0.1.0.tar.gz
- Upload date:
- Size: 9.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8f94dbb422a7328b8d6b61a0118a8a3c26617eb432ab32985dab3b2786deaa9e
|
|
| MD5 |
82b641da65b174c7ce4f7720979a3d22
|
|
| BLAKE2b-256 |
34bf6f3f13521173f63ae2c241f7387c79b313fcf224649c7cc1f2dcd1e986d5
|
Provenance
The following attestation bundles were made for anycomplextree-0.1.0.tar.gz:
Publisher:
release.yml on mluttikh/anycomplextree
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
anycomplextree-0.1.0.tar.gz -
Subject digest:
8f94dbb422a7328b8d6b61a0118a8a3c26617eb432ab32985dab3b2786deaa9e - Sigstore transparency entry: 1280065176
- Sigstore integration time:
-
Permalink:
mluttikh/anycomplextree@8bd97642c586b4338044ec6b669418ba06cd9429 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/mluttikh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8bd97642c586b4338044ec6b669418ba06cd9429 -
Trigger Event:
push
-
Statement type:
File details
Details for the file anycomplextree-0.1.0-py3-none-any.whl.
File metadata
- Download URL: anycomplextree-0.1.0-py3-none-any.whl
- Upload date:
- Size: 3.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8f553087e0f2dac3d6c37a36b30fdc8397c91bac94e1d38b2a4577cfd75338a9
|
|
| MD5 |
9c6b5f3d95b1816f31c81069bf0c9b99
|
|
| BLAKE2b-256 |
314bcbe438c246d073f608196c2e0d7dfad4abc477a43f3e3e0c82577b3f9dee
|
Provenance
The following attestation bundles were made for anycomplextree-0.1.0-py3-none-any.whl:
Publisher:
release.yml on mluttikh/anycomplextree
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
anycomplextree-0.1.0-py3-none-any.whl -
Subject digest:
8f553087e0f2dac3d6c37a36b30fdc8397c91bac94e1d38b2a4577cfd75338a9 - Sigstore transparency entry: 1280065190
- Sigstore integration time:
-
Permalink:
mluttikh/anycomplextree@8bd97642c586b4338044ec6b669418ba06cd9429 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/mluttikh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8bd97642c586b4338044ec6b669418ba06cd9429 -
Trigger Event:
push
-
Statement type: