UNPKG

choerodon-ui

Version:

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

659 lines (558 loc) 23.5 kB
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