Skip to content

Commit

Permalink
fix: upgrade rc-form and refactor to be compatible with react@16
Browse files Browse the repository at this point in the history
  • Loading branch information
benjycui committed Oct 31, 2017
1 parent 2a14b46 commit 7ff7519
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 70 deletions.
43 changes: 3 additions & 40 deletions components/form/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import classNames from 'classnames';
import createDOMForm from 'rc-form/lib/createDOMForm';
import PureRenderMixin from 'rc-util/lib/PureRenderMixin';
import omit from 'omit.js';
import createReactClass from 'create-react-class';
import warning from '../_util/warning';
import FormItem from './FormItem';
import { FIELD_META_PROP } from './constants';
import { FIELD_META_PROP, FIELD_DATA_PROP } from './constants';

export interface FormCreateOption<T> {
onFieldsChange?: (props: T, fields: Array<any>) => void;
Expand Down Expand Up @@ -149,48 +148,12 @@ export default class Form extends React.Component<FormProps, any> {
static Item = FormItem;

static create = function<TOwnProps>(options: FormCreateOption<TOwnProps> = {}): ComponentDecorator<TOwnProps> {
const formWrapper = createDOMForm({
return createDOMForm({
fieldNameProp: 'id',
...options,
fieldMetaProp: FIELD_META_PROP,
fieldDataProp: FIELD_DATA_PROP,
});

/* eslint-disable react/prefer-es6-class */
return (Component) => formWrapper(createReactClass({
propTypes: {
form: PropTypes.object.isRequired,
},
childContextTypes: {
form: PropTypes.object.isRequired,
},
getChildContext() {
return {
form: this.props.form,
};
},
componentWillMount() {
this.__getFieldProps = this.props.form.getFieldProps;
},
deprecatedGetFieldProps(name, option) {
warning(
false,
'`getFieldProps` is not recommended, please use `getFieldDecorator` instead, ' +
'see: https://u.ant.design/get-field-decorator',
);
return this.__getFieldProps(name, option);
},
render() {
this.props.form.getFieldProps = this.deprecatedGetFieldProps;

const withRef: any = {};
if (options.withRef) {
withRef.ref = 'formWrappedComponent';
} else if (this.props.wrappedComponentRef) {
withRef.ref = this.props.wrappedComponentRef;
}
return <Component {...this.props} {...withRef} />;
},
}));
};

constructor(props) {
Expand Down
58 changes: 29 additions & 29 deletions components/form/FormItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import Animate from 'rc-animate';
import PureRenderMixin from 'rc-util/lib/PureRenderMixin';
import Row from '../grid/row';
import Col, { ColProps } from '../grid/col';
import { WrappedFormUtils } from './Form';
import { FIELD_META_PROP } from './constants';
import warning from '../_util/warning';
import { FIELD_META_PROP, FIELD_DATA_PROP } from './constants';

export interface FormItemProps {
prefixCls?: string;
className?: string;
id?: string;
label?: React.ReactNode;
labelCol?: ColProps;
Expand All @@ -20,14 +20,12 @@ export interface FormItemProps {
extra?: React.ReactNode;
validateStatus?: 'success' | 'warning' | 'error' | 'validating';
hasFeedback?: boolean;
className?: string;
required?: boolean;
style?: React.CSSProperties;
colon?: boolean;
}

export interface FormItemContext {
form: WrappedFormUtils;
vertical: boolean;
}

Expand All @@ -53,7 +51,6 @@ export default class FormItem extends React.Component<FormItemProps, any> {
};

static contextTypes = {
form: PropTypes.object,
vertical: PropTypes.bool,
};

Expand All @@ -72,10 +69,11 @@ export default class FormItem extends React.Component<FormItemProps, any> {
}

getHelpMsg() {
const context = this.context;
const props = this.props;
if (props.help === undefined && context.form) {
return this.getId() ? (context.form.getFieldError(this.getId()) || []).join(', ') : '';
const onlyControl = this.getOnlyControl();
if (props.help === undefined && onlyControl) {
const errors = this.getField().errors;
return errors ? errors.map(e => e.message).join(', ') : '';
}

return props.help;
Expand All @@ -97,7 +95,7 @@ export default class FormItem extends React.Component<FormItemProps, any> {
if (!child.props) {
continue;
}
if (FIELD_META_PROP in child.props) {
if (FIELD_META_PROP in child.props) { // And means FIELD_DATA_PROP in chidl.props, too.
controls.push(child);
} else if (child.props.children) {
controls = controls.concat(this.getControls(child.props.children, recursively));
Expand All @@ -124,6 +122,10 @@ export default class FormItem extends React.Component<FormItemProps, any> {
return this.getChildProp(FIELD_META_PROP);
}

getField() {
return this.getChildProp(FIELD_DATA_PROP);
}

renderHelp() {
const prefixCls = this.props.prefixCls;
const help = this.getHelpMsg();
Expand All @@ -147,42 +149,40 @@ export default class FormItem extends React.Component<FormItemProps, any> {
}

getValidateStatus() {
const { isFieldValidating, getFieldError, getFieldValue } = this.context.form;
const fieldId = this.getId();
if (!fieldId) {
const onlyControl = this.getOnlyControl();
if (!onlyControl) {
return '';
}
if (isFieldValidating(fieldId)) {
const field = this.getField();
if (field.validating) {
return 'validating';
}
if (!!getFieldError(fieldId)) {
if (field.errors) {
return 'error';
}
const fieldValue = getFieldValue(fieldId);
const fieldValue = 'value' in field ? field.value : this.getMeta().initialValue;
if (fieldValue !== undefined && fieldValue !== null && fieldValue !== '') {
return 'success';
}
return '';
}

renderValidateWrapper(c1, c2, c3) {
let classes = '';
const form = this.context.form;
const props = this.props;
const validateStatus = (props.validateStatus === undefined && form) ?
const onlyControl = this.getOnlyControl;
const validateStatus = (props.validateStatus === undefined && onlyControl) ?
this.getValidateStatus() :
props.validateStatus;

let classes = '';
if (validateStatus) {
classes = classNames(
{
'has-feedback': props.hasFeedback || validateStatus === 'validating',
'has-success': validateStatus === 'success',
'has-warning': validateStatus === 'warning',
'has-error': validateStatus === 'error',
'is-validating': validateStatus === 'validating',
},
);
classes = classNames({
'has-feedback': props.hasFeedback || validateStatus === 'validating',
'has-success': validateStatus === 'success',
'has-warning': validateStatus === 'warning',
'has-error': validateStatus === 'error',
'is-validating': validateStatus === 'validating',
});
}
return (
<div className={`${this.props.prefixCls}-item-control ${classes}`}>
Expand All @@ -209,9 +209,9 @@ export default class FormItem extends React.Component<FormItemProps, any> {
if (required !== undefined) {
return required;
}
if (this.context.form) {
if (this.getOnlyControl()) {
const meta = this.getMeta() || {};
const validate = (meta.validate || []);
const validate = meta.validate || [];

return validate.filter((item) => !!item.rules).some((item) => {
return item.rules.some((rule) => rule.required);
Expand Down
Loading

0 comments on commit 7ff7519

Please sign in to comment.