@darksnow-ui/node-tree-react
Version:
Ready-to-use React component for node-tree-headless
219 lines (173 loc) • 5.98 kB
Markdown
# @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