AsyncTreeMenu#
@palmyralabs/rt-forms · src/palmyra/menu/AsyncTreeMenu.tsx
Overview#
Sidebar tree menu. On mount it calls store.getRoot() once against a Wire TreeQueryStore to fetch the whole tree, converts the flat list into react-accessible-treeview nodes, and renders a checkbox-less expandable sidebar.
Selecting a leaf calls useNavigate() from react-router-dom with the leaf’s metadata.code (or metadata.target for non-leaf shortcut links). Expand state and the last selection are persisted to localStorage under the keys palmyra.rui.sidemenu.expanded and palmyra.rui.sidemenu.expanded.selected, so the menu restores itself on page refresh.
Icons are pluggable — pass an IconProvider to map per-leaf metadata.code values to React icons; omit it to get the SimpleIconProvider default.
Props — IAsyncTreeMenuInput#
interface IAsyncTreeMenuInput {
store: TreeQueryStore<IChildTreeRequest, any>;
iconProvider?: IconProvider;
}Node shape#
getRoot() is expected to return { result: MenuRow[] } where each row has:
{
id: number,
parent: number | null, // null / -1 for roots
name: string, // label displayed in the sidebar
children: string, // comma-separated child ids, e.g. "12,13,15"
code: string, // navigation target for leaves (router path)
action?: string,
target?: string, // navigation target for non-leaf shortcuts
}children is a comma-separated string of ids — the component parses it into the tree on its own. isBranch is derived from whether children is non-empty.
Example#
import AsyncTreeMenu from '@palmyralabs/rt-forms/menu/AsyncTreeMenu';
import AppStoreFactory from '@/wire/StoreFactory';
export function Sidebar() {
const store = AppStoreFactory.getTreeStore({}, '/menu');
return (
<aside className="sidebar">
<AsyncTreeMenu store={store} />
</aside>
);
}With a custom icon provider:
import type { IconProvider } from '@palmyralabs/rt-forms';
import { Users, Package, BarChart3 } from 'lucide-react';
const iconProvider: IconProvider = {
getIcon(code: string) {
switch (code) {
case '/app/users': return Users;
case '/app/products': return Package;
case '/app/reports': return BarChart3;
default: return null;
}
}
};
<AsyncTreeMenu store={store} iconProvider={iconProvider} />State persistence#
Clear the persisted state — e.g. after logout — by removing both keys:
localStorage.removeItem('palmyra.rui.sidemenu.expanded');
localStorage.removeItem('palmyra.rui.sidemenu.expanded.selected');