UNPKG

choerodon-ui

Version:

An enterprise-class UI design language and React-based implementation

556 lines (484 loc) 19.5 kB
import _extends from "@babel/runtime/helpers/extends"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _createSuper from "@babel/runtime/helpers/createSuper"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import React, { Component } from 'react'; import debounce from 'lodash/debounce'; import shallowequal from 'shallowequal'; import merge from 'lodash/merge'; import { create, Provider } from 'mini-store'; import classes from 'component-classes'; import warning from '../../_util/warning'; import addEventListener from '../../_util/addEventListener'; import ColumnManager from './ColumnManager'; import HeadTable from './HeadTable'; import BodyTable from './BodyTable'; import FootTable from './FootTable'; import ExpandableTable from './ExpandableTable'; import { TableContextProvider } from './TableContext'; var Table = /*#__PURE__*/function (_Component) { _inherits(Table, _Component); var _super = _createSuper(Table); function Table(props) { var _this; _classCallCheck(this, Table); _this = _super.call(this, props); _defineProperty(_assertThisInitialized(_this), "state", {}); _defineProperty(_assertThisInitialized(_this), "getRowKey", function (record, index) { var rowKey = _this.props.rowKey; var key = typeof rowKey === 'function' ? rowKey(record, index) : record[rowKey]; warning(key !== undefined, 'Each record in table should have a unique `key` prop,' + 'or set `rowKey` to an unique primary key.'); return key === undefined ? index : key; }); _defineProperty(_assertThisInitialized(_this), "handleWindowResize", function () { _this.syncFixedTableRowHeight(); _this.setScrollPositionClassName(); }); _defineProperty(_assertThisInitialized(_this), "syncFixedTableRowHeight", function () { var tableRect = _this.tableNode.getBoundingClientRect(); // If tableNode's height less than 0, suppose it is hidden and don't recalculate rowHeight. if (tableRect.height !== undefined && tableRect.height <= 0) { return; } var prefixCls = _this.props.prefixCls; var headRows = _this.headTable ? _this.headTable.querySelectorAll('thead') : _this.bodyTable.querySelectorAll('thead'); var footRows = _this.footTable ? _this.footTable.querySelectorAll('tfoot') : _this.bodyTable.querySelectorAll('tfoot'); var bodyRows = _this.bodyTable.querySelectorAll(".".concat(prefixCls, "-row")) || []; var fixedColumnsHeadRowsHeight = [].map.call(headRows, function (row) { return row.getBoundingClientRect().height || 'auto'; }); var fixedColumnsFootRowsHeight = [].map.call(footRows, function (row) { return row.getBoundingClientRect().height || 'auto'; }); var state = _this.store.getState(); var fixedColumnsBodyRowsHeight = [].reduce.call(bodyRows, function (acc, row) { var rowKey = row.getAttribute('data-row-key'); var height = row.getBoundingClientRect().height || state.fixedColumnsBodyRowsHeight[rowKey] || 'auto'; acc[rowKey] = height; return acc; }, {}); if (shallowequal(state.fixedColumnsHeadRowsHeight, fixedColumnsHeadRowsHeight) && shallowequal(state.fixedColumnsFootRowsHeight, fixedColumnsFootRowsHeight) && shallowequal(state.fixedColumnsBodyRowsHeight, fixedColumnsBodyRowsHeight)) { return; } _this.store.setState({ fixedColumnsHeadRowsHeight: fixedColumnsHeadRowsHeight, fixedColumnsFootRowsHeight: fixedColumnsFootRowsHeight, fixedColumnsBodyRowsHeight: fixedColumnsBodyRowsHeight }); }); _defineProperty(_assertThisInitialized(_this), "handleBodyScrollLeft", function (e) { if (e.currentTarget !== e.target) { return; } var target = e.target; var _this$props$scroll = _this.props.scroll, scroll = _this$props$scroll === void 0 ? {} : _this$props$scroll; var _assertThisInitialize = _assertThisInitialized(_this), headTable = _assertThisInitialize.headTable, bodyTable = _assertThisInitialize.bodyTable, footTable = _assertThisInitialize.footTable; if (target.scrollLeft !== _this.lastScrollLeft && scroll.x) { if (target === bodyTable) { if (headTable) headTable.scrollLeft = target.scrollLeft; if (footTable) footTable.scrollLeft = target.scrollLeft; } else if (target === headTable) { if (bodyTable) bodyTable.scrollLeft = target.scrollLeft; if (footTable) footTable.scrollLeft = target.scrollLeft; } else if (target === footTable) { if (bodyTable) bodyTable.scrollLeft = target.scrollLeft; if (headTable) headTable.scrollLeft = target.scrollLeft; } _this.setScrollPositionClassName(); } // Remember last scrollLeft for scroll direction detecting. _this.lastScrollLeft = target.scrollLeft; }); _defineProperty(_assertThisInitialized(_this), "handleBodyScrollTop", function (e) { var target = e.target; if (e.currentTarget !== target) { return; } var _this$props$scroll2 = _this.props.scroll, scroll = _this$props$scroll2 === void 0 ? {} : _this$props$scroll2; var _assertThisInitialize2 = _assertThisInitialized(_this), headTable = _assertThisInitialize2.headTable, bodyTable = _assertThisInitialize2.bodyTable, fixedColumnsBodyLeft = _assertThisInitialize2.fixedColumnsBodyLeft, fixedColumnsBodyRight = _assertThisInitialize2.fixedColumnsBodyRight; if (target.scrollTop !== _this.lastScrollTop && scroll.y && target !== headTable) { var scrollTop = target.scrollTop; if (fixedColumnsBodyLeft && target !== fixedColumnsBodyLeft) { fixedColumnsBodyLeft.scrollTop = scrollTop; } if (fixedColumnsBodyRight && target !== fixedColumnsBodyRight) { fixedColumnsBodyRight.scrollTop = scrollTop; } if (bodyTable && target !== bodyTable) { bodyTable.scrollTop = scrollTop; } } // Remember last scrollTop for scroll direction detecting. _this.lastScrollTop = target.scrollTop; }); _defineProperty(_assertThisInitialized(_this), "handleBodyScroll", function (e) { _this.handleBodyScrollLeft(e); _this.handleBodyScrollTop(e); }); _defineProperty(_assertThisInitialized(_this), "handleWheel", function (event) { var _this$props$scroll3 = _this.props.scroll, scroll = _this$props$scroll3 === void 0 ? {} : _this$props$scroll3; if (window.navigator.userAgent.match(/Trident\/7\./) && scroll.y) { event.preventDefault(); var wd = event.deltaY; var target = event.target; var _assertThisInitialize3 = _assertThisInitialized(_this), bodyTable = _assertThisInitialize3.bodyTable, fixedColumnsBodyLeft = _assertThisInitialize3.fixedColumnsBodyLeft, fixedColumnsBodyRight = _assertThisInitialize3.fixedColumnsBodyRight; var scrollTop = 0; if (_this.lastScrollTop) { scrollTop = _this.lastScrollTop + wd; } else { scrollTop = wd; } if (fixedColumnsBodyLeft && target !== fixedColumnsBodyLeft) { fixedColumnsBodyLeft.scrollTop = scrollTop; } if (fixedColumnsBodyRight && target !== fixedColumnsBodyRight) { fixedColumnsBodyRight.scrollTop = scrollTop; } if (bodyTable && target !== bodyTable) { bodyTable.scrollTop = scrollTop; } } }); _defineProperty(_assertThisInitialized(_this), "saveRef", function (name) { return function (node) { _this[name] = node; }; }); ['onRowClick', 'onRowDoubleClick', 'onRowContextMenu', 'onRowMouseEnter', 'onRowMouseLeave'].forEach(function (name) { warning(props[name] === undefined, "".concat(name, " is deprecated, please use onRow instead.")); }); warning(props.getBodyWrapper === undefined, 'getBodyWrapper is deprecated, please use custom components instead.'); _this.columnManager = new ColumnManager(props.columns, props.children); _this.store = create({ currentHoverKey: null, fixedColumnsHeadRowsHeight: [], fixedColumnsFootRowsHeight: [], fixedColumnsBodyRowsHeight: {} }); _this.setScrollPosition('left'); _this.debouncedWindowResize = debounce(_this.handleWindowResize, 150); return _this; } _createClass(Table, [{ key: "getContextValue", value: function getContextValue() { return { props: this.props, columnManager: this.columnManager, saveRef: this.saveRef, components: merge({ table: 'table', header: { wrapper: 'thead', row: 'tr', cell: 'th' }, body: { wrapper: 'tbody', row: 'tr', cell: 'td' }, footer: { wrapper: 'tfoot', row: 'tr', cell: 'td' } }, this.props.components) }; } }, { key: "componentDidMount", value: function componentDidMount() { if (this.columnManager.isAnyColumnsFixed()) { this.handleWindowResize(); this.resizeEvent = addEventListener(window, 'resize', this.debouncedWindowResize); } } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps) { if (this.columnManager.isAnyColumnsFixed()) { this.handleWindowResize(); if (!this.resizeEvent) { this.resizeEvent = addEventListener(window, 'resize', this.debouncedWindowResize); } } // when table changes to empty, reset scrollLeft if (prevProps.data.length > 0 && this.props.data.length === 0 && this.hasScrollX()) { this.resetScrollX(); } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { if (this.resizeEvent) { this.resizeEvent.remove(); } if (this.debouncedWindowResize) { this.debouncedWindowResize.cancel(); } } }, { key: "setScrollPosition", value: function setScrollPosition(position) { this.scrollPosition = position; if (this.tableNode) { var prefixCls = this.props.prefixCls; if (position === 'both') { classes(this.tableNode).remove(new RegExp("^".concat(prefixCls, "-scroll-position-.+$"))).add("".concat(prefixCls, "-scroll-position-left")).add("".concat(prefixCls, "-scroll-position-right")); } else { classes(this.tableNode).remove(new RegExp("^".concat(prefixCls, "-scroll-position-.+$"))).add("".concat(prefixCls, "-scroll-position-").concat(position)); } } } }, { key: "setScrollPositionClassName", value: function setScrollPositionClassName() { var node = this.bodyTable; var scrollToLeft = node.scrollLeft === 0; var scrollToRight = node.scrollLeft + 1 >= node.children[0].getBoundingClientRect().width - node.getBoundingClientRect().width; if (scrollToLeft && scrollToRight) { this.setScrollPosition('both'); } else if (scrollToLeft) { this.setScrollPosition('left'); } else if (scrollToRight) { this.setScrollPosition('right'); } else if (this.scrollPosition !== 'middle') { this.setScrollPosition('middle'); } } }, { key: "resetScrollX", value: function resetScrollX() { if (this.headTable) { this.headTable.scrollLeft = 0; } if (this.bodyTable) { this.bodyTable.scrollLeft = 0; } if (this.footTable) { this.footTable.scrollLeft = 0; } } }, { key: "hasScrollX", value: function hasScrollX() { var _this$props$scroll4 = this.props.scroll, scroll = _this$props$scroll4 === void 0 ? {} : _this$props$scroll4; return 'x' in scroll; } }, { key: "renderMainTable", value: function renderMainTable() { var _this$props = this.props, scroll = _this$props.scroll, prefixCls = _this$props.prefixCls; var isAnyColumnsFixed = this.columnManager.isAnyColumnsFixed(); var scrollable = isAnyColumnsFixed || scroll.x || scroll.y; var table = [this.renderTable({ columns: this.columnManager.groupedColumns(), isAnyColumnsFixed: isAnyColumnsFixed }), this.renderEmptyText(), this.renderFooter()]; return scrollable ? /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-scroll") }, table) : table; } }, { key: "renderLeftFixedTable", value: function renderLeftFixedTable() { var prefixCls = this.props.prefixCls; return /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-fixed-left") }, this.renderTable({ columns: this.columnManager.leftColumns(), fixed: 'left' })); } }, { key: "renderRightFixedTable", value: function renderRightFixedTable() { var prefixCls = this.props.prefixCls; return /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-fixed-right") }, this.renderTable({ columns: this.columnManager.rightColumns(), fixed: 'right' })); } }, { key: "renderTable", value: function renderTable(options) { var columns = options.columns, fixed = options.fixed, isAnyColumnsFixed = options.isAnyColumnsFixed; var _this$props2 = this.props, prefixCls = _this$props2.prefixCls, _this$props2$scroll = _this$props2.scroll, scroll = _this$props2$scroll === void 0 ? {} : _this$props2$scroll, resizable = _this$props2.resizable; var tableClassName = scroll.x || fixed ? "".concat(prefixCls, "-fixed") : ''; var headTable = /*#__PURE__*/React.createElement(HeadTable, { key: "head", columns: columns, fixed: fixed, tableClassName: tableClassName, handleBodyScrollLeft: this.handleBodyScrollLeft, expander: this.expander }); var bodyTable = /*#__PURE__*/React.createElement(BodyTable, { key: "body", columns: columns, fixed: fixed, resizable: resizable, tableClassName: tableClassName, getRowKey: this.getRowKey, handleWheel: this.handleWheel, handleBodyScroll: this.handleBodyScroll, expander: this.expander, isAnyColumnsFixed: isAnyColumnsFixed }); var footTable = /*#__PURE__*/React.createElement(FootTable, { key: "foot", columns: columns, fixed: fixed, tableClassName: tableClassName, handleBodyScrollLeft: this.handleBodyScrollLeft, expander: this.expander }); return [headTable, bodyTable, footTable]; } }, { key: "renderTitle", value: function renderTitle() { var _this$props3 = this.props, title = _this$props3.title, prefixCls = _this$props3.prefixCls; return title ? /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-title"), key: "title" }, title(this.props.data)) : null; } }, { key: "renderFooter", value: function renderFooter() { var _this$props4 = this.props, footer = _this$props4.footer, prefixCls = _this$props4.prefixCls; return footer ? /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-footer"), key: "footer" }, footer(this.props.data)) : null; } }, { key: "renderEmptyText", value: function renderEmptyText() { var _this$props5 = this.props, emptyText = _this$props5.emptyText, prefixCls = _this$props5.prefixCls, data = _this$props5.data; if (data.length) { return null; } var emptyClassName = "".concat(prefixCls, "-placeholder"); return /*#__PURE__*/React.createElement("div", { className: emptyClassName, key: "emptyText" }, typeof emptyText === 'function' ? emptyText() : emptyText); } }, { key: "render", value: function render() { var _this2 = this; var props = this.props; var prefixCls = props.prefixCls; if (this.state.columns) { this.columnManager.reset(props.columns); } else if (this.state.children) { this.columnManager.reset(null, props.children); } var className = props.prefixCls; if (props.className) { className += " ".concat(props.className); } if (props.useFixedHeader || props.scroll && props.scroll.y) { className += " ".concat(prefixCls, "-fixed-header"); } if (this.scrollPosition === 'both') { className += " ".concat(prefixCls, "-scroll-position-left ").concat(prefixCls, "-scroll-position-right"); } else { className += " ".concat(prefixCls, "-scroll-position-").concat(this.scrollPosition); } var hasLeftFixed = this.columnManager.isAnyColumnsLeftFixed(); var hasRightFixed = this.columnManager.isAnyColumnsRightFixed(); return /*#__PURE__*/React.createElement(TableContextProvider, this.getContextValue(), /*#__PURE__*/React.createElement(Provider, { store: this.store }, /*#__PURE__*/React.createElement(ExpandableTable, _extends({}, props, { columnManager: this.columnManager, getRowKey: this.getRowKey }), function (expander) { _this2.expander = expander; return /*#__PURE__*/React.createElement("div", { ref: _this2.saveRef('tableNode'), className: className, style: props.style, id: props.id }, _this2.renderTitle(), /*#__PURE__*/React.createElement("div", { ref: _this2.saveRef('tableContent'), className: "".concat(prefixCls, "-content") }, _this2.renderMainTable(), hasLeftFixed && _this2.renderLeftFixedTable(), hasRightFixed && _this2.renderRightFixedTable())); }))); } }], [{ key: "getDerivedStateFromProps", value: function getDerivedStateFromProps(nextProps, prevState) { if (nextProps.columns && nextProps.columns !== prevState.columns) { return { columns: nextProps.columns, children: null }; } else if (nextProps.children !== prevState.children) { return { columns: null, children: nextProps.children }; } return null; } }]); return Table; }(Component); _defineProperty(Table, "defaultProps", { data: [], useFixedHeader: false, rowKey: 'key', rowClassName: function rowClassName() { return ''; }, onRow: function onRow() {}, onHeaderRow: function onHeaderRow() {}, prefixCls: 'rc-table', bodyStyle: {}, style: {}, showHeader: true, scroll: {}, rowRef: function rowRef() { return null; }, emptyText: function emptyText() { return 'No Data'; } }); export { Table as default }; //# sourceMappingURL=Table.js.map