choerodon-ui
Version:
An enterprise-class UI design language and React-based implementation
659 lines (558 loc) • 23.5 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _extends from "@babel/runtime/helpers/extends";
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
import _objectSpread from "@babel/runtime/helpers/objectSpread2";
import _regeneratorRuntime from "@babel/runtime/regenerator";
import React, { cloneElement, isValidElement, useCallback, useContext, useEffect, useRef } from 'react';
import { observer } from 'mobx-react-lite';
import { action, get, remove, set } from 'mobx';
import classNames from 'classnames';
import defer from 'lodash/defer';
import { Size } from '../../../es/_util/enum';
import { pxToRem } from '../../../es/_util/UnitConvertor';
import measureScrollbar from '../../../es/_util/measureScrollbar';
import TableCell from './TableCell';
import TableVirtualCell from './TableVirtualCell';
import TableContext from './TableContext';
import ExpandIcon from './ExpandIcon';
import { ColumnLock, DragColumnAlign, HighLightRowType, SelectionMode } from './enum';
import { findCell, getColumnKey, getColumnLock, isDisabledRow, isSelectedRow, isStickySupport } from './utils';
import { CUSTOMIZED_KEY, DRAG_KEY, EXPAND_KEY } from './TableStore';
import { RecordStatus } from '../data-set/enum';
import ResizeObservedRow from './ResizeObservedRow';
import Spin from '../spin';
import useComputed from '../use-computed';
import { iteratorSome } from '../_util/iteratorUtils';
function getGroupByPath(group, groupPath) {
var subGroups = group.subGroups;
if (groupPath.length) {
var path = groupPath.shift();
if (path && subGroups.length) {
var subGroup = subGroups.find(function (sub) {
return sub.value === path[0].value;
});
if (subGroup) {
return getGroupByPath(subGroup, groupPath);
}
return undefined;
}
}
return group;
}
function getRecord(columnGroup, groupPath, index, record) {
if (index !== undefined && groupPath) {
var headerGroup = columnGroup.headerGroup;
if (headerGroup) {
var group = getGroupByPath(headerGroup, groupPath.slice());
if (group) {
return group.totalRecords[index];
}
return undefined;
}
}
return record;
}
var VIRTUAL_HEIGHT = '__VIRTUAL_HEIGHT__';
var TableRow = function TableRow(props) {
var _classNames;
var record = props.record,
hidden = props.hidden,
index = props.index,
virtualIndex = props.virtualIndex,
headerGroupIndex = props.headerGroupIndex,
provided = props.provided,
snapshot = props.snapshot,
isDragDisabled = props.isDragDisabled,
className = props.className,
lock = props.lock,
columnGroups = props.columnGroups,
children = props.children,
groupPath = props.groupPath,
expandIconColumnIndex = props.expandIconColumnIndex,
metaData = props.metaData,
propStyle = props.style,
intersectionRef = props.intersectionRef,
_props$inView = props.inView,
inView = _props$inView === void 0 ? true : _props$inView,
virtualHeight = props.virtualHeight,
isFixedRowHeight = props.isFixedRowHeight,
_props$columnsInView = props.columnsInView,
columnsInView = _props$columnsInView === void 0 ? true : _props$columnsInView;
var context = useContext(TableContext);
var tableStore = context.tableStore,
prefixCls = context.prefixCls,
dataSet = context.dataSet,
selectionMode = context.selectionMode,
onRow = context.onRow,
rowRenderer = context.rowRenderer,
parityRow = context.parityRow,
expandIconAsCell = context.expandIconAsCell,
expandedRowRenderer = context.expandedRowRenderer,
isTree = context.isTree,
canTreeLoadData = context.canTreeLoadData,
fullColumnWidth = context.fullColumnWidth,
expandRowByClick = context.expandRowByClick;
var highLightRow = tableStore.highLightRow,
selectedHighLightRow = tableStore.selectedHighLightRow,
mouseBatchChooseState = tableStore.mouseBatchChooseState,
dragColumnAlign = tableStore.dragColumnAlign,
rowDraggable = tableStore.rowDraggable,
showRemovedRow = tableStore.showRemovedRow,
node = tableStore.node,
propVirtual = tableStore.propVirtual,
isRenderRange = tableStore.isRenderRange,
blankVirtualCell = tableStore.blankVirtualCell,
_tableStore$virtualCo = tableStore.virtualColumnRange,
left = _tableStore$virtualCo.left,
center = _tableStore$virtualCo.center,
right = _tableStore$virtualCo.right;
var id = record.id,
rowKey = record.key;
var mounted = useRef(false);
var dragRef = useRef(false);
var needIntersection = intersectionRef;
var disabled = isDisabledRow(record);
var rowRef = useRef(null);
var childrenRenderedRef = useRef();
var needSaveRowHeight = isStickySupport() ? !isFixedRowHeight || propVirtual || needIntersection : !lock && (!isFixedRowHeight || iteratorSome(dataSet.fields.values(), function (field) {
return field.get('multiLine', record);
}));
var rowExternalProps = useComputed(function () {
return _objectSpread(_objectSpread({}, typeof rowRenderer === 'function' ? rowRenderer(record, index) : {}), typeof onRow === 'function' ? onRow({
dataSet: dataSet,
record: record,
expandedRow: false,
index: index
}) : {});
}, [record, dataSet, index, onRow, rowRenderer]);
var isLoading = tableStore.isRowPending(record);
var isLoaded = tableStore.isRowLoaded(record);
var isExpanded = tableStore.isRowExpanded(record);
var isHover = tableStore.isRowHover(record);
var expandable = function () {
var isLeaf = rowExternalProps.isLeaf;
if (isLeaf === true) {
return false;
}
return !!expandedRowRenderer || isTree && (!!record.children || canTreeLoadData && !isLoaded);
}();
var setRowHeight = useCallback(action(function (key, height, target) {
// TODO: TABLE 行内编辑并且拖拽操作兼容火狐浏览器的适配
if (inView && columnsInView && height && target.offsetParent && navigator.userAgent.indexOf("Firefox") < 0) {
if (metaData) {
if (metaData.actualHeight !== height) {
tableStore.batchSetRowHeight(key, function () {
return metaData.setHeight(height);
});
}
} else if (needIntersection) {
if (record.getState(VIRTUAL_HEIGHT) !== height) {
record.setState(VIRTUAL_HEIGHT, height);
}
}
if (!isStickySupport()) {
if (get(tableStore.lockColumnsBodyRowsHeight, key) !== height) {
set(tableStore.lockColumnsBodyRowsHeight, key, height);
}
}
tableStore.alignEditor();
}
}), [tableStore, metaData, inView, columnsInView, needIntersection, record]);
var saveRef = useCallback(action(function (row) {
rowRef.current = row;
if (needSaveRowHeight) {
if (row) {
setRowHeight(rowKey, row.offsetHeight, row);
} else if (!isStickySupport() && get(tableStore.lockColumnsBodyRowsHeight, rowKey)) {
remove(tableStore.lockColumnsBodyRowsHeight, rowKey);
}
}
if (provided) {
provided.innerRef(row);
}
if (needIntersection && typeof intersectionRef === 'function') {
intersectionRef(row);
}
}), [rowRef, intersectionRef, needIntersection, needSaveRowHeight, rowKey, provided, setRowHeight]);
var handleMouseEnter = useCallback(function () {
if (highLightRow) {
tableStore.setRowHover(record, true);
}
}, [highLightRow, tableStore, record]);
var handleMouseLeave = useCallback(function () {
if (highLightRow) {
tableStore.setRowHover(record, false);
}
}, [highLightRow, tableStore, record]);
var handleSelection = useCallback(function () {
dataSet[record.isSelected ? 'unSelect' : 'select'](record);
}, [record, dataSet]);
var handleExpandChange = useCallback(function () {
if (expandable) {
tableStore.setRowExpanded(record, !isExpanded);
}
}, [tableStore, record, expandable, isExpanded]);
var handleClick = useCallback(action(function (e) {
if (expandRowByClick) {
handleExpandChange();
}
var onClick = rowExternalProps.onClick;
if (highLightRow === HighLightRowType.click && !tableStore.rowClicked) {
tableStore.rowClicked = true;
}
if (typeof onClick === 'function') {
return onClick(e);
}
}), [tableStore, rowExternalProps, expandRowByClick, handleExpandChange]);
var handleSelectionByClick = useCallback( /*#__PURE__*/function () {
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(e) {
return _regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return handleClick(e);
case 2:
_context.t0 = _context.sent;
if (!(_context.t0 !== false)) {
_context.next = 5;
break;
}
handleSelection();
case 5:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return function (_x) {
return _ref.apply(this, arguments);
};
}(), [handleClick, handleSelection]);
var handleSelectionByMouseDown = useCallback(function (e) {
handleSelection();
var onMouseDown = rowExternalProps.onMouseDown;
if (typeof onMouseDown === 'function') {
onMouseDown(e);
}
}, [handleSelection, rowExternalProps]);
var handleSelectionByDblClick = useCallback(function (e) {
handleSelection();
var onDoubleClick = rowExternalProps.onDoubleClick;
if (typeof onDoubleClick === 'function') {
onDoubleClick(e);
}
}, [handleSelection, rowExternalProps]);
var focusRow = useCallback(function () {
var current = rowRef.current;
if (current) {
if (!lock && !tableStore.editing) {
var element = node.element;
var _document = document,
activeElement = _document.activeElement;
if (element && element.contains(activeElement) && (isStickySupport() ? !current.contains(activeElement) : Array.from(element.querySelectorAll("tr[data-index=\"".concat(record.id, "\"]"))).every(function (tr) {
return !tr.contains(activeElement);
}))) {
current.focus();
} // table 包含目前被focus的element
// 找到当前组件对应record生成的组件对象 然后遍历 每个 tr里面不是focus的目标那么这个函数触发row.focus
}
if (tableStore.overflowY) {
var offsetParent = current.offsetParent;
if (offsetParent) {
var tableBodyWrap = offsetParent.parentNode;
if (tableBodyWrap) {
var offsetTop = current.offsetTop,
offsetHeight = current.offsetHeight;
var scrollTop = tableBodyWrap.scrollTop,
_height = tableBodyWrap.offsetHeight;
var bottomSide = offsetTop + offsetHeight - _height + measureScrollbar();
var st = scrollTop;
if (st < bottomSide) {
st = bottomSide;
}
if (st > offsetTop) {
st = offsetTop + 1;
}
if (st !== scrollTop) {
tableBodyWrap.scrollTop = st; // node.handleBodyScrollTop({
// target: tableBodyWrap,
// currentTarget: tableBodyWrap,
// });
}
}
}
}
}
}, [rowRef, tableStore, lock, node]); // componentDidMount
useEffect(function () {
mounted.current = true;
if (record.status === RecordStatus.add && tableStore.autoFocus) {
var editor = tableStore.editors.values().next().value;
if (editor && (isStickySupport() || getColumnLock(editor.props.column.lock) === getColumnLock(lock))) {
var cell = findCell(tableStore, getColumnKey(editor.props.column), lock);
if (cell) {
defer(function () {
return cell.focus();
});
}
}
} // componentWillUnmount
return action(function () {
mounted.current = false;
/**
* Fixed the when row resize has scrollbar the expanded row would be collapsed
*/
if (!tableStore.isRowExpanded(record)) {
tableStore.setRowExpanded(record, false, true);
}
if (!isStickySupport()) {
remove(tableStore.lockColumnsBodyRowsHeight, rowKey);
}
});
}, []);
useEffect(function () {
if (!isLoading && expandable && isExpanded && !isLoaded && tableStore.canTreeLoadData && !record.children) {
tableStore.onTreeNodeLoad({
record: record
});
}
}, [isLoading, expandable, isExpanded, isLoaded, tableStore, record]); // 行内编辑模式,某一行在编辑状态,在它上方的行展开或者折叠行时,重新渲染编辑器位置
useEffect(function () {
var inlineEdit = tableStore.inlineEdit,
currentEditRecord = tableStore.currentEditRecord,
editors = tableStore.editors;
if (inlineEdit && currentEditRecord && currentEditRecord.index > record.index && editors.size) {
tableStore.editors.forEach(function (editor) {
editor.alignEditor();
});
}
}, [tableStore, record, record.isExpanded]);
var renderExpandRow = function renderExpandRow() {
if (expandable && (isExpanded || childrenRenderedRef.current)) {
var expandRows = [];
childrenRenderedRef.current = true;
if (expandedRowRenderer) {
var expandRowExternalProps = typeof onRow === 'function' ? onRow({
dataSet: dataSet,
record: record,
expandedRow: true,
index: index
}) : {};
var _classString = classNames("".concat(prefixCls, "-expanded-row"), expandRowExternalProps.className);
var _rowProps = {
key: "".concat(rowKey, "-expanded-row"),
className: _classString,
style: _objectSpread({}, expandRowExternalProps.style)
};
if (!isStickySupport() && (tableStore.overflowX || !record.isCurrent)) {
_rowProps.onMouseEnter = handleMouseEnter;
_rowProps.onMouseLeave = handleMouseLeave;
}
if (!isExpanded) {
_rowProps.hidden = true;
}
var _Element = isExpanded || !parityRow ? 'tr' : 'div';
var hasExpandTd = expandIconAsCell && !tableStore.expandIconColumnIndex;
expandRows.push( /*#__PURE__*/React.createElement(_Element, _extends({}, expandRowExternalProps, _rowProps), hasExpandTd && /*#__PURE__*/React.createElement("td", {
className: "".concat(prefixCls, "-cell"),
key: EXPAND_KEY
}), /*#__PURE__*/React.createElement("td", {
key: "".concat(EXPAND_KEY, "-rest"),
className: "".concat(prefixCls, "-cell"),
colSpan: columnGroups.leafs.length - (hasExpandTd ? 1 : 0)
}, /*#__PURE__*/React.createElement("div", {
className: "".concat(prefixCls, "-cell-inner")
}, expandedRowRenderer({
dataSet: dataSet,
record: record
})))));
}
if ( /*#__PURE__*/isValidElement(children)) {
expandRows.push( /*#__PURE__*/cloneElement(children, {
parentExpanded: isExpanded,
key: "".concat(rowKey, "-expanded-rows")
}));
}
return expandRows;
}
return [];
};
var renderExpandIcon = function renderExpandIcon() {
var expandIcon = tableStore.expandIcon;
if (typeof expandIcon === 'function') {
return expandIcon({
prefixCls: prefixCls,
expanded: isExpanded,
expandable: expandable,
needIndentSpaced: !expandable,
record: record,
onExpand: handleExpandChange
});
}
if (tableStore.isRowPending(record)) {
return /*#__PURE__*/React.createElement(Spin, {
size: Size.small
});
}
return /*#__PURE__*/React.createElement(ExpandIcon, {
prefixCls: prefixCls,
expandable: expandable,
onChange: handleExpandChange,
expanded: isExpanded
});
};
var hasExpandIcon = function hasExpandIcon(columnIndex) {
return expandIconColumnIndex !== undefined && expandIconColumnIndex > -1 && columnIndex + expandIconColumnIndex === tableStore.expandIconColumnIndex;
};
var getCell = function getCell(columnGroup, columnIndex, rest) {
var actualRecord = getRecord(columnGroup, groupPath, headerGroupIndex, record);
var cellProps = {
columnGroup: columnGroup,
record: actualRecord,
isDragging: snapshot ? snapshot.isDragging : false,
isFixedRowHeight: isFixedRowHeight,
provided: rest.key === DRAG_KEY ? provided : undefined,
groupPath: groupPath,
rowIndex: virtualIndex === undefined ? index : virtualIndex,
children: hasExpandIcon(columnIndex) ? renderExpandIcon() : undefined,
isDragDisabled: isDragDisabled,
isRenderCell: isRenderRange(columnIndex)
};
if (!isFixedRowHeight && propVirtual && !hidden) {
return [/*#__PURE__*/React.createElement(TableVirtualCell, _extends({}, cellProps, rest, {
key: rest.key
})), actualRecord];
}
return [/*#__PURE__*/React.createElement(TableCell, _extends({}, cellProps, rest, {
inView: inView,
key: rest.key
})), actualRecord];
};
var _ref2 = function () {
var customizable = tableStore.customizable,
customizedBtn = tableStore.customizedBtn;
var leafs = columnGroups.leafs;
var sliceLeafs = !propVirtual ? leafs : (left ? leafs.slice.apply(leafs, _toConsumableArray(left)) : []).concat(leafs.slice.apply(leafs, _toConsumableArray(center))).concat(right ? leafs.slice.apply(leafs, _toConsumableArray(right)) : []);
var columnLength = sliceLeafs.length;
var hasBlankCell = leafs.length > sliceLeafs.length;
return sliceLeafs.reduce(function (result, columnGroup, columnIndex) {
var key = columnGroup.key;
var colIndex = propVirtual && hasBlankCell ? leafs.findIndex(function (x) {
return x.key === key;
}) : columnIndex;
if (key !== CUSTOMIZED_KEY) {
var colSpan = customizable && !customizedBtn && lock !== ColumnLock.left && (!rowDraggable || dragColumnAlign !== DragColumnAlign.right) && columnIndex === columnLength - 2 ? 2 : 1;
var rest = {
key: key,
disabled: disabled
};
if (colSpan > 1) {
rest.colSpan = colSpan;
}
var _getCell = getCell(columnGroup, colIndex, rest),
_getCell2 = _slicedToArray(_getCell, 2),
cell = _getCell2[0],
actualRecord = _getCell2[1];
result[0].push(cell);
if (highLightRow && actualRecord && actualRecord.isCurrent) {
result[1].isCurrent = true;
}
}
return result;
}, [[], {}]);
}(),
_ref3 = _slicedToArray(_ref2, 2),
columns = _ref3[0],
isCurrent = _ref3[1].isCurrent;
useEffect(function () {
if (isCurrent) {
focusRow();
}
}, [isCurrent, focusRow]);
var rowPrefixCls = "".concat(prefixCls, "-row");
var classString = classNames(rowPrefixCls, (_classNames = {}, _defineProperty(_classNames, "".concat(rowPrefixCls, "-current"), isCurrent && (highLightRow === HighLightRowType.click ? tableStore.rowClicked : highLightRow === HighLightRowType.focus ? node.isFocused : highLightRow)), _defineProperty(_classNames, "".concat(rowPrefixCls, "-hover"), !isStickySupport() && highLightRow && isHover), _defineProperty(_classNames, "".concat(rowPrefixCls, "-selected"), selectedHighLightRow && isSelectedRow(record)), _defineProperty(_classNames, "".concat(rowPrefixCls, "-disabled"), disabled), _defineProperty(_classNames, "".concat(rowPrefixCls, "-mouse-batch-choose"), mouseBatchChooseState && record.selectable && (tableStore.mouseBatchChooseIdList || []).includes(id)), _defineProperty(_classNames, "".concat(rowPrefixCls, "-expanded"), expandable && isExpanded), _defineProperty(_classNames, "".concat(rowPrefixCls, "-has-next"), metaData && metaData.next), _classNames), className, // 增加可以自定义类名满足拖拽功能
rowExternalProps.className);
var style = rowExternalProps.style;
var rowProps = {
ref: saveRef,
className: classString,
onClick: handleClick,
tabIndex: -1,
disabled: disabled,
'data-index': id
};
if (!isStickySupport() && tableStore.overflowX) {
rowProps.onMouseEnter = handleMouseEnter;
rowProps.onMouseLeave = handleMouseLeave;
}
if (hidden || !showRemovedRow && record.status === RecordStatus["delete"]) {
rowProps.hidden = true;
}
var Element = hidden && parityRow ? 'div' : 'tr';
if (selectionMode === SelectionMode.click) {
rowProps.onClick = handleSelectionByClick;
} else if (selectionMode === SelectionMode.dblclick) {
rowProps.onDoubleClick = handleSelectionByDblClick;
} else if (selectionMode === SelectionMode.mousedown) {
rowProps.onMouseDown = handleSelectionByMouseDown;
}
var rowStyle = _objectSpread({}, style);
if (rowDraggable && provided) {
_extends(rowProps, provided.draggableProps);
_extends(rowStyle, provided.draggableProps.style, style);
if (propStyle) {
var transform = propStyle.transform;
if (transform) {
if (rowStyle.transform) {
rowStyle.transform = 'none';
} else {
rowStyle.transform = transform;
if (!dragRef.current) {
rowStyle.transition = 'none';
dragRef.current = true;
}
}
}
} else {
dragRef.current = false;
}
rowStyle.width = Math.max(tableStore.columnGroups.width, tableStore.width || 0);
if (!dragColumnAlign) {
rowStyle.cursor = 'move';
_extends(rowProps, provided.dragHandleProps);
}
}
var height = intersectionRef ? virtualHeight !== undefined ? virtualHeight : pxToRem(metaData ? metaData.height : record.getState(VIRTUAL_HEIGHT) || tableStore.virtualRowHeight, true) : lock ? pxToRem(get(tableStore.lockColumnsBodyRowsHeight, rowKey), true) : undefined;
if (height) {
rowStyle.height = height;
}
var useEmptyColumn = !fullColumnWidth && lock !== ColumnLock.left && !tableStore.overflowX && !tableStore.hasEmptyWidthColumn;
if (useEmptyColumn) {
columns.push( /*#__PURE__*/React.createElement("td", {
key: "empty-column"
}));
}
if (propVirtual && blankVirtualCell.left.length) {
columns.splice.apply(columns, [left ? left[1] : 0, 0].concat(_toConsumableArray(blankVirtualCell.left)));
}
if (propVirtual && right && blankVirtualCell.right.length) {
columns.splice.apply(columns, [center[1], 0].concat(_toConsumableArray(blankVirtualCell.right)));
}
var tr = /*#__PURE__*/React.createElement(Element, _extends({
key: rowKey
}, rowExternalProps, rowProps, {
style: rowStyle
}), columns);
return /*#__PURE__*/React.createElement(React.Fragment, null, needSaveRowHeight ? /*#__PURE__*/React.createElement(ResizeObservedRow, {
onResize: setRowHeight,
rowIndex: rowKey,
key: rowKey
}, tr) : tr, renderExpandRow());
};
TableRow.displayName = 'TableRow';
export default observer(TableRow);
//# sourceMappingURL=TableRow.js.map