# Tree View

> Hierarchies, in-place editing and object menus: TreeView, InlineEdit, ContextMenu.

Component · Foundations · Pro kit · [Live page](https://ui.twentyfirst.media/pro/components/TreeView/)

Hierarchies, in-place editing and object menus: `TreeView`, `InlineEdit`, `ContextMenu`.

TreeView: `items` ({id, label, icon, meta, children}), `defaultOpen` (ids), `selected` + `onSelect`, `label`. Arrow keys open, close and move; meta sits right in mono.
InlineEdit: `value`, `onSave(v)`, `options` (select instead of text), `mono`, `type`, `display(v)`, `align`. Double-click or Enter edits, Enter saves, Esc cancels.
ContextMenu: `items` (Menu items), children (the target). Right-click or a long press opens it at the pointer; destructive actions last.

## Example

```tsx
import * as React from "react";
import { ContextMenu, InlineEdit, KeyValue, TreeView } from "@twentyfirstmedia/pro";

const tree = [
  {
    id: "fx",
    label: "FollowerX GmbH",
    meta: "€48,210",
    children: [
      {
        id: "fp",
        label: "Northwind",
        meta: "€31,400",
        children: [
          {
            id: "ads",
            label: "Ads",
            meta: "€9,800",
          },
          {
            id: "smm",
            label: "SMM providers",
            meta: "€14,100",
          },
        ],
      },
      {
        id: "ch",
        label: "Chatteo",
        meta: "€12,610",
      },
    ],
  },
  {
    id: "tv",
    label: "Trepte Ventures UG",
    meta: "€4,200",
  },
];
function App() {
  const s = React.useState("ads");
  return (
    <div
      className="tf-grid"
      style={
        {
          "--cols": "1fr 1fr",
          gap: 16,
        } as React.CSSProperties
      }
    >
      <div
        className="tf-panel"
        style={{
          padding: 12,
        }}
      >
        <TreeView
          items={tree}
          defaultOpen={["fx", "fp"]}
          selected={s[0]}
          onSelect={s[1]}
          label="Cost centres"
        />
      </div>
      <div
        className="tf-panel"
        style={{
          gap: 16,
        }}
      >
        <span className="tf-card-desc">Double-click or Enter to edit</span>
        <KeyValue
          items={[
            [
              "Category",
              <InlineEdit value="Software" options={["Software", "Hosting", "Marketing"]} />,
            ],
            ["Amount", <InlineEdit value="1,240.00" mono />],
          ]}
        />
        <ContextMenu
          items={[
            {
              label: "Open",
              icon: "eye",
            },
            {
              label: "Rename",
              icon: "edit",
              shortcut: "R",
            },
            "-",
            {
              label: "Delete",
              icon: "trash",
              danger: true,
            },
          ]}
        >
          <div
            style={{
              padding: 24,
              borderRadius: "var(--radius-md)",
              background: "var(--canvas)",
              textAlign: "center",
            }}
          >
            Right-click or long-press here
          </div>
        </ContextMenu>
      </div>
    </div>
  );
}
export default App;
```

## Props

### ContextMenu

| Prop | Type | Notes |
| --- | --- | --- |
| `items` | `(MenuItem \| "-")[]` | Required |
| `children` | `ReactNode` | Required |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |

### InlineEdit

| Prop | Type | Notes |
| --- | --- | --- |
| `value` | `string` | Required |
| `onSave?` | `(v: string) => void` |  |
| `options?` | `string[]` |  |
| `mono?` | `boolean` |  |
| `type?` | `string` |  |
| `display?` | `(v: string) => ReactNode` |  |
| `align?` | `"left" \| "right"` |  |
| `label?` | `string` |  |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |

### KeyValue

| Prop | Type | Notes |
| --- | --- | --- |
| `items` | `KeyValueItem[]` | Required |
| `dense?` | `boolean` |  |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |

### TreeView

| Prop | Type | Notes |
| --- | --- | --- |
| `items` | `TreeItem[]` | Required |
| `defaultOpen?` | `string[]` |  |
| `selected?` | `string` |  |
| `onSelect?` | `(id: string) => void` |  |
| `label?` | `string` |  |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |
