react-virtualized-dnd
Version:
A React-based, virtualized drag-and-drop framework.
1,588 lines (1,369 loc) • 211 kB
JavaScript
import React, { Component } from 'react';
import PropTypes from 'prop-types';
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function unwrapExports (x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var _this = commonjsGlobal;
var eventMap = new Map();
var subscribe = function subscribe(eventId, callback) {
if (!eventMap.has(eventId)) {
eventMap.set(eventId, []);
}
eventMap.get(eventId).push(callback);
};
var unsubscribe = function unsubscribe(eventId, callback) {
if (eventMap.has(eventId)) {
var handlerArray = eventMap.get(eventId);
var callbackIndex = handlerArray.indexOf(callback);
if (callbackIndex >= 0) {
handlerArray.splice(callbackIndex, 1);
} else {
console.warn('Unsubscription unsuccessful - callback not found.');
}
} else {
console.warn('Unsubscription unsuccessful - eventId not found.');
}
};
var dispatch = function dispatch(eventId) {
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
if (!eventMap.has(eventId)) return;
eventMap.get(eventId).forEach(function (callback) {
return callback.call.apply(callback, [_this].concat(args));
});
};
var EVENT_ID = {
SCHEDULING_MODAL_MUTATION_SUCCESS: 0,
WORKFLOW_DRAG_DESTINATION_PLACERHOLDER: 1,
WORKFLOW_SAVE_DRAG: 2,
WORKFLOW_MULTISELECT: 3,
CANVAS_TIMELINE_FORCE_REDRAW: 4,
SOCKET_NOTIFY: 5,
DND_REGISTER_DRAG_MOVE: 6,
DND_RESET_PLACEHOLDER: 7
};
var event_manager = {
EVENT_ID: EVENT_ID,
subscribe: subscribe,
unsubscribe: unsubscribe,
dispatch: dispatch
};
var event_manager_2 = event_manager.subscribe;
var event_manager_3 = event_manager.unsubscribe;
var event_manager_4 = event_manager.dispatch;
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
var createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var _extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
var inherits = function (subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
};
var possibleConstructorReturn = function (self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return call && (typeof call === "object" || typeof call === "function") ? call : self;
};
var slicedToArray = function () {
function sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"]) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
return function (arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return sliceIterator(arr, i);
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
};
}();
var toConsumableArray = function (arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
} else {
return Array.from(arr);
}
};
var Util = function () {
function Util() {
classCallCheck(this, Util);
}
createClass(Util, null, [{
key: 'getDragEvents',
value: function getDragEvents(group) {
return {
id: group,
moveEvent: group + '-MOVE',
resetEvent: group + '-RESET',
startEvent: group + '-START',
endEvent: group + '-END',
scrollEvent: group + '-SCROLL',
placeholderEvent: group + '-PLACEHOLDER'
};
}
}, {
key: 'getDroppableParentElement',
value: function getDroppableParentElement(element, dragAndDropGroup) {
var count = 0;
var maxTries = 15;
var droppableParentElem = null;
while (element && element.parentNode && !droppableParentElem && element.tagName !== 'body' && count <= maxTries) {
var foundDragAndDropGroup = element.getAttribute('droppablegroup');
if (foundDragAndDropGroup && foundDragAndDropGroup === dragAndDropGroup) {
droppableParentElem = element;
}
element = element.parentNode;
count++;
}
return droppableParentElem;
}
}, {
key: 'getDraggableParentElement',
value: function getDraggableParentElement(element) {
var count = 0;
var maxTries = 10;
var draggableParentElem = null;
while (element && element.parentNode && !draggableParentElem && element.tagName !== 'body' && count <= maxTries) {
if (element.getAttribute('draggableid')) {
draggableParentElem = element;
break;
}
element = element.parentNode;
count++;
}
return draggableParentElem;
}
}, {
key: 'logUpdateReason',
value: function logUpdateReason(props, state, prevProps, prevState) {
Object.entries(props).forEach(function (_ref) {
var _ref2 = slicedToArray(_ref, 2),
key = _ref2[0],
val = _ref2[1];
return prevProps[key] !== val && console.log('Prop \'' + key + '\' changed');
});
Object.entries(state).forEach(function (_ref3) {
var _ref4 = slicedToArray(_ref3, 2),
key = _ref4[0],
val = _ref4[1];
return prevState[key] !== val && console.log('State \'' + key + '\' changed');
});
}
}]);
return Util;
}();
var Draggable = function (_Component) {
inherits(Draggable, _Component);
function Draggable(props) {
classCallCheck(this, Draggable);
var _this = possibleConstructorReturn(this, (Draggable.__proto__ || Object.getPrototypeOf(Draggable)).call(this, props));
_this.state = {
startX: null,
startY: null,
isDragging: false,
wasClicked: false,
isTouch: false,
xClickOffset: 0,
yClickOffset: 0,
didMoveMinDistanceDuringDrag: false,
dragSensitivityX: 15,
dragSensitivityY: 15
};
_this.handleDragShortcuts = _this.handleDragShortcuts.bind(_this);
_this.onPointerMove = _this.onPointerMove.bind(_this);
_this.onPointerUp = _this.onPointerUp.bind(_this);
_this.dragAndDropGroup = Util.getDragEvents(_this.props.dragAndDropGroup);
_this.elFromPointCounter = 0;
_this.latestUpdateX = null;
_this.latestUpdateY = null;
// Minimum pixels moved before looking for new cards etc.
_this.minDragDistanceThreshold = _this.props.minDragDistanceThreshold ? _this.props.minDragDistanceThreshold : 5;
_this.draggableHoveringOver = null;
_this.droppableDraggedOver = null;
return _this;
}
createClass(Draggable, [{
key: 'componentDidMount',
value: function componentDidMount() {
document.addEventListener('keydown', this.handleDragShortcuts);
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
document.removeEventListener('keydown', this.handleDragShortcuts);
cancelAnimationFrame(this.frame);
this.frame = null;
}
}, {
key: 'handleDragShortcuts',
value: function handleDragShortcuts(e) {
if (e.key === 'Escape') {
this.onPointerCancel(e);
}
}
/*setPointerCapture(pointerId) {
if (!this.state.capturing && pointerId) {
this.draggable.setPointerCapture(pointerId);
this.setState({capturing: true, pointerId: pointerId});
}
}
releasePointerCapture() {
if (this.state.isTouch && this.state.pointerId && this.draggable) {
this.draggable.releasePointerCapture(this.state.pointerId);
}
}*/
}, {
key: 'getBoundingClientRect',
value: function getBoundingClientRect() {
if (this.draggable) {
return this.draggable.getBoundingClientRect();
}
}
}, {
key: 'removeDragEventListeners',
value: function removeDragEventListeners() {
var _this2 = this;
if (!this.state.isTouch) {
document.removeEventListener('mousemove', this.onPointerMove);
document.removeEventListener('mouseup', this.onPointerUp);
// Remove the click blocker after ended drag (on next available frame)
requestAnimationFrame(function () {
return document.removeEventListener('click', _this2.clickBlocker, true);
});
}
}
}, {
key: 'clickBlocker',
value: function clickBlocker(e) {
e.stopPropagation();
e.preventDefault();
}
}, {
key: 'onPointerDown',
value: function onPointerDown(e, isTouch) {
var isMouse = e.buttons === 1;
if (!isTouch && !isMouse || e.target.className && typeof e.target.className === 'string' && e.target.className.includes('no-drag') || this.props.disabled || this.props.isSectionHeader) {
return;
}
if (e) {
if (!isTouch) e.preventDefault();
e.stopPropagation();
}
if (!isTouch) {
document.addEventListener('mousemove', this.onPointerMove);
document.addEventListener('mouseup', this.onPointerUp);
}
var dragObject = { draggableId: this.props.draggableId, droppableId: this.props.droppableId };
event_manager_4(this.dragAndDropGroup.moveEvent, dragObject, null, null, null, null);
if (this.droppableDraggedOver !== null || this.draggableHoveringOver !== null) {
this.droppableDraggedOver = null;
this.draggableHoveringOver = null;
}
var x = isTouch ? e.changedTouches[e.changedTouches.length - 1].clientX : e.clientX;
var y = isTouch ? e.changedTouches[e.changedTouches.length - 1].clientY : e.clientY;
var cardWidth = this.draggable.offsetWidth;
var cardTop = this.draggable.getBoundingClientRect().top;
var cardLeft = this.draggable.getBoundingClientRect().left;
this.setState({
width: cardWidth,
didMoveMinDistanceDuringDrag: false,
minDragDistanceMoved: false,
startX: x,
startY: y,
wasClicked: true,
isTouch: isTouch,
isDragging: false,
// +8 for margin for error
xClickOffset: Math.abs(x - cardLeft) + 8,
yClickOffset: Math.abs(y - cardTop) + 8
});
}
}, {
key: 'onPointerUp',
value: function onPointerUp(e) {
e.preventDefault();
e.stopPropagation();
if (this.props.disabled || this.props.isSectionHeader) {
return;
}
if (this.state.isTouch && this.state.pointerId) ;
if (this.state.didMoveMinDistanceDuringDrag) {
event_manager_4(this.dragAndDropGroup.endEvent);
}
event_manager_4(this.dragAndDropGroup.resetEvent);
this.draggableHoveringOver = null;
this.setState({
isDragging: false,
capturing: false,
didMoveMinDistanceDuringDrag: false,
minDragDistanceMoved: false,
cardLeft: 0,
cardTop: 0,
top: null,
left: null,
wasClicked: false
});
this.removeDragEventListeners();
}
}, {
key: 'onPointerCancel',
value: function onPointerCancel() {
event_manager_4(this.dragAndDropGroup.resetEvent);
this.draggableHoveringOver = null;
this.setState({
isDragging: false,
capturing: false,
didMoveMinDistanceDuringDrag: false,
minDragDistanceMoved: false,
left: null,
top: null,
cardLeft: 0,
cardTop: 0,
wasClicked: false
});
this.removeDragEventListeners();
//this.releasePointerCapture();
}
// Don't update what we're dragging over on every single drag
}, {
key: 'shouldRefindDragElems',
value: function shouldRefindDragElems(x, y) {
if (!this.latestUpdateX || !this.latestUpdateY) {
this.latestUpdateX = x;
this.latestUpdateY = y;
return true;
} else {
// Only update if we've moved some x + y distance that is larger than threshold
var shouldUpdate = Math.abs(this.latestUpdateX - x) + Math.abs(this.latestUpdateY - y) >= this.minDragDistanceThreshold;
if (shouldUpdate) {
this.latestUpdateX = x;
this.latestUpdateY = y;
return true;
}
return false;
}
}
}, {
key: 'moveElement',
value: function moveElement(x, y) {
var hasDispatched = false;
var shouldRefindDragElems = this.shouldRefindDragElems(x, y);
var droppableDraggedOver = shouldRefindDragElems || this.droppableDraggedOver == null ? this.getDroppableElemUnderDrag(x, y) : this.droppableDraggedOver;
var draggableHoveringOver = shouldRefindDragElems || this.draggableHoveringOver == null ? this.getDraggableElemUnderDrag(x, y) : this.draggableHoveringOver;
var newLeft = x - this.state.xClickOffset;
var newTop = y - this.state.yClickOffset;
var minDistanceMoved = Math.abs(this.state.startX - x) > this.state.dragSensitivityX || Math.abs(this.state.startY - y) > this.state.dragSensitivityY;
if (minDistanceMoved && !this.state.didMoveMinDistanceDuringDrag) {
this.setState({ didMoveMinDistanceDuringDrag: true });
}
if (!minDistanceMoved && !this.state.didMoveMinDistanceDuringDrag) {
var dragObject = { draggableId: this.props.draggableId, droppableId: this.props.droppableId };
event_manager_4(this.dragAndDropGroup.moveEvent, dragObject, null, null, null, null);
hasDispatched = true;
return;
}
if (!droppableDraggedOver) {
event_manager_4(this.dragAndDropGroup.resetEvent);
this.droppableDraggedOver = null;
this.draggableHoveringOver = null;
}
var shouldRegisterAsDrag = this.state.didMoveMinDistanceDuringDrag || minDistanceMoved;
if (shouldRegisterAsDrag && this.state.wasClicked && !this.state.isDragging) {
var _dragObject = {
draggableId: this.props.draggableId,
droppableId: this.props.droppableId,
height: this.draggable ? this.draggable.clientHeight : null
};
event_manager_4(this.dragAndDropGroup.startEvent, _dragObject, x, y);
hasDispatched = true;
}
// We're hovering over a droppable and a draggable
if (droppableDraggedOver && draggableHoveringOver && shouldRegisterAsDrag) {
var draggableHoveredOverId = draggableHoveringOver.getAttribute('draggableid');
if (!draggableHoveredOverId.includes('placeholder')) {
if (this.droppableDraggedOver !== droppableDraggedOver || this.draggableHoveringOver !== draggableHoveringOver) {
var _dragObject2 = { draggableId: this.props.draggableId, droppableId: this.props.droppableId };
event_manager_4(this.dragAndDropGroup.moveEvent, _dragObject2, droppableDraggedOver, draggableHoveredOverId, x, y);
hasDispatched = true;
this.droppableDraggedOver = droppableDraggedOver;
this.draggableHoveringOver = draggableHoveringOver;
}
}
} else if (droppableDraggedOver && shouldRegisterAsDrag) {
// We're hovering over a droppable, but no draggable
this.droppableDraggedOver = droppableDraggedOver;
this.draggableHoveringOver = null;
var _dragObject3 = { draggableId: this.props.draggableId, droppableId: this.props.droppableId };
event_manager_4(this.dragAndDropGroup.moveEvent, _dragObject3, droppableDraggedOver, null, x, y, null);
hasDispatched = true;
}
if (!hasDispatched) {
// If nothing changed, we still wanna notify move for scrolling
event_manager_4(this.dragAndDropGroup.moveEvent, null, null, null, x, y, null);
hasDispatched = true;
}
this.setState({
isDragging: shouldRegisterAsDrag,
// We need to move more than the drag sensitivity before we consider it an intended drag
minDragDistanceMoved: minDistanceMoved,
left: newLeft,
top: newTop
});
}
}, {
key: 'onPointerMove',
value: function onPointerMove(e) {
var _this3 = this;
if (this.props.disabled || !this.state.wasClicked || this.props.isSectionHeader) {
return;
}
var x = this.state.isTouch ? e.changedTouches[e.changedTouches.length - 1].clientX : e.clientX;
var y = this.state.isTouch ? e.changedTouches[e.changedTouches.length - 1].clientY : e.clientY;
if (this.state.isTouch) ;
var minDistanceMoved = Math.abs(this.state.startX - x) > this.state.dragSensitivityX || Math.abs(this.state.startY - y) > this.state.dragSensitivityY;
if (!minDistanceMoved && !this.state.didMoveMinDistanceDuringDrag) {
return;
}
document.addEventListener('click', this.clickBlocker, true);
if (!this.state.isTouch) e.preventDefault();else e.nativeEvent.preventDefault();
e.stopPropagation();
if (e.buttons === 1 || this.state.isTouch) {
requestAnimationFrame(function () {
return _this3.moveElement(x, y);
});
} else {
this.onPointerCancel();
}
}
}, {
key: 'getDroppableElemUnderDrag',
value: function getDroppableElemUnderDrag(x, y) {
var colUnder = null;
var draggingElement = this.draggable;
if (draggingElement) {
// Disable pointer events to look through element
draggingElement.style.pointerEvents = 'none';
// Get element under dragged (look through)
var elementUnder = document.elementFromPoint(x, y);
// Reset dragged element's pointers
draggingElement.style.pointerEvents = 'all';
colUnder = Util.getDroppableParentElement(elementUnder, this.props.dragAndDropGroup);
}
return colUnder;
}
}, {
key: 'getDraggableElemUnderDrag',
value: function getDraggableElemUnderDrag(x, y) {
if (!this.state.wasClicked || !this.state.didMoveMinDistanceDuringDrag) {
return;
}
var cardUnder = null;
// The Element we're dragging
var draggingElement = this.draggable;
if (draggingElement) {
// Disable pointer events to look through element
draggingElement.style.pointerEvents = 'none';
// Get element under dragged tasks (look through)
var elementUnder = document.elementFromPoint(x, y);
// Reset dragged element's pointers
cardUnder = Util.getDraggableParentElement(elementUnder);
draggingElement.style.pointerEvents = 'all';
}
return cardUnder;
}
/*handlePointerCaptureLoss(e) {
if (this.state.wasClicked && e.pointerId != null) {
this.draggable.setPointerCapture(e.pointerId);
}
}*/
}, {
key: 'render',
value: function render() {
var _this4 = this;
var active = this.state.isDragging && this.state.wasClicked;
var draggingStyle = {
cursor: 'move',
position: this.state.didMoveMinDistanceDuringDrag || this.state.minDragDistanceMoved ? 'fixed' : '',
width: this.state.width,
transition: 'none',
animation: 'none',
zIndex: 500,
top: this.state.minDragDistanceMoved || this.state.didMoveMinDistanceDuringDrag ? this.state.top + 'px' : 0,
left: this.state.minDragDistanceMoved || this.state.didMoveMinDistanceDuringDrag ? this.state.left + 'px' : 0
};
var propsObject = {
'data-cy': 'draggable-' + this.props.draggableId,
className: 'draggable' + (active ? this.props.dragActiveClass : ''),
style: active ? _extends({}, draggingStyle) : { transform: 'none', top: 0, left: 0, cursor: this.props.disabled || this.props.isSectionHeader ? 'arrow' : this.state.wasClicked ? 'move' : 'grab' },
key: this.props.draggableId,
draggableid: this.props.isSectionHeader ? 'SECTION_HEADER_' + this.props.draggableId + (this.props.disableMove ? '_DISABLE_MOVE' : '') : this.props.draggableId,
index: this.props.innerIndex,
tabIndex: '0',
ref: function ref(div) {
return _this4.draggable = div;
},
'aria-grabbed': true,
'aria-dropeffect': 'move'
};
propsObject.onMouseDown = function (e) {
return _this4.onPointerDown(e, false);
};
var CustomTag = this.props.tagName ? this.props.tagName : 'div';
return React.createElement(
CustomTag,
propsObject,
this.props.children
);
}
}]);
return Draggable;
}(Component);
Draggable.propTypes = {
dragAndDropGroup: PropTypes.string.isRequired,
draggableId: PropTypes.string.isRequired,
dragDisabled: PropTypes.bool,
section: PropTypes.string
};
var performanceNow = createCommonjsModule(function (module) {
// Generated by CoffeeScript 1.12.2
(function() {
var getNanoSeconds, hrtime, loadTime, moduleLoadTime, nodeLoadTime, upTime;
if ((typeof performance !== "undefined" && performance !== null) && performance.now) {
module.exports = function() {
return performance.now();
};
} else if ((typeof process !== "undefined" && process !== null) && process.hrtime) {
module.exports = function() {
return (getNanoSeconds() - nodeLoadTime) / 1e6;
};
hrtime = process.hrtime;
getNanoSeconds = function() {
var hr;
hr = hrtime();
return hr[0] * 1e9 + hr[1];
};
moduleLoadTime = getNanoSeconds();
upTime = process.uptime() * 1e9;
nodeLoadTime = moduleLoadTime - upTime;
} else if (Date.now) {
module.exports = function() {
return Date.now() - loadTime;
};
loadTime = Date.now();
} else {
module.exports = function() {
return new Date().getTime() - loadTime;
};
loadTime = new Date().getTime();
}
}).call(commonjsGlobal);
});
var root = typeof window === 'undefined' ? commonjsGlobal : window
, vendors = ['moz', 'webkit']
, suffix = 'AnimationFrame'
, raf = root['request' + suffix]
, caf = root['cancel' + suffix] || root['cancelRequest' + suffix];
for(var i = 0; !raf && i < vendors.length; i++) {
raf = root[vendors[i] + 'Request' + suffix];
caf = root[vendors[i] + 'Cancel' + suffix]
|| root[vendors[i] + 'CancelRequest' + suffix];
}
// Some versions of FF have rAF but not cAF
if(!raf || !caf) {
var last = 0
, id = 0
, queue = []
, frameDuration = 1000 / 60;
raf = function(callback) {
if(queue.length === 0) {
var _now = performanceNow()
, next = Math.max(0, frameDuration - (_now - last));
last = next + _now;
setTimeout(function() {
var cp = queue.slice(0);
// Clear queue here to prevent
// callbacks from appending listeners
// to the current frame's queue
queue.length = 0;
for(var i = 0; i < cp.length; i++) {
if(!cp[i].cancelled) {
try{
cp[i].callback(last);
} catch(e) {
setTimeout(function() { throw e }, 0);
}
}
}
}, Math.round(next));
}
queue.push({
handle: ++id,
callback: callback,
cancelled: false
});
return id
};
caf = function(handle) {
for(var i = 0; i < queue.length; i++) {
if(queue[i].handle === handle) {
queue[i].cancelled = true;
}
}
};
}
var raf_1 = function(fn) {
// Wrap in a new function to prevent
// `cancel` potentially being assigned
// to the native rAF function
return raf.call(root, fn)
};
var cancel = function() {
caf.apply(root, arguments);
};
var polyfill = function(object) {
if (!object) {
object = root;
}
object.requestAnimationFrame = raf;
object.cancelAnimationFrame = caf;
};
raf_1.cancel = cancel;
raf_1.polyfill = polyfill;
var div = null;
var prefixes = [ 'Webkit', 'Moz', 'O', 'ms' ];
var prefixStyle = function prefixStyle (prop) {
// re-use a dummy div
if (!div) {
div = document.createElement('div');
}
var style = div.style;
// prop exists without prefix
if (prop in style) {
return prop
}
// borderRadius -> BorderRadius
var titleCase = prop.charAt(0).toUpperCase() + prop.slice(1);
// find the vendor-prefixed prop
for (var i = prefixes.length; i >= 0; i--) {
var name = prefixes[i] + titleCase;
// e.g. WebkitBorderRadius or webkitBorderRadius
if (name in style) {
return name
}
}
return false
};
/**
* Export.
*/
var toNoCase_1 = toNoCase;
/**
* Test whether a string is camel-case.
*/
var hasSpace = /\s/;
var hasSeparator = /(_|-|\.|:)/;
var hasCamel = /([a-z][A-Z]|[A-Z][a-z])/;
/**
* Remove any starting case from a `string`, like camel or snake, but keep
* spaces and punctuation that may be important otherwise.
*
* @param {String} string
* @return {String}
*/
function toNoCase(string) {
if (hasSpace.test(string)) return string.toLowerCase()
if (hasSeparator.test(string)) return (unseparate(string) || string).toLowerCase()
if (hasCamel.test(string)) return uncamelize(string).toLowerCase()
return string.toLowerCase()
}
/**
* Separator splitter.
*/
var separatorSplitter = /[\W_]+(.|$)/g;
/**
* Un-separate a `string`.
*
* @param {String} string
* @return {String}
*/
function unseparate(string) {
return string.replace(separatorSplitter, function (m, next) {
return next ? ' ' + next : ''
})
}
/**
* Camelcase splitter.
*/
var camelSplitter = /(.)([A-Z]+)/g;
/**
* Un-camelcase a `string`.
*
* @param {String} string
* @return {String}
*/
function uncamelize(string) {
return string.replace(camelSplitter, function (m, previous, uppers) {
return previous + ' ' + uppers.toLowerCase().split('').join(' ')
})
}
/**
* Export.
*/
var toSpaceCase_1 = toSpaceCase;
/**
* Convert a `string` to space case.
*
* @param {String} string
* @return {String}
*/
function toSpaceCase(string) {
return toNoCase_1(string).replace(/[\W_]+(.|$)/g, function (matches, match) {
return match ? ' ' + match : ''
}).trim()
}
/**
* Export.
*/
var toCamelCase_1 = toCamelCase;
/**
* Convert a `string` to camel case.
*
* @param {String} string
* @return {String}
*/
function toCamelCase(string) {
return toSpaceCase_1(string).replace(/\s(\w)/g, function (matches, letter) {
return letter.toUpperCase()
})
}
/* The following list is defined in React's core */
var IS_UNITLESS = {
animationIterationCount: true,
boxFlex: true,
boxFlexGroup: true,
boxOrdinalGroup: true,
columnCount: true,
flex: true,
flexGrow: true,
flexPositive: true,
flexShrink: true,
flexNegative: true,
flexOrder: true,
gridRow: true,
gridColumn: true,
fontWeight: true,
lineClamp: true,
lineHeight: true,
opacity: true,
order: true,
orphans: true,
tabSize: true,
widows: true,
zIndex: true,
zoom: true,
// SVG-related properties
fillOpacity: true,
stopOpacity: true,
strokeDashoffset: true,
strokeOpacity: true,
strokeWidth: true
};
var addPxToStyle = function(name, value) {
if(typeof value === 'number' && !IS_UNITLESS[ name ]) {
return value + 'px';
} else {
return value;
}
};
var cache = { 'float': 'cssFloat' };
function style (element, property, value) {
var camel = cache[property];
if (typeof camel === 'undefined') {
camel = detect(property);
}
// may be false if CSS prop is unsupported
if (camel) {
if (value === undefined) {
return element.style[camel]
}
element.style[camel] = addPxToStyle(camel, value);
}
}
function each (element, properties) {
for (var k in properties) {
if (properties.hasOwnProperty(k)) {
style(element, k, properties[k]);
}
}
}
function detect (cssProp) {
var camel = toCamelCase_1(cssProp);
var result = prefixStyle(camel);
cache[camel] = cache[cssProp] = cache[result] = result;
return result
}
function set$1 () {
if (arguments.length === 2) {
if (typeof arguments[1] === 'string') {
arguments[0].style.cssText = arguments[1];
} else {
each(arguments[0], arguments[1]);
}
} else {
style(arguments[0], arguments[1], arguments[2]);
}
}
var domCss = set$1;
var set_1 = set$1;
var get$1 = function (element, properties) {
if (Array.isArray(properties)) {
return properties.reduce(function (obj, prop) {
obj[prop] = style(element, prop || '');
return obj
}, {})
} else {
return style(element, properties || '')
}
};
domCss.set = set_1;
domCss.get = get$1;
var isString_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = isString;
function isString(maybe) {
return typeof maybe === 'string';
}
});
unwrapExports(isString_1);
var getScrollbarWidth_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = getScrollbarWidth;
var _domCss2 = _interopRequireDefault(domCss);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var scrollbarWidth = false;
function getScrollbarWidth() {
if (scrollbarWidth !== false) return scrollbarWidth;
/* istanbul ignore else */
if (typeof document !== 'undefined') {
var div = document.createElement('div');
(0, _domCss2["default"])(div, {
width: 100,
height: 100,
position: 'absolute',
top: -9999,
overflow: 'scroll',
MsOverflowStyle: 'scrollbar'
});
document.body.appendChild(div);
scrollbarWidth = div.offsetWidth - div.clientWidth;
document.body.removeChild(div);
} else {
scrollbarWidth = 0;
}
return scrollbarWidth || 0;
}
});
unwrapExports(getScrollbarWidth_1);
var returnFalse_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = returnFalse;
function returnFalse() {
return false;
}
});
unwrapExports(returnFalse_1);
var getInnerWidth_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = getInnerWidth;
function getInnerWidth(el) {
var clientWidth = el.clientWidth;
var _getComputedStyle = getComputedStyle(el),
paddingLeft = _getComputedStyle.paddingLeft,
paddingRight = _getComputedStyle.paddingRight;
return clientWidth - parseFloat(paddingLeft) - parseFloat(paddingRight);
}
});
unwrapExports(getInnerWidth_1);
var getInnerHeight_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = getInnerHeight;
function getInnerHeight(el) {
var clientHeight = el.clientHeight;
var _getComputedStyle = getComputedStyle(el),
paddingTop = _getComputedStyle.paddingTop,
paddingBottom = _getComputedStyle.paddingBottom;
return clientHeight - parseFloat(paddingTop) - parseFloat(paddingBottom);
}
});
unwrapExports(getInnerHeight_1);
var styles = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
var containerStyleDefault = exports.containerStyleDefault = {
position: 'relative',
overflow: 'hidden',
width: '100%',
height: '100%'
};
// Overrides containerStyleDefault properties
var containerStyleAutoHeight = exports.containerStyleAutoHeight = {
height: 'auto'
};
var viewStyleDefault = exports.viewStyleDefault = {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
overflow: 'scroll',
WebkitOverflowScrolling: 'touch'
};
// Overrides viewStyleDefault properties
var viewStyleAutoHeight = exports.viewStyleAutoHeight = {
position: 'relative',
top: undefined,
left: undefined,
right: undefined,
bottom: undefined
};
var viewStyleUniversalInitial = exports.viewStyleUniversalInitial = {
overflow: 'hidden',
marginRight: 0,
marginBottom: 0
};
var trackHorizontalStyleDefault = exports.trackHorizontalStyleDefault = {
position: 'absolute',
height: 6
};
var trackVerticalStyleDefault = exports.trackVerticalStyleDefault = {
position: 'absolute',
width: 6
};
var thumbHorizontalStyleDefault = exports.thumbHorizontalStyleDefault = {
position: 'relative',
display: 'block',
height: '100%'
};
var thumbVerticalStyleDefault = exports.thumbVerticalStyleDefault = {
position: 'relative',
display: 'block',
width: '100%'
};
var disableSelectStyle = exports.disableSelectStyle = {
userSelect: 'none'
};
var disableSelectStyleReset = exports.disableSelectStyleReset = {
userSelect: ''
};
});
unwrapExports(styles);
var styles_1 = styles.containerStyleDefault;
var styles_2 = styles.containerStyleAutoHeight;
var styles_3 = styles.viewStyleDefault;
var styles_4 = styles.viewStyleAutoHeight;
var styles_5 = styles.viewStyleUniversalInitial;
var styles_6 = styles.trackHorizontalStyleDefault;
var styles_7 = styles.trackVerticalStyleDefault;
var styles_8 = styles.thumbHorizontalStyleDefault;
var styles_9 = styles.thumbVerticalStyleDefault;
var styles_10 = styles.disableSelectStyle;
var styles_11 = styles.disableSelectStyleReset;
var defaultRenderElements = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
exports.renderViewDefault = renderViewDefault;
exports.renderTrackHorizontalDefault = renderTrackHorizontalDefault;
exports.renderTrackVerticalDefault = renderTrackVerticalDefault;
exports.renderThumbHorizontalDefault = renderThumbHorizontalDefault;
exports.renderThumbVerticalDefault = renderThumbVerticalDefault;
var _react2 = _interopRequireDefault(React);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
/* eslint-disable react/prop-types */
function renderViewDefault(props) {
return _react2["default"].createElement('div', props);
}
function renderTrackHorizontalDefault(_ref) {
var style = _ref.style,
props = _objectWithoutProperties(_ref, ['style']);
var finalStyle = _extends({}, style, {
right: 2,
bottom: 2,
left: 2,
borderRadius: 3
});
return _react2["default"].createElement('div', _extends({ style: finalStyle }, props));
}
function renderTrackVerticalDefault(_ref2) {
var style = _ref2.style,
props = _objectWithoutProperties(_ref2, ['style']);
var finalStyle = _extends({}, style, {
right: 2,
bottom: 2,
top: 2,
borderRadius: 3
});
return _react2["default"].createElement('div', _extends({ style: finalStyle }, props));
}
function renderThumbHorizontalDefault(_ref3) {
var style = _ref3.style,
props = _objectWithoutProperties(_ref3, ['style']);
var finalStyle = _extends({}, style, {
cursor: 'pointer',
borderRadius: 'inherit',
backgroundColor: 'rgba(0,0,0,.2)'
});
return _react2["default"].createElement('div', _extends({ style: finalStyle }, props));
}
function renderThumbVerticalDefault(_ref4) {
var style = _ref4.style,
props = _objectWithoutProperties(_ref4, ['style']);
var finalStyle = _extends({}, style, {
cursor: 'pointer',
borderRadius: 'inherit',
backgroundColor: 'rgba(0,0,0,.2)'
});
return _react2["default"].createElement('div', _extends({ style: finalStyle }, props));
}
});
unwrapExports(defaultRenderElements);
var defaultRenderElements_1 = defaultRenderElements.renderViewDefault;
var defaultRenderElements_2 = defaultRenderElements.renderTrackHorizontalDefault;
var defaultRenderElements_3 = defaultRenderElements.renderTrackVerticalDefault;
var defaultRenderElements_4 = defaultRenderElements.renderThumbHorizontalDefault;
var defaultRenderElements_5 = defaultRenderElements.renderThumbVerticalDefault;
var Scrollbars_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _raf3 = _interopRequireDefault(raf_1);
var _domCss2 = _interopRequireDefault(domCss);
var _propTypes2 = _interopRequireDefault(PropTypes);
var _isString2 = _interopRequireDefault(isString_1);
var _getScrollbarWidth2 = _interopRequireDefault(getScrollbarWidth_1);
var _returnFalse2 = _interopRequireDefault(returnFalse_1);
var _getInnerWidth2 = _interopRequireDefault(getInnerWidth_1);
var _getInnerHeight2 = _interopRequireDefault(getInnerHeight_1);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var Scrollbars = function (_Component) {
_inherits(Scrollbars, _Component);
function Scrollbars(props) {
var _ref;
_classCallCheck(this, Scrollbars);
for (var _len = arguments.length, rest = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
rest[_key - 1] = arguments[_key];
}
var _this = _possibleConstructorReturn(this, (_ref = Scrollbars.__proto__ || Object.getPrototypeOf(Scrollbars)).call.apply(_ref, [this, props].concat(rest)));
_this.getScrollLeft = _this.getScrollLeft.bind(_this);
_this.getScrollTop = _this.getScrollTop.bind(_this);
_this.getScrollWidth = _this.getScrollWidth.bind(_this);
_this.getScrollHeight = _this.getScrollHeight.bind(_this);
_this.getClientWidth = _this.getClientWidth.bind(_this);
_this.getClientHeight = _this.getClientHeight.bind(_this);
_this.getValues = _this.getValues.bind(_this);
_this.getThumbHorizontalWidth = _this.getThumbHorizontalWidth.bind(_this);
_this.getThumbVerticalHeight = _this.getThumbVerticalHeight.bind(_this);
_this.getScrollLeftForOffset = _this.getScrollLeftForOffset.bind(_this);
_this.getScrollTopForOffset = _this.getScrollTopForOffset.bind(_this);
_this.scrollLeft = _this.scrollLeft.bind(_this);
_this.scrollTop = _this.scrollTop.bind(_this);
_this.scrollToLeft = _this.scrollToLeft.bind(_this);
_this.scrollToTop = _this.scrollToTop.bind(_this);
_this.scrollToRight = _this.scrollToRight.bind(_this);
_this.scrollToBottom = _this.scrollToBottom.bind(_this);
_this.handleTrackMouseEnter = _this.handleTrackMouseEnter.bind(_this);
_this.handleTrackMouseLeave = _this.handleTrackMouseLeave.bind(_this);
_this.handleHorizontalTrackMouseDown = _this.handleHorizontalTrackMouseDown.bind(_this);
_this.handleVerticalTrackMouseDown = _this.handleVerticalTrackMouseDown.bind(_this);
_this.handleHorizontalThumbMouseDown = _this.handleHorizontalThumbMouseDown.bind(_this);
_this.handleVerticalThumbMouseDown = _this.handleVerticalThumbMouseDown.bind(_this);
_this.handleWindowResize = _this.handleWindowResize.bind(_this);
_this.handleScroll = _this.handleScroll.bind(_this);
_this.handleDrag = _this.handleDrag.bind(_this);
_this.handleDragEnd = _this.handleDragEnd.bind(_this);
_this.state = {
didMountUniversal: false
};
return _this;
}
_createClass(Scrollbars, [{
key: 'componentDidMount',
value: function componentDidMount() {
this.addListeners();
this.update();
this.componentDidMountUniversal();
}
}, {
key: 'componentDidMountUniversal',
value: function componentDidMountUniversal() {
// eslint-disable-line react/sort-comp
var universal = this.props.universal;
if (!universal) return;
this.setState({ didMountUniversal: true });
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate() {
this.update();
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this.removeListeners();
(0, raf_1.cancel)(this.requestFrame);
clearTimeout(this.hideTracksTimeout);
clearInterval(this.detectScrollingInterval);
}
}, {
key: 'getScrollLeft',
value: function getScrollLeft() {
if (!this.view) return 0;
return this.view.scrollLeft;
}
}, {
key: 'getScrollTop',
value: function getScrollTop() {
if (!this.view) return 0;
return this.view.scrollTop;
}
}, {
key: 'getScrollWidth',
value: function getScrollWidth() {
if (!this.view) return 0;
return this.view.scrollWidth;
}
}, {
key: 'getScrollHeight',
value: function getScrollHeight() {
if (!this.view) return 0;
return this.view.scrollHeight;
}
}, {
key: 'getClientWidth',
value: function getClientWidth() {
if (!this.view) return 0;
return this.view.clientWidth;
}
}, {
key: 'getClientHeight',
value: function getClientHeight() {
if (!this.view) return 0;
return this.view.clientHeight;
}
}, {
key: 'getValues',
value: function getValues() {
var _ref2 = this.view || {},
_ref2$scrollLeft = _ref2.scrollLeft,
scrollLeft = _ref2$scrollLeft === undefined ? 0 : _ref2$scrollLeft,
_ref2$scrollTop = _ref2.scrollTop,
scrollTop = _ref2$scrollTop === undefined ? 0 : _ref2$scrollTop,
_ref2$scrollWidth = _ref2.scrollWidth,
scrollWidth = _ref2$scrollWidth === undefined ? 0 : _ref2$scrollWidth,
_ref2$scrollHeight = _ref2.scrollHeight,
scrollHeight = _ref2$scrollHeight === undefined ? 0 : _ref2$scrollHeight,
_ref2$clientWidth = _ref2.clientWidth,
clientWidth = _ref2$clientWidth === undefined ? 0 : _ref2$clientWidth,
_ref2$clientHeight = _ref2.clientHeight,
clientHeight = _ref2$clientHeight === undefined ? 0 : _ref2$clientHeight;
return {
left: scrollLeft / (scrollWidth - clientWidth) || 0,
top: scrollTop / (scrollHeight - clientHeight) || 0,
scrollLeft: scrollLeft,
scrollTop: scrollTop,
scrollWidth: scrollWidth,
scrollHeight: scrollHeight,
clientWidth: clientWidth,
clientHeight: clientHeight
};
}
}, {
key: 'getThumbHorizontalWidth',
value: function getThumbHorizontalWidth() {
var _props = this.props,
thumbSize = _props.thumbSize,
thumbMinSize = _props.thumbMinSize;
var _view = this.view,
scrollWidth = _view.scrollWidth,
clientWidth = _view.clientWidth;
var trackWidth = (0, _getInnerWidth2["default"])(this.trackHorizontal);
var width = Math.ceil(clientWidth / scrollWidth * trackWidth);
if (trackWidth === width) return 0;
if (thumbSize) return thumbSize;
return Math.max(width, thumbMinSize);
}
}, {
key: 'getThumbVerticalHeight',
value: function getThumbVerticalHeight() {
var _props2 = this.props,
thumbSize = _props2.thumbSize,
thumbMinSize = _props2.thumbMinSize;
var _view2 = this.view,
scrollHeight = _view2.scrollHeight,
clientHeight = _view2.clientHeight;
var trackHeight = (0, _getInnerHeight2["default"])(this.trackVertical);
var height = Math.ceil(clientHeight / scrollHeight * trackHeight);
if (trackHeight === height) return 0;
if (thumbSize) return thumbSize;
return Math.max(height, thumbMinSize);
}
}, {
key: 'getScrollLeftForOffset',
value: function getScrollLeftForOffset(offset) {
var _view3 = this.view,
scrollWidth = _view3.scrollWidth,
clientWidth = _view3.clientWidth;
var trackWidth = (0, _getInnerWidth2["default"])(this.trackHorizontal);
var thumbWidth = this.getThumbHorizontalWidth();
return offset / (trackWidth - thumbWidth) * (scrollWidth - clientWidth);
}
}, {
key: 'getScrollTopForOffset',
value: function getScrollTopForOffset(offset) {
var _view4 = this.view,
scrollHeight = _view4.scrollHeight,
clientHeight = _view4.clientHeight;
var trackHeight = (0, _getInnerHeight2["default"])(this.trackVertical);
var thumbHeight = this.getThumbVerticalHeight();
return offset / (trackHeight - thumbHeight) * (scrollHeight - clientHeight);
}
}, {
key: 'scrollLeft',
value: function scrollLeft() {
var left = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
if (!this.view) return;
this.view.scrollLeft = left;
}
}, {
key: 'scrollTop',
value: function scrollTop() {
var top = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
if (!this.view) return;
this.view.scrollTop = top;
}
}, {
key: 'scrollToLeft',
value: function scrollToLeft() {
if (!this.view) return;
this.view.scrollLeft = 0;
}
}, {
key: 'scrollToTop',
value: function scrollToTop() {
if (!this.view) return;
this.view.scrollTop = 0;
}
}, {
key: 'scrollToRight',
value: function scrollToRight() {
if (!this.view) return;
this.view.scrollLeft = this.view.scrollWidth;
}
}, {
key: 'scrollToBottom',
value: function scrollToBottom() {
if (!this.view) return;
this.view.scrollTop = this.view.scrollHeight;
}
}, {
key: 'addListeners',
value: function addListeners() {
/* istanbul ignore if */
if (typeof document === 'undefined' || !this.view) return;
var view = this.view,
trackHorizontal = this.trackHorizontal,
trackVertical = this.trackVertical,
thumbHorizontal = this.thumbHorizontal,
thumbVertical = this.thumbVertical;
view.addEventListener('scroll', this.handleScroll);
if (!(0, _getScrollbarWidth2["default"])()) return;
trackHorizontal.addEventListener('mouseenter', this.handleTrackMouseEnter);
trackHorizontal.addEventListener('mouseleave', this.handleTrackMouseLeave);
trackHorizontal.addEventListener('mousedown', this.handleHorizontalTrackMouseDown);
trackVertical.addEventListener('mouseenter', this.handleTrackMouseEnter);
trackVertical.addEventListener('mouseleave', this.handleTrackMouseLeave);
trackVertical.addEventL