https://github.com/thekashey/react-stroller
🚶♂️Scroll as you Stroll - the most native custom scrollbars ever made
https://github.com/thekashey/react-stroller
react scroll scrollbar
Last synced: 9 months ago
JSON representation
🚶♂️Scroll as you Stroll - the most native custom scrollbars ever made
- Host: GitHub
- URL: https://github.com/thekashey/react-stroller
- Owner: theKashey
- License: mit
- Created: 2018-05-26T11:41:30.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2024-02-08T05:46:35.000Z (over 2 years ago)
- Last Synced: 2025-01-11T23:47:51.794Z (over 1 year ago)
- Topics: react, scroll, scrollbar
- Language: TypeScript
- Homepage:
- Size: 527 KB
- Stars: 44
- Watchers: 4
- Forks: 3
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
-----
The right page scroller - browser friendly custom draggable scrollbars.
[Demo](https://codesandbox.io/s/mm5xq5kv5y)
# Capabilities
- ⛓display any custom scroll bar, even, well, [nyan-cat](https://github.com/theKashey/react-nyan-stroller)🐈🏳️🌈🏳️🌈🏳️🌈 scroll bar
- 📜 vertical and horizontal, as well as not matching main scroll axis - like displaying horizontal "reading indicator" for the vertical scroll.
- 👨🔬display scrollbar 1) inside 2) outside 3) at window the target scrollable
- 🤓support for "ScrollIndicators", and actually any other "custom" 🤹♀️ effects
- 🚀support for passive scroll observation (🥳 performance)
- 🧸easy to use out of the box/fully customizable.
# API
Stroller provides 4 components - to create Scrollable `container`, to draw a `scroll bar` and
to `combine` all together. The 4th component is a magic one - `StrollCaptor`.
Written in TypeScript. IDE should provide 100% prop competition.
Provides friction-less expirience, as long stroller does not hook into `onwheel` event,
observing browser scroll silently, keeping all animations smooth.
Could be used inside and outside scrollable node, autodetecting nearest scrollable parent.
```js
import {StrollableContainer} from 'react-stroller';
```
React-stroller consists from 3 parts:
- `Strollable` - "scrollable" container. It will remove native browser scroll.
- `Stroller` - the main component, containing all the logic
- `StrollCaptor` - component, which bypasses scrollable elements, finding the nodes to control.
`StrollableContainer` - just combines them all in the right order.
### Strollable
Is a scrollable, but __scroll-bar-less container__. It uses _padding-hack_ to hide browser scrollbars
on any system.
Read more about scroll bars here - [Scroll to the future](https://evilmartians.com/chronicles/scroll-to-the-future-modern-javascript-css-scrolling-implementations)
```js
import {Strollable} from 'react-stroller';
Strollable will consume 100% width/height - all the possible space
setup `position:relative` to the child
and display any content inside
```
### Stroller
Stroller is a React-scrollbar. It observes `scroll` event, and position itself where it should be.
Stroller likes to be placed inside Strollable.
Meanwhile could be used to scroll "unscrollable"(unwheelable) containers.
```js
import {Stroller} from 'react-stroller';
scrollBar={() =>
oppositePosition /* if you want scroll bar on left, or top */
draggable /* should it be draggable? */
barHeight={(height, scrollHeight, {dragging}) => dragging ? 42 : 24} /* you can override scroll element height */
scrollKey={any} // key to indicate that stroller should update data (scroll height)
passive={true} // enable passive scroll observation. Better for perf, worse for scroll synchronization
onScroll={() => {}} // handle scroll event
/>
```
Stroller will find nearest scrollable parent, and set a scroll bar.
`bar`, you can override is just a view, an internal node for a _real_ Bar Stroller will
draw itself. `bar` should fill 100% height and 100% width, and be just _style_.
`scrollBar` property currently is not documented, and used only by [react-nyan-scroll](https://github.com/theKashey/react-nyan-stroller).
### StrollableContainer
Just combine all Components together in the right order
```js
import {StrollableContainer} from 'react-stroller';
any content
```
- __Do not set `overflow` property for StrollableContainer's parent__, as long it will
set it for itself.
- Always __set height__, you can change it via `flex-grow`, or `flex-shrink`, but it has to be set.
### StrollCaptor - the secret sauce
By default Stroller could be not super smooth, as long it will be first "scrolled"
as a part of scrollable node content, and then will be moved to a new position.
It is natural to have some visual glitches and jumps, if you are not controlling wheel and emulating
scroll event as any other "custom-scroll-bar" does.
`StrollCaptor` is a fix - place it __inside__ scrollable node, while placing Stroller __outside__.
As result - on component scroll Strolled will not be moved, removing any possible _jumps_.
```js
// this is optional
// StrollCaptor will report to Stroller about his scrollable parent
// which is a child for Stroller, and invisible by default.
```
### StrollerState
It's possible to create "Virtual Container", similar to `react-window`, using React-Strollable.
Stroller will expose internal state via `StrollerState` component, you can _consume_ and then react
to scroll or resize.
```js
{({
scrollWidth: number,
scrollHeight: number,
clientWidth: number,
clientHeight: number,
scrollLeft: number,
scrollTop: number,
}) => (
// render elements based on visibility.
)}
```
## ScrollIndicators
Just read stroller state and display them
```js
import {StrollerState} from 'react-stroller';
export const VerticalScrollIndicator= () => (
{({scrollTop, scrollHeight, clientHeight}) => (
<>
= scrollHeight && styles['indicator--hidden']
)}
/>
>
)}
);
```
## Separated scrollbar
You might display scrollbar in the parent, while observing scroll at the children
```js
// "Bar" would be displayed on this level
any code
// we are "observing" scroll in this node
{children}
any code
```
## Testing
React-stroller is a library, which could not be unit tested. Things like smooth scroll, right overflows and
touch-n-feel experience are not something robot could test.
Tested manually and carefully by a human being.
Uses TypeScript and a finite state machine(Faste) underneath, for a better confidence.
# See also
[react-custom-scrollbars](https://github.com/malte-wessel/react-custom-scrollbars) - another great package for custom scrollbars
[React-Locky](https://github.com/theKashey/react-locky) - gather a full control under your scroll.
[React-focus-lock](https://github.com/theKashey/react-focus-lock) - scope your focus in browser friendly way.
# Licence
MIT