taye/interact.js

View on GitHub
packages/@interactjs/auto-start/hold.ts

Summary

Maintainability
A
0 mins
Test Coverage
import type Interaction from '@interactjs/core/Interaction'
import type { Scope, Plugin } from '@interactjs/core/scope'

/* eslint-disable import/no-duplicates -- for typescript module augmentations */
import './base'
import basePlugin from './base'
/* eslint-enable */

declare module '@interactjs/core/options' {
  interface PerActionDefaults {
    hold?: number
    delay?: number
  }
}

declare module '@interactjs/core/Interaction' {
  interface Interaction {
    autoStartHoldTimer?: any
  }
}

function install(scope: Scope) {
  const { defaults } = scope

  scope.usePlugin(basePlugin)

  defaults.perAction.hold = 0
  defaults.perAction.delay = 0
}

function getHoldDuration(interaction: Interaction) {
  const actionName = interaction.prepared && interaction.prepared.name

  if (!actionName) {
    return null
  }

  const options = interaction.interactable.options

  return options[actionName].hold || options[actionName].delay
}

const hold: Plugin = {
  id: 'auto-start/hold',
  install,
  listeners: {
    'interactions:new': ({ interaction }) => {
      interaction.autoStartHoldTimer = null
    },

    'autoStart:prepared': ({ interaction }) => {
      const hold = getHoldDuration(interaction)

      if (hold > 0) {
        interaction.autoStartHoldTimer = setTimeout(() => {
          interaction.start(interaction.prepared, interaction.interactable, interaction.element)
        }, hold)
      }
    },

    'interactions:move': ({ interaction, duplicate }) => {
      if (interaction.autoStartHoldTimer && interaction.pointerWasMoved && !duplicate) {
        clearTimeout(interaction.autoStartHoldTimer)
        interaction.autoStartHoldTimer = null
      }
    },

    // prevent regular down->move autoStart
    'autoStart:before-start': ({ interaction }) => {
      const holdDuration = getHoldDuration(interaction)

      if (holdDuration > 0) {
        interaction.prepared.name = null
      }
    },
  },
  getHoldDuration,
}
export default hold