ayamflow/virtual-scroll

Example Next.js Typescript Hook

michaeldll opened this issue · 0 comments

Hey, just leaving this Issue here for anyone wanting to write this as a Next.js Typescript hook.

  1. In src/support.js, make sure to check for process.browser or you'll get a document is undefined error. This is due to SSR, I think.
const getSupport = () => {
  if (process.browser) {
    return {
      hasWheelEvent: "onwheel" in document,
      hasMouseWheelEvent: "onmousewheel" in document,
      hasTouch: "ontouchstart" in document,
      hasTouchWin: navigator.msMaxTouchPoints && navigator.msMaxTouchPoints > 1,
      hasPointer: !!window.navigator.msPointerEnabled,
      hasKeyDown: "onkeydown" in document,
      isFirefox: navigator.userAgent.indexOf("Firefox") > -1,
    }
  }
}

export default getSupport
  1. Hook :
import VirtualScroll from "libs/virtual-scroll/src/index"
import { useEffect, MutableRefObject } from "react"

export type VirtualScrollEvent = {
  x: number // total distance scrolled on the x axis
  y: number // total distance scrolled on the y axis
  deltaX: number // distance scrolled since the last event on the x axis
  deltaY: number // distance scrolled since the last event on the y axis
  originalEvent: Event // the native event triggered by the pointer device or keyboard
}
type VirtualScrollCallback = (e: VirtualScrollEvent) => void

const useVirtualScroll = (
  ref: MutableRefObject<HTMLElement>,
  callback: VirtualScrollCallback,
  dependencies: any = [],
) => {
  useEffect(() => {
    if (ref.current) {
      const instance = new VirtualScroll(ref.current)
      instance.on((e: VirtualScrollEvent) => callback(e))

      return () => {
        instance.destroy()
      }
    }
  }, dependencies)

  return typeof window !== "undefined"
}

export default useVirtualScroll
  1. Usage:
import useVirtualScroll, { VirtualScrollEvent } from "hooks/useVirtualScroll"

const HomeView: FC<Props> = ({ home, descriptionContent }) => {
  const testRef= useRef(null)
  const onVirtualScroll = (e: VirtualScrollEvent) => {
    console.log(e)
  }
  useVirtualScroll(testRef, onVirtualScroll, [testRef.current])

  return (
    <div ref={testRef}></div>
  )