About
React Move | Beautiful, data-driven animations for React
# React-Move
Beautiful, data-driven animations for React. Just 3.5kb (gzipped)!
### [Documentation and Examples](https://react-move-docs.netlify.app)
## Features
- Animate HTML, SVG & React-Native
- Fine-grained control of delay, duration and easing
- Animation lifecycle events: start, interrupt, end
- Custom tweening functions
- Awesome documentation and lots of examples
- Supports TypeScript
## Installation
```bash
// React ^16.3.0
npm install react-move
// React ^0.14.9 || ^15.3.0 || ^16.0.0
npm install react-move@^5.0.0
```
**Note:** The API for React Move 5.x and 6.x is exactly the same. The 5.x version just includes [react-lifecycles-compat](https://www.npmjs.com/package/react-lifecycles-compat) to make the library work with earlier versions of React. This adds a little to the bundle so use 6.x if you're using React 16.3+.
### Upgrading from React Move 2.x and 3.x
The API for React Move has been essentially stable since the 2.0 version. The 4.0 version of React Move introduced a change that broke the hard dependency on d3-interpolate and introduced the `interpolation` prop. The current version of React Move will by default only do numeric interpolation and apply easing functions. **If you only need to do numeric interpolation you don't need to do anything. Just upgrade and done.**
To get the same interpolation found in React Move 2.x and 3.x which includes support for colors, paths and SVG transforms do this:
Install d3-interpolate:
```
npm install d3-interpolate
```
Then in your app:
```js
import { NodeGroup } from 'react-move'
import { interpolate, interpolateTransformSvg } from 'd3-interpolate'
...
d.name}
start={(data, index) => ({
...
})}
enter={(data, index) => ([ // An array
...
])}
update={(data) => ({
...
})}
leave={() => ({
...
})}
interpolation ={(begValue, endValue, attr) => { // pass as prop
if (attr === 'transform') {
return interpolateTransformSvg(begValue, endValue)
}
return interpolate(begValue, endValue)
}}
>
...children
```
## Demos
- [CodeSandbox - Animated Bars](https://codesandbox.io/s/w0ol90x9z5) ([@peterrcook](https://github.com/peterrcook))
- [Blog Post by Peter Cook](https://www.createwithdata.com/react-move-bar-chart)
- [CodeSandbox - Collapsible Tree](https://codesandbox.io/s/ww0xkyqonk) ([@techniq](https://github.com/techniq))
- [CodeSandbox - Draggable List](https://codesandbox.io/s/j2povnz8ly)
- [CodeSandbox - Circle Inferno](https://codesandbox.io/s/n033m6nw00)
- [CodeSandbox - Animated Mount/Unmount](https://codesandbox.io/s/9z04rpypny)
- [Examples](https://react-move-docs.netlify.app)
# Documentation
The docs below are for version **6.x.x** of React-Move.
Older versions:
- [Version 1.x.x](https://github.com/sghall/react-move/tree/v1.6.1)
The API for `NodeGroup` and `Animate` have not changed except for the `interpolation`xw prop, but if you want to refer back:
- [Version 2.x.x](https://github.com/sghall/react-move/tree/v2.9.1)
- [Version 3.x.x](https://github.com/sghall/react-move/tree/v3.1.0)
- [Version 4.x.x](https://github.com/sghall/react-move/tree/v4.0.0)
- [Version 5.x.x](https://github.com/sghall/react-move/tree/v5.0.0)
# Getting Started
React Move exports just two components:
- NodeGroup - If you have an **array of items** that enter, update and leave
- Animate - If you have a **singe item** that enters, updates and leaves
## < NodeGroup />
### Component Props
| Name | Type | Default | Description |
| :------------------------------------------------- | :------- | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------- |
| data \* | array | | An array. The data prop is treated as immutable so the nodes will only update if prev.data !== next.data. |
| keyAccessor \* | function | | Function that returns a string key given the data and its index. Used to track which nodes are entering, updating and leaving. |
| interpolation | function | numeric | A function that returns an interpolator given the begin value, end value, attr and namespace. Defaults to numeric interpolation. See docs for more. |
| start \* | function | | A function that returns the starting state. The function is passed the data and index and must return an object. |
| enter | function | () => {} | A function that **returns an object or array of objects** describing how the state should transform on enter. The function is passed the data and index. |
| update | function | () => {} | A function that **returns an object or array of objects** describing how the state should transform on update. The function is passed the data and index. |
| leave | function | () => {} | A function that **returns an object or array of objects** describing how the state should transform on leave. The function is passed the data and index. |
| children \* | function | | A function that receives an array of nodes. |
## < Animate />
### Component Props
| Name | Type | Default | Description |
| :---------------------------------------------- | :------------------------------------------------------ | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| show | bool | true | Boolean value that determines if the child should be rendered or not. |
| interpolation | function | numeric | A function that returns an interpolator given the begin value, end value, atrr and namespace. See docs for more. |
| start | union:
func
object
| | An object or function that returns an obejct to be used as the starting state. |
| enter | union:
func
array
object
| | An object, array of objects, or function that returns an object or array of objects describing how the state should transform on enter. |
| update | union:
func
array
object
| | An object, array of objects, or function that returns an object or array of objects describing how the state should transform on update. **_Note:_** although not required, in most cases it make sense to specify an update prop to handle interrupted enter and leave transitions. |
| leave | union:
func
array
object
| | An object, array of objects, or function that returns an object or array of objects describing how the state should transform on leave. |
| children \* | function | | A function that receives the state. |
## Starting state
Before looking at the components it might be good to look at starting state. You are going to be asked to define starting states for each item in your `NodeGroup` and `Animate` components. This is a key concept and probably the most error prone for developers working with React Move. The starting state for each item is always **an object with string or number leaves**. The leaf keys are referred to as "attrs" as in "attribute." There are also "namespaces" which are a purely organizational concept.
Two rules to live by for starting states:
- Don't use the strings "timing" or "events" as an attr or namespace.
- There should never be an array anywhere in your object.
Example starting state:
```js
// GOOD
{
attr1: 100,
attr2: 200,
attr3: '#dadada'
}
// BAD
{
attr1: [100], // NO ARRAYS
attr2: 200,
attr3: '#dadada'
}
```
A more concrete example might be:
```js
{
opacity: 0.1,
x: 200,
y: 100,
color: '#dadada'
}
```
You can add "namespaces" to help organize your state:
```js
{
attr1: 100,
attr2: 200,
attr3: '#ddaabb',
namespace1: {
attr1: 100,
attr2: 200
}
}
```
Or something like:
```js
{
namespace1: {
attr1: 100,
attr2: 200
},
namespace2: {
attr1: 100,
attr2: 200
}
}
```
You might use namespaces like so:
```js
{
inner: {
x: 100,
y: 150,
color: '#545454'
},
outer: {
x: 300,
y: 350,
color: '#3e3e3e'
}
}
```
#### Starting state in NodeGroup
In `NodeGroup` you are working with an array of items and you pass a start prop (a function) that receives the data item and its index. The start prop will be called when that data item (identified by its key) enters. Note it could leave and come back and that prop will be called again. Immediately after the starting state is set your enter transition (optional) is called allowing you to transform that state.
```js
item.name} // function to get the key of each object (required)
start={(item, index) => ({ // returns the starting state of node (required)
...
})}
>
{(nodes) => (
...
{nodes.map(({ key, data, state }) => {
...
})}
...
)}
```
#### Starting state in Animate
In `Animate` you are animating a single item and pass a start prop that is an object or a function. The start prop will be called when that the item enters. Note it could leave and come back by toggling the show prop. Immedi