Skip to content

Commit 1f4026a

Browse files
committed
docs: add readme
1 parent 80f88d3 commit 1f4026a

File tree

1 file changed

+182
-0
lines changed

1 file changed

+182
-0
lines changed

README.md

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
# react-vtree
2+
3+
This component is designed as a basic solution for rendering huge tree structures without affecting performance. Under
4+
the hood it uses [react-virtualized](https://github.com/bvaughn/react-virtualized) library and also can be considered
5+
as a part of this library.
6+
7+
### Terminology
8+
* **Node** - basic structure element of tree. Nodes nested in each other form tree structure.
9+
* **Row** - single line of virtualized list that contains one node and a margin showing nesting level of the node. Row
10+
can also contain a button to toggle visibility of the node's children.
11+
12+
### Prop Types
13+
| Property | Type | Required? | Description |
14+
|----------|----------|:--------:|----------|
15+
| autoHeight | Boolean | | Removes fixed height from the `scrollingContainer` so that the total height of rows can stretch the window. Intended for use with `WindowScroller` HOC. |
16+
| className | String | | Optional CSS class name. |
17+
| controlClassName | String | | Optional CSS class for all toggle controls. |
18+
| controlStyle | Object | | Optional inline styles for all toggle controls. |
19+
| estimatedRowSize | Number | | Used to estimate the total height of a Tree before all of its rows have actually been measured. The estimated total height is adjusted as rows are rendered. |
20+
| height | Number || Sets height of a container Tree is rendered inside of. It also determines how many actual rows are rendered. |
21+
| id | String | | Custom HTML id |
22+
| nodeGetter | Function || Generator flattens tree data to display it in a list form basing on information of nodes' openness. It should yield node metadata or node id depending on boolean `refresh` parameter it receives. |
23+
| nodeNestingMultiplier | Number | | Multiplier for a margin that depends on node's nesting level. E.g. if multiplier is 10 margin for node with nesting level 2 will be 20px and for node with nesting level 3 - 30px. |
24+
| noRowsRenderer | Function | | Optional renderer to be used in place of rows when tree is empty. |
25+
| onRowClick | Function | | Callback invoked when a user clicks on a node |
26+
| onRowDoubleClick | Function | | Callback invoked when a user double-clicks on a node |
27+
| onRowMouseOut | Function | | Callback invoked when the mouse leaves a node |
28+
| onRowMouseOver | Function | | Callback invoked when a user moves the mouse over a node |
29+
| onRowRightClick | Function | | Callback invoked when a user right-clicks on a node |
30+
| onRowsRendered | Function | | Callback invoked with information about the slice of rows that were just rendered |
31+
| onScroll | Function | | Callback invoked whenever the scroll offset changes within the inner scrollable region. This callback can be used to sync scrolling between lists, tables, or grids. |
32+
| overscanIndicesGetter | Object | | See Grid#overscanIndicesGetter. |
33+
| overscanRowCount | Number | | Number of rows to render above/below the visible bounds of the list. These rows can help for smoother scrolling on touch devices. |
34+
| rowClassName | String | | Optional CSS class to apply to all rows. |
35+
| rowHeight | Number || Fixed row height. |
36+
| rowRenderer | Function | | Renders data received from NodeGetter. |
37+
| rowStyle | Object | | Optional inline styles for all rows. |
38+
| scrollToAlignment | String | | See Grid#scrollToAlignment |
39+
| scrollToIndex | Number | | Row index to ensure visible (by forcefully scrolling if necessary). |
40+
| scrollTop | Number | | Vertical offset. |
41+
| style | Object | | Optional inline styles. |
42+
| tabIndex | Number | | Tab index for focus. |
43+
| update | Number | | If is set and is different than Update.None forces component to recompute and call nodeGetter. This property is not pure: component will re-render any time it receives this property and it is not Update.None. Useful if you changed something in the tree structure and want to re-render component using new data. |
44+
| width | Number || Width of Tree container. |
45+
46+
### Public Methods
47+
48+
#### forceUpdateGrid (callback?: () => any)
49+
Forcefully re-render the inner `Grid` component.
50+
51+
Calling `forceUpdate` on `Tree` may not re-render the inner `Grid` since it uses `shallowCompare` as a performance
52+
optimization. Use this method if you want to manually trigger a re-render. This may be appropriate if the underlying
53+
row data has changed but the row sizes themselves have not.
54+
55+
#### getOffsetForRow (params: {alignment?: string, index?: number}): number
56+
Gets offset for a given row and alignment.
57+
58+
#### measureAllRows (): void
59+
Pre-measure all rows in a `Tree`.
60+
61+
Typically rows are only measured as needed and estimated heights are used for cells that have not yet been measured.
62+
This method ensures that the next call to getTotalSize() returns an exact size (as opposed to just an estimated one).
63+
64+
#### recomputeTree (update: Update): Promise<void>
65+
Recomputes Tree component basing on update type.
66+
67+
Method calls `nodeGetter` internally and flattens tree structure to an array. Depending on `update` value it runs
68+
one of the following algorithms:
69+
1) **Update.NodesAndOpenness**. Requires full node metadata. Updates order, number and rendering data of all
70+
nodes. Overrides current openness state with `openedByDefault` value.
71+
2) **Update.Nodes**. Requires full node metadata. Updates order, number and rendering data of all nodes. Preserves
72+
openness state of all nodes.
73+
3) **Update.Order**. Requires only node id. Updates nodes order (useful for sorting etc.). Preserves openness
74+
state of all nodes.
75+
4) **Update.None**. Updates nothing.
76+
77+
After all computations forces inner `Grid` to re-render. Returns promise that resolves after all re-rendering is done.
78+
79+
#### scrollToPosition (scrollTop: number): void
80+
Scroll to the specified offset.
81+
Useful for animating position changes.
82+
83+
#### scrollToRow (index: number): void
84+
Ensure row is visible.
85+
This method can be used to safely scroll back to a cell that a user has scrolled away from even if it was previously
86+
scrolled to.
87+
88+
### nodeGetter (refresh: boolean): IterableIterator<Node | string | null>
89+
This callback is responsible for providing tree data in consumable form. It should be a `generator` that yields node
90+
metadata to render. Depending on `refresh` parameter it should yield full metadata or only node id. The result of
91+
yielding will be current openness state of the node. This value should be used as a rule to decide if `nodeGetter`
92+
should render node's children or not.
93+
94+
#### Node
95+
| Property | Type | Can be omitted? | Description |
96+
|----------|----------|:--------:|----------|
97+
| childrenCount | Number | | Number of current node children. |
98+
| id | String | | Unique ID of current node. Used to identify node inside Tree component. |
99+
| height | Number || Current node height. Specify only if you want your tree to have nodes with different heights. |
100+
| isOpenedByDefault | Boolean | | Current node openness state. Will set node openness state on first rendering or if `update` is set to Update.NodeAndOpenness. |
101+
| nestingLevel | Number | | Current node nesting level (how deep it is placed relative to tree root). |
102+
| nodeData | Any | | Node data to be rendered. Will be sent as is to `rowRenderer` callback. |
103+
| style | Object || Specific styles for row contains current node. |
104+
105+
#### Example
106+
Let's imagine our tree is build from following nodes:
107+
```typescript
108+
interface TreeNode {
109+
id: string;
110+
name: string;
111+
children: TreeNode[];
112+
}
113+
```
114+
Then `nodeGetter` for this tree could be following:
115+
```typescript
116+
function * nodeGetter(refresh: boolean): IterableIterator<Node | string | null> {
117+
const stack = [];
118+
119+
stack.push({
120+
nestingLevel: 0,
121+
node: root, // tree data structure
122+
});
123+
124+
while (stack.length !== 0) {
125+
const {node, nestingLevel} = stack.pop()!;
126+
const id = node.id.toString();
127+
128+
const isOpened = yield (
129+
refresh ? {
130+
childrenCount: node.children.length,
131+
height: 20, // only if you want to use dynamic heights; otherwise use "rowHeight"
132+
id,
133+
isOpenedByDefault: true, // set "true" if you want your tree to be opened by default, or "false" if you want it closed
134+
nestingLevel,
135+
nodeData: node.name,
136+
} : id
137+
);
138+
139+
if (node.children.length !== 0 && isOpened) {
140+
for (let i = node.children.length - 1; i >= 0; i--) {
141+
stack.push({
142+
nestingLevel: nestingLevel + 1,
143+
node: node.children[i],
144+
});
145+
}
146+
}
147+
}
148+
}
149+
```
150+
151+
### rowRenderer (params: RowRendererParams): React.ReactNode
152+
This callback is responsible for rendering single tree row. It receives metadata including data from `nodeGetter` and
153+
renders it to a React node.
154+
155+
Default tree renderer can provide only the very basic tree rendering: toggle button and string body. So if you need
156+
more functional tree, you can fork `defaultRowRenderer`.
157+
158+
159+
#### RowRendererParams
160+
| Property | Type | Can be undefined? | Description |
161+
|----------|----------|:--------:|----------|
162+
| childrenCount | Number | | Number of children current node has. |
163+
| className | String || Optional CSS class name (a `rowClassName` property set in Tree component). |
164+
| controlClassName | String || Optional CSS class name for toggle control (a `controlClassName` property set in Tree component). |
165+
| controlStyle | Object | | Inline styles for toggle control. Contains two styles: 1) a `controlStyle` property set in Tree component, 2) default styles necessary for displaying control |
166+
| id | String | | Optional HTML id (an `id` property set in Tree component). |
167+
| index | Number | | Current row index in the list of all rows. |
168+
| isOpened | Boolean | | Current node openness state. |
169+
| isScrolling | Boolean | | Current row scrolling state. |
170+
| key | String | | Unique key to specify current row. Should be sent to row container to avoid re-rendering issues. |
171+
| nestingLevel | Number | | Current node nesting level (how deep it is placed relative to tree root). |
172+
| nodeData | Any | | Node data to be rendered. |
173+
| onNodeToggle | Function | | Callback to control node toggling. Should be sent to control element (e.g. `<button>`) to show and hide node children. |
174+
| onRowClick | Function || Callback invoked when a user clicks on a node (a `onRowClick` property set in Tree component). |
175+
| onRowDoubleClick | Function || Callback invoked when a user double-clicks on a node (a `onRowDoubleClick` property set in Tree component). |
176+
| onRowMouseOut | Function || Callback invoked when the mouse leaves a node (a `onRowMouseOut` property set in Tree component). |
177+
| onRowMouseOver | Function || Callback invoked when a user moves the mouse over a node (a `onRowMouseOver` property set in Tree component). |
178+
| onRowRightClick | Function || Callback invoked when a user right-clicks on a node (a `onRowRightClick` property set in Tree component). |
179+
| style | Object | | Inline styles for row container. Should be sent to a row container to display tree structure property. Contains tree styles: 1) Styles provided by Grid necessary to display row as an element of Grid. 2) Default row styles provided by Tree component. 3) Row styles provided by `rowStyle` prop from Tree component. 4) Row styles provided by `style` property of metadata gotten from `nodeGetter`. |
180+
181+
### Example
182+
You can find very basic example in the [stories](./__stories__/Tree.tsx).

0 commit comments

Comments
 (0)