choerodon-ui
Version:
An enterprise-class UI design language and React-based implementation
594 lines (501 loc) • 20.9 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
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, reaction, remove, set } from 'mobx';
import classNames from 'classnames';
import defer from 'lodash/defer';
import { useInView } from 'react-intersection-observer';
import { Size } from '../../../es/_util/enum';
import { pxToRem } from '../../../es/_util/UnitConvertor';
import measureScrollbar from '../../../es/_util/measureScrollbar';
import TableCell from './TableCell';
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, SELECTION_KEY, VIRTUAL_ROOT_MARGIN } 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) {
var headerGroup = columnGroup.headerGroup;
if (headerGroup && groupPath) {
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,
className = props.className,
lock = props.lock,
columnGroups = props.columnGroups,
children = props.children,
groupPath = props.groupPath,
expandIconColumnIndex = props.expandIconColumnIndex,
metaData = props.metaData,
propStyle = props.style;
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;
var highLightRow = tableStore.highLightRow,
selectedHighLightRow = tableStore.selectedHighLightRow,
mouseBatchChooseState = tableStore.mouseBatchChooseState,
dragColumnAlign = tableStore.dragColumnAlign,
rowDraggable = tableStore.rowDraggable,
showRemovedRow = tableStore.showRemovedRow,
node = tableStore.node;
var id = record.id,
rowKey = record.key;
var mounted = useRef(false);
var dragRef = useRef(false);
var needIntersection = !hidden && tableStore.virtualCell;
var columnsInView = needIntersection ? tableStore.columnGroups.inView : true;
var _useInView = useInView({
root: needIntersection && tableStore.overflowY ? node.tableBodyWrap || node.element : null,
rootMargin: "".concat(VIRTUAL_ROOT_MARGIN, "px"),
initialInView: !needIntersection || mounted.current || tableStore.isRowInView(index)
}),
intersectionRef = _useInView.ref,
inView = _useInView.inView,
entry = _useInView.entry;
var disabled = isDisabledRow(record);
var rowRef = useRef(null);
var childrenRenderedRef = useRef();
var needSaveRowHeight = isStickySupport() ? tableStore.propVirtual || needIntersection : !lock && (!tableStore.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) {
if (inView && columnsInView && height && target.offsetParent) {
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, 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 handleClickCapture = useCallback(action(function (e) {
if (!isDisabledRow(record) && e.target.dataset.selectionKey !== SELECTION_KEY) {
dataSet.current = record;
}
var onClickCapture = rowExternalProps.onClickCapture;
if (typeof onClickCapture === 'function') {
onClickCapture(e);
}
}), [record, dataSet, rowExternalProps]);
var handleClick = useCallback(action(function (e) {
var onClick = rowExternalProps.onClick;
if (highLightRow === HighLightRowType.click && !tableStore.rowClicked) {
tableStore.rowClicked = true;
}
if (typeof onClick === 'function') {
return onClick(e);
}
}), [tableStore, rowExternalProps]);
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 handleExpandChange = useCallback(function () {
if (expandable) {
tableStore.setRowExpanded(record, !isExpanded);
}
}, [tableStore, record, expandable, isExpanded]);
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 () {
return reaction(function () {
return record.isCurrent;
}, function (isCurrent) {
return isCurrent && focusRow();
});
}, [record, focusRow]);
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';
expandRows.push( /*#__PURE__*/React.createElement(_Element, _extends({}, expandRowExternalProps, _rowProps), expandIconAsCell && /*#__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 - (expandIconAsCell ? 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) {
return /*#__PURE__*/React.createElement(TableCell, _extends({
columnGroup: columnGroup,
record: headerGroupIndex === undefined ? record : getRecord(columnGroup, groupPath, headerGroupIndex, record),
isDragging: snapshot ? snapshot.isDragging : false,
provided: rest.key === DRAG_KEY ? provided : undefined,
inView: needIntersection ? inView : undefined,
groupPath: groupPath,
rowIndex: virtualIndex === undefined ? index : virtualIndex
}, rest), hasExpandIcon(columnIndex) ? renderExpandIcon() : undefined);
};
var getColumns = function getColumns() {
var customizable = tableStore.customizable;
var leafs = columnGroups.leafs;
var columnLength = leafs.length;
return leafs.map(function (columnGroup, columnIndex) {
var key = columnGroup.key;
if (key !== CUSTOMIZED_KEY) {
var colSpan = customizable && lock !== ColumnLock.left && (!rowDraggable || dragColumnAlign !== DragColumnAlign.right) && columnIndex === columnLength - 2 ? 2 : 1;
var rest = {
key: key,
disabled: disabled
};
if (colSpan > 1) {
rest.colSpan = colSpan;
}
return getCell(columnGroup, columnIndex, rest);
}
return undefined;
});
};
var rowPrefixCls = "".concat(prefixCls, "-row");
var classString = classNames(rowPrefixCls, (_classNames = {}, _defineProperty(_classNames, "".concat(rowPrefixCls, "-current"), highLightRow && record.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,
onClickCapture: handleClickCapture,
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 = needIntersection && (!inView || !columnsInView) ? entry && entry.target.offsetParent ? pxToRem(entry.boundingClientRect.height || entry.target.offsetHeight, true) : 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 tr = /*#__PURE__*/React.createElement(Element, _extends({
key: rowKey
}, rowExternalProps, rowProps, {
style: rowStyle
}), getColumns());
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