"use strict";

exports.__esModule = true;
exports.default = void 0;
var _clamp2 = _interopRequireDefault(require("lodash/fp/clamp"));
var _set2 = _interopRequireDefault(require("lodash/fp/set"));
var _noop2 = _interopRequireDefault(require("lodash/fp/noop"));
var _react = _interopRequireDefault(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _handle = _interopRequireDefault(require("./handle"));
var _style = _interopRequireDefault(require("./style.css"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const valueOnTrack = (track, x) => {
  const {
    left,
    right
  } = track.getBoundingClientRect();
  return (0, _clamp2.default)(0, 1, (x - left) / (right - left));
};
const extractStateFromProps = props => {
  const {
    multi = false,
    value = multi ? [0, 1] : 0
  } = props;
  return {
    multi,
    value: multi ? value : [0, value]
  };
};
const RenderHandles = props => {
  const {
    left,
    right,
    multi = false,
    pending,
    onHandleMinChange,
    onHandleMinChangeEnd,
    onHandleMaxChange,
    onHandleMaxChangeEnd,
    HammerForTestingMin,
    HammerForTestingMax
  } = props;
  return /*#__PURE__*/_react.default.createElement("div", {
    "data-testid": "handles"
  }, multi ? /*#__PURE__*/_react.default.createElement("span", {
    className: pending ? _style.default.handle : _style.default.animatedHandle,
    style: {
      left: `${left * 100}%`
    }
  }, /*#__PURE__*/_react.default.createElement(_handle.default, {
    axis: "x",
    onPan: onHandleMinChange,
    onPanEnd: onHandleMinChangeEnd,
    HammerForTesting: HammerForTestingMin
  })) : null, /*#__PURE__*/_react.default.createElement("span", {
    className: pending ? _style.default.handle : _style.default.animatedHandle,
    style: {
      left: `${right * 100}%`
    }
  }, /*#__PURE__*/_react.default.createElement(_handle.default, {
    axis: "x",
    onPan: onHandleMaxChange,
    onPanEnd: onHandleMaxChangeEnd,
    HammerForTesting: HammerForTestingMax
  })));
};
RenderHandles.propTypes = process.env.NODE_ENV !== "production" ? {
  left: _propTypes.default.number,
  right: _propTypes.default.number,
  multi: _propTypes.default.bool,
  pending: _propTypes.default.bool,
  onHandleMinChange: _propTypes.default.func,
  onHandleMinChangeEnd: _propTypes.default.func,
  onHandleMaxChange: _propTypes.default.func,
  onHandleMaxChangeEnd: _propTypes.default.func,
  HammerForTestingMin: _handle.default.propTypes.HammerForTesting,
  HammerForTestingMax: _handle.default.propTypes.HammerForTesting
} : {};
class Range extends _react.default.Component {
  static getDerivedStateFromProps(props, state) {
    const {
      pending
    } = state;
    if (pending) return null;
    return extractStateFromProps(props);
  }
  constructor(props, context) {
    super(props, context);
    this.state = {
      ...extractStateFromProps(props),
      pending: false
    };
    this.handleClick = this.handleClick.bind(this);
    this.setRefTrack = this.setRefTrack.bind(this);
    this.handleMinChange = this.handleMinChange.bind(this);
    this.handleMaxChange = this.handleMaxChange.bind(this);
    this.handleMinChangeEnd = this.handleMinChangeEnd.bind(this);
    this.handleMaxChangeEnd = this.handleMaxChangeEnd.bind(this);
  }
  setRefTrack(track) {
    this.track = track;
  }
  handleMinChange(e) {
    e.srcEvent.stopPropagation();
    e.srcEvent.preventDefault();
    const newValue = valueOnTrack(this.track, e.center.x);
    return this.handleChange(newValue, 0, true);
  }
  handleMaxChange(e) {
    e.srcEvent.stopPropagation();
    e.srcEvent.preventDefault();
    const newValue = valueOnTrack(this.track, e.center.x);
    return this.handleChange(newValue, 1, true);
  }
  handleMinChangeEnd(e) {
    e.srcEvent.stopPropagation();
    e.srcEvent.preventDefault();
    const newValue = valueOnTrack(this.track, e.center.x);
    return this.handleChange(newValue, 0, false);
  }
  handleMaxChangeEnd(e) {
    e.srcEvent.stopPropagation();
    e.srcEvent.preventDefault();
    const newValue = valueOnTrack(this.track, e.center.x);
    return this.handleChange(newValue, 1, false);
  }
  handleChange(value, valueIndex, pending) {
    const {
      value: prevValue
    } = this.state;
    const newValue = (0, _set2.default)(valueIndex, value, prevValue);
    const [minValue, maxValue] = newValue;
    const nextValue = minValue > maxValue ? prevValue : newValue;
    this.triggerChange(nextValue, pending);
    return this.setState({
      pending,
      value: pending ? nextValue : extractStateFromProps(this.props).value
    });
  }
  triggerChange(newValues, pending) {
    const {
      onChange = _noop2.default,
      onChangeEnd = onChange,
      multi = false
    } = this.props;
    const handle = pending ? onChange : onChangeEnd;
    return handle(multi ? newValues : newValues[1]);
  }
  handleClick(e) {
    e.stopPropagation();
    e.preventDefault();
    const {
      value: [left, right],
      multi
    } = this.state;
    const x = e.clientX;
    const newValue = valueOnTrack(this.track, x);
    if (!multi) return this.handleChange(newValue, 1, false);
    if (left === right) {
      const isClickToTheLeft = left - newValue > 0;
      return this.handleChange(newValue, isClickToTheLeft ? 0 : 1, false);
    }
    const closestHandle = Math.abs(newValue - left) < Math.abs(newValue - right) ? 0 : 1;
    return this.handleChange(newValue, closestHandle, false);
  }
  render() {
    const {
      multi = false,
      value: [left, right],
      pending
    } = this.state;
    const railWidth = right - left;
    const railLeft = left;
    const railStyle = {
      backgroundColor: '#9999A8',
      width: `${railWidth * 100}%`,
      left: `${railLeft * 100}%`
    };
    const {
      HammerForTestingMin,
      HammerForTestingMax
    } = this.props;
    return /*#__PURE__*/_react.default.createElement("div", {
      "data-testid": "slider",
      className: _style.default.containerWrapper,
      onClick: this.handleClick
    }, /*#__PURE__*/_react.default.createElement("div", {
      className: _style.default.container
    }, /*#__PURE__*/_react.default.createElement("div", {
      "data-testid": "track",
      className: _style.default.track,
      "data-name": "sliderTrack",
      ref: this.setRefTrack
    }), /*#__PURE__*/_react.default.createElement("div", {
      className: pending ? _style.default.rail : _style.default.animatedRail,
      style: railStyle
    }), /*#__PURE__*/_react.default.createElement(RenderHandles, {
      HammerForTestingMin: HammerForTestingMin,
      HammerForTestingMax: HammerForTestingMax,
      left: left,
      right: right,
      pending: pending,
      multi: multi,
      onHandleMinChange: this.handleMinChange,
      onHandleMinChangeEnd: this.handleMinChangeEnd,
      onHandleMaxChange: this.handleMaxChange,
      onHandleMaxChangeEnd: this.handleMaxChangeEnd
    })));
  }
}
Range.propTypes = process.env.NODE_ENV !== "production" ? {
  onChange: _propTypes.default.func,
  onChangeEnd: _propTypes.default.func,
  multi: _propTypes.default.bool,
  HammerForTestingMin: RenderHandles.propTypes.HammerForTestingMin,
  HammerForTestingMax: RenderHandles.propTypes.HammerForTestingMax,
  // eslint-disable-next-line react/no-unused-prop-types
  value: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.arrayOf(_propTypes.default.number)])
} : {};
var _default = exports.default = Range;
//# sourceMappingURL=index.js.map