Trees, by Pierre, for spaday
Overview
spaday-trees wraps Pierre's imperative FileTree in a <spaday-tree> custom element and exposes it
as the Python Tree component. The first release supports reactive path replacement, selected paths,
search, Git status, and path-based selection-change / search-change events.
Setting selected_paths reveals the selection — ancestor directories are expanded automatically and
the first selected path is scrolled into view. This reveal behaviour is a supported contract. A bare
string is coerced to a one-element list; other non-list values raise a TypeError.
The virtualized tree needs a height: give the element or an ancestor one (the quick example uses
.style(height="22rem")). Without one, the package stylesheet applies a min-height fallback of
200px, overridable through the --trees-min-height CSS variable. A tree that still measures zero
height with non-empty paths logs a one-time console warning.
Documentation
- Build a reactive project tree — guided first application.
- Synchronize paths, selection, and search — task-focused recipes.
- API reference — props, events, and package descriptor.
- Why Trees uses an imperative wrapper — integration design and tradeoffs.
Quick example
This app filters the tree as you type. The button changes its selected path through spaday's reactive store; selecting and expanding nodes in the tree remains client-side.
from spaday import SetField, element
from spaday.backends.starlette import serve
from spaday_trees import Tree
paths = [
"README.md",
"pyproject.toml",
"src/app.py",
"src/components/tree.py",
"tests/test_app.py",
]
tree = (
Tree(paths=paths)
.bind("search", "query")
.bind("selected_paths", "selected")
.style(height="22rem")
)
page = (
element("main")
.style(max_width="42rem", margin="2rem auto", font_family="system-ui")
.child(element("h1").text("Project files"))
.child(
element("input", type="search", placeholder="Filter files…")
.bind("value", "query", mode="two-way")
.style(width="100%", padding="0.6rem", margin_bottom="0.75rem")
)
.child(element("button").text("Select README").on("click", SetField("selected", ["README.md"])))
.child(tree)
)
app = serve(page, packages=["trees"], store={"query": "", "selected": []})
Save this as app.py, then run pip install spaday-trees starlette uvicorn and
uvicorn app:app. Open http://127.0.0.1:8000.
Installing this project registers the trees entry point with spaday. The equivalent explicit forms
are packages=[spaday_trees.package] and packages=["spaday_trees:package"].
The integration pins @pierre/trees 1.0.0-beta.5. Rename, drag-and-drop persistence, custom
composition renderers, and SSR/hydration are intentionally deferred while its beta API settles.
Testing
Rows render inside the shadow root of the engine's <file-tree-container> element, so innerText
or childElementCount on the <spaday-tree> host show nothing even when rendering works. Row
labels are fragmented for truncation, so text selectors fail. Use the stable hooks instead: each
rendered row carries [data-item-path] (its path, directories with a trailing /) and
[role="treeitem"].
Run the local example
python -m pip install -e ".[examples]"
python -m spaday_trees.example
Open http://127.0.0.1:8016 to inspect the complete project-explorer example: reactive
server path updates, selection, built-in search, Git status, responsive styling, and client events logged
by Python. It passes the local package descriptor directly, so it does not install or resolve the
integration from GitHub.
[!NOTE] This library was generated using copier from the Base Python Project Template repository.
Metadata
Release files for spaday-trees 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| spaday_trees-0.2.1.tar.gz | 364.5 kB | Details |
Release files / spaday_trees-0.2.1.tar.gz
| Download URL | spaday_trees-0.2.1.tar.gz |
|---|---|
| Size | 364.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ef5ebffcde2aea103334f4b7535f3dd9bf47d63fc1ac9a13892f927943e4f9b8
|
|
BLAKE2b-256 checksum How to use checksums |
377e4f22a758003f018e7679ced585f306ddbe93bbc14141145b55efcedc6011
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|