UNPKG

zarm-web

Version:
255 lines (222 loc) 6.53 kB
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } import React, { PureComponent, createRef } from 'react'; import PropTypes from 'prop-types'; import Schema from 'async-validator'; import classnames from 'classnames'; import { FormContext, FormItemContext } from './createContext'; import Icon from '../icon'; import { noop } from '../utils'; import Transition from '../transition'; Schema.warning = noop; class FormItem extends PureComponent { constructor(props) { super(props); this.initialData = void 0; this.validateMessage = void 0; this.formItemInstance = void 0; this.handleFieldBlur = () => { Promise.resolve('blur').then(this.validateItem.bind(this)); }; this.handleFieldChange = () => { Promise.resolve('change').then(this.validateItem.bind(this)); }; this.formItemInstance = createRef(); this.validateMessage = ''; this.state = { validateStatus: '' }; } componentDidMount() { this.initialData = this.recordInitialData(); this.addFormItem(); } componentWillUnmount() { this.removeFormItem(); } get fieldValue() { const { model } = this.context; const { prop } = this.props; const propArr = prop.split('.'); return propArr.length > 1 ? model[propArr[0]][propArr[1]] : model[prop]; } getRules() { const { rules, prop } = this.props; const { rules: contextRules } = this.context; let formRules = contextRules; const formItemRules = rules; formRules = formRules ? formRules[prop] : []; return [].concat(formItemRules || formRules || []); } getFilteredRules(trigger) { const rules = this.getRules(); const filteredRules = rules.filter(rule => !rule.trigger || rule.trigger.includes(trigger)); return filteredRules; } getId() { const { children } = this.props; if (children.props) { return children.props.id; } } getControlNode() { return this.formItemInstance.current; } validateItem(trigger, callback = () => {}) { const { prop } = this.props; const rules = this.getFilteredRules(trigger); if (!rules || rules.length === 0) { return true; } const descriptor = { [prop]: rules }; const validator = new Schema(descriptor); const model = { [prop]: this.fieldValue }; validator.validate(model, { firstFields: true }, errors => { this.validateMessage = errors ? errors[0].message : ''; this.setState({ validateStatus: !errors ? 'success' : 'error' }, () => { callback(this.validateMessage); }); }); } resetItem() { const { prop } = this.props; const { model } = this.context; this.setState({ validateStatus: '' }); this.validateMessage = ''; if (Array.isArray(this.fieldValue) && this.fieldValue.length > 0) { model[prop] = []; } else { model[prop] = this.initialData; } } recordInitialData() { const { model } = this.context; if (!model) { return; } const { prop } = this.props; const value = model[prop]; return value === undefined ? undefined : JSON.parse(JSON.stringify(value)); } addFormItem() { const { fields } = this.context; if (this.props.prop) { fields.push(this); } } removeFormItem() { const { fields } = this.context; if (this.props.prop) { const index = fields.indexOf(this); fields.splice(index, 1); } } renderLabel() { const { id, label, prefixCls, prop, rules, required } = this.props; const { labelWidth } = this.context; const styleObj = {}; const star = required || prop || rules ? React.createElement("span", { className: `${prefixCls}-item--required` }, React.createElement(Icon, { type: "required" })) : null; if (labelWidth) { styleObj.width = parseInt(labelWidth, 10); } return 'label' in this.props ? React.createElement("label", { className: "za-form-item__label", style: _objectSpread({}, styleObj), htmlFor: id || this.getId() }, star, label) : null; } render() { const { validateStatus } = this.state; const { className, children, style, prefixCls } = this.props; const cls = classnames({ [`${prefixCls}-item`]: true, 'has-error': validateStatus === 'error', [className]: !!className }); const controlCls = classnames({ [`${prefixCls}-item__control`]: true }); return React.createElement(FormItemContext.Provider, { value: this }, React.createElement("div", { className: cls, style: style, ref: this.formItemInstance }, this.renderLabel(), React.createElement("div", { className: controlCls, onBlur: this.handleFieldBlur, onChange: this.handleFieldChange }, children, React.createElement(Transition, { name: "scaleDown", visible: validateStatus === 'error' }, React.createElement("div", { className: `${prefixCls}-item__error` }, this.validateMessage))))); } } FormItem.contextType = FormContext; FormItem.defaultProps = { prefixCls: 'za-form', required: false }; FormItem.propTypes = { prefixCls: PropTypes.string, required: PropTypes.bool }; export default FormItem;