react-virtualized
Advanced tools
Comparing version 3.0.1 to 3.1.0
Changelog | ||
------------ | ||
#### 3.1.0 | ||
Added high-order `InfiniteLoader` component to manage just-in-time fetching of data as a user scrolls up or down in a list. | ||
For more information about this component refer to the [API docs](https://github.com/bvaughn/react-virtualized/blob/master/docs/InfiniteLoader.md). | ||
#### 3.0.1 | ||
@@ -5,0 +9,0 @@ Fixed small NPE when up/down arrow key was used while an empty VirtualScroll was in-focus. |
@@ -6,3 +6,3 @@ { | ||
"user": "bvaughn", | ||
"version": "3.0.1", | ||
"version": "3.1.0", | ||
"scripts": { | ||
@@ -9,0 +9,0 @@ "build": "npm run build:demo && npm run build:dist", |
@@ -130,3 +130,3 @@ <img src="https://cloud.githubusercontent.com/assets/29597/11737732/0ca1e55e-9f91-11e5-97f3-098f2f8ed866.png" alt="React virtualized" data-canonical-src="https://cloud.githubusercontent.com/assets/29597/11737732/0ca1e55e-9f91-11e5-97f3-098f2f8ed866.png" width="330" height="100" /> | ||
#### Autosizer Example | ||
#### AutoSizer Example | ||
`VirtualScroll` and `FlexTable` require explicit dimensions but sometimes you just want a component to just grow to fill all of the available space. In that case you should use the `AutoSizer` component. Building on the `VirtualScroll` example above... | ||
@@ -167,2 +167,47 @@ | ||
#### InfiniteLoader Example | ||
High-order component that manages just-in-time fetching of data as a user scrolls up or down in a list. | ||
```javascript | ||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import { InfiniteLoader, VirtualScroll } from 'react-virtualized'; | ||
const list = {}; | ||
function isRowLoaded (index) { | ||
return !!list[index]; | ||
} | ||
function loadMoreRows ({ startIndex, stopIndex }) { | ||
return fetch(`path/to/api?startIndex=${startIndex}&stopIndex=${stopIndex}`) | ||
.then(response => { | ||
// Store response data in list... | ||
}) | ||
} | ||
// Render your list | ||
ReactDOM.render( | ||
<InfiniteLoader | ||
isRowLoaded={isRowLoaded} | ||
loadMoreRows={loadMoreRows} | ||
rowsCount={remoteRowsCount} | ||
> | ||
<VirtualScroll | ||
height={300} | ||
rowsCount={list.length} | ||
rowHeight={20} | ||
rowRenderer={ | ||
index => ( | ||
<div key={index}> | ||
{list[index]} | ||
</div> | ||
) | ||
} | ||
/> | ||
</InfiniteLoader>, | ||
document.getElementById('example') | ||
); | ||
``` | ||
Contributions | ||
@@ -169,0 +214,0 @@ ------------ |
/** @flow */ | ||
import React, { Component } from 'react' | ||
import Immutable from 'immutable' | ||
import React, { Component, PropTypes } from 'react' | ||
import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox' | ||
@@ -9,2 +10,6 @@ import AutoSizer from './AutoSizer' | ||
export default class AutoSizerExample extends Component { | ||
static propTypes = { | ||
list: PropTypes.instanceOf(Immutable.List).isRequired | ||
} | ||
constructor (props) { | ||
@@ -16,2 +21,4 @@ super(props) | ||
} | ||
this._rowRenderer = this._rowRenderer.bind(this) | ||
} | ||
@@ -21,6 +28,7 @@ | ||
const { hideDescription } = this.state | ||
const { list } = this.props | ||
return ( | ||
<ContentBox | ||
className={styles.AutoSizerExample} | ||
{...this.props} | ||
style={{ | ||
@@ -59,11 +67,7 @@ maxHeight: 600 | ||
<VirtualScroll | ||
className={styles.VirtualScroll} | ||
height={0} | ||
noRowsRenderer={() => ( | ||
<div className={styles.Empty}> | ||
Empty <code>VirtualScroll</code> | ||
</div> | ||
)} | ||
rowsCount={0} | ||
rowHeight={1} | ||
rowRenderer={() => {}} | ||
rowsCount={list.size} | ||
rowHeight={30} | ||
rowRenderer={this._rowRenderer} | ||
/> | ||
@@ -75,2 +79,17 @@ </AutoSizer> | ||
} | ||
_rowRenderer (index) { | ||
const { list } = this.props | ||
const row = list.get(index) | ||
return ( | ||
<div | ||
key={index} | ||
className={styles.row} | ||
style={{ height: 30 }} | ||
> | ||
{row.name} | ||
</div> | ||
) | ||
} | ||
} |
@@ -1,9 +0,15 @@ | ||
import React from 'react' | ||
import { render } from 'react-dom' | ||
import AutoSizerExample from '../AutoSizer/AutoSizer.example' | ||
import FlexTableExample from '../FlexTable/FlexTable.example' | ||
import Immutable from 'immutable' | ||
import InfiniteLoaderExample from '../InfiniteLoader/InfiniteLoader.example' | ||
import NavLink from './NavLink' | ||
import React from 'react' | ||
import styles from './Application.css' | ||
import VirtualScrollExample from '../VirtualScroll/VirtualScroll.example' | ||
import styles from './Application.css' | ||
import { generateRandomList } from './utils' | ||
import { render } from 'react-dom' | ||
// HACK Generate arbitrary data for use in example components :) | ||
const list = Immutable.List(generateRandomList()) | ||
render(( | ||
@@ -46,5 +52,18 @@ <div className={styles.demo}> | ||
<div className={styles.row}> | ||
<VirtualScrollExample/> | ||
<FlexTableExample/> | ||
<AutoSizerExample/> | ||
<VirtualScrollExample | ||
className={styles.column} | ||
list={list} | ||
/> | ||
<FlexTableExample | ||
className={styles.column} | ||
list={list} | ||
/> | ||
<AutoSizerExample | ||
className={styles.column} | ||
list={list} | ||
/> | ||
<InfiniteLoaderExample | ||
className={styles.column} | ||
list={list} | ||
/> | ||
</div> | ||
@@ -51,0 +70,0 @@ |
/** @flow */ | ||
import React, { Component } from 'react' | ||
import Immutable from 'immutable' | ||
import React, { Component, PropTypes } from 'react' | ||
import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox' | ||
@@ -7,6 +8,9 @@ import { LabeledInput, InputRow } from '../demo/LabeledInput' | ||
import FlexTable, { SortDirection } from './FlexTable' | ||
import Immutable from 'immutable' | ||
import styles from './FlexTable.example.css' | ||
export default class TableExample extends Component { | ||
static propTypes = { | ||
list: PropTypes.instanceOf(Immutable.List).isRequired | ||
} | ||
constructor (props, context) { | ||
@@ -25,13 +29,2 @@ super(props, context) | ||
// HACK :) | ||
const list = [] | ||
for (var i = 0; i < 1000; i++) { | ||
list.push({ | ||
id: i, | ||
name: `Item ${i + 1}`, | ||
random: loremIpsum[i % loremIpsum.length] | ||
}) | ||
} | ||
this._list = Immutable.List(list) | ||
this._noRowsRenderer = this._noRowsRenderer.bind(this) | ||
@@ -54,4 +47,5 @@ this._onRowsCountChange = this._onRowsCountChange.bind(this) | ||
const list = this._list | ||
.sortBy(index => this._list.getIn([index, sortBy])) | ||
const { list } = this.props | ||
const filteredList = list | ||
.sortBy(index => list.getIn([index, sortBy])) | ||
.update(list => | ||
@@ -64,7 +58,7 @@ sortDirection === SortDirection.DESC | ||
function rowGetter (index) { | ||
return list.get(index) | ||
return filteredList.get(index) | ||
} | ||
return ( | ||
<ContentBox className={styles.FlexTableExample}> | ||
<ContentBox {...this.props}> | ||
<ContentBoxHeader | ||
@@ -120,3 +114,2 @@ text='FlexTable' | ||
className={styles.FlexTable} | ||
width={430} | ||
headerClassName={styles.headerColumn} | ||
@@ -133,2 +126,3 @@ headerHeight={headerHeight} | ||
sortDirection={sortDirection} | ||
width={430} | ||
> | ||
@@ -174,3 +168,3 @@ <FlexColumn | ||
let rowsCount = parseInt(event.target.value, 10) || 0 | ||
rowsCount = Math.max(0, Math.min(this._list.size, rowsCount)) | ||
rowsCount = Math.max(0, Math.min(this.props.list.size, rowsCount)) | ||
@@ -205,23 +199,1 @@ this.setState({ rowsCount }) | ||
} | ||
const loremIpsum = [ | ||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', | ||
'Phasellus vulputate odio commodo tortor sodales, et vehicula ipsum viverra.', | ||
'Cras tincidunt nisi in urna molestie varius.', | ||
'Curabitur ac enim dictum arcu varius fermentum vel sodales dui.', | ||
'Ut tristique augue at congue molestie.', | ||
'Cras eget enim nec odio feugiat tristique eu quis ante.', | ||
'Phasellus eget enim vitae nunc luctus sodales a eu erat.', | ||
'Nulla bibendum quam id velit blandit dictum.', | ||
'Donec dignissim mi ac libero feugiat, vitae lacinia odio viverra.', | ||
'Praesent vel lectus venenatis, elementum mauris vitae, ullamcorper nulla.', | ||
'Quisque sollicitudin nulla nec tellus feugiat hendrerit.', | ||
'Vestibulum a eros accumsan, lacinia eros non, pretium diam.', | ||
'Donec ornare felis et dui hendrerit, eget bibendum nibh interdum.', | ||
'Donec nec diam vel tellus egestas lobortis.', | ||
'Sed ornare nisl sit amet dolor pellentesque, eu fermentum leo interdum.', | ||
'Sed eget mauris condimentum, molestie justo eu, feugiat felis.', | ||
'Sed luctus justo vitae nibh bibendum blandit.', | ||
'Nulla ac eros vestibulum, mollis ante eu, rutrum nulla.', | ||
'Sed cursus magna ut vehicula rutrum.' | ||
] |
@@ -28,3 +28,3 @@ /** @flow */ | ||
export default class FlexTable extends Component { | ||
static shouldComponentUpdate = shouldPureComponentUpdate | ||
shouldComponentUpdate = shouldPureComponentUpdate | ||
@@ -31,0 +31,0 @@ static propTypes = { |
/* @flow */ | ||
export { AutoSizer } from './AutoSizer' | ||
export { FlexTable, FlexColumn, SortDirection, SortIndicator } from './FlexTable' | ||
export { InfiniteLoader } from './InfiniteLoader' | ||
export { VirtualScroll } from './VirtualScroll' |
/** | ||
* @flow | ||
*/ | ||
import React, { Component } from 'react' | ||
import Immutable from 'immutable' | ||
import React, { Component, PropTypes } from 'react' | ||
import styles from './VirtualScroll.example.css' | ||
import VirtualScroll from './VirtualScroll' | ||
import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox' | ||
import { LabeledInput, InputRow } from '../demo/LabeledInput' | ||
import VirtualScroll from './VirtualScroll' | ||
import styles from './VirtualScroll.example.css' | ||
export default class VirtualScrollExample extends Component { | ||
static propTypes = { | ||
list: PropTypes.instanceOf(Immutable.List).isRequired | ||
} | ||
constructor (props) { | ||
super(props) | ||
// HACK :) | ||
this._list = [] | ||
for (var i = 0; i < 1000; i++) { | ||
this._list.push({ | ||
index: i, | ||
color: BADGE_COLORS[i % BADGE_COLORS.length], | ||
name: NAMES[i % NAMES.length], | ||
height: ROW_HEIGHTS[Math.floor(Math.random() * ROW_HEIGHTS.length)] | ||
}) | ||
} | ||
this.state = { | ||
rowsCount: this._list.length, | ||
rowsCount: props.list.size, | ||
scrollToIndex: undefined, | ||
@@ -51,3 +45,3 @@ useDynamicRowHeight: false, | ||
return ( | ||
<ContentBox className={styles.VirtualScrollExample}> | ||
<ContentBox {...this.props}> | ||
<ContentBoxHeader | ||
@@ -108,3 +102,2 @@ text='VirtualScroll' | ||
className={styles.VirtualScroll} | ||
width={310} | ||
height={virtualScrollHeight} | ||
@@ -122,3 +115,4 @@ noRowsRenderer={this._noRowsRenderer} | ||
_getRowHeight (index) { | ||
return this._list[index].height | ||
const { list } = this.props | ||
return list.get(index).height | ||
} | ||
@@ -135,4 +129,6 @@ | ||
_onRowsCountChange (event) { | ||
const { list } = this.props | ||
let rowsCount = parseInt(event.target.value, 10) || 0 | ||
rowsCount = Math.max(0, Math.min(this._list.length, rowsCount)) | ||
rowsCount = Math.max(0, Math.min(list.size, rowsCount)) | ||
@@ -154,7 +150,8 @@ this.setState({ rowsCount }) | ||
_rowRenderer (index) { | ||
const { list } = this.props | ||
const { useDynamicRowHeight, virtualScrollRowHeight } = this.state | ||
const datum = this._list[index] | ||
const datum = list.get(index) | ||
const height = useDynamicRowHeight | ||
? datum.height | ||
? datum.size | ||
: virtualScrollRowHeight | ||
@@ -165,3 +162,3 @@ | ||
if (useDynamicRowHeight) { | ||
switch (datum.height) { | ||
switch (datum.size) { | ||
case 75: | ||
@@ -201,3 +198,3 @@ additionalContent = <div>It is medium-sized.</div> | ||
<span className={styles.height}> | ||
{datum.height}px | ||
{datum.size}px | ||
</span> | ||
@@ -216,5 +213,1 @@ } | ||
} | ||
const BADGE_COLORS = ['#f44336', '#3f51b5', '#4caf50', '#ff9800', '#2196f3', '#374046', '#cddc39', '#2196f3', '#9c27b0', '#ffc107', '#009688', '#673ab7', '#ffeb3b', '#cddc39', '#795548'] | ||
const NAMES = ['Peter Brimer', 'Tera Gaona', 'Kandy Liston', 'Lonna Wrede', 'Kristie Yard', 'Raul Host', 'Yukiko Binger', 'Velvet Natera', 'Donette Ponton', 'Loraine Grim', 'Shyla Mable', 'Marhta Sing', 'Alene Munden', 'Holley Pagel', 'Randell Tolman', 'Wilfred Juneau', 'Naida Madson', 'Marine Amison', 'Glinda Palazzo', 'Lupe Island', 'Cordelia Trotta', 'Samara Berrier', 'Era Stepp', 'Malka Spradlin', 'Edward Haner', 'Clemencia Feather', 'Loretta Rasnake', 'Dana Hasbrouck', 'Sanda Nery', 'Soo Reiling', 'Apolonia Volk', 'Liliana Cacho', 'Angel Couchman', 'Yvonne Adam', 'Jonas Curci', 'Tran Cesar', 'Buddy Panos', 'Rosita Ells', 'Rosalind Tavares', 'Renae Keehn', 'Deandrea Bester', 'Kelvin Lemmon', 'Guadalupe Mccullar', 'Zelma Mayers', 'Laurel Stcyr', 'Edyth Everette', 'Marylin Shevlin', 'Hsiu Blackwelder', 'Mark Ferguson', 'Winford Noggle', 'Shizuko Gilchrist', 'Roslyn Cress', 'Nilsa Lesniak', 'Agustin Grant', 'Earlie Jester', 'Libby Daigle', 'Shanna Maloy', 'Brendan Wilken', 'Windy Knittel', 'Alice Curren', 'Eden Lumsden', 'Klara Morfin', 'Sherryl Noack', 'Gala Munsey', 'Stephani Frew', 'Twana Anthony', 'Mauro Matlock', 'Claudie Meisner', 'Adrienne Petrarca', 'Pearlene Shurtleff', 'Rachelle Piro', 'Louis Cocco', 'Susann Mcsweeney', 'Mandi Kempker', 'Ola Moller', 'Leif Mcgahan', 'Tisha Wurster', 'Hector Pinkett', 'Benita Jemison', 'Kaley Findley', 'Jim Torkelson', 'Freda Okafor', 'Rafaela Markert', 'Stasia Carwile', 'Evia Kahler', 'Rocky Almon', 'Sonja Beals', 'Dee Fomby', 'Damon Eatman', 'Alma Grieve', 'Linsey Bollig', 'Stefan Cloninger', 'Giovanna Blind', 'Myrtis Remy', 'Marguerita Dostal', 'Junior Baranowski', 'Allene Seto', 'Margery Caves', 'Nelly Moudy', 'Felix Sailer'] | ||
const ROW_HEIGHTS = [50, 75, 100] |
@@ -32,3 +32,3 @@ /** @flow */ | ||
export default class VirtualScroll extends Component { | ||
static shouldComponentUpdate = shouldPureComponentUpdate | ||
shouldComponentUpdate = shouldPureComponentUpdate | ||
@@ -35,0 +35,0 @@ static propTypes = { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
671551
58
7129
227
1