Primitives
Tree view
Sites → levels → bays. Select one, or check many with tri-state parents. Full keyboard support.
selectable · ↑ ↓ → ← Home End Enter
- Gulshan ParkingOpen
- Level 1
- Bay A · 40 cars
- Bay B · 32 cars
- Level 2
- Bay A · 48 cars
- Gates
- Gate 1 (in)
- Gate 2 (out)
- Banani Tower
- Basement 1
- Basement 2Closed
- Dhanmondi Lot
Selected: g-l1-a
checkable · parents tick when all children do
- Gulshan ParkingOpen
- Level 1
- Bay A · 40 cars
- Bay B · 32 cars
- Level 2
- Bay A · 48 cars
- Gates
- Gate 1 (in)
- Gate 2 (out)
- Banani Tower
- Basement 1
- Basement 2Closed
- Dhanmondi Lot
2 bays chosen
tree-view.tsx
"use client";
import { Badge, TreeView, type TreeNode } from "@waveinno/ui";
import { Building2, Car, DoorOpen, Layers, MapPin, ParkingSquare } from "lucide-react";
import * as React from "react";
const SITES: TreeNode[] = [
{
id: "gulshan",
label: "Gulshan Parking",
icon: <Building2 />,
badge: <Badge tone="success">Open</Badge>,
children: [
{
id: "g-l1",
label: "Level 1",
icon: <Layers />,
children: [
{ id: "g-l1-a", label: "Bay A · 40 cars", icon: <Car /> },
{ id: "g-l1-b", label: "Bay B · 32 cars", icon: <Car /> },
],
},
{ id: "g-l2", label: "Level 2", icon: <Layers />, children: [{ id: "g-l2-a", label: "Bay A · 48 cars", icon: <Car /> }] },
{ id: "g-gate", label: "Gates", icon: <DoorOpen />, children: [{ id: "g-gate-1", label: "Gate 1 (in)", icon: <DoorOpen /> }, { id: "g-gate-2", label: "Gate 2 (out)", icon: <DoorOpen /> }] },
],
},
{
id: "banani",
label: "Banani Tower",
icon: <Building2 />,
children: [
{ id: "b-b1", label: "Basement 1", icon: <ParkingSquare /> },
{ id: "b-b2", label: "Basement 2", icon: <ParkingSquare />, disabled: true, badge: <span className="text-[11px] text-muted">Closed</span> },
],
},
{ id: "dhanmondi", label: "Dhanmondi Lot", icon: <MapPin /> },
];
export default function TreeDemo() {
const [picked, setPicked] = React.useState<string>("g-l1-a");
const [checked, setChecked] = React.useState<string[]>(["g-l1-a", "g-l2-a"]);
return (
<div className="grid gap-8 md:grid-cols-2">
<div className="space-y-2">
<p className="text-[12px] text-muted">selectable · ↑ ↓ → ← Home End Enter</p>
<TreeView data={SITES} defaultExpanded={["gulshan", "g-l1"]} selected={picked} onSelectedChange={setPicked} aria-label="Sites" className="rounded-card border border-border bg-raised p-1.5" />
<p className="text-[12px] text-muted">Selected: {picked}</p>
</div>
<div className="space-y-2">
<p className="text-[12px] text-muted">checkable · parents tick when all children do</p>
<TreeView data={SITES} checkable defaultExpanded={["gulshan", "g-l1", "g-l2"]} checked={checked} onCheckedChange={setChecked} aria-label="Bays to report on" className="rounded-card border border-border bg-raised p-1.5" />
<p className="text-[12px] text-muted">{checked.length} bays chosen</p>
</div>
</div>
);
}Import#
Everything comes from the package root. The example above uses:
your-component.tsx
import { Badge, TreeView, type TreeNode } from "@waveinno/ui";Props#
Read from the source of this version, so they match the code exactly.
<TreeView>
src/components/ui/tree-view.tsx| Prop | Type | Default | Description |
|---|---|---|---|
datarequired | TreeNode[] | — | |
expanded | string[] | — | |
defaultExpanded | string[] | [] | |
onExpandedChange | (ids: string[]) => void | — | |
selected | string | null | — | |
defaultSelected | string | null | null | |
onSelectedChange | (id: string) => void | — | |
checkable | boolean | — | Checkboxes with tri-state parents. The value holds leaf ids. |
checked | string[] | — | |
defaultChecked | string[] | [] | |
onCheckedChange | (leafIds: string[]) => void | — | |
guides | boolean | true | Lines from each branch to its children. |
aria-label | string | "Tree" | |
className | string | — |
<Badge>
src/components/ui/badge.tsx| Prop | Type | Default | Description |
|---|---|---|---|
dot | boolean | true | |
variant | "soft" | "solid" | "outline" | "dot" | "gradient" | "live" | "soft" |
Also takes HTMLAttributes<HTMLSpanElement> & VariantProps<typeof badgeVariants>.
Install#
If the project does not have the package yet, add it, then follow the setup for Next.js or Vite once.
$ npm install @waveinno/ui