framer-motion
Version:
A simple and powerful React animation library
132 lines (129 loc) • 6.36 kB
JavaScript
import { __extends, __assign, __read } from 'tslib';
import sync from 'framesync';
import React__default, { useContext } from 'react';
import { usePresence } from '../../../components/AnimatePresence/use-presence.mjs';
import { LayoutGroupContext } from '../../../context/LayoutGroupContext.mjs';
import { SwitchLayoutGroupContext } from '../../../context/SwitchLayoutGroupContext.mjs';
import { globalProjectionState } from '../../../projection/node/create-projection-node.mjs';
import { correctBorderRadius } from '../../../projection/styles/scale-border-radius.mjs';
import { correctBoxShadow } from '../../../projection/styles/scale-box-shadow.mjs';
import { addScaleCorrector } from '../../../projection/styles/scale-correction.mjs';
var MeasureLayoutWithContext = /** @class */ (function (_super) {
__extends(MeasureLayoutWithContext, _super);
function MeasureLayoutWithContext() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* This only mounts projection nodes for components that
* need measuring, we might want to do it for all components
* in order to incorporate transforms
*/
MeasureLayoutWithContext.prototype.componentDidMount = function () {
var _this = this;
var _a = this.props, visualElement = _a.visualElement, layoutGroup = _a.layoutGroup, switchLayoutGroup = _a.switchLayoutGroup, layoutId = _a.layoutId;
var projection = visualElement.projection;
addScaleCorrector(defaultScaleCorrectors);
if (projection) {
if (layoutGroup === null || layoutGroup === void 0 ? void 0 : layoutGroup.group)
layoutGroup.group.add(projection);
if ((switchLayoutGroup === null || switchLayoutGroup === void 0 ? void 0 : switchLayoutGroup.register) && layoutId) {
switchLayoutGroup.register(projection);
}
projection.root.didUpdate();
projection.addEventListener("animationComplete", function () {
_this.safeToRemove();
});
projection.setOptions(__assign(__assign({}, projection.options), { onExitComplete: function () { return _this.safeToRemove(); } }));
}
globalProjectionState.hasEverUpdated = true;
};
MeasureLayoutWithContext.prototype.getSnapshotBeforeUpdate = function (prevProps) {
var _this = this;
var _a = this.props, layoutDependency = _a.layoutDependency, visualElement = _a.visualElement, drag = _a.drag, isPresent = _a.isPresent;
var projection = visualElement.projection;
if (!projection)
return null;
/**
* TODO: We use this data in relegate to determine whether to
* promote a previous element. There's no guarantee its presence data
* will have updated by this point - if a bug like this arises it will
* have to be that we markForRelegation and then find a new lead some other way,
* perhaps in didUpdate
*/
projection.isPresent = isPresent;
if (drag ||
prevProps.layoutDependency !== layoutDependency ||
layoutDependency === undefined) {
projection.willUpdate();
}
else {
this.safeToRemove();
}
if (prevProps.isPresent !== isPresent) {
if (isPresent) {
projection.promote();
}
else if (!projection.relegate()) {
/**
* If there's another stack member taking over from this one,
* it's in charge of the exit animation and therefore should
* be in charge of the safe to remove. Otherwise we call it here.
*/
sync.postRender(function () {
var _a;
if (!((_a = projection.getStack()) === null || _a === void 0 ? void 0 : _a.members.length)) {
_this.safeToRemove();
}
});
}
}
return null;
};
MeasureLayoutWithContext.prototype.componentDidUpdate = function () {
var projection = this.props.visualElement.projection;
if (projection) {
projection.root.didUpdate();
if (!projection.currentAnimation && projection.isLead()) {
this.safeToRemove();
}
}
};
MeasureLayoutWithContext.prototype.componentWillUnmount = function () {
var _a = this.props, visualElement = _a.visualElement, layoutGroup = _a.layoutGroup, promoteContext = _a.switchLayoutGroup;
var projection = visualElement.projection;
if (projection) {
projection.scheduleCheckAfterUnmount();
if (layoutGroup === null || layoutGroup === void 0 ? void 0 : layoutGroup.group)
layoutGroup.group.remove(projection);
if (promoteContext === null || promoteContext === void 0 ? void 0 : promoteContext.deregister)
promoteContext.deregister(projection);
}
};
MeasureLayoutWithContext.prototype.safeToRemove = function () {
var safeToRemove = this.props.safeToRemove;
safeToRemove === null || safeToRemove === void 0 ? void 0 : safeToRemove();
};
MeasureLayoutWithContext.prototype.render = function () {
return null;
};
return MeasureLayoutWithContext;
}(React__default.Component));
function MeasureLayout(props) {
var _a = __read(usePresence(), 2), isPresent = _a[0], safeToRemove = _a[1];
var layoutGroup = useContext(LayoutGroupContext);
return (React__default.createElement(MeasureLayoutWithContext, __assign({}, props, { layoutGroup: layoutGroup, switchLayoutGroup: useContext(SwitchLayoutGroupContext), isPresent: isPresent, safeToRemove: safeToRemove })));
}
var defaultScaleCorrectors = {
borderRadius: __assign(__assign({}, correctBorderRadius), { applyTo: [
"borderTopLeftRadius",
"borderTopRightRadius",
"borderBottomLeftRadius",
"borderBottomRightRadius",
] }),
borderTopLeftRadius: correctBorderRadius,
borderTopRightRadius: correctBorderRadius,
borderBottomLeftRadius: correctBorderRadius,
borderBottomRightRadius: correctBorderRadius,
boxShadow: correctBoxShadow,
};
export { MeasureLayout };