@atlaskit/motion
Version:
A set of utilities to apply motion in your application.
68 lines • 2.68 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import { durations } from '../utils/durations';
import { isReducedMotion } from '../utils/is-reduced-motion';
import { useElementRef } from '../utils/use-element-ref';
import { useLayoutEffect } from '../utils/use-layout-effect';
import { useRequestAnimationFrame } from '../utils/use-request-animation-frame';
import { useSetTimeout } from '../utils/use-set-timeout';
import { useExitingPersistence } from './exiting-persistence';
/**
* __ShrinkOut__
*
* Will shrink an element down to nothing when exiting.
* Works best with flex children as collapsing margins can come with undesired behaviour.
*
* - [Examples](https://atlaskit.atlassian.com/packages/design-system/motion/docs/entering-motion)
*/
var ShrinkOut = function ShrinkOut(_ref) {
var children = _ref.children,
_ref$duration = _ref.duration,
duration = _ref$duration === void 0 ? 'small' : _ref$duration,
onFinish = _ref.onFinish;
var _useElementRef = useElementRef(),
_useElementRef2 = _slicedToArray(_useElementRef, 2),
element = _useElementRef2[0],
setElementRef = _useElementRef2[1];
var exiting = useExitingPersistence();
var requestAnimationFrame = useRequestAnimationFrame();
var setTimeout = useSetTimeout();
var direction = exiting.isExiting ? 'exiting' : 'entering';
useLayoutEffect(function () {
if (exiting.isExiting && element) {
if (isReducedMotion()) {
exiting.onFinish && exiting.onFinish();
onFinish && onFinish('exiting');
return;
}
var newStyles = {
// We fix both width and height because when changing box sizing to border-box.
width: "".concat(element.offsetWidth, "px"),
height: "".concat(element.offsetHeight, "px"),
boxSizing: 'border-box',
willChange: 'width,margin'
};
Object.assign(element.style, newStyles);
requestAnimationFrame(function () {
requestAnimationFrame(function () {
var newStyles = {
width: '0px',
margin: '0px',
// We animate margin down to zero so it doesn't take any space.
transitionTimingFunction: 'cubic-bezier(0.8,0,0,0.8)',
transitionDuration: durations[duration] + 'ms',
transitionProperty: 'width,margin'
};
Object.assign(element.style, newStyles);
setTimeout(function () {
exiting.onFinish && exiting.onFinish();
onFinish && onFinish('exiting');
}, durations[duration]);
});
});
}
});
return children({
ref: setElementRef
}, direction);
};
export default ShrinkOut;