GithubHelp home page GithubHelp logo

clauderic / react-tiny-virtual-list Goto Github PK

View Code? Open in Web Editor NEW
2.5K 18.0 165.0 956 KB

A tiny but mighty 3kb list virtualization library, with zero dependencies ๐Ÿ’ช Supports variable heights/widths, sticky items, scrolling to index, and more!

Home Page: https://clauderic.github.io/react-tiny-virtual-list/

License: MIT License

JavaScript 8.31% TypeScript 91.69%
react react-component virtualization virtual-scroll windowing

react-tiny-virtual-list's Introduction

react-tiny-virtual-list

A tiny but mighty list virtualization library, with zero dependencies ๐Ÿ’ช

npm version npm downloads Build Status codecov typescript license Gitter

  • Tiny & dependency free โ€“ Only 3kb gzipped
  • Render millions of items, without breaking a sweat
  • Scroll to index or set the initial scroll offset
  • Supports fixed or variable heights/widths
  • Vertical or Horizontal lists

Check out the demo for some examples, or take it for a test drive right away in Code Sandbox.

Getting Started

Using npm:

npm install react-tiny-virtual-list --save

ES6, CommonJS, and UMD builds are available with each distribution. For example:

import VirtualList from 'react-tiny-virtual-list';

You can also use a global-friendly UMD build:

<script src="react-tiny-virtual-list/umd/react-tiny-virtual-list.js"></script>
<script>
var VirtualList = window.VirtualList;
...
</script>

Example usage

import React from 'react';
import {render} from 'react-dom';
import VirtualList from 'react-tiny-virtual-list';

const data = ['A', 'B', 'C', 'D', 'E', 'F', ...];

render(
  <VirtualList
    width='100%'
    height={600}
    itemCount={data.length}
    itemSize={50} // Also supports variable heights (array or function getter)
    renderItem={({index, style}) =>
      <div key={index} style={style}> // The style property contains the item's absolute position
        Letter: {data[index]}, Row: #{index}
      </div>
    }
  />,
  document.getElementById('root')
);

Prop Types

Property Type Required? Description
width Number | String* โœ“ Width of List. This property will determine the number of rendered items when scrollDirection is 'horizontal'.
height Number | String* โœ“ Height of List. This property will determine the number of rendered items when scrollDirection is 'vertical'.
itemCount Number โœ“ The number of items you want to render
renderItem Function โœ“ Responsible for rendering an item given it's index: ({index: number, style: Object}): React.PropTypes.node. The returned element must handle key and style.
itemSize โœ“ Either a fixed height/width (depending on the scrollDirection), an array containing the heights of all the items in your list, or a function that returns the height of an item given its index: (index: number): number
scrollDirection String Whether the list should scroll vertically or horizontally. One of 'vertical' (default) or 'horizontal'.
scrollOffset Number Can be used to control the scroll offset; Also useful for setting an initial scroll offset
scrollToIndex Number Item index to scroll to (by forcefully scrolling if necessary) x
scrollToAlignment String Used in combination with scrollToIndex, this prop controls the alignment of the scrolled to item. One of: 'start', 'center', 'end' or 'auto'. Use 'start' to always align items to the top of the container and 'end' to align them bottom. Use 'center' to align them in the middle of the container. 'auto' scrolls the least amount possible to ensure that the specified scrollToIndex item is fully visible.
stickyIndices Number[] An array of indexes (eg. [0, 10, 25, 30]) to make certain items in the list sticky (position: sticky)
overscanCount Number Number of extra buffer items to render above/below the visible items. Tweaking this can help reduce scroll flickering on certain browsers/devices.
estimatedItemSize Number Used to estimate the total size of the list before all of its items have actually been measured. The estimated total height is progressively adjusted as items are rendered.
onItemsRendered Function Callback invoked with information about the slice of rows/columns that were just rendered. It has the following signature: ({startIndex: number, stopIndex: number}).
onScroll Function Callback invoked whenever the scroll offset changes within the inner scrollable region. It has the following signature: (scrollTop: number, event: React.UIEvent<HTMLDivElement>).

* Width may only be a string when scrollDirection is 'vertical'. Similarly, Height may only be a string if scrollDirection is 'horizontal'

Public Methods

recomputeSizes (index: number)

This method force recomputes the item sizes after the specified index (these are normally cached).

VirtualList has no way of knowing when its underlying data has changed, since it only receives a itemSize property. If the itemSize is a number, this isn't an issue, as it can compare before and after values and automatically call recomputeSizes internally. However, if you're passing a function to itemSize, that type of comparison is error prone. In that event, you'll need to call recomputeSizes manually to inform the VirtualList that the size of its items has changed.

Common Issues with PureComponent

react-tiny-virtual-list uses PureComponent, so it only updates when it's props change. Therefore, if only the order of your data changes (eg ['a','b','c'] => ['d','e','f']), react-tiny-virtual-list has no way to know your data has changed and that it needs to re-render.

You can force it to re-render by calling forceUpdate on it or by passing it an extra prop that will change every time your data changes.

Reporting Issues

Found an issue? Please report it along with any relevant details to reproduce it. If you can, please provide a live demo replicating the issue you're describing. You can fork this Code Sandbox as a starting point.

Contributions

Feature requests / pull requests are welcome, though please take a moment to make sure your contributions fits within the scope of the project. Learn how to contribute

Acknowledgments

This library draws inspiration from react-virtualized, and is meant as a bare-minimum replacement for the List component. If you're looking for a tiny, lightweight and dependency-free list virtualization library that supports variable heights, you're in the right place! If you're looking for something that supports more use-cases, I highly encourage you to check out react-virtualized instead, it's a fantastic library โค๏ธ

License

react-tiny-virtual-list is available under the MIT License.

react-tiny-virtual-list's People

Contributors

aymericbouzy avatar clauderic avatar dependabot[bot] avatar gabrielecirulli avatar kakadiadarpan avatar megahertz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-tiny-virtual-list's Issues

Horizontal overflow is being cut off

Hello!

I'm trying to incorporate this library into an application I'm building and I'm running in to issues with content that is larger than the original viewport. Currently, I have it set to overflow-x: scroll but it is being overwritten (or in conflict with) overflow: auto. When I render the page and scroll to the right, I see:

image

However, when I remove the overflow: auto property with Chrome DevTools, it appears to render and react like I would expect, and I see no discernible difference in performance.

I'm not sure if this is an "Issue" with the library, an issue with how I have my CSS and HTML structured, or somewhere in between. Ideally, I'd like to be able to customize the overflow property with a prop. If that's something that would be beneficial elsewhere, I can gladly write up a PR for it!

CSS `will-change` causing position problems

Hey, thanks for the great tiny module.

There is a small problem in case there are elements with position: fixed inside the virtualized list (container) which is settings will-change: transform. According to the 2 links below the elements with position: fixed will become relative to the element with the transform - not relative to the viewport, in this case to the virtualized container.

I am not sure what is the purpose of will-change: transform style. But for now I overwrote the style by setting will-change: unset

The below links I wrote above:
(Stackoverflow) CSS: position:fixed inside of position:absolute
W3C transform-rendering

Sticky rows

