• Stars
    star
    151
  • Rank 238,324 (Top 5 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 6 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

React container that will auto scroll to bottom

react-scroll-to-bottom

npm version Node.js CI

React container that will auto scroll to bottom or top if new content is added and viewport is at the bottom, similar to tail -f. Otherwise, a "jump to bottom" button will be shown to allow user to quickly jump to bottom.

Demo

Try out the demo at https://compulim.github.io/react-scroll-to-bottom/.

Demo

Breaking changes

[3.0.0] - 2020-06-21

  • scrollToBottom/scrollToEnd/scrollToStart/scrollToTop now accept an option { behavior: 'auto' | 'smooth' }
    • Without the option, it is by default to artificial smooth scrolling (smooth), to keep existing behavior
    • This behavior may change in the future, by defaulting to discrete scrolling (auto), to better align with HTML DOMElement.scrollIntoView standard
    • During the transition, please always pass { behavior: 'smooth' } to keep existing behavior

[2.0.0] - 2020-05-07

  • Starting from react-scroll-to-bottom@2, we requires React 16.8.6 or above. This enable developers to use React Hooks to add features to the scroll view.

Sample code

import { css } from 'emotion';
import ScrollToBottom from 'react-scroll-to-bottom';

const ROOT_CSS = css({
  height: 600,
  width: 400
});

export default props => (
  <ScrollToBottom className={ROOT_CSS}>
    <p>
      Nostrud nisi duis veniam ex esse laboris consectetur officia et. Velit cillum est veniam culpa magna sit
      exercitation excepteur consectetur ea proident. Minim pariatur nisi dolore Lorem ipsum adipisicing do. Ea
      cupidatat Lorem sunt fugiat. Irure est sunt nostrud commodo sint.
    </p>
    <p>
      Duis consectetur ad in fugiat et aliquip esse adipisicing occaecat et sunt ea occaecat ad. Tempor anim consequat
      commodo veniam nostrud sunt deserunt adipisicing Lorem Lorem magna irure. Eu ut ipsum magna nulla sunt duis Lorem
      officia pariatur. Nostrud nisi anim nostrud ea est do nostrud cupidatat occaecat dolor labore do anim. Laborum
      quis veniam ipsum ullamco voluptate sit ea qui adipisicing aliqua sunt dolor nulla. Nulla consequat sunt qui amet.
      Pariatur esse pariatur veniam non fugiat laboris eu nulla incididunt.
    </p>
    <p>
      Laboris duis do consectetur aliquip non aliquip ad ad quis minim. Aute magna tempor occaecat magna fugiat culpa.
      Commodo id eiusmod ea pariatur consequat fugiat minim est anim. Ipsum amet ipsum eu nisi. Exercitation minim amet
      incididunt tempor do ut id in officia eu sit est. Dolor qui laboris laboris tempor sunt velit eiusmod non ipsum
      exercitation ut sint ipsum officia.
    </p>
  </ScrollToBottom>
);

We use glamor for component styles. It is not required, but we don't support style props for performance reason.

Props

Name Type Default Description
checkInterval number 150 Recurring interval of stickiness check, in milliseconds (minimum is 17 ms)
className string Set the class name for the root element
debounce number 17 Set the debounce for tracking the onScroll event
debug bool NODE_ENV === 'development' Show debug information in console
followButtonClassName string Set the class name for the follow button
initialScrollBehavior string smooth Set the initial scroll behavior, either "auto" (discrete scrolling) or "smooth"
mode string "bottom" Set it to "bottom" for scroll-to-bottom, "top" for scroll-to-top
nonce string Set the nonce for Content Security Policy
scroller function () => Infinity A function to determine how far should scroll when scroll is needed
scrollViewClassName string Set the class name for the container element that house all props.children

Hooks

You can use React Hooks to perform various operations and signal state changes. The component which use the hook must stay under <ScrollToBottom> or <Composer>.

Category Name Type Description
Function useScrollTo () => (scrollTop: number | '100%') => void Scroll panel to specified position
Function useScrollToBottom () => () => void Scroll panel to bottom
Function useScrollToEnd () => () => void Scroll panel to end (depends on mode)
Function useScrollToStart () => () => void Scroll panel to start (depends on mode)
Function useScrollToTop () => () => void Scroll panel to top
Observer useObserveScrollPosition (observer: (({ scrollTop: number }) => void) | false) => void Observe scroll position change by passing a callback function
State useAnimating () => [boolean] true if the panel is animating scroll effect
State useAnimatingToEnd boolean true if the panel is animating scroll effect and towards the end (depends on mode)
State useAtBottom () => [boolean] true if the panel is currently near bottom
State useAtEnd () => [boolean] true if the panel is currently near the end (depends on mode)
State useAtStart () => [boolean] true if the panel is currently near the start (depends on mode)
State useAtTop () => [boolean] true if the panel is currently near top
State useMode () => [string] "bottom" for scroll-to-bottom, "top" for scroll-to-top
State useSticky () => [boolean] true if the panel is sticking to the end

Callback function passed to useObserveScrollPosition will be called rapidly during scrolling. To unsubscribe, pass a falsy value.

Sample code

The following sample code will put a button inside the content view only if the view is not at the bottom. When the button is clicked, it will scroll the view to the bottom.

Note: useScrollToBottom can only be called inside components hosted under <ScrollToBottom>.

import ScrollToBottom, { useScrollToBottom, useSticky } from 'react-scroll-to-bottom';

const Content = () => {
  const scrollToBottom = useScrollToBottom();
  const [sticky] = useSticky();

  return (
    <React.Fragment>
      <p>
        Labore commodo consectetur commodo et Lorem mollit voluptate velit adipisicing proident sit. Dolor consequat
        nostrud aliquip ea anim enim. Culpa quis tempor et quis esse proident cupidatat reprehenderit laborum ullamco.
      </p>
      <p>
        Incididunt labore nulla cupidatat occaecat elit esse occaecat culpa irure et nisi excepteur. Duis Lorem labore
        consectetur nostrud et voluptate culpa consequat enim reprehenderit. Id voluptate occaecat anim consequat id ea
        eiusmod laborum proident irure veniam esse. Aliquip nostrud culpa nostrud laborum cillum adipisicing dolore. Est
        tempor labore Lorem ad cupidatat reprehenderit exercitation pariatur officia ex adipisicing cupidatat
        exercitation.
      </p>
      <p>
        Est labore cupidatat exercitation est laboris et tempor Lorem irure velit ea commodo sint officia. Ullamco
        exercitation cillum est fugiat do. Enim qui eu veniam nostrud tempor elit. Duis elit mollit ut reprehenderit sit
        adipisicing proident culpa veniam sint veniam consectetur fugiat Lorem. Sint dolor proident commodo proident non
        cupidatat labore.
      </p>
      {!sticky && <button onClick={scrollToBottom}>Click me to scroll to bottom</button>}
    </React.Fragment>
  );
};

export default () => (
  <ScrollToBottom>
    <Content />
  </ScrollToBottom>
);

Context

Starting with React Hooks, we are deprecating the React Context. New functions may not be added to context.

We use 2 different contexts with different performance characteristics to provide better overall performance. Function context contains immutable functions. State context may change when the user scroll the panel.

Function context

This context contains functions used to manipulate the container. And will not update throughout the lifetime of the composer.

Name Type Description
scrollTo (scrollTop: number | '100%') => void Scroll panel to specified position
scrollToBottom () => void Scroll panel to bottom
scrollToEnd () => void Scroll panel to end (depends on mode)
scrollToStart () => void Scroll panel to start (depends on mode)
scrollToTop () => void Scroll panel to top

State context

This context contains state of the container.

Name Type Description
animating boolean true if the panel is animating scroll effect
animatingToEnd boolean true if the panel is animating scroll effect and towards the end (depends on mode)
atBottom boolean true if the panel is currently near bottom
atEnd boolean true if the panel is currently near the end (depends on mode)
atStart boolean true if the panel is currently near the start (depends on mode)
atTop boolean true if the panel is currently near top
mode string "bottom" for scroll-to-bottom, "top" for scroll-to-top
sticky boolean true if the panel is sticking to the end

atEnd and sticky are slightly different. During scroll animation, the panel is not at the end yet, but it is still sticky.

Sample code

The following sample code will put a button inside the content view only if the view is not at the bottom. When the button is clicked, it will scroll the view to the bottom.

import ScrollToBottom from 'react-scroll-to-bottom';

const Content = ({ scrollToBottom, sticky }) => {
  return (
    <React.Fragment>
      <p>
        Labore commodo consectetur commodo et Lorem mollit voluptate velit adipisicing proident sit. Dolor consequat
        nostrud aliquip ea anim enim. Culpa quis tempor et quis esse proident cupidatat reprehenderit laborum ullamco.
      </p>
      <p>
        Incididunt labore nulla cupidatat occaecat elit esse occaecat culpa irure et nisi excepteur. Duis Lorem labore
        consectetur nostrud et voluptate culpa consequat enim reprehenderit. Id voluptate occaecat anim consequat id ea
        eiusmod laborum proident irure veniam esse. Aliquip nostrud culpa nostrud laborum cillum adipisicing dolore. Est
        tempor labore Lorem ad cupidatat reprehenderit exercitation pariatur officia ex adipisicing cupidatat
        exercitation.
      </p>
      <p>
        Est labore cupidatat exercitation est laboris et tempor Lorem irure velit ea commodo sint officia. Ullamco
        exercitation cillum est fugiat do. Enim qui eu veniam nostrud tempor elit. Duis elit mollit ut reprehenderit sit
        adipisicing proident culpa veniam sint veniam consectetur fugiat Lorem. Sint dolor proident commodo proident non
        cupidatat labore.
      </p>
      {!sticky && <button onClick={scrollToBottom}>Click me to scroll to bottom</button>}
    </React.Fragment>
  );
};

export default () => (
  <ScrollToBottom>
    <FunctionContext.Consumer>
      {({ scrollToBottom }) => (
        <StateContext.Consumer>
          {({ sticky }) => <Content scrollToBottom={scrollToBottom} sticky={sticky} />}
        </StateContext.Consumer>
      )}
    </FunctionContext.Consumer>
  </ScrollToBottom>
);

Observing scroll position

You can use useObserveScrollPosition to listen to scroll change.

// This is the content rendered inside the scrollable container
const ScrollContent = () => {
  const observer = useCallback(({ scrollTop }) => {
    console.log(scrollTop);
  }, []);

  useObserveScrollPosition(observer);

  return <div>Hello, World!</div>;
};

If you want to turn off the hook, in the render call, pass a falsy value, e.g. useObserveScrollPosition(false).

Please note that the observer will called very frequently, it is recommended:

  • Only observe the scroll position when needed
  • Don't put too much logic inside the callback function
  • If logic is needed, consider deferring handling using setTimeout or similar functions
  • Make sure the callback function passed on each render call is memoized appropriately, e.g. useCallback

For best practices on handling scroll event, please read this article.

Programmatically pausing scroll

This only works when mode prop is set to bottom (default).

You can pass a function to the scroller prop to customize how far the scrollable should animate/scroll (in pixel) when its content changed. The signature of the scroller function is:

scroller({ maxValue, minValue, offsetHeight, scrollHeight, scrollTop }) => number;
Argument Type Description
maxValue number Maximum distance (in pixel) to scroll
minValue number Minimum distance (in pixel) to scroll, see notes below
offsetHeight number View height of the scrollable container
scrollHeight number Total height of the content in the container, must be equal or greater than offsetHeight
scrollTop number Current scroll position (in pixel)

Note: the scroller function will get called when the scrollable is sticky and the content size change. If the scrollable is not sticky, the function will not be called as animation is not needed.

When the scrollable is animating, if there are new contents added to the scrollable, the scroller function will get called again with minValue set to the current position. The minValue means how far the animation has already scrolled.

By default, the scroller function will returns Infinity. When new content is added, it will scroll all the way to the bottom.

You can return a different value (in number) to indicates how far you want to scroll when the content has changed. If you return 0, the scrollable will stop scrolling for any new content. Returning any values less than maxValue will make the scrollable to lose its stickiness after animation. After the scrollable lose its stickiness, the scroller function will not be called again for any future content change, until the scrollable regains its stickiness.

Security

We support nonce-based Content Security Policy. To enable, the following directive is required:

Road map

  • Easier customization for "scroll to bottom" button
  • Debounce on showing "scroll to bottom" button
  • Investigate using scroll for scrolling and polyfill IE11

Contributions

Like us? Star us.

Want to make it better? File us an issue.

Don't like something you see? Submit a pull request.

More Repositories

1

node-opencc

OpenCC implementation for pure Node.js
JavaScript
56
star
2

web-speech-cognitive-services

Polyfill Web Speech API with Cognitive Services Bing Speech for both speech-to-text and text-to-speech service.
JavaScript
38
star
3

vscode-clock

Displays clock in status bar in Visual Studio Code
JavaScript
27
star
4

docker-msbuild

MSBuild 2017 for Windows Container
27
star
5

react-dictate-button

A button to start dictation using Web Speech API.
JavaScript
23
star
6

lock-walker

Visualize dependency tree in package-lock.json
JavaScript
23
star
7

vscode-mocha

Runs Mocha tests inside Visual Studio Code
JavaScript
21
star
8

react-say

A React component that synthesis text into speech using Web Speech API.
JavaScript
19
star
9

react-sanitized-html

A React component that will sanitize user-inputted HTML code, using the popular sanitize-html package
JavaScript
19
star
10

vscode-chinese-translation

Translates between Traditional Chinese and Simplified Chinese in Visual Studio Code
JavaScript
17
star
11

vscode-express

Hosts current workspace in Express
JavaScript
16
star
12

vscode-indent-4to2

Visual Studio Code extension to convert indentation of tab or 4 spaces into 2 spaces
JavaScript
16
star
13

BotFramework-MockBot

MockBot for testing all features of Web Chat
TypeScript
15
star
14

vscode-closetag

Quickly close last opened HTML/XML tag in Visual Studio Code
JavaScript
14
star
15

vscode-qrcode

Visual Studio Code extension for generating QR code
JavaScript
13
star
16

azure-storage-fs

A drop-in "fs" replacement for accessing Azure Storage with Node.js "fs" API
JavaScript
10
star
17

redux-websocket-bridge

Bridge WebSocket messages and Redux actions
JavaScript
9
star
18

docker-bot

Template for developing bot with Docker and Bot Framework Emulator
JavaScript
9
star
19

generator-azure-web-app

Web site template with React, Webpack, hot module replacement, and Express. MSDeploy to prepare deployment for Azure Web Apps.
JavaScript
9
star
20

vscode-ipaddress

Shows and inserts IP address to Visual Studio Code
JavaScript
8
star
21

acme-http-01-azure-key-vault-middleware

JavaScript
8
star
22

version-from-git

Bump package.json version to pre-release tagged with Git branch and short commit hash, 1.0.0-master.1a2b3c4
JavaScript
8
star
23

azure-webapp-for-containers-template

Template for creating an Azure Web App for Containers with Travis CI
Shell
7
star
24

react-drop-to-upload

A simple React component for "drop-to-upload" feature
JavaScript
6
star
25

docker-nanoserver-node

Windows Server 2016 Nano Server with Node.js
5
star
26

uncork

SSH-over-HTTPS proxy that works like Unix "corkscrew"
JavaScript
5
star
27

azure-blob-ftpd

A FTP server for Azure Storage Blob
JavaScript
5
star
28

webchat-loader

TypeScript
4
star
29

todobot

JavaScript
4
star
30

gm-image-tile

Creates image tiles with Graphicsmagick in Node.js
JavaScript
4
star
31

promise-critical-section

Critical section in Promise fashion
JavaScript
3
star
32

react-wrap-with

Wrap a React component in another component by Higher-Order Component.
TypeScript
3
star
33

botframework-directlinejs-speech

JavaScript
3
star
34

simple-update-in

Immutable update-in with zero dependencies
JavaScript
3
star
35

event-as-promise

Handle continuous steam of events in Promise fashion
JavaScript
3
star
36

template-create-react-app

Set up scaffolding of create-react-app using GitHub Actions
3
star
37

memoize-one-with-dispose

A memoization function with cache of one and disposing function
JavaScript
3
star
38

adaptive-card-loader

Quickly preview an Adaptive Card
JavaScript
3
star
39

vscode-dictionary

Visual Studio Code extension to lookup text in dictionary and thesaurus
JavaScript
3
star
40

template-react-esbuild

Template to build a vanilla React app using ESBuild with preconfigured GitHub workflows.
TypeScript
3
star
41

react-augmentation

DOM augmentation operators to simplify UI code and promote data-driven DOM hierarchy
JavaScript
2
star
42

react-scripts-ts

JavaScript
2
star
43

auto-reset-event

An acquire-release one semantic implemented in Promise.
JavaScript
2
star
44

has-resolved

Checks if a Promise is resolved or rejected asynchronously
JavaScript
2
star
45

rpi-pihole-cloudflared

Shell
2
star
46

opencc-loader

Webpack loader for converting Traditional Chinese into Simplified Chinese (and vice versa).
JavaScript
2
star
47

react-hooks-component-under-babel-standalone

React Hooks component library running under Babel Standalone
JavaScript
2
star
48

use-ref-from

React.useRef with an immediate setter and read-only value.
JavaScript
2
star
49

bookstore

A data storage pattern for Azure Blob Storage
JavaScript
2
star
50

experiment-lerna-esbuild

JavaScript
2
star
51

event-target-shim-es5

ES5 wrapper for event-target-shim
JavaScript
2
star
52

on-error-resume-next

Run a function, synchronously or asynchronously, and ignore errors.
JavaScript
2
star
53

react-component-template

My React component template
JavaScript
2
star
54

react-chain-of-responsibility

Renders family of UI components with strategy and middleware pattern.
TypeScript
2
star
55

use-memo-map

Memoizes calls to array map function similar to React.useMemo.
TypeScript
2
star
56

promise-race-map

Promise.race implementation to works with a JavaScript map
JavaScript
2
star
57

commit-publish

JavaScript
1
star
58

messageport-websocket

Turns HTML MessagePort into HTML WebSocket
JavaScript
1
star
59

electron-ipcmain-messageport

Turns Electron IPCMain into HTML MessagePort
JavaScript
1
star
60

experiment-webchat-react17

JavaScript
1
star
61

use-read-alert

JavaScript
1
star
62

experiment-shim-dljs

Experiment to show how to build a shim of DirectLineJS
JavaScript
1
star
63

botframework-virtual-assistant-demo

Virtual Assistant demo for Bot Framework
JavaScript
1
star
64

BotFramework-Samples-Template

JavaScript
1
star
65

gulp-remotebuild

Gulp plug-in to build Cordova iOS app remotely using Visual Studio Tools for Apache Cordova
JavaScript
1
star
66

docker-iisnode

Dockerfile for iisnode
Batchfile
1
star
67

react-accent-color

Accent color palette for React components
JavaScript
1
star
68

azure-iot-alexa-smart-home-skill

Alexa Smart Home Skill for devices on Azure IoT
JavaScript
1
star
69

travis-encrypt

Simple React web app to encrypt secret for Travis CI
JavaScript
1
star
70

electron-ipcrenderer-messageport

Turns Electron IPCRenderer into MessagePort
JavaScript
1
star
71

use-propagate

Propagates an event to multiple subscribers using React hooks.
TypeScript
1
star
72

experiment-dova-rx-bot-offline

TypeScript
1
star
73

react-scrolling-background

TypeScript
1
star
74

template-mock-bot

Echo bot with built-in token server
TypeScript
1
star
75

experiment-webchat-dialpad

TypeScript
1
star
76

generator-babel-typescript

TypeScript package transpiled with Babel using babel-preset-typescript and works with Jest
JavaScript
1
star
77

botframework-webchat-chat-adapter

TypeScript
1
star
78

botframework-virtual-assistant-template

JavaScript
1
star
79

experiment-github-issue-template

1
star
80

crawl-fs

Recursively crawl the content of a folder
JavaScript
1
star
81

config

Keep my favorites set of configuration
1
star
82

template-webchat-customization

TypeScript
1
star
83

experiment-how-to-use-hooks

TypeScript
1
star
84

experiment-websocket-idle

JavaScript
1
star
85

experiment-fluent-gradient-icon

HTML
1
star
86

redux-saga-demo

JavaScript
1
star
87

websocket-util

Helper utilities for multiple Web Socket packages
JavaScript
1
star
88

experiment-safari-auto-scroll-keyboard

HTML
1
star
89

react-accent-color-testbed

Testbed for react-accent-color
JavaScript
1
star
90

experiment-treeshake-directlinejs

Experiment on tree-shaking botframework-directlinejs
JavaScript
1
star
91

p-defer-es5

ES5 version of p-defer
JavaScript
1
star
92

childprocess-messageport

Turns ChildProcess IPC into MessagePort
JavaScript
1
star
93

childprocess-websocket

Turns ChildProcess IPC into WebSocket
JavaScript
1
star
94

codeaholics-iot-demo

Codeaholics meetup: Alexa + Azure IoT + Arduino
Arduino
1
star
95

app-qr-code-share-target

Shares links/texts as QR Code
CSS
1
star