packages/react-moveable/src/ables/Clickable.ts

  1. import {
  2. MoveableManagerInterface, MoveableGroupInterface,
  3. ClickableProps, OnClick, OnClickGroup,
  4. } from "../types";
  5. import { triggerEvent, fillParams } from "../utils";
  6. import { findIndex } from "@daybrush/utils";
  7. import { makeAble } from "./AbleManager";
  8. export default makeAble("clickable", {
  9. props: [
  10. "clickable",
  11. ] as const,
  12. events: [
  13. "click",
  14. "clickGroup",
  15. ] as const,
  16. always: true,
  17. dragRelation: "weak",
  18. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  19. dragStart() {
  20. return;
  21. },
  22. dragControlStart() {
  23. return;
  24. },
  25. dragGroupStart(moveable: MoveableManagerInterface<ClickableProps>, e: any) {
  26. e.datas.inputTarget = e.inputEvent && e.inputEvent.target;
  27. },
  28. dragEnd(moveable: MoveableManagerInterface<ClickableProps>, e: any) {
  29. const target = moveable.props.target!;
  30. const inputEvent = e.inputEvent;
  31. const inputTarget = e.inputTarget;
  32. const isMoveableElement = moveable.isMoveableElement(inputTarget);
  33. const containsElement = !isMoveableElement && moveable.controlBox.contains(inputTarget);
  34. if (
  35. !inputEvent || !inputTarget || e.isDrag
  36. || moveable.isMoveableElement(inputTarget)
  37. || containsElement
  38. // External event duplicate target or dragAreaElement
  39. ) {
  40. return;
  41. }
  42. const containsTarget = target.contains(inputTarget);
  43. triggerEvent(moveable, "onClick", fillParams<OnClick>(moveable, e, {
  44. isDouble: e.isDouble,
  45. inputTarget,
  46. isTarget: target === inputTarget,
  47. moveableTarget: moveable.props.target!,
  48. containsTarget,
  49. }));
  50. },
  51. dragGroupEnd(moveable: MoveableGroupInterface<ClickableProps>, e: any) {
  52. const inputEvent = e.inputEvent;
  53. const inputTarget = e.inputTarget;
  54. if (
  55. !inputEvent || !inputTarget || e.isDrag
  56. || moveable.isMoveableElement(inputTarget)
  57. // External event duplicate target or dragAreaElement
  58. || e.datas.inputTarget === inputTarget
  59. ) {
  60. return;
  61. }
  62. const targets = moveable.props.targets!;
  63. let targetIndex = targets.indexOf(inputTarget);
  64. const isTarget = targetIndex > -1;
  65. let containsTarget = false;
  66. if (targetIndex === -1) {
  67. targetIndex = findIndex(targets, parentTarget => parentTarget.contains(inputTarget));
  68. containsTarget = targetIndex > -1;
  69. }
  70. triggerEvent(moveable, "onClickGroup", fillParams<OnClickGroup>(moveable, e, {
  71. isDouble: e.isDouble,
  72. targets,
  73. inputTarget,
  74. targetIndex,
  75. isTarget,
  76. containsTarget,
  77. moveableTarget: targets[targetIndex],
  78. }));
  79. },
  80. dragControlEnd(moveable: MoveableManagerInterface<ClickableProps>, e: any) {
  81. this.dragEnd(moveable, e);
  82. },
  83. dragGroupControlEnd(moveable: MoveableManagerInterface<ClickableProps>, e: any) {
  84. this.dragEnd(moveable, e);
  85. },
  86. });
  87. /**
  88. * When you click on the element, the `click` event is called.
  89. * @memberof Moveable
  90. * @event click
  91. * @param {Moveable.OnClick} - Parameters for the `click` event
  92. * @example
  93. * import Moveable from "moveable";
  94. *
  95. * const moveable = new Moveable(document.body, {
  96. * target: document.querySelector(".target"),
  97. * });
  98. * moveable.on("click", ({ hasTarget, containsTarget, targetIndex }) => {
  99. * // If you click on an element other than the target and not included in the target, index is -1.
  100. * console.log("onClickGroup", target, hasTarget, containsTarget, targetIndex);
  101. * });
  102. */
  103. /**
  104. * When you click on the element inside the group, the `clickGroup` event is called.
  105. * @memberof Moveable
  106. * @event clickGroup
  107. * @param {Moveable.OnClickGroup} - Parameters for the `clickGroup` event
  108. * @example
  109. * import Moveable from "moveable";
  110. *
  111. * const moveable = new Moveable(document.body, {
  112. * target: [].slice.call(document.querySelectorAll(".target")),
  113. * });
  114. * moveable.on("clickGroup", ({ inputTarget, isTarget, containsTarget, targetIndex }) => {
  115. * // If you click on an element other than the target and not included in the target, index is -1.
  116. * console.log("onClickGroup", inputTarget, isTarget, containsTarget, targetIndex);
  117. * });
  118. */