MCPcopy
hub / github.com/sghall/react-move

github.com/sghall/react-move @v6.1.0 sqlite

repository ↗ · DeepWiki ↗ · release v6.1.0 ↗
92 symbols 267 edges 56 files 0 documented · 0%
README

React Table Logo

React-Move

Beautiful, data-driven animations for React. Just 3.5kb (gzipped)!

Documentation and Examples

Build Status npm version npm downloads license

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

// 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 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:

import { NodeGroup } from 'react-move'
import { interpolate, interpolateTransformSvg } from 'd3-interpolate'

...
<NodeGroup
  data={this.state.data}
  keyAccessor={(d) => 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
</NodeGroup>

Demos

Documentation

The docs below are for version 6.x.x of React-Move.

Older versions:

The API for NodeGroup and Animate have not changed except for the interpolationxw prop, but if you want to refer back: * Version 2.x.x * Version 3.x.x * Version 4.x.x * Version 5.x.x

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:

// GOOD
{
  attr1: 100,
  attr2: 200,
  attr3: '#dadada'
}

// BAD
{
  attr1: [100], // NO ARRAYS
  attr2: 200,
  attr3: '#dadada'
}

A more concrete example might be:

{
  opacity: 0.1,
  x: 200,
  y: 100,
  color: '#dadada'
}

You can add "namespaces" to help organize your state:

{
  attr1: 100,
  attr2: 200,
  attr3: '#ddaabb',
  namespace1: {
    attr1: 100,
    attr2: 200
  }
}

Or something like:

{
  namespace1: {
    attr1: 100,
    attr2: 200
  },
  namespace2: {
    attr1: 100,
    attr2: 200
  }
}

You might use namespaces like so:

{
  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.

<NodeGroup
  data={data} // an array (required)
  keyAccessor={item => 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 }) => {
        ...
      })}
    ...
  )}
</NodeGroup>

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. Immediately after the starting state is set your enter transition (optional) is called allowing you to transform that state.

<Animate
  start={{ // object or function
    ...
  }}
>
  {state => (
    ...
  )}
</Animate>

Transitioning state

You return a config object or an array of config objects in your enter, update and leave props functions for both NodeGroup and Animate. Instead of simply returning the next state these objects describe how to transform the state. Each config object can specify its own duration, delay, easing and events independently.

There are two special keys you can use: timing and events. Both are optional. Timing and events are covered in more detail below.

If you aren't transitioning anything then it wouldn't make sense to be using NodeGroup. That said, it's convenient to be able to set a key to value when a node enters, updates or leaves without transitioning. To support this you can return four different types of values to specify how you want to transform the state.

  • string or number: Set the key to the value immediately with no transition. Ignores all timing values.

  • array [value]: Transition from the key's current value to the specified value. Value is a string or number.

  • array [value, value]: Transition from the first value to the second value. Each value is a string or number.

  • function: Function will be used as a custom tween function.

Example config object:

{
  attr1: [200],
  attr2: 300,
  attr3: ['#dadada']
  timing: { duration: 300, delay: 100 }
}

Using namespaces:

{
  attr1: [100],
  attr3: '#ddaabb',
  namespace1: {
    attr1: [300],
    attr2: 200
  },
  timing: { duration: 300, delay: 100 }
}

To have different timing for some keys use an array of config objects:

[
  {
    attr1: [200, 500],
    timing: { duration: 300, delay: 100 }
  },
  {
    attr2: 300, // this item, not wrapped in an array, will be set immediately, so which object it's in doesn't matter
    attr3: ['#dadada']
    timing: { duration: 600 }
  },
]

Example Transitions in NodeGroup

<NodeGroup
  data={this.state.data}
  keyAccessor={(d) => d.name}

  start={(data, index) => ({
    opacity: 1e-6,
    x: 1e-6,
    fill: 'green',
    width: scale.bandwidth(),
  })}

  enter={(data, index) => ({
    opacity: [0.5], // transition opacity on enter
    x: [scale(data.name)], // transition x on on enter
    timing: { duration: 1500 }, // timing for transitions
  })}

  update={(data) => ({
    ...
  })}

  leave={() => ({
    ...
  })}
