motion-v
Version:
<p align="center"> <img width="100" height="100" alt="Motion logo" src="https://user-images.githubusercontent.com/7850794/164965523-3eced4c4-6020-467e-acde-f11b7900ad62.png" /> </p> <h1 align="center">Motion for Vue</h1>
127 lines (126 loc) • 3.81 kB
JavaScript
import { defineComponent, onMounted, onUnmounted, computed, openBlock, createBlock, resolveDynamicComponent, Transition, TransitionGroup, mergeProps, withCtx, renderSlot } from "vue";
import { mountedStates } from "../../state/motion-state.mjs";
import { provideAnimatePresence, removeDoneCallback, doneCallbacks } from "../presence.mjs";
import { usePopLayout } from "./use-pop-layout.mjs";
import { delay } from "../../utils/delay.mjs";
const _sfc_main = /* @__PURE__ */ defineComponent({
...{
name: "AnimatePresence",
inheritAttrs: true
},
__name: "AnimatePresence",
props: {
mode: { default: "sync" },
initial: { type: Boolean, default: true },
as: {},
custom: {},
onExitComplete: {},
anchorX: { default: "left" }
},
setup(__props) {
const props = __props;
const presenceContext = {
initial: props.initial,
custom: props.custom
};
provideAnimatePresence(presenceContext);
onMounted(() => {
presenceContext.initial = void 0;
});
const { addPopStyle, removePopStyle, styles } = usePopLayout(props);
function findMotionElement(el) {
let current = el;
while (current) {
if (mountedStates.get(current)) {
return current;
}
current = current.firstElementChild;
}
return null;
}
function enter(el) {
const state = mountedStates.get(el);
if (!state) {
return;
}
removePopStyle(state);
state.isVShow = true;
removeDoneCallback(el);
delay(() => {
state.setActive("exit", false);
});
}
const exitDom = /* @__PURE__ */ new Map();
onUnmounted(() => {
exitDom.clear();
});
function exit(el, done) {
var _a;
const motionEl = findMotionElement(el);
const state = mountedStates.get(motionEl);
if (!motionEl || !state) {
done();
if (exitDom.size === 0) {
(_a = props.onExitComplete) == null ? void 0 : _a.call(props);
}
return;
}
exitDom.set(motionEl, true);
removeDoneCallback(motionEl);
addPopStyle(state);
function doneCallback(e) {
var _a2, _b;
if ((_a2 = e == null ? void 0 : e.detail) == null ? void 0 : _a2.isExit) {
const projection = state.visualElement.projection;
if ((projection == null ? void 0 : projection.animationProgress) > 0 && !state.isSafeToRemove && !state.isVShow) {
return;
}
removeDoneCallback(motionEl);
exitDom.delete(motionEl);
if (exitDom.size === 0) {
(_b = props.onExitComplete) == null ? void 0 : _b.call(props);
}
if (!styles.has(state)) {
state.willUpdate("done");
} else {
removePopStyle(state);
}
done();
if (!motionEl.isConnected) {
state.unmount(true);
}
}
}
delay(() => {
state.setActive("exit", true);
doneCallbacks.set(motionEl, doneCallback);
motionEl.addEventListener("motioncomplete", doneCallback);
});
}
const transitionProps = computed(() => {
if (props.mode !== "wait") {
return {
tag: props.as
};
}
return {
mode: props.mode === "wait" ? "out-in" : void 0
};
});
return (_ctx, _cache) => {
return openBlock(), createBlock(resolveDynamicComponent(_ctx.mode === "wait" ? Transition : TransitionGroup), mergeProps({ css: false }, transitionProps.value, {
appear: "",
onEnter: enter,
onLeave: exit
}), {
default: withCtx(() => [
renderSlot(_ctx.$slots, "default")
]),
_: 3
}, 16);
};
}
});
export {
_sfc_main as default
};