text: 'use strict';
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  
  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 _classnames = require('classnames');
  
  var _classnames2 = _interopRequireDefault(_classnames);
  
  var _react = require('react');
  
  var _react2 = _interopRequireDefault(_react);
  
  var _propTypes = require('prop-types');
  
  var _propTypes2 = _interopRequireDefault(_propTypes);
  
  var _resizeObserverPolyfill = require('resize-observer-polyfill');
  
  var _resizeObserverPolyfill2 = _interopRequireDefault(_resizeObserverPolyfill);
  
  var _utils = require('./utils');
  
  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; }
  
  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; } /* eslint no-debugger: "warn" */
  
  
  /**
   * Predefined constants
   * @type {Object}
   */
  var constants = {
    orientation: {
      horizontal: {
        dimension: 'width',
        direction: 'left',
        reverseDirection: 'right',
        coordinate: 'x'
      },
      vertical: {
        dimension: 'height',
        direction: 'top',
        reverseDirection: 'bottom',
        coordinate: 'y'
      }
    }
  };
  
  var Slider = function (_Component) {
    _inherits(Slider, _Component);
  
    function Slider(props, context) {
      _classCallCheck(this, Slider);
  
      var _this = _possibleConstructorReturn(this, (Slider.__proto__ || Object.getPrototypeOf(Slider)).call(this, props, context));
  
      _this.handleFormat = function (value) {
        var format = _this.props.format;
  
        return format ? format(value) : value;
      };
  
      _this.handleUpdate = function () {
        if (!_this.slider) {
          // for shallow rendering
          return;
        }
        var orientation = _this.props.orientation;
  
        var dimension = (0, _utils.capitalize)(constants.orientation[orientation].dimension);
        var sliderPos = _this.slider['offset' + dimension];
        var handlePos = _this.handle['offset' + dimension];
  
        _this.setState({
          limit: sliderPos - handlePos,
          grab: handlePos / 2
        });
      };
  
      _this.handleStart = function (e) {
        var onChangeStart = _this.props.onChangeStart;
  
        document.addEventListener('mousemove', _this.handleDrag);
        document.addEventListener('mouseup', _this.handleEnd);
        _this.setState({
          active: true
        }, function () {
          onChangeStart && onChangeStart(e);
        });
      };
  
      _this.handleDrag = function (e) {
        e.stopPropagation();
        var onChange = _this.props.onChange;
        var _e$target = e.target,
            className = _e$target.className,
            classList = _e$target.classList,
            dataset = _e$target.dataset;
  
        if (!onChange || className === 'rangeslider__labels') return;
  
        var value = _this.position(e);
  
        if (classList && classList.contains('rangeslider__label-item') && dataset.value) {
          value = parseFloat(dataset.value);
        }
  
        onChange && onChange(value, e);
      };
  
      _this.handleEnd = function (e) {
        var onChangeComplete = _this.props.onChangeComplete;
  
        _this.setState({
          active: false
        }, function () {
          onChangeComplete && onChangeComplete(e);
        });
        document.removeEventListener('mousemove', _this.handleDrag);
        document.removeEventListener('mouseup', _this.handleEnd);
      };
  
      _this.handleKeyDown = function (e) {
        e.preventDefault();
        var keyCode = e.keyCode;
        var _this$props = _this.props,
            value = _this$props.value,
            min = _this$props.min,
            max = _this$props.max,
            step = _this$props.step,
            onChange = _this$props.onChange;
  
        var sliderValue = void 0;
  
        switch (keyCode) {
          case 38:
          case 39:
            sliderValue = value + step > max ? max : value + step;
            onChange && onChange(sliderValue, e);
            break;
          case 37:
          case 40:
            sliderValue = value - step < min ? min : value - step;
            onChange && onChange(sliderValue, e);
            break;
        }
      };
  
      _this.getPositionFromValue = function (value) {
        var limit = _this.state.limit;
        var _this$props2 = _this.props,
            min = _this$props2.min,
            max = _this$props2.max;
  
        var diffMaxMin = max - min;
        var diffValMin = value - min;
        var percentage = diffValMin / diffMaxMin;
        var pos = Math.round(percentage * limit);
  
        return pos;
      };
  
      _this.getValueFromPosition = function (pos) {
        var limit = _this.state.limit;
        var _this$props3 = _this.props,
            orientation = _this$props3.orientation,
            min = _this$props3.min,
            max = _this$props3.max,
            step = _this$props3.step;
  
        var percentage = (0, _utils.clamp)(pos, 0, limit) / (limit || 1);
        var baseVal = step * Math.round(percentage * (max - min) / step);
        var value = orientation === 'horizontal' ? baseVal + min : max - baseVal;
  
        return (0, _utils.clamp)(value, min, max);
      };
  
      _this.position = function (e) {
        var grab = _this.state.grab;
        var _this$props4 = _this.props,
            orientation = _this$props4.orientation,
            reverse = _this$props4.reverse;
  
  
        var node = _this.slider;
        var coordinateStyle = constants.orientation[orientation].coordinate;
        var directionStyle = reverse ? constants.orientation[orientation].reverseDirection : constants.orientation[orientation].direction;
        var clientCoordinateStyle = 'client' + (0, _utils.capitalize)(coordinateStyle);
        var coordinate = !e.touches ? e[clientCoordinateStyle] : e.touches[0][clientCoordinateStyle];
        var direction = node.getBoundingClientRect()[directionStyle];
        var pos = reverse ? direction - coordinate - grab : coordinate - direction - grab;
        var value = _this.getValueFromPosition(pos);
  
        return value;
      };
  
      _this.coordinates = function (pos) {
        var _this$state = _this.state,
            limit = _this$state.limit,
            grab = _this$state.grab;
        var orientation = _this.props.orientation;
  
        var value = _this.getValueFromPosition(pos);
        var position = _this.getPositionFromValue(value);
        var handlePos = orientation === 'horizontal' ? position + grab : position;
        var fillPos = orientation === 'horizontal' ? handlePos : limit - handlePos;
  
        return {
          fill: fillPos,
          handle: handlePos,
          label: handlePos
        };
      };
  
      _this.renderLabels = function (labels) {
        return _react2.default.createElement(
          'ul',
          {
            ref: function ref(sl) {
              _this.labels = sl;
            },
            className: (0, _classnames2.default)('rangeslider__labels')
          },
          labels
        );
      };
  
      _this.state = {
        active: false,
        limit: 0,
        grab: 0
      };
      return _this;
    }
  
    _createClass(Slider, [{
      key: 'componentDidMount',
      value: function componentDidMount() {
        this.handleUpdate();
        var resizeObserver = new _resizeObserverPolyfill2.default(this.handleUpdate);
        resizeObserver.observe(this.slider);
      }
  
      /**
       * Format label/tooltip value
       * @param  {Number} - value
       * @return {Formatted Number}
       */
  
  
      /**
       * Update slider state on change
       * @return {void}
       */
  
  
      /**
       * Attach event listeners to mousemove/mouseup events
       * @return {void}
       */
  
  
      /**
       * Handle drag/mousemove event
       * @param  {Object} e - Event object
       * @return {void}
       */
  
  
      /**
       * Detach event listeners to mousemove/mouseup events
       * @return {void}
       */
  
  
      /**
       * Support for key events on the slider handle
       * @param  {Object} e - Event object
       * @return {void}
       */
  
  
      /**
       * Calculate position of slider based on its value
       * @param  {number} value - Current value of slider
       * @return {position} pos - Calculated position of slider based on value
       */
  
  
      /**
       * Translate position of slider to slider value
       * @param  {number} pos - Current position/coordinates of slider
       * @return {number} value - Slider value
       */
  
  
      /**
       * Calculate position of slider based on value
       * @param  {Object} e - Event object
       * @return {number} value - Slider value
       */
  
  
      /**
       * Grab coordinates of slider
       * @param  {Object} pos - Position object
       * @return {Object} - Slider fill/handle coordinates
       */
  
    }, {
      key: 'render',
      value: function render() {
        var _this2 = this;
  
        var _props = this.props,
            value = _props.value,
            orientation = _props.orientation,
            className = _props.className,
            tooltip = _props.tooltip,
            reverse = _props.reverse,
            labels = _props.labels,
            min = _props.min,
            max = _props.max,
            handleLabel = _props.handleLabel;
        var active = this.state.active;
  
        var dimension = constants.orientation[orientation].dimension;
        var direction = reverse ? constants.orientation[orientation].reverseDirection : constants.orientation[orientation].direction;
        var position = this.getPositionFromValue(value);
        var coords = this.coordinates(position);
        var fillStyle = _defineProperty({}, dimension, coords.fill + 'px');
        var handleStyle = _defineProperty({}, direction, coords.handle + 'px');
        var showTooltip = tooltip && active;
  
        var labelItems = [];
        var labelKeys = Object.keys(labels);
  
        if (labelKeys.length > 0) {
          labelKeys = labelKeys.sort(function (a, b) {
            return reverse ? a - b : b - a;
          });
  
          var _iteratorNormalCompletion = true;
          var _didIteratorError = false;
          var _iteratorError = undefined;
  
          try {
            for (var _iterator = labelKeys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
              var key = _step.value;
  
              var labelPosition = this.getPositionFromValue(key);
              var labelCoords = this.coordinates(labelPosition);
              var labelStyle = _defineProperty({}, direction, labelCoords.label + 'px');
  
              labelItems.push(_react2.default.createElement(
                'li',
                {
                  key: key,
                  className: (0, _classnames2.default)('rangeslider__label-item'),
                  'data-value': key,
                  onMouseDown: this.handleDrag,
                  onTouchStart: this.handleStart,
                  onTouchEnd: this.handleEnd,
                  style: labelStyle
                },
                this.props.labels[key]
              ));
            }
          } catch (err) {
            _didIteratorError = true;
            _iteratorError = err;
          } finally {
            try {
              if (!_iteratorNormalCompletion && _iterator.return) {
                _iterator.return();
              }
            } finally {
              if (_didIteratorError) {
                throw _iteratorError;
              }
            }
          }
        }
  
        return _react2.default.createElement(
          'div',
          {
            ref: function ref(s) {
              _this2.slider = s;
            },
            className: (0, _classnames2.default)('rangeslider', 'rangeslider-' + orientation, { 'rangeslider-reverse': reverse }, className),
            onMouseDown: this.handleDrag,
            onMouseUp: this.handleEnd,
            onTouchStart: this.handleStart,
            onTouchEnd: this.handleEnd,
            'aria-valuemin': min,
            'aria-valuemax': max,
            'aria-valuenow': value,
            'aria-orientation': orientation,
            style: this.props.backgroundColor ? { background: this.props.backgroundColor } : {}
          },
          _react2.default.createElement('div', { className: 'rangeslider__fill', style: this.props.fillColor ? { background: this.props.fillColor } : fillStyle }),
          _react2.default.createElement(
            'div',
            {
              ref: function ref(sh) {
                _this2.handle = sh;
              },
              className: 'rangeslider__handle',
              onMouseDown: this.handleStart,
              onTouchMove: this.handleDrag,
              onTouchEnd: this.handleEnd,
              onKeyDown: this.handleKeyDown,
              style: handleStyle,
              tabIndex: 0
            },
            showTooltip ? _react2.default.createElement(
              'div',
              {
                ref: function ref(st) {
                  _this2.tooltip = st;
                },
                className: 'rangeslider__handle-tooltip'
              },
              _react2.default.createElement(
                'span',
                null,
                this.handleFormat(value)
              )
            ) : null,
            _react2.default.createElement(
              'div',
              { className: 'rangeslider__handle-label' },
              handleLabel
            )
          ),
          labels ? this.renderLabels(labelItems) : null
        );
      }
    }]);
  
    return Slider;
  }(_react.Component);
  
  Slider.propTypes = {
    min: _propTypes2.default.number,
    max: _propTypes2.default.number,
    step: _propTypes2.default.number,
    value: _propTypes2.default.number,
    orientation: _propTypes2.default.string,
    tooltip: _propTypes2.default.bool,
    reverse: _propTypes2.default.bool,
    labels: _propTypes2.default.object,
    handleLabel: _propTypes2.default.string,
    fillColor: _propTypes2.default.string,
    backgroundColor: _propTypes2.default.string,
    format: _propTypes2.default.func,
    onChangeStart: _propTypes2.default.func,
    onChange: _propTypes2.default.func,
    onChangeComplete: _propTypes2.default.func
  };
  Slider.defaultProps = {
    min: 0,
    max: 100,
    step: 1,
    value: 0,
    orientation: 'horizontal',
    tooltip: true,
    reverse: false,
    labels: {},
    handleLabel: ''
  };
  exports.default = Slider;