Repository URL to install this package:
|
Version:
3.12.20 ▾
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
/**
* Borrows heavily from and inspired by react-draggable https://github.com/react-grid-layout/react-draggable,
* basically a stripped-down version of it. Using only the core functionalities and using what we need from it
*/
import { useState, useEffect, cloneElement, useRef, Children } from 'react';
import { createCoreData, getControlPosition, addEvent, removeEvent, addUserSelectStyles, getTouchIdentifier, removeUserSelectStyles } from './Drawer.utils';
var eventsFor = {
touch: {
start: 'touchstart',
move: 'touchmove',
stop: 'touchend'
},
mouse: {
start: 'mousedown',
move: 'mousemove',
stop: 'mouseup'
}
};
// Default to mouse events.
var dragEventFor = eventsFor.mouse;
var animationRequestID = null;
var ResizerCore = function ResizerCore(props) {
var _useState = useState(null),
_useState2 = _slicedToArray(_useState, 2),
touchIdentifier = _useState2[0],
setTouchIdentifier = _useState2[1];
var mounted = useRef(false);
var resizerRef = useRef();
var draggingRef = useRef(false);
var lastXRef = useRef(NaN);
var lastYRef = useRef(NaN);
useEffect(function () {
mounted.current = true;
// Touch handlers must be added with {passive: false} to be cancelable.
// https://developers.google.com/web/updates/2017/01/scrolling-intervention
var thisNode = findDOMNode();
if (thisNode) {
addEvent(thisNode, eventsFor.touch.start, onTouchStart, {
passive: false
});
}
return function () {
mounted.current = false;
// Remove any leftover event handlers. Remove both touch and mouse handlers in case
// some browser quirk caused a touch event to fire during a mouse move, or vice versa.
var thisNode = findDOMNode();
if (thisNode) {
var ownerDocument = thisNode.ownerDocument;
removeEvent(ownerDocument, eventsFor.mouse.move, handleDrag);
removeEvent(ownerDocument, eventsFor.touch.move, handleDrag);
removeEvent(ownerDocument, eventsFor.mouse.stop, handleDragStop);
removeEvent(ownerDocument, eventsFor.touch.stop, handleDragStop);
removeEvent(thisNode, eventsFor.touch.start, onTouchStart, {
passive: false
});
removeUserSelectStyles(ownerDocument);
}
};
}, []);
// React Strict Mode compatibility: if `nodeRef` is passed, we will use it instead of trying to find
// the underlying DOM node ourselves. See the README for more information.
var findDOMNode = function findDOMNode() {
return resizerRef.current;
};
var handleDragStart = function handleDragStart(e) {
// Make it possible to attach event handlers on top of this one.
if (props.onMouseDown) {
props.onMouseDown(e);
}
// Get nodes. Be sure to grab relative document (could be iframed)
var thisNode = findDOMNode();
if (!thisNode || !thisNode.ownerDocument || !thisNode.ownerDocument.body) {
throw new Error('not mounted on DragStart!');
}
var ownerDocument = thisNode.ownerDocument;
// Prevent scrolling on mobile devices, like ipad/iphone.
// Important that this is after handle/cancel.
if (e.type === 'touchstart') e.preventDefault();
// Set touch identifier in component state if this is a touch event. This allows us to
// distinguish between individual touches on multitouch screens by identifying which
// touchpoint was set to this element.
var touchIdentifier = getTouchIdentifier(e);
setTouchIdentifier(touchIdentifier);
// Get the current drag point from the event. This is used as the offset.
var position = getControlPosition(e, touchIdentifier, resizerRef.current);
var x = position.x,
y = position.y;
// Create an event object with all the data parents need to make a decision here.
if (mounted.current === false) return;
// Add a style to the body to disable user-select. This prevents text from
// being selected all over the page.
addUserSelectStyles(ownerDocument);
// Initiate dragging. Set the current x and y as offsets
// so we know how much we've moved during the drag. This allows us
// to drag elements around even if they have been moved, without issue.
lastXRef.current = x;
lastYRef.current = y;
draggingRef.current = true;
// Add events to the document directly so we catch when the user's mouse/touch moves outside of
// this element. We use different events depending on whether or not we have detected that this
// is a touch-capable device.
addEvent(ownerDocument, dragEventFor.move, handleDrag);
addEvent(ownerDocument, dragEventFor.stop, handleDragStop);
};
var handleDrag = function handleDrag(e) {
if (animationRequestID) {
window.cancelAnimationFrame(animationRequestID);
}
animationRequestID = window.requestAnimationFrame(function () {
var position = getControlPosition(e, touchIdentifier, resizerRef.current);
if (position == null) return;
var x = position.x,
y = position.y;
var coreEvent = createCoreData({
node: resizerRef.current,
lastPositions: {
x: lastXRef.current,
y: lastYRef.current
},
x: x,
y: y
});
// Call event handler
var shouldUpdate = props.onDrag(e, coreEvent);
if (shouldUpdate === false || mounted.current === false) return;
lastXRef.current = x;
lastYRef.current = y;
animationRequestID = null;
});
// Get the current drag point from the event. This is used as the offset.
};
var handleDragStop = function handleDragStop(e) {
if (!draggingRef.current) return;
var position = getControlPosition(e, touchIdentifier, resizerRef.current);
if (position == null) return;
var x = position.x,
y = position.y;
var coreEvent = createCoreData({
node: resizerRef.current,
lastPositions: {
x: lastXRef.current,
y: lastYRef.current
},
x: x,
y: y
});
// Call event handler
var shouldContinue = props.onStop(e, coreEvent);
if (shouldContinue === false || mounted.current === false) return false;
var thisNode = findDOMNode();
if (thisNode) {
// Remove user-select hack
removeUserSelectStyles(thisNode.ownerDocument);
}
// Reset the el.
lastXRef.current = NaN;
lastYRef.current = NaN;
draggingRef.current = false;
if (thisNode) {
// Remove event handlers
removeEvent(thisNode.ownerDocument, dragEventFor.move, handleDrag);
removeEvent(thisNode.ownerDocument, dragEventFor.stop, handleDragStop);
}
};
var onMouseDown = function onMouseDown(e) {
dragEventFor = eventsFor.mouse; // on touchscreen laptops we could switch back to mouse
return handleDragStart(e);
};
var onMouseUp = function onMouseUp(e) {
dragEventFor = eventsFor.mouse;
return handleDragStop(e);
};
// Same as onMouseDown (start drag), but now consider this a touch device.
var onTouchStart = function onTouchStart(e) {
// We're on a touch device now, so change the event handlers
dragEventFor = eventsFor.touch;
return handleDragStart(e);
};
var onTouchEnd = function onTouchEnd(e) {
// We're on a touch device now, so change the event handlers
dragEventFor = eventsFor.touch;
return handleDragStop(e);
};
return /*#__PURE__*/cloneElement(Children.only(props.children), {
onMouseDown: onMouseDown,
onMouseUp: onMouseUp,
onTouchEnd: onTouchEnd,
ref: resizerRef
});
};
export default ResizerCore;