forked from ant-design/ant-design
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathForm.tsx
175 lines (156 loc) · 5.61 KB
/
Form.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import React from 'react';
import { PropTypes } from 'react';
import classNames from 'classnames';
import PureRenderMixin from 'react-addons-pure-render-mixin';
import omit from 'omit.js';
import warning from 'warning';
import assign from 'object-assign';
import FormItem from './FormItem';
import createDOMForm from 'rc-form/lib/createDOMForm';
import { FIELD_META_PROP } from './constants';
export interface FormCreateOption {
onFieldsChange?: (props: any, fields: Array<any>) => void;
mapPropsToFields?: (props: any) => void;
withRef?: boolean;
}
export interface FormProps {
horizontal?: boolean;
inline?: boolean;
vertical?: boolean;
form?: WrappedFormUtils;
onSubmit?: React.FormEventHandler;
style?: React.CSSProperties;
className?: string;
prefixCls?: string;
}
// function create
export type WrappedFormUtils = {
/** 获取一组输入控件的值,如不传入参数,则获取全部组件的值 */
getFieldsValue(fieldNames?: Array<string>): Object;
/** 获取一个输入控件的值*/
getFieldValue(fieldName: string): any;
/** 设置一组输入控件的值*/
setFieldsValue(obj: Object): void;
/** 设置一组输入控件的值*/
setFields(obj: Object): void;
/** 校验并获取一组输入域的值与 Error */
validateFields(fieldNames: Array<string>, options: Object, callback: (erros: any, values: any) => void): any;
validateFields(fieldNames: Array<string>, callback: (erros: any, values: any) => void): any;
validateFields(options: Object, callback: (erros: any, values: any) => void): any;
validateFields(callback: (erros: any, values: any) => void): any;
/** 与 `validateFields` 相似,但校验完后,如果校验不通过的菜单域不在可见范围内,则自动滚动进可见范围 */
validateFieldsAndScroll(
fieldNames?: Array<string>,
options?: Object,
callback?: (erros: any, values: any) => void
): void;
/** 获取某个输入控件的 Error */
getFieldError(name: string): Object[];
/** 判断一个输入控件是否在校验状态*/
isFieldValidating(name: string): boolean;
/** 重置一组输入控件的值与状态,如不传入参数,则重置所有组件 */
resetFields(names?: Array<string>): void;
getFieldDecorator(id: string, options: {
/** 子节点的值的属性,如 Checkbox 的是 'checked' */
valuePropName?: string;
/** 子节点的初始值,类型、可选值均由子节点决定 */
initialValue?: any;
/** 收集子节点的值的时机 */
trigger?: string;
/** 可以把 onChange 的参数转化为控件的值,例如 DatePicker 可设为:(date, dateString) => dateString */
getValueFromEvent?: (...args) => any;
/** 校验子节点值的时机 */
validateTrigger?: string;
/** 校验规则,参见 [async-validator](https://github.com/yiminghe/async-validator) */
rules?: Array<any>;
/** 是否和其他控件互斥,特别用于 Radio 单选控件 */
exclusive?: boolean;
}): (node: React.ReactNode) => React.ReactNode;
}
export interface FormComponentProps {
form?: WrappedFormUtils;
}
export class FormComponent extends React.Component<FormComponentProps, {}> {
}
export interface ComponentDecorator {
<T extends (typeof FormComponent)>(component: T): T;
}
export default class Form extends React.Component<FormProps, any> {
static defaultProps = {
prefixCls: 'ant-form',
onSubmit(e) {
e.preventDefault();
},
};
static propTypes = {
prefixCls: React.PropTypes.string,
vertical: React.PropTypes.bool,
horizontal: React.PropTypes.bool,
inline: React.PropTypes.bool,
children: React.PropTypes.any,
onSubmit: React.PropTypes.func,
};
static Item = FormItem;
static create = (options?: FormCreateOption): ComponentDecorator => {
const formWrapper = createDOMForm(assign({}, options, {
fieldNameProp: 'id',
fieldMetaProp: FIELD_META_PROP,
}));
/* eslint-disable react/prefer-es6-class */
return (Component) => formWrapper(React.createClass({
propTypes: {
form: PropTypes.object.isRequired,
},
childContextTypes: {
form: PropTypes.object.isRequired,
},
getChildContext() {
return {
form: this.props.form,
};
},
render() {
const getFieldProps = this.props.form.getFieldProps;
function deprecatedGetFieldProps(name, option) {
warning(
false,
'`getFieldProps` is deprecated and will be removed in future, please use `getFieldDecorator` instead'
);
return getFieldProps(name, option);
}
this.props.form.getFieldProps = deprecatedGetFieldProps;
const withRef: any = {};
if (options && options.withRef) {
withRef.ref = 'formWrappedComponent';
}
return <Component {...this.props} {...withRef} />;
},
}));
};
constructor(props) {
super(props);
warning(!props.form, 'It is unnecessary to pass `form` to `Form` after [email protected].');
}
shouldComponentUpdate(...args) {
return PureRenderMixin.shouldComponentUpdate.apply(this, args);
}
render() {
const { prefixCls, className, inline, horizontal, vertical } = this.props;
const formClassName = classNames({
[`${prefixCls}`]: true,
[`${prefixCls}-horizontal`]: horizontal,
[`${prefixCls}-vertical`]: vertical,
[`${prefixCls}-inline`]: inline,
[className]: !!className,
});
const formProps = omit(this.props, [
'prefixCls',
'className',
'inline',
'horizontal',
'vertical',
'form',
]);
return <form {...formProps} className={formClassName} />;
}
}