Skip to content

Commit

Permalink
fix(form): success feedback should display when pass hasFeedback prop…
Browse files Browse the repository at this point in the history
… and current value is valid value (ant-design#41116)

* fix: success feedback should display when pass hasFeedback prop and type valid value

* feat: optimize code

* feat: update test case

* feat: optimize code

* feat: optimize code

* feat: update demo

* feat: update test case

* feat: update demo

* feat: update test case

* feat: reset demo
  • Loading branch information
kiner-tang authored and RedJue committed Apr 25, 2023
1 parent 042c066 commit 2bdfe23
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 24 deletions.
3 changes: 2 additions & 1 deletion components/form/FormItem/ItemHolder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ export default function ItemHolder(props: ItemHolderProps) {
mergedValidateStatus = 'error';
} else if (debounceWarnings.length) {
mergedValidateStatus = 'warning';
} else if (meta.touched) {
} else if (meta.touched || (hasFeedback && meta.validated)) {
// success feedback should display when pass hasFeedback prop and current value is valid value
mergedValidateStatus = 'success';
}

Expand Down
1 change: 1 addition & 0 deletions components/form/FormItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ function genEmptyMeta(): Meta {
touched: false,
validating: false,
name: [],
validated: false,
};
}

Expand Down
87 changes: 65 additions & 22 deletions components/form/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { ChangeEventHandler } from 'react';
import React, { useState } from 'react';
import React, { useState, useEffect, useRef } from 'react';
import scrollIntoView from 'scroll-into-view-if-needed';
import classNames from 'classnames';
import type { ColProps } from 'antd/es/grid';
import type { FormInstance } from '..';
import Form from '..';
import * as Util from '../util';
import Button from '../../button';
Expand Down Expand Up @@ -41,25 +42,6 @@ describe('Form', () => {
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});

// const change = async (
// container: ReturnType<typeof render>['container'],
// index: number,
// value: string,
// executeMockTimer: boolean,
// ) => {
// fireEvent.change(container.querySelectorAll('input')?.[index], { target: { value } });
// await sleep(200);

// if (executeMockTimer) {
// for (let i = 0; i < 10; i += 1) {
// act(() => {
// jest.runAllTimers();
// });
// }
// await sleep(1);
// }
// };

const changeValue = async (
input: HTMLElement | null | number,
value: string,
Expand Down Expand Up @@ -1473,13 +1455,13 @@ describe('Form', () => {

const { container } = render(<Demo />);

expect(container.querySelector('.custom-input-required')?.classList).toContain(
expect(container.querySelector('.custom-input-required')?.className).toContain(
'custom-input-status-',
);
expect(container.querySelector('.custom-input-warning')?.classList).toContain(
'custom-input-status-warning',
);
expect(container.querySelector('.custom-input')?.classList).toContain('custom-input-status-');
expect(container.querySelector('.custom-input')?.className).toContain('custom-input-status-');
expect(container.querySelector('.custom-input-wrong')?.classList).toContain(
'custom-input-status-undefined',
);
Expand Down Expand Up @@ -1583,4 +1565,65 @@ describe('Form', () => {

expect(wrapper5.container.querySelectorAll('[disabled]').length).toBe(0);
});

it('success feedback should display when pass hasFeedback prop and current value is valid value', async () => {
const App = ({ trigger = false }: { trigger?: boolean }) => {
const form = useRef<FormInstance<any>>(null);

useEffect(() => {
if (!trigger) return;
form.current?.validateFields();
}, [trigger]);

return (
<Form ref={form}>
<Form.Item
label="Success"
name="name1"
hasFeedback
initialValue="test@qq.com"
rules={[
{
type: 'email',
message: 'Please input your e-mail',
},
{
required: true,
message: 'Please input your value',
},
]}
>
<Input />
</Form.Item>
<Form.Item
label="Success"
name="name2"
initialValue="test@qq.com"
rules={[
{
type: 'email',
message: 'Please input your e-mail',
},
{
required: true,
message: 'Please input your value',
},
]}
>
<Input />
</Form.Item>
</Form>
);
};
const { container, rerender } = render(<App />);

expect(container.querySelectorAll('.ant-form-item-has-feedback').length).toBe(0);
expect(container.querySelectorAll('.ant-form-item-has-success').length).toBe(0);

rerender(<App trigger />);
await waitFakeTimer();

expect(container.querySelectorAll('.ant-form-item-has-feedback').length).toBe(1);
expect(container.querySelectorAll('.ant-form-item-has-success').length).toBe(1);
});
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
"rc-dialog": "~9.0.2",
"rc-drawer": "~6.1.1",
"rc-dropdown": "~4.0.0",
"rc-field-form": "~1.27.0",
"rc-field-form": "~1.28.0",
"rc-image": "~5.15.2",
"rc-input": "~0.2.1",
"rc-input-number": "~7.4.0",
Expand Down

0 comments on commit 2bdfe23

Please sign in to comment.