- Notifications
You must be signed in to change notification settings - Fork0
A Morden React Tree component library with virtualization, search, and Tailwind CSS support.
License
fireangle/rstree
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
A Morden React tree component library with virtualization, search, and Tailwind CSS support.Demo
Another choice for React tree components.
- 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
npm install rstree-ui
npm install react react-dom
Works with Tailwind CSS v3+ and v4+, or as a standalone component.
Add to your CSS file:
@import"tailwindcss";@source"../node_modules/rstree-ui";
Add the library path to yourtailwind.config.js:
module.exports={content:["./src/**/*.{js,ts,jsx,tsx}","./node_modules/rstree-ui/**/*.{js,ts,jsx,tsx}",],// ... other config}
Import the pre-compiled styles:
import'rstree-ui/style.css'
import{RsTree}from'rstree-ui'constdata=[{id:'1',label:'Documents',children:[{id:'1-1',label:'Resume.pdf'},{id:'1-2',label:'Cover Letter.docx'}]},{id:'2',label:'Pictures'}]functionApp(){const[selectedIds,setSelectedIds]=useState([])return(<RsTreedata={data}selectedIds={selectedIds}onSelect={setSelectedIds}showIcons={true}/>)}
| 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 |
| 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 |
| Prop | Type | Default | Description |
|---|---|---|---|
checkable | boolean | false | Enable checkboxes |
checkedIds | string[] | [] | Array of checked node IDs |
onCheck | (ids: string[]) => void | - | Check state change callback |
| 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 |
| 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 |
| Prop | Type | Default | Description |
|---|---|---|---|
searchTerm | string | '' | Search query string |
autoExpandSearch | boolean | true | Auto-expand search results |
onSearchMatch | (id: string | null) => void | - | Best match callback |
| 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 |
| Prop | Type | Description |
|---|---|---|
renderNode | (node: TreeNode, props: TreeNodeRenderProps) => React.ReactNode | Custom node renderer |
onNodeClick | (node: TreeNode, event: React.MouseEvent) => void | Node click handler |
interfaceTreeNode{id:string// Unique identifierlabel:string// Display textchildren?:TreeNode[]// Child nodesdisabled?:boolean// Disable this nodeicon?:React.ComponentType<{className?:string}>|ReactNode// Custom icon for this nodemetadata?:Record<string,unknown>// Additional metadatadata?:any// Additional custom data}
<RsTreedata={data}multiSelect={true}selectedIds={selectedIds}onSelect={setSelectedIds}/>
<RsTreedata={data}checkable={true}checkedIds={checkedIds}onCheck={setCheckedIds}/>
<RsTreedata={data}searchTerm={searchTerm}autoExpandSearch={true}virtualizeEnabled={true}/>
constMyExpandIcon=<span>▶</span>constMyCollapseIcon=<span>▼</span><RsTreedata={data}expandIcon={MyExpandIcon}collapseIcon={MyCollapseIcon}showIcons={true}/>
<RsTreedata={largeDataset}height={500}virtualizeEnabled={true}itemHeight={36}/>
// Custom tree lines and node styling<RsTreedata={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<RsTreedata={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"/>
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 metadataconstprojectData=[{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}},]}];constcustomRenderer=(node,props)=>{const{ data}=node;if(data?.type==="project"){return(<divclassName="flex items-center gap-3 py-1 w-full min-w-0"><divclassName="flex items-center gap-2 flex-1 min-w-0"><spanclassName="font-semibold text-gray-100">{node.label}</span><spanclassName={`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><divclassName="w-2 h-2 rounded-full bg-red-500"></div><spanclassName="text-xs text-gray-400">{data.priority}</span></div><spanclassName="text-xs text-gray-400">📅{data.lastModified}</span></div>);}if(data?.type==="file"){return(<divclassName="flex items-center gap-3 py-1 w-full min-w-0"><divclassName="flex items-center gap-2 flex-1 min-w-0"><spanclassName="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><spanclassName="text-gray-200">{node.label}</span></div><divclassName="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>;};<RsTreedata={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.
npm install
npm run dev# Watch modenpm run build# Build librarynpm runtest# Run testsnpm run lint# Lint code
npm run build
npm runtestContributions are welcome!
- Fork the repository
- Create your feature branch
- Commit your changes
- Push to the branch
- Open a Pull Request
This project is licensed under the MIT License - see theLICENSE file for details.
- ⭐ Star this repository if you find it useful
- 🐛Report bugs
- 💡Request features
About
A Morden React Tree component library with virtualization, search, and Tailwind CSS support.
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.