return c.pause(finished);
* const props = useSpring({ ... })
* const [props, set] = useSpring(() => ({ ... }))
var useSpring = function useSpring(props) {
var isFn = is.fun(props);
var _useSprings = useSprings(1, isFn ? props : [props]),
return isFn ? [result[0], set, pause] : result;
* const trails = useTrail(number, { ... })
* const [trails, set] = useTrail(number, () => ({ ... }))
var useTrail = function useTrail(length, props) {
var mounted = React.useRef(false);
var isFn = is.fun(props);
var updateProps = callProp(props);
var instances = React.useRef();
var _useSprings = useSprings(length, function (i, ctrl) {
if (i === 0) instances.current = [];
instances.current.push(ctrl);
return _extends({}, updateProps, {
config: callProp(updateProps.config, i),
attach: i > 0 && function () {
return instances.current[i - 1];
pause = _useSprings[2]; // Set up function to update controller
var updateCtrl = React.useMemo(function () {
return function (props) {
return set(function (i, ctrl) {
var last = props.reverse ? i === 0 : length - 1 === i;
var attachIdx = props.reverse ? i + 1 : i - 1;
var attachController = instances.current[attachIdx];
return _extends({}, props, {
config: callProp(props.config || updateProps.config, i),
attach: attachController && function () {
}, [length, updateProps.reverse]); // Update controller if props aren't functional
React.useEffect(function () {
return void (mounted.current && !isFn && updateCtrl(props));
}); // Update mounted flag and destroy controller on unmount
React.useEffect(function () {
return void (mounted.current = true);
return isFn ? [result, updateCtrl, pause] : result;
* const transitions = useTransition(items, itemKeys, { ... })
* const [transitions, update] = useTransition(items, itemKeys, () => ({ ... }))
var mapKeys = function mapKeys(items, keys) {
return (typeof keys === 'function' ? items.map(keys) : toArray(keys)).map(String);
var get = function get(props) {
_props$keys = props.keys,
keys = _props$keys === void 0 ? function (item) {
rest = _objectWithoutPropertiesLoose(props, ["items", "keys"]);
items = toArray(items !== void 0 ? items : null);
keys: mapKeys(items, keys)
function useTransition(input, keyTransform, config) {
keys: keyTransform || function (i) {
lazy = _get$lazy === void 0 ? false : _get$lazy,
_get$unique = _get.unique,
reset = _get$reset === void 0 ? false : _get$reset,
onDestroyed = _get.onDestroyed,
extra = _objectWithoutPropertiesLoose(_get, ["lazy", "unique", "reset", "enter", "leave", "update", "onDestroyed", "keys", "items", "onFrame", "onRest", "onStart", "ref"]);
var forceUpdate = useForceUpdate();
var mounted = React.useRef(false);
var state = React.useRef({
instances: !mounted.current && new Map(),
React.useImperativeHandle(props.ref, function () {
start: function start() {
return Promise.all(Array.from(state.current.instances).map(function (_ref) {
return new Promise(function (r) {
stop: function stop(finished) {
return Array.from(state.current.instances).forEach(function (_ref2) {
return Array.from(state.current.instances).map(function (_ref3) {
state.current = diffItems(state.current, props);
if (state.current.changed) {
state.current.transitions.forEach(function (transition) {
var slot = transition.slot,
config = transition.config,
trail = transition.trail,
if (!state.current.instances.has(key)) state.current.instances.set(key, new Controller()); // update the map object
var ctrl = state.current.instances.get(key);
var newProps = _extends({}, extra, {
onRest: function onRest(values) {
if (state.current.mounted) {
if (transition.destroyed) {
// If no ref is given delete destroyed items immediately
if (!ref && !lazy) cleanUp(state, key);
if (onDestroyed) onDestroyed(item);
} // A transition comes to rest once all its springs conclude
var curInstances = Array.from(state.current.instances);
var active = curInstances.some(function (_ref4) {
if (!active && (ref || lazy) && state.current.deleted.length > 0) cleanUp(state);
if (_onRest) _onRest(item, slot, values);
onStart: onStart && function () {
return onStart(item, slot);
onFrame: onFrame && function (values) {
return onFrame(item, slot, values);
reset: reset && slot === ENTER // Update controller
if (!state.current.paused) ctrl.start();
React.useEffect(function () {
state.current.mounted = mounted.current = true;
state.current.mounted = mounted.current = false;
Array.from(state.current.instances).map(function (_ref5) {
state.current.instances.clear();
return state.current.transitions.map(function (_ref6) {
props: state.current.instances.get(key).getValues()
function cleanUp(state, filterKey) {
var deleted = state.current.deleted;
var _loop = function _loop() {
if (_i >= _iterator.length) return "break";
if (_i.done) return "break";
var filter = function filter(t) {
if (is.und(filterKey) || filterKey === key) {
state.current.instances.delete(key);
state.current.transitions = state.current.transitions.filter(filter);
state.current.deleted = state.current.deleted.filter(filter);
for (var _iterator = deleted, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
if (_ret === "break") break;
state.current.forceUpdate();
function diffItems(_ref9, props) {
prevProps = _ref9.prevProps,
state = _objectWithoutPropertiesLoose(_ref9, ["first", "prevProps"]);
_get2$trail = _get2.trail,
trail = _get2$trail === void 0 ? 0 : _get2$trail,
_get2$order = _get2.order,
order = _get2$order === void 0 ? [ENTER, LEAVE, UPDATE] : _get2$order;
var _get3 = get(prevProps),
var current = _extends({}, state.current);
var deleted = [].concat(state.deleted); // Compare next keys with current keys
var currentKeys = Object.keys(current);
var currentSet = new Set(currentKeys);
var nextSet = new Set(keys);
var added = keys.filter(function (item) {
return !currentSet.has(item);
var removed = state.transitions.filter(function (item) {
return !item.destroyed && !nextSet.has(item.originalKey);
var updated = keys.filter(function (item) {
return currentSet.has(item);
var changeType = order.shift();
added.forEach(function (key, index) {
// In unique mode, remove fading out transitions if their key comes in again
if (unique && deleted.find(function (d) {
return d.originalKey === key;
})) deleted = deleted.filter(function (t) {
return t.originalKey !== key;
var keyIndex = keys.indexOf(key);
var item = items[keyIndex];
var slot = first && initial !== void 0 ? 'initial' : ENTER;
key: unique ? String(key) : guid++,
trail: delay = delay + trail,
config: callProp(config, item, slot),
from: callProp(first ? initial !== void 0 ? initial || {} : from : from, item),
to: callProp(enter, item)
removed.forEach(function (key) {
var keyIndex = _keys.indexOf(key);
var item = _items[keyIndex];
deleted.unshift(_extends({}, current[key], {
left: _keys[Math.max(0, keyIndex - 1)],
right: _keys[Math.min(_keys.length, keyIndex + 1)],
trail: delay = delay + trail,
config: callProp(config, item, slot),
to: callProp(leave, item)
updated.forEach(function (key) {
var keyIndex = keys.indexOf(key);
var item = items[keyIndex];
current[key] = _extends({}, current[key], {
trail: delay = delay + trail,
config: callProp(config, item, slot),
to: callProp(update, item)
var out = keys.map(function (key) {
}); // This tries to restore order for deleted items by finding their last known siblings
// only using the left sibling to keep order placement consistent for all deleted items
deleted.forEach(function (_ref10) {
item = _objectWithoutPropertiesLoose(_ref10, ["left", "right"]);
var pos; // Was it the element on the left, if yes, move there ...
if ((pos = out.findIndex(function (t) {
return t.originalKey === left;
})) !== -1) pos += 1; // And if nothing else helps, move it to the start ¯\_(ツ)_/¯
out = [].concat(out.slice(0, pos), [item], out.slice(pos));
return _extends({}, state, {
changed: added.length || removed.length || updated.length,
first: first && added.length === 0,
function (_AnimatedObject) {
_inheritsLoose(AnimatedStyle, _AnimatedObject);
function AnimatedStyle(style) {
_this = _AnimatedObject.call(this) || this;
if (style.transform && !(style.transform instanceof Animated)) {
style = applyAnimatedValues.transform(style);
// http://www.w3.org/TR/css3-color/#svg-color
antiquewhite: 0xfaebd7ff,
blanchedalmond: 0xffebcdff,
cornflowerblue: 0x6495edff,
darkgoldenrod: 0xb8860bff,
darkolivegreen: 0x556b2fff,
darkseagreen: 0x8fbc8fff,
darkslateblue: 0x483d8bff,
darkslategray: 0x2f4f4fff,
darkslategrey: 0x2f4f4fff,
darkturquoise: 0x00ced1ff,