Wrapper component around React Motion for easier UI transitions

Last update: Apr 28, 2022

☢️ THIS PROJECT IS NO LONGER MAINTAINED 💀

Please use react-spring for all of your animation needs.

React Motion UI Pack

npm version Dependency Status CDNJS

React Motion is an amazing animation library for React. React Motion UI Pack tries to help ease entry level / common use cases with React Motion by providing a higher level way to work with it and create common UI transitions easier. If you need more complex animations I suggest using React Motion directly.

Usage

yarn add react-motion-ui-pack

npm install react-motion-ui-pack --save

<script src="https://unpkg.com/react-motion-ui-pack/dist/react-motion-ui-pack.js"></script>
(UMD library exposed as `Transition`)

Example

import Transition from 'react-motion-ui-pack'

// Animate a list of items as they are added
<Transition
  component="ul"
  enter={{
    opacity: 1,
  }}
  leave={{
    opacity: 0,
  }}
>  
  { this.state.items.map(item =>
      <li key={item.id}>{item.content}</li>
    )
  }
</Transition>

// Animate a modal
<Transition
  component={false} // don't use a wrapping component
  enter={{
    opacity: 1,
    translateY: spring(0, {stiffness: 400, damping: 10})
  }}
  leave={{
    opacity: 0,
    translateY: 250
  }}
>
  { this.state.modalOpen &&
    <div key="modal" className="modal__content">
      // modal code
    </div>
  }
</Transition>

Props

component: PropTypes.oneOfType([PropTypes.string, PropTypes.bool, isElement])

Define the wrapping tag/component around the children passed in, pass false to not use a wrapping component at all for only child components.

runOnMount: PropTypes.bool

Determines whether the animation runs on mount or not

appear: PropTypes.object

Where the animation starts, defaults to leave value if nothing passed

enter: PropTypes.object

The resting state of the animation

leave: PropTypes.object

The ending value of the animation

onEnter: PropTypes.func

Callback right before an element enters, passes in your current animating values onEnter={currentValues => /* do something */} called only once.

onLeave: PropTypes.func

Same as onEnter, but fires multiple times as an element is leaving.

FAQ

How appear, enter, & leave work

These values are automatically wrapped in a React Motion spring to keep the API simple. If you need a custom config you can pass your own spring e.g. spring(22, { stiffness: 30, damping: 300 }).

My animation values aren't being applied to any elements

If you decide to use a custom component as a child, style and dimensions props will be passed into that component for you to use however you want. If you pass a regular React DOM element, <Transition/> will take care of applying the values for you by cloning your element and passing it in.

Running Locally

clone repo

git clone [email protected]:souporserious/react-motion-ui-pack.git

move into folder

cd ~/react-motion-ui-pack

install dependencies

npm install

run dev mode

npm run dev

open your browser and visit: http://localhost:8080/

GitHub

https://github.com/souporserious/react-motion-ui-pack
Comments
  • 1. Fixes #36

    Allow to pass custom component class as component property of Transition. For that it's using validation function from https://github.com/react-bootstrap/react-prop-types (instead repeating similar stuff). Also i added consuming of component prop in render() to not pass this prop again into custom component.

    Reviewed by asvetliakov at 2016-02-25 03:15
  • 2. Slide in/out animation

    This isn't really an issue with your library, but I'm hoping you can help me out.

    I'm trying to do a simple "slide new content in from the right, slide old content out to the right" animation using your library, but what happens is the new content gets placed below the old content until the old content is removed from the dom, at which point the new content pops into the right position. Here's a gif that shows the effect:

    http://g.recordit.co/hlk0fEyBEn.gif

    Any ideas how I could solve this?

    Reviewed by svk31 at 2015-12-03 15:15
  • 3. This Error appears at every animation : "You must provide a key for every child of Transition."

    Transition.js:99 You must provide a key for every child of Transition.                      
    
    warning.js:36 Warning: Failed prop type: The prop `defaultStyles[0].key` is marked as required in `<<anonymous>>`, but its value is `null`.
        in Unknown (created by Transition)
        in Transition (at index.js:95)
        in Chat (at index.js:466)
        in div (created by Flex)
        in Flex (created by Col)
        in Col (at index.js:465)
        in Sandbox2 (created by Connect(Sandbox2))
        in Connect(Sandbox2) (created by RouterContext)
        in div (at root.js:107)
        in Root (created by Connect(Root))
        in Connect(Root) (created by RouterContext)
        in RouterContext (created by Router)
        in Router (at index.js:57)
        in Provider (at index.js:56)
        in IntlProvider (at index.js:55)
    
    warning.js:36 Warning: Failed prop type: Invalid prop `styles` supplied to `<<anonymous>>`.
        in Unknown (created by Transition)
        in Transition (at index.js:95)
        in Chat (at index.js:466)
        in div (created by Flex)
        in Flex (created by Col)
        in Col (at index.js:465)
        in Sandbox2 (created by Connect(Sandbox2))
        in Connect(Sandbox2) (created by RouterContext)
        in div (at root.js:107)
        in Root (created by Connect(Root))
        in Connect(Root) (created by RouterContext)
        in RouterContext (created by Router)
        in Router (at index.js:57)
        in Provider (at index.js:56)
        in IntlProvider (at index.js:55)
    
    
    Reviewed by aziz-boudi4 at 2017-08-07 22:55
  • 4. Why does my component immediately disappear?

    const TextField = (props) =>
      <Transition
        component={false}
        measure={false}
        enter={{
          opacity: 1,
        }}
        leave={{
          opacity: 0//spring(0, {...presets.gentle, precision: 1000}),
        }}>
        <TF {...props} />
      </Transition>
    
    

    I see the animation when it is mounted, but not when it is unmounted.

    Reviewed by liveresume at 2016-12-20 23:21
  • 5. Transition component doesn't unmount nicely

    When the Transition element gets unmounted while an enter animation is taking place, following warning is spammed:

    Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the TransitionMotion component.
    

    This can be easily reproduced by replacing the ToDos component in the example directory with next piece of code an press the 'Toggle' button randomly.

    class ToDos extends Component {
      constructor(props) {
        super(props);
        this.state = { on: true, items: ['apples', 'oranges', 'bananas', 'pears', 'kiwis'] };
      }
    
      addItem() {
        let newItems = this.state.items.concat([prompt('Enter some text')]);
        this.setState({ items: newItems });
      }
    
      removeItem = (index) => {
        let newItems = this.state.items;
        newItems.splice(index, 1);
        this.setState({ items: newItems });
      }
    
      addRandom = () => {
        const add = Math.random() > 0.5;
        if (add) {
          let newItems = this.state.items.concat([Math.random()]);
          this.setState({ items: newItems });
        }
        setTimeout(this.addRandom, 400);
      }
    
      componentDidMount() {
        setTimeout(this.addRandom, 400);
      }
    
      toggle = () => {
        this.setState({on : !this.state.on});
      }
    
    
    
      render() {
        const items = this.state.items.map((item, index) => {
          return <Todo key={item} item={item} index={index} onDelete={this.removeItem} />
        });
    
        return (
          <div className="todo-app">
            <div className="buttons">
              <button onClick={this.addItem.bind(this)}>Add Item</button>
              <button onClick={this.toggle}>Toggle</button>
            </div>
            {this.state.on ? <Transition
              component="div"
              className="todos"
              measure={true}
              enter={{
                height: 'auto',
                scale: 1,
                translateY: 0,
                opacity: 1
              }}
              leave={{
                height: 0,
                scale: 0.5,
                translateY: 0,
                opacity: -1
              }}
            >
              {items}
            </Transition> : null}
          </div>
          );
      }
    }
    
    Reviewed by Nimaear at 2016-02-29 13:30
  • 6. Transition.render(): A valid ReactComponent must be returned.

    @souporserious I am getting this error in safari, and cant figure out whats going on?

    Invariant Violation: Objects are not valid as a React child (found: object with keys {$$typeof, type, key, ref, props, _owner, _store}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons.

    <Transition key="key-2" component={false} enter={{ opacity: 1, translateY: spring(0, [210, 14]) }} leave={{ opacity: 0, translateY: spring(50, [210, 14]) }}> <div></div> </Transition>

    Reviewed by vinceprofeta at 2016-02-26 18:01
  • 7. Support nested `Transition`

    I embed a onlyChild (component={false} in new version) Transition component in a normal list Transition like

    <Transition
      className="content-blocks"
      component={'div'}
      enter={{
        height: 'auto',
        opacity: 1,
      }}
      leave={{
        height: 0,
        opacity: 0,
      }}
    >
      {blocks.map((block, i)=>{
        let trash = <Transition
          onlyChild
          enter={{width: 32, margin: 5, padding: 2}}
          leave={{width: 0, margin: 0, padding: 0}}
        >
          {editMode && <button
            key="trash"
            style={{overflow: 'hidden'}}
            className="btn btn-icon"
            onClick={this.removeBlock.bind(this, block)}>
            <span className="icon icon-trash"></span>
          </button>}
        </Transition>
        if (block.__typename === 'TextBlock') {
          return <div className="editor-block-wrap" key={i}>
              <TextEditor block={block} />
              {trash}
            </div>
        } else if (block.__typename === 'VoiceBlock') {
          return <div className="editor-block-wrap" key={i}>
              <VoiceBlock block={block}
                          meta={block.__meta}
                          refreshing={this.state.refreshing}
                          onRefreshClick={::this.refresh} />
              {trash}
            </div>
        }
        return null // unsupported block type
      })}
    </Transition>
    

    ~~when i change editMode to true, trash element's parent also change his height.~~ no matter the height is 'auto' or specific value, trash element's parent will change its height only if i set editMode to ture. or it will not change his height (opacity is acting normal)

    Reviewed by filod at 2015-11-12 08:23
  • 8. Auto height doesn't work as expected

    Hey, I've created this branch to (badly) demonstrate what I mean: https://github.com/frederickfogerty/react-motion-ui-pack/tree/height-auto-example

    First off, in the example, I can't get it to calculate the right auto height as much as I try, I assure you it works in my own project. Not sure if this is desired behaviour.

    Secondly, and more majorly, when height: 'auto' is passed to Transition, it only animates the height after the previous 'animation' has 'finished'. That is, if we interrupt it, it will break, and height won't animate at all, often jumping to 0px. This is shown in the example.

    This doesn't happen when height is set to a set value, of course.

    Other than this I have no qualms with this library, thanks!

    Reviewed by frederickfogerty at 2015-10-14 10:42
  • 9. Are all values wrapped in `spring()` as default?

    I'm not quite clear from the README.md, but am I correct in thinking that all style values passed to enter and leave are wrapped in spring() by default? I am assuming that there is no way to jump immediately to any style values on enter or leave, since all style properties are animated?

    Reviewed by gmaclennan at 2015-11-07 21:03
  • 10. Remove auto height

    I've tried to make auto height transitions as easy as I could with little luck so far. It's buggy and it adds a big dependency to this library. It will be removed in the next major release to get the library down to a smaller size. All with the intention of adding it back in at a later time with an option to include it or not.

    Reviewed by souporserious at 2016-09-26 17:25
  • 11. Props not filtered warning since React 15.2.0

    When I set up this:

    <Transition component="div" enter={{ opacity: 1 }} leave={{ opacity: 0 }}>
      // ...
    </Transition/>
    

    I got a warning produced by React since 15.2.0:

    Warning: Unknown props `enter`, `leave`, `runOnMount`, `onEnter`, `onLeave` on <div> tag. Remove these props from the element. For details, see https://fb.me/react-unknown-prop
    

    Is there a way to filter props ?

    Reviewed by PEM-- at 2016-07-07 12:21
  • 12. Using spring for 'leave' property produces an error

    Hi, It works fine when I'm using a spring for the 'enter' property, but returns the following error if I use a spring for 'leave': "NaN is an invalid value for the opacity css style property. Check the render method of nameComponent"

    Could you please help me to understand what's wrong here?

    render(){
        const {text} = this.state
    
       return (
            <Transition
              component={false}
              measure={false}
              enter={{
                opacity: spring(1, {stiffness: 170, damping: 25 }),
              }}
              leave={{
                opacity: spring(0, {stiffness: 170, damping: 25 }),
              }}
            >
              {text !== '' && this.renderTextInfo(text)}
            </Transition>
        )
      }
    
    Reviewed by kosChupahin at 2017-11-24 14:15
  • 13. (0 , _reactMotion2.default) is not a function in the line that calls spring.

    Hello,

    I've installed react-motion and react-motion-ui-pack in my project, and I would like to get my LogoPage component to animate out when unmounted.

    This is my LogoPage component:

    import PropTypes from "prop-types";
    import React from "react";
    
    import ReactOnRails from "react-on-rails";
    import LocationContainer from "../containers/LocationContainer";
    import EttandoLogo from "./app.svg";
    
    import Transition from "react-motion-ui-pack";
    import spring from "react-motion";
    
    const LogoPage = () => {
      return (
        <Transition
          component={false} // don't use a wrapping component
          enter={{
            opacity: 1,
            translateY: spring(0, { stiffness: 400, damping: 10 })
          }}
          leave={{
            opacity: 0,
            translateY: 250
          }}
        >
          {
            <div className="logo-page">
              <AppLogo />
              <div className="row">
                <div className="col-md-6 mx-auto">
                  <LocationContainer />
                </div>
              </div>
            </div>
          }
        </Transition>
      );
    };
    
    LogoPage.propTypes = {};
    
    export default LogoPage;
    

    it's mostly the boilerplate from the example, applied to my markup.

    in the line 17: translateY: spring(0, { stiffness: 400, damping: 10 }) throws this error in the js console:

    Uncaught TypeError: ReactOnRails encountered an error while rendering component: App.
    Original message: (0 , _reactMotion2.default) is not a function
        at LogoPage (LogoPage.js?93a7:17)
        at eval (ReactCompositeComponent.js?d2b3:303)
        at measureLifeCyclePerf (ReactCompositeComponent.js?d2b3:73)
        at ReactCompositeComponentWrapper._constructComponentWithoutOwner (ReactCompositeComponent.js?d2b3:302)
        at ReactCompositeComponentWrapper._constructComponent (ReactCompositeComponent.js?d2b3:277)
        at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js?d2b3:185)
        at Object.mountComponent (ReactReconciler.js?399b:43)
        at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js?d2b3:368)
        at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js?d2b3:255)
        at Object.mountComponent (ReactReconciler.js?399b:43)
    
    Reviewed by DonGiulio at 2017-10-20 14:55
Component-wrapper for collapse animation with react-motion for elements with variable (and dynamic) height
Component-wrapper for collapse animation with react-motion for elements with variable (and dynamic) height

Component-wrapper for collapse animation with react-motion for elements with variable (and dynamic) height

May 2, 2022
A wrapper over Motion One, An animation library, built on the Web Animations API for the smallest filesize and the fastest performance

A wrapper over Motion One, An animation library, built on the Web Animations API for the smallest filesize and the fastest performance. Works with solid-js

Apr 24, 2022
Suspense like transitions for react

@n1ru4l/react-use-transition Suspense like transitions without experimental react features today. For any fetching library. Why? Ever experienced flas

Nov 8, 2021
Framer motion demo with React

Creating modals in React Framer Motion Features Installation Set up Live Demo What is Framer Motion? Framer Motion is a relatively new open source, pr

May 4, 2022
React Shoe - a project developed to study the Three.js technology for 3d objects and framer motion for 2d animations
React Shoe - a project developed to study the Three.js technology for 3d objects and framer motion for 2d animations

React Shoe - a project developed to study the Three.js technology for 3d objects and framer motion for 2d animations

Apr 30, 2022
A React.js wrapper component to animate the line stroke in SVGs
A React.js wrapper component to animate the line stroke in SVGs

