optimizely-oui
Version:
Optimizely's Component Library.
81 lines (68 loc) • 2.48 kB
JavaScript
import PropTypes from "prop-types";
import React from "react";
import { DropTarget } from "react-dnd";
import types from "../draggableTypes";
/**
* areArraysEqual
* @param {Array.<Any>} a - First array to compare
* @param {Array.<Any>} b - Second array to compare
* @returns {Boolean} - Whether or not the arrays are equal
*/
function areArraysEqual(a, b) {
if (a.length !== b.length) {
return false;
}
return a.reduce((isEqual, itemInA, i) => isEqual && itemInA === b[i], true);
}
/**
* handleHover
* @description Adjusts the item order when an item is dragged over this target
* @param {Object} props - SortTarget props
* @param {Object} monitor - Interface for accessing react-dnd state
*/
function handleHover(props, monitor) {
const dragItem = monitor.getItem();
const { position: currentPosition } = dragItem;
const { position: nextPosition, onMove, ownerId, ownerType } = props;
if (!areArraysEqual(currentPosition, nextPosition)) {
if (dragItem.type === "item" && ownerType === "item" && dragItem.data.get("id") === ownerId) {
return;
}
if (
dragItem.type === "group" &&
((ownerType === "group" && dragItem.id === ownerId) || nextPosition.length !== 1)
) {
return;
}
onMove(currentPosition, nextPosition).then(({ position }) => {
dragItem.position = position;
});
}
}
class SortTarget extends React.PureComponent {
static propTypes = {
baseTestSection: PropTypes.string.isRequired,
connectDropTarget: PropTypes.func.isRequired,
onMove: PropTypes.func.isRequired,
ownerId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
ownerType: PropTypes.oneOf(["item", "group"]).isRequired,
position: PropTypes.arrayOf(PropTypes.number).isRequired,
};
render() {
const { baseTestSection, connectDropTarget, position } = this.props;
const testSectionId = position.join("-");
const testSection = `${baseTestSection}-target-${testSectionId}`;
return connectDropTarget(<li className="soft-half--top" data-test-section={testSection} />);
}
}
export default DropTarget(
types.item,
{
hover: handleHover,
},
(connect, monitor) => ({
canDrop: monitor.canDrop(),
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver(),
})
)(SortTarget);