- {children && (
+ {children && type !== 'vertical' && (
{children}
diff --git a/components/form/__tests__/__snapshots__/index.test.js.snap b/components/form/__tests__/__snapshots__/index.test.tsx.snap
similarity index 100%
rename from components/form/__tests__/__snapshots__/index.test.js.snap
rename to components/form/__tests__/__snapshots__/index.test.tsx.snap
diff --git a/components/form/__tests__/index.test.js b/components/form/__tests__/index.test.tsx
similarity index 93%
rename from components/form/__tests__/index.test.js
rename to components/form/__tests__/index.test.tsx
index c4263bbbcb..6dafb1be3e 100644
--- a/components/form/__tests__/index.test.js
+++ b/components/form/__tests__/index.test.tsx
@@ -1,9 +1,9 @@
import { mount } from 'enzyme';
import React, { Component, useState } from 'react';
-import { act } from 'react-dom/test-utils';
import scrollIntoView from 'scroll-into-view-if-needed';
import classNames from 'classnames';
import Form from '..';
+import type { FormInstance } from '..';
import * as Util from '../util';
import Button from '../../button';
@@ -20,7 +20,7 @@ import TreeSelect from '../../tree-select';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
-import { fireEvent, render, sleep } from '../../../tests/utils';
+import { fireEvent, render, sleep, act } from '../../../tests/utils';
import ConfigProvider from '../../config-provider';
import Drawer from '../../drawer';
import zhCN from '../../locale/zh_CN';
@@ -38,10 +38,10 @@ describe('Form', () => {
rtlTest(Form);
rtlTest(Form.Item);
- scrollIntoView.mockImplementation(() => {});
+ (scrollIntoView as any).mockImplementation(() => {});
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
- async function change(container, index, value, executeMockTimer) {
+ async function change(container: Element, index: number, value: any, executeMockTimer: boolean) {
fireEvent.change(container.querySelectorAll('input')[index], {
target: { value },
});
@@ -59,7 +59,7 @@ describe('Form', () => {
beforeEach(() => {
jest.useRealTimers();
- scrollIntoView.mockReset();
+ (scrollIntoView as any).mockReset();
});
afterEach(() => {
@@ -68,7 +68,7 @@ describe('Form', () => {
afterAll(() => {
errorSpy.mockRestore();
- scrollIntoView.mockRestore();
+ (scrollIntoView as any).mockRestore();
});
describe('noStyle Form.Item', () => {
@@ -143,11 +143,11 @@ describe('Form', () => {
const { container } = render(
);
await change(container, 0, '1', true);
- expect(container.querySelector('.ant-form-item-explain').textContent).toEqual('aaa');
+ expect(container.querySelector('.ant-form-item-explain')!.textContent).toEqual('aaa');
await change(container, 0, '2', true);
- expect(container.querySelector('.ant-form-item-explain').textContent).toEqual('ccc');
+ expect(container.querySelector('.ant-form-item-explain')!.textContent).toEqual('ccc');
await change(container, 0, '1', true);
- expect(container.querySelector('.ant-form-item-explain').textContent).toEqual('aaa');
+ expect(container.querySelector('.ant-form-item-explain')!.textContent).toEqual('aaa');
jest.useRealTimers();
});
@@ -356,9 +356,9 @@ describe('Form', () => {
});
describe('scrollToField', () => {
- function test(name, genForm) {
+ function test(name: string, genForm: () => { props: any; getForm: () => FormInstance }) {
it(name, () => {
- let callGetForm;
+ let callGetForm: () => FormInstance = undefined!;
const Demo = () => {
const { props, getForm } = genForm();
@@ -402,10 +402,10 @@ describe('Form', () => {
// ref
test('ref', () => {
- let form;
+ let form: FormInstance;
return {
props: {
- ref: instance => {
+ ref: (instance: FormInstance) => {
form = instance;
},
},
@@ -442,7 +442,7 @@ describe('Form', () => {
it('Form.Item should support data-*、aria-* and custom attribute', () => {
const wrapper = mount(
+
text
,
@@ -547,13 +547,13 @@ describe('Form', () => {
for (let i = 0; i < 3; i += 1) {
await change(container, 0, 'bamboo', true);
await change(container, 0, '', true);
- expect(container.querySelector('.ant-form-item-explain').textContent).toEqual(
+ expect(container.querySelector('.ant-form-item-explain')!.textContent).toEqual(
"'name' is required",
);
await change(container, 0, 'p', true);
await sleep(100);
- expect(container.querySelector('.ant-form-item-explain').textContent).toEqual('not a p');
+ expect(container.querySelector('.ant-form-item-explain')!.textContent).toEqual('not a p');
}
/* eslint-enable */
@@ -605,7 +605,7 @@ describe('Form', () => {
return ;
};
- const formRef = React.createRef();
+ const formRef = React.createRef();
mount(
@@ -620,13 +620,13 @@ describe('Form', () => {
,
{
strictMode: false,
- },
+ } as any,
);
expect(shouldNotRender).toHaveBeenCalledTimes(1);
expect(shouldRender).toHaveBeenCalledTimes(1);
- formRef.current.setFieldsValue({ light: 'bamboo' });
+ formRef.current!.setFieldsValue({ light: 'bamboo' });
await Promise.resolve();
expect(shouldNotRender).toHaveBeenCalledTimes(1);
expect(shouldRender).toHaveBeenCalledTimes(2);
@@ -659,7 +659,7 @@ describe('Form', () => {
await change(container, 0, '', true);
expect(container.querySelector('.ant-form-item')).toHaveClass('ant-form-item-has-error');
- expect(container.querySelector('.ant-form-item-explain').textContent).toEqual('help');
+ expect(container.querySelector('.ant-form-item-explain')!.textContent).toEqual('help');
jest.useRealTimers();
});
@@ -710,7 +710,7 @@ describe('Form', () => {
it('`null` triggers warning and is treated as `undefined`', () => {
const wrapper = mount(
-
+
,
);
@@ -747,7 +747,7 @@ describe('Form', () => {
it('change `help` should not warning', () => {
const Demo = () => {
- const [error, setError] = React.useState(null);
+ const [error, setError] = React.useState(null);
return (
,
@@ -1117,15 +1129,17 @@ describe('Form', () => {
(
-
- {doms.input}
- {doms.errorList}
- {doms.extra}
-
- ),
+ {...{
+ _internalItemRender: {
+ mark: 'pro_table_render',
+ render: (_: any, doms: any) => (
+
+ {doms.input}
+ {doms.errorList}
+ {doms.extra}
+
+ ),
+ },
}}
>
@@ -1173,7 +1187,7 @@ describe('Form', () => {
const wrapper = mount(, { attachTo: document.body });
expect(mockFn).toHaveBeenCalled();
- expect(Util.getFieldId()).toBe(itemName);
+ expect((Util as any).getFieldId()).toBe(itemName); // Mock here
// make sure input id is parentNode
expect(wrapper.find(`#${itemName}`).exists()).toBeTruthy();
@@ -1244,7 +1258,7 @@ describe('Form', () => {
it('not warning when remove on validate', async () => {
jest.useFakeTimers();
- let rejectFn = null;
+ let rejectFn: Function = null!;
const { container, unmount } = render(
+
@@ -1405,7 +1419,7 @@ describe('Form', () => {
Item: { useStatus },
} = Form;
- const CustomInput = ({ className, value }) => {
+ const CustomInput = ({ className, value }: { className: string; value?: React.ReactNode }) => {
const { status } = useStatus();
return {value}
;
};
@@ -1447,7 +1461,7 @@ describe('Form', () => {
expect(errorSpy).toHaveBeenCalledWith(
expect.stringContaining('Form.Item.useStatus should be used under Form.Item component.'),
);
- fireEvent.click(container.querySelector('.submit-button'));
+ fireEvent.click(container.querySelector('.submit-button')!);
await sleep(0);
expect(container.querySelector('.custom-input-required')?.classList).toContain(
'custom-input-status-error',
@@ -1455,9 +1469,12 @@ describe('Form', () => {
});
it('item customize margin', async () => {
- const computeSpy = jest.spyOn(window, 'getComputedStyle').mockImplementation(() => ({
- marginBottom: 24,
- }));
+ const computeSpy = jest.spyOn(window, 'getComputedStyle').mockImplementation(
+ () =>
+ ({
+ marginBottom: 24,
+ } as any),
+ );
const { container } = render(
,
);
- fireEvent.change(container.querySelector('input'), {
+ fireEvent.change(container.querySelector('input')!, {
target: {
value: '',
},
diff --git a/components/locale/pt_PT.tsx b/components/locale/pt_PT.tsx
index 9656c47c88..9fce8c76d2 100644
--- a/components/locale/pt_PT.tsx
+++ b/components/locale/pt_PT.tsx
@@ -31,7 +31,7 @@ const localeValues: Locale = {
searchPlaceholder: 'Procurar...',
itemUnit: 'item',
itemsUnit: 'itens',
- selectAll: 'Seleccionar Tudo',
+ selectAll: 'Selecionar tudo',
selectInvert: 'Inverter a página actual',
},
Upload: {
diff --git a/components/tree/index.en-US.md b/components/tree/index.en-US.md
index 77aaab480e..8daabb5167 100644
--- a/components/tree/index.en-US.md
+++ b/components/tree/index.en-US.md
@@ -109,9 +109,9 @@ Before `3.4.0`: The number of treeNodes can be very large, but when `checkable=t
File icon realize by using switcherIcon. You can overwrite the style to hide it:
-### Why defaultExpandedAll not working on ajax data?
+### Why defaultExpandAll not working on ajax data?
-`default` prefix prop only works when inited. So `defaultExpandedAll` has already executed when ajax load data. You can control `expandedKeys` or render Tree when data loaded to realize expanded all.
+`default` prefix prop only works when inited. So `defaultExpandAll` has already executed when ajax load data. You can control `expandedKeys` or render Tree when data loaded to realize expanded all.
### Virtual scroll limitation
diff --git a/components/tree/index.zh-CN.md b/components/tree/index.zh-CN.md
index cccc34db83..c813be306b 100644
--- a/components/tree/index.zh-CN.md
+++ b/components/tree/index.zh-CN.md
@@ -110,9 +110,9 @@ cover: https://gw.alipayobjects.com/zos/alicdn/Xh-oWqg9k/Tree.svg
文件图标通过 switcherIcon 来实现,如果不需要你可以覆盖对应的样式:
-### defaultExpandedAll 在异步加载数据时为何不生效?
+### defaultExpandAll 在异步加载数据时为何不生效?
-`default` 前缀属性只有在初始化时生效,因而异步加载数据时 `defaultExpandedAll` 已经执行完成。你可以通过受控 `expandedKeys` 或者在数据加载完成后渲染 Tree 来实现全部展开。
+`default` 前缀属性只有在初始化时生效,因而异步加载数据时 `defaultExpandAll` 已经执行完成。你可以通过受控 `expandedKeys` 或者在数据加载完成后渲染 Tree 来实现全部展开。
### 虚拟滚动的限制
diff --git a/components/upload/utils.tsx b/components/upload/utils.tsx
index aed130a3bc..4bd1a7e9c5 100644
--- a/components/upload/utils.tsx
+++ b/components/upload/utils.tsx
@@ -58,7 +58,7 @@ export const isImageUrl = (file: UploadFile): boolean => {
const extension = extname(url);
if (
/^data:image\//.test(url) ||
- /(webp|svg|png|gif|jpg|jpeg|jfif|bmp|dpg|ico)$/i.test(extension)
+ /(webp|svg|png|gif|jpg|jpeg|jfif|bmp|dpg|ico|heic|heif)$/i.test(extension)
) {
return true;
}
diff --git a/docs/react/recommendation.en-US.md b/docs/react/recommendation.en-US.md
index 3893afcc1d..d43f075d69 100644
--- a/docs/react/recommendation.en-US.md
+++ b/docs/react/recommendation.en-US.md
@@ -29,7 +29,7 @@ title: Third-Party Libraries
| Infinite Scroll | [rc-virtual-list](https://github.com/react-component/virtual-list/) [react-infinite-scroll-component](https://github.com/ankeetmaini/react-infinite-scroll-component) |
| Map | [react-google-maps](https://github.com/tomchentw/react-google-maps) [google-map-react](https://github.com/istarkov/google-map-react) [react-amap](https://github.com/ElemeFE/react-amap) |
| Video | [react-player](https://github.com/CookPete/react-player) [video-react](https://github.com/video-react/video-react) [video.js](http://docs.videojs.com/tutorial-react.html) |
-| Context Menu | [react-contextmenu](https://github.com/vkbansal/react-contextmenu/) [react-contexify](https://github.com/fkhadra/react-contexify) |
+| Context Menu | [react-contexify](https://github.com/fkhadra/react-contexify) |
| Emoji | [emoji-mart](https://github.com/missive/emoji-mart) |
| Split View | [react-split-pane](https://github.com/tomkp/react-split-pane) |
| Image Crop | [antd-img-crop](https://github.com/nanxiaobei/antd-img-crop) [react-image-crop](https://github.com/DominicTobias/react-image-crop) |
diff --git a/docs/react/recommendation.zh-CN.md b/docs/react/recommendation.zh-CN.md
index 203219e97b..597b8162fe 100644
--- a/docs/react/recommendation.zh-CN.md
+++ b/docs/react/recommendation.zh-CN.md
@@ -29,7 +29,7 @@ title: 社区精选组件
| 无限滚动 | [rc-virtual-list](https://github.com/react-component/virtual-list/) [react-infinite-scroll-component](https://github.com/ankeetmaini/react-infinite-scroll-component) |
| 地图 | [react-google-maps](https://github.com/tomchentw/react-google-maps) [google-map-react](https://github.com/istarkov/google-map-react) [react-amap 高德](https://github.com/ElemeFE/react-amap) |
| 视频播放 | [react-player](https://github.com/CookPete/react-player) [video-react](https://github.com/video-react/video-react) [video.js](http://docs.videojs.com/tutorial-react.html) |
-| 右键菜单 | [react-contextmenu](https://github.com/vkbansal/react-contextmenu/) [react-contexify](https://github.com/fkhadra/react-contexify) |
+| 右键菜单 | [react-contexify](https://github.com/fkhadra/react-contexify) |
| Emoji | [emoji-mart](https://github.com/missive/emoji-mart) |
| 分割面板 | [react-split-pane](https://github.com/tomkp/react-split-pane) |
| 图片裁切 | [antd-img-crop](https://github.com/nanxiaobei/antd-img-crop) [react-image-crop](https://github.com/DominicTobias/react-image-crop) |