sorenabedi/artist-svelte

View on GitHub
src/lib/utilities/hook/scroll/index.ts

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
import type { Readable } from 'svelte/store';
import type { scrollHook } from '../../../types/hook';
import { browser } from '$app/env';
import { readable } from 'svelte/store';

export const currentBodyPosition = (): { scrollX: number; scrollY: number } =>
    browser && { scrollY: window.scrollY, scrollX: window.scrollX };
let scrollThreshold = 50;
export const store = readable<scrollHook>(currentBodyPosition(), (set) => {
    let position = currentBodyPosition().scrollY;
    /* istanbul ignore next */
    const setScrollHeight = () => {
        const currentScrollPosition = currentBodyPosition();
        const direction = position > currentScrollPosition.scrollY ? 'up' : 'down';
        if (Math.abs(position - currentScrollPosition.scrollY) > scrollThreshold)
            position = currentScrollPosition.scrollY;
        set({ ...currentScrollPosition, direction });
    };
    browser && window.addEventListener('scroll', setScrollHeight);

    return () => {
        if (browser) window.removeEventListener('scroll', setScrollHeight);
    };
});

export default (
    threshold = 50
): {
    scrollPosition: Readable<scrollHook>;
    scrollToTop: () => void;
    setScroll: (ScrollToOptions: ScrollToOptions) => void;
} => {
    scrollThreshold = threshold;
    const setScroll = (ScrollToOptions: ScrollToOptions) => {
        if (!browser) /* istanbul ignore next */ return;
        window.scrollTo({ behavior: 'smooth', ...ScrollToOptions });
    };
    const scrollToTop = () => {
        if (!browser) /* istanbul ignore next */ return;
        window.scrollTo({ behavior: 'smooth', top: 0 });
    };
    return {
        scrollPosition: store,
        scrollToTop,
        setScroll
    };
};