@onesy/ui-react
Version:
UI for React
163 lines (160 loc) • 11.2 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireDefault(require("react"));
var _utils = require("@onesy/utils");
var _styleReact = require("@onesy/style-react");
var _jsxRuntime = require("react/jsx-runtime");
const _excluded = ["ref", "onChange", "items", "image", "delay", "precise", "draggedIsElement", "isEqual", "getDraggingElement", "onDraggedElement", "onDragStart", "className", "children"];
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
const DragAndDropList = props_ => {
var _theme$ui, _theme$ui2;
const theme = (0, _styleReact.useOnesyTheme)();
const props = _objectSpread(_objectSpread(_objectSpread({}, theme === null || theme === void 0 || (_theme$ui = theme.ui) === null || _theme$ui === void 0 || (_theme$ui = _theme$ui.elements) === null || _theme$ui === void 0 || (_theme$ui = _theme$ui.all) === null || _theme$ui === void 0 || (_theme$ui = _theme$ui.props) === null || _theme$ui === void 0 ? void 0 : _theme$ui.default), theme === null || theme === void 0 || (_theme$ui2 = theme.ui) === null || _theme$ui2 === void 0 || (_theme$ui2 = _theme$ui2.elements) === null || _theme$ui2 === void 0 || (_theme$ui2 = _theme$ui2.onesyDragAndDropList) === null || _theme$ui2 === void 0 || (_theme$ui2 = _theme$ui2.props) === null || _theme$ui2 === void 0 ? void 0 : _theme$ui2.default), props_);
const {
ref,
onChange: onChange_,
items,
image,
delay = 0,
precise = true,
draggedIsElement = true,
isEqual,
getDraggingElement,
onDraggedElement,
onDragStart: onDragStart_,
className,
children
// @ts-ignore
} = props,
other = (0, _objectWithoutProperties2.default)(props, _excluded);
const refs = {
root: _react.default.useRef(null),
dragging: _react.default.useRef(null),
rectDragged: _react.default.useRef(null),
isDragging: _react.default.useRef(null),
previous: _react.default.useRef(null)
};
const onChange = _react.default.useMemo(() => {
return (0, _utils.debounce)((indexPrevious, indexNew) => onChange_(indexPrevious, indexNew), delay);
}, [onChange_, delay]);
_react.default.useEffect(() => {
var _refs$root$current;
const onMouseUp = event => {
// in use case
// where onDragEnd is never emited
// due to original element having it
// has been removed from the dom
// prior to onDragEnd event is to be emited
// alternative way to provide a callback
// to dragging has ended
if (refs.isDragging.current) {
if ((0, _utils.is)('function', onDraggedElement)) onDraggedElement(null);
refs.isDragging.current = false;
}
};
const rootDocument = (0, _utils.isEnvironment)('browser') ? ((_refs$root$current = refs.root.current) === null || _refs$root$current === void 0 ? void 0 : _refs$root$current.ownerDocument) || window.document : undefined;
rootDocument.body.addEventListener('mouseup', onMouseUp);
rootDocument.body.addEventListener('touchend', onMouseUp);
return () => {
rootDocument.body.removeEventListener('mouseup', onMouseUp);
rootDocument.body.removeEventListener('touchend', onMouseUp);
};
}, []);
const img = _react.default.useMemo(() => {
var _refs$root$current2;
const rootDocument_0 = (0, _utils.isEnvironment)('browser') ? ((_refs$root$current2 = refs.root.current) === null || _refs$root$current2 === void 0 ? void 0 : _refs$root$current2.ownerDocument) || window.document : undefined;
const element = rootDocument_0.createElement('img');
element.src = (0, _utils.is)('string', image) ? image : `data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAAWAC8DAREAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD+/igAoAKACgAoAKACgD8gtF+E3xs1/wD4UzrXiHxZ+1dZaj43/au+P/gj4r2Vt8RPjBo1np/7PsfiP42654IE+mxalFB4H8OzzeGvAlr4Z+IWjReH9dbQvE1noei+K10q+8N29l/LWD4Z4vx3+qeLx+Z+JdGvnHiXxvk/E1KGe8VYSlQ4Hjj+L8Zk/Ph44iMMnwM55fk1PL89wkcDjXgswpYPCZksNWwFOj7cq2Hj7eMYYNqng8NUot0qEm8Ty4eNSzt+8klOo50pc0eaDlKHMptyG2+Kml/8Id4f+NFz+1o3wN8JeLf2t/DOnan8MZPjbffFG81Xw18aYdI/Zw1Hx1rHw5gm+K3ijwpdfC9dUuvBvie/uNV8M+JdZh0bVvGt5f2cun3V3Tp8SYb+ysDxbU8TnwdlmaeJ+X0MRw7Li+txHVxOX8XRwvANfOcVkMJcS5jltThxYirlOY16mJy/MMXHCYrN61alKhUql6L55UFgvrE4YKbVX6uqKU6HNilTjVfsYTVaynBJThHmjTSd0ptK039seDSvhH8P/FN18ZH1L9pXwD8JdH8f+OdNu9WnufgFrHwx8RSXnxN1TVNb0O9m0r4ceJ/ir8GbnTdIju9Ney0+f4saPfXtl9o1TUbt5LwtDxVhhuF8jzKpxY8R4gZLwxhc7zihUxM6nBOK4ex0qvEOIxOMwdaeGyHMeJeFKmHwsauHlRoT4lwtatS58RXq8yk8C3WqQVC2FqVpU6bStiY1Y2pJRkr1YUa6crO79jJJ6JE/wmtf2kZv2kLEeLNa+Ltj4lX43/E678cx3+j/ABs1D4UXvwTsz44i8Eabpdxq+saZ+znYeGbvSJ/CR8Lal4I0i7+Ky+K4x/wkti8Uviq/t74Yp8fS4+o/2ni+KKOYLi/iKrnMa+F4vr8M1eEaTziOT4fDTxWKw/AdDL6mFnln9m4jJ8NV4lWZR/4UKLjLMq1MrPC/VXyRoOH1ekqdpYdVliH7P2jajF4pzUufnVSSo8nwP4E/1sr+nTxQoAKACgAoAKACgAD/2Q==`;
return element;
}, []);
const onDragStart = item => async event_0 => {
var _dragging$dataset;
event_0.dataTransfer.setData('text', (item === null || item === void 0 ? void 0 : item.value) !== undefined ? item.value : item);
if (image) event_0.dataTransfer.setDragImage(img, 0, 0);
refs.isDragging.current = true;
const dragging = (0, _utils.is)('function', getDraggingElement) ? getDraggingElement(event_0) : event_0.target;
if (onDragStart_) onDragStart_(item, event_0);
refs.dragging.current = draggedIsElement ? dragging : dragging === null || dragging === void 0 || (_dragging$dataset = dragging.dataset) === null || _dragging$dataset === void 0 ? void 0 : _dragging$dataset.onesyDragAndDropListValue;
refs.rectDragged.current = {
height: dragging.clientHeight,
x: event_0.clientX - dragging.offsetLeft,
y: event_0.clientY - dragging.offsetTop
};
setTimeout(() => {
if ((0, _utils.is)('function', onDraggedElement)) onDraggedElement === null || onDraggedElement === void 0 || onDraggedElement(item);
});
};
const onDragEnd = () => event_1 => {
// clean up
refs.isDragging.current = false;
refs.rectDragged.current = null;
refs.dragging.current = null;
if ((0, _utils.is)('function', onDraggedElement)) onDraggedElement(null);
};
const onDragOver = () => event_2 => {
var _refs$root$current3;
event_2.preventDefault();
const rootDocument_1 = (0, _utils.isEnvironment)('browser') ? ((_refs$root$current3 = refs.root.current) === null || _refs$root$current3 === void 0 ? void 0 : _refs$root$current3.ownerDocument) || window.document : undefined;
const over = event_2.currentTarget;
const dragging_0 = draggedIsElement ? refs.dragging.current : rootDocument_1.body.querySelector(`[data-onesy-drag-and-drop-list-value="${refs.dragging.current}"]`);
if (!(over && dragging_0)) return;
if (precise) {
if (over !== dragging_0) {
const rectOver = {
height: over.clientHeight,
x: over.offsetLeft,
y: over.offsetTop
};
const mousePosition = {
x: event_2.clientX - rectOver.x,
y: event_2.clientY - rectOver.y
};
const partBottom = Math.abs(refs.rectDragged.current.height - refs.rectDragged.current.y);
const partTop = refs.rectDragged.current.y;
const half = rectOver.height / 2;
const positionTopBottom = partBottom + mousePosition.y >= half ? 'bottom' : 'top';
const positionBottomTop = mousePosition.y - partTop <= half ? 'top' : 'bottom';
const overIndex = items.findIndex(item_0 => isEqual ? isEqual(item_0, over.dataset.onesyDragAndDropListValue) : item_0 === over.dataset.onesyDragAndDropListValue);
const draggedIndex = items.findIndex(item_1 => isEqual ? isEqual(item_1, dragging_0.dataset.onesyDragAndDropListValue) : item_1 === dragging_0.dataset.onesyDragAndDropListValue);
// if dragged is above over & bottom swap their indexes
// if dragged is below over && top swap their indexes
if (draggedIndex < overIndex && positionTopBottom === 'bottom' || draggedIndex > overIndex && positionBottomTop === 'top') {
if (!refs.previous.current || !(0, _utils.equalDeep)(refs.previous.current, [draggedIndex, overIndex])) {
onChange(draggedIndex, overIndex);
refs.previous.current = [draggedIndex, overIndex];
}
}
}
} else {
const overIndex_0 = items.findIndex(item_2 => isEqual ? isEqual(item_2, over.dataset.onesyDragAndDropListValue) : item_2 === over.dataset.onesyDragAndDropListValue);
const draggedIndex_0 = items.findIndex(item_3 => isEqual ? isEqual(item_3, dragging_0.dataset.onesyDragAndDropListValue) : item_3 === dragging_0.dataset.onesyDragAndDropListValue);
if (!refs.previous.current || !(0, _utils.equalDeep)(refs.previous.current, [draggedIndex_0, overIndex_0])) {
if ((0, _utils.is)('function', onChange)) onChange(draggedIndex_0, overIndex_0);
refs.previous.current = [draggedIndex_0, overIndex_0];
}
}
};
if ((0, _utils.is)('function', children)) return children({
ref: item_4 => {
if (ref) {
if ((0, _utils.is)('function', ref)) ref(item_4);else ref.current = item_4;
}
refs.root.current = item_4;
},
onDragStart,
onDragOver,
onDragEnd
});
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
children: children
});
};
DragAndDropList.displayName = 'onesy-DragAndDropList';
var _default = exports.default = DragAndDropList;