react-hook-sticky
Version:
207 lines (161 loc) • 5.96 kB
Markdown
<div >
<div align="left">
<img src="https://img.shields.io/bundlephobia/minzip/react-hook-sticky?style=for-the-badge">
</div>
</br>
<div align="left">
<img src="https://img.shields.io/npm/v/react-hook-sticky?style=for-the-badge">
</div>
<p>
<img src="https://img.shields.io/github/last-commit/Ariel-Rodriguez/react-hook-sticky?style=flat-square">
<img src="https://img.shields.io/librariesio/dependent-repos/npm/react-hook-sticky?color=lightgreen&style=flat-square">
<img src="https://img.shields.io/snyk/vulnerabilities/github/Ariel-Rodriguez/react-hook-sticky?style=flat-square">
</p>
</div>
<span><img src="https://image.flaticon.com/icons/svg/220/220603.svg" alt="chrome" width="32"></span>
<span><img src="https://image.flaticon.com/icons/svg/888/888914.svg" alt="ie 10" width="32"></span>
<span><img src="https://image.flaticon.com/icons/svg/888/888899.svg" alt="edge" width="32"></span>
<span><img src="https://image.flaticon.com/icons/svg/1177/1177512.svg" alt="firefox" width="32"></span>
<span><img src="https://image.flaticon.com/icons/svg/179/179337.svg" alt="safari" width="32"></span>
# React hook sticky
Top performant lightweight solution for sticky components.
Start to collaborate and share your sticky plugin.
Provide your ideas, feel free to contribute.
## Demo

[react-hook-sticky-playground](https://codesandbox.io/s/github/Ariel-Rodriguez/react-hook-sticky-playground/tree/main/?autoresize=1&fontsize=14&hidenavigation=1&theme=dark)
## Roadmap
Would you like to contribute? Here are some nice to have ideas:
- [ ] Add plugins.
- [ ] Storybook and examples.
- [ ] Add development runtime invalidations for warning and error check.
- [ ] Create Wiki Page.
- [ ] Add unit test.
- [ ] Add E2E tests for IE and Chrome. (Probably Puppeter)
- [ ] Add E2E perfomance painting tests
- [ ] Configure CI (Probably Travis)
- [ ] Add code coverage and bundle size check.
- [ ] Add support for Horizontal scrolling / resizing
## Install
```bash
yarn add react-hook-sticky --exact
```
## Quickstart
#### Basic
```jsx
// sticky-component.js
import React from 'react';
// 1 - Import
import { useSticky, plugins } from 'react-hook-sticky';
const stickyConfig = {
// Define the context for this sticky, you may have many sticky elements.
context: 'my-sticky-1',
// 2 - Make use of builtin plugins
plugin: plugins.fillBetween, // you may combine with throttling or wrap as your needs throttle(plugins.fillBetween, 10),
// Optional - Specify the proper event listener strategy for better performance over any browser.
// default { passive: true } https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
eventListenerOptions: Modernizr.passiveeventlisteners
? { passive: true }
: false,
};
export const StickyComponent = props => {
const { createBoundary } = useSticky(stickyConfig);
return (
<div className="sticky-outer" ref={createBoundary('outer')}>
{/* 3 - Register the target to become sticky */}
<div className="sticky" ref={createBoundary('sticky')}>
I am sticky between outer height or screen height
</div>
</div>
);
};
```
#### Optional define specific boundaries
```jsx
export const StickyComponent = props => {
const { createBoundary } = useSticky(stickyConfig);
return (
<div className="sticky-outer">
<h1 ref={createBoundary('top')}>Top boundary</h1>
{/* 3 - Register the target to become sticky */}
<div className="sticky" ref={createBoundary('sticky')}>
I am sticky between top and bottom boundaries or screen height
</div>
<div ref={createBoundary('bottom')}>Bottom boundary</div>
</div>
);
};
```
## Development
Contribute and create your own plug-in right away.
### Quick
- Fork demo https://codesandbox.io/s/react-hook-sticky-ts0rb
- Create your sticky logic
```jsx
// You may reuse common code and tools
import {
useMomentum,
getClampArea,
createStyle,
setInlineStyle,
} from '../commons';
// Explode your creativity, create your new module sticky to later being integrated
export const bunnyJump = (context, event) => {
const { cacheStyles, boundaries } = context;
const stickyBoundary = boundaries.sticky;
const clampArea = getClampArea(boundaries);
if (!stickyBoundary || !clampArea.height) {
return;
}
const nextPosition = {
position: 'absolute',
maxHeight: clampArea.height,
};
const { isGoingDown } = useMomentum(event);
if (isGoingDown) {
nextPosition.top = clampArea.top;
} else {
nextPosition.bottom = clampArea.bottom;
}
setInlineStyle(stickyBoundary, createStyle(nextPosition), cacheStyles);
};
```
- Implement in real time in your sandbox
```jsx
// 1 - Import your snippet
import { bunnyJump } from './sticky-jump-draft';
import { useSticky } from 'react-hook-sticky';
const stickyConfig = {
context: 'stickyJump',
// 2 - Register it!
plugin: bunnyJump,
};
export const StickyComponent = props => {
const { createBoundary } = useSticky(stickyConfig);
return (
<section ref={createBoundary('top')}>
<div className="ad" ref={createBoundary('sticky')} />
{/* Registering boundaries all in one collection under stickyJump context */}
<div className="block" ref={createBoundary(['jumpMe'])} />
<div className="block" ref={createBoundary(['jumpMe'])} />
<div className="block" ref={createBoundary('bottom')} />
</section>
);
};
```
## How to develop local
### Setup
```bash
git clone git@github.com:Ariel-Rodriguez/react-hook-sticky.git
yarn
# Link library
yarn link
# install and link library into example
# any change done in library will be hor reloaded in example page.
cd example && yarn && yarn link react-hook-sticky
```
### Run examples
```bash
yarn start
```
## Share or contribute!