UNPKG

bootstrap-vue-next

Version:

Seamless integration of Vue 3, Bootstrap 5, and TypeScript for modern, type-safe UI development

144 lines (143 loc) 5.32 kB
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); require("../../../chunk-CoQrYLCe.js"); const require_dist = require("../../../dist-BJ15ThEs.js"); const require_dom = require("../../../dom-Bs6DzM72.js"); const require_getElement = require("../../../getElement-CxWWOx3K.js"); let vue = require("vue"); //#region src/composables/useScrollspy/index.ts var useScrollspy = (content, target, options = {}) => { const cont = (0, vue.toRef)(content); const tar = (0, vue.toRef)(target); const resolvedContent = (0, vue.ref)(require_getElement.getElement(cont.value)); const resolvedTarget = (0, vue.ref)(require_getElement.getElement(tar.value)); (0, vue.watch)([cont, tar], () => { updateList(); }); const { contentQuery = ":scope > [id]", targetQuery = "[href]", manual = false, root, rootMargin = "0px 0px -25%", threshold = [ .1, .5, 1 ], watchChanges = true } = options; const current = (0, vue.ref)(null); const list = (0, vue.ref)([]); const nodeList = (0, vue.ref)([]); if (!(0, vue.getCurrentInstance)()) (0, vue.nextTick)(() => { updateList(); }); else (0, vue.onMounted)(() => { require_dist.syncRef(cont, resolvedContent, { transform: { ltr: (v) => require_getElement.getElement(v) }, direction: "ltr", immediate: true }); require_dist.syncRef(tar, resolvedTarget, { transform: { ltr: (v) => require_getElement.getElement(v) }, direction: "ltr", immediate: true }); updateList(); }); const updateList = () => { nodeList.value = resolvedContent.value ? Array.from(resolvedContent.value.querySelectorAll(contentQuery)) : []; list.value = nodeList.value.map((el) => ({ id: el.id, el, visible: false, text: el.textContent })); }; let isScrollingDown = true; let previousScrollTop = 0; const scrollRoot = (0, vue.computed)(() => resolvedContent.value && getComputedStyle(resolvedContent.value).overflowY === "visible" ? null : resolvedContent.value); const jobs = require_dist.useIntersectionObserver(nodeList, (entries) => { const doc = require_dom.getSafeDocument(); const scrollTop = (scrollRoot.value ? scrollRoot.value : doc !== null ? doc.documentElement : void 0)?.scrollTop || 0; isScrollingDown = scrollTop > previousScrollTop; previousScrollTop = scrollTop; entries.forEach((entry) => { if (entry.isIntersecting) { list.value.forEach((node) => { if (node.el === entry.target) node.visible = true; }); return; } list.value.forEach((node) => { if (node.el === entry.target) node.visible = false; }); }); let newId = null; if (isScrollingDown) newId = [...list.value].reverse().find((node) => node.visible)?.id || null; else newId = list.value.find((node) => node.visible)?.id || null; if (newId !== null) current.value = newId; if (!current.value) current.value = list.value[0]?.id || null; }, { root: (0, vue.computed)(() => root ? require_getElement.getElement((0, vue.unref)(root)) : scrollRoot.value), rootMargin, threshold }); (0, vue.watch)(current, (newId) => { if (manual) return; const nodes = resolvedTarget.value?.querySelectorAll(targetQuery); if (nodes === void 0) return; let foundParent = false; let activeElement = null; nodes.forEach((node) => { const parentDropdown = node.closest(".dropdown"); if (node.getAttribute("href")?.includes(`#${newId}`)) { activeElement = node; node.classList.add("active"); if (parentDropdown) { parentDropdown?.querySelector(".dropdown-toggle")?.classList.add("active"); foundParent = true; } let parentNav = node.closest(".nav")?.previousSibling; while (parentNav?.classList?.contains("nav-item")) { foundParent = true; parentNav.querySelector(".nav-link")?.classList.add("active"); parentNav = parentNav.closest(".nav")?.previousSibling; } } else { node.classList.remove("active"); if (parentDropdown && !foundParent) parentDropdown?.querySelector(".dropdown-toggle")?.classList.remove("active"); if (!foundParent) { let parentNav = node.closest(".nav")?.previousSibling; while (parentNav?.classList?.contains("nav-item")) { foundParent = true; if (parentNav.querySelector(".nav-link") !== activeElement) parentNav.querySelector(".nav-link")?.classList.remove("active"); parentNav = parentNav.closest(".nav")?.previousSibling; } } } }); }); const mobs = !watchChanges ? { stop: () => {} } : require_dist.useMutationObserver(resolvedContent, () => { updateList(); }, { childList: true }); const scrollIntoView = (event, smooth = false) => { event.preventDefault(); const href = event.target?.getAttribute?.("href"); const doc = require_dom.getSafeDocument(); const el = href ? doc?.querySelector(href) ?? null : null; if (el && resolvedContent.value) if (resolvedContent.value.scrollTo) resolvedContent.value.scrollTo({ top: el.offsetTop, behavior: smooth ? "smooth" : "auto" }); else resolvedContent.value.scrollTop = el.offsetTop; }; const cleanup = () => { jobs.stop(); mobs.stop(); }; return { current: (0, vue.readonly)(current), list, content: resolvedContent, target: resolvedTarget, scrollIntoView, updateList, cleanup }; }; //#endregion exports.useScrollspy = useScrollspy; //# sourceMappingURL=index.umd.js.map