choerodon-ui
Version:
An enterprise-class UI design language and React-based implementation
529 lines (459 loc) • 17.2 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _objectSpread from "@babel/runtime/helpers/objectSpread2";
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _inherits from "@babel/runtime/helpers/inherits";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
function _createSuper(Derived) {
function isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
return true;
} catch (e) {
return false;
}
}
return function () {
var Super = _getPrototypeOf(Derived),
result;
if (isNativeReflectConstruct()) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
};
}
import { __decorate } from "tslib";
import React, { cloneElement, Component, isValidElement } from 'react';
import PropTypes from 'prop-types';
import { action, observable } from 'mobx';
import classNames from 'classnames';
import { observer } from 'mobx-react';
import omit from 'lodash/omit';
import isString from 'lodash/isString';
import debounce from 'lodash/debounce';
import defaultTo from 'lodash/defaultTo';
import classes from 'component-classes';
import { pxToRem } from '../../../es/_util/UnitConvertor';
import ReactResizeObserver from '../../../es/_util/resizeObserver';
import raf from 'raf';
import { minColumnWidth } from './Column';
import TableContext from './TableContext';
import Icon from '../icon';
import EventManager from '../_util/EventManager';
import { getAlignByField, getColumnKey, getColumnLock, getHeader, getPlacementByAlign, isStickySupport } from './utils';
import { ColumnAlign, TableColumnTooltip } from './enum';
import { ShowHelp } from '../field/enum';
import Tooltip from '../tooltip/Tooltip';
import autobind from '../_util/autobind';
var TableHeaderCell =
/*#__PURE__*/
function (_Component) {
_inherits(TableHeaderCell, _Component);
var _super = _createSuper(TableHeaderCell);
function TableHeaderCell() {
var _this;
_classCallCheck(this, TableHeaderCell);
_this = _super.apply(this, arguments);
_this.resizeEvent = new EventManager(typeof window !== 'undefined' && document);
_this.resizeBoundary = 0;
_this.delayResizeStart = debounce(function (e) {
_this.resizeStart(e);
}, 300);
return _this;
}
_createClass(TableHeaderCell, [{
key: "saveElement",
value: function saveElement(element) {
this.element = element;
}
}, {
key: "handleClick",
value: function handleClick() {
var _this$props = this.props,
column = _this$props.column,
dataSet = _this$props.dataSet;
var name = column.name;
if (name) {
dataSet.sort(name);
}
}
}, {
key: "getNode",
value: function getNode(column) {
var getHeaderNode = this.props.getHeaderNode;
var headerDom = getHeaderNode();
if (headerDom) {
return headerDom.querySelector("[data-index=\"".concat(getColumnKey(column), "\"]"));
}
}
}, {
key: "setResizeColumn",
value: function setResizeColumn(column) {
this.resizeColumn = column;
var node = this.getNode(column);
if (node) {
this.resizeBoundary = node.getBoundingClientRect().left;
}
}
}, {
key: "handleLeftResize",
value: function handleLeftResize(e) {
var prevColumn = this.props.prevColumn;
var autoMaxWidth = this.context.tableStore.props.autoMaxWidth;
this.setResizeColumn(prevColumn);
if (autoMaxWidth) {
e.persist();
this.delayResizeStart(e);
} else {
this.resizeStart(e);
}
}
}, {
key: "handleStopResize",
value: function handleStopResize() {
if (this.delayResizeStart) {
this.delayResizeStart.cancel();
}
}
}, {
key: "handleRightResize",
value: function handleRightResize(e) {
var resizeColumn = this.props.resizeColumn;
var autoMaxWidth = this.context.tableStore.props.autoMaxWidth;
this.setResizeColumn(resizeColumn);
if (autoMaxWidth) {
e.persist();
this.delayResizeStart(e);
} else {
this.resizeStart(e);
}
}
}, {
key: "handleLeftDoubleClick",
value: function handleLeftDoubleClick(_e) {
if (this.delayResizeStart) {
this.delayResizeStart.cancel();
this.resizeDoubleClick();
}
}
}, {
key: "handleRightDoubleClick",
value: function handleRightDoubleClick(_e) {
if (this.delayResizeStart) {
this.delayResizeStart.cancel();
this.resizeDoubleClick();
}
}
}, {
key: "resizeDoubleClick",
value: function resizeDoubleClick() {
var column = this.resizeColumn;
var tableStore = this.context.tableStore;
var prefixCls = tableStore.prefixCls,
element = tableStore.node.element;
if (column) {
var maxWidth = Math.max.apply(Math, _toConsumableArray(_toConsumableArray(element.querySelectorAll("td[data-index=".concat(getColumnKey(column), "] > .").concat(prefixCls, "-cell-inner"))).map(function (_ref) {
var clientWidth = _ref.clientWidth,
scrollWidth = _ref.scrollWidth,
offsetWidth = _ref.parentNode.offsetWidth;
return offsetWidth + scrollWidth - clientWidth + 1;
})).concat([minColumnWidth(column), column.width ? column.width : 0]));
if (maxWidth !== column.width) {
tableStore.changeCustomizedColumnValue(column, {
width: maxWidth
});
} else if (column.minWidth) {
tableStore.changeCustomizedColumnValue(column, {
width: column.minWidth
});
}
}
}
}, {
key: "resizeStart",
value: function resizeStart(e) {
var tableStore = this.context.tableStore;
var prefixCls = tableStore.prefixCls,
element = tableStore.node.element;
tableStore.columnResizing = true;
classes(element).add("".concat(prefixCls, "-resizing"));
delete this.resizePosition;
this.setSplitLinePosition(e.pageX);
this.resizeEvent.addEventListener('mousemove', this.resize).addEventListener('mouseup', this.resizeEnd);
}
}, {
key: "resize",
value: function resize(e) {
var column = this.resizeColumn;
var limit = this.resizeBoundary + minColumnWidth(column);
var left = e.pageX;
if (left < limit) {
left = limit;
}
this.resizePosition = this.setSplitLinePosition(left);
}
}, {
key: "resizeEnd",
value: function resizeEnd() {
var tableStore = this.context.tableStore;
var prefixCls = tableStore.prefixCls,
element = tableStore.node.element;
tableStore.columnResizing = false;
classes(element).remove("".concat(prefixCls, "-resizing"));
this.resizeEvent.removeEventListener('mousemove').removeEventListener('mouseup');
var column = this.resizeColumn;
if (this.resizePosition && column) {
var newWidth = Math.round(Math.max(this.resizePosition - this.resizeBoundary, minColumnWidth(column)));
if (newWidth !== column.width) {
tableStore.changeCustomizedColumnValue(column, {
width: newWidth
});
}
}
}
}, {
key: "setSplitLinePosition",
value: function setSplitLinePosition(left) {
var resizeLine = this.context.tableStore.node.resizeLine;
var _resizeLine$offsetPar = resizeLine.offsetParent.getBoundingClientRect(),
rectLeft = _resizeLine$offsetPar.left;
left -= rectLeft;
if (left < 0) {
left = 0;
}
resizeLine.style.left = pxToRem(left) || null;
return left + rectLeft;
}
}, {
key: "renderResizer",
value: function renderResizer() {
var _this$props2 = this.props,
prevColumn = _this$props2.prevColumn,
column = _this$props2.column;
var _this$context$tableSt = this.context.tableStore,
prefixCls = _this$context$tableSt.prefixCls,
autoMaxWidth = _this$context$tableSt.props.autoMaxWidth;
var resizerPrefixCls = "".concat(prefixCls, "-resizer");
var pre = prevColumn && prevColumn.resizable && React.createElement("div", {
key: "pre",
className: "".concat(resizerPrefixCls, " ").concat(resizerPrefixCls, "-left"),
onDoubleClick: autoMaxWidth ? this.handleLeftDoubleClick : undefined,
onMouseDown: this.handleLeftResize,
onMouseUp: autoMaxWidth ? this.handleStopResize : undefined
});
var next = column.resizable && React.createElement("div", {
key: "next",
className: "".concat(resizerPrefixCls, " ").concat(resizerPrefixCls, "-right"),
onDoubleClick: autoMaxWidth ? this.handleRightDoubleClick : undefined,
onMouseDown: this.handleRightResize,
onMouseUp: autoMaxWidth ? this.handleStopResize : undefined
});
return [pre, next];
}
}, {
key: "handleResize",
value: function handleResize() {
var element = this.element;
var tableStore = this.context.tableStore;
if (element && !tableStore.hidden) {
if (this.nextFrameActionId !== undefined) {
raf.cancel(this.nextFrameActionId);
}
this.nextFrameActionId = raf(this.syncSize);
}
}
}, {
key: "syncSize",
value: function syncSize() {
this.overflow = this.computeOverFlow();
}
}, {
key: "computeOverFlow",
value: function computeOverFlow() {
var element = this.element;
if (element && element.textContent) {
var column = this.props.column;
var tableStore = this.context.tableStore;
if (tableStore.getColumnTooltip(column) === TableColumnTooltip.overflow) {
var clientWidth = element.clientWidth,
scrollWidth = element.scrollWidth;
return scrollWidth > clientWidth;
}
}
return false;
}
}, {
key: "getHelpIcon",
value: function getHelpIcon(field) {
var column = this.props.column;
var prefixCls = this.context.tableStore.prefixCls;
var help = column.help,
showHelp = column.showHelp;
if (showHelp !== ShowHelp.none) {
var fieldHelp = defaultTo(field && field.get('help'), help);
if (fieldHelp) {
return React.createElement(Tooltip, {
title: fieldHelp,
placement: "bottom",
key: "help"
}, React.createElement(Icon, {
type: "help_outline",
className: "".concat(prefixCls, "-help-icon")
}));
}
}
}
}, {
key: "getSortIcon",
value: function getSortIcon() {
var column = this.props.column;
var prefixCls = this.context.tableStore.prefixCls;
var sortable = column.sortable,
name = column.name;
if (sortable && name) {
return React.createElement(Icon, {
key: "sort",
type: "arrow_upward",
className: "".concat(prefixCls, "-sort-icon")
});
}
}
}, {
key: "render",
value: function render() {
var _this$props3 = this.props,
column = _this$props3.column,
dataSet = _this$props3.dataSet,
rowSpan = _this$props3.rowSpan,
colSpan = _this$props3.colSpan,
style = _this$props3.style,
className = _this$props3.className;
var tableStore = this.context.tableStore;
var prefixCls = tableStore.prefixCls,
rowHeight = tableStore.rowHeight,
columnResizable = tableStore.columnResizable;
var headerClassName = column.headerClassName,
_column$headerStyle = column.headerStyle,
headerStyle = _column$headerStyle === void 0 ? {} : _column$headerStyle,
name = column.name,
align = column.align,
children = column.children,
command = column.command,
lock = column.lock;
var tooltip = tableStore.getColumnTooltip(column);
var columnKey = getColumnKey(column);
var columnLock = isStickySupport() && tableStore.overflowX && getColumnLock(lock);
var classList = ["".concat(prefixCls, "-cell")];
if (columnLock) {
classList.push("".concat(prefixCls, "-cell-fix-").concat(columnLock));
}
if (className) {
classList.push(className);
}
var field = dataSet.getField(name);
if (headerClassName) {
classList.push(headerClassName);
}
var cellStyle = _objectSpread({
textAlign: align || (command || children && children.length ? ColumnAlign.center : getAlignByField(field))
}, headerStyle, {}, style);
var header = getHeader(column, dataSet);
var headerNode = isValidElement(header) ? cloneElement(header, {
key: 'text'
}) : isString(header) ? React.createElement("span", {
key: "text"
}, header) : header; // 帮助按钮
var helpIcon = this.getHelpIcon(field); // 排序按钮
var sortIcon = this.getSortIcon();
var childNodes = [headerNode];
var innerProps = {
className: classNames("".concat(prefixCls, "-cell-inner")),
children: childNodes,
style: {}
};
if (helpIcon) {
if (cellStyle.textAlign === ColumnAlign.right) {
childNodes.unshift(helpIcon);
} else {
childNodes.push(helpIcon);
}
}
if (sortIcon) {
if (field && field.order) {
classList.push("".concat(prefixCls, "-sort-").concat(field.order));
}
innerProps.onClick = this.handleClick;
if (cellStyle.textAlign === ColumnAlign.right) {
childNodes.unshift(sortIcon);
} else {
childNodes.push(sortIcon);
}
}
if (rowHeight !== 'auto') {
var height = Number(cellStyle.height) || rowHeight * (rowSpan || 1);
innerProps.style = {
height: pxToRem(height),
lineHeight: pxToRem(height - 2)
};
}
if (tooltip === TableColumnTooltip.overflow) {
innerProps.ref = this.saveElement;
}
var thProps = {
className: classList.join(' '),
rowSpan: rowSpan,
colSpan: colSpan,
'data-index': columnKey,
style: omit(cellStyle, ['width', 'height'])
};
var inner = React.createElement("div", _extends({}, innerProps));
var th = React.createElement("th", _extends({}, thProps), this.overflow || tooltip === TableColumnTooltip.always ? React.createElement(Tooltip, {
key: "tooltip",
title: header,
placement: getPlacementByAlign(cellStyle.textAlign)
}, inner) : inner, columnResizable && this.renderResizer());
return tooltip === TableColumnTooltip.overflow ? React.createElement(ReactResizeObserver, {
onResize: this.handleResize,
resizeProp: "width"
}, th) : th;
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
this.resizeEvent.clear();
this.delayResizeStart.cancel();
}
}]);
return TableHeaderCell;
}(Component);
TableHeaderCell.displayName = 'TableHeaderCell';
TableHeaderCell.propTypes = {
column: PropTypes.object.isRequired
};
TableHeaderCell.contextType = TableContext;
__decorate([observable], TableHeaderCell.prototype, "overflow", void 0);
__decorate([autobind], TableHeaderCell.prototype, "saveElement", null);
__decorate([autobind], TableHeaderCell.prototype, "handleClick", null);
__decorate([autobind], TableHeaderCell.prototype, "handleLeftResize", null);
__decorate([autobind], TableHeaderCell.prototype, "handleStopResize", null);
__decorate([autobind], TableHeaderCell.prototype, "handleRightResize", null);
__decorate([autobind], TableHeaderCell.prototype, "handleLeftDoubleClick", null);
__decorate([autobind], TableHeaderCell.prototype, "handleRightDoubleClick", null);
__decorate([autobind, action], TableHeaderCell.prototype, "resizeDoubleClick", null);
__decorate([action], TableHeaderCell.prototype, "resizeStart", null);
__decorate([autobind], TableHeaderCell.prototype, "resize", null);
__decorate([autobind, action], TableHeaderCell.prototype, "resizeEnd", null);
__decorate([action], TableHeaderCell.prototype, "setSplitLinePosition", null);
__decorate([autobind], TableHeaderCell.prototype, "handleResize", null);
__decorate([autobind, action], TableHeaderCell.prototype, "syncSize", null);
TableHeaderCell = __decorate([observer], TableHeaderCell);
export default TableHeaderCell;
//# sourceMappingURL=TableHeaderCell.js.map