mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-29 13:47:02 +08:00
Merge pull request #15276 from DiamondYuan/form-prop
feat: Form support set colon
This commit is contained in:
commit
d02ec78567
@ -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>
|
||||
);
|
||||
|
@ -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() {
|
||||
|
89
components/form/__tests__/__snapshots__/label.test.js.snap
Normal file
89
components/form/__tests__/__snapshots__/label.test.js.snap
Normal 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>
|
||||
`;
|
@ -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>
|
||||
|
@ -3,6 +3,7 @@ import { ColProps } from '../grid/col';
|
||||
|
||||
export interface FormContextProps {
|
||||
vertical: boolean;
|
||||
colon?: boolean;
|
||||
labelCol?: ColProps;
|
||||
wrapperCol?: ColProps;
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user