omi-transition
Version:
Define transition animation for entering and leaving
97 lines (96 loc) • 3.38 kB
JavaScript
import { registerDirective } from "omi";
registerDirective("transition", (dom, options) => {
if (dom["__updateClasses"])
return;
dom["__updateClasses"] = debounce(updateClasses, 0);
const { name, delay = 0 } = options;
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === "attributes" && mutation.attributeName === "show") {
const show2 = getShowAttribute(dom);
dom["__updateClasses"](dom, name, show2, delay, options);
}
});
});
observer.observe(dom, { attributes: true });
const onTransitionEnd = debounce(() => {
var _a, _b;
const show2 = getShowAttribute(dom);
if (show2) {
(_a = options.afterEnter) == null ? void 0 : _a.call(options, dom);
} else {
(_b = options.afterLeave) == null ? void 0 : _b.call(options, dom);
dom.style.display = "none";
}
dom.classList.remove(`${name}-enter-active`);
dom.classList.remove(`${name}-leave-active`);
}, 0);
if (dom["__onTransitionEnd"]) {
dom.removeEventListener("transitionend", dom["__onTransitionEnd"]);
dom.removeEventListener("animationend", dom["__onTransitionEnd"]);
}
dom.addEventListener("transitionend", onTransitionEnd);
dom.addEventListener("animationend", onTransitionEnd);
dom["__onTransitionEnd"] = onTransitionEnd;
const show = getShowAttribute(dom);
dom["__updateClasses"](dom, name, show, delay, options);
});
function getShowAttribute(dom) {
var _a;
return dom.getAttribute("show") === "true" || dom.getAttribute("show") === "1" || ((_a = dom.props) == null ? void 0 : _a.show);
}
let isFirstRender = true;
let previousDisplay = null;
function updateClasses(dom, name, show, delay, options) {
var _a, _b;
if (show) {
isFirstRender = false;
dom.style.display = previousDisplay || "";
(_a = options.beforeEnter) == null ? void 0 : _a.call(options, dom);
dom.classList.remove(`${name}-leave-to`);
dom.classList.remove(`${name}-leave-active`);
dom.classList.add(`${name}-enter-from`);
requestAnimationFrame(() => {
setTimeout(() => {
var _a2;
(_a2 = options.enter) == null ? void 0 : _a2.call(options, dom);
dom.classList.remove(`${name}-enter-from`);
dom.classList.add(`${name}-enter-to`);
dom.classList.add(`${name}-enter-active`);
}, 1 + delay);
});
} else {
if (dom.style.display !== "none") {
previousDisplay = dom.style.display;
}
(_b = options.beforeLeave) == null ? void 0 : _b.call(options, dom);
if (isFirstRender) {
dom.style.display = "none";
isFirstRender = false;
} else {
dom.classList.remove(`${name}-enter-to`);
dom.classList.remove(`${name}-enter-active`);
dom.classList.add(`${name}-leave-from`);
requestAnimationFrame(() => {
setTimeout(() => {
var _a2;
(_a2 = options.leave) == null ? void 0 : _a2.call(options, dom);
dom.classList.remove(`${name}-leave-from`);
dom.classList.add(`${name}-leave-to`);
dom.classList.add(`${name}-leave-active`);
}, 1 + delay);
});
}
}
}
function debounce(func, wait) {
let timeout;
return function(...args) {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
func.apply(this, args);
}, wait);
};
}