useTreeView
useTreeView takes the flat array of entities a listing page already has and builds the client-side tree that Tree View renders. It links nodes through their parent relation, sorts siblings, and owns the expand/collapse state.
Import
import { useTreeView } from "@phpcreation/frontend-crud-react-nextjs-bundle/utils/hooks";Signature
const {
treeData, // TreeItem[] root nodes, children nested
itemsMap, // Map<number, TreeItem> every node by id
visibleItems, // TreeItem[] flattened rows to render, respecting expansion
expandedRows, // Set<number> ids of expanded nodes
toggleTreeRow, // (id: number) => void
expandAll, // () => void
collapseAll, // () => void
expandNodeAndParents, // (id: number) => void expand a node and all its ancestors
findNode, // (id | predicate) => TreeItem | null
isTreeEmpty, // boolean
} = useTreeView(data, options);interface TreeViewOptions {
idField?: string; // default "id"
parentField?: string; // default "parent"
levelField?: string; // default "lvl"
sortField?: string; // default "ref"
defaultExpandLevel?: number; // default 1, levels expanded on load
}Each TreeItem wraps the original entity:
interface TreeItem<T> {
id: number;
item: T; // the raw entity
level: number; // from levelField
children: TreeItem<T>[];
parentId: number | null;
}Behavior
- Parenting. Nodes attach to their parent through
parentField. A node whose parent is not in the current page of data becomes a root, so a filtered subtree still renders. - Sibling order. Siblings sort by
lftascending. Nodes without a usablelftfall back tosortField, thenid. This keeps the display order equal to the stored tree order. - Expansion survives refetches. When
datachanges (a move, an inline edit, a filter), previously expanded ids that still exist stay expanded.defaultExpandLevelonly adds to that set. visibleItemsis what the table maps over: a depth-first flattening oftreeDatathat skips children of collapsed nodes.
Usage
How ListingTable uses it:
const {
visibleItems,
toggleTreeRow,
expandAll,
collapseAll,
expandedRows,
expandNodeAndParents,
} = useTreeView(data, {
parentField: "parent",
levelField: "lvl",
defaultExpandLevel: 0,
});
// ?anchor=<id> deep link: open the path to the node
useEffect(() => {
if (anchoredId) expandNodeAndParents(Number(anchoredId));
}, [anchoredId, data]);Related
Last updated on