UNPKG

nuxt-anchorscroll

Version:
72 lines (71 loc) 3.05 kB
import { computed, toValue } from "vue"; import { useNuxtApp } from "nuxt/app"; export const useAnchorScroll = (options = {}) => { const toAnchorSurfaces = computed(() => { const unwrappedOptions = toValue(options); return unwrappedOptions?.surfaces ?? unwrappedOptions?.toAnchor?.surfaces ?? toValue(useNuxtApp().$anchorScroll?.defaults.surfaces) ?? []; }); const toAnchorScrollOptions = computed(() => { const unwrappedOptions = toValue(options); return unwrappedOptions?.scrollOptions ?? unwrappedOptions?.toAnchor?.scrollOptions ?? toValue(useNuxtApp().$anchorScroll?.defaults?.toAnchor); }); const toTopSurfaces = computed(() => { const unwrappedOptions = toValue(options); return unwrappedOptions?.surfaces ?? unwrappedOptions?.toTop?.surfaces ?? toValue(useNuxtApp().$anchorScroll?.defaults.surfaces) ?? []; }); const toTopScrollOptions = computed(() => { const unwrappedOptions = toValue(options); return unwrappedOptions?.scrollOptions ?? unwrappedOptions?.toTop?.scrollOptions ?? toValue(useNuxtApp().$anchorScroll?.defaults?.toTop); }); return { scrollToAnchor(target) { const maybeElement = toValue(target); let anchorElement = null; if (typeof maybeElement === "string") { anchorElement = document.getElementById(maybeElement.replace(/^#/, "")); } else if (maybeElement instanceof HTMLElement) { anchorElement = maybeElement; } else { const elementId = toValue(maybeElement.id); const elementSelector = toValue(maybeElement.sr); if (elementId) { anchorElement = document.getElementById(elementId.replace(/^#/, "")); } else if (elementSelector) { try { anchorElement = document.querySelector(elementSelector); } catch (error) { console.error("[useAnchorScroll]: While select element from document, next error occurred:", error); } } else { console.error( "[useAnchorScroll]: Wrong object provided to scrollToAnchor composable:", "either 'id' and 'sr' (selector) are not provided in object", maybeElement ); } } if (!anchorElement) return false; const { top, left } = anchorElement.getBoundingClientRect(); const { behavior, offsetLeft, offsetTop } = toValue(toAnchorScrollOptions) ?? {}; const scrollToAnchorOptions = { behavior, ...offsetLeft !== void 0 && { left: left + offsetLeft }, ...offsetTop !== void 0 && { top: top + offsetTop } }; for (const surface of toValue(toAnchorSurfaces)) surface.scrollBy(scrollToAnchorOptions); return true; }, scrollToTop() { const { behavior, offsetLeft, offsetTop } = toValue(toTopScrollOptions) ?? {}; const scrollToTopOptions = { behavior, left: offsetLeft, top: offsetTop }; for (const surface of toValue(toTopSurfaces)) surface.scrollTo(scrollToTopOptions); } }; };