bootstrap-vue-next
Version:
BootstrapVueNext is an early and lovely component library for Vue 3 & Nuxt 3 based on Bootstrap 5 and Typescript.
467 lines (466 loc) • 14.9 kB
JavaScript
import { ref, watch, computed, onMounted, nextTick, inject, getCurrentInstance, readonly, onBeforeUnmount, onUnmounted } from "vue";
import { g as globalShowHideStorageInjectionKey } from "./keys-DUCx0SNv.mjs";
import { a as BvTriggerableEvent } from "./classes-B4vxmOuN.mjs";
import { e as useEventListener } from "./index-CMqRvrZx.mjs";
import { q as useThrottleFn } from "./index-CaguhSuF.mjs";
const fadeBaseTransitionProps = {
name: "fade",
enterActiveClass: "",
enterFromClass: "showing",
enterToClass: "",
leaveActiveClass: "",
leaveFromClass: "",
leaveToClass: "showing",
css: true
};
const useShowHide = (modelValue, props, emit, element, computedId, options = {
transitionProps: {},
showFn: () => {
},
hideFn: () => {
}
}) => {
var _a;
let noAction = false;
const initialShow = !!modelValue.value && !props.initialAnimation || props.visible || false;
const showRef = ref(initialShow);
const renderRef = ref(initialShow);
const renderBackdropRef = ref(initialShow);
let isCountdown = typeof modelValue.value !== "boolean";
watch(modelValue, () => {
isCountdown = typeof modelValue.value !== "boolean";
if (noAction) {
noAction = false;
return;
}
if (modelValue.value) {
show();
} else {
hide("modelValue", true);
}
});
const localNoAnimation = ref(initialShow);
const localTemporaryHide = ref(false);
const computedNoAnimation = computed(
() => props.noAnimation || props.noFade || localNoAnimation.value || false
);
let isMounted = false;
onMounted(() => {
var _a2;
isMounted = true;
if (!props.show && initialShow) {
const event = buildTriggerableEvent("show", { cancelable: true });
emit("show", event);
if (event.defaultPrevented) {
emit("show-prevented", buildTriggerableEvent("show-prevented"));
return;
}
localNoAnimation.value = true;
if (!modelValue.value) {
noAction = true;
modelValue.value = true;
}
renderRef.value = true;
renderBackdropRef.value = true;
isVisible.value = true;
backdropVisible.value = true;
backdropReady.value = true;
showRef.value = true;
(_a2 = options.showFn) == null ? void 0 : _a2.call(options);
} else if (props.show || !!modelValue.value && props.initialAnimation) {
show();
}
});
watch(
() => props.visible,
(newval) => {
localNoAnimation.value = true;
nextTick(() => {
if (newval) isVisible.value = true;
if (newval) {
show();
} else {
hide("visible-prop", true);
}
});
}
);
watch(
() => props.show,
(newval) => {
if (newval) {
show();
} else {
hide("show-prop", true);
}
}
);
useEventListener(element, "bv-toggle", () => {
modelValue.value = !modelValue.value;
});
const buildTriggerableEvent = (type, opts = {}) => new BvTriggerableEvent(type, {
cancelable: false,
target: (element == null ? void 0 : element.value) || null,
relatedTarget: null,
trigger: null,
...opts,
componentId: computedId == null ? void 0 : computedId.value
});
let showTimeout;
let hideTimeout;
let _Resolve;
let _Promise;
let _resolveOnHide;
const show = (resolveOnHide = false) => {
if (showRef.value && !hideTimeout && !_Promise) return Promise.resolve(true);
_resolveOnHide = resolveOnHide;
if (showRef.value && !hideTimeout && _Promise) return _Promise;
_Promise = new Promise((resolve) => {
_Resolve = resolve;
});
const event = buildTriggerableEvent("show", { cancelable: true });
emit("show", event);
if (event.defaultPrevented) {
emit("show-prevented", buildTriggerableEvent("show-prevented"));
if (isVisible.value) {
isVisible.value = false;
}
if (modelValue.value && !isCountdown) {
noAction = true;
nextTick(() => {
modelValue.value = false;
});
}
_Resolve == null ? void 0 : _Resolve("show-prevented");
return _Promise;
}
if (hideTimeout) {
clearTimeout(hideTimeout);
hideTimeout = void 0;
}
renderRef.value = true;
renderBackdropRef.value = true;
requestAnimationFrame(() => {
var _a2, _b;
if (localNoAnimation.value || props.delay === void 0) {
if (!isMounted) return;
showTimeout = void 0;
showRef.value = true;
(_a2 = options.showFn) == null ? void 0 : _a2.call(options);
if (!modelValue.value) {
noAction = true;
nextTick(() => {
modelValue.value = true;
});
}
return;
}
showTimeout = setTimeout(
() => {
var _a3;
if (!isMounted) return;
showTimeout = void 0;
showRef.value = true;
(_a3 = options.showFn) == null ? void 0 : _a3.call(options);
if (!modelValue.value) {
noAction = true;
nextTick(() => {
modelValue.value = true;
});
}
},
typeof props.delay === "number" ? props.delay : ((_b = props.delay) == null ? void 0 : _b.show) || 0
);
});
return _Promise;
};
let leaveTrigger;
const hide = (trigger, noTriggerEmit) => {
var _a2;
if (!showRef.value && !showTimeout) return Promise.resolve("");
if (!_Promise)
_Promise = new Promise((resolve) => {
_Resolve = resolve;
});
if (typeof trigger !== "string") trigger = void 0;
leaveTrigger = trigger;
const event = buildTriggerableEvent("hide", { cancelable: true, trigger });
const event2 = buildTriggerableEvent(trigger || "ignore", { cancelable: true, trigger });
if (trigger === "backdrop" && props.noCloseOnBackdrop || trigger === "esc" && props.noCloseOnEsc) {
emit("hide-prevented", buildTriggerableEvent("hide-prevented", { trigger }));
_Resolve == null ? void 0 : _Resolve("hide-prevented");
return _Promise;
}
if (showTimeout) {
clearTimeout(showTimeout);
showTimeout = void 0;
}
if (trigger && !noTriggerEmit) {
emit(trigger, event2);
}
emit("hide", event);
if (event.defaultPrevented || event2.defaultPrevented) {
emit("hide-prevented", buildTriggerableEvent("hide-prevented", { trigger }));
if (!modelValue.value) {
nextTick(() => {
noAction = true;
modelValue.value = true;
});
}
_Resolve == null ? void 0 : _Resolve("hide-prevented");
return _Promise;
}
trapActive.value = false;
if (showTimeout) {
clearTimeout(showTimeout);
showTimeout = void 0;
if (!localTemporaryHide.value) renderRef.value = false;
renderBackdropRef.value = false;
}
hideTimeout = setTimeout(
() => {
var _a3;
if (!isMounted) return;
hideTimeout = void 0;
isLeaving.value = true;
showRef.value = false;
(_a3 = options.hideFn) == null ? void 0 : _a3.call(options);
if (modelValue.value) {
noAction = true;
modelValue.value = isCountdown ? 0 : false;
}
},
localNoAnimation.value ? 0 : typeof props.delay === "number" ? props.delay : ((_a2 = props.delay) == null ? void 0 : _a2.hide) || 0
);
return _Promise;
};
const throttleHide = useThrottleFn((a) => hide(a), 500);
const throttleShow = useThrottleFn(() => show(), 500);
const toggle = (resolveOnHide = false) => {
const e = buildTriggerableEvent("toggle", { cancelable: true });
emit("toggle", e);
if (e.defaultPrevented) {
emit("toggle-prevented", buildTriggerableEvent("toggle-prevented"));
return Promise.resolve("toggle-prevented");
}
if (showRef.value) {
return hide("toggle-function", true);
}
return show(resolveOnHide);
};
const triggerToggle = () => {
const e = buildTriggerableEvent("toggle", { cancelable: true });
emit("toggle", e);
if (e.defaultPrevented) {
emit("toggle-prevented", buildTriggerableEvent("toggle-prevented"));
return;
}
if (showRef.value) {
hide("toggle-trigger", true);
} else {
show();
}
};
const triggerRegistry = [];
const registerTrigger = (trigger, el) => {
triggerRegistry.push({ trigger, el });
el.addEventListener(trigger, triggerToggle);
checkVisibility(el);
};
const unregisterTrigger = (trigger, el, clean = true) => {
const idx = triggerRegistry.findIndex((t) => (t == null ? void 0 : t.trigger) === trigger && t.el === el);
if (idx > -1) {
triggerRegistry.splice(idx, 1);
el.removeEventListener(trigger, triggerToggle);
if (clean) {
el.removeAttribute("aria-expanded");
el.classList.remove("collapsed");
el.classList.remove("not-collapsed");
}
}
};
const appRegistry = (_a = inject(globalShowHideStorageInjectionKey, void 0)) == null ? void 0 : _a.register({
id: computedId.value,
toggle,
show,
hide,
value: readonly(showRef),
registerTrigger,
unregisterTrigger,
component: getCurrentInstance()
});
const checkVisibility = (el) => {
el.setAttribute("aria-expanded", modelValue.value ? "true" : "false");
el.classList.toggle("collapsed", !modelValue.value);
el.classList.toggle("not-collapsed", !!modelValue.value);
};
watch(modelValue, () => {
triggerRegistry.forEach((t) => {
checkVisibility(t.el);
});
});
onBeforeUnmount(() => {
appRegistry == null ? void 0 : appRegistry.unregister();
triggerRegistry.forEach((t) => {
t.el.removeEventListener(t.trigger, triggerToggle);
});
});
onUnmounted(() => {
isMounted = false;
clearTimeout(showTimeout);
clearTimeout(hideTimeout);
showTimeout = void 0;
hideTimeout = void 0;
});
const lazyLoadCompleted = ref(false);
const markLazyLoadCompleted = () => {
if (props.lazy === true) lazyLoadCompleted.value = true;
};
const isLeaving = ref(false);
const isActive = ref(initialShow);
const isVisible = ref(initialShow);
const onBeforeEnter = (el) => {
var _a2, _b, _c, _d;
(_b = (_a2 = options.transitionProps) == null ? void 0 : _a2.onBeforeEnter) == null ? void 0 : _b.call(_a2, el);
(_d = (_c = props.transitionProps) == null ? void 0 : _c.onBeforeEnter) == null ? void 0 : _d.call(_c, el);
isActive.value = true;
};
const onEnter = (el) => {
var _a2, _b, _c, _d;
requestAnimationFrame(() => {
requestAnimationFrame(() => {
isVisible.value = true;
});
});
(_b = (_a2 = options.transitionProps) == null ? void 0 : _a2.onEnter) == null ? void 0 : _b.call(_a2, el);
(_d = (_c = props.transitionProps) == null ? void 0 : _c.onEnter) == null ? void 0 : _d.call(_c, el);
};
const onAfterEnter = (el) => {
var _a2, _b, _c, _d;
markLazyLoadCompleted();
(_b = (_a2 = options.transitionProps) == null ? void 0 : _a2.onAfterEnter) == null ? void 0 : _b.call(_a2, el);
(_d = (_c = props.transitionProps) == null ? void 0 : _c.onAfterEnter) == null ? void 0 : _d.call(_c, el);
if (localNoAnimation.value) {
requestAnimationFrame(() => {
localNoAnimation.value = false;
});
}
if (localTemporaryHide.value) {
localTemporaryHide.value = false;
}
requestAnimationFrame(() => {
trapActive.value = true;
nextTick(() => {
emit("shown", buildTriggerableEvent("shown", { cancelable: false }));
});
});
if (!_resolveOnHide) {
_Resolve == null ? void 0 : _Resolve(true);
_Promise = void 0;
_Resolve = void 0;
}
};
const onBeforeLeave = (el) => {
var _a2, _b, _c, _d;
if (!isLeaving.value) isLeaving.value = true;
(_b = (_a2 = options.transitionProps) == null ? void 0 : _a2.onBeforeLeave) == null ? void 0 : _b.call(_a2, el);
(_d = (_c = props.transitionProps) == null ? void 0 : _c.onBeforeLeave) == null ? void 0 : _d.call(_c, el);
trapActive.value = false;
};
const onLeave = (el) => {
var _a2, _b, _c, _d;
isVisible.value = false;
(_b = (_a2 = options.transitionProps) == null ? void 0 : _a2.onLeave) == null ? void 0 : _b.call(_a2, el);
(_d = (_c = props.transitionProps) == null ? void 0 : _c.onLeave) == null ? void 0 : _d.call(_c, el);
};
const onAfterLeave = (el) => {
var _a2, _b, _c, _d;
emit("hidden", buildTriggerableEvent("hidden", { trigger: leaveTrigger, cancelable: false }));
(_b = (_a2 = options.transitionProps) == null ? void 0 : _a2.onAfterLeave) == null ? void 0 : _b.call(_a2, el);
(_d = (_c = props.transitionProps) == null ? void 0 : _c.onAfterLeave) == null ? void 0 : _d.call(_c, el);
isLeaving.value = false;
isActive.value = false;
if (localNoAnimation.value) {
requestAnimationFrame(() => {
localNoAnimation.value = false;
});
}
requestAnimationFrame(() => {
if (!localTemporaryHide.value) renderRef.value = false;
});
_Resolve == null ? void 0 : _Resolve(leaveTrigger || "");
_Promise = void 0;
_Resolve = void 0;
leaveTrigger = void 0;
};
const contentShowing = computed(
() => localTemporaryHide.value === true || isActive.value === true || props.lazy === false || props.lazy === true && lazyLoadCompleted.value === true && props.unmountLazy === false
);
const trapActive = ref(false);
const backdropVisible = ref(false);
const backdropReady = ref(false);
const transitionFunctions = {
...options.transitionProps,
onBeforeEnter,
onEnter,
onAfterEnter,
onBeforeLeave,
onLeave,
onAfterLeave
};
return {
showRef,
renderRef,
renderBackdropRef,
isVisible,
isActive,
trapActive,
show,
hide,
toggle,
throttleHide,
throttleShow,
buildTriggerableEvent,
computedNoAnimation,
localNoAnimation,
localTemporaryHide,
isLeaving,
transitionProps: {
...fadeBaseTransitionProps,
...props.transitionProps,
...transitionFunctions
},
lazyLoadCompleted,
markLazyLoadCompleted,
contentShowing,
backdropReady,
backdropVisible,
backdropTransitionProps: {
...fadeBaseTransitionProps,
onBeforeEnter: () => {
requestAnimationFrame(() => {
requestAnimationFrame(() => {
backdropVisible.value = true;
});
});
backdropReady.value = false;
},
onAfterEnter: () => {
backdropReady.value = true;
},
onBeforeLeave: () => {
backdropVisible.value = false;
},
onAfterLeave: () => {
backdropReady.value = false;
requestAnimationFrame(() => {
renderBackdropRef.value = false;
});
}
}
};
};
export {
useShowHide as u
};
//# sourceMappingURL=useShowHide-CguGFDSN.mjs.map