>
  {(nodes) => (
    ...
  )}
</NodeGroup>

Using an array of config objects:

import { easeQuadInOut } from 'd3-ease';

...

<NodeGroup
  data={this.state.data}
  keyAccessor={(d) => d.name}

  start={(data, index) => ({
    opacity: 1e-6,
    x: 1e-6,
    fill: 'green',
    width: scale.bandwidth(),
  })}

  enter={(data, index) => ([ // An array
    {
      opacity: [0.5], // transition opacity on enter
      timing: { duration: 1000 }, // timing for transition
    },
    {
      x: [scale(data.name)], // transition x on on enter
      timing: { delay: 750, duration: 1500, ease: easeQuadInOut }, // timing for transition
    },
  ])}

  update={(data) => ({
    ...
  })}

  leave={() => ({
    ...
  })}
>
  {(nodes) => (
    ...
  )}
</NodeGroup>

Timing

If there's no timing key in your object you'll get the timing defaults. You can specify just the things you want to override on your timing key.

Here's the timing defaults...

const defaultTiming = {
  delay: 0,
  duration: 250,
  ease: easeLinear
};

For the ease key, just provide the function. You can use any easing function, like those from d3-ease...

List of ease functions exported from d3-ease

Events

You can add events on your config objects. You can pass a function that will run when the transition starts, is interrupted (an update to the data occurs) or ends.

Using Events: ```js { attr1: [100], attr3: '#ddaabb', namespace1: { attr1: [300], attr2: 200 }, timing: { duration: 300, delay: 100 }, events: { start: () => { ..do stuff - use an arrow function to keep the context of the outer component }, interrupt: () => { ..do stuff - use an arrow function to k

Extension points exported contracts — how you extend this code

HashMap (Interface)
(no doc)
src/index.d.ts
INodeGroupProps (Interface)
(no doc)
src/NodeGroup/index.d.ts
IAnimateProps (Interface)
(no doc)
src/Animate/index.d.ts

Core symbols most depended-on inside this repo

anchorLinkStyle
called by 5
docs/src/components/MarkdownElement.js
getDeprecatedInfo
called by 3
docs/src/components/PropsDescription/PropsDescription.js
startInterval
called by 2
src/NodeGroup/index.js
mergeKeys
called by 2
src/core/mergeKeys.js
render
called by 2
docs/src/index.js
setPrismTheme
called by 2
docs/src/utils/prism.js
getData
called by 2
docs/src/pages/demos/node-group/Example2.js
getRandom
called by 2
docs/src/pages/demos/charts/DonutChart2.js

Shape

Function 47
Class 29
Method 13
Interface 3

Languages

TypeScript100%

Modules by API surface

src/NodeGroup/index.js12 symbols
src/NodeGroup/index.spec.js6 symbols
docs/src/pages/demos/charts/DonutChart2.js6 symbols
docs/src/pages/demos/charts/DonutChart1.js6 symbols
docs/src/pages/demos/node-group/Example2.js5 symbols
src/Animate/index.spec.js4 symbols
src/Animate/index.js4 symbols
docs/src/components/PropsDescription/PropsDescription.js4 symbols
src/NodeGroup/index.d.ts3 symbols
src/Animate/index.d.ts3 symbols
scripts/copy-files.js3 symbols
docs/src/utils/helpers.js3 symbols

Dependencies from manifests, versioned

@babel/cli7.7.7 · 1×
@babel/core7.7.7 · 1×
@babel/node7.7.7 · 1×
@babel/plugin-proposal-class-properties7.7.4 · 1×
@babel/plugin-transform-runtime7.7.6 · 1×
@babel/preset-env7.7.7 · 1×
@babel/preset-react7.7.4 · 1×
@babel/register7.7.7 · 1×
@babel/runtime7.7.7 · 1×
@material-ui/core3.9.4 · 1×
@material-ui/icons3.0.2 · 1×
babel-eslint10.0.3 · 1×

For agents

$ claude mcp add react-move \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact