UNPKG

choerodon-ui

Version:

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

1,528 lines (1,249 loc) 115 kB
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray"; import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _extends from "@babel/runtime/helpers/extends"; import _objectSpread from "@babel/runtime/helpers/objectSpread2"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _createSuper from "@babel/runtime/helpers/createSuper"; var _excluded = ["depth", "rowIndex", "isHeaderRow"], _excluded2 = ["children", "columns", "className", "data", "style", "isTree", "hover", "bordered", "cellBordered", "wordWrap", "classPrefix", "loading", "showHeader", "queryBar"]; import _regeneratorRuntime from "@babel/runtime/regenerator"; import * as React from 'react'; import { get, isArrayLike, runInAction } from 'mobx'; import classNames from 'classnames'; import isFunction from 'lodash/isFunction'; import flatten from 'lodash/flatten'; import debounce from 'lodash/debounce'; import isEqual from 'lodash/isEqual'; import eq from 'lodash/eq'; import defaultTo from 'lodash/defaultTo'; import omit from 'lodash/omit'; import merge from 'lodash/merge'; import isNil from 'lodash/isNil'; import BScroll from '@better-scroll/core'; import bindElementResize, { unbind as unbindElementResize } from 'element-resize-event'; import { getTranslateDOMPositionXY } from "dom-lib/es/transition/translateDOMPositionXY"; import { addStyle, getHeight, getOffset, getWidth, on, scrollLeft, scrollTop, WheelHandler } from 'dom-lib'; import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd'; import isPromise from 'is-promise'; import ConfigContext from '../../../es/config-provider/ConfigContext'; import { toPx } from '../../../es/_util/UnitConvertor'; import LocaleReceiver from '../../../es/locale-provider/LocaleReceiver'; import defaultLocale from '../../../es/locale-provider/default'; import warning from '../../../es/_util/warning'; import { stopPropagation } from '../_util/EventManager'; import ModalProvider from '../modal-provider/ModalProvider'; import Row from './Row'; import CellGroup from './CellGroup'; import Scrollbar from './Scrollbar'; import SelectionBox from './SelectionBox'; import SelectionCheckboxAll from './SelectionCheckboxAll'; import TableContext from './TableContext'; import { CELL_PADDING_HEIGHT, SCROLLBAR_LARGE_WIDTH, SCROLLBAR_WIDTH } from './constants'; import { TableQueryBarType } from './enum'; import { cancelAnimationTimeout, defaultClassPrefix, findAllParents, findRowKeys, flattenData, getTotalByColumns, getUnhandledProps, isNumberOrTrue, isRTL as _isRTL, mergeCells, prefix, requestAnimationTimeout, resetLeftForCells, shouldShowRowByExpanded, toggleClass } from './utils'; import isMobile from '../_util/isMobile'; import { transformZoomData } from '../_util/DocumentUtils'; import ColumnGroup from './ColumnGroup'; import Column from './Column'; import Cell from './Cell'; import HeaderCell from './HeaderCell'; import Spin from '../spin'; import PerformanceTableQueryBar from './query-bar'; import ProfessionalBar from './query-bar/TableProfessionalBar'; import DynamicFilterBar from './query-bar/TableDynamicFilterBar'; import TableStore from './TableStore'; import Toolbar from './tool-bar'; import { TableAutoHeightType, TableColumnResizeTriggerType, TableHeightType } from '../table/enum'; import { isDropresult } from '../table/utils'; import { arrayMove } from '../data-set/utils'; import { $l } from '../locale-context'; export { TableQueryBarType }; var SORT_TYPE = { DESC: 'desc', ASC: 'asc' }; var propTypeKeys = ['columns', 'autoHeight', 'affixHeader', 'affixHorizontalScrollbar', 'bordered', 'bodyRef', 'className', 'classPrefix', 'children', 'cellBordered', 'clickScrollLength', 'data', 'defaultExpandAllRows', 'defaultExpandedRowKeys', 'defaultSortType', 'disabledScroll', 'expandedRowKeys', 'hover', 'height', 'headerHeight', 'locale', 'loading', 'loadAnimation', 'minHeight', 'rowKey', 'rowHeight', 'renderTreeToggle', 'renderRowExpanded', 'rowExpandedHeight', 'renderEmpty', 'renderLoading', 'rowClassName', 'rtl', 'style', 'sortColumn', 'sortType', 'showHeader', 'showScrollArrow', 'shouldUpdateScroll', 'translate3d', 'wordWrap', 'width', 'virtualized', 'isTree', 'onRowClick', 'onRowContextMenu', 'onScroll', 'onSortColumn', 'onExpandChange', 'onTouchStart', 'onTouchMove', 'onDataUpdated', 'highLightRow', 'queryBar', 'customizedCode', 'customizable', 'columnDraggable', 'columnTitleEditable', 'columnsDragRender', 'rowSelection', 'rowDraggable', 'onDragEndBefore', 'onDragEnd', 'onDragStart']; export var CUSTOMIZED_KEY = '__customized-column__'; // TODO:Symbol function getRowSelection(props) { return props.rowSelection || {}; } //计算两根手指之间的距离 function getDistance(start, stop) { return Math.sqrt(Math.pow(Math.abs(start.x - stop.x), 2) + Math.pow(Math.abs(start.y - stop.y), 2)); } ; var PerformanceTable = /*#__PURE__*/function (_React$Component) { _inherits(PerformanceTable, _React$Component); var _super = _createSuper(PerformanceTable); function PerformanceTable(props, context) { var _this; _classCallCheck(this, PerformanceTable); _this = _super.call(this, props, context); _this.translateDOMPositionXY = null; _this.scrollListener = null; _this.bscroll = null; _this.tableRows = {}; _this.mounted = false; _this.disableEventsTimeoutId = null; _this.scrollY = 0; _this.scrollX = 0; _this.nextRowZIndex = []; _this.calcStartRowSpan = { rowIndex: 0, rowSpan: 0, height: 0 }; _this._cacheCalcStartRowSpan = []; // 缓存合并行的计算结果 _this._cacheCells = null; _this._cacheScrollX = 0; _this._cacheRenderCols = []; _this._cacheChildrenSize = 0; _this._visibleRows = []; _this.tableStore = new TableStore(_assertThisInitialized(_this)); _this.scaleStore = { firstDistance: 0, centerPoint: [0, 0], scale: 1, originScale: 1 // 原始缩放比例 }; _this.setSelectionColumn = function (props) { var rowSelection = props.rowSelection, _props$columns = props.columns, columns = _props$columns === void 0 ? [] : _props$columns, _props$children = props.children, children = _props$children === void 0 ? [] : _props$children; var index = columns.findIndex(function (column) { return column.key === 'rowSelection'; }); if (rowSelection) { if (index > -1) columns.splice(index, 1); var rowSelectionFixed = 'left'; if ('fixed' in rowSelection) { rowSelectionFixed = rowSelection.fixed; } if (columns && columns.length) { var columnsWithRowSelectionProps = { title: $l('Table', 'select_current_page'), key: 'rowSelection', width: 50, align: 'center', fixed: rowSelectionFixed }; columns.splice(rowSelection.columnIndex || 0, 0, columnsWithRowSelectionProps); } if (children && children.length) { var columnsWithRowSelection = _this.renderRowSelection(rowSelectionFixed); if (columnsWithRowSelection) { if (rowSelectionFixed) { children.splice(rowSelectionFixed === true || 'left' ? rowSelection.columnIndex || 0 : rowSelection.columnIndex || children.length, 0, columnsWithRowSelection); _this.setState({ shouldFixedColumn: true }); } else { children.splice(rowSelection.columnIndex || 0, 0, columnsWithRowSelection); } } } } _this.tableStore.originalColumns = columns; _this.tableStore.originalChildren = children; }; _this.listenWheel = function (deltaX, deltaY) { _this.handleWheel(deltaX, deltaY); var xRef = _this.scrollbarXRef.current; if (xRef && xRef.onWheelScroll) { xRef.onWheelScroll(deltaX); } var yRef = _this.scrollbarYRef.current; if (yRef && yRef.onWheelScroll) { yRef.onWheelScroll(deltaY); } }; _this.getRecordKey = function (record, index) { var rowKey = _this.props.rowKey; var recordKey = record[rowKey]; warning(recordKey !== undefined, 'Each record in dataSource of table should have a unique `key` prop, ' + 'or set `rowKey` of Table to an unique primary key.'); return recordKey === undefined ? index : recordKey; }; _this.getCheckboxPropsByItem = function (item, index) { var rowSelection = getRowSelection(_this.props); if (!rowSelection.getCheckboxProps) { return {}; } var key = _this.getRecordKey(item, index); // Cache checkboxProps if (!_this.tableStore.checkboxPropsCache[key]) { _this.tableStore.checkboxPropsCache[key] = rowSelection.getCheckboxProps(item) || {}; var checkboxProps = _this.tableStore.checkboxPropsCache[key]; warning(!('checked' in checkboxProps) && !('defaultChecked' in checkboxProps), 'Do not set `checked` or `defaultChecked` in `getCheckboxProps`. Please use `selectedRowKeys` instead.'); } return _this.tableStore.checkboxPropsCache[key]; }; _this.handleSelect = function (record, rowIndex, e) { var checked = e.target.checked; var nativeEvent = e.nativeEvent; var defaultSelection = _this.tableStore.selectionDirty ? [] : _this.getDefaultSelection(); // @ts-ignore var selectedRowKeys = _this.tableStore.selectedRowKeys.concat(defaultSelection); var key = _this.getRecordKey(record, rowIndex); var _this$state = _this.state, pivot = _this$state.pivot, data = _this$state.data; var rows = _objectSpread({}, data); var realIndex = rowIndex; if (_this.props.expandedRowRender) { realIndex = rows.findIndex(function (row) { return _this.getRecordKey(row, rowIndex) === key; }); } if (nativeEvent.shiftKey && pivot !== undefined && realIndex !== pivot) { var changeRowKeys = []; var direction = Math.sign(pivot - realIndex); var dist = Math.abs(pivot - realIndex); var step = 0; var _loop = function _loop() { var i = realIndex + step * direction; step += 1; var row = rows[i]; var rowKey = _this.getRecordKey(row, i); var checkboxProps = _this.getCheckboxPropsByItem(row, i); if (!checkboxProps.disabled) { if (selectedRowKeys.includes(rowKey)) { if (!checked) { selectedRowKeys = selectedRowKeys.filter(function (j) { return rowKey !== j; }); changeRowKeys.push(rowKey); } } else if (checked) { selectedRowKeys.push(rowKey); changeRowKeys.push(rowKey); } } }; while (step <= dist) { _loop(); } _this.setState({ pivot: realIndex }); _this.tableStore.selectionDirty = true; _this.setSelectedRowKeys(selectedRowKeys, { selectWay: 'onSelectMultiple', record: record, checked: checked, changeRowKeys: changeRowKeys, nativeEvent: nativeEvent }); } else { if (checked) { selectedRowKeys.push(_this.getRecordKey(record, realIndex)); } else { selectedRowKeys = selectedRowKeys.filter(function (i) { return key !== i; }); } _this.setState({ pivot: realIndex }); _this.setSelectedRowKeys(selectedRowKeys, { selectWay: 'onSelect', record: record, checked: checked, changeRowKeys: undefined, nativeEvent: nativeEvent }); } }; _this.handleSelectRow = function (selectionKey, index, onSelectFunc) { var data = _this.state.data; var defaultSelection = _this.tableStore.selectionDirty ? [] : _this.getDefaultSelection(); //@ts-ignore var selectedRowKeys = _this.tableStore.selectedRowKeys.concat(defaultSelection); var changeableRowKeys = data.filter(function (item, i) { return !_this.getCheckboxPropsByItem(item, i).disabled; }).map(function (item, i) { return _this.getRecordKey(item, i); }); var changeRowKeys = []; var selectWay = 'onSelectAll'; var checked; // handle default selection switch (selectionKey) { case 'all': changeableRowKeys.forEach(function (key) { if (selectedRowKeys.indexOf(key) < 0) { selectedRowKeys.push(key); changeRowKeys.push(key); } }); selectWay = 'onSelectAll'; checked = true; break; case 'removeAll': changeableRowKeys.forEach(function (key) { if (selectedRowKeys.indexOf(key) >= 0) { selectedRowKeys.splice(selectedRowKeys.indexOf(key), 1); changeRowKeys.push(key); } }); selectWay = 'onSelectAll'; checked = false; break; case 'invert': changeableRowKeys.forEach(function (key) { if (selectedRowKeys.indexOf(key) < 0) { selectedRowKeys.push(key); } else { selectedRowKeys.splice(selectedRowKeys.indexOf(key), 1); } changeRowKeys.push(key); selectWay = 'onSelectInvert'; }); break; default: break; } _this.tableStore.selectionDirty = true; // when select custom selection, callback selections[n].onSelect var rowSelection = _this.props.rowSelection; var customSelectionStartIndex = 2; if (rowSelection && rowSelection.hideDefaultSelections) { customSelectionStartIndex = 0; } if (index >= customSelectionStartIndex && typeof onSelectFunc === 'function') { return onSelectFunc(changeableRowKeys); } _this.setSelectedRowKeys(selectedRowKeys, { selectWay: selectWay, checked: checked, changeRowKeys: changeRowKeys }); }; _this.handleRadioSelect = function (record, rowIndex, e) { var checked = e.target.checked; var nativeEvent = e.nativeEvent; var key = _this.getRecordKey(record, rowIndex); var selectedRowKeys = [key]; _this.tableStore.selectionDirty = true; _this.setSelectedRowKeys(selectedRowKeys, { selectWay: 'onSelect', record: record, checked: checked, changeRowKeys: undefined, nativeEvent: nativeEvent }); }; _this.renderSelectionBox = function (type, rowData, rowIndex) { var rowKey = _this.getRecordKey(rowData, rowIndex); var props = _this.getCheckboxPropsByItem(rowData, rowIndex); var handleChange = function handleChange(e) { return type === 'radio' ? _this.handleRadioSelect(rowData, rowIndex, e) : _this.handleSelect(rowData, rowIndex, e); }; return /*#__PURE__*/React.createElement("span", { onClick: stopPropagation }, /*#__PURE__*/React.createElement(SelectionBox, _extends({ store: _this.tableStore, type: type, rowIndex: rowKey, onChange: handleChange, defaultSelection: _this.getDefaultSelection() }, props))); }; _this.setOffsetByAffix = function () { var _this$props = _this.props, affixHeader = _this$props.affixHeader, affixHorizontalScrollbar = _this$props.affixHorizontalScrollbar; var _assertThisInitialize = _assertThisInitialized(_this), headerWrapperRef = _assertThisInitialize.headerWrapperRef, tableRef = _assertThisInitialize.tableRef; var headerNode = headerWrapperRef && headerWrapperRef.current; if (isNumberOrTrue(affixHeader) && headerNode) { _this.setState(function () { return { headerOffset: getOffset(headerNode) }; }); } var tableNode = tableRef && tableRef.current; if (isNumberOrTrue(affixHorizontalScrollbar) && tableNode) { _this.setState(function () { return { tableOffset: getOffset(tableNode) }; }); } }; _this.handleWindowScroll = function () { var _this$props2 = _this.props, affixHeader = _this$props2.affixHeader, affixHorizontalScrollbar = _this$props2.affixHorizontalScrollbar; if (isNumberOrTrue(affixHeader)) { _this.affixTableHeader(); } if (isNumberOrTrue(affixHorizontalScrollbar)) { _this.affixHorizontalScrollbar(); } }; _this.affixHorizontalScrollbar = function () { var scrollY = window.scrollY || window.pageYOffset; var windowHeight = getHeight(window); var height = _this.getTableHeight(); var _this$state2 = _this.state, tableOffset = _this$state2.tableOffset, fixedHorizontalScrollbar = _this$state2.fixedHorizontalScrollbar; var affixHorizontalScrollbar = _this.props.affixHorizontalScrollbar; var headerHeight = _this.getTableHeaderHeight(); var bottom = typeof affixHorizontalScrollbar === 'number' ? affixHorizontalScrollbar : 0; var offset = defaultTo(tableOffset && tableOffset.top, 0) + bottom; var fixedScrollbar = // @ts-ignore scrollY + windowHeight < height + offset && // @ts-ignore scrollY + windowHeight - headerHeight > offset; var _assertThisInitialize2 = _assertThisInitialized(_this), scrollbarXRef = _assertThisInitialize2.scrollbarXRef; if (scrollbarXRef) { var current = scrollbarXRef.current; if (current) { var barRef = current.barRef; if (barRef && barRef.current && fixedHorizontalScrollbar !== fixedScrollbar) { _this.setState({ fixedHorizontalScrollbar: fixedScrollbar }); } } } }; _this.affixTableHeader = function () { var affixHeader = _this.props.affixHeader; var top = typeof affixHeader === 'number' ? affixHeader : 0; var _this$state3 = _this.state, headerOffset = _this$state3.headerOffset, contentHeight = _this$state3.contentHeight; var scrollY = window.scrollY || window.pageYOffset; var fixedHeader = // @ts-ignore scrollY - (headerOffset.top - top) >= 0 && scrollY < headerOffset.top - top + contentHeight; if (_this.affixHeaderWrapperRef.current) { toggleClass(_this.affixHeaderWrapperRef.current, 'fixed', fixedHeader); } }; _this.handleSortColumn = function (dataKey) { var sortType = _this.getSortType(); var _this$props3 = _this.props, onSortColumn = _this$props3.onSortColumn, sortColumn = _this$props3.sortColumn; if (sortColumn === dataKey) { switch (sortType) { case SORT_TYPE.ASC: sortType = SORT_TYPE.DESC; break; case SORT_TYPE.DESC: sortType = undefined; break; default: sortType = SORT_TYPE.ASC; } _this.setState({ sortType: sortType }); } if (onSortColumn) { onSortColumn(dataKey, sortType); } }; _this.handleShowMouseArea = function (width, left, fixed) { var tableColumnResizeTrigger = _this.tableStore.tableColumnResizeTrigger; if (tableColumnResizeTrigger !== TableColumnResizeTriggerType.hover) return; _this.handleColumnResizeMove(width, left, !!fixed); }; _this.handleHideMouseArea = function () { var tableColumnResizeTrigger = _this.tableStore.tableColumnResizeTrigger; if (tableColumnResizeTrigger !== TableColumnResizeTriggerType.hover) return; addStyle(_this.mouseAreaRef.current, { display: 'none' }); }; _this.handleColumnResizeEnd = function (columnWidth, _cursorDelta, dataKey, index) { _this._cacheCells = null; if (_this.tableStore.customizable) { _this.tableStore.changeCustomizedColumnValue(dataKey, { width: columnWidth }); } _this.setState(_defineProperty({ isColumnResizing: false }, "".concat(dataKey, "_").concat(index, "_width"), columnWidth)); addStyle(_this.mouseAreaRef.current, { display: 'none' }); _this.scrollLeft(-_this.scrollX); }; _this.handleColumnResizeStart = function (width, left, fixed) { _this.setState({ isColumnResizing: true }); _this.handleColumnResizeMove(width, left, fixed); }; _this.handleColumnResizeMove = function (width, left, fixed) { var mouseAreaLeft = width + left; var x = mouseAreaLeft; var dir = 'left'; if (_this.isRTL()) { mouseAreaLeft += _this.minScrollX + _this.getScrollBarYWidth; dir = 'right'; } if (!fixed) { x = mouseAreaLeft + (_this.isRTL() ? -_this.scrollX : _this.scrollX); } addStyle(_this.mouseAreaRef.current, _defineProperty({ display: 'block' }, dir, "".concat(x, "px"))); }; _this.handleTreeToggle = function (rowKey, _rowIndex, rowData) { var expandedRowKeys = _this.getExpandedRowKeys(); var open = false; var nextExpandedRowKeys = []; for (var i = 0; i < expandedRowKeys.length; i++) { var key = expandedRowKeys[i]; if (key === rowKey) { open = true; } else { // @ts-ignore nextExpandedRowKeys.push(key); } } if (!open) { // @ts-ignore nextExpandedRowKeys.push(rowKey); } _this.setState({ expandedRowKeys: nextExpandedRowKeys }); var onExpandChange = _this.props.onExpandChange; if (onExpandChange) { onExpandChange(!open, rowData); } }; _this.handleScrollX = function (delta) { _this.handleWheel(delta, 0); }; _this.handleScrollY = function (delta) { _this.handleWheel(0, delta); }; _this.handleWheel = function (deltaX, deltaY) { var _this$props4 = _this.props, onScroll = _this$props4.onScroll, virtualized = _this$props4.virtualized; var _this$state4 = _this.state, contentWidth = _this$state4.contentWidth, width = _this$state4.width; if (!_this.tableRef.current) { return; } var nextScrollX = contentWidth <= width ? 0 : _this.scrollX - deltaX; var nextScrollY = _this.scrollY - deltaY; _this.scrollY = Math.min(0, nextScrollY < _this.minScrollY ? _this.minScrollY : nextScrollY); _this.scrollX = Math.min(0, nextScrollX < _this.minScrollX ? _this.minScrollX : nextScrollX); _this.updatePosition(); if (onScroll) { onScroll(_this.scrollX, _this.scrollY); } if (virtualized) { _this.setState({ isScrolling: true, scrollY: _this.scrollY, scrollX: _this.scrollX }); if (_this.disableEventsTimeoutId) { // @ts-ignore cancelAnimationTimeout(_this.disableEventsTimeoutId); } // @ts-ignore _this.disableEventsTimeoutId = requestAnimationTimeout(_this.debounceScrollEndedCallback, 150); } }; _this.debounceScrollEndedCallback = function () { _this.disableEventsTimeoutId = null; _this.setState({ isScrolling: false }); }; // 处理移动端 Touch 事件, Start 的时候初始化 x,y _this.handleTouchStart = function (event) { if (event.touches) { var _event$touches$ = event.touches[0], pageX = _event$touches$.pageX, pageY = _event$touches$.pageY; _this.touchX = transformZoomData(pageX); _this.touchY = transformZoomData(pageY); } var onTouchStart = _this.props.onTouchStart; if (onTouchStart) { onTouchStart(event); } }; // 处理移动端 Touch 事件, Move 的时候初始化,更新 scroll _this.handleTouchMove = function (_ref) { var e = _ref.e; var _this$props5 = _this.props, autoHeight = _this$props5.autoHeight, onTouchMove = _this$props5.onTouchMove; if (e.touches) { var eTouch = e.touches[0]; var pageX = transformZoomData(eTouch.pageX); var pageY = transformZoomData(eTouch.pageY); var deltaX = _this.touchX - pageX; var deltaY = autoHeight ? 0 : _this.touchY - pageY; if (!_this.shouldHandleWheelY(deltaY) && !_this.shouldHandleWheelX(deltaX)) { return; } if (e.preventDefault) { e.preventDefault(); } _this.handleWheel(deltaX, deltaY); var xRef = _this.scrollbarXRef.current; if (xRef && xRef.onWheelScroll) { xRef.onWheelScroll(deltaX); } var yRef = _this.scrollbarYRef.current; if (yRef && yRef.onWheelScroll) { yRef.onWheelScroll(deltaY); } _this.touchX = pageX; _this.touchY = pageY; } if (onTouchMove) { onTouchMove(e); } }; _this.handleWheelTouchStart = function (e) { var touches = e.touches; //判断是否是两指 if (touches.length === 2) { var events1 = touches[0]; var events2 = touches[1]; // 第一根手指的坐标 var one = { x: events1.pageX, y: events1.pageY }; // 第二根手指的坐标 var two = { x: events2.pageX, y: events2.pageY }; // 取手指中间坐标 var centerX = (one.x + two.x) / 2; var centerY = (one.y + two.y) / 2; _this.scaleStore.centerPoint = [centerX, centerY]; _this.scaleStore.firstDistance = getDistance(one, two); _this.scaleStore.originScale = _this.scaleStore.scale || 1; } }; _this.handleWheelTouchMove = function (e) { var touches = e.touches; if (touches.length === 2) { e.stopPropagation(); var events1 = touches[0]; var events2 = touches[1]; // 第一根手指的横坐标 var one = { x: events1.pageX, y: events1.pageY }; // 第二根手指的横坐标 var two = { x: events2.pageX, y: events2.pageY }; var distance = getDistance(one, two); var zoom = distance / _this.scaleStore.firstDistance; var newScale = _this.scaleStore.originScale * zoom; // 最大缩放比例限制 if (newScale > 3) { newScale = 3; } else if (newScale < 1) { newScale = 1; } // 记住使用的缩放值 _this.scaleStore.scale = newScale; document.documentElement.style.transformOrigin = "".concat(_this.scaleStore.centerPoint[0], "px ").concat(_this.scaleStore.centerPoint[1], "px"); document.documentElement.style.transform = 'scale(' + newScale + ')'; } }; /** * 当用户在 Table 内使用 tab 键,触发了 onScroll 事件,这个时候应该更新滚动条位置 * https://github.com/rsuite/rsuite/issues/234 */ _this.handleBodyScroll = function (event) { if (event.target !== _this.tableBodyRef.current) { return; } var left = scrollLeft(event.target); var top = scrollTop(event.target); if (top === 0 && left === 0) { return; } _this.listenWheel(left, top); scrollLeft(event.target, 0); scrollTop(event.target, 0); }; _this.handleDragStart = function (initial, provided) { var onDragStart = _this.props.onDragStart; var draggableId = initial.draggableId; _this.setState({ dragRowIndex: draggableId }); if (isFunction(onDragStart)) { onDragStart(initial, provided); } }; _this.handleDragEnd = /*#__PURE__*/function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(resultDrag, provided) { var _this$props6, onDragEnd, onDragEndBefore, data, resultBefore, resultStatus, result, resData; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _this$props6 = _this.props, onDragEnd = _this$props6.onDragEnd, onDragEndBefore = _this$props6.onDragEndBefore; data = _this.state.data; _this.setState({ dragRowIndex: '' }); resultBefore = resultDrag; if (!onDragEndBefore) { _context.next = 17; break; } resultStatus = onDragEndBefore(resultDrag, provided); if (!isPromise(resultStatus)) { _context.next = 12; break; } _context.next = 9; return resultStatus; case 9: _context.t0 = _context.sent; _context.next = 13; break; case 12: _context.t0 = resultStatus; case 13: result = _context.t0; if (result) { _context.next = 16; break; } return _context.abrupt("return"); case 16: if (isDropresult(result)) { resultBefore = result; } case 17: if (resultBefore && resultBefore.destination) { resData = _toConsumableArray(data); arrayMove(resData, resultBefore.source.index, resultBefore.destination.index); // 使setState变成同步处理 setTimeout(function () { _this.setState({ data: resData }); }); if (onDragEnd) { onDragEnd(resultBefore, provided, resData); } } case 18: case "end": return _context.stop(); } } }, _callee); })); return function (_x, _x2) { return _ref2.apply(this, arguments); }; }(); _this.shouldHandleWheelX = function (delta) { var _this$props7 = _this.props, disabledScroll = _this$props7.disabledScroll, loading = _this$props7.loading; if (delta === 0 || disabledScroll || loading) { return false; } return true; }; _this.shouldHandleWheelY = function (delta) { var _this$props8 = _this.props, disabledScroll = _this$props8.disabledScroll, loading = _this$props8.loading; if (delta === 0 || disabledScroll || loading) { return false; } return delta >= 0 && _this.scrollY > _this.minScrollY || delta < 0 && _this.scrollY < 0; }; _this.addPrefix = function (name) { return prefix(_this.props.classPrefix)(name); }; _this.calculateTableWidth = function () { var table = _this.tableRef && _this.tableRef.current; var width = _this.state.width; if (table) { var nextWidth = getWidth(table); if (width !== nextWidth) { _this.scrollX = 0; var current = _this.scrollbarXRef && _this.scrollbarXRef.current; current && current.resetScrollBarPosition(); _this._cacheCells = null; } if (nextWidth !== 0) { _this.setState({ width: nextWidth }); } } _this.setOffsetByAffix(); }; /** * public method */ _this.scrollTop = function () { var top = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; var _this$getControlledSc = _this.getControlledScrollTopValue(top), _this$getControlledSc2 = _slicedToArray(_this$getControlledSc, 2), scrollY = _this$getControlledSc2[0], handleScrollY = _this$getControlledSc2[1]; _this.scrollY = scrollY; var current = _this.scrollbarYRef && _this.scrollbarYRef.current; current && current.resetScrollBarPosition && current.resetScrollBarPosition(handleScrollY); _this.updatePosition(); /** * 当开启 virtualized,调用 scrollTop 后会出现白屏现象, * 原因是直接操作 DOM 的坐标,但是组件没有重新渲染,需要调用 forceUpdate 重新进入 render。 * Fix: rsuite#1044 */ if (_this.props.virtualized && _this.state.contentHeight > _this.getTableHeight()) { _this.forceUpdate(); } }; // public method _this.scrollLeft = function () { var left = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; var _this$getControlledSc3 = _this.getControlledScrollLeftValue(left), _this$getControlledSc4 = _slicedToArray(_this$getControlledSc3, 2), scrollX = _this$getControlledSc4[0], handleScrollX = _this$getControlledSc4[1]; _this.scrollX = scrollX; var current = _this.scrollbarXRef && _this.scrollbarXRef.current; current && current.resetScrollBarPosition && current.resetScrollBarPosition(handleScrollX); _this.updatePosition(); /** * 这里的条件与 scrollTop 触发强制更新的条件相反,避免重复的渲染。 */ if (_this.props.virtualized && _this.state.contentHeight <= _this.getTableHeight()) { _this.forceUpdate(); } }; _this.scrollTo = function (coord) { var _ref3 = coord || {}, x = _ref3.x, y = _ref3.y; if (typeof x === 'number') { _this.scrollLeft(x); } if (typeof y === 'number') { _this.scrollTop(y); } }; _this.bindTableRowsRef = function (index, rowData, provided) { return function (ref) { if (ref) { _this.tableRows[index] = [ref, rowData]; if (provided) { provided.innerRef(ref); } } }; }; _this.bindRowClick = function (rowIndex, index, rowData) { return function (event) { _this.onRowClick(rowData, event, rowIndex, index); }; }; _this.bindRowContextMenu = function (rowData) { return function (event) { var onRowContextMenu = _this.props.onRowContextMenu; if (onRowContextMenu) { onRowContextMenu(rowData, event); } }; }; var width = props.width, height = props.height, data = props.data, rowKey = props.rowKey, defaultExpandAllRows = props.defaultExpandAllRows, renderRowExpanded = props.renderRowExpanded, defaultExpandedRowKeys = props.defaultExpandedRowKeys, _props$children2 = props.children, children = _props$children2 === void 0 ? [] : _props$children2, _props$columns2 = props.columns, columns = _props$columns2 === void 0 ? [] : _props$columns2, isTree = props.isTree, defaultSortType = props.defaultSortType; var expandedRowKeys = defaultExpandAllRows ? findRowKeys(data, rowKey, isFunction(renderRowExpanded)) : defaultExpandedRowKeys || []; var shouldFixedColumn = Array.from(children).some(function (child) { return child && child.props && child.props.fixed; }); if (columns && columns.length) { shouldFixedColumn = Array.from(columns).some(function (child) { return child && child.fixed; }); } if (isTree && !rowKey) { throw new Error('The `rowKey` is required when set isTree'); } _this.state = { isTree: isTree, expandedRowKeys: expandedRowKeys, shouldFixedColumn: shouldFixedColumn, cacheData: data, data: isTree ? flattenData(data) : data, width: width || 0, height: height || 0, columnWidth: 0, dataKey: 0, contentHeight: 0, contentWidth: 0, tableRowsMaxHeight: [], sortType: defaultSortType, scrollY: 0, isScrolling: false, fixedHeader: false, searchText: '', pivot: undefined, selectedRowKeys: [], dragRowIndex: '' }; _this.scrollY = 0; _this.scrollX = 0; _this._cacheScrollX = 0; _this._cacheRenderCols = []; _this.wheelHandler = new WheelHandler(_this.listenWheel, _this.shouldHandleWheelX, _this.shouldHandleWheelY, false); _this._cacheChildrenSize = flatten(children || columns).length; _this.translateDOMPositionXY = getTranslateDOMPositionXY({ enable3DTransform: props.translate3d }); _this.tableRef = /*#__PURE__*/React.createRef(); _this.scrollbarYRef = /*#__PURE__*/React.createRef(); _this.scrollbarXRef = /*#__PURE__*/React.createRef(); _this.tableBodyRef = /*#__PURE__*/React.createRef(); _this.affixHeaderWrapperRef = /*#__PURE__*/React.createRef(); _this.mouseAreaRef = /*#__PURE__*/React.createRef(); _this.headerWrapperRef = /*#__PURE__*/React.createRef(); _this.wheelWrapperRef = /*#__PURE__*/React.createRef(); _this.tableHeaderRef = /*#__PURE__*/React.createRef(); runInAction(function () { return _this.setSelectionColumn(props); }); return _this; } _createClass(PerformanceTable, [{ key: "componentDidMount", value: function componentDidMount() { this.calculateTableWidth(); this.calculateTableContextHeight(); this.calculateRowMaxHeight(); this.setOffsetByAffix(); this.initPosition(); bindElementResize(this.tableRef.current, debounce(this.calculateTableWidth, 400)); var options = { passive: false }; var tableBody = this.tableBodyRef.current; var wheelWrapper = this.wheelWrapperRef.current; if (tableBody) { if (isMobile()) { this.initBScroll(tableBody); // 移动端适配缩放功能 if (wheelWrapper) { this.touchStartListener = on(wheelWrapper, 'touchstart', this.handleWheelTouchStart); this.touchMoveListener = on(wheelWrapper, 'touchmove', this.handleWheelTouchMove); } } this.wheelListener = on(tableBody, 'wheel', this.wheelHandler.onWheel, options); // this.touchStartListener = on(tableBody, 'touchstart', this.handleTouchStart, options); // this.touchMoveListener = on(tableBody, 'touchmove', this.handleTouchMove, options); } var _this$props9 = this.props, affixHeader = _this$props9.affixHeader, affixHorizontalScrollbar = _this$props9.affixHorizontalScrollbar, bodyRef = _this$props9.bodyRef; if (isNumberOrTrue(affixHeader) || isNumberOrTrue(affixHorizontalScrollbar)) { this.scrollListener = on(window, 'scroll', this.handleWindowScroll); } if (bodyRef) { bodyRef(this.wheelWrapperRef.current); } } }, { key: "shouldComponentUpdate", value: function shouldComponentUpdate(nextProps, nextState) { var _this2 = this; var _cacheChildrenSize = flatten(nextProps.children || nextProps.columns || []).length; /** * 单元格列的信息在初始化后会被缓存,在某些属性被更新以后,需要清除缓存。 */ if (_cacheChildrenSize !== this._cacheChildrenSize) { this._cacheChildrenSize = _cacheChildrenSize; this._cacheCells = null; this.tableStore.updateProps(nextProps, this); } else if (this.props.children !== nextProps.children || this.props.columns !== nextProps.columns || this.props.sortColumn !== nextProps.sortColumn || this.props.sortType !== nextProps.sortType) { this._cacheCells = null; this.tableStore.updateProps(nextProps, this); } else if (this.props.data !== nextProps.data && this._cacheCells) { var rowSelection = nextProps.rowSelection; if (rowSelection && rowSelection.type !== 'radio') { var flatData = nextState.data.filter(function (item, index) { if (rowSelection.getCheckboxProps) { return !_this2.getCheckboxPropsByItem(item, index).disabled; } return true; }); var checkboxAllDisabled = flatData.every(function (item, index) { return _this2.getCheckboxPropsByItem(item, index).disabled; }); var checkboxAllHeaderCell = /*#__PURE__*/React.cloneElement(this._cacheCells.headerCells[0], { children: /*#__PURE__*/React.cloneElement(this._cacheCells.headerCells[0].props.children, { disabled: checkboxAllDisabled, data: flatData }) }); this._cacheCells.headerCells[0] = checkboxAllHeaderCell; } } var flag = this.props.columns !== nextProps.columns || this.props.children !== nextProps.children || this.props.rowSelection !== nextProps.rowSelection; if (flag) { runInAction(function () { return _this2.setSelectionColumn(nextProps); }); } return !eq(this.props, nextProps) || !isEqual(this.state, nextState); } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps, prevState) { var _this3 = this; var rowHeight = prevProps.rowHeight, data = prevProps.data, autoHeight = prevProps.autoHeight, height = prevProps.height, virtualized = prevProps.virtualized, children = prevProps.children, columns = prevProps.columns; var props = this.props, state = this.state; var nextData = props.data, nextAutoHeight = props.autoHeight, onDataUpdated = props.onDataUpdated, shouldUpdateScroll = props.shouldUpdateScroll, nextColumns = props.columns, rowSelection = props.rowSelection, nextChildren = props.children; if (data !== nextData) { this.calculateRowMaxHeight(); if (onDataUpdated) { onDataUpdated(nextData, this.scrollTo); } var maxHeight = nextData.length * (typeof rowHeight === 'function' ? rowHeight({}) : rowHeight); // 当开启允许更新滚动条,或者滚动条位置大于表格的最大高度,则初始滚动条位置 if (shouldUpdateScroll || Math.abs(this.scrollY) > maxHeight) { this.scrollTo({ x: 0, y: 0 }); } } else { this.updatePosition(); } if (columns !== nextColumns || children !== nextChildren || this.tableStore.customizable) { var shouldFixedColumn = false; if ((!columns || columns.length === 0) && rowSelection && nextColumns && nextColumns.length) { var rowSelectionFixed = 'left'; if ('fixed' in rowSelection) { rowSelectionFixed = rowSelection.fixed; } var columnsWithRowSelectionProps = { title: $l('Table', 'select_current_page'), key: 'rowSelection', width: 50, align: 'center', fixed: rowSelectionFixed }; runInAction(function () { _this3.tableStore.originalColumns = nextColumns.splice(rowSelection.columnIndex || 0, 0, columnsWithRowSelectionProps); }); } if (rowSelection) { runInAction(function () { _this3.tableStore.selectedRowKeys = rowSelection.selectedRowKeys || []; }); } if (nextChildren) { shouldFixedColumn = Array.from(nextChildren).some(function (child) { return child && child.props && child.props.fixed; }); } var originalColumns = this.tableStore.originalColumns; if (originalColumns && originalColumns.length) { shouldFixedColumn = Array.from(originalColumns).some(function (child) { return child && child.fixed; }); } this.setState({ shouldFixedColumn: shouldFixedColumn }); } if ( // 当 Table 的 data 发生变化,需要重新计算高度 data !== nextData || // 当 Table 内容区的高度发生变化需要重新计算 height !== props.height || autoHeight !== nextAutoHeight || // 当 Table 内容区的高度发生变化需要重新计算 prevState.contentHeight !== state.contentHeight || // 当 expandedRowKeys 发生变化,需要重新计算 Table 高度,如果重算会导致滚动条不显示。 prevState.expandedRowKeys !== state.expandedRowKeys || prevProps.expandedRowKeys !== props.expandedRowKeys) { this.calculateTableContextHeight(prevProps); } this.calculateTableContentWidth(prevProps); if (virtualized) { this.calculateTableWidth(); } var tableBody = this.tableBodyRef.current; if (!this.wheelListener && tableBody) { var options = { passive: false }; if (isMobile()) { this.initBScroll(tableBody); } this.wheelListener = on(tableBody, 'wheel', this.wheelHandler.onWheel, options); } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { this.wheelHandler = null; var current = this.tableRef.current; if (current) { unbindElementResize(current); } var wheelListener = this.wheelListener, touchStartListener = this.touchStartListener, touchMoveListener = this.touchMoveListener, scrollListener = this.scrollListener; if (wheelListener) { wheelListener.off(); } if (touchStartListener) { touchStartListener.off(); } if (touchMoveListener) { touchMoveListener.off(); } if (scrollListener) { scrollListener.off(); } } }, { key: "getExpandedRowKeys", value: function getExpandedRowKeys() { var expandedRowKeys = this.props.expandedRowKeys; return typeof expandedRowKeys === 'undefined' ? this.state.expandedRowKeys : expandedRowKeys; } }, { key: "getSortType", value: function getSortType() { var sortType = this.props.sortType; return typeof sortType === 'undefined' ? this.state.sortType : sortType; } }, { key: "getScrollCellGroups", value: function getScrollCellGroups() { var current = this.tableRef.current; return current && current.querySelectorAll(".".concat(this.addPrefix('cell-group-scroll'))); } }, { key: "getFixedLeftCellGroups", value: function getFixedLeftCellGroups() { var current = this.tableRef.current; return current && current.querySelectorAll(".".concat(this.addPrefix('cell-group-fixed-left'))); } }, { key: "getFixedRightCellGroups", value: function getFixedRightCellGroups() { var current = this.tableRef.current; return current && current.querySelectorAll(".".concat(this.addPrefix('cell-group-fixed-right'))); } }, { key: "isRTL", value: function isRTL() { return this.props.rtl || _isRTL(); } }, { key: "getRowHeight", value: function getRowHeight() { var rowData = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var rowHeight = this.props.rowHeight; return typeof rowHeight === 'function' ? rowHeight(rowData) : rowHeight; } }, { key: "getScrollBarYWidth", get: function get() { var contentHeight = this.state.contentHeight; var showScrollArrow = this.props.showScrollArrow; var height = this.getTableHeight(); if (contentHeight > height && !!this.scrollbarYRef) { return showScrollArrow ? SCROLLBAR_LARGE_WIDTH : SCROLLBAR_WIDTH; } return 0; } /** * 获取表头高度 */ }, { key: "getTableHeaderHeight", value: function getTableHeaderHeight() { var _this$props10 = this.props, headerHeight = _this$props10.headerHeight, showHeader = _this$props10.showHeader; return showHeader ? headerHeight : 0; } /** * Table 个性化高度变更 */ }, { key: "handleHeightTypeChange", value: function handleHeightTypeChange() { this.calculateTableContextHeight(); } /** * 获取 Table 需要渲染的高度 */ }, { key: "getTableHeight", value: function getTableHeight() { var contentHeight = this.state.contentHeight; var _this$props11 = this.props, minHeight = _this$props11.minHeight, height = _this$props11.height, data = _this$props11.data, showScrollArrow = _this$props11.showScrollArrow; var headerHeight = this.getTableHeaderHeight(); var _this$tableStore = this.tableStore, _this$tableStore$cust = _this$tableStore.customized, heightType = _this$tableStore$cust.heightType, cusHeight = _this$tableStore$cust.height, heightDiff = _this$tableStore$cust.heightDiff, tempCustomized = _this$tableStore.tempCustomized, autoHeight = _this$tableStore.autoHeight; var tableHeight = Math.max(height, minHeight); if (this.tableStore.customizable) { var tempHeightType = get(tempCustomized, 'heightType'); if (tempHeightType) { if (tempHeightType === TableHeightType.fixed) { tableHeight = get(tempCustomized, 'height'); } if (tempHeightType === TableHeightType.flex) { tableHeight = document.documentElement.clientHeight - (get(tempCustomized, 'heightDiff') || 0); } } if (heightType) { if (heightType === TableHeightType.fixed) { tableHeight = cusHeight; } if (heightType === TableHeightType.flex) { tableHeight = document.documentElement.clientHeight - (heightDiff || 0); } } this.setState({ height: tableHeight