Skip to content

⬅️ Back to Table of Contents

📄 onLongPress

📊 Analysis Summary

Metric Count
🔧 Functions 7
📦 Imports 6
📊 Variables & Constants 2
🟢 Vue Composition API 1
📐 Interfaces 2
📑 Type Aliases 2

📚 Table of Contents

🛠️ File Location:

📂 packages/core/onLongPress/index.ts

📦 Imports

Name Source
TimerHandle @vueuse/shared
Position ../types
MaybeElementRef ../unrefElement
computed vue
unrefElement ../unrefElement
useEventListener ../useEventListener

Variables & Constants

Name Type Kind Value Exported
DEFAULT_DELAY 500 const 500
DEFAULT_THRESHOLD 10 const 10

Vue Composition API

Name Type Reactive Variables Composables
computed computed none none

Functions

onLongPress(target: MaybeElementRef, handler: (evt: PointerEvent) => void, options: OnLongPressOptions): OnLongPressReturn

Parameters:

  • target MaybeElementRef
  • handler (evt: PointerEvent) => void
  • options OnLongPressOptions

Returns: OnLongPressReturn

Calls:

  • computed (from vue)
  • unrefElement (from ../unrefElement)
  • clearTimeout
  • delay
  • clear
  • ev.preventDefault
  • ev.stopPropagation
  • Math.sqrt
  • options.onMouseUp
  • setTimeout
  • handler
  • getDelay
  • useEventListener (from ../useEventListener)
  • cleanup.forEach
  • fn
Code
export function onLongPress(
  target: MaybeElementRef,
  handler: (evt: PointerEvent) => void,
  options?: OnLongPressOptions,
): OnLongPressReturn {
  const elementRef = computed(() => unrefElement(target))

  let timeout: TimerHandle
  let posStart: Position | undefined
  let startTimestamp: number | undefined
  let hasLongPressed = false

  function clear() {
    if (timeout) {
      clearTimeout(timeout)
      timeout = undefined
    }
    posStart = undefined
    startTimestamp = undefined
    hasLongPressed = false
  }

  function getDelay(ev: PointerEvent): number {
    const delay = options?.delay
    if (typeof delay === 'function') {
      return delay(ev)
    }
    return delay ?? DEFAULT_DELAY
  }

  function onRelease(ev: PointerEvent) {
    const [_startTimestamp, _posStart, _hasLongPressed] = [startTimestamp, posStart, hasLongPressed]
    clear()

    if (!options?.onMouseUp || !_posStart || !_startTimestamp)
      return

    if (options?.modifiers?.self && ev.target !== elementRef.value)
      return

    if (options?.modifiers?.prevent)
      ev.preventDefault()

    if (options?.modifiers?.stop)
      ev.stopPropagation()

    const dx = ev.x - _posStart.x
    const dy = ev.y - _posStart.y
    const distance = Math.sqrt(dx * dx + dy * dy)
    options.onMouseUp(ev.timeStamp - _startTimestamp, distance, _hasLongPressed, ev)
  }

  function onDown(ev: PointerEvent) {
    if (options?.modifiers?.self && ev.target !== elementRef.value)
      return

    clear()

    if (options?.modifiers?.prevent)
      ev.preventDefault()

    if (options?.modifiers?.stop)
      ev.stopPropagation()

    posStart = {
      x: ev.x,
      y: ev.y,
    }
    startTimestamp = ev.timeStamp
    timeout = setTimeout(
      () => {
        hasLongPressed = true
        handler(ev)
      },
      getDelay(ev),
    )
  }

  function onMove(ev: PointerEvent) {
    if (options?.modifiers?.self && ev.target !== elementRef.value)
      return

    if (!posStart || options?.distanceThreshold === false)
      return

    if (options?.modifiers?.prevent)
      ev.preventDefault()

    if (options?.modifiers?.stop)
      ev.stopPropagation()

    const dx = ev.x - posStart.x
    const dy = ev.y - posStart.y
    const distance = Math.sqrt(dx * dx + dy * dy)
    if (distance >= (options?.distanceThreshold ?? DEFAULT_THRESHOLD))
      clear()
  }

  const listenerOptions: AddEventListenerOptions = {
    capture: options?.modifiers?.capture,
    once: options?.modifiers?.once,
  }

  const cleanup = [
    useEventListener(elementRef, 'pointerdown', onDown, listenerOptions),
    useEventListener(elementRef, 'pointermove', onMove, listenerOptions),
    useEventListener(elementRef, ['pointerup', 'pointerleave', 'pointercancel'], onRelease, listenerOptions),
  ]

  const stop = () => cleanup.forEach(fn => fn())

  return stop
}

Internal helpers

Declared inside another function in this file.

clear(): void

Returns: void

Calls:

  • clearTimeout
Code
function clear() {
    if (timeout) {
      clearTimeout(timeout)
      timeout = undefined
    }
    posStart = undefined
    startTimestamp = undefined
    hasLongPressed = false
  }

getDelay(ev: PointerEvent): number

Parameters:

  • ev PointerEvent

Returns: number

Calls:

  • delay
Code
function getDelay(ev: PointerEvent): number {
    const delay = options?.delay
    if (typeof delay === 'function') {
      return delay(ev)
    }
    return delay ?? DEFAULT_DELAY
  }

onRelease(ev: PointerEvent): void

Parameters:

  • ev PointerEvent

Returns: void

Calls:

  • clear
  • ev.preventDefault
  • ev.stopPropagation
  • Math.sqrt
  • options.onMouseUp
Code
function onRelease(ev: PointerEvent) {
    const [_startTimestamp, _posStart, _hasLongPressed] = [startTimestamp, posStart, hasLongPressed]
    clear()

    if (!options?.onMouseUp || !_posStart || !_startTimestamp)
      return

    if (options?.modifiers?.self && ev.target !== elementRef.value)
      return

    if (options?.modifiers?.prevent)
      ev.preventDefault()

    if (options?.modifiers?.stop)
      ev.stopPropagation()

    const dx = ev.x - _posStart.x
    const dy = ev.y - _posStart.y
    const distance = Math.sqrt(dx * dx + dy * dy)
    options.onMouseUp(ev.timeStamp - _startTimestamp, distance, _hasLongPressed, ev)
  }

onDown(ev: PointerEvent): void

Parameters:

  • ev PointerEvent

Returns: void

Calls:

  • clear
  • ev.preventDefault
  • ev.stopPropagation
  • setTimeout
  • handler
  • getDelay
Code
function onDown(ev: PointerEvent) {
    if (options?.modifiers?.self && ev.target !== elementRef.value)
      return

    clear()

    if (options?.modifiers?.prevent)
      ev.preventDefault()

    if (options?.modifiers?.stop)
      ev.stopPropagation()

    posStart = {
      x: ev.x,
      y: ev.y,
    }
    startTimestamp = ev.timeStamp
    timeout = setTimeout(
      () => {
        hasLongPressed = true
        handler(ev)
      },
      getDelay(ev),
    )
  }

onMove(ev: PointerEvent): void

Parameters:

  • ev PointerEvent

Returns: void

Calls:

  • ev.preventDefault
  • ev.stopPropagation
  • Math.sqrt
  • clear
Code
function onMove(ev: PointerEvent) {
    if (options?.modifiers?.self && ev.target !== elementRef.value)
      return

    if (!posStart || options?.distanceThreshold === false)
      return

    if (options?.modifiers?.prevent)
      ev.preventDefault()

    if (options?.modifiers?.stop)
      ev.stopPropagation()

    const dx = ev.x - posStart.x
    const dy = ev.y - posStart.y
    const distance = Math.sqrt(dx * dx + dy * dy)
    if (distance >= (options?.distanceThreshold ?? DEFAULT_THRESHOLD))
      clear()
  }

stop(): void

Returns: void

Calls:

  • cleanup.forEach
Code
() => cleanup.forEach(fn => fn())

Interfaces

OnLongPressOptions

Interface Code
export interface OnLongPressOptions {
  /**
   * Time in ms till `longpress` gets called
   *
   * @default 500
   */
  delay?: number | ((ev: PointerEvent) => number)

  modifiers?: OnLongPressModifiers

  /**
   * Allowance of moving distance in pixels,
   * The action will get canceled When moving too far from the pointerdown position.
   * @default 10
   */
  distanceThreshold?: number | false

  /**
   * Function called when the ref element is released.
   * @param duration how long the element was pressed in ms
   * @param distance distance from the pointerdown position
   * @param isLongPress whether the action was a long press or not
   * @param pointerEvent the native {@link PointerEvent} triggered by the browser
   */
  onMouseUp?: (duration: number, distance: number, isLongPress: boolean, pointerEvent: PointerEvent) => void
}

Properties

Name Type Optional Description
delay number \| ((ev: PointerEvent) => number) not shown
modifiers OnLongPressModifiers not shown
distanceThreshold number \| false not shown
onMouseUp (duration: number, distance: number, isLongPress: boolean, pointerEvent: Poin... not shown

OnLongPressModifiers

Interface Code
export interface OnLongPressModifiers {
  stop?: boolean
  once?: boolean
  prevent?: boolean
  capture?: boolean
  self?: boolean
}

Properties

Name Type Optional Description
stop boolean not shown
once boolean not shown
prevent boolean not shown
capture boolean not shown
self boolean not shown

Type Aliases

OnLongPressReturn

type OnLongPressReturn = () => void;

UseOnLongPressReturn

/* @deprecated use {@link OnLongPressReturn} instead /

type UseOnLongPressReturn = OnLongPressReturn;

Generated by Syntax Scribe