UNPKG

@auraxy/react-table

Version:

React table

754 lines (681 loc) 24.1 kB
/** * Bundle of @auraxy/react-table * Generated: 2021-01-28 * Version: 2.4.7 * License: MIT * Author: 2611541504@qq.com */ import classNames from 'classnames'; import React, { useMemo, useRef, useCallback, useState, useLayoutEffect, Fragment } from 'react'; import { AutoSizer, Grid } from 'react-virtualized'; import { getRect } from '@livelybone/scroll-get'; import Scrollbar from 'react-perfect-scrollbar'; function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } /** * When the span is equal to 0, the node will not render * */ var ColumnFixType; (function (ColumnFixType) { ColumnFixType["Left"] = "left"; ColumnFixType["Right"] = "right"; })(ColumnFixType || (ColumnFixType = {})); function calcClassName(fn, i) { if (!fn) return ''; if (typeof fn === 'string') return fn; return fn(i); } function defaultSpanCalculator() { return { rowSpan: 1, colSpan: 1 }; } function defaultTd() { return '-'; } // 获取最大高度 function getMaxHeight(column) { var height = 1; if (column.children && column.children instanceof Array) { var heights = column.children.map(getMaxHeight); height += Math.max.apply(Math, _toConsumableArray(heights)); } return height; } // 遍历每个子叶节点 function traverseLeafsNode(columns, cb) { var index = 0; columns.forEach(function (column) { if (!column.children || !(column.children.length > 0)) { cb(column, [], index); index += 1; } else { traverseLeafsNode(column.children, function ($column, $parents) { cb($column, [column].concat(_toConsumableArray($parents)), index); index += 1; }); } }); } function columnsFlat(columns, maxHeight) { var thRows = []; var subColumns = []; var $maxHeight = maxHeight || getMaxHeight({ children: columns }) - 1; traverseLeafsNode(columns, function (column, parents, index) { var paths = [].concat(_toConsumableArray(parents), [column]); var _loop = function _loop(rowIndex) { if (!thRows[rowIndex]) thRows[rowIndex] = []; var thRow = thRows[rowIndex]; if (!paths[rowIndex]) { thRows[paths.length - 1][index].props.rowSpan += 1; } else { var item = thRow.find(function (item) { return item && item._origin === paths[rowIndex]; }); if (!item) { thRow[index] = _objectSpread2(_objectSpread2({}, paths[rowIndex]), {}, { props: _objectSpread2(_objectSpread2({}, paths[rowIndex].props), {}, { colSpan: 1, rowSpan: 1 }), _origin: paths[rowIndex] }); subColumns[index] = thRow[index]; } else { item.props.colSpan += 1; } } }; for (var rowIndex = 0; rowIndex < $maxHeight; rowIndex++) { _loop(rowIndex); } }); return { thRows: thRows.filter(function (thRow) { return thRow.length > 0; }), subColumns: subColumns }; } function useColumns(columns) { return useMemo(function () { var left = []; var normal = []; var right = []; columns.forEach(function (column) { if (column.fix === ColumnFixType.Left) left.push(column);else if (column.fix === ColumnFixType.Right) right.push(column);else normal.push(column); }); return { left: left, right: right, normal: normal }; }, [columns]); } function useScroll() { var leftScroll = useRef(null); var rightScroll = useRef(null); var normalScroll = useRef(null); var onScrollY = useCallback(function (el) { var scrollY = el.scrollTop; console.log('scrollY: ', scrollY); if (leftScroll.current) leftScroll.current.scrollTop = scrollY; if (rightScroll.current) rightScroll.current.scrollTop = scrollY; if (normalScroll.current) normalScroll.current.scrollTop = scrollY; }, []); return { leftScroll: leftScroll, rightScroll: rightScroll, normalScroll: normalScroll, onScrollY: onScrollY }; } function compareRect(target, oldRect) { return target.width === oldRect.width && target.height === oldRect.height; } function useHeadHeight(maxThRowCount) { var leftHead = useRef(null); var rightHead = useRef(null); var normalHead = useRef(null); var _useState = useState({ left: {}, right: {}, normal: {} }), _useState2 = _slicedToArray(_useState, 2), rectInfos = _useState2[0], setRectInfo = _useState2[1]; var maxPxHeight = Math.max.apply(Math, _toConsumableArray(['left', 'right', 'normal'].map(function (k) { return rectInfos[k].height || 0; }))); var calcLastTrHeight = function calcLastTrHeight(headEl) { if (maxPxHeight && headEl) { var childrenLen = headEl.children.length; if (childrenLen !== maxThRowCount) { var $children = _toConsumableArray(headEl.children); $children.pop(); return maxPxHeight - $children.reduce(function (pre, el) { return pre + getRect(el).height; }, 0); } } return NaN; }; useLayoutEffect(function () { var left = leftHead.current ? getRect(leftHead.current) : {}; var right = rightHead.current ? getRect(rightHead.current) : {}; var normal = normalHead.current ? getRect(normalHead.current) : {}; if (!compareRect(left, rectInfos.left) || !compareRect(right, rectInfos.right) || !compareRect(normal, rectInfos.normal)) { setRectInfo({ left: left, right: right, normal: normal }); } }, [rectInfos]); return { leftHead: leftHead, rightHead: rightHead, normalHead: normalHead, rectInfos: rectInfos, maxPxHeight: maxPxHeight, calcLastTrHeight: calcLastTrHeight }; } function renderNode(val) { for (var _len = arguments.length, rest = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { rest[_key - 1] = arguments[_key]; } return typeof val === 'function' ? val.apply(void 0, rest) : val; } var TBody = function TBody(_ref) { var data = _ref.data, rowKey = _ref.rowKey, trClassName = _ref.trClassName, subColumns = _ref.subColumns, spanCalculator = _ref.spanCalculator, _ref$showNoData = _ref.showNoData, showNoData = _ref$showNoData === void 0 ? true : _ref$showNoData, virtualScrollEnable = _ref.virtualScrollEnable, elRef = _ref.elRef, onClick = _ref.onClick, emptyPlaceholder = _ref.emptyPlaceholder, optionsForTd = _ref.optionsForTd, onScroll = _ref.onScroll; if (virtualScrollEnable) { var rowCount = data.length; var columnCount = subColumns.length; return /*#__PURE__*/React.createElement("div", { className: "tbody" }, /*#__PURE__*/React.createElement(AutoSizer, null, function (_ref2) { var width = _ref2.width, height = _ref2.height; return /*#__PURE__*/React.createElement(Grid, { onScroll: onScroll, cellRenderer: function cellRenderer(_ref3) { var rowIndex = _ref3.rowIndex, columnIndex = _ref3.columnIndex, key = _ref3.key, style = _ref3.style; var column = subColumns[columnIndex]; var item = data[rowIndex]; return /*#__PURE__*/React.createElement("div", { key: key, style: style, className: classNames(calcClassName(column.className, columnIndex), calcClassName(trClassName, rowIndex), 'td', "col-".concat(columnIndex)) }, (column.td || defaultTd)(item, rowIndex, optionsForTd, column, virtualScrollEnable)); }, height: height, width: width, columnCount: columnCount, columnWidth: function columnWidth(_ref4) { var index = _ref4.index; return subColumns[index].props.width || 100; }, rowHeight: 32, rowCount: rowCount }); })); } return /*#__PURE__*/React.createElement("tbody", { ref: elRef }, data.length > 0 ? data.map(function (item, i) { return /*#__PURE__*/React.createElement("tr", { className: calcClassName(trClassName, i), key: rowKey ? rowKey(item, i) : i }, subColumns.map(function (column, j) { var spanInfo = spanCalculator(column, i, j); if (spanInfo.rowSpan === 0 || spanInfo.colSpan === 0) { return /*#__PURE__*/React.createElement(Fragment, { key: j }); } return /*#__PURE__*/React.createElement("td", Object.assign({ className: calcClassName(column.className, j), key: j, onClick: onClick && onClick.bind(null, i, j) }, spanInfo), (column.td || defaultTd)(item, i, optionsForTd, column)); })); }) : showNoData && /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", { className: "auraxy-table-no-data", colSpan: subColumns.length }, emptyPlaceholder))); }; var THead = function THead(_ref) { var thRows = _ref.thRows, trClassName = _ref.trClassName, elRef = _ref.elRef, lastTrHeight = _ref.lastTrHeight, optionsForTd = _ref.optionsForTd, onClick = _ref.onClick, virtualScrollEnable = _ref.virtualScrollEnable; if (virtualScrollEnable) { return /*#__PURE__*/React.createElement("div", { className: "thead" }, thRows.map(function (tr, k) { return /*#__PURE__*/React.createElement("div", { className: classNames(calcClassName(trClassName, -1), 'tr'), key: k, style: { width: tr.reduce(function (pre, cur) { return pre + cur.props.width; }, 0) + 'px' } }, tr.map(function (column, i) { return /*#__PURE__*/React.createElement("div", { className: classNames('th', calcClassName(column.className, i)), key: i, style: { flex: "0 0 ".concat(column.props.width + 'px') } }, renderNode(column.th, k - thRows.length, i, optionsForTd, column)); })); })); } return /*#__PURE__*/React.createElement("thead", { ref: elRef }, thRows.map(function (tr, k) { return /*#__PURE__*/React.createElement("tr", { className: calcClassName(trClassName, -1), style: k === thRows.length - 1 && lastTrHeight ? { height: lastTrHeight } : undefined, key: k }, tr.map(function (column, i) { return /*#__PURE__*/React.createElement("th", Object.assign({ className: calcClassName(column.className, i), key: i }, column.props, { onClick: onClick && onClick.bind(null, k - thRows.length, i) }), renderNode(column.th, k - thRows.length, i, optionsForTd, column)); })); })); }; var TableBase = function TableBase(_ref) { var data = _ref.data, columns = _ref.columns, _ref$showHead = _ref.showHead, showHead = _ref$showHead === void 0 ? true : _ref$showHead, virtualScrollEnable = _ref.virtualScrollEnable, onVirtualScroll = _ref.onVirtualScroll, className = _ref.className, trClassName = _ref.trClassName, rowKey = _ref.rowKey, onClick = _ref.onClick, _ref$spanCalculator = _ref.spanCalculator, spanCalculator = _ref$spanCalculator === void 0 ? defaultSpanCalculator : _ref$spanCalculator, emptyPlaceholder = _ref.emptyPlaceholder, optionsForTd = _ref.optionsForTd; var _useMemo = useMemo(function () { return columnsFlat(columns); }, [columns]), thRows = _useMemo.thRows, subColumns = _useMemo.subColumns; if (virtualScrollEnable) { return /*#__PURE__*/React.createElement("div", { className: classNames('auraxy-table virtual-table', className) }, showHead && /*#__PURE__*/React.createElement(THead, { thRows: thRows, virtualScrollEnable: virtualScrollEnable, trClassName: trClassName, onClick: onClick, optionsForTd: optionsForTd }), /*#__PURE__*/React.createElement(TBody, { data: data, subColumns: subColumns, virtualScrollEnable: virtualScrollEnable, trClassName: trClassName, rowKey: rowKey, onClick: onClick, spanCalculator: spanCalculator, emptyPlaceholder: emptyPlaceholder || '暂无数据', optionsForTd: optionsForTd, onScroll: onVirtualScroll })); } return /*#__PURE__*/React.createElement("table", { className: classNames('auraxy-table', className) }, showHead && /*#__PURE__*/React.createElement(THead, { thRows: thRows, trClassName: trClassName, onClick: onClick, optionsForTd: optionsForTd }), /*#__PURE__*/React.createElement(TBody, { data: data, subColumns: subColumns, virtualScrollEnable: virtualScrollEnable, trClassName: trClassName, rowKey: rowKey, onClick: onClick, spanCalculator: spanCalculator, emptyPlaceholder: emptyPlaceholder || '暂无数据', optionsForTd: optionsForTd })); }; var TableExtend = function TableExtend(props) { var data = props.data, columns = props.columns, _props$showHead = props.showHead, showHead = _props$showHead === void 0 ? true : _props$showHead, virtualScrollEnable = props.virtualScrollEnable, className = props.className, trClassName = props.trClassName, rowKey = props.rowKey, onClick = props.onClick, _props$spanCalculator = props.spanCalculator, spanCalculator = _props$spanCalculator === void 0 ? defaultSpanCalculator : _props$spanCalculator, _props$scrollBarProps = props.scrollBarProps, scrollBarProps = _props$scrollBarProps === void 0 ? {} : _props$scrollBarProps, emptyPlaceholder = props.emptyPlaceholder, optionsForTd = props.optionsForTd; var _useColumns = useColumns(columns), left = _useColumns.left, right = _useColumns.right, normal = _useColumns.normal; var maxHeadHeight = useMemo(function () { return getMaxHeight({ children: columns }) - 1; }, [columns]); var _useMemo = useMemo(function () { return columnsFlat(left, maxHeadHeight); }, [left, maxHeadHeight]), lThRows = _useMemo.thRows, lSubColumns = _useMemo.subColumns; var _useMemo2 = useMemo(function () { return columnsFlat(right, maxHeadHeight); }, [right, maxHeadHeight]), rThRows = _useMemo2.thRows, rSubColumns = _useMemo2.subColumns; var _useMemo3 = useMemo(function () { return columnsFlat(normal, maxHeadHeight); }, [normal, maxHeadHeight]), thRows = _useMemo3.thRows, subColumns = _useMemo3.subColumns; var _useHeadHeight = useHeadHeight(maxHeadHeight), leftHead = _useHeadHeight.leftHead, rightHead = _useHeadHeight.rightHead, normalHead = _useHeadHeight.normalHead, rectInfos = _useHeadHeight.rectInfos, calcLastTrHeight = _useHeadHeight.calcLastTrHeight; var _useScroll = useScroll(), leftScroll = _useScroll.leftScroll, rightScroll = _useScroll.rightScroll, normalScroll = _useScroll.normalScroll, onScrollY = _useScroll.onScrollY; var headScroll = useRef(); var _useState = useState(false), _useState2 = _slicedToArray(_useState, 2), reachLeft = _useState2[0], setReachLeft = _useState2[1]; var _useState3 = useState(false), _useState4 = _slicedToArray(_useState3, 2), reachRight = _useState4[0], setReachRight = _useState4[1]; var onScrollX = function onScrollX(el) { var scrollX = el.scrollLeft; if (headScroll.current) headScroll.current.scrollLeft = scrollX; if (normalScroll.current) normalScroll.current.scrollLeft = scrollX; if (scrollX) { setReachLeft(false); setReachRight(false); } }; if (virtualScrollEnable) { return /*#__PURE__*/React.createElement(TableBase, props); } return /*#__PURE__*/React.createElement("div", { className: classNames('auraxy-table-wrapper', className, { 'has-fixed-right': rSubColumns.length > 0, 'has-fixed-left': lSubColumns.length > 0 }), style: { width: "calc(".concat(rectInfos.left.width, "px + ").concat(rectInfos.right.width, "px + ").concat(scrollBarProps.maxWidth, ")") } }, showHead && /*#__PURE__*/React.createElement(Scrollbar, { className: "auraxy-table-fixed-head-scroll-wrapper", style: { marginLeft: "".concat(rectInfos.left.width, "px"), marginRight: "".concat(rectInfos.right.width, "px"), maxWidth: scrollBarProps.maxWidth }, containerRef: function containerRef(ref) { return headScroll.current = ref; }, onScrollX: onScrollX, onXReachStart: function onXReachStart() { return setTimeout(function () { return setReachLeft(true); }); }, onXReachEnd: function onXReachEnd() { return setTimeout(function () { return setReachRight(true); }); } }, /*#__PURE__*/React.createElement("table", { className: "auraxy-table-fixed-head", style: { minWidth: '100%', width: normalScroll.current && "".concat(normalScroll.current.scrollWidth, "px") } }, /*#__PURE__*/React.createElement(THead, { elRef: normalHead, thRows: thRows, trClassName: trClassName, onClick: onClick, lastTrHeight: calcLastTrHeight(normalHead.current), optionsForTd: optionsForTd }))), /*#__PURE__*/React.createElement(Scrollbar, Object.assign({}, scrollBarProps, { className: classNames(scrollBarProps.className, { 'hide-scrollbar': rSubColumns.length > 0 }), containerRef: function containerRef(ref) { return normalScroll.current = ref; }, onScrollY: onScrollY, onScrollX: onScrollX, style: _objectSpread2(_objectSpread2({}, scrollBarProps.style), {}, { marginLeft: "".concat(rectInfos.left.width, "px"), marginRight: "".concat(rectInfos.right.width, "px"), maxHeight: scrollBarProps.maxHeight, maxWidth: scrollBarProps.maxWidth }) }), /*#__PURE__*/React.createElement("table", { className: "auraxy-table-content", style: { minWidth: '100%' } }, /*#__PURE__*/React.createElement(TBody, { data: data, subColumns: subColumns, trClassName: trClassName, rowKey: rowKey, onClick: onClick, spanCalculator: spanCalculator, emptyPlaceholder: emptyPlaceholder || '暂无数据', optionsForTd: optionsForTd }))), lSubColumns.length > 0 && /*#__PURE__*/React.createElement("div", { className: classNames('auraxy-table-fixed-left', { 'left-shadow': !reachLeft }) }, showHead && /*#__PURE__*/React.createElement("table", { className: "auraxy-table-fixed-head" }, /*#__PURE__*/React.createElement(THead, { elRef: leftHead, thRows: lThRows, trClassName: trClassName, onClick: onClick, lastTrHeight: calcLastTrHeight(leftHead.current), optionsForTd: optionsForTd })), /*#__PURE__*/React.createElement(Scrollbar, Object.assign({}, scrollBarProps, { containerRef: function containerRef(ref) { return leftScroll.current = ref; }, onScrollY: onScrollY, style: _objectSpread2(_objectSpread2({}, scrollBarProps.style), {}, { maxHeight: scrollBarProps.maxHeight }) }), /*#__PURE__*/React.createElement("table", { className: "auraxy-table-left-content" }, /*#__PURE__*/React.createElement(TBody, { data: data, subColumns: lSubColumns, trClassName: trClassName, rowKey: rowKey, onClick: onClick, spanCalculator: spanCalculator, optionsForTd: optionsForTd })))), rSubColumns.length > 0 && /*#__PURE__*/React.createElement("div", { className: classNames('auraxy-table-fixed-right', { 'right-shadow': !reachRight }) }, showHead && /*#__PURE__*/React.createElement("table", { className: "auraxy-table-fixed-head" }, /*#__PURE__*/React.createElement(THead, { elRef: rightHead, thRows: rThRows, trClassName: trClassName, onClick: onClick, lastTrHeight: calcLastTrHeight(rightHead.current), optionsForTd: optionsForTd })), /*#__PURE__*/React.createElement(Scrollbar, Object.assign({}, scrollBarProps, { containerRef: function containerRef(ref) { return rightScroll.current = ref; }, onScrollY: onScrollY, style: _objectSpread2(_objectSpread2({}, scrollBarProps.style), {}, { maxHeight: scrollBarProps.maxHeight }) }), /*#__PURE__*/React.createElement("table", { className: "auraxy-table-right-content" }, /*#__PURE__*/React.createElement(TBody, { data: data, subColumns: rSubColumns, trClassName: trClassName, rowKey: rowKey, onClick: onClick, spanCalculator: spanCalculator, optionsForTd: optionsForTd }))))); }; export { ColumnFixType, TableBase, TableExtend };