Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/papermana/react-modern-sticky
Lightweight sticky component for the modern web.
https://github.com/papermana/react-modern-sticky
react react-component sticky
Last synced: 2 months ago
JSON representation
Lightweight sticky component for the modern web.
- Host: GitHub
- URL: https://github.com/papermana/react-modern-sticky
- Owner: papermana
- Created: 2019-03-07T21:03:53.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2019-03-18T23:19:06.000Z (almost 6 years ago)
- Last Synced: 2024-11-03T04:02:51.008Z (2 months ago)
- Topics: react, react-component, sticky
- Language: JavaScript
- Size: 1.86 MB
- Stars: 7
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# react-modern-sticky
> Lightweight sticky component for the modern web.
[![NPM](https://img.shields.io/npm/v/react-modern-sticky.svg)](https://www.npmjs.com/package/react-modern-sticky)
[![CircleCI](https://circleci.com/gh/papermana/react-modern-sticky.svg?style=svg)](https://circleci.com/gh/papermana/react-modern-sticky)Traditionally, making headers sticky was achieved by watching scroll events, which creates some performance problems. Thankfully, there is now a native way of doing this in CSS: `position: sticky;`. However, there's no built-in way of telling when an element switches between "stuck" and "unstuck" modes.
`react-modern-sticky` is a simple component that uses `position: sticky` and, additionally, watches for when the sticky mode changes. It does so by utilizing the `IntersectionObserver` API for maximum performance.
See it in action [here](https://papermana.github.io/react-modern-sticky/).
- [Browser support](#browser-support)
- [Installation](#installation)
- [Usage](#usage)
- [Basic usage](#basic-usage)
- [Offset](#offset)
- [Callback](#callback)
- [Thanks](#thanks)
- [License](#license)## Browser support
At the time of writing this, [support for `position: sticky;`](https://caniuse.com/#feat=css-sticky) is fairly good.
However, `IntersectionObserver` is still a somewhat recent addition and is not supported by every browser; notably, it's unsupported on Safari 12.
It is recommended to use the polyfill [`intersection-observer`](https://www.npmjs.com/package/intersection-observer) for now. It's enough to just add it to your `package.json` and then put the following somewhere in the code (like in `index.js`):
```js
import "intersection-observer";
```## Installation
```bash
npm install --save react-modern-sticky
# or
yarn add react-modern-sticky
```Note that `react-modern-sticky` requires at least React version 16.8.
## Usage
### Basic usage
The most basic usage is to just wrap your content in `Sticky`.
```jsx
import React from "react";
import Sticky from "react-modern-sticky";const Example = () => My sticky content.;
````Sticky` renders a `div`, and it will accept any usual `div` props, including `className`. You can additionally pass `stuckClassName`, which will be added whenever the element sticks to the top of the screen.
```jsx
const Example = () => (
Header
);
```If you need more control, you can pass a render function as a child instead. This function will be called with the `isStuck` argument.
```jsx
const Example = () => (
{({ isStuck }) => (isStuck ? "I'm stuck!" : "Waiting for a scroll...")}
);
```### Offset
You can set a vertical offset for the `Sticky` element if you need it to not be stuck at the very top of the screen. A common use case for this would be if you have a fixed header and want your sticky sub-header to appear below it.
You can do this simply by passing a prop:
```jsx
const Example = () => (
I'll be offset 50px from the top of the screen when I'm stuck.
);
```Alternatively, if you want to keep all your styles in CSS, you can just apply the `top` property to the element. This may require the use of `!important` to override the default style for `Sticky`, depending on whether your CSS or the library's CSS gets loaded first.
```css
.sticky {
top: 50px !important;
}
``````jsx
const Example = () => (
I'll be offset 50px from the top of the screen when I'm stuck.
);
```### Callback
You can optionally add an `onStuck` callback. `Sticky` is not a controlled element, and in most situations you will not need this. However, sometimes you may want a component to know about the "stuck" state of one of its descendants.
The function passed to `onStuck` will be called with true or false depending on whether the element is currently stuck.
```jsx
const Example = () => {
const [isStuck, setIsStuck] = useState(false);return (
<>
{isStuck ? "It's stuck." : "It's not stuck."}
Some content.
>
);
};
```## Thanks
Eric Bidelman, author of [this article](https://developers.google.com/web/updates/2017/09/sticky-headers), for inspiring this package.
## License
MIT © [Dominik Rowicki](https://github.com/papermana)