vue3-slide-up-down-fix
Version:
Vue 3 version of the vue-slide-up-down package
160 lines (159 loc) • 5.28 kB
JavaScript
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
import { ref, computed, onMounted, watch, h } from "vue";
const propsModel = {
modelValue: {
type: Boolean,
default: false
},
duration: {
type: Number,
default: 500
},
timingFunction: {
type: String,
default: "ease-in-out"
},
tag: {
type: String,
default: "div"
},
responsive: {
type: Boolean,
default: false
}
};
var index = {
emits: ["open-start", "close-start", "open-end", "close-end", "layout-shift"],
props: __spreadValues({}, propsModel),
setup(props, { slots, attrs, emit }) {
const containerRef = ref(null);
const isInit = ref(false);
const shouldHideOverflow = ref(false);
const contentHeight = ref(0);
const currentHeight = ref(0);
const isTransitioning = ref(false);
const transitionDuration = computed(() => {
return typeof props.duration === "number" ? `${props.duration}ms` : props.duration;
});
const delayAction = (fn) => {
setTimeout(() => {
window.requestAnimationFrame(fn);
}, 0);
};
const updateContainerHeight = () => {
containerRef.value ? contentHeight.value = containerRef.value.scrollHeight : "";
};
const updateDisplay = () => {
if (isTransitioning.value === true) {
if (props.modelValue === false)
currentHeight.value = 0;
updateContainerHeight();
return transitionEnd({ target: containerRef.value });
}
currentHeight.value = contentHeight.value + "px";
if (props.modelValue === false) {
shouldHideOverflow.value = true;
emit("close-start");
delayAction(() => {
currentHeight.value = 0;
});
} else
emit("open-start");
isTransitioning.value = true;
};
const checkScrollHeight = () => {
const idInterval = setInterval(() => {
if (containerRef.value && containerRef.value.scrollHeight !== 0 && contentHeight.value === 0) {
clearInterval(idInterval);
contentHeight.value = containerRef.value.scrollHeight;
updateDisplay();
}
}, 5);
setTimeout(() => {
clearInterval(idInterval);
}, 5 * 1e3);
};
const generatedBaseStyles = computed(() => ({
transition: isInit.value ? `height ${transitionDuration.value} ${props.timingFunction}` : null,
height: isInit.value ? currentHeight.value : null,
overflowY: shouldHideOverflow.value ? "hidden" : null,
"--content-height": contentHeight.value
}));
const generatedBaseAttributes = computed(() => ({
"aria-hidden": props.modelValue === false ? true : false,
tabindex: props.modelValue === false ? "-1" : null
}));
const transitionEnd = (event) => {
if (event.target !== containerRef.value)
return;
if (props.modelValue === true) {
currentHeight.value = null;
shouldHideOverflow.value = false;
emit("open-end");
} else
emit("close-end");
isTransitioning.value = false;
};
onMounted(() => {
updateContainerHeight();
if (!props.modelValue) {
currentHeight.value = 0;
shouldHideOverflow.value = true;
} else {
currentHeight.value = contentHeight.value + "px";
}
if (props.responsive)
setResizeListener();
isInit.value = true;
checkScrollHeight();
});
watch(() => props.modelValue, (v) => {
updateContainerHeight();
updateDisplay();
});
const resizeCallback = () => {
if (props.modelValue === false)
return;
emit("layout-shift");
currentHeight.value = contentHeight.value + "px";
shouldHideOverflow.value = true;
updateContainerHeight();
setTimeout(updateDisplay, 0);
};
const setResizeListener = () => {
const observer = new MutationObserver(resizeCallback);
const config = {
subtree: true,
attributes: false,
childList: true,
characterData: false
};
observer.observe(containerRef.value, config);
};
return () => h(props.tag, __spreadProps(__spreadValues(__spreadProps(__spreadValues({}, Object.assign({}, attrs, { style: generatedBaseStyles.value })), {
class: "slide-up-down__container",
onTransitionend: transitionEnd
}), generatedBaseAttributes.value), {
ref: containerRef
}), slots.default());
}
};
export { index as default };