{"version":3,"file":"lenis-snap.mjs","names":[],"sources":["../packages/snap/src/debounce.ts","../packages/snap/src/element.ts","../packages/snap/src/uid.ts","../packages/snap/src/snap.ts"],"sourcesContent":["export function debounce<CB extends (...args: unknown[]) => void>(\n  callback: CB,\n  delay: number\n) {\n  let timer: ReturnType<typeof setTimeout> | undefined\n  return function <T>(this: T, ...args: Parameters<typeof callback>): void {\n    clearTimeout(timer)\n    timer = setTimeout(() => {\n      timer = undefined\n      callback.apply(this, args)\n    }, delay)\n  }\n}\n","import { debounce } from './debounce'\n\nfunction removeParentSticky(element: HTMLElement) {\n  const position = getComputedStyle(element).position\n\n  const isSticky = position === 'sticky'\n\n  if (isSticky) {\n    element.style.setProperty('position', 'static')\n    element.dataset.sticky = 'true'\n  }\n\n  if (element.offsetParent) {\n    removeParentSticky(element.offsetParent as HTMLElement)\n  }\n}\n\nfunction addParentSticky(element: HTMLElement) {\n  if (element?.dataset?.sticky === 'true') {\n    element.style.removeProperty('position')\n    delete element.dataset.sticky\n  }\n\n  if (element.offsetParent) {\n    addParentSticky(element.offsetParent as HTMLElement)\n  }\n}\n\nfunction offsetTop(element: HTMLElement, accumulator = 0) {\n  const top = accumulator + element.offsetTop\n  if (element.offsetParent) {\n    return offsetTop(element.offsetParent as HTMLElement, top)\n  }\n  return top\n}\n\nfunction offsetLeft(element: HTMLElement, accumulator = 0) {\n  const left = accumulator + element.offsetLeft\n  if (element.offsetParent) {\n    return offsetLeft(element.offsetParent as HTMLElement, left)\n  }\n  return left\n}\n\nfunction scrollTop(element: HTMLElement, accumulator = 0) {\n  const top = accumulator + element.scrollTop\n  if (element.offsetParent) {\n    return scrollTop(element.offsetParent as HTMLElement, top)\n  }\n  return top + window.scrollY\n}\n\nfunction scrollLeft(element: HTMLElement, accumulator = 0) {\n  const left = accumulator + element.scrollLeft\n  if (element.offsetParent) {\n    return scrollLeft(element.offsetParent as HTMLElement, left)\n  }\n  return left + window.scrollX\n}\n\nexport type SnapElementOptions = {\n  align?: string | string[]\n  ignoreSticky?: boolean\n  ignoreTransform?: boolean\n}\n\ntype Rect = {\n  top: number\n  left: number\n  width: number\n  height: number\n  x: number\n  y: number\n  bottom: number\n  right: number\n  element: HTMLElement\n}\n\nexport class SnapElement {\n  element: HTMLElement\n  options: SnapElementOptions\n  align: string[]\n  // @ts-expect-error\n  rect: Rect = {}\n  wrapperResizeObserver: ResizeObserver\n  resizeObserver: ResizeObserver\n  debouncedWrapperResize: () => void\n\n  constructor(\n    element: HTMLElement,\n    {\n      align = ['start'],\n      ignoreSticky = true,\n      ignoreTransform = false,\n    }: SnapElementOptions = {}\n  ) {\n    this.element = element\n\n    this.options = { align, ignoreSticky, ignoreTransform }\n\n    this.align = [align].flat()\n\n    this.debouncedWrapperResize = debounce(this.onWrapperResize, 500)\n\n    this.wrapperResizeObserver = new ResizeObserver(this.debouncedWrapperResize)\n    this.wrapperResizeObserver.observe(document.body)\n    this.onWrapperResize()\n\n    this.resizeObserver = new ResizeObserver(this.onResize)\n    this.resizeObserver.observe(this.element)\n    this.setRect({\n      width: this.element.offsetWidth,\n      height: this.element.offsetHeight,\n    })\n  }\n\n  destroy() {\n    this.wrapperResizeObserver.disconnect()\n    this.resizeObserver.disconnect()\n  }\n\n  setRect({\n    top,\n    left,\n    width,\n    height,\n    element,\n  }: {\n    top?: number\n    left?: number\n    width?: number\n    height?: number\n    element?: HTMLElement\n  } = {}) {\n    top = top ?? this.rect.top\n    left = left ?? this.rect.left\n    width = width ?? this.rect.width\n    height = height ?? this.rect.height\n    element = element ?? this.rect.element\n\n    if (\n      top === this.rect.top &&\n      left === this.rect.left &&\n      width === this.rect.width &&\n      height === this.rect.height &&\n      element === this.rect.element\n    )\n      return\n\n    this.rect.top = top\n    this.rect.y = top\n    this.rect.width = width\n    this.rect.height = height\n    this.rect.left = left\n    this.rect.x = left\n    this.rect.bottom = top + height\n    this.rect.right = left + width\n  }\n\n  onWrapperResize = () => {\n    let top: number | undefined\n    let left: number | undefined\n\n    if (this.options.ignoreSticky) removeParentSticky(this.element)\n    if (this.options.ignoreTransform) {\n      top = offsetTop(this.element)\n      left = offsetLeft(this.element)\n    } else {\n      const rect = this.element.getBoundingClientRect()\n      top = rect.top + scrollTop(this.element)\n      left = rect.left + scrollLeft(this.element)\n    }\n    if (this.options.ignoreSticky) addParentSticky(this.element)\n\n    this.setRect({ top, left })\n  }\n\n  onResize = ([entry]: ResizeObserverEntry[]) => {\n    if (!entry?.borderBoxSize[0]) return\n    const width = entry.borderBoxSize[0].inlineSize\n    const height = entry.borderBoxSize[0].blockSize\n\n    this.setRect({ width, height })\n  }\n}\n","let index = 0\r\n\r\nexport type UID = number\r\n\r\nexport function uid(): UID {\r\n  return index++\r\n}\r\n","import type Lenis from 'lenis'\nimport type { VirtualScrollData } from 'lenis'\nimport { debounce } from './debounce'\nimport type { SnapElementOptions } from './element'\nimport { SnapElement } from './element'\nimport type { SnapItem, SnapOptions } from './types'\nimport type { UID } from './uid'\nimport { uid } from './uid'\n\n// TODO:\n// - fix wheel scrolling after limits (see console scroll to)\n// - arrow, spacebar\n\ntype RequiredPick<T, F extends keyof T> = Omit<T, F> & Required<Pick<T, F>>\n\n/**\n * Snap class to handle the snap functionality\n *\n * @example\n * const snap = new Snap(lenis, {\n *   type: 'mandatory', // 'mandatory', 'proximity' or 'lock'\n *   onSnapStart: (snap) => {\n *     console.log('onSnapStart', snap)\n *   },\n *   onSnapComplete: (snap) => {\n *     console.log('onSnapComplete', snap)\n *   },\n * })\n *\n * snap.add(500) // snap at 500px\n *\n * const removeSnap = snap.add(500)\n *\n * if (someCondition) {\n *   removeSnap()\n * }\n */\nexport class Snap {\n  options: RequiredPick<SnapOptions, 'type' | 'debounce'>\n  elements = new Map<UID, SnapElement>()\n  snaps = new Map<UID, SnapItem>()\n  viewport: { width: number; height: number } = {\n    width: window.innerWidth,\n    height: window.innerHeight,\n  }\n  isStopped = false\n  onSnapDebounced: (e: VirtualScrollData) => void\n  currentSnapIndex?: number\n\n  constructor(\n    private lenis: Lenis,\n    {\n      type = 'proximity',\n      lerp,\n      easing,\n      duration,\n      distanceThreshold = '50%', // useless when type is \"mandatory\"\n      debounce: debounceDelay = 500,\n      onSnapStart,\n      onSnapComplete,\n    }: SnapOptions = {}\n  ) {\n    if (!window.lenis) {\n      window.lenis = {}\n    }\n\n    window.lenis.snap = true\n\n    this.options = {\n      type,\n      lerp,\n      easing,\n      duration,\n      distanceThreshold,\n      debounce: debounceDelay,\n      onSnapStart,\n      onSnapComplete,\n    }\n\n    this.onWindowResize()\n    window.addEventListener('resize', this.onWindowResize)\n\n    this.onSnapDebounced = debounce(\n      this.onSnap as (...args: unknown[]) => void,\n      this.options.debounce\n    )\n\n    this.lenis.on('virtual-scroll', this.onSnapDebounced)\n  }\n\n  /**\n   * Destroy the snap instance\n   */\n  destroy() {\n    this.lenis.off('virtual-scroll', this.onSnapDebounced)\n    window.removeEventListener('resize', this.onWindowResize)\n    this.elements.forEach((element) => {\n      element.destroy()\n    })\n  }\n\n  /**\n   * Start the snap after it has been stopped\n   */\n  start() {\n    this.isStopped = false\n  }\n\n  /**\n   * Stop the snap\n   */\n  stop() {\n    this.isStopped = true\n  }\n\n  /**\n   * Add a snap to the snap instance\n   *\n   * @param value The value to snap to\n   * @param userData User data that will be forwarded through the snap event\n   * @returns Unsubscribe function\n   */\n  add(value: number): () => void {\n    const id = uid()\n\n    this.snaps.set(id, { value })\n\n    return () => this.snaps.delete(id)\n  }\n\n  /**\n   * Add an element to the snap instance\n   *\n   * @param element The element to add\n   * @param options The options for the element\n   * @returns Unsubscribe function\n   */\n  addElement(\n    element: HTMLElement,\n    options: SnapElementOptions = {}\n  ): () => void {\n    const id = uid()\n\n    this.elements.set(id, new SnapElement(element, options))\n\n    return () => this.elements.delete(id)\n  }\n\n  addElements(\n    elements: HTMLElement[],\n    options: SnapElementOptions = {}\n  ): () => void {\n    const map = [...elements].map((element) =>\n      this.addElement(element, options)\n    )\n    return () => {\n      map.forEach((remove) => {\n        remove()\n      })\n    }\n  }\n\n  private onWindowResize = () => {\n    this.viewport.width = window.innerWidth\n    this.viewport.height = window.innerHeight\n  }\n\n  private computeSnaps = () => {\n    const { isHorizontal } = this.lenis\n\n    let snaps = [...this.snaps.values()] as SnapItem[]\n\n    this.elements.forEach(({ rect, align }) => {\n      let value: number | undefined\n\n      align.forEach((align) => {\n        if (align === 'start') {\n          value = rect.top\n        } else if (align === 'center') {\n          value = isHorizontal\n            ? rect.left + rect.width / 2 - this.viewport.width / 2\n            : rect.top + rect.height / 2 - this.viewport.height / 2\n        } else if (align === 'end') {\n          value = isHorizontal\n            ? rect.left + rect.width - this.viewport.width\n            : rect.top + rect.height - this.viewport.height\n        }\n\n        if (typeof value === 'number') {\n          snaps.push({ value: Math.ceil(value) })\n        }\n      })\n    })\n\n    snaps = snaps.sort((a, b) => Math.abs(a.value) - Math.abs(b.value))\n\n    return snaps\n  }\n\n  previous() {\n    this.goTo((this.currentSnapIndex ?? 0) - 1)\n  }\n\n  next() {\n    this.goTo((this.currentSnapIndex ?? 0) + 1)\n  }\n\n  goTo(index: number) {\n    const snaps = this.computeSnaps()\n\n    if (snaps.length === 0) return\n\n    this.currentSnapIndex = Math.max(0, Math.min(index, snaps.length - 1))\n\n    const currentSnap = snaps[this.currentSnapIndex]\n    if (currentSnap === undefined) return\n\n    this.lenis.scrollTo(currentSnap.value, {\n      duration: this.options.duration,\n      easing: this.options.easing,\n      lerp: this.options.lerp,\n      lock: this.options.type === 'lock',\n      userData: { initiator: 'snap' },\n      onStart: () => {\n        this.options.onSnapStart?.({\n          index: this.currentSnapIndex,\n          ...currentSnap,\n        })\n      },\n      onComplete: () => {\n        this.options.onSnapComplete?.({\n          index: this.currentSnapIndex,\n          ...currentSnap,\n        })\n      },\n    })\n  }\n\n  get distanceThreshold() {\n    let distanceThreshold = Number.POSITIVE_INFINITY\n    if (this.options.type === 'mandatory') return Number.POSITIVE_INFINITY\n\n    const { isHorizontal } = this.lenis\n\n    const axis = isHorizontal ? 'width' : 'height'\n\n    if (\n      typeof this.options.distanceThreshold === 'string' &&\n      this.options.distanceThreshold.endsWith('%')\n    ) {\n      distanceThreshold =\n        (Number(this.options.distanceThreshold.replace('%', '')) / 100) *\n        this.viewport[axis]\n    } else if (typeof this.options.distanceThreshold === 'number') {\n      distanceThreshold = this.options.distanceThreshold\n    } else {\n      distanceThreshold = this.viewport[axis]\n    }\n\n    return distanceThreshold\n  }\n\n  private onSnap = (e: VirtualScrollData) => {\n    if (this.isStopped) return\n\n    if (e.event.type === 'touchmove') return\n\n    if (\n      this.options.type === 'lock' &&\n      this.lenis.userData?.initiator === 'snap'\n    )\n      return\n\n    let { scroll, isHorizontal } = this.lenis\n    const delta = isHorizontal ? e.deltaX : e.deltaY\n    scroll = Math.ceil(this.lenis.scroll + delta)\n\n    const snaps = this.computeSnaps()\n\n    if (snaps.length === 0) return\n\n    let snapIndex: number | undefined\n\n    const prevSnapIndex = snaps.findLastIndex(({ value }) => value < scroll)\n    const nextSnapIndex = snaps.findIndex(({ value }) => value > scroll)\n\n    if (this.options.type === 'lock') {\n      if (delta > 0) {\n        snapIndex = nextSnapIndex\n      } else if (delta < 0) {\n        snapIndex = prevSnapIndex\n      }\n    } else {\n      const prevSnap = snaps[prevSnapIndex]!\n      const distanceToPrevSnap = prevSnap\n        ? Math.abs(scroll - prevSnap.value)\n        : Number.POSITIVE_INFINITY\n\n      const nextSnap = snaps[nextSnapIndex]!\n      const distanceToNextSnap = nextSnap\n        ? Math.abs(scroll - nextSnap.value)\n        : Number.POSITIVE_INFINITY\n      snapIndex =\n        distanceToPrevSnap < distanceToNextSnap ? prevSnapIndex : nextSnapIndex\n    }\n\n    if (snapIndex === undefined) return\n    if (snapIndex === -1) return\n\n    snapIndex = Math.max(0, Math.min(snapIndex, snaps.length - 1))\n\n    const snap = snaps[snapIndex]!\n\n    const distance = Math.abs(scroll - snap.value)\n\n    if (distance <= this.distanceThreshold) {\n      this.goTo(snapIndex)\n    }\n  }\n\n  resize() {\n    this.elements.forEach((element) => {\n      element.onWrapperResize()\n    })\n  }\n}\n"],"mappings":"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"}