Browse Source

feat(Form.Item): useStatus supports get error messages and warning messages (#41554)

* feat: useStatus supports get error messages

* feat: useStatus supports get warning messages

* chore: update example

* chore: add test case
pull/41582/head
JiaQi 2 years ago
committed by GitHub
parent
commit
b73b37eee9
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      components/form/FormItem/ItemHolder.tsx
  2. 47
      components/form/__tests__/index.test.tsx
  3. 2
      components/form/context.tsx
  4. 6
      components/form/hooks/useFormItemStatus.ts
  5. 15
      components/form/index.en-US.md
  6. 15
      components/form/index.zh-CN.md

2
components/form/FormItem/ItemHolder.tsx

@ -122,6 +122,8 @@ export default function ItemHolder(props: ItemHolderProps) {
return {
status: mergedValidateStatus,
errors,
warnings,
hasFeedback,
feedbackIcon,
isFormItemInput: true,

47
components/form/__tests__/index.test.tsx

@ -1477,6 +1477,53 @@ describe('Form', () => {
);
});
it('Form.Item.useStatus should supports get error messages and warning messages', async () => {
const {
Item: { useStatus },
} = Form;
const ErrorItem: React.FC = () => {
const { errors } = useStatus();
return <div className="test-error">{errors[0]}</div>;
};
const WarningItem: React.FC = () => {
const { warnings } = useStatus();
return <div className="test-warning">{warnings[0]}</div>;
};
const Demo: React.FC = () => {
const [form] = Form.useForm();
return (
<Form form={form} name='test-form'>
<Form.Item name="error" rules={[{ required: true, message: 'This is a error message.' }]}>
<ErrorItem />
</Form.Item>
<Form.Item
name="warning"
rules={[{ required: true, message: 'This is a warning message.', warningOnly: true }]}
>
<WarningItem />
</Form.Item>
<Button onClick={() => form.submit()} className="submit-button">
Submit
</Button>
</Form>
);
};
const { container } = render(<Demo />);
fireEvent.click(container.querySelector('.submit-button')!);
await waitFakeTimer();
expect(container.querySelector('.test-error')).toHaveTextContent('This is a error message.');
expect(container.querySelector('.test-warning')).toHaveTextContent(
'This is a warning message.',
);
});
it('item customize margin', async () => {
const computeSpy = jest
.spyOn(window, 'getComputedStyle')

2
components/form/context.tsx

@ -57,6 +57,8 @@ export const FormItemPrefixContext = React.createContext<FormItemPrefixContextPr
export interface FormItemStatusContextProps {
isFormItemInput?: boolean;
status?: ValidateStatus;
errors?: React.ReactNode[];
warnings?: React.ReactNode[];
hasFeedback?: boolean;
feedbackIcon?: ReactNode;
}

6
components/form/hooks/useFormItemStatus.ts

@ -5,10 +5,12 @@ import warning from '../../_util/warning';
type UseFormItemStatus = () => {
status?: ValidateStatus;
errors: React.ReactNode[];
warnings: React.ReactNode[];
};
const useFormItemStatus: UseFormItemStatus = () => {
const { status } = useContext(FormItemInputContext);
const { status, errors = [], warnings = [] } = useContext(FormItemInputContext);
warning(
status !== undefined,
@ -16,7 +18,7 @@ const useFormItemStatus: UseFormItemStatus = () => {
'Form.Item.useStatus should be used under Form.Item component. For more information: https://u.ant.design/form-item-usestatus',
);
return { status };
return { status, errors, warnings };
};
// Only used for compatible package. Not promise this will work on future version.

15
components/form/index.en-US.md

@ -401,14 +401,21 @@ const Demo = () => {
### Form.Item.useStatus
`type Form.useFormItemStatus = (): { status: ValidateStatus | undefined }`
`type Form.Item.useStatus = (): { status: ValidateStatus | undefined, errors: ReactNode[], warnings: ReactNode[] }`
Added in `4.22.0`. Could be used to get validate status of Form.Item. If this hook is not used under Form.Item, `status` would be `undefined`:
Added in `4.22.0`. Could be used to get validate status of Form.Item. If this hook is not used under Form.Item, `status` would be `undefined`. Added `error` and `warnings` in `5.4.0`, Could be used to get error messages and warning messages of Form.Item:
```tsx
const CustomInput = ({ value, onChange }) => {
const { status } = Form.Item.useStatus();
return <input value={value} onChange={onChange} className={`custom-input-${status}`} />;
const { status, errors } = Form.Item.useStatus();
return (
<input
value={value}
onChange={onChange}
className={`custom-input-${status}`}
placeholder={(errors.length && errors[0]) || ''}
/>
);
};
export default () => (

15
components/form/index.zh-CN.md

@ -400,14 +400,21 @@ const Demo = () => {
### Form.Item.useStatus
`type Form.Item.useStatus = (): { status: ValidateStatus | undefined }`
`type Form.Item.useStatus = (): { status: ValidateStatus | undefined, errors: ReactNode[], warnings: ReactNode[] }`
`4.22.0` 新增,可用于获取当前 Form.Item 的校验状态,如果上层没有 Form.Item,`status` 将会返回 `undefined`
`4.22.0` 新增,可用于获取当前 Form.Item 的校验状态,如果上层没有 Form.Item,`status` 将会返回 `undefined`。`5.4.0` 新增 `errors``warnings`,可用于获取当前 Form.Item 的错误信息和警告信息
```tsx
const CustomInput = ({ value, onChange }) => {
const { status } = Form.Item.useStatus();
return <input value={value} onChange={onChange} className={`custom-input-${status}`} />;
const { status, errors } = Form.Item.useStatus();
return (
<input
value={value}
onChange={onChange}
className={`custom-input-${status}`}
placeholder={(errors.length && errors[0]) || ''}
/>
);
};
export default () => (

Loading…
Cancel
Save