mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-12-15 09:21:22 +08:00
commit
b50a92266c
@ -15,6 +15,13 @@ timeline: true
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 4.22.7
|
||||||
|
|
||||||
|
`2022-08-21`
|
||||||
|
|
||||||
|
- 🐞 Fix Typography visible change some time Tooltip not work with ellipsis. [#37147](https://github.com/ant-design/ant-design/pull/37147)
|
||||||
|
- 🐞 Fix InputNumber that style cannot be customized with controls less variables. [#37070](https://github.com/ant-design/ant-design/pull/37070) [@coldice945](https://github.com/coldice945)
|
||||||
|
|
||||||
## 4.22.6
|
## 4.22.6
|
||||||
|
|
||||||
`2022-08-17`
|
`2022-08-17`
|
||||||
|
@ -15,6 +15,13 @@ timeline: true
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 4.22.7
|
||||||
|
|
||||||
|
`2022-08-21`
|
||||||
|
|
||||||
|
- 🐞 修复 Typography 可见度切换时有时候省略不会显示 Tooltip 的问题。[#37147](https://github.com/ant-design/ant-design/pull/37147)
|
||||||
|
- 🐞 修复 InputNumber 样式不跟随控件 less 变量改变的问题。[#37070](https://github.com/ant-design/ant-design/pull/37070) [@coldice945](https://github.com/coldice945)
|
||||||
|
|
||||||
## 4.22.6
|
## 4.22.6
|
||||||
|
|
||||||
`2022-08-17`
|
`2022-08-17`
|
||||||
|
@ -2,7 +2,7 @@ import { easeInOutCubic } from '../easings';
|
|||||||
|
|
||||||
describe('Test easings', () => {
|
describe('Test easings', () => {
|
||||||
it('easeInOutCubic return value', () => {
|
it('easeInOutCubic return value', () => {
|
||||||
const nums = [];
|
const nums: number[] = [];
|
||||||
// eslint-disable-next-line no-plusplus
|
// eslint-disable-next-line no-plusplus
|
||||||
for (let index = 0; index < 5; index++) {
|
for (let index = 0; index < 5; index++) {
|
||||||
nums.push(easeInOutCubic(index, 1, 5, 4));
|
nums.push(easeInOutCubic(index, 1, 5, 4));
|
@ -41,7 +41,7 @@ describe('getScroll', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('getScroll documentElement', async () => {
|
it('getScroll documentElement', async () => {
|
||||||
const div = {};
|
const div: any = {};
|
||||||
const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => {
|
const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => {
|
||||||
div.scrollLeft = null;
|
div.scrollLeft = null;
|
||||||
div.scrollTop = null;
|
div.scrollTop = null;
|
@ -2,7 +2,7 @@ import { sleep } from '../../../tests/utils';
|
|||||||
import scrollTo from '../scrollTo';
|
import scrollTo from '../scrollTo';
|
||||||
|
|
||||||
describe('Test ScrollTo function', () => {
|
describe('Test ScrollTo function', () => {
|
||||||
let dateNowMock;
|
let dateNowMock: jest.SpyInstance;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
dateNowMock = jest
|
dateNowMock = jest
|
||||||
@ -16,7 +16,7 @@ describe('Test ScrollTo function', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('test scrollTo', async () => {
|
it('test scrollTo', async () => {
|
||||||
const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => {
|
const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((_, y) => {
|
||||||
window.scrollY = y;
|
window.scrollY = y;
|
||||||
window.pageYOffset = y;
|
window.pageYOffset = y;
|
||||||
});
|
});
|
@ -1,12 +0,0 @@
|
|||||||
import { mount } from 'enzyme';
|
|
||||||
import React from 'react';
|
|
||||||
import TransButton from '../transButton';
|
|
||||||
|
|
||||||
describe('transButton component', () => {
|
|
||||||
it('disabled should update style', () => {
|
|
||||||
const wrapper = mount(<TransButton disabled />);
|
|
||||||
expect(wrapper.find('div').first().props().style).toEqual(
|
|
||||||
expect.objectContaining({ pointerEvents: 'none' }),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
10
components/_util/__tests__/transButton.test.tsx
Normal file
10
components/_util/__tests__/transButton.test.tsx
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import TransButton from '../transButton';
|
||||||
|
import { render } from '../../../tests/utils';
|
||||||
|
|
||||||
|
describe('transButton component', () => {
|
||||||
|
it('disabled should update style', () => {
|
||||||
|
const { container } = render(<TransButton disabled />);
|
||||||
|
expect(container.querySelector('div')?.style.pointerEvents).toBe('none');
|
||||||
|
});
|
||||||
|
});
|
@ -1,26 +0,0 @@
|
|||||||
import { mount } from 'enzyme';
|
|
||||||
import React from 'react';
|
|
||||||
import useSyncState from '../hooks/useSyncState';
|
|
||||||
|
|
||||||
describe('Table', () => {
|
|
||||||
it('useSyncState', () => {
|
|
||||||
const Test = () => {
|
|
||||||
const [getVal, setVal] = useSyncState('light');
|
|
||||||
|
|
||||||
return (
|
|
||||||
<span
|
|
||||||
onClick={() => {
|
|
||||||
setVal('bamboo');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{getVal()}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const wrapper = mount(<Test />);
|
|
||||||
expect(wrapper.text()).toEqual('light');
|
|
||||||
wrapper.find('span').simulate('click');
|
|
||||||
expect(wrapper.text()).toEqual('bamboo');
|
|
||||||
});
|
|
||||||
});
|
|
17
components/_util/__tests__/useSyncState.test.tsx
Normal file
17
components/_util/__tests__/useSyncState.test.tsx
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import useSyncState from '../hooks/useSyncState';
|
||||||
|
import { render, fireEvent } from '../../../tests/utils';
|
||||||
|
|
||||||
|
describe('Table', () => {
|
||||||
|
it('useSyncState', () => {
|
||||||
|
const Test: React.FC = () => {
|
||||||
|
const [getVal, setVal] = useSyncState('light');
|
||||||
|
return <span onClick={() => setVal('bamboo')}>{getVal()}</span>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const { container } = render(<Test />);
|
||||||
|
expect(container.querySelector('span')?.innerHTML).toBe('light');
|
||||||
|
fireEvent.click(container.querySelector('span')!);
|
||||||
|
expect(container.querySelector('span')?.innerHTML).toBe('bamboo');
|
||||||
|
});
|
||||||
|
});
|
@ -1,9 +1,8 @@
|
|||||||
/* eslint-disable class-methods-use-this */
|
/* eslint-disable class-methods-use-this */
|
||||||
import { mount } from 'enzyme';
|
|
||||||
import KeyCode from 'rc-util/lib/KeyCode';
|
import KeyCode from 'rc-util/lib/KeyCode';
|
||||||
import raf from 'rc-util/lib/raf';
|
import raf from 'rc-util/lib/raf';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { sleep } from '../../../tests/utils';
|
import { sleep, render, fireEvent } from '../../../tests/utils';
|
||||||
import getDataOrAriaProps from '../getDataOrAriaProps';
|
import getDataOrAriaProps from '../getDataOrAriaProps';
|
||||||
import delayRaf from '../raf';
|
import delayRaf from '../raf';
|
||||||
import { isStyleSupport } from '../styleChecker';
|
import { isStyleSupport } from '../styleChecker';
|
||||||
@ -141,20 +140,24 @@ describe('Test utils function', () => {
|
|||||||
|
|
||||||
describe('TransButton', () => {
|
describe('TransButton', () => {
|
||||||
it('can be focus/blur', () => {
|
it('can be focus/blur', () => {
|
||||||
const ref = React.createRef();
|
const ref = React.createRef<any>();
|
||||||
mount(<TransButton ref={ref}>TransButton</TransButton>);
|
render(<TransButton ref={ref}>TransButton</TransButton>);
|
||||||
expect(typeof ref.current.focus).toBe('function');
|
expect(typeof ref.current?.focus).toBe('function');
|
||||||
expect(typeof ref.current.blur).toBe('function');
|
expect(typeof ref.current?.blur).toBe('function');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should trigger onClick when press enter', () => {
|
it('should trigger onClick when press enter', () => {
|
||||||
const onClick = jest.fn();
|
const onClick = jest.fn();
|
||||||
const preventDefault = jest.fn();
|
|
||||||
const wrapper = mount(<TransButton onClick={onClick}>TransButton</TransButton>);
|
const { container } = render(<TransButton onClick={onClick}>TransButton</TransButton>);
|
||||||
wrapper.simulate('keyUp', { keyCode: KeyCode.ENTER });
|
|
||||||
expect(onClick).toHaveBeenCalled();
|
// callback should trigger
|
||||||
wrapper.simulate('keyDown', { keyCode: KeyCode.ENTER, preventDefault });
|
fireEvent.keyUp(container.querySelector('div')!, { keyCode: KeyCode.ENTER });
|
||||||
expect(preventDefault).toHaveBeenCalled();
|
expect(onClick).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
// callback should not trigger
|
||||||
|
fireEvent.keyDown(container.querySelector('div')!, { keyCode: KeyCode.ENTER });
|
||||||
|
expect(onClick).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -167,7 +170,7 @@ describe('Test utils function', () => {
|
|||||||
it('isStyleSupport return false in service side', () => {
|
it('isStyleSupport return false in service side', () => {
|
||||||
const spy = jest
|
const spy = jest
|
||||||
.spyOn(window.document, 'documentElement', 'get')
|
.spyOn(window.document, 'documentElement', 'get')
|
||||||
.mockImplementation(() => undefined);
|
.mockImplementation(() => undefined as unknown as HTMLElement);
|
||||||
expect(isStyleSupport('color')).toBe(false);
|
expect(isStyleSupport('color')).toBe(false);
|
||||||
expect(isStyleSupport('not-existed')).toBe(false);
|
expect(isStyleSupport('not-existed')).toBe(false);
|
||||||
spy.mockRestore();
|
spy.mockRestore();
|
@ -23,9 +23,7 @@ describe('Test warning', () => {
|
|||||||
|
|
||||||
expect(value).toBe(undefined);
|
expect(value).toBe(undefined);
|
||||||
expect(spy).not.toHaveBeenCalled();
|
expect(spy).not.toHaveBeenCalled();
|
||||||
expect(() => {
|
expect(noop).not.toThrow();
|
||||||
noop();
|
|
||||||
}).not.toThrow();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('process.env.NODE_ENV !== "production"', () => {
|
describe('process.env.NODE_ENV !== "production"', () => {
|
@ -1,13 +1,16 @@
|
|||||||
import { mount } from 'enzyme';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import { render, sleep } from '../../../tests/utils';
|
import { render, sleep, fireEvent } from '../../../tests/utils';
|
||||||
import ConfigProvider from '../../config-provider';
|
import ConfigProvider from '../../config-provider';
|
||||||
import Wave from '../wave';
|
import Wave from '../wave';
|
||||||
|
|
||||||
describe('Wave component', () => {
|
describe('Wave component', () => {
|
||||||
mountTest(Wave);
|
mountTest(Wave);
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
document.body.innerHTML = '';
|
||||||
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
const styles = document.getElementsByTagName('style');
|
const styles = document.getElementsByTagName('style');
|
||||||
for (let i = 0; i < styles.length; i += 1) {
|
for (let i = 0; i < styles.length; i += 1) {
|
||||||
@ -15,39 +18,47 @@ describe('Wave component', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function filterStyles(styles: any) {
|
||||||
|
return Array.from<HTMLStyleElement>(styles).filter(
|
||||||
|
(style: HTMLStyleElement) => !style.hasAttribute('data-css-hash'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
it('isHidden works', () => {
|
it('isHidden works', () => {
|
||||||
const TEST_NODE_ENV = process.env.NODE_ENV;
|
const TEST_NODE_ENV = process.env.NODE_ENV;
|
||||||
process.env.NODE_ENV = 'development';
|
process.env.NODE_ENV = 'development';
|
||||||
const wrapper = mount(
|
const { container, unmount } = render(
|
||||||
<Wave>
|
<Wave>
|
||||||
<button type="button">button</button>
|
<button type="button">button</button>
|
||||||
</Wave>,
|
</Wave>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('button').getDOMNode().className).toBe('');
|
expect(container.querySelector('button')?.className).toBe('');
|
||||||
wrapper.find('button').getDOMNode().click();
|
|
||||||
|
container.querySelector('button')?.click();
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
wrapper.find('button').getDOMNode().hasAttribute('ant-click-animating-without-extra-node'),
|
container.querySelector('button')?.hasAttribute('ant-click-animating-without-extra-node'),
|
||||||
).toBe(false);
|
).toBeFalsy();
|
||||||
wrapper.unmount();
|
unmount();
|
||||||
process.env.NODE_ENV = TEST_NODE_ENV;
|
process.env.NODE_ENV = TEST_NODE_ENV;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('isHidden is mocked', () => {
|
it('isHidden is mocked', () => {
|
||||||
const wrapper = mount(
|
const { container, unmount } = render(
|
||||||
<Wave>
|
<Wave>
|
||||||
<button type="button">button</button>
|
<button type="button">button</button>
|
||||||
</Wave>,
|
</Wave>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('button').getDOMNode().className).toBe('');
|
expect(container.querySelector('button')?.className).toBe('');
|
||||||
wrapper.find('button').getDOMNode().click();
|
container.querySelector('button')?.click();
|
||||||
expect(
|
expect(
|
||||||
wrapper.find('button').getDOMNode().getAttribute('ant-click-animating-without-extra-node'),
|
container.querySelector('button')?.getAttribute('ant-click-animating-without-extra-node'),
|
||||||
).toBe('false');
|
).toBe('false');
|
||||||
wrapper.unmount();
|
unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('wave color is grey', async () => {
|
it('wave color is grey', async () => {
|
||||||
const wrapper = mount(
|
const { container, unmount } = render(
|
||||||
<Wave>
|
<Wave>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@ -57,103 +68,124 @@ describe('Wave component', () => {
|
|||||||
</button>
|
</button>
|
||||||
</Wave>,
|
</Wave>,
|
||||||
);
|
);
|
||||||
wrapper.find('button').getDOMNode().click();
|
container.querySelector('button')?.click();
|
||||||
await sleep(0);
|
await sleep(0);
|
||||||
const styles = wrapper.find('button').getDOMNode().getRootNode().getElementsByTagName('style');
|
let styles: HTMLCollectionOf<HTMLStyleElement> | HTMLStyleElement[] = (
|
||||||
|
container.querySelector('button')?.getRootNode() as HTMLButtonElement
|
||||||
|
).getElementsByTagName('style');
|
||||||
|
styles = filterStyles(styles);
|
||||||
expect(styles.length).toBe(0);
|
expect(styles.length).toBe(0);
|
||||||
wrapper.unmount();
|
unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('wave color is not grey', async () => {
|
it('wave color is not grey', async () => {
|
||||||
const wrapper = mount(
|
const { container, unmount } = render(
|
||||||
<Wave>
|
<Wave>
|
||||||
<button type="button" style={{ borderColor: 'red' }}>
|
<button type="button" style={{ borderColor: 'red' }}>
|
||||||
button
|
button
|
||||||
</button>
|
</button>
|
||||||
</Wave>,
|
</Wave>,
|
||||||
);
|
);
|
||||||
wrapper.find('button').getDOMNode().click();
|
container.querySelector('button')?.click();
|
||||||
await sleep(200);
|
await sleep(200);
|
||||||
const styles = wrapper.find('button').getDOMNode().getRootNode().getElementsByTagName('style');
|
let styles: HTMLCollectionOf<HTMLStyleElement> | HTMLStyleElement[] = (
|
||||||
|
container.querySelector('button')?.getRootNode() as HTMLButtonElement
|
||||||
|
).getElementsByTagName('style');
|
||||||
|
styles = filterStyles(styles);
|
||||||
expect(styles.length).toBe(1);
|
expect(styles.length).toBe(1);
|
||||||
expect(styles[0].innerHTML).toContain('--antd-wave-shadow-color: red;');
|
expect(styles[0].innerHTML).toContain('--antd-wave-shadow-color: red;');
|
||||||
wrapper.unmount();
|
unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('read wave color from border-top-color', async () => {
|
it('read wave color from border-top-color', async () => {
|
||||||
const wrapper = mount(
|
const { container, unmount } = render(
|
||||||
<Wave>
|
<Wave>
|
||||||
<div style={{ borderTopColor: 'blue' }}>button</div>
|
<div style={{ borderTopColor: 'blue' }}>button</div>
|
||||||
</Wave>,
|
</Wave>,
|
||||||
);
|
);
|
||||||
wrapper.find('div').getDOMNode().click();
|
container.querySelector('div')?.click();
|
||||||
await sleep(0);
|
await sleep(0);
|
||||||
const styles = wrapper.find('div').getDOMNode().getRootNode().getElementsByTagName('style');
|
let styles: HTMLCollectionOf<HTMLStyleElement> | HTMLStyleElement[] = (
|
||||||
|
container.querySelector('div')?.getRootNode() as HTMLDivElement
|
||||||
|
).getElementsByTagName('style');
|
||||||
|
styles = filterStyles(styles);
|
||||||
expect(styles.length).toBe(1);
|
expect(styles.length).toBe(1);
|
||||||
expect(styles[0].innerHTML).toContain('--antd-wave-shadow-color: blue;');
|
expect(styles[0].innerHTML).toContain('--antd-wave-shadow-color: blue;');
|
||||||
wrapper.unmount();
|
unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('read wave color from background color', async () => {
|
it('read wave color from background color', async () => {
|
||||||
const wrapper = mount(
|
const { container, unmount } = render(
|
||||||
<Wave>
|
<Wave>
|
||||||
<div style={{ backgroundColor: 'green' }}>button</div>
|
<div style={{ backgroundColor: 'green' }}>button</div>
|
||||||
</Wave>,
|
</Wave>,
|
||||||
);
|
);
|
||||||
wrapper.find('div').getDOMNode().click();
|
container.querySelector('div')?.click();
|
||||||
await sleep(0);
|
await sleep(0);
|
||||||
const styles = wrapper.find('div').getDOMNode().getRootNode().getElementsByTagName('style');
|
let styles: HTMLCollectionOf<HTMLStyleElement> | HTMLStyleElement[] = (
|
||||||
|
container.querySelector('div')?.getRootNode() as HTMLDivElement
|
||||||
|
).getElementsByTagName('style');
|
||||||
|
styles = filterStyles(styles);
|
||||||
expect(styles.length).toBe(1);
|
expect(styles.length).toBe(1);
|
||||||
expect(styles[0].innerHTML).toContain('--antd-wave-shadow-color: green;');
|
expect(styles[0].innerHTML).toContain('--antd-wave-shadow-color: green;');
|
||||||
wrapper.unmount();
|
unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('read wave color from border firstly', async () => {
|
it('read wave color from border firstly', async () => {
|
||||||
const wrapper = mount(
|
const { container, unmount } = render(
|
||||||
<Wave>
|
<Wave>
|
||||||
<div style={{ borderColor: 'yellow', backgroundColor: 'green' }}>button</div>
|
<div style={{ borderColor: 'yellow', backgroundColor: 'green' }}>button</div>
|
||||||
</Wave>,
|
</Wave>,
|
||||||
);
|
);
|
||||||
wrapper.find('div').getDOMNode().click();
|
container.querySelector('div')?.click();
|
||||||
await sleep(0);
|
await sleep(0);
|
||||||
const styles = wrapper.find('div').getDOMNode().getRootNode().getElementsByTagName('style');
|
let styles: HTMLCollectionOf<HTMLStyleElement> | HTMLStyleElement[] = (
|
||||||
|
container.querySelector('div')?.getRootNode() as HTMLDivElement
|
||||||
|
).getElementsByTagName('style');
|
||||||
|
styles = filterStyles(styles);
|
||||||
expect(styles.length).toBe(1);
|
expect(styles.length).toBe(1);
|
||||||
expect(styles[0].innerHTML).toContain('--antd-wave-shadow-color: yellow;');
|
expect(styles[0].innerHTML).toContain('--antd-wave-shadow-color: yellow;');
|
||||||
wrapper.unmount();
|
unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('hidden element with -leave className', async () => {
|
it('hidden element with -leave className', async () => {
|
||||||
const wrapper = mount(
|
const { container, unmount } = render(
|
||||||
<Wave>
|
<Wave>
|
||||||
<button type="button" className="xx-leave">
|
<button type="button" className="xx-leave">
|
||||||
button
|
button
|
||||||
</button>
|
</button>
|
||||||
</Wave>,
|
</Wave>,
|
||||||
);
|
);
|
||||||
wrapper.find('button').getDOMNode().click();
|
container.querySelector('button')?.click();
|
||||||
await sleep(0);
|
await sleep(0);
|
||||||
const styles = wrapper.find('button').getDOMNode().getRootNode().getElementsByTagName('style');
|
let styles: HTMLCollectionOf<HTMLStyleElement> | HTMLStyleElement[] = (
|
||||||
|
container.querySelector('button')?.getRootNode() as HTMLButtonElement
|
||||||
|
).getElementsByTagName('style');
|
||||||
|
styles = filterStyles(styles);
|
||||||
expect(styles.length).toBe(0);
|
expect(styles.length).toBe(0);
|
||||||
wrapper.unmount();
|
unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('ConfigProvider csp', async () => {
|
it('ConfigProvider csp', async () => {
|
||||||
const wrapper = mount(
|
const { container, unmount } = render(
|
||||||
<ConfigProvider csp={{ nonce: 'YourNonceCode' }}>
|
<ConfigProvider csp={{ nonce: 'YourNonceCode' }}>
|
||||||
<Wave>
|
<Wave>
|
||||||
<button type="button">button</button>
|
<button type="button">button</button>
|
||||||
</Wave>
|
</Wave>
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
wrapper.find('button').getDOMNode().click();
|
container.querySelector('button')?.click();
|
||||||
await sleep(0);
|
await sleep(0);
|
||||||
const styles = wrapper.find('button').getDOMNode().getRootNode().getElementsByTagName('style');
|
let styles: HTMLCollectionOf<HTMLStyleElement> | HTMLStyleElement[] = (
|
||||||
|
container.querySelector('button')?.getRootNode() as HTMLButtonElement
|
||||||
|
).getElementsByTagName('style');
|
||||||
|
styles = filterStyles(styles);
|
||||||
expect(styles[0].getAttribute('nonce')).toBe('YourNonceCode');
|
expect(styles[0].getAttribute('nonce')).toBe('YourNonceCode');
|
||||||
wrapper.unmount();
|
unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('bindAnimationEvent should return when node is null', () => {
|
it('bindAnimationEvent should return when node is null', () => {
|
||||||
const ref = React.createRef();
|
const ref = React.createRef<any>();
|
||||||
render(
|
render(
|
||||||
<Wave ref={ref}>
|
<Wave ref={ref}>
|
||||||
<button type="button" disabled>
|
<button type="button" disabled>
|
||||||
@ -165,7 +197,7 @@ describe('Wave component', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('bindAnimationEvent.onClick should return when children is hidden', () => {
|
it('bindAnimationEvent.onClick should return when children is hidden', () => {
|
||||||
const ref = React.createRef();
|
const ref = React.createRef<any>();
|
||||||
render(
|
render(
|
||||||
<Wave ref={ref}>
|
<Wave ref={ref}>
|
||||||
<button type="button" style={{ display: 'none' }}>
|
<button type="button" style={{ display: 'none' }}>
|
||||||
@ -177,7 +209,7 @@ describe('Wave component', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('bindAnimationEvent.onClick should return when children is input', () => {
|
it('bindAnimationEvent.onClick should return when children is input', () => {
|
||||||
const ref = React.createRef();
|
const ref = React.createRef<any>();
|
||||||
render(
|
render(
|
||||||
<Wave ref={ref}>
|
<Wave ref={ref}>
|
||||||
<input />
|
<input />
|
||||||
@ -188,48 +220,54 @@ describe('Wave component', () => {
|
|||||||
|
|
||||||
it('should not throw when click it', () => {
|
it('should not throw when click it', () => {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<Wave>
|
<Wave>
|
||||||
<div />
|
<div />
|
||||||
</Wave>,
|
</Wave>,
|
||||||
);
|
);
|
||||||
wrapper.simulate('click');
|
fireEvent.click(container);
|
||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not throw when no children', () => {
|
it('should not throw when no children', () => {
|
||||||
expect(() => mount(<Wave />)).not.toThrow();
|
expect(() => render(<Wave />)).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('wave color should inferred if border is transparent and background is not', async () => {
|
it('wave color should inferred if border is transparent and background is not', async () => {
|
||||||
const wrapper = mount(
|
const { container, unmount } = render(
|
||||||
<Wave>
|
<Wave>
|
||||||
<button type="button" style={{ borderColor: 'transparent', background: 'red' }}>
|
<button type="button" style={{ borderColor: 'transparent', background: 'red' }}>
|
||||||
button
|
button
|
||||||
</button>
|
</button>
|
||||||
</Wave>,
|
</Wave>,
|
||||||
);
|
);
|
||||||
wrapper.find('button').getDOMNode().click();
|
fireEvent.click(container.querySelector('button')!);
|
||||||
await sleep(200);
|
await sleep(200);
|
||||||
const styles = wrapper.find('button').getDOMNode().getRootNode().getElementsByTagName('style');
|
let styles = (container.querySelector('button')!.getRootNode() as any).getElementsByTagName(
|
||||||
|
'style',
|
||||||
|
);
|
||||||
|
styles = filterStyles(styles);
|
||||||
expect(styles.length).toBe(1);
|
expect(styles.length).toBe(1);
|
||||||
expect(styles[0].innerHTML).toContain('--antd-wave-shadow-color: red;');
|
expect(styles[0].innerHTML).toContain('--antd-wave-shadow-color: red;');
|
||||||
wrapper.unmount();
|
unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('wave color should inferred if borderTopColor is transparent and borderColor is not', async () => {
|
it('wave color should inferred if borderTopColor is transparent and borderColor is not', async () => {
|
||||||
const wrapper = mount(
|
const { container, unmount } = render(
|
||||||
<Wave>
|
<Wave>
|
||||||
<button type="button" style={{ borderColor: 'red', borderTopColor: 'transparent' }}>
|
<button type="button" style={{ borderColor: 'red', borderTopColor: 'transparent' }}>
|
||||||
button
|
button
|
||||||
</button>
|
</button>
|
||||||
</Wave>,
|
</Wave>,
|
||||||
);
|
);
|
||||||
wrapper.find('button').getDOMNode().click();
|
fireEvent.click(container.querySelector('button')!);
|
||||||
await sleep(200);
|
await sleep(200);
|
||||||
const styles = wrapper.find('button').getDOMNode().getRootNode().getElementsByTagName('style');
|
let styles = (container.querySelector('button')!.getRootNode() as any).getElementsByTagName(
|
||||||
expect(styles.length).toBe(1);
|
'style',
|
||||||
|
);
|
||||||
|
styles = filterStyles(styles);
|
||||||
|
|
||||||
expect(styles[0].innerHTML).toContain('--antd-wave-shadow-color: red;');
|
expect(styles[0].innerHTML).toContain('--antd-wave-shadow-color: red;');
|
||||||
wrapper.unmount();
|
unmount();
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -3,7 +3,7 @@ import rcWarning, { resetWarned } from 'rc-util/lib/warning';
|
|||||||
export { resetWarned };
|
export { resetWarned };
|
||||||
export function noop() {}
|
export function noop() {}
|
||||||
|
|
||||||
type Warning = (valid: boolean, component: string, message: string) => void;
|
type Warning = (valid: boolean, component: string, message?: string) => void;
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-mutable-exports
|
// eslint-disable-next-line import/no-mutable-exports
|
||||||
let warning: Warning = noop;
|
let warning: Warning = noop;
|
||||||
|
@ -902,7 +902,6 @@ exports[`Cascader legacy props should support showCheckedStrategy child 1`] = `
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
class="ant-select-selection-search-mirror"
|
class="ant-select-selection-search-mirror"
|
||||||
>
|
>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -1056,7 +1055,6 @@ exports[`Cascader legacy props should support showCheckedStrategy parent 1`] = `
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
class="ant-select-selection-search-mirror"
|
class="ant-select-selection-search-mirror"
|
||||||
>
|
>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
241
components/checkbox/style/mixin.less
Normal file
241
components/checkbox/style/mixin.less
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
@import '../../style/mixins/index';
|
||||||
|
|
||||||
|
.antCheckboxFn(@checkbox-prefix-cls: ~'@{ant-prefix}-checkbox') {
|
||||||
|
@checkbox-inner-prefix-cls: ~'@{checkbox-prefix-cls}-inner';
|
||||||
|
// 一般状态
|
||||||
|
.@{checkbox-prefix-cls} {
|
||||||
|
.reset-component();
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
top: 0.2em;
|
||||||
|
line-height: 1;
|
||||||
|
white-space: nowrap;
|
||||||
|
outline: none;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.@{checkbox-prefix-cls}-wrapper:hover &-inner,
|
||||||
|
&:hover &-inner,
|
||||||
|
&-input:focus + &-inner {
|
||||||
|
border-color: @checkbox-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-checked::after {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: 1px solid @checkbox-color;
|
||||||
|
border-radius: @checkbox-border-radius;
|
||||||
|
visibility: hidden;
|
||||||
|
animation: antCheckboxEffect 0.36s ease-in-out;
|
||||||
|
animation-fill-mode: backwards;
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover::after,
|
||||||
|
.@{checkbox-prefix-cls}-wrapper:hover &::after {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-inner {
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
display: block;
|
||||||
|
width: @checkbox-size;
|
||||||
|
height: @checkbox-size;
|
||||||
|
direction: ltr;
|
||||||
|
background-color: @checkbox-check-bg;
|
||||||
|
border: @checkbox-border-width @border-style-base @border-color-base;
|
||||||
|
border-radius: @checkbox-border-radius;
|
||||||
|
// Fix IE checked style
|
||||||
|
// https://github.com/ant-design/ant-design/issues/12597
|
||||||
|
border-collapse: separate;
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
@check-width: (@checkbox-size / 14) * 5px;
|
||||||
|
@check-height: (@checkbox-size / 14) * 8px;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
// https://github.com/ant-design/ant-design/pull/19452
|
||||||
|
// https://github.com/ant-design/ant-design/pull/31726
|
||||||
|
left: 21.5%;
|
||||||
|
display: table;
|
||||||
|
width: @check-width;
|
||||||
|
height: @check-height;
|
||||||
|
border: 2px solid @checkbox-check-color;
|
||||||
|
border-top: 0;
|
||||||
|
border-left: 0;
|
||||||
|
transform: rotate(45deg) scale(0) translate(-50%, -50%);
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 0.1s @ease-in-back, opacity 0.1s;
|
||||||
|
content: ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-input {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选中状态
|
||||||
|
.@{checkbox-prefix-cls}-checked .@{checkbox-inner-prefix-cls}::after {
|
||||||
|
position: absolute;
|
||||||
|
display: table;
|
||||||
|
border: 2px solid @checkbox-check-color;
|
||||||
|
border-top: 0;
|
||||||
|
border-left: 0;
|
||||||
|
transform: rotate(45deg) scale(1) translate(-50%, -50%);
|
||||||
|
opacity: 1;
|
||||||
|
transition: all 0.2s @ease-out-back 0.1s;
|
||||||
|
content: ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{checkbox-prefix-cls}-checked {
|
||||||
|
.@{checkbox-inner-prefix-cls} {
|
||||||
|
background-color: @checkbox-color;
|
||||||
|
border-color: @checkbox-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{checkbox-prefix-cls}-disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
|
||||||
|
&.@{checkbox-prefix-cls}-checked {
|
||||||
|
.@{checkbox-inner-prefix-cls}::after {
|
||||||
|
border-color: @disabled-color;
|
||||||
|
animation-name: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{checkbox-prefix-cls}-input {
|
||||||
|
cursor: not-allowed;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{checkbox-inner-prefix-cls} {
|
||||||
|
background-color: @input-disabled-bg;
|
||||||
|
border-color: @border-color-base !important;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
border-color: @input-disabled-bg;
|
||||||
|
border-collapse: separate;
|
||||||
|
animation-name: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& + span {
|
||||||
|
color: @disabled-color;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not show highlight border of checkbox when disabled
|
||||||
|
&:hover::after,
|
||||||
|
.@{checkbox-prefix-cls}-wrapper:hover &::after {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{checkbox-prefix-cls}-wrapper {
|
||||||
|
.reset-component();
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: baseline;
|
||||||
|
line-height: unset;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
display: inline-block;
|
||||||
|
width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
content: '\a0';
|
||||||
|
}
|
||||||
|
|
||||||
|
&.@{checkbox-prefix-cls}-wrapper-disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
& + & {
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&&-in-form-item {
|
||||||
|
input[type='checkbox'] {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{checkbox-prefix-cls} + span {
|
||||||
|
padding-right: 8px;
|
||||||
|
padding-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{checkbox-prefix-cls}-group {
|
||||||
|
.reset-component();
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
&-item {
|
||||||
|
margin-right: @checkbox-group-item-margin-right;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-item + &-item {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 半选状态
|
||||||
|
.@{checkbox-prefix-cls}-indeterminate {
|
||||||
|
.@{checkbox-inner-prefix-cls} {
|
||||||
|
background-color: @checkbox-check-bg;
|
||||||
|
border-color: @border-color-base;
|
||||||
|
}
|
||||||
|
.@{checkbox-inner-prefix-cls}::after {
|
||||||
|
@indeterminate-width: @checkbox-size - 8px;
|
||||||
|
@indeterminate-height: @checkbox-size - 8px;
|
||||||
|
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
width: @indeterminate-width;
|
||||||
|
height: @indeterminate-height;
|
||||||
|
background-color: @checkbox-color;
|
||||||
|
border: 0;
|
||||||
|
transform: translate(-50%, -50%) scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
content: ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
&.@{checkbox-prefix-cls}-disabled .@{checkbox-inner-prefix-cls}::after {
|
||||||
|
background-color: @disabled-color;
|
||||||
|
border-color: @disabled-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes antCheckboxEffect {
|
||||||
|
0% {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: scale(1.6);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,5 @@
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
||||||
import { render } from 'enzyme';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ConfigProvider from '..';
|
import ConfigProvider from '..';
|
||||||
import Alert from '../../alert';
|
import Alert from '../../alert';
|
||||||
@ -54,6 +53,7 @@ import Transfer from '../../transfer';
|
|||||||
import Tree from '../../tree';
|
import Tree from '../../tree';
|
||||||
import TreeSelect from '../../tree-select';
|
import TreeSelect from '../../tree-select';
|
||||||
import Upload from '../../upload';
|
import Upload from '../../upload';
|
||||||
|
import { render } from '../../../tests/utils';
|
||||||
|
|
||||||
dayjs.extend(customParseFormat);
|
dayjs.extend(customParseFormat);
|
||||||
jest.mock('rc-util/lib/Portal');
|
jest.mock('rc-util/lib/Portal');
|
||||||
@ -61,66 +61,64 @@ jest.mock('rc-util/lib/Portal');
|
|||||||
describe('ConfigProvider', () => {
|
describe('ConfigProvider', () => {
|
||||||
describe('components', () => {
|
describe('components', () => {
|
||||||
function testPair(name, renderComponent) {
|
function testPair(name, renderComponent) {
|
||||||
|
const isArray = ['Menu', 'TimePicker', 'Tooltip'].includes(name);
|
||||||
describe(`${name}`, () => {
|
describe(`${name}`, () => {
|
||||||
// normal
|
// normal
|
||||||
it('normal', () => {
|
it('normal', () => {
|
||||||
expect(render(renderComponent({}))).toMatchSnapshot();
|
const { container } = render(renderComponent({}));
|
||||||
|
expect(isArray ? Array.from(container.children) : container.firstChild).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
// prefixCls
|
// prefixCls
|
||||||
it('prefixCls', () => {
|
it('prefixCls', () => {
|
||||||
expect(render(renderComponent({ prefixCls: `prefix-${name}` }))).toMatchSnapshot();
|
const { container } = render(renderComponent({ prefixCls: `prefix-${name}` }));
|
||||||
|
expect(isArray ? Array.from(container.children) : container.firstChild).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
// configProvider
|
// configProvider
|
||||||
it('configProvider', () => {
|
it('configProvider', () => {
|
||||||
expect(
|
const { container } = render(
|
||||||
render(
|
|
||||||
<ConfigProvider pageHeader={{ ghost: false }} prefixCls="config">
|
<ConfigProvider pageHeader={{ ghost: false }} prefixCls="config">
|
||||||
{renderComponent({})}
|
{renderComponent({})}
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
),
|
);
|
||||||
).toMatchSnapshot();
|
expect(isArray ? Array.from(container.children) : container.firstChild).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('configProvider componentSize large', () => {
|
it('configProvider componentSize large', () => {
|
||||||
expect(
|
const { container } = render(
|
||||||
render(
|
|
||||||
<ConfigProvider componentSize="large" prefixCls="config">
|
<ConfigProvider componentSize="large" prefixCls="config">
|
||||||
{renderComponent({})}
|
{renderComponent({})}
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
),
|
);
|
||||||
).toMatchSnapshot();
|
expect(isArray ? Array.from(container.children) : container.firstChild).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('configProvider componentSize middle', () => {
|
it('configProvider componentSize middle', () => {
|
||||||
expect(
|
const { container } = render(
|
||||||
render(
|
|
||||||
<ConfigProvider componentSize="middle" prefixCls="config">
|
<ConfigProvider componentSize="middle" prefixCls="config">
|
||||||
{renderComponent({})}
|
{renderComponent({})}
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
),
|
);
|
||||||
).toMatchSnapshot();
|
expect(isArray ? Array.from(container.children) : container.firstChild).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('configProvider componentDisabled', () => {
|
it('configProvider componentDisabled', () => {
|
||||||
expect(
|
const { container } = render(
|
||||||
render(
|
|
||||||
<ConfigProvider componentDisabled prefixCls="config">
|
<ConfigProvider componentDisabled prefixCls="config">
|
||||||
{renderComponent({})}
|
{renderComponent({})}
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
),
|
);
|
||||||
).toMatchSnapshot();
|
expect(isArray ? Array.from(container.children) : container.firstChild).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('configProvider virtual and dropdownMatchSelectWidth', () => {
|
it('configProvider virtual and dropdownMatchSelectWidth', () => {
|
||||||
expect(
|
const { container } = render(
|
||||||
render(
|
|
||||||
<ConfigProvider virtual={false} dropdownMatchSelectWidth={false}>
|
<ConfigProvider virtual={false} dropdownMatchSelectWidth={false}>
|
||||||
{renderComponent({})}
|
{renderComponent({})}
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
),
|
);
|
||||||
).toMatchSnapshot();
|
expect(isArray ? Array.from(container.children) : container.firstChild).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -148,9 +146,7 @@ describe('ConfigProvider', () => {
|
|||||||
|
|
||||||
// Badge
|
// Badge
|
||||||
testPair('Badge', props => {
|
testPair('Badge', props => {
|
||||||
const newProps = {
|
const newProps = { ...props };
|
||||||
...props,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Hook for additional `scrollNumberPrefixCls` prop
|
// Hook for additional `scrollNumberPrefixCls` prop
|
||||||
if (props.prefixCls) {
|
if (props.prefixCls) {
|
||||||
@ -162,7 +158,6 @@ describe('ConfigProvider', () => {
|
|||||||
<Badge {...newProps} count={5}>
|
<Badge {...newProps} count={5}>
|
||||||
<span />
|
<span />
|
||||||
</Badge>
|
</Badge>
|
||||||
|
|
||||||
<Badge {...newProps} dot>
|
<Badge {...newProps} dot>
|
||||||
<span />
|
<span />
|
||||||
</Badge>
|
</Badge>
|
||||||
@ -231,7 +226,7 @@ describe('ConfigProvider', () => {
|
|||||||
// Collapse
|
// Collapse
|
||||||
testPair('Collapse', props => (
|
testPair('Collapse', props => (
|
||||||
<Collapse {...props}>
|
<Collapse {...props}>
|
||||||
<Collapse.Panel header="Bamboo">
|
<Collapse.Panel key="Collapse" header="Bamboo">
|
||||||
<p>Light</p>
|
<p>Light</p>
|
||||||
</Collapse.Panel>
|
</Collapse.Panel>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
@ -391,7 +386,7 @@ describe('ConfigProvider', () => {
|
|||||||
// Modal
|
// Modal
|
||||||
testPair('Modal', props => (
|
testPair('Modal', props => (
|
||||||
<div>
|
<div>
|
||||||
<Modal {...props} visible getContainer={false}>
|
<Modal {...props} open getContainer={false}>
|
||||||
Bamboo is Little Light
|
Bamboo is Little Light
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
@ -495,19 +490,11 @@ describe('ConfigProvider', () => {
|
|||||||
title: 'Name',
|
title: 'Name',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
filters: [
|
filters: [
|
||||||
{
|
{ text: 'Joe', value: 'Joe' },
|
||||||
text: 'Joe',
|
|
||||||
value: 'Joe',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
text: 'Submenu',
|
text: 'Submenu',
|
||||||
value: 'Submenu',
|
value: 'Submenu',
|
||||||
children: [
|
children: [{ text: 'Green', value: 'Green' }],
|
||||||
{
|
|
||||||
text: 'Green',
|
|
||||||
value: 'Green',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
filterDropdownOpen: true,
|
filterDropdownOpen: true,
|
||||||
@ -567,7 +554,6 @@ describe('ConfigProvider', () => {
|
|||||||
<Tree {...props}>
|
<Tree {...props}>
|
||||||
<Tree.TreeNode title="bamboo" />
|
<Tree.TreeNode title="bamboo" />
|
||||||
</Tree>
|
</Tree>
|
||||||
|
|
||||||
<Tree.DirectoryTree {...props}>
|
<Tree.DirectoryTree {...props}>
|
||||||
<Tree.TreeNode title="bamboo" />
|
<Tree.TreeNode title="bamboo" />
|
||||||
</Tree.DirectoryTree>
|
</Tree.DirectoryTree>
|
||||||
@ -583,16 +569,7 @@ describe('ConfigProvider', () => {
|
|||||||
|
|
||||||
// Upload
|
// Upload
|
||||||
testPair('Upload', props => (
|
testPair('Upload', props => (
|
||||||
<Upload
|
<Upload {...props} defaultFileList={[{ uid: '1', name: 'xxx.png', status: 'done' }]}>
|
||||||
{...props}
|
|
||||||
defaultFileList={[
|
|
||||||
{
|
|
||||||
uid: '1',
|
|
||||||
name: 'xxx.png',
|
|
||||||
status: 'done',
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<span />
|
<span />
|
||||||
</Upload>
|
</Upload>
|
||||||
));
|
));
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import { mount } from 'enzyme';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ConfigProvider from '..';
|
import ConfigProvider from '..';
|
||||||
import Cascader from '../../cascader';
|
import Cascader from '../../cascader';
|
||||||
import DatePicker from '../../date-picker';
|
import DatePicker from '../../date-picker';
|
||||||
import Drawer from '../../drawer';
|
import Drawer from '../../drawer';
|
||||||
import Slider from '../../slider';
|
import Slider from '../../slider';
|
||||||
|
import { render, fireEvent } from '../../../tests/utils';
|
||||||
|
|
||||||
describe('ConfigProvider.GetPopupContainer', () => {
|
describe('ConfigProvider.GetPopupContainer', () => {
|
||||||
it('Datepicker', () => {
|
it('Datepicker', () => {
|
||||||
const getPopupContainer = jest.fn(node => node.parentNode);
|
const getPopupContainer = jest.fn(node => node.parentNode);
|
||||||
mount(
|
render(
|
||||||
<ConfigProvider getPopupContainer={getPopupContainer}>
|
<ConfigProvider getPopupContainer={getPopupContainer}>
|
||||||
<DatePicker open />
|
<DatePicker open />
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
@ -19,29 +19,29 @@ describe('ConfigProvider.GetPopupContainer', () => {
|
|||||||
|
|
||||||
it('Slider', () => {
|
it('Slider', () => {
|
||||||
const getPopupContainer = jest.fn(node => node.parentNode);
|
const getPopupContainer = jest.fn(node => node.parentNode);
|
||||||
const wrapper = mount(
|
const wrapper = render(
|
||||||
<ConfigProvider getPopupContainer={getPopupContainer}>
|
<ConfigProvider getPopupContainer={getPopupContainer}>
|
||||||
<Slider />
|
<Slider />
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
wrapper.find('.ant-slider-handle').first().simulate('mouseenter');
|
fireEvent.mouseEnter(wrapper.container.querySelector('.ant-slider-handle')!);
|
||||||
expect(getPopupContainer).toHaveBeenCalled();
|
expect(getPopupContainer).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Drawer', () => {
|
it('Drawer', () => {
|
||||||
const getPopupContainer = jest.fn(node => node.parentNode);
|
const getPopupContainer = jest.fn(node => node.parentNode);
|
||||||
const Demo = ({ open }) => (
|
const Demo: React.FC<{ open?: boolean }> = ({ open }) => (
|
||||||
<ConfigProvider getPopupContainer={getPopupContainer}>
|
<ConfigProvider getPopupContainer={getPopupContainer}>
|
||||||
<Drawer open={open} />
|
<Drawer open={open} />
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
);
|
);
|
||||||
mount(<Demo open />);
|
render(<Demo open />);
|
||||||
expect(getPopupContainer).toHaveBeenCalled();
|
expect(getPopupContainer).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Cascader', () => {
|
it('Cascader', () => {
|
||||||
const getPopupContainer = jest.fn(node => node.parentNode);
|
const getPopupContainer = jest.fn(node => node.parentNode);
|
||||||
mount(<Cascader getPopupContainer={getPopupContainer} open />);
|
render(<Cascader getPopupContainer={getPopupContainer} open />);
|
||||||
expect(getPopupContainer).toHaveBeenCalled();
|
expect(getPopupContainer).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -1,4 +1,3 @@
|
|||||||
import { mount } from 'enzyme';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act } from 'react-dom/test-utils';
|
import { act } from 'react-dom/test-utils';
|
||||||
import ConfigProvider from '..';
|
import ConfigProvider from '..';
|
||||||
@ -16,9 +15,8 @@ describe('ConfigProvider.Form', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('form validateMessages', () => {
|
describe('form validateMessages', () => {
|
||||||
const renderComponent = ({ validateMessages }) => {
|
const renderComponent = ({ validateMessages }: { validateMessages?: any }) => {
|
||||||
const formRef = React.createRef();
|
const formRef = React.createRef<any>();
|
||||||
|
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
<ConfigProvider locale={zhCN} form={{ validateMessages }}>
|
<ConfigProvider locale={zhCN} form={{ validateMessages }}>
|
||||||
<Form ref={formRef} initialValues={{ age: 18 }}>
|
<Form ref={formRef} initialValues={{ age: 18 }}>
|
||||||
@ -31,8 +29,7 @@ describe('ConfigProvider.Form', () => {
|
|||||||
</Form>
|
</Form>
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
|
return [container, formRef] as const;
|
||||||
return [container, formRef];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
it('set locale zhCN', async () => {
|
it('set locale zhCN', async () => {
|
||||||
@ -40,7 +37,7 @@ describe('ConfigProvider.Form', () => {
|
|||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
try {
|
try {
|
||||||
await formRef.current.validateFields();
|
await formRef.current?.validateFields();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
@ -63,7 +60,7 @@ describe('ConfigProvider.Form', () => {
|
|||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
try {
|
try {
|
||||||
await formRef.current.validateFields();
|
await formRef.current?.validateFields();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
@ -86,8 +83,8 @@ describe('ConfigProvider.Form', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('form requiredMark', () => {
|
describe('form requiredMark', () => {
|
||||||
it('set requiredMark optional', async () => {
|
it('set requiredMark optional', () => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<ConfigProvider form={{ requiredMark: 'optional' }}>
|
<ConfigProvider form={{ requiredMark: 'optional' }}>
|
||||||
<Form initialValues={{ age: 18 }}>
|
<Form initialValues={{ age: 18 }}>
|
||||||
<Form.Item name="age" label="年龄" rules={[{ type: 'number', len: 17 }]}>
|
<Form.Item name="age" label="年龄" rules={[{ type: 'number', len: 17 }]}>
|
||||||
@ -96,14 +93,13 @@ describe('ConfigProvider.Form', () => {
|
|||||||
</Form>
|
</Form>
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
|
expect(container.firstChild).toMatchSnapshot();
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('form colon', () => {
|
describe('form colon', () => {
|
||||||
it('set colon false', async () => {
|
it('set colon false', () => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<ConfigProvider form={{ colon: false }}>
|
<ConfigProvider form={{ colon: false }}>
|
||||||
<Form>
|
<Form>
|
||||||
<Form.Item label="没有冒号">
|
<Form.Item label="没有冒号">
|
||||||
@ -112,12 +108,11 @@ describe('ConfigProvider.Form', () => {
|
|||||||
</Form>
|
</Form>
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
|
expect(container.querySelector('.ant-form-item-no-colon')).toBeTruthy();
|
||||||
expect(wrapper.exists('.ant-form-item-no-colon')).toBeTruthy();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('set colon default', async () => {
|
it('set colon default', () => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<ConfigProvider>
|
<ConfigProvider>
|
||||||
<Form>
|
<Form>
|
||||||
<Form.Item label="姓名">
|
<Form.Item label="姓名">
|
||||||
@ -126,8 +121,7 @@ describe('ConfigProvider.Form', () => {
|
|||||||
</Form>
|
</Form>
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
|
expect(container.querySelector('.ant-form-item-no-colon')).toBeFalsy();
|
||||||
expect(wrapper.exists('.ant-form-item-no-colon')).toBeFalsy();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -1,7 +1,7 @@
|
|||||||
import { SmileOutlined } from '@ant-design/icons';
|
import { SmileOutlined } from '@ant-design/icons';
|
||||||
import IconContext from '@ant-design/icons/lib/components/Context';
|
import IconContext from '@ant-design/icons/lib/components/Context';
|
||||||
import { mount } from 'enzyme';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { render } from '../../../tests/utils';
|
||||||
import ConfigProvider from '..';
|
import ConfigProvider from '..';
|
||||||
|
|
||||||
describe('ConfigProvider.Icon', () => {
|
describe('ConfigProvider.Icon', () => {
|
||||||
@ -12,24 +12,23 @@ describe('ConfigProvider.Icon', () => {
|
|||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
document.querySelectorAll('style').forEach(style => {
|
document.querySelectorAll('style').forEach(style => {
|
||||||
style.parentNode.removeChild(style);
|
style.parentNode?.removeChild(style);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('csp', () => {
|
describe('csp', () => {
|
||||||
it('raw', () => {
|
it('raw', () => {
|
||||||
mount(
|
render(
|
||||||
<ConfigProvider csp={{ nonce: 'little' }}>
|
<ConfigProvider csp={{ nonce: 'little' }}>
|
||||||
<SmileOutlined />
|
<SmileOutlined />
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
|
|
||||||
const styleNode = document.querySelector('style');
|
const styleNode = document.querySelector('style');
|
||||||
expect(styleNode.nonce).toEqual('little');
|
expect(styleNode?.nonce).toEqual('little');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('mix with iconPrefixCls', () => {
|
it('mix with iconPrefixCls', () => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<ConfigProvider iconPrefixCls="bamboo" csp={{ nonce: 'light' }}>
|
<ConfigProvider iconPrefixCls="bamboo" csp={{ nonce: 'light' }}>
|
||||||
<SmileOutlined />
|
<SmileOutlined />
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
@ -37,18 +36,18 @@ describe('ConfigProvider.Icon', () => {
|
|||||||
|
|
||||||
const styleNode = document.querySelector('style');
|
const styleNode = document.querySelector('style');
|
||||||
|
|
||||||
expect(wrapper.exists('.bamboo-smile')).toBeTruthy();
|
expect(container.querySelector('.bamboo-smile')).toBeTruthy();
|
||||||
expect(styleNode.nonce).toEqual('light');
|
expect(styleNode?.nonce).toEqual('light');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('nest', () => {
|
it('nest', () => {
|
||||||
const Checker = () => {
|
const Checker = () => {
|
||||||
const { csp } = React.useContext(IconContext);
|
const { csp } = React.useContext(IconContext);
|
||||||
return <div id="csp">{csp.nonce}</div>;
|
return <div id="csp">{csp?.nonce}</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<ConfigProvider iconPrefixCls="bamboo" csp={{ nonce: 'light' }}>
|
<ConfigProvider iconPrefixCls="bamboo" csp={{ nonce: 'light' }}>
|
||||||
<ConfigProvider>
|
<ConfigProvider>
|
||||||
<SmileOutlined />
|
<SmileOutlined />
|
||||||
@ -59,8 +58,8 @@ describe('ConfigProvider.Icon', () => {
|
|||||||
|
|
||||||
const styleNode = document.querySelector('style');
|
const styleNode = document.querySelector('style');
|
||||||
|
|
||||||
expect(wrapper.exists('.bamboo-smile')).toBeTruthy();
|
expect(container.querySelector('.bamboo-smile')).toBeTruthy();
|
||||||
expect(styleNode.nonce).toEqual('light');
|
expect(styleNode?.nonce).toEqual('light');
|
||||||
expect(wrapper.find('#csp').text()).toEqual('light');
|
expect(container.querySelector('#csp')?.innerHTML).toEqual('light');
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -1,9 +1,9 @@
|
|||||||
import { SmileOutlined } from '@ant-design/icons';
|
import { SmileOutlined } from '@ant-design/icons';
|
||||||
import { mount } from 'enzyme';
|
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
import type { ConfigConsumerProps } from '..';
|
||||||
import ConfigProvider, { ConfigContext } from '..';
|
import ConfigProvider, { ConfigContext } from '..';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import { fireEvent, render } from '../../../tests/utils';
|
import { act, fireEvent, render } from '../../../tests/utils';
|
||||||
import Button from '../../button';
|
import Button from '../../button';
|
||||||
import Input from '../../input';
|
import Input from '../../input';
|
||||||
import Table from '../../table';
|
import Table from '../../table';
|
||||||
@ -16,38 +16,49 @@ describe('ConfigProvider', () => {
|
|||||||
));
|
));
|
||||||
|
|
||||||
it('Content Security Policy', () => {
|
it('Content Security Policy', () => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
const csp = { nonce: 'test-antd' };
|
const csp = { nonce: 'test-antd' };
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<ConfigProvider csp={csp}>
|
<ConfigProvider csp={csp}>
|
||||||
<Button />
|
<Button />
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(wrapper.find('InternalWave').instance().csp).toBe(csp);
|
fireEvent.click(container.querySelector('button')!);
|
||||||
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
const styles = Array.from(document.body.querySelectorAll<HTMLStyleElement>('style'));
|
||||||
|
expect(styles[styles.length - 1].nonce).toEqual(csp.nonce);
|
||||||
|
|
||||||
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('autoInsertSpaceInButton', () => {
|
it('autoInsertSpaceInButton', () => {
|
||||||
const wrapper = mount(
|
const text = '确定';
|
||||||
|
const { container } = render(
|
||||||
<ConfigProvider autoInsertSpaceInButton={false}>
|
<ConfigProvider autoInsertSpaceInButton={false}>
|
||||||
<Button>确定</Button>
|
<Button>{text}</Button>
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
|
expect(container.querySelector('span')?.innerHTML).toBe(text);
|
||||||
expect(wrapper.find('Button').text()).toBe('确定');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renderEmpty', () => {
|
it('renderEmpty', () => {
|
||||||
const wrapper = mount(
|
const text = 'empty placeholder';
|
||||||
<ConfigProvider renderEmpty={() => <div>empty placeholder</div>}>
|
const { container } = render(
|
||||||
|
<ConfigProvider renderEmpty={() => <div>{text}</div>}>
|
||||||
<Table />
|
<Table />
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
|
expect(container.querySelector('.ant-table-placeholder')?.querySelector('div')?.innerHTML).toBe(
|
||||||
expect(wrapper.text()).toContain('empty placeholder');
|
text,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('nest prefixCls', () => {
|
it('nest prefixCls', () => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<ConfigProvider prefixCls="bamboo">
|
<ConfigProvider prefixCls="bamboo">
|
||||||
<ConfigProvider>
|
<ConfigProvider>
|
||||||
<Button />
|
<Button />
|
||||||
@ -55,11 +66,11 @@ describe('ConfigProvider', () => {
|
|||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(wrapper.exists('button.bamboo-btn')).toBeTruthy();
|
expect(container.querySelector('button.bamboo-btn')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dynamic prefixCls', () => {
|
it('dynamic prefixCls', () => {
|
||||||
const DynamicPrefixCls = () => {
|
const DynamicPrefixCls: React.FC = () => {
|
||||||
const [prefixCls, setPrefixCls] = useState('bamboo');
|
const [prefixCls, setPrefixCls] = useState('bamboo');
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@ -78,37 +89,36 @@ describe('ConfigProvider', () => {
|
|||||||
const { container } = render(<DynamicPrefixCls />);
|
const { container } = render(<DynamicPrefixCls />);
|
||||||
|
|
||||||
expect(container.querySelector('button.bamboo-btn')).toBeTruthy();
|
expect(container.querySelector('button.bamboo-btn')).toBeTruthy();
|
||||||
fireEvent.click(container.querySelector('.toggle-button'));
|
fireEvent.click(container.querySelector('.toggle-button')!);
|
||||||
expect(container.querySelector('button.light-btn')).toBeTruthy();
|
expect(container.querySelector('button.light-btn')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('iconPrefixCls', () => {
|
it('iconPrefixCls', () => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<ConfigProvider iconPrefixCls="bamboo">
|
<ConfigProvider iconPrefixCls="bamboo">
|
||||||
<SmileOutlined />
|
<SmileOutlined />
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(wrapper.find('[role="img"]').hasClass('bamboo')).toBeTruthy();
|
expect(container.querySelector('[role="img"]')).toHaveClass('bamboo');
|
||||||
expect(wrapper.find('[role="img"]').hasClass('bamboo-smile')).toBeTruthy();
|
expect(container.querySelector('[role="img"]')).toHaveClass('bamboo-smile');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('input autoComplete', () => {
|
it('input autoComplete', () => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<ConfigProvider input={{ autoComplete: 'off' }}>
|
<ConfigProvider input={{ autoComplete: 'off' }}>
|
||||||
<Input />
|
<Input />
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
|
expect(container.querySelector('input')?.autocomplete).toEqual('off');
|
||||||
expect(wrapper.find('input').props().autoComplete).toEqual('off');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('render empty', () => {
|
it('render empty', () => {
|
||||||
let rendered = false;
|
let rendered = false;
|
||||||
let cacheRenderEmpty;
|
let cacheRenderEmpty;
|
||||||
|
|
||||||
const App = () => {
|
const App: React.FC = () => {
|
||||||
const { renderEmpty } = React.useContext(ConfigContext);
|
const { renderEmpty } = React.useContext<ConfigConsumerProps>(ConfigContext);
|
||||||
rendered = true;
|
rendered = true;
|
||||||
cacheRenderEmpty = renderEmpty;
|
cacheRenderEmpty = renderEmpty;
|
||||||
return null;
|
return null;
|
@ -1,24 +1,24 @@
|
|||||||
import { mount } from 'enzyme';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { closePicker, openPicker, selectCell } from '../../date-picker/__tests__/utils';
|
||||||
import ConfigProvider from '..';
|
import ConfigProvider from '..';
|
||||||
import DatePicker from '../../date-picker';
|
import DatePicker from '../../date-picker';
|
||||||
import { closePicker, openPicker, selectCell } from '../../date-picker/__tests__/utils';
|
import type { Locale } from '../../locale-provider';
|
||||||
import LocaleProvider from '../../locale-provider';
|
import LocaleProvider from '../../locale-provider';
|
||||||
import enUS from '../../locale/en_US';
|
import enUS from '../../locale/en_US';
|
||||||
import zhCN from '../../locale/zh_CN';
|
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';
|
import { act, render, fireEvent } from '../../../tests/utils';
|
||||||
|
|
||||||
describe('ConfigProvider.Locale', () => {
|
describe('ConfigProvider.Locale', () => {
|
||||||
function $$(className) {
|
function $$(className: string): NodeListOf<Element> {
|
||||||
return document.body.querySelectorAll(className);
|
return document.body.querySelectorAll(className);
|
||||||
}
|
}
|
||||||
|
|
||||||
it('not throw', () => {
|
it('not throw', () => {
|
||||||
mount(
|
render(
|
||||||
<ConfigProvider locale={{}}>
|
<ConfigProvider locale={{} as Locale}>
|
||||||
<span />
|
<span />
|
||||||
<span />
|
<span />
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
@ -28,23 +28,16 @@ describe('ConfigProvider.Locale', () => {
|
|||||||
// https://github.com/ant-design/ant-design/issues/18731
|
// https://github.com/ant-design/ant-design/issues/18731
|
||||||
it('should not reset locale for Modal', () => {
|
it('should not reset locale for Modal', () => {
|
||||||
class App extends React.Component {
|
class App extends React.Component {
|
||||||
state = {
|
state = { showButton: false };
|
||||||
showButton: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.setState({
|
this.setState({ showButton: true });
|
||||||
showButton: true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
openConfirm = () => {
|
openConfirm = () => {
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
Modal.confirm({
|
Modal.confirm({ title: 'title', content: 'Some descriptions' });
|
||||||
title: 'title',
|
|
||||||
content: 'Some descriptions',
|
|
||||||
});
|
|
||||||
act(() => {
|
act(() => {
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
});
|
});
|
||||||
@ -66,24 +59,24 @@ describe('ConfigProvider.Locale', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const wrapper = mount(<App />);
|
const wrapper = render(<App />);
|
||||||
wrapper.find('button').simulate('click');
|
fireEvent.click(wrapper.container.querySelector('button')!);
|
||||||
expect($$('.ant-btn-primary')[0].textContent).toBe('OK');
|
expect($$('.ant-btn-primary')[0].textContent).toBe('OK');
|
||||||
});
|
});
|
||||||
|
|
||||||
// https://github.com/ant-design/ant-design/issues/31592
|
// https://github.com/ant-design/ant-design/issues/31592
|
||||||
it('should not reset the component state when switching locale', () => {
|
it('should not reset the component state when switching locale', () => {
|
||||||
const wrapper = mount(
|
const wrapper = render(
|
||||||
<ConfigProvider locale={zhCN}>
|
<ConfigProvider locale={zhCN}>
|
||||||
<DatePicker />
|
<DatePicker />
|
||||||
<Pagination total={50} />
|
<Pagination total={50} />
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
|
|
||||||
const datepickerInitProps = wrapper.find('.ant-picker-input input').props();
|
const datepicke = wrapper.container.querySelector<HTMLInputElement>('.ant-picker-input input');
|
||||||
expect(datepickerInitProps.value).toBe('');
|
expect(datepicke?.value).toBe('');
|
||||||
expect(datepickerInitProps.placeholder).toBe('请选择日期');
|
expect(datepicke?.placeholder).toBe('请选择日期');
|
||||||
expect(wrapper.find('.ant-pagination-item-1').props().className).toContain(
|
expect(wrapper.container.querySelector('.ant-pagination-item-1')?.className).toContain(
|
||||||
'ant-pagination-item-active',
|
'ant-pagination-item-active',
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -91,58 +84,68 @@ describe('ConfigProvider.Locale', () => {
|
|||||||
selectCell(wrapper, 10);
|
selectCell(wrapper, 10);
|
||||||
closePicker(wrapper);
|
closePicker(wrapper);
|
||||||
|
|
||||||
expect(wrapper.find('.ant-picker-input input').props().value).not.toBe('');
|
expect(
|
||||||
|
wrapper.container.querySelector<HTMLInputElement>('.ant-picker-input input')?.value,
|
||||||
|
).not.toBe('');
|
||||||
|
wrapper.rerender(
|
||||||
|
<ConfigProvider locale={{} as Locale}>
|
||||||
|
<DatePicker />
|
||||||
|
<Pagination total={50} />
|
||||||
|
</ConfigProvider>,
|
||||||
|
);
|
||||||
|
|
||||||
wrapper.setProps({ locale: {} });
|
fireEvent.click(wrapper.container.querySelector('.ant-pagination-item-3')!);
|
||||||
wrapper.find('.ant-pagination-item-3').simulate('click');
|
|
||||||
|
|
||||||
const datepickerProps = wrapper.find('.ant-picker-input input').props();
|
const datepicker = wrapper.container.querySelector<HTMLInputElement>('.ant-picker-input input');
|
||||||
expect(datepickerProps.placeholder).not.toBe('请选择日期');
|
|
||||||
expect(datepickerProps.value).not.toBe('');
|
|
||||||
expect(datepickerProps.value).toContain('-10');
|
|
||||||
|
|
||||||
expect(wrapper.find('.ant-pagination-item-3').props().className).toContain(
|
expect(datepicker?.placeholder).not.toBe('请选择日期');
|
||||||
|
expect(datepicker?.value).not.toBe('');
|
||||||
|
expect(datepicker?.value).toContain('-10');
|
||||||
|
|
||||||
|
expect(wrapper.container.querySelector('.ant-pagination-item-3')?.className).toContain(
|
||||||
'ant-pagination-item-active',
|
'ant-pagination-item-active',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('support legacy LocaleProvider', () => {
|
describe('support legacy LocaleProvider', () => {
|
||||||
function testLocale(wrapper) {
|
function testLocale(wrapper: ReturnType<typeof render>): void {
|
||||||
expect(wrapper.find('input').props().placeholder).toBe(zhCN.TimePicker.placeholder);
|
expect(wrapper.container.querySelector('input')?.placeholder).toBe(
|
||||||
|
zhCN.TimePicker?.placeholder,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
it('LocaleProvider', () => {
|
it('LocaleProvider', () => {
|
||||||
const wrapper = mount(
|
testLocale(
|
||||||
|
render(
|
||||||
<LocaleProvider locale={zhCN}>
|
<LocaleProvider locale={zhCN}>
|
||||||
<TimePicker />
|
<TimePicker />
|
||||||
</LocaleProvider>,
|
</LocaleProvider>,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
testLocale(wrapper);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('LocaleProvider > ConfigProvider', () => {
|
it('LocaleProvider > ConfigProvider', () => {
|
||||||
const wrapper = mount(
|
testLocale(
|
||||||
|
render(
|
||||||
<LocaleProvider locale={zhCN}>
|
<LocaleProvider locale={zhCN}>
|
||||||
<ConfigProvider>
|
<ConfigProvider>
|
||||||
<TimePicker />
|
<TimePicker />
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
</LocaleProvider>,
|
</LocaleProvider>,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
testLocale(wrapper);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('ConfigProvider > ConfigProvider', () => {
|
it('ConfigProvider > ConfigProvider', () => {
|
||||||
const wrapper = mount(
|
testLocale(
|
||||||
|
render(
|
||||||
<ConfigProvider locale={zhCN}>
|
<ConfigProvider locale={zhCN}>
|
||||||
<ConfigProvider>
|
<ConfigProvider>
|
||||||
<TimePicker />
|
<TimePicker />
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
testLocale(wrapper);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -1,16 +1,20 @@
|
|||||||
import { mount } from 'enzyme';
|
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import ConfigProvider from '..';
|
import ConfigProvider from '..';
|
||||||
import Tooltip from '../../tooltip';
|
import Tooltip from '../../tooltip';
|
||||||
|
import { pureRender, fireEvent } from '../../../tests/utils';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
spy: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
// https://github.com/ant-design/ant-design/issues/27617
|
// https://github.com/ant-design/ant-design/issues/27617
|
||||||
describe('ConfigProvider', () => {
|
describe('ConfigProvider', () => {
|
||||||
const Child = ({ spy }) => {
|
const Child: React.FC<Props> = ({ spy }) => {
|
||||||
React.useEffect(() => spy());
|
React.useEffect(() => spy());
|
||||||
return <div />;
|
return <div />;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Sibling = ({ spy }) => (
|
const Sibling: React.FC<Props> = ({ spy }) => (
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<Child spy={spy} />
|
<Child spy={spy} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@ -19,7 +23,7 @@ describe('ConfigProvider', () => {
|
|||||||
it('should not generate new context config when render', () => {
|
it('should not generate new context config when render', () => {
|
||||||
const MemoedSibling = React.memo(Sibling);
|
const MemoedSibling = React.memo(Sibling);
|
||||||
const spy = jest.fn();
|
const spy = jest.fn();
|
||||||
const App = () => {
|
const App: React.FC = () => {
|
||||||
const [pageHeader, setPageHeader] = useState({ ghost: true });
|
const [pageHeader, setPageHeader] = useState({ ghost: true });
|
||||||
const [, forceRender] = React.useReducer(v => v + 1, 1);
|
const [, forceRender] = React.useReducer(v => v + 1, 1);
|
||||||
|
|
||||||
@ -40,18 +44,19 @@ describe('ConfigProvider', () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const wrapper = mount(<App />);
|
const { container } = pureRender(<App />);
|
||||||
wrapper.find('.render').simulate('click');
|
|
||||||
|
fireEvent.click(container.querySelector('.render')!);
|
||||||
expect(spy.mock.calls.length).toEqual(1);
|
expect(spy.mock.calls.length).toEqual(1);
|
||||||
|
|
||||||
wrapper.find('.setState').simulate('click');
|
fireEvent.click(container.querySelector('.setState')!);
|
||||||
expect(spy.mock.calls.length).toEqual(2);
|
expect(spy.mock.calls.length).toEqual(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not generate new context config in nested ConfigProvider when render', () => {
|
it('should not generate new context config in nested ConfigProvider when render', () => {
|
||||||
const MemoedSibling = React.memo(Sibling);
|
const MemoedSibling = React.memo(Sibling);
|
||||||
const spy = jest.fn();
|
const spy = jest.fn();
|
||||||
const App = () => {
|
const App: React.FC = () => {
|
||||||
const [pageHeader, setPageHeader] = useState({ ghost: true });
|
const [pageHeader, setPageHeader] = useState({ ghost: true });
|
||||||
const [, forceRender] = React.useReducer(v => v + 1, 1);
|
const [, forceRender] = React.useReducer(v => v + 1, 1);
|
||||||
|
|
||||||
@ -74,11 +79,12 @@ describe('ConfigProvider', () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const wrapper = mount(<App />);
|
const { container } = pureRender(<App />);
|
||||||
wrapper.find('.render').simulate('click');
|
|
||||||
|
fireEvent.click(container.querySelector('.render')!);
|
||||||
expect(spy.mock.calls.length).toEqual(1);
|
expect(spy.mock.calls.length).toEqual(1);
|
||||||
|
|
||||||
wrapper.find('.setState').simulate('click');
|
fireEvent.click(container.querySelector('.setState')!);
|
||||||
expect(spy.mock.calls.length).toEqual(2);
|
expect(spy.mock.calls.length).toEqual(2);
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -1,15 +1,14 @@
|
|||||||
import { mount } from 'enzyme';
|
|
||||||
import React from 'react';
|
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';
|
import { act, render } from '../../../tests/utils';
|
||||||
|
|
||||||
describe('ConfigProvider.getTargetContainer', () => {
|
describe('ConfigProvider.getTargetContainer', () => {
|
||||||
it('Affix', () => {
|
it('Affix', () => {
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
const getTargetContainer = jest.fn(() => window);
|
const getTargetContainer = jest.fn(() => window as unknown as HTMLElement);
|
||||||
mount(
|
render(
|
||||||
<ConfigProvider getTargetContainer={getTargetContainer}>
|
<ConfigProvider getTargetContainer={getTargetContainer}>
|
||||||
<Affix>
|
<Affix>
|
||||||
<span />
|
<span />
|
||||||
@ -27,8 +26,8 @@ describe('ConfigProvider.getTargetContainer', () => {
|
|||||||
|
|
||||||
it('Anchor', () => {
|
it('Anchor', () => {
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
const getTargetContainer = jest.fn(() => window);
|
const getTargetContainer = jest.fn(() => window as unknown as HTMLElement);
|
||||||
mount(
|
render(
|
||||||
<ConfigProvider getTargetContainer={getTargetContainer}>
|
<ConfigProvider getTargetContainer={getTargetContainer}>
|
||||||
<Anchor>
|
<Anchor>
|
||||||
<Anchor.Link href="#API" title="API" />
|
<Anchor.Link href="#API" title="API" />
|
48
components/config-provider/__tests__/theme.test.ts
Normal file
48
components/config-provider/__tests__/theme.test.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { kebabCase } from 'lodash';
|
||||||
|
import canUseDom from 'rc-util/lib/Dom/canUseDom';
|
||||||
|
import ConfigProvider from '..';
|
||||||
|
import { resetWarned } from '../../_util/warning';
|
||||||
|
|
||||||
|
let mockCanUseDom = true;
|
||||||
|
|
||||||
|
jest.mock('rc-util/lib/Dom/canUseDom', () => () => mockCanUseDom);
|
||||||
|
|
||||||
|
describe('ConfigProvider.Theme', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
mockCanUseDom = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
const colorList = ['primaryColor', 'successColor', 'warningColor', 'errorColor', 'infoColor'];
|
||||||
|
|
||||||
|
colorList.forEach(colorName => {
|
||||||
|
it(colorName, () => {
|
||||||
|
ConfigProvider.config({
|
||||||
|
prefixCls: 'bamboo',
|
||||||
|
theme: { [colorName]: '#0000FF' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const styles: HTMLStyleElement[] = Array.from(document.querySelectorAll('style'));
|
||||||
|
const themeStyle = styles.find(style =>
|
||||||
|
style.getAttribute('rc-util-key')?.includes('-dynamic-theme'),
|
||||||
|
);
|
||||||
|
expect(themeStyle).toBeTruthy();
|
||||||
|
|
||||||
|
expect(themeStyle?.innerHTML).toContain(`--bamboo-${kebabCase(colorName)}: rgb(0, 0, 255)`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('warning for SSR', () => {
|
||||||
|
resetWarned();
|
||||||
|
|
||||||
|
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
mockCanUseDom = false;
|
||||||
|
expect(canUseDom()).toBeFalsy();
|
||||||
|
|
||||||
|
ConfigProvider.config({ theme: {} });
|
||||||
|
|
||||||
|
expect(errorSpy).toHaveBeenCalledWith(
|
||||||
|
'Warning: [antd: ConfigProvider] SSR do not support dynamic theme with css variables.',
|
||||||
|
);
|
||||||
|
errorSpy.mockRestore();
|
||||||
|
});
|
||||||
|
});
|
@ -108,7 +108,7 @@ type Placement = 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight';
|
|||||||
|
|
||||||
const Page: React.FC<{ popupPlacement: Placement }> = ({ popupPlacement }) => {
|
const Page: React.FC<{ popupPlacement: Placement }> = ({ popupPlacement }) => {
|
||||||
const [currentStep, setCurrentStep] = useState(0);
|
const [currentStep, setCurrentStep] = useState(0);
|
||||||
const [modalVisible, setModalVisible] = useState(false);
|
const [modalOpen, setModalOpen] = useState(false);
|
||||||
const [badgeCount, setBadgeCount] = useState(5);
|
const [badgeCount, setBadgeCount] = useState(5);
|
||||||
const [showBadge, setShowBadge] = useState(true);
|
const [showBadge, setShowBadge] = useState(true);
|
||||||
|
|
||||||
@ -139,17 +139,17 @@ const Page: React.FC<{ popupPlacement: Placement }> = ({ popupPlacement }) => {
|
|||||||
|
|
||||||
// ==== Modal ====
|
// ==== Modal ====
|
||||||
const showModal = () => {
|
const showModal = () => {
|
||||||
setModalVisible(true);
|
setModalOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOk = (e: React.MouseEvent<HTMLElement>) => {
|
const handleOk = (e: React.MouseEvent<HTMLElement>) => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
setModalVisible(false);
|
setModalOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = (e: React.MouseEvent<HTMLElement>) => {
|
const handleCancel = (e: React.MouseEvent<HTMLElement>) => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
setModalVisible(false);
|
setModalOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
// ==== End Modal ====
|
// ==== End Modal ====
|
||||||
@ -378,12 +378,7 @@ const Page: React.FC<{ popupPlacement: Placement }> = ({ popupPlacement }) => {
|
|||||||
<Button type="primary" onClick={showModal}>
|
<Button type="primary" onClick={showModal}>
|
||||||
Open Modal
|
Open Modal
|
||||||
</Button>
|
</Button>
|
||||||
<Modal
|
<Modal title="پنچره ساده" open={modalOpen} onOk={handleOk} onCancel={handleCancel}>
|
||||||
title="پنچره ساده"
|
|
||||||
visible={modalVisible}
|
|
||||||
onOk={handleOk}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<p>نگاشتههای خود را اینجا قراردهید</p>
|
<p>نگاشتههای خود را اینجا قراردهید</p>
|
||||||
<p>نگاشتههای خود را اینجا قراردهید</p>
|
<p>نگاشتههای خود را اینجا قراردهید</p>
|
||||||
<p>نگاشتههای خود را اینجا قراردهید</p>
|
<p>نگاشتههای خود را اینجا قراردهید</p>
|
||||||
|
@ -58,14 +58,14 @@ const columns = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const Page = () => {
|
const Page = () => {
|
||||||
const [visible, setVisible] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
const showModal = () => {
|
const showModal = () => {
|
||||||
setVisible(true);
|
setOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const hideModal = () => {
|
const hideModal = () => {
|
||||||
setVisible(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const info = () => {
|
const info = () => {
|
||||||
@ -115,7 +115,7 @@ const Page = () => {
|
|||||||
<div className="example">
|
<div className="example">
|
||||||
<Table dataSource={[]} columns={columns} />
|
<Table dataSource={[]} columns={columns} />
|
||||||
</div>
|
</div>
|
||||||
<Modal title="Locale Modal" visible={visible} onCancel={hideModal}>
|
<Modal title="Locale Modal" open={open} onCancel={hideModal}>
|
||||||
<p>Locale Modal</p>
|
<p>Locale Modal</p>
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,250 +0,0 @@
|
|||||||
import dayjs from 'dayjs';
|
|
||||||
import 'dayjs/locale/mk'; // to test local in 'prop locale should works' test case
|
|
||||||
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
|
||||||
import { mount } from 'enzyme';
|
|
||||||
import MockDate from 'mockdate';
|
|
||||||
import React from 'react';
|
|
||||||
import DatePicker from '..';
|
|
||||||
import focusTest from '../../../tests/shared/focusTest';
|
|
||||||
|
|
||||||
dayjs.extend(customParseFormat);
|
|
||||||
|
|
||||||
describe('DatePicker', () => {
|
|
||||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
|
||||||
|
|
||||||
focusTest(DatePicker, { refFocus: true });
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
MockDate.set(dayjs('2016-11-22').valueOf());
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
MockDate.reset();
|
|
||||||
errorSpy.mockReset();
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
errorSpy.mockRestore();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('prop locale should works', () => {
|
|
||||||
const locale = {
|
|
||||||
lang: {
|
|
||||||
locale: 'mk',
|
|
||||||
placeholder: 'Избери дата',
|
|
||||||
rangePlaceholder: ['Начална дата', 'Крайна дата'],
|
|
||||||
today: 'Днес',
|
|
||||||
now: 'Сега',
|
|
||||||
backToToday: 'Към днес',
|
|
||||||
ok: 'Добре',
|
|
||||||
clear: 'Изчистване',
|
|
||||||
month: 'Месец',
|
|
||||||
year: 'Година',
|
|
||||||
timeSelect: 'Избор на час',
|
|
||||||
dateSelect: 'Избор на дата',
|
|
||||||
monthSelect: 'Избор на месец',
|
|
||||||
yearSelect: 'Избор на година',
|
|
||||||
decadeSelect: 'Десетилетие',
|
|
||||||
previousMonth: 'Предишен месец (PageUp)',
|
|
||||||
nextMonth: 'Следващ месец (PageDown)',
|
|
||||||
previousYear: 'Последна година (Control + left)',
|
|
||||||
nextYear: 'Следваща година (Control + right)',
|
|
||||||
previousDecade: 'Предишно десетилетие',
|
|
||||||
nextDecade: 'Следващо десетилетие',
|
|
||||||
previousCentury: 'Последен век',
|
|
||||||
nextCentury: 'Следващ век',
|
|
||||||
yearFormat: 'YYYY',
|
|
||||||
dateFormat: 'D M YYYY',
|
|
||||||
dayFormat: 'D',
|
|
||||||
dateTimeFormat: 'D M YYYY HH:mm:ss',
|
|
||||||
monthBeforeYear: true,
|
|
||||||
},
|
|
||||||
timePickerLocale: {
|
|
||||||
placeholder: 'Избор на час',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const birthday = dayjs('2000-01-01', 'YYYY-MM-DD');
|
|
||||||
const wrapper = mount(<DatePicker open locale={locale} value={birthday} />);
|
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('disabled date', () => {
|
|
||||||
const disabledDate = current => current && current < dayjs().endOf('day');
|
|
||||||
const wrapper = mount(<DatePicker disabledDate={disabledDate} open />);
|
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('placeholder', () => {
|
|
||||||
const wrapper = mount(<DatePicker placeholder={undefined} />);
|
|
||||||
expect(wrapper.find('input').props().placeholder).toEqual('Select date');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('showTime={{ showHour: true, showMinute: true }}', () => {
|
|
||||||
const wrapper = mount(
|
|
||||||
<DatePicker
|
|
||||||
defaultValue={dayjs()}
|
|
||||||
showTime={{ showHour: true, showMinute: true }}
|
|
||||||
format="YYYY-MM-DD"
|
|
||||||
open
|
|
||||||
/>,
|
|
||||||
);
|
|
||||||
expect(wrapper.find('.ant-picker-time-panel-column').length).toBe(2);
|
|
||||||
expect(
|
|
||||||
wrapper.find('.ant-picker-time-panel-column').at(0).find('.ant-picker-time-panel-cell')
|
|
||||||
.length,
|
|
||||||
).toBe(24);
|
|
||||||
expect(
|
|
||||||
wrapper.find('.ant-picker-time-panel-column').at(1).find('.ant-picker-time-panel-cell')
|
|
||||||
.length,
|
|
||||||
).toBe(60);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('showTime={{ showHour: true, showSecond: true }}', () => {
|
|
||||||
const wrapper = mount(
|
|
||||||
<DatePicker
|
|
||||||
defaultValue={dayjs()}
|
|
||||||
showTime={{ showHour: true, showSecond: true }}
|
|
||||||
format="YYYY-MM-DD"
|
|
||||||
open
|
|
||||||
/>,
|
|
||||||
);
|
|
||||||
expect(wrapper.find('.ant-picker-time-panel-column').length).toBe(2);
|
|
||||||
expect(
|
|
||||||
wrapper.find('.ant-picker-time-panel-column').at(0).find('.ant-picker-time-panel-cell')
|
|
||||||
.length,
|
|
||||||
).toBe(24);
|
|
||||||
expect(
|
|
||||||
wrapper.find('.ant-picker-time-panel-column').at(1).find('.ant-picker-time-panel-cell')
|
|
||||||
.length,
|
|
||||||
).toBe(60);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('showTime={{ showMinute: true, showSecond: true }}', () => {
|
|
||||||
const wrapper = mount(
|
|
||||||
<DatePicker
|
|
||||||
defaultValue={dayjs()}
|
|
||||||
showTime={{ showMinute: true, showSecond: true }}
|
|
||||||
format="YYYY-MM-DD"
|
|
||||||
open
|
|
||||||
/>,
|
|
||||||
);
|
|
||||||
expect(wrapper.find('.ant-picker-time-panel-column').length).toBe(2);
|
|
||||||
expect(
|
|
||||||
wrapper.find('.ant-picker-time-panel-column').at(0).find('.ant-picker-time-panel-cell')
|
|
||||||
.length,
|
|
||||||
).toBe(60);
|
|
||||||
expect(
|
|
||||||
wrapper.find('.ant-picker-time-panel-column').at(1).find('.ant-picker-time-panel-cell')
|
|
||||||
.length,
|
|
||||||
).toBe(60);
|
|
||||||
});
|
|
||||||
it('showTime should work correctly when format is custom function', () => {
|
|
||||||
const wrapper = mount(
|
|
||||||
<DatePicker defaultValue={dayjs()} showTime format={val => val.format('YYYY-MM-DD')} open />,
|
|
||||||
);
|
|
||||||
const input = wrapper.find('input').simulate('mousedown');
|
|
||||||
expect(input.simulate.bind(input, 'focus')).not.toThrowError();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('12 hours', () => {
|
|
||||||
const wrapper = mount(
|
|
||||||
<DatePicker defaultValue={dayjs()} showTime format="YYYY-MM-DD HH:mm:ss A" open />,
|
|
||||||
);
|
|
||||||
expect(wrapper.find('.ant-picker-time-panel-column').length).toBe(4);
|
|
||||||
expect(
|
|
||||||
wrapper.find('.ant-picker-time-panel-column').at(0).find('.ant-picker-time-panel-cell')
|
|
||||||
.length,
|
|
||||||
).toBe(12);
|
|
||||||
expect(
|
|
||||||
wrapper.find('.ant-picker-time-panel-column').at(1).find('.ant-picker-time-panel-cell')
|
|
||||||
.length,
|
|
||||||
).toBe(60);
|
|
||||||
expect(
|
|
||||||
wrapper.find('.ant-picker-time-panel-column').at(2).find('.ant-picker-time-panel-cell')
|
|
||||||
.length,
|
|
||||||
).toBe(60);
|
|
||||||
expect(
|
|
||||||
wrapper.find('.ant-picker-time-panel-column').at(3).find('.ant-picker-time-panel-cell')
|
|
||||||
.length,
|
|
||||||
).toBe(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('24 hours', () => {
|
|
||||||
const wrapper = mount(
|
|
||||||
<DatePicker defaultValue={dayjs()} showTime format="YYYY-MM-DD HH:mm:ss" open />,
|
|
||||||
);
|
|
||||||
expect(wrapper.find('.ant-picker-time-panel-column').length).toBe(3);
|
|
||||||
expect(
|
|
||||||
wrapper.find('.ant-picker-time-panel-column').at(0).find('.ant-picker-time-panel-cell')
|
|
||||||
.length,
|
|
||||||
).toBe(24);
|
|
||||||
expect(
|
|
||||||
wrapper.find('.ant-picker-time-panel-column').at(1).find('.ant-picker-time-panel-cell')
|
|
||||||
.length,
|
|
||||||
).toBe(60);
|
|
||||||
expect(
|
|
||||||
wrapper.find('.ant-picker-time-panel-column').at(2).find('.ant-picker-time-panel-cell')
|
|
||||||
.length,
|
|
||||||
).toBe(60);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('DatePicker should show warning when use dropdownClassName', () => {
|
|
||||||
mount(<DatePicker dropdownClassName="myCustomClassName" />);
|
|
||||||
expect(errorSpy).toHaveBeenCalledWith(
|
|
||||||
'Warning: [antd: DatePicker] `dropdownClassName` is deprecated which will be removed in next major version. Please use `popupClassName` instead.',
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('RangePicker should show warning when use dropdownClassName', () => {
|
|
||||||
mount(<DatePicker.RangePicker dropdownClassName="myCustomClassName" />);
|
|
||||||
expect(errorSpy).toHaveBeenCalledWith(
|
|
||||||
'Warning: [antd: RangePicker] `dropdownClassName` is deprecated which will be removed in next major version. Please use `popupClassName` instead.',
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('DatePicker.RangePicker with defaultPickerValue and showTime', () => {
|
|
||||||
const startDate = dayjs('1982-02-12');
|
|
||||||
const endDate = dayjs('1982-02-22');
|
|
||||||
|
|
||||||
const wrapper = mount(
|
|
||||||
<DatePicker.RangePicker defaultPickerValue={[startDate, endDate]} showTime open />,
|
|
||||||
);
|
|
||||||
|
|
||||||
const month = wrapper.find('.ant-picker-header-view .ant-picker-month-btn').text();
|
|
||||||
const year = wrapper.find('.ant-picker-header-view .ant-picker-year-btn').text();
|
|
||||||
|
|
||||||
expect(month).toBe(startDate.format('MMM'));
|
|
||||||
expect(year).toBe(startDate.format('YYYY'));
|
|
||||||
expect(wrapper.find('.ant-picker-time-panel').length).toBe(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('placement api work correctly ', () => {
|
|
||||||
const popupAlignDefault = (points = ['tl', 'bl'], offset = [0, 4]) => ({
|
|
||||||
points,
|
|
||||||
offset,
|
|
||||||
overflow: {
|
|
||||||
adjustX: 1,
|
|
||||||
adjustY: 1,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const wrapper = mount(<DatePicker.RangePicker defaultValue={dayjs()} placement="bottomLeft" />);
|
|
||||||
expect(wrapper.find('Trigger').prop('popupAlign')).toEqual(popupAlignDefault(['tl', 'bl']));
|
|
||||||
wrapper.setProps({
|
|
||||||
placement: 'bottomRight',
|
|
||||||
});
|
|
||||||
expect(wrapper.find('Trigger').prop('popupAlign')).toEqual(popupAlignDefault(['tr', 'br']));
|
|
||||||
wrapper.setProps({
|
|
||||||
placement: 'topLeft',
|
|
||||||
});
|
|
||||||
expect(wrapper.find('Trigger').prop('popupAlign')).toEqual(
|
|
||||||
popupAlignDefault(['bl', 'tl'], [0, -4]),
|
|
||||||
);
|
|
||||||
wrapper.setProps({
|
|
||||||
placement: 'topRight',
|
|
||||||
});
|
|
||||||
expect(wrapper.find('Trigger').prop('popupAlign')).toEqual(
|
|
||||||
popupAlignDefault(['br', 'tr'], [0, -4]),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
286
components/date-picker/__tests__/DatePicker.test.tsx
Normal file
286
components/date-picker/__tests__/DatePicker.test.tsx
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
import dayjs from 'dayjs';
|
||||||
|
import 'dayjs/locale/mk'; // to test local in 'prop locale should works' test case
|
||||||
|
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
||||||
|
import MockDate from 'mockdate';
|
||||||
|
import React from 'react';
|
||||||
|
import type { TriggerProps } from 'rc-trigger';
|
||||||
|
import { fireEvent, render } from '../../../tests/utils';
|
||||||
|
import DatePicker from '..';
|
||||||
|
import focusTest from '../../../tests/shared/focusTest';
|
||||||
|
import type { PickerLocale } from '../generatePicker';
|
||||||
|
|
||||||
|
dayjs.extend(customParseFormat);
|
||||||
|
|
||||||
|
let triggerProps: TriggerProps;
|
||||||
|
|
||||||
|
jest.mock('rc-trigger', () => {
|
||||||
|
let Trigger = jest.requireActual('rc-trigger/lib/mock');
|
||||||
|
Trigger = Trigger.default || Trigger;
|
||||||
|
const h: typeof React = jest.requireActual('react');
|
||||||
|
|
||||||
|
return {
|
||||||
|
default: h.forwardRef<unknown, TriggerProps>((props, ref) => {
|
||||||
|
triggerProps = props;
|
||||||
|
return h.createElement(Trigger, { ref, ...props });
|
||||||
|
}),
|
||||||
|
__esModule: true,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('DatePicker', () => {
|
||||||
|
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
|
||||||
|
focusTest(DatePicker, { refFocus: true });
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
MockDate.set(dayjs('2016-11-22').valueOf());
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
MockDate.reset();
|
||||||
|
errorSpy.mockReset();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
errorSpy.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('prop locale should works', () => {
|
||||||
|
const locale = {
|
||||||
|
lang: {
|
||||||
|
locale: 'mk',
|
||||||
|
placeholder: 'Избери дата',
|
||||||
|
rangePlaceholder: ['Начална дата', 'Крайна дата'],
|
||||||
|
today: 'Днес',
|
||||||
|
now: 'Сега',
|
||||||
|
backToToday: 'Към днес',
|
||||||
|
ok: 'Добре',
|
||||||
|
clear: 'Изчистване',
|
||||||
|
month: 'Месец',
|
||||||
|
year: 'Година',
|
||||||
|
timeSelect: 'Избор на час',
|
||||||
|
dateSelect: 'Избор на дата',
|
||||||
|
monthSelect: 'Избор на месец',
|
||||||
|
yearSelect: 'Избор на година',
|
||||||
|
decadeSelect: 'Десетилетие',
|
||||||
|
previousMonth: 'Предишен месец (PageUp)',
|
||||||
|
nextMonth: 'Следващ месец (PageDown)',
|
||||||
|
previousYear: 'Последна година (Control + left)',
|
||||||
|
nextYear: 'Следваща година (Control + right)',
|
||||||
|
previousDecade: 'Предишно десетилетие',
|
||||||
|
nextDecade: 'Следващо десетилетие',
|
||||||
|
previousCentury: 'Последен век',
|
||||||
|
nextCentury: 'Следващ век',
|
||||||
|
yearFormat: 'YYYY',
|
||||||
|
dateFormat: 'D M YYYY',
|
||||||
|
dayFormat: 'D',
|
||||||
|
dateTimeFormat: 'D M YYYY HH:mm:ss',
|
||||||
|
monthBeforeYear: true,
|
||||||
|
},
|
||||||
|
timePickerLocale: {
|
||||||
|
placeholder: 'Избор на час',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const birthday = dayjs('2000-01-01', 'YYYY-MM-DD');
|
||||||
|
const wrapper = render(<DatePicker open locale={locale as PickerLocale} value={birthday} />);
|
||||||
|
expect(Array.from(wrapper.container.children)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('disabled date', () => {
|
||||||
|
const disabledDate = (current: any) => current && current < dayjs().endOf('day');
|
||||||
|
const wrapper = render(<DatePicker disabledDate={disabledDate} open />);
|
||||||
|
expect(Array.from(wrapper.container.children)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('placeholder', () => {
|
||||||
|
const wrapper = render(<DatePicker placeholder={undefined} />);
|
||||||
|
expect(wrapper.container.querySelector('input')?.placeholder).toEqual('Select date');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('showTime={{ showHour: true, showMinute: true }}', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<DatePicker
|
||||||
|
defaultValue={dayjs()}
|
||||||
|
showTime={{ showHour: true, showMinute: true }}
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
open
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(2);
|
||||||
|
expect(
|
||||||
|
container
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-column')?.[0]
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-cell').length,
|
||||||
|
).toBe(24);
|
||||||
|
expect(
|
||||||
|
container
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-column')?.[1]
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-cell').length,
|
||||||
|
).toBe(60);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('showTime={{ showHour: true, showSecond: true }}', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<DatePicker
|
||||||
|
defaultValue={dayjs()}
|
||||||
|
showTime={{ showHour: true, showSecond: true }}
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
open
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(2);
|
||||||
|
expect(
|
||||||
|
container
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-column')?.[0]
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-cell').length,
|
||||||
|
).toBe(24);
|
||||||
|
expect(
|
||||||
|
container
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-column')?.[1]
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-cell').length,
|
||||||
|
).toBe(60);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('showTime={{ showMinute: true, showSecond: true }}', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<DatePicker
|
||||||
|
defaultValue={dayjs()}
|
||||||
|
showTime={{ showMinute: true, showSecond: true }}
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
open
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(2);
|
||||||
|
expect(
|
||||||
|
container
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-column')?.[0]
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-cell').length,
|
||||||
|
).toBe(60);
|
||||||
|
expect(
|
||||||
|
container
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-column')?.[1]
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-cell').length,
|
||||||
|
).toBe(60);
|
||||||
|
});
|
||||||
|
it('showTime should work correctly when format is custom function', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<DatePicker defaultValue={dayjs()} showTime format={val => val.format('YYYY-MM-DD')} open />,
|
||||||
|
);
|
||||||
|
const fuousEvent = () => {
|
||||||
|
fireEvent.focus(container.querySelector('input')!);
|
||||||
|
};
|
||||||
|
const mouseDownEvent = () => {
|
||||||
|
fireEvent.mouseDown(container.querySelector('input')!);
|
||||||
|
};
|
||||||
|
expect(fuousEvent).not.toThrowError();
|
||||||
|
expect(mouseDownEvent).not.toThrowError();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('12 hours', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<DatePicker defaultValue={dayjs()} showTime format="YYYY-MM-DD HH:mm:ss A" open />,
|
||||||
|
);
|
||||||
|
expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(4);
|
||||||
|
expect(
|
||||||
|
container
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-column')?.[0]
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-cell').length,
|
||||||
|
).toBe(12);
|
||||||
|
expect(
|
||||||
|
container
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-column')?.[1]
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-cell').length,
|
||||||
|
).toBe(60);
|
||||||
|
expect(
|
||||||
|
container
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-column')?.[2]
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-cell').length,
|
||||||
|
).toBe(60);
|
||||||
|
expect(
|
||||||
|
container
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-column')?.[3]
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-cell').length,
|
||||||
|
).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('24 hours', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<DatePicker defaultValue={dayjs()} showTime format="YYYY-MM-DD HH:mm:ss" open />,
|
||||||
|
);
|
||||||
|
expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(3);
|
||||||
|
expect(
|
||||||
|
container
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-column')?.[0]
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-cell').length,
|
||||||
|
).toBe(24);
|
||||||
|
expect(
|
||||||
|
container
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-column')?.[1]
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-cell').length,
|
||||||
|
).toBe(60);
|
||||||
|
expect(
|
||||||
|
container
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-column')?.[2]
|
||||||
|
.querySelectorAll('.ant-picker-time-panel-cell').length,
|
||||||
|
).toBe(60);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('DatePicker should show warning when use dropdownClassName', () => {
|
||||||
|
render(<DatePicker dropdownClassName="myCustomClassName" />);
|
||||||
|
expect(errorSpy).toHaveBeenCalledWith(
|
||||||
|
'Warning: [antd: DatePicker] `dropdownClassName` is deprecated which will be removed in next major version. Please use `popupClassName` instead.',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('RangePicker should show warning when use dropdownClassName', () => {
|
||||||
|
render(<DatePicker.RangePicker dropdownClassName="myCustomClassName" />);
|
||||||
|
expect(errorSpy).toHaveBeenCalledWith(
|
||||||
|
'Warning: [antd: RangePicker] `dropdownClassName` is deprecated which will be removed in next major version. Please use `popupClassName` instead.',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('DatePicker.RangePicker with defaultPickerValue and showTime', () => {
|
||||||
|
const startDate = dayjs('1982-02-12');
|
||||||
|
const endDate = dayjs('1982-02-22');
|
||||||
|
|
||||||
|
const { container } = render(
|
||||||
|
<DatePicker.RangePicker defaultPickerValue={[startDate, endDate]} showTime open />,
|
||||||
|
);
|
||||||
|
|
||||||
|
const m = container.querySelector('.ant-picker-header-view .ant-picker-month-btn')?.innerHTML;
|
||||||
|
const y = container.querySelector('.ant-picker-header-view .ant-picker-year-btn')?.innerHTML;
|
||||||
|
expect(m).toBe(startDate.format('MMM'));
|
||||||
|
expect(y).toBe(startDate.format('YYYY'));
|
||||||
|
expect(container.querySelectorAll('.ant-picker-time-panel').length).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('placement api work correctly', () => {
|
||||||
|
const { rerender } = render(<DatePicker.RangePicker open placement="topLeft" />);
|
||||||
|
expect(triggerProps?.builtinPlacements).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
topLeft: expect.objectContaining({ offset: [0, -4], points: ['bl', 'tl'] }),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
rerender(<DatePicker.RangePicker open placement="topRight" />);
|
||||||
|
expect(triggerProps?.builtinPlacements).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
topRight: expect.objectContaining({ offset: [0, -4], points: ['br', 'tr'] }),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
rerender(<DatePicker.RangePicker open placement="bottomLeft" />);
|
||||||
|
expect(triggerProps?.builtinPlacements).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
bottomLeft: expect.objectContaining({ offset: [0, 4], points: ['tl', 'bl'] }),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
rerender(<DatePicker.RangePicker open placement="bottomRight" />);
|
||||||
|
expect(triggerProps?.builtinPlacements).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
bottomRight: expect.objectContaining({ offset: [0, 4], points: ['tr', 'br'] }),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
@ -1,6 +1,6 @@
|
|||||||
import { mount } from 'enzyme';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import DatePicker from '..';
|
import DatePicker from '..';
|
||||||
|
import { render } from '../../../tests/utils';
|
||||||
import { resetWarned } from '../../_util/warning';
|
import { resetWarned } from '../../_util/warning';
|
||||||
|
|
||||||
const { QuarterPicker } = DatePicker;
|
const { QuarterPicker } = DatePicker;
|
||||||
@ -10,8 +10,8 @@ describe('QuarterPicker', () => {
|
|||||||
resetWarned();
|
resetWarned();
|
||||||
const warnSpy = jest.spyOn(console, 'error');
|
const warnSpy = jest.spyOn(console, 'error');
|
||||||
|
|
||||||
const wrapper = mount(<QuarterPicker style={{ width: 400 }} />);
|
const { container } = render(<QuarterPicker style={{ width: 400 }} />);
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
expect(container.firstChild).toMatchSnapshot();
|
||||||
|
|
||||||
expect(warnSpy).toHaveBeenCalledWith(
|
expect(warnSpy).toHaveBeenCalledWith(
|
||||||
"Warning: [antd: QuarterPicker] DatePicker.QuarterPicker is legacy usage. Please use DatePicker[picker='quarter'] directly.",
|
"Warning: [antd: QuarterPicker] DatePicker.QuarterPicker is legacy usage. Please use DatePicker[picker='quarter'] directly.",
|
@ -1,11 +1,11 @@
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
||||||
import { mount } from 'enzyme';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import DatePicker from '..';
|
import DatePicker from '..';
|
||||||
import focusTest from '../../../tests/shared/focusTest';
|
import focusTest from '../../../tests/shared/focusTest';
|
||||||
import { resetMockDate, setMockDate } from '../../../tests/utils';
|
import { render, resetMockDate, setMockDate } from '../../../tests/utils';
|
||||||
import enUS from '../locale/en_US';
|
import enUS from '../locale/en_US';
|
||||||
|
|
||||||
import { closePicker, openPicker, selectCell } from './utils';
|
import { closePicker, openPicker, selectCell } from './utils';
|
||||||
|
|
||||||
dayjs.extend(customParseFormat);
|
dayjs.extend(customParseFormat);
|
||||||
@ -26,82 +26,92 @@ describe('RangePicker', () => {
|
|||||||
// issue: https://github.com/ant-design/ant-design/issues/5872
|
// issue: https://github.com/ant-design/ant-design/issues/5872
|
||||||
it('should not throw error when value is reset to `[]`', () => {
|
it('should not throw error when value is reset to `[]`', () => {
|
||||||
const birthday = dayjs('2000-01-01', 'YYYY-MM-DD');
|
const birthday = dayjs('2000-01-01', 'YYYY-MM-DD');
|
||||||
const wrapper = mount(<RangePicker value={[birthday, birthday]} open />);
|
const wrapper1 = render(<RangePicker value={[birthday, birthday]} open />);
|
||||||
wrapper.setProps({ value: [] });
|
const wrapper2 = render(<RangePicker value={[] as unknown as null} open />);
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
openPicker(wrapper);
|
openPicker(wrapper1);
|
||||||
selectCell(wrapper, 3);
|
selectCell(wrapper1, 3);
|
||||||
closePicker(wrapper);
|
closePicker(wrapper1);
|
||||||
|
|
||||||
openPicker(wrapper, 1);
|
openPicker(wrapper1, 1);
|
||||||
selectCell(wrapper, 5, 1);
|
selectCell(wrapper1, 5, 1);
|
||||||
closePicker(wrapper, 1);
|
closePicker(wrapper1, 1);
|
||||||
|
|
||||||
|
openPicker(wrapper2);
|
||||||
|
selectCell(wrapper2, 3);
|
||||||
|
closePicker(wrapper2);
|
||||||
|
|
||||||
|
openPicker(wrapper2, 1);
|
||||||
|
selectCell(wrapper2, 5, 1);
|
||||||
|
closePicker(wrapper2, 1);
|
||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('customize separator', () => {
|
it('customize separator', () => {
|
||||||
const wrapper = mount(<RangePicker separator="test" />);
|
const { container } = render(<RangePicker separator="test" />);
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
expect(container.firstChild).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
// https://github.com/ant-design/ant-design/issues/13302
|
// https://github.com/ant-design/ant-design/issues/13302
|
||||||
describe('in "month" mode, when the left and right panels select the same month', () => {
|
describe('in "month" mode, when the left and right panels select the same month', () => {
|
||||||
it('the cell status is correct', () => {
|
it('the cell status is correct', () => {
|
||||||
|
let rangePickerValue: dayjs.Dayjs[] = [] as any;
|
||||||
class Test extends React.Component {
|
class Test extends React.Component {
|
||||||
state = {
|
state = { value: null };
|
||||||
value: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
onPanelChange = value => {
|
|
||||||
this.setState({ value });
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<RangePicker
|
<RangePicker
|
||||||
value={this.state.value}
|
value={this.state.value}
|
||||||
mode={['month', 'month']}
|
mode={['month', 'month']}
|
||||||
onPanelChange={this.onPanelChange}
|
onPanelChange={value => {
|
||||||
|
this.setState({ value });
|
||||||
|
rangePickerValue = value as any;
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const wrapper = mount(<Test />);
|
const wrapper = render(<Test />);
|
||||||
|
|
||||||
openPicker(wrapper);
|
openPicker(wrapper);
|
||||||
selectCell(wrapper, 'Feb');
|
selectCell(wrapper, 'Feb');
|
||||||
openPicker(wrapper, 1);
|
openPicker(wrapper, 1);
|
||||||
selectCell(wrapper, 'Feb');
|
selectCell(wrapper, 'Feb');
|
||||||
closePicker(wrapper, 1);
|
closePicker(wrapper, 1);
|
||||||
const { value } = wrapper.find(Test).state();
|
|
||||||
expect(value[0].isSame(value[1], 'date')).toBeTruthy();
|
const [start, end] = rangePickerValue;
|
||||||
|
|
||||||
|
expect(start.isSame(end, 'date')).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('ranges', () => {
|
describe('ranges', () => {
|
||||||
it('RangePicker support presetted ranges with Tags', () => {
|
it('RangePicker support presetted ranges with Tags', () => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<RangePicker
|
<RangePicker
|
||||||
|
open
|
||||||
ranges={{
|
ranges={{
|
||||||
Today: [dayjs(), dayjs()],
|
Today: [dayjs(), dayjs()],
|
||||||
'This Month': [dayjs().startOf('month'), dayjs().endOf('month')],
|
'This Month': [dayjs().startOf('month'), dayjs().endOf('month')],
|
||||||
}}
|
}}
|
||||||
open
|
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
expect(Array.from(container.children)).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('placeholder', () => {
|
it('placeholder', () => {
|
||||||
const wrapper = mount(<RangePicker placeholder={undefined} />);
|
const { container } = render(<RangePicker placeholder={undefined} />);
|
||||||
expect(wrapper.find('input').first().props().placeholder).toEqual('Start date');
|
const inputLists = container.querySelectorAll('input');
|
||||||
expect(wrapper.find('input').last().props().placeholder).toEqual('End date');
|
expect(inputLists[0]?.placeholder).toEqual('Start date');
|
||||||
|
expect(inputLists[inputLists.length - 1].placeholder).toEqual('End date');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('RangePicker picker quarter placeholder', () => {
|
it('RangePicker picker quarter placeholder', () => {
|
||||||
const wrapper = mount(<RangePicker picker="quarter" locale={enUS} />);
|
const { container } = render(<RangePicker picker="quarter" locale={enUS} />);
|
||||||
expect(wrapper.find('input').at(0).props().placeholder).toEqual('Start quarter');
|
expect(container.querySelectorAll('input')[0]?.placeholder).toEqual('Start quarter');
|
||||||
expect(wrapper.find('input').at(1).props().placeholder).toEqual('End quarter');
|
expect(container.querySelectorAll('input')[1]?.placeholder).toEqual('End quarter');
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -1,8 +1,7 @@
|
|||||||
import { mount } from 'enzyme';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import DatePicker from '..';
|
import DatePicker from '..';
|
||||||
import focusTest from '../../../tests/shared/focusTest';
|
import focusTest from '../../../tests/shared/focusTest';
|
||||||
import { resetMockDate, setMockDate } from '../../../tests/utils';
|
import { render, resetMockDate, setMockDate } from '../../../tests/utils';
|
||||||
|
|
||||||
const { WeekPicker } = DatePicker;
|
const { WeekPicker } = DatePicker;
|
||||||
|
|
||||||
@ -18,7 +17,7 @@ describe('WeekPicker', () => {
|
|||||||
focusTest(WeekPicker, { refFocus: true });
|
focusTest(WeekPicker, { refFocus: true });
|
||||||
|
|
||||||
it('should support style prop', () => {
|
it('should support style prop', () => {
|
||||||
const wrapper = mount(<WeekPicker style={{ width: 400 }} />);
|
const { container } = render(<WeekPicker style={{ width: 400 }} />);
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
expect(container.firstChild).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -3,8 +3,8 @@
|
|||||||
exports[`MonthPicker and WeekPicker render MonthPicker 1`] = `
|
exports[`MonthPicker and WeekPicker render MonthPicker 1`] = `
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-picker-dropdown"
|
class="ant-picker-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
||||||
style="opacity:0"
|
style="opacity: 0;"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-picker-panel-container"
|
class="ant-picker-panel-container"
|
||||||
@ -196,8 +196,8 @@ exports[`MonthPicker and WeekPicker render MonthPicker 1`] = `
|
|||||||
exports[`MonthPicker and WeekPicker render WeekPicker 1`] = `
|
exports[`MonthPicker and WeekPicker render WeekPicker 1`] = `
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-picker-dropdown"
|
class="ant-picker-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
||||||
style="opacity:0"
|
style="opacity: 0;"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-picker-panel-container"
|
class="ant-picker-panel-container"
|
@ -1,14 +1,15 @@
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import 'dayjs/locale/zh-cn';
|
import 'dayjs/locale/zh-cn';
|
||||||
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
||||||
import { mount, render } from 'enzyme';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import DatePicker from '..';
|
import DatePicker from '..';
|
||||||
import ConfigProvider from '../../config-provider';
|
import ConfigProvider from '../../config-provider';
|
||||||
|
import type { Locale } from '../../locale-provider';
|
||||||
import LocaleProvider from '../../locale-provider';
|
import LocaleProvider from '../../locale-provider';
|
||||||
import locale from '../../locale-provider/zh_CN';
|
import locale from '../../locale-provider/zh_CN';
|
||||||
import jaJP from '../../locale/ja_JP';
|
import jaJP from '../../locale/ja_JP';
|
||||||
import zhTW from '../locale/zh_TW';
|
import zhTW from '../locale/zh_TW';
|
||||||
|
import { render } from '../../../tests/utils';
|
||||||
|
|
||||||
dayjs.extend(customParseFormat);
|
dayjs.extend(customParseFormat);
|
||||||
|
|
||||||
@ -27,15 +28,14 @@ describe('Picker format by locale', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const date = dayjs('2000-01-01', 'YYYY-MM-DD');
|
const date = dayjs('2000-01-01', 'YYYY-MM-DD');
|
||||||
function matchPicker(name, Picker, props) {
|
function matchPicker(name: string, Picker: typeof MonthPicker | typeof WeekPicker, props?: any) {
|
||||||
it(name, () => {
|
it(name, () => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<LocaleProvider locale={myLocale}>
|
<LocaleProvider locale={myLocale as Locale}>
|
||||||
<Picker value={date} {...props} />
|
<Picker value={date} {...props} />
|
||||||
</LocaleProvider>,
|
</LocaleProvider>,
|
||||||
);
|
);
|
||||||
|
expect(container.firstChild).toMatchSnapshot();
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,35 +48,33 @@ describe('Picker format by locale', () => {
|
|||||||
describe('MonthPicker and WeekPicker', () => {
|
describe('MonthPicker and WeekPicker', () => {
|
||||||
it('render MonthPicker', () => {
|
it('render MonthPicker', () => {
|
||||||
const birthday = dayjs('2000-01-01', 'YYYY-MM-DD').locale('zh-cn');
|
const birthday = dayjs('2000-01-01', 'YYYY-MM-DD').locale('zh-cn');
|
||||||
const wrapper = mount(<MonthPicker open />);
|
const { container } = render(<MonthPicker open value={birthday} />);
|
||||||
wrapper.setProps({ value: birthday });
|
expect(container.querySelector('div.ant-picker-dropdown')?.parentNode).toMatchSnapshot();
|
||||||
expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('render WeekPicker', () => {
|
it('render WeekPicker', () => {
|
||||||
const birthday = dayjs('2000-01-01', 'YYYY-MM-DD').locale('zh-cn');
|
const birthday = dayjs('2000-01-01', 'YYYY-MM-DD').locale('zh-cn');
|
||||||
const wrapper = mount(<WeekPicker open />);
|
const { container } = render(<WeekPicker open value={birthday} />);
|
||||||
wrapper.setProps({ value: birthday });
|
expect(container.querySelector('div.ant-picker-dropdown')?.parentNode).toMatchSnapshot();
|
||||||
expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Override locale setting of the ConfigProvider', () => {
|
describe('Override locale setting of the ConfigProvider', () => {
|
||||||
it('DatePicker', () => {
|
it('DatePicker', () => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<ConfigProvider locale={jaJP}>
|
<ConfigProvider locale={jaJP}>
|
||||||
<DatePicker locale={zhTW} />
|
<DatePicker locale={zhTW} />
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('input').props().placeholder).toEqual('請選擇日期');
|
expect(container.querySelector('input')?.placeholder).toEqual('請選擇日期');
|
||||||
});
|
});
|
||||||
it('RangePicker', () => {
|
it('RangePicker', () => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<ConfigProvider locale={jaJP}>
|
<ConfigProvider locale={jaJP}>
|
||||||
<DatePicker.RangePicker locale={zhTW} />
|
<DatePicker.RangePicker locale={zhTW} />
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('input').at(0).props().placeholder).toEqual('開始日期');
|
expect(container.querySelectorAll('input')[0]?.placeholder).toEqual('開始日期');
|
||||||
expect(wrapper.find('input').at(1).props().placeholder).toEqual('結束日期');
|
expect(container.querySelectorAll('input')[1]?.placeholder).toEqual('結束日期');
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -1,58 +0,0 @@
|
|||||||
/* eslint-disable import/prefer-default-export */
|
|
||||||
export function selectDate(wrapper, date, index) {
|
|
||||||
let calendar = wrapper;
|
|
||||||
if (index !== undefined) {
|
|
||||||
calendar = wrapper.find('.ant-calendar-range-part').at(index);
|
|
||||||
}
|
|
||||||
calendar.find({ title: date.format('LL'), role: 'gridcell' }).simulate('click');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function hasSelected(wrapper, date) {
|
|
||||||
return wrapper
|
|
||||||
.find({ title: date.format('LL'), role: 'gridcell' })
|
|
||||||
.hasClass('ant-calendar-selected-day');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function openPanel(wrapper) {
|
|
||||||
wrapper.find('.ant-calendar-picker-input').simulate('click');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function clearInput(wrapper) {
|
|
||||||
wrapper.find('.ant-calendar-picker-clear').hostNodes().simulate('click');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function nextYear(wrapper) {
|
|
||||||
wrapper.find('.ant-calendar-next-year-btn').simulate('click');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function nextMonth(wrapper) {
|
|
||||||
wrapper.find('.ant-calendar-next-month-btn').simulate('click');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function openPicker(wrapper, index = 0) {
|
|
||||||
wrapper.find('input').at(index).simulate('mousedown').simulate('focus');
|
|
||||||
}
|
|
||||||
export function closePicker(wrapper, index = 0) {
|
|
||||||
wrapper.find('input').at(index).simulate('blur');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function selectCell(wrapper, text, index = 0) {
|
|
||||||
let matchCell;
|
|
||||||
|
|
||||||
wrapper
|
|
||||||
.find('table')
|
|
||||||
.at(index)
|
|
||||||
.find('td')
|
|
||||||
.forEach(td => {
|
|
||||||
if (td.text() === String(text) && td.props().className.includes('-in-view')) {
|
|
||||||
matchCell = td;
|
|
||||||
td.simulate('click');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!matchCell) {
|
|
||||||
throw new Error('Cell not match in picker panel.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return matchCell;
|
|
||||||
}
|
|
27
components/date-picker/__tests__/utils.ts
Normal file
27
components/date-picker/__tests__/utils.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { fireEvent } from '../../../tests/utils';
|
||||||
|
import type { render } from '../../../tests/utils';
|
||||||
|
|
||||||
|
export function openPicker(wrapper: ReturnType<typeof render>, index = 0) {
|
||||||
|
fireEvent.mouseDown(wrapper.container?.querySelectorAll('input')?.[index]!);
|
||||||
|
fireEvent.focus(wrapper.container?.querySelectorAll('input')?.[index]!);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function closePicker(wrapper: ReturnType<typeof render>, index = 0) {
|
||||||
|
fireEvent.blur(wrapper.container?.querySelectorAll('input')[index]!);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function selectCell(wrapper: ReturnType<typeof render>, text: string | number, index = 0) {
|
||||||
|
let matchCell: HTMLTableCellElement | null = null;
|
||||||
|
const tds = wrapper.container?.querySelectorAll('table')?.[index]?.querySelectorAll('td');
|
||||||
|
tds.forEach(td => {
|
||||||
|
if (td.querySelector('div')?.innerHTML === String(text) && td.className.includes('-in-view')) {
|
||||||
|
matchCell = td;
|
||||||
|
fireEvent.click(td);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/* istanbul ignore next */
|
||||||
|
if (!matchCell) {
|
||||||
|
throw new Error('Cell not match in picker panel.');
|
||||||
|
}
|
||||||
|
return matchCell;
|
||||||
|
}
|
@ -95,14 +95,8 @@ export function transPlacement2DropdownAlign(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
return direction === 'rtl'
|
return {
|
||||||
? {
|
points: direction === 'rtl' ? ['tr', 'br'] : ['tl', 'bl'],
|
||||||
points: ['tr', 'br'],
|
|
||||||
offset: [0, 4],
|
|
||||||
overflow,
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
points: ['tl', 'bl'],
|
|
||||||
offset: [0, 4],
|
offset: [0, 4],
|
||||||
overflow,
|
overflow,
|
||||||
};
|
};
|
||||||
|
@ -200,9 +200,22 @@ describe('Drawer', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('zIndex should work', () => {
|
it('zIndex should work', () => {
|
||||||
const { container } = render(<Drawer getContainer={false} visible zIndex={903} />);
|
const { container } = render(<Drawer getContainer={false} open zIndex={903} />);
|
||||||
expect(container.querySelector('.ant-drawer')).toHaveStyle({
|
expect(container.querySelector('.ant-drawer')).toHaveStyle({
|
||||||
zIndex: 903,
|
zIndex: 903,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it('deprecated warning', () => {
|
||||||
|
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
|
||||||
|
const { rerender } = render(<Drawer visible />);
|
||||||
|
expect(errSpy).toHaveBeenCalledWith(
|
||||||
|
'Warning: [antd: Drawer] `visible` is deprecated which will be removed in next major version, please use `open` instead.',
|
||||||
|
);
|
||||||
|
rerender(<Drawer afterVisibleChange={() => {}} />);
|
||||||
|
expect(errSpy).toHaveBeenCalledWith(
|
||||||
|
'Warning: [antd: Drawer] `afterVisibleChange` is deprecated which will be removed in next major version, please use `afterOpenChange` instead.',
|
||||||
|
);
|
||||||
|
errSpy.mockRestore();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -11,7 +11,7 @@ title:
|
|||||||
|
|
||||||
## en-US
|
## en-US
|
||||||
|
|
||||||
Extra actions should be placed at corner of drawer in Ant Design, you can using `extra` prop for that.
|
Extra actions should be placed at corner of drawer in Ant Design, you can use `extra` prop for that.
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
import { Button, Drawer, Radio, Space } from 'antd';
|
import { Button, Drawer, Radio, Space } from 'antd';
|
||||||
|
@ -48,7 +48,7 @@ A Drawer is a panel that is typically overlaid on top of a page and slides in fr
|
|||||||
| style | Style of Drawer panel. Use `bodyStyle` if want to config body only | CSSProperties | - | |
|
| style | Style of Drawer panel. Use `bodyStyle` if want to config body only | CSSProperties | - | |
|
||||||
| size | presetted size of drawer, default `378px` and large `736px` | 'default' \| 'large' | 'default' | 4.17.0 |
|
| size | presetted size of drawer, default `378px` and large `736px` | 'default' \| 'large' | 'default' | 4.17.0 |
|
||||||
| title | The title for Drawer | ReactNode | - | |
|
| title | The title for Drawer | ReactNode | - | |
|
||||||
| open | Whether the Drawer dialog is visible or not | boolean | false | |
|
|
||||||
| width | Width of the Drawer dialog | string \| number | 378 | |
|
<<<<<<< HEAD | open | Whether the Drawer dialog is visible or not | boolean | false | | ======= | open | Whether the Drawer dialog is visible or not | boolean | false | 4.23.0 |
|
||||||
| zIndex | The `z-index` of the Drawer | number | 1000 | |
|
|
||||||
| onClose | Specify a callback that will be called when a user clicks mask, close button or Cancel button | function(e) | - | |
|
> > > > > > > feature | width | Width of the Drawer dialog | string \| number | 378 | | | zIndex | The `z-index` of the Drawer | number | 1000 | | | onClose | Specify a callback that will be called when a user clicks mask, close button or Cancel button | function(e) | - | |
|
||||||
|
@ -86,6 +86,17 @@ function Drawer(props: DrawerProps) {
|
|||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
[
|
||||||
|
['visible', 'open'],
|
||||||
|
['afterVisibleChange', 'afterOpenChange'],
|
||||||
|
].forEach(([deprecatedName, newName]) => {
|
||||||
|
warning(
|
||||||
|
!(deprecatedName in props),
|
||||||
|
'Drawer',
|
||||||
|
`\`${deprecatedName}\` is deprecated which will be removed in next major version, please use \`${newName}\` instead.`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
function renderHeader() {
|
function renderHeader() {
|
||||||
if (!title && !closable) {
|
if (!title && !closable) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -47,7 +47,7 @@ cover: https://img.alicdn.com/imgextra/i4/O1CN019djdZP1OHwXSRGCOW_!!600000000168
|
|||||||
| size | 预设抽屉宽度(或高度),default `378px` 和 large `736px` | 'default' \| 'large' | 'default' | 4.17.0 |
|
| size | 预设抽屉宽度(或高度),default `378px` 和 large `736px` | 'default' \| 'large' | 'default' | 4.17.0 |
|
||||||
| style | 设计 Drawer 容器样式,如果你只需要设置内容部分请使用 `bodyStyle` | CSSProperties | - | |
|
| style | 设计 Drawer 容器样式,如果你只需要设置内容部分请使用 `bodyStyle` | CSSProperties | - | |
|
||||||
| title | 标题 | ReactNode | - | |
|
| title | 标题 | ReactNode | - | |
|
||||||
| open | Drawer 是否可见 | boolean | - | |
|
|
||||||
| width | 宽度 | string \| number | 378 | |
|
<<<<<<< HEAD | open | Drawer 是否可见 | boolean | - | | ======= | open | Drawer 是否可见 | boolean | - | 4.23.0 |
|
||||||
| zIndex | 设置 Drawer 的 `z-index` | number | 1000 | |
|
|
||||||
| onClose | 点击遮罩层或左上角叉或取消按钮的回调 | function(e) | - | |
|
> > > > > > > feature | width | 宽度 | string \| number | 378 | | | zIndex | 设置 Drawer 的 `z-index` | number | 1000 | | | onClose | 点击遮罩层或左上角叉或取消按钮的回调 | function(e) | - | |
|
||||||
|
@ -1232,7 +1232,7 @@ describe('Form', () => {
|
|||||||
const Demo = () => (
|
const Demo = () => (
|
||||||
<Form>
|
<Form>
|
||||||
<Form.Item labelCol={4} validateStatus="error">
|
<Form.Item labelCol={4} validateStatus="error">
|
||||||
<Modal visible>
|
<Modal open>
|
||||||
<Select className="modal-select" />
|
<Select className="modal-select" />
|
||||||
</Modal>
|
</Modal>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
@ -33,31 +33,31 @@ interface UserType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ModalFormProps {
|
interface ModalFormProps {
|
||||||
visible: boolean;
|
open: boolean;
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset form fields when modal is form, closed
|
// reset form fields when modal is form, closed
|
||||||
const useResetFormOnCloseModal = ({ form, visible }: { form: FormInstance; visible: boolean }) => {
|
const useResetFormOnCloseModal = ({ form, open }: { form: FormInstance; open: boolean }) => {
|
||||||
const prevVisibleRef = useRef<boolean>();
|
const prevOpenRef = useRef<boolean>();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
prevVisibleRef.current = visible;
|
prevOpenRef.current = open;
|
||||||
}, [visible]);
|
}, [open]);
|
||||||
const prevVisible = prevVisibleRef.current;
|
const prevOpen = prevOpenRef.current;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!visible && prevVisible) {
|
if (!open && prevOpen) {
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
}
|
}
|
||||||
}, [form, prevVisible, visible]);
|
}, [form, prevOpen, open]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const ModalForm: React.FC<ModalFormProps> = ({ visible, onCancel }) => {
|
const ModalForm: React.FC<ModalFormProps> = ({ open, onCancel }) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
useResetFormOnCloseModal({
|
useResetFormOnCloseModal({
|
||||||
form,
|
form,
|
||||||
visible,
|
open,
|
||||||
});
|
});
|
||||||
|
|
||||||
const onOk = () => {
|
const onOk = () => {
|
||||||
@ -65,7 +65,7 @@ const ModalForm: React.FC<ModalFormProps> = ({ visible, onCancel }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal title="Basic Drawer" visible={visible} onOk={onOk} onCancel={onCancel}>
|
<Modal title="Basic Drawer" open={open} onOk={onOk} onCancel={onCancel}>
|
||||||
<Form form={form} layout="vertical" name="userForm">
|
<Form form={form} layout="vertical" name="userForm">
|
||||||
<Form.Item name="name" label="User Name" rules={[{ required: true }]}>
|
<Form.Item name="name" label="User Name" rules={[{ required: true }]}>
|
||||||
<Input />
|
<Input />
|
||||||
@ -79,14 +79,14 @@ const ModalForm: React.FC<ModalFormProps> = ({ visible, onCancel }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const [visible, setVisible] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
const showUserModal = () => {
|
const showUserModal = () => {
|
||||||
setVisible(true);
|
setOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const hideUserModal = () => {
|
const hideUserModal = () => {
|
||||||
setVisible(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onFinish = (values: any) => {
|
const onFinish = (values: any) => {
|
||||||
@ -100,7 +100,7 @@ const App: React.FC = () => {
|
|||||||
const { basicForm } = forms;
|
const { basicForm } = forms;
|
||||||
const users = basicForm.getFieldValue('users') || [];
|
const users = basicForm.getFieldValue('users') || [];
|
||||||
basicForm.setFieldsValue({ users: [...users, values] });
|
basicForm.setFieldsValue({ users: [...users, values] });
|
||||||
setVisible(false);
|
setOpen(false);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -140,7 +140,7 @@ const App: React.FC = () => {
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
<ModalForm visible={visible} onCancel={hideUserModal} />
|
<ModalForm open={open} onCancel={hideUserModal} />
|
||||||
</Form.Provider>
|
</Form.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -26,20 +26,20 @@ interface Values {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface CollectionCreateFormProps {
|
interface CollectionCreateFormProps {
|
||||||
visible: boolean;
|
open: boolean;
|
||||||
onCreate: (values: Values) => void;
|
onCreate: (values: Values) => void;
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CollectionCreateForm: React.FC<CollectionCreateFormProps> = ({
|
const CollectionCreateForm: React.FC<CollectionCreateFormProps> = ({
|
||||||
visible,
|
open,
|
||||||
onCreate,
|
onCreate,
|
||||||
onCancel,
|
onCancel,
|
||||||
}) => {
|
}) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
visible={visible}
|
open={open}
|
||||||
title="Create a new collection"
|
title="Create a new collection"
|
||||||
okText="Create"
|
okText="Create"
|
||||||
cancelText="Cancel"
|
cancelText="Cancel"
|
||||||
@ -84,11 +84,11 @@ const CollectionCreateForm: React.FC<CollectionCreateFormProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const [visible, setVisible] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
const onCreate = (values: any) => {
|
const onCreate = (values: any) => {
|
||||||
console.log('Received values of form: ', values);
|
console.log('Received values of form: ', values);
|
||||||
setVisible(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -96,16 +96,16 @@ const App: React.FC = () => {
|
|||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setVisible(true);
|
setOpen(true);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
New Collection
|
New Collection
|
||||||
</Button>
|
</Button>
|
||||||
<CollectionCreateForm
|
<CollectionCreateForm
|
||||||
visible={visible}
|
open={open}
|
||||||
onCreate={onCreate}
|
onCreate={onCreate}
|
||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
setVisible(false);
|
setOpen(false);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -258,7 +258,7 @@ const App = () => (
|
|||||||
<Transfer dataSource={[]} showSearch targetKeys={[]} render={item => item.title} />
|
<Transfer dataSource={[]} showSearch targetKeys={[]} render={item => item.title} />
|
||||||
<Calendar fullscreen={false} value={dayjs()} />
|
<Calendar fullscreen={false} value={dayjs()} />
|
||||||
<Table dataSource={[]} columns={columns} />
|
<Table dataSource={[]} columns={columns} />
|
||||||
<Modal title="Locale Modal" visible getContainer={false}>
|
<Modal title="Locale Modal" open getContainer={false}>
|
||||||
<p>Locale Modal</p>
|
<p>Locale Modal</p>
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
|
@ -131,7 +131,7 @@ const ConfirmDialog = (props: ConfirmDialogProps) => {
|
|||||||
close,
|
close,
|
||||||
zIndex,
|
zIndex,
|
||||||
afterClose,
|
afterClose,
|
||||||
visible,
|
open,
|
||||||
keyboard,
|
keyboard,
|
||||||
centered,
|
centered,
|
||||||
getContainer,
|
getContainer,
|
||||||
@ -173,7 +173,7 @@ const ConfirmDialog = (props: ConfirmDialogProps) => {
|
|||||||
wrapClassName,
|
wrapClassName,
|
||||||
)}
|
)}
|
||||||
onCancel={() => close?.({ triggerCancel: true })}
|
onCancel={() => close?.({ triggerCancel: true })}
|
||||||
visible={visible}
|
open={open}
|
||||||
title=""
|
title=""
|
||||||
footer=""
|
footer=""
|
||||||
transitionName={getTransitionName(rootPrefixCls, 'zoom', props.transitionName)}
|
transitionName={getTransitionName(rootPrefixCls, 'zoom', props.transitionName)}
|
||||||
|
@ -7,6 +7,7 @@ import { ConfigContext } from '../config-provider';
|
|||||||
import { NoFormStyle } from '../form/context';
|
import { NoFormStyle } from '../form/context';
|
||||||
import { getTransitionName } from '../_util/motion';
|
import { getTransitionName } from '../_util/motion';
|
||||||
import { canUseDocElement } from '../_util/styleChecker';
|
import { canUseDocElement } from '../_util/styleChecker';
|
||||||
|
import warning from '../_util/warning';
|
||||||
import { renderCloseIcon, renderFooter } from './PurePanel';
|
import { renderCloseIcon, renderFooter } from './PurePanel';
|
||||||
import useStyle from './style';
|
import useStyle from './style';
|
||||||
|
|
||||||
@ -33,7 +34,12 @@ if (canUseDocElement()) {
|
|||||||
|
|
||||||
export interface ModalProps {
|
export interface ModalProps {
|
||||||
/** 对话框是否可见 */
|
/** 对话框是否可见 */
|
||||||
|
/**
|
||||||
|
* @deprecated `visible` is deprecated which will be removed in next major version. Please use
|
||||||
|
* `open` instead.
|
||||||
|
*/
|
||||||
visible?: boolean;
|
visible?: boolean;
|
||||||
|
open?: boolean;
|
||||||
/** 确定按钮 loading */
|
/** 确定按钮 loading */
|
||||||
confirmLoading?: boolean;
|
confirmLoading?: boolean;
|
||||||
/** 标题 */
|
/** 标题 */
|
||||||
@ -88,7 +94,12 @@ type getContainerFunc = () => HTMLElement;
|
|||||||
export interface ModalFuncProps {
|
export interface ModalFuncProps {
|
||||||
prefixCls?: string;
|
prefixCls?: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
/**
|
||||||
|
* @deprecated `visible` is deprecated which will be removed in next major version. Please use
|
||||||
|
* `open` instead.
|
||||||
|
*/
|
||||||
visible?: boolean;
|
visible?: boolean;
|
||||||
|
open?: boolean;
|
||||||
title?: React.ReactNode;
|
title?: React.ReactNode;
|
||||||
closable?: boolean;
|
closable?: boolean;
|
||||||
content?: React.ReactNode;
|
content?: React.ReactNode;
|
||||||
@ -147,10 +158,18 @@ const Modal: React.FC<ModalProps> = props => {
|
|||||||
onOk?.(e);
|
onOk?.(e);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
warning(
|
||||||
|
props.visible === undefined,
|
||||||
|
'Modal',
|
||||||
|
`\`visible\` is removed in v5, please use \`open\` instead.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
prefixCls: customizePrefixCls,
|
prefixCls: customizePrefixCls,
|
||||||
className,
|
className,
|
||||||
visible,
|
open,
|
||||||
wrapClassName,
|
wrapClassName,
|
||||||
centered,
|
centered,
|
||||||
getContainer,
|
getContainer,
|
||||||
@ -183,7 +202,7 @@ const Modal: React.FC<ModalProps> = props => {
|
|||||||
onOk: handleOk,
|
onOk: handleOk,
|
||||||
onCancel: handleCancel,
|
onCancel: handleCancel,
|
||||||
})}
|
})}
|
||||||
visible={visible}
|
visible={open}
|
||||||
mousePosition={mousePosition}
|
mousePosition={mousePosition}
|
||||||
onClose={handleCancel}
|
onClose={handleCancel}
|
||||||
closeIcon={renderCloseIcon(prefixCls, closeIcon)}
|
closeIcon={renderCloseIcon(prefixCls, closeIcon)}
|
||||||
@ -199,7 +218,8 @@ const Modal: React.FC<ModalProps> = props => {
|
|||||||
Modal.defaultProps = {
|
Modal.defaultProps = {
|
||||||
width: 520,
|
width: 520,
|
||||||
confirmLoading: false,
|
confirmLoading: false,
|
||||||
visible: false,
|
open: false,
|
||||||
|
okType: 'primary' as LegacyButtonType,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Modal;
|
export default Modal;
|
||||||
|
@ -4,14 +4,15 @@ import Modal 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 } from '../../../tests/utils';
|
||||||
|
import { resetWarned } from '../../_util/warning';
|
||||||
|
|
||||||
jest.mock('rc-util/lib/Portal');
|
jest.mock('rc-util/lib/Portal');
|
||||||
|
|
||||||
class ModalTester extends React.Component<ModalProps, { visible: boolean }> {
|
class ModalTester extends React.Component<ModalProps, { open: boolean }> {
|
||||||
state = { visible: false };
|
state = { open: false };
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.setState({ visible: true }); // eslint-disable-line react/no-did-mount-set-state
|
this.setState({ open: true }); // eslint-disable-line react/no-did-mount-set-state
|
||||||
}
|
}
|
||||||
|
|
||||||
container = React.createRef<HTMLDivElement>();
|
container = React.createRef<HTMLDivElement>();
|
||||||
@ -19,11 +20,11 @@ class ModalTester extends React.Component<ModalProps, { visible: boolean }> {
|
|||||||
getContainer = () => this.container?.current!;
|
getContainer = () => this.container?.current!;
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { visible } = this.state;
|
const { open } = this.state;
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div ref={this.container} />
|
<div ref={this.container} />
|
||||||
<Modal {...this.props} visible={visible} getContainer={this.getContainer}>
|
<Modal {...this.props} open={open} getContainer={this.getContainer}>
|
||||||
Here is content of Modal
|
Here is content of Modal
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
@ -36,7 +37,7 @@ describe('Modal', () => {
|
|||||||
rtlTest(Modal);
|
rtlTest(Modal);
|
||||||
|
|
||||||
it('support closeIcon', () => {
|
it('support closeIcon', () => {
|
||||||
render(<Modal closeIcon={<a>closeIcon</a>} visible />);
|
render(<Modal closeIcon={<a>closeIcon</a>} open />);
|
||||||
expect(document.body.querySelectorAll('.ant-modal-root')[0]).toMatchSnapshot();
|
expect(document.body.querySelectorAll('.ant-modal-root')[0]).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -52,35 +53,35 @@ describe('Modal', () => {
|
|||||||
|
|
||||||
it('onCancel should be called', () => {
|
it('onCancel should be called', () => {
|
||||||
const onCancel = jest.fn();
|
const onCancel = jest.fn();
|
||||||
render(<Modal visible onCancel={onCancel} />);
|
render(<Modal open onCancel={onCancel} />);
|
||||||
fireEvent.click(document.body.querySelectorAll('.ant-btn')[0]);
|
fireEvent.click(document.body.querySelectorAll('.ant-btn')[0]);
|
||||||
expect(onCancel).toHaveBeenCalled();
|
expect(onCancel).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('onOk should be called', () => {
|
it('onOk should be called', () => {
|
||||||
const onOk = jest.fn();
|
const onOk = jest.fn();
|
||||||
render(<Modal visible onOk={onOk} />);
|
render(<Modal open onOk={onOk} />);
|
||||||
const btns = document.body.querySelectorAll('.ant-btn');
|
const btns = document.body.querySelectorAll('.ant-btn');
|
||||||
fireEvent.click(btns[btns.length - 1]);
|
fireEvent.click(btns[btns.length - 1]);
|
||||||
expect(onOk).toHaveBeenCalled();
|
expect(onOk).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('danger type', () => {
|
it('danger type', () => {
|
||||||
render(<Modal okType="danger" okText="123" visible />);
|
render(<Modal okType="danger" okText="123" open />);
|
||||||
const btns = document.body.querySelectorAll('.ant-btn');
|
const btns = document.body.querySelectorAll('.ant-btn');
|
||||||
expect(btns[btns.length - 1].classList.contains('ant-btn-dangerous')).toBeTruthy();
|
expect(btns[btns.length - 1].classList.contains('ant-btn-dangerous')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('mouse position', () => {
|
it('mouse position', () => {
|
||||||
const Demo = () => {
|
const Demo = () => {
|
||||||
const [visible, setVisible] = React.useState(false);
|
const [open, setOpen] = React.useState(false);
|
||||||
const containerRef = React.useRef<HTMLDivElement>(null);
|
const containerRef = React.useRef<HTMLDivElement>(null);
|
||||||
return (
|
return (
|
||||||
<div ref={containerRef}>
|
<div ref={containerRef}>
|
||||||
<div id="trigger" onClick={() => setVisible(true)}>
|
<div id="trigger" onClick={() => setOpen(true)}>
|
||||||
click me
|
click me
|
||||||
</div>
|
</div>
|
||||||
<Modal visible={visible} getContainer={() => containerRef.current!} />
|
<Modal open={open} getContainer={() => containerRef.current!} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -90,4 +91,16 @@ describe('Modal', () => {
|
|||||||
(container.querySelectorAll('.ant-modal')[0] as HTMLDivElement).style.transformOrigin,
|
(container.querySelectorAll('.ant-modal')[0] as HTMLDivElement).style.transformOrigin,
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('deprecated warning', () => {
|
||||||
|
resetWarned();
|
||||||
|
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
|
||||||
|
render(<Modal visible />);
|
||||||
|
expect(errSpy).toHaveBeenCalledWith(
|
||||||
|
'Warning: [antd: Modal] `visible` is removed in v5, please use `open` instead.',
|
||||||
|
);
|
||||||
|
|
||||||
|
errSpy.mockRestore();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -25,7 +25,7 @@ export type ModalStaticFunctions = Record<NonNullable<ModalFuncProps['type']>, M
|
|||||||
export default function confirm(config: ModalFuncProps) {
|
export default function confirm(config: ModalFuncProps) {
|
||||||
const container = document.createDocumentFragment();
|
const container = document.createDocumentFragment();
|
||||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||||
let currentConfig = { ...config, close, visible: true } as any;
|
let currentConfig = { ...config, close, open: true } as any;
|
||||||
|
|
||||||
function destroy(...args: any[]) {
|
function destroy(...args: any[]) {
|
||||||
const triggerCancel = args.some(param => param && param.triggerCancel);
|
const triggerCancel = args.some(param => param && param.triggerCancel);
|
||||||
@ -76,7 +76,7 @@ export default function confirm(config: ModalFuncProps) {
|
|||||||
function close(...args: any[]) {
|
function close(...args: any[]) {
|
||||||
currentConfig = {
|
currentConfig = {
|
||||||
...currentConfig,
|
...currentConfig,
|
||||||
visible: false,
|
open: false,
|
||||||
afterClose: () => {
|
afterClose: () => {
|
||||||
if (typeof config.afterClose === 'function') {
|
if (typeof config.afterClose === 'function') {
|
||||||
config.afterClose();
|
config.afterClose();
|
||||||
|
@ -18,26 +18,26 @@ import { Button, Modal } from 'antd';
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const [visible, setVisible] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [confirmLoading, setConfirmLoading] = useState(false);
|
const [confirmLoading, setConfirmLoading] = useState(false);
|
||||||
const [modalText, setModalText] = useState('Content of the modal');
|
const [modalText, setModalText] = useState('Content of the modal');
|
||||||
|
|
||||||
const showModal = () => {
|
const showModal = () => {
|
||||||
setVisible(true);
|
setOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
setModalText('The modal will be closed after two seconds');
|
setModalText('The modal will be closed after two seconds');
|
||||||
setConfirmLoading(true);
|
setConfirmLoading(true);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setVisible(false);
|
setOpen(false);
|
||||||
setConfirmLoading(false);
|
setConfirmLoading(false);
|
||||||
}, 2000);
|
}, 2000);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
console.log('Clicked cancel button');
|
console.log('Clicked cancel button');
|
||||||
setVisible(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -47,7 +47,7 @@ const App: React.FC = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
<Modal
|
<Modal
|
||||||
title="Title"
|
title="Title"
|
||||||
visible={visible}
|
open={open}
|
||||||
onOk={handleOk}
|
onOk={handleOk}
|
||||||
confirmLoading={confirmLoading}
|
confirmLoading={confirmLoading}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
@ -18,18 +18,18 @@ import { Button, Modal } from 'antd';
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const [isModalVisible, setIsModalVisible] = useState(false);
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
|
|
||||||
const showModal = () => {
|
const showModal = () => {
|
||||||
setIsModalVisible(true);
|
setIsModalOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
setIsModalVisible(false);
|
setIsModalOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
setIsModalVisible(false);
|
setIsModalOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -37,7 +37,7 @@ const App: React.FC = () => {
|
|||||||
<Button type="primary" onClick={showModal}>
|
<Button type="primary" onClick={showModal}>
|
||||||
Open Modal
|
Open Modal
|
||||||
</Button>
|
</Button>
|
||||||
<Modal title="Basic Modal" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
|
<Modal title="Basic Modal" open={isModalOpen} onOk={handleOk} onCancel={handleCancel}>
|
||||||
<p>Some contents...</p>
|
<p>Some contents...</p>
|
||||||
<p>Some contents...</p>
|
<p>Some contents...</p>
|
||||||
<p>Some contents...</p>
|
<p>Some contents...</p>
|
||||||
|
@ -18,20 +18,20 @@ import { Button, Modal } from 'antd';
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const [visible, setVisible] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
const showModal = () => {
|
const showModal = () => {
|
||||||
setVisible(true);
|
setOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOk = (e: React.MouseEvent<HTMLElement>) => {
|
const handleOk = (e: React.MouseEvent<HTMLElement>) => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
setVisible(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = (e: React.MouseEvent<HTMLElement>) => {
|
const handleCancel = (e: React.MouseEvent<HTMLElement>) => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
setVisible(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -41,7 +41,7 @@ const App: React.FC = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
<Modal
|
<Modal
|
||||||
title="Basic Modal"
|
title="Basic Modal"
|
||||||
visible={visible}
|
open={open}
|
||||||
onOk={handleOk}
|
onOk={handleOk}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
okButtonProps={{ disabled: true }}
|
okButtonProps={{ disabled: true }}
|
||||||
|
@ -301,7 +301,7 @@ const TableTransfer = ({ leftColumns, rightColumns, ...restProps }) => (
|
|||||||
);
|
);
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const [visible, setVisible] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [targetKeys, setTargetKeys] = useState(oriTargetKeys);
|
const [targetKeys, setTargetKeys] = useState(oriTargetKeys);
|
||||||
const [selectedKeys, setSelectedKeys] = useState([]);
|
const [selectedKeys, setSelectedKeys] = useState([]);
|
||||||
const [disabled, setDisabled] = useState(false);
|
const [disabled, setDisabled] = useState(false);
|
||||||
@ -332,17 +332,17 @@ export default () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const showModal = () => {
|
const showModal = () => {
|
||||||
setVisible(true);
|
setOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOk = e => {
|
const handleOk = e => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
setVisible(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = e => {
|
const handleCancel = e => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
setVisible(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
@ -388,7 +388,7 @@ export default () => {
|
|||||||
<Button type="primary" onClick={showModal}>
|
<Button type="primary" onClick={showModal}>
|
||||||
Open Modal
|
Open Modal
|
||||||
</Button>
|
</Button>
|
||||||
<Modal title="Basic Modal" visible={visible} onOk={handleOk} onCancel={handleCancel}>
|
<Modal title="Basic Modal" open={open} onOk={handleOk} onCancel={handleCancel}>
|
||||||
<Switch
|
<Switch
|
||||||
unCheckedChildren="disabled"
|
unCheckedChildren="disabled"
|
||||||
checkedChildren="disabled"
|
checkedChildren="disabled"
|
||||||
|
@ -23,22 +23,22 @@ import React, { useState } from 'react';
|
|||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [visible, setVisible] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
const showModal = () => {
|
const showModal = () => {
|
||||||
setVisible(true);
|
setOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
setVisible(false);
|
setOpen(false);
|
||||||
}, 3000);
|
}, 3000);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
setVisible(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -47,7 +47,7 @@ const App: React.FC = () => {
|
|||||||
Open Modal with customized footer
|
Open Modal with customized footer
|
||||||
</Button>
|
</Button>
|
||||||
<Modal
|
<Modal
|
||||||
visible={visible}
|
open={open}
|
||||||
title="Title"
|
title="Title"
|
||||||
onOk={handleOk}
|
onOk={handleOk}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
@ -19,14 +19,14 @@ import { Button, Modal, Space } from 'antd';
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
const LocalizedModal = () => {
|
const LocalizedModal = () => {
|
||||||
const [visible, setVisible] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
const showModal = () => {
|
const showModal = () => {
|
||||||
setVisible(true);
|
setOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const hideModal = () => {
|
const hideModal = () => {
|
||||||
setVisible(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -36,7 +36,7 @@ const LocalizedModal = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
<Modal
|
<Modal
|
||||||
title="Modal"
|
title="Modal"
|
||||||
visible={visible}
|
open={open}
|
||||||
onOk={hideModal}
|
onOk={hideModal}
|
||||||
onCancel={hideModal}
|
onCancel={hideModal}
|
||||||
okText="确认"
|
okText="确认"
|
||||||
|
@ -20,23 +20,23 @@ import type { DraggableData, DraggableEvent } from 'react-draggable';
|
|||||||
import Draggable from 'react-draggable';
|
import Draggable from 'react-draggable';
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const [visible, setVisible] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [disabled, setDisabled] = useState(false);
|
const [disabled, setDisabled] = useState(false);
|
||||||
const [bounds, setBounds] = useState({ left: 0, top: 0, bottom: 0, right: 0 });
|
const [bounds, setBounds] = useState({ left: 0, top: 0, bottom: 0, right: 0 });
|
||||||
const draggleRef = useRef<HTMLDivElement>(null);
|
const draggleRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const showModal = () => {
|
const showModal = () => {
|
||||||
setVisible(true);
|
setOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOk = (e: React.MouseEvent<HTMLElement>) => {
|
const handleOk = (e: React.MouseEvent<HTMLElement>) => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
setVisible(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = (e: React.MouseEvent<HTMLElement>) => {
|
const handleCancel = (e: React.MouseEvent<HTMLElement>) => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
setVisible(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onStart = (_event: DraggableEvent, uiData: DraggableData) => {
|
const onStart = (_event: DraggableEvent, uiData: DraggableData) => {
|
||||||
@ -80,7 +80,7 @@ const App: React.FC = () => {
|
|||||||
Draggable Modal
|
Draggable Modal
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
visible={visible}
|
open={open}
|
||||||
onOk={handleOk}
|
onOk={handleOk}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
modalRender={modal => (
|
modalRender={modal => (
|
||||||
|
@ -18,20 +18,20 @@ import { Button, Modal } from 'antd';
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const [modal1Visible, setModal1Visible] = useState(false);
|
const [modal1Open, setModal1Open] = useState(false);
|
||||||
const [modal2Visible, setModal2Visible] = useState(false);
|
const [modal2Open, setModal2Open] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button type="primary" onClick={() => setModal1Visible(true)}>
|
<Button type="primary" onClick={() => setModal1Open(true)}>
|
||||||
Display a modal dialog at 20px to Top
|
Display a modal dialog at 20px to Top
|
||||||
</Button>
|
</Button>
|
||||||
<Modal
|
<Modal
|
||||||
title="20px to Top"
|
title="20px to Top"
|
||||||
style={{ top: 20 }}
|
style={{ top: 20 }}
|
||||||
visible={modal1Visible}
|
visible={modal1Open}
|
||||||
onOk={() => setModal1Visible(false)}
|
onOk={() => setModal1Open(false)}
|
||||||
onCancel={() => setModal1Visible(false)}
|
onCancel={() => setModal1Open(false)}
|
||||||
>
|
>
|
||||||
<p>some contents...</p>
|
<p>some contents...</p>
|
||||||
<p>some contents...</p>
|
<p>some contents...</p>
|
||||||
@ -39,15 +39,15 @@ const App: React.FC = () => {
|
|||||||
</Modal>
|
</Modal>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<Button type="primary" onClick={() => setModal2Visible(true)}>
|
<Button type="primary" onClick={() => setModal2Open(true)}>
|
||||||
Vertically centered modal dialog
|
Vertically centered modal dialog
|
||||||
</Button>
|
</Button>
|
||||||
<Modal
|
<Modal
|
||||||
title="Vertically centered modal dialog"
|
title="Vertically centered modal dialog"
|
||||||
centered
|
centered
|
||||||
visible={modal2Visible}
|
visible={modal2Open}
|
||||||
onOk={() => setModal2Visible(false)}
|
onOk={() => setModal2Open(false)}
|
||||||
onCancel={() => setModal2Visible(false)}
|
onCancel={() => setModal2Open(false)}
|
||||||
>
|
>
|
||||||
<p>some contents...</p>
|
<p>some contents...</p>
|
||||||
<p>some contents...</p>
|
<p>some contents...</p>
|
||||||
|
@ -18,19 +18,19 @@ import { Button, Modal } from 'antd';
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const [visible, setVisible] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button type="primary" onClick={() => setVisible(true)}>
|
<Button type="primary" onClick={() => setOpen(true)}>
|
||||||
Open Modal of 1000px width
|
Open Modal of 1000px width
|
||||||
</Button>
|
</Button>
|
||||||
<Modal
|
<Modal
|
||||||
title="Modal 1000px width"
|
title="Modal 1000px width"
|
||||||
centered
|
centered
|
||||||
visible={visible}
|
open={open}
|
||||||
onOk={() => setVisible(false)}
|
onOk={() => setOpen(false)}
|
||||||
onCancel={() => setVisible(false)}
|
onCancel={() => setOpen(false)}
|
||||||
width={1000}
|
width={1000}
|
||||||
>
|
>
|
||||||
<p>some contents...</p>
|
<p>some contents...</p>
|
||||||
|
@ -38,7 +38,7 @@ When requiring users to interact with the application, but without jumping to a
|
|||||||
| okType | Button `type` of the OK button | string | `primary` | |
|
| okType | Button `type` of the OK button | string | `primary` | |
|
||||||
| style | Style of floating layer, typically used at least for adjusting the position | CSSProperties | - | |
|
| style | Style of floating layer, typically used at least for adjusting the position | CSSProperties | - | |
|
||||||
| title | The modal dialog's title | ReactNode | - | |
|
| title | The modal dialog's title | ReactNode | - | |
|
||||||
| visible | Whether the modal dialog is visible or not | boolean | false | |
|
| open | Whether the modal dialog is visible or not | boolean | false | 4.23.0 |
|
||||||
| width | Width of the modal dialog | string \| number | 520 | |
|
| width | Width of the modal dialog | string \| number | 520 | |
|
||||||
| wrapClassName | The class name of the container of the modal dialog | string | - | |
|
| wrapClassName | The class name of the container of the modal dialog | string | - | |
|
||||||
| zIndex | The `z-index` of the Modal | number | 1000 | |
|
| zIndex | The `z-index` of the Modal | number | 1000 | |
|
||||||
|
@ -41,7 +41,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/3StSdUlSH/Modal.svg
|
|||||||
| okType | 确认按钮类型 | string | `primary` | |
|
| okType | 确认按钮类型 | string | `primary` | |
|
||||||
| style | 可用于设置浮层的样式,调整浮层位置等 | CSSProperties | - | |
|
| style | 可用于设置浮层的样式,调整浮层位置等 | CSSProperties | - | |
|
||||||
| title | 标题 | ReactNode | - | |
|
| title | 标题 | ReactNode | - | |
|
||||||
| visible | 对话框是否可见 | boolean | - | |
|
| open | 对话框是否可见 | boolean | - | 4.23.0 |
|
||||||
| width | 宽度 | string \| number | 520 | |
|
| width | 宽度 | string \| number | 520 | |
|
||||||
| wrapClassName | 对话框外层容器的类名 | string | - | |
|
| wrapClassName | 对话框外层容器的类名 | string | - | |
|
||||||
| zIndex | 设置 Modal 的 `z-index` | number | 1000 | |
|
| zIndex | 设置 Modal 的 `z-index` | number | 1000 | |
|
||||||
|
@ -25,7 +25,7 @@ const HookModal: React.ForwardRefRenderFunction<HookModalRef, HookModalProps> =
|
|||||||
{ afterClose, config },
|
{ afterClose, config },
|
||||||
ref,
|
ref,
|
||||||
) => {
|
) => {
|
||||||
const [visible, setVisible] = React.useState(true);
|
const [open, setOpen] = React.useState(true);
|
||||||
const [innerConfig, setInnerConfig] = React.useState(config);
|
const [innerConfig, setInnerConfig] = React.useState(config);
|
||||||
const { direction, getPrefixCls } = React.useContext(ConfigContext);
|
const { direction, getPrefixCls } = React.useContext(ConfigContext);
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ const HookModal: React.ForwardRefRenderFunction<HookModalRef, HookModalProps> =
|
|||||||
const rootPrefixCls = getPrefixCls();
|
const rootPrefixCls = getPrefixCls();
|
||||||
|
|
||||||
const close = (...args: any[]) => {
|
const close = (...args: any[]) => {
|
||||||
setVisible(false);
|
setOpen(false);
|
||||||
const triggerCancel = args.some(param => param && param.triggerCancel);
|
const triggerCancel = args.some(param => param && param.triggerCancel);
|
||||||
if (innerConfig.onCancel && triggerCancel) {
|
if (innerConfig.onCancel && triggerCancel) {
|
||||||
innerConfig.onCancel(() => {}, ...args.slice(1));
|
innerConfig.onCancel(() => {}, ...args.slice(1));
|
||||||
@ -58,7 +58,7 @@ const HookModal: React.ForwardRefRenderFunction<HookModalRef, HookModalProps> =
|
|||||||
rootPrefixCls={rootPrefixCls}
|
rootPrefixCls={rootPrefixCls}
|
||||||
{...innerConfig}
|
{...innerConfig}
|
||||||
close={close}
|
close={close}
|
||||||
visible={visible}
|
open={open}
|
||||||
afterClose={afterClose}
|
afterClose={afterClose}
|
||||||
okText={innerConfig.okText}
|
okText={innerConfig.okText}
|
||||||
direction={direction}
|
direction={direction}
|
||||||
|
295
components/style/themes/compact.less
Normal file
295
components/style/themes/compact.less
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
@import './default.less';
|
||||||
|
|
||||||
|
@line-height-base: 1.66667;
|
||||||
|
@mode: compact;
|
||||||
|
@font-size-base: 12px;
|
||||||
|
@font-size-lg: @font-size-base + 2px;
|
||||||
|
|
||||||
|
// default paddings
|
||||||
|
@default-padding-lg: 24px; // containers
|
||||||
|
@default-padding-md: 16px; // small containers and buttons
|
||||||
|
@default-padding-sm: 12px; // Form controls and items
|
||||||
|
@default-padding-xs: 8px; // small items
|
||||||
|
@default-padding-xss: 4px; // more small
|
||||||
|
|
||||||
|
// vertical paddings
|
||||||
|
@padding-lg: 16px; // containers
|
||||||
|
@padding-md: 8px; // small containers and buttons
|
||||||
|
@padding-sm: 8px; // Form controls and items
|
||||||
|
@padding-xs: 4px; // small items
|
||||||
|
@padding-xss: 0px; // more small
|
||||||
|
|
||||||
|
// vertical padding for all form controls
|
||||||
|
@control-padding-horizontal: @padding-sm;
|
||||||
|
@control-padding-horizontal-sm: @default-padding-xs;
|
||||||
|
|
||||||
|
// vertical margins
|
||||||
|
@margin-lg: 16px; // containers
|
||||||
|
@margin-md: 8px; // small containers and buttons
|
||||||
|
@margin-sm: 8px; // Form controls and items
|
||||||
|
@margin-xs: 4px; // small items
|
||||||
|
@margin-xss: 0px; // more small
|
||||||
|
|
||||||
|
// height rules
|
||||||
|
@height-base: 28px;
|
||||||
|
@height-lg: 32px;
|
||||||
|
@height-sm: 22px;
|
||||||
|
|
||||||
|
// Button
|
||||||
|
// ---
|
||||||
|
@btn-padding-horizontal-base: @default-padding-sm - 1px;
|
||||||
|
@btn-padding-horizontal-lg: @btn-padding-horizontal-base;
|
||||||
|
@btn-padding-horizontal-sm: @default-padding-xs - 1px;
|
||||||
|
@btn-square-only-icon-size-lg: 16px;
|
||||||
|
@btn-square-only-icon-size: 14px;
|
||||||
|
@btn-square-only-icon-size-sm: 12px;
|
||||||
|
|
||||||
|
// Breadcrumb
|
||||||
|
// ---
|
||||||
|
@breadcrumb-font-size: @font-size-base;
|
||||||
|
@breadcrumb-icon-font-size: @font-size-base;
|
||||||
|
|
||||||
|
//Dropdown
|
||||||
|
@dropdown-line-height: 18px;
|
||||||
|
|
||||||
|
// Menu
|
||||||
|
@menu-item-padding: 0 12px;
|
||||||
|
@menu-horizontal-line-height: 38px;
|
||||||
|
@menu-inline-toplevel-item-height: 32px;
|
||||||
|
@menu-item-height: 32px;
|
||||||
|
@menu-item-vertical-margin: 0px;
|
||||||
|
@menu-item-boundary-margin: 0px;
|
||||||
|
@menu-icon-margin-right: 8px;
|
||||||
|
|
||||||
|
// Checkbox
|
||||||
|
@checkbox-size: 14px;
|
||||||
|
@checkbox-group-item-margin-right: 6px;
|
||||||
|
|
||||||
|
// picker
|
||||||
|
@picker-panel-cell-height: 22px;
|
||||||
|
@picker-panel-cell-width: 32px;
|
||||||
|
@picker-text-height: 32px;
|
||||||
|
@picker-time-panel-cell-height: 24px;
|
||||||
|
@picker-panel-without-time-cell-height: 48px;
|
||||||
|
|
||||||
|
// Form
|
||||||
|
// ---
|
||||||
|
@form-item-margin-bottom: 16px;
|
||||||
|
@form-vertical-label-padding: 0 0 4px;
|
||||||
|
|
||||||
|
// Rate
|
||||||
|
// ---
|
||||||
|
@rate-star-size: 16px;
|
||||||
|
|
||||||
|
// Radio
|
||||||
|
// ---
|
||||||
|
@radio-size: 14px;
|
||||||
|
@radio-wrapper-margin-right: 6px;
|
||||||
|
|
||||||
|
// Switch
|
||||||
|
// ---
|
||||||
|
@switch-height: 20px;
|
||||||
|
@switch-sm-height: 14px;
|
||||||
|
@switch-min-width: 40px;
|
||||||
|
@switch-sm-min-width: 24px;
|
||||||
|
@switch-inner-margin-min: 4px;
|
||||||
|
@switch-inner-margin-max: 22px;
|
||||||
|
|
||||||
|
// Slider
|
||||||
|
// ---
|
||||||
|
@slider-handle-size: 12px;
|
||||||
|
@slider-handle-margin-top: -4px;
|
||||||
|
|
||||||
|
// Input
|
||||||
|
// ---
|
||||||
|
@input-padding-vertical-base: round(
|
||||||
|
max(
|
||||||
|
(round(((@input-height-base - @font-size-base * @line-height-base) / 2) * 10) / 10) -
|
||||||
|
@border-width-base,
|
||||||
|
2px
|
||||||
|
)
|
||||||
|
);
|
||||||
|
@input-padding-horizontal-lg: 11px;
|
||||||
|
|
||||||
|
// PageHeader
|
||||||
|
// ---
|
||||||
|
@page-header-padding: 16px;
|
||||||
|
@page-header-padding-vertical: 8px;
|
||||||
|
@page-header-heading-title: 16px;
|
||||||
|
@page-header-heading-sub-title: 12px;
|
||||||
|
@page-header-tabs-tab-font-size: 14px;
|
||||||
|
|
||||||
|
// Pagination
|
||||||
|
// ---
|
||||||
|
@pagination-mini-options-size-changer-top: 1px;
|
||||||
|
@pagination-item-size-sm: 22px;
|
||||||
|
|
||||||
|
// Cascader
|
||||||
|
// ----
|
||||||
|
@cascader-dropdown-line-height: @dropdown-line-height;
|
||||||
|
|
||||||
|
// Select
|
||||||
|
// ---
|
||||||
|
@select-dropdown-height: @height-base;
|
||||||
|
@select-single-item-height-lg: 32px;
|
||||||
|
@select-multiple-item-height: @input-height-base - max(@input-padding-vertical-base, 4) * 2; // Normal 24px
|
||||||
|
@select-multiple-item-height-lg: 24px;
|
||||||
|
@select-multiple-item-spacing-half: 3px;
|
||||||
|
|
||||||
|
// Tree
|
||||||
|
// ---
|
||||||
|
@tree-title-height: 20px;
|
||||||
|
|
||||||
|
// Transfer
|
||||||
|
// ---
|
||||||
|
@transfer-item-padding-vertical: 3px;
|
||||||
|
@transfer-list-search-icon-top: 8px;
|
||||||
|
@transfer-header-height: 36px;
|
||||||
|
|
||||||
|
// Comment
|
||||||
|
// ---
|
||||||
|
@comment-actions-margin-bottom: 0px;
|
||||||
|
@comment-actions-margin-top: @margin-xs;
|
||||||
|
@comment-content-detail-p-margin-bottom: 0px;
|
||||||
|
|
||||||
|
// Steps
|
||||||
|
// ---
|
||||||
|
@steps-icon-size: 24px;
|
||||||
|
@steps-icon-custom-size: 20px;
|
||||||
|
@steps-icon-custom-font-size: 20px;
|
||||||
|
@steps-icon-custom-top: 2px;
|
||||||
|
@steps-icon-margin: 2px 8px 2px 0;
|
||||||
|
@steps-icon-font-size: @font-size-base;
|
||||||
|
@steps-dot-top: 4px;
|
||||||
|
@steps-icon-top: 0px;
|
||||||
|
@steps-small-icon-size: 20px;
|
||||||
|
@steps-vertical-icon-width: 12px;
|
||||||
|
@steps-vertical-tail-width: 12px;
|
||||||
|
@steps-vertical-tail-width-sm: 10px;
|
||||||
|
// Collapse
|
||||||
|
// ---
|
||||||
|
//@collapse-header-padding-extra: 32px;
|
||||||
|
@collapse-content-padding: @padding-md @padding-lg;
|
||||||
|
|
||||||
|
// List
|
||||||
|
// ---
|
||||||
|
@list-item-meta-description-font-size: @font-size-sm;
|
||||||
|
@list-item-padding-sm: 4px 12px;
|
||||||
|
@list-item-padding-lg: 12px 16px;
|
||||||
|
|
||||||
|
// Drawer
|
||||||
|
// ---
|
||||||
|
@drawer-header-padding: 11px @padding-lg;
|
||||||
|
@drawer-footer-padding-vertical: @padding-sm;
|
||||||
|
@drawer-footer-padding-horizontal: @padding-sm;
|
||||||
|
@drawer-header-close-size: 44px;
|
||||||
|
|
||||||
|
// Modal
|
||||||
|
// --
|
||||||
|
@modal-header-padding-vertical: 11px;
|
||||||
|
@modal-header-padding: @modal-header-padding-vertical @modal-header-padding-horizontal;
|
||||||
|
@modal-footer-padding-vertical: @padding-sm;
|
||||||
|
@modal-header-close-size: @modal-header-title-line-height + 2 * @modal-header-padding-vertical;
|
||||||
|
@modal-confirm-body-padding: 24px 24px 16px;
|
||||||
|
|
||||||
|
// Message
|
||||||
|
// ---
|
||||||
|
@message-notice-content-padding: 8px 16px;
|
||||||
|
|
||||||
|
// popover
|
||||||
|
// --
|
||||||
|
@popover-min-height: 28px;
|
||||||
|
@popover-padding-horizontal: @default-padding-sm;
|
||||||
|
|
||||||
|
// Card
|
||||||
|
// ---
|
||||||
|
@card-head-height: 36px;
|
||||||
|
@card-head-font-size: @card-head-font-size-sm;
|
||||||
|
@card-head-padding: 8.5px;
|
||||||
|
@card-padding-base: 12px;
|
||||||
|
@card-padding-base-sm: @card-padding-base;
|
||||||
|
@card-head-height-sm: 30px;
|
||||||
|
@card-head-padding-sm: 6px;
|
||||||
|
@card-actions-li-margin: 4px 0;
|
||||||
|
@card-head-tabs-margin-bottom: -9px;
|
||||||
|
|
||||||
|
// Table
|
||||||
|
// ---
|
||||||
|
@table-padding-vertical: 12px;
|
||||||
|
@table-padding-horizontal: 8px;
|
||||||
|
@table-padding-vertical-md: 8px;
|
||||||
|
@table-padding-horizontal-md: 8px;
|
||||||
|
@table-padding-vertical-sm: 4px;
|
||||||
|
@table-padding-horizontal-sm: 4px;
|
||||||
|
@table-selection-column-width: 32px;
|
||||||
|
|
||||||
|
// Statistic
|
||||||
|
// ---
|
||||||
|
@statistic-content-font-size: 20px;
|
||||||
|
|
||||||
|
// Alert
|
||||||
|
// ---
|
||||||
|
@alert-with-description-no-icon-padding-vertical: 7px;
|
||||||
|
@alert-with-description-padding-vertical: 11px;
|
||||||
|
@alert-icon-top: 7px + @font-size-base * (@line-height-base / 2) - (@font-size-base / 2);
|
||||||
|
@alert-with-description-icon-size: 20px;
|
||||||
|
|
||||||
|
// Skeleton
|
||||||
|
// ---
|
||||||
|
@skeleton-paragraph-margin-top: 20px;
|
||||||
|
@skeleton-paragraph-li-margin-top: 12px;
|
||||||
|
@skeleton-paragraph-li-height: 14px;
|
||||||
|
@skeleton-title-height: 14px;
|
||||||
|
@skeleton-title-paragraph-margin-top: 20px;
|
||||||
|
|
||||||
|
// Descriptions
|
||||||
|
@descriptions-title-margin-bottom: 8px;
|
||||||
|
@descriptions-default-padding: 12px @padding-lg;
|
||||||
|
@descriptions-item-padding-bottom: @padding-xs;
|
||||||
|
|
||||||
|
// Avatar
|
||||||
|
// ---
|
||||||
|
@avatar-size-base: 28px;
|
||||||
|
@avatar-size-lg: 32px;
|
||||||
|
@avatar-size-sm: 22px;
|
||||||
|
@avatar-font-size-base: 16px;
|
||||||
|
@avatar-font-size-lg: 20px;
|
||||||
|
@avatar-font-size-sm: 12px;
|
||||||
|
|
||||||
|
// Badge
|
||||||
|
// ---
|
||||||
|
@badge-height: 18px;
|
||||||
|
|
||||||
|
// Tag
|
||||||
|
// ---
|
||||||
|
@tag-line-height: 18px;
|
||||||
|
|
||||||
|
// Notification
|
||||||
|
// ---
|
||||||
|
@notification-padding-vertical: 12px;
|
||||||
|
@notification-padding-horizontal: 16px;
|
||||||
|
|
||||||
|
// Result
|
||||||
|
// ---
|
||||||
|
@result-title-font-size: 20px;
|
||||||
|
@result-icon-font-size: 64px;
|
||||||
|
@result-extra-margin: 24px 0 0 0;
|
||||||
|
|
||||||
|
// Anchor
|
||||||
|
// ---
|
||||||
|
@anchor-link-top: 4px;
|
||||||
|
@anchor-link-left: 16px;
|
||||||
|
@anchor-link-padding: @anchor-link-top 0 @anchor-link-top @anchor-link-left;
|
||||||
|
|
||||||
|
// Tabs
|
||||||
|
// ---
|
||||||
|
@tabs-card-horizontal-padding: 4px @padding-md;
|
||||||
|
|
||||||
|
// Progress
|
||||||
|
// ---
|
||||||
|
@progress-circle-text-font-size: 0.833333em;
|
||||||
|
|
||||||
|
// Image
|
||||||
|
// ---
|
||||||
|
@image-size-base: 48px;
|
||||||
|
@image-font-size-base: 24px;
|
@ -104,6 +104,33 @@ describe('Table.sorter', () => {
|
|||||||
expect(getNameColumn().getAttribute('aria-sort')).toEqual(null);
|
expect(getNameColumn().getAttribute('aria-sort')).toEqual(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should have aria-lable if the column is sortable and is not sorted', () => {
|
||||||
|
const { container } = render(
|
||||||
|
createTable(
|
||||||
|
{
|
||||||
|
sortDirections: ['descend', 'ascend'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
defaultSortOrder: 'descend',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
const getNameColumn = () => container.querySelector('th');
|
||||||
|
|
||||||
|
expect(renderedNames(container)).toEqual(['Tom', 'Lucy', 'Jack', 'Jerry']);
|
||||||
|
expect(getNameColumn().getAttribute('aria-sort')).toEqual('descending');
|
||||||
|
expect(getNameColumn().getAttribute('aria-label')).toEqual(null);
|
||||||
|
|
||||||
|
fireEvent.click(container.querySelector('.ant-table-column-sorters'));
|
||||||
|
expect(getNameColumn().getAttribute('aria-sort')).toEqual('ascending');
|
||||||
|
expect(getNameColumn().getAttribute('aria-label')).toEqual(null);
|
||||||
|
|
||||||
|
fireEvent.click(container.querySelector('.ant-table-column-sorters'));
|
||||||
|
expect(getNameColumn().getAttribute('aria-sort')).toEqual(null);
|
||||||
|
expect(getNameColumn().getAttribute('aria-label')).toEqual('Name sortable');
|
||||||
|
});
|
||||||
|
|
||||||
it('sort records', () => {
|
it('sort records', () => {
|
||||||
const { container } = render(createTable());
|
const { container } = render(createTable());
|
||||||
const getNameColumn = () => container.querySelector('th');
|
const getNameColumn = () => container.querySelector('th');
|
||||||
|
@ -85,7 +85,6 @@ exports[`Table.rowSelection fix expand on th left when selection column fixed on
|
|||||||
<div
|
<div
|
||||||
style="height: 0px; overflow: hidden;"
|
style="height: 0px; overflow: hidden;"
|
||||||
>
|
>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
@ -94,7 +93,6 @@ exports[`Table.rowSelection fix expand on th left when selection column fixed on
|
|||||||
<div
|
<div
|
||||||
style="height: 0px; overflow: hidden;"
|
style="height: 0px; overflow: hidden;"
|
||||||
>
|
>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
@ -103,7 +101,6 @@ exports[`Table.rowSelection fix expand on th left when selection column fixed on
|
|||||||
<div
|
<div
|
||||||
style="height: 0px; overflow: hidden;"
|
style="height: 0px; overflow: hidden;"
|
||||||
>
|
>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -443,7 +440,6 @@ exports[`Table.rowSelection fix selection column on the left 1`] = `
|
|||||||
<div
|
<div
|
||||||
style="height: 0px; overflow: hidden;"
|
style="height: 0px; overflow: hidden;"
|
||||||
>
|
>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
@ -452,7 +448,6 @@ exports[`Table.rowSelection fix selection column on the left 1`] = `
|
|||||||
<div
|
<div
|
||||||
style="height: 0px; overflow: hidden;"
|
style="height: 0px; overflow: hidden;"
|
||||||
>
|
>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -749,7 +744,6 @@ exports[`Table.rowSelection fix selection column on the left when any other colu
|
|||||||
<div
|
<div
|
||||||
style="height: 0px; overflow: hidden;"
|
style="height: 0px; overflow: hidden;"
|
||||||
>
|
>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
@ -758,7 +752,6 @@ exports[`Table.rowSelection fix selection column on the left when any other colu
|
|||||||
<div
|
<div
|
||||||
style="height: 0px; overflow: hidden;"
|
style="height: 0px; overflow: hidden;"
|
||||||
>
|
>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -6,6 +6,7 @@ exports[`Table.sorter renders sorter icon correctly 1`] = `
|
|||||||
>
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Name sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -26,7 +27,7 @@ exports[`Table.sorter renders sorter icon correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -45,7 +46,7 @@ exports[`Table.sorter renders sorter icon correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -118,7 +119,7 @@ exports[`Table.sorter should support defaultOrder in Column 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up active"
|
class="anticon anticon-caret-up ant-table-column-sorter-up active"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -137,7 +138,7 @@ exports[`Table.sorter should support defaultOrder in Column 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
|
@ -35,6 +35,7 @@ exports[`renders ./components/table/demo/ajax.md extend context correctly 1`] =
|
|||||||
>
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Name sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -55,7 +56,7 @@ exports[`renders ./components/table/demo/ajax.md extend context correctly 1`] =
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -74,7 +75,7 @@ exports[`renders ./components/table/demo/ajax.md extend context correctly 1`] =
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -1515,6 +1516,7 @@ exports[`renders ./components/table/demo/custom-filter-panel.md extend context c
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Address sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -1541,7 +1543,7 @@ exports[`renders ./components/table/demo/custom-filter-panel.md extend context c
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -1560,7 +1562,7 @@ exports[`renders ./components/table/demo/custom-filter-panel.md extend context c
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -3265,6 +3267,7 @@ Array [
|
|||||||
Name
|
Name
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Age sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -3285,7 +3288,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -3304,7 +3307,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -3575,6 +3578,7 @@ Array [
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Action sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -3595,7 +3599,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -3614,7 +3618,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -7530,6 +7534,7 @@ exports[`renders ./components/table/demo/filter-in-tree.md extend context correc
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Age sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -7550,7 +7555,7 @@ exports[`renders ./components/table/demo/filter-in-tree.md extend context correc
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -7569,7 +7574,7 @@ exports[`renders ./components/table/demo/filter-in-tree.md extend context correc
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -8350,6 +8355,7 @@ exports[`renders ./components/table/demo/filter-search.md extend context correct
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Age sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -8370,7 +8376,7 @@ exports[`renders ./components/table/demo/filter-search.md extend context correct
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -8389,7 +8395,7 @@ exports[`renders ./components/table/demo/filter-search.md extend context correct
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -12222,6 +12228,7 @@ exports[`renders ./components/table/demo/grouping-columns.md extend context corr
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Age sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
rowspan="3"
|
rowspan="3"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@ -12243,7 +12250,7 @@ exports[`renders ./components/table/demo/grouping-columns.md extend context corr
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -12262,7 +12269,7 @@ exports[`renders ./components/table/demo/grouping-columns.md extend context corr
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -13329,6 +13336,7 @@ exports[`renders ./components/table/demo/head.md extend context correctly 1`] =
|
|||||||
>
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Name sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -13355,7 +13363,7 @@ exports[`renders ./components/table/demo/head.md extend context correctly 1`] =
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -13833,7 +13841,7 @@ exports[`renders ./components/table/demo/head.md extend context correctly 1`] =
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -13852,7 +13860,7 @@ exports[`renders ./components/table/demo/head.md extend context correctly 1`] =
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down active"
|
class="anticon anticon-caret-down ant-table-column-sorter-down active"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -14675,6 +14683,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md extend context corre
|
|||||||
Name
|
Name
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Chinese Score sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -14695,7 +14704,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md extend context corre
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -14714,7 +14723,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md extend context corre
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -14759,6 +14768,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md extend context corre
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Math Score sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -14779,7 +14789,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md extend context corre
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -14798,7 +14808,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md extend context corre
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -14843,6 +14853,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md extend context corre
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="English Score sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -14863,7 +14874,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md extend context corre
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -14882,7 +14893,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md extend context corre
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -20359,6 +20370,7 @@ Array [
|
|||||||
>
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Name sortable"
|
||||||
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -20385,7 +20397,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -20404,7 +20416,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -20664,6 +20676,7 @@ Array [
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Age sortable"
|
||||||
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -20684,7 +20697,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -20703,7 +20716,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -20748,6 +20761,7 @@ Array [
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Address sortable"
|
||||||
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -20774,7 +20788,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -20793,7 +20807,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -21289,6 +21303,7 @@ exports[`renders ./components/table/demo/resizable-column.md extend context corr
|
|||||||
/>
|
/>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Amount sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters react-resizable"
|
class="ant-table-cell ant-table-column-has-sorters react-resizable"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -21309,7 +21324,7 @@ exports[`renders ./components/table/demo/resizable-column.md extend context corr
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -21328,7 +21343,7 @@ exports[`renders ./components/table/demo/resizable-column.md extend context corr
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
|
@ -35,6 +35,7 @@ exports[`renders ./components/table/demo/ajax.md correctly 1`] = `
|
|||||||
>
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Name sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -55,7 +56,7 @@ exports[`renders ./components/table/demo/ajax.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -74,7 +75,7 @@ exports[`renders ./components/table/demo/ajax.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -1133,6 +1134,7 @@ exports[`renders ./components/table/demo/custom-filter-panel.md correctly 1`] =
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Address sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -1159,7 +1161,7 @@ exports[`renders ./components/table/demo/custom-filter-panel.md correctly 1`] =
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -1178,7 +1180,7 @@ exports[`renders ./components/table/demo/custom-filter-panel.md correctly 1`] =
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -2774,6 +2776,7 @@ Array [
|
|||||||
Name
|
Name
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Age sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -2794,7 +2797,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -2813,7 +2816,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -2872,6 +2875,7 @@ Array [
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Action sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -2892,7 +2896,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -2911,7 +2915,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -5849,6 +5853,7 @@ exports[`renders ./components/table/demo/filter-in-tree.md correctly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Age sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -5869,7 +5874,7 @@ exports[`renders ./components/table/demo/filter-in-tree.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -5888,7 +5893,7 @@ exports[`renders ./components/table/demo/filter-in-tree.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -6195,6 +6200,7 @@ exports[`renders ./components/table/demo/filter-search.md correctly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Age sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -6215,7 +6221,7 @@ exports[`renders ./components/table/demo/filter-search.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -6234,7 +6240,7 @@ exports[`renders ./components/table/demo/filter-search.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -9393,6 +9399,7 @@ exports[`renders ./components/table/demo/grouping-columns.md correctly 1`] = `
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Age sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
rowspan="3"
|
rowspan="3"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@ -9414,7 +9421,7 @@ exports[`renders ./components/table/demo/grouping-columns.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -9433,7 +9440,7 @@ exports[`renders ./components/table/demo/grouping-columns.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -10360,6 +10367,7 @@ exports[`renders ./components/table/demo/head.md correctly 1`] = `
|
|||||||
>
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Name sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -10386,7 +10394,7 @@ exports[`renders ./components/table/demo/head.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -10455,7 +10463,7 @@ exports[`renders ./components/table/demo/head.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -10474,7 +10482,7 @@ exports[`renders ./components/table/demo/head.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down active"
|
class="anticon anticon-caret-down ant-table-column-sorter-down active"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -11085,6 +11093,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md correctly 1`] = `
|
|||||||
Name
|
Name
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Chinese Score sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -11105,7 +11114,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -11124,7 +11133,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -11145,6 +11154,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md correctly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Math Score sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -11165,7 +11175,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -11184,7 +11194,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -11205,6 +11215,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md correctly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="English Score sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -11225,7 +11236,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -11244,7 +11255,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -15420,6 +15431,7 @@ Array [
|
|||||||
>
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Name sortable"
|
||||||
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -15446,7 +15458,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -15465,7 +15477,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -15513,6 +15525,7 @@ Array [
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Age sortable"
|
||||||
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -15533,7 +15546,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -15552,7 +15565,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -15573,6 +15586,7 @@ Array [
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Address sortable"
|
||||||
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
|
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -15599,7 +15613,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -15618,7 +15632,7 @@ Array [
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -15902,6 +15916,7 @@ exports[`renders ./components/table/demo/resizable-column.md correctly 1`] = `
|
|||||||
/>
|
/>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
|
aria-label="Amount sortable"
|
||||||
class="ant-table-cell ant-table-column-has-sorters react-resizable"
|
class="ant-table-cell ant-table-column-has-sorters react-resizable"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -15922,7 +15937,7 @@ exports[`renders ./components/table/demo/resizable-column.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-up"
|
aria-label="caret-up"
|
||||||
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
class="anticon anticon-caret-up ant-table-column-sorter-up"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -15941,7 +15956,7 @@ exports[`renders ./components/table/demo/resizable-column.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-label="caret-down"
|
aria-label="caret-down"
|
||||||
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
class="anticon anticon-caret-down ant-table-column-sorter-down"
|
||||||
role="img"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
|
@ -348,7 +348,6 @@ exports[`Table renders empty table with fixed columns should work 1`] = `
|
|||||||
<div
|
<div
|
||||||
style="height: 0px; overflow: hidden;"
|
style="height: 0px; overflow: hidden;"
|
||||||
>
|
>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
@ -357,7 +356,6 @@ exports[`Table renders empty table with fixed columns should work 1`] = `
|
|||||||
<div
|
<div
|
||||||
style="height: 0px; overflow: hidden;"
|
style="height: 0px; overflow: hidden;"
|
||||||
>
|
>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
@ -366,7 +364,6 @@ exports[`Table renders empty table with fixed columns should work 1`] = `
|
|||||||
<div
|
<div
|
||||||
style="height: 0px; overflow: hidden;"
|
style="height: 0px; overflow: hidden;"
|
||||||
>
|
>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
@ -375,7 +372,6 @@ exports[`Table renders empty table with fixed columns should work 1`] = `
|
|||||||
<div
|
<div
|
||||||
style="height: 0px; overflow: hidden;"
|
style="height: 0px; overflow: hidden;"
|
||||||
>
|
>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
@ -384,7 +380,6 @@ exports[`Table renders empty table with fixed columns should work 1`] = `
|
|||||||
<div
|
<div
|
||||||
style="height: 0px; overflow: hidden;"
|
style="height: 0px; overflow: hidden;"
|
||||||
>
|
>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
@ -393,7 +388,6 @@ exports[`Table renders empty table with fixed columns should work 1`] = `
|
|||||||
<div
|
<div
|
||||||
style="height: 0px; overflow: hidden;"
|
style="height: 0px; overflow: hidden;"
|
||||||
>
|
>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
@ -402,7 +396,6 @@ exports[`Table renders empty table with fixed columns should work 1`] = `
|
|||||||
<div
|
<div
|
||||||
style="height: 0px; overflow: hidden;"
|
style="height: 0px; overflow: hidden;"
|
||||||
>
|
>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
@ -411,7 +404,6 @@ exports[`Table renders empty table with fixed columns should work 1`] = `
|
|||||||
<div
|
<div
|
||||||
style="height: 0px; overflow: hidden;"
|
style="height: 0px; overflow: hidden;"
|
||||||
>
|
>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
@ -420,7 +412,6 @@ exports[`Table renders empty table with fixed columns should work 1`] = `
|
|||||||
<div
|
<div
|
||||||
style="height: 0px; overflow: hidden;"
|
style="height: 0px; overflow: hidden;"
|
||||||
>
|
>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
@ -429,7 +420,6 @@ exports[`Table renders empty table with fixed columns should work 1`] = `
|
|||||||
<div
|
<div
|
||||||
style="height: 0px; overflow: hidden;"
|
style="height: 0px; overflow: hidden;"
|
||||||
>
|
>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
@ -438,7 +428,6 @@ exports[`Table renders empty table with fixed columns should work 1`] = `
|
|||||||
<div
|
<div
|
||||||
style="height: 0px; overflow: hidden;"
|
style="height: 0px; overflow: hidden;"
|
||||||
>
|
>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -132,6 +132,7 @@ function injectSorter<RecordType>(
|
|||||||
className={classNames(`${prefixCls}-column-sorter-up`, {
|
className={classNames(`${prefixCls}-column-sorter-up`, {
|
||||||
active: sorterOrder === ASCEND,
|
active: sorterOrder === ASCEND,
|
||||||
})}
|
})}
|
||||||
|
role="presentation"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
const downNode: React.ReactNode = sortDirections.includes(DESCEND) && (
|
const downNode: React.ReactNode = sortDirections.includes(DESCEND) && (
|
||||||
@ -139,6 +140,7 @@ function injectSorter<RecordType>(
|
|||||||
className={classNames(`${prefixCls}-column-sorter-down`, {
|
className={classNames(`${prefixCls}-column-sorter-down`, {
|
||||||
active: sorterOrder === DESCEND,
|
active: sorterOrder === DESCEND,
|
||||||
})}
|
})}
|
||||||
|
role="presentation"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
const { cancelSort, triggerAsc, triggerDesc } = tableLocale || {};
|
const { cancelSort, triggerAsc, triggerDesc } = tableLocale || {};
|
||||||
@ -210,6 +212,8 @@ function injectSorter<RecordType>(
|
|||||||
} else {
|
} else {
|
||||||
cell['aria-sort'] = 'descending';
|
cell['aria-sort'] = 'descending';
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
cell['aria-label'] = `${renderColumnTitle(column.title, {})} sortable`;
|
||||||
}
|
}
|
||||||
|
|
||||||
cell.className = classNames(cell.className, `${prefixCls}-column-has-sorters`);
|
cell.className = classNames(cell.className, `${prefixCls}-column-has-sorters`);
|
||||||
|
@ -227,6 +227,7 @@ const Base = React.forwardRef((props: InternalBlockProps, ref: any) => {
|
|||||||
const [expanded, setExpanded] = React.useState(false);
|
const [expanded, setExpanded] = React.useState(false);
|
||||||
const [isJsEllipsis, setIsJsEllipsis] = React.useState(false);
|
const [isJsEllipsis, setIsJsEllipsis] = React.useState(false);
|
||||||
const [isNativeEllipsis, setIsNativeEllipsis] = React.useState(false);
|
const [isNativeEllipsis, setIsNativeEllipsis] = React.useState(false);
|
||||||
|
const [isNativeVisible, setIsNativeVisible] = React.useState(true);
|
||||||
const [enableEllipsis, ellipsisConfig] = useMergedConfig<EllipsisConfig>(ellipsis, {
|
const [enableEllipsis, ellipsisConfig] = useMergedConfig<EllipsisConfig>(ellipsis, {
|
||||||
expandable: false,
|
expandable: false,
|
||||||
});
|
});
|
||||||
@ -307,7 +308,31 @@ const Base = React.forwardRef((props: InternalBlockProps, ref: any) => {
|
|||||||
setIsNativeEllipsis(currentEllipsis);
|
setIsNativeEllipsis(currentEllipsis);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [enableEllipsis, cssEllipsis, children, cssLineClamp]);
|
}, [enableEllipsis, cssEllipsis, children, cssLineClamp, isNativeVisible]);
|
||||||
|
|
||||||
|
// https://github.com/ant-design/ant-design/issues/36786
|
||||||
|
// Use IntersectionObserver to check if element is invisible
|
||||||
|
React.useEffect(() => {
|
||||||
|
const textEle = typographyRef.current;
|
||||||
|
if (
|
||||||
|
typeof IntersectionObserver === 'undefined' ||
|
||||||
|
!textEle ||
|
||||||
|
!cssEllipsis ||
|
||||||
|
!mergedEnableEllipsis
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* eslint-disable-next-line compat/compat */
|
||||||
|
const observer = new IntersectionObserver(() => {
|
||||||
|
setIsNativeVisible(!!textEle.offsetParent);
|
||||||
|
});
|
||||||
|
observer.observe(textEle!);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
observer.disconnect();
|
||||||
|
};
|
||||||
|
}, [cssEllipsis, mergedEnableEllipsis]);
|
||||||
|
|
||||||
// ========================== Tooltip ===========================
|
// ========================== Tooltip ===========================
|
||||||
let tooltipProps: TooltipProps = {};
|
let tooltipProps: TooltipProps = {};
|
||||||
|
@ -618,6 +618,57 @@ Array [
|
|||||||
</span>
|
</span>
|
||||||
[After]
|
[After]
|
||||||
</p>,
|
</p>,
|
||||||
|
<div
|
||||||
|
style="display:none"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-label="默认display none 样式的超长文字, 悬停tooltip失效了"
|
||||||
|
class="ant-typography ant-typography-ellipsis ant-typography-single-line"
|
||||||
|
style="width:100px"
|
||||||
|
>
|
||||||
|
默认display none 样式的超长文字, 悬停tooltip失效了
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
style="position:fixed;display:block;left:0;top:0;z-index:-9999;visibility:hidden;pointer-events:none;word-break:keep-all;white-space:nowrap"
|
||||||
|
>
|
||||||
|
lg
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
style="position:fixed;display:block;left:0;top:0;z-index:-9999;visibility:hidden;pointer-events:none;width:0;white-space:normal;margin:0;padding:0"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
...
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="ant-tooltip"
|
||||||
|
style="opacity:0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-tooltip-content"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-tooltip-arrow"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="ant-tooltip-arrow-content"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-tooltip-inner"
|
||||||
|
role="tooltip"
|
||||||
|
>
|
||||||
|
I am ellipsis now!
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>,
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -522,6 +522,33 @@ Array [
|
|||||||
</span>
|
</span>
|
||||||
[After]
|
[After]
|
||||||
</p>,
|
</p>,
|
||||||
|
<div
|
||||||
|
style="display:none"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-label="默认display none 样式的超长文字, 悬停tooltip失效了"
|
||||||
|
class="ant-typography ant-typography-ellipsis ant-typography-single-line"
|
||||||
|
style="width:100px"
|
||||||
|
>
|
||||||
|
默认display none 样式的超长文字, 悬停tooltip失效了
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
style="position:fixed;display:block;left:0;top:0;z-index:-9999;visibility:hidden;pointer-events:none;word-break:keep-all;white-space:nowrap"
|
||||||
|
>
|
||||||
|
lg
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
style="position:fixed;display:block;left:0;top:0;z-index:-9999;visibility:hidden;pointer-events:none;width:0;white-space:normal;margin:0;padding:0"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
...
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>,
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { spyElementPrototypes } from 'rc-util/lib/test/domHook';
|
import { spyElementPrototypes } from 'rc-util/lib/test/domHook';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { act } from 'react-dom/test-utils';
|
||||||
import { fireEvent, render, sleep, triggerResize, waitFor } from '../../../tests/utils';
|
import { fireEvent, render, sleep, triggerResize, waitFor } from '../../../tests/utils';
|
||||||
import Base from '../Base';
|
import Base from '../Base';
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
@ -14,6 +15,7 @@ describe('Typography.Ellipsis', () => {
|
|||||||
const LINE_STR_COUNT = 20;
|
const LINE_STR_COUNT = 20;
|
||||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
let mockRectSpy;
|
let mockRectSpy;
|
||||||
|
let getWidthTimes = 0;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
mockRectSpy = spyElementPrototypes(HTMLElement, {
|
mockRectSpy = spyElementPrototypes(HTMLElement, {
|
||||||
@ -26,7 +28,10 @@ describe('Typography.Ellipsis', () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
offsetWidth: {
|
offsetWidth: {
|
||||||
get: () => 100,
|
get: () => {
|
||||||
|
getWidthTimes += 1;
|
||||||
|
return 100;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
getBoundingClientRect() {
|
getBoundingClientRect() {
|
||||||
let html = this.innerHTML;
|
let html = this.innerHTML;
|
||||||
@ -39,6 +44,7 @@ describe('Typography.Ellipsis', () => {
|
|||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
errorSpy.mockReset();
|
errorSpy.mockReset();
|
||||||
|
getWidthTimes = 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
@ -223,28 +229,70 @@ describe('Typography.Ellipsis', () => {
|
|||||||
|
|
||||||
it('should have custom expand style', async () => {
|
it('should have custom expand style', async () => {
|
||||||
const symbol = 'more';
|
const symbol = 'more';
|
||||||
const { container: wrapper } = render(
|
const { container } = render(
|
||||||
<Base ellipsis={{ expandable: true, symbol }} component="p">
|
<Base ellipsis={{ expandable: true, symbol }} component="p">
|
||||||
{fullStr}
|
{fullStr}
|
||||||
</Base>,
|
</Base>,
|
||||||
);
|
);
|
||||||
expect(wrapper.querySelector('.ant-typography-expand').textContent).toEqual('more');
|
expect(container.querySelector('.ant-typography-expand').textContent).toEqual('more');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('native css ellipsis', () => {
|
||||||
it('can use css ellipsis', () => {
|
it('can use css ellipsis', () => {
|
||||||
const { container: wrapper } = render(<Base ellipsis component="p" />);
|
const { container } = render(<Base ellipsis component="p" />);
|
||||||
expect(wrapper.querySelectorAll('.ant-typography-ellipsis-single-line').length).toBeGreaterThan(
|
expect(container.querySelector('.ant-typography-ellipsis-single-line')).toBeTruthy();
|
||||||
0,
|
});
|
||||||
);
|
|
||||||
|
// https://github.com/ant-design/ant-design/issues/36786
|
||||||
|
it('Tooltip should recheck on parent visible change', () => {
|
||||||
|
const originIntersectionObserver = global.IntersectionObserver;
|
||||||
|
|
||||||
|
let elementChangeCallback;
|
||||||
|
const observeFn = jest.fn();
|
||||||
|
const disconnectFn = jest.fn();
|
||||||
|
|
||||||
|
global.IntersectionObserver = class MockIntersectionObserver {
|
||||||
|
constructor(callback) {
|
||||||
|
elementChangeCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
observe = observeFn;
|
||||||
|
|
||||||
|
disconnect = disconnectFn;
|
||||||
|
};
|
||||||
|
|
||||||
|
const { container, unmount } = render(<Base ellipsis component="p" />);
|
||||||
|
|
||||||
|
expect(observeFn).toHaveBeenCalled();
|
||||||
|
|
||||||
|
// Hide first
|
||||||
|
act(() => {
|
||||||
|
elementChangeCallback();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Trigger visible should trigger recheck
|
||||||
|
getWidthTimes = 0;
|
||||||
|
Object.defineProperty(container.querySelector('.ant-typography'), 'offsetParent', {
|
||||||
|
get: () => document.body,
|
||||||
|
});
|
||||||
|
act(() => {
|
||||||
|
elementChangeCallback();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getWidthTimes).toBeGreaterThan(0);
|
||||||
|
|
||||||
|
unmount();
|
||||||
|
expect(disconnectFn).toHaveBeenCalled();
|
||||||
|
|
||||||
|
global.IntersectionObserver = originIntersectionObserver;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should calculate padding', () => {
|
it('should calculate padding', () => {
|
||||||
const { container: wrapper } = render(
|
const { container } = render(
|
||||||
<Base ellipsis component="p" style={{ paddingTop: '12px', paddingBottom: '12px' }} />,
|
<Base ellipsis component="p" style={{ paddingTop: '12px', paddingBottom: '12px' }} />,
|
||||||
);
|
);
|
||||||
expect(wrapper.querySelectorAll('.ant-typography-ellipsis-single-line').length).toBeGreaterThan(
|
expect(container.querySelector('.ant-typography-ellipsis-single-line')).toBeTruthy();
|
||||||
0,
|
});
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('should tooltip support', () => {
|
describe('should tooltip support', () => {
|
||||||
|
@ -26,6 +26,13 @@ const App: React.FC = () => {
|
|||||||
const [copyable, setCopyable] = useState(false);
|
const [copyable, setCopyable] = useState(false);
|
||||||
const [editable, setEditable] = useState(false);
|
const [editable, setEditable] = useState(false);
|
||||||
const [expandable, setExpandable] = useState(false);
|
const [expandable, setExpandable] = useState(false);
|
||||||
|
const [display, setDisplay] = useState('none');
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
setDisplay('block');
|
||||||
|
}, 100);
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -60,6 +67,12 @@ const App: React.FC = () => {
|
|||||||
<p>
|
<p>
|
||||||
[Before]<Text ellipsis>not ellipsis</Text>[After]
|
[Before]<Text ellipsis>not ellipsis</Text>[After]
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<div style={{ display }}>
|
||||||
|
<Text style={{ width: 100 }} ellipsis={{ tooltip: 'I am ellipsis now!' }}>
|
||||||
|
默认display none 样式的超长文字, 悬停tooltip失效了
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -37,7 +37,7 @@ const getBase64 = (file: RcFile): Promise<string> =>
|
|||||||
});
|
});
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const [previewVisible, setPreviewVisible] = useState(false);
|
const [previewOpen, setPreviewOpen] = useState(false);
|
||||||
const [previewImage, setPreviewImage] = useState('');
|
const [previewImage, setPreviewImage] = useState('');
|
||||||
const [fileList, setFileList] = useState<UploadFile[]>([
|
const [fileList, setFileList] = useState<UploadFile[]>([
|
||||||
{
|
{
|
||||||
@ -69,14 +69,14 @@ const App: React.FC = () => {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const handleCancel = () => setPreviewVisible(false);
|
const handleCancel = () => setPreviewOpen(false);
|
||||||
|
|
||||||
const handlePreview = async (file: UploadFile) => {
|
const handlePreview = async (file: UploadFile) => {
|
||||||
if (!file.url && !file.preview) {
|
if (!file.url && !file.preview) {
|
||||||
file.preview = await getBase64(file.originFileObj as RcFile);
|
file.preview = await getBase64(file.originFileObj as RcFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
setPreviewVisible(true);
|
setPreviewOpen(true);
|
||||||
setPreviewImage(file.url || (file.preview as string));
|
setPreviewImage(file.url || (file.preview as string));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ const App: React.FC = () => {
|
|||||||
>
|
>
|
||||||
{fileList.length >= 8 ? null : uploadButton}
|
{fileList.length >= 8 ? null : uploadButton}
|
||||||
</Upload>
|
</Upload>
|
||||||
<Modal visible={previewVisible} footer={null} onCancel={handleCancel}>
|
<Modal open={previewOpen} footer={null} onCancel={handleCancel}>
|
||||||
<img alt="example" style={{ width: '100%' }} src={previewImage} />
|
<img alt="example" style={{ width: '100%' }} src={previewImage} />
|
||||||
</Modal>
|
</Modal>
|
||||||
</>
|
</>
|
||||||
|
@ -29,7 +29,7 @@ const getBase64 = (file: RcFile): Promise<string> =>
|
|||||||
});
|
});
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const [previewVisible, setPreviewVisible] = useState(false);
|
const [previewOpen, setPreviewOpen] = useState(false);
|
||||||
const [previewImage, setPreviewImage] = useState('');
|
const [previewImage, setPreviewImage] = useState('');
|
||||||
const [previewTitle, setPreviewTitle] = useState('');
|
const [previewTitle, setPreviewTitle] = useState('');
|
||||||
const [fileList, setFileList] = useState<UploadFile[]>([
|
const [fileList, setFileList] = useState<UploadFile[]>([
|
||||||
@ -71,7 +71,7 @@ const App: React.FC = () => {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const handleCancel = () => setPreviewVisible(false);
|
const handleCancel = () => setPreviewOpen(false);
|
||||||
|
|
||||||
const handlePreview = async (file: UploadFile) => {
|
const handlePreview = async (file: UploadFile) => {
|
||||||
if (!file.url && !file.preview) {
|
if (!file.url && !file.preview) {
|
||||||
@ -79,7 +79,7 @@ const App: React.FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setPreviewImage(file.url || (file.preview as string));
|
setPreviewImage(file.url || (file.preview as string));
|
||||||
setPreviewVisible(true);
|
setPreviewOpen(true);
|
||||||
setPreviewTitle(file.name || file.url!.substring(file.url!.lastIndexOf('/') + 1));
|
setPreviewTitle(file.name || file.url!.substring(file.url!.lastIndexOf('/') + 1));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ const App: React.FC = () => {
|
|||||||
>
|
>
|
||||||
{fileList.length >= 8 ? null : uploadButton}
|
{fileList.length >= 8 ? null : uploadButton}
|
||||||
</Upload>
|
</Upload>
|
||||||
<Modal visible={previewVisible} title={previewTitle} footer={null} onCancel={handleCancel}>
|
<Modal open={previewOpen} title={previewTitle} footer={null} onCancel={handleCancel}>
|
||||||
<img alt="example" style={{ width: '100%' }} src={previewImage} />
|
<img alt="example" style={{ width: '100%' }} src={previewImage} />
|
||||||
</Modal>
|
</Modal>
|
||||||
</>
|
</>
|
||||||
|
@ -253,6 +253,7 @@
|
|||||||
"open": "^8.0.1",
|
"open": "^8.0.1",
|
||||||
"prettier": "^2.3.2",
|
"prettier": "^2.3.2",
|
||||||
"prettier-plugin-jsdoc": "^0.3.0",
|
"prettier-plugin-jsdoc": "^0.3.0",
|
||||||
|
"pretty-format": "^28.1.3",
|
||||||
"pretty-quick": "^3.0.0",
|
"pretty-quick": "^3.0.0",
|
||||||
"progress": "^2.0.3",
|
"progress": "^2.0.3",
|
||||||
"qs": "^6.10.1",
|
"qs": "^6.10.1",
|
||||||
|
@ -23,7 +23,7 @@ interface PicSearcherProps {
|
|||||||
|
|
||||||
interface PicSearcherState {
|
interface PicSearcherState {
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
modalVisible: boolean;
|
modalOpen: boolean;
|
||||||
popoverVisible: boolean;
|
popoverVisible: boolean;
|
||||||
icons: iconObject[];
|
icons: iconObject[];
|
||||||
fileList: any[];
|
fileList: any[];
|
||||||
@ -40,7 +40,7 @@ const PicSearcher: React.FC<PicSearcherProps> = ({ intl }) => {
|
|||||||
const { messages } = intl;
|
const { messages } = intl;
|
||||||
const [state, setState] = useState<PicSearcherState>({
|
const [state, setState] = useState<PicSearcherState>({
|
||||||
loading: false,
|
loading: false,
|
||||||
modalVisible: false,
|
modalOpen: false,
|
||||||
popoverVisible: false,
|
popoverVisible: false,
|
||||||
icons: [],
|
icons: [],
|
||||||
fileList: [],
|
fileList: [],
|
||||||
@ -104,7 +104,7 @@ const PicSearcher: React.FC<PicSearcherProps> = ({ intl }) => {
|
|||||||
const toggleModal = useCallback(() => {
|
const toggleModal = useCallback(() => {
|
||||||
setState(prev => ({
|
setState(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
modalVisible: !prev.modalVisible,
|
modalOpen: !prev.modalOpen,
|
||||||
popoverVisible: false,
|
popoverVisible: false,
|
||||||
fileList: [],
|
fileList: [],
|
||||||
icons: [],
|
icons: [],
|
||||||
@ -146,7 +146,7 @@ const PicSearcher: React.FC<PicSearcherProps> = ({ intl }) => {
|
|||||||
</Popover>
|
</Popover>
|
||||||
<Modal
|
<Modal
|
||||||
title={messages[`app.docs.components.icon.pic-searcher.title`]}
|
title={messages[`app.docs.components.icon.pic-searcher.title`]}
|
||||||
visible={state.modalVisible}
|
open={state.modalOpen}
|
||||||
onCancel={toggleModal}
|
onCancel={toggleModal}
|
||||||
footer={null}
|
footer={null}
|
||||||
>
|
>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { toHaveNoViolations } from 'jest-axe';
|
import { toHaveNoViolations } from 'jest-axe';
|
||||||
import '@testing-library/jest-dom';
|
import '@testing-library/jest-dom';
|
||||||
|
import format, { plugins } from 'pretty-format';
|
||||||
import { defaultConfig } from '../components/theme/index';
|
import { defaultConfig } from '../components/theme/index';
|
||||||
|
|
||||||
// Not use dynamic hashed for test env since version will change hash dynamically.
|
// Not use dynamic hashed for test env since version will change hash dynamically.
|
||||||
@ -23,4 +24,42 @@ if (process.env.LIB_DIR === 'dist') {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* React 17 & 18 will have different behavior in some special cases:
|
||||||
|
*
|
||||||
|
* React 17:
|
||||||
|
*
|
||||||
|
* ```html
|
||||||
|
* <span> Hello World </span>
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* React 18:
|
||||||
|
*
|
||||||
|
* ```html
|
||||||
|
* <span> Hello World </span>
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* These diff is nothing important in front end but will break in snapshot diff.
|
||||||
|
*/
|
||||||
|
expect.addSnapshotSerializer({
|
||||||
|
test: element =>
|
||||||
|
typeof HTMLElement !== 'undefined' &&
|
||||||
|
(element instanceof HTMLElement ||
|
||||||
|
element instanceof DocumentFragment ||
|
||||||
|
element instanceof HTMLCollection ||
|
||||||
|
(Array.isArray(element) && element[0] instanceof HTMLElement)),
|
||||||
|
print: element => {
|
||||||
|
const htmlContent = format(element, {
|
||||||
|
plugins: [plugins.DOMCollection, plugins.DOMElement],
|
||||||
|
});
|
||||||
|
|
||||||
|
const filtered = htmlContent
|
||||||
|
.split(/[\n\r]+/)
|
||||||
|
.filter(line => line.trim())
|
||||||
|
.join('\n');
|
||||||
|
|
||||||
|
return filtered;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
expect.extend(toHaveNoViolations);
|
expect.extend(toHaveNoViolations);
|
||||||
|
@ -43,7 +43,14 @@ export function renderHook<T>(func: () => T): { result: React.RefObject<T> } {
|
|||||||
return { result };
|
return { result };
|
||||||
}
|
}
|
||||||
|
|
||||||
export { customRender as render };
|
/**
|
||||||
|
* Pure render like `@testing-lib` render which will not wrap with StrictMode.
|
||||||
|
*
|
||||||
|
* Please only use with render times times of memo usage case.
|
||||||
|
*/
|
||||||
|
const pureRender = render;
|
||||||
|
|
||||||
|
export { customRender as render, pureRender };
|
||||||
|
|
||||||
export const triggerResize = (target: Element) => {
|
export const triggerResize = (target: Element) => {
|
||||||
const originGetBoundingClientRect = target.getBoundingClientRect;
|
const originGetBoundingClientRect = target.getBoundingClientRect;
|
||||||
|
Loading…
Reference in New Issue
Block a user