UNPKG

choerodon-ui

Version:

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

766 lines (638 loc) 24.1 kB
import _extends from "@babel/runtime/helpers/extends"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _objectSpread from "@babel/runtime/helpers/objectSpread2"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _inherits from "@babel/runtime/helpers/inherits"; import _createSuper from "@babel/runtime/helpers/createSuper"; var _excluded = ["style"], _excluded2 = ["style", "tagRenderer"]; import { __decorate } from "tslib"; import React, { cloneElement, Component, isValidElement } from 'react'; import { action, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import classNames from 'classnames'; import raf from 'raf'; import noop from 'lodash/noop'; import KeyCode from '../../../es/_util/KeyCode'; import { pxToRem } from '../../../es/_util/UnitConvertor'; import Row from '../../../es/row'; import Col from '../../../es/col'; import TableContext from './TableContext'; import { findCell, findIndexedSibling, findRow, getColumnKey, getEditorByColumnAndRecord, getEditorByField, isInCellEditor, isStickySupport } from './utils'; import { stopEvent } from '../_util/EventManager'; import { ShowHelp } from '../field/enum'; import autobind from '../_util/autobind'; import { ResizeType } from '../text-area/enum'; import transform from '../_util/transform'; import { LabelLayout, ShowValidation } from '../form/enum'; function isTextArea(editor) { return editor.type.__PRO_TEXTAREA; } function isHTMLElement(el) { return el; } function offset(node, topNode) { var initialize = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [node.offsetLeft, node.offsetTop]; if (topNode) { var offsetParent = node.offsetParent; if (isHTMLElement(offsetParent)) { if (offsetParent === topNode) { return initialize; } return offset(offsetParent, topNode, [offsetParent.offsetLeft + initialize[0], offsetParent.offsetTop + initialize[1]]); } } return initialize; } var TableEditor = /*#__PURE__*/function (_Component) { _inherits(TableEditor, _Component); var _super = _createSuper(TableEditor); function TableEditor() { var _this; _classCallCheck(this, TableEditor); _this = _super.apply(this, arguments); _this.inTab = false; return _this; } _createClass(TableEditor, [{ key: "lock", get: function get() { var column = this.props.column; return column.lock; } }, { key: "handleWindowResize", value: function handleWindowResize() { if (this.cellNode) { this.alignEditor(); } } /** * 触发多行编辑器失焦切换编辑/只读模式 * @param e */ }, { key: "handleWindowClick", value: function handleWindowClick(e) { var prefixCls = this.context.prefixCls; if (e.target.className !== "".concat(prefixCls, "-content") && e.target.className !== "".concat(prefixCls, "-body")) { this.handleEditorBlur(e); } } }, { key: "connect", value: function connect() { var _this2 = this; this.disconnect(); var tableStore = this.context.tableStore; var dataSet = tableStore.dataSet, virtual = tableStore.virtual; if (virtual) { this.reaction = reaction(function () { return [tableStore.virtualVisibleStartIndex, tableStore.virtualVisibleEndIndex]; }, function () { var current = dataSet.current; if (current && findRow(tableStore, current)) { var cellNode = _this2.cellNode, keep = _this2.keep; if (cellNode || keep) { raf(function () { _this2.alignEditor(cellNode); if (keep) { delete _this2.keep; } }); } } else if (!_this2.keep) { _this2.hideEditor(true); } }); } else { this.reaction = reaction(function () { return dataSet.current; }, function (r) { return r && _this2.cellNode ? raf(function () { return _this2.alignEditor(); }) : _this2.hideEditor(); }); } } }, { key: "disconnect", value: function disconnect() { if (this.reaction) { this.reaction(); } } }, { key: "componentDidMount", value: function componentDidMount() { var _this3 = this; var name = this.props.column.name; if (name) { var tableStore = this.context.tableStore; var dataSet = tableStore.dataSet, currentEditRecord = tableStore.currentEditRecord, editors = tableStore.editors; var record = currentEditRecord || dataSet.current; var field = dataSet.getField(name); if (field && field.get('multiLine', record)) { window.addEventListener('click', this.handleWindowClick); } window.addEventListener('resize', this.handleWindowResize); if (tableStore.inlineEdit) { this.reaction = reaction(function () { return tableStore.currentEditRecord; }, function (r) { return r ? raf(function () { return _this3.alignEditor(); }) : _this3.hideEditor(); }); } editors.set(name, this); } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { var name = this.props.column.name; if (name) { var editors = this.context.tableStore.editors; editors["delete"](name); window.removeEventListener('resize', this.handleWindowResize); window.removeEventListener('click', this.handleWindowClick); this.disconnect(); } } }, { key: "saveRef", value: function saveRef(node) { this.editor = node; } }, { key: "saveWrap", value: function saveWrap(node) { this.wrap = node; var _this$context$tableSt = this.context.tableStore, inlineEdit = _this$context$tableSt.inlineEdit, currentEditRecord = _this$context$tableSt.currentEditRecord; if (node && (!inlineEdit || currentEditRecord)) { this.alignEditor(this.cellNode); } } }, { key: "handleEditorKeyEnterDown", value: function handleEditorKeyEnterDown(e) { var tableStore = this.context.tableStore; var editorNextKeyEnterDown = tableStore.editorNextKeyEnterDown; if (!e.isDefaultPrevented() && editorNextKeyEnterDown) { this.showNextEditor(e.shiftKey); } } // copy the previous tr value to to this cell value }, { key: "handleKeyDownCTRLD", value: function handleKeyDownCTRLD(e) { e.preventDefault(); var cellNode = this.cellNode, tableStore = this.context.tableStore; var name = this.props.column.name; var dataSet = tableStore.dataSet; if (cellNode && tableStore && dataSet) { var parentTdNode = cellNode.parentNode; if (parentTdNode) { var parentTrNode = parentTdNode.parentNode; if (parentTrNode) { var previousElementSibling = findIndexedSibling(parentTrNode, -1); if (previousElementSibling) { var index = previousElementSibling.dataset.index; var currentIndex = parentTrNode.dataset.index; if (index && currentIndex) { var record = dataSet.findRecordById(index); var currentRecord = dataSet.findRecordById(currentIndex); if (record && currentRecord && tableStore) { var cloneRecordData = record.clone().toData() || {}; var dealCloneRecordData = {}; if (name) { dealCloneRecordData[name] = cloneRecordData[name]; currentRecord.set(dealCloneRecordData); } } } } } } } } }, { key: "handleKeyDownCTRLS", value: function handleKeyDownCTRLS(e) { e.preventDefault(); var dataSet = this.context.tableStore.dataSet; dataSet.submit(); } }, { key: "handleEditorKeyDown", value: function handleEditorKeyDown(e) { if (![KeyCode.ESC, KeyCode.TAB].includes(e.keyCode) || !e.isDefaultPrevented()) { var ctrlKey = e.ctrlKey || e.metaKey; var tableStore = this.context.tableStore; var keyboard = tableStore.keyboard; switch (e.keyCode) { case KeyCode.ESC: this.blur(); break; case KeyCode.TAB: { this.inTab = true; var column = this.props.column; var cellNode = !isStickySupport() && column.lock ? findCell(tableStore, getColumnKey(column), undefined, undefined, true) : this.cellNode; if (cellNode && cellNode.parentElement) { cellNode.focus(); } else { var tdNode = this.tdNode; if (tdNode) { tdNode.focus(); this.hideEditor(); } } break; } case KeyCode.PAGE_UP: case KeyCode.PAGE_DOWN: stopEvent(e); break; case KeyCode.D: if (ctrlKey === true && keyboard) this.handleKeyDownCTRLD(e); break; case KeyCode.S: if (ctrlKey === true && keyboard) this.handleKeyDownCTRLS(e); break; default: } } var editorProps = this.editorProps; if (editorProps) { var _editorProps$onKeyDow = editorProps.onKeyDown, onKeyDown = _editorProps$onKeyDow === void 0 ? noop : _editorProps$onKeyDow; onKeyDown(e); } } }, { key: "handleEditorBlur", value: function handleEditorBlur(e) { var editorProps = this.editorProps, inTab = this.inTab, inlineEdit = this.context.tableStore.inlineEdit; if (!inTab && !inlineEdit) { this.hideEditor(); } if (editorProps) { var _editorProps$onBlur = editorProps.onBlur, onBlur = _editorProps$onBlur === void 0 ? noop : _editorProps$onBlur; onBlur(e); } } /** * 多行编辑切换编辑器阻止冒泡 * @param e */ }, { key: "handleEditorClick", value: function handleEditorClick(e) { var editorProps = this.editorProps; if (editorProps) { var _editorProps$onClick = editorProps.onClick, onClick = _editorProps$onClick === void 0 ? noop : _editorProps$onClick; onClick(e); } stopEvent(e); } }, { key: "handleEditorResize", value: function handleEditorResize(width, height, target) { var _this4 = this; var editorProps = this.editorProps, cellNode = this.cellNode; var name = this.props.column.name; if (editorProps) { var _this$context = this.context, tableStore = _this$context.tableStore, dataSet = _this$context.dataSet, inlineEdit = _this$context.inlineEdit, rowHeight = _this$context.rowHeight; var currentEditRecord = tableStore.currentEditRecord; var _editorProps$onResize = editorProps.onResize, onResize = _editorProps$onResize === void 0 ? noop : _editorProps$onResize; onResize(width, height, target); var current = currentEditRecord || dataSet.current; if (current && name && (rowHeight !== height || current.getState("__column_resize_height_".concat(name)) !== undefined)) { current.setState("__column_resize_height_".concat(name), height); } if (inlineEdit) { raf(function () { tableStore.editors.forEach(function (editor) { var editorCellNode = editor.cellNode; if (editorCellNode) { editor.alignEditor(editorCellNode, editor === _this4 ? height : undefined); } }); }); } else if (cellNode) { this.alignEditor(cellNode, height); } } } }, { key: "blur", value: function blur() { var editor = this.editor; if (editor && editor.blur) { editor.blur(); } } }, { key: "focus", value: function focus() { var editor = this.editor; if (editor && editor.focus) { editor.focus(); } } }, { key: "alignEditor", value: function alignEditor(cellNode, height) { var wrap = this.wrap, editor = this.editor; var tableStore = this.context.tableStore; if (!cellNode || !cellNode.offsetParent) { var column = this.props.column; cellNode = findCell(tableStore, getColumnKey(column), undefined, undefined, true); } if (!this.cellNode && !tableStore.inlineEdit) { this.connect(); } this.cellNode = undefined; if (cellNode) { var _cellNode = cellNode, parentElement = _cellNode.parentElement; this.tdNode = parentElement; if (parentElement) { this.cellNode = cellNode; if (height === undefined) { var _cellNode2 = cellNode, offsetHeight = _cellNode2.offsetHeight; if (offsetHeight !== this.height) { this.height = offsetHeight; } } else { this.height = height; } if (!this.rendered) { this.rendered = true; } else if (wrap) { var _cellNode3 = cellNode, offsetWidth = _cellNode3.offsetWidth; var _offset = offset(cellNode, wrap.parentElement), _offset2 = _slicedToArray(_offset, 2), left = _offset2[0], top = _offset2[1]; if (this.originalCssText === undefined) { this.originalCssText = wrap.style.cssText; } var width = pxToRem(offsetWidth, true); if (width !== this.width) { this.width = width; } wrap.style.cssText = "width:".concat(width, ";").concat(transform("translate(".concat(pxToRem(left, true), ", ").concat(pxToRem(top, true), ")"))); if (editor && editor.forcePositionChanged) { editor.forcePositionChanged(); } } } } } }, { key: "hideEditor", value: function hideEditor(keep) { this.inTab = false; if (keep) { this.keep = true; } if (this.cellNode) { var tableStore = this.context.tableStore; tableStore.hideEditor(); var wrap = this.wrap; if (wrap) { if (this.originalCssText !== undefined) { wrap.style.cssText = "width:".concat(this.width, ";").concat(this.originalCssText); this.originalCssText = undefined; } } this.cellNode = undefined; if (!keep && !tableStore.inlineEdit) { this.disconnect(); } } } }, { key: "showNextEditor", value: function showNextEditor(reserve) { var name = this.props.column.name; if (name) { this.blur(); var tableStore = this.context.tableStore; if (tableStore.showNextEditor(name, reserve)) { this.alignEditor(); this.focus(); } } } /** * 渲染多行编辑单元格 */ }, { key: "renderMultiLineEditor", value: function renderMultiLineEditor() { var _this5 = this; var name = this.props.column.name; if (name) { var _this$context2 = this.context, prefixCls = _this$context2.prefixCls, dataSet = _this$context2.dataSet, inlineEdit = _this$context2.inlineEdit, rowHeight = _this$context2.rowHeight, currentEditRecord = _this$context2.tableStore.currentEditRecord; var record = currentEditRecord || dataSet.current; if (record) { var multiLineFields = []; var ref = true; dataSet.fields.forEach(function (dsField, fieldName) { var bind = dsField.get('bind', record); if (bind && bind.split('.')[0] === name) { var field = record.fields.get(fieldName) || dsField; var editor = getEditorByField(field, record); _this5.editorProps = editor.props; var _this5$editorProps = _this5.editorProps, _this5$editorProps$st = _this5$editorProps.style, style = _this5$editorProps$st === void 0 ? {} : _this5$editorProps$st, otherProps = _objectWithoutProperties(_this5$editorProps, _excluded); if (rowHeight !== 'auto') { style.height = pxToRem(rowHeight); } var newEditorProps = _objectSpread(_objectSpread({}, otherProps), {}, { style: style, ref: ref ? _this5.saveRef : undefined, record: record, name: fieldName, onKeyDown: _this5.handleEditorKeyDown, onEnterDown: _this5.handleEditorKeyEnterDown, onClick: _this5.handleEditorClick, tabIndex: -1, showHelp: ShowHelp.none, showValidation: ShowValidation.tooltip, labelLayout: LabelLayout.none, // 目前测试inline时候需要放开限制 _inTable: !inlineEdit, preventRenderer: true }); ref = false; var label = field.get('label', record); var key = "".concat(record.index, "-multi-").concat(fieldName); multiLineFields.push( /*#__PURE__*/React.createElement(Row, { key: key, className: "".concat(prefixCls, "-multi") }, label && /*#__PURE__*/React.createElement(Col, { span: 8, className: "".concat(prefixCls, "-multi-label") }, label), /*#__PURE__*/React.createElement(Col, { span: label ? 16 : 24, className: "".concat(prefixCls, "-multi-value") }, /*#__PURE__*/cloneElement(editor, newEditorProps)))); } }); if (multiLineFields.length) { return /*#__PURE__*/React.createElement("div", null, multiLineFields); } } } } }, { key: "renderEditor", value: function renderEditor() { var column = this.props.column; var name = column.name; if (name) { var _this$context3 = this.context, dataSet = _this$context3.dataSet, pristine = _this$context3.pristine, inlineEdit = _this$context3.inlineEdit, _this$context3$tableS = _this$context3.tableStore, currentEditRecord = _this$context3$tableS.currentEditRecord, currentEditorName = _this$context3$tableS.currentEditorName, getColumnTagRenderer = _this$context3$tableS.getColumnTagRenderer, rowHeight = _this$context3.rowHeight; var record = currentEditRecord || dataSet.current; var field = dataSet.getField(name); // 多行编辑拦截返回渲染器 if (!pristine && field && field.get('multiLine', record)) { return this.renderMultiLineEditor(); } var cellEditor = getEditorByColumnAndRecord(column, record); if (!pristine && /*#__PURE__*/isValidElement(cellEditor) && !isInCellEditor(cellEditor)) { this.editorProps = cellEditor.props; var height = this.height; var _this$editorProps = this.editorProps, _this$editorProps$sty = _this$editorProps.style, style = _this$editorProps$sty === void 0 ? {} : _this$editorProps$sty, editorTagRenderer = _this$editorProps.tagRenderer, otherProps = _objectWithoutProperties(_this$editorProps, _excluded2); var tagRenderer = editorTagRenderer || getColumnTagRenderer(column); if (height !== undefined) { style.height = pxToRem(height, true); } var newEditorProps = _objectSpread(_objectSpread({}, otherProps), {}, { style: style, ref: this.saveRef, record: record, name: name, tagRenderer: tagRenderer, onKeyDown: this.handleEditorKeyDown, onEnterDown: isTextArea(cellEditor) ? undefined : this.handleEditorKeyEnterDown, onBlur: this.handleEditorBlur, tabIndex: currentEditorName ? 0 : -1, showHelp: ShowHelp.none, showValidation: ShowValidation.tooltip, labelLayout: LabelLayout.none, // 目前测试inline时候需要放开限制 _inTable: !inlineEdit, preventRenderer: true }); if (isTextArea(cellEditor)) { var resize = newEditorProps.resize || cellEditor.props.resize || ResizeType.vertical; newEditorProps.resize = resize; if (resize !== ResizeType.none) { newEditorProps.onResize = this.handleEditorResize; if (rowHeight === 'auto') { newEditorProps.autoSize = true; } } } return /*#__PURE__*/cloneElement(cellEditor, newEditorProps); } } this.cellNode = undefined; } }, { key: "render", value: function render() { var _this6 = this; if (this.rendered) { var editor = this.renderEditor(); if (editor) { var lock = this.props.column.lock; var prefixCls = this.context.prefixCls; var props = { className: classNames("".concat(prefixCls, "-editor"), _defineProperty({}, "".concat(prefixCls, "-editor-lock"), isStickySupport() && lock)) }; return /*#__PURE__*/React.createElement("div", _extends({}, props, { ref: this.saveWrap }), editor); } var tableStore = this.context.tableStore; if (!tableStore.inlineEdit) { runInAction(function () { _this6.rendered = false; }); } } return null; } }], [{ key: "contextType", get: function get() { return TableContext; } }]); return TableEditor; }(Component); TableEditor.displayName = 'TableEditor'; __decorate([observable], TableEditor.prototype, "height", void 0); __decorate([observable], TableEditor.prototype, "rendered", void 0); __decorate([autobind], TableEditor.prototype, "handleWindowResize", null); __decorate([autobind], TableEditor.prototype, "handleWindowClick", null); __decorate([autobind], TableEditor.prototype, "saveRef", null); __decorate([autobind], TableEditor.prototype, "saveWrap", null); __decorate([autobind], TableEditor.prototype, "handleEditorKeyEnterDown", null); __decorate([autobind], TableEditor.prototype, "handleKeyDownCTRLD", null); __decorate([autobind], TableEditor.prototype, "handleKeyDownCTRLS", null); __decorate([autobind], TableEditor.prototype, "handleEditorKeyDown", null); __decorate([autobind], TableEditor.prototype, "handleEditorBlur", null); __decorate([autobind], TableEditor.prototype, "handleEditorClick", null); __decorate([autobind], TableEditor.prototype, "handleEditorResize", null); __decorate([action], TableEditor.prototype, "alignEditor", null); __decorate([autobind], TableEditor.prototype, "hideEditor", null); TableEditor = __decorate([observer], TableEditor); export default TableEditor; //# sourceMappingURL=TableEditor.js.map