"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

exports.__esModule = true;
exports.GridHeaderCell = void 0;

var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));

var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));

var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));

var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

var _react = _interopRequireDefault(require("react"));

var _reactDom = _interopRequireDefault(require("react-dom"));

var _propTypes = _interopRequireDefault(require("prop-types"));

var _lodash = _interopRequireDefault(require("lodash"));

var _classnames = _interopRequireDefault(require("classnames"));

var _EventBus = _interopRequireDefault(require("../../../utils/EventBus"));

var _LocalStorage = require("../../../data/LocalStorage");

var _GridSorter = require("./GridSorter");

var RESIZE_OVERLAY_ID = 'GridHeaderCellResizeOverlay';
var COLUMNS_KEY = 'columns';
var RESIZE_EVENT = 'GridHeaderCellResize';

var GridHeaderCell =
/*#__PURE__*/
function (_React$Component) {
  (0, _inheritsLoose2.default)(GridHeaderCell, _React$Component);

  function GridHeaderCell() {
    var _this;

    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "state", {
      minWidth: null,
      resizing: null
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleSiblingResize", function (localStoragePrefix) {
      var localStorage = _this.context.localStorage;
      var resizing = _this.state.resizing;

      if (resizing || !localStorage || localStoragePrefix !== localStorage.prefix) {
        return;
      }

      var cell = _this.cellRef || _reactDom.default.findDOMNode(_this.gridSorterRef);

      if (!cell) {
        return;
      }

      var minWidth = _this.props.minWidth;

      if (!minWidth) {
        return;
      }

      var width = cell.clientWidth;

      if (width <= minWidth) {
        if (minWidth !== _this.state.minWidth) {
          _this.setState({
            minWidth: minWidth
          });
        } else {
          // Reset minWidth -> Render -> Re-calculate minWidth
          _this.setState({
            minWidth: null
          }, function () {
            return _this.handleSiblingResize(localStoragePrefix);
          });
        }
      } else if (_this.state.minWidth) {
        _this.setState({
          minWidth: null
        });
      }
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "startResizing", function (event) {
      event.stopPropagation();

      var cell = _this.getParentCell(event.target);

      if (!cell) {
        return;
      }

      var overlay = _this.createResizeOverlay();

      document.body.appendChild(overlay);
      document.addEventListener('mousemove', _this.resize);
      document.addEventListener('mouseup', _this.stopResizing);

      _this.setState({
        minWidth: null,
        resizing: {
          x: event.pageX,
          width: cell.clientWidth,
          startWidth: cell.clientWidth
        }
      });
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "resize", function (event) {
      event.stopPropagation();
      var _this$props = _this.props,
          minWidth = _this$props.minWidth,
          maxWidth = _this$props.maxWidth;
      var resizing = _this.state.resizing;

      if (resizing) {
        var width = resizing.startWidth - resizing.x + event.pageX;

        if (width < minWidth) {
          width = minWidth;
        } else if (width > maxWidth) {
          width = maxWidth;
        }

        if (width !== resizing.width) {
          _this.setState({
            minWidth: null,
            resizing: Object.assign({}, resizing, {
              width: width
            })
          }, _this.notifySiblings);
        }
      }
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "stopResizing", function (event) {
      event.stopPropagation();
      var localStorage = _this.context.localStorage;
      var property = _this.props.property;
      var resizing = _this.state.resizing;

      if (resizing && localStorage && property) {
        var columns = localStorage.getItem(COLUMNS_KEY) || {};
        columns[property] = Object.assign({}, columns[property], {
          width: resizing.width
        });
        localStorage.setItem(COLUMNS_KEY, columns);
      }

      _this.cancelResizing();

      _this.setState({
        resizing: null
      });
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "notifySiblings", function () {
      var localStorage = _this.context.localStorage;

      if (localStorage && localStorage.prefix) {
        _EventBus.default.emit(RESIZE_EVENT, localStorage.prefix);
      }
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "renderChildren", function (ariaDescription, skipContentForSR, ariaDescriptionId, children) {
      return _react.default.createElement("span", null, children && _react.default.createElement("span", {
        "aria-hidden": skipContentForSR
      }, children), ariaDescription && _react.default.createElement("span", {
        className: "sr-only",
        id: ariaDescriptionId
      }, ariaDescription));
    });
    return _this;
  }

  var _proto = GridHeaderCell.prototype;

  _proto.componentDidMount = function componentDidMount() {
    _EventBus.default.on(RESIZE_EVENT, this.handleSiblingResize);
  };

  _proto.componentWillUnmount = function componentWillUnmount() {
    _EventBus.default.off(RESIZE_EVENT, this.handleSiblingResize);

    this.cancelResizing();
  };

  _proto.getResizeColumnWidth = function getResizeColumnWidth() {
    var _this$state = this.state,
        resizing = _this$state.resizing,
        minWidth = _this$state.minWidth;

    if (resizing) {
      return resizing.width;
    }

    if (minWidth) {
      return minWidth;
    }

    var localStorage = this.context.localStorage;
    var property = this.props.property;

    if (localStorage && property) {
      var columns = localStorage.getItem(COLUMNS_KEY);

      if (columns && columns[property]) {
        return columns[property].width;
      }
    }
  };

  _proto.getParentCell = function getParentCell(element) {
    var cell = element;

    while (cell && cell.tagName !== 'TH' && cell.tagName !== 'TD') {
      cell = cell.parentNode;
    }

    return cell;
  };

  _proto.createResizeOverlay = function createResizeOverlay() {
    var container = document.createElement('div');
    var overlay = document.createElement('div');
    container.id = RESIZE_OVERLAY_ID;
    container.className = 'bootstrap-rc';
    overlay.className = 'resizing-overlay resizing-overlay-ew';
    container.appendChild(overlay);
    return container;
  };

  _proto.cancelResizing = function cancelResizing() {
    var overlay = document.getElementById(RESIZE_OVERLAY_ID);

    if (overlay) {
      overlay.parentNode.removeChild(overlay);
    }

    document.removeEventListener('mousemove', this.resize);
    document.removeEventListener('mouseup', this.stopResizing);
  };

  _proto.isResizable = function isResizable() {
    var localStorage = this.context.localStorage;
    var _this$props2 = this.props,
        isResizable = _this$props2.isResizable,
        property = _this$props2.property;
    return !!(localStorage && isResizable && property);
  };

  _proto.renderResizeHandler = function renderResizeHandler() {
    if (this.props.noRightBorder) {
      return null;
    }

    var isResizable = this.isResizable();
    var className = (0, _classnames.default)('resize-handler', {
      active: isResizable
    });
    return _react.default.createElement("span", {
      className: className,
      onMouseDown: isResizable ? this.startResizing : null
    });
  };

  _proto.render = function render() {
    var _this2 = this;

    var _this$props3 = this.props,
        isSortable = _this$props3.isSortable,
        _isResizable = _this$props3.isResizable,
        append = _this$props3.append,
        _minWidth = _this$props3.minWidth,
        maxWidth = _this$props3.maxWidth,
        noRightBorder = _this$props3.noRightBorder,
        ariaDescription = _this$props3.ariaDescription,
        ariaDescriptionId = _this$props3.ariaDescriptionId,
        skipContentForSR = _this$props3.skipContentForSR,
        displayName = _this$props3.displayName,
        className = _this$props3.className,
        style = _this$props3.style,
        children = _this$props3.children,
        props = (0, _objectWithoutPropertiesLoose2.default)(_this$props3, ["isSortable", "isResizable", "append", "minWidth", "maxWidth", "noRightBorder", "ariaDescription", "ariaDescriptionId", "skipContentForSR", "displayName", "className", "style", "children"]);
    var _this$state2 = this.state,
        resizing = _this$state2.resizing,
        minWidth = _this$state2.minWidth;
    var child = this.renderChildren(ariaDescription, skipContentForSR, ariaDescriptionId, children);
    var isResizable = this.isResizable();
    var resizeHandler = this.renderResizeHandler();
    var classNames = (0, _classnames.default)(className, {
      resizable: isResizable,
      resizing: isResizable && resizing
    });
    var styles = style;

    if (isResizable) {
      var width = this.getResizeColumnWidth();

      if (width) {
        styles = Object.assign({}, styles, {
          width: width
        });
      }
    } else if (minWidth) {
      styles = Object.assign({}, styles, {
        width: minWidth
      });
    }

    if (isSortable) {
      return _react.default.createElement(_GridSorter.GridSorter, (0, _extends2.default)({
        ref: function ref(th) {
          return _this2.gridSorterRef = th;
        },
        displayName: displayName || children,
        className: classNames,
        style: styles
      }, props, {
        append: append,
        prepend: resizeHandler
      }), child);
    } else {
      var testAutomationId = props.testAutomationId,
          restProps = (0, _objectWithoutPropertiesLoose2.default)(props, ["testAutomationId"]);

      var tableHeaderProps = _lodash.default.omit(restProps, Object.keys(GridHeaderCell.defaultProps));

      return _react.default.createElement("th", (0, _extends2.default)({
        ref: function ref(cell) {
          return _this2.cellRef = cell;
        },
        "data-test-automation-id": testAutomationId,
        className: classNames,
        style: styles
      }, tableHeaderProps), resizeHandler, append && _react.default.createElement("span", {
        className: "column-header-append"
      }, append), _react.default.createElement("div", {
        className: "text-overflow"
      }, child));
    }
  };

  return GridHeaderCell;
}(_react.default.Component);

exports.GridHeaderCell = GridHeaderCell;
(0, _defineProperty2.default)(GridHeaderCell, "propTypes", Object.assign({}, _GridSorter.GridSorter.propTypes, {
  isSortable: _propTypes.default.bool,
  isResizable: _propTypes.default.bool,
  append: _propTypes.default.node,
  minWidth: _propTypes.default.number,
  maxWidth: _propTypes.default.number,
  ariaDescription: _propTypes.default.string,
  ariaDescriptionId: _propTypes.default.string,
  skipContentForSR: _propTypes.default.bool,
  noRightBorder: _propTypes.default.bool
}));
(0, _defineProperty2.default)(GridHeaderCell, "defaultProps", Object.assign({}, _GridSorter.GridSorter.defaultProps, {
  isSortable: true,
  isResizable: false,
  append: null,
  minWidth: 50,
  maxWidth: 500,
  skipContentForSR: false,
  ariaDescriptionId: null,
  noRightBorder: false
}));
(0, _defineProperty2.default)(GridHeaderCell, "contextTypes", {
  localStorage: _propTypes.default.instanceOf(_LocalStorage.LocalStorage)
});