react-mt-svg-lines Bring your SVGs to life Live Demo A React.js wrapper component that lets you trigger an "animated lines" effect within your SVGs by

Feb 11, 2022
react-magic-move - MagicMove wrapper.

React Magic Move Magic Move for React.JS NOT A PRODUCTION MODULE This was just a fun experiment, with some love, it could definitely be a real thing,

May 2, 2022
A wrapper to painlessly integrate Spline projects into your React code-space. ☀
A wrapper to painlessly integrate Spline projects into your React code-space. ☀

React Spline A painless, configurable, spline wrapper for React to add sweet animations easily into your projects. Install npm install --save react-sp

May 10, 2022
Simple React.js wrapper for StPageFlip library, for creating realistic and beautiful page turning effect
Simple React.js wrapper for StPageFlip library, for creating realistic and beautiful page turning effect

Version 2.0.0 This version fixed some bugs and is completely written with react hooks. !!! Method access api changed !!! React.js wrapper for StPageFl

May 8, 2022
React component to apply transition effect to numeric strings, a la old Groupon timers
React component to apply transition effect to numeric strings, a la old Groupon timers

react-transitive-number React component to apply transition effect to numeric strings, a la old Groupon timers Live demo Example Usage var TransitiveN

Mar 22, 2022
React particles animation background component
React particles animation background component

particles-bg React component for particles backgrounds This project refers to the source code of the Proton official website, I packaged it into a com

May 9, 2022
A mouse particle effect react component
A mouse particle effect react component

react-mouse-particles A mouse particle effect react component A very fun react library that can be used to create mouse particle effects, which are as

May 9, 2022
A React component for creating typing animations.

react-typewriter A react component for animated typing text. Installation npm install --save react-typewriter Usage Pass in children to the TypeWrite

Apr 8, 2022
A Snow Effect component for React.

react-snowstorm A Snow Effect component for React. Uses Snowstorm under the hood. Live Demo : http://burakcan.github.io/react-snowstorm Getting Starte

Mar 26, 2022
Very simple react component for rotate element based on scroll position

Very simple react component for rotate element based on scroll position

Jun 28, 2021
👇Bread n butter utility for component-tied mouse/touch gestures in React
👇Bread n butter utility for component-tied mouse/touch gestures in React

??Bread n butter utility for component-tied mouse/touch gestures in React

May 15, 2022
A React component implementing the latest version of Animate.css

react-animatecss A React component implementing the latest version of Animate.css! Zero dependencies - All self contained code Minimal package size -

Mar 3, 2022
🍿 React component for animating an element's children, one by one
🍿 React component for animating an element's children, one by one

react-smooth-list ?? React component for animating an element's children, one by one. Installation This package is distributed via npm. npm install re

Apr 7, 2022