UNPKG

nuxt-arch

Version:

Arch is a Nuxt 3 template for creating your personal website less than a minute.

116 lines (105 loc) 2.67 kB
import { defineComponent, h, onBeforeUnmount, ref } from 'vue' import { useNuxtApp } from '#app' export default defineComponent({ name: 'NuxtScrollIndicator', props: { height: { type: Number, default: 3, }, color: { type: String, default: 'linear-gradient(to right, #00dc82 0%,#34cdfe 50%,#0047e1 100%)', required: false, }, background: { type: String, default: 'transparent', }, shadow: { type: String, default: 'none', }, borderRadius: { type: Number, default: 0, }, elementId: { type: String, required: false, default: undefined, }, }, setup(props, { slots }) { const indicator = useScrollIndicator(props.elementId) const nuxtApp = useNuxtApp() nuxtApp.hook('app:mounted', indicator.init) onBeforeUnmount(() => indicator.clear()) return () => h( 'div', { class: 'nuxt-scroll-indicator-wrapper', style: { position: 'fixed', zIndex: 999998, right: 0, left: 0, top: 0, pointerEvents: 'none', height: `${props.height}px`, background: props.background, }, }, [ h( 'div', { class: 'nuxt-scroll-indicator', style: { height: '100%', background: props.color, boxShadow: props.shadow, borderRadius: `0 ${props.borderRadius}px ${props.borderRadius}px 0`, width: `${indicator.width.value}%`, }, }, slots, ), ], ) }, }) function useScrollIndicator(element?: string) { const width = ref<number>(0) const content = ref<number>(0) function onScroll() { const { documentElement, body } = document const windowScroll = documentElement.scrollTop - content.value || body.scrollTop const height = documentElement.scrollHeight - (documentElement.clientHeight + content.value) if (windowScroll > 0) width.value = (windowScroll / height) * 100 else width.value = 0 } function init() { if (element !== undefined) { const elementTarget = document.getElementById(element) const TargetTop = elementTarget?.offsetTop || 0 // TODO: Add breakpoints for mobile content.value = TargetTop } window.addEventListener('scroll', onScroll) } function clear() { window.removeEventListener('scroll', onScroll) } return { width, init, clear, } }