choerodon-ui
Version:
An enterprise-class UI design language and React-based implementation
330 lines (278 loc) • 11 kB
JavaScript
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 _get from "@babel/runtime/helpers/get";
import _inherits from "@babel/runtime/helpers/inherits";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
function _createSuper(Derived) {
function isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
return true;
} catch (e) {
return false;
}
}
return function () {
var Super = _getPrototypeOf(Derived),
result;
if (isNativeReflectConstruct()) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
};
}
import { __decorate } from "tslib";
import React from 'react';
import PropTypes from 'prop-types';
import { findDOMNode } from 'react-dom';
import classes from 'component-classes';
import { action, autorun, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import isString from 'lodash/isString';
import isEqual from 'lodash/isEqual';
import noop from 'lodash/noop';
import KeyCode from '../../../es/_util/KeyCode';
import { FormField } from '../field/FormField';
import autobind from '../_util/autobind';
import { LabelLayout } from '../form/enum';
var CodeMirror;
if (typeof window !== 'undefined') {
// eslint-disable-next-line global-require
CodeMirror = require('react-codemirror2').Controlled;
}
var defaultCodeMirrorOptions = {
theme: 'neat',
lineNumbers: true,
lint: true,
gutters: ['CodeMirror-lint-markers']
};
var CodeArea =
/*#__PURE__*/
function (_FormField) {
_inherits(CodeArea, _FormField);
var _super = _createSuper(CodeArea);
function CodeArea(props, content) {
var _this;
_classCallCheck(this, CodeArea);
_this = _super.call(this, props, content);
_this.cmOptions = _this.getCodeMirrorOptions();
/**
* 编辑器失去焦点时,调用父类方法,同步DataSet中的内容
*
* @memberof CodeArea
*/
_this.handleCodeMirrorBlur = action(function (codeMirrorInstance) {
var formatter = _this.props.formatter; // 更新DataSet的值之前,先去拿到原始的raw格式
var codeMirrorText = codeMirrorInstance.getValue();
var value = formatter ? formatter.getRaw(codeMirrorText) : codeMirrorText;
_this.midText = value;
_this.setValue(value);
_this.isFocused = false;
_this.isFocus = false;
var element = _this.wrapper || findDOMNode(_assertThisInitialized(_this));
if (element) {
classes(element).remove("".concat(_this.prefixCls, "-focused"));
}
});
/**
* 在CodeMirror编辑器实例挂载前添加额外配置
*
* @memberof CodeArea
*/
_this.handleCodeMirrorDidMount = function (editor, value, cb) {
var _this$props = _this.props,
formatter = _this$props.formatter,
style = _this$props.style,
formatHotKey = _this$props.formatHotKey,
unFormatHotKey = _this$props.unFormatHotKey,
editorDidMount = _this$props.editorDidMount;
var _ref = style || {},
_ref$width = _ref.width,
width = _ref$width === void 0 ? '100%' : _ref$width,
_ref$height = _ref.height,
height = _ref$height === void 0 ? 100 : _ref$height;
var options = {
Tab: function Tab(cm) {
if (cm.somethingSelected()) {
cm.indentSelection('add'); // 有选中内容时整体缩进
} else {
// 使用空格代替缩进
var spaces = Array(cm.getOption('indentUnit') + 1).join(' ');
cm.replaceSelection(spaces);
}
}
};
if (formatter) {
if (formatHotKey) {
// default: 'Alt-F'
options[formatHotKey] = function (cm) {
return cm.setValue(formatter.getFormatted(cm.getValue()));
};
}
if (unFormatHotKey) {
// default: 'Alt-R'
options[unFormatHotKey] = function (cm) {
return cm.setValue(formatter.getRaw(cm.getValue()));
};
}
}
editor.setSize(width, height); // default size: ('100%', 100)
editor.setOption('extraKeys', options);
if (editorDidMount) {
editorDidMount(editor, value, cb);
}
if (_this.labelLayout === LabelLayout["float"]) {
var display = editor.display;
if (display) {
var gutters = display.gutters;
if (gutters) {
var offsetWidth = gutters.offsetWidth;
if (offsetWidth !== _this.floatLabelOffsetX) {
runInAction(function () {
_this.floatLabelOffsetX = offsetWidth;
});
}
}
}
}
};
_this.disposer = autorun(function () {
// 在绑定dataSet的情况下
// 当手动修改过codeArea里面的值以后 再使用record.set去更新值 组件不会更新
// 原因在于此时 this.text 不为 undefined 因此 getTextNode 的计算值不会进行改变 导致组件不重新渲染
// 其他的组件会对 this.text 在blur的时候进行undefined的修改 但是这个组件不能这么做
// 原因在于 record 中的值为 raw的非格式化数据 blur后因为进行了一次record数据的修改 所以再次重新那数据必然导致
// 当数据存在错误的时候 codeArea去格式化 因为格式化失败了
// 当数据不存在存在错误的时候即使特地将其去格式化也依旧会被格式化
// 因此需要使用中间变量进行处理
var formatter = _this.props.formatter;
var recordValue = _this.getValue();
var value = formatter ? formatter.getFormatted(recordValue) : recordValue; // 判断跟中间值是否一致 通过这个判断 数据的来源是 blur的时候设置的值 还是直接通过外部进行修改的值
if (recordValue !== _this.midText) {
_this.setText(value);
}
});
return _this;
}
_createClass(CodeArea, [{
key: "componentWillUnmount",
value: function componentWillUnmount() {
this.disposer();
}
}, {
key: "handleBeforeChange",
value: function handleBeforeChange(_editor, _data, value) {
this.setText(value);
}
}, {
key: "handleCodeMirrorKeyDown",
value: function handleCodeMirrorKeyDown(cm, e) {
var _this$props2 = this.props,
_this$props2$onKeyDow = _this$props2.onKeyDown,
onKeyDown = _this$props2$onKeyDow === void 0 ? noop : _this$props2$onKeyDow,
_this$props2$onEnterD = _this$props2.onEnterDown,
onEnterDown = _this$props2$onEnterD === void 0 ? noop : _this$props2$onEnterD;
switch (e.keyCode) {
case KeyCode.ENTER:
onEnterDown(e);
break;
case KeyCode.ESC:
cm.getInputField().blur();
break;
default:
}
onKeyDown(e);
}
}, {
key: "getCodeMirrorOptions",
value: function getCodeMirrorOptions() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props.options;
return _objectSpread({}, defaultCodeMirrorOptions, {}, options);
}
}, {
key: "getOmitPropsKeys",
value: function getOmitPropsKeys() {
return _get(_getPrototypeOf(CodeArea.prototype), "getOmitPropsKeys", this).call(this).concat(['formatHotKey', 'unFormatHotKey', 'editorDidMount']);
}
}, {
key: "getOtherProps",
value: function getOtherProps() {
var otherProps = _get(_getPrototypeOf(CodeArea.prototype), "getOtherProps", this).call(this);
delete otherProps.onChange;
otherProps.onKeyDown = this.handleCodeMirrorKeyDown;
return otherProps;
}
}, {
key: "componentWillReceiveProps",
value: function componentWillReceiveProps(nextProps, nextContext) {
var options = nextProps.options;
if (!isEqual(options, this.props.options)) {
this.cmOptions = this.getCodeMirrorOptions(options);
}
_get(_getPrototypeOf(CodeArea.prototype), "componentWillReceiveProps", this).call(this, nextProps, nextContext);
}
}, {
key: "renderWrapper",
value: function renderWrapper() {
if (CodeMirror) {
this.cmOptions.readOnly = this.disabled ? 'nocursor' : this.readOnly;
var text = this.getTextNode();
return React.createElement("div", _extends({}, this.getWrapperProps()), React.createElement("label", null, React.createElement(CodeMirror, _extends({}, this.getOtherProps(), {
value: isString(text) ? text : this.processValue(this.getValue()),
options: this.cmOptions,
onBeforeChange: this.handleBeforeChange,
onBlur: this.handleCodeMirrorBlur,
editorDidMount: this.handleCodeMirrorDidMount
})), this.renderFloatLabel()));
}
}
}, {
key: "setText",
value: function setText(text) {
this.text = text;
}
}, {
key: "getTextNode",
value: function getTextNode(value) {
return this.text === undefined ? _get(_getPrototypeOf(CodeArea.prototype), "getTextNode", this).call(this, value) || '' : this.text;
}
}, {
key: "processValue",
value: function processValue(value) {
var text = _get(_getPrototypeOf(CodeArea.prototype), "processValue", this).call(this, value);
var formatter = this.props.formatter;
return formatter && isString(text) ? formatter.getFormatted(text) : text;
}
}]);
return CodeArea;
}(FormField);
CodeArea.displayName = 'CodeArea';
CodeArea.propTypes = _objectSpread({
options: PropTypes.object,
formatHotKey: PropTypes.string,
unFormatHotKey: PropTypes.string,
formatter: PropTypes.object,
editorDidMount: PropTypes.func
}, FormField.propTypes);
CodeArea.defaultProps = _objectSpread({}, FormField.defaultProps, {
suffixCls: 'code-area',
formatHotKey: 'Alt-F',
unFormatHotKey: 'Alt-R'
});
__decorate([observable], CodeArea.prototype, "text", void 0);
__decorate([autobind], CodeArea.prototype, "handleBeforeChange", null);
__decorate([autobind], CodeArea.prototype, "handleCodeMirrorKeyDown", null);
__decorate([action], CodeArea.prototype, "setText", null);
CodeArea = __decorate([observer], CodeArea);
export default CodeArea;
//# sourceMappingURL=CodeArea.js.map