Skip to content

Automatically scrolls a component to the bottom, unless the user has scrolled up.

License

Notifications You must be signed in to change notification settings

thk2b/autoscroll-react

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

77 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

autoscroll-react

npm version Open Source Love

Install

npm install --save autoscroll-react

What it does

live demo

This package exports a function that takes a React.Component class and returns a React.PureComponent that renders the passed component without any additional markup. It adds the following behaviours to the wrapped component:

  • Whenever the list updates, it is scrolled to the bottom, unless the user has scrolled up.

Suppose the wrapped component is a chat. When a message is added, the chat should be scrolled to the bottom to show the lastest message. But if the user has scrolled up, and a new message is posted by another user, the list should not scroll down to show the new message, as the user is reading another message.

  • If the list is scrolled all the way up and content is added, the current scroll position is preserved.

This feature was added to suport infinite scrolling lists where new content is fetched when the list is scrolled all the way up. Again, consider the case where the wrapped component is a chat. When the user scrolls all the way up, the app (somehow) gets older messages from the server and adds them to the list. By default, the current scroll position of the list is preserved, leading to the the list showing the first of the newly added messages instead of the previous last message. This means the list 'jumps' when content is added to the top of the list. A pragmatic solution to this issue is to scroll down the list by the correct amount when it updates and is scrolled all the way up. But this causes some issues when the list is scrolled all the way up and content is added to the bottom.

Usage

import React from 'react'
import autoscroll from 'autoscroll-react'

import Item from './Item'

class MyList extends React.Component {
    render(){
        const { items, ...props } = this.props
        return (
            <ul { ...props } >{ //  ⚠️ You MUST pass down props, otherwise the event listener will not be attached ⚠️
                items.map(
                    item => <Item 
                        key={ item.id } 
                        {...item}
                    />
                )
            }</ul>
        )
    }
}

export default autoscroll(MyList)

Then, in another file:

import React from 'react'
import MyList from './MyList'

export default ({ items, fetchMoreItems }) => <div>
    <MyList
        items={items} /* pass props directly to your component */
        onScrolledTop={e => fetchMoreItems()} /* add props to be intercepted by autoscroll */
        onScrolled={e => console.log('the list was scrolled')}
    />
    {/* ... */}
</div>

⚠️ caveats ⚠️

  • You must Explicitly pass down props to the wrapped component. This is so an event listener can be attached. This means you can also pass down your own props to the wrapped component by passing them to the component returned by Autoscroll.
  • The wrapped component must be a Class-based component, not a functional one, because Autoscroll uses a ref.
  • This package is agnostic about any CSS you use. However, it assumes that you provide the adequate CSS to make the wrapped component have a scroll bar. (ie. overflow-y:scroll; and a set height)

API

props

The autoscroll higher-order-component supports the followig props

name default description
onScrolled undefined called without arguments whenever the list is scrolled
onScrolledTop undefined called without arguments whenever the list is scrolled to the top

options

When creating a component by calling the autoscroll higher-order-component, an options object can be passed in as the second argument. It may contain the following keys:

name default description
isScrolledDownThreshold 150(px) Used when determining whether the user has scrolled back to the bottom. If the element's scrollBottom is within isScrolledDownThresholdpx of the maximum scroll (scrollHeight), the component will scroll down on the next updates. This option exists because scrolling almost all the way down, but not entirely, can be interpreted as a sign that the user intends to see the bottom of the list. Set it to 0 to enforce scrolling all the way down.

About

Automatically scrolls a component to the bottom, unless the user has scrolled up.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published