zent
Version:
一套前端设计语言和基于React的实现
360 lines (270 loc) • 9.89 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ControlGroup = exports.DesignEditor = undefined;
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _classnames = require('classnames');
var _classnames2 = _interopRequireDefault(_classnames);
var _assign3 = require('lodash/assign');
var _assign4 = _interopRequireDefault(_assign3);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var NOT_EVENT_MSG = 'onInputChange expects an `Event` with { target: { name, value } } as argument';
var DesignEditor = exports.DesignEditor = function (_ref) {
(0, _inherits3['default'])(DesignEditor, _ref);
(0, _createClass3['default'])(DesignEditor, null, [{
key: 'validate',
// value 的验证函数
// eslint-disable-next-line
// 以下属性需要子类重写
// 组件的类型
value: function validate(value, prevValue, changedProps) {
return new Promise(function (resolve) {
return resolve({});
});
}
// 添加组件实例时的初始值
// 组件的描述
}]);
function DesignEditor(props) {
(0, _classCallCheck3['default'])(this, DesignEditor);
var _this = (0, _possibleConstructorReturn3['default'])(this, (DesignEditor.__proto__ || Object.getPrototypeOf(DesignEditor)).call(this, props));
_this.onInputChange = function (evt) {
// 如果抛出来的不是 Event 对象,直接丢给 onChange
if (!isEventLikeObject(evt)) {
throw new Error(NOT_EVENT_MSG);
}
var onChange = _this.props.onChange;
var target = evt.target;
var name = target.name,
type = target.type;
var value = target.value;
if (type === 'checkbox') {
value = target.checked;
}
onChange((0, _defineProperty3['default'])({}, name, value));
_this.setMetaProperty(name, 'dirty');
};
_this.onCustomInputChange = function (name) {
return function (value) {
var onChange = _this.props.onChange;
onChange((0, _defineProperty3['default'])({}, name, value));
_this.setMetaProperty(name, 'dirty');
};
};
_this.onInputBlur = function (evt) {
// 如果抛出来的不是 Event 对象,直接丢给 onChange
if (!isEventLikeObject(evt)) {
throw new Error(NOT_EVENT_MSG);
}
var name = evt.target.name;
_this.onCustomInputBlur(name);
};
_this.onCustomInputBlur = function (name) {
_this.setMetaProperty(name, 'touched');
_this.validateValue();
};
_this.state = (0, _assign4['default'])({}, _this.state, {
meta: {}
});
_this.validateValue();
return _this;
}
/**
* 通用的 Input 元素 onChange 回调函数
*
* 适用于 Input, Checkbox, Select, Radio
*/
/**
* 有些组件的 onChange 事件抛出来的不是 Event 对象
*
* 适用于 Slider, Switch, DatePicker 以及其它自定义组件
*/
/**
* 处理 Input 元素的 blur 事件。
*/
/**
* 有些组件没有 onBlur 事件,用这个函数处理
*/
(0, _createClass3['default'])(DesignEditor, [{
key: 'getMetaProperty',
/**
* 获取 Field 的 meta 属性,包括 dirty, touched 等
* @param {string} name Field 名字
* @param {string} property meta 属性名字
*/
value: function getMetaProperty(name, property) {
var meta = this.state.meta;
return !!(meta && meta[name] && meta[name][property]);
}
/**
* 设置 Field 的 meta 属性
* @param {string} name Field 名字
* @param {string} property meta 属性名字
* @param {any} state 属性的值
*/
}, {
key: 'setMetaProperty',
value: function setMetaProperty(name, property) {
var state = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var meta = this.state.meta;
var states = meta[name];
if (!states || states[property] !== state) {
this.setState({
meta: (0, _assign4['default'])({}, meta, (0, _defineProperty3['default'])({}, name, (0, _assign4['default'])({}, states, (0, _defineProperty3['default'])({}, property, state))))
});
}
}
/**
* 返回表单是否有错误
*/
}, {
key: 'isValid',
value: function isValid() {
var validation = this.props.validation;
return Object.keys(validation).length > 0;
}
}, {
key: 'isInvalid',
value: function isInvalid() {
return !this.isValid();
}
/**
* 触发一次表单校验
*/
}, {
key: 'validateValue',
value: function validateValue() {
var _props = this.props,
value = _props.value,
design = _props.design;
design.validateComponentValue(value, value, []).then(function (errors) {
var id = design.getUUID(value);
design.setValidation((0, _defineProperty3['default'])({}, id, errors));
});
}
}]);
return DesignEditor;
}(_react.PureComponent || _react.Component);
/**
* 表单每个域的基础样式
*/
DesignEditor.propTypes = {
value: _propTypes2['default'].object,
onChange: _propTypes2['default'].func.isRequired,
// 验证状态
validation: _propTypes2['default'].object.isRequired,
// 是否强制显示所有错误
showError: _propTypes2['default'].bool.isRequired,
// 用来和 Design 交互
design: _propTypes2['default'].object.isRequired,
// 自定义配置
globalConfig: _propTypes2['default'].object
};
DesignEditor.designType = 'unknown';
DesignEditor.designDescription = '未知组件';
DesignEditor.getInitialValue = function () {};
var ControlGroup = exports.ControlGroup = function (_ref2) {
(0, _inherits3['default'])(ControlGroup, _ref2);
function ControlGroup() {
(0, _classCallCheck3['default'])(this, ControlGroup);
return (0, _possibleConstructorReturn3['default'])(this, (ControlGroup.__proto__ || Object.getPrototypeOf(ControlGroup)).apply(this, arguments));
}
(0, _createClass3['default'])(ControlGroup, [{
key: 'render',
value: function render() {
var _props2 = this.props,
className = _props2.className,
prefix = _props2.prefix,
showError = _props2.showError,
error = _props2.error,
showLabel = _props2.showLabel,
label = _props2.label,
labelAlign = _props2.labelAlign,
helpDesc = _props2.helpDesc,
required = _props2.required,
children = _props2.children,
focusOnLabelClick = _props2.focusOnLabelClick;
var errorVisible = showError && error;
return _react2['default'].createElement(
'div',
{
className: (0, _classnames2['default'])(prefix + '-design-editor__control-group', className, {
'has-error': errorVisible
})
},
_react2['default'].createElement(focusOnLabelClick ? 'label' : 'div', {
className: prefix + '-design-editor__control-group-container'
}, showLabel ? _react2['default'].createElement(
'div',
{
className: (0, _classnames2['default'])(prefix + '-design-editor__control-group-label', labelAlign && prefix + '-design-editor__control-group-label--' + labelAlign)
},
required && _react2['default'].createElement(
'span',
{
className: prefix + '-design-editor__control-group-required-star'
},
'*'
),
label
) : null, _react2['default'].createElement(
'div',
{ className: prefix + '-design-editor__control-group-control' },
children,
helpDesc && _react2['default'].createElement(
'div',
{
className: prefix + '-design-editor__control-group-help-desc'
},
helpDesc
)
)),
errorVisible && _react2['default'].createElement(
'div',
{ className: prefix + '-design-editor__control-group-error' },
error
)
);
}
}]);
return ControlGroup;
}(_react.PureComponent || _react.Component);
ControlGroup.propTypes = {
showError: _propTypes2['default'].bool,
error: _propTypes2['default'].node,
showLabel: _propTypes2['default'].bool,
helpDesc: _propTypes2['default'].string,
label: _propTypes2['default'].node,
// 自定义label对齐方式
labelAlign: _propTypes2['default'].string,
// 点击 label 区域时是否 focus 到 control 的 input 上
focusOnLabelClick: _propTypes2['default'].bool,
required: _propTypes2['default'].bool,
className: _propTypes2['default'].string,
prefix: _propTypes2['default'].string
};
ControlGroup.defaultProps = {
required: false,
showError: false,
showLabel: true,
focusOnLabelClick: true,
error: '',
prefix: 'zent'
};
function isEventLikeObject(evt) {
return evt && evt.target && evt.target.name && evt.preventDefault && evt.stopPropagation;
}