Skip to content

Instantly share code, notes, and snippets.

@robgev
Created August 11, 2017 11:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robgev/c3c0f91e611afe57c6d6c3e9d3d6921e to your computer and use it in GitHub Desktop.
Save robgev/c3c0f91e611afe57c6d6c3e9d3d6921e to your computer and use it in GitHub Desktop.
/* @flow */
/**
* VirtualizedTreeview molecule
* @module molecules/virtualized-treeview
* @version v1.0.1
*/
import React, { Component } from 'react';
import { List, AutoSizer } from 'react-virtualized';
import './index.scss';
import _ from 'lodash';
export type IVirtualizedTreeViewItemCompProps<T> = {
toggle?: (e: Event) => void,
isOpen?: boolean,
level: number,
path: string,
data: T,
index: number,
};
type IVirtualizedTreeViewItem<T> = {
Comp: (props: IVirtualizedTreeViewItemCompProps<T>) => React.Element<*>,
height: number,
isInitiallyOpen: boolean,
children?: IVirtualizedTreeViewItem<T>[],
data: T,
compProps: Object,
}
type IVirtualizedTreeViewProps = {
items: IVirtualizedTreeViewItem<*>[],
scrollToIndex: number,
}
type IVirtualizedTreeViewState = {
openItems: { [n: string]: boolean, }
}
/**
* Represents virtualizes tree view
* @class VirtualizedTreeview
* @extends React.Component
*/
export default class VirtualizedTreeview extends Component<*, IVirtualizedTreeViewProps, IVirtualizedTreeViewState> {
state: IVirtualizedTreeViewState;
/**
* @constructor
* @param {Object} props - props
*/
constructor(props: IVirtualizedTreeViewProps) {
super(props);
this.state = {
openItems: this.getInitiallyOpenBranches(props.items),
};
}
/**
* Gets initially open branches
* @param {IVirtualizedTreeViewItem<*>[]} rootItems - root items
* @returns {Object} initiallyOpenBranches
*/
getInitiallyOpenBranches = (rootItems: IVirtualizedTreeViewItem<*>[]) => {
const initiallyOpenBranches = {};
const iter = (items: IVirtualizedTreeViewItem<*>[], parentPath) => {
return items.forEach((item, i) => {
const path = parentPath + '-' + i;
if (item.isInitiallyOpen) {
initiallyOpenBranches[path] = true;
}
if (item.children) {
iter((item.children: any), path);
}
});
};
iter(rootItems, '0');
return initiallyOpenBranches;
};
/**
* Flattens items
* @param {IVirtualizedTreeViewItem<*>[]} rootItems - root items
* @returns {Object} items
*/
flattenItems = (rootItems: IVirtualizedTreeViewItem<*>[]) => {
const flattenedItems = [];
const iter = (items: IVirtualizedTreeViewItem<*>[], level, parentPath) => {
return items.forEach((item, i) => {
const ItemComp = item.Comp;
const path = parentPath + '-' + i;
const leafProps = { level, path }
console.log(<ItemComp />)
console.log(ItemComp())
flattenedItems.push({
Comp: React.createElement(ItemComp),
level,
index: i,
height: item.height,
});
});
};
iter(rootItems, 0, '0');
return flattenedItems;
};
render() {
const flattenedItems = this.flattenItems(this.props.items);
const flattenedItemHeights = flattenedItems.map(i => i.height);
const flattenedItemComponents = flattenedItems.map(c => c.Comp);
return (
<AutoSizer>
{({ width, height }: { width: number, height: number }) => (
<List
scrollToIndex={this.props.scrollToIndex}
rowCount={flattenedItems.length}
overscanRowCount={10}
rowHeight={(props) => {
const { index } = props;
const h = flattenedItemHeights[index];
return _.isFunction(h) ? h(props) : h;
}}
rowRenderer={({ index, style, key }) => {
const Comp = flattenedItemComponents[index];
return (<fb style={style} key={key}>{Comp}</fb>);
}}
width={width}
height={height}
/>
)}
</AutoSizer>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment