Tree
A Tree shows hierarchical data, such as folders of datasets. It holds no state: you pass the nodes and handle expansion and selection.
Usage#
import { Tree, type TreeNodeInfo } from "@clawscale/react";Each node needs a unique id and a label. childNodes makes it expandable. More than one top-level node makes a tree with several roots.
Examples#
Dataset browser#
Keep the expanded ids and the selected id in state, and set isExpanded and isSelected from them. icon and secondaryLabel add context to each row.
- raw
import { Tree, type TreeNodeInfo } from "@clawscale/react";
import { useState } from "react";
const DATASETS: TreeNodeInfo[] = [
{
id: "raw",
label: "raw",
childNodes: [
{ id: "raw.events", label: "events", icon: "th", secondaryLabel: "1.2B rows" },
{ id: "raw.orders", label: "orders", icon: "th", secondaryLabel: "84M rows" },
],
},
{
id: "curated",
label: "curated",
childNodes: [
{ id: "curated.orders_daily", label: "orders_daily", icon: "th", secondaryLabel: "3.4M rows" },
{ id: "curated.revenue_by_region", label: "revenue_by_region", icon: "th", secondaryLabel: "12K rows" },
],
},
];
export default function TreeDatasets() {
const [expanded, setExpanded] = useState<TreeNodeInfo["id"][]>(["curated"]);
const [selected, setSelected] = useState<TreeNodeInfo["id"]>("curated.orders_daily");
const withState = (nodes: TreeNodeInfo[]): TreeNodeInfo[] =>
nodes.map((node) => ({
...node,
icon: node.childNodes ? (expanded.includes(node.id) ? "folder-open" : "folder-close") : node.icon,
isExpanded: expanded.includes(node.id),
isSelected: node.id === selected,
childNodes: node.childNodes && withState(node.childNodes),
}));
const toggle = ({ id }: TreeNodeInfo) =>
setExpanded((current) => (current.includes(id) ? current.filter((item) => item !== id) : [...current, id]));
return (
<div style={{ maxWidth: 360, width: "100%" }}>
<Tree
contents={withState(DATASETS)}
onNodeClick={(node) => setSelected(node.id)}
onNodeCollapse={toggle}
onNodeExpand={toggle}
/>
</div>
);
}Props interface#
Every callback receives the node, its path and the mouse event. The path lists indexes from the root: [1, 0] is the first child of the second top-level node.
interface TreeProps extends Props@clawscale/react| Props | Description |
|---|---|
className | stringA space-delimited list of class names to pass along to a child element. Inherited from Props |
compact | booleanWhether to use a compact appearance which reduces the visual padding around node content. |
contentsrequired | ReadonlyArray<TreeNodeInfo<T>>The data specifying the contents and appearance of the tree. |
onNodeClick | TreeEventHandler<T>Invoked when a node is clicked anywhere other than the caret for expanding/collapsing the node. |
onNodeCollapse | TreeEventHandler<T>Invoked when caret of an expanded node is clicked. |
onNodeContextMenu | TreeEventHandler<T>Invoked when a node is right-clicked or the context menu button is pressed on a focused node. |
onNodeDoubleClick | TreeEventHandler<T>Invoked when a node is double-clicked. Be careful when using this in combination with an onNodeClick (single-click) handler, as the way this behaves can vary between browsers. See http://stackoverflow.com/q/5497073/3124288 |
onNodeExpand | TreeEventHandler<T>Invoked when the caret of a collapsed node is clicked. |
onNodeMouseEnter | TreeEventHandler<T>Invoked when the mouse is moved over a node. |
onNodeMouseLeave | TreeEventHandler<T>Invoked when the mouse is moved out of a node. |
interface TreeNodeInfo@clawscale/react| Props | Description |
|---|---|
childNodes | Array<TreeNodeInfo<T>>Child tree nodes of this node. |
className | stringA space-delimited list of class names for this tree node element. |
disabled | booleanWhether this tree node is non-interactive. Enabling this prop will ignore mouse event handlers (in particular click, down, enter, leave). |
hasCaret | booleanWhether the caret to expand/collapse a node should be shown. If not specified, this will be true if the node has children and false otherwise. |
icon | IconName | MaybeElementThe name of a Blueprint icon (or an icon element) to render next to the node's label. |
idrequired | string | numberA unique identifier for the node. |
isExpanded | boolean |
isSelected | boolean = falseWhether this node is selected. |
labelrequired | string | React.JSX.ElementThe main label for the node. |
nodeData | TAn optional custom user object to associate with the node. This property can then be used in the onClick, onContextMenu and onDoubleClick event handlers for doing custom logic per node. |
secondaryLabel | string | MaybeElementA secondary label/component that is displayed at the right side of the node. |