All Projects → josepot → React Redux Scroll

josepot / React Redux Scroll

Licence: mit

Programming Languages

javascript
184084 projects - #8 most used programming language
declarative
70 projects

Projects that are alternatives of or similar to React Redux Scroll

Vue Mugen Scroll
Infinite scroll component for Vue.js 2
Stars: ✭ 532 (+1673.33%)
Mutual labels:  scroll
Txscrolllabelview
🌭TXScrollLabelView, the best way to show & display information such as adverts / boardcast / onsale e.g. with a customView.
Stars: ✭ 714 (+2280%)
Mutual labels:  scroll
Eager Image Loader
The eager-loading for image files on the web page that loads the files according to your plan. This differs from the lazy-loading, for example, this can be used to avoid that the user waits for the loading.
Stars: ✭ 22 (-26.67%)
Mutual labels:  scroll
Recyclerview Fastscroller
A fully customizable Fast Scroller for the RecyclerView in Android, written in Kotlin
Stars: ✭ 585 (+1850%)
Mutual labels:  scroll
Vuebar
(🗃️ Archived) Vue 2 directive for custom scrollbar that uses native scroll behavior. Lightweight, performant, customizable and without dependencies. Used successfully in production on https://ggather.com
Stars: ✭ 650 (+2066.67%)
Mutual labels:  scroll
Mos
一个用于在 macOS 上平滑你的鼠标滚动效果或单独设置滚动方向的小工具, 让你的滚轮爽如触控板 | A lightweight tool used to smooth scrolling and set scroll direction independently for your mouse on macOS
Stars: ✭ 7,772 (+25806.67%)
Mutual labels:  scroll
Motus
Animation library that mimics CSS keyframes when scrolling.
Stars: ✭ 502 (+1573.33%)
Mutual labels:  scroll
Fuckmyscroll.js
🔮 Animated scrolling to certain point or anchor
Stars: ✭ 10 (-66.67%)
Mutual labels:  scroll
Scrolldir
0 dependency JS plugin to leverage scroll direction with CSS ⬆⬇ 🔌💉
Stars: ✭ 679 (+2163.33%)
Mutual labels:  scroll
Infinite Ajax Scroll
Turn your existing pagination into infinite scrolling pages with ease
Stars: ✭ 804 (+2580%)
Mutual labels:  scroll
Navigation Toolbar
Navigation toolbar is a slide-modeled UI navigation controller made by @Ramotion
Stars: ✭ 587 (+1856.67%)
Mutual labels:  scroll
Wxp Ui
小程序插件合集(下拉刷新, 拖拽排序, 索引列表, 日期选择, 侧滑删除...)
Stars: ✭ 636 (+2020%)
Mutual labels:  scroll
Scrollbooster
Enjoyable content drag-to-scroll library
Stars: ✭ 775 (+2483.33%)
Mutual labels:  scroll
React Scrollbars Custom
The best React custom scrollbars component
Stars: ✭ 576 (+1820%)
Mutual labels:  scroll
Nice Anim
An animate on scroll Web Component built with StencilJS
Stars: ✭ 23 (-23.33%)
Mutual labels:  scroll
Vue Virtual Collection
Vue component for efficiently rendering large collection data
Stars: ✭ 506 (+1586.67%)
Mutual labels:  scroll
Scroll Through Time
⌛️ 🎩 🐇 Two fingers scroll moves through time instead of space
Stars: ✭ 720 (+2300%)
Mutual labels:  scroll
Android scroll endless
Scroll endless for Android recyclerview
Stars: ✭ 12 (-60%)
Mutual labels:  scroll
Rsdayflow
iOS 7+ Calendar (Date Picker) with Infinite Scrolling.
Stars: ✭ 843 (+2710%)
Mutual labels:  scroll
Gravityslider
🔄 GravitySlider is a beautiful alternative to the standard UICollectionView flow layout.
Stars: ✭ 784 (+2513.33%)
Mutual labels:  scroll

React Redux Scroll

Scroll management library for react-redux apps.

Table of Contents

Install

npm install --save react-redux-scroll

Configuration

Use createScrollMiddleware() to add the middleware to your redux store. For example:

import { createStore, applyMiddleware, compose } from 'redux';
import createLogger from 'redux-logger';
import { createScrollMiddleware } from 'react-redux-scroll';

const devMode = process.env.NODE_ENV !== 'production';

const scrollMiddleware = createScrollMiddleware();
const loggerMiddleware = createLogger();

const getMiddlewares = () => {
  const common = [scrollMiddleware];
  const dev = [loggerMiddleware];
  const prod = [];
  return [...common, ...(devMode ? dev : prod)];
};

const getOtherEnhancers = () => (
  devMode && window.devToolsExtension ? [window.devToolsExtension()] : []
);

const configureStore = reducer => compose(
  applyMiddleware(...getMiddlewares()),
  ...getOtherEnhancers()
)(createStore)(reducer);

export default configureStore;

Usage

Basic

Imagine that you have a ErrorMessages component that's used for displaying a bunch of form errors. Now, lets say that we want to trigger a smooth scroll to the DOM element of that component when the action type ERRORS_REPORTED gets dispatched.

import React from 'react';
import { scrollToWhen } from 'react-redux-scroll';
import ErrorMessages from './ErrorMessages';
import FancyForm from './FancyForm';
import { ERRORS_REPORTED } from 'action-types';

const ScrollableErrorMessages =
  scrollToWhen(ERRORS_REPORTED)(ErrorMessages);

export default () =>
  <div>
    <ScrollableErrorMessages />
    <FancyForm />
  </div>;

Now, lets pretend that the FancyForm and the ErrorMessages are inside an overflow: scroll element. Therefore we want the scroll to happen for that "overflowed" element, instead of the window. To do so, we will use the scrollableArea enhancer:

import React from 'react';
import { scrollableArea, scrollToWhen } from 'react-redux-scroll';
import ErrorMessages from './ErrorMessages';
import FancyForm from './FancyForm';
import { ERRORS_REPORTED } from 'action-types';

const ScrollableDiv = scrollableArea('div');

const ScrollableErrorMessages =
  scrollToWhen(ERRORS_REPORTED)(ErrorMessages);

export default () => (
  <ScrollableDiv
    style={{
      overflow: 'scroll',
      width: '400px',
      height: '800px',
    }}
  >
    <ScrollableErrorMessages />
    <FancyForm />
  </ScrollableDiv>
);

Intermediate

import React from 'react';
import PropTypes from 'prop-types';
import { scrollToWhen } from 'react-redux-scroll';
import { PARAGRAPH_SELECTED } from 'action-types';

const isParagraphSelected = (action, props) => (
  action.type === SCROLL_TO_PARAGRAPH && props.id === action.paragraphId
);

const ScrollableParagraph = scrollToWhen({
  pattern: isParagraphSelected,
  excludeProps: ['id']
})('p');

const Paragraphs = ({ paragraphsData }) =>
  <div>
    {paragraphsData.map(({ id, content }) =>
      <ScrollableParagraph id={id} key={id}>
        {content}
      </ScrollableParagraph>
    )}
  </div>;

Paragraphs.proptypes = {
  paragraphsData = PropTypes.arrayOf(PropTypes.shape({
    id: PropTypes.string.isRequired,
    content: Proptyes.node.isRequired,
  })),
};

export default Paragraphs;

Complete Examples

There are some examples in this repo that take advantage of all the different usages of the API:

  • paragraphs: It's a pretty basic one based on the code above.
  • lottery: This one is more advanced: it demonstarates how to use multiple ScrollAreas and having more than one scroll happneing at the same time. In order to try the examples, clone this repo, go the example folder that you want to try and do an npm install, npm start. For example:
  • fiddler: A fiddler of the different scrollOptions.

API

createScrollMiddleware()

It returns a redux middleware.

scrollToWhen({pattern, [onEnd], [scrollOptions], [excludeProps]})

It returns a Higher Order React Component Function that will trigger scroll to the provided component when the pattern matches the dispatched

Arguments

- pattern (String | Function | Array):

It will trigger a scroll when a dispatched action matches the pattern. (Very similar to the way that redux-saga take pattern works).

  • If it's a String: the pattern will match if action.type === pattern
  • If it's a Function: the pattern will match if the return value of the function is truthy. This function receives the following arguments: (action, props, newState, oldState). It can also return an object containing a different onEnd function (which will take precedence over the one provided in the second parameter of the scrollToWhen function) and/or scrollOptions (object which will get merged with the options provided in the third parameter of the scrollToWhen function).
  • If it's an Array: each item in the array is matched with beforementioned rules, so the mixed array of strings and function predicates is supported.

- [ onEnd(dispatch, canceled): void ] (Function):

A callback function that will get called once the scroll has finished. The first argument is the redux store dispatch function. The second parameter is a boolean flag indicating whether the scroll got cancelled.

- [ scrollOptions ] (Object):

If specified further customizes the behavior of the scroll. The possible options are:

  • [ duration ] (Number): Number of milliseconds that it will take for the scroll to complete. Defaults to 500.
  • [ transitionTimingFunction ] (String | Function):
    • If a String, one of:
      • LINEAR
      • EASE_IN_QUAD
      • EASE_OUT_QUAD
      • EASE_IN_OUT_QUAD
      • EASE_IN_CUBIC
      • EASE_OUT_CUBIC
      • EASE_IN_OUT_CUBIC
      • EASE_IN_QUART
      • EASE_OUT_QUART
      • EASE_IN_OUT_QUART
    • If a function: it takes one argument t which is a decimal value between 0 and 1 (including both 0 and 1) that represents the proportional amount of time that has passed since the motion started. This function is supposed to returs a value between 0 and 1 that represents the proportional distance that has been completed in t time. The only conditions are that if t is zero the return value must be zero and that if t is 1 the return value must be 1 too.
    • Defaults to: EASE_IN_QUAD.
  • [ xAlignment ] (String): Either LEFT, CENTER or RIGHT, pass null or undefined if you don't want for the scroll function to change the x position. Defaults to null. If you want a horizontal scroll set this to any of the possible values and the yAlignment to null.
  • [ xMargin ] (Number): Margin in pixels to the x alignment. Defaults to 0.
  • [ yAlignment ] (String): Either TOP, CENTER or BOTTOM, pass null or undefined if you don't want for the scroll function to change the y position. Defaults to TOP.
  • [ yMargin ] (Number): Margin in pixels to the y alignment. Defaults to 0.

- [ excludeProps ] (Array):

An array of Strings indicating the names of the props that shouldn't be propagated to the enhanced component.

scrollableArea

It returns a Higher Order React Component Function that creates a ScrollableArea for the Scrollable components that it has inside. It's meant to be used for enhancing "overflowing" components. If a Scrollable component is not inside a ScrollableArea, the ScrollableArea defaults to window.

FAQ

Is there an easy way to disable this library for the SSR build?

Setting the env variable IS_SSR to true will accomplish that.

- What happens when more than one scroll tries to take place as a result of the latest action that was dispatched?

Depends. If the scrolls are for different "Scrolling Areas" all scrolls will happen simultaneusly, no problem. However, if they belong to the same "Scrolling Area" (i.e. they are all requesting a window scroll) then the middleware will only allow the first scroll that got subscribed to happen. In the development env you will get warnings in the console letting you know that some scrolls were prevented from happening because they all requested a scroll inside the same scrolling area as a result of the latest action. In the production environemnt the warning won't appear and just one scroll will happen.

- What if a scroll gets triggered while another scroll is still running (in the same scrolling area)?

The running scroll will stop and the new scroll will start.

- Is there a way to know when a scroll has finished?

Yes. You can use the onEnd function.

- Can I dispatch an action once a scroll has finished?

Yes. The first argument of the onEnd function is the store.dispatch. Use it to dispatch another action.

- Is there a way to know if the scroll got cancelled?

Yes. The second argument of the onEnd function is a boolean value that indicates whether or not the scroll got canceled.

- Is this library compatible with IE9?

Yes.

- What's the size of this library?

Without its peer dependencies, the gzipped size is < 5Kb.

Rationale

So, you have your nice and functional React-Redux app: no stateful components, everything that gets rendered is in response to the state of your store... And now a new requirement comes in: "whenever this or that happens we need a smooth scroll towards that component". Now what? How are we going to make that scroll happen? Maybe we could add a boolean entry in the state like: needsToScroll and then use the lifecycle event componentWillReceiveProps to trigger a scroll whenever that value changes from false to true... And hope that no other component instance is trying to do the same thing. We would also have to dispatch another action when the scroll finishes to set that entry back to false. And how do we cancel that scroll if now another acction happened that requires that scroll to be directed somewhere else? A bit messy, and convoluted, right?

This library helps you manage the scrolls of your app declaratively, while keeping your presentational components decoupled from the actions and the state of the app... You won't need to deal with "refs", "classes" or lifecycle events.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].