@alpernative/tree is a high-performance, customizable tree component for React. It provides a wide range of features, including virtualization, drag-and-drop, and nested drag-and-drop support.
- High Performance:
@alpernative/treeis designed to handle large datasets with ease, providing smooth and responsive user experiences. - Customizable:
@alpernative/treeoffers a wide range of customization options, allowing you to tailor the appearance and behavior of the tree to your specific needs. - Virtualization:
@alpernative/treesupports virtualization, enabling you to render only the visible portion of the tree, which can significantly improve performance when working with large datasets. - Drag and Drop:
@alpernative/treeprovides built-in support for drag-and-drop operations, making it easy to rearrange tree nodes. - Nested Drag and Drop:
@alpernative/treesupports nested drag-and-drop operations, allowing you to move nodes within and between different levels of the tree.
npm install @alpernative/treeor using yarn:
yarn add @alpernative/treeWe need to create TreeItem.tsx file to render the tree items
import { FC, useState } from 'react';
import { RenderItemParams, TreeItem as TreeItemType } from '@alpernative/tree';
import { AiOutlineFile, AiOutlineFolder, AiOutlineFolderOpen } from 'react-icons/ai';
import { FaChevronRight, FaChevronDown } from 'react-icons/fa';
export const TreeItem: FC<RenderItemParams> = ({ item, provided, onCollapse, onExpand }) => {
const [isSelected, setIsSelected] = useState(false);
const renderItemIcon = () => {
// You can customize the your icons based on the item's properties
if (!item.hasChildren) return <AiOutlineFile />;
if (item.isExpanded) return <AiOutlineFolderOpen />;
return <AiOutlineFolder />;
};
const handleOnClick = (item: TreeItemType) => {
setIsSelected(value => !value);
if (item.isExpanded) onCollapse(item.id);
if (!item.isExpanded) onExpand(item.id);
};
return (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
onClick={() => handleOnClick(item)}
>
<div style={{ color: isSelected ? 'red' : 'gray' }}>
{item.hasChildren && (item.isExpanded ? <FaChevronDown /> : <FaChevronRight />)}
{renderItemIcon()}
{item.data.title}
</div>
</div>
);
};Then we can use the Tree component in our App.tsx file
import { FC, useState } from 'react';
import Tree from '@alpernative/tree';
import { TreeItem } from './TreeItem';
export const basicTreeData = {
rootId: 'root',
items: {
root: {
id: 'root',
data: { title: 'Root' },
children: ['item-0'],
hasChildren: true,
isExpanded: true,
isChildrenLoading: false,
},
'item-0': {
id: 'item-0',
data: {
title: 'Item 0',
},
children: ['item-1', 'item-2', 'item-3', 'item-4'],
hasChildren: true,
isExpanded: true,
isChildrenLoading: false,
},
'item-1': {
id: 'item-1',
data: {
title: 'Item 1',
},
children: [],
hasChildren: false,
isExpanded: true,
isChildrenLoading: false,
},
'item-2': {
id: 'item-2',
data: {
title: 'Item 2',
},
children: [],
hasChildren: false,
isExpanded: true,
isChildrenLoading: false,
},
'item-3': {
id: 'item-3',
data: {
title: 'Item 3',
},
children: [],
hasChildren: false,
isExpanded: true,
isChildrenLoading: false,
},
'item-4': {
id: 'item-4',
data: {
title: 'Item 4',
},
children: [],
hasChildren: false,
isExpanded: true,
isChildrenLoading: false,
},
},
};
export const App: FC = () => {
const [treeData, setTreeData] = useState<TreeData>(basicTreeData);
const onExpand = (ItemId: ItemId) => {
setTreeData(mutateTree(treeData, ItemId, { isExpanded: true }));
};
const onCollapse = (ItemId: ItemId) => {
setTreeData(mutateTree(treeData, ItemId, { isExpanded: false }));
};
const onDragEnd = (source: TreeSourcePosition, destination?: TreeDestinationPosition) => {
if (!destination) return;
const newTree = moveItemOnTree(treeData, source, destination);
setTreeData(newTree);
};
return (
<div style={{ width: 200, height: 300 }}>
<Tree
tree={treeData}
offsetPerLevel={19}
renderItem={props => <TreeItem {...props} />}
onExpand={onExpand}
onCollapse={onCollapse}
onDragEnd={onDragEnd}
isNestingEnabled
isDragEnabled
virtualItemHeight={24}
isVirtualizationEnabled
/>
</div>
);
};Looking for more examples? Check out the Storybook for a wide range of use cases and customization options.
Do you want more? Check out the CodeSandbox for a wide range of use cases and customization options.
For full documentation, visit Link to Documentation.
Contributions are always welcome! Please read the contribution guidelines first.
This project is licensed under the MIT License - see the LICENSE.md file for details.