mirror of
https://github.com/ant-design/ant-design.git
synced 2025-06-12 20:43:11 +08:00
Merge branch 'master' into next-merge-master
This commit is contained in:
commit
dbff63666a
@ -148,6 +148,7 @@ module.exports = {
|
|||||||
'jest/no-done-callback': 0,
|
'jest/no-done-callback': 0,
|
||||||
'jest/valid-title': 0,
|
'jest/valid-title': 0,
|
||||||
'jest/no-conditional-expect': 0,
|
'jest/no-conditional-expect': 0,
|
||||||
|
'jest/no-standalone-expect': 0,
|
||||||
|
|
||||||
'unicorn/better-regex': 2,
|
'unicorn/better-regex': 2,
|
||||||
'unicorn/prefer-string-trim-start-end': 2,
|
'unicorn/prefer-string-trim-start-end': 2,
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act } from 'react-dom/test-utils';
|
|
||||||
import Alert from '..';
|
import Alert from '..';
|
||||||
import accessibilityTest from '../../../tests/shared/accessibilityTest';
|
import accessibilityTest from '../../../tests/shared/accessibilityTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
import { fireEvent, render, sleep } from '../../../tests/utils';
|
import { fireEvent, render, sleep, act } from '../../../tests/utils';
|
||||||
import Button from '../../button';
|
import Button from '../../button';
|
||||||
import Popconfirm from '../../popconfirm';
|
import Popconfirm from '../../popconfirm';
|
||||||
import Tooltip from '../../tooltip';
|
import Tooltip from '../../tooltip';
|
||||||
@ -33,13 +32,13 @@ describe('Alert', () => {
|
|||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
jest.useFakeTimers();
|
||||||
|
fireEvent.click(container.querySelector('.ant-alert-close-icon')!);
|
||||||
act(() => {
|
act(() => {
|
||||||
jest.useFakeTimers();
|
|
||||||
fireEvent.click(container.querySelector('.ant-alert-close-icon')!);
|
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
jest.useRealTimers();
|
|
||||||
});
|
});
|
||||||
expect(onClose).toHaveBeenCalled();
|
expect(onClose).toHaveBeenCalled();
|
||||||
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('action of Alert', () => {
|
describe('action of Alert', () => {
|
||||||
|
@ -221,4 +221,11 @@ describe('Avatar Render', () => {
|
|||||||
expect(wrapper.querySelector('[crossorigin]')).toBeNull();
|
expect(wrapper.querySelector('[crossorigin]')).toBeNull();
|
||||||
expect(getByRole('img').getAttribute('crossOrigin')).toEqual(null);
|
expect(getByRole('img').getAttribute('crossOrigin')).toEqual(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('clickable', async () => {
|
||||||
|
const onClick = jest.fn();
|
||||||
|
const { container } = render(<Avatar onClick={onClick}>TestString</Avatar>);
|
||||||
|
fireEvent.click(container.querySelector('.ant-avatar-string'));
|
||||||
|
expect(onClick).toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -33,6 +33,7 @@ export interface AvatarProps {
|
|||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
alt?: string;
|
alt?: string;
|
||||||
crossOrigin?: '' | 'anonymous' | 'use-credentials';
|
crossOrigin?: '' | 'anonymous' | 'use-credentials';
|
||||||
|
onClick?: (e?: React.MouseEvent<HTMLElement>) => void;
|
||||||
/* callback when img load error */
|
/* callback when img load error */
|
||||||
/* return false to prevent Avatar show default fallback behavior, then you can do fallback by your self */
|
/* return false to prevent Avatar show default fallback behavior, then you can do fallback by your self */
|
||||||
onError?: () => boolean;
|
onError?: () => boolean;
|
||||||
|
@ -9,6 +9,7 @@ import zhCN from '../../locale/zh_CN';
|
|||||||
import Modal from '../../modal';
|
import Modal from '../../modal';
|
||||||
import Pagination from '../../pagination';
|
import Pagination from '../../pagination';
|
||||||
import TimePicker from '../../time-picker';
|
import TimePicker from '../../time-picker';
|
||||||
|
import { act } from '../../../tests/utils';
|
||||||
|
|
||||||
describe('ConfigProvider.Locale', () => {
|
describe('ConfigProvider.Locale', () => {
|
||||||
function $$(className) {
|
function $$(className) {
|
||||||
@ -44,7 +45,9 @@ describe('ConfigProvider.Locale', () => {
|
|||||||
title: 'title',
|
title: 'title',
|
||||||
content: 'Some descriptions',
|
content: 'Some descriptions',
|
||||||
});
|
});
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import React from 'react';
|
|||||||
import ConfigProvider from '..';
|
import ConfigProvider from '..';
|
||||||
import Affix from '../../affix';
|
import Affix from '../../affix';
|
||||||
import Anchor from '../../anchor';
|
import Anchor from '../../anchor';
|
||||||
|
import { act } from '../../../tests/utils';
|
||||||
|
|
||||||
describe('ConfigProvider.getTargetContainer', () => {
|
describe('ConfigProvider.getTargetContainer', () => {
|
||||||
it('Affix', () => {
|
it('Affix', () => {
|
||||||
@ -16,7 +17,9 @@ describe('ConfigProvider.getTargetContainer', () => {
|
|||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
|
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
|
||||||
expect(getTargetContainer).toHaveBeenCalled();
|
expect(getTargetContainer).toHaveBeenCalled();
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
@ -33,7 +36,9 @@ describe('ConfigProvider.getTargetContainer', () => {
|
|||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
|
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
|
||||||
expect(getTargetContainer).toHaveBeenCalled();
|
expect(getTargetContainer).toHaveBeenCalled();
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act } from 'react-dom/test-utils';
|
|
||||||
import Form from '..';
|
import Form from '..';
|
||||||
import { fireEvent, render, sleep } from '../../../tests/utils';
|
import { fireEvent, render, sleep, act } from '../../../tests/utils';
|
||||||
import Button from '../../button';
|
import Button from '../../button';
|
||||||
import Input from '../../input';
|
import Input from '../../input';
|
||||||
|
|
||||||
@ -43,8 +42,8 @@ describe('Form.List', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
function operate(className) {
|
function operate(className) {
|
||||||
|
fireEvent.click(container.querySelector(className));
|
||||||
act(() => {
|
act(() => {
|
||||||
fireEvent.click(container.querySelector(className));
|
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,7 @@ import {
|
|||||||
Transfer,
|
Transfer,
|
||||||
} from '../..';
|
} from '../..';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
|
import { act } from '../../../tests/utils';
|
||||||
import arEG from '../ar_EG';
|
import arEG from '../ar_EG';
|
||||||
import azAZ from '../az_AZ';
|
import azAZ from '../az_AZ';
|
||||||
import bgBG from '../bg_BG';
|
import bgBG from '../bg_BG';
|
||||||
@ -296,7 +297,9 @@ describe('Locale Provider', () => {
|
|||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: 'Hello World!',
|
title: 'Hello World!',
|
||||||
});
|
});
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import Mentions from '..';
|
|||||||
import focusTest from '../../../tests/shared/focusTest';
|
import focusTest from '../../../tests/shared/focusTest';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
|
import { act } from '../../../tests/utils';
|
||||||
|
|
||||||
const { getMentions } = Mentions;
|
const { getMentions } = Mentions;
|
||||||
|
|
||||||
@ -68,7 +69,9 @@ describe('Mentions', () => {
|
|||||||
expect(onFocus).toHaveBeenCalled();
|
expect(onFocus).toHaveBeenCalled();
|
||||||
|
|
||||||
wrapper.find('textarea').simulate('blur');
|
wrapper.find('textarea').simulate('blur');
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(wrapper.find('.ant-mentions').hasClass('ant-mentions-focused')).toBeFalsy();
|
expect(wrapper.find('.ant-mentions').hasClass('ant-mentions-focused')).toBeFalsy();
|
||||||
expect(onBlur).toHaveBeenCalled();
|
expect(onBlur).toHaveBeenCalled();
|
||||||
|
@ -7,11 +7,10 @@ import {
|
|||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import { mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { act } from 'react-dom/test-utils';
|
|
||||||
import Menu from '..';
|
import Menu from '..';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
import { fireEvent, render } from '../../../tests/utils';
|
import { fireEvent, render, act } from '../../../tests/utils';
|
||||||
import Layout from '../../layout';
|
import Layout from '../../layout';
|
||||||
import Tooltip from '../../tooltip';
|
import Tooltip from '../../tooltip';
|
||||||
import initCollapseMotion from '../../_util/motion';
|
import initCollapseMotion from '../../_util/motion';
|
||||||
@ -378,8 +377,8 @@ describe('Menu', () => {
|
|||||||
wrapper.setProps({ inlineCollapsed: true });
|
wrapper.setProps({ inlineCollapsed: true });
|
||||||
act(() => {
|
act(() => {
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
wrapper.update();
|
|
||||||
});
|
});
|
||||||
|
wrapper.update();
|
||||||
|
|
||||||
expect(wrapper.find('ul.ant-menu-root').hasClass('ant-menu-vertical')).toBeTruthy();
|
expect(wrapper.find('ul.ant-menu-root').hasClass('ant-menu-vertical')).toBeTruthy();
|
||||||
expect(wrapper.find('PopupTrigger').prop('visible')).toBeFalsy();
|
expect(wrapper.find('PopupTrigger').prop('visible')).toBeFalsy();
|
||||||
@ -388,8 +387,8 @@ describe('Menu', () => {
|
|||||||
wrapper.setProps({ inlineCollapsed: false });
|
wrapper.setProps({ inlineCollapsed: false });
|
||||||
act(() => {
|
act(() => {
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
wrapper.update();
|
|
||||||
});
|
});
|
||||||
|
wrapper.update();
|
||||||
|
|
||||||
expect(wrapper.find('ul.ant-menu-sub').last().hasClass('ant-menu-inline')).toBeTruthy();
|
expect(wrapper.find('ul.ant-menu-sub').last().hasClass('ant-menu-inline')).toBeTruthy();
|
||||||
expect(wrapper.find('InlineSubMenuList').prop('open')).toBeTruthy();
|
expect(wrapper.find('InlineSubMenuList').prop('open')).toBeTruthy();
|
||||||
@ -708,8 +707,8 @@ describe('Menu', () => {
|
|||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
wrapper.update();
|
|
||||||
});
|
});
|
||||||
|
wrapper.update();
|
||||||
|
|
||||||
expect(wrapper.find('.ant-tooltip-inner').length).toBe(0);
|
expect(wrapper.find('.ant-tooltip-inner').length).toBe(0);
|
||||||
});
|
});
|
||||||
@ -752,7 +751,9 @@ describe('Menu', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
wrapper.find('.ant-menu-item').hostNodes().simulate('mouseenter');
|
wrapper.find('.ant-menu-item').hostNodes().simulate('mouseenter');
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
|
|
||||||
expect(wrapper.find('.ant-tooltip-inner').length).toBeFalsy();
|
expect(wrapper.find('.ant-tooltip-inner').length).toBeFalsy();
|
||||||
|
@ -4,9 +4,9 @@ import { genCSSMotion } from 'rc-motion/lib/CSSMotion';
|
|||||||
import KeyCode from 'rc-util/lib/KeyCode';
|
import KeyCode from 'rc-util/lib/KeyCode';
|
||||||
import { resetWarned } from 'rc-util/lib/warning';
|
import { resetWarned } from 'rc-util/lib/warning';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import TestUtils, { act } from 'react-dom/test-utils';
|
import TestUtils from 'react-dom/test-utils';
|
||||||
import Modal from '..';
|
import Modal from '..';
|
||||||
import { sleep } from '../../../tests/utils';
|
import { sleep, act } from '../../../tests/utils';
|
||||||
import ConfigProvider from '../../config-provider';
|
import ConfigProvider from '../../config-provider';
|
||||||
import destroyFns from '../destroyFns';
|
import destroyFns from '../destroyFns';
|
||||||
|
|
||||||
@ -78,7 +78,9 @@ describe('Modal.confirm triggers callbacks correctly', () => {
|
|||||||
content: 'some descriptions',
|
content: 'some descriptions',
|
||||||
...args,
|
...args,
|
||||||
});
|
});
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +89,9 @@ describe('Modal.confirm triggers callbacks correctly', () => {
|
|||||||
confirm({
|
confirm({
|
||||||
content: 'some descriptions',
|
content: 'some descriptions',
|
||||||
});
|
});
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
expect(document.querySelector('.ant-modal-confirm-title')).toBe(null);
|
expect(document.querySelector('.ant-modal-confirm-title')).toBe(null);
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
@ -150,18 +154,26 @@ describe('Modal.confirm triggers callbacks correctly', () => {
|
|||||||
onCancel,
|
onCancel,
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
await sleep();
|
await sleep();
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
|
||||||
expect($$(`.ant-modal-confirm-confirm`)).toHaveLength(1);
|
expect($$(`.ant-modal-confirm-confirm`)).toHaveLength(1);
|
||||||
TestUtils.Simulate.keyDown($$('.ant-modal')[0], {
|
TestUtils.Simulate.keyDown($$('.ant-modal')[0], {
|
||||||
keyCode: KeyCode.ESC,
|
keyCode: KeyCode.ESC,
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
await sleep(0);
|
await sleep(0);
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
|
||||||
expect($$(`.ant-modal-confirm-confirm`)).toHaveLength(0);
|
expect($$(`.ant-modal-confirm-confirm`)).toHaveLength(0);
|
||||||
expect(onCancel).toHaveBeenCalledTimes(1);
|
expect(onCancel).toHaveBeenCalledTimes(1);
|
||||||
@ -197,18 +209,26 @@ describe('Modal.confirm triggers callbacks correctly', () => {
|
|||||||
open();
|
open();
|
||||||
|
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
await sleep();
|
await sleep();
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
|
||||||
expect($$('.ant-modal-confirm')).toHaveLength(1);
|
expect($$('.ant-modal-confirm')).toHaveLength(1);
|
||||||
|
|
||||||
await sleep();
|
await sleep();
|
||||||
$$('.ant-btn')[0].click();
|
$$('.ant-btn')[0].click();
|
||||||
|
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
await sleep();
|
await sleep();
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
|
||||||
expect($$('.ant-modal-confirm')).toHaveLength(0);
|
expect($$('.ant-modal-confirm')).toHaveLength(0);
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
@ -358,7 +378,9 @@ describe('Modal.confirm triggers callbacks correctly', () => {
|
|||||||
expect($$('.ant-modal-confirm-title')[0].innerHTML).toBe('new title');
|
expect($$('.ant-modal-confirm-title')[0].innerHTML).toBe('new title');
|
||||||
expect($$('.ant-modal-confirm-content')[0].innerHTML).toBe('new content');
|
expect($$('.ant-modal-confirm-content')[0].innerHTML).toBe('new content');
|
||||||
instance.destroy();
|
instance.destroy();
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -403,7 +425,9 @@ describe('Modal.confirm triggers callbacks correctly', () => {
|
|||||||
);
|
);
|
||||||
expect($$('.ant-modal-confirm-btns .ant-btn-primary')[0].style.color).toBe('red');
|
expect($$('.ant-modal-confirm-btns .ant-btn-primary')[0].style.color).toBe('red');
|
||||||
instance.destroy();
|
instance.destroy();
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -487,7 +511,9 @@ describe('Modal.confirm triggers callbacks correctly', () => {
|
|||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
|
|
||||||
Modal.destroyAll(); // clear destroyFns
|
Modal.destroyAll(); // clear destroyFns
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
|
||||||
const instances = [];
|
const instances = [];
|
||||||
['info', 'success', 'warning', 'error'].forEach(type => {
|
['info', 'success', 'warning', 'error'].forEach(type => {
|
||||||
@ -716,18 +742,26 @@ describe('Modal.confirm triggers callbacks correctly', () => {
|
|||||||
onCancel: close => mock(close),
|
onCancel: close => mock(close),
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
await sleep();
|
await sleep();
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
|
||||||
expect($$(`.ant-modal-confirm-${type}`)).toHaveLength(1);
|
expect($$(`.ant-modal-confirm-${type}`)).toHaveLength(1);
|
||||||
TestUtils.Simulate.keyDown($$('.ant-modal')[0], {
|
TestUtils.Simulate.keyDown($$('.ant-modal')[0], {
|
||||||
keyCode: KeyCode.ESC,
|
keyCode: KeyCode.ESC,
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
await sleep(0);
|
await sleep(0);
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
|
||||||
expect($$(`.ant-modal-confirm-${type}`)).toHaveLength(0);
|
expect($$(`.ant-modal-confirm-${type}`)).toHaveLength(0);
|
||||||
expect(mock).toBeCalledWith(expect.any(Function));
|
expect(mock).toBeCalledWith(expect.any(Function));
|
||||||
|
@ -4,7 +4,7 @@ import React from 'react';
|
|||||||
import Popconfirm from '..';
|
import Popconfirm from '..';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
import { fireEvent, render, sleep } from '../../../tests/utils';
|
import { fireEvent, render, sleep, act } from '../../../tests/utils';
|
||||||
import Button from '../../button';
|
import Button from '../../button';
|
||||||
|
|
||||||
describe('Popconfirm', () => {
|
describe('Popconfirm', () => {
|
||||||
@ -102,7 +102,9 @@ describe('Popconfirm', () => {
|
|||||||
expect(ref.current.getPopupDomNode().className).not.toContain('ant-popover-hidden');
|
expect(ref.current.getPopupDomNode().className).not.toContain('ant-popover-hidden');
|
||||||
popconfirm.setProps({ visible: false });
|
popconfirm.setProps({ visible: false });
|
||||||
popconfirm.update(); // https://github.com/enzymejs/enzyme/issues/2305
|
popconfirm.update(); // https://github.com/enzymejs/enzyme/issues/2305
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
expect(popconfirm.find('Trigger').props().popupVisible).toBe(false);
|
expect(popconfirm.find('Trigger').props().popupVisible).toBe(false);
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act } from 'react-dom/test-utils';
|
|
||||||
import Select from '..';
|
import Select from '..';
|
||||||
import focusTest from '../../../tests/shared/focusTest';
|
import focusTest from '../../../tests/shared/focusTest';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
import { fireEvent, render } from '../../../tests/utils';
|
import { fireEvent, render, act } from '../../../tests/utils';
|
||||||
import Icon from '../../icon';
|
import Icon from '../../icon';
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
@ -15,8 +14,8 @@ describe('Select', () => {
|
|||||||
rtlTest(Select);
|
rtlTest(Select);
|
||||||
|
|
||||||
function toggleOpen(container) {
|
function toggleOpen(container) {
|
||||||
|
fireEvent.mouseDown(container.querySelector('.ant-select-selector'));
|
||||||
act(() => {
|
act(() => {
|
||||||
fireEvent.mouseDown(container.querySelector('.ant-select-selector'));
|
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -123,7 +122,9 @@ describe('Select', () => {
|
|||||||
<Option value="1">1</Option>
|
<Option value="1">1</Option>
|
||||||
</Select>,
|
</Select>,
|
||||||
);
|
);
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
expect(asFragment().firstChild).toMatchSnapshot();
|
expect(asFragment().firstChild).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
/* eslint-disable react/no-multi-comp */
|
/* eslint-disable react/no-multi-comp */
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act } from 'react-dom/test-utils';
|
|
||||||
import Table from '..';
|
import Table from '..';
|
||||||
import { fireEvent, render, waitFor } from '../../../tests/utils';
|
import { fireEvent, render, waitFor, act } from '../../../tests/utils';
|
||||||
import Button from '../../button';
|
import Button from '../../button';
|
||||||
import ConfigProvider from '../../config-provider';
|
import ConfigProvider from '../../config-provider';
|
||||||
import Input from '../../input';
|
import Input from '../../input';
|
||||||
|
@ -2,9 +2,8 @@
|
|||||||
jest.mock('../../_util/scrollTo');
|
jest.mock('../../_util/scrollTo');
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act } from 'react-dom/test-utils';
|
|
||||||
import Table from '..';
|
import Table from '..';
|
||||||
import { fireEvent, render } from '../../../tests/utils';
|
import { fireEvent, render, act } from '../../../tests/utils';
|
||||||
import scrollTo from '../../_util/scrollTo';
|
import scrollTo from '../../_util/scrollTo';
|
||||||
import { resetWarned } from '../../_util/warning';
|
import { resetWarned } from '../../_util/warning';
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act } from 'react-dom/test-utils';
|
|
||||||
import Table from '..';
|
import Table from '..';
|
||||||
import { fireEvent, render } from '../../../tests/utils';
|
import { fireEvent, render, act } from '../../../tests/utils';
|
||||||
import ConfigProvider from '../../config-provider';
|
import ConfigProvider from '../../config-provider';
|
||||||
import { resetWarned } from '../../_util/warning';
|
import { resetWarned } from '../../_util/warning';
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import React from 'react';
|
|||||||
import Tag from '..';
|
import Tag from '..';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
|
import { act } from '../../../tests/utils';
|
||||||
|
|
||||||
describe('Tag', () => {
|
describe('Tag', () => {
|
||||||
mountTest(Tag);
|
mountTest(Tag);
|
||||||
@ -25,7 +26,9 @@ describe('Tag', () => {
|
|||||||
expect(wrapper.find('.ant-tag:not(.ant-tag-hidden)').length).toBe(1);
|
expect(wrapper.find('.ant-tag:not(.ant-tag-hidden)').length).toBe(1);
|
||||||
wrapper.find('.anticon-close').simulate('click');
|
wrapper.find('.anticon-close').simulate('click');
|
||||||
expect(onClose).toHaveBeenCalled();
|
expect(onClose).toHaveBeenCalled();
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(wrapper.find('.ant-tag:not(.ant-tag-hidden)').length).toBe(0);
|
expect(wrapper.find('.ant-tag:not(.ant-tag-hidden)').length).toBe(0);
|
||||||
});
|
});
|
||||||
@ -38,7 +41,9 @@ describe('Tag', () => {
|
|||||||
expect(wrapper.find('.anticon-close').length).toBe(1);
|
expect(wrapper.find('.anticon-close').length).toBe(1);
|
||||||
expect(wrapper.find('.ant-tag:not(.ant-tag-hidden)').length).toBe(1);
|
expect(wrapper.find('.ant-tag:not(.ant-tag-hidden)').length).toBe(1);
|
||||||
wrapper.find('.anticon-close').simulate('click');
|
wrapper.find('.anticon-close').simulate('click');
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
expect(wrapper.find('.ant-tag:not(.ant-tag-hidden)').length).toBe(1);
|
expect(wrapper.find('.ant-tag:not(.ant-tag-hidden)').length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -81,10 +86,14 @@ describe('Tag', () => {
|
|||||||
const wrapper = mount(<Tag visible />);
|
const wrapper = mount(<Tag visible />);
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
expect(wrapper.render()).toMatchSnapshot();
|
||||||
wrapper.setProps({ visible: false });
|
wrapper.setProps({ visible: false });
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
expect(wrapper.render()).toMatchSnapshot();
|
||||||
wrapper.setProps({ visible: true });
|
wrapper.setProps({ visible: true });
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
expect(wrapper.render()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -92,10 +101,14 @@ describe('Tag', () => {
|
|||||||
const wrapper = mount(<Tag visible={false} />);
|
const wrapper = mount(<Tag visible={false} />);
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
expect(wrapper.render()).toMatchSnapshot();
|
||||||
wrapper.setProps({ visible: true });
|
wrapper.setProps({ visible: true });
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
expect(wrapper.render()).toMatchSnapshot();
|
||||||
wrapper.setProps({ visible: false });
|
wrapper.setProps({ visible: false });
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
expect(wrapper.render()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { LikeOutlined, SmileOutlined } from '@ant-design/icons';
|
import { LikeOutlined, SmileOutlined } from '@ant-design/icons';
|
||||||
import { act } from '@testing-library/react';
|
|
||||||
import * as copyObj from 'copy-to-clipboard';
|
import * as copyObj from 'copy-to-clipboard';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { fireEvent, render, waitFor } from '../../../tests/utils';
|
import { fireEvent, render, waitFor, act } from '../../../tests/utils';
|
||||||
|
|
||||||
import Base from '../Base';
|
import Base from '../Base';
|
||||||
|
|
||||||
@ -90,7 +89,9 @@ describe('Typography copy', () => {
|
|||||||
|
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
fireEvent.click(wrapper.querySelectorAll('.ant-typography-copy')[0]);
|
fireEvent.click(wrapper.querySelectorAll('.ant-typography-copy')[0]);
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
|
||||||
unmount();
|
unmount();
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
|
@ -5,7 +5,7 @@ import { resetWarned } from 'rc-util/lib/warning';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
import { fireEvent, render, sleep, waitFor } from '../../../tests/utils';
|
import { fireEvent, render, sleep, waitFor, act } from '../../../tests/utils';
|
||||||
import Base from '../Base';
|
import Base from '../Base';
|
||||||
import Link from '../Link';
|
import Link from '../Link';
|
||||||
import Paragraph from '../Paragraph';
|
import Paragraph from '../Paragraph';
|
||||||
@ -104,7 +104,9 @@ describe('Typography', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fireEvent.mouseEnter(wrapper.querySelector('.ant-typography-copy'));
|
fireEvent.mouseEnter(wrapper.querySelector('.ant-typography-copy'));
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
|
||||||
if (tooltips === undefined || tooltips === true) {
|
if (tooltips === undefined || tooltips === true) {
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
@ -271,7 +273,9 @@ describe('Typography', () => {
|
|||||||
expect(onStart).not.toHaveBeenCalled();
|
expect(onStart).not.toHaveBeenCalled();
|
||||||
}
|
}
|
||||||
fireEvent.mouseEnter(wrapper.querySelectorAll('.ant-typography-edit')[0]);
|
fireEvent.mouseEnter(wrapper.querySelectorAll('.ant-typography-edit')[0]);
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
|
||||||
if (tooltip === undefined || tooltip === true) {
|
if (tooltip === undefined || tooltip === true) {
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
/* eslint-disable react/no-string-refs, react/prefer-es6-class */
|
/* eslint-disable react/no-string-refs, react/prefer-es6-class */
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act } from 'react-dom/test-utils';
|
|
||||||
import Upload from '..';
|
import Upload from '..';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import { fireEvent, render, waitFor } from '../../../tests/utils';
|
import { fireEvent, render, waitFor, act } from '../../../tests/utils';
|
||||||
import { setup, teardown } from './mock';
|
import { setup, teardown } from './mock';
|
||||||
|
|
||||||
describe('Upload.Dragger', () => {
|
describe('Upload.Dragger', () => {
|
||||||
@ -26,7 +25,7 @@ describe('Upload.Dragger', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
act(() => {
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2,11 +2,10 @@
|
|||||||
import produce from 'immer';
|
import produce from 'immer';
|
||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act } from 'react-dom/test-utils';
|
|
||||||
import Upload from '..';
|
import Upload from '..';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
import { fireEvent, render, sleep } from '../../../tests/utils';
|
import { fireEvent, render, sleep, act } from '../../../tests/utils';
|
||||||
import Form from '../../form';
|
import Form from '../../form';
|
||||||
import { resetWarned } from '../../_util/warning';
|
import { resetWarned } from '../../_util/warning';
|
||||||
import { getFileItem, isImageUrl, removeFileItem } from '../utils';
|
import { getFileItem, isImageUrl, removeFileItem } from '../utils';
|
||||||
@ -322,7 +321,9 @@ describe('Upload', () => {
|
|||||||
const { rerender } = render(<Upload ref={ref} />);
|
const { rerender } = render(<Upload ref={ref} />);
|
||||||
expect(ref.current.fileList).toEqual([]);
|
expect(ref.current.fileList).toEqual([]);
|
||||||
rerender(<Upload ref={ref} fileList={fileList} />);
|
rerender(<Upload ref={ref} fileList={fileList} />);
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
expect(ref.current.fileList).toEqual(fileList);
|
expect(ref.current.fileList).toEqual(fileList);
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
@ -725,7 +726,7 @@ describe('Upload', () => {
|
|||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await act(() => {
|
act(() => {
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
});
|
});
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
@ -945,7 +946,7 @@ describe('Upload', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Motion leave status change: start > active
|
// Motion leave status change: start > active
|
||||||
await act(() => {
|
act(() => {
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act } from 'react-dom/test-utils';
|
|
||||||
import Upload from '..';
|
import Upload from '..';
|
||||||
import { fireEvent, render, sleep, waitFor } from '../../../tests/utils';
|
import { fireEvent, render, sleep, waitFor, act } from '../../../tests/utils';
|
||||||
import Form from '../../form';
|
import Form from '../../form';
|
||||||
import UploadList from '../UploadList';
|
import UploadList from '../UploadList';
|
||||||
import { previewImage } from '../utils';
|
import { previewImage } from '../utils';
|
||||||
@ -263,7 +262,7 @@ describe('Upload List', () => {
|
|||||||
// Error message
|
// Error message
|
||||||
fireEvent.mouseEnter(wrapper.querySelector('.ant-upload-list-item'));
|
fireEvent.mouseEnter(wrapper.querySelector('.ant-upload-list-item'));
|
||||||
|
|
||||||
await act(() => {
|
act(() => {
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -574,7 +573,9 @@ describe('Upload List', () => {
|
|||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
|
||||||
unmount();
|
unmount();
|
||||||
|
|
||||||
@ -1132,13 +1133,15 @@ describe('Upload List', () => {
|
|||||||
await waitPromise();
|
await waitPromise();
|
||||||
|
|
||||||
// Wait for mock request finish request
|
// Wait for mock request finish request
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
|
||||||
// Basic called times
|
// Basic called times
|
||||||
expect(onChange).toHaveBeenCalled();
|
expect(onChange).toHaveBeenCalled();
|
||||||
|
|
||||||
// Check for images
|
// Check for images
|
||||||
await act(() => {
|
act(() => {
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
});
|
});
|
||||||
const afterImgNode = wrapper.container.querySelectorAll(
|
const afterImgNode = wrapper.container.querySelectorAll(
|
||||||
@ -1313,7 +1316,7 @@ describe('Upload List', () => {
|
|||||||
|
|
||||||
expect(uploadRef.current.fileList).toHaveLength(fileNames.length);
|
expect(uploadRef.current.fileList).toHaveLength(fileNames.length);
|
||||||
|
|
||||||
await act(() => {
|
act(() => {
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
});
|
});
|
||||||
expect(uploadRef.current.fileList).toHaveLength(fileNames.length);
|
expect(uploadRef.current.fileList).toHaveLength(fileNames.length);
|
||||||
|
9
site/theme/en-US.d.ts
vendored
Normal file
9
site/theme/en-US.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
interface ENLocale {
|
||||||
|
locale: 'en-US';
|
||||||
|
messages: {
|
||||||
|
[key: PropertyKey]: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const enLocale: ENLocale;
|
||||||
|
export default enLocale;
|
@ -1,7 +1,6 @@
|
|||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import AntdIcon, { createFromIconfontCN } from '@ant-design/icons';
|
import AntdIcon, { createFromIconfontCN } from '@ant-design/icons';
|
||||||
|
|
||||||
import { withThemeSuffix, removeTypeTheme, getThemeFromTypeName } from './utils';
|
import { withThemeSuffix, removeTypeTheme, getThemeFromTypeName } from './utils';
|
||||||
import warning from '../../../../components/_util/warning';
|
import warning from '../../../../components/_util/warning';
|
||||||
|
|
||||||
@ -9,7 +8,16 @@ const IconFont = createFromIconfontCN({
|
|||||||
scriptUrl: '//at.alicdn.com/t/font_1329669_t1u72b9zk8s.js',
|
scriptUrl: '//at.alicdn.com/t/font_1329669_t1u72b9zk8s.js',
|
||||||
});
|
});
|
||||||
|
|
||||||
const OldIcon = props => {
|
interface IconProps {
|
||||||
|
type: string;
|
||||||
|
theme: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CreateIconfont {
|
||||||
|
createFromIconfontCN: typeof createFromIconfontCN;
|
||||||
|
}
|
||||||
|
|
||||||
|
const OldIcon: React.FC<IconProps> = props => {
|
||||||
const { type, theme } = props;
|
const { type, theme } = props;
|
||||||
let computedType = type;
|
let computedType = type;
|
||||||
if (theme) {
|
if (theme) {
|
||||||
@ -25,12 +33,8 @@ const OldIcon = props => {
|
|||||||
return <IconFont {...props} type={`icon-${computedType}`} />;
|
return <IconFont {...props} type={`icon-${computedType}`} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Icon = props => {
|
const Icon: React.FC<IconProps> & CreateIconfont = props =>
|
||||||
if (typeof props.type === 'string') {
|
typeof props.type === 'string' ? <OldIcon {...props} /> : <AntdIcon {...props} />;
|
||||||
return <OldIcon {...props} />;
|
|
||||||
}
|
|
||||||
return <AntdIcon {...props} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
Icon.createFromIconfontCN = createFromIconfontCN;
|
Icon.createFromIconfontCN = createFromIconfontCN;
|
||||||
|
|
@ -14,8 +14,8 @@ const fillTester = /-fill$/;
|
|||||||
const outlineTester = /-o$/;
|
const outlineTester = /-o$/;
|
||||||
const twoToneTester = /-twotone$/;
|
const twoToneTester = /-twotone$/;
|
||||||
|
|
||||||
export function getThemeFromTypeName(type) {
|
export function getThemeFromTypeName(type: string) {
|
||||||
let result = null;
|
let result: string | null = null;
|
||||||
if (fillTester.test(type)) {
|
if (fillTester.test(type)) {
|
||||||
result = 'filled';
|
result = 'filled';
|
||||||
} else if (outlineTester.test(type)) {
|
} else if (outlineTester.test(type)) {
|
||||||
@ -26,12 +26,12 @@ export function getThemeFromTypeName(type) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function removeTypeTheme(type) {
|
export function removeTypeTheme(type: string): string {
|
||||||
return type.replace(fillTester, '').replace(outlineTester, '').replace(twoToneTester, '');
|
return type.replace(fillTester, '').replace(outlineTester, '').replace(twoToneTester, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function withThemeSuffix(type, theme) {
|
export function withThemeSuffix(type: string, theme: string): string {
|
||||||
let result = type;
|
let result: string = type;
|
||||||
if (theme === 'filled') {
|
if (theme === 'filled') {
|
||||||
result += '-fill';
|
result += '-fill';
|
||||||
} else if (theme === 'outlined') {
|
} else if (theme === 'outlined') {
|
@ -31,7 +31,7 @@ export interface HeaderProps {
|
|||||||
intl: { locale: string };
|
intl: { locale: string };
|
||||||
location: { pathname: string; query: any };
|
location: { pathname: string; query: any };
|
||||||
router: any;
|
router: any;
|
||||||
themeConfig: { docVersions: Record<string, string> };
|
themeConfig?: { docVersions: Record<string, string> };
|
||||||
changeDirection: (direction: DirectionType) => void;
|
changeDirection: (direction: DirectionType) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ const Header: React.FC<HeaderProps & WrappedComponentProps<'intl'>> = props => {
|
|||||||
const { menuVisible, windowWidth, searching, showTechUIButton } = headerState;
|
const { menuVisible, windowWidth, searching, showTechUIButton } = headerState;
|
||||||
const docVersions: Record<string, string> = {
|
const docVersions: Record<string, string> = {
|
||||||
[antdVersion]: antdVersion,
|
[antdVersion]: antdVersion,
|
||||||
...themeConfig.docVersions,
|
...themeConfig?.docVersions,
|
||||||
};
|
};
|
||||||
const versionOptions = Object.keys(docVersions).map(version => (
|
const versionOptions = Object.keys(docVersions).map(version => (
|
||||||
<Option value={docVersions[version]} key={version}>
|
<Option value={docVersions[version]} key={version}>
|
||||||
|
@ -4,6 +4,9 @@ import type { DirectionType } from 'antd/es/config-provider';
|
|||||||
export interface SiteContextProps {
|
export interface SiteContextProps {
|
||||||
isMobile: boolean;
|
isMobile: boolean;
|
||||||
direction: DirectionType;
|
direction: DirectionType;
|
||||||
|
theme?: string;
|
||||||
|
setTheme?: (theme: string, persist?: boolean) => void;
|
||||||
|
setIframeTheme?: (iframeNode: HTMLIFrameElement, theme: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SiteContext = React.createContext<SiteContextProps>({
|
const SiteContext = React.createContext<SiteContextProps>({
|
||||||
|
@ -1,24 +1,28 @@
|
|||||||
import { presetDarkPalettes, presetPalettes } from '@ant-design/colors';
|
/* eslint-disable class-methods-use-this */
|
||||||
import { createCache, StyleProvider } from '@ant-design/cssinjs';
|
|
||||||
import { setTwoToneColor } from '@ant-design/icons';
|
|
||||||
import { ConfigProvider, theme as antdTheme } from 'antd';
|
|
||||||
import zhCN from 'antd/lib/locale/zh_CN';
|
|
||||||
import { browserHistory } from 'bisheng/router';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
import 'dayjs/locale/zh-cn';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import { Helmet, HelmetProvider } from 'react-helmet-async';
|
import { Helmet, HelmetProvider } from 'react-helmet-async';
|
||||||
import { IntlProvider } from 'react-intl';
|
import { IntlProvider } from 'react-intl';
|
||||||
import themeSwitcher from 'theme-switcher';
|
import themeSwitcher from 'theme-switcher';
|
||||||
|
import type { TwoToneColor } from '@ant-design/icons';
|
||||||
|
import { setTwoToneColor } from '@ant-design/icons';
|
||||||
|
import { ConfigProvider, theme as antdTheme } from 'antd';
|
||||||
|
import { browserHistory } from 'bisheng/router';
|
||||||
|
import { createCache, StyleProvider } from '@ant-design/cssinjs';
|
||||||
|
import type { SeedToken } from 'antd/es/theme';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import { presetDarkPalettes, presetPalettes } from '@ant-design/colors';
|
||||||
|
import zhCN from 'antd/lib/locale/zh_CN';
|
||||||
|
import type { DirectionType } from 'antd/es/config-provider';
|
||||||
import enLocale from '../../en-US';
|
import enLocale from '../../en-US';
|
||||||
import cnLocale from '../../zh-CN';
|
import cnLocale from '../../zh-CN';
|
||||||
import * as utils from '../utils';
|
import * as utils from '../utils';
|
||||||
import Header from './Header';
|
import Header from './Header';
|
||||||
|
import type { SiteContextProps } from './SiteContext';
|
||||||
import SiteContext from './SiteContext';
|
import SiteContext from './SiteContext';
|
||||||
|
|
||||||
import defaultSeedToken from '../../../../components/theme/themes/seed';
|
import defaultSeedToken from '../../../../components/theme/themes/seed';
|
||||||
import DynamicTheme from './DynamicTheme';
|
import DynamicTheme from './DynamicTheme';
|
||||||
|
import 'moment/locale/zh-cn';
|
||||||
|
|
||||||
if (typeof window !== 'undefined' && navigator.serviceWorker) {
|
if (typeof window !== 'undefined' && navigator.serviceWorker) {
|
||||||
navigator.serviceWorker.getRegistrations().then(registrations => {
|
navigator.serviceWorker.getRegistrations().then(registrations => {
|
||||||
@ -36,12 +40,12 @@ if (typeof window !== 'undefined') {
|
|||||||
require('../../static/style');
|
require('../../static/style');
|
||||||
|
|
||||||
// Expose to iframe
|
// Expose to iframe
|
||||||
window.react = React;
|
(window as any).react = React;
|
||||||
window['react-dom'] = ReactDOM;
|
(window as any)['react-dom'] = ReactDOM;
|
||||||
// eslint-disable-next-line global-require
|
// eslint-disable-next-line global-require
|
||||||
window.antd = require('antd');
|
(window as any).antd = require('antd');
|
||||||
// eslint-disable-next-line global-require
|
// eslint-disable-next-line global-require
|
||||||
window['@ant-design/icons'] = require('@ant-design/icons');
|
(window as any)['@ant-design/icons'] = require('@ant-design/icons');
|
||||||
|
|
||||||
// Error log statistic
|
// Error log statistic
|
||||||
window.addEventListener('error', e => {
|
window.addEventListener('error', e => {
|
||||||
@ -56,7 +60,7 @@ if (typeof window !== 'undefined') {
|
|||||||
const RESPONSIVE_MOBILE = 768;
|
const RESPONSIVE_MOBILE = 768;
|
||||||
|
|
||||||
// for dark.css timestamp to remove cache
|
// for dark.css timestamp to remove cache
|
||||||
const timestamp = new Date().getTime();
|
const timestamp = Date.now();
|
||||||
const themeMap = {
|
const themeMap = {
|
||||||
dark: `/dark.css?${timestamp}`,
|
dark: `/dark.css?${timestamp}`,
|
||||||
compact: `/compact.css?${timestamp}`,
|
compact: `/compact.css?${timestamp}`,
|
||||||
@ -69,17 +73,38 @@ const { switcher } = themeSwitcher(themeConfig);
|
|||||||
// Pass to global since bisheng do not have the process for wrapper
|
// Pass to global since bisheng do not have the process for wrapper
|
||||||
const styleCache = createCache();
|
const styleCache = createCache();
|
||||||
if (typeof global !== 'undefined') {
|
if (typeof global !== 'undefined') {
|
||||||
global.styleCache = styleCache;
|
(global as any).styleCache = styleCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Layout extends React.Component {
|
interface LayoutPropsType {
|
||||||
|
location: any;
|
||||||
|
router: any;
|
||||||
|
helmetContext: any;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LayoutStateType {
|
||||||
|
appLocale: typeof cnLocale | typeof enLocale;
|
||||||
|
theme: string;
|
||||||
|
isMobile: boolean;
|
||||||
|
direction: DirectionType;
|
||||||
|
setTheme: SiteContextProps['setTheme'];
|
||||||
|
setIframeTheme: SiteContextProps['setIframeTheme'];
|
||||||
|
v5theme: string;
|
||||||
|
designToken: SeedToken;
|
||||||
|
hashedStyle: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class Layout extends React.Component<LayoutPropsType, LayoutStateType> {
|
||||||
static contextType = SiteContext;
|
static contextType = SiteContext;
|
||||||
|
|
||||||
|
timer: NodeJS.Timeout | null = null;
|
||||||
|
|
||||||
isBeforeComponent = false;
|
isBeforeComponent = false;
|
||||||
|
|
||||||
syncIframeThemeId = null;
|
syncIframeThemeId?: number;
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props: LayoutPropsType) {
|
||||||
super(props);
|
super(props);
|
||||||
const { pathname } = props.location;
|
const { pathname } = props.location;
|
||||||
const appLocale = utils.isZhCN(pathname) ? cnLocale : enLocale;
|
const appLocale = utils.isZhCN(pathname) ? cnLocale : enLocale;
|
||||||
@ -87,8 +112,9 @@ export default class Layout extends React.Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
appLocale,
|
appLocale,
|
||||||
theme: 'default',
|
theme: 'default',
|
||||||
setTheme: this.setTheme,
|
|
||||||
direction: 'ltr',
|
direction: 'ltr',
|
||||||
|
isMobile: false,
|
||||||
|
setTheme: this.setTheme,
|
||||||
setIframeTheme: this.setIframeTheme,
|
setIframeTheme: this.setIframeTheme,
|
||||||
v5theme: 'default',
|
v5theme: 'default',
|
||||||
designToken: defaultSeedToken,
|
designToken: defaultSeedToken,
|
||||||
@ -98,50 +124,40 @@ export default class Layout extends React.Component {
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { location, router } = this.props;
|
const { location, router } = this.props;
|
||||||
router.listen(({ pathname, search }) => {
|
router.listen(({ pathname, search }: any) => {
|
||||||
const { theme } = this.props.location.query;
|
const { theme } = this.props.location.query;
|
||||||
if (typeof window.ga !== 'undefined') {
|
if (typeof (window as any).ga !== 'undefined') {
|
||||||
window.ga('send', 'pageview', pathname + search);
|
(window as any).ga('send', 'pageview', pathname + search);
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line
|
if (typeof (window as any)._hmt !== 'undefined') {
|
||||||
if (typeof window._hmt !== 'undefined') {
|
(window as any)._hmt.push(['_trackPageview', pathname + search]);
|
||||||
// eslint-disable-next-line
|
|
||||||
window._hmt.push(['_trackPageview', pathname + search]);
|
|
||||||
}
|
}
|
||||||
const componentPage = /^\/?components/.test(pathname);
|
const componentPage = /^\/?components/.test(pathname);
|
||||||
|
|
||||||
// only component page can use `dark` theme
|
// only component page can use `dark` theme
|
||||||
if (!componentPage) {
|
if (!componentPage) {
|
||||||
this.isBeforeComponent = false;
|
this.isBeforeComponent = false;
|
||||||
this.setTheme('default', false);
|
this.setTheme?.('default', false);
|
||||||
} else if (theme && !this.isBeforeComponent) {
|
} else if (theme && !this.isBeforeComponent) {
|
||||||
this.isBeforeComponent = true;
|
this.isBeforeComponent = true;
|
||||||
this.setTheme(theme, false);
|
this.setTheme?.(theme, false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (location.query.theme && /^\/?components/.test(location.pathname)) {
|
if (location.query.theme && /^\/?components/.test(location.pathname)) {
|
||||||
this.isBeforeComponent = true;
|
this.isBeforeComponent = true;
|
||||||
this.setTheme(location.query.theme, false);
|
this.setTheme?.(location.query.theme, false);
|
||||||
} else {
|
} else {
|
||||||
this.isBeforeComponent = false;
|
this.isBeforeComponent = false;
|
||||||
this.setTheme('default', false);
|
this.setTheme?.('default', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (location.query.direction) {
|
this.setState({ direction: location.query.direction || 'ltr' });
|
||||||
this.setState({
|
|
||||||
direction: location.query.direction,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
direction: 'ltr',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const nprogressHiddenStyle = document.getElementById('nprogress-style');
|
const nprogressHiddenStyle = document.getElementById('nprogress-style');
|
||||||
if (nprogressHiddenStyle) {
|
if (nprogressHiddenStyle) {
|
||||||
this.timer = setTimeout(() => {
|
this.timer = setTimeout(() => {
|
||||||
nprogressHiddenStyle.parentNode.removeChild(nprogressHiddenStyle);
|
nprogressHiddenStyle.parentNode?.removeChild(nprogressHiddenStyle);
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +165,7 @@ export default class Layout extends React.Component {
|
|||||||
window.addEventListener('resize', this.updateMobileMode);
|
window.addEventListener('resize', this.updateMobileMode);
|
||||||
|
|
||||||
// Sync iframe theme with current theme
|
// Sync iframe theme with current theme
|
||||||
this.syncIframeThemeId = setInterval(() => {
|
this.syncIframeThemeId = window.setInterval(() => {
|
||||||
const { designToken, hashedStyle } = this.state;
|
const { designToken, hashedStyle } = this.state;
|
||||||
const content = JSON.stringify({
|
const content = JSON.stringify({
|
||||||
action: 'sync.theme',
|
action: 'sync.theme',
|
||||||
@ -157,16 +173,19 @@ export default class Layout extends React.Component {
|
|||||||
hashed: hashedStyle,
|
hashed: hashedStyle,
|
||||||
});
|
});
|
||||||
|
|
||||||
document.querySelectorAll('iframe.iframe-demo').forEach(iframe => {
|
document.querySelectorAll<HTMLIFrameElement>('iframe.iframe-demo').forEach(iframe => {
|
||||||
iframe.contentWindow.postMessage(content);
|
iframe.contentWindow?.postMessage(content);
|
||||||
});
|
});
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
clearTimeout(this.timer);
|
clearTimeout(this.timer as unknown as number);
|
||||||
clearInterval(this.syncIframeThemeId);
|
clearInterval(this.syncIframeThemeId as unknown as number);
|
||||||
window.removeEventListener('resize', this.updateMobileMode);
|
window.removeEventListener('resize', this.updateMobileMode);
|
||||||
|
if (this.timer) {
|
||||||
|
clearTimeout(this.timer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMobileMode = () => {
|
updateMobileMode = () => {
|
||||||
@ -179,19 +198,16 @@ export default class Layout extends React.Component {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
setIframeTheme = (iframeNode, theme) => {
|
setIframeTheme: LayoutStateType['setIframeTheme'] = (iframeNode, theme) => {
|
||||||
iframeNode.contentWindow.postMessage(
|
iframeNode.contentWindow?.postMessage(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
action: 'change.theme',
|
action: 'change.theme',
|
||||||
data: {
|
data: { themeConfig, theme },
|
||||||
themeConfig,
|
|
||||||
theme,
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
setTheme = (theme, persist = true) => {
|
setTheme: LayoutStateType['setTheme'] = (theme, persist = true) => {
|
||||||
if (typeof window === 'undefined') {
|
if (typeof window === 'undefined') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -203,24 +219,23 @@ export default class Layout extends React.Component {
|
|||||||
|
|
||||||
const iframeNodes = document.querySelectorAll('.iframe-demo');
|
const iframeNodes = document.querySelectorAll('.iframe-demo');
|
||||||
// loop element node
|
// loop element node
|
||||||
[].forEach.call(iframeNodes, iframeNode => {
|
[].forEach.call(iframeNodes, (iframeNode: HTMLIFrameElement) => {
|
||||||
this.setIframeTheme(iframeNode, theme);
|
this.setIframeTheme?.(iframeNode, theme);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setState({
|
this.setState({ theme });
|
||||||
theme,
|
|
||||||
});
|
|
||||||
const iconTwoToneThemeMap = {
|
const iconTwoToneThemeMap = {
|
||||||
dark: [presetDarkPalettes.blue.primary, '#111d2c'],
|
dark: [presetDarkPalettes.blue.primary, '#111d2c'],
|
||||||
default: presetPalettes.blue.primary,
|
default: presetPalettes.blue.primary,
|
||||||
};
|
} as const;
|
||||||
setTwoToneColor(iconTwoToneThemeMap[theme] || iconTwoToneThemeMap.default);
|
setTwoToneColor(
|
||||||
|
(iconTwoToneThemeMap[theme as keyof typeof iconTwoToneThemeMap] ||
|
||||||
|
iconTwoToneThemeMap.default) as TwoToneColor,
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
changeDirection = direction => {
|
changeDirection = (direction: DirectionType): void => {
|
||||||
this.setState({
|
this.setState({ direction });
|
||||||
direction,
|
|
||||||
});
|
|
||||||
const { pathname, hash, query } = this.props.location;
|
const { pathname, hash, query } = this.props.location;
|
||||||
if (direction === 'ltr') {
|
if (direction === 'ltr') {
|
||||||
delete query.direction;
|
delete query.direction;
|
||||||
@ -257,15 +272,14 @@ export default class Layout extends React.Component {
|
|||||||
: 'An enterprise-class UI design language and React UI library with a set of high-quality React components, one of best React UI library for enterprises';
|
: 'An enterprise-class UI design language and React UI library with a set of high-quality React components, one of best React UI library for enterprises';
|
||||||
return (
|
return (
|
||||||
<StyleProvider cache={styleCache}>
|
<StyleProvider cache={styleCache}>
|
||||||
|
{/* eslint-disable-next-line react/jsx-no-constructed-context-values */}
|
||||||
<SiteContext.Provider value={{ isMobile, direction, theme, setTheme, setIframeTheme }}>
|
<SiteContext.Provider value={{ isMobile, direction, theme, setTheme, setIframeTheme }}>
|
||||||
<HelmetProvider context={helmetContext}>
|
<HelmetProvider context={helmetContext}>
|
||||||
<Helmet encodeSpecialCharacters={false}>
|
<Helmet encodeSpecialCharacters={false}>
|
||||||
<html
|
<html
|
||||||
lang={appLocale.locale === 'zh-CN' ? 'zh' : 'en'}
|
lang={appLocale.locale === 'zh-CN' ? 'zh' : 'en'}
|
||||||
data-direction={direction}
|
data-direction={direction}
|
||||||
className={classNames({
|
className={classNames({ [`rtl`]: direction === 'rtl' })}
|
||||||
[`rtl`]: direction === 'rtl',
|
|
||||||
})}
|
|
||||||
/>
|
/>
|
||||||
<title>{title}</title>
|
<title>{title}</title>
|
||||||
<link
|
<link
|
||||||
@ -286,7 +300,7 @@ export default class Layout extends React.Component {
|
|||||||
defaultLocale="en-US"
|
defaultLocale="en-US"
|
||||||
>
|
>
|
||||||
<ConfigProvider
|
<ConfigProvider
|
||||||
locale={appLocale.locale === 'zh-CN' ? zhCN : null}
|
locale={appLocale.locale === 'zh-CN' ? zhCN : undefined}
|
||||||
direction={direction}
|
direction={direction}
|
||||||
theme={{
|
theme={{
|
||||||
token: designToken,
|
token: designToken,
|
||||||
@ -299,17 +313,19 @@ export default class Layout extends React.Component {
|
|||||||
{children}
|
{children}
|
||||||
|
|
||||||
<DynamicTheme
|
<DynamicTheme
|
||||||
componentName={this.props.params?.children?.replace('-cn', '')}
|
componentName={(this.props as any).params?.children?.replace('-cn', '')}
|
||||||
defaultToken={{
|
defaultToken={
|
||||||
theme: v5theme,
|
{
|
||||||
...designToken,
|
theme: v5theme,
|
||||||
hashed: hashedStyle,
|
...designToken,
|
||||||
}}
|
hashed: hashedStyle,
|
||||||
|
} as any
|
||||||
|
}
|
||||||
onChangeTheme={newToken => {
|
onChangeTheme={newToken => {
|
||||||
console.log('Change Theme:', newToken);
|
console.log('Change Theme:', newToken);
|
||||||
const { hashed, theme, ...restToken } = newToken;
|
const { hashed, newTheme, ...restToken } = newToken as any;
|
||||||
this.setState({
|
this.setState({
|
||||||
v5theme: theme,
|
v5theme: newTheme,
|
||||||
designToken: restToken,
|
designToken: restToken,
|
||||||
hashedStyle: hashed,
|
hashedStyle: hashed,
|
||||||
});
|
});
|
9
site/theme/zh-CN.d.ts
vendored
Normal file
9
site/theme/zh-CN.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
interface CNLocale {
|
||||||
|
locale: 'zh-CN';
|
||||||
|
messages: {
|
||||||
|
[key: PropertyKey]: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const cnLocale: CNLocale;
|
||||||
|
export default cnLocale;
|
@ -1,9 +1,8 @@
|
|||||||
import type { RenderOptions } from '@testing-library/react';
|
|
||||||
import { render } from '@testing-library/react';
|
|
||||||
import MockDate from 'mockdate';
|
import MockDate from 'mockdate';
|
||||||
import type { ReactElement } from 'react';
|
import type { ReactElement } from 'react';
|
||||||
import React, { StrictMode } from 'react';
|
import React, { StrictMode } from 'react';
|
||||||
import { act } from 'react-dom/test-utils';
|
import type { RenderOptions } from '@testing-library/react';
|
||||||
|
import { render, act } from '@testing-library/react';
|
||||||
import { _rs as onLibResize } from 'rc-resize-observer/lib/utils/observerUtil';
|
import { _rs as onLibResize } from 'rc-resize-observer/lib/utils/observerUtil';
|
||||||
import { _rs as onEsResize } from 'rc-resize-observer/es/utils/observerUtil';
|
import { _rs as onEsResize } from 'rc-resize-observer/es/utils/observerUtil';
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user