Icons
TreeKit doesn't bundle an icon set or force one on you — pass any React node: an SVG, an emoji, or a component from your own icon library.
Engineering
Frontend
React
Vue
Svelte
Backend
Platform
Design
Marketing
Show code
<TreeKit data={data} icons={{ leafIcon: "🧩" }} />| Prop | Type | Default | Description |
|---|---|---|---|
| icons.expandIcon | ReactNode | chevron ▶ | Replaces the chevron shown for an expanded node. |
| icons.collapseIcon | ReactNode | chevron ▼ | Replaces the chevron shown for a collapsed node. |
| icons.leafIcon | ReactNode | (node) => ReactNode | — | Icon for nodes without children. Can be static or computed per node. |
| icons.loadingIcon | ReactNode | spinner | Shown in the chevron slot while onLoadChildren is pending. |
| icons.checkedIcon / uncheckedIcon / indeterminateIcon | ReactNode | — | Reserved for custom checkbox renderers built on the exported Checkbox primitive. |
Per-node icons
For icons that vary node-by-node in a way icons.leafIcon can't express (e.g. an open vs. closed folder), set icon directly on the node when you build your data — it always takes priority over the icons prop:
src
components
Input.tsx
Modal.tsx
hooks
index.ts
public
package.json
README.md
Show code
const data = fileTree.map((node) => ({
...node,
icon: node.children ? <FolderIcon /> : <FileIcon />,
}));
<TreeKit data={data} variant="connected" />Because node.icon is a plain ReactNode rather than a component reference, it composes naturally with any icon library — lucide-react, @radix-ui/react-icons, a custom SVG sprite — without TreeKit needing to know it exists.
import { Folder, File } from "lucide-react";
const data = fileTree.map((node) => ({
...node,
icon: node.children ? <Folder size={15} /> : <File size={15} />,
}));