@auraxy/react-table
Version:
React table
754 lines (681 loc) • 24.1 kB
JavaScript
/**
* 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 };