taye/interact.js

View on GitHub
packages/@interactjs/pointer-events/interactableTargets.ts

Summary

Maintainability
A
0 mins
Test Coverage
import type { Interactable } from '@interactjs/core/Interactable'
import type { Scope, Plugin } from '@interactjs/core/scope'
import type { Element } from '@interactjs/core/types'
import extend from '@interactjs/utils/extend'

import type { PointerEventOptions } from '@interactjs/pointer-events/base'

declare module '@interactjs/core/Interactable' {
  interface Interactable {
    pointerEvents(options: Partial<PointerEventOptions>): this
    /** @internal */
    __backCompatOption: (optionName: string, newValue: any) => any
  }
}

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

  Interactable.prototype.pointerEvents = function (
    this: Interactable,
    options: Partial<PointerEventOptions>,
  ) {
    extend(this.events.options, options)

    return this
  }

  const __backCompatOption = Interactable.prototype._backCompatOption

  Interactable.prototype._backCompatOption = function (optionName, newValue) {
    const ret = __backCompatOption.call(this, optionName, newValue)

    if (ret === this) {
      this.events.options[optionName] = newValue
    }

    return ret
  }
}

const plugin: Plugin = {
  id: 'pointer-events/interactableTargets',
  install,
  listeners: {
    'pointerEvents:collect-targets': ({ targets, node, type, eventTarget }, scope) => {
      scope.interactables.forEachMatch(node, (interactable: Interactable) => {
        const eventable = interactable.events
        const options = eventable.options

        if (
          eventable.types[type] &&
          eventable.types[type].length &&
          interactable.testIgnoreAllow(options, node, eventTarget)
        ) {
          targets.push({
            node,
            eventable,
            props: { interactable },
          })
        }
      })
    },

    'interactable:new': ({ interactable }) => {
      interactable.events.getRect = function (element: Element) {
        return interactable.getRect(element)
      }
    },

    'interactable:set': ({ interactable, options }, scope) => {
      extend(interactable.events.options, scope.pointerEvents.defaults)
      extend(interactable.events.options, options.pointerEvents || {})
    },
  },
}

export default plugin