npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-simple-scroll

v2.0.0

Published

Declarative API for SPA scroll position

Downloads

4

Readme

react-simple-scroll Build Status

react-simple-scroll is a declarative API for managing the scroll position of a React application that uses react-router. Its goal is nothing more than to bring the scroll-behavior of full-page refreshes to an SPA (setting the scroll position to (0, 0) when a new "page" is navigated to).

Sometimes, even when the URL path has changed, we don't want the screen position to reset. This might be the case in an onboarding flow when navigating from onboarding/step/1 to onboarding/step/2. Navigating from onboarding/step/2 to / however should reset the scroll position.

If your app has N routes, you'd ostensibly have to declare how N^2 transitions should be handled. react-simple-scroll instead allows you to annotate your react-router route hierarchy with the "boundaries" of a page and handles all possible transitions for you.

npm
npm install --save react-simple-scroll
yarn
yarn add react-simple-scroll

Dependencies

react-simple-scroll has no explicit dependencies, but will need you to provide three things:

  • React
  • react-router
  • An implementation of isEqual. isEqual should accept two objects and return true if their contents are deeply equal and false otherwise. Lodash, underscore, et. al. ship with such a method. It wasn't included in this package assuming most users would already have an implementation hanging around.

We support any browser supported by both react and react-router.

React 16 Support

Please note that as of 2.0.0 we provided React 16 support but with react-router ^3.2.0 as a peer dependency. Since react-router 4, the Route architecture has changed significantly which means that using react-simple-scroll as a middleware is no longer compatible. We will work on a new version of react-simple-scroll in the future that will support react-router 4 and beyond.

Quick Start

To install react-simple-scroll, add it as a middleware to <Router />:

import { Router, applyRouterMiddleware } from 'react-router';
import { scrollMiddleware } from 'react-simple-scroll';
import isEqual from 'lodash.isequal';

const render = applyRouterMiddleware(
  scrollMiddleware({ isEqual })
);

<Router render={render}>
  {routes}
</Router>

Next, annotate your react-router route hierarchy with the scrollFrame prop. A scrollFrame declares a "frame" within which we consider the page to have not transitioned. Any route's frame is found by starting with itself and looking up the tree for the closest route which has the srollFrame property set to true. If the app transitions from route A to route B and they have the same scroll frame, the scroll position is not touched. If they're different, the scroll position is reset to (0, 0).

const routes = (
  <Route path="/">

    <Route path="foo" component={FooView} scrollFrame>
      <IndexRoute component={FooContainer} />
      <Route path="bar" component={BarContainer} />
      <Route path="baz" component={BazContainer} />
    </Route>

    <Route path="bloop" component={BloopView} scrollFrame>
      <IndexRoute component={BloopIndexContainer} />
      <Route scrollFrame>
        <Route path="bleep" component={BleepContainer} />
        <Route path="bleep/blap" component={BleepBlapContainer} />
        <Route path="bleep/blorp" component={BleepBlorpContainer} />
      </Route>
    </Route>

  </Route>
);

| From | To | Reset? | |---------------|---------------------|------------| | /foo/bar | /foo/baz | no | |/foo | /foo/bar | no | |/foo | / | yes | |/bloop/bleep | /bloop/bleep/blap | no | |/bloop | /bloop/bleep | yes | |/foo | /bloop | yes |

Algorithm

The algorithm for reseting the window position based on the current active route and the previous active route in a transition is as follows:

  • If my previous route and my current route have different scrollFrame routes (the nearest scrollFrame annotated route looking up my ancestor list), reset the window position
  • If neither my previous route nor current route define a scrollFrame, reset the window position
  • If the same route was clicked twice in a row and the query and search didn't change, reset the window position
  • else do nothing

API Reference

react-simple-scroll exports a component and a router middleware factory:

import SimpleScroll, { scrollMiddleware } from 'react-simple-scroll'

scrollMiddleware(props)

scrollMiddleware is a function that accepts props to bind to the underlying <SimpleScroll /> component and returns an appropriate middleware for react-router.

import { scrollMiddleware } from 'react-simple-scroll';
import isEqual from 'lodash.isequal'


const middleware = scrollMiddleware({ isEqual });

<SimpleScroll />

This component will likely never be used directly by the user. It emits no DOM and is designed to sit between the <Router /> and <RouterContext /> components of your heirarchy.

props

| Name | Type | Required? | Description | |-----------------------------------|----------|---------------|---------------------------------------| | routerProps | object | true | Supplied by react-router | | isEqual | func | true | Returns true if two objects are equal | | enableBrowserScrollRestoration | bool | false | Default false, see Scroll Restoration | | children | node | false | Supplied by react-router |

Scroll Restoration

Many history implementations for react-router will fall back to the History API provided by most modern browsers. The History API has a feature wherin scroll positions are recorded when pushing and restored when popping pages. This has the unwanted side-effect of hijacking the scrolling we're trying to manually set here. By default, react-simple-scroll will make an effort to disable this feature. If however you'd rather leave it enabled, simply pass the enableBrowserScrollRestoration to scrollMiddleware:

const middleware = scrollMiddleware({
  isEqual,
  enableBrowserScrollRestoration: true
});

License

MIT

Contributing

If you're interested in contributing to react-simple-scroll, a good place to start is by opening up an Issue and describing the change you'd like to see, be it a bug, feature request, or otherwise. This gives everyone a chance to review the proposal from a high-level before any development effort is invested.

Lifecycle of a Change

  • Open an Issue describing the change
  • Fork react-simple-scroll
  • Create a new branch for your changes: git checkout -b <user>/update-bloop
  • Implement and add tests as necessary
  • Make sure all tests pass: npm test
  • Open a PR on Github against your branch: <user>/update-bloop
  • Address any PR feedback
  • We'll merge and cut a release!