UNPKG

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
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