# @darksnow-ui/node-tree-react

VSCode-styled React component for tree views, built on [@darksnow-ui/node-tree-headless](https://www.npmjs.com/package/@darksnow-ui/node-tree-headless).

## Features

- 🎯 **Ready to use** - Drop-in tree component with VSCode styling
- 🎨 **VSCode themed** - Dark theme matching Visual Studio Code
- ⌨️ **Full keyboard navigation** - Arrow keys, Home/End, expand/collapse
- 🖱️ **Drag & drop** - Built-in node reordering
- 📋 **Context menu** - Right-click actions included
- ♿ **Accessible** - ARIA labels and keyboard support
- 🎭 **Customizable** - Override any part of the UI

## Installation

```bash
npm install @darksnow-ui/node-tree-react @darksnow-ui/node-tree-headless
# or
yarn add @darksnow-ui/node-tree-react @darksnow-ui/node-tree-headless
# or
pnpm add @darksnow-ui/node-tree-react @darksnow-ui/node-tree-headless
```

## Quick Start

### 1. Import the component and styles

```tsx
import { NodeTree } from '@darksnow-ui/node-tree-react'
import { NodeTreeProvider } from '@darksnow-ui/node-tree-headless'
import '@darksnow-ui/node-tree-react/styles.css' // Important! Import the CSS
```

### 2. Create your node service

```tsx
const nodeClientService = () => ({
  async fetchNodes() {
    return {
      nodes: [
        { id: '1', label: 'src', expandable: true },
        { id: '2', parentId: '1', label: 'components', expandable: true },
        { id: '3', parentId: '2', label: 'Button.tsx' },
        { id: '4', parentId: '2', label: 'Input.tsx' },
        { id: '5', parentId: '1', label: 'index.ts' },
      ]
    }
  },
  // Optional methods for CRUD operations
  async createNode(fileName: string) {
    // Your create logic
  },
  async deleteNodes(nodeIds: string[]) {
    // Your delete logic
  },
  async moveNodes(nodeIds: string[], targetId: string) {
    // Your move logic
  },
  async renameNode(nodeId: string, newName: string) {
    // Your rename logic
  }
})
```

### 3. Use the component

```tsx
function App() {
  return (
    <NodeTreeProvider nodeClientService={nodeClientService}>
      <div style={{ height: '400px', width: '300px' }}>
        <NodeTree />
      </div>
    </NodeTreeProvider>
  )
}
```

## Styling

The component comes with VSCode-like dark theme by default. The CSS file includes:

- VSCode color scheme
- Hover and selection states
- Focus indicators
- Smooth transitions
- Custom scrollbars
- Context menu styles

### Import CSS

Always import the CSS file to get the default styles:

```tsx
import '@darksnow-ui/node-tree-react/styles.css'
```

### Customize with CSS Variables

You can override the default theme using CSS variables:

```css
.node-tree-container {
  /* Background and borders */
  --node-tree-bg: #1e1e1e;
  --node-tree-border: #464647;
  
  /* Text colors */
  --node-tree-text: #cccccc;
  --node-tree-selected-text: white;
  
  /* Selection colors */
  --node-tree-selected-bg: #094771;
  --node-tree-hover-bg: rgba(255, 255, 255, 0.04);
  
  /* Focus colors */
  --node-tree-focus-color: #007acc;
  
  /* Sizes */
  --node-tree-item-height: 22px;
  --node-tree-font-size: 13px;
}
```

## Basic Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `className` | `string` | - | Additional CSS class for the container |
| `style` | `React.CSSProperties` | - | Inline styles for the container |
| `showContextMenu` | `boolean` | `true` | Enable/disable context menu |
| `indentSize` | `number` | `20` | Indentation width in pixels |
| `onContextMenuAction` | `(action, nodeId) => void` | - | Handle context menu actions |

## Keyboard Shortcuts

- **↑/↓** - Navigate between nodes
- **←** - Collapse node or move to parent
- **→** - Expand node or move to first child
- **Space** - Toggle selection
- **Enter** - Expand/collapse
- **Home/End** - Go to first/last node
- **Delete** - Delete selected nodes
- **F2** - Rename node
- **Menu/Right-click** - Open context menu

## Learn More

For advanced usage, hooks, and services, check the headless library documentation:

### 📚 [@darksnow-ui/node-tree-headless Documentation](https://github.com/andersondrosa/node-tree-headless/tree/main/packages/node-tree-headless)

The headless library provides:

- **Hooks**: `useNodeTree`, `useNodeTreeState`, `useContextMenu`
- **Services**: `NodeService`, `NavigationService`, `DOMQueryService`
- **Events**: Complete event system for custom integrations
- **Plugins**: Extend functionality with the plugin system
- **Controller**: Imperative API for advanced control

## Examples

### Custom Node Rendering

```tsx
<NodeTree
  renderNode={({ row }) => (
    <div className="custom-node">
      <img src={`/icons/${row.node.type}.svg`} />
      <span>{row.node.label}</span>
      {row.node.isModified && <span className="dot">•</span>}
    </div>
  )}
/>
```

### Handle Context Menu Actions

```tsx
<NodeTree
  onContextMenuAction={(action, nodeId) => {
    switch (action) {
      case 'create-folder':
        console.log('Creating folder in', nodeId)
        break
      case 'delete':
        console.log('Deleting', nodeId)
        break
      case 'rename':
        console.log('Renaming', nodeId)
        break
    }
  }}
/>
```

### Custom Empty State

```tsx
<NodeTree
  renderEmptyState={() => (
    <div className="empty-state">
      <p>No files yet</p>
      <button onClick={createFirstFile}>Create your first file</button>
    </div>
  )}
/>
```

## Support

- **Issues**: [GitHub Issues](https://github.com/andersondrosa/node-tree-headless/issues)
- **Headless Docs**: [node-tree-headless](https://github.com/andersondrosa/node-tree-headless/tree/main/packages/node-tree-headless)

## License

MIT