- Notifications
You must be signed in to change notification settings - Fork 921
Description
I'm facing a couple of issues while using react-sortable-tree in my Next js project: using "react-sortable-tree": "^2.7.1", version
Search query not working: The search functionality is not returning expected results. When I search for a node, no matching nodes are highlighted or returned.
Expand/Collapse issue after dragging nodes: After dragging nodes from one place to another, the expand/collapse functionality doesn't work on the node level. The nodes remain expanded or collapsed, and I cannot toggle them properly after moving. at node level expand and collapse and buttons as well.
I created a new node configuration and moved to under contact:
please find below my code can any one help to resolve this.
import React, { useEffect, useState } from 'react';
import dynamic from 'next/dynamic';
import { FaPlus, FaChevronDown, FaChevronUp, FaSearch } from 'react-icons/fa';
const SortableTree = dynamic(() => import('react-sortable-tree'), { ssr: false });
import 'react-sortable-tree/style.css';
interface TreeNode {
title: string;
expanded?: boolean;
children?: TreeNode[];
}
const Tree = () => {
const [treeData, setTreeData] = useState<TreeNode[]>([]);
const [newNodeTitle, setNewNodeTitle] = useState('');
const [searchText, setSearchText] = useState('');
const [matchedNodeIds, setMatchedNodeIds] = useState<string[]>([]);
useEffect(() => {
setTreeData([
{
title: 'Profile',
expanded: true,
children: [
{ title: 'Official' },
{ title: 'Contact' },
{ title: 'License/Passport' },
{ title: 'Education' },
{ title: 'Family' },
],
},
{
title: 'Time Tracking',
expanded: false,
children: [{ title: 'Timesheet Entry' }],
},
]);
}, []);
/*** Expand All Nodes ***/
const expandAll = () => {
const updatedTree = treeData.map((node) => ({
...node,
expanded: true,
children: node.children ? node.children.map((child) => ({ ...child, expanded: true })) : [],
}));
setTreeData(updatedTree);
};
/*** Collapse All Nodes ***/
const collapseAll = () => {
const updatedTree = treeData.map((node) => ({
...node,
expanded: false,
children: node.children ? node.children.map((child) => ({ ...child, expanded: false })) : [],
}));
setTreeData(updatedTree);
};
/*** Add a new node to the main tree ***/
const addNode = () => {
if (newNodeTitle.trim() === '') return;
setTreeData([...treeData, { title: newNodeTitle, expanded: false }]);
setNewNodeTitle('');
};
/*** Search Node in the Tree ***/
const handleSearch = (e: React.ChangeEvent) => {
const query = e.target.value;
setSearchText(query);
};
return (
<div style={{ height: 1000, padding: '10px', fontFamily: 'Arial, sans-serif' }}>
{/* Top Controls /}
<div style={{ display: 'flex', alignItems: 'center', gap: '10px', marginBottom: '10px' }}>
{/ Create Node Input */}
<input
type="text"
value={newNodeTitle}
onChange={(e) => setNewNodeTitle(e.target.value)}
placeholder="Enter node title"
style={{ padding: '5px', width: '180px', borderRadius: '5px', border: '1px solid #ccc' }}
/>
<button
onClick={addNode}
style={{
padding: '5px 10px',
cursor: 'pointer',
borderRadius: '50%',
background: '#4CAF50',
color: 'white',
border: 'none',
}}
title="Add Node"
>
{/* Search Box */} <input type="text" value={searchText} onChange={handleSearch} placeholder="Search node..." style={{ padding: '5px', width: '180px', borderRadius: '5px', border: '1px solid #ccc' }} /> <FaSearch style={{ color: '#666' }} /> {/* Expand and Collapse Buttons */} <div style={{ display: 'flex', alignItems: 'center', gap: '10px', marginBottom: '10px' }}> <button onClick={expandAll} style={{ marginRight: '10px', padding: '10px 20px', backgroundColor: '#FFFFFF', color: 'black', border: '1 px solid black', borderRadius: '5px', display: 'flex', alignItems: 'center', justifyContent: 'center', }} > <span style={{ fontSize: '18px', marginRight: '8px' }}>+</span> <span>Expand All Nodes</span> </button> <button onClick={collapseAll} style={{ marginRight: '10px', padding: '10px 20px', backgroundColor: '#FFFFFF', color: 'black', border: '1 px solid black', borderRadius: '5px', display: 'flex', alignItems: 'center', justifyContent: 'center', }} > <span style={{ fontSize: '18px', marginRight: '8px' }}>-</span> <span>Collapse All Nodes</span> </button> </div> </div> {/* Tree View */} <div style={{ height: 400 }}> <SortableTree treeData={treeData} isVirtualized={true} searchQuery={searchText} onChange={(newTreeData: TreeNode[]) => { setTreeData(newTreeData); console.log('Updated Tree Data:', newTreeData); }} canNodeHaveChildren={() => true} generateNodeProps={({ node, path }) => ({ title: ( <span style={{ fontWeight: matchedNodeIds.includes(path.join('-')) ? 'bold' : 'normal', backgroundColor: matchedNodeIds.includes(path.join('-')) ? '#ffff99' : 'transparent', padding: '2px 5px', borderRadius: '4px', }} > {node.title} </span> ), onClick: () => { node.expanded = !node.expanded; setTreeData([...treeData]); }, })} /> </div> </div>
);
};
export default Tree;