{"id":18563283,"url":"https://github.com/compulim/react-scroll-to-bottom","last_synced_at":"2025-04-04T14:05:41.824Z","repository":{"id":32583346,"uuid":"137563573","full_name":"compulim/react-scroll-to-bottom","owner":"compulim","description":"React container that will auto scroll to bottom","archived":false,"fork":false,"pushed_at":"2024-03-16T22:46:31.000Z","size":15024,"stargazers_count":167,"open_issues_count":52,"forks_count":30,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-04-14T05:53:15.665Z","etag":null,"topics":["auto-scrolling","scroll","sticky","tail"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/compulim.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-16T07:50:46.000Z","updated_at":"2024-05-30T23:07:11.373Z","dependencies_parsed_at":"2024-05-30T23:06:46.257Z","dependency_job_id":"811228c2-5e73-4d34-bcde-3a753baedca9","html_url":"https://github.com/compulim/react-scroll-to-bottom","commit_stats":{"total_commits":106,"total_committers":3,"mean_commits":"35.333333333333336","dds":"0.41509433962264153","last_synced_commit":"0a2d7e8206284c94976434c232e2845c21d7b150"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/compulim%2Freact-scroll-to-bottom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/compulim%2Freact-scroll-to-bottom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/compulim%2Freact-scroll-to-bottom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/compulim%2Freact-scroll-to-bottom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/compulim","download_url":"https://codeload.github.com/compulim/react-scroll-to-bottom/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246837684,"owners_count":20841903,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["auto-scrolling","scroll","sticky","tail"],"created_at":"2024-11-06T22:12:15.266Z","updated_at":"2025-04-04T14:05:41.799Z","avatar_url":"https://github.com/compulim.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# react-scroll-to-bottom\n\n[![npm version](https://badge.fury.io/js/react-scroll-to-bottom.svg)](https://badge.fury.io/js/react-scroll-to-bottom) ![Node.js CI](https://github.com/compulim/react-scroll-to-bottom/workflows/Node.js%20CI/badge.svg)\n\nReact 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.\n\n# Demo\n\nTry out the demo at [https://compulim.github.io/react-scroll-to-bottom/](https://compulim.github.io/react-scroll-to-bottom/).\n\n![Demo](https://raw.githubusercontent.com/compulim/react-scroll-to-bottom/master/docs/demo.gif)\n\n# Breaking changes\n\n## [3.0.0] - 2020-06-21\n\n- `scrollToBottom`/`scrollToEnd`/`scrollToStart`/`scrollToTop` now accept an option `{ behavior: 'auto' | 'smooth' }`\n  - Without the option, it is by default to artificial smooth scrolling (`smooth`), to keep existing behavior\n  - This behavior may change in the future, by defaulting to discrete scrolling (`auto`), to better align with HTML `DOMElement.scrollIntoView` standard\n  - During the transition, please always pass `{ behavior: 'smooth' }` to keep existing behavior\n\n## [2.0.0] - 2020-05-07\n\n- 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.\n\n# Sample code\n\n```jsx\nimport { css } from 'emotion';\nimport ScrollToBottom from 'react-scroll-to-bottom';\n\nconst ROOT_CSS = css({\n  height: 600,\n  width: 400\n});\n\nexport default props =\u003e (\n  \u003cScrollToBottom className={ROOT_CSS}\u003e\n    \u003cp\u003e\n      Nostrud nisi duis veniam ex esse laboris consectetur officia et. Velit cillum est veniam culpa magna sit\n      exercitation excepteur consectetur ea proident. Minim pariatur nisi dolore Lorem ipsum adipisicing do. Ea\n      cupidatat Lorem sunt fugiat. Irure est sunt nostrud commodo sint.\n    \u003c/p\u003e\n    \u003cp\u003e\n      Duis consectetur ad in fugiat et aliquip esse adipisicing occaecat et sunt ea occaecat ad. Tempor anim consequat\n      commodo veniam nostrud sunt deserunt adipisicing Lorem Lorem magna irure. Eu ut ipsum magna nulla sunt duis Lorem\n      officia pariatur. Nostrud nisi anim nostrud ea est do nostrud cupidatat occaecat dolor labore do anim. Laborum\n      quis veniam ipsum ullamco voluptate sit ea qui adipisicing aliqua sunt dolor nulla. Nulla consequat sunt qui amet.\n      Pariatur esse pariatur veniam non fugiat laboris eu nulla incididunt.\n    \u003c/p\u003e\n    \u003cp\u003e\n      Laboris duis do consectetur aliquip non aliquip ad ad quis minim. Aute magna tempor occaecat magna fugiat culpa.\n      Commodo id eiusmod ea pariatur consequat fugiat minim est anim. Ipsum amet ipsum eu nisi. Exercitation minim amet\n      incididunt tempor do ut id in officia eu sit est. Dolor qui laboris laboris tempor sunt velit eiusmod non ipsum\n      exercitation ut sint ipsum officia.\n    \u003c/p\u003e\n  \u003c/ScrollToBottom\u003e\n);\n```\n\n\u003e We use [`glamor`](https://github.com/threepointone/glamor/) for component styles. It is not required, but we don't support `style` props for performance reason.\n\n## Props\n\n| Name                      | Type       | Default                      | Description                                                                                                                    |\n| ------------------------- | ---------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |\n| `checkInterval`           | `number`   | 150                          | Recurring interval of stickiness check, in milliseconds (minimum is 17 ms)                                                     |\n| `className`               | `string`   |                              | Set the class name for the root element                                                                                        |\n| `debounce`                | `number`   | `17`                         | Set the debounce for tracking the `onScroll` event                                                                             |\n| `debug`                   | `bool`     | `NODE_ENV === 'development'` | Show debug information in console                                                                                              |\n| `followButtonClassName`   | `string`   |                              | Set the class name for the follow button                                                                                       |\n| `initialScrollBehavior`   | `string`   | `smooth`                     | Set the initial scroll behavior, either `\"auto\"` (discrete scrolling) or `\"smooth\"`                                            |\n| `mode`                    | `string`   | `\"bottom\"`                   | Set it to `\"bottom\"` for scroll-to-bottom, `\"top\"` for scroll-to-top                                                           |\n| `nonce`                   | `string`   |                              | Set the nonce for [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy) |\n| `scroller`                | `function` | `() =\u003e Infinity`             | A function to determine how far should scroll when scroll is needed                                                            |\n| `scrollViewClassName`     | `string`   |                              | Set the class name for the container element that house all `props.children`                                                   |\n| `styleOptions.stylesRoot` | `Node`     | `undefined`                  | Set the container node for component styles to be placed into. When set to `undefined`, will use `document.head`               |\n\n## Hooks\n\nYou can use React Hooks to perform various operations and signal state changes. The component which use the hook must stay under `\u003cScrollToBottom\u003e` or `\u003cComposer\u003e`.\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eCategory\u003c/th\u003e\n      \u003cth\u003eName\u003c/th\u003e\n      \u003cth\u003eType\u003c/th\u003e\n      \u003cth\u003eDescription\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eFunction\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003euseScrollTo\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e() =\u003e (scrollTop: number | '100%') =\u003e void\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eScroll panel to specified position\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eFunction\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003euseScrollToBottom\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e() =\u003e () =\u003e void\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eScroll panel to bottom\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eFunction\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003euseScrollToEnd\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e() =\u003e () =\u003e void\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eScroll panel to end (depends on \u003ccode\u003emode\u003c/code\u003e)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eFunction\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003euseScrollToStart\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e() =\u003e () =\u003e void\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eScroll panel to start (depends on \u003ccode\u003emode\u003c/code\u003e)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eFunction\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003euseScrollToTop\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e() =\u003e () =\u003e void\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eScroll panel to top\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eObserver\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003euseObserveScrollPosition\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e(observer: (({ scrollTop: number }) =\u003e void) | false) =\u003e void\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eObserve scroll position change by passing a callback function\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eState\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003euseAnimating\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e() =\u003e [boolean]\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e if the panel is animating scroll effect\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eState\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003euseAnimatingToEnd\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e if the panel is animating scroll effect and towards the end (depends on \u003ccode\u003emode\u003c/code\u003e)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eState\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003euseAtBottom\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e() =\u003e [boolean]\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e if the panel is currently near bottom\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eState\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003euseAtEnd\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e() =\u003e [boolean]\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e if the panel is currently near the end (depends on \u003ccode\u003emode\u003c/code\u003e)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eState\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003euseAtStart\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e() =\u003e [boolean]\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e if the panel is currently near the start (depends on \u003ccode\u003emode\u003c/code\u003e)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eState\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003euseAtTop\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e() =\u003e [boolean]\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e if the panel is currently near top\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eState\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003euseMode\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e() =\u003e [string]\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e\"bottom\"\u003c/code\u003e for scroll-to-bottom, \u003ccode\u003e\"top\"\u003c/code\u003e for scroll-to-top\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eState\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003euseSticky\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e() =\u003e [boolean]\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e if the panel is sticking to the end\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003e Callback function passed to `useObserveScrollPosition` will be called rapidly during scrolling. To unsubscribe, pass a falsy value.\n\n### Sample code\n\nThe 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.\n\n\u003e Note: `useScrollToBottom` can only be called inside components hosted under `\u003cScrollToBottom\u003e`.\n\n```jsx\nimport ScrollToBottom, { useScrollToBottom, useSticky } from 'react-scroll-to-bottom';\n\nconst Content = () =\u003e {\n  const scrollToBottom = useScrollToBottom();\n  const [sticky] = useSticky();\n\n  return (\n    \u003cReact.Fragment\u003e\n      \u003cp\u003e\n        Labore commodo consectetur commodo et Lorem mollit voluptate velit adipisicing proident sit. Dolor consequat\n        nostrud aliquip ea anim enim. Culpa quis tempor et quis esse proident cupidatat reprehenderit laborum ullamco.\n      \u003c/p\u003e\n      \u003cp\u003e\n        Incididunt labore nulla cupidatat occaecat elit esse occaecat culpa irure et nisi excepteur. Duis Lorem labore\n        consectetur nostrud et voluptate culpa consequat enim reprehenderit. Id voluptate occaecat anim consequat id ea\n        eiusmod laborum proident irure veniam esse. Aliquip nostrud culpa nostrud laborum cillum adipisicing dolore. Est\n        tempor labore Lorem ad cupidatat reprehenderit exercitation pariatur officia ex adipisicing cupidatat\n        exercitation.\n      \u003c/p\u003e\n      \u003cp\u003e\n        Est labore cupidatat exercitation est laboris et tempor Lorem irure velit ea commodo sint officia. Ullamco\n        exercitation cillum est fugiat do. Enim qui eu veniam nostrud tempor elit. Duis elit mollit ut reprehenderit sit\n        adipisicing proident culpa veniam sint veniam consectetur fugiat Lorem. Sint dolor proident commodo proident non\n        cupidatat labore.\n      \u003c/p\u003e\n      {!sticky \u0026\u0026 \u003cbutton onClick={scrollToBottom}\u003eClick me to scroll to bottom\u003c/button\u003e}\n    \u003c/React.Fragment\u003e\n  );\n};\n\nexport default () =\u003e (\n  \u003cScrollToBottom\u003e\n    \u003cContent /\u003e\n  \u003c/ScrollToBottom\u003e\n);\n```\n\n## Context\n\n\u003e Starting with React Hooks, we are deprecating the React Context. New functions may not be added to context.\n\nWe use 2 different contexts with different performance characteristics to provide better overall performance. [Function context](#function-context) contains immutable functions. [State context](#state-context) may change when the user scroll the panel.\n\n### Function context\n\nThis context contains functions used to manipulate the container. And will not update throughout the lifetime of the composer.\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eName\u003c/th\u003e\n      \u003cth\u003eType\u003c/th\u003e\n      \u003cth\u003eDescription\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003escrollTo\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e(scrollTop: number | '100%') =\u003e void\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eScroll panel to specified position\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003escrollToBottom\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e() =\u003e void\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eScroll panel to bottom\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003escrollToEnd\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e() =\u003e void\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eScroll panel to end (depends on \u003ccode\u003emode\u003c/code\u003e)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003escrollToStart\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e() =\u003e void\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eScroll panel to start (depends on \u003ccode\u003emode\u003c/code\u003e)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003escrollToTop\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e() =\u003e void\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eScroll panel to top\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n### State context\n\nThis context contains state of the container.\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eName\u003c/th\u003e\n      \u003cth\u003eType\u003c/th\u003e\n      \u003cth\u003eDescription\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eanimating\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e if the panel is animating scroll effect\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eanimatingToEnd\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e if the panel is animating scroll effect and towards the end (depends on \u003ccode\u003emode\u003c/code\u003e)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eatBottom\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e if the panel is currently near bottom\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eatEnd\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e if the panel is currently near the end (depends on \u003ccode\u003emode\u003c/code\u003e)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eatStart\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e if the panel is currently near the start (depends on \u003ccode\u003emode\u003c/code\u003e)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eatTop\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e if the panel is currently near top\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003emode\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003estring\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e\"bottom\"\u003c/code\u003e for scroll-to-bottom, \u003ccode\u003e\"top\"\u003c/code\u003e for scroll-to-top\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003esticky\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e if the panel is sticking to the end\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003e `atEnd` and `sticky` are slightly different. During scroll animation, the panel is not at the end yet, but it is still sticky.\n\n### Sample code\n\nThe 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.\n\n```jsx\nimport ScrollToBottom from 'react-scroll-to-bottom';\n\nconst Content = ({ scrollToBottom, sticky }) =\u003e {\n  return (\n    \u003cReact.Fragment\u003e\n      \u003cp\u003e\n        Labore commodo consectetur commodo et Lorem mollit voluptate velit adipisicing proident sit. Dolor consequat\n        nostrud aliquip ea anim enim. Culpa quis tempor et quis esse proident cupidatat reprehenderit laborum ullamco.\n      \u003c/p\u003e\n      \u003cp\u003e\n        Incididunt labore nulla cupidatat occaecat elit esse occaecat culpa irure et nisi excepteur. Duis Lorem labore\n        consectetur nostrud et voluptate culpa consequat enim reprehenderit. Id voluptate occaecat anim consequat id ea\n        eiusmod laborum proident irure veniam esse. Aliquip nostrud culpa nostrud laborum cillum adipisicing dolore. Est\n        tempor labore Lorem ad cupidatat reprehenderit exercitation pariatur officia ex adipisicing cupidatat\n        exercitation.\n      \u003c/p\u003e\n      \u003cp\u003e\n        Est labore cupidatat exercitation est laboris et tempor Lorem irure velit ea commodo sint officia. Ullamco\n        exercitation cillum est fugiat do. Enim qui eu veniam nostrud tempor elit. Duis elit mollit ut reprehenderit sit\n        adipisicing proident culpa veniam sint veniam consectetur fugiat Lorem. Sint dolor proident commodo proident non\n        cupidatat labore.\n      \u003c/p\u003e\n      {!sticky \u0026\u0026 \u003cbutton onClick={scrollToBottom}\u003eClick me to scroll to bottom\u003c/button\u003e}\n    \u003c/React.Fragment\u003e\n  );\n};\n\nexport default () =\u003e (\n  \u003cScrollToBottom\u003e\n    \u003cFunctionContext.Consumer\u003e\n      {({ scrollToBottom }) =\u003e (\n        \u003cStateContext.Consumer\u003e\n          {({ sticky }) =\u003e \u003cContent scrollToBottom={scrollToBottom} sticky={sticky} /\u003e}\n        \u003c/StateContext.Consumer\u003e\n      )}\n    \u003c/FunctionContext.Consumer\u003e\n  \u003c/ScrollToBottom\u003e\n);\n```\n\n## Observing scroll position\n\nYou can use `useObserveScrollPosition` to listen to scroll change.\n\n```js\n// This is the content rendered inside the scrollable container\nconst ScrollContent = () =\u003e {\n  const observer = useCallback(({ scrollTop }) =\u003e {\n    console.log(scrollTop);\n  }, []);\n\n  useObserveScrollPosition(observer);\n\n  return \u003cdiv\u003eHello, World!\u003c/div\u003e;\n};\n```\n\n\u003e If you want to turn off the hook, in the render call, pass a falsy value, e.g. `useObserveScrollPosition(false)`.\n\nPlease note that the observer will called very frequently, it is recommended:\n\n- Only observe the scroll position when needed\n- Don't put too much logic inside the callback function\n- If logic is needed, consider deferring handling using `setTimeout` or similar functions\n- Make sure the callback function passed on each render call is memoized appropriately, e.g. `useCallback`\n\nFor best practices on handling `scroll` event, please read [this article](https://developer.mozilla.org/en-US/docs/Web/API/Document/scroll_event).\n\n## Programmatically pausing scroll\n\n\u003e This only works when `mode` prop is set to `bottom` (default).\n\nYou 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:\n\n```js\nscroller({ maxValue, minValue, offsetHeight, scrollHeight, scrollTop }) =\u003e number;\n```\n\n| Argument       | Type     | Description                                                                                |\n| -------------- | -------- | ------------------------------------------------------------------------------------------ |\n| `maxValue`     | `number` | Maximum distance (in pixel) to scroll                                                      |\n| `minValue`     | `number` | Minimum distance (in pixel) to scroll, see notes below                                     |\n| `offsetHeight` | `number` | View height of the scrollable container                                                    |\n| `scrollHeight` | `number` | Total height of the content in the container, must be equal or greater than `offsetHeight` |\n| `scrollTop`    | `number` | Current scroll position (in pixel)                                                         |\n\nNote: 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.\n\nWhen 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.\n\nBy default, the `scroller` function will returns `Infinity`. When new content is added, it will scroll all the way to the bottom.\n\nYou 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.\n\n# Security\n\nWe support nonce-based [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy). To enable, the following directive is required:\n\n- [`style-src 'nonce-XXX'`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src)\n\n# Road map\n\n- [x] Easier customization for \"scroll to bottom\" button\n- [ ] Debounce on showing \"scroll to bottom\" button\n- [ ] Investigate using [`scroll`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scroll) for scrolling and polyfill IE11\n\n# Contributions\n\nLike us? [Star](https://github.com/compulim/react-scroll-to-bottom/stargazers) us.\n\nWant to make it better? [File](https://github.com/compulim/react-scroll-to-bottom/issues) us an issue.\n\nDon't like something you see? [Submit](https://github.com/compulim/react-scroll-to-bottom/pulls) a pull request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcompulim%2Freact-scroll-to-bottom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcompulim%2Freact-scroll-to-bottom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcompulim%2Freact-scroll-to-bottom/lists"}