Skip to content

Commit b094d4c

Browse files
committed
Add option to render without virtualization
1 parent 2dca5a9 commit b094d4c

File tree

5 files changed

+64
-14
lines changed

5 files changed

+64
-14
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ reactVirtualizedListProps | object | | | Cu
6262
rowHeight | number or func | `62` | | Used by react-virtualized. Either a fixed row height (number) or a function that returns the height of a row given its index: `({ index: number }): number`
6363
slideRegionSize | number | `100` | | Size in px of the region near the edges that initiates scrolling on dragover.
6464
scaffoldBlockPxWidth | number | `44` | | The width of the blocks containing the lines representing the structure of the tree.
65+
isVirtualized | bool | `true` | | Set to false to disable virtualization. __NOTE__: Auto-scrolling while dragging, and scrolling to the `searchFocusOffset` will be disabled.
6566
nodeContentRenderer | any | NodeRendererDefault | | Override the default component for rendering nodes (but keep the scaffolding generator) This is an advanced option for complete customization of the appearance. It is best to copy the component in `node-renderer-default.js` to use as a base, and customize as needed.
6667

6768
## Data Helper Functions

src/examples/basicExample/app.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,9 @@ class App extends Component {
202202
0,
203203
});
204204

205+
const isVirtualized = true;
206+
const treeContainerStyle = isVirtualized ? { height: 450 } : {};
207+
205208
return (
206209
<div>
207210
<section className={styles['page-header']}>
@@ -265,7 +268,7 @@ class App extends Component {
265268
</span>
266269
</form>
267270

268-
<div style={{ height: 450 }}>
271+
<div style={treeContainerStyle}>
269272
<SortableTree
270273
treeData={treeData}
271274
onChange={this.updateTreeData}
@@ -285,6 +288,7 @@ class App extends Component {
285288
searchFocusIndex: matches.length > 0 ? searchFocusIndex % matches.length : 0,
286289
})
287290
}
291+
isVirtualized={isVirtualized}
288292
generateNodeProps={rowInfo => ({
289293
buttons: [
290294
<button

src/node-renderer-default.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@ $row-padding: 10px;
33
.rowWrapper {
44
padding: $row-padding $row-padding $row-padding 0;
55
height: 100%;
6+
box-sizing: border-box;
67
}
78

89
.row {
910
height: 100%;
1011
white-space: nowrap;
1112
display: flex;
13+
14+
& > * {
15+
box-sizing: border-box;
16+
}
1217
}
1318

1419
/**

src/react-sortable-tree.js

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,22 +40,32 @@ class ReactSortableTree extends Component {
4040
constructor(props) {
4141
super(props);
4242

43+
const {
44+
dndType,
45+
nodeContentRenderer,
46+
isVirtualized,
47+
slideRegionSize,
48+
treeData,
49+
} = props;
50+
4351
// Wrapping classes for use with react-dnd
44-
this.dndType = props.dndType || `rst__${dndTypeCounter++}`;
45-
this.nodeContentRenderer = dndWrapSource(props.nodeContentRenderer, this.dndType);
52+
this.dndType = dndType || `rst__${dndTypeCounter++}`;
53+
this.nodeContentRenderer = dndWrapSource(nodeContentRenderer, this.dndType);
4654
this.treeNodeRenderer = dndWrapTarget(TreeNode, this.dndType);
4755

4856
// Prepare scroll-on-drag options for this list
49-
this.scrollZoneVirtualList = withScrolling(List);
50-
this.vStrength = createVerticalStrength(props.slideRegionSize);
51-
this.hStrength = createHorizontalStrength(props.slideRegionSize);
57+
if (isVirtualized) {
58+
this.scrollZoneVirtualList = withScrolling(List);
59+
this.vStrength = createVerticalStrength(slideRegionSize);
60+
this.hStrength = createHorizontalStrength(slideRegionSize);
61+
}
5262

5363
this.state = {
5464
draggingTreeData: null,
5565
swapFrom: null,
5666
swapLength: null,
5767
swapDepth: null,
58-
rows: this.getRows(props.treeData),
68+
rows: this.getRows(treeData),
5969
searchMatches: [],
6070
searchFocusTreeIndex: null,
6171
};
@@ -309,6 +319,8 @@ class ReactSortableTree extends Component {
309319
className,
310320
innerStyle,
311321
rowHeight,
322+
getNodeKey,
323+
isVirtualized,
312324
} = this.props;
313325
const {
314326
rows,
@@ -323,14 +335,14 @@ class ReactSortableTree extends Component {
323335
// Seek to the focused search result if there is one specified
324336
const scrollToInfo = searchFocusTreeIndex !== null ? { scrollToIndex: searchFocusTreeIndex } : {};
325337

326-
const ScrollZoneVirtualList = this.scrollZoneVirtualList;
338+
let containerStyle = style;
339+
let list;
340+
if (isVirtualized) {
341+
containerStyle = { height: '100%', ...containerStyle };
327342

328-
return (
329-
<div
330-
className={styles.tree + (className ? ` ${className}` : '')}
331-
style={{ height: '100%', ...style }}
332-
ref={(el) => { this.containerRef = el; }}
333-
>
343+
const ScrollZoneVirtualList = this.scrollZoneVirtualList;
344+
// Render list with react-virtualized
345+
list = (
334346
<AutoSizer>
335347
{({height, width}) => (
336348
<ScrollZoneVirtualList
@@ -359,6 +371,28 @@ class ReactSortableTree extends Component {
359371
/>
360372
)}
361373
</AutoSizer>
374+
);
375+
} else {
376+
// Render list without react-virtualized
377+
list = rows.map((row, index) => this.renderRow(
378+
row,
379+
index,
380+
getNodeKey({
381+
node: row.node,
382+
treeIndex: row.treeIndex,
383+
}),
384+
{ height: rowHeight },
385+
() => (rows[index - 1] || null),
386+
matchKeys
387+
));
388+
}
389+
390+
return (
391+
<div
392+
className={styles.tree + (className ? ` ${className}` : '')}
393+
style={containerStyle}
394+
>
395+
{list}
362396
</div>
363397
);
364398
}
@@ -471,6 +505,10 @@ ReactSortableTree.propTypes = {
471505
// or additional `style` / `className` settings.
472506
generateNodeProps: PropTypes.func,
473507

508+
// Set to false to disable virtualization.
509+
// NOTE: Auto-scrolling while dragging, and scrolling to the `searchFocusOffset` will be disabled.
510+
isVirtualized: PropTypes.bool,
511+
474512
// Override the default component for rendering nodes (but keep the scaffolding generator)
475513
// This is an advanced option for complete customization of the appearance.
476514
// It is best to copy the component in `node-renderer-default.js` to use as a base, and customize as needed.
@@ -504,6 +542,7 @@ ReactSortableTree.defaultProps = {
504542
style: {},
505543
innerStyle: {},
506544
searchQuery: null,
545+
isVirtualized: true,
507546
};
508547

509548
export default dndWrapRoot(ReactSortableTree);

src/tree-node.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.node {
22
min-width: 100%;
33
white-space: nowrap;
4+
position: relative;
45
}
56

67
.nodeContent {

0 commit comments

Comments
 (0)