Merge pull request #15276 from DiamondYuan/form-prop

feat: Form support set colon
This commit is contained in:
偏右 2019-03-08 14:50:31 +08:00 committed by GitHub
commit d02ec78567
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 187 additions and 19 deletions

View File

@ -38,8 +38,18 @@ export interface FormProps extends React.FormHTMLAttributes<HTMLFormElement> {
className?: string;
prefixCls?: string;
hideRequiredMark?: boolean;
/**
* @since 3.14.0
*/
labelCol?: ColProps;
/**
* @since 3.14.0
*/
wrapperCol?: ColProps;
/**
* @since 3.15.0
*/
colon?: boolean;
}
export type ValidationRule = {
@ -193,6 +203,7 @@ export interface ComponentDecorator {
export default class Form extends React.Component<FormProps, any> {
static defaultProps = {
colon: true,
layout: 'horizontal' as FormLayout,
hideRequiredMark: false,
onSubmit(e: React.FormEvent<HTMLFormElement>) {
@ -206,6 +217,7 @@ export default class Form extends React.Component<FormProps, any> {
children: PropTypes.any,
onSubmit: PropTypes.func,
hideRequiredMark: PropTypes.bool,
colon: PropTypes.bool,
};
static Item = FormItem;
@ -251,15 +263,18 @@ export default class Form extends React.Component<FormProps, any> {
'hideRequiredMark',
'wrapperCol',
'labelCol',
'colon',
]);
return <form {...formProps} className={formClassName} />;
};
render() {
const { wrapperCol, labelCol, layout } = this.props;
const { wrapperCol, labelCol, layout, colon } = this.props;
return (
<FormContext.Provider value={{ wrapperCol, labelCol, vertical: layout === 'vertical' }}>
<FormContext.Provider
value={{ wrapperCol, labelCol, vertical: layout === 'vertical', colon }}
>
<ConfigConsumer>{this.renderForm}</ConfigConsumer>
</FormContext.Provider>
);

View File

@ -37,7 +37,6 @@ function intersperseSpace<T>(list: Array<T>): Array<T | string> {
export default class FormItem extends React.Component<FormItemProps, any> {
static defaultProps = {
hasFeedback: false,
colon: true,
};
static propTypes = {
@ -70,7 +69,7 @@ export default class FormItem extends React.Component<FormItemProps, any> {
getHelpMessage() {
const { help } = this.props;
if (help === undefined && this.getOnlyControl()) {
const errors = this.getField().errors;
const { errors } = this.getField();
if (errors) {
return intersperseSpace(
errors.map((e: any, index: number) => {
@ -201,7 +200,7 @@ export default class FormItem extends React.Component<FormItemProps, any> {
c2: React.ReactNode,
c3: React.ReactNode,
) {
const props = this.props;
const { props } = this;
const onlyControl = this.getOnlyControl;
const validateStatus =
props.validateStatus === undefined && onlyControl
@ -329,7 +328,7 @@ export default class FormItem extends React.Component<FormItemProps, any> {
renderLabel(prefixCls: string) {
return (
<FormContext.Consumer key="label">
{({ vertical, labelCol: contextLabelCol }: FormContextProps) => {
{({ vertical, labelCol: contextLabelCol, colon: contextColon }: FormContextProps) => {
const { label, labelCol, colon, id } = this.props;
const required = this.isRequired();
@ -343,7 +342,8 @@ export default class FormItem extends React.Component<FormItemProps, any> {
let labelChildren = label;
// Keep label is original where there should have no colon
const haveColon = colon && !vertical;
const computedColon = colon === true || (contextColon !== false && colon !== false);
const haveColon = computedColon && !vertical;
// Remove duplicated user input colon
if (haveColon && typeof label === 'string' && (label as string).trim() !== '') {
labelChildren = (label as string).replace(/[|:]\s*$/, '');
@ -383,13 +383,19 @@ export default class FormItem extends React.Component<FormItemProps, any> {
}
renderFormItem = ({ getPrefixCls }: ConfigConsumerProps) => {
return (
<FormContext.Consumer key="row">
{({ colon: contextColon }: FormContextProps) => {
const { prefixCls: customizePrefixCls, style, colon, className } = this.props;
const computedColon = colon === true || (contextColon !== false && colon !== false);
const prefixCls = getPrefixCls('form', customizePrefixCls);
const children = this.renderChildren(prefixCls);
const itemClassName = {
[`${prefixCls}-item`]: true,
[`${prefixCls}-item-with-help`]: this.helpShow,
[`${prefixCls}-item-no-colon`]: !colon,
[`${prefixCls}-item-no-colon`]: !computedColon,
[`${className}`]: !!className,
};
return (
@ -397,6 +403,9 @@ export default class FormItem extends React.Component<FormItemProps, any> {
{children}
</Row>
);
}}
</FormContext.Consumer>
);
};
render() {

View File

@ -0,0 +1,89 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Form should props colon of Form.Item override the props colon of Form. 1`] = `
<form
class="ant-form ant-form-horizontal"
>
<div
class="ant-row ant-form-item ant-form-item-no-colon"
>
<div
class="ant-form-item-label"
>
<label
class=""
title="label"
>
label
</label>
</div>
<div
class="ant-form-item-control-wrapper"
>
<div
class="ant-form-item-control"
>
<span
class="ant-form-item-children"
>
input
</span>
</div>
</div>
</div>
<div
class="ant-row ant-form-item"
>
<div
class="ant-form-item-label"
>
<label
class=""
title="label"
>
label
</label>
</div>
<div
class="ant-form-item-control-wrapper"
>
<div
class="ant-form-item-control"
>
<span
class="ant-form-item-children"
>
input
</span>
</div>
</div>
</div>
<div
class="ant-row ant-form-item ant-form-item-no-colon"
>
<div
class="ant-form-item-label"
>
<label
class=""
title="label"
>
label
</label>
</div>
<div
class="ant-form-item-control-wrapper"
>
<div
class="ant-form-item-control"
>
<span
class="ant-form-item-children"
>
input
</span>
</div>
</div>
</div>
</form>
`;

View File

@ -45,6 +45,58 @@ describe('Form', () => {
).not.toContain('');
});
it('should disable colon when props colon Form is false', () => {
const wrapper = mount(
<Form colon={false}>
<Form.Item>input</Form.Item>
</Form>,
);
expect(
wrapper
.find('.ant-form-item')
.at(0)
.hasClass('ant-form-item-no-colon'),
).toBe(true);
});
it('should props colon of Form.Item override the props colon of Form.', () => {
const wrapper = mount(
<Form colon={false}>
<Form.Item label="label">input</Form.Item>
<Form.Item label="label" colon>
input
</Form.Item>
<Form.Item label="label" colon={false}>
input
</Form.Item>
</Form>,
);
expect(wrapper.render()).toMatchSnapshot();
const testLabel = mount(
<Form colon={false}>
<Form.Item label="label:" colon>
input
</Form.Item>
<Form.Item label="label" colon>
input
</Form.Item>
</Form>,
);
expect(
testLabel
.find('.ant-form-item-label label')
.at(0)
.text(),
).not.toContain(':');
expect(
testLabel
.find('.ant-form-item-label label')
.at(1)
.text(),
).not.toContain('');
});
it('should not remove duplicated user input colon when props colon is false', () => {
const wrapper = mount(
<Form>

View File

@ -3,6 +3,7 @@ import { ColProps } from '../grid/col';
export interface FormContextProps {
vertical: boolean;
colon?: boolean;
labelCol?: ColProps;
wrapperCol?: ColProps;
}

View File

@ -40,6 +40,7 @@ A form field is defined using `<Form.Item />`.
| layout | Define form layout | 'horizontal'\|'vertical'\|'inline' | 'horizontal' |
| onSubmit | Defines a function will be called if form data validation is successful. | Function(e:Event) | |
| wrapperCol | (Added in 3.14.0. Previous version can only set on FormItem.) The layout for input controls, same as `labelCol` | [object](https://ant.design/components/grid/#Col) | |
| colon | change default props colon value of Form.Item | boolean | true |
### Form.create(options)

View File

@ -42,6 +42,7 @@ title: Form
| layout | 表单布局 | 'horizontal'\|'vertical'\|'inline' | 'horizontal' |
| onSubmit | 数据验证成功后回调事件 | Function(e:Event) | |
| wrapperCol | 3.14.0 新增,之前的版本只能设置到 FormItem 上。)需要为输入控件设置布局样式时,使用该属性,用法同 labelCol | [object](https://ant.design/components/grid/#Col) | |
| colon | 配置 Form.Item 的 colon 的默认值 | boolean | true |
### Form.create(options)