rstree-ui
v0.1.8
Published
A modern React tree component library with virtualization, search, and Tailwind CSS support. Features include multi-select, checkboxes, custom icons, fuzzy search with highlighting, and virtual scrolling for large datasets.
Maintainers
Readme
RsTree
A Morden React tree component library with virtualization, search, and Tailwind CSS support. Demo
Another choice for React tree components.

Features
- Virtual scrolling for large datasets (1000+ nodes)
- Fuzzy search with highlighting and auto-expansion
- Full customization of icons and nodes
- Responsive design for all screen sizes
- TypeScript support with complete type definitions
- Multiple selection modes - single/multi-select, checkboxes, disabled states
- Tailwind CSS integration - works with or without Tailwind
- Tree utilities - connecting lines, click-to-toggle, auto-expand
Installation
npm install rstree-uiPeer Dependencies
npm install react react-domTailwind CSS Support (Optional)
Works with Tailwind CSS v3+ and v4+, or as a standalone component.
Quick Start
Option 1: With Tailwind CSS v4
Add to your CSS file:
@import "tailwindcss";
@source "../node_modules/rstree-ui";Option 2: With Tailwind CSS v3
Add the library path to your tailwind.config.js:
module.exports = {
content: [
"./src/**/*.{js,ts,jsx,tsx}",
"./node_modules/rstree-ui/**/*.{js,ts,jsx,tsx}",
],
// ... other config
}Option 3: Standalone CSS
Import the pre-compiled styles:
import 'rstree-ui/style.css'Basic Usage
import { RsTree } from 'rstree-ui'
const data = [
{
id: '1',
label: 'Documents',
children: [
{ id: '1-1', label: 'Resume.pdf' },
{ id: '1-2', label: 'Cover Letter.docx' }
]
},
{ id: '2', label: 'Pictures' }
]
function App() {
const [selectedIds, setSelectedIds] = useState([])
return (
<RsTree
data={data}
selectedIds={selectedIds}
onSelect={setSelectedIds}
showIcons={true}
/>
)
}API Reference
RsTree Props
Core Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | TreeNode[] | required | Tree data structure |
| selectedIds | string[] | [] | Array of selected node IDs |
| onSelect | (ids: string[]) => void | - | Selection change callback |
| multiSelect | boolean | false | Enable multi-selection |
Expansion Control
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| expandedIds | string[] | [] | Array of expanded node IDs |
| onExpand | (ids: string[]) => void | - | Expansion change callback |
| clickToToggle | boolean | false | Click anywhere on node to toggle |
Checkbox Support
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| checkable | boolean | false | Enable checkboxes |
| checkedIds | string[] | [] | Array of checked node IDs |
| onCheck | (ids: string[]) => void | - | Check state change callback |
Visual Customization
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| showIcons | boolean | true | Show folder/file icons |
| showTreeLines | boolean | false | Show connecting lines |
| disabled | boolean | false | Disable all interactions |
| className | string | '' | Additional CSS classes for container |
| treeLineClassName | string | '' | Custom CSS classes for tree lines |
| treeNodeClassName | string | '' | Custom CSS classes for tree nodes |
Custom Icons
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| expandIcon | React.ReactNode | <ChevronRight /> | Custom expand icon |
| collapseIcon | React.ReactNode | <ChevronDown /> | Custom collapse icon |
| folderIcon | React.ReactNode | <Folder /> | Custom folder icon |
| fileIcon | React.ReactNode | <File /> | Custom file icon |
Search Features
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| searchTerm | string | '' | Search query string |
| autoExpandSearch | boolean | true | Auto-expand search results |
| onSearchMatch | (id: string \| null) => void | - | Best match callback |
Performance & Layout
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| virtualizeEnabled | boolean | true | Enable virtual scrolling |
| height | number | 400 | Fixed height in pixels |
| itemHeight | number | 32 | Height per item |
| autoHeight | boolean | false | Auto-adjust height |
| maxHeight | number | 400 | Maximum height |
| minHeight | number | 100 | Minimum height |
Advanced Customization
| Prop | Type | Description |
|------|------|-------------|
| renderNode | (node: TreeNode, props: TreeNodeRenderProps) => React.ReactNode | Custom node renderer |
| onNodeClick | (node: TreeNode, event: React.MouseEvent) => void | Node click handler |
TreeNode Interface
interface TreeNode {
id: string // Unique identifier
label: string // Display text
children?: TreeNode[] // Child nodes
disabled?: boolean // Disable this node
icon?: React.ComponentType<{ className?: string }> | ReactNode // Custom icon for this node
metadata?: Record<string, unknown> // Additional metadata
data?: any // Additional custom data
}Examples
Multi-Select Tree
<RsTree
data={data}
multiSelect={true}
selectedIds={selectedIds}
onSelect={setSelectedIds}
/>Checkable Tree
<RsTree
data={data}
checkable={true}
checkedIds={checkedIds}
onCheck={setCheckedIds}
/>Search with Auto-Expand
<RsTree
data={data}
searchTerm={searchTerm}
autoExpandSearch={true}
virtualizeEnabled={true}
/>Custom Icons
const MyExpandIcon = <span>▶</span>
const MyCollapseIcon = <span>▼</span>
<RsTree
data={data}
expandIcon={MyExpandIcon}
collapseIcon={MyCollapseIcon}
showIcons={true}
/>Large Dataset with Virtualization
<RsTree
data={largeDataset}
height={500}
virtualizeEnabled={true}
itemHeight={36}
/>Custom Styling
// Custom tree lines and node styling
<RsTree
data={data}
showTreeLines={true}
treeLineClassName="border-blue-300 border-dashed"
treeNodeClassName="rounded-lg shadow-sm hover:shadow-md"
className="border border-gray-200 rounded-md"
/>
// Dark theme styling example
<RsTree
data={data}
showTreeLines={true}
treeLineClassName="border-gray-600"
treeNodeClassName="text-gray-100 hover:bg-gray-800 bg-gray-900"
className="bg-gray-900 border border-gray-700"
/>Custom Node Renderer
The library automatically handles layout structure (indentation, tree lines, expand icons, checkboxes) while allowing you to customize the content area:
// Rich project management tree with custom metadata
const projectData = [
{
id: "project-1",
label: "React Dashboard",
data: {
type: "project",
status: "active",
priority: "high",
lastModified: "2 hours ago"
},
children: [
{
id: "src",
label: "src",
data: { type: "folder", fileCount: 12, size: "298 KB" }
},
{
id: "app.tsx",
label: "App.tsx",
data: { type: "file", language: "typescript", size: "12.5 KB", lines: 340 }
},
]
}
];
const customRenderer = (node, props) => {
const { data } = node;
if (data?.type === "project") {
return (
<div className="flex items-center gap-3 py-1 w-full min-w-0">
<div className="flex items-center gap-2 flex-1 min-w-0">
<span className="font-semibold text-gray-100">{node.label}</span>
<span className={`px-2 py-0.5 text-xs rounded-full ${
data.status === 'active' ? 'bg-green-500/20 text-green-400' : 'bg-blue-500/20 text-blue-400'
}`}>
{data.status}
</span>
<div className="w-2 h-2 rounded-full bg-red-500"></div>
<span className="text-xs text-gray-400">{data.priority}</span>
</div>
<span className="text-xs text-gray-400">📅 {data.lastModified}</span>
</div>
);
}
if (data?.type === "file") {
return (
<div className="flex items-center gap-3 py-1 w-full min-w-0">
<div className="flex items-center gap-2 flex-1 min-w-0">
<span className="w-6 h-6 bg-gray-700 text-gray-300 rounded text-xs flex items-center justify-center font-mono">
{data.language === 'typescript' ? 'TS' : 'JS'}
</span>
<span className="text-gray-200">{node.label}</span>
</div>
<div className="flex items-center gap-3 text-xs text-gray-500">
<span>{data.lines} lines</span>
<span>{data.size}</span>
</div>
</div>
);
}
return <span>{node.label}</span>;
};
<RsTree
data={projectData}
renderNode={customRenderer}
showTreeLines={true}
multiSelect={true}
/>Key Features:
- ✅ Automatic Layout: Indentation, tree lines, and controls are handled automatically
- ✅ Rich Content: Display badges, icons, metadata, and custom styling
- ✅ Responsive Design: Content adapts to available space with proper text truncation
- ✅ Interaction Support: Maintain full tree functionality (select, expand, check)
Note: Your custom content is automatically wrapped in the standard tree layout structure, so you don't need to handle indentation, tree lines, or control elements yourself. Just focus on the node content.
Development
Install Dependencies
npm installDevelopment
npm run dev # Watch mode
npm run build # Build library
npm run test # Run tests
npm run lint # Lint codeBuild
npm run buildTesting
npm run testContributing
Contributions are welcome!
- Fork the repository
- Create your feature branch
- Commit your changes
- Push to the branch
- Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
- ⭐ Star this repository if you find it useful
- 🐛 Report bugs
- 💡 Request features