This project has been super helpful implementing virtualization in our React UI Framework (http://evergreen.surge.sh/).

Recently we wanted to create a select menu with grouped options: segmentio/evergreen#190
image

I flatten the options and things work fine. However the usability drawback is that the option headers are not sticky at the top of the list. They scroll like any other item.

I am currently exploring two options, either biting the bullet and using react-virtualized. Or, extend react-tiny-virtual-list. Or, find a different solution all together.

I understand wanting to keep the API simple and focused, I was wondering if this seems like a reasonable thing to extend in react-tiny-virtual-list. If that is the case, I will dig deeper into the code and see how to implement it.

getTotalSize when using itemSize array.

When I learned itemSize can be a getter or array โ€” I was hoping the array approach would help with the getTotalSize function and reduce the total height of the container โ€” instead of estimating it.

In of our use cases the heights for each row are much different, resulting in janky scrolling and poor estimates for the total height.

The below example is just me trying to explain what I mean. The actual implementation might be different, for example, it might make sense to determine this in the constructor and updateConfig โ€” as well as have some caching.

/**
   * Total size of all items being measured.
   * This value will be completedly estimated initially.
   * As items as measured the estimate will be updated.
   * ---
   * When itemSizeGetter is an array, use it to determine the total height.
   */
  getTotalSize(): number {
    const lastMeasuredSizeAndPosition = this.getSizeAndPositionOfLastMeasuredItem();

    // Just an example.
    if (Array.isArray(this.itemSizeGetter)) {
      return this.itemSizeGetter.reduce((acc, currentValue) {
        return acc + currentValue
      }, 0)
    }

    return (
      lastMeasuredSizeAndPosition.offset +
      lastMeasuredSizeAndPosition.size +
      (this.itemCount - this.lastMeasuredIndex - 1) * this.estimatedItemSize
    );
  }

@clauderic do you have any thoughts around this? I wouldn't mind passing a property to accomplish this either. Potentially we can do the same if itemSizeGetter is a function.

Update

Looking at the code it seems that itemSizeGetter is always a function within the component:

  itemSizeGetter = (itemSize: Props['itemSize']) => {
    return index => this.getSize(index, itemSize);
  };

I am currently trying out adding a preCalculateTotalHeight bool prop in my fork.

setState in onItemsRendered

I need to keep track of which items are visible outside of the VirtualList component. However, if I call setState in onItemsRendered, then React will correctly complain:

Warning: Cannot update during an existing state transition (such as within `render` or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to `componentWillMount`.

Is there are correct pattern for this? Ideally VirtualList would have a renderProp style prop that could look like ({ RenderedListNode, startIndex, endIndex}) => Node.

This is the code, it works in this simple example but causes the React warning and issues in more complicated code:

// @flow

import React from "react";
import VirtualList from "react-tiny-virtual-list";

const data = Array(1000)
  .fill(0)
  .map((item, index) => index);

type Props = {};

type State = {
  currentlyVisibleIndex: number,
};

class Test extends React.Component<Props, State> {
  state = { currentlyVisibleIndex: 0 };

  onItemsRendered = ({ startIndex, stopIndex }) => {
    const { currentlyVisibleIndex } = this.state;
    if (currentlyVisibleIndex !== startIndex) {
      this.setState({ currentlyVisibleIndex: startIndex });
    }
  };

  render() {
    const { currentlyVisibleIndex } = this.state;

    return (
      <div>
        <div>Currently Visible: {currentlyVisibleIndex}</div>
        <VirtualList
          width="100%"
          height={600}
          itemCount={data.length}
          itemSize={50}
          overscanCount={0}
          renderItem={({ index, style }) => (
            <div key={index} style={style}>
              {data[index]}, Row: #{index}
            </div>
          )}
          onItemsRendered={this.onItemsRendered}
        />
      </div>
    );
  }
}

export default Test;

when render item with image

Hi @clauderic ,thanks for your great work.

Recently , I've used tiny list to render a list that each item contains a different image .
And there is a blink of image between the replacement of inner element

could you please cast some light? I still want to use this package to improve huge list render performance, but the blink is unacceptable for a production app.

Thanks
Any help will be appreciated

enum ALIGNMENT needs exported to pass values to scrollToAlignment prop with TypeScript

Hello ย ๐Ÿ™‚

I am using react-tiny-virtual-list in a real-world TypeScript project.

Apparently the type of scrollToAlignment prop has changed from string in v2.1.4 to enum ALIGNMENT in v2.2.0 and scrollToAlignment props which is not available at the moment in TypeScript because enum ALIGNMENT is not exported in index.d.ts

I could only use scrollToAlignment prop with a value of appropriate type namely enum ALIGNMENT as follows:

in some-project > node_modules/react-tiny-virtual-list/types/index.d.ts

export { DIRECTION as ScrollDirection, ALIGNMENT as scrollAlignment } from './constants';

in some-project > some-component

<VirtualList
    width="99%"
    height={100}
    itemCount={5}
    itemSize={30}
    scrollToIndex={0}
    renderItem={doSomething}
    scrollToAlignment={scrollAlignment.AUTO}
    onItemsRendered={doSomething}
/>

Appreciated if scrollToAlignment is available to use in TypeScript in v2.2.0.

I made the following PR to offer a solution to this issue:
https://github.com/clauderic/react-tiny-virtual-list/pull/69

Rationale for using PureComponent

Is there a reason why VirtualList extends PureComponent instead of Component?

In my use case (a checkbox list) I find that I have to re-generate the renderItem prop in order to fool the virtual list into re-rendering itself.

I think it would make more sense to use Component, and let the user decide when and how to "purify" its rendering based on some state change.

Alternately, a pure prop that defaulted to true (in order to keep VirtualList backward compatible) could be added to return a component of the corresponding type.

Issues with the list when attaching to iOS homescreen

Hey, I am experiencing some issues with the list when attaching to iOS homescreen. Not sure if I should file a bug as I read it might be better to talk about it here first. I made a video of the issue using iPad mini 2:

iPad Screencast: https://youtu.be/KIDnUovmGVo
Example: https://pymwymi.io/clusterizejs/reactjs/index.html
Code: https://gist.github.com/Shaked/6b9d7e22a0b8ef3b5754c017fad4cf33

Thank you,
Shaked

P.S
I also tried to create the same example without ReactJS and experienced similar issues:
NeXTs/Clusterize.js#130
Maybe it's a iOS/Safari bug?

TypeScript definition files as part of NPM package

First off - great work!!! I'd like to use this library with TypeScript, and seeing how it appears that it was recently migrated to TypeScript would you please include the TypeScript definition file as part of the NPM package?

Should `height` actually be `max-height`?

There's a way to set a custom height for the list. This property is used to set the height in css.
Would it make sense to change it for max-height?

I could eventually do something like this. But the lib should probably do it?

height={Math.min(items.length * 50, 300)}

Height of item

Can I set height of my item is dynamically.?
This depency is good I got more 1000 data is works fine.
But when i resize my window to min-wid. If line to ling the go to nextLine so the height of item broken.
U say height item can be set with function. If cannt set dynamically can u gift some example to use function for height of item

Error when running dev

image

Node: 8.9.1
npm: 5.5.1
tsc: 2.7.2

Doing clean install;

$ git clone [email protected]:clauderic/react-tiny-virtual-list.git
$ cd react-tiny-virtual-list
$ npm install
$ npm start

After set scrollToIndex, itemSize of previous indexes get wrong (Using previously cached item)

Here is my code snippet

In Render

        let { collections } = this.props;
       
        console.log( collections[2].isCollapse, 'collapsed');  // will print **true** (it was **false** previously but changed to **true** by dispatching action)

        let calculateItemSize = (i)=> {

            console.log(i, collections[2].isCollapse, 'collapsed') // will print **false** 

            let minLength = 1;
            if(collections[i].tabs.length){
                minLength = collections[i].tabs.length;
            }
            return collections[i].isCollapse ? (Math.round(minLength / 2) * 50) + 100 : 70;
        }

<VirtualList
     itemSize={ calculateItemSize }
     scrollToIndex={ 5 }
     ...
/>

I'm collapsing the div and accordingly height also get changed in virtual list, now what happen here is height works fine when starting index starts from 0 but once I set scrollToIndex=5 then item from index 0 to 5 will behave totally opposite in nature. like open collapse with reduced height and close will increase height.

By debugging the library I found that after set manual scroll index It will use previous cached data to manipulate itemSize logic. please review the above code snippet with comment.

thank you :)

Set initial scrollOffset Not working

Hi Now i use react-infinite-calendar.An when i click to show in modal calendar is work fine.But have just a problem.Is initial scrollOffset not set initial scroll position for calendar.I try to Debug in this repo but scrollOffset have value when component mount.

thank you

scrollToIndex and itemSize (caching?) issues

Hi thanks for this awesome library!

I am experiencing an odd issue (possibly a bug). When using scrollToIndex and resizing a (vertical) list the row styles seem to be incorrect. Specifically height and top seem to be wrong.

I prepared a simple testcase for you to try out https://codesandbox.io/s/3wm42q716
When clicking the ๐Ÿ’ฅ button the list resizes (itemSize changes) and the height of all rows up to the scrollToIndex are wrong.

Do you have any idea of what it is going on?

Warnings when using custom prop to force update

I am using a custom prop to force my list to re-render, as recommended in the readme. However, doing so causes me this warning:

Warning: React does not recognize the isScrolling prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase isscrolling instead. If you accidentally passed it from a parent component, remove it from the DOM element.

(my prop is called isScrolling)

Scrolling with keyboard

Hi, can you please implement a feature to allow scroll with pg down, pg up, home, end and arrows?
Since the rows are rendered out of the DOM the focus is lost and its impossible to use it.
Please add feature to set focus automatically on row render

es.js in build directory breaks webpack compilation

ERROR in main.bundle.js from UglifyJs
Unexpected token: punc ([) [./~/react-tiny-virtual-list/build/react-tiny-virtual-list.es.js:43,0][main.bundle.js:25816,4]

Please remove this - even with the latest uglifyJs webpack plugin with es6 support it fails

LICENSE file

Hi there and thanks for this great project!

We have a script that scans for licenses and if you'd add a LICENSE file with the actual MIT license that would make our life a lot easier! I can open a PR as well but figured you might want to do that yourself to be the creator of that one.

Thanks!

Perf

Hi @clauderic, thanks for this library!

I'm having a few performance issues which seem to be caused by onScroll triggering a setState which triggers a re-render. Here's a capture of scrolling through a list with a renderItem that only render simple <span>Hi</span>-items:

image

For reference, this is using the dev build of React 15.6.1, with 6x CPU slowdown.

This can be improved by adding the scroll listener as a passive event listener instead of using onScroll (AFAIK React does not support specifying events as passive using on*-props, so it must be set up in componentDidMount).

Additionally, to increase performance even more the VirtualList component could support a debounce-prop, which takes a number of milliseconds to debounce the handleScroll method with.

Would you be interested in a PR for this?

Vibrating scrollbar in nested lists

I have this problem with my list actually this is my render funct:

<div style={{ height: '100%', overflow: 'hidden' }}>
              {(budget && budget.length && !fetching) && (
                <VirtualList
                  itemCount={budget.length}
                  height={height //this belong to clientHeight}
                  renderItem={this.renderChild(null)}
                  itemSize={(index => heights[index] || 24)}
                />
              )}
</div>

and this is renderChild:

<Collapse style={{ height: 200, overflowY: 'auto' }} isOpen={toggles[realId]}>
          {(toggles[realId] && nextData) && (
            <div>
              <VirtualList
                itemCount={nextData.length}
                height={200}
                renderItem={this.renderBudget(nextData)}
                itemSize={(index => heights[index] || 24)}
              />
            </div>
          )}
</Collapse>

well this is what happen when i scroll down the list of collapsable data:
Gif

Scroll lagging/slow performance

Hi,

This looks like a great little add on (only 3kb's!).

I'm having some difficultly implementing. I tried following your example, but had no success. T

I had some success. But performance isn't great. The scroll is laggy. I've probably implemented it wrong.

See here https://codesandbox.io/s/vo1xjpxrL

Here's the code:

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      demoData: x.demoData,
    };
  }
  render() {
    return (
        <VirtualList
    width='100%'
    height={800}
    itemCount={this.state.demoData.length}
    itemSize={50}
    renderItem={({index, style}) =>
      <div style={style} key={index}> 
{this.state.demoData.map(e => {
          return <Result e={e}/>;
        })[index]}
      </div>
    }
  />

    );
  }
}

class Result extends React.Component {
  render() {
    const { e, remove } = this.props;

    return (
      <div key={e.id}>
        {e.name} {' '} {e.id}
      </div>
    );
  }
}

Cheers,

Dynamic inserting does not work

I have a reproduction of the issue here: https://www.webpackbin.com/bins/-KgWJv_0IC1-9cyvzud8

As you can see from the comment inside Hello.js, the list only renders the items initially populated inside the provided list. If you update that list after the VirtualList is rendered, it does not re-render to reflect those changes.

I'm trying to use this component for an insert-heavy project, does this library not support dynamic inserting? If not, is this something you are wanting to support?

className support [feature request]

I was trying to hide/style scrollbars on Windows/Chrome but I noticed that my className is swallowed and not applied!

    //in @injectSheet
    tbody: {
        width: '100%',
        '&::-webkit-scrollbar': {
            width: 0, // remove scrollbar space
            background: 'transparent', // make scrollbar invisible
        },
    },

   //in render
        <VirtualList
            id={'tableBody'}
            className={classes.tbody} //my class with styles for scrollbars here in classes.tbody
            height={tbodyHeight}
            ....

[Question] Max height div

I am running some tests as to render lists with 100kโ€“1m rows. It seems that browsers have a max height for divs: 1.67771e+07px for me on Chrome Mac. It seems that react-virtualized somehow handles it. This is very much an edge-case, but just curious if anyone is aware of this? Feel free to close issue.

1.67771e+07px => 16,777,100px

Use window as container instead of element

Is it possible to use the window as the container element, so it increases the height of the main scrollbar, rather than having the table in a container with its own scrollbar?

It appears react-virtual-list does this, but it requires fixed height elements.

Get index of top/last visible element on scroll

Here on onScroll event we're getting top, event in callback function.
Is there any way to get the index of Top or Bottom visible element?

something like

onScroll(top, event, topIndex, bottomIndex){

}

I have to force render the list again, if the list item heights are dynamic

  1. The list item heights are dynamic and are only known after their first render, so I collect the heights in the list item componentDidMount() and cache the heights.
  2. The list props itemSize={this.getItemSize} returns the cached heights.
  3. However itemSize is invoked before step 1 (it is invoked inside this.getStyle(index)), so the first list render gets the wrong height.
  4. So I now have to do recomputeSizes() and forceUpdate() in the list componentDidUpdate to trigger itemSize again, so that the correct height could be used.
  5. The list items are like varying length texts and images; I'm building a chat history list.

The question: is this necessary? I'd like to know if it's a must to always render twice since the item height can't be known in the first render?

My codes are below for reference:

  componentDidUpdate(prevProps, prevState, snapshot) {
    //...based on some conditions I do the following
    this.li.recomputeSizes();
    this.li.forceUpdate();
  }
  getItemSize = (index) => {
    const { chatObjects } = this.props;
    const chatObject = chatObjects[index];
    return this.heightCache[chatObject.messageId] || 40;
  }
  renderItem = ({ index, style }) => {
    const { chatObjects } = this.props;
    const chatObject = chatObjects[index];
    return (
      <div key={chatObject.messageId} style={style}>
        <ChatObject
          key={chatObject.messageId}
          chatObject={chatObject}
          onDidMount={(height) => { this.heightCache[chatObject.messageId] = height; }}
          onDidUpdate={(height) => { this.heightCache[chatObject.messageId] = height; }}
        />
      </div>
    );
  }
  render() {
    return (
          <VirtualList
            ref={this.addVirtualList}
            width={width}
            height={height}
            itemCount={chatObjects.length}
            itemSize={this.getItemSize}
            renderItem={this.renderItem}
            onItemsRendered={this.onItemsRendered}
            onScroll={this.onScroll}
            {...scrollToIndex}
            overscanCount={20}
          />
    );
  }

[Feature-Request] Loader

Hello, react tiny virtual list is running good, but I miss a loader component because when you scroll too fast appear a blank screen until load more items but scrolling is working pretty fast, I think don't need to implement the loader itself, just implement a prop to receive the loader or an callback to render the loader, that would be fine. Thanks!

not support commonjs require syntax

I tried to include it with require syntax like:
const VirtualList = require('react-tiny-virtual-list');

then use it in render method

render() {
    return (
      <div className="Root">
        <VirtualList
          width="auto"
          height={400}
          itemCount={1000}
          renderItem={this.renderItem}
          itemSize={50}
          className="VirtualList"
        />
      </div>
    );
  }

And got the following error from Chrome logs:
warning.js:33 Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.

get height from element style [feature request]

What about adding the possibility to not give an "height" prop and derive it from element.style.height?

Use case:

I already deal with height in my classes for proper UI and it's redundant to add the logic twice into renderer.

@withWindowSize //HOC passing window height and width
@injectSheet(theme => ({
   tbody: ({ windowHeight }) => ({
      width: '100%',
      height: windowHeight - headerHeight - theadHeight,
   }),
}))
export default class Table extends React.Component {
....
       render = () => {
            const { windowHeight, classes } = this.props; //windowHeight from HOC not needed!
            const { items } = this;

             const tbodyHeight = windowHeight - headerHeight - theadHeight; //AGAIN!
    
             return (
                 <VirtualList
                    className={classes.tbody} //here element has already proper style.height applied
                    height={tbodyHeight}
                    .... 
                  />
              );
         }
}

scrollToIndex not work in ReactDOM.createPortal ?

When i use ReactDOM.createPortal and react-motion render VirtualList, and scrollToIndex > 20
It not works!
2017-12-06 21_55_08

I console rootNode.offsetHeight, is zero.(https://github.com/clauderic/react-tiny-virtual-list/blob/master/src/index.tsx#L223)

// this.rootNode[scrollProp[scrollDirection]] 0
console.log('this.rootNode[scrollProp[scrollDirection]]', this.rootNode[scrollProp[scrollDirection]].offsetHeight)

And in chorme, it render success.
image

what happen?

TimePickerOption.styled

import styled from 'styled-components'
import { clearFix } from 'polished'
import mainColor, { black, bd, bg, greenLightnessBg } from 'resources/styles/color.styled'

export default styled.div`
    position: relative;
    float: left;
    ${({ type }) => (type !== 'hour' ? `
        border-left: 1px solid ${bd};
    ` : '')};
    ${clearFix()};
`
import React, { Component } from 'react'
import VirtualList from 'react-tiny-virtual-list'
import Wrap from '../TimePickerOption.styled'
import Option from './Option'

export default class Options extends Component<DefaultProps, Props, void> {
    defaultProps: DefaultProps
    props: Props
    renderItem: Function
    static displayName = 'Options'
    static defaultProps = {
        type: 'hour'
    }
    constructor (props: Object) {
        super(props)
        this.renderItem = this.renderItem.bind(this)
    }
    getSelectedIndex (): number {
        const options = this.props.type === 'hour' ? hours : secsMins
        return options.findIndex(value => (value === this.props.selected))
    }
    renderItem (config: {
        index: number,
        style: Object
    }) {
        const { onChange, type, selected } = this.props
        const { index, style } = config
        const option = type === 'hour' ? hours[index] : secsMins[index]
        return (
            <Option
                key={`Option_${option}`}
                style={style}
                value={option}
                onClick={onChange}
                active={selected === option}
            />
        )
    }
    render () {
        const { type } = this.props
        const optionCount = type === 'hour' ? hours.length : secsMins.length
        return (
            <Wrap type={type}>
                <VirtualList
                    width={60}
                    height={5 * 27}
                    itemCount={optionCount}
                    itemSize={27}
                    renderItem={this.renderItem}
                    scrollToIndex={this.getSelectedIndex()}
                />
            </Wrap>
        )
    }
}

package.json

    "react": "^16.2.0",
    "react-dom": "^16.2.0",
    "react-hot-loader": "3.1.2",
    "react-motion": "^0.5.2",
    "react-router": "^4.2.0",
    "react-router-dom": "^4.2.2",
    "react-router-transition": "^1.1.2",
    "react-tiny-virtual-list": "^2.1.4",

CSS Scroll Direction Support

I am using this lovely component and have used the prop scrollDirection="horizontal".
However, I am also wanting to change the CSS prop direction: rtl so that the scroll direction begins on the right.

When the VirtualList component renders initially with that CSS property set it renders blank contents until I scroll a little bit...which causes the component to update so it knows where to place the relevant DOM.

Do you have any recommendations on how I can fix this blank blip?
Nice-to-have would be to some how have the overscanCount know about this change in the content flow.

Video file to help explain my issue/request.

Jan-22-2018 15-58-53.mp4.zip

Height 100%

Hi! I'm not a 100% sure if this is an actual issue, or if I'm just using it wrong, but I have a variable-height container in which I render a VirtualList with its height set to "100%". This renders only the first item plus the overscanCount.

Here's an example of what I'm seeing, I've changed two things after forking your example, I've set the height of #root to 500px and I've set the height of VirtualList to 100%: https://codesandbox.io/s/nr91pm8mx0

Could you advise me if this is actually a bug, or if I'm doing something stupid?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.