"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.DragNDropWrapper = DragNDropWrapper;
var _react = _interopRequireWildcard(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
/** A Drag-And-Drop wrapper creates a drag-and-drop area around children and passes dataTransfer payload to provided dropAction */
function DragNDropWrapper({
  onDropAction,
  onDragOverAction,
  children,
  isDisabled = false,
  isDropAllowed = () => true,
  containerClassName = 'drag-and-drop-wrapper',
  onDragClassName = 'is-dragging',
  onDropNotAllowedClassName = 'isDropNotAllowed',
  testId = 'drag-n-drop-zone'
}) {
  const [isDragging, setIsDraggingState] = (0, _react.useState)(false);
  const [isDropNotAllowed, setIsDropNotAllowed] = (0, _react.useState)(false);
  const enterLeaveCounter = (0, _react.useRef)(0);
  const updateCounter = value => {
    enterLeaveCounter.current = enterLeaveCounter.current + value;
  };
  const onDragEnterAction = () => onDragOverAction && onDragOverAction(true);
  const onDragLeaveAction = () => onDragOverAction && onDragOverAction(false);
  const endDrag = () => {
    onDragLeaveAction();
    setIsDraggingState(false);
    setIsDropNotAllowed(false);
  };
  const onDragOver = e => {
    e.preventDefault();
    const {
      dataTransfer
    } = e;
    if (!isDropAllowed(dataTransfer)) {
      e.dataTransfer.dropEffect = 'none';
      if (!isDropNotAllowed) {
        setIsDropNotAllowed(true);
      }
    }
  };
  const onDragEnter = e => {
    e.preventDefault();
    updateCounter(1);
    if (!isDragging) {
      onDragEnterAction();
      setIsDraggingState(true);
    }
  };
  const onDragLeave = e => {
    e.preventDefault();
    updateCounter(-1);
    if (!enterLeaveCounter.current && isDragging) {
      endDrag();
    }
  };
  const onDrop = e => {
    e.preventDefault();
    enterLeaveCounter.current = 0;
    endDrag();
    const {
      dataTransfer
    } = e;
    if (!isDropAllowed(dataTransfer)) {
      return;
    }
    onDropAction(dataTransfer);
  };
  const protectedDragNDrop = e => {
    e.preventDefault();
  };
  (0, _react.useEffect)(() => {
    window.addEventListener('drop', protectedDragNDrop);
    window.addEventListener('dragover', protectedDragNDrop);
    return () => {
      window.removeEventListener('drop', protectedDragNDrop);
      window.removeEventListener('dragover', protectedDragNDrop);
    };
  });
  if (isDisabled) {
    return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
      children: children
    });
  }
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
    className: (0, _classnames.default)({
      [containerClassName]: containerClassName,
      [onDragClassName]: isDragging,
      [onDropNotAllowedClassName]: isDropNotAllowed
    }),
    onDragOver: onDragOver,
    onDrop: onDrop,
    onDragLeave: onDragLeave,
    onDragEnter: onDragEnter,
    "test-id": testId,
    "aria-dropeffect": "move",
    children: children
  });
}