Socket
Socket
Sign inDemoInstall

react-virtualized-sticky-tree

Package Overview
Dependencies
12
Maintainers
1
Versions
71
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    react-virtualized-sticky-tree

A React component for efficiently rendering tree like structures with support for position: sticky


Version published
Weekly downloads
495
increased by9.51%
Maintainers
1
Created
Weekly downloads
 

Readme

Source

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.

Demo

https://marchaos.github.io/react-virtualized-sticky-tree/

Getting Started

npm install react-virtualized-sticky-tree --save

Usage

Basic Example

import { StickyTree } from 'react-virtualized-sticky-tree';

const tree = {
  root: { name: 'Root', children: ['child1', 'child2', 'child3'], depth: 0 },
  child1: { name: 'Child 1', children: ['child4'], depth: 1 },
  child2: { name: 'Child 2', depth: 2 },
  child3: { name: 'Child 3', depth: 2 },
  child4: { name: 'Child 4', depth: 3 },
};

const getChildren = (id) => {
  if (tree[id].children) {
    return tree[id].children.map(id => ({ id, height: 30, isSticky: true }));
  }
};

const rowRenderer = ({ id, style }) => {
  const node = tree[id];
  return <div style={style}>{node.name}</div>
};

render() {
  return (
      <StickyTree
        root={{ id: 'root', height: 30 }}
        width={width}
        height={height}
        getChildren={getChildren}
        rowRenderer={rowRenderer}
        renderRoot={true}
        overscanRowCount={20}
      />
  );
)

Nested Sticky Header Styles

StickyTree renders the component within a nested structure so that the header's position may be 'stuck' at different levels (see demo). When passing the root node or items in the children array, specifying isSticky: true will make the item sticky.

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:

const getChildren = (id) => {
    if (shouldBeSticky(id)) {
      return tree[id].children.map(childId => ({
         id: childId, 
         isSticky: true,
         stickyTop: tree[childId].depth * 10,
         zIndex: 30 - tree[childId].depth, 
         height: 10
      }))
    }
    return tree[id].children.map(childId => ({ id: childId, isSticky: false, height: 10 }))
};

/**
 * Here, style will include the styles to make the node sticky in the right position. 
 */
const rowRenderer = ({ id, style }) => {
  return <div className="row" style={style}>{mytree[id].name}</div>;
};

Be sure to pass a sticky root node to StickyTree if it should be sticky

<StickyTree
    className="treee"
    root={{ id: 'root', isSticky: true, stickyTop: 0, zIndex: 3, height: 10 }}
    rowRenderer={rowRenderer}
    getChildren={getChildren}
/>

Dynamic Height Container

If the containing element of your tree has a dynamic height, you can use react-measure to provide the width and height to sticky-tree so that it can resize to the available width.

For Simplicity, react-virtualized-sticky-tree includes a component which uses react-measure to achieve this:

import { AutoSizedStickyTree } from 'react-virtualized-sticky-tree';

<AutoSizedStickyTree
    className="tree"
    root={{ id: 'root', isSticky: true, stickyTop: 0, zIndex: 3, height: 30 }}
    rowRenderer={rowRenderer}
    getChildren={getChildren}
    ...
/>

If you want to do this yourself, you can install react-measure:

npm install react-measure --save

as a HOC:

const MeasuredTree = withContentRect('bounds')(({ measureRef, measure, contentRect }) => (
  <div ref={measureRef} className="sticky-wrapper">
    <StickyTree
      root={{id: 0}}
      getChildren={getChildren}
      rowRenderer={rowRenderer}
      renderRoot={true}
      width={contentRect.bounds.width}
      height={contentRect.bounds.height}
      overscanRowCount={20}
    />
  </div>
));

or within render()

<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={{id: 0 }}
                  renderRoot={true}
                  rowRenderer={this.rowRenderer}
                  getChildren={this.getChildren}
                  overscanRowCount={20}
              />
          </div>
    }
</Measure>

Supported Browsers

  • Tested with Chrome 59+
  • Tested with Safari 11+
  • Tested with Firefox 54+

Rendering tree structures is supported in all modern browsers. For position: sticky, See http://caniuse.com/#search=position%3Asticky

Keywords

FAQs

Last updated on 12 Mar 2024

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc