# Core/Tree - Usage

A hierarchical tree with cascading multi-select and Capra ListItem row layout.

## Basic usage

```tsx
import { Tree, type TreeItemType } from '@capra/core';

const items: TreeItemType[] = [
  {
    key: 'logs',
    label: 'Logs',
    children: [
      { key: 'auth', label: 'Auth' },
      { key: 'system', label: 'System' },
    ],
  },
];

function Example() {
  return <Tree items={items} aria-label="Log sources" defaultExpandedKeys={['logs']} />;
}
```

## Props

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `className` | `never` | No | `--` | Use `FORCE__className` instead. |
| `style` | `never` | No | `--` | Inline styles are not supported; use component props or `FORCE__className`. |
| `FORCE__className` | `string` | No | `--` | 🚨 This prop is meant to be an escape hatch. 🚨<br><br>If the desired style cannot be achieved using component props, use this as a last resort. The inner workings of Capra components are implementation details and this escape hatch gives one access to those implementation details. We cannot make any guarantees that styles will applied correctly across version updates. Please use it responsibly.<br><br>Add a CSS class to the component. |
| `aria-label` | `string` | No | `--` | Defines a string value that labels the current element. |
| `aria-labelledby` | `string` | No | `--` | Identifies the element (or elements) that labels the current element. |
| `items` | `TreeItemType[]` | Yes | `--` | Items to render in the tree. |
| `onAction` | `(key: Key) => void` | No | `--` | Handler that is called when a user performs an action on an item. |
| `defaultExpandedKeys` | `Iterable<Key>` | No | `--` | The initial expanded keys when in uncontrolled mode. |
| `defaultSelectedKeys` | `Iterable<Key>` | No | `--` | The initial selected keys when in uncontrolled mode. |
| `expandedKeys` | `Iterable<Key>` | No | `--` | The currently expanded keys when in controlled mode. |
| `onExpandedChange` | `(keys: Set<Key>) => void` | No | `--` | Handler that is called when the expanded keys change. |
| `onSelectionChange` | `(keys: Set<Key>) => void` | No | `--` | Callback that is fired when the selection changes. |
| `selectedKeys` | `Iterable<Key>` | No | `--` | The currently selected keys when in controlled mode. |
| `selectionMode` | `'none' \| 'multiple'` | No | 'multiple' | The selection mode of the tree.<br>@default 'multiple' |

## Selection patterns

### Uncontrolled selection

Use `defaultSelectedKeys` for simple uncontrolled multi-select. Selecting a parent cascades to all enabled
descendants, and deselecting the parent removes the whole enabled branch.

```tsx
<Tree items={filesystemItems} aria-label="Remote filesystem" defaultSelectedKeys={['logs']} />
```

### Controlled selection

Use `selectedKeys` with `onSelectionChange` when the selected branch needs to stay in application state. The callback
receives the normalized key set after cascade rules are applied.

```tsx
const [selectedKeys, setSelectedKeys] = useState<Set<string>>(new Set(['logs']));

<Tree
  items={filesystemItems}
  aria-label="Remote filesystem"
  selectedKeys={selectedKeys}
  onSelectionChange={setSelectedKeys}
/>;
```

### Disabled items

Set `isDisabled` on an item to disable just that row. Disabled items are skipped during cascade selection and cannot
be toggled directly.

```tsx
const items = [
  {
    key: 'notebooks',
    label: 'Notebooks',
    isDisabled: true,
  },
];
```

## Content options

### Suffix and trailing slot

Use `suffix` for short secondary metadata and `trailingSlot` for decorative affordances.

## Accessibility

| Key                          | Function                                                                                                                                                                                                                                                              |
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Tab`<br />`Shift+Tab`       | Moves focus into the tree.<br />- Focus is given to the last Tree \| Item to have focus.<br />- If no selection and no previous item had focus, focus is given to first item.<br />- If select and no previous item had focus, focus is given to first selected item. |
| `Right Arrow`                | - When on a closed parent item, open the node; focus does not move.<br />- When on an open item, or item with no children, does nothing.                                                                                                                              |
| `Left Arrow`                 | - When on an open parent item, closes the item; focus does not move.<br />- When on a closed item, or item with no children, does nothing.                                                                                                                            |
| `Up Arrow`<br />`Down Arrow` | Moves focus to the next/previous visible item, without opening or closing a node.                                                                                                                                                                                     |
| `Enter`                      | Triggers the default action.<br />- If selection is available, selects the currently focused item.<br />- If no selection is available, open/close the currently focused item.                                                                                        |
| `Space`                      | Selects the currently focused item.                                                                                                                                                                                                                                   |