New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More

react-virtualized-sticky-tree

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-virtualized-sticky-tree - npm Package Compare versions

Comparing version

to
1.0.3

@@ -36,7 +36,8 @@ 'use strict';

_this.state = {
scrollTop: 0,
currNodePos: 0
};
_this.scrollTop = 0;
_this.nodePosCache = [];
_this.rowRenderRange = undefined;
return _this;

@@ -78,3 +79,2 @@ }

nodeInfo.children = [];
for (var i = 0; i < children.length; i++) {

@@ -112,2 +112,5 @@ // Need to reset parentIndex here as we are recursive.

}
if (newProps.scrollTop !== this.scrollTop) {
this.elem.scrollTop = newProps.scrollTop;
}
}

@@ -118,2 +121,22 @@

}, {
key: 'componentDidUpdate',
value: function () {
function componentDidUpdate(prevProps, prevState) {
if (this.props.onRowsRendered !== undefined && prevState.currNodePos !== this.props.currNodePos) {
var range = this.rowRenderRange;
this.props.onRowsRendered({
overscanStartIndex: range.start,
overscanStopIndex: range.end,
startIndex: range.visibleStart,
stopIndex: range.visibleEnd,
startNode: this.nodePosCache[range.visibleStart].node,
endNode: this.nodePosCache[range.visibleEnd].node
});
}
}
return componentDidUpdate;
}()
}, {
key: 'getChildContainerStyle',

@@ -131,4 +154,4 @@ value: function () {

function renderParentTree() {
var rowRenderRange = this.getRenderRowRange();
var path = this.getParentPath(rowRenderRange.start);
this.rowRenderRange = this.getRenderRowRange();
var path = this.getParentPath(this.rowRenderRange.start);

@@ -142,3 +165,3 @@ // Parent nodes to the current range.

// The rest of the nodes within the range.
for (var _i = rowRenderRange.start; _i <= rowRenderRange.end; _i++) {
for (var _i = this.rowRenderRange.start; _i <= this.rowRenderRange.end; _i++) {
indexesToRender.add(this.nodePosCache[_i].index);

@@ -233,9 +256,9 @@ }

}
var end = this.state.currNodePos + 1;
var visibleEnd = this.state.currNodePos + 1;
while (this.nodePosCache[end] && this.nodePosCache[end].top < this.state.scrollTop + this.props.height) {
end++;
while (this.nodePosCache[visibleEnd] && this.nodePosCache[visibleEnd].top < this.scrollTop + this.props.height) {
visibleEnd++;
}
end = end + this.props.overscanRowCount;
var end = visibleEnd + this.props.overscanRowCount;
if (end > this.nodePosCache.length - 1) {

@@ -245,3 +268,3 @@ end = this.nodePosCache.length - 1;

return { start: start, end: end };
return { start: start, end: end, visibleStart: this.state.currNodePos, visibleEnd: visibleEnd };
}

@@ -316,5 +339,5 @@

var pos = void 0;
if (scrollTop > this.state.scrollTop) {
if (scrollTop > this.scrollTop) {
pos = this.forwardSearch(scrollTop);
} else if (scrollTop < this.state.scrollTop) {
} else if (scrollTop < this.scrollTop) {
pos = this.backwardSearch(scrollTop);

@@ -335,3 +358,7 @@ }

this.findClosestNode(scrollTop);
this.setState({ scrollTop: scrollTop });
this.scrollTop = scrollTop;
if (this.props.onScroll !== undefined) {
this.props.onScroll({ scrollTop: this.scrollTop });
}
}

@@ -361,5 +388,13 @@

function render() {
var _this3 = this;
return _react2['default'].createElement(
'div',
{ className: 'rv-sticky-tree', style: this.getStyle(), onScroll: this.onScroll },
{ ref: function () {
function ref(elem) {
return _this3.elem = elem;
}
return ref;
}(), className: 'rv-sticky-tree', style: this.getStyle(), onScroll: this.onScroll },
this.renderParentTree()

@@ -384,3 +419,13 @@ );

width: _propTypes2['default'].number,
renderRoot: _propTypes2['default'].bool
renderRoot: _propTypes2['default'].bool,
/**
* Called whenever the scrollTop position changes.
*/
onScroll: _propTypes2['default'].func,
/**
* Called to indicate that a new render range for rows has been rendered.
*/
onRowsRendered: _propTypes2['default'].func
};

@@ -387,0 +432,0 @@ StickyTree.defaultProps = {

@@ -36,7 +36,8 @@ 'use strict';

_this.state = {
scrollTop: 0,
currNodePos: 0
};
_this.scrollTop = 0;
_this.nodePosCache = [];
_this.rowRenderRange = undefined;
return _this;

@@ -78,3 +79,2 @@ }

nodeInfo.children = [];
for (var i = 0; i < children.length; i++) {

@@ -112,2 +112,5 @@ // Need to reset parentIndex here as we are recursive.

}
if (newProps.scrollTop !== this.scrollTop) {
this.elem.scrollTop = newProps.scrollTop;
}
}

@@ -118,2 +121,22 @@

}, {
key: 'componentDidUpdate',
value: function () {
function componentDidUpdate(prevProps, prevState) {
if (this.props.onRowsRendered !== undefined && prevState.currNodePos !== this.props.currNodePos) {
var range = this.rowRenderRange;
this.props.onRowsRendered({
overscanStartIndex: range.start,
overscanStopIndex: range.end,
startIndex: range.visibleStart,
stopIndex: range.visibleEnd,
startNode: this.nodePosCache[range.visibleStart].node,
endNode: this.nodePosCache[range.visibleEnd].node
});
}
}
return componentDidUpdate;
}()
}, {
key: 'getChildContainerStyle',

@@ -131,4 +154,4 @@ value: function () {

function renderParentTree() {
var rowRenderRange = this.getRenderRowRange();
var path = this.getParentPath(rowRenderRange.start);
this.rowRenderRange = this.getRenderRowRange();
var path = this.getParentPath(this.rowRenderRange.start);

@@ -142,3 +165,3 @@ // Parent nodes to the current range.

// The rest of the nodes within the range.
for (var _i = rowRenderRange.start; _i <= rowRenderRange.end; _i++) {
for (var _i = this.rowRenderRange.start; _i <= this.rowRenderRange.end; _i++) {
indexesToRender.add(this.nodePosCache[_i].index);

@@ -233,9 +256,9 @@ }

}
var end = this.state.currNodePos + 1;
var visibleEnd = this.state.currNodePos + 1;
while (this.nodePosCache[end] && this.nodePosCache[end].top < this.state.scrollTop + this.props.height) {
end++;
while (this.nodePosCache[visibleEnd] && this.nodePosCache[visibleEnd].top < this.scrollTop + this.props.height) {
visibleEnd++;
}
end = end + this.props.overscanRowCount;
var end = visibleEnd + this.props.overscanRowCount;
if (end > this.nodePosCache.length - 1) {

@@ -245,3 +268,3 @@ end = this.nodePosCache.length - 1;

return { start: start, end: end };
return { start: start, end: end, visibleStart: this.state.currNodePos, visibleEnd: visibleEnd };
}

@@ -316,5 +339,5 @@

var pos = void 0;
if (scrollTop > this.state.scrollTop) {
if (scrollTop > this.scrollTop) {
pos = this.forwardSearch(scrollTop);
} else if (scrollTop < this.state.scrollTop) {
} else if (scrollTop < this.scrollTop) {
pos = this.backwardSearch(scrollTop);

@@ -335,3 +358,7 @@ }

this.findClosestNode(scrollTop);
this.setState({ scrollTop: scrollTop });
this.scrollTop = scrollTop;
if (this.props.onScroll !== undefined) {
this.props.onScroll({ scrollTop: this.scrollTop });
}
}

@@ -361,5 +388,13 @@

function render() {
var _this3 = this;
return _react2['default'].createElement(
'div',
{ className: 'rv-sticky-tree', style: this.getStyle(), onScroll: this.onScroll },
{ ref: function () {
function ref(elem) {
return _this3.elem = elem;
}
return ref;
}(), className: 'rv-sticky-tree', style: this.getStyle(), onScroll: this.onScroll },
this.renderParentTree()

@@ -384,3 +419,13 @@ );

width: _propTypes2['default'].number,
renderRoot: _propTypes2['default'].bool
renderRoot: _propTypes2['default'].bool,
/**
* Called whenever the scrollTop position changes.
*/
onScroll: _propTypes2['default'].func,
/**
* Called to indicate that a new render range for rows has been rendered.
*/
onRowsRendered: _propTypes2['default'].func
};

@@ -387,0 +432,0 @@ StickyTree.defaultProps = {

{
"name": "react-virtualized-sticky-tree",
"description": "A React component for efficiently rendering tree like structures with support for position: sticky",
"version": "1.0.2",
"version": "1.0.3",
"author": "Marc McIntyre <marchaos@gmail.com>",

@@ -6,0 +6,0 @@ "license": "MIT",

# react-virtualized-sticky-tree
A React component for efficiently rendering tree like structures with support for position: sticky. `react-virtualized-sticky-tree` uses a similar API to [react-virtualized](https://github.com/bvaughn/react-virtualized).
## Demo
https://marchaos.github.io/react-virtualized-sticky-tree/
## Getting Started

@@ -37,2 +41,4 @@

root="root"
width={width}
height={height}
getChildren={getChildren}

@@ -47,2 +53,22 @@ getHeight={getHeight}

## Nested Sticky Header Styles
sticky header components are rendered directly via your rowRenderer() function where styles are used to make the component sticky. StickyTree renders the component within a nested structure so that the header's position may be 'stuck' at different levels (see [demo](https://marchaos.github.io/react-virtualized-sticky-tree/)).
Every nested sticky level should have a top which is at the bottom of the sticky level above it. For example. If your root node is 30px high and has a top of 0, the next sticky node should have a top of 30px. The z-index of the node should also be lower than the nodes above it (so that it is scrolled out of view underneath its parent node). If your root node is z-index 4, then the node below could be 3, below that 2 and so on.
An implementation of this would look like:
```js
const rowRenderer = (id) => {
let style = {};
if (nodeShouldBeSticky(id)) {
const depth = mytree[id].depth;
const nodeHeight = 30;
style = { position: 'sticky', top: depth * nodeHeight, zIndex: 4 - depth };
}
return <div className="row" style={style}>{mytree[id].name}</div>;
};
```
## Dynamic Height Container

@@ -54,2 +80,3 @@

as a HOC:
```js

@@ -71,5 +98,28 @@ const MeasuredTree = withContentRect('bounds')(({ measureRef, measure, contentRect }) => (

```
or within render()
```js
<Measure
bounds={true}
onResize={(contentRect) => {this.setState({ dimensions: contentRect.bounds });}}
>
{({ measureRef }) =>
<div ref={measureRef} className="sticky-tree-wrapper">
<StickyTree
width={this.state.dimensions.width}
height={this.state.dimensions.height}
root={0}
renderRoot={true}
rowRenderer={this.rowRenderer}
getChildren={this.getChildren}
getHeight={() => 30}
overscanRowCount={20}
/>
</div>
}
</Measure>
```
## Supported Browsers
Rendering tree structures is supported in all modern browsers. position: sticky has only been tested in Chrome 59 and Firefox 54, but should work in Edge, Safari and Opera. See http://caniuse.com/#search=position%3Asticky