@innobrix/react-virtualized-tree
v0.1.1
Published
A performant tree view React component built on top of [react-virtualized](https://bvaughn.github.io/react-virtualized/#/components/List).
Readme
@innobrix/react-virtualized-tree
A performant tree view React component built on top of react-virtualized.
Features
- TypeScript support with full type definitions
- Virtualized rendering for large trees
- Customizable node renderers (Expandable, Deletable, Favorite)
- Built-in filtering with group support
- Tree state management utilities
- React 18 and 19 compatible
Installation
npm install @innobrix/react-virtualized-treeor
yarn add @innobrix/react-virtualized-treePeer Dependencies
This library requires the following peer dependencies:
npm install react react-dom react-virtualizedStyles
Import the required styles:
import 'react-virtualized/styles.css';For the default icon renderers, also import Material Icons:
import 'material-icons/css/material-icons.css';Usage
Basic Tree
import { Tree, TreeState, TreeStateModifiers } from '@innobrix/react-virtualized-tree';
import type { Node, RendererProps } from '@innobrix/react-virtualized-tree';
const nodes: Node[] = [
{
id: 1,
name: 'Parent',
state: { expanded: true },
children: [
{ id: 2, name: 'Child 1' },
{ id: 3, name: 'Child 2' },
],
},
];
function MyTree() {
const [treeNodes, setTreeNodes] = useState(nodes);
return (
<Tree nodes={treeNodes} onChange={setTreeNodes}>
{({ node, ...rest }: RendererProps) => (
<div>{node.name}</div>
)}
</Tree>
);
}With Filtering
import { Tree, FilteringContainer } from '@innobrix/react-virtualized-tree';
function FilterableTree() {
const [nodes, setNodes] = useState(initialNodes);
return (
<FilteringContainer nodes={nodes}>
{({ nodes: filteredNodes }) => (
<Tree nodes={filteredNodes} onChange={setNodes}>
{({ node }) => <div>{node.name}</div>}
</Tree>
)}
</FilteringContainer>
);
}Built-in Renderers
The library provides several built-in renderers:
import { renderers } from '@innobrix/react-virtualized-tree';
const { Expandable, Deletable, Favorite } = renderers;API
Exports
import {
Tree, // Main tree component
FilteringContainer, // Container for filtering functionality
TreeState, // Tree state management
TreeStateModifiers, // State modification utilities
selectors, // Node selection utilities
renderers, // Built-in renderers (Expandable, Deletable, Favorite)
constants, // Constants (UPDATE_TYPE, etc.)
debounce, // Debounce utility
} from '@innobrix/react-virtualized-tree';Types
import type {
Node,
NodeId,
NodeState,
FlattenedNode,
NodeAction,
RendererProps,
TreeProps,
TreeContainerProps,
FilteringContainerProps,
Extensions,
UpdateType,
} from '@innobrix/react-virtualized-tree';Tree Props
| Prop | Type | Description |
|------|------|-------------|
| nodes | Node[] | Array of tree nodes |
| onChange | (nodes: Node[]) => void | Callback when nodes change |
| children | ComponentType<RendererProps> | Node renderer component |
| nodeMarginLeft | number | Left margin for nested nodes (default: 25) |
| width | number | Tree width |
| scrollToId | NodeId | ID of node to scroll to |
| scrollToAlignment | string | Scroll alignment |
| onScrollComplete | () => void | Callback when scroll completes |
| extensions | Extensions | Custom update type handlers |
Node Structure
interface Node {
id: NodeId; // Unique identifier (number or string)
name: string; // Display name
state?: NodeState; // Node state (expanded, deletable, favorite, etc.)
children?: Node[]; // Child nodes
}
interface NodeState {
expanded?: boolean;
deletable?: boolean;
favorite?: boolean;
[key: string]: unknown; // Custom state properties
}Performance
For optimal performance, memoize your node tree before passing it to the Tree component. This prevents unnecessary re-renders and tree flattening calculations.
With Redux (recommended)
import { createSelector } from '@reduxjs/toolkit';
const selectRawNodes = (state: RootState) => state.tree.nodes;
// Memoized selector - tree only recalculates when nodes actually change
export const selectNodes = createSelector(
[selectRawNodes],
(nodes) => nodes
);With React
import { useMemo } from 'react';
function MyTree({ data }) {
// Memoize the nodes array
const nodes = useMemo(() => transformToNodes(data), [data]);
return (
<Tree nodes={nodes} onChange={setNodes}>
{({ node }) => <div>{node.name}</div>}
</Tree>
);
}Without memoization, the tree will re-flatten on every parent render, which can be expensive for large trees.
Development
# Install dependencies
npm install
# Run development server
npm run dev
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Type check
npm run typecheck
# Build
npm run build
# Lint
npm run lintLicense
MIT
Credits
Originally forked from diogofcunha/react-virtualized-tree.
