nw-react-slider--bki
Version:
Slider Component
1,497 lines (1,246 loc) • 86.4 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("react"), require("react-dom"));
else if(typeof define === 'function' && define.amd)
define(["react", "react-dom"], factory);
else if(typeof exports === 'object')
exports["NWReactSlider"] = factory(require("react"), require("react-dom"));
else
root["NWReactSlider"] = factory(root["React"], root["ReactDOM"]);
})(this, function(__WEBPACK_EXTERNAL_MODULE_6__, __WEBPACK_EXTERNAL_MODULE_8__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
__webpack_require__(1);
module.exports = __webpack_require__(5);
/***/ },
/* 1 */
/***/ function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ },
/* 2 */,
/* 3 */,
/* 4 */,
/* 5 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var React = __webpack_require__(6);
var Popover = __webpack_require__(7);
var Slider = __webpack_require__(10);
var isFunction = __webpack_require__(11);
var classnames = __webpack_require__(22);
var isUndefined = __webpack_require__(9);
var VALID_POSITIONS = ['top', 'bottom'];
var VALID_SHAPES = ['line', 'circle'];
module.exports = React.createClass({
displayName: 'nw-slider',
propTypes: {
value: React.PropTypes.number,
min: React.PropTypes.number,
max: React.PropTypes.number,
ticks: React.PropTypes.bool,
tickShape: React.PropTypes.oneOf(VALID_SHAPES),
onChange: React.PropTypes.func,
onDragStart: React.PropTypes.func,
onDragEnd: React.PropTypes.func,
markerLabel: React.PropTypes.array,
markerLabelPosition: React.PropTypes.oneOf(VALID_POSITIONS),
displayFollowerPopover: React.PropTypes.bool,
fill: React.PropTypes.bool
},
getInitialState: function getInitialState() {
return {
rtPosition: undefined,
handleWidth: undefined
};
},
componentDidUpdate: function componentDidUpdate() {
if (isUndefined(this.state.handleWidth) && this.refs.slider.refs.handle) {
this.setState({ handleWidth: this.refs.slider.refs.handle.offsetWidth }); // eslint-disable-line
}
},
handleSliderChange: function handleSliderChange(value, rtPosition) {
if (isFunction(this.props.onChange)) {
// Send the value and position of the slider in case the container needs it.
this.props.onChange(value, rtPosition);
}
this.setState({ rtPosition: rtPosition });
},
render: function render() {
var markerLabelPosition = this.props.markerLabelPosition || VALID_POSITIONS[0];
var popoverArrowPlacement = markerLabelPosition === 'top' ? 'bottom' : 'top';
var trackWidth = this.refs.slider && this.refs.slider.state.trackWidth;
var handleWidth = this.state.handleWidth;
var dragging = this.refs.slider && this.refs.slider.state.dragging;
var follower = this.props.displayFollowerPopover && !isUndefined(this.state.rtPosition) ? React.createElement(Popover, { trackWidth: trackWidth, handleWidth: handleWidth, value: this.props.value, position: this.state.rtPosition, arrowPlacement: popoverArrowPlacement }) : React.createElement('span', null);
var markerLabel = this.props.markerLabel || [];
var ticks = this.props.ticks;
return React.createElement(
'div',
{ className: classnames('slider-container-component', { dragging: dragging }) },
React.createElement(Slider, {
ref: 'slider',
min: this.props.min,
max: this.props.max,
value: this.props.value,
onChange: this.handleSliderChange,
onDragStart: this.props.onDragStart,
onDragEnd: this.props.onDragEnd,
ticks: ticks !== undefined ? ticks : markerLabel.length > 0,
tickShape: this.props.tickShape || VALID_SHAPES[0],
markerLabel: markerLabel,
markerLabelPosition: markerLabelPosition,
fill: this.props.fill }),
follower
);
}
});
/***/ },
/* 6 */
/***/ function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_6__;
/***/ },
/* 7 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var React = __webpack_require__(6);
var ReactDOM = __webpack_require__(8);
var isUndefined = __webpack_require__(9);
module.exports = React.createClass({
displayName: 'popover-follow',
propTypes: {
position: React.PropTypes.number,
value: React.PropTypes.number,
trackWidth: React.PropTypes.number,
handleWidth: React.PropTypes.number,
arrowPlacement: React.PropTypes.string
},
getDefaultProps: function getDefaultProps() {
return {
position: 0,
value: 0,
trackWidth: 0
};
},
getInitialState: function getInitialState() {
return {
arrowPosition: undefined,
bubblePosition: undefined,
popoverWidth: 0,
arrowWidth: 0
};
},
componentDidMount: function componentDidMount() {
var _this = this;
this.updatePopoverAndArrowWidth();
window.addEventListener('resize', function () {
_this.updatePopoverAndArrowWidth();
});
},
setPosition: function setPosition() {
var props = arguments.length <= 0 || arguments[0] === undefined ? this.props : arguments[0];
var trackWidth = this.props.trackWidth;
if (this.props.handleWidth) {
trackWidth += this.props.handleWidth;
}
var spaceArrowShouldMove = this.state.popoverWidth / 2 - this.state.arrowWidth;
if (props.position >= spaceArrowShouldMove && props.position <= this.props.trackWidth - spaceArrowShouldMove) {
// Middle of the slider where the popover is completely inside the width of the slider
this.setState({ bubblePosition: props.position, arrowPosition: spaceArrowShouldMove });
} else if (props.position < spaceArrowShouldMove) {
// Left section of the slider
this.setState({ arrowPosition: props.position, bubblePosition: spaceArrowShouldMove });
} else if (props.position > this.props.trackWidth - spaceArrowShouldMove) {
// Right section of the slider
this.setState({ arrowPosition: props.position - 2 * spaceArrowShouldMove, bubblePosition: trackWidth - spaceArrowShouldMove - this.props.handleWidth });
}
},
componentWillReceiveProps: function componentWillReceiveProps(nextProps) {
this.setPosition(nextProps);
},
updatePopoverAndArrowWidth: function updatePopoverAndArrowWidth() {
var popover = ReactDOM.findDOMNode(this.refs.popover);
if (!popover) {
return;
}
var popoverWidth = popover.offsetWidth;
var arrowWidth = ReactDOM.findDOMNode(this.refs.popover).getElementsByClassName('arrow').length > 0 ? ReactDOM.findDOMNode(this.refs.popover).getElementsByClassName('arrow')[0].offsetWidth : 12;
this.setState({ popoverWidth: popoverWidth, arrowWidth: arrowWidth }, this.setPosition);
},
render: function render() {
var styles = {};
if (isUndefined(this.state.arrowPosition) || isUndefined(this.state.bubblePosition)) {
styles = { visibility: 'hidden' };
}
var popoverStyle = {
display: 'block',
left: this.state.bubblePosition
};
var arrowStyle = {
left: this.state.arrowPosition
};
return React.createElement(
'div',
{ style: styles, ref: 'container', className: 'popover-container popover-container--arrow-' + this.props.arrowPlacement },
React.createElement(
'div',
{ role: 'tooltip', ref: 'popover', className: 'popover', style: popoverStyle },
React.createElement('div', { className: 'popover__arrow', style: arrowStyle }),
React.createElement(
'div',
{ className: 'popover__content' },
this.props.value
)
)
);
}
});
/***/ },
/* 8 */
/***/ function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_8__;
/***/ },
/* 9 */
/***/ function(module, exports) {
/**
* Checks if `value` is `undefined`.
*
* @static
* @since 0.1.0
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
* @example
*
* _.isUndefined(void 0);
* // => true
*
* _.isUndefined(null);
* // => false
*/
function isUndefined(value) {
return value === undefined;
}
module.exports = isUndefined;
/***/ },
/* 10 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
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 React = __webpack_require__(6);
var ReactDOM = __webpack_require__(8);
var isFunction = __webpack_require__(11);
var Draggable = __webpack_require__(13);
var isUndefined = __webpack_require__(9);
var throttle = __webpack_require__(14);
module.exports = React.createClass({
displayName: 'core-slider',
propTypes: {
value: React.PropTypes.number,
min: React.PropTypes.number,
max: React.PropTypes.number,
ticks: React.PropTypes.bool,
tickShape: React.PropTypes.string,
onChange: React.PropTypes.func,
onDragStart: React.PropTypes.func,
onDragEnd: React.PropTypes.func,
markerLabel: React.PropTypes.array,
markerLabelPosition: React.PropTypes.string,
fill: React.PropTypes.bool
},
getDefaultProps: function getDefaultProps() {
return {
value: 0,
min: 0,
max: 10,
ticks: false
};
},
getInitialState: function getInitialState() {
return {
position: undefined,
value: this.props.value,
dragging: false
};
},
componentWillReceiveProps: function componentWillReceiveProps(nextProps, nextState) {
var newValue;
// keep state up to date with passed in props
if (this.state.value !== nextProps.value) {
newValue = this.getBoundValue(nextProps, nextProps.value);
this.setState({ value: newValue });
this.setHandlePosition(nextProps, newValue);
}
// if min or max changes, have to reposition the handle
if (this.props.min !== nextProps.min || this.props.max !== nextProps.max) {
newValue = this.getBoundValue(nextProps, newValue || this.state.value);
this.setState({ value: newValue });
this.setHandlePosition(nextProps, newValue);
}
},
componentWillUpdate: function componentWillUpdate(nextProps, nextState) {
if (isUndefined(this.state.position) && !isUndefined(nextState.position)) {
this.props.onChange(nextState.value, nextState.position);
}
},
shouldComponentUpdate: function shouldComponentUpdate(nextProps, nextState) {
// Don't alter the component while dragging is occurring
return !nextState.dragging;
},
componentDidMount: function componentDidMount() {
this.updateTrackWidth();
this.updateTrackWidth = throttle(this.updateTrackWidth, 100, { leading: false });
window.addEventListener('resize', this.updateTrackWidth);
},
componentWillUnmount: function componentWillUnmount() {
window.removeEventListener('resize', this.updateTrackWidth);
},
getBoundValue: function getBoundValue(props, value) {
var newValue = value;
if (newValue < props.min) {
newValue = props.min;
} else if (newValue > props.max) {
newValue = props.max;
}
return newValue;
},
updateTrackWidth: function updateTrackWidth() {
var track = ReactDOM.findDOMNode(this.refs.track);
if (!track) {
return;
}
var trackWidth = track.offsetWidth;
this.setState({ trackWidth: trackWidth }, this.setHandlePosition);
},
componentDidUpdate: function componentDidUpdate() {
// after a render, ensure that draggable is in correct position
this.refs.drag && this.refs.drag.setState({ clientX: this.state.position });
},
setHandlePosition: function setHandlePosition() {
var props = arguments.length <= 0 || arguments[0] === undefined ? this.props : arguments[0];
var value = arguments.length <= 1 || arguments[1] === undefined ? this.state.value : arguments[1];
var position = this.state.trackWidth / (props.max - props.min) * (value - props.min);
this.setState({ position: position });
if (isFunction(this.props.onChange)) {
this.props.onChange(value, position);
}
},
updateValueFromPosition: function updateValueFromPosition(newPosition) {
var currentPosition = newPosition;
var value, position;
if (this.props.max === this.props.min) {
value = this.props.min;
position = this.state.trackWidth / 2;
} else {
// find the two closest ticks to the current position
var currentPercent = currentPosition / this.state.trackWidth * 100;
var percentStep = 100 / (this.props.max - this.props.min);
var closestSmallerValue = Math.floor(currentPercent / percentStep);
var closestLargerValue = closestSmallerValue + 1;
var bestMatchPercent, bestMatchTick;
// determine which of the two values is closest
if (currentPercent - closestSmallerValue * percentStep <= closestLargerValue * percentStep - currentPercent) {
bestMatchTick = closestSmallerValue;
bestMatchPercent = bestMatchTick * percentStep;
} else {
bestMatchTick = closestLargerValue;
bestMatchPercent = bestMatchTick * percentStep;
}
// update the value and position
value = this.props.min + bestMatchTick;
position = this.state.trackWidth * (bestMatchPercent / 100);
}
// fire change event if callback exists
if (isFunction(this.props.onChange)) {
var rtposition = position;
if (this.state.dragging) {
rtposition = currentPosition;
}
this.props.onChange(value, rtposition);
}
// Although set state is async, pushing its invocation as late as possible
this.setState({ value: value, position: position });
return position;
},
cumulativeOffset: function cumulativeOffset(element) {
// determine the overall offset of the element by crawling up the DOM, borrowed from Prototype.js
var top = 0;
var left = 0;
do {
top += element.offsetTop || 0;
left += element.offsetLeft || 0;
element = element.offsetParent;
} while (element);
return {
top: top,
left: left
};
},
clickOnTrack: function clickOnTrack(event) {
var clickFromLeft = event.clientX - this.cumulativeOffset(event.target).left;
this.updateValueFromPosition(clickFromLeft);
},
handleUp: function handleUp(event, ui) {
var position = this.state.position;
// Do we have a drag end hook ?
if (isFunction(this.props.onDragEnd)) {
this.props.onDragEnd(position);
}
this.setState({ dragging: false });
this.updateValueFromPosition(position);
},
handleDown: function handleDown(event, ui) {
// Do we have a drag start hook ?
if (isFunction(this.props.onDragStart)) {
this.props.onDragStart(this.state.position);
}
this.setState({ dragging: true });
},
dragging: function dragging(event, ui) {
var pos = this.refs.drag.state.clientX || 0;
this.updateValueFromPosition(pos);
event.preventDefault();
},
renderTicks: function renderTicks() {
if (!this.props.ticks) return React.createElement('span', null);
var elements = [];
var min = this.props.min;
var max = this.props.max;
var percentStep = 100 / (max - min);
// Don't render ticks if it is too high. Will crash the browser and the ticks become useless
if (max - min < 200) {
for (var i = min + 1; i < max; i++) {
var style = {
left: percentStep * (i - min) + '%'
};
elements.push(React.createElement('span', { key: 'tick' + i, className: 'slider__tick', style: style }));
}
}
return React.createElement(
'div',
{ key: 'ticks', className: 'slider__ticks slider__ticks--' + this.props.tickShape, onClick: this.clickOnTrack },
elements
);
},
renderMarkers: function renderMarkers() {
if (!this.props.markerLabel) return React.createElement('span', null);
var elements = [];
var _props = this.props;
var min = _props.min;
var max = _props.max;
var markers = _props.markerLabel;
var percentStep = 100 / (max - min);
for (var i in markers) {
var style = {
left: percentStep * (markers[i].value - min) + '%'
};
if (markers[i].value <= max && markers[i].value >= min && max - min < 200) {
// don't render a tick for this marker if ticks are already being rendered
elements.push(React.createElement(
'div',
{ key: 'marker' + i, className: 'slider__marker marker', style: style },
React.createElement(
'p',
{ className: 'marker__label' },
markers[i].label
)
));
}
}
return React.createElement(
'div',
{ key: 'markers', className: 'slider__markers slider__markers--' + this.props.markerLabelPosition, onClick: this.clickOnTrack },
elements
);
},
renderFill: function renderFill() {
if (!this.props.fill) {
return;
}
return React.createElement('div', {
className: 'slider__fill',
style: {
right: this.state.trackWidth - this.state.position + 'px'
} });
},
render: function render() {
var draggableProps, draggable;
if (!isUndefined(this.state.position)) {
draggableProps = {
axis: 'x',
handle: '.slider__handle',
bounds: { left: 0, right: this.state.trackWidth },
start: { x: this.state.position, y: 0 },
onStop: this.handleUp,
onStart: this.handleDown,
onDrag: this.dragging
};
draggable = React.createElement(
Draggable,
_extends({ ref: 'drag', key: 'draggable' }, draggableProps),
React.createElement('span', { ref: 'handle', className: 'slider__handle' })
);
}
return React.createElement(
'div',
{ ref: 'slider', className: 'slider' },
draggable,
React.createElement(
'div',
{ ref: 'track', className: 'slider__track', onClick: this.clickOnTrack },
this.renderTicks(),
this.renderMarkers(),
this.renderFill()
)
);
}
});
/***/ },
/* 11 */
/***/ function(module, exports, __webpack_require__) {
var isObject = __webpack_require__(12);
/** `Object#toString` result references. */
var funcTag = '[object Function]',
genTag = '[object GeneratorFunction]';
/** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var objectToString = objectProto.toString;
/**
* Checks if `value` is classified as a `Function` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
* @example
*
* _.isFunction(_);
* // => true
*
* _.isFunction(/abc/);
* // => false
*/
function isFunction(value) {
// The use of `Object#toString` avoids issues with the `typeof` operator
// in Safari 8-9 which returns 'object' for typed array and other constructors.
var tag = isObject(value) ? objectToString.call(value) : '';
return tag == funcTag || tag == genTag;
}
module.exports = isFunction;
/***/ },
/* 12 */
/***/ function(module, exports) {
/**
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(_.noop);
* // => true
*
* _.isObject(null);
* // => false
*/
function isObject(value) {
var type = typeof value;
return !!value && (type == 'object' || type == 'function');
}
module.exports = isObject;
/***/ },
/* 13 */
/***/ function(module, exports, __webpack_require__) {
(function webpackUniversalModuleDefinition(root, factory) {
if(true)
module.exports = factory(__webpack_require__(6), __webpack_require__(8));
else if(typeof define === 'function' && define.amd)
define(["react", "react-dom"], factory);
else if(typeof exports === 'object')
exports["ReactDraggable"] = factory(require("react"), require("react-dom"));
else
root["ReactDraggable"] = factory(root["React"], root["ReactDOM"]);
})(this, function(__WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_3__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
module.exports = __webpack_require__(1).default;
module.exports.DraggableCore = __webpack_require__(9).default;
/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
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 _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 _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 _react = __webpack_require__(2);
var _react2 = _interopRequireDefault(_react);
var _reactDom = __webpack_require__(3);
var _reactDom2 = _interopRequireDefault(_reactDom);
var _classnames = __webpack_require__(4);
var _classnames2 = _interopRequireDefault(_classnames);
var _domFns = __webpack_require__(5);
var _positionFns = __webpack_require__(8);
var _shims = __webpack_require__(6);
var _DraggableCore = __webpack_require__(9);
var _DraggableCore2 = _interopRequireDefault(_DraggableCore);
var _log = __webpack_require__(10);
var _log2 = _interopRequireDefault(_log);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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; }
// $FlowIgnore
//
// Define <Draggable>
//
var Draggable = function (_React$Component) {
_inherits(Draggable, _React$Component);
function Draggable() {
var _Object$getPrototypeO;
var _temp, _this, _ret;
_classCallCheck(this, Draggable);
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(Draggable)).call.apply(_Object$getPrototypeO, [this].concat(args))), _this), _this.state = {
// Whether or not we are currently dragging.
dragging: false,
// Whether or not we have been dragged before.
dragged: false,
// Current transform x and y.
clientX: _this.props.start.x, clientY: _this.props.start.y,
// Used for compensating for out-of-bounds drags
slackX: 0, slackY: 0,
// Can only determine if SVG after mounting
isElementSVG: false
}, _this.onDragStart = function (e, coreEvent) {
(0, _log2.default)('Draggable: onDragStart: %j', coreEvent.position);
// Short-circuit if user's callback killed it.
var shouldStart = _this.props.onStart(e, (0, _domFns.createUIEvent)(_this, coreEvent));
// Kills start event on core as well, so move handlers are never bound.
if (shouldStart === false) return false;
_this.setState({ dragging: true, dragged: true });
}, _this.onDrag = function (e, coreEvent) {
if (!_this.state.dragging) return false;
(0, _log2.default)('Draggable: onDrag: %j', coreEvent.position);
var uiEvent = (0, _domFns.createUIEvent)(_this, coreEvent);
var newState = {
clientX: uiEvent.position.left,
clientY: uiEvent.position.top
};
// Keep within bounds.
if (_this.props.bounds) {
// Save original x and y.
var _clientX = newState.clientX;
var _clientY = newState.clientY;
// Add slack to the values used to calculate bound position. This will ensure that if
// we start removing slack, the element won't react to it right away until it's been
// completely removed.
newState.clientX += _this.state.slackX;
newState.clientY += _this.state.slackY;
// Get bound position. This will ceil/floor the x and y within the boundaries.
// Recalculate slack by noting how much was shaved by the boundPosition handler.
var _getBoundPosition = (0, _positionFns.getBoundPosition)(_this, newState.clientX, newState.clientY);
var _getBoundPosition2 = _slicedToArray(_getBoundPosition, 2);
newState.clientX = _getBoundPosition2[0];
newState.clientY = _getBoundPosition2[1];
newState.slackX = _this.state.slackX + (_clientX - newState.clientX);
newState.slackY = _this.state.slackY + (_clientY - newState.clientY);
// Update the event we fire to reflect what really happened after bounds took effect.
uiEvent.position.left = _clientX;
uiEvent.position.top = _clientY;
uiEvent.deltaX = newState.clientX - _this.state.clientX;
uiEvent.deltaY = newState.clientY - _this.state.clientY;
}
// Short-circuit if user's callback killed it.
var shouldUpdate = _this.props.onDrag(e, uiEvent);
if (shouldUpdate === false) return false;
_this.setState(newState);
}, _this.onDragStop = function (e, coreEvent) {
if (!_this.state.dragging) return false;
// Short-circuit if user's callback killed it.
var shouldStop = _this.props.onStop(e, (0, _domFns.createUIEvent)(_this, coreEvent));
if (shouldStop === false) return false;
(0, _log2.default)('Draggable: onDragStop: %j', coreEvent.position);
_this.setState({
dragging: false,
slackX: 0,
slackY: 0
});
}, _temp), _possibleConstructorReturn(_this, _ret);
}
_createClass(Draggable, [{
key: 'componentDidMount',
value: function componentDidMount() {
// Check to see if the element passed is an instanceof SVGElement
if (_reactDom2.default.findDOMNode(this) instanceof SVGElement) {
this.setState({ isElementSVG: true });
}
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this.setState({ dragging: false }); // prevents invariant if unmounted while dragging
}
}, {
key: 'render',
value: function render() {
var style = {},
svgTransform = null;
// Add a CSS transform to move the element around. This allows us to move the element around
// without worrying about whether or not it is relatively or absolutely positioned.
// If the item you are dragging already has a transform set, wrap it in a <span> so <Draggable>
// has a clean slate.
var transformOpts = {
// Set left if horizontal drag is enabled
x: (0, _positionFns.canDragX)(this) ? this.state.clientX : this.props.start.x,
// Set top if vertical drag is enabled
y: (0, _positionFns.canDragY)(this) ? this.state.clientY : this.props.start.y
};
// If this element was SVG, we use the `transform` attribute.
if (this.state.isElementSVG) {
svgTransform = (0, _domFns.createSVGTransform)(transformOpts);
} else {
style = (0, _domFns.createCSSTransform)(transformOpts);
}
// zIndex option
if (this.state.dragging && !isNaN(this.props.zIndex)) {
style.zIndex = this.props.zIndex;
}
// Mark with class while dragging
var className = (0, _classnames2.default)(this.props.children.props.className || '', 'react-draggable', {
'react-draggable-dragging': this.state.dragging,
'react-draggable-dragged': this.state.dragged
});
// Reuse the child provided
// This makes it flexible to use whatever element is wanted (div, ul, etc)
return _react2.default.createElement(
_DraggableCore2.default,
_extends({}, this.props, { onStart: this.onDragStart, onDrag: this.onDrag, onStop: this.onDragStop }),
_react2.default.cloneElement(_react2.default.Children.only(this.props.children), {
className: className,
style: _extends({}, this.props.children.props.style, style),
transform: svgTransform
})
);
}
}]);
return Draggable;
}(_react2.default.Component);
Draggable.displayName = 'Draggable';
Draggable.propTypes = _extends({}, _DraggableCore2.default.propTypes, {
/**
* `axis` determines which axis the draggable can move.
*
* Note that all callbacks will still return data as normal. This only
* controls flushing to the DOM.
*
* 'both' allows movement horizontally and vertically.
* 'x' limits movement to horizontal axis.
* 'y' limits movement to vertical axis.
* 'none' limits all movement.
*
* Defaults to 'both'.
*/
axis: _react.PropTypes.oneOf(['both', 'x', 'y', 'none']),
/**
* `bounds` determines the range of movement available to the element.
* Available values are:
*
* 'parent' restricts movement within the Draggable's parent node.
*
* Alternatively, pass an object with the following properties, all of which are optional:
*
* {left: LEFT_BOUND, right: RIGHT_BOUND, bottom: BOTTOM_BOUND, top: TOP_BOUND}
*
* All values are in px.
*
* Example:
*
* ```jsx
* let App = React.createClass({
* render: function () {
* return (
* <Draggable bounds={{right: 300, bottom: 300}}>
* <div>Content</div>
* </Draggable>
* );
* }
* });
* ```
*/
bounds: _react.PropTypes.oneOfType([_react.PropTypes.shape({
left: _react.PropTypes.Number,
right: _react.PropTypes.Number,
top: _react.PropTypes.Number,
bottom: _react.PropTypes.Number
}), _react.PropTypes.string, _react.PropTypes.oneOf([false])]),
/**
* `start` specifies the x and y that the dragged item should start at
*
* Example:
*
* ```jsx
* let App = React.createClass({
* render: function () {
* return (
* <Draggable start={{x: 25, y: 25}}>
* <div>I start with transformX: 25px and transformY: 25px;</div>
* </Draggable>
* );
* }
* });
* ```
*/
start: _react.PropTypes.shape({
x: _react.PropTypes.number,
y: _react.PropTypes.number
}),
/**
* `zIndex` specifies the zIndex to use while dragging.
*
* Example:
*
* ```jsx
* let App = React.createClass({
* render: function () {
* return (
* <Draggable zIndex={100}>
* <div>I have a zIndex</div>
* </Draggable>
* );
* }
* });
* ```
*/
zIndex: _react.PropTypes.number,
/**
* These properties should be defined on the child, not here.
*/
className: _shims.dontSetMe,
style: _shims.dontSetMe,
transform: _shims.dontSetMe
});
Draggable.defaultProps = _extends({}, _DraggableCore2.default.defaultProps, {
axis: 'both',
bounds: false,
start: { x: 0, y: 0 },
zIndex: NaN
});
exports.default = Draggable;
/***/ },
/* 2 */
/***/ function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_2__;
/***/ },
/* 3 */
/***/ function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_3__;
/***/ },
/* 4 */
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
Copyright (c) 2016 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
/* global define */
(function () {
'use strict';
var hasOwn = {}.hasOwnProperty;
function classNames () {
var classes = [];
for (var i = 0; i < arguments.length; i++) {
var arg = arguments[i];
if (!arg) continue;
var argType = typeof arg;
if (argType === 'string' || argType === 'number') {
classes.push(arg);
} else if (Array.isArray(arg)) {
classes.push(classNames.apply(null, arg));
} else if (argType === 'object') {
for (var key in arg) {
if (hasOwn.call(arg, key) && arg[key]) {
classes.push(key);
}
}
}
}
return classes.join(' ');
}
if (typeof module !== 'undefined' && module.exports) {
module.exports = classNames;
} else if (true) {
// register as 'classnames', consistent with npm package name
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function () {
return classNames;
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
} else {
window.classNames = classNames;
}
}());
/***/ },
/* 5 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
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.matchesSelector = matchesSelector;
exports.addEvent = addEvent;
exports.removeEvent = removeEvent;
exports.outerHeight = outerHeight;
exports.outerWidth = outerWidth;
exports.innerHeight = innerHeight;
exports.innerWidth = innerWidth;
exports.createCSSTransform = createCSSTransform;
exports.createSVGTransform = createSVGTransform;
exports.addUserSelectStyles = addUserSelectStyles;
exports.removeUserSelectStyles = removeUserSelectStyles;
exports.styleHacks = styleHacks;
exports.createCoreEvent = createCoreEvent;
exports.createUIEvent = createUIEvent;
var _shims = __webpack_require__(6);
var _getPrefix = __webpack_require__(7);
var _getPrefix2 = _interopRequireDefault(_getPrefix);
var _reactDom = __webpack_require__(3);
var _reactDom2 = _interopRequireDefault(_reactDom);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var matchesSelectorFunc = '';
function matchesSelector(el, selector) {
if (!matchesSelectorFunc) {
matchesSelectorFunc = (0, _shims.findInArray)(['matches', 'webkitMatchesSelector', 'mozMatchesSelector', 'msMatchesSelector', 'oMatchesSelector'], function (method) {
// $FlowIgnore: Doesn't think elements are indexable
return (0, _shims.isFunction)(el[method]);
});
}
// $FlowIgnore: Doesn't think elements are indexable
return el[matchesSelectorFunc].call(el, selector);
}
function addEvent(el, event, handler) {
if (!el) {
return;
}
if (el.attachEvent) {
el.attachEvent('on' + event, handler);
} else if (el.addEventListener) {
el.addEventListener(event, handler, true);
} else {
// $FlowIgnore: Doesn't think elements are indexable
el['on' + event] = handler;
}
}
function removeEvent(el, event, handler) {
if (!el) {
return;
}
if (el.detachEvent) {
el.detachEvent('on' + event, handler);
} else if (el.removeEventListener) {
el.removeEventListener(event, handler, true);
} else {
// $FlowIgnore: Doesn't think elements are indexable
el['on' + event] = null;
}
}
function outerHeight(node) {
// This is deliberately excluding margin for our calculations, since we are using
// offsetTop which is including margin. See getBoundPosition
var height = node.clientHeight;
var computedStyle = window.getComputedStyle(node);
height += (0, _shims.int)(computedStyle.borderTopWidth);
height += (0, _shims.int)(computedStyle.borderBottomWidth);
return height;
}
function outerWidth(node) {
// This is deliberately excluding margin for our calculations, since we are using
// offsetLeft which is including margin. See getBoundPosition
var width = node.clientWidth;
var computedStyle = window.getComputedStyle(node);
width += (0, _shims.int)(computedStyle.borderLeftWidth);
width += (0, _shims.int)(computedStyle.borderRightWidth);
return width;
}
function innerHeight(node) {
var height = node.clientHeight;
var computedStyle = window.getComputedStyle(node);
height -= (0, _shims.int)(computedStyle.paddingTop);
height -= (0, _shims.int)(computedStyle.paddingBottom);
return height;
}
function innerWidth(node) {
var width = node.clientWidth;
var computedStyle = window.getComputedStyle(node);
width -= (0, _shims.int)(computedStyle.paddingLeft);
width -= (0, _shims.int)(computedStyle.paddingRight);
return width;
}
function createCSSTransform(_ref) {
var x = _ref.x;
var y = _ref.y;
// Replace unitless items with px
return _defineProperty({}, (0, _getPrefix.browserPrefixToKey)('transform', _getPrefix2.default), 'translate(' + x + 'px,' + y + 'px)');
}
function createSVGTransform(_ref3) {
var x = _ref3.x;
var y = _ref3.y;
return 'translate(' + x + ',' + y + ')';
}
// User-select Hacks:
//
// Useful for preventing blue highlights all over everything when dragging.
var userSelectPrefix = (0, _getPrefix.getPrefix)('user-select');
var userSelect = (0, _getPrefix.browserPrefixToStyle)('user-select', userSelectPrefix);
var userSelectStyle = ';' + userSelect + ': none;';
function addUserSelectStyles() {
var style = document.body.getAttribute('style') || '';
document.body.setAttribute('style', style + userSelectStyle);
}
function removeUserSelectStyles() {
var style = document.body.getAttribute('style') || '';
document.body.setAttribute('style', style.replace(userSelectStyle, ''));
}
function styleHacks() {
var childStyle = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
// Workaround IE pointer events; see #51
// https://github.com/mzabriskie/react-draggable/issues/51#issuecomment-103488278
return _extends({
touchAction: 'none'
}, childStyle);
}
// Create an event exposed by <DraggableCore>
function createCoreEvent(draggable, clientX, clientY) {
// State changes are often (but not always!) async. We want the latest value.
var state = draggable._pendingState || draggable.state;
var isStart = !(0, _shims.isNum)(state.lastX);
return {
node: _reactDom2.default.findDOMNode(draggable),
position: isStart ?
// If this is our first move, use the clientX and clientY as last coords.
{
deltaX: 0, deltaY: 0,
lastX: clientX, lastY: clientY,
clientX: clientX, clientY: clientY
} :
// Otherwise calculate proper values.
{
deltaX: clientX - state.lastX, deltaY: clientY - state.lastY,
lastX: state.lastX, lastY: state.lastY,
clientX: clientX, clientY: clientY
}
};
}
// Create an event exposed by <Draggable>
function createUIEvent(draggable, coreEvent) {
return {
node: _reactDom2.default.findDOMNode(draggable),
position: {
left: draggable.state.clientX + coreEvent.position.deltaX,
top: draggable.state.clientY + coreEvent.position.deltaY
},
deltaX: coreEvent.position.deltaX,
deltaY: coreEvent.position.deltaY
};
}
/***/ },
/* 6 */
/***/ function(module, exports) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.findInArray = findInArray;
exports.isFunction = isFunction;
exports.isNum = isNum;
exports.int = int;
exports.dontSetMe = dontSetMe;
// @credits https://gist.github.com/rogozhnikoff/a43cfed27c41e4e68cdc
function findInArray(array, callback) {
for (var i = 0, length = array.length; i < length; i++) {
if (callback.apply(callback, [array[i], i, array])) return array[i];
}
}
function isFunction(func) {
return typeof func === 'function' || Object.prototype.toString.call(func) === '[object Function]';
}
function isNum(num) {
return typeof num === 'number' && !isNaN(num);
}
function int(a) {
return parseInt(a, 10);
}
function dontSetMe(props, propName, componentName) {
if (props[propName]) {
throw new Error('Invalid prop ' + propName + ' passed to ' + componentName + ' - do not set this, set it on the child.');
}
}
/***/ },
/* 7 */
/***/ function(module, exports) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getPrefix = getPrefix;
exports.browserPrefixToKey = browserPrefixToKey;
exports.browserPrefixToStyle = browserPrefixToStyle;
var prefixes = ['Moz', 'Webkit', 'O', 'ms'];
function getPrefix() {
var prop = arguments.length <= 0 || arguments[0] === undefined ? 'transform' : arguments[0];
// Checking specifically for 'window.document' is for pseudo-browser server-side
// environments that define 'window' as the global context.
// E.g. React-rails (see https://github.com/reactjs/react-rails/pull/84)
if (typeof window === 'undefined' || typeof window.document === 'undefined') return '';
var style = window.document.documentElement.style;
if (prop in style) return '';
for (var i = 0; i < prefixes.length; i++) {
if (browserPrefixToStyle(prop, prefixes[i]) in style) return prefixes[i];
}
return '';
}
function browserPrefixToKey(prop, prefix) {
return prefix ? '' + prefix + kebabToTitleCase(prop) : prop;
}
function browserPrefixToStyle(prop, prefix) {
return prefix ? '-' + prefix.toLowerCase() + '-' + prop : prop;
}
function kebabToTitleCase(str) {
var out = '';
var shouldCapitalize = true;
for (var i = 0; i < str.length; i++) {
if (shouldCapitalize) {
out += str[i].toUpperCase();
shouldCapitalize = false;
} else if (str[i] === '-') {
shouldCapitalize = true;
} else {
out += str[i];
}
}
return out;
}
// Default export is the prefix itself, like 'Moz', 'Webkit', etc
// Note that you may have to re-test for certain things; for instance, Chrome 50
// can handle unprefixed `transform`, but not unprefixed `user-select`
exports.default = getPrefix();
/***/ },
/* 8 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getBoundPosition = getBoundPosition;
exports.snapToGrid = snapToGrid;
exports.canDragX = canDragX;
exports.canDragY = canDragY;
exports.getControlPosition = getControlPosition;
var _react = __webpack_require__(2);
var _react2 = _interopRequireDefault(_react);
var _shims = __webpack_require__(6);
var _reactDom = __webpack_require__(3);
var _reactDom2 = _interopRequireDefault(_reactDom);
var _domFns = __webpack_require__(5);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function getBoundPosition(draggable, clientX, clientY) {
// If no bounds, short-circuit a