@gnarlycode/react-scroll-state v1.1.0
GNARLY CODE Production Introducing
React Scroll State
Bunch of components that will help you to lock, track, change and restore scroll position on routing properly.
Installation
npm i --save @gnarlycode/react-scroll-stateUsage
First of all you should add next global styles to your app:
html.html-scroll-lock {
overflow-y: scroll;
}
body.body-scroll-lock {
overflow: hidden;
position: fixed;
}You can get this names as strings importing it:
import { injectGlobal } from 'styled-components'
import {
defaultBodyLockClass,
defaultHtmlLockClass,
} from '@gnarlycode/react-scroll-state'
injectGlobal`
html.${defaultHtmlLockClass} {
overflow-y: scroll;
}
body.${defaultBodyLockClass} {
overflow: hidden;
position: fixed;
}
`You can use your own classnames. In this case you should pass it to ScrollStateProvider
ScrollStateProvider
Manages all scroll operations. You can just wrap all your app with this provider:
import { App } from 'your-app'
import { ScrollStateProvider } from '@gnarlycode/react-scroll-state'
return (
<ScrollStateProvider>
<App />
</ScrollStateProvider>
)You can pass custom lock classes as bodyLockClass and htmlLockClass props.
ScrollLocker
Locks browser scroll when mounted:
import { ScrollLocker } from '@gnarlycode/react-scroll-state'
return (
<>
...
{isScrollLocked && <ScrollLocker />}
...
</>
)ScrollRestorer
This component restores scroll position when history changes. Designed to work with React Router 4.
It uses withRouter and withScrollState under the hood so should be mounted anywhere inside Router and ScrollStateProvider:
import { App } from 'your-app'
import {
ScrollRestorer,
ScrollStateProvider,
} from '@gnarlycode/react-scroll-state'
return (
<ScrollStateProvider>
<ScrollRestorer />
<App />
</ScrollStateProvider>
)withScrollState
The high-order component provides you scrollState from ScrollStateProvider as prop:
import { withScrollState } from '@gnarlycode/react-scroll-state'
const myComponent = withScrollState(({ scrollState }) => <div />)The scrollState object will contain next fields:
export interface ScrollStateContext {
animateScroll(to: number, duration?: number): void
getScrollPosition(): number
isScrollLocked(): boolean
lockScroll(): void
scrollEvent: {
fire(): void
subscribe(fn: () => void)): void
unsubscribe(fn: () => void)): void
}
setScrollPosition(scroll: number): void
unlockScroll(): void
}