shineout
Version:
Shein 前端组件库
353 lines (294 loc) • 13.3 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = void 0;
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireDefault(require("react"));
var _component = require("../component");
var _styles = require("./styles");
var _numbers = require("../utils/numbers");
var _Colgroup = _interopRequireDefault(require("./Colgroup"));
var _Tbody = _interopRequireDefault(require("./Tbody"));
var _Thead = _interopRequireDefault(require("./Thead"));
var _Tfoot = _interopRequireDefault(require("./Tfoot"));
var _shallowEqual = require("../utils/shallowEqual");
var _Sticky = _interopRequireDefault(require("../Sticky"));
var _element = require("../utils/dom/element");
function setScrollLeft(target, scrollLeft) {
if (target && target.scrollLeft !== scrollLeft) target.scrollLeft = scrollLeft;
}
var SimpleTable =
/*#__PURE__*/
function (_PureComponent) {
(0, _inheritsLoose2.default)(SimpleTable, _PureComponent);
function SimpleTable(props) {
var _this;
_this = _PureComponent.call(this, props) || this;
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "bindHeader", void 0);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "bindBody", void 0);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "bindFooter", void 0);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "removeReiszeObserver", void 0);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "body", void 0);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "header", void 0);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "footer", void 0);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "lastColGroup", void 0);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "cyclicCounter", void 0);
_this.state = {
colgroup: undefined,
overHeight: false,
overWidth: false,
resize: false
};
_this.handleSortChange = _this.handleSortChange.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)));
_this.bindHeader = _this.bindElement.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), 'header');
_this.bindBody = _this.bindElement.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), 'body');
_this.bindFooter = _this.bindElement.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), 'footer');
_this.handleScroll = _this.handleScroll.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)));
_this.handleColgroup = _this.handleColgroup.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)));
_this.resetColGroup = _this.resetColGroup.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); // 循环计数器。某些情况[*]下滚动条的出现会导致死循环问题,这里做一个计数器,超过一定次数就不再重置,认定最大 10 次为死循环
// [*] 横向滚动条的出现可能导致竖向滚动条从有到无。此时需要重新计算表头的宽度,否则会出现表头与表格内容不对齐的问题。纵向滚动条消失后,可能导致横向滚动条宽度足够,纵向滚动条再次出现,又导致横向滚动条消失,如此循环。
_this.cyclicCounter = 0;
return _this;
}
var _proto = SimpleTable.prototype;
_proto.componentDidMount = function componentDidMount() {
this.scrollCheck();
};
_proto.componentDidUpdate = function componentDidUpdate(prevProps) {
this.scrollCheck();
var resize = prevProps.data.length === 0 && this.props.data.length; // when resize
if (resize && this.body) this.handleScroll({
currentTarget: this.body
});
var shouldResetColgroup = this.props.dataChangeResize && this.props.data !== prevProps.data;
if (resize || shouldResetColgroup || !(0, _shallowEqual.compareColumns)(prevProps.columns, this.props.columns)) {
// eslint-disable-next-line react/no-did-update-set-state
this.setState({
colgroup: undefined,
resize: true
});
}
};
_proto.componentWillUnmount = function componentWillUnmount() {
if (this.body) this.body.removeEventListener('wheel', this.handleScroll);
if (this.removeReiszeObserver) this.removeReiszeObserver();
};
_proto.bindElement = function bindElement(key, el) {
this[key] = el; // this.body will be undefined on componentDidMount when columns length is 0
if (key === 'body' && el) {
el.addEventListener('wheel', this.handleScroll, {
passive: false
});
this.removeReiszeObserver = (0, _element.addResizeObserver)(el, this.resetColGroup, {
direction: 'x'
});
}
};
_proto.resetColGroup = function resetColGroup() {
this.lastColGroup = this.state.colgroup || this.lastColGroup;
this.setState({
colgroup: undefined,
resize: true
});
};
_proto.scrollCheck = function scrollCheck() {
var _this2 = this;
if (!this.body) return;
if (this.cyclicCounter > 10) {
this.setState({
overHeight: true
});
return;
}
var overHeight = this.body.scrollHeight > this.body.clientHeight;
var overWidth = this.body.scrollWidth > this.body.clientWidth;
if (overWidth !== this.state.overWidth) this.setState({
overWidth: overWidth
});
if (overHeight !== this.state.overHeight) this.setState({
overHeight: overHeight
});
this.cyclicCounter += 1;
setTimeout(function () {
_this2.cyclicCounter = 0;
});
};
_proto.handleSortChange = function handleSortChange(finalOrder, sorter, index, cancelOrder, // 是否是自动触发
manual) {
if (this.body) this.body.scrollTop = 0;
this.props.onSortChange(finalOrder, sorter, index, cancelOrder, manual);
};
_proto.handleColgroup = function handleColgroup(tds) {
var columns = this.props.columns;
var colgroup = [];
var _loop = function _loop(i, count) {
var _tds$i$getBoundingCli = tds[i].getBoundingClientRect(),
width = _tds$i$getBoundingCli.width;
var colSpan = parseInt(tds[i].getAttribute('colspan') || '', 10);
if (colSpan > 1) {
(0, _numbers.split)(width, (0, _numbers.range)(colSpan).map(function (j) {
return columns[i + j].width;
})).forEach(function (w) {
return colgroup.push(w);
});
} else {
colgroup.push(width);
}
};
for (var i = 0, count = tds.length; i < count; i++) {
_loop(i, count);
}
this.setState({
colgroup: colgroup,
resize: false
});
};
_proto.handleScroll = function handleScroll(_ref) {
var currentTarget = _ref.currentTarget;
var scrollLeft = currentTarget.scrollLeft;
setScrollLeft(this.header, scrollLeft);
setScrollLeft(this.body, scrollLeft);
setScrollLeft(this.footer, scrollLeft);
};
_proto.renderHeader = function renderHeader() {
var _this$props = this.props,
columns = _this$props.columns,
width = _this$props.width,
data = _this$props.data,
onResize = _this$props.onResize,
columnResizable = _this$props.columnResizable,
sticky = _this$props.sticky,
bordered = _this$props.bordered;
var _this$state = this.state,
colgroup = _this$state.colgroup,
overHeight = _this$state.overHeight;
var inner = _react.default.createElement("table", {
style: {
width: width
},
className: (0, _styles.tableClass)(bordered && 'table-bordered')
}, _react.default.createElement(_Colgroup.default, {
colgroup: colgroup || this.lastColGroup,
columns: columns,
resizable: columnResizable
}), _react.default.createElement(_Thead.default, (0, _extends2.default)({}, this.props, {
colgroup: colgroup,
onSortChange: this.handleSortChange,
onColChange: onResize
})));
var empty = data.length === 0;
var headerStyle = {};
if (!empty) headerStyle.overflowY = overHeight ? 'scroll' : 'hidden';
var header = _react.default.createElement("div", {
key: "head",
style: headerStyle,
className: (0, _styles.tableClass)('head', 'simple-head', empty && 'empty-head'),
ref: this.bindHeader
}, inner);
if (sticky) {
var stickyProps = Object.assign({
top: 0
}, sticky);
return _react.default.createElement(_Sticky.default, (0, _extends2.default)({}, stickyProps, {
key: "head"
}), header);
}
return header;
};
_proto.renderFooter = function renderFooter() {
var _this$props2 = this.props,
columns = _this$props2.columns,
width = _this$props2.width,
data = _this$props2.data,
columnResizable = _this$props2.columnResizable,
bordered = _this$props2.bordered,
summary = _this$props2.summary;
var _this$state2 = this.state,
colgroup = _this$state2.colgroup,
overHeight = _this$state2.overHeight,
overWidth = _this$state2.overWidth;
if (!(data && data.length)) return null;
if (!(summary && summary.length)) return null;
var inner = _react.default.createElement("table", {
style: {
width: width
},
className: (0, _styles.tableClass)(bordered && 'table-bordered')
}, _react.default.createElement(_Colgroup.default, {
colgroup: colgroup || this.lastColGroup,
columns: columns,
resizable: columnResizable
}), _react.default.createElement(_Tfoot.default, this.props));
var footStyle = {};
footStyle.overflowY = overHeight ? 'scroll' : 'hidden';
var footer = _react.default.createElement("div", {
key: "foot",
style: footStyle,
className: (0, _styles.tableClass)('foot', overWidth && 'foot-scroll-x', 'simple-foot'),
ref: this.bindFooter,
onScroll: this.handleScroll
}, inner);
return footer;
};
_proto.renderBody = function renderBody() {
var _this$props3 = this.props,
columns = _this$props3.columns,
width = _this$props3.width,
fixed = _this$props3.fixed,
columnResizable = _this$props3.columnResizable,
bordered = _this$props3.bordered,
others = (0, _objectWithoutPropertiesLoose2.default)(_this$props3, ["columns", "width", "fixed", "columnResizable", "bordered"]);
var _this$state3 = this.state,
colgroup = _this$state3.colgroup,
resize = _this$state3.resize;
var minWidthSup = columns.find(function (d) {
return d.minWidth;
});
return _react.default.createElement("div", {
key: "body",
className: (0, _styles.tableClass)('simple-body'),
ref: this.bindBody,
onScroll: this.handleScroll
}, _react.default.createElement("table", {
style: {
width: width
},
className: (0, _styles.tableClass)(!colgroup && minWidthSup && 'init', bordered && 'table-bordered')
}, _react.default.createElement(_Colgroup.default, {
colgroup: colgroup,
columns: columns,
resizable: columnResizable
}), _react.default.createElement(_Tbody.default, (0, _extends2.default)({
colgroup: colgroup,
lazy: false,
index: 0,
columns: columns,
onBodyRender: this.handleColgroup,
resize: resize,
bordered: bordered,
columnResizable: columnResizable
}, others))));
};
_proto.render = function render() {
var _this$props4 = this.props,
columns = _this$props4.columns,
width = _this$props4.width,
children = _this$props4.children,
hideHeader = _this$props4.hideHeader,
bordered = _this$props4.bordered;
if (!columns || columns.length === 0) return _react.default.createElement("table", {
style: {
width: width
},
className: (0, _styles.tableClass)(bordered && 'table-bordered')
}, children);
return [hideHeader ? null : this.renderHeader(), this.renderBody(), this.renderFooter(), children];
};
return SimpleTable;
}(_component.PureComponent);
var _default = SimpleTable;
exports.default = _default;