leptos-column-browser
Finder-style column navigation for Leptos, with async loading, keyboard support, resizable columns, and CSS-variable theming.
A multi-pane column browser for Leptos, modeled on
macOS Finder's Miller-column navigation. Navigate any deeply-nested hierarchy
via an async TopologyProvider trait you implement — filesystems, APIs, org
charts, or anything tree-shaped.
Features
- Domain-agnostic —
TopologyProvideris your contract; the library has no opinion about what "node types" mean. - Async-first — children are fetched lazily on drill-down via
async fn get_children. - Keyboard accessible — ↑/↓ within columns, → to drill, ← to pop back.
- ARIA compliant —
role="tree",role="treeitem",aria-selected,aria-expanded. - Resizable columns — drag the right edge of any column.
- Custom icons — supply an
IconRendererclosure; no built-in opinions. - Controlled or uncontrolled state — pass an
RwSignal<DrillPath>for deep-link routing, or let the component manage state internally. - Theming — pure CSS variables, no style injection.
Quick Start
Requirements
- Rust
1.94+ leptos = "0.8"- Default
uifeature enabled wasm32-unknown-unknowntarget for browser builds
Install
Add to Cargo.toml:
[]
= "0.1"
Link the bundled stylesheet from style/column-browser.css in your index.html
(or import it from your bundler):
Mount a static browser:
use *;
use ;
Implementing TopologyProvider
TopologyProvider is the primary contract between your data and the UI:
use Future;
use ;
;
Key points:
get_childrenis called once per drill-down.- Return
Ok(Vec::new())for leaf nodes — the UI distinguishes leaves byNodeKind, not by an empty child list. Node::container/Node::leafcontrolNodeKind.node_typeis a free-form string you define; it is passed to yourIconRendererso you can map it to icons.
Custom Icons
Supply an IconRenderer to ColumnBrowser:
use ;
use Arc;
let icons: IconRenderer = new;
The renderer receives node_kind ("container" or "leaf").
Controlled Navigation State
For URL-based routing or programmatic navigation, supply an external signal:
use *;
use DrillPath;
let path = new;
// Navigate programmatically:
path.set;
Pass external_path=path to ColumnBrowser to enable controlled mode.
Feature Flags
ui(default): enables the Leptos UI components and web bindings
CSS Theming
Link style/column-browser.css and override the --lcb-* variables on
:root or any ancestor element:
}
| Variable | Default | Description |
|---|---|---|
--lcb-bg |
#1e1e2e |
Root container background |
--lcb-column-bg |
#181825 |
Per-column background |
--lcb-border |
#313244 |
Column divider colour |
--lcb-item-hover |
#313244 |
Item hover background |
--lcb-selected |
#45475a |
Selected item background |
--lcb-text |
#cdd6f4 |
Primary text colour |
--lcb-text-muted |
#6c7086 |
Secondary / muted text colour |
--lcb-accent |
#89b4fa |
Icon colour, focus ring, resize handle |
All colours use Catppuccin Mocha by default. A light-theme override:
}
Examples
Run the examples with Trunk:
&&
&&
file_explorer demonstrates a static in-memory tree.
api_navigator demonstrates async loading against the crates.io/GitHub ecosystem.
